这并不是一个恰当的题目,因为我主要想说的是OpenGL的今生,基于OpenGL3.x一种更现代化的方式。但是把前世和今生放在一起在语言上更加连贯,而且适当的了解过去,会帮助理解现在的OpenGL,以一种更彻底更开放的方式拥抱OpenGL的今生。

 

OpenGL3.x的优势和劣势

OpenGL3.0是新旧的分水岭,在3.0以前的老旧API中包含内建的光照模式(点光源,线光源以及平面光),有方便的矩阵堆栈,有简单的纹理应用程序,有轻松编写代码的立即模式传送数据,总之这些是固定管线的经典OpenGL实现。在OpenGL3.1及以后的版本中这特性都被移除了,无论做什么都要编写一个着色器。OpenGL3.x具有更丰富的渲染效果和更快的渲染速度。可想而知丰富的渲染效果是通过灵活的编写着色器来实现的,在速度方面,新版本中使用VBO(顶点缓冲区)一次性向GPU发送数据的,与此相对旧版本中使用glBegin,glEnd多次向GPU传送数据,因此使用VBO这种方式具有更快的速度。特别是在模型数据特别巨大的时候。当然OpenGL3.x也有不便利的地方,不方便的矩阵处理(这一点其实可以忽略,因为使用glm这个矩阵处理库,所有工作变的更便和有条理),着色器出错不容易调试。深入介绍之前,再来看看新旧版本在形式上的区别,下图左是旧的,下图右是新的。

opengl opencv 一起开发 opencv opengl 前景_着色器

opengl opencv 一起开发 opencv opengl 前景_着色器_02

 

OpenGL是什么

前面说了很多概念,像着色器,VBO,Glm。如果这些令你很困惑,别担心这些我会在后面的部分进行介绍。重要的是要知道OpenGL是什么,它会给我的工作和生活带来哪些改变。当我面对任何一个新概念的时候我会看wiki上是怎么定义的,当我理解了以后我会用自己的话来叙述它。对我来说,OpenGL是计算机图形处理单元GPU的软件接口,包含了丰富的图形处理函数。可以使用OpenGL生成二维和三维的图像,更简单的可以把OpenGL理解成照相机和摄像机,相机把三维场景投影成二维场景,这一过程对应于OpenGL的静帧渲染;摄像机把三维世界的场景编程视频资料,这一过程对应于OpenGL动态渲染。OpenGL在医疗,教育和游戏中应用广泛,值得一提的是很多手机游戏使用OpenGL ES(OpenGL的移动版)。

 

计算机图像学

在学习OpenGL之前,最好先来了解一些计算机图像学的知识,这会是我们更透彻地理解OpenGL的工作原理,应用的得心应手。我们经常会看到3D游戏中的虚拟形象,3D动画中的各种离奇角色。那么请思考下,这些计算机是怎么产生这些现实世界中的形象的?大体上说是这样的,美工使用建模软件绘制3D模型,使用OpenGL进行静帧或者动态的渲染。把3D物体渲染成2D照片,这就是计算机图形学的主要目的,这一过程就是渲染(如下图所示)。渲染包含三方面的内容:几何变换,光栅化,着色。

opengl opencv 一起开发 opencv opengl 前景_几何变换_03

    在展开介绍之前,还需要再明确下渲染的输入,3D模型(渲染的对象),虚拟的相机和光源(辅助渲染,模拟真实世界的成像过程)。相机的内参和外参决定了几何变换,光源的位置和属性影响了着色的效果。

 

几何变换

几何变化的目的是把三维物体投影到屏幕空间。三维模型,或者说三维点云是定义在局部坐标系下(也叫模型坐标系)的,通过几何变换将其变换到屏幕坐标系下。包含以下过程:模型坐标系->世界坐标系->相机坐标系->剪裁坐标系->设备坐标系->屏幕坐标系。涉及到三个变换矩阵,分别是模型矩阵(M),视图矩阵(V),投影矩阵(P)。

opengl opencv 一起开发 opencv opengl 前景_光栅化_04

光栅化

三维模型是由众多的三角形组成的,这些三角形之间具有一定的拓扑关系。这些三角形经过几何变换投影到了屏幕空间,这些点是连续的,然而最终的图像确是离散的,如何确定一个投影后的三角形所包含的像素点,这就是光栅化的工作。光栅化有很多种方法,常用的是基于边方程和重心坐标插值的光栅化,如下图所示。

