OpenGL上机练习.docx
- 文档编号:10291786
- 上传时间:2023-02-09
- 格式:DOCX
- 页数:136
- 大小:425.64KB
OpenGL上机练习.docx
《OpenGL上机练习.docx》由会员分享,可在线阅读,更多相关《OpenGL上机练习.docx(136页珍藏版)》请在冰豆网上搜索。
OpenGL上机练习
第一章OpenGL的基本框架
1.1OpenGL简介
在计算机发展初期,人们就开始从事计算机图形的开发,但直到20世纪80年代末90年代初,三维图形才开始迅速发展。
于是各种三维图形工具软件包相继推出,如GL,RenderMan等,但没有一种软件包能够在三维图形建模能力和编程方便程度上与OpenGL相比拟。
OpenGL(OpenGraphicsLibrary,开放图形库),是一个三维的计算机图形和模型库,它源于SGI公司为其图形工作站开发的IRISGL,在跨平台移植过程中发展成为OpenGL。
SGI公司在1992年6月发布1.0版,后成为工业标准。
目前,OpenGL标准由1992年成立的独立财团OpenGLArchitectureReviewBoard(ARB)以投票方式产生,并制成规范文档公布,各软硬件厂商据此开发自己系统上的实现。
目前最新版规范是1999年5月通过的1.2.1。
OpenGL作为一个性能优越的图形应用程序设计界面(API),它独立于硬件和窗口系统,在运行各种操作系统的各种计算机上都可用,并能在网络环境下以客户/服务器模式工作,是专业图形处理、科学计算等高端应用领域的标准图形库。
OpenGL在军事、广播电视、CAD/CAM/CAE、娱乐、艺术造型、医疗影像、虚拟世界等领域都有着广泛的应用。
它具有以下功能。
1.模型绘制
OpenGL能够绘制点、线和多边形。
应用这些基本的形体,可以构造出几乎所有的三维模型。
OpenGL通常用模型的多边形的顶点来描述三维模型。
2.模型观察
在建立了三维景物模型后,就需要用OpenGL描述如何观察所建立的三维模型。
观察三维模型是通过一系列的坐标变换进行的。
模型的坐标变换在使观察者能够在视点位置观察与视点相适应的三维模型景观。
在整个三维模型的观察过程中,投影变换的类型决定观察三维模型的观察方式,不同的投影变换得到的三维模型的景象也是不同的。
最后的视窗变换则对模型的景象进行裁剪缩放,即决定整个三维模型在屏幕上的图象。
3.颜色模式的指定
OpenGL应用了一些专门的函数来指定三维模型的颜色。
程序开发者可以选择二个颜色模式,即RGBA模式和颜色表模式。
在RGBA模式中,颜色直接由RGB值来指定;在颜色表模式中,颜色值则由颜色表中的一个颜色索引值来指定。
开发者还可以选择平面着色和光滑着色二种着色方式对整个三维景观进行着色。
4.光照应用
用OpenGL绘制的三维模型必须加上光照才能更加与客观物体相似。
OpenGL提供了管理四种光(辐射光、环境光、镜面光和漫射光)的方法,另外还可以指定模型表面的反射特性。
5.图象效果增强
OpenGL提供了一系列的增强三维景观的图象效果的函数,这些函数通过反走样、混合和雾化来增强图象的效果。
反走样用于改善图象中线段图形的锯齿而更平滑,混合用于处理模型的半透明效果,雾使得影像从视点到远处逐渐褪色,更接近于真实。
6.位图和图象处理
OpenGL还提供了专门对位图和图象进行操作的函数。
7.纹理映射
三维景物因缺少景物的具体细节而显得不够真实,为了更加逼真地表现三维景物,OpenGL提供了纹理映射的功能。
OpenGL提供的一系列纹理映射函数使得开发者可以十分方便地把真实图象贴到景物的多边形上,从而可以在视窗内绘制逼真的三维景观。
8.实时动画
为了获得平滑的动画效果,需要先在内存中生成下一幅图象,然后把已经生成的图象从内存拷贝到屏幕上,这就是OpenGL的双缓存技术(doublebuffer)。
OpenGL提供了双缓存技术的一系列函数。
9.交互技术
目前有许多图形应用需要人机交互,OpenGL提供了方便的三维图形人机交互接口,用户可以选择修改三维景观中的物体。
1.2OpenGL的工作方式
1.2.1OpenGL的体系结构
OpenGL是一套图形标准,它严格按照计算机图形学原理设计而成,符合光学和视觉原理,非常适合可视化仿真系统。
由于OpenGL是一种API,其中不包含任何窗口管理、用户交互或文件I/O函数。
每个主机环境(如MicrosoftWindows)在这些方面都有自己的函数,由这些函数负责实现某些方法,以便把窗口或位图的绘制控制权移交给OpenGL。
通常,一个完整的窗口系统的OpenGL图形处理系统的结构如图1.1所示:
最底层为图形硬件,第二层为操作系统,第三层为窗口系统,第四层为OpenGL,最上面的层为应用软件。
图1.1OpenGL图形处理系统的层次结构
OpenGL在WindowsNT上的实现是基于客户机/服务器模式的,应用程序发出OpenGL命令,由动态链接库OpenGL32.DLL接受和打包后,发送到服务器端的WINSRV.DLL,然后由它通过DDI(DeviceDriverInterface,设备驱动程序接口)层发往视频显示驱动程序。
如果系统安装了硬件加速器,则由硬件相关的DDI来处理。
OpenGL/NT的体系结构图如图1.2所示。
图1.2OpenGL/NT体系结构
1.2.2OpenGL的流水线
当应用程序进行OpenGLAPI函数调用的时候,OpenGL命令将被放在一个命令缓冲区中,这样,命令缓冲区中包含了大量的命令、顶点数据和纹理数据。
当这个缓冲区被清空时,缓冲区中的命令和数据都将传递给流水线的下一个阶段,或者说,只有当命令缓冲区被清空时,OpenGL命令才会被执行。
图1.3显示了一条简化版的OpenGL流水线。
图1.3一条简化版的OpenGL流水线
在OpenGL中,命令缓冲区中的几何顶点数据通常还要进行几何变换以及光照计算,并通过指定的方法进行投影,为下一步光栅化做准备。
光栅化根据图形的几何形状、颜色和纹理数据产生一系列图像的帧缓存地址和图元的二维描述值,光栅化的结果最后被放置在帧缓存中。
帧缓存是图形显示设备的内存,这样图像就显示在屏幕上了。
1.2.3OpenGL状态机
OpenGL是一种直接模式的API,每条命令根据当前的渲染状态都会产生某种立即效果。
渲染状态是各种标记,他们指出哪些特性是打开的,哪些是关闭的,以及应该如何应用他们。
在OpenGL中,使用glEnable函数和glDisable函数来启用和禁用渲染特征。
1.3OpenGL的操作步骤
在OpenGL中进行的图形操作直至在计算机屏幕上渲染绘制出三维图形景观的基本步骤如下:
1.根据基本图形单元建立景物模型,得到景物模型的数学描述(OpenGL中把点、线、多边形、图像和位图都作为基本图形单元);
2.把景物模型放在三维空间中的合适的位置,并且设置视点(Viewpoint)以观察所感兴趣的景观;
3.计算模型中所有物体的色彩,同时确定光照条件、纹理粘贴方式等;
4.把景物模型的数学描述及其色彩信息转换至计算机屏幕上的像素,这个过程也就是光栅化(rasterization)。
在这些步骤的执行过程中,OpenGL可能执行其他的一些操作,例如自动消隐处理等。
另外,景物光栅化之后被送入帧缓冲器之前还可以根据需要对象素数据进行操作。
1.4OpenGL的组成
OpenGL不是一种编程语言,而是一种API(应用程序编程接口),它实际上是一种图形与硬件的接口,包括了多个图形函数。
OpenGL主要由以下函数库组成。
1.OpenGL核心库
OpenGL核心库中包含了115个最基本的命令函数,它们都是以“gl”为前缀,可以在任何OpenGL的工作平台上应用。
这部分函数用于常规的、核心的图形处理,如建立各种各样的几何模型,产生光照效果,进行反走样以及进行纹理映射,以及进行投影变换等等。
由于许多函数可以接收不同数据类型的参数,因此派生出来的函数原形有300多个。
2.OpenGL实用程序库
OpenGL的实用程序库包含有43个函数,以“glu”为前缀,在任何OpenGL平台都可以应用。
这部分函数通过调用核心库的函数,来实现一些较为复杂的操作,如纹理映射、坐标变换、网格化、曲线曲面以及二次物体(圆柱、球体等)绘制等。
3.OpenGL编程辅助库
OpenGL的辅助库包含31个函数,以“aux”为前缀,但它们不能在所有的OpenGL平台上使用。
OpenGL的辅助库的函数主要用于窗口管理、输入输出处理以及绘制一些简单的三维形体。
4.OpenGL实用程序工具包
OpenGL实用程序工具包(OpenGLutilitytoolkit,GLUT)包含30多个函数,函数名前缀是“glut”。
其中的函数主要提供基于窗口的工具,如窗口系统的初始化,多窗口管理,菜单管理,字体以及一些较复杂物体的绘制等。
由于glut库中的窗口管理函数是不依赖于运行环境的,因此OpenGL中的工具库可以在所有的OpenGL平台上运行,在后面的示例中,我们均使用glut库建立OpenGL程序运行框架。
5.Windows专用库
Windows专用库函数包含有6个,每个函数以wgl开头,用于连接OpenGL和WindowsNT,这些函数用于在WindowsNT环境下的OpenGL窗口能够进行渲染着色,在窗口内绘制位图字体以及把文本放在窗口的某一位置等这些函数把Windows和OpenGL揉合在一起。
6.Win32API函数库
这部分函数没有专用的前缀,主要用于处理像素存储格式和双帧缓存。
1.5OpenGL的数据类型
由于OpenGL具有平台无关性,它定义了自己的数据类型,这些数据类型将映射为常规的C数据类型,在程序中也可以直接使用这些C数据类型,下表列出了在OpenGL中定义的数据类型。
表1-1OpenGL变量类型和相应的C数据类型
OpenGL数据类型
内部表示法
定义为C类型
C字面值后缀
GLbyte
8位整数
signedchar
b
GLshort
16位整数
short
s
GLint,GLsizei
32位整数
song
l
GLfloat,GLclampf
32位浮点数
float
f
GLdouble,GLclampd
64位浮点数
double
d
GLubyte,GLboolean
8位无符号整数
unsignedchar
ub
GLshort
16位无符号整数
unsignedshort
us
GLuint,GLenum,GLbitfield
32位无符号整数
unsignedlong
ui
1.6OpenGL函数命名约定
OpenGL函数都遵循一个命名约定,通过这个约定可以了解函数来源于哪个库,需要多少个参数以及参数的类型。
每一个函数都有一个根段,代表该函数相应的OpenGL命令。
所有的OpenGL函数都采用以下格式:
<库前缀><根命令><可选的参数个数><可选的参数类型>
例如函数glColor3f(…),gl表示这个函数来自库gl.h,color是该函数的根段,表示该函数用于颜色设定,3f表示这个函数采用了三个浮点数参数。
这种把参数数目和参数类型加入OpenGL函数结尾的约定使人们更容易记住参数列表而无需查找它。
1.7用OpenGL绘制图形
由于OpenGL是一种API,OpenGL库遵循C调用约定,这意味着在C语言中编写的程序可以很容易地调用API中的函数,本书的示例程序均以C语言编写。
下面的程序利用GLUT库,在窗口的中心位置绘制一个矩形,其输出如图1.4所示。
程序清单1.1:
在窗口内绘制一个矩形
//GLRect.c
#include
#include
#include
#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;
//设置视区尺寸
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);
else
glOrtho(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);
}
voidmain(void)
{
//初始化GLUT库OpenGL窗口的显示模式
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
//创建一个名为GLRect的窗口
glutCreateWindow("GLRect");
//设置当前窗口的显示回调函数和窗口再整形回调函数
glutDisplayFunc(RenderScene);
glutReshapeFunc(ChangeSize);
SetupRC();
//启动主GLUT事件处理循环
glutMainLoop();
}
图1.4GLRect程序运行结果
1.7.1库和头文件程序GLRect中包含了4个头文件,其中定义了程序所用的函数原形。
此外,OpenGL需要下列*.lib包含在你的工程中:
opengl.lib,glu.lib,glut32.lib;另外在运行程序路径下或\win98\system\(\winNT\system32)下需要一些动态连接库:
opengl32.dll,glu32.dll,glut32.dll。
1.7.2函数主体
我们先看所有C程序的入口点:
voidmain(void)
{
1.显示模式
第一行代码如下:
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
它告诉GLUT库在创建窗口时使用单缓冲区窗口(GLUT_SINGLE)并使用RGB颜色模式(GLUT_RGB)。
由于在屏幕上显示图形是由像素构成的,而像素的颜色及灰度信息都是存储在帧缓冲存储区中,单缓冲区窗口使用单一的帧缓冲存储区,这样所有的绘图命令都在显示窗口中执行;另一种是双缓冲区窗口(GLUT_DOUBLE),它使用了两个帧缓冲存储区,这样在窗口中执行的绘图命令实际上利用其中一个帧缓冲存储区创建一个场景,然后很快地交换到窗口视图中来,这种方法常用于产生动画效果的场合。
RGB颜色模式意味着要通过分别提供红、绿、蓝成分的浓度来指定颜色。
2.创建OpenGL窗口
下一行代码:
glutCreateWindow("GLRect");
它利用glut库中的窗口管理函数在屏幕上创建一个标题为“GLRect”的窗口。
3.回调函数
后面的两行代码
glutDisplayFunc(RenderScene);
glutReshapeFunc(ChangeSize);
分别用于指定当前窗口的显示回调函数和再整形回调函数。
回调函数是响应某种事件而被调用的函数,他由程序员编制,通过GLUT注册函数连接到特定的函数。
这样只要需要绘制窗口,GLUT就会调用函数RenderScene;而当窗口的大小或形状发生变化时,GLUT会调用函数ChangeSize。
4.设置上下文并执行
SetupRC()函数与GLUT框架无关,其作用是进行OpenGL的初始化。
OpenGL的初始化必须在渲染之前进行,由于OpenGL使用状态机,即每条OpenGL命令都使用当前的渲染状态完成,而对当前渲染状态的任何修改都会影响到之后的任何OpenGL命令,直至再次修改当前渲染状态,故此在一个场景中,许多的状态只要设置一次就可以了。
程序的结尾是最后一个GLUT函数调用:
glutMainLoop();
}
该函数让GLUT框架开始运行,所有设置的回调函数开始工作,直到用户终止程序为止。
1.7.3OpenGL图形的绘制
1.初始化
函数SetupRC主要用于初始化,其中只调用了一个函数
glClearColor(1.0f,1.0f,1.0f,1.0f);
这个函数用于设置清除窗口时使用的颜色,即设定窗口内的背景色。
在OpenGL中,一种颜色用红、绿、蓝成分的混合来表示,每种成分的值可以是0.0到1.0之间的任意有效浮点数,这样虽理论上可以产生无限多种颜色,但实际可输出的颜色是有限的。
这类似于Windows中使用RGB宏来创建COLORREF值时的颜色规范,不同的只是其中红、绿、蓝三种颜色成分的取值范围是0到255。
表1-2给出了一些常见的混合色。
表1-2一些常用的混合色
混合色
红色成分(R)
绿色成分(G)
蓝色成分(B)
黑
0.0
0.0
0.0
红
1.0
0.0
0.0
绿
0.0
1.0
0.0
黄
1.0
1.0
0.0
蓝
0.0
0.0
1.0
紫
1.0
0.0
1.0
青
0.0
1.0
1.0
深灰
0.25
0.25
0.25
浅灰
0.75
0.75
0.75
棕
0.60
0.40
0.12
南瓜橙
0.98
0.625
0.12
粉红
0.98
0.04
0.70
紫红
0.60
0.40
0.70
白
1.0
1.0
1.0
glClearColor的最后一个参数是alpha成分,主要用于混合的特殊效果,如半透明效果等。
2.再整形回调函数
窗口在物理上是以象素数来测量的。
开始在窗口中绘图之前,必须告诉OpenGL如何把指定的坐标对转换为屏幕坐标。
为此,先指定窗口在笛卡儿空间中占据的区域,这一区域在计算机图形学中称为“窗口”,这里为了与操作系统的窗口有所区别,我们称这一区域为“修剪区”。
而以象素计算的话,修剪区的宽度和高度很少会恰好与窗口的宽度和高度一致。
所以坐标系必须从逻辑笛卡儿坐标映射为物理屏幕的象素坐标。
这种映射是由称为“视区”的设置指定的。
视区是窗口的客户区内用于绘制修剪区的区域,即把修剪区映射为窗口的一个区域。
通常把视区定义充满整个窗口。
在程序1.1中,当窗口的大小改变,函数ChangeSize就会收到新的宽度和高度,在函数中利用这些信息可以完成修剪区到视区(坐标系到实际屏幕坐标)的映射。
(1)利用函数glViewport定义视区,glViewport函数的定义如下:
voidglViewport(GLintx,GLinty,GLsizeiwidth,Glsizeiheight);
x和y参数指定窗口内视区的左下角,width和height参数以象素为单位指定宽度和高度。
通常,x和y都是0,但是可以用视区来渲染窗口不同区域中的多幅图形。
(2)利用函数glOrtho定义修剪区。
这里需要注意一点,如果指定的视区不是正方形,而定义的修剪区是正方形,这样在完成修剪区到视区的映射后,显示的图形会发生变形,影响效果,为此必须保证定义的视区和修剪区的纵横比保持一致。
glOrtho函数的定义如下:
voidglOrtho(Gldoubleleft,Gldoubleright,Gldoublebottom,Gldoubletop,Gldoublenear,Gldoublefar);
该函数在3D笛卡儿坐标空间中定义了一个修剪空间,left和right指定x轴上显示的最小和最大坐标值;bottom和top则用于y轴;near和far参数用于z轴,通常是远离观察者的负值。
由于这个修剪空间要映射到视区,这种三维空间到二维的映射,需要利用投影来实现,这里使用的是正投影。
故此在调用函数glOrtho之前,调用了两个函数:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
这两个函数定义了投影矩阵,投影矩阵是实际定义视见空间的地方,而函数glOrtho并不是真正建立修剪空间,而是修改现有的修剪空间,它用描述了其参数中说明的修剪空间的矩阵乘以描述当前修剪空间的矩阵,为了避免每次调用glOrtho时对修剪空间造成进一步的破坏,所以使用函数glLoadIdentity使坐标系“复位”。
函数ChangeSize的最后为:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
这两个函数告诉OpenGL将来所有变换都会影响模型。
3.显示回调函数
显示回调函数RenderScene是调用OpenGL渲染函数的地方。
(1)实际清除
我们在初始化时指定了蓝色为窗口清除色,此时需要调用函数
glClear(GL_COLOR_BUFFER_BIT);
执行实际的清除操作。
一幅图像的红、绿、蓝成分通常被并称为颜色缓冲区或象素缓冲区,用glClear清除颜色缓冲区会清除窗口中所有图形,并用指定的清除色填充整个窗口。
(2)指定当前绘图颜色
函数glColor3f(1.0f,0.0f,0.0f)用于设置当前绘图颜色,即调用glColor3f设置以后,绘制操作(包括画线和填充)所用的颜色均为设置的当前颜色。
(3)图形绘制
这里我们使用函数
glRectf(100.0f,150.0f,150.0f,100.0f);
来绘制一个矩形,该函数的四个参数表示矩形左上角点和右下角点的坐标。
(4)刷新队列
函数glFlush()用于让所有尚未执行的OpenGL命令都被执行。
在内部,OpenGL使用一条渲染流水线来顺序处理命令。
OpenGL命令和语言通常要排队,以便OpenGL驱动程序一次处理若干条“请求”。
这种设置能提高性能,特别是在构造复杂对象的时候。
GlFlush函数只是告诉OpenGL,它应处理到目前为止收到的绘图指令,而不要再等待更多的绘图命令。
由上面的程序可以看出,一个OpenGL程序的基本结构主要包括以下几个部分:
(1)定义窗口:
包括指定窗口的大小、位置、显示模式以及设置各种回调函数;
(2)初始化设置:
清除各种缓冲区,并设置各种OpenGL状态,例如设置背景色,打开光照,设置纹理等等。
(3)绘制场景:
利用OpenGL函数绘制场景中的各种物体。
(4)变换:
指定场景中需要显示的范围并指定由修剪区到视区的变换。
(5)结束运行:
清除命令缓冲区
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- OpenGL 上机 练习