OpenGL缓冲区对象支持各种明确宽度的数据类型(GL_FLOAT
32位,GL_HALF_FLOAT
16位,GL_INT
32位......)
如何确保OpenGL的跨平台和未来类型?例如,将float
数据从c ++数组提供给缓冲区对象并说明其类型GL_FLOAT
将不适用于float
不是32位的平台.
在对此进行一些研究时,我注意到GL规范中如何定义这些类型的细微但有趣的变化.OpenGL 4.1和4.2之间发生了变化.
在OpenGL 4.1中,列出数据类型的表(最近的规范文档中的表2.2)具有size列的最小位宽度,表格标题显示(由我添加的重点):
GL类型不是C类型.因此,例如,GL类型int在本文档之外被称为GLint,并且不一定等同于C类型int.实现可以使用比表中指示的数字更多的比特来表示GL类型.但是,不需要对最小范围之外的整数值进行正确解释.
从OpenGL 4.2规范开始,表头更改为位宽,表标题更改为:
GL类型不是C类型.因此,例如,GL类型int在本文档之外被称为GLint,并且不一定等同于C类型int.实现必须精确使用表中指示的位数来表示GL类型.
这影响了问题的答案.如果使用最新的定义,则可以在代码中使用标准大小的类型定义而不是GL类型,并安全地假设它们匹配.例如,您可以使用int32_t
from <cstdint>
而不是GLint
.
使用GL类型仍然是最直接的解决方案.但是,根据您的代码体系结构和首选项,可能不合需要.如果您希望将软件划分为组件,并希望在提供一定级别的抽象的同时将OpenGL渲染隔离在单个组件中,那么您可能不希望在代码中使用GL类型.然而,一旦数据到达渲染代码,它必须匹配相应的GL类型.
作为一个典型的例子,假设你有计算代码产生你想要渲染的数据.您可能不希望GLfloat
在计算代码中都有类型,因为它可以独立于OpenGL使用.然而,一旦你准备好显示计算结果,并希望将数据放入VBO中进行OpenGL渲染,那么类型必须与之相同GLfloat
.
您可以使用各种方法.一个是我在上面提到的,使用非渲染代码中标准C++头文件的大小类型.同样,您可以定义自己的typedef,它们与OpenGL使用的类型相匹配.或者,由于性能原因不太理想,您可以根据需要转换数据,可能基于比较sizeof()
传入类型和GL类型之间的值.