第二章OpenGL的二维编程计算机图形学

上传人:cl****1 文档编号:578933765 上传时间:2024-08-25 格式:PPT 页数:111 大小:1,023KB
返回 下载 相关 举报
第二章OpenGL的二维编程计算机图形学_第1页
第1页 / 共111页
第二章OpenGL的二维编程计算机图形学_第2页
第2页 / 共111页
第二章OpenGL的二维编程计算机图形学_第3页
第3页 / 共111页
第二章OpenGL的二维编程计算机图形学_第4页
第4页 / 共111页
第二章OpenGL的二维编程计算机图形学_第5页
第5页 / 共111页
点击查看更多>>
资源描述

《第二章OpenGL的二维编程计算机图形学》由会员分享,可在线阅读,更多相关《第二章OpenGL的二维编程计算机图形学(111页珍藏版)》请在金锄头文库上搜索。

1、OpenGL及二维编程8/25/2024华中科技大学计算机学院李国宽21、OpenGL简介简介 OpenGL(Open Graphics Library,开放图形库),是一个二维/三维的计算机图形和模型库,它源于SGI(Silicon Graphics inc.)公司为其图形工作站开发的IRIS GL,在跨平台移植过程中发展成为OpenGL。目前, OpenGL已成为开放的国际图形标准。2.1从一个简单的示例程序开始8/25/20243OpenGL的功能:的功能: 模型绘制模型绘制 绘制点、线和多边形,构造三维模型。绘制点、线和多边形,构造三维模型。 模型观察模型观察 建立变换建立变换( (坐

2、标变换,投影变换,视窗变换坐标变换,投影变换,视窗变换) )。 颜色模式的指定:颜色模式的指定:RGBA模式和颜色索引模式 光照应用光照应用 图象效果增强:图象效果增强:反走样、混合和雾化 位图和图象处理位图和图象处理 纹理映射纹理映射 实时动画:实时动画:双缓存技术(doublebuffer) 交互技术交互技术 提供人机交互的接口。提供人机交互的接口。OpenGL的特点的特点从程序开发人员的角度来看,从程序开发人员的角度来看,OpenGL是一组是一组绘图命令的绘图命令的API集合。集合。利用这些利用这些API能够方便地能够方便地描述二维和三维几何物体,并控制这些物体按描述二维和三维几何物体,

3、并控制这些物体按某种方式绘制到显示缓冲区中。某种方式绘制到显示缓冲区中。OpenGL的的API集提供了物体描述、平移、旋转、缩放、光照、集提供了物体描述、平移、旋转、缩放、光照、纹理、材质、像素、位图、文字、交互以及提纹理、材质、像素、位图、文字、交互以及提高显示性能等方面的功能,基本涵盖了开发二、高显示性能等方面的功能,基本涵盖了开发二、三维图形程序所需的各个方面。与一般的图形三维图形程序所需的各个方面。与一般的图形开发工具相比,开发工具相比,OpenGL具有以下几个突出特具有以下几个突出特点点: :(1 1)跨平台特性跨平台特性 OpenGL与硬件、窗口和操作系统是相互独立的。与硬件、窗口

4、和操作系统是相互独立的。为了构成一个完整功能的图形处理系统,其设计实现为了构成一个完整功能的图形处理系统,其设计实现共分共分 5 5 层:图形硬件、操作系统、窗口系统、层:图形硬件、操作系统、窗口系统、 OpenGL和和应用软件。应用软件。 因而,因而, OpenGL可以集成到各种标准窗口和操作系可以集成到各种标准窗口和操作系统中。例如,操作系统包括统中。例如,操作系统包括UNIX,WindowsNT, , Windows95/98,DOS等;窗口系统包括等;窗口系统包括XWindows, , MicrosoftWindows等。等。OpenGL图形函数定义独立于任何程序设计语言,在图形函数定

5、义独立于任何程序设计语言,在各种编程语言中,如各种编程语言中,如C,C+,FORTRAIN,Ada和和Java等,都可以调用等,都可以调用OpenGL的库函数。的库函数。(2)应用的广泛性应用的广泛性OpenGL是目前最主要的二、三维交互式图形应用程是目前最主要的二、三维交互式图形应用程序开发环境,已成为业界最受推荐的图形应用编程接序开发环境,已成为业界最受推荐的图形应用编程接口。自从口。自从1992年发表以来,年发表以来,OpenGL已被广泛地应用已被广泛地应用于于CAD/CAM、三维动画、数字图像处理以及虚拟现三维动画、数字图像处理以及虚拟现实等领域,实等领域,Kinetix公司的公司的3

6、DStudioMax就是突出的就是突出的代表。无论是在代表。无论是在PC机上,还是在工作站甚至是大型机上,还是在工作站甚至是大型机和超级计算机上,机和超级计算机上,OpenGL都能表现出它的高性能都能表现出它的高性能和强大威力。和强大威力。(3)网络透明性网络透明性 建立在客户建立在客户/ /服务器模型上的网络透明性是服务器模型上的网络透明性是OpenGL的固有特性,它允许一个运行在工作站上的的固有特性,它允许一个运行在工作站上的进程在本机或通过网络在远程工作站上显示图形。利进程在本机或通过网络在远程工作站上显示图形。利用这种性质能够均衡各工作站的工作负荷用这种性质能够均衡各工作站的工作负荷,

7、 ,共同承担共同承担图形应用任务。图形应用任务。(4)高质量和高性能高质量和高性能 无论是在无论是在CAD/CAM、三维动画还是可视化仿真三维动画还是可视化仿真等领域,等领域,OpenGL高质量和高效率的图形生成能力都高质量和高效率的图形生成能力都能得到充分的体现。在这些领域中,开发人员可以利能得到充分的体现。在这些领域中,开发人员可以利用用OpenGL制作出效果逼真的二、三维图像来。制作出效果逼真的二、三维图像来。(5)出色的编程特性出色的编程特性OpenGL在各种平台上已有多年的应用在各种平台上已有多年的应用实践,加上严格的规范控制,因此实践,加上严格的规范控制,因此OpenGL具具有良好

8、的稳定性。有良好的稳定性。OpenGL具有充分的独立性与易使用性等。具有充分的独立性与易使用性等。8/25/202492、OpenGL的工作方式的工作方式 (1)体系结构 一个完整的窗口系统的OpenGL图形处理系统的结构如右图所示:最底层为图形硬件,第二层为操作系统,第三层为窗口系统,第四层为OpenGL,最上面的层为应用软件。 8/25/202410(2)OpenGL的流水线的流水线 当应用程序进行OpenGL API函数调用时,OpenGL命令将被放在一个命令缓冲区中,这样,命令缓冲区中包含了大量的命令、顶点数据和纹理数据。当这个缓冲区被清空时,缓冲区中的命令和数据都将传递给流水线的下一

