05图形实验.ppt

上传人:hyn****60 文档编号:70680648 上传时间:2023-01-24 格式:PPT 页数:92 大小:667KB
返回 下载 相关 举报
05图形实验.ppt_第1页
第1页 / 共92页
05图形实验.ppt_第2页
第2页 / 共92页
点击查看更多>>
资源描述

《05图形实验.ppt》由会员分享,可在线阅读,更多相关《05图形实验.ppt(92页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。

1、计算机图形学实验参考书计算机图形学实验教程(OpenGL版),李胜睿等编著,机械工业出版社NeHe教程OpenGL官方站点:www.opengl.org红皮书、蓝皮书(上面站点有下载)三维图形显示流程图模型坐标模型坐标模型模型变换变换场景坐标场景坐标观察观察变换变换投影坐标投影坐标投影投影变换变换观察坐标观察坐标视口视口变换变换设备坐标设备坐标第一部分 OpenGL概述Open GL原先是Silicon Graphics Incorporated(SGI公司)开发的图形接口。OpenGL已成为跨平台的开放式三维图形编程接口 1992年,Open GL1.0正式发布。Open GL ARB分别在

2、1995、1998、2001、2002、2003年发布了1.1、1.2、1.3、1.4、1.5版本。OpenGL特点应用广泛跨平台性高质量和高性能出色的编程特性网络透明性OpenGL的主要功能:绘制模型:各种变换:着色模式:光照处理:纹理映射:选择和反馈:位图和图像:制作动画:Windows下OpenGL编程常用的函数库:OpenGL图形库-函数以gl开头,可以实现比较简单的绘制功能,这些函数可以运行在现在任何主流操作系统中。OpenGL实用库-函数以glu开头,其函数功能更高级一些,如绘制复杂的曲线曲面、高级坐标变换、多边形分割等,这些函数可以运行在现在任何主流操作系统中。OpenGL辅助库

3、-函数以aux开头,它们是一些特殊的函数,包括简单的窗口管理、输入事件处理、某些复杂三维物体绘制等函数,它只能在Win32平台下运行。OpenGL实用工具开发库-函数以glut开头,它们提供更为复杂的绘制功能。Windows专用函数库-以wgl开头,负责OpenGL与Windows窗口系统的连接。如何在windows下利用Visual C+6.0调用OpenGL:安装VC+6.0(如需详细的帮助文件,还安装MSN)。将opengl32.lib,glu32.lib,glaux.lib文件放到vc下的Lib目录里,如:c:Program FilesMicrosot Visual StudioVC9

4、8Lib。将gl.h,glu.h,glaux.h文件放到vc下的IncludeGL目录里,如:c:Program FilesMicrosot Visual StudioVC98IncludeGL。将opengl32.dll,glu32.dll文件放到system目录里,如:C:WINDOWSsystem32注:若想使用glut库,则相应的glut32.lib,glut.h,glut32.dll文件要分别放入上面所说的目录里。这三个文件系统不自带。在程序的开头include头文件:gl.h,glu.h,glaux.h,glut.h(如果需要的话)链接器中加入对应的库文件:opengl32.lib

5、,glu32.lib,glaux.lib,glut32.lib(如果需要的话)OpenGL的工作顺序1)构造几何要素(点、线、多边形、图像、位图),创建对象的数学描述;在三维空间上放置对象,选择合适的场景观察点。2)计算对象的颜色,这些颜色可能直接定义,或由光照条件及纹理间接给出。3)光栅化,把对象的数学描述和颜色信息转换到屏幕的像素。OpenGL程序结构基本语法:1)基本函数使用gl作为函数名的前缀,如glClear();2)实用函数使用glu作为函数名的前缀,如gluSphere();3)辅助函数使用aux作为函数名的前缀,如auxInitPosition();4)专用函数使用wgl作为函

