openGL使用GetTextureImage读取仅含红色组件的纹理数据

时间:2015-04-21 09:48:45

标签: opengl

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

  

如果所选纹理图像不包含四个组件,则应用以下映射。单组件纹理被视为RGBA缓冲区,红色设置为单组件值,绿色设置为0,蓝色设置为0,alpha设置为1.双组件纹理被视为RGBA缓冲区,红色设置为值组件零,alpha设置为组件1的值,绿色和蓝色设置为0.最后,三组件纹理被视为RGBA缓冲区,红色设置为组件零,绿色设置为组件一,蓝色设置为组件二,alpha设置为1。

第一个令人困惑的事情是,nvidia实现将值紧密地组合在一起。如果我有四个一个字节的值,我只需要四个字节空间,而不是16个。 所以我读了openGL specification并且它在表格8.18中的第236页告诉我相同,除了双组件纹理存储它不是在alpha通道中的第二个值,而是在绿色通道中,这对于我。但哪个定义是正确的?

它还说:

  

如果format是颜色格式,则分配组件   根据表8.18 [...]

,在R,G,B和A之间

所以我问你:“什么是颜色格式?”并且“如果格式不是彩色格式,我的纹理数据是否紧凑”? 我的纹理定义如下: 类型:GL_UNSIGNED_BYTE 格式:GL_RED internalformat: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);

1 个答案:

答案 0 :(得分:0)

  

第一个令人困惑的事情是,nvidia实现将值紧密地组合在一起。

这正是应该发生的事情。只有在您实际使用GL_RGGL_RGBGL_RGBA格式进行回读时,才能扩展到2,3或4个组件(并且源纹理需要较少的组件。如果您只是需要GL_RED您只会获得GL_RED

  

[...]除了双组件纹理存储它不是在alpha通道中的第二个值,而是在绿色通道中,这对我来说也更有意义。但哪个定义是正确的?

正确的定义是规范中的定义。遗憾的是,参考页面通常存在很小的不准确或遗漏。在这种情况下,我认为该引用刚刚过时。该说明与一个和两个频道的旧版本和现已弃用的GL_LUMINANCEGL_LUMINANCE_ALPHA格式相匹配,而不是现代GL_REDGL_RG

  

所以我问你:“什么是颜色格式?”

颜色纹理是一种颜色纹理,与GL_DEPTH_COMPONENTGL_STENCIL_INDEX等非颜色格式相反。

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