自学 openGL(一)-理论基础
核心渲染模式与立即渲染模式
立即渲染模式
早期 openGL 使用的渲染模式,也称固定渲染管线,这个模式下绘制图形很方便。openGL的大多数功能都被隐藏起来,开发者很好有控制openGL如何进行计算的自由。openGL 3.2 开始,规范文档开始废弃立即渲染模式,并鼓励开发者在 openGL的核心模式下开发,这个分之规范完全移出就的特性。
核心渲染模式
当使用 OpenGL 核心模式时,OpenGL 迫使我们使用现代函数。当我们视图使用一个已被废弃的函数时,OpenGL会跑出一个错误并终止绘图。现代函数的优势时灵活性和效率,然而也更难学习。理解渲染模式从OpenGL 世纪运作中抽象掉很多细节,因此易学习,也很难让人去把我OpenGL具体时如何运作的。现代函数要求使用者真正理解 OpenGL 和图形编程
我学习的是 OpenGL 3.3 版本,虽然上手更加困难,但这份努力一定值得。
扩展
OpenGL 的一大特性就是对扩展的支持,当显卡工时提出一个新特性或者渲染上的优化,通常以扩展的方式在驱动中实现。如果一个程序在支持这个扩展的显卡上运行,开发者可以使用这个扩展提供一些更优先更有效的图形功能。通过这种方式开发者不必等待新的OpenGL规范面试就可以使用这些新的渲染特性,只需要简单地检查一下显卡是否支持此扩展。通常,当一个扩展非常流行或者非常游泳的时候,它将最终成为未来的OpenGL 规范的一部分。
使用扩展的代码大多看上去如下:
if(GL_ARB_extension_name)
{
// 使用硬件支持的全新的现代特性
}
else
{
// 不支持此扩展: 用旧的方式去做
}
状态机
OpenGL 自身是一个巨大的状态机:一系列的变量描述OpenGL 此刻应当如何运行。OpenGL 的状态通常被称为OpenGL 上下文。我们同城使用如下途径去更改OpenGL 状态:设置选项,曹祖缓冲。最后,我们使用当前OpenGL上下文来渲染。
假设当我们想告诉OpenGL去画线段而不是三角形的时候,我们通过改变上下文变量来改变OpenGL 状态,从而告诉OpenGL如何去绘制。一旦我们改变了OpenGL的状态为绘制线段,下一个绘制命令就会画出现断而不是三角形。
当使用OpenGL的时候我们会遇到一些状态设置函数,这类函数将会改变上下文。以及状态使用函数,这类函数会根据当前OpenGL的状态执行操作。只要你记住OpenGL本质是一个巨大的状态及,就能更容易理解它的大部分特性。
对象
OpenGL库是用c语言写的,同时支持多种语言的派生,但其内核认识一个c库。由于c的一些语言结构不易被翻译到其他高级语言,因此OpenGL开发的时候引入一些抽象层。“对象”就是其中一个。
在OpenGL中一对象是指一些选项的集合,它代表OpenGL状态的子集,比如,我们可以用一个对象来代表绘图窗口的设置,之后我们就可以设置他的大小、支持的颜色位数等等。可以吧对象看做一个c风格的结构体:
struct object_name {
float option1;
int option2;
char[] name;
};
当我们使用一个对象时,通常看起来像如下一样:
// OpenGL的状态
struct OpenGL_Context {
...
object* object_Window_Target;
...
};
//------------------------
// 创建对象
unsigned int 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);
// 将上下文对象设回默认
glBindObject(GL_WINDOW_TARGET, 0);
这一小段代码展现了你以后使用OpenGL 时常见的工作流。我们首先常见一个对象,然后使用一个id保存引用。然后我们将对象绑定至上下文的目标位置。接下来我们设置窗口的选项。最后我们将目标位置的对象id设回0,解绑这个对象。设置的选项将被保存在objectId所引用的对象中,一旦我们重新绑定这个对象到 GL_WINDOW_TARGET位置,这些选项就会重新生效。
使用对象的一哥好处是在程序中,我们不知可以定义一个对象并设置它们的选项,每个对象都可以不同的设置。在我们执行一个使用OpenGL状态操作的时候,只需要绑定含有需要的设置对象即可。比如说我们有一些作为3D模型数据的容器对象,在我们想绘制其中任何一个模型的时候,只需绑定一个对象模型数据对象就可以了。拥有数个这样的对象允许我们指定多个模型,在想画其中任何一个的时候,直接将对应的对象想绑定上去,便不需要再重复设置选项了。