6、数名的前缀,如wglCreateContext();5)基本常量名以GL开头,如GL_LINES;6)实用常量名以GLU开头,如GLU_FILL;7)某些函数后可以接不同的后缀以支持不同的数据类型和格式,如glVetex234sifdv(coords);8)变量类型,如Glfloat,Glvoid,其实就是C中的float和void。状态机制:1)OpenGL各种执行的命令都是在某种状态或模式模式下进行的,这些状态和模式一直有效地保持到改变它们之后。2)许多状态变量可以通过glEnable(),glDisable()这两个函数来设置成有效或无效状态。3)绝大部分状态变量都有一个默认值,在被设置

7、成有效状态之后,可以用glGetBooleanv(),glGetDoublev(),glGetFloatv(),glGetIntegerv()来获取某个状态变量的值。4)有些状态变量有特殊的查询函数,如glGetError()。5)使用glPushAttrib()和glPopAttrib(),可以存储和恢复最近的状态变量值。程序的基本框架:1)第一部分是初始化部分。主要是设置一些OpenGL的状态。2)第二部分是设置观察坐标系下的取景模式和取景框位置及大小。3)第三部分是主要部分,使用库函数构造三维图形或场景。第二部分 OpenGL坐标变换机制例:显示一个由正方形和球体构成的场景。其中正方形的

8、中心位于点(0,0,-10)处,边长为2,球的中心位于点(4,4,-20)处,半径为1。步骤:模型的建立:场景的建立:观察坐标系的建立:视景体的建立:视区的建立:第一步:模型的建立建立一个边长为2,中心在原点,且每一面均与坐标面平行的正方形。glBegin(GL_QUADS);六个面分别定义,每个面由4个顶点构成;glEnd();建立一个半径为1,中心在原点的球。GLUquadricObj*quadric;quadric=gluNewQuadric();gluSphere(quadric,1.0f,32,32);第二步:场景的建立将前面定义的正方形和球的中心分别移到(0,0,-10)处和(4,

9、4,-20)处。glPushMatrix();glTranslatef(0,0,-10);glRotatef(45,0,1,0);glRotatef(45,1,0,0);正方形的绘制;glPopMatrix();glPushMatrix();glTranslatef(4,4,-20);球的绘制;glPopMatrix();第三步:观察坐标系的建立gluLookAt();第四步:视景体的建立 透视投影:gluPerspective();glFrustum();平行投影:glOrtho();第五步:视区的建立glViewPort();OpenGL坐标变换机制:OpenGL中与变换有关的数据结构:O

10、penGL中的ModelView变换机制:OpenGL中的Model变换使用方法:OpenGL中的View变换使用方法:OpenGL的投影:OpenGL的深度缓冲区:OpenGL中的反变换:一.OpenGL中与变换有关的数据结构:矩阵:OpenGL中的多数变换均对应于相应的变换矩阵,可以说OpenGL就是实现将物体的各个顶点通过各种变换矩阵的作用映射到屏幕上的过程。与变换有关的矩阵有ModelView矩阵和Projection矩阵。矩阵堆栈:与变换有关的矩阵堆栈有ModelView矩阵堆栈和Projection矩阵堆栈。OpenGL中提供了glPushMatrix()和glPopMatrix(

11、)两条命令来进行矩阵堆栈的操作。二.OpenGL中的ModelView变换机制:对ModelView矩阵进行操作前,要用命令glMatrixMode(GL_MODELVIEW)来申明。系统默认方式是对ModelView矩阵操作。ModelView变换是由Model变换和View变换构成。Model变换相当于确定物体在场景中的位置,前面例子里的第一、二步就属于Model变换。View变换相当于建立观察坐标系,前面例子里的第三步就属于View变换。场景与观察坐标系的位置是相对的。比如可以通过View变换将观察点拉离场景,也可以通过Model变换将场景拉离观察点。所以,在OpenGL中View变换和

12、Model变换用同一个ModelView矩阵表示。三.OpenGL中的Model变换使用方法:直接定义变换矩阵:void glLoadMatrixfd(const TYPE*m);直接将当前矩阵设置为m所指定的矩阵。void glMultiMatrixfd(const TYPE*m);将当前矩阵乘以m所指定的矩阵,所得结果置为当前矩阵。用OpenGL中库函数:glTranslate*();glRotate*();glScale*();四.OpenGL中的View变换使用方法:View变换是改变视点的位置和方向。View变换命令一般在调用Model变换之前完成。视点变换的实现方法:1.使用Mod

