什么是OpenGL
OpenGL通常被认为是一组API,通过它我们可以操作显卡和图像。尽管如此,OpenGL并非是API,它仅仅是一个specification,由
Khonos
开发和维护。
也就是说OpenGL只定义了每个函数的输入和输出规则,而是由开发者来提供实现。这里的开发者一般是显卡制作商。
Core-profile 模式和 Immediate 模式
Immediate 模式是早期的模式,通常又被称为固定管线模式。在该模式下,OpenGL的绝大多数功能都被隐藏在编译好的库中,开发者没有太多的自由来影响OpenGL的计算过程。
为了满足开发者对显卡有更多的控制,从3.2版本开始OpenGL开始deprecate Immediate 模式,启发开发者在Core-profile 模式下进行开发。Core-profile 模式非常的灵活和高效。我们这个课程就是针对Core-profile 模式来进行学习的。
扩展
OpenGL最重要的一个特性是它支持扩展(Extensions)。
也就是说显卡制造商可以通过它在自己驱动中实现的的扩展来发布新技术,不用等到OpenGL出新的版本。当一个扩展很流行之后,就很有可能变成OpenGL spec的一部分。
开发者可以按如下代码的方式来查询一个扩展是否支持:
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该如何运作。OpenGL的状态通常被称为上下文(Context)。使用OpenGl时,我们通常通过设置各个选项来改变它的上下文,基于当前上下文修改一些buffer然后渲染。
例如当你想告诉OpenGL你不要绘制三角形了,而改绘制直线,我们会通过修改某些设置OpenGL如何渲染的上下文变量来改变OpenGL的状态。一旦我们把OpenGL的状态转到如何绘制直线上了,那么接下来的渲染命令将由原来渲染三角形变成渲染直线。
对象
在OpenGL里的对象(Object)就是选项的集合,这个集合是OpenGL状态的一个子集。对象可以用以下的C结构来表示:
struct object_name {
float option1;
int option2;
char[] name;
};
// The State of OpenGL
struct OpenGL_Context {
...
object_name* object_Window_Target;
...
};
当我们使用对象时,一般的代码如下所示:
// create object
unsigned int objectId = 0;
glGenObject(1, &objectId);
// bind 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);