9、个阶段。8/25/202411(3)OpenGL状态机制状态机制 OpenGL的工作方式是一种状态机制,它可以进行各种状态或模式设置,这些状态或模式在重新改变它们之前一直有效。 状态变量可以通过glEnable()、glDisable()这两个函数来设置成有效或无效状态 。 8/25/2024123、OpenGL的组成的组成 OpenGL是一种API,包括了多个图形函数,主要由以下函数库组成。(1)OpenGL核心库:gl(2)OpenGL实用程序库: glu(3)OpenGL编程辅助库:aux(4)OpenGL实用程序工具包(OpenGL utility toolkit,GLUT):glut

10、(5)Windows专用库:wgl(6)Win32 API函数库8/25/2024134、OpenGL中的数据类型中的数据类型 数据类型 内部表示法 定义为C类型 GLbyte 8位整数 signed char GLshort 16位整数 short GLint,GLsizei 32位整数 long GLfloat,GLclampf 32位浮点数 float GLdouble,GLclampd 64位浮点数 double GLubyte,GLboolean 8位无符号整数 unsigned char GLshort 16位无符号整数 unsigned short GLuint,GLenum,G

11、Lbitfield 32位无符号整数 unsigned long 8/25/2024145、函数命名约定、函数命名约定OpenGL函数都遵循一个命名约定,即采用以下格式:例如函数glColor3f(),gl表示这个函数来自库gl.h,color表示该函数用于颜色设定,3f表示这个函数采用了三个浮点数参数。 8/25/2024156、OpenGL中的颜色中的颜色在OpenGL中,一种颜色用红、绿、蓝成分的混合来表示,每种成分的值范围是0.0到1.0 。数据类型 红色成分 绿色成分蓝色成分黑 0.0 0.00.0红 1.00.00.0绿 0.0 1.00.0黄 1.0 1.00.0紫 1.0 0.

12、01.0青 0.0 1.01.0深灰 0.25 0.250.25OpenGLOpenGL初步编程初步编程在在WindowsWindows下开发和创建一个下开发和创建一个OpenGLOpenGL程序的基程序的基本步骤:本步骤:第一步,选择一个编译环境,如第一步,选择一个编译环境,如VC+第二步,安装第二步,安装GLUT工具包工具包第三步,建立一个第三步,建立一个OpenGL工程工程第四步,编译连接第四步,编译连接第五步,执行程序第五步,执行程序OpenGLOpenGL初步编程初步编程OpenGL库和头文件:库和头文件:动态库:动态库:opengl32.dllglu32.dllglut32.dll

13、放入windowssystem32目录下静态库:静态库:opengl32.libglu32.libglut32.lib放入VC安装目录的LIB目录下头文件:头文件:gl.hglu.hglut.h放入VC安装目录的IncludeGL文件夹下程序清单程序清单1.11.1:在窗口内绘制一个矩形:在窗口内绘制一个矩形/GLRect.cGLRect.c#include #include #include #include #include#include #include#include / / 函数函数RenderSceneRenderScene用于在窗口中绘制需要的图形用于在窗口中绘制需要的图形vo

14、id void RenderScene(voidRenderScene(void) ) /用当前清除色清除颜色缓冲区,即设定窗口的背景色用当前清除色清除颜色缓冲区,即设定窗口的背景色glClear(GL_COLOR_BUFFER_BITglClear(GL_COLOR_BUFFER_BIT); ); /设置当前绘图使用的设置当前绘图使用的RGBRGB颜色颜色 glColor3f(1.0f, 0.0f, 0.0f); glColor3f(1.0f, 0.0f, 0.0f); /使用当前颜色绘制一个填充的矩形使用当前颜色绘制一个填充的矩形glRectf(100.0f, 150.0f, 150.0f

15、, 100.0f); glRectf(100.0f, 150.0f, 150.0f, 100.0f); /刷新刷新OpenGLOpenGL命令队列命令队列glFlushglFlush();(); / / 函数函数ChangeSizeChangeSize是窗口大小改变时调用的登记函数是窗口大小改变时调用的登记函数void void ChangeSize(GLsizeiChangeSize(GLsizei w, w, GLsizeiGLsizei h) h) if(hif(h = 0) h = 1; = 0) h = 1;/设置视区尺寸设置视区尺寸glViewport(0, 0, w, h); g

16、lViewport(0, 0, w, h); / / 重置坐标系统,使投影变换复位重置坐标系统,使投影变换复位glMatrixMode(GL_PROJECTIONglMatrixMode(GL_PROJECTION););glLoadIdentityglLoadIdentity();();/ / 建立修剪空间的范围建立修剪空间的范围 if (w = h) if (w = h) glOrthoglOrtho (0.0f, 250.0f, 0.0f, 250.0f* (0.0f, 250.0f, 0.0f, 250.0f*h/wh/w, 1.0f, -, 1.0f, -1.0f);1.0f); e

17、lse else glOrthoglOrtho (0.0f, 250.0f* (0.0f, 250.0f*w/hw/h, 0.0f, 250.0f, 1.0f, -1.0f);, 0.0f, 250.0f, 1.0f, -1.0f);glMatrixMode(GL_MODELVIEWglMatrixMode(GL_MODELVIEW););glLoadIdentityglLoadIdentity();(); /函数函数SetupRCSetupRC用于初始化,常用来设置场景渲染状态用于初始化,常用来设置场景渲染状态void void SetupRC(voidSetupRC(void) ) / /

18、 设置窗口的清除色为白色设置窗口的清除色为白色 glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glClearColor(1.0f, 1.0f, 1.0f, 1.0f); void void main(voidmain(void) ) /初始化初始化GLUTGLUT库库OpenGLOpenGL窗口的显示模式窗口的显示模式glutInitDisplayMode(GLUT_SINGLEglutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); | GLUT_RGB); / / 创建一个名为创建一个名为GLRectGLRect的窗口的窗口gl

19、utCreateWindow(GLRectglutCreateWindow(GLRect); ); / / 设置当前窗口的显示回调函数和窗口再整形回调函数设置当前窗口的显示回调函数和窗口再整形回调函数glutDisplayFunc(RenderSceneglutDisplayFunc(RenderScene); ); glutReshapeFunc(ChangeSizeglutReshapeFunc(ChangeSize); ); SetupRCSetupRC();(); /启动主启动主GLUTGLUT事件处理循环事件处理循环glutMainLoopglutMainLoop();(); GLR