13、el变换命令glTranslate*()和 glRotate*();2.使用gluLookAt();3.使用用户自己生成的函数;五.OpenGL的投影:透视投影 glFrustum();gluPerspective();正投影:glOrtho();六.OpenGL的深度缓冲区:深度缓冲区存储每个象素的深度值,可以根据像素与观察者的距离,用最近的像素覆盖远的像素。通过深度检测,可以始终将深度值较小的像素点保存在深度缓存中,以达到物体消隐的目的。要使用深度缓冲区,需用glEnable(GL_DEPTH_TEST)来激活。可以用glDepthFunc()函数为深度测试选择不同的比较函数。在重画每一帧

14、之前,要把深度缓存每位都置为1。七.OpenGL中的反变换:gluUnProject()可以实现视区坐标到世界坐标的转换。利用函数glReadPixels()可以得到视区内任一像素的深度值。OpenGL中要注意的问题:变换的顺序:glPushMatrix()和glPopMatrix()的使用。三维场景下,多边形面由正反面构成。默认时,在屏幕上以逆时针方向出现顶点的多边形为正面,反之为反面。可以利用glFrontFace()设置多边形的正面方向。利用glPolygonMode()来选择绘制多边形的正反面。第三部分 用OpenGL生成基本图形OpenGL提供了描述点、线、多边形的绘制机制,它们通过

15、glBegin()和glEnd()函数配对来完成。glBegin()的参数有多种选择,分别对应着不同的点、线、多边形。glEnd()无参数,只是标志着所绘制图形的结束。glBegin()和glEnd()之间的内容决定了图形的形状,是由顶点坐标函数glVertex()来定义,。1 用OpenGL生成点例1:二维点 glBegin(GL_POINTS);glVertex2f(0.0,0.0);glVertex2f(0.0,2.0);glVertex2f(2.0,0.0);glVertex2f(3.0,3.0);glEnd();例2:三维点 glBegin(GL_POINTS);glVertex3f

16、(0.0,0.0,-7.0);glVertex3f(0.0,2.0,-7.0);glVertex3f(2.0,0.0,-7.0);glVertex3f(3.0,3.0,-7.0);glEnd();用glBegin(GL_POINTS)和glEnd()配对完成。glPointSize()用来设置点的显示大小。注意:位置要放在glBegin()前面。程序:void DrawOpenGL()glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);glLoadIdentity();glTranslatef(-1.5f,1.0f,-7.0f);glPointSi

17、ze(5.0);glBegin(GL_POINTS);glColor3ub(255,0,0);glVertex3f(0.0,0.0,-7.0);glColor3ub(255,250,0);glVertex3f(0.0,2.0,-7.0);glColor3ub(255,0,250);glVertex3f(2.0,0.0,-7.0);glColor3ub(255,250,240);glVertex3f(3.0,3.0,-7.0);glEnd();glFlush();/刷新命令队列,确保所有命令都被执行效果图2 用OpenGL生成直线例1:glBegin(GL_LINES);glVertex2f(0

18、.0,0.0);glVertex2f(0.0,2.0);glVertex2f(2.0,0.0);glVertex2f(3.0,3.0);glEnd();在例1中共生成2条线段。若GL_LINES换成GL_LINE_STRIP,则生成一条由3条线段连成的折线。若换成GL_LINE_LOOP,则生成一条由4条线段连成的闭合折线。glBegin()的参数可以选GL_LINES,GL_LINE_STRIP,GL_LINE_LOOP线宽:glLineWidth();线型:glLineStipple();在使用前,必须先用glEnable(GL_LINE_STIPPLE)启动,glDisable(GL_L

19、INE_STIPPLE)用来关闭该功能。效果图:利用生成直线的函数,可以生成曲线。3 用OpenGL生成多边形例1:glBegin(GL_TRIANGLES);glVertex2f(0.0,0.0);glVertex2f(0.0,2.0);glVertex2f(2.0,0.0);glVertex2f(3.0,-3.0);glEnd();在例1中,只画出1个三角形,第4个顶点不起作用。如果参数改为GL_TRIANGLE_STRIP和GL_TRIANGLE_ FAN,则均画出2个三角形,第1个三角形都一样,但第2个不同。见效果图。glBegin()的参数可以选GL_POLYGON,GL_TRIAN

