《计算机图形学》课程实验指导1课件.docx

上传人:b****6 文档编号:7305627 上传时间:2023-01-22 格式:DOCX 页数:35 大小:963.52KB
下载 相关 举报
《计算机图形学》课程实验指导1课件.docx_第1页
第1页 / 共35页
《计算机图形学》课程实验指导1课件.docx_第2页
第2页 / 共35页
《计算机图形学》课程实验指导1课件.docx_第3页
第3页 / 共35页
《计算机图形学》课程实验指导1课件.docx_第4页
第4页 / 共35页
《计算机图形学》课程实验指导1课件.docx_第5页
第5页 / 共35页
点击查看更多>>
下载资源
资源描述

《计算机图形学》课程实验指导1课件.docx

《《计算机图形学》课程实验指导1课件.docx》由会员分享,可在线阅读,更多相关《《计算机图形学》课程实验指导1课件.docx(35页珍藏版)》请在冰豆网上搜索。

《计算机图形学》课程实验指导1课件.docx

《计算机图形学》课程实验指导1课件

《计算机图形学》 课程实验指导

一. 实验总体方案 

1.教学目标与基本要求 

(1) 掌握教材所介绍的图形算法的原理; 

(2) 掌握通过具体的平台实现图形算法的方法,培养相应能力;  

(3) 通过实验培养具有开发一个基本图形软件包的能力。

 

2. 实验平台与考核 

实验主要结合OpenGL设计程序实现各种课堂教学中讲过的图形算法为主。

程序设计语言主要以C/C++语言为主,开发平台为Visual C++。

每次实验前完成实验报告的实验目的、实验内容、实验原理、实验代码四部分并接受抽查,实验完成后完成实验结果、实验体会两部分,本次实验课结束前提交。

 

3. 实验步骤 

(1) 预习教材与实验指导相关的算法理论及原理;

(2) 仿照教材与实验指导提供的算法,利用VC+OpenGL进行实现; 

(3) 调试、编译、运行程序,运行通过后,可考虑对程序进行修改或改进。

 

二. 实验具体方案 

实验预备知识 

OpenGL作为当前主流的图形API之一,它在一些场合具有比DirectX更优越的特性。

 1)与C语言紧密结合:

 

OpenGL命令最初就是用C语言函数来进行描述的,对于学习过C语言的人来讲,OpenGL是容易理解和学习的。

如果你曾经接触过TC的graphics.h,你会发现,使用OpenGL作图甚至比TC更加简单; 

2)强大的可移植性:

 

微软的Direct3D虽然也是十分优秀的图形API,但它只用于Windows系统。

而OpenGL不仅用于 Windows,还可以用于Unix/Linux等其它系统,它甚至在大型计算机、各种专业计算机(如:

医疗用显示设备)上都有应用。

并且,OpenGL 的基本命令都做到了硬件无关,甚至是平台无关; 

3)高性能的图形渲染:

 

OpenGL是一个工业标准,它的技术紧跟时代,现今各个显卡厂家无一不对OpenGL提供强力支持,激烈的竞争中使得OpenGL性能一直领先。

总之,OpenGL是一个非常优秀的图形软件接口。

OpenGL官方网站(英文)http:

//www.opengl.org 

下面将对Windows下的OpenGL编程进行简单介绍。

如下是学习OpenGL前的准备工作:

 

1.选择一个编译环境 

现在Windows系统的主流编译环境有Visual C++,C++ Builder,Dev-C++等,它们都是支持OpenGL的。

但这里我们选择Visual C++ 作为学习OpenGL的实验环境。

 

2.安装GLUT工具包 

GLUT不是OpenGL所必须的,但它会给我们的学习带来一定的方便,推荐安装。

Windows环境下的GLUT下载地址:

(大小约为150k) 

http:

//www.opengl.org/resources/libraries/glut/glutdlls37beta.zip 

Windows环境下安装GLUT的步骤:

 

1)将下载的压缩包解开,将得到5个文件 

2)在“我的电脑”中搜索“gl.h”,并找到其所在文件夹(如果是VisualStudio2005,则应该是其安装目录下面的“VC\PlatformSDK\include\gl文件夹”)。

把解压得到的glut.h放到这个文件夹。

 

3)把解压得到的glut.lib和glut32.lib放到静态函数库所在文件夹(如果是VisualStudio2005,则应该是其安装目录下面的“VC\lib”文件夹)。

 

4)把解压得到的glut.dll和glut32.dll放到操作系统目录下面的system32文件夹内。

(典型的位置为:

C:

\Windows\System32)

3.建立一个OpenGL工程 

