1.1 格式

内容为空。

1.2 OpenGL Graphics System 是什么

在介绍OpenGL之前,首先了解framebuffer的概念。framebuffer本质上也是一块memory,一般用以存储最终绘制结果,并可以经由硬件(display hardware)在显示设备中显示,从而人眼可以看到绘制结果。有时候,framebuffer也被用以保持绘制过程中的中间结果,并且不在显示设备中输出。前者用法的framebuffer可以被称为onscreen buffer,后者用法则是offscreen buffer。

OpenGL由数百个API函数组成(以下简称glAPI),借助glAPI,可以输入现实世界中的几何对象、灯光、眼睛位置等信息,这些三维(3D)空间中的信息将被转换为一幅二维(2D)平面图像(即人眼在屏幕中所看到的),而这幅平面图像被绘制在framebuffer中,所以,某些glAPI还和具体framebuffer情况相关,某些glAPI则用来直接操作framebuffer。

什么是三维空间模型被转换为二维图像,以第一人称视角游戏为例,进入一个新的游戏场景时,整个三维空间场景首先被建模,然后绘制出当前视角下能看到的内容,这个内容就是人眼在显示器屏幕中所看到的,本质上就是一个二维平面图像。假如移动一下鼠标(即调整视角),就会在屏幕上看到新视角下的场景内容。所以,根据视角的调整,同一个三维空间场景会被绘制成不同的二维图像,在这个过程中,整个三维空间场景不需要被重新建模,只需要应用程序检测鼠标事件并通过glAPI来修改视角即可。

本spec会介绍所有glAPI。

1.3 Programmer的角度看OpenGL

programmer通过glAPI来使用OpenGL,包括输入三维/二维的几何对象,控制这些对象是如何被绘制到到framebuffer中。一般来说,porgrammer首先要创建一个window,然后创建一个GL context,并将window和GL context关联在一起,然后,就可以使用glAPI在window中绘制了,这里的window背后隐含着一个onscreen buffer。

应用程序可以有多个线程,每个线程都可以创建若干GL context和window,然后,当某线程将可以匹配的contex和window绑定在一起时,如下图所示,该线程接下去所有调用的glAPI都将作用于该GL context,而GL pipeline的最终结果则被绘制到该window对应的framebuffer中。其中,GL context是一个逻辑上的OpenGL实现,内部维护着一个OpenGL状态机。一个实际的OpenGL实现(包括graphics hardware和其上的驱动程序)可以模拟出多个逻辑上的OpenGL实现,这样,多个OpenGL应用程序就可以同时在一块显卡上运行了。在多线程多窗口环境下,每个线程同时只能最多链接一个context(此时的context被称为该线程上是active的,即每个线程最多有一个active context),而每个context最多只能成为一个线程的active context;每个context只能同时绘制到一个window中,而一个window是否只能同时被一个context绘制,这在spec中并没有定义,个人建议应该也是唯一的,估计很多OpenGL实现也是基于这样的假设来支持的。

(1). 第一章 Introduction_OpenGL

1.4 Implementor的角度看OpenGL

Implementator要完成glAPI之下的所有实现,由graphics硬件和驱动软件共同组成。根据graphics硬件能够提供的功能不同,需要在驱动软件中完成的事情也随之改变。假如graphics硬件只提供framebuffer操作,那么驱动软件就需要完成整个OpenGL的功能,mesa就是这样的一个例子,用纯软件方式来实现OpenGL。假如graphics硬件提供更多的诸如光栅化、fragment shader、vertext shader等功能,那么驱动软件要做的事情就会少很多。所以实现者的主要任务就是将OpenGL分解到graphics硬件和驱动软件中实现,使其整体上对外提供正确的glAPI支持即可。

OpenGL是一个巨大的状态机,其绝大部分状态值保存在GL context中,由glAPI设置;有些状态值可由glAPI查询,而有些状态值是无法被显式查询到的。所有状态值共同决定了最终的绘制结果,任何一个状态值的错误都可能引起绘制出错;而且不少状态之间相互联系相互影响,这都给实现者的调试带来了巨大的困难。

Intel、AMD/ATI、NVidia、Imagination、XGI、S3/VIA等公司的显卡及其对应的驱动程序是一个OpenGL实现,这些公司内部的硬件工程师、软件工程师等则是实现者。

1.5 本Spec的角度

本spec将OpenGL的绘制过程看成一个pipeline,三维空间模型流经这个pipeline后,即被转换为二维图像。pipeline由多个stage组成,本spec规定了这些stage的功能,但并不规定这些功能的具体实现方法,并且允许实现者采用不同的或粗略或精细的实现方法,只需要能够达到spec规定的要求即可。所以,不同OpenGL实现(不同显卡产品)的绘制结果略有区别,这是完全正常的。

GL context和GL pipeline是分别从静态和动态角度对OpenGL实现的描述,在不引起混淆的情况下,这两个概念在本系列介绍中往往被混用。

1.6 Deprecation模式

以前的OpenGL spec都是向下兼容的,高版本的spec必须兼容低版本spec,可以保证古老的OpenGL应用程序不做任何修改的继续跑在最新的显卡产品上,在当时具有积极作用。但随着图形学技术发展,以前的某些规定逐渐成为历史包袱,这对programmer和implementor来说,都是个累赘,为了解决这个问题,从OpenGL spec 3.0开始增加了deprecation模式,所有deprecation内容有可能在下一版本的spec中被删除,当然也可能不被删除,不过总的趋势是要被删除的。

所以,现在的OpenGL core spec都不再完全向下兼容,比如本系列讨论的OpenGL 4.1 Core Profile Specification;而为了照顾历史情况,还是会同步推出兼容spec,比如OpenGL 4.1 core spec对应的兼容版本就是OpenGL 4.1 Compatibility Profile Specification

1.7 相关文档 1.7.1 OpenGL Shading Language

本spec应该和GLSL (OpenGL Shading Language) spec 4.10一起阅读。GLSL spec规定了shader的语法,比如数据类型、数组、循环语句等,本spec则主要规定了shader是如何和OpenGL Pipeline交互的,pipeline中的数据如何流入shader中,而shader的输出又如何流回pipeline的。

1.7.2 Window system

除了glAPI外,还需要其他API来创建window,创建context,参见section1.3。在windows操作系统中,windows API可以创建window,WGL定义的API创建context并进行绑定。在X Window系统中,X API创建window,GLX定义的API创建context并进行绑定。在嵌入式系统中,每个平台可以有自己私有的API创建window,EGL定义的API可以创建context并绑定。

所以,除了本spec外,还要阅读相关平台的native window system定义的API,以及建立在其之上的GLX/WGL/EGL等spec。