opengl

来源:互联网 发布:电气工程师难考吗 知乎 编辑:程序博客网 时间:2024/06/12 00:36

转自:http://blog.csdn.net/fengbingchun/article/details/20219689

OpenGL介绍:OpenGL 是图形硬件的一个软件接口, 是国际上通用的开放式三维图形标准。它提供了一个标准的计算机图形学所使用的数学模型到显示的接口, 应用非常广泛。OpenGL( open graphics library, 开放性图形库) 是以SGI 的GL 三维图形库为基础制定的一个开放式三维图形标准。SGI 在1992 年7 月发布了1. 0 版。OpenGL 规范由ARB( OpenGL architecture review board, OpenGL 结构评审委员会) 负责管理, 目前加入OpenGL ARB 的成员有SGI、Microsoft、Intel、IBM、Sun、Compaq 和HP 等公司, 它们均采用了OpenGL 图形标准, 许多软件厂商以OpenGL 为基础开发自己的产品, 硬件厂商提供对OpenGL 的支持。由于OpenGL 的广泛应用, 它已经成为一个工业标准。OpenGL独立于硬件设备、窗口系统和操作系统使得以OpenGL 为基础开发的应用程序可以在各种平台间移植。OpenGL 可以运行在当前各种流行操作系统之上, 如Windows 95 /98、Windows NT/2000、Linux、Mac OS、UNIX 和OS /2 等。需要特别指出的是,由于Microsoft 公司在其Windows 95 或更高版本的操作系统和Visual 系列高级语言开发环境中捆绑了OpenGL 标准, 使得OpenGL 在微机中得到了更为普遍的应用。OpenGL 可以用各种编程语言调用。各种流行的编程语言如C、C ++ 、FORTRAN、Ada和Java 等都可以调用OpenGL 中的库函数。

OpenGL的主要功能:OpenGL 可以绘制各种简单的三维物体, 也可以高效地生成交互的复杂动态场景, 它有如下主要功能:

(1)、绘制模型:OpenGL 图形库提供了绘制点、线及多边形的函数, 应用这些基本几何图形可以绘制出用户需要的三维模型。另外, OpenGL 图形库还提供了球、锥、多面体和茶壶等复杂的三维物体以及贝塞尔和NURBS 等复杂曲线曲面的绘制函数;

(2)、各种变换: 在现实世界中, 所有的物体都是三维的, 因此, OpenGL 通过一系列的变换来实现将三维的物体显示在二维的显示设备上。OpenGL 图形库提供了基本变换和投影变换。基本变换有平移、旋转、变比(缩放)和镜像4种变换, 投影变换包括平行投影和透视投影两种。在算法上, 它们是通过矩阵操作来实现的;

(3)、着色模式: OpenGL 提供了两种颜色的显示方式, 一种是RGBA模式, 另一种是颜色索引方式。在RGBA 模式下, 每一像素的颜色值由红、绿、蓝色值和可能存在的A值来描述。在颜色索引模式下, 每个像素的颜色值由颜色索引表中的颜色索引值来指定, 颜色索引表是一个定义了R、G和B值的特定集合;

(4)、光照处理:在自然界我们所见到的物体都是由其材质和光照相互作用的结果,OpenGL 提供了辐射光( emitted light)、环境光( ambient light)、漫反射光( diffuse light)和镜面光( specular light) 。材质是指物体表面对光的反射特性,在OpenGL 中用光的反射率来表示材质;

(5)、纹理映射( texture mapping):纹理是数据的简单矩阵排列, 数据有颜色数据、亮度数据和alpha 数据。OpenGL 应用纹理映射将真实感的纹理粘贴在物体表面, 使物体逼真生动;

(6)、位图和图像:OpenGL提供了一系列函数来实现位图和图像的操作。位图和图像数据均采用像素的矩阵形式表示。位图主要应用于各字体中的字符,只保存像素的信息, 可以用于遮盖其他图像, 类似于掩码。图像可通过扫描和计算得到,图像数据包含每一像素的多个信息。位图和图像数据可以在屏幕和内存间进行传递;

(7)、制作动画:OpenGL 提供了双缓存( double buffering)技术来实现动画绘制。双缓存即前台缓存和后台缓存, 后台缓存用来计算场景和生成画面, 前台缓存用来显示后台缓存已经画好的画面。当画完一帧时, 交互两个缓存, 这样循环交替以产生平滑动画;

