我面临的情况是,为了兼容性,首先我分配纹理的存储空间,然后将纹理数据上传到其中。根据是支持还是不支持不可变存储,我们的想法是保持代码路径相似。
在没有不可变存储的情况下,存储通过glTexImage2D
调用(使用NULL数据指针,没有绑定像素解包缓冲区)进行分配,例如:
glTexImage2D(GL_TEXTURE_2D, 0,
GL_RGBA,
width, height, 0,
GL_RGBA,
GL_UNSIGNED_BYTE,
0);
此后,实际数据上传:
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
width, height,
GL_RGBA,
GL_UNSIGNED_BYTE,
data);
问题是:在上传时,像素传输格式是否可以与分配存储时指定的格式不同?有些驱动程序认为是,某些驱动程序(特别是:ANGLE)认为不是。< / p>
换句话说,那么这个调用应该是什么?
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
width, height,
GL_RGBA,
GL_FLOAT, // <-- DIFFERENT
data);
我对OpenGL 4.5规范的解释是的。不仅glTexSubImage2D
应该使用不可变纹理(并且在glTexStorage
调用中没有指定像素传输格式); 4.5规范在§8.6(强调我的)中说:
TexSubImage * D和TextureSubImage * D参数的宽度,高度,深度,格式,类型和数据与相应的TexImage * D命令(存在这些参数的地方)的相应参数匹配,这意味着它们接受相同的参数值,并具有相同的含义。
对我而言,这意味着“他们接受相同的值集”(有效值中的任何值),而不是“他们接受传递给glTexImage*D
的相同值。”
在OpenGL ES 2.0规范中,措辞略有不同:
TexSubImage2D参数width,height,format,type和data匹配TexImage2D的相应参数,这意味着它们使用相同的值指定,并具有相同的含义。
同样,对我而言,这并不意味着像素传输格式必须匹配,只是接受的值来自同一集合。
那么,我的解释是否正确?
附录
我一直在深入研究OpenGL手册页。现在当然它们不是规范性的(规范是),但是ES2 / 3手册页和OpenGL 4.5之间存在显着差异:
请注意,在GLES3的情况下,有这样的措辞:“internalFormat可能是显示的未规划(基本)内部格式之一,以及有效的格式和类型组合”,强烈暗示三元组确实用于分配存储
但是,GLES3还具有开箱即用的不可变存储空间,所以没有任何意义......
但无论如何,这使我对glTexImage2D
的呼吁完全合法。然后,有问题的电话会变成glTexSubImage2D
:
在那里,引用内部格式的唯一错误条件是GLES 2:
如果纹理数组尚未由 internalformat 与格式匹配的先前GL_INVALID_OPERATION
或glTexImage2D
操作定义,则会生成of
glCopyTexImage2D
glTexSubImage2D
。
这在GLES 3中:
如果先前指定的纹理数组 format 和 type 的 internalFormat 的组合无效,则会生成
GL_INVALID_OPERATION
。见glTexImage2D
。
这再次意味着我的解释是正确的:传递给glTexSubImage2D
的格式+类型的组合加上传递给glTexImage2D
的内部格式,确实是glTexImage2D
中列出的有效组合文件:
答案 0 :(得分:2)
那么,我的解释是否正确?
总之一句:是的。出于某种原因,它被称为内部格式和像素数据格式。 ANGLE是OpenGL-ES的仿真,因此遵循为此指定的规范和行为。这与你的观察结果一致。