OpenGL有四个不同的主要版本,不包括移动设备和嵌入式系统(OpenGL | ES)以及通过JavaScript通过Web(WebGL)的版本。就像Direct3D 11与Direct3D 8具有不同的处理方式一样,OpenGL 3与OpenGL 1也具有不同的处理方式。最大的不同是OpenGL版本基本上只是旧版本的附件(但不是完全)。
除了OpenGL的不同版本外,主要OpenGL还添加了配置文件的概念。即兼容性配置文件(启用对较早版本的API的支持)和核心配置文件(禁用那些旧的API)。glBegin
当您使用Core Profile时,诸如此类的东西根本不起作用,而当您使用Compatibility Profile(默认情况)时,则不会。
另一个严重的麻烦是,某些OpenGL实现(例如Apple的实现)仅在使用Core Profile时才启用较新的OpenGL功能。这意味着您必须停止使用较旧的API才能使用较新的API。
然后,您将遇到几种非常令人困惑的教程场景:
- 本教程很旧,仅使用不推荐使用的API。
- 本教程是新的且编写良好,仅使用与Core兼容的API。
- 本教程是新的,但是会犯一个错误,即假定您正在使用在兼容模式下启用所有API并自由地混合使用新旧API的驱动程序。
- 本教程适用于其他版本的OpenGL,例如OpenGL | ES,该版本完全不支持任何版本的旧API。
类似glBegin
的事情是有时称为即时模式API的一部分。这也非常令人困惑,因为在OpenGL中没有保留模式,而“即时模式”在图形中已经有了不同的定义。最好将它们称为OpenGL 1.x API,因为自OpenGL 2.1以来它们已经过时了。
过去,OpenGL的1.x API会立即将顶点提交给图形管道。当渲染顶点的硬件速度与生成顶点数据的CPU速度大致相当时,此方法效果很好。当时的OpenGL仅卸载了三角形栅格化,而没有其他事情。
如今,GPU可以以极高的速度咀嚼大量顶点,同时执行高级顶点和像素转换,CPU甚至无法远程跟上。最重要的是,CPU和GPU之间的接口是围绕这种速度差异而设计的,这意味着不再可能一次将顶点提交给GPU。
所有GL驱动程序都必须glBegin
在内部进行仿真,方法是在内部分配一个顶点缓冲区,将与提交的顶点一起glVertex
放入此缓冲区,然后在调用时在单个绘制调用中提交整个缓冲区glEnd
。这些功能的开销远比您自己更新顶点缓冲区要大得多,这就是为什么某些文档(非常错误!)将顶点缓冲区称为“优化”(这不是优化;这是实际实现的唯一方法)的原因。与GPU对话)。
多年来,OpenGL中已弃用或废弃了各种其他API。所谓的固定功能管道就是另一个这样的部分。一些文档可能仍然使用此管道或与可编程管道混合使用。固定功能流水线源于过去的日子,当时图形卡对用于渲染3D场景的所有数学运算进行硬编码,并且OpenGL API限于为该数学运算设置一些配置值。如今,硬件几乎没有硬编码的数学运算了(就像您的CPU一样),而是运行用户提供的程序(通常称为着色器)。
再次,驱动程序必须模拟旧的API,因为硬件上不再存在固定功能。这意味着驱动程序中嵌入了许多兼容的着色器,这些着色器从固定功能开始执行旧的数学运算,而当您不提供自己的着色器时会使用该数学运算。修改该旧固定功能状态的旧OpenGL函数(例如旧OpenGL照明API)实际上是在使用现代OpenGL功能(例如统一缓冲区)将这些值提供给驱动程序的兼容性着色器。
支持兼容性的驱动程序必须做很多幕后工作,才能弄清楚何时使用这些过时的功能,并确保可以将它们与现代功能平滑地结合在一起,这增加了开销,并使驱动程序大大复杂化。这是一些驱动程序迫使您启用Core Profile以获得更新功能的原因之一;它不必同时支持新旧API,从而大大简化了其驱动程序内部。
许多文档可能建议您仅从旧的API开始,因为它们较容易上手。Direct3D通过提供一个随附的库(DirectX Tool Kit)为初学者解决了此问题,该库提供了更简单的绘图API和预编写的着色器,可以随您的专业知识的增长与Direct3D 11的原始用法自由地混合。不幸的是,更广泛的OpenGL社区大多数人都坚持使用Compatibility Profile,这是有问题的,因为有些系统不允许您将旧的OpenGL API与较新的OpenGL API混合使用。有一些非官方的库和工具,可以在新的OpenGL上使用功能和目标用例和语言的不同级别简化渲染(MonoGame (例如.NET使用者),但没有任何正式认可或广泛同意的内容。
您找到的文档甚至可能不是针对OpenGL的,而是针对其他类似API之一的。OpenGL | ES 1.x具有固定功能的渲染,但没有用于顶点提交的OpenGL 1.x API。OpenGL | ES 2.x +和WebGL 1+根本没有任何固定功能,并且这些API没有向后兼容模式。
这些API与主要的OpenGL非常相似。它们并不完全兼容,但是OpenGL有官方扩展,某些(并非全部)驱动程序支持这些扩展以与OpenGL | ES(基于WebGL的)兼容。因为之前的事情还不够混乱。