20、ectGLRect程序运行结果程序运行结果 2.1一个简单的示例程序#includevoiddisplay()glClear(GL_COLOR_BUFFER_BIT);glBegin(GL_POLYGON);glVertex2f(-0.5,-0.5);glVertex2f(-0.5,0.5);glVertex2f(0.5,0.5);glVertex2f(0.5,-0.5);glEnd();glFlush();intmain(intargc,char*argv)glutInit(&argc,argv);glutCreateWindow(Simple);/窗口名为SimpleglutDisplay

21、Func(display);glutMainLoop();包含两个函数:包含两个函数:main()和和display()。其中。其中main()负责负责opengl的初始化,的初始化,display()负责负责所要绘制图形的定义。所要绘制图形的定义。这些语句以gl开头这些语句以glut开头2.2GLUTOpengl包含了许多渲染函数,但是它并没有包含打开窗口或者从键盘或鼠标读取事件的函数。所以GLUT的使用能够使Opengl得以完整实现。另外,Opengl绘图函数仅限于生成简单的几何图元(点、直线、多边形),GLUT还包含了一些函数,用于创建更复杂的三维物体。GLUT是学习Opengl的一个非

22、常好的起点。2.2.1GLUT窗口管理GLUT通过几个函数执行初始化窗口所需要的任务。glutInit(int*argc,char*argv)glutInitDisplayMode(unsignedintmode)glutInitWindowPosition(intx,inty)glutInitWindowSize(intwidth,intsize)glutInitContextVersion(intmajorVersion,intminorVersion)glutCreateWindow(char*string)glutInit(int*argc,char*argv)对GLUT进行初始化,并