(8)、选择和反馈:OpenGL为支持交互式应用程序设计了选择操作模式和反馈模式。在选择模式下, 则可以确定用户鼠标指定或拾取的是哪一个物体, 可以决定将把哪些图元绘入窗口的某个区域。而反馈模式, OpenGL把即将光栅化的图元信息反馈给应用程序, 而不是用于绘图。此外, OpenGL 还提供了点、线及多边形的反走样技术, 能够实现深度暗示(depthcue)、运动模糊(motion blur)和雾化(fog)等特殊效果。

    OpenGL的绘制流程和原理:OpenGL 的绘制主要是将二维或三维的物体模型描绘至帧缓存, 这些物体由一系列的描述物体几何性质的顶点( vertex) 或描述图像的像素( pixel)组成。OpenGL 执行一系列的操作把这些数据最终转化为像素数据并在帧缓存中形成最后的结果。OpenGL 指令从左侧进入OpenGL, 有两类数据, 分别是由顶点描述的几何模型和由像素描述的位图、影像等模型, 其中后者经过像素操作后直接进入光栅化。评价器(evaluator) 用于处理输入的模型数据, 例如对顶点进行转换、光照, 并把图元剪切到视景体中, 为下一步光栅化做好准备。显示列表(display list)用于存储一部分指令,留待合适时间以便于快速处理。光栅化将图元转化成二维操作, 并计算结果图像中每个点的颜色和深度等信息, 产生一系列图像的帧缓存描述值, 其生成结果称为基片( fragment)。基片操作主要的有帧缓存的更新、测试、融合和屏蔽操作, 以及基片之间的逻辑操作和抖动(dithering) 。

在OpenGL 中, 除了描述顶点的属性信息外, 还有许多其他的状态变量,OpenGL 将根据具体的参数值来决定如何绘制图形、如何显示图形和如何处理错误。它们的使用规则一致,当设置了其状态值后如果不重新设置与之相对应的状态值,那么所设置的状态值将一直有效。

OpenGL的缓冲区:OpenGL需要用到4个缓冲区进行图形显示,它们分别是:颜色缓存、深度缓存、模板缓存和累积缓存:

(1)、颜色缓存:颜色缓存是由红、绿、蓝、alpha 位等位平面(bitplane)组成的,有前缓存(front buffer)、后缓存(back buffer)、左前( front_ left) 和右前(front _right)缓存、左后(back _left)和右后(back_right)缓存。左前缓存是必需的颜色缓存。前缓存是可见缓存,后缓存是不可见缓存。前后缓存技术可以实现动画操作。与颜色缓存相关的主要函数有:A、清除颜色缓存:glClear(GL_COLOR_BUFFER_BIT),用于清除当前显示缓冲区内容, 为开始新的绘制做好准备;B、设置清除颜色:glClearColor(red, green, blue, alpha),用当前颜色(red, green,blue, alpha) 清除当前显示缓冲区内容,为开始新的绘制做好准备;C、屏蔽颜色缓存:glColorMask(),分别设置红、绿、蓝和alpha 的可写属性;D、选择颜色缓存:glDrawBuffer(),用于对双缓存中一个进行选择;E、交换颜色缓存:swapBuffer( ),交换前后缓存中的颜色,以实现动画。

(2)、深度缓存:深度缓存也叫Z-buffer,它记录每个像素点所对应的物体点到视点的距离, 由此决定表面的可见性。在进行消隐的时候,OpenGL必须知道各物体间的相对位置关系, 从而模拟出物体相互遮挡的效果,因此,需要进行深度测试。而深度测试的结果就生成了深度缓存。与深度缓存相关的OpenGL操作主要有:A、清除深度缓存:glClear(GL_DEPTH_BUFFER_BIT) ,用于清除当前显示缓冲区内容, 为开始新的绘制做好准备;B、设置清除值:glClearDepth(1.0);C、屏蔽深度缓存:glDepthMask(GL_TRUE),表示可以写深度缓存;glDepthMask(GL_FALSE),表示禁止写深度缓存;D、启动和关闭深度测试:glEnable(GL_ DEPTH _ TEST),表示开启深度测试;glDisable(GL_DEPTH_TEST),表示禁止深度测试;E、确定测试条件:glDepthFunc() , 根据函数参数确定测试方式, 具体的参数说明请参考OpenGL 手册;F、确定深度范围:glDepthRange(GlclampdzNear, Glclampd zFar),参数zNear 和zFar 分别说明视景体的前景面和后景面向窗口坐标映射的规格化坐标, 便于后续使用。

