2

由于纹理在 OpenGL 中必须是 2 的幂,因此我在 OpenGL 中遇到了麻烦。我正在做的是以下内容:

我使用 PNGLIB 或 SOIL 将 PNG 文件加载到无符号字符数组中。这个想法是我可以通过这个数组运行并“选择”与我相关的部分。例如,假设我加载了一个人,但我只想将头部存储在单独的纹理中。所以我循环遍历数组并只选择必要的部分。

第一个问题: 我相信数组中的数据是以 RGBA 模式存储的,但我还不确定数据是按行填充还是按列填充。有可能知道这些信息吗?

第二个问题:由于需要始终创建 2 个纹理的幂,因此我可能有一个宽度为 513 像素的图像,因此我需要一个宽度为 1024 像素的纹理。所以发生的事情是图片看起来像是被完全“破坏”了,因为像素不在它们应该在的地方 - 纹理的大小与填充在数组中的相关数据不同。那么我怎样才能设法重新组织数组以再次获取图像的内容呢?我尝试了以下方法,但它不起作用:

unsigned char* new_memory = 0;

    int index = 0;
    int new_index = 0;
    new_memory = new unsigned char[new_tex_width * new_tex_height * 4];

    for(int i=0; i<picture.width; i++) // WIDTH
    {
        for(int j=0; j<picture.height; j++) // HEIGHT
        {
            for(int k=0; k<4; k++) // DEPTH
                new_memory[new_index++] = picture.memory[index++];//picture.memory[i + picture.height * (j + 4 * k)];
        }
        new_index += new_tex_height - picture.height;
    }


    glGenTextures(1, &png_texture);
    glBindTexture(GL_TEXTURE_2D, png_texture);

    glTexImage2D(GL_TEXTURE_2D, 0, 3, new_tex_width, new_tex_height, 0 , GL_RGBA, GL_UNSIGNED_BYTE, new_memory);
4

1 回答 1

3

很久以前就支持两种纹理的非幂次。但是,创建纹理图集和重新排列纹理仍然有很多优点,我们这样做的方式是简单地使用freeimage,因为它们会为您处理所有这些并支持一些压缩格式。

如果您想按照自己的方式进行操作,并且知道它只是一个位图,那么我会按照以下方式进行更多操作(未经测试,不检查输入,但应该给您一个想法):

void Blit( int xOffset, int yOffset, int targetW, int sourceW, int sourceH, unsigned char* source, unsigned char* target, unsigned int bpp )
{
    for( unsigned int i = 0; i < sourceH; ++i )
    {
        memcpy( target + bpp * ( targetW * ( yOffset + i ) + xOffset ), source + sourceW * i * bpp, sourceW * bpp );
    }
}

基本上,只需将每一行都记录下来。

于 2012-06-18T10:01:23.020 回答