23、处理所有的命令行参数。glutInit()应该在调用其他任何GLUT函数和OpenGL函数之前调用。glutInit()接受来自main()函数的参数,程序可以具体实现相关的方式来使用这些参数。glutInitDisplayMode(unsignedintmode)指定了是使用RGBA模式还是颜色索引模式,另外还可以指定是使用单缓冲还是使用双缓冲窗口。glutInitWindowPosition(intx,inty)指定了窗口左上角的屏幕位置glutInitWindowSize(intwidth,intsize)指定了窗口的大小(以像素为单位)glutInitContextVersion(in

24、tmajorVersion,intminorVersion)声明了要使用opengl哪个版本。glutCreateWindow(char*string)创建一个支持OpenGL渲染环境的窗口。这个函数返回一个唯一的标示符,标识了这个窗口。这个函数将一个窗口以默认尺寸300*300像素显示在屏幕的默认位置上(屏幕左上角),参数可以为窗口创建一个标题。注意:在调用glutMainLoop()函数之前,这个窗口并没有显示。2.2.2GLUT显示回调函数glutDisplayFunc(void(*func)(void)-每当GLUT确定一个窗口的内容需要重新显示时,通过glutDisplayFunc(

25、)注册的那个回调函数就会被执行。因此应该把重绘场景所需要的所有代码都放在这个显示回调函数里。如果程序修改了窗口的内容,有时候可能需要调用glutPostRedisplay(),这个函数会指示glutMainLoop()调用已注册的显示回调函数。2.2.3GLUT运行程序最后,必须调用glutMainLoop()来启动程序,而进入事件循环。所有已创建的窗口将会在这时显示,对这些窗口的渲染也开始生效。事件处理循环开始启动,已注册的显示回调函数被触发。一旦进入循环,它就永远不会退出!(除非借助回调函数或一些外部干预,如按下“终止”键),main函数中的任何位于该函数之后的代码将永远无法得到执行的机会

26、。该函数调用应作为main函数的最后一条语句出现。2.2.4GLUT处理输入事件可以使用下面这些函数注册一些回调函数,当指定的事件发生时,这些函数便会被调用。glutReshapeFunc(void(*func)intw,inth)glutKeyboardFunc(void(*func)(unsignedcharkey,intx,inty)glutMotionFunc(void(*func)intx,inty)2.2.5GLUT空闲处理glutIdleFunc(void(*func)void)回调函数中指定一个函数,如果不存在其他尚未完成的事件,就执行这个函数。这个回调函数接受一个函数指针作为

27、它的唯一参数。如果向它传递NULL(0),就相当于禁用这个函数。2.3绘图工具箱2.3.1清除窗口2.3.2指定颜色2.3.3强制完成绘图操作2.3.4坐标系统工具箱2.3.1清除窗口绘制几何物体的程序都需要处理这些问题。计算机屏幕绘图和纸上绘图不同:纸本白色,直接画计算机中,保存图片的内存通常被计算机前一幅图像所填充,因此在绘制新场景之前,一般需要把它清除为某种背景颜色。像素颜色存储方式有两种:可以把像素颜色的红、绿、蓝和alpha值(RGBA)直接存储在位平面中。(常用)也可以存储一个颜色索引值,用它来引用颜色查找表中的一个颜色项。下面两行代码把一个RGBA模式的窗口清除为黑色glClea

28、rColor(0.0,0.0,0.0,0.0);glClear(GL_COLOR_BUFFER_BIT);第一行代码把清除颜色设置为黑色第二行代码把整个窗口清除为当前清除颜色。glClear()的唯一参数表示需要清除的缓冲区。一般情况下,只要在程序早期设置一次清除颜色即可,以后可以根据需要随时清除缓冲区。VoidglClearColor(GLclampfred,GLclampfgreen,GLclampfblue,GLclampfalpha)颜色范围限定在0,1之间,默认清除颜色是(0,0,0,0)即黑色。VoidglClear(GLbitfieldmask);mask指定缓冲区:OpenGL

29、允许同时清除多个缓冲区glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)-执行速度快2.3.2指定颜色物体颜色和形状无关,一般而言,程序员首先设置颜色和颜色方案,然后再绘制物体。为了设置颜色,可以使用glColor3f()函数。这个函数接受3个参数,都是0.01.0之间的浮点数,分别表示颜色的红、绿、蓝色成分。0.0表示不使用这种成分,1.0表示最大限度的使用这种成分。2.3.3强制完成绘图操作多条绘图命令由CPU发出,但须顺序等待执行,会造成系统性能低,所以OpenGL提供了glFlush()函数,强制客户机发送网络数据包。glFlush()并不

30、等待绘图完成,只是强制绘图命令开始执行,以保证所有命令在有限时间内执行。VoidglFlush(void)强制以前发出的OpenGL命令开始执行,以保证它们能够在有限时间内完成。2.3.4坐标系统工具箱使用OpenGL编程时,往往会用到各种坐标系。应用程序所使用的坐标x轴正方向水平向右,y轴正方向竖直向上。大多数窗口系统所使用的坐标系中的y轴正方向都是竖直向下,所以如果我们想使x和y坐标只出现正值,可将坐标系原点设在屏幕的左上角。X轴Y轴原点2.4描述点、直线、和多边形讨论如何描述OpenGL几何图元。所有几何图元最终都是根据它们的顶点(vertex)来描述的。2.4.1什么是点、直线、多边形

31、2.4.2指定顶点2.4.3OpenGL几何图元2.4.1什么是点、直线、多边形点、直线、多边形数学概念比较简单。点:用一组称为顶点的浮点数表示。所有的内部计算都是建立在把顶点看成是三维数据的基础上完成的。用户可以把顶点指定为二维形式(也就是说,只指定x和y坐标),并由OpenGL把它的z坐标设置为0.直线:OpenGL中,直线这个术语表示一段线段,而不是数学意义上的两端无限延伸的直线。OpenGL指定的直线都是根据它们的端点(顶点)指定的。多边形:由线段构成的单闭合环,其中线段是由它们的端点位置的顶点指定的。多边形可能很复杂,OpenGL对它实行了很强的限制:1.OpenGL多边形各条边不能

32、相交。2.OpenGL多边形必须是凸多边形。矩形:在应用程序中极为常见,OpenGL特别提供了填充矩形图元函数glRect*().VoidglRect(typex1,typey1,typex2,typey2)-用矩形的左上角和右下角的x坐标和y坐标来指定一个长和宽二维矩形。曲线和弯曲表面:通过模拟实现,组合大量的短直线或小多边形。2.4.2指定顶点在OpenGL中,所有的几何物体最终都描述成一组有序的顶点。glVertex*()函数用于指定顶点。VoidglVertex234sifd(TYPEcoords);VoidglVertex234sifdv(constTYPE*coords);说明:指

33、定了一个用于描述几何物体的顶点。可以选择这个函数的适当版本,既可以为一个顶点提供多达4个的坐标(x,y,z,w),也可以只提供2个坐标(x,y).注意:glVertex*()函数只有位于glBegin()和glEnd()之间才有效。举例glVertex2s(2,3);glVertex3d(0.0,0.0,3.1415926535898);glVertex4f(2.3,1.0,-2.2,2.0);GLdoubledvect3=5.0,9.0,1992.0;glVertex3dv(dvect);-dvect是指向数组的指针2.4.3OpenGL几何图元知道如何指定顶点,还需要知道如何告诉Openg

34、l根据这些顶点创建一组点、一条直线、一个多边形。为了实现这个目的,需要把一组顶点放在一对glBegin()和glEnd()之间。函数glBegin的参数指定绘制图元的类型。见本章例题。几何图元的名称和含义模式图元类型GL_POINTSGL_POINTS将指定的各个顶点用于创建单个的点GL_LINESGL_LINES将指定的顶点用于创建线段。每两个顶点指定一条单独的线段。如果顶点个数是奇数,则忽略最后一个GL_LINE_STRIPGL_LINE_STRIP将指定的顶点用于创建线条。第一个顶点之后的每个顶点指定的是线条延伸到的下一个点GL_LINE_LOOPGL_LINE_LOOP特性和GL_LI

35、NE_STRIP相似,只不过最后一条线段是在指定的最后一个和第一个顶点之间绘制。典型情况下,这用于绘制那些可能违反了GL_POLYGON用法规则的封闭区域GL_TRIANGLESGL_TRIANGLES将指定的顶点用于构造三角形。每三个顶点指定一个新三角形。如果顶点个数不是三的倍数,多余的顶点将被忽略GL_TRIANGLE_STRIGL_TRIANGLE_STRIP P将指定的顶点用于创建三角条。指定前三个顶点之后,后继的每个顶点与它前面两个顶点一起用来构造下一个三角形。每个顶点三元组(在最初的组之后)会自动重新排列以确保三角形绕法的一致性。GL_TRIANGLE_FANGL_TRIANGLE

36、_FAN将指定的顶点用于构造三角扇形。第一个顶点充当原点,第三个顶点之后的每个顶点与它的前一个顶点还有原点一起组合。GL_QUADSGL_QUADS每四个顶点一组用于构造一个四边形。如果顶点个数不是四的倍数,多余的顶点将被忽略GL_QUADS_STRIPGL_QUADS_STRIP将指定的顶点用于构造四条形边。在第一对顶点之后,每对顶点定义一个四边形。和GL_QUADS的顶点顺序不一样,每对顶点以指定顺序的逆序使用,以便保证绕法的一致GL_POLYGONGL_POLYGON将指定的顶点用于构造一个凸多边形。多边形的边缘决不能相交。最后一个顶点会自动连接到第一个顶点以确保多边形是封闭的使用glB

37、egin()和glEnd()的限制除这些函数外,之间不能使用其他OpenGL函数。2.4基本状态管理OpenGL维护了许多状态和状态变量。物体在进行渲染时可能会使用光照、纹理、隐藏表面消除、雾以及其他物体外观的状态。默认情况下,这些状态的大部分一开始是处于不活动状态的。激活这些状态可能需要较大的开销。为了打开或关闭这些状态,可以使用下面这两个简单的函数:VoidglEnable(GLenumcapability);VoidglDisable(GLenumcapability);glEnable()启用一个功能,glDisable()关闭一个功能。2.5显示点、直线、多边形最简单的计算机图形就是

38、在屏幕上某个位置绘制一个点,并用特定的颜色绘制出来。请看下面的代码:glBegin(GL_POINTS);glVertex3f(0.0f,0.0f,0.0f);glVertex3f(10.0f,10.0f,10.0f);glEnd();计算机中的图元只是把一组顶点或顶点列表解释为屏幕上绘制的某些形状,而顶点是用函数glVertex3f来定义,该函数中的参数指明定义点的x、y和z坐标。OpenGL中定义的定点到放在函数glBegin和glEnd之间,由函数glBegin的参数指定绘制图元的类型,GL_POINTS表示这个序列中绘制的是单个的点。点的绘制glVertex函数用于指定顶点,它可以有2

39、,3,4个参数。带2个参数时指定的是空间点的x,y坐标,其z坐标为默认值0,在绘制平面图形时常常使用这类函数;带3个参数时指定的是空间点的x,y和z坐标;带4个参数时,除了定义空间点的x,y,z坐标,还有一个不为0的w坐标,这样,点的坐标(x,y,z,w)实际上构成了一个齐次坐标。在OpenGL中,我们仍然使用规范化齐次坐标以保证点的齐次坐标与三维坐标的一一对应关系,最后指定的空间点的坐标为(x/w,y/w,z/w,1),w成了坐标值的一个缩放因子。直线属性在OpenGL中绘制一个点时,点大小的默认值是一个象素。可以用函数glPointSize修改这个值:voidglPointSize(GLf

40、loatsize);这个函数采用一个参数来指定画点时以象素为单位的近似直径。但是不是任意大小点都支持,通常使用下面的代码来获取点大小的范围和它们之间最小的中间值:GLfloatsizes2;/保存绘制点的尺寸范围GLfloatstep;/保存绘制点尺寸的步长glGetFloatv(GL_POINT_SIZE_RANGE,sizes);glGetFloatv(GL_POINT_SIZE_GRANULARITY,&step);在数组size中包含两个元素,分别保存了glPointSize的最小有效值和最大有效值,而变量step将保存点大小之间允许的最小增量。指定范围之外的大小不会被解释为错误,而是

41、使用最接近指定值的可支持的最大或最小尺寸。在OpenGL程序中,我们常可以利用离散的点来拟合一些常见的曲线,如圆,螺旋线等等。直线的绘制使用模式GL_LINES可以在两点之间画线,如下面的代码在两点(0,0,0)和(10,10,10)之间画一条直线:glBegin(GL_LINES);glVertex3f(0.0f,0.0f,0.0f);glVertex3f(10.0f,10.0f,10.0f);glEnd();注意,在glBegin/glEnd序列中两个顶点指定了一个图元(直线),如果序列中指定的点为奇数个,那么最后一个顶点将被忽略。有时我们需要在一系列的顶点之间绘制连续直线,此时需要用到G

42、L_LINE_STRIP或GL_LINE_LOOP模式。GL_LINE_STRIP模式可以根据指定的一系列顶点,从一个顶点到另一个顶点用连续的线段画线。glBegin(GL_LINE_STRIP);glVertex3f(0.0f,0.0f,0.0f);glVertex3f(10.0f,10.0f,0.0f);glVertex3f(20.0f,5.0f,0.0f);glEnd();上面这段代码实际上在xy平面内绘制了两条直线(0,0,0)到(10,0,0)和(0,10,0)到(20,5,0)。特别的,当沿着某条曲线指定一系列靠的很近的点,使用GL_LINE_STRIP模式可以绘制一条曲线。曲线属

43、性GL_LINE_LOOP模式与GL_LINE_STRIP模式类似,只是会在指定的最后一个顶点与第一个顶点之间画最后一条线。直线的属性包括线宽和线型。在OpenGL中可用glLineWidth指定线宽:voidglLineWidth(GLfloatwidth)与点的大小类似,glLineWidth函数采用一个参数来指定要画的线以象素计的近似宽度,可以用下面的代码来获取线宽范围和它们之间的最小间隔:GLfloatsizes2;/保存线宽的尺寸范围GLfloatstep;/保存线宽尺寸的最小间隔glGetFloatv(GL_LINE_WIDTH_RANGE,sizes);glGetFloatv(G

44、L_LINE_WIDTH_GRANULARITY,&step);数组seize中保存了glLineWidth的最小有效值和最大有效值,而变量step将保存线宽之间允许的最小增量。OpenGL规范只要求支持一种线宽:1.0。Microsoft的OpenGL实现允许线宽从0.5到10.0,最小增量为0.125。多边形面的绘制多边形面的绘制1.三角形的绘制在OpenGL中,面是由多边形构成的。三角形可能是最简单的多边形,它有三条边。可以使用GL_TRIANGLES模式通过把三个顶点连接到一起而绘出三角形。下面的代码绘制了一个三角形:glBegin(GL_TRIANGLES);glVertex2f(0

45、.0,0.0);glVertex2f(15.0,15.0);glVertex2f(30.0,0.0);glEnd();注意,这里三角形将被用当前选定的颜色填充,如果尚未指定绘图的颜色,结果将是不确定的。使用GL_TRIANGLE_STRIP模式可以绘制几个相连的三角形,系统根据前三个顶点绘制第一个多边形,以后每指定一个顶点,就与构成上一个三角形的后两个顶点绘制新的一个三角形。使用GL_TRIANGLE_FAN模式可以绘制一组相连的三角形,这些三角形绕着一个中心点成扇形排列。第一个顶点构成扇形的中心,用前三个顶点绘制出最初的三角形之后,随后的所有顶点都和扇形中心以及紧跟在它前面的顶点构成下一个三

46、角形,此时是以顺时针方向穿过顶点。这两种模式的推进如图:绕法在绘制三角形的过程中,三个顶点将三角形封闭的过程是有序的,即三角形的构成路径具有方向性,我们把指定顶点时顺序和方向的组合称为“绕法”。比如上面的例子中画出的三角形的绕法就是顺时针的,若把后两个顶点的位置互换,就得到了逆时针绕法。绕法是任何多边形图元的一个重要特性。一般默认情况下,OpenGL认为逆时针绕法的多边形是正对着的,这一特性对于希望给多边形的正面和背面赋予不同的物理特性十分有用。如果要反转OpenGL的默认行为,可以调用函数:glFrontFace(GL_CW);CL_CW告诉OpenGL应该把顺时针缠绕的多边形为正对着的。为

47、了改回把逆时针绕法视为正面,可以使用CL_CCW。明暗处理在绘制多边形时,我们常常要指定绘制的颜色,而在OpenGL中,颜色实际上是对各个顶点而不是对各个多边形指定的。多边形的轮廓或者内部用单一的颜色或许多不同的颜色来填充的处理方式称为明暗处理。在OpenGL中,用单一颜色处理的称为平面明暗处理(FlatShading),用许多不同颜色处理的称为光滑明暗处理(SmoothShading),也称为Gourand明暗处理(GourandShading)。设置明暗处理模式的函数为:voidglShadeModel(GLenummode);其中参数mode的取值为GL_FLAT或GL_SMOOTH,分

48、别表示平面明暗处理和光滑明暗处理。应用平面明暗处理模式时,多边形内每个点的法向一致,且颜色也一致,OpenGL用指定多边形最后一个顶点时的当前颜色作为填充多边形的纯色;应用光滑明暗处理模式时,多边形所有点的法向是由内插生成的,具有一定的连续性,因此每个点的颜色也相应内插,故呈现不同色。这种模式下,插值方法采用的是双线性插值法多边形的模式多边形不是必须用当前颜色填充的。默认情况下绘制的多边形是实心的,但可以通过指定把多边形绘制为轮廓或只是点(只画出顶点)来修改这项默认行为。函数glPolygonMode允许把多边形渲染为填充的实心、轮廓线或只是点。另外,可以把这项渲染模式应用到多边形的两面或只应

49、用到正面或背面。使用下面的函数可以改变多边形模式:glPolygonMode(Glenumface,Glenummode);其中,参数face指定多边形的哪一面受模式改变的影响GL_FRONT,GL_BACK或GL_FRONT_AND_BACK。参数mode用于指定新的绘图模式。GL_FILL是默认值,生成填充的多边形;GL_LINE生成多边形的轮廓;而GL_POINT只画出顶点。GL_LINE和GL_POINT绘制的点和线受glEdgeFlag所设置边缘标记的影响。我们也可以不对表面中的某一个或全部进行绘制,方法是借助glCullFace()将正面朝向或背面朝向多边形或全部多边形进行剪裁。V

50、oidglCullFace(GLenummode)在绘图时忽略由mode(GL_FRONT,GL_BACK,GL_FRONT_AND_BACK)所指定的表面。裁剪必须通过如下方式启用:glEnable(GL_CULL_FACE);VoidglFrontFace(GLenummode)允许将逆时针(GL_CCW)方向或顺时针(GL_CW)方向定义为正面朝向。多边形的绘制规则在使用大量多边形构造一个复杂表面时,有两条重要规则。第一条规则是所有多边形都必须是平面的,也就是说,多边形的所有顶点必须位于一个平面上,不能在空间中扭曲。第二条规则是多边形的边缘决不能相交,而且多边形必须是凸的。如果有任意两条

51、边交叉,就称这个多边形与自己相交。“凸的”是指任意经过多边形的直线进入和离开多边形的次数不超过一次。对于非凸多边形,可以把它分割成几个凸多边形(通常是三角形),再将它绘制出来。这样有出现了一个问题,如果这样的多边形被填充时看不到任何边缘,但如果切换到轮廓图形,就会看到组成大表面的所有小三角形,这会分散你的注意力。OpenGL提供了一个特殊标记来处理这些边缘,称为边缘标记。在指定顶点的列表时,通过设置和清除边缘标记,可以通知OpenGL哪些线段被认为是边线(围绕图形边界的线),哪些线段不是(不应该显示的内部线段)。glEdgeFlag函数用一个参数把边缘标记设为True或false。当函数被设置

52、为True时,后面的顶点将标记出边界线段的起点。2.6颜色插值绘制多边形的颜色由当前颜色状态决定。在两次glVertex*()调用之间改变颜色时,修改了当前状态,但是在概念上我们是将新颜色与新顶点建立了关联。例:glBegin(GL_LINE);glColor3f(1.0,0.0,0.0);glVertex2f(1.0,0.0);glColor3f(0.0,0.0,1.0);glVertex2f(0.0,1.0);glEnd();但是,两点之间的颜色是什么呢?红色点蓝色点默认情况下,将使用平滑着色依据两端顶点的颜色通过插值计算出中间点的颜色值。所以这条线的颜色是从红色逐渐过渡到蓝色,中间将经历

53、明暗的紫红色。见openGLTest1程序Opengl允许用最后一个顶点颜色来确定整个图元属性。平面着色VoidglShadeModel(GLenummode)将明暗模型设为平滑模式(GL_SMOOTH)或平面模式(GL_FLAT)。着色模式点默认为平滑模式。将一个多边形分解为5个三角形时,如果对这5个三角形进行填充时,显示是没有问题的。但将多边形模式设为边模式时,我们实际上想显示的是原始多边形的各边,而非产生的虚线新边。所以我们借助函数glEdgeFlag*(),可决定哪些边将被显示。如果该标记设为了GL_TRUE,则每个顶点都被认为是所要显示的线段的起点;若该标记被设为GL_FALSE,则

54、构成虚边的顶点不被显示。VoidglEdgeFlag(GLbooleanflag)VoidglEdgeFlagv(GLboolean*flag)顶点数组OpenGL需要进行大量的函数调用才能完成对几何图元的渲染。绘制一个20条边的多边形至少需要22个函数调用。首先调用1次glBegin(),然后为每个顶点调用1次函数,最后调用1次glEnd()。由于还需要额外的信息(多边形边界标志或表面法线),所以在每个顶点上还要增加函数调用。这可能会成倍地增加渲染几何物体所需要的函数调用数量。在有些系统中,函数调用具有相当大的开销,可能会影响应用程序的性能。OpenGL提供了一些顶点数组函数,允许只用少数几

55、个数组指定大量的与顶点相关的数据,并用少量函数调用(与顶点数组的数量相仿)访问这些数据。使用顶点数组函数,一个拥有20条边的多边形的20个顶点可以放在1个数组中,并且只通过1个函数进行调用。如果每个顶点还有一条法线向量,所有20条法线向量可以放在另一个数组中,也可以只通过1个函数进行调用。把数据放在顶点数组中可以提高应用程序的性能。使用顶点数组可以减少函数调用的次数,从而提高性能。另外,使用顶点数组还可以避免共享顶点的冗余处理。使用顶点数组对几何图形进行渲染需要3个步骤:1)激活(启用)最多可达8个数组,每个数组用于存储不同类型的数据:顶点坐标、表面法线、RGBA颜色、辅助颜色、颜色索引、雾坐