20、GLES,GL_TRIANGLE_STRIP,GL_TRIANGLE_ FAN,GL_QUADS,GL_QUAD_STRIP效果图:OpenGL绘制的多边形的区域内部在缺省情况下是被指定的颜色填充,颜色用glColor()指定。利用生成多边形的函数,可以生成三维图形,如四面体、六面体或曲面等。4 顶点数组到目前为止,生成几何图元遇到的问题有:1.需要进行很多函数调用;如:绘制一个n边形,至少需要调用n+2次函数,若还指定其他信息(如颜色、边标记、面法线),则调用的函数更多。2.顶点冗余量很大。如:如绘制一个六面体,每个顶点都将使用 三次。改进办法:1.第一种:利用glVertex*的向量形式,

21、将顶点和面信息以数组形式给出,再在glBegin和glEnd之间循环调用glVertex*。2.第二种:使用OpenGL中的顶点数组。如何使用OpenGL中的顶点数组启用顶点数组:glEnableClientState,glDisableClientStateThe glEnableClientState and glDisableClientState functions enable and disable arrays respectively.void void glEnableClientStateglEnableClientState(GLenum GLenum array););

22、void void glDisableClientStateglDisableClientState(GLenumGLenum array););Parameters array A symbolic constant for the array you want to enable or disable.This parameter can assume one of the following values:GL_COLOR_ARRAY If enabled,use color arrays with calls to glArrayElement,glDrawElements,or gl

23、DrawArrays.See also glColorPointer.GL_EDGE_FLAG_ARRAY If enabled,use edge flag arrays with calls to glArrayElement,glDrawElements,or glDrawArrays.See also glEdgeFlagPointer.GL_INDEX_ARRAY If enabled,use index arrays with calls to glArrayElement,glDrawElements,or glDrawArrays.See also glIndexPointer.

24、GL_NORMAL_ARRAY If enabled,use normal arrays with calls to glArrayElement,glDrawElements,or glDrawArrays.See also glNormalPointer.GL_TEXTURE_COORD_ARRAY If enabled,use texture coordinate arrays with calls to glArrayElement,glDrawElements,or glDrawArrays.See also glTexCoordPointer.GL_VERTEX_ARRAY If

25、enabled,use vertex arrays with calls to glArrayElement,glDrawElements,or glDrawArrays.See also glVertexPointer.指定数组中的数据:例例:glVertexPointer The glVertexPointer function defines an array of vertex data.void void glVertexPointerglVertexPointer(GLint GLint size,GLenumGLenum type,GLsizeiGLsizei stride,GL

26、sizeiGLsizei count,constconst GLvoid GLvoid*pointer););读取数组元素:1.glArrayElementThe glArrayElement function specifies the array elements used to render a vertex.voidvoid glArrayElement glArrayElement(GLint GLint index););2.2.glDrawElements glDrawElementsThe glDrawElementsglDrawElements function render

27、s primitives from array data.voidvoid glDrawElements glDrawElements(GLenum GLenum mode,GLsizei GLsizei count,GLenum GLenum type,const,const GLvoid GLvoid*indices););3.3.glDrawArrays glDrawArraysThe glDrawArraysglDrawArrays function specifies multiple primitives to render.voidvoid glDrawArrays glDraw

28、Arrays(GLenum GLenum mode,GLintGLint first,GLsizeiGLsizei count););例:glEnableClientState(GL_COLOR_ARRAY);glEnableClientState(GL_VERTEX_ARRAY);glColorPointer(3,GL_FLOAT,0,colors);glVertexPointer(2,GL_INT,0,vertices);glBegin(GL_TRIANGLES);glArrayElement(2);glArrayElement(3);glArrayElement(4);glEnd();例