(3)、模板缓存:模板缓存和累积缓存主要用于图形的特殊效果绘制。模板缓存存放像素的模板值。可用于控制像素是否被改写, 因而其可以禁止在屏幕的某些区域绘图。模板缓存可以用于多种复杂图形的绘制, 例如, 屏蔽屏幕区域(凸区域或凹区域, 因而也可以绘制凹多边形等);遮盖物体; 制作物体的交集等。

(4)、累积缓存:顾名思义, 累积缓存是一系列绘制结果的累积,可以用来实现场景的反走样、景深模拟和运动模糊等。例如为了实现全局反走样, 可多次绘制场景, 每次绘制时轻微移动场景(相当于在空间上抖动场景),把多次绘制的结果进行累积并最后一次输出, 结果场景的边界会变得模糊, 从而实现全局反走样。

用OpenGL生成基本图形:OpenGL提供了描述点、线、多边形的绘制机制。它们通过glBegin()和glEnd()函数配对来完成。

(1)、glVertex2f()函数用于定义二维点,其后的参数是点的坐标;

(2)、可以使用glPointSize()函数来定义点在屏幕上的显示大小(甚至还可以对点进行反走样处理);

(3)、可以使用glLineWidth()来设置直线的宽度;

(4)、使用glLineStipple()函数来绘制点划线;

(5)、可以使用glPolygonStipple()函数来填充区域。多边形面的绘制:如果多边形是三维的,则在OpenGL中,每个多边形被认为是由两个面组成的:正面和反面。在绘制时,需要控制反转多边形面和剔除不绘制的面。此外,有时多边形还需控制边界线的绘制;

(6)、可以使用glPolygonMode()函数来选择多边形的正反面;

(7)、默认时,在屏幕上以逆时针方向出现定点的多边形称为正面,反之为背面,也可以使用glFrontFace()函数自行设置多边形的正面方向;

(8)、由一致方向的多边形构成完全闭合的曲面, 其背面多边形总是被正面多边形所遮挡。因此, 通过OpenGL 确定为背面时剔除这些多边形, 可以极大地提高几何体的绘制速度。同样, 如果处在几何对象内部, 只是背面多边形是可见时, 则剔除正面多边形。利用函数glCullFace( ),选择剔除(cull)正面或背面多边形, 在这之前需利用glEnable( )激活剔除处理;

(9)、多边形面的法向量:法向量是垂直于面的方向上点的向量。在平展的面上,各个点有同一个方向; 在弯曲的面上, 各个点具有不同的法向量。几何对象的法向量定义了它在空间中的方向。在进行光照处理时, 法向量是一项重要的参数, 因为法向量决定了该对象可以接收多少光照。与法向量有关的操作有两类, 分别是: 指定法向量和计算法向量。A、利用函数glNormal*( )设置当前法向量,用glNormal*( )指定的法向量不一定为单位长度。如果利用命令glEnable(GL_NORMALIZE)激活自动规格化法向量, 则经过变换后,就会自动规格化glNormal*( )所指定的法向量。利用glNormal*( )设置当前法向量后,相继调用glVertex*( ),使指定的顶点被赋予当前的法向量。当每个顶点具有不同的法向量时, 需要有一系列的交替调用。B、OpenGL并不能自动地计算几何对象的法向量,而只能是由用户显示地指定。法向量的计算是一个纯碎的几何和数学问题;