56、标、纹理坐标以及多边形的边界标志。步骤1:启用数组第一个步骤是调用glEnableClientState()函数(使用一个枚举值参数),激活选择的数组。从理论上说,最多可能调用这个函数8次,激活8个可用的数组。但是在实践中,可以激活的数组最多只有6个,这是因为有些数组不能同时激活。例如,不可能同时激活GL_COLOR_ARRAY和GL_INDEX_ARRAY。应用程序的显示模式可以支持RGBA模式,也可以支持颜色索引模式,但是不能同时支持这两种模式。voidglEnableClientState(GLenumarray)指定了需要启用的数组。array参数可以使用下面这些符号常量:GL_VER

57、TEX_ARRAY、GL_COLOR_ARRAY、GL_SECONDARY_COLOR_ARRAY、GL_INDEX_ARRAY、GL_NORMAL_ARRAY、GL_FOG_COORDINATE_ARRAY、GL_TEXTURE_COORD_ARRAY和GL_EDGE_FLAG_ARRAY。如果需要使用光照,可能需要为每个顶点定义一条法线向量。在这种情况下使用顶点数组时,需要同时激活表面法线数组和顶点坐标数组:glEnableClientState(GL_NORMAL_ARRAY);glEnableClientState(GL_VERTEX_ARRAY);步骤2:指定数组的数据可以通过一种简

