Monthly Archives: February 2015

OpenGL原理介绍

转载请注明原文章链接:http://www.twinklingstar.cn/2015/1532/introduce-to-opengl/ 代码下载地址:https://github.com/twinklingstar20/twinklingstar_cn_demo_introduce_to_opengl 1. OpenGL简介 OpenGL是Open Graphics Library的缩写,是个定义了一个跨编程语言、跨平台的编程接口的标准,显卡通常有OpenGL的实现,不同显卡上的OpenGL实现也不一定相同,OpenGL标准不是平台相关的,所以同一个程序可能在不同的显卡上运行。OpenGL API只处理图形渲染,并不提供动画、定时器、文件IO、图像文件格式处理、GUI等功能,GLUT并不是OpenGL,也不是OpenGL的一部分,它仅是被一些用户用于创建OpenGL窗口。OpenGL不是开源代码,OpenGL指的是开放标准,在网上可以找到,任何人都可以免费下载,也有一个开源的GL实现,名叫 Mesa3D,已经实现了OpenGL 3.0和GLSL 1.30。 OpenGL被当作客户端-服务器系统来实现的,应用程序是客户端,图形硬件厂商提供的OpenGL实现是服务器。如图1所示,客户端程序需要调用OpenGL的接口实现3D渲染,那么OpenGL命令和数据会缓存在RAM中,在一定条件下,会将这些命令和数据通过CPU时钟发送到VRAM,在GPU的控制下,使用VRAM中的数据和命令,完成图形的渲染,并将结果存入帧缓冲区中,帧缓冲区中的帧最终会被发送到显示器上,显示出结果。在现代的图形硬件系统中,还支持不通过CPU时钟直接将数据由RAM发送至VRAM或直接将数据由帧缓冲区发送至RAM(例如OpenGL中的VBO,PBO)。 图1. 计算机图形硬件系统 在一些OpenGL实现中,比如那些与X windows system相关的实现,客户端和服务器在不同的机器上执行,两者通过网络连通起来。在这种情况下,客户端发送OpenGL命令,这些命令被转化成窗口系统相关的协议,再通过共享的网络发送给server。 如图2所示,OpenGL中的顶点、像素等数据需要通过不同阶段的处理,才能产生最后的可视图像,就像是工厂里的生产线,称为图形渲染管线。像素和顶点数据可以选择存储在显示列表中,我们可以把显示列表看成是存储数据的媒介,用于加速渲染速度。顶点数据经过求值器,产生法向量、纹理坐标、点的空间坐标等,通过顶点操作和图元装配,生成相应的像素信息,进行光栅化处理,光栅化是把几何和像素数据转化成片段,每个片段块对应帧缓冲区中的一个像素。其中,顶点操作和图元装配中又可以细分出一条渲染管线,这里称为顶点处理管线。在光栅化完成后,还可以根据命令,对每个像素进行处理,最后写入帧缓冲区内。 图2. OpenGL的图形渲染管线 2. 顶点处理管线 本节介绍如何将三维空间上的图元转化为二维屏幕上渲染出的图元,包括图元的顶点位置、大小等。 顶点的处理管线如图2所示,设我们在三维空间上的坐标\((0,0,0)\)处画一个小球,对小球移动至\((1,0,0)\),再绕着\(y\)坐标轴旋转90度,对小球位移和旋转的处理完成后,这是模型矩阵完成的功能。在空间中放置好模型后,需要架设摄像机,然后才能够观察到模型,架设摄像机,是视图矩阵实现的功能,把这两部分统一起来,就得到模型视图矩阵。接着,需要把小球投影到一个虚拟屏幕上,计算小球的虚拟投影点,这是投影矩阵完成的功能。如果场景中存在多个小球,相对于摄像机的视角,有一部分小球被前面的小球阻挡了,那么被阻挡的小球就不会被渲染出来,裁剪掉被阻挡的模型就是裁剪处理完成的功能。最后,根据屏幕的长宽,把虚拟屏幕映射到真实屏幕上。这就是OpenGL顶点处理的简化流程。接着,详细阐述技术细节。 图3. 顶点处理管线        首先引入齐次坐标的概念,齐次表示是什么?为什么要采用齐次表示呢?在 维空间上,把点和向量扩展一维,就是它们的齐次表示,点\(P\)的齐次表示为\(({p_1},{p_2}, \cdots ,{p_n},1)\),向量\(\vec v\)的齐次表示为\(({v_1},{v_2}, \cdots ,{v_n},0)\)。一个顶点可以表示为\((x,y,z,1)\),一个向量则表示为\((a,b,c,0)\)。点表示空间上的一个位置,向量表示一个方向而没有具体的位置,因此点的位移是有意义的,但是向量的位移是没有意义的。采用齐次表示,三维空间上的图形变换包括旋转、位移、透视、正交等都可以用一个\(4 \times 4\)的矩阵来表示,矩阵的连乘就是各个矩阵代表的变换的叠加。因此,图3中的模型视图变换、投影变换都可以用一个\(4 \times 4\)的矩阵来表示。 2.1.   模型视图变换 我们又可以把模型视图矩阵细分为两个部分,如图4所示,对象坐标先经过模型变换,转化为世界坐标,再经过视图变换,转化为视点坐标。

spacer