(10)、用OpenGL生成字符:A、生成英文字体:在OpenGL中有3种渲染字体的方法:位图、画轮廓(多边形)及纹理映射。每个方法有自己的优点与缺点。a、位图字体:对于处理场景中独立旋转及缩放的标题而言, 位图字体是比较理想的选择。从本质上说, 它是预先光栅化, 所以渲染速度比较快, 使用它们对提高程序执行速度是显而易见的。位图字体的定位由glRasterPos( )决定。b、轮廓字体:轮廓字体主要用于描述带控制点及曲线集合的字符特征。可以用下列渲染方法对多边形(或轮廓)进行填充。具体操作与OpenGL 里处理多边形是一致的。它们包括:旋转、平移、缩放( rotate、translate、scale);颜色、材质、光照( color、material、lighting);反走样( antialiasing);纹理映射( texture mapping)。轮廓字体对创建拉伸效果很有帮助。c、纹理映射字体(texture mappedtext):它是用纹素来表现正文字符, 例如对字符串的处理使用与OpenGL 纹理映射相同的操作。此项技术主要实现街道、水塔墙面上的标记等。使用wglUseFontBitmaps()将ASCII字符装入显示列表,然后使用glCallLists()函数利用显示列表序列显示文本。B、生成中文字体:在OpenGL 中使用中文字体的基本思想是:a、用wglUseFontOutlines 或wglUseFontBitmaps 为每个字生成一个List;b、为每个字调用glCallList( )或为一个字串调用glCallLists( )。具体来说, OpenGL 设计时考虑了非ASCII 字符集文字的需求,在OpenGL 中使用汉字是没有问题的。

OpenGL的颜色缓冲区:OpenGL 提供两种颜色模式: RGB( RGBA)模式和颜色索引模式。在RGBA 模式下所有颜色的定义用R、G、B 3个值来表示,有时也加上Alpha值(表示透明度)。RGB 3个分量值的范围都在之间,它们在最终颜色中所占的比例与它们的值成正比。如:( 1 , 1, 0)表示黄色,( 0, 0, 1 ) 表示蓝色。颜色索引模式下每个像素的颜色是用颜色索引表中的某个颜色索引值表示(类似于从调色板中选取颜色)。由于三维图形处理中要求颜色灵活, 而且在阴影、光照、雾化和融合等效果处理中RGBA的效果要比颜色索引模式好, 所以, 在编程时大多采用RGBA 模式。实际使用时, OpenGL 在显示缓冲区中存储了其他图形的绘图信息, 所以必须清除当前的这些内容, 以免影响绘图的效果, 可以用函数glClearColor,设置当前屏幕的背景颜色,也可以使用函数glClear(mask)清除标志的缓冲区。注意, 这个函数还可以清除其他缓冲区,由参数mask来控制也可以使用glClearColor( )、glClearDepth( )、glClearIndex( )、glClearStencil( )和glClearAcc( )为各自对应的缓冲区赋值。若要同时清除多个缓冲区, 使用mask位的“ 或”(OR)组合,在速度上要比使用多次调用glClear 函数要快得多。在绘制图形前,通常要先设定颜色或颜色方式,这样有利于达到较高的绘图性能。设置颜色的常用命令是: glColor* ( )。相邻顶点之间的部分也会有颜色, 实际上OpenGL 会在顶点之间进行插值分割,最终计算出对应光栅每一点的颜色,这个计算结果就是最终显示在屏幕上的图像。

    OpenGL坐标变换机制:OpenGL中的多数变换均对应于相应的变换矩阵,可以说OpenGL就是实现将物体的各个顶点通过各种变换矩阵的作用映射到屏幕上的过程。因此,在OpenGL中提供了一些必不可少的矩阵及矩阵操作命令。其中与变换有关的矩阵有ModeView矩阵、Projection矩阵。Projection矩阵描述了怎样从三维空间变换到屏幕坐标,而ModeView矩阵则描述了物体旋转、平移、缩放等变换。在调用变换命令之前,需要声明其后矩阵操作的对象,可以用命令glMatrixMode(GLenummode)定义。