58、单的方法,用一条命令指定客户空间中的一个数组。共有8个不同的函数可以用来指定数组,每个函数用于指定一个不同类型的数组。另外,还有一个函数可以一次指定客户空间中的几个数组,它们均来源于一个混合数组。voidglVertexPointer(GLintsize,GLenumtype,GLsizeistride,constGLvoid*pointer);指定了需要访问的空间坐标数据。pointer是数组包含的第一个顶点的第一个坐标的内存地址。type指定了数组中每个坐标的数据类型(GL_SHORT、GL_INT、GL_FLOAT或GL_DOUBLE)。size是每个顶点的坐标数量,它必须是2、3或4。

59、stride是连续顶点之间的字节偏移量。如果stride是0,数组中的顶点便是紧密相邻的。为了访问其他几个数组,可以使用下面这些类似的函数:为了访问其他几个数组,可以使用下面这些类似的函数:voidglColorPointer(GLintsize,GLenumtype,GLsizeistride,constGLvoid*pointer);voidglSecondaryColorPointer(GLintsize,GLenumtype,GLsizeistrideconstGLvoid*pointer);voidglIndexPointer(GLenumtype,GLsizeistride,con

60、stGLvoid*pointer);voidglNormalPointer(GLenumtype,GLsizeistride,constGLvoid*pointer);voidglFogCoordPointer(GLenumtype,GLsizeistride,constGLvoid*pointer);voidglTexCoordPointer(GLintsize,GLenumtype,GLsizeistride,constGLvoid*pointer);voidglEdgeFlagPointer(GLsizeistride,constGLvoid*pointer);示例程序;启用和加载顶点数

