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

标签 c++ opengl textures

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

宽度=16:

宽度=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);

最佳答案

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

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

由于图像有 1 个 (RED) 颜色 channel ,并且被紧密打包,所以如果 width=16,则图像行的开始对齐到 4 字节,但它没有对齐到 4字节,如果 width=15

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

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整除。

关于c++ - OpenGL:当尺寸不能被 4 整除时,灰度纹理数据布局不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57346317/

相关文章:

c++ - std::optional<std::reference_wrapper<T>> - 可以吗?

c++ - 使用注入(inject)的 DLL 从外部应用程序渲染 OpenGL 场景内部

OpenGL 2D 形状问题

c++ - 使用 GLM(旋转)为 OpenGL 创建变换矩阵

c# - 如何在 XNA 中的 3D 地形上画一个圆圈?

c++ - 在表面上循环纹理

javascript - 是否可以在不使用自定义着色器的情况下使用 2 个纹理(一个在另一个之上)作为 Material ?

C++ 无法建立对 'parent' 对象的句柄引用——循环包含或未定义类型错误

c++ - 从原始指针创建 weak_ptr<>

c++ - 映射动态纹理导致 "Already Mapped Error"