OpenGL对图形交互的支持:(1)、用OpenGL的反向坐标变换实现三维坐标输入;(2)、用OpenGL缓冲区技术实现橡皮筋功能。

    用OpenGL生成真实感图形:利用OpenGL提供的函数可以方便地实现图形绘制过程中的隐藏面消除,以及物体表面亮度的光照计算,还可以实现纹理映射,从而生成具有真实感的图形。

    4种主要的OpenGL库:(1)、基本GL库:OpenGL库的基础,它提供OpenGL的基本函数,每个OpenGL函数都以字符GL开头;(2)、GLUT库:GL实用工具包(the GLUtility Toolkit),它主要用来打开窗口、开发和管理菜单,以及管理事件等;(3)、GLU库:GL实用库(the GLUtility Library),它提供高级例程,处理矩阵操作和绘制二次曲面如球和圆柱体。GLU库也提供将非凸和非简单多边形分解成简单形状(如三角形)的实用函数(基本的OpenGL处理不好这些操作)。它还在别的方面为简化程序员的工作提供帮助;(4)、GLUI库:用户接口库(theUser Interface Library),只要使用GLUT,GLUI就将适当地运行。GLUI为OpenGL程序提供了良好的控制工具和菜单。

    OpenGL的基本图形元素:(1)、OpenGL数据类型:GLbyte、GLshort、GLint、GLsizei、GLfloat、GLclampf、GLdouble、GLclampd、GLubyte、GLboolean、GLushort、GLuint、GLenum、GLbitfield;(2)、OpenGL状态:OpenGL是由许多状态变量组成的状态机,这些状态包括点的大小、绘图的颜色和屏幕窗口大小等。在给定新值之前,状态变量的值一直保持不变;(3)、OpenGL中的其他图形元素:除了点、线和多边形,OpenGL还支持绘制五种其他元素,为了绘制其中某个元素,需要在使用glBegin()时指定下列参数:A、GL_TRIANGLES:一次使用3个顶点,每次绘制一个独立的三角形;B、GL_QUADS:一次使用4个顶点,每次绘制一个独立的四边形;C、GL_TRIANGLE_STRIP:基于3个一组的顶点v0,v1,v2;然后是v1,v2,v3;接着是v2,v3,v4,依次递推,绘制一系列三角形(按同样的顺序,即逆时针方向,遍历所有的三角形);D、GL_TRIANGLE_FAN:基于3个一组的顶点v0,v1,v2;然后是v0,v2,v3;接着是v0,v3,v4;依次递推,绘制一系列与v0相连的三角形;E、GL_QUAD_STRIP:基于4个一组的顶点v0,v1,v3,v2;然后是v2,v3,v5,v4;接着是v4,v5,v7,v6.依次递推,绘制一系列四边形(按同样的顺序,遍历所有的四边形,如逆时针方向)。

    OpenGL被设计成与硬件无关

两种最令人感兴趣的高级着色语言是OpenGL着色语言和Cg,这两种语言非常相似,但具有不同的目标用户。

OpenGL着色语言(OpenGL Shading Language, GLSL),是OpenGL的一个标准部分,可以用来开发各种各样的用于计算顶点位置和颜色等属性的顶点着色器。还设计了片元着色器,可以用它来编写程序对每个片元进行计算,并最终计算出每个像素的颜色。OpenGL着色语言是一个类似于C语言语法的高级语言,程序员可以用它编写顶点着色器和片段着色器。

顶点程序(vertex program)或顶点着色器(vertex shader)将使用其自定义的运算操作代替由顶点处理器执行的固定功能的运算操作。如果应用程序没有提供顶点程序,那么可编程的顶点处理器就会执行OpenGL固定功能顶点处理器中的标准运算操作。

    使用GLSL语言编写的片元程序与顶点程序具有相同的语法。然而,片元程序在光栅器之后执行,因此它们处理的对象是每个片元而不是每个顶点。

    使用GLSL语言编写的着色器是独立于任何OpenGL应用程序的。虽然目前有各种各样的开发环境可供用户编写和测试着色器,但在某些时候,必须把着色器与OpenGL应用程序连接起来才能运行。有一组OpenGL函数专门用来处理这样的连续工作,包括如何创建顶点对象和着色器对象,如何将这些对象与OpenGL应用程序进行连接,以及利用变量在OpenGL应用程序与着色器直接传送数据。通常使用以下8个步骤来对应用程序中的一个或多个着色器进行初始化:(1)、将着色器读入内存;(2)、创建一个程序对象;(3)、创建着色器对象;(4)、把着色器对象绑定到程序对象;(5)、编译着色器;(6)、将所有的程序连接起来;(7)、选择当前的程序对象;(8)、把应用程序和着色器直接的uniform变量及atrribute变量关联起来。

    OpenGL的一个主要特性就是它的API非常稳定,每个版本都兼容其前面的版本

    个别的硬件供应商通过提供新的OpenGL函数供用户访问硬件特性,但这些函数可能只在某些特定制造商提供的图形硬件产品中才能正常工作,供应商是通过OpenGL的扩展函数名来识别的。例如,一个具有类似glCommandNV的扩展名表示该函数是由NVIDIA公司提供的。其它硬件制造商在他们的硬件上也能实现同样的扩展。那些被广泛使用的扩展在得到OpenGL结构评审委员会(Architectural Review Board,ARB)认可后被命名为ARB扩展。

0 0