前言
对于C++和OpenGL的学习是同时进行的,因为我觉得相较于简单的编程练习,OpenGL本身就是对于C++的非常好的实践,能够有助于我们进一步理解C++的语言特性。作为OpenGL系列的第一篇文章,本文将会帮助大家建立起对于OpenGL的初步印象。
什么是OpenGL
在我们学习一个东西之前我们第一个疑问就是它是什么?那么什么是OpenGL呢?一些人认为OpenGL是一系列跨平台的操作图像的API,其实这个定义并不准确,准确来说OpenGL是由www.khronos.org 提出并维护的与平台无关的操作图像的规范,OpenGL规范严格规定了每个函数的结果和输出以及运行过程,但是却不包含具体的实现细节,我们熟知的OpenGL库则是基于OpenGL规范的实现,其中包含了大量的操作图像的API。OpenGL库一般是由显卡制造商开发并维护的,例如Apple平台的OpenGL库就是他们自己开发维护的。
基本概念
核心模式vs立即渲染模式
在早期OpenGL采用的是立即渲染模式(Immediate mode,也就是固定管线),在这种模式下能够非常容易的使用提供的方法渲染图像,很多实现的细节隐藏在是OpenGL库的内部,开发者无法控制OpenGL的计算过程。这种模式易于理解和使用但是灵活性差。为了提供更加灵活和有效的开发模式,OpenGL规范提供了核心模式,这是OpenGL规范的一个分水岭,在核心模式中,OpenGL更加关注一些现代化的实践,并移除了所有废弃的功能,如果使用废弃的函数将会引发错误并停止绘制。这种现代化的实践需要开发者深入了解OpenGL和图像编程,学习曲线比较陡峭,但是更加灵活和高效,由此我们的学习也是基于核心模式,难但是值得去花时间。
扩展
OpenGL一大优点是支持扩展,如果一个显卡公司提出了一个新技术或者极大地优化渲染,通常会通过在驱动中添加扩展的方式实现,如果硬件支持这个扩展,开发者就可以使用这个扩展提供的能力,如果这个扩展真的十分受欢迎,那么一般在OpenGL之后的版本中会包含相关插件。其中需要注意的是在使用扩展的过程中需要确定是否支持这个扩展,可以通过以下的方法去判断。
if(GL_ARB_extension_name)
{
// Do cool new and modern stuff supported by hardware
}
else
{
// Extension not supported: do it the old way
}
状态机
OpenGL本身就是一个大的状态机,OpenGL当时的操作就是通过一系列的变量确定的,其状态被称为context,当使用OpenGL时,通常通过设置选项,操作buffer来设置状态,然后使用当下的context来渲染。例如当我们想要画条线而不是三角形时,可以通过设置context的变量来改变OpenGL的状态,从而画出一条线而不是一个三角形(画一条线和画一个三角形context的变量显然不相同)。OpenGL提供了一些改变状态的函数来改变conetxt以及一些使用状态的函数给予当前当前的状态执行一些操作,只要将OpenGL是一个大的状态机铭记于心,其提供的大多数的能力也就可以理解了。
对象
OpenGL的库是由C语言写的,虽然有很多其他语言的派生版本,但是是核心的库依然是C语言的写的,由于C语言的结构不是很容易转化为其他高级语言,所以OpenGL提供了一个object的抽象,在OpenGL中object是一系列的选项,其代表了OpenGL的状态,例如我们有一个object代表来绘制窗口的设置,可以通过这个object设置窗口的位置,支持的颜色等等,对于这个object的定义可以如下
struct object_name {
float option1;
int option2;
char[] name;
};
下面一段代码展示了OpenGL的工作流,首先需要创建一个对象去存储自己的引用作为id(实际的数据存储在后台),之后通过id将这个object绑定到context的目标位置(例子中窗口对象的目标位置定义为GL_WINDOW_TARGET),之后设置窗口的选项,最后通过将窗口的对象的object的id设置为0来将object与窗口解绑。我们设置的选项是保存在objectId的引用中,只要我们重新绑定就能恢复。
// create object
unsigned int objectId = 0;
glGenObject(1, &objectId);
// bind/assign object to context
glBindObject(GL_WINDOW_TARGET, objectId);
// set options of object currently bound to GL_WINDOW_TARGET
glSetObjectOption(GL_WINDOW_TARGET, GL_OPTION_WINDOW_WIDTH, 800);
glSetObjectOption(GL_WINDOW_TARGET, GL_OPTION_WINDOW_HEIGHT, 600);
// set context target back to default
glBindObject(GL_WINDOW_TARGET, 0);
最后
这篇文章我们主要了解了什么是OpenGL,OpenGL是由www.khronos.org 提出并维护的与平台无关的操作图像的规范,还介绍了OpenGL的一些基础概念立即渲染模式和核心模式,扩展,状态机以及对象。更多文章可以关注公众号QStack。