这里以VC为例:

选择File->New->Project,然后选择Win32 Console Application,选择一个名字,然后按OK。

在谈出的对话框左边点Application Settings,找到Empty project并勾上,选择Finish。

然后向该工程添加一个代码文件,取名为“OpenGL.cpp”。

 

实验1 像素点的生成

1.实验目的:

 

熟悉编程环境;了解光栅图形显示器的特点;了解计算机绘图的特点;利用VC+OpenGL作为开发平台设计程序,以能够在屏幕上生成任意一个像素点为本实验的结束。

 

2.实验内容:

 

(1) 了解和使用VC的开发环境,理解简单的OpenGL程序结构。

 

(2) 掌握OpenGL提供的基本图形函数,尤其是生成点的函数。

 3.实验原理:

 

(1)基本语法 

常用的程序设计语言,如C、C++、Pascal、Fortran和Java等,都支持OpenGL的开发。

这里只讨论C版本下OpenGL的语法。

OpenGL基本函数均使用gl作为函数名的前缀,如glClearColor();实用函数则使用glu作为函数名的前缀,如gluSphere()。

OpenGL基本常量的名字以GL_开头,如GL_LINE_LOOP;实用常量的名字以GLU_开头,如GLU_FILL。

一些函数如glColor*()(定义颜色值),函数名后可以接不同的后缀以支持不同的数据类型和格式。

如glColor3b(...)、glColor3d(...)、glColor3f(...)和glColor3bv(...)等,这几个函数在功能上是相似的,只是适用于不同的数据类型和格式,其中3表示该函数带有三个参数,b、d、f分别表示参数的类型是字节型、双精度浮点型和单精度浮点型,v则表示这些参数是以向量形式出现的。

 

OpenGL定义了一些特殊标识符,如GLfloat,GLvoid。

它们其实就是C中的float和void。

在gl.h文件中可以看到以下定义:

 

…… 

typedef float GLfloat; typedef void GLvoid; …… 

一些基本的数据类型都有类似的定义项。

 

(2)程序的基本结构 

OpenGL程序的基本结构可分为三个部分:

 

第一部分是初始化部分。

主要是设置一些OpenGL的状态开关,如颜色模式(RGBA或ALPHA)的选择,是否作光照处理(若有的话,还需设置光源的特性),深度检验,裁剪等等。

这些状态一般都用函数glEnable(...), glDisable(…)来设置,…表示特定的状态。

 

第二部分设置观察坐标系下的取景模式和取景框位置大小。

主要利用了三个函数:

 函数void glViewport(left,top,right,bottom):

设置在屏幕上的窗口大小,四个参数描述屏幕窗口四个角上的坐标(以象素表示)

函数void glOrtho(left,right,bottom,top,near,far):

设置投影方式为正交投影(平行投影),其取景体积是一个各面均为矩形的六面体; 

函数void gluPerspective(fovy,aspect,zNear,zFar):

设置投影方式为透视投影,其取景体积是一个截头锥体。

 

第三部分是OpenGL的主要部分,使用OpenGL的库函数构造几何物体对象的数学描述,包括点线面的位置和拓扑关系、几何变换、光照处理等等。

 

以上三个部分是OpenGL程序的基本框架,即使移植到使用MFC的Windows程序中,也是如此。

只是由于Windows自身有一套显示方式,需要进行一些必要的改动以协调这两种不同显示方式。

 

(3)状态机制 

OpenGL的工作方式是一种状态机制,它可以进行各种状态或模式设置,这些状态或模式在重新改变它们之前一直有效。

例如,当前颜色就是一个状态变量,在这个状态改变之前,绘制的每个象素都将使用该颜色,直到当前颜色被设置为其它颜色为止。

OpenGL中大量地使用了这种状态机制,如颜色模式、投影模式、单双显示缓存区的设置、背景色的设置、光源的位置和特性等等。

许多状态变量可以通过glEnable()、glDisable()这两个函数来设置成有效或无效状态,如是否设置光照、是否进行深度检测等;在被设置成有效状态之后,绝大部分状态变量都有一个缺省值。

通常情况下,可以用下列四个函数来获取某个状态变量的值:

glGetBooleanv()、glGetDouble()、glGetFloatv()和glGetIntegerv()。

究竟选择哪个函数应该根据所要获得的返回值的数据类型来决定。

还有些状态变量有特殊的查询函数,如glGetLight*()、glGetError()和glPolygonStipple()等。

另外,使用glPushAttrib()和glPopAttrib()

函数,可以存储和恢复最近的状态变量的值。

