课程设计报告示例Word文件下载.docx
《课程设计报告示例Word文件下载.docx》由会员分享,可在线阅读,更多相关《课程设计报告示例Word文件下载.docx(19页珍藏版)》请在冰豆网上搜索。
后者被定义为光度中分配给主导或纯正颜色部分的百分比。
三基色理论在光学中属于最基本的理论知识,假定S代表某一给定光,即引起颜色感觉的外界刺激。
我们可以通过按适当比例将来自三种颜色(三原色)的光源的光混合在一起来取得S的效果(也就是看到S的观察者的颜色感觉):
S=r·
红+g·
绿+b·
蓝
换句话说,对于观察者来说,给定光和来自三原色光源的成比例的混合光看起来完全一样。
理论上只要三种颜色中没有任何一种可以用另外两种的线性组合来表示,也就是说没有任何一种的视觉效果可以通过另外两种的线性混合来获得,这三种颜色就构成一组三原色。
材料对光的红、绿、蓝三原色的反射率来近似定义材料的颜色。
象光源一样,材料颜色也分成环境、漫反射和镜面反射成分,它们决定了材料对环境光、漫反射光和镜面反射光的反射程度。
在进行光照计算时,材料对环境光的反射率与每个进入光源的环境光结合,对漫反射光的反射率与每个进入光源的漫反射光结合,对镜面光的反射率与每个进入光源的镜面反射光结合。
对环境光与漫反射光的反射程度决定了材料的颜色,并且它们很相似。
对镜面反射光的反射率通常是白色或灰色(即对镜面反射光中红、绿、蓝的反射率相同)。
镜面反射高光最亮的地方将变成具有光源镜面光强度的颜色。
例如一个光亮的红色塑料球,球的大部分表现为红色,光亮的高光将是白色的。
在材质RGB值和光源RGB值的关系中材质的颜色与光源的颜色有些不同。
对于光源,R、G、B值等于R、G、B对其最大强度的百分比。
若光源颜色的R、G、B值都是1.0,则是最强的白光;
若值变为0.5,颜色仍为白色,但强度为原来的一半,于是表现为灰色;
若R=G=1.0,B=0.0,则光源为黄色。
对于材质,R、G、B值为材质对光的R、G、B成分的反射率。
比如,一种材质的R=1.0、G=0.5、B=0.0,则材质反射全部的红色成分,一半的绿色成分,不反射蓝色成分。
也就是说,若光源颜色为(LR、LG、LB),材质颜色为(MR、MG、MB),那么,在忽略所有其他反射效果的情况下,最终到达眼睛的光的颜色为(LR*MR、LG*MG、LB*MB)。
同样,如果有两束光,相应的值分别为(R1、G1、B1)和(R2、G2、B2),则OpenGL将各个颜色成分相加,得到(R1+R2、G1+G2、B1+B2),若任一成分的和值大于1(超出了设备所能显示的亮度)则约简到1.0。
在实际应用的许多情况下,不同的物体或同一物体的不同部分都有可能设置不同的材质,OpenGL函数库提供了两种方式实现这种要求。
1.1
物体材料的选择
系统的光照与着色功能主要是基于Phong模型与Gouraud着色法,制作三维立体图形过程中所需要的材质与光照就是首先要定义物体表面的材料特性,建立光源,选择光照与着色参数,然后再启动光照计算。
物体的前面和后面中的每一个都有许多个材料特性,一旦启动光照,系统所保持的当前材料特性就被用来决定表面的着色。
每个特性可以通过调用语句:
glMaterialfv(Glenum
face,Glenum
pname,TYPE
pvalue)
其默认值或当前值改为其他值。
其中Glenum
face是用来指明要作的改变应该对哪一面或两面生效,有GL_FRONT,GL_BACK或GL_FRONT_AND_BACK的符号常数;
Glenum
pname是用来指定要改变的材料特性的符号常数(见表1);
TYPE
pvalue是指向一个为该特性提供新值的GLfloat数组的指针。
表1
代表材料特性的符号常数
特性名称
默认值
备注
GL_AMBIENT
(0.2,0.2,0.2,1.0)
环境光
GL_DIFFUSE
(0.8,0.8,0.8,1.0)
漫反射
GL_AMBIENT_AND_DIFFUSE
环境光、漫反射
GL_SPECULAR
(0,0,0,0.1)
GL_SHININESS
(0)
GL_EMISSION
设计中对三维图形在材质和光照上的选择是有要求,如果采用不同的角度去观察,会发现图形的表面颜色鲜艳程度与光照亮度成正比。
如用计算机来实现的图形视觉与现实中的图形相近,指定一个物体材料特性比较难完成的。
所以为了使设计出来的三维立体图形呈现出来的更加逼真,因此,采用三个不同的位置不同的材料特性从分别从正面、背面和两面三种情况进行设置。
1.2
光源建立及启动
在简单光照模型中的几种光分为:
辐射光(Emitted
Light)、环境光(Ambient
Light)、漫射光(Diffuse
Light)、镜面光(Specular
Light)。
辐射光是最简单的一种光,它直接从物体发出并且不受任何光源影响。
环境光是由光源发出经环境多次散射而无法确定其方向的光,即似乎来自所有方向。
当环境光照到曲面上时,它在各个方向上均等地发散(类似于无影灯光)。
漫射光来自一个方向,它垂直于物体时比倾斜时更明亮。
一旦它照射到物体上,则在各个方向上均匀地发散出去。
镜面光来自特定方向并沿另一方向反射出去,一个平行激光束在高质量的镜面上产生100%的镜面反射。
因此,从某种意义上讲,物体的反射程度等同于其上的光强(或光亮度)。
设计中允许应用程序使用多达八个光源,每个光源都由一组特性定义,包括它的位置。
这G光源定名为GL_LIGHT0,GL_LIGHT1,…,GL_LIGHT7。
应用程序可以通过调用语句:
glLightfv(GLenum
light,GLenum
pname,TYPE*p)
来设置指定光源的指定特性。
其中GLenum
light用来指定光源的符号常数,如GL_LIGHT0;
GLenum
pname指定要改变的特性的符号常数,如GL_AMBIENT;
TYPE*p是指向一个为该特性提供新值的GLfloat数组的指针。
在调用glLightfv来设置光源的位置或方向时,系统当前的建模与观察矩阵是要对代表该位置或方向的坐标值进行变换的,当灯源在不同的位置或方向时,就可以获得不同的视觉效果。
所以在这次设计工艺品茶壶的光源设置中,可以在整个场景中只设一个不动的光源,让物体与观察者的视角发生改变。
在光源建立的基础上可以通过下面两条语句来启动光照,通常条件下Opengl的默认设置是用当前的颜色来画当前的顶点,所以如果要启动当前光照那么就要通过下列语句来启用:
glEnable(GL_LIGHTING);
另外,每个光源都要在建立之后再经过启动才能用在光照计算中。
下列语句启动GL_LIGHT0:
glEnable(GL_LIGHT0);
要终止光照或停止使用某一特定光源,则需以相应的符号常数为参数调用glDisable。
二、项目需求
2.1几何变换的原理及设计
2.1.1几何变换的原理
计算机图形系统的基本功能之一是模拟在空间对物体进行操纵。
这种模拟的空间操纵称为变换。
可以从两种互补的观点出发来描述物体的变换。
第一种是物体本身相对于一个固定不动的坐标系或背景作变换。
此观点从数学角度讲就是对物体上的每一个点进行几何变换。
第二种观点将物体看成固定不动,而坐标系则相对于物体作变换。
这一效果可通过进行坐标变换来取得。
物体的空间操纵有三种基本形式。
第一,它们可以在不改变大小和朝向的前提下移动到新的位置。
第二,它们可以被放大和缩小。
第三,它们可以绕一个点或一条轴旋转。
但本论文设计中只应用了后两者几何变换。
在程序设计中,在缩放以及旋转几何变换时首先必须建立modelview的矩阵。
它是和来进行建模变换与观察变换的合成变换矩阵。
这个建模与观察矩阵的初始化可以通过以下语句完:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
其中glMatrixMode将建模与观察矩阵设为系统当前的矩阵,所有随后指定的变换都对当前的矩阵生效。
2.1.2几何变换—缩放
基本的缩放变换是相对于坐标系的原点来定义的,它用一组缩放因数乘以物体上的点的坐标(每个因数乘以与其对应的坐标)来取得缩放效果。
图1表示以Sx为坐标x的缩放因数,Sy为y坐标的缩放因数的二维几何缩放变换S(Sx,Sy):
如果Sx=Sy,该变换就称为均匀缩放,它能保持物体形状不变。
图1二维缩放(几何变换)
但由于缩放是相对于坐标系的原点进行的,缩放后物体在位置上也有所移动。
我们可以用定点缩放来对物体的位移现象加以控制:
相对于物体上的一个参考点进行缩放,进而使得该参考点在缩放变换后仍然留在它的原始位置上。
定点缩放可以分三步进行:
首先对物体作平移变换以将参考点(Xc,Yc)移到坐标系的原点,然后对平移后的物体作相对于原点(此时也就是参考点)的缩放变化,最后对缩放后的物体作平移变换以将参考点移回到它的原始位置(见图2)。
整个变换序列可以用函数合成的形式来表达:
T(Xc,Yc)·
S(Sx,Sy)·
T(-Xc,-Yc)。
图2二维定点缩放
在二维缩放的基础上,增加一个独立的第三维并可以类似方式处理来定义三维几何缩放S(Sx,Sy,Sz)以及与其互补的三维坐标缩放S′(1/Sx,1/Sy,1/Sz)。
如果Sx=Sy=Sz,该变换就称为均匀变换。
计算(x′,y′,z′)的公式为:
缩放功能的设计可以通过调用glScale*语句来实现:
voidglScale{fd}(TYPESx,TYPESy,TYPESz)
其中函数三个参数Sx,Sy,Sz分别为物体在x,y,z三个方向上缩放的比例。
2.1.3几何变换—旋转
图3二维旋转(几何变换)
平面上的旋转是相对于一个点(旋转中心)来进行的,而空间中的旋转则是相对于一条轴来完成。
我们将基本的两维旋转定义为绕xy坐标系的原点进行。
图3表示位于(x,y)的点经过大小为
角的两维几何旋转R(
)后的新位置(x′,y′)。
首先考虑斜边连接原点及(x′,y′)的直角三角形并使用三角恒等式来得到:
然后从斜边连接原点及(x,y)的另一个直角三角形得到x=rcos
和y=rsin
。
将此结果代入上式就有:
在二维旋转的基础上,来实现三维旋转。
三维旋转有三种基本方式:
绕z轴旋转(见图4(a)和5(a)),绕x轴旋转(见图4(b)和5(b)),绕y轴旋转(见图4(c)和5(c))。
与正旋转角在二维旋转中意味着反时针旋转的规定一致,正旋转角在三维旋转中意味着旋转方向按右手定则确定(拇指与旋转轴指向相同时,其余四指给出旋转方向)。
图4三维旋转(几何变换)
图5三维旋转(几何变换)
绕y轴旋转时(既包括几何变换Ry(
)也包括与其互补的坐标变换Ry′(-
))物体上的点的y坐标保持不变。
这就是说每个点可以看成是一个与xz平面平行的平面上旋转——旋转方式与一个在xz平面上的点完全相同。
于是我们可以得出三维旋转公式:
旋转变换可以通过调用glRotate*语句来实现:
voidglRotate{fd}(TYPEangle,TYPEx,TYPEy,TYPEz)
其中该函数有四个GLfloat或GLdouble类型的参数:
angle,x,y和z。
angle表示要旋转的角度,以度数方式表示,为0~360之间的值;
x,y,z构成一个向量,依次代表该向量x,y,z三个方向上的分量值,旋转是按反时针方向围绕从原点到(x,y,z)的轴进行。
在设计中单方面的对X轴、Y轴、Z轴中的某一轴定义旋转这样会使三维立体图在实现旋转时存在单一性和局限性,所以通过程序的编写对参数的改变使旋转可以通过任意轴旋转来完成,在设计中可以围绕一条经过某一点并与它的方向向量同向的轴线作为任意轴旋转。
2.2动画的设计
在本设计过程中为了达到艺术上的效果和最终在视觉上产生动态效果,达到以三维图像效果出现,通过运行程序所设计有三维立体图会自行按照Y轴旋转同时它的外形以及颜色也会发生改变,在人为的单击控制下可以在运行和停止之间相互切换,这样就实现了动画设计。
在编程模型设计中,用计时器方法来实现动画是非常简洁。
在编程环境下创建一个计时器,该计时器通知WM_TIMER消息隔多长时间给当前的窗口发送信息。
通过响应这个消息,就能够以一定的时间间隔完成所要完成的任务和达到最终想得到的效果。
处理计时器事件时,设置一个情况语句用来处理WM_TIMER消息,在该消息处理语句中,可以实现所要求的渲染,贴图等,也可以产生连续更新的图像。
下面就是实现动画的过程的语句:
glutPostRedisplay();
glutTimerFunc(200,timer,0);
在语句中glutTimerFunc(200,timer,0);
语句就是初始时注册一个定时器的回调函数。
glutPostRedisplay();
表示标记当前窗口需要重新绘制。
2.3纹理的设计
2.3.1纹理映射的原理
纹理映射是一项有助于获得比较真实感和多样化胡表面着色技术,在二维纹理图中对映射函数的一个常规制约是要使纹理图成比例地伸展和收缩。
可以写出:
U=As+Bv=Ct+D
其中的常数A,B,C和D由纹理空间和参数空间中的已知点之间的关系导出。
纹理图通常含有可以用来以不同方式改变物体表面的原始着色的颜色值。
然而其作用还可以扩展到提供其他种能够影响着色过程的结果的信息。
系统中实现纹理映射包括5个基本步骤:
(1)建立一个纹理并指定其纹理类型;
(2)指明该纹理的使用方式;
(3)为该纹理对象产生一张纹理图;
(4)启用纹理映射功能;
(5)通过为各顶点提供几何坐标以及纹理坐标来绘制接受映射的物体。
2.3.2纹理定义
(1)一维纹理定义的函数
voidglTexImage1D(GLenumtarget,GLintlevel,GLintcomponents,GLsizeiwidth,GLintborder,GLenumformat,GLenumtype,constGLvoid*pixels);
定义一个一维纹理映射。
其中参数target是常数GL_TEXTURE_1D。
参数level表示多级分辨率的纹理图像的级数,若只有一种分辨率,则level设为0。
参数components是一个从1到4的整数,指出选择了R、G、B、A中的哪些分量用于调整和混合,1表示选择了R分量,2表示选择了R和A两个分量,3表示选择了R、G、B三个分量,4表示选择了R、G、B、A四个分量。
参数width和height给出了纹理图像的长度和宽度,参数border为纹理边界宽度,它通常为0,width和height必须是2m+2b,这里m是整数,长和宽可以有不同的值,b是border的值。
纹理映射必须是使用64x64(若带边界为66x66),若width和height设置为0,则纹理映射有效地关闭。
参数format和type描述了纹理映射的格式和数据类型,它们在这里的意义与在函数glDrawPixels()中的意义相同,事实上,纹理数据与glDrawPixels()所用的数据有同样的格式。
参数format可以是GL_COLOR_INDEX、GL_RGB、GL_RGBA、GL_RED、GL_GREEN、GL_BLUE、GL_ALPHA、GL_LUMINANCE或GL_LUMINANCE_ALPHA(注意:
不能用GL_STENCIL_INDEX和GL_DEPTH_COMPONENT)。
类似地,参数type是GL_BYPE、GL_UNSIGNED_BYTE、GL_SHORT、GL_UNSIGNED_SHORT、GL_INT、GL_UNSIGNED_INT、GL_FLOAT或GL_BITMAP。
参数pixels包含了纹理图像数据,这个数据描述了纹理图像本身和它的边界。
(2)滤波
一般来说,纹理图像为正方形或长方形。
但当它映射到一个多边形或曲面上并变换到屏幕坐标时,纹理的单个纹素很少对应于屏幕图像上的象素。
根据所用变换和所用纹理映射,屏幕上单个象素可以对应于一个纹素的一小部分(即放大)或一大批纹素(即缩小)。
下面用函数glTexParameter*()说明放大和缩小的方法:
glTexParameter*(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameter*(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
实际上,第一个参数可以是GL_TEXTURE_1D或GL_TEXTURE_2D,即表明所用的纹理是一维的还是二维的;
第二个参数指定滤波方法,其中参数值GL_TEXTURE_MAG_FILTER指定为放大滤波方法,GL_TEXTURE_MIN_FILTER指定为缩小滤波方法;
第三个参数说明滤波方式。
若选择GL_NEAREST则采用坐标最靠近象素中心的纹素,这有可能使图像走样;
若选择GL_LINEAR则采用最靠近象素中心的四个象素的加权平均值。
GL_NEAREST所需计算比GL_LINEAR要少,因而执行得更快,但GL_LINEAR提供了比较光滑的效果。
纹理坐标可以超出(0,1)范围,并且在纹理映射过程中可以重复映射或约简映射。
在重复映射的情况下,纹理可以在s,t方向上重复,即:
glTexParameterfv(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameterfv(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
若将参数GL_REPEAT改为GL_CLAMP,则所有大于1的纹素值都置为1,所有小于0的值都置为0。
(3)映射方式
纹理图像是直接作为画到多边形上的颜色。
实际上,可以用纹理中的值来调整多边形(曲面)原来的颜色,或用纹理图像中的颜色与多边形(曲面)原来的颜色进行混合。
因此,OpenGL提供了三种纹理映射的方式,这个函数是:
voidglTexEnv{if}[v](GLenumtarget,GLenumpname,TYPEparam);
设置纹理映射方式。
参数target必须是GL_TEXTURE_ENV;
若参数pname是GL_TEXTURE_ENV_MODE,则参数param可以是GL_DECAL、GL_MODULATE或GL_BLEND,以说明纹理值怎样与原来表面颜色的处理方式;
若参数pname是GL_TEXTURE_ENV_COLOR,则参数param是包含四个浮点数(分别是R、G、B、A分量)的数组,这些值只在采用GL_BLEND纹理函数时才有用。
(4)纹理坐标
在绘制纹理映射场景时,不仅要给每个顶点定义几何坐标,而且也要定义纹理坐标。
经过多种变换后,几何坐标决定顶点在屏幕上绘制的位置,而纹理坐标决定纹理图像中的哪一个纹素赋予该顶点。
并且顶点之间的纹理坐标插值与基础篇中所讲的平滑着色插值方法相同。
纹理图像是方形数组,纹理坐标通常可定义成一、二、三或四维形式,称为s,t,r和q坐标,以区别于物体坐标(x,y,z,,w)和其他坐标。
一维纹理常用s坐标表示,二维纹理常用(s,t)坐标表示,目前忽略r坐标,q坐标象w一样,一半值为1,主要用于建立齐次坐标。
OpenGL坐标定义的函数是:
voidgltexCoord{1234}{sifd}[v](TYPEcoords);
设置当前纹理坐标,此后调用glVertex*()所产生的顶点都赋予当前的纹理坐标。
对于gltexCoord1*(),s坐标被设置成给定值,t和r设置为0,q设置为1;
用gltexCoord2*()可以设置s和t坐标值,r设置为0,q设置为1;
对于gltexCoord3*(),q设置为1,其它坐标按给定值设置;
用gltexCoord4*()可以给定所有的坐标。
使用适当的后缀(s,i,f或d)和TYPE的相应值(GLshort、GLint、glfloat或GLdouble)来说明坐标的类型。
注意:
整型纹理坐标可以直接应用,而不是象普通坐标那样被映射到[-1,1]之间。
在某些场合(环境映射等)下,为获得