OpenGL:当尺寸不能被 4 整除时,灰度纹理数据布局不匹配

Posted

技术标签:

【中文标题】OpenGL:当尺寸不能被 4 整除时,灰度纹理数据布局不匹配【英文标题】:OpenGL: Greyscale texture data layout doesn't match when the dimensions aren't divisible by 4 【发布时间】:2019-08-04 11:53:13 【问题描述】:

如果我创建尺寸不能被 4 整除的灰度纹理,则布局与给定数据不匹配。如果我制作纹理 RGBA,一切正常。这是怎么回事? openGL 是否在内部将数据打包成 RGBA 格式?

width=16:

width=15

int width = 15;
unsigned char* localBuffer = new unsigned char[width*width];

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

for (int i = 0; i < width*width; i++)

    float x = (i % width) / (float)width;
    localBuffer[i] = x * 255;


glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width, width, 0, GL_RED, GL_UNSIGNED_BYTE, localBuffer);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

【问题讨论】:

【参考方案1】:

默认情况下,OpenGL 假定图像每行的开头对齐 4 个字节。

这是因为GL_UNPACK_ALIGNMENT参数默认为4。

由于图像有 1 个 (RED) 颜色通道,并且是紧密排列的,因此如果 width=16,图像行的开头对齐到 4 个字节,但如果 width=15,它不会对齐到 4 个字节。

在指定二维纹理图像(glTexImage2D)之前,将GL_UNPACK_ALIGNMENT参数更改为1:

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width, width, 
             0, GL_RED, GL_UNSIGNED_BYTE, localBuffer);

由于错过了这一点,这会在图像的每一行产生移位效果,除非图像的宽度可以被 4 整除。 当图片的格式改为GL_RGBA时,单个像素的大小为4,所以一行的大小(以字节为单位)无论如何都可以被4整除。

【讨论】:

以上是关于OpenGL:当尺寸不能被 4 整除时,灰度纹理数据布局不匹配的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL:随机调用 OpenGL 函数时崩溃

OpenGL灰度纹理作为浮动错误格式

将灰度 OpenCV 图像传递给 OpenGL 纹理

如何显示带有opengl纹理的灰度图像

CUDA/OpenGL InterOp:使用灰度图像作为纹理

ffmpeg:宽度不能被 2 整除(保持比例时)