通过 glTexSubImage3d 上传纹理数据时,像素传输格式可以改变吗?
Posted
技术标签:
【中文标题】通过 glTexSubImage3d 上传纹理数据时,像素传输格式可以改变吗?【英文标题】:Can the pixel transfer format change when uploading texture data via glTexSubImage? 【发布时间】:2014-11-12 09:25:57 【问题描述】:我面临的情况是,为了兼容性,我首先分配纹理的存储空间,然后将纹理数据上传到其中。这个想法是根据是否支持不可变存储来保持代码路径相似。
在没有不可变存储的情况下,存储通过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)认为不可以。
换句话说,这个调用应该起作用吗?
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 参数宽度、高度、格式、类型和数据与 TexImage2D 的相应参数匹配,这意味着它们使用相同的值指定,并且具有相同的含义。
再一次,对我来说,这并不意味着像素传输格式必须匹配,只是接受的值来自同一个集合。
那么,我的解释正确吗?
附录。
我一直在研究 OpenGL 手册页。现在当然它们不是规范的(规范是),但是 ES2/3 手册页和 OpenGL 4.5 手册页之间存在显着差异:
GLES 2:https://www.khronos.org/opengles/sdk/docs/man/xhtml/glTexImage2D.xml GLES 3:https://www.khronos.org/opengles/sdk/docs/man3/html/glTexImage2D.xhtml GL 4.5:https://www.opengl.org/sdk/docs/man/html/glTexImage2D.xhtml请注意,在 GLES3 案例中,有这样的措辞:“internalFormat 可能是显示的未调整大小的(基本)内部格式之一,以及有效的格式和类型组合”,强烈暗示确实使用三元组来分配存储空间.
不过,GLES3 也有开箱即用的不可变存储,所以这没有任何意义...
但无论如何,这使我对glTexImage2D
的调用完全合法。然后,有问题的调用变成了glTexSubImage2D
:
在那里,引用内部格式的唯一错误条件是 GLES 2 中的:
GL_INVALID_OPERATION
如果纹理数组未被先前的glTexImage2D
或glCopyTexImage2D
操作定义,其internalformat 匹配glTexSubImage2D
的格式 .
这在 GLES 3 中:
GL_INVALID_OPERATION
如果之前指定的纹理数组的internalFormat、format和type的组合无效则生成。见glTexImage2D
。
这再次意味着我的解释是正确的:传递给glTexSubImage2D
的格式+类型的组合,加上传递给glTexImage2D
的内部格式,确实是glTexImage2D
文档中列出的有效组合。
【问题讨论】:
【参考方案1】:那么,我的解释正确吗?
一句话:是的。它被称为内部格式和像素数据格式是有原因的。 ANGLE 是 OpenGL-ES 的仿真,因此遵循为此指定的规范和行为。这与您的观察一致。
【讨论】:
对不起,什么是“一致的”?我解释 OpenGL ES 2.0 规范的方式与解释 OpenGL 4.5 的方式相同——“使用相同的值”意味着“接受来自同一组的值”。所以 ANGLE 的行为在这里是有问题的。 @peppe:我必须仔细阅读 ES 规范的那部分内容。 在原帖中添加了一些内容。 @peppe:OpenGL ES 与桌面 GL 的不同之处在于它不支持像素传输期间的数据转换。您的内部格式必须与像素数据格式匹配,这就是 ES 手册页中有entire tables dedicated to matching formats 的原因。这一切都归结为简化 ES 中的实现,并且在像素传输期间转换图像格式会增加许多不必要的复杂性,这显然只在桌面 GL 中值得;) @AndonM.Coleman:这也是我最初对 ES 规范措辞的解释。以上是关于通过 glTexSubImage3d 上传纹理数据时,像素传输格式可以改变吗?的主要内容,如果未能解决你的问题,请参考以下文章
glTexSubImage3D vs QOpenGLTexture setData