2012-04-20 221 views
0

我已經在下面回答了我的問題。感謝gavinb的幫助。將Uint8轉換爲無符號字符的RGB值

問題: 我試圖複製紋理只是爲了學習體驗。我使用24位TGA圖像,並使用SDL加載它。我已經創建了自己的結構

struct Colour24 
{ 
    unsigned char r; 
    unsigned char g; 
    unsigned char b; 
} 

unsigned char* texture = new unsigned char[width * height * 3]; 

    for (int y = 0; y < height; y++) 
    { 
     for (int x = 0; x < width; x++) 
     { 
      int index = (y * width) + x; 

      Colour24 colour = getColourAt(x, y); 

      newTexture[index] = colour.r; 
      newTexture[index + 1] = colour.g; 
      newTexture[index + 2] = colour.b; 
     } 
    } 

Colour24 getColour(int x, int y) 
{ 
    Uint32 pixel; 
    Uint8 red, green, blue; 
    Colour24 rgb; 

    pixel = getPixel(m_surface, x, y); // using the SDL get pixel function 

    SDL_GetRGB(pixel, m_surface->format, &red, &green, &blue); 

    rgb.r = red; 
    rgb.b = blue; 
    rgb.g = green; 

    return rgb; 
} 

OLD: 我打算髮送到一個OpenGL紋理這個和它的工作時,我直接將表面 - >像素。但我想自己創建數據數組。非常感謝幫助!

編輯:對不起,我沒有解釋得很好。我試圖從包含24位TGA圖像的SDL_Surface中手動重新創建紋理,然後我將它交給opengl來創建紋理。我已經用surface-> pixels測試了我的opengl代碼,它工作正常。我只是試圖找出我在哪裏加載錯誤。

+0

究竟是什麼問題?編譯器錯誤?不符合你的期望?至少你的代碼是不完整的,因爲它包含與函數定義相同級別的代碼。 – bjhend 2012-04-20 10:40:09

+0

我可以將這個紋理加載到opengl中,但它不正確。我得到了很多紅色,綠色和藍色的交叉孵化發生。 – rocklobster 2012-04-20 10:48:12

回答

1

結束寫我自己的TGA加載程序,然後發現我需要乘以每像素字節的高度。仍然不是100%確定爲什麼(隨意評論),但它現在起作用。

代碼:

TGAReader* reader = new TGAReader(); 
reader->readSurface("MyTexture.tga"); 

int height = reader->height; 
int width = reader->width; 
int bpp = reader->bpp; 

unsigned char* texture = new unsigned char[width * height * bpp]; 

for (int y = 0; y < height * bpp; y++) 
{ 
    for (int x = 0; x < width; x += 3) 
    { 
     int index = (y * width) + x; 

     Colour24 colour = reader->getColourAt(x, y); 

     newTexture[index] = colour.r; 
     newTexture[index + 1] = colour.g; 
     newTexture[index + 2] = colour.b; 
    } 
} 
// create OpenGL texture 
unsigned int = createTextureFromData(newTexture, width, height, bpp); 

// reading tga data 
Colour24 TGAReader::getColourAt(int x, int y) 
{ 
    Colour24 rgb; 

    rgb.r = m_data[((y * width) + x)]; 
    rgb.g = m_data[((y * width) + x) + 1]; 
    rgb.b = m_data[((y * width) + x) + 2]; 

    return rgb; 
} 
0

Uint8的大小取決於其聲明。另一方面,在C++標準中,unsigned char的大小也沒有被指定爲8位,儘管它在許多平臺上都是8位。

最好在您的Colour24中直接使用Uint8以避免轉換錯誤。

+0

謝謝,我現在就試試。 – rocklobster 2012-04-20 10:48:21

+0

編輯:只是檢查。 Uint8是uint8_t的typedef,這是一個unsigned char的typedef ... – rocklobster 2012-04-20 10:51:11

2

unsigned char幾乎可以肯定相當於uint8_t,除非你使用了一些令人難以置信的深奧的架構。

但是在代碼中存在一些問題,儘管目前還不清楚你想要做什麼或者問題是什麼。

首先,您在調用getColourAt()時轉置了x,y座標。您正在使用我索引的高度和j索引的寬度,所以你應該使用J,I這樣的:

Colour24 colour = getColourAt(j, i); 

也許這將是簡單的堅持與X,Y命名。

其次,索引到紋理緩衝區是錯誤的。它應該是:

texture[i*width+j+0] = colour.red; 
texture[i*width+j+1] = colour.green; 
texture[i*width+j+2] = colour.blue; 

,因爲你將有width字節i完整行,並在不完全排j字節。

此外,您正在丟失SDL_GetRGB調用中的像素格式,所以這甚至不會編譯。

最後,您的getColour()函數將無法正常工作;它總是會返回0,0像素的值,因爲您沒有通過x,y偏移到圖像中。您可以使用與上述相同的技術。只要注意索引,就好像您使用的是帶有SDL的UInt32,這意味着RGBA(32位)像素格式,但是您使用的是RGB(24位)。

+0

現在測試一下。爲了清晰起見,我還編輯了原始文章。 – rocklobster 2012-04-20 10:54:03

+0

好吧,我已經使用新代碼更新了原始帖子。我有不同的結果,但仍然是奇怪的。 – rocklobster 2012-04-20 11:01:46

+1

將y值索引乘以紋理緩衝區時,仍然需要使用寬度而不是高度。另外,由於像素是UInt32,因此您會陷入上述陷阱中,將緩衝區視爲32bpp而不是24bpp。查看http://www.libsdl.org/cgi/docwiki.cgi/Introduction_to_SDL_Video#getpixel,瞭解適用於所有像素格式的完整解決方案。 – gavinb 2012-04-20 11:08:51

相關問題