我的问题是,我无法读取存储在只有正确红色组件的纹理中的值。我的第一个实现导致缓冲区溢出。所以我阅读了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);
答案 0 :(得分:0)
第一个令人困惑的事情是,nvidia实现将值紧密地组合在一起。
这正是应该发生的事情。只有在您实际使用GL_RG
,GL_RGB
或GL_RGBA
格式进行回读时,才能扩展到2,3或4个组件(并且源纹理需要较少的组件。如果您只是需要GL_RED
您只会获得GL_RED
[...]除了双组件纹理存储它不是在alpha通道中的第二个值,而是在绿色通道中,这对我来说也更有意义。但哪个定义是正确的?
正确的定义是规范中的定义。遗憾的是,参考页面通常存在很小的不准确或遗漏。在这种情况下,我认为该引用刚刚过时。该说明与一个和两个频道的旧版本和现已弃用的GL_LUMINANCE
和GL_LUMINANCE_ALPHA
格式相匹配,而不是现代GL_RED
和GL_RG
。
所以我问你:“什么是颜色格式?”
颜色纹理是一种颜色纹理,与GL_DEPTH_COMPONENT
或GL_STENCIL_INDEX
等非颜色格式相反。
关于GL_PACK_ALIGNMENT
的问题:GL的行为完全符合预期的行为。你有一个2x2纹理和GL_PACK_ALIGNMENT
4,这意味着数据将在每个行填充,所以从下一行拖动的距离将是4的倍数。所以你会得到第一行紧密包装,2个填充字节,最后是第二行。