opengl opencv 一起开发 opencv opengl 前景_光栅化_05

着色

光栅化后得到的是没有颜色信息的像素块,怎样把颜色作用到物体上得到最终的像素值,就是着色的内容。OpenGL默认的着色是冯氏着色,冯氏着色是建立在冯关照模型的基础上。冯光照模型刻画了光源作用在物体上的方式,下图体现出了着色的概念。

opengl opencv 一起开发 opencv opengl 前景_几何变换_06

我只是粗略的介绍了几何变换,光栅化和着色的内涵,在这些概念背后有着众多的细节和复杂的过程。下面是加州大学的计算机图形学课件,很棒。

http://www.cs.ucr.edu/~shinar/courses/cs130-spring-2012/

 

着色器

OpenGL3.x是用着色进行渲染的,这些着色器包括顶点着色器,片段着色器和几何着色器。前面提到渲染包含几何变换,光栅化和着色。其中几何变换在顶点着色器中完成,着色对应着片段着色的工作,光栅化则是在硬件上自动完成的。至于几何着色器我还不是很了解。下图表达了这种对应关系。

opengl opencv 一起开发 opencv opengl 前景_光栅化_07

 

顶点着色器和片段着色器是用GLSL写的程序,GLSL是类似于C的语言,着色器程序是运行在GPU上的,它需要经过编译和链接。下面的程序是建立着色器的标准流程。

opengl opencv 一起开发 opencv opengl 前景_几何变换_08

其中"simple.vert",是顶点着色器文件的名字,"simple.frag"是片段着色器的名字。这些文件可以txt格式的。为求简单我们就在txt中编写顶点着色器和片段着色器。下图左是顶点着色器,下图右是片段着色器。

 

opengl opencv 一起开发 opencv opengl 前景_着色器_09

opengl opencv 一起开发 opencv opengl 前景_几何变换_10

 

怎样使用OpenGL

配置OpenGL        Window上不支持OpenGL3.x,这需要使用glew扩展库,为了操作矩阵执行几何变换又需要使用glm库,再次避免涉及windows api,使用glfw调用窗口资源。这样的话,为了让OpenGL3.x在我们的电脑上工作,这少配置这三个库。我使用visual studio 2013这个编译器,具体的配置方法,网上都有教程,无非就是定义头文件和库文件路径,链接必要的库文件。另外保证OpenGL3.x能正确工作的很重要一点是,你的图像显卡要支持这个OpenGL版本,可以用GLview软件来查看。

 

渲染一个三角形        这恐怕是最简单的模型了,仅仅包含三个点的位置信息。使用简单的模型,从简单到复杂是很有效的学习方式。三个点定义如下

opengl opencv 一起开发 opencv opengl 前景_几何变换_11

着色器编译和链接        这部分是标准的,几乎每个程序都一样,只是要把特定着色器的名字传入到此程序,包含着色器程序的txt文件放在工程文件同一目录下,我们可以顶一个Shader类来完成此部分标准工作。

 

编写渲染程序        我把渲染程序分成几个阶段,分别是程序初始化(加载着色器),VBO初始化(把顶点的信息装入顶点缓冲区,获得统一值句柄,统一值包括投影矩阵,模型视图矩阵,相机位置,光源位置,光源的其他属性等,在这一示例程序中仅包含前两项),画图(传递统一值,绘制顶点数组序列)。

opengl opencv 一起开发 opencv opengl 前景_光栅化_12

 

opengl opencv 一起开发 opencv opengl 前景_几何变换_13

opengl opencv 一起开发 opencv opengl 前景_opengl opencv 一起开发_14

编写着色器        使用OpenGL默认的着色方式,着色器的代码异常简单。顶点着色器的在txt文件中的内容如下图左,片段的如下图右。

opengl opencv 一起开发 opencv opengl 前景_opengl opencv 一起开发_15

opengl opencv 一起开发 opencv opengl 前景_opengl opencv 一起开发_16

 

结果        如果每个环节都弄对了会得到下面的结果

opengl opencv 一起开发 opencv opengl 前景_几何变换_17