OpenGL学习总结
一.OpenGL是做什么的
一种图形硬件的接口。而不是像C和C++一样的编程语言,更像是一个运行库,提供一些预先封装的函数。
二.OpenGL的主要功能是什么
建模,变换,颜色模式设置,光照和材质设置,纹理映射,位图显示和图像。
三.OpenGL的体系结构是什么
最底层为图形硬件,第二层为操作系统,第三层为窗口系统,第四层为OpenGL,第五层为应用软件。
四.怎么样利用OpenGL来实现我们想要做的事情
首先要明白一点,OpenGL是一个与平台无关的三维图形接口,操作系统必须提供像素格式管理和渲染环境管理。因此要使用OpenGL来做我们想做的事情的时候,一定要先为OpenGL搭建一个窗口环境。在这个窗口环境中,我们才能够使用OpenGL来实现我们自己的目的。
另外要注意的是OpenGL应用的不是保留模式,而是直接模式。即我们去操作的并非是已经封装好的一些建好的图形信息,而仅是相当于操作一个图形界面。也就是说如果我们要画一个复杂的形体,我们要把这个形体的几何信息,包括点、线和面的一些信息包括进去,然后使用一定的方法,把这些基本的信息合起来,构成我们要创建的那个物体。
五.绘制图元能干什么
此处我们当明白,OpenGL能够绘制复杂和有趣的图形,但这些图形都是由几个为数不多的基本图形元素构建而成的。所以,能够绘制图元是我们构建一个复杂有趣图形的一个基础。这些基本的图元,包括点、线和面。
glBegin();
glEnd();
六.变换能干什么
当我们绘制出一个复杂或者简单图形的时候,我们要把这个图形显示到我们的电脑屏幕上。这个时候我们可能会需要用到变换,变换的目的是让我们能够从一个合适的角度,观察到我们对图形中所关注的那部分。变换包括,视图变换,模型变换,投影变换。经过这几个变换中的一个变换、几个变换或者几种变换的相互组合,我们可以得到我们想要达到的效果。
七.光照能干什么
我们绘制图形的时候要深切地知道一个事情。那就是我们做出的图形可能需要有3D效果,或者说需要让我们做出来的模型更加的有立体感,并和实际的物体尽量的接近。这个时候,我们可能要加上光照。光照让我们做出的模型更加立体。
光照模型、明暗处理、光源设置、材质定义。
真实感图形绘制是计算机图形学的一个重要组成部分,它综合利用数学、物理学、计算机科学和其他科学知识在计算机图形设备上生成象彩色照片那样的具有真实感的图形。在计算机图形设备上生成真实感图形须完成以下四个步骤:
一是用建模,即用一定的数学方法建立所需三维场景的几何描述,场景的几何描述直接影响图形的复杂性和图形绘制的计算耗费;二是将三维几何模型经过一定变换转为二维平面透视投影图;三是确定场景中所有可见面,运用隐藏面消隐算法将视域外或被遮挡住的不可见面去除;四是计算场景中可见面的颜色,即根据基于光学物理的光照模型计算可见面投射到观察者眼中的光亮度大小和颜色分量,并将它转换成适合图形设备的颜色值,从而确定投影画面上每一象素的颜色,最终生成图形。
简单光照模型:当光照射到一个物体表面上时,出现三种情形。
只考虑被照明物体表面的反射光影响,假定物体表面光滑不透明其由理想材料构成,环境假设为白光照明。
环境反射,慢反射和镜面反射。
创建光源,启动光照,明暗处理(在计算机图形学中,光滑的曲面表面常用多边形予以逼近和表示,而每个小多边形轮廓(或内部)就用单一的颜色或许多不同的颜色来勾画(或填充),这种处理方式就成为明暗处理。)
材质:材质颜色,材质定义
OpenGL用材料对光的红、绿、蓝三原色的反射率来近似定义材料的颜色。象光源一样,材料颜色也分成环境、漫反射和镜面反射成分,它们决定了材料对环境光、漫反射光和镜面反射光的反射程度。
八.颜色能干什么
颜色生成原理,计算机屏幕上每一个点的颜色都是由监视器内部的电子枪激发的三束不同颜色的光混合而成。
两种颜色模式:RGB(RGBA)模式和颜色表模式。在RGB模式下,所有的颜色定义全用RGB三个值来表示,有时也加上alpha值。颜色表模式下,每一个象素的颜色是用颜色表中的某个颜色索引值表示,这个颜色索引值指向了相应的R、G、B值。
glcolor*();glIndex*();
单调着色(flat)和平滑着色(smooth)
颜色的作用之一是能让我们做出的图形的3D效果更好。
用法:
九.混合,抗锯齿,雾,多边形偏移,这些干什么
当我们想通过一个颜色的物体,看到另一个颜色物体的时候,这时候要使用混合的功能。OpenGL会把源颜色和目标颜色各自取出,并乘以一个系数(源颜色乘以的系数称为“源因子”,目标颜色乘以的系数称为“目标因子”),然后相加,这样就得到了新的颜色。原因子和目标因子是可以通过glBlendFunc函数来进行设置的。glBlendFunc有两个参数,前者表示源因子,后者表示目标因子。
图形绘制到屏幕时,光栅化图像通过离散的像素点来表示,如此绘制出来的图元会产生锯齿。而抗锯齿则是一种处理,通过这种处理可以在一定程度上消除锯齿的影响,增强显示效果。glHint()来对图像质量和绘制速度之间的权衡作一些控制。
为了让我们做出来的图形和真实的景物,自然中的景物更加的逼近,要加上一个特效即雾。有了雾的效果,场景看起来才会更加真实。在OpenGL中,实现雾的效果。其工作模式有两种:线型模式和指数模式。两种模式是根据雾的浓度变化来区分的。线型模式中,提供一个距离视点的开始位置和结束位置。从开始到结束,雾的浓度越来越高。浓度变化和距离成正比。指数模式下,雾的浓度随着距离增长呈指数增长。这种模式常用来用于烟雾。烟幕效果。开启glEnable(GL_FOG),取消雾的效果glDisable(GL_FOG)。
线框和填充物体重合时,看起来可能很丑陋;使多边形偏移,改变其深度值,可以使带轮廓的物体更美观。着重显示实心物体边缘时,可以用GL_FILL绘制这个物体,再用GL_LINE重新绘制这个物体。
十.为什么使用显示列表
显示列表是一组存储在一起的OpenGL函数,是由一组预先存储起来的留待以后调用OpenGL函数语句组成,当调用这张显示列表时就依次执行表中所列出的函数语句。
其优势是OpenGL显示列表的设计能优化程序运行性能,尤其是网络性能。它被设计成命令高速缓存,而不是动态数据库缓存。即一旦建立了显示列表,就不能修改它。因为若显示列表可以被修改,则显示列表的搜索,内存管理的执行等开销会降低性能。如此,也就失去了其最大的优势。显示列表方式绘图比瞬时方式快,尤其是显示列表方式可以大量地提高网络性能,当通过网络发出绘图命令时,由于显示列表驻留在服务器中,因而使网络的负担减轻到最小。在单用户的机器上,显示列表同样可以提高效率。一旦显示列表被处理成适合于图形硬件的格式,则不同的OpenGL实现对命令的优化程度也不同。
显示列表的适用场合。需要注意的是并不是只要调用显示列表就能优化程序性能。因为调用显示列表本身时程序也有一些开销,若一个显示列表太小,这个开销将超过显示列表的优越性。
矩阵操作,光栅位图和图像,光、材质和光照模型、纹理、多边形的填充模式。
void glNewList(GLuint list,GLenum mode);
void glEndList(void);
void glCallList(GLuint list);
十一. 纹理,和绘制像素,位图,字体,图像
当我们想要使绘制出的模型显得更加得真实,此时我们可能需要给图形加上纹理,尤其是真实感的物体。纹理映射的方式,让我们在绘制真实感图形的时候,变得简单。纹理映射能够保证在变换多边形时,多边形上的纹理图案也随之变化。
纹理映射的基本步骤:定义纹理,控制滤波,说明映射方式,绘制场景——给出顶点和纹理坐标和几何坐标。
纹理映射只能在RGBA方式下执行,不能运用于颜色表方式。
计算机保存图象的方法有两种:矢量图和像素图。矢量图保存了图象中每一个几何物体的位置、形状、大小等信息。像素图是将完整的图像纵横分为若干行、列,这些行列使得图象被分割为很细小的分块,每一分块称为像素,保存每一像素的颜色也就保存了整个图像。
glReadPixels:读取一些像素,把已经绘制好的像素(可能已经被保存到显卡的显存中)读到内存。
glDrawPixels:绘制一些像素,把内存中一些数据作为像素数据,进行绘制。
glCopyPixels:复制一些像素,把已经绘制好的像素从一个位置复制到另一个位置。
OpenGL除去点,线,多边形,的另外两种重要的数据类型:位图和图像。这两种数据都是以象素矩阵形式存储,即用一个矩形数组来表示某一位图或图像。二者不同之处是位图包含每个象素的一位信息,而图像数据一般包含每个象素的多位信息;位图类似于掩码,可用于遮掩别的图像,而图像数据则简单地覆盖先前已经存在的数据或与之混合。
十二. 帧缓存
颜色缓存color buffer其中内容可以是颜色索引或者RGBA数据,如果用OPENGL系统支持立体图,则有左右两个缓存。
深度缓存depth buffer就是Z-BUffER,用于保存像素Z方向的数值,深度大的被深度小的代替,用以实现消隐。
模板缓存Stencil Buffer用以保持屏幕上某些位置图形不变,而其他部分重绘。
累计缓存Accumulation buffer只保存RGBA数据,用于合成图象。
glGetIntegerv()查询每个像素占据的缓存空间的参数。
颜色缓存存储了颜色索引或RGB颜色数据,还可能存储了alpha值
支持立体观察stereoscopic viewing的OpenGL实现有左颜色缓存和右颜色缓存,它们分别用于左立体图象和右立体图象。
深度缓存,存储了每个像素的深度值,通常是离视点的距离,因此深度值大的像素会被深度值小的像素覆盖。
累积缓存也存储RGBA颜色数据,将一系列的图像合成一幅图像。可以对图像进行超量采样,然后对样本进行平均,并将结果写入颜色缓存中,从而实现场景反走样,不能将数据直接写入累积缓存,累加操作总是针对一个矩形块的,通常是将数据移入或移出颜色缓存。
清空缓存
指定要读写的颜色缓存
写入glDrawBuffer();
读取glReadBuffer();
屏蔽缓存:设置掩码,用于控制写入到指定缓存中的数据。
禁用深度缓存:如果背景很复杂,则在背景绘制之后,禁用深度缓存,绘制新增物体,只要不相互重叠。下一帧时,只需要恢复数据图像,无需恢复深度缓存中的值。
十三. 求值器
计算机图形学中,所有的光滑曲线、曲面都采用线段或三角形来模拟,为了精确地表现曲线,通常需要成千上万个线段或三角形来逼近,这种方法对于计算机的硬件资源有相当高的要求。然而,许多有用的曲线、曲面在数学上只需要用少数几个参数(控制点等)来描述。这种方法所需要的存储空间比线段、三角形逼近的方法所需要的空间要小得多,并且控制点方法描述的曲线、曲面比线段、三角形逼近的曲线、曲面更精确。
求值器可以创建以Bezier为基础的样条和表面。如果想要使用求值器绘制基于其他算法的曲线和表面,必须知道如何把它们转换为Bezier曲线和表面。另外,如果想使用求值器来渲染Bezier曲线和表面的一部分,需要对它们的分割粒度做出决定。在做出这些决定时,需要在图像质量和渲染速度之间进行权衡。
为了使用求值器,首先需要定义函数C()或S(),然后启用它,并使用glEvalCoord1或glEvalCoord2()函数代替glVertex()函数。按照这种方式,我们可以像使用其他顶点一样使用曲线或曲面上的点。
十四. 选择和反馈
建立允许用户选择(select)屏幕区域或拾取(pick)绘制在屏幕上的物体的应用程序
利用OpenGL的反馈(feedback)模式获取绚染计算结果
有些图形应用程序只绘制两维和三维物体构成的静态图形,另一些允许用户识别屏幕上的物体并移动、修改、删除或用其它方法操纵这些物体。OpenGL正是设计用于支持这些交互式应用程序的。因为绘制在屏幕上的物体通常经过多次旋转、移动和透视变换,所以确定用户选中了三维场景中的哪个物体会很困难。OpenGL提供了一个选取机制可惟自动告诉你哪个物体被绘制在窗口的提定区域里。你可以用这个机制与一个工具例程(a special utility routine)一道决定哪个物体在用户说明或用光标选取的区域里。
选择(selection)实际上是OpenGL的一个操作模式;反馈(feedback)是这类模式中的别一个。在反馈模式中,你用你的图形硬件和OpenGL完成通常的绚染计算。但与用这个计算结果去在屏幕上绘制图形相反,OpenGL返回(或反馈(feeds back))这些绘制信息给你。如果你想在绘图仪而不是屏幕上绘制图形,举个例子,你就得在反馈模式绘制它们,收集绘制指令,然后将这些指令转换为绘图仪可以理解的命令。
在选择和反馈模式中,绘制信息返回给应用程序而不是像在渲染模式中那样送往帧缓冲。因此,当OpenGL处于选择或反馈模式时,屏幕将被冻结-没有图形出现
“选择(Selection)” 讨论怎样使用选择模式和相关的例程以使你程序的用户能拾取画在屏幕上的物体。
“反馈(Feedback)” 描述了怎样获取有关什么将被画在屏幕上的信息和这些信息是以什么格式组织的。
附录
OpenGL绘图的基本过程:
- 清除缓冲区
缓冲区是用来保存绘图过程中产生的图像数据的内存区域,OpenGL有颜色、深度、累积和模板等四种常用的缓冲区。
由于缓冲区中可能保留有上一次绘图遗留下来的图像数据,这些数据会影响本次绘图,因此在绘制新图之前必须将它们清除掉。颜色缓冲区中存放的是图像的像素颜色数据,深度缓冲区存放的是用于图像消隐的深度信息。在一个三维场景中,距离视点较近的物体肯能部分地或全部地遮挡住距离视点较远的物体。将被遮挡的部分消去不显示的技术称为图像消隐技术。
清除缓冲区的两个步骤:设置清除值和清除缓冲区
设置当前颜色
根据需要设置当前颜色,一旦一种颜色被设置为当前颜色,其后所有物体都将用该颜色绘出,直到当前颜色被设置为新的颜色为止。glColor()。
绘制几何图形
OpenGL中用于绘图的函数有很多,基本几何图元的绘图函数。glBegin()和glEnd()函数之间调用函数完成点、线、和多边形的绘制。glBegin(GLenum mode);
输出图形
glFlush();函数启动OpenGL绘图命令的执行,并将图形光栅化后输出在设备上。
OpenGL是个状态机
什么是状态机?状态机是一种存在于理论中的机器,具有以下的特点:
- 它有记忆的能力,能够记住自己当前的状态。
- 它可以接收输入,根据输入的内容和自己的状态,修改自己的状态,并可以得到输出。
- 当它进入某个特殊的状态的时候,它不再接收输入,停止工作。
OpenGL也可以看成这样的一种机器:
1. OpenGL可以记录自己的状态(比如,当前所使用的颜色、是否开启了混合功能,等等。)
2. OpenGL可以接收输入(当我们调用OpenGL函数的时候,实际上可以看成OpenGL在接收我们的输入),根据输入的内容和自己的状态,修改自己的状态,并且可以得到输出(我们调用glColor3f,则OpenGL接收到这个输入后会修改自己的当前状态这个状态;我们调用glRectf,则OpenGL会输出一个矩形)
3. OpenGL可以进入停止状态,不再接收输入。这个可能在我们的程序中表现得不太明显,不过在程序退出前,OpenGL总会先停止工作的。
OpenGL是一个状态机,它保持自身的状态,除非用户输入一条命令让它改变状态。