0

我已经在下面回答了我的问题。感谢 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 纹理中,当我直接发送表面-> 像素时它确实有效。但我想自己创建数据数组。非常感谢您的帮助!

编辑:对不起,我没有很好地解释自己。我正在尝试从包含 24 位 TGA 图像的 SDL_Surface 手动重新创建纹理,然后将其交给 opengl 以创建纹理。我用表面->像素测试了我的opengl代码,它工作正常。我只是想弄清楚我在哪里出错了加载它。

4

3 回答 3

2

除非您使用一些令人难以置信的深奥体系结构,否则unsigned char几乎可以肯定它等同于。uint8_t

但是代码中存在一些问题,尽管尚不清楚您正在尝试做什么或问题是什么。

首先,您在调用 getColourAt() 时已转置了 x,y 坐标。您正在使用 i 来索引高度和 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;

因为您将拥有i完整的width字节行,以及j不完整行上的字节。

此外,您在SDL_GetRGB调用中缺少像素格式,因此甚至无法编译。

最后,您的 getColour() 函数将无法正常工作;它将始终返回 0,0 处的像素值,因为您没有将 x,y 偏移到图像中。为此,您可以使用与上述相同的技术。请注意您的索引,就好像您使用带有 SDL 的 UInt32 暗示 RGBA(32 位)像素格式,但您使用的是 RGB(24 位)。

于 2012-04-20T10:49:33.250 回答
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;
}
于 2012-04-20T17:29:51.977 回答
0

的大小Uint8取决于它的声明。另一方面,unsigned char尽管在许多平台上它是 8 位,但在 C++ 标准中也没有将其大小指定为精确的 8 位。

最好Uint8直接在你的中使用,Colour24以避免转换错误。

于 2012-04-20T10:44:04.593 回答