只要有可能,都应该使用这些函数,因为它们比其它查询函数的效率更高。

 

4.实验代码:

 

一个简单的OpenGL程序如下:

(注意,如果需要编译并运行,需要正确安装GLUT,安装方法如预备知识中所述) 

该程序的作用是在一个黑色的窗口中央画一个矩形、三角形和三个点。

下面对各行语句进行说明:

 

首先,需要包含头文件#include ,这是GLUT的头文件。

本来OpenGL程序一般还要包含,但GLUT的头文件中已经自动将这两个文件包含了,不必再次包含; 

然后看main函数。

int main(int argc, char *argv[]),这个是带命令行参数的main函数。

注意main函数中的各语句,除了最后的return之外,其余全部以glut开头。

这种以glut开头的函数都是GLUT工具包所提供的函数,下面对用到的几个函数进行介绍; 

1)glutInit,对GLUT进行初始化,这个函数必须在其它的GLUT使用之前调用一次。

其格式比较固定,一般都是glutInit(&argc, argv)就行; 

2) glutInitDisplayMode,设置显示方式,其中GLUT_RGB表示使用RGB颜色,与之对应的还有GLUT_INDEX(表示使用索引颜色)。

GLUT_SINGLE表示使用单缓冲,与之对应的还有GLUT_DOUBLE(使用双缓冲)。

更多信息,以后的实验教程会有讲解介绍; 

3) glutInitWindowPosition,设置窗口在屏幕中的位置;

4) glutInitWindowSize,设置窗口的大小; 

5) glutCreateWindow,根据前述设置的信息创建窗口。

参数将被作为窗口的标题。

注意:

窗口被创建后,并不立即显示到屏幕上。

需要调用glutMainLoop才能看到窗口; 

6) glutDisplayFunc,设置一个函数,当需要进行画图时,这个函数就会被调用。

(暂且这样理解); 

7) glutMainLoop,进行一个消息循环。

(现在只需知道这个函数可以显示窗口,并且等待窗口关闭后才会返回。

) 

在glutDisplayFunc函数中,我们设置了“当需要画图时,请调用myDisplay函数”。

于是myDisplay函数就用来画图。

观察myDisplay中的三个函数调用,发现它们都以gl开头。

这种以gl开头的函数都是OpenGL的标准函数,下面对用到的函数进行介绍:

 

1) glClearColor(0.0, 0.0, 0.0, 0.0) :

将清空颜色设为黑色(为什么会有四个参数?

);

2) glClear(GL_COLOR_BUFFER_BIT):

将窗口的背景设置为当前清空颜色; 

3) glRectf,画一个矩形。

四个参数分别表示了位于对角线上的两个点的横、纵坐标;

4) glFlush,保证前面的OpenGL命令立即执行(而不是让它们在缓冲区中等待)。

 

5. 思考题 

如图所示,根据示范程序,能否在原有结果基础上添加三条直线组成三角形?

实验2 直线生成算法的实现

1.实验目的:

 

理解基本图形元素光栅化的基本原理,掌握一种基本图形元素光栅化算法,利用OpenGL实现直线光栅化的DDA算法。

 

2.实验内容:

 

(1) 根据所给的直线光栅化的示范源程序,在计算机上编译运行,输出正确结果; 

(2) 指出示范程序采用的算法,以此为基础将其改造为中点线算法或Bresenham算法,写入实验报告; 

(3) 根据示范代码,将其改造为圆的光栅化算法,写入实验报告; 

(4) 了解和使用OpenGL的生成直线的命令,来验证程序运行结果。

 

3.实验原理:

 

示范代码原理参见教材直线光栅化一节中的DDA算法。

下面介绍下OpenGL画线的一些基础知识和glutReshapeFunc()函数。

 

(1)数学上的直线没有宽度,但OpenGL的直线则是有宽度的。

同时,OpenGL的直线必须是有限长度,而不是像数学概念那样是无限的。

可以认为,OpenGL的“直线”概念与数学上的“线段”接近,它可以由两个端点来确定。

这里的线由一系列顶点顺次连结而成,有闭合和不闭合两种。

 

前面的实验已经知道如何绘“点”,那么OpenGL是如何知道拿这些顶点来做什么呢?

是一个一个的画出来,还是连成线?

或者构成一个多边形?

或是做其它事情呢?

为了解决这一问题,OpenGL要求:

指定顶点的命令必须包含在glBegin函数之后,glEnd函数之前(否则指定的顶点将被忽略),并由glBegin来指明如何使用这些点。

 

例如:

 

glBegin(GL_POINTS);    

glVertex2f(0.0f, 0.0f);     