61、组staticGLintvertices=25,25,100,325,175,25,175,325,250,25,325,325;staticGLfloatcolors=1.0,0.2,0.2,0.2,0.2,1.0,0.8,1.0,0.2,0.75,0.75,0.75,0.35,0.35,0.35,0.5,0.5,0.5;glEnableClientState(GL_COLOR_ARRAY);glEnableClientState(GL_VERTEX_ARRAY);glColorPointer(3,GL_FLOAT,0,colors);glVertexPointer(2,GL_INT,0,v

62、ertices);跨距(Stride)gl*Pointer()函数的stride参数告诉OpenGL如何访问指针数组中的数据。它的值应该是两个连续的指针元素之间的字节数量(或者是0,这是一种特殊情况)。例如,假设顶点的RGB值和(x,y,z)坐标存储在同一个数组中,如下所示:staticGLfloatintertwined=1.0,0.2,1.0,100.0,100.0,0.0,1.0,0.2,0.2,0.0,200.0,0.0,1.0,1.0,0.2,100.0,300.0,0.0,0.2,1.0,0.2,200.0,300.0,0.0,0.2,1.0,1.0,300.0,200.0,0.0

63、,0.2,0.2,1.0,200.0,100.0,0.0;如果只想引用这个intertwined数组中的颜色值,下面这个调用从数组的起始地址(可以用&intertwined0表示)开始,然后跳跃6*sizeof(GLfloat)个字节(也就是颜色和顶点坐标值的字节总数)。这次跳跃确保到达了下一个顶点数据的开始位置:glColorPointer(3,GL_FLOAT,6*sizeof(GLfloat),&intertwined0);对于顶点坐标指针,需要从这个数组的其他位置开始引用。我们从intertwined的第4个元素开始(记住,C的数组是从0开始计数的):glVertexPointer(3

64、,GL_FLOAT,6*sizeof(GLfloat),&intertwined3);如果stride参数的值为0,每种类型的顶点数组(RGB颜色、颜色索引、顶点坐标等)必须紧密相邻。数组中的数据必须是一致的。也就是说,数据必须全部是RGB颜色值,或者全部是顶点坐标,也可以是其他类似的数据。步骤3:解引用和渲染在顶点数组的内容被解引用(即提取指针所指向的数据)之前,数组一直保存在客户端,它们的内容很容易进行修改。在步骤3中,数组中的数据被提取,接着发送到服务器,然后发送到图形处理管线进行渲染。可以从单个数组元素(索引位置)提取数据,也可以从一个有序的数组元素列表(可能被限制为整个顶点数组数据的

65、一个子集)中提取数据,或者从一个数组元素序列中提取数据。解引用单个数组元素voidglArrayElement(GLintith)获取当前所有已启用数组的一个顶点(第ith个)的数据。对于顶点坐标数组,对应的函数是glVertexsizetypev(),其中size是2,3,4之一。type是s,i,f,d之一,分别表示GLshort、GLint、GLfloat和GLdouble。glArrayElement()通常是在glBegin()和glEnd()之间调用。否则,glArrayElement()函数就会设置所有启用的数组的当前状态(顶点除外,因为它不存在当前状态)。使用取自启用的顶点数组

66、的第3、第4和第6个顶点绘制了一个三角形(同样,我们需要记住C的数组是从0开始计数的)。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(5);glEnd();解引用数组元素的一个列表glArrayElement

67、()对于随机存取数据的数组是非常有效的。与它类似的函数,例如glDrawElements()、glMultiDrawElements()和glDrawRangeElements()则采用一种更为有序的方式对数据数组进行随机存取。voidglDrawElements(GLenummode,GLsizeicount,GLenumtype,constGLvoid*indices);使用count个元素定义一个几何图元序列,这些元素的索引值保存在indices数组中。type必须是GL_UNSIGNED_BYTE、GL_UNSIGNED_SHORT或GL_UNSIGNED_INT,表示indices数

68、组的数据类型。mode参数指定了被创建的是哪种类型的图元,它的值和glBegin()函数所接受的参数值相同,例如GL_POLYGON、GL_LINE_LOOP、GL_LINES和GL_POINTS等。glDrawElements()的效果差不多相当于下面这段代码:glBegin(mode);for(i=0;icount;i+)glArrayElement(indicesi);glEnd();glDrawElements()还会执行检查,确保mode、count和type参数的值都是合法的。使用glDrawElements(),立方体每个侧面的顶点可以放在一个索引数组中。程序显示了用glDraw

69、Elements()对这个立方体进行渲染的两种方法;staticGLubytefrontIndices=4,5,6,7;staticGLubyterightIndices=1,2,6,5;staticGLubytebottomIndices=0,1,5,4;staticGLubytebackIndices=0,3,2,1;staticGLubyteleftIndices=0,4,7,3;staticGLubytetopIndices=2,3,7,6;glDrawElements(GL_QUADS,4,GL_UNSIGNED_BYTE,frontIndices);glDrawElements(G

70、L_QUADS,4,GL_UNSIGNED_BYTE,rightIndices);glDrawElements(GL_QUADS,4,GL_UNSIGNED_BYTE,bottomIndices);glDrawElements(GL_QUADS,4,GL_UNSIGNED_BYTE,backIndices);glDrawElements(GL_QUADS,4,GL_UNSIGNED_BYTE,leftIndices);glDrawElements(GL_QUADS,4,GL_UNSIGNED_BYTE,topIndices);把glDrawElements()放在glBegin()和glEnd

