OpenGL基本概念

来源:互联网 发布:b2b发帖软件 编辑:程序博客网 时间:2024/05/19 17:52

对于OpenGL的基本概念,各个技术论坛和博客中都有描述。本人为了从计算机3D图形原理到GPU,再到OpenGL标准能完整学习,做了如下整理。


OpenGL由SGI公司的IRIS GL发展而来。最初IRIS GL是个2D函数库,逐渐发展到高级3D编程API。对IRIS GL移植性进行了改进便产生了OpenGL,由于OpenGL开放的缘故,得到各大硬件厂商支持,发展很好。其官方网站为:http://www.opengl.org/ OpenGL有两个含义,其一:是一个3D图形编程API,其二:是一个行业标准,使得硬件厂商在OpenGL标准的约束下能够得到很好的支持和发展。


OpenGL ES是OpenGL的子集,专门为手机,PDA,移动设备等嵌入设备开发。在上一篇博文:计算机3D图形简介中提到了很多和3D图形相关的概念。如,顶点,多边形,三角形,纹理,纹理贴图,投影,视角,透视等。接下来将简短介绍和解释这些基本概念。


顶点(Vertex)

3D图像的最小单位称为点(point)或者顶点vertex。它们代表三维空间中的一个点并用来建造更复杂的物体。多边形就是由点构成,而物体是由多个多边形组成。尽管通常OpenGL支持多种多边形,但OpenGLEs只支持三边形(即三角形)所以即使我们要绘制一个正方形也要把它拆分为两个三角形绘制。


坐标(coordinate)

默认情况下,以屏幕中心为坐标轴原点。原点左方x为负值,右边为正值。原点上方y为正,原点下方为负。垂直屏幕向外为z正,垂直屏幕向里为z负。默认情况下,从原点到屏幕边缘为1.0f,沿各轴增加或减小的数值是以任意刻度进行的–它们不代表任何真实单位,如英尺,像素或米等。你可以选择任何对你的程序有意义的刻度(全局必须保持单位一致,不能一部分使用米,一部分使用像素)。OpenGL只是将它作为一个参照单位处理,保证它们具有相同的距离。如图:


描述一个点使用浮点值{x,y,z}数组来描述,也就是x,y,z都是有符号的浮点值。多边形则使用多维数组来描述。


多边形(三角形)

多边形是由点和边构成的单闭合环。 绘制多边形时需要特别注意顶点的绘制顺序,可以分为顺时针和逆时针。因为方向决定了多边形的朝向, 即正面和背面。避免渲染那些被遮挡的部分可以了有效提高程序性能。默认以逆时针次序绘制顶点的构成的面是正面。


纹理与纹理贴图

将图像数据应用到一个几何图元时,图像称之为纹理,这种技术或者方法称为纹理贴图。或者说通过一幅图像一个多边形提供细节的技术。纹理有规格,也就是分辨率,在使用的时候需要放大或者缩小使用。这个时候会带来纹理颜色失真,所以需要使用纹理采样滤波器(texture sample filter)或者映像(Mipmap)。另外纹理作为图像数据存储会占用较大空间,使用纹理压缩来(Texture compression)存储纹理数据。


渲染(render)

渲染是把物体坐标所指定的图元转化成帧缓冲区中的图像。图像和顶点坐标有着密切的关系。这个关系通过绘制模式给出。常用到得绘制模式有GL_POINTS、GL_LINE_STRIP、GL_LINE_LOOP、GL_LINES、GL_TRIANGLES、GL_TRIANGLE_STRIP、GL_TRIANGLE_FAN。下面分别介绍:

· GL_POINTS:把每一个顶点作为一个点进行处理,顶点n即定义了点n,共绘制n个点。



· GL_LINES:把每一个顶点作为一个独立的线段,顶点2n-1和2n之间共定义了n个线段,总共绘制N/2条线段。,如果N为奇数,则忽略最后一个顶点。



· GL_LINE_STRIP:绘制从第一个顶点到最后一个顶点依次相连的一组线段,第n和n+1个顶点定义了线段n,总共绘制N-1条线段。



· GL_LINE_LOOP:绘制从定义第一个顶点到最后一个顶点依次相连的一组线段,然后最后一个顶点与第一个顶点相连。第n和n+1个顶点定义了线段n,然后最后一个线段是由顶点N和1之间定义,总共绘制N条线段。



· GL_TRIANGLES:把每三个顶点作为一个独立的三角形。顶点3n-2,3n-1和3n定义了第n个三角形,总共绘制N/3个三角形。



