1 - 简介

准备学学OpenGL,这系列文章参考了LearnOpenGL-CN,描述我学习OpenGL3.3的历程。

OpenGL简介

OpenGL本身并不是一个API,它仅仅是一个由Khronos组织制定并维护的规范(Specification)。

OpenGL规范严格规定了每个函数该如何执行,以及它们的输出值。至于内部具体每个函数是如何实现(Implement)的,将由写OpenGL库的开发者自行决定。

实际的OpenGL库的开发者通常是显卡的生产商。这也意味着任何时候OpenGL库表现的行为与规范规定的不一致时,基本都是库的开发者留下的bug。(产生一个bug时通常可以通过升级显卡驱动来解决)

OpenGL3.3 的规范可以在这里找到。

核心模式与立即渲染模式

早期的OpenGL使用立即渲染模式(Immediate mode,也就是固定渲染管线),这个模式下绘制图形很方便。但是OpenGL的大多数功能都被隐藏,开发者很少有控制OpenGL如何进行计算的自由。

因此从OpenGL3.2开始,规范文档开始废弃立即渲染模式,鼓励开发者在OpenGL的核心模式(Core-profile)下进行开发,这个分支的规范完全移除了旧的特性。当试图使用一个已废弃的函数时,OpenGL会抛出一个错误并终止绘图。

扩展

OpenGL的一大特性就是对扩展(Extension)的支持,当一个显卡公司提出一个新特性或者渲染上的大优化,通常会以扩展的方式在驱动中实现。如果一个程序在支持这个扩展的显卡上运行,开发者可以使用这个扩展提供的一些更先进更有效的图形功能。

使用扩展的代码格式如下:

if(GL_ARB_extension_name)
{
    // 使用硬件支持的全新的现代特性
}
else
{
    // 不支持此扩展: 用旧的方式去做
}

状态机

OpenGL自身是一个巨大的状态机,通过一系列变量描述它应该如何运行。OpenGL的状态通常被称为OpenGL上下文(Context)。

OpenGL还有和状态有关的函数:

  • 状态设置函数(State-changing Function),这类函数将会改变上下文。
  • 状态使用函数(State-using Function),这类函数会根据当前OpenGL的状态执行一些操作。

对象

在OpenGL中一个对象是指一些选项的集合,它代表OpenGL状态的一个子集。可以把对象看做一个C风格的结构体(Struct):

struct object_name {
    float  option1;
    int    option2;
    char[] name;
};

使用对象通常有如下几步:

  • 创建对象:创建一个对象,然后用一个id保存它的引用。
  • 绑定对象至上下文:将对象绑定至上下文的目标位置。
  • 设置相关选项:配置该对象对应上下文的选项
  • 解绑对象:将目标位置的对象id设为0,如果还想使用重新绑定即可。
// 以GL_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);

参考资料

  • LearnOpenGL-CN