glVertex2f(0.5f, 0.0f); 

glEnd(); 

则这两个点将分别被画出来。

如果将GL_POINTS替换成GL_LINES,则两个点将被认为是直线的两个端点,OpenGL将会画出一条直线。

还可以指定更多的顶点,然后画出更复杂的图形。

另一方面,glBegin支持的方式除了GL_POINTS和GL_LINES,还有GL_LINE_STRIP,GL_LINE_LOOP,GL_TRIANGLES,GL_TRIANGLE_STRIP,GL_TRIANGLE_FAN等,每种方式的大致效果见下图:

(2)首次打开窗口、移动窗口和改变窗口大小时,窗口系统都将发送一个事件,以通知程序员。

如果使用的是GLUT,通知将自动完成,并调用向glutReshapeFunc()注册的函数。

该函数必须完成下列工作:

 

●重新建立用作新渲染画布的矩形区域; Ÿ 

●定义绘制物体时使用的坐标系。

 

如:

 

在GLUT内部,将给该函数传递两个参数:

窗口被移动或修改大小后的宽度和高度,单位为像素。

glViewport()调整像素矩形,用于绘制整个窗口。

接下来三个函数调整绘图坐标系,使左下角位置为(0, 0),右上角为(w, h)。

 

4.实验代码:

注:

 glShadeModel选择平坦或光滑渐变模式。

GL_SMOOTH为缺省值,为光滑渐变模式,GL_FLAT为平坦渐变模式。

 

5.思考题 

示范代码有个小错误,能否指出并改正?

请将结果写入实验报告。

实验3 变换

1.实验目的:

 

进一步掌握二维、三维变换的数学知识、变换原理、变换种类、变换方法;进一步理解采用齐次坐标进行二维、三维变换的必要性;利用OpenGL实现二维、三维图形变换。

 

2.实验内容:

 

(1) 掌握二维、三维变换的原理及数学公式; 

(2) 利用OpenGL实现二维、三维图形变换,在屏幕上显示变换过程或变换结果。

(3) 掌握OpenGL常用的变换函数。

 

3.实验原理:

 

OpenGL的三个基本几何变换函数介绍如下:

(1)平移变换 

平移变换函数如下:

 

void  glTranslate{fd}(TYPE x,TYPE y,TYPE z); 

三个函数参数就是目标分别沿三个轴向平移的偏移量。

这个函数表示用这三个偏移量生成的矩阵乘以当前矩阵。

当参数是(0.0,0.0,0.0)时,表示对函数glTranslate*()的操作是单位矩阵,也就是对物体没有影响。

 

(2) 旋转变换

旋转变换函数如下:

 

void  glRotate{fd}(TYPE angle,TYPE x,TYPE y,TYPE z); 

函数中第一个参数是表示目标沿从点(x,y,z)到原点的方向逆时针旋转的角度,后三个参数是旋转的方向点坐标。

这个函数表示用这四个参数生成的矩阵乘以当前矩阵。

当角度参数是0.0时,表示对物体没有影响。

 

(3) 比例变换

比例变换函数如下:

 

void  glScale{fd}(TYPE x,TYPE y,TYPE z); 

三个函数参数值就是目标分别沿三个轴向缩放的比例因子。

这个函数表示用这三个比例因子生成的矩阵乘以当前矩阵。

这个函数能完成沿相应的轴对目标进行拉伸、压缩和反射三项功能。

当参数是(1.0,1.0,1.0)时,表示对函数glScale*()操作是单位矩阵,也就是对物体没有影响。

当其中某个参数为负值时,表示将对目标进行相应轴的反射变换,且这个参数不为1.0,则还要进行相应轴的缩放变换。

最好不要令三个参数值都为零,这将导致目标沿三轴都缩为零。

 

4.实验代码:

这个程序需要注意的地方有几点。

 

使用了双缓存模式,程序在空闲时一直不停的调用display函数,这个函数绘制完图像后,改变旋转的角度,然后交换双缓存,这样,每画完一帧就交换,形成了动画。

 

另外,使用了深度缓存,激活了深度测试,这样,被遮挡的面就不会显示,大家可以把激活深度缓存的一行去掉看看效果。

大家还可以改变变换的方式,达到不同的效果。

实验4 裁剪

1.实验目的:

 

了解二维图形裁剪的原理(点的裁剪、直线的裁剪、多边形的裁剪),利用VC+OpenGL实现直线的裁剪算法。

 

2.实验内容:

 

(1) 理解直线裁剪的原理(Cohen-Surtherland算法、梁友栋算法) 