71、()之间是错误的做法。对于其中几种图元类型(例如GL_QUADS、GL_TRIANGLES和GL_LINES),可以把几个索引列表压缩在一起,放在同一个数组中。由于GL_QUADS图元把每4个顶点解释为一个多边形,因此可以把上个程序使用的所有索引值压缩到一个数组中。staticGLubyteallIndices=4,5,6,7,1,2,6,5,0,1,5,4,0,3,2,1,0,4,7,3,2,3,7,6;glDrawElements(GL_QUADS,24,GL_UNSIGNED_BYTE,allIndices);glMultiDrawElements()函数的作用是把几个glDraw-El

72、ements()调用合并到1个函数调用中。voidglMultiDrawElements(GLenummode,GLsizei*count,GLenumtype,constGLvoid*indices,GLsizeiprimcount);调用一系列的glDrawElements()函数(数量为primcount个)。indices是一个指针数组,包含了数组元素的列表。count是一个数组,包含了每个相应的数组元素列表中能够找到的顶点数量。mode(图元类型)和type(数据类型)与它们在glDrawElements()函数中的含义相同。与glDrawElements()和glMultiDraw

73、Elements()相似,glDrawRangeElements()函数也适用于随机存取的数据数组,用于对它们的内容进行渲染。glDrawRangeElements()还对它所接受的合法索引值引入了范围限制,这可以提高程序的性能。为了实现优化的性能,有些OpenGL实现能够预先提取(在渲染之前获取)有限数量的顶点数组数据。glDrawRangeElements()允许指定预先提取的顶点的范围。voidglDrawRangeElements(GLenummode,GLuintstart,GLuintend,GLsizeicount,GLenumtype,constGLvoid*indices);

74、创建了一个几何图元序列,类似于glDrawElements()创建的序列,但是具有更强的限制。glDrawRangeElements()引入了两个新参数:start和end,它们指定了indices可以接受的值的范围。indices数组中的值必须位于start和end之间才是合法的(包含start和end)。解引用一个数组元素序列解引用一个数组元素序列glArrayElements()、glDrawElements()和glDrawRangeElements()能够对数据数组进行随机存取,但是glDrawArrays()只能按顺序访问它们。voidglDrawArrays(GLenummode

75、,GLintfirst,GLsizeicount);创建一个几何图元序列,使用每个被启用的数组中从first开始,到first+count-1结束的数组元素。mode指定了创建的图元类型,它的值和glBegin()函数所接受的参数值相同。例如:GL_POLYGON、GL_LINE_LOOP、GL_LINES和GL_POINTS等。调用glDrawArrays()函数的效果差不多相当于下面这段代码:glBegin(mode);for(i=0;icount;i+)glArrayElement(first+i);glEnd();和glDrawElements()相似,glDrawArrays()也会

76、对它的参数值执行错误检查,如果对应的数组被启用,它会导致当前的RGB颜色、辅助颜色、颜色索引、法线坐标、雾坐标、纹理坐标和边界标志处于不确定状态。重启图元当开始操作大量成组的顶点数据的时候,可能会发现需要很多次地调用OpenGL绘图函数,通常是渲染之前的绘图调用中所用过的相同类型的图元(例如,GL_TRIANGLE_STRIP)。当然,可以使用glMultiDraw*()函数,但是,它们需要额外的开销来维护数组,以保存每个图元的起始索引和长度。OpenGL3.1通过指定一个专门由OpenGL处理的特定的值(图元重启索引),增加了在同一绘图调用中重启图元的能力。当在绘图调用中遇到图元重启索引的时

77、候,从紧接着索引的顶点开始对相同类型的图元进行一次新的渲染。图元重启索引由glPrimitiveRestartIndex()函数指定。voidglPrimitiveRestartIndex(GLuintindex);指定一个顶点数组元素索引,用来表示一个新的图元在渲染时的开始位置。当顶点数组元素索引的处理中遇到和index匹配的一个值的时候,就没有顶点数据需要处理了,当前的图形图元就终止了,相同类型的一个新图元开始。二维取景第一个例题中,我们使用了默认的取景条件。在取景问题中,我们所使用的基本模型称为合成摄像机模型模拟观察者(或摄像师)以及为了生成一幅图像我们需要在计算机中完成的工作。视口显示

78、OpenGL在屏幕窗口的任一部分进行绘制坐标系与变换坐标变换存放物体信息负责为场景增加透视状态保存我们对属性和其他状态变量所做出的全部修改,例如模型视图矩阵和投影矩阵,都会改变当前状态。许多修改都需要对相应的变量进行重新计算。OpenGL提供了两种类型的堆栈,我们将当前的状态保存在堆栈中,以便后期使用。矩阵堆栈(matrixstack)可以用来保存投影矩阵和模型视图矩阵。每种堆栈只能容纳相应类型的矩阵。可用函数glPushMatrix()和glPopMatrix()使矩阵入栈或出栈。所使用的矩阵由当前矩阵模式(GL_MODELVIEW或GL_PROJECTION)决定。VoidglPushMa

79、trix()VoidglPopMatrix()入栈和出栈操作必须成对使用;一次出栈必须与一次入栈对应。依据当前矩阵模式使矩阵入栈或出栈OpenGL依据相关性将其属性划分为20组。例如,所有的多边形属性都位于GL_POLYGON_BIT组中。所有的直线属性都位于组GL_LINE_BIT中。我们可将多组属性或全部属性通过函数glPushAttrib()压入属性堆栈中,恢复这些状态则使用函数glPopAttrib()。VoidglPushAttrib(GLbitfieldmask)VoidglPopAttrib()使属性组入栈或出战简单示例绘制一个矩形:#include#include#includ

80、e#include/函数RenderScene用于在窗口中绘制需要的图形voidRenderScene(void)/用当前清除色清除颜色缓冲区,即设定窗口的背景色glClear(GL_COLOR_BUFFER_BIT);/设置当前绘图使用的RGB颜色glColor3f(1.0f,0.0f,0.0f);/使用当前颜色绘制一个填充的矩形glRectf(100.0f,150.0f,150.0f,100.0f);/刷新OpenGL命令队列glFlush();/函数ChangeSize是窗口大小改变时调用的登记函数voidChangeSize(GLsizeiw,GLsizeih)if(h=0)h=1;/

81、设置视区尺寸glViewport(0,0,w,h);/重置坐标系统,使投影变换复位glMatrixMode(GL_PROJECTION);glLoadIdentity();/建立修剪空间的范围if(w=h)glOrtho(0.0f,250.0f,0.0f,250.0f*h/w,1.0f,-1.0f);elseglOrtho(0.0f,250.0f*w/h,0.0f,250.0f,1.0f,-1.0f);glMatrixMode(GL_MODELVIEW);glLoadIdentity();/函数SetupRC用于初始化,常用来设置场景渲染状态voidSetupRC(void)/设置窗口的清除色为白色glClearColor(1.0f,1.0f,1.0f,1.0f);

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 医学/心理学 > 基础医学

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号