1、2本章目标本章目标l掌握真实感图形绘制的主要内容掌握真实感图形绘制的主要内容n光照、纹理、阴影等光照、纹理、阴影等l重点掌握光照方程、基本纹理映射及多边形绘制重点掌握光照方程、基本纹理映射及多边形绘制l学会使用学会使用OpenGL的相关函数的相关函数911.1 简单光照模型简单光照模型11.1.3 镜面反射光和冯(镜面反射光和冯(Phong)反射模型)反射模型l高光(高光(high light):光滑物体表面在点光源的照射下形成一):光滑物体表面在点光源的照射下形成一块特别亮的区域块特别亮的区域l镜面反射(镜面反射(Specular Reflection)n物体表面对入射光的反射物体表面对入射
2、光的反射n遵循反射定律遵循反射定律(1)反射光与入射光位于表面法向两侧)反射光与入射光位于表面法向两侧(2)理想反射面而言:入射角反射角)理想反射面而言:入射角反射角n观察者在反射方向上看到反射光最强观察者在反射方向上看到反射光最强1011.1 简单光照模型简单光照模型lPhong模型(非理想反射面)模型(非理想反射面)nspnspsRVKIKII)(cos计算公式:计算公式:Ks是物体表面镜面反射系数,它与是物体表面镜面反射系数,它与入射角和波长有关;入射角和波长有关;是视线与反射方向的夹角;是视线与反射方向的夹角;n 为镜面高光系数,用来模拟镜面为镜面高光系数,用来模拟镜面反射光在空间中的
3、汇聚程度,它是一反射光在空间中的汇聚程度,它是一个反映物体表面光泽度的常数;个反映物体表面光泽度的常数;近似地描述了镜面反射光的近似地描述了镜面反射光的空间分布。空间分布。ncos1111.1 简单光照模型简单光照模型l简化简化Phong模型模型LNLNRNLLNSNRLNS)(coscoscoscos22RVNHVLH/2/2)2/)((2SSHnspnspnspsNHKIRVKIKII)()(cosL,N,R都是单位向量都是单位向量1211.1 简单光照模型简单光照模型l镜面参数镜面参数 n的影响效果的影响效果n=15 n=5 n=1n 常规取值常规取值 5-205-201311.1 简单
4、光照模型简单光照模型l局部光照方程局部光照方程n结合环境光、漫反射光及镜面反射光结合环境光、漫反射光及镜面反射光n当光源与视点无穷远时,对表面上任意一点而言,当光源与视点无穷远时,对表面上任意一点而言,L和和V固定不变,固定不变,H只需计算一次只需计算一次)()(nsdpaasdeNHKNLKIIKIIIIH1411.1 简单光照模型简单光照模型11.1.4 光的衰减光的衰减n光在传播过程中,能量会衰减光在传播过程中,能量会衰减n传播过程传播过程u光源到物体表面的传播,使入射光强度变弱光源到物体表面的传播,使入射光强度变弱u物体表面到人眼的传播,使人接受到物体表面的反射光强度减弱物体表面到人眼
5、的传播,使人接受到物体表面的反射光强度减弱n光到物体表面的衰减光到物体表面的衰减n考虑衰减的方程考虑衰减的方程1,1min)(1)(22102dcdccdfddf)()()(nsdpaasdeNHKNLKIdfIKIIII1511.1 简单光照模型简单光照模型n物体表面到人眼过程中的衰减物体表面到人眼过程中的衰减u深度暗示技术(深度暗示技术(Depth Cueing)u使据视点远的点比近的点暗一些使据视点远的点比近的点暗一些亮度计算亮度计算u前参考面前参考面 n=Nf;后参考面;后参考面 n=Nb(规范化视见体内)(规范化视见体内)u分别赋比例因子分别赋比例因子Sf和和Sb(Sf Sb)u给点
6、物体上的一点的深度给点物体上的一点的深度N0,比例因子比例因子S0,)(fbbfbbfbfbbfNNNNNNNNNNNSSSSSS000001611.1 简单光照模型简单光照模型亮度计算亮度计算u光照方程计算出的光照方程计算出的I按比例按比例S0与熔合亮度与熔合亮度Idc混合混合u若若Sf=1,Sb=0,Idc=0时时(1)当物体位于前参考面前,)当物体位于前参考面前,I=I(2)当物体位于后参考面后,)当物体位于后参考面后,I=0(3)N0在在Nb和和Nf间时,间时,I=S0I,亮度部分衰减,亮度部分衰减dcISISI)(0011711.1 简单光照模型简单光照模型13.1.5 产生颜色产生
7、颜色n前面的光照模型仅用于白光,只能产生灰度前面的光照模型仅用于白光,只能产生灰度n彩色模型计算彩色模型计算u选择合适模型(如选择合适模型(如RGB、HSV等)等)u为颜色的三个分量分别建立光照方程为颜色的三个分量分别建立光照方程nRGB模型模型u光源的颜色光源的颜色IpR,IpG,IpB,环境光的颜色,环境光的颜色IaR,IaG,IaBu表面反射系数表面反射系数(1)环境反射:)环境反射:KaR,KaG,KaB(2)漫反射:)漫反射:KdR,KdG,KdB(3)镜面反射:)镜面反射:KsR,KsG,KsB1811.1 简单光照模型简单光照模型 彩色光照方程(模型)彩色光照方程(模型))()(
8、)()()()()()()(nsBdBpBaBaBBnsGdGpGaGaGGnsRdRpRaRaRRNHKNLKIdfIKINHKNLKIdfIKINHKNLKIdfIKI1911.1 简单光照模型简单光照模型11.1.6 多个光源多个光源 如果场景中有如果场景中有m个光源,那么物体上任一点的亮度应该为个光源,那么物体上任一点的亮度应该为m个光源的贡献之和个光源的贡献之和 在在RGB彩色模型中,彩色模型中,分别为分别为R、G和和B。注意:注意:I可能会超出系统允许的最大亮度值,处理方法可能会超出系统允许的最大亮度值,处理方法 (1)截去超出部分,设置为最大值)截去超出部分,设置为最大值 (2)
9、首先计算出所有亮度值,)首先计算出所有亮度值,再进行变换(如缩放变换)再进行变换(如缩放变换)使其落在系统规定范围之内使其落在系统规定范围之内minisidpiaaNHKNLKIdfIKIi1)()()(2011.1 简单光照模型简单光照模型11.1.7 OpneGL光照函数光照函数(1)OpenGL 光组成光组成 在在OpenGL简单光照模型中的几种光分为:环境光简单光照模型中的几种光分为:环境光(Ambient Light)、漫射光、漫射光(Diffuse Light)、镜面光、镜面光(Specular Light)。(2)创建光源)创建光源(Light Source)void glLig
10、htifv(GLenum light,GLenum pname,TYPE param)l创建具有某种特性的光源。其中第一个参数创建具有某种特性的光源。其中第一个参数light指定所创指定所创建的光源号,如建的光源号,如GL_LIGHT0、GL_LIGHT1、.、GL_LIGHT7。第二个参数。第二个参数pname指定光源特性,这个参数指定光源特性,这个参数的辅助信息见表的辅助信息见表11-1-7-1所示。最后一个参数设置相应的光所示。最后一个参数设置相应的光源特性值。源特性值。2111.1 简单光照模型简单光照模型函数函数glLight*()参数参数pname及及param说明说明 2211.
11、1 简单光照模型简单光照模型(3)启动光照)启动光照 l在在OpenGL中,必须明确指出光照是否有效或无效。如果光照无中,必须明确指出光照是否有效或无效。如果光照无效,则只是简单地将当前颜色映射到当前顶点上去,不进行法向、效,则只是简单地将当前颜色映射到当前顶点上去,不进行法向、光源等复杂计算,那么显示的图形就没有真实感光源等复杂计算,那么显示的图形就没有真实感l要使光照有效,首先得启动光照,即:要使光照有效,首先得启动光照,即:glEnable(GL_LIGHTING);若使光照无效,则调用若使光照无效,则调用 gDisable(GL_LIGHTING)可关闭当可关闭当前光照。前光照。l然后
12、,必须使所定义的每个光源有效。然后,必须使所定义的每个光源有效。glEnable(GL_LIGHT0);其它光源类似,只是光源号不同而已其它光源类似,只是光源号不同而已2311.1 简单光照模型简单光照模型(4)例:简单光照)例:简单光照#include#include#pragma comment(lib,glaux.lib)void myinit(void)GLfloat light_position=1.0,1.0,1.0,0.1;GLfloat light_color=1.0,0.0,0.0,1.0;glLightfv(GL_LIGHT0,GL_POSITION,light_posit
13、ion);glLightfv(GL_LIGHT0,GL_AMBIENT,light_color);glLightfv(GL_LIGHT0,GL_DIFFUSE,light_color);glLightfv(GL_LIGHT0,GL_SPECULAR,light_color);glEnable(GL_LIGHTING);glEnable(GL_LIGHT0);glEnable(GL_DEPTH_TEST);void display(void)glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);auxSolidSphere(1.0);/绘制球体绘制球体
14、 glFlush();2411.1 简单光照模型简单光照模型void myReshape(int w,int h)glViewport(0,0,w,h);glMatrixMode(GL_PROJECTION);glLoadIdentity();if(w=h)glOrtho(-1.5,1.5,-1.5*(GLfloat)h/(GLfloat)w,1.5*(GLfloat)h/(GLfloat)w,-10.0,10.0);else glOrtho(-1.5*(GLfloat)w/(GLfloat)h,1.5*(GLfloat)w/(GLfloat)h,-1.5,1.5,-10.0,10.0);gl
15、MatrixMode(GL_MODELVIEW);glLoadIdentity();2511.1 简单光照模型简单光照模型void main(void)glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);glutInitWindowSize(250,250);glutInitWindowPosition(300,300);glutCreateWindow(Simple Lighting);myinit();glutReshapeFunc(myReshape);glutDisplayFunc(display);glutMainLoop();2611.1 简单光照模
16、型简单光照模型(5)聚光)聚光 定位光源可以定义成聚光灯形式,即将光的形状限制在一个定位光源可以定义成聚光灯形式,即将光的形状限制在一个圆锥内。圆锥内。一、定义聚光源位置。一、定义聚光源位置。因为聚光源也是定向光源,因为聚光源也是定向光源,所以他的位置同一般定向光一样。所以他的位置同一般定向光一样。如:如:GLfloat light_position=1.0,1.0,1.0,1.0;glLightfv(GL_LIGHT0,LIGHT_POSITION,light_position);2711.1 简单光照模型简单光照模型二、定义聚光截止角二、定义聚光截止角 参数参数GL_SPOT_CUTOFF
17、给定光锥的轴与中给定光锥的轴与中 心线的夹角,也可心线的夹角,也可说成是光锥顶角的一半。说成是光锥顶角的一半。缺省时,这个参数为缺省时,这个参数为180.0,即顶角为,即顶角为360度,度,光向所有的方向发射,因此聚光关闭。光向所有的方向发射,因此聚光关闭。一般在聚光启动情况下,聚光截止角限制在一般在聚光启动情况下,聚光截止角限制在0.0,90.0之间,如下面一行代码设置截止角为之间,如下面一行代码设置截止角为45度:度:glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,45.0);2811.1 简单光照模型简单光照模型三、定义聚光方向三、定义聚光方向 聚光方向决定光锥的轴,
18、它齐次坐标定义,其缺省值为聚光方向决定光锥的轴,它齐次坐标定义,其缺省值为(0.0,0.0,-1.0),即指向即指向Z负轴。聚光方向也要进行几何变换,其结果保存在视点坐标中。负轴。聚光方向也要进行几何变换,其结果保存在视点坐标中。定义如下:定义如下:GLfloat spot_direction=-1.0,-1.0,0.0,-1;glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,spot_direction);四、定义聚光指数四、定义聚光指数 参数参数GL_SPOT_EXPONENT控制光的集中控制光的集中程度,光锥中心的光强最大,越靠边的光强越小,程度,光锥中心的光强
19、最大,越靠边的光强越小,缺省时为缺省时为0。如:。如:glLightf(GL_LIGHT0,GL_SPOT_EXPONENT,2.0);2911.1 简单光照模型简单光照模型(6)例:多光源)例:多光源#include#include#pragma comment(lib,glaux.lib)/*初始化光源、材质等初始化光源、材质等*/void myinit(void)GLfloat mat_ambient=0.2,0.2,0.2,1.0;GLfloat mat_diffuse=0.8,0.8,0.8,1.0;GLfloat mat_specular=1.0,1.0,1.0,1.0;GLflo
20、at mat_shininess=50.0;GLfloat light0_diffuse=0.0,0.0,1.0,1.0;GLfloat light0_position=1.0,1.0,1.0,0.0;GLfloat light1_ambient=0.2,0.2,0.2,1.0;GLfloat light1_diffuse=1.0,0.0,0.0,1.0;GLfloat light1_specular=1.0,0.6,0.6,1.0;GLfloat light1_position=-3.0,-3.0,3.0,1.0;GLfloat spot_direction=1.0,1.0,-1.0;glM
21、aterialfv(GL_FRONT,GL_AMBIENT,mat_ambient);glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse);glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess);/转下页转下页3011.1 简单光照模型简单光照模型 /接上页接上页 glLightfv(GL_LIGHT0,GL_DIFFUSE,light0_diffuse);glLightfv(GL_LIGHT0,GL_POSITION
22、,light0_position);glLightfv(GL_LIGHT1,GL_AMBIENT,light1_ambient);glLightfv(GL_LIGHT1,GL_DIFFUSE,l ight1_diffuse);glLightfv(GL_LIGHT1,GL_SPECULAR,light1_specular);glLightfv(GL_LIGHT1,GL_POSITION,light1_position);glLightf(GL_LIGHT1,GL_SPOT_CUTOFF,30.0);glLightfv(GL_LIGHT1,GL_SPOT_DIRECTION,spot_direct
23、ion);glEnable(GL_LIGHTING);glEnable(GL_LIGHT0);glEnable(GL_LIGHT1);glDepthFunc(GL_LESS);glEnable(GL_DEPTH_TEST);3111.1 简单光照模型简单光照模型void display(void)glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);glPushMatrix();glTranslated(-3.0,-3.0,3.0);/光源光源1位置位置 glDisable(GL_LIGHTING);glColor3f(1.0,0.0,0.0);au
24、xWireCube(0.1);/绘制光源绘制光源1 glEnable(GL_LIGHTING);glPopMatrix();auxSolidSphere(2.0);glFlush();3211.1 简单光照模型简单光照模型void myReshape(GLsizei w,GLsizei h)glViewport(0,0,w,h);glMatrixMode(GL_PROJECTION);glLoadIdentity();if(w=h)glOrtho(-5.5,5.5,-5.5*(GLfloat)h/(GLfloat)w,5.5*(GLfloat)h/(GLfloat)w,-10.0,10.0);
25、else glOrtho(-5.5*(GLfloat)w/(GLfloat)h,5.5*(GLfloat)w/(GLfloat)h,-5.5,5.5,-10.0,10.0);glMatrixMode(GL_MODELVIEW);glLoadIdentity();void main(void)glutInitDisplayMode(GLUT_SINGLE GLUT_RGBA);glutInitWindowSize(250,250);glutInitWindowPosition(300,300);glutCreateWindow(Multi_lights);myinit();glutReshape
26、Func(myReshape);glutDisplayFunc(display);glutMainLoop();33第第11章章 真实感图形的绘制真实感图形的绘制l简单光照模型简单光照模型l多边形绘制方法多边形绘制方法l纹理映射纹理映射l阴影阴影3411.2 多边形绘制方法多边形绘制方法11.2.1 均匀着色均匀着色(Flat Shading)n方法方法u任取多边形上一点,利用光照明方程计算出它的颜色任取多边形上一点,利用光照明方程计算出它的颜色u用这个颜色填充整个多边形用这个颜色填充整个多边形n适合于如下情况适合于如下情况u光源在无穷远处,光源在无穷远处,LN 相等相等u视点在无穷远处,视点
27、在无穷远处,HN 相等相等u多边形是物体表面的精确表示多边形是物体表面的精确表示n特点特点u优点:每个多边形只需计算一次光照明方程,速度快优点:每个多边形只需计算一次光照明方程,速度快u缺点:相邻多边形颜色过渡不光滑缺点:相邻多边形颜色过渡不光滑3511.2 多边形绘制方法多边形绘制方法11.2.2 光滑着色(光滑着色(Smooth Shading)n采用插值方法采用插值方法nGouraud(高洛德高洛德)方法方法u用多边形顶点的颜色进行插值生成中间点的颜色用多边形顶点的颜色进行插值生成中间点的颜色nPhone(冯冯)方法方法u对顶点的法向量进行插值计算出中间点的法向量对顶点的法向量进行插值计
28、算出中间点的法向量3611.2 多边形绘制方法多边形绘制方法11.2.3 Gouraud 着色方法(颜色插值方法)着色方法(颜色插值方法)主要步骤主要步骤1、计算多边形的单位法向量、计算多边形的单位法向量2、计算多边形顶点的单位法向量(共享顶点的多边形法向量的平均值)、计算多边形顶点的单位法向量(共享顶点的多边形法向量的平均值)3、利用光照明方程计算顶点颜色、利用光照明方程计算顶点颜色4、对多边形顶点颜色进行双线性插值,获得多边形内部各点的颜色、对多边形顶点颜色进行双线性插值,获得多边形内部各点的颜色3711.2 多边形绘制方法多边形绘制方法(1)计算多边形顶点的单位法)计算多边形顶点的单位法
29、向向量量 近似取顶点近似取顶点v的法向量为共享该顶点的多边形单位法向的法向量为共享该顶点的多边形单位法向量的平均值量的平均值niiniivNNN113811.2 多边形绘制方法多边形绘制方法(2)内部点颜色计算:双线性插值)内部点颜色计算:双线性插值 已知已知P1(x1,y1)、P2(x2,y2)、P3(x3,y3),颜色分别为,颜色分别为I1、I2和和I3。A(xA,yA)和和B(xB,yB)为交点,为交点,P(x,y)为)为AB上一上一点,计算点,计算P点的颜色点的颜色22111212IyyyyIyyyyIAAA33111313IyyyyIyyyyIBBBBABAAABBPIxxxxIxx
30、xxI3911.2 多边形绘制方法多边形绘制方法增量法优化计算增量法优化计算IA,IB,IP(1)扫描线)扫描线 y 递增为递增为 y+1,IA和和IB的增量分别为的增量分别为IA和和IB(2)当)当x递增一个单位(递增一个单位(P点沿扫描线右移一个单位)时,点沿扫描线右移一个单位)时,IP的增量为的增量为IP13131212,-,-yyIIIyyIIIIIIIIIBAByByBAyAyA其中其中11ABABPPxPxPxxIIIIII-,其中其中14011.2 多边形绘制方法多边形绘制方法11.2.3 Phong 着色方法(法向插值着色方法)着色方法(法向插值着色方法)方法:通过对多边形顶点
31、法向量进行插值,获得多边形内方法:通过对多边形顶点法向量进行插值,获得多边形内 部各点的法向量,再利用光照方程计算各点的亮度部各点的法向量,再利用光照方程计算各点的亮度主要步骤:主要步骤:1、计算多边形单位法向量、计算多边形单位法向量2、计算多边形顶点单位法向量、计算多边形顶点单位法向量(以上两步同(以上两步同Gouraud着色方法)着色方法)3、对多边形顶点法向量进行双线性插值,、对多边形顶点法向量进行双线性插值,获得内部各点的法向量获得内部各点的法向量4、利用光照明方程计算多边形内部各点颜色、利用光照明方程计算多边形内部各点颜色4111.2 多边形绘制方法多边形绘制方法l法向量双线性插值法
32、向量双线性插值22111212NyyyyNyyyyNAAA33111313NyyyyNyyyyNBBBBABAAABBPNxxxxNxxxxN4211.2 多边形绘制方法多边形绘制方法l法向量双线性插值计算优化法向量双线性插值计算优化(1)扫描线)扫描线 y 递增为递增为 y+1,NA和和NB的增量分别为的增量分别为NA和和NB(2)当)当x递增一个单位(递增一个单位(P点沿扫描线右移一个单位)时,点沿扫描线右移一个单位)时,NP的增的增量为量为NP13131212,-,-NNNNNyyNNNNNNNNNBAByByBAyAyA其中其中11ABABPPxPxPxxNNNNNN-,其中其中143
33、第第11章章 真实感图形的绘制真实感图形的绘制l简单光照模型简单光照模型l多边形绘制方法多边形绘制方法l纹理映射纹理映射l阴影阴影4411.3 纹理映射l背景背景n光照模型只能生成光滑的物体表面光照模型只能生成光滑的物体表面n自然界中的物体表面具有丰富的细节,如木纹、桔子凹凸自然界中的物体表面具有丰富的细节,如木纹、桔子凹凸表面、沙砾路面表面、沙砾路面n丰富的表面细节难以用计算机图形方法生成丰富的表面细节难以用计算机图形方法生成n采用将图片贴到物体表面上的方法绘制采用将图片贴到物体表面上的方法绘制樱桃木樱桃木桔子凹凸面桔子凹凸面沙砾路面沙砾路面4511.3 纹理映射l纹理(纹理(Texture
34、)n纹理是物体表面的细小结构,它可以是光滑表面的花纹理是物体表面的细小结构,它可以是光滑表面的花纹、图案,即颜色纹理纹、图案,即颜色纹理(2D)n纹理也可以是物体表面的三维结构纹理也可以是物体表面的三维结构n纹理还可以是粗糙的表面纹理还可以是粗糙的表面(如桔子表面的皱纹如桔子表面的皱纹),称为,称为几何纹理,是基于物体表面的微观几何形状的表面纹几何纹理,是基于物体表面的微观几何形状的表面纹理理4611.3 纹理映射l纹理(续)纹理(续)n纹理空间:纹理图案所在空间,记为纹理空间:纹理图案所在空间,记为st坐标系(一般是平坐标系(一般是平面)面)n纹素(纹素(texel):纹理最小单元,位置由纹
35、理坐标():纹理最小单元,位置由纹理坐标(s,t)标识标识n两种来源两种来源u数字图像,用二维数组表示数字图像,用二维数组表示u数学公式定义得纹理函数数学公式定义得纹理函数4711.3 纹理映射l纹理映射(纹理映射(Texture Mapping)n将一块纹理图案映射到物体表面上,产生物体表面的细将一块纹理图案映射到物体表面上,产生物体表面的细节节n颜色计算方法颜色计算方法u用表面上点对应的纹素值代替该点的漫反射系数用表面上点对应的纹素值代替该点的漫反射系数u纹理与物体表面的对应关系纹理与物体表面的对应关系n纹理坐标:纹理坐标:s,t变化范围变化范围0,122110021010tsctsbts
36、atscbacbacPbPaPP,PT4811.3 纹理映射l实例:圆柱面映射实例:圆柱面映射 圆柱面上的点圆柱面上的点对应的纹理坐标对应的纹理坐标hhyts2360/styxz22hyhryryP)cos,sin(),(rh4911.3 纹理映射l实例:球面映射实例:球面映射 和和变化范围分别变化范围分别0,3600,360和和-90,90-90,90(1)(2)球面垂直向外映射到柱面上,再将柱面球面垂直向外映射到柱面上,再将柱面展开到矩形上展开到矩形上212360sin,ts21180360ts,)coscos,sin,cossin(),(rrrP5011.3 纹理映射纹理映射l实例:圆环
37、面映射实例:圆环面映射R是环的主半径,是环的主半径,r是次半径;是次半径;和和变化范围变化范围0,3600,360)cos)cos(,sin,sin)cos(),(rRrrRP360360ts,Rr对应的纹理坐标对应的纹理坐标5111.3 纹理映射纹理映射lOpenGL函数函数n纹理映射是一个相当复杂的过程,最基本的执行纹理映纹理映射是一个相当复杂的过程,最基本的执行纹理映射所需的步骤。基本步骤如下:射所需的步骤。基本步骤如下:一、定义纹理;一、定义纹理;二、控制滤波;二、控制滤波;三、说明映射方式;三、说明映射方式;四、激活纹理;四、激活纹理;五、绘制图形,即给出顶点的纹理坐标和几何坐标。五
38、、绘制图形,即给出顶点的纹理坐标和几何坐标。注意:纹理映射只能在注意:纹理映射只能在RGBA方式下执行,不能运用方式下执行,不能运用于颜色表方式。于颜色表方式。5211.3 纹理映射纹理映射一、定义纹理一、定义纹理 二维纹理定义的函数:二维纹理定义的函数:void glTexImage2D(GLenum target,GLint level,Glint components,GLsizei width,glsizei height,GLint border,GLenum format,GLenum type,const GLvoid*pixels);ltarget是常数是常数GL_TEXTUR
39、E_2D;level表示多级分辨率的纹理图像的级数,若只有一种分辨表示多级分辨率的纹理图像的级数,若只有一种分辨率,则率,则level设为设为0;lcomponents是一个从是一个从1到到4的整数,指出选择了的整数,指出选择了R、G、B、A中的哪些分量用于调整和混合,中的哪些分量用于调整和混合,1表示选择了表示选择了R分量,分量,2表表示选择了示选择了R和和A两个分量,两个分量,3表示选择了表示选择了R、G、B三个分量,三个分量,4表示选择了表示选择了R、G、B、A四个分量;四个分量;5311.3 纹理映射纹理映射lwidth和和height给出了纹理图像的长度和宽度;给出了纹理图像的长度和
40、宽度;border为纹理边界为纹理边界宽度,它通常为宽度,它通常为0,width和和height必须是必须是2m+2b,这里,这里m是整数,是整数,长和宽可以有不同的值,长和宽可以有不同的值,b是是border的值。纹理映射的最大尺寸的值。纹理映射的最大尺寸依赖于依赖于OpenGL,但它至少必须是使用,但它至少必须是使用64x64(若带边界为(若带边界为66x66),若),若width和和height设置为设置为0,则纹理映射有效地关闭;,则纹理映射有效地关闭;l参数参数format和和type描述了纹理映射的格式和数据类型,参数描述了纹理映射的格式和数据类型,参数format可以是可以是GL
41、_RGB、GL_RGBA、GL_RED、GL_GREEN、GL_BLUE、GL_ALPHA、GL_LUMINANCE或或GL_LUMINANCE_ALPHA;参数;参数type是是GL_BYPE、GL_UNSIGNED_BYTE、GL_SHORT、GL_UNSIGNED_SHORT、GL_INT、GL_UNSIGNED_INT、GL_FLOAT或或GL_BITMAP;l参数参数pixels包含了纹理图像数据,这个数据描述了纹理图像本身包含了纹理图像数据,这个数据描述了纹理图像本身和它的边界。和它的边界。5411.3 纹理映射纹理映射二、控制滤波;二、控制滤波;void glTexParamet
42、erifv(GLenum target,GLenum pname,TYPE param);l参数参数target可以是可以是GL_TEXTURE_1D或或GL_TEXTURE_2DlPname和和paramPnameparamGL_TEXTURE_WRAP_SGL_CLAM或或GL_REPEATGL_TEXTURE_WRAP_TGL_CLAM或或GL_REPEATGL_TEXTURE_MAG_FILTERGL_NEAREST或或GL_LINEARGL_TEXTURE_MIN_FILTERGL_NEAREST或或GL_LINEAR.5511.3 纹理映射纹理映射三、设置纹理映射方式三、设置纹理映
43、射方式l可以用纹理中的值来取代多边形(曲面)原来的颜色,或可以用纹理中的值来取代多边形(曲面)原来的颜色,或用纹理图像中的颜色与多边形(曲面)原来的颜色进行混用纹理图像中的颜色与多边形(曲面)原来的颜色进行混合。合。lvoid glTexEnvifv(GLenum target,GLenum pname,TYPE param);l参数参数target必须是必须是GL_TEXTURE_ENV;l若参数若参数pname是是GL_TEXTURE_ENV_MODE,则参数,则参数param可可以是以是GL_DECAL、GL_MODULATE或或GL_BLEND,以说明纹,以说明纹理值怎样与原来表面颜色
44、的处理方式;若参数理值怎样与原来表面颜色的处理方式;若参数pname是是GL_TEXTURE_ENV_COLOR,则参数,则参数param是包含四个浮点是包含四个浮点数(分别是数(分别是R、G、B、a分量)的数组,这些值只在采用分量)的数组,这些值只在采用GL_BLEND纹理函数时才有用。纹理函数时才有用。5611.3 纹理映射纹理映射四、激活纹理;四、激活纹理;glEnable(GL_TEXTURE_2D);五、定义纹理坐标五、定义纹理坐标n在绘制纹理映射图形时,不仅要给每个顶点定义几何坐在绘制纹理映射图形时,不仅要给每个顶点定义几何坐标,而且也要定义纹理坐标。标,而且也要定义纹理坐标。nv
45、oid glTexCoord1234sifdv(TYPE coords);设置当前纹理坐标,此后调用设置当前纹理坐标,此后调用glVertex*()所产生的顶所产生的顶点都赋予当前的纹理坐标。点都赋予当前的纹理坐标。5711.3 纹理映射纹理映射l例:简单纹理映射例:简单纹理映射#include#include#define nRows 128#define nCols 128GLubyte Image3*nRows*nCols;/生成黑白棋盘格图像数据生成黑白棋盘格图像数据void makeCheckerboard(void)long count=0;for(int i=0;i nRows;
46、i+)for(int j=0;j nCols;j+)GLubyte c=(i/8)+(j/8)%2)*255;Imagecount+=c;Imagecount+=c;Imagecount+=c;5811.3 纹理映射纹理映射/纹理初始化纹理初始化void myinit(void)glClearColor(0.0,0.0,0.0,0.0);makeCheckerboard();glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL);glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP
47、);/GL_REPEAT glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);/GL_CLAMP glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,nRows,nCols,0,GL_RGB,GL_UNSIGNED_BYTE,Image);glEnable(GL_
48、DEPTH_TEST);glDepthFunc(GL_LESS);glEnable(GL_TEXTURE_2D);5911.3 纹理映射纹理映射/绘制图形绘制图形void drawRect()/正方形正方形glBegin(GL_POLYGON);glTexCoord2f(1,0);glVertex3f(-2,2,0);glTexCoord2f(1,1);glVertex3f(2,2,0);glTexCoord2f(0,1);glVertex3f(2,-2,0);glTexCoord2f(0,0);glVertex3f(-2,-2,0);glEnd();6011.3 纹理映射纹理映射#defin
49、e nH 30#define nC 30void drawClinder(float r,float h)/绘制圆柱面绘制圆柱面 float dh=(float)h/nH;float dc=2*3.14/nC;float xnC+1,znC+1,y1,y2;float snC+1,t1,t2;for(int j=0;j=nC;j+)xj=r*sin(j*dc);zj=r*cos(j*dc);sj=j*dc/3.14/2;for(int i=0;i=nH;i+)if(i!=0)y1=y2;t1=t2;y2=i*dh-0.5*h;t2=(y1+0.5*h)/h;if(i=0)continue;fo
50、r(j=0;jnC;j+)glBegin(GL_POLYGON);glTexCoord2f(sj,t1);glVertex3f(xj,y1,zj);glTexCoord2f(sj+1,t1);glVertex3f(xj+1,y1,zj+1);glTexCoord2f(sj+1,t2);glVertex3f(xj+1,y2,zj+1);glTexCoord2f(sj,t2);glVertex3f(xj,y2,zj);glEnd();6111.3 纹理映射纹理映射void drawTorus(float r,float R)/绘制圆环绘制圆环 float dh=6.28/nH;float dc=6