29、:Glubyte Indices=1,2,3,4;glDrawElements(GL_QUADS,4,GL_UNSIGNED_BYTE,Indices);注:在glBegin和glEnd之间调用glDrawElements将导致错误。第四部分 OpenGL中的缓存以统一的方式对每个象素的数据进行存储的存储空间称为缓存。在不同的缓存中为每个象素存储的数据量可能不同,但在同一种缓存中是相同的。存储一位像素信息的缓存称为位面。1.缓存类型颜色缓存深度缓存模板缓存累积缓存2 清空缓存void void glClearglClear(GLbitfield GLbitfield mask););Param

30、eters mask Bitwise OR of masks that indicate the buffers to be cleared.The four masks are as follows.GL_COLOR_BUFFER_BITThe buffers currently enabled for color writing.GL_DEPTH_BUFFER_BITThe depth buffer.GL_ACCUM_BUFFER_BITThe accumulation buffer.GL_STENCIL_BUFFER_BITThe stencil buffer.RemarksThe gl

31、Clear function sets the bitplane area of the window to values previously selected by glClearColor,glClearIndex,glClearDepth,glClearStencil,and glClearAccum.You can clear multiple color buffers simultaneously by selecting more than one buffer at a time using glDrawBuffer.3 屏蔽缓存voidvoid glColorMask gl

32、ColorMask(GLboolean GLboolean red,GLbooleanGLboolean green,GLbooleanGLboolean blue,GLbooleanGLboolean alpha););voidvoid glStencilMask glStencilMask(GLuint GLuint mask););voidvoid glDepthMask glDepthMask(GLboolean GLboolean flag););voidvoid glDepthFunc glDepthFunc(GLenum GLenum func););4.指定要读写的颜色缓存1.

33、glDrawBufferThe glDrawBuffer function specifies which color buffers are to be drawn into.voidvoid glDrawBuffer glDrawBuffer(GLenum GLenum mode););2.2.glReadBuffer glReadBufferThe glReadBufferglReadBuffer function selects a color buffer source for pixels.voidvoid glReadBuffer glReadBuffer(GLenum GLen

34、um mode););例1:使用深度缓存实现不透明物体穿过半透明物体。关键:1.绘制半透明物体时,将深度缓存设置为只读(glDepthMask())。2.实现物体的透明效果。(1)glBlendFuncThe glBlendFunc function specifies pixel arithmetic.voidvoid glBlendFunc glBlendFunc(GLenum GLenum sfactor,GLenumGLenum dfactor););(2)glEnable(GL_BLEND);例2:利用深度缓存实现切割。1.绘制切割面时用glDrawBuffer(GL_NONE)防止

35、数据被写入颜色缓存;2.绘制完毕后用glDrawBuffer(GL_BACK)重新往颜色缓存写入数据。注:OpenGL本身为用户提供了6个自定义的切割面,分别为GL_CLIP_PLANEi(i=0,5)。调用函数voidvoid glClipPlane glClipPlane(GLenum GLenum plane,constconst GLdouble GLdouble*equation););例3:使用模板缓存实现透视。1.glStencilFuncThe glStencilFunc function sets the function and reference value for st

36、encil testing.voidvoid glStencilFunc glStencilFunc(GLenum GLenum func,GLint GLint ref,GLuintGLuint mask););2.2.glStencilOp glStencilOpThe glStencilOpglStencilOp function sets the stencil test actions.voidvoid glStencilOp glStencilOp(GLenum GLenum fail,GLenum GLenum zfail,GLenumGLenum zpass););例4:使用累

37、积缓存实现场景反走样。glAccum(GL_ACCUM,1.0/n);glAccum(GL_RETURN,1.0);函数说明:glAccumThe glAccum function operates on the accumulation buffer.voidvoid glAccum glAccum(GLenum GLenum op,GLfloatGLfloat value););第五部分 复杂物体建模二次曲面Bezier曲线曲面NURBS曲线曲面1.二次曲面用gluNewQuadric()创建二次对象 GLUquadricObj*quadObj;quadObj=gluNewQuadric(

38、);调用gluQuadricOrientation(),gluQuadricDrawStyle(),gluQuadricNormals(),gluQuadricTexture()设置其属性。gluQuadricDrawStyle(quadObj,GLU_FILL);gluQuadricOrientation(quadObj,GLU_OUTSIDE);gluQuadricNormals(quadObj,GLU_SMOOTH);gluQuadricTexture(quadObj,GL_TRUE);调用gluSphere(),gluCylinder(),gluDisk(),gluPartialDis