· GL_TRIANGLE_STRIP:绘制一组相连的三角形。对于奇数点n,顶点n,n+1和n+2定义了第n个三角形;对于偶数n,顶点n+1,n和n+2定义了第n个三角形,总共绘制N-2个三角形。这是最常使用的渲染方式,第一个三角形条是由前三个顶点构成(索引0,1, 2)。第二个三角形条是由前一个三角形的两个顶点加上数组中的下一个顶点构成,继续直到整个数组结束。



· GL_TRIANGLE_FAN:绘制一组相连的三角形。三角形是由第一个顶点及其后给定的顶点所确定。顶点1,n+1和n+2定义了第n个三角形,总共绘制N-2个三角形。




视图与投影

我们生活在一个三维的世界——如果要观察一个物体,我们可以:
1、从不同的位置去观察它。(视图变换)
2、移动或者旋转它,当然了,如果它只是计算机里面的物体,我们还可以放大或缩小它。(模型变换)
3、如果把物体画下来,我们可以选择:是否需要一种“近大远小”的透视效果。另外,我们可能只希望看到物体的一部分,而不是全部(剪裁)。(投影变换)
4、我们可能希望把整个看到的图形画下来,但它只占据纸张的一部分,而不是全部。(视口变换)
这些,都可以在OpenGL中实现。

OpenGL变换实际上是通过矩阵乘法来实现。无论是移动、旋转还是缩放大小,都是通过在当前矩阵的基础上乘以一个新的矩阵来达到目的。

1、模型变换和视图变换

即设置3D模型的位移,旋转等属性。由于模型和视图的变换都通过矩阵运算来实现,在进行变换前,应先设置当前操作的矩阵为“模型视图矩阵”。设置的方法是以GL_MODELVIEW为参数调用glMatrixMode函数,像这样:
glMatrixMode(GL_MODELVIEW);
通常,我们需要在进行变换前把当前矩阵设置为单位矩阵。这也只需要一行代码:
glLoadIdentity();
然后,就可以进行模型变换和视图变换了。进行模型和视图变换,主要涉及到三个函数:
glTranslate*,(*表示这个函数分为float型的glTranslatef和int型的glTranslatex)把当前矩阵和一个表示移动物体的矩阵相乘。三个参数分别表示了在三个坐标上的位移值。
glRotate*,把当前矩阵和一个表示旋转物体的矩阵相乘。物体将绕着(0,0,0)到(x,y,z)的直线以逆时针旋转,参数angle表示旋转的角度。
glScale*,把当前矩阵和一个表示缩放物体的矩阵相乘。x,y,z分别表示在该方向上的缩放比例。


2、投影变换
投影变换就是定义一个可视空间,可视空间以外的物体不会被绘制到屏幕上。(注意,从现在起,坐标可以不再是-1.0到1.0了!)
OpenGL支持两种类型的投影变换,即透视投影和正投影。投影也是使用矩阵来实现的。如果需要操作投影矩阵,需要以GL_PROJECTION为参数调用glMatrixMode函数。
glMatrixMode(GL_PROJECTION);
通常,我们需要在进行变换前把当前矩阵设置为单位矩阵。
glLoadIdentity();

透视投影所产生的结果类似于照片,有近大远小的效果,比如在火车头内向前照一个铁轨的照片,两条铁轨似乎在远处相交了。
使用glFrustum函数可以将当前的可视空间设置为透视投影空间。其参数的意义如下图:

图片来自www.opengl.org
也可以使用更常用的gluPerspective函数。其参数的意义如下图:

图片来自www.opengl.org

正投影相当于在无限远处观察得到的结果,它只是一种理想状态。但对于计算机来说,使用正投影有可能获得更好的运行速度。
使用glOrtho函数可以将当前的可视空间设置为正投影空间。其参数的意义如下图:

图片来自www.opengl.org

如果绘制的图形空间本身就是二维的,可以使用gluOrtho2D。他的使用类似于glOrgho。

3、视口变换
当一切工作已经就绪,只需要把像素绘制到屏幕上了。这时候还剩最后一个问题:应该把像素绘制到窗口的哪个区域呢?通常情况下,默认是完整的填充整个窗口,但我们完全可以只填充一半。(即:把整个图象填充到一半的窗口内)

图片来自www.opengl.org

使用glViewport来定义视口。其中前两个参数定义了视口的左下脚(0,0表示最左下方),后两个参数分别是宽度和高度。



参考原文:http://www.oschina.net/question/4873_28324

参考书籍:OpenGL超级宝典(第4版OpenGL SuperBible)
原创粉丝点击