(2) 利用VC+OpenGL实现直线的编码裁剪算法,在屏幕上用一个封闭矩形裁剪任意一条直线。

 

(3) 调试、编译、修改程序。

 

(4) 尝试实现梁友栋裁剪算法。

 3.实验原理:

 

编码裁剪算法的主要思想是:

对于每条线段,分为三种情况处理。

(1)若线段完全在窗口之内,则显示该线段,称为“取”;

(2)若线段明显在窗口之外,则丢弃该线段,称为“弃”;(3)若线段既不满足“取”的条件,也不满足“舍”的条件,则把线段分割为两段。

其中一段完全在窗口之外,可弃之;对另一段则重复上述处理。

 

算法中,为了快速判断一条直线段与矩形窗口的位置关系,采用了如图所示的空间划分和编码方案。

延长窗口的四条边界,把未经裁剪的图形区域分为九个区,每个区有一个四位二进制的编码,从左到右各位依次表示上、下、右、左。

例如,区号0101,左起第二位1表示该区在窗口的下方;右起第一位的1表示该区在窗口的左方。

整个区号表示该区在窗口的左下方。

裁剪一条线段时,先求出两端点所在的区号code1和code2,若code1 = 0且code2 = 0,则说明线段的两个端点均在窗口内,那么整条线段必在窗口内,应取之;若code1和code2经按位与运算的结果不为0,则说明两个端点同在窗口的上方、下方、左方或右方。

这种情况下,对线段的处理是弃之。

如果上述两种条件都不成立,则按第三种情况处理。

求出线段与窗口某边的交点,在交点处把线段一分为二,其中必有一段完全在窗口外,可弃之,对另一段则重复上述处理。

 

4.实验代码:

5.实验思考题 

请分别给出直线的三种不同位置情况,测试实验代码是否存在问题,有的话请调试改正。

可能的话,可以尝试实现梁友栋裁剪算法。

实验5 Bezier曲线

1.实验目的:

 

了解曲线的生成原理,掌握几种常见的曲线生成算法,利用VC+OpenGL实现Bezier曲线生成算法。

 

2.实验内容:

 

(1) 结合示范代码了解曲线生成原理与算法实现,尤其是Bezier曲线; 

(2) 调试、编译、修改示范程序。

 3.实验原理:

 

Bezier曲线是通过一组多边形折线的顶点来定义的。

如果折线的顶点固定不变,则由其定义的Bezier曲线是唯一的。

在折线的各顶点中,只有第一点和最后一点在曲线上且作为曲线的起始处和终止处,其他的点用于控制曲线的形状及阶次。

曲线的形状趋向于多边形折线的形状,要修改曲线,只要修改折线的各顶点就可以了。

因此,多边形折线又称Bezier曲线的控制多边形,其顶点称为控制点。

 

三次多项式,有四个控制点,其数学表示如下:

其矩阵形式为 

4.实验代码:

5.实验思考题 

尝试实现B样条曲线算法。

实验6 简单光照明模型实现

1.实验目的:

 

了解简单光照明模型的基本原理,利用VC+OpenGL实现物体的真实感图形。

 

2.实验内容:

 

(1) 结合示范代码了解简单光照明模型的基本原理与实现; 

(2) 调试、编译、修改示范程序,给出不同光照系数,观察验证显示效果。

 

(3) 尝试实现圆锥体的光照效果。

 

3.实验原理:

Phong光照明模型是由物体表面上一点P反射到视点的光强I为环境光的反射光强Ie、理想漫反射光强Id、和镜面反射光Is的总和,即 

其中R,V,N为单位矢量;Ip为点光源发出的入射光强;Ia为环境光的漫反射光强;Ka环境光的漫反射系数;Kd漫反射系数

取决于表面的材料;Ks镜面反射系数

;n幂次,用以模拟反射光的空间分布,表面越光滑,n越大。

 

在用Phong模型进行真实感图形计算时,对物体表面上的每个点P,均需计算光线的反射方向R,再由V计算

为减少计算量,我们可以作如下假设:

a)光源在无穷远处,即光线方向L为常数;b)视点在无穷远处,即视线方向V为常数;c)用

近似

这里H为L和V的角平分向量,

在这种简化下,由于对所有的点总共只需计算一次H的值,节省了计算时间。

结合RGB颜色模型,Phong光照明模型最终有如下的形式:

本次实验中,光源在无穷远处,光线方向为单位向量L(0.5, 0.5, 0.707),视点在无穷远处,视线方向V为(0, 0, 1)。

4.实验代码:

5.实验思考题 

尝试绘制一个圆锥体的简单光照效果。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 语文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1