39、k()绘制相应的二次曲面对象.gluSphere(quadObj,4,20,20);gluCylinder(quadObj,3,0,10,20,8);gluCylinder(quadObj,3,3,10,20,20);gluDisk(quadObj,1,7,10,5);gluPartialDisk(quadObj,1,7,10,5,100,200);最后用gluDeleteQuadric()删除二次对象。gluDeleteQuadric(quadObj);2.Bezier曲线和曲面一.用OpenGL生成Bezier曲线GLU函数库提供了evaluator(赋值器)。用户需要提供控制点序列。生成

40、一条Bezier曲线的步骤:1.提供控制点序列;2.定义evaluator(赋值器);3.绘制曲线。定义evaluator(赋值器):1.void glMap1f(Glenum target,TYPE u1,TYPE u2,Glint stride,Glint order,const TYPE*points);2.然后要用glEnable(GL_MAP1_VERTEX_3)启用。绘制曲线:1.Void glMapGrid1f(Glint n,TYPE u1,TYPE u2)定义一个均匀的一维网格;2.Void glEvalMesh1(Glenum mode,Glint p1,Glint p2)

41、根据当前定义的网格调用所有开启的evaluator进行计算,绘制图形。二.用OpenGL生成Bezier曲面生成一张Bezier曲面的步骤:1.提供控制点序列;2.给出或自动生成法矢序列;3.定义evaluator(赋值器);4.进行光照、纹理映射;5.激活各种所需功能;6.绘制曲面;7.挂起各种已用功能。定义evaluator(赋值器):1.void glMap2f(Glenum target,TYPE u1,TYPE u2,Glint ustride,Glint uorder,TYPE v1,TYPE v2,Glint vstride,Glint vorder,const TYPE*poi

42、nts);2.然后要用glEnable(GL_MAP2_VERTEX_3)启用。绘制曲面:1.Void glMapGrid2f(Glint n1,TYPE u1,TYPE u2,Glint n2,TYPE v1,TYPE v2)定义一个均匀的二维网格;2.Void glEvalMesh2(Glenum mode,Glint pu1,Glint pu2,Glint pv1,Glint pv2)根据当前定义的网格调用所有开启的evaluator进行计算,绘制图形。三.用OpenGL生成NURBS曲线和曲面GLU函数库提供了一个NURBS接口。用户需提供控制点、节点等数据。绘制一条NURBS曲线的步

43、骤:1.提供控制点序列和节点序列;2.创建一个NURBS对象,设置NURBS对象 属性;3.绘制曲线。创建一个NURBS对象:GLUnurbsObj*theNurbs;theNurbs=gluNewNurbsRender();设置NURBS对象属性:void gluNurbsProperty(GLUnurbsObj*nobj,Glenum property,GLfloat value);绘制曲线:1.在gluBeginCurve(theNurbs)/gluEndCurve(theNurbs)函数对中完成;2.Void gluNurbsCurve(GLUnurbsObj*nobj,Glint n

44、knots,Glfloat*knot,Glint stride,Glfloat*ctlarray,Glint order,Glenum type);删除NURBS对象 gluDeleteNurbsRenderer(theNurbs);四.用OpenGL生成NURBS曲面绘制一张NURBS曲面的步骤:1.提供控制点序列和节点序列;2.给出或自动生成法矢序列;3.创建一个NURBS对象并设置属性;4.进行光照、纹理映射;5.激活各种所需功能;6.绘制曲面;7.挂起各种已用功能。绘制NURBS曲面:1.在gluBeginSurface()/gluEndSurface()函 数对中完成;2.Void

