openGL 使用 GetTextureImage 读取只有红色分量的纹理数据

openGL reading red-component-only texture data with GetTextureImage

我的问题是,我无法正确读取存储在只有红色分量的纹理中的值。我的第一个实现导致缓冲区溢出。所以我阅读了 openGL 参考,它说:

If the selected texture image does not contain four components, the following mappings are applied. Single-component textures are treated as RGBA buffers with red set to the single-component value, green set to 0, blue set to 0, and alpha set to 1. Two-component textures are treated as RGBA buffers with red set to the value of component zero, alpha set to the value of component one, and green and blue set to 0. Finally, three-component textures are treated as RGBA buffers with red set to component zero, green set to component one, blue set to component two, and alpha set to 1.

首先令人困惑的是,nvidia 实现将这些值紧密地打包在一起。如果我有四个单字节值,我只需要四个字节 space,而不是 16。 所以我读了 openGL specification,它在 table 8.18 的第 236 页告诉我相同,除了双分量纹理将它的第二个值存储在绿色通道中,而不是在 alpha 通道中,这使得对我来说也更有意义。但哪个定义是正确的?

它还说:

If format is a color format then the components are assigned among R, G, B, and A according to table 8.18[...]

所以我问你:"What is a color format?"和"Is my texture data tight packed if the format is not a color format"? 我的纹理定义如下: 类型:GL_UNSIGNED_BYTE 格式:GL_RED 内部格式:GL_R8

另一件事是,当我的纹理的大小是像素的两倍时,前两个值保存在前两个字节中,而另外两个值保存在缓冲区的第五个和第六个字节中。中间的两个字节是填充。所以我得到了 "GL_PACK_ALIGNMENT" 状态,它表示四个字节。怎么可能?

GetTexImage 调用:

std::vector<GLubyte> values(TEXTURERESOLUTION * TEXTURERESOLUTION);

GLvoid *data = &values[0];//values are being passed through a function which does that

glBindTexture(GL_TEXTURE_2D, TEXTUREINDEX);
glGetTexImage(GL_TEXTURE_2D, 0, GL_RED, GL_UNSIGNED_BYTE, data);
glBindTexture(GL_TEXTURE_2D, 0);

The first confusing thing is, that the nvidia implementation packs the values tight together.

这正是应该发生的事情。仅当您实际使用 GL_RGGL_RGBGL_RGBA 格式回读时,对 2、3 或 4 个组件的扩展才有意义(并且源纹理的组件较少​​。如果您只是要求GL_RED 你也只会得到 GL_RED

[...] except that a two component texture stores it second value not in the alpha channel, but in the green channel, which makes also more sense for me. But which definition is correct?

正确的定义是规范中的定义。不幸的是,参考页经常有小的不准确或遗漏。在这种情况下,我认为参考已经过时了。该说明分别与一个和两个频道的旧的和现在已弃用的 GL_LUMINANCEGL_LUMINANCE_ALPHA 格式相匹配,而不是现代的 GL_REDGL_RG 格式。

So I ask you: "What is a color format?"

颜色格式是一种用于颜色纹理的格式,与 GL_DEPTH_COMPONENTGL_STENCIL_INDEX 等非颜色格式形成对比。

关于 GL_PACK_ALIGNMENT 的问题:GL 的行为完全符合预期。您有一个 2x2 纹理和 GL_PACK_ALIGNMENT 为 4,这意味着数据将在每个 处填充,因此一行与下一行之间的距离将是 4 的倍数。所以你会得到第一行紧密打包,2个填充字节,最后是第二行。