OpenGL(Open Graphics Libaray)
OpenGL本身并不是一个API,仅仅是一个规范,由Khronos组织制定并维护。
OpenGL严格规定了每个函数该如何执行,以及它们该如何返回。至于内部具体每个函数是如何实现的,将由OpenGL库的开发者自行决定(注:这里开发者是指编写OpenGL库的人)。
OpenGL库是用C语言写的,同时也支持多种语言的派生,但是核心是一个C库。
实际的OpenGL库的开发者通常是显卡的生产商。每个你购买的显卡都会支持特定版本的OpenGL,通常是为一个系列的显卡专门开发的。当你使用苹果系统的时候,OpenGL库是由苹果自身维护的。
核心模式(Core-profile)与立即渲染模式(Immediate mode)
早期的OpenGL使用立即渲染模式(也就是固定渲染管线),即渲染模式确实容易使用和理解,但是效率太低。从OpenGL3.2开始,规范书开始废弃立即渲染模式,推出核心模式,这个模式完全移除了旧的特性。
立即渲染模式从OpenGL实际操作中抽象掉了很多细节,因而它易于学习的同时,也很难去把握OpenGL具体是如何操作的。现代做法要求使用者真正理解OpenGL和图形编程,它有一些难度,然而提供了更多的灵活性,更高的效率,更重要的是可以更深入的理解图形编程。
我们的教程面向OpenGL3.3的核心模式。
当使用新版本的OpenGL特性时,只有新一代的显卡能够支持你的应用程序。这也是为什么大多数开发者基于较低版本的OpenGL编写程序,并有选择的启用新特性。
扩展(Extension)
OpenGL的一大特性就是对扩展的支持,当一个显卡公司提出一个新特性或者渲染上的大优化,通常会以扩展的方式在驱动中实现。
状态机(State Machine)
OpenGL自身是一个巨大的状态机:一个描述OpenGL该如何操作的所有变量的大集合。OpenGL的状态通常被称为OpenGL上下文(Context)。我们通常使用如下途径去更改OpenGL状态:设置一些选项,操作一些缓冲。最后,我们使用当前OpenGL上下文来渲染。
假设当我们想告诉OpenGL去画线而不是三角形的时候,我们通过改变一些上下文变量来改变OpenGL状态,从而告诉OpenGL如何去绘图。一旦我们改变了OpenGL的状态为绘制线段,下一个绘制命令就会画出线段而不是三角形。
用OpenGL工作时,我们会遇到一些状态设置函数(State-changing Function),以及一些在这些状态的基础上状态应用的函数(State-using Function)。只要你记住OpenGL本质上是个大状态机,就能更容易理解它的大部分特性。
对象(Object)
在OpenGL中一个对象是指一些选项的集合,代表OpenGL状态的一个子集。比如,我们可以用一个对象来代表绘图窗口的设置,可以设置它的大小、支持的颜色位数等等。可以把对象看做一个C风格的结构体:
struct object_name {
GLfloat option1;
GLuint option2;
GLchar[] name;
};
原始类型(Primitive Type) 使用OpenGL时,建议使用OpenGL定义的原始类型。比如使用float时我们加上前缀GL(因此写作GLfloat)。int,uint,char,bool等等类似。OpenGL定义的这些GL原始类型是平台无关的内存排列方式。而int等原始类型在不同平台上可能有不同的内存排列方式。使用GL原始类型可以保证你的程序在不同的平台上工作一致。
当我们使用一个对象时,通常看起来像如下一样(把OpenGL上下文比作一个大的结构体):
// OpenGL的状态
struct OpenGL_Context
{
...
object* object_Window_Target;
...
};
// 创建对象
GLuint objectId = 0;
glGenObject(1, &objectId);
// 绑定对象至上下文
glBindObject(GL_WINDOW_TARGET, objectId);
// 设置GL_WINDOW_TARGET对象的一些选项
glSetObjectOption(GL_WINDOW_TARGET, GL_OPTION_WINDOW_WIDTH, 800);
glSetObjectOption(GL_WINDOW_TARGET, GL_OPTION_WINDOW_HEIGHT, 600);
// 将上下文的GL_WINDOW_TARGET对象设回默认
glBindObject(GL_WINDOW_TARGET, 0);
我们首先创建一个对象,然后用一个id保存它的引用(实际数据被储存在后台)。然后我们将对象绑定至上下文的目标位置(例子里窗口对象的目标位置被定义成GL_WINDOW_TARGET)。接下来我们设置窗口的选项。最后我们通过将目标位置的对象id设回0的方式解绑这个对象。设置的选项被保存在objectId代表的对象中,一旦我们重新绑定这个对象到GL_WINDOW_TARGET位置,这些选项就会重新生效。
使用对象的一个好处是我们在程序中不止可以定义一个对象并且设置他们的状态,在我们需要进行一个操作的时候,只需要绑定预设了需要设置的对象即可。
额外的资源
- opengl.org:OpenGL官方网站。
- OpenGL registry: OpenGL各版本的规范和扩展的主站。
网友评论