OpenGL纹理加载问题:交叉的图像处理。

3

问题图片:

问题图片

我发现图像有些偏移。我认为贴图位置是问题所在,但我无法解决这个问题。

我的代码:

GLuint LoadTexture(const char * filename, int width, int height)

GLuint texture;
unsigned char * data;
FILE * file;

file = fopen(filename, "r");

if (file == NULL) return 0;

data = (unsigned char *)malloc(width * height * 3);
fread(data, width * height * 3, 1, file);
fclose(file);

// RGB
for (int i = 0; i < width * height; ++i)
{
    int index = i * 3;
    unsigned char B, R;
    B = data[index];
    R = data[index + 2];

    data[index] = R;
    data[index + 2] = B;
}

glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND); // GL_REPLACE에서 교체했음
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); // GL_CLAMP
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);

return texture;

并且

    glBindTexture(GL_TEXTURE_2D, texture_image[2]);
    glBlendFunc(GL_ONE, GL_ONE);
    glBegin(GL_QUADS);
    glTexCoord2i(0, 0); glVertex3f(-32, -32, 0);
    glTexCoord2i(0, 1); glVertex3f(-32, 32, 0);
    glTexCoord2i(1, 1); glVertex3f(32, 32, 0);
    glTexCoord2i(1, 0); glVertex3f(32, -32, 0);
    glEnd();

这是我的第一个问题, 我不知道是否正确,但感谢你。


1
纹理的格式是什么?你确定每个像素都有24位吗?原始图像文件是什么? - Rabbid76
它是Bmp和RGB24。 - Kyurestial
1
但是 BMP 文件有一个文件头! - Rabbid76
我发现头文件包含宽度、高度、分辨率和像素位数。 如果没错的话,它应该是64、64、64X64、24位。 - Kyurestial
2个回答

1

一个Windows位图文件有54个字节的文件头。在这个头中编码了文件的格式。

如果你知道文件格式是24位RGB,那么你可以简单地跳过头部。

data = (unsigned char *)malloc(width * height * 3 + 54);
fread(data, width * height * 3 + 54, 1, file);
fclose(file);

.....

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data+54);

进一步说明,默认情况下,纹理的每一行都假定对齐到4个字节。
在24位RGB BMP图像中,每个纹素需要24位或3个字节,并且纹素紧密地填充在纹理的行中。 这意味着纹理行开头的4个字节对齐被忽略(除非纹理的宽度乘以3可被4整除而没有余数)。

在您的情况下,这不是任何问题,因为您的纹理宽度为64像素,而64 * 3可被4整除。但是,如果每行的字节数不能被4整除,则必须将对齐方式更改为1。

这意味着在将紧密打包的纹理加载到GPU(glTexImage2D)之前,必须将GL_UNPACK_ALIGNMENT参数设置为1。
否则,在纹理查找时会获得每行0-3个字节的偏移。这将导致纹理不断扭曲或倾斜。
glPixelStore(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data+54);

0

你需要一个裸的GL_UNSIGNED_BYTE GL_RGB图像,而那可能不是这个图像的格式。OpenGL根本不提供任何文件格式支持。你可以使用例如GIMP将文件保存为这样的格式,但那将是一个大文件(编辑:一旦你跨越BMP头部,未压缩的位图24BPP就是这样的格式)。更可持续的解决方案是将文件保存在已知格式中,并使用库对其进行解压缩。我最喜欢的一些库包括:


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接