45、gluNurbsSurface(GLUnurbsObj*nobj,Glint sknot_count,Glint*sknot,Glint tknot_count,Glint*tknot,Glint s_stride,Glint t_stride,Glfloat*ctlarray,Glint sorder,Glint torder,Glenumtype);五.用OpenGL生成裁剪NURBS曲面裁剪曲线可由gluPwlCurve()和gluNurbsCurve()或其组合定义;gluPwlCurve()的定义:void gluPwlCurve(GLUnurbs*nobj,Glint count,

46、Glfloat*ctlarray,Glint stride,Glenum type);在调用函数gluBeginSurface()和gluNurbsSurface()后,但调用函数gluEndsurface之前,调用函数gluBeginTrim()开始定义裁剪,以gluEndTrim()结束。第六部分 光照OpenGL采用简单光照模型进行光照计算。OpenGL进行光照计算时不考虑物体对光的可能遮挡,因此阴影不会自动产生。OpenGL将物体表面的反射光分为物体本身发出的光、对环境光的反射、对特定光源的反射。反射光物体本身发出的光:OpenGL认为物体本身可以发光,但只对物体本身的亮度产生影响,记

47、为 。对环境光的反射:这里的环境光指的是全局环境光,它不依赖于任何特定光源。它使得即使场景中没有任何特定光源,观察者也能看到物体。假设全局环境光亮度 ,物体表面的环境光反射系数为 ,则物体对全局环境光的反射为 。对特定光源的反射:OpenGL将特定光源的光亮度分为环境光分量 、漫反射光分量 、镜面光分量 ,物体表面对特定光源的反射光可以用下式表示:其中Ka,Kd,Ks分别是物体表面的环境光反射系数、漫反射系数、镜面反射系数。n为物体的会聚指数。光源OpenGL中,光源可设置为离场景无穷远,也可设置为离场景很近。前者称为定向光源。后者称为定位光源。定位光源OpenGL中,定位光源被定义为聚光灯,

48、由光源的位置(即锥顶),方向(即圆锥轴的方向),散射角(即圆锥中轴和边的夹角,介于0到180度)定义。聚光灯将光的发射形状调整为圆锥形,此时空间光强度分布可用聚光灯光强分布系数C乘以锥顶处聚光灯光强。另外,光沿直线传播时能量会衰减,OpenGL将衰减因子K定义为 ,其中Kc,Kl,Kq分别为常量、线性、二次的衰减系数,d为光的传播距离。因此物体表面对定位光源的反射亮度修改为:定向光源光源位置的第四个分量设为0.0,则定义了定向光源,前三个分量则描述了光源的方向。对定向光源,将禁用衰减。物体表面的反射光亮度综合其它反射光,OpenGL中物体表面的反射光亮度为:如果场景中存在多个聚光灯,则物体表面

49、的反射光亮度为:多边形的光照处理采用Gouraud明暗处理,对应glShadeModel(GL_SMOOTH)。直接用某个顶点的光亮度代替多边形的亮度,对应glShadeModel(GL_FLAT)。OpenGL光照环境设置由前面的介绍知道,在进行光照计算时要用到特定光源的如下属性:光源的环境光分量、漫反射光分量、镜面光分量以及光源的位置、方向、散射角、聚光指数及常量、线性、二次的衰减系数。OpenGL提供了一组函数用于设置光源的上述属性。这组函数具有统一的函数声明:void glLight*(Glenum light,Glenum pname,TYPE param)。其中,light表示当前

50、被设置的光源的标识,可以取符号常量GL_LIGHT0、GL_LIGHT7;pname表示将要对光源的那个属性进行设置,可以取代表光源属性的相应符号常量,见下页;param是pname所标识属性项的期望值。glLight*可以是glLighti、glLightf、glLightiv、glLightfv,与此对应,TYPE应为int、float、int*、float*。代表光源属性的符号常量及其含义符号常量 默认值 含义GL_AMBIENT (0.0,0.0,0.0,1.0)光源的环境光分量GL_DIFFUSE GL_LIGHT0为白色,光源的漫反射光分量 其它光源为黑色GL_SPECULAR G

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 生活休闲 > 生活常识

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知得利文库网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号-8 |  经营许可证:黑B2-20190332号 |   黑公网安备:91230400333293403D

© 2020-2023 www.deliwenku.com 得利文库. All Rights Reserved 黑龙江转换宝科技有限公司 

黑龙江省互联网违法和不良信息举报
举报电话:0468-3380021 邮箱:hgswwxb@163.com