OpenGL 入门(实际是看见大门)
一直对OpenGL感兴趣,但是之前了解过它两次,也写过例子,但是没弄懂,最近工作需要,学习了一下,找到了一个好的教程,才算弄明白了一点,这篇文章只是开个头,试着按照我的理解将OpenGL的基本原理讲明白,希望读者反馈,一块讨论:)
从哪开始
学习一个东西,最快的方式应该是先从宏观的角度去了解它,起点当然是官方网站和Wiki,这里是最正确的一手资料。
OpenGL 是 open graphics library 的缩写。从名字来看,它是一个库, 但是它只是一个 API(application programming interface),只是一套规范,用来渲染 2D 或者 3D 向量图形的。为什么是向量图形,以后会会讲到,先来把它的用途说完,它是通常用来与GPU交互,实现硬件加速。”通常”,你懂得他的意思吧?因为它就是一套接口,如果你要实现它不与GPU交互那也是可以的。要去实现它的是那些生产显卡GPU的厂商,这样,他的GPU被叫做支持OpenGL。
硬件加速是什么意思? 硬件加速是借助硬件模块来替代 运行在通用目的的CPU上的 软件算法。注意加粗的部分,没有这个修饰,就很难理解了,因为所有软件算法都是运行在硬件上的,是吧?这里的意思,CPU是通用目的的,而GPU是专门处理图像的,所以GPU的图像处理操作要比CPU块,不然也没它事了。
这样,我们知道OpenGL操作GPU, GPU在显卡上,显卡有现存,而我们平时编程只是跟内存打交道, 当然还有CPU,我们是摆脱不掉他的。所以我们在进行OpenGL开发时,就牵扯到CPU, GPU, 内存, 显存,还有文件存储系统。
状态机–给我发个红包,我笑给你看
OpenGL 本身是一个大的状态机,这只鸡有多大, 大到我们总是在它肚子里,哈哈,开个玩笑,不过也算贴切。
我们先来理解什么是状态机。 数学上有有限状态机, 用来描述有限个状态,而且这些状态之间会相互转换。 形象一点,一个烤面包机也算一个状态机,有没有插电两种状态,有没有打开开关两个状态, 有没有插入面包两个状态。这些状态,都会因为一些行为而改变,比如插入插销,烤面包机就由未插电状态变成插电状态。而某些状态会支持某些行为,如只有插电,插入面包,打开开关,这时才能够加热面包。
下面还有个图简单的不能再简单的状态机:
这是我画的,还挺有感觉:)
一个大开关,里边有三个按钮,这就表示了6种状态,而每个按钮的拨动,都会导致大开关的状态转换,这就是状态机。
OpenGL里有个Context的概念,而这个Context,中文译为上下文。我们在进行 OpenGL 开发时, 会设置某些选项,操作某些缓冲,这些操作并没有指明是对谁,但是实际上是改变了当前上下文的状态, 然后进行绘制,绘制出来的图像是那种状态下的样子。
然后,当切换了上下文时,之前的配置就都无效了。
这就像我们本来看着一个正在烤着面包的面包机,突然目光转向一个电都没插,开关没开的烤面包机,然后插电,插面包,打开,这一系列的操作的对象都不用指明是那个烤面包机,但是,读起来却明白是它,这就是上下文的作用。
对象–状态的集合,数据的容器
OpenGL 里也有对象, 但是此对象并不是面向对象编程语言里的对象,更不是你妈让你找的对象,而是一个可选项的集合,此集合是OpenGL状态的一个子集。如图:
我们可以把控制灯光的两个开关看做一个对象,控制风扇的一个开关看做一个对象,这样这个状态机就有两个对象。
无论何时何地,我们都像下面这样使用对象:
1 | // OpenGL的状态 |
(代码来自:五十弦翻译的教程,啥叫禁止演义)
OpenGL如何工作的
前面已经提到过,OpenGL总共牵扯到计算机的5个大部分,它们分别是:
CPU,内存,GPU,显存,外存, 主要干了三个大事:
- CPU将数据从内存复制到显存
- CPU将着色器程序上传到GPU
- 通知GPU运行着色器程序,处理数据
下面一个图来表示 OpenGL 是如何工作的:
根据以上我们说的三个大事,和图片所示,我们就可以解释几个语句块
上传顶点数据的代码:
1 | // 这是在内存中的数据 |
上面我们上传了顶点数据到显存,下面我们上传着色器程序到GPU,着色器程序是什么,我们暂时只需要知道,它会在GPU执行,处理我们上传到显存的数据就行了:
1 | // 通知GPU分配一个顶点类型的着色器 |
下面是绘制代码部分:
1 | glUseProgram(shaderProgram); // 通知GPU使用shaderProgram着色器程序, 这里算是切换上下文,之后的GPU运行的都是这个Program |
当然,OpenGL的基本概念还有很多,这里这篇文章知识让你远远的看一看它的全貌,如果喜欢,请继续关注, 如果您能提出宝贵的意见,不胜感激。