我在下面回答了我的问题。感谢gavinb的帮助。
问题: 我试图复制纹理只是为了学习体验。我正在使用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纹理中,当我直接发送surface-&gt;像素时,它确实有效。但是我想自己创建数据阵列。非常感谢帮助!
编辑:对不起,我没有给自己解释得很好。我试图从包含24位TGA图像的SDL_Surface手动重新创建纹理,然后我将它交给opengl来创建纹理。我用surface-&gt;像素测试了我的opengl代码,它运行正常。我只是试图找出我装错的地方。答案 0 :(得分:2)
unsigned char
几乎肯定等同于uint8_t
,除非你使用了一些令人难以置信的深奥架构。
但代码中存在一些问题,但目前尚不清楚您正在尝试做什么或问题是什么。
首先,在调用getColourAt()时,您已转换了x,y坐标。您使用i来索引高度,使用j来索引宽度,因此您应该使用j,因此:
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;
因为在不完整的行上将有i
个完整的width
个字节行和j
个字节。
此外,您在SDL_GetRGB
调用中缺少像素格式,因此甚至无法编译。
最后,你的getColour()函数将无法正常工作;它将始终返回0,0处像素的值,因为您没有通过x,y偏移到图像中。您可以使用与上面相同的技术。请注意您的索引,就像您使用带有SDL的UInt32暗示RGBA(32位)像素格式,但您使用的是RGB(24位)。
答案 1 :(得分: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;
}
答案 2 :(得分:0)
Uint8
的大小取决于其声明。另一方面,unsigned char
的大小也没有在C ++标准中指定为8位,尽管它在许多平台上都是8位。
最好在Uint8
中直接使用Colour24
以避免转换错误。