




已阅读5页,还剩36页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第七章 OpenGL纹理映射前面我们学习了基本的三维图形的程序设计,但物体表面的细节(比如带有木纹的桌面等)依靠现有的技术还不能表现出来,因而三维物体看起来不是很真实。如何来表现物体表面的细节就纹理映射技术要研究的内容。就是在三维图形中,纹理映射技术应用很广,尤其描述具有真实感的物体。比如绘制一面砖墙,就可以用一幅真实的砖墙图像或照片作为纹理贴到一个矩形上,砖墙就很逼真。如果不用纹理映射的方法,则墙上的每一块砖都必须作为一个独立的多边形来画,这样会增加许多的计算量。纹理映射也常常运用在其他一些领域,如飞行仿真中常把一大片植被的图像映射到一些大多边形上用以表示地面,或用大理石、木材、布匹等自然物质的图像作为纹理映射到多边形上表示相应的物体。纹理映射有许多种情况。例如,任意一块纹理可以映射到平面或曲面上,且对光亮的物体进行纹理映射,其表面可以映射出周围环境的景象;纹理还可按不同的方式映射到曲面上,一是可以直接画上去(或称贴花法),二是可以调整曲面颜色或把纹理颜色与曲面颜色混合。纹理不仅可以是二维的,也可以是一维和三维。7.1 基本概念1、纹理映射技术能够模拟物体表面颜色细节或几何细节的计算机图形学技术称为纹理映射技术(texture mapping technology)。利用纹理映射技术,可以在不增加场景绘制复杂度,不显著增加计算量的前提下,大幅度提高图形的真实感。2、纹理及纹理空间 待映射的图形称为纹理;纹理中某点也是有位置的,一般用坐标来标识,对应的坐标系称为纹理坐标空间。3、纹理函数 纹理函数是关于纹理坐标的函数。函数值一般为光的亮度值。在计算机中处理时,一般用RGB三个分量来表示。当纹理函数的定义域为一维、二维、三维时,对应的纹理函数称为一维纹理函数、二维纹理函数、三维纹理函数。4、纹理函数来源(1)数学方式描述的纹理函数示例1(长峰波函数):示例2(棋盘):(2)数字图像二维数组,imageMN, M*N表示图像的大小,数组中每个元素的值为光亮度。(3)两类纹理函数的转化 也就是数字图像(离散)与数学公式(连续)之间的转化。通过采样,连续函数可变成离散的样本阵列;通过双线性插值,离散的数组可转化为连续的函数。7.2 纹理映射的基本步骤定义纹理绘制场景指定映射方式滤波图7-1 纹理映射步骤第六章中我们学到了混合,纹理映射方法中也要用到混合,目的是把原来的颜色和将要画上去的颜色经过某种方式处理后得到一种新的颜色。这里把将要画上去的颜色称为源颜色,也称为片元,把当前存储在帧缓存中的颜色称为目标颜色。OpenGL会把源颜色和目标颜色各自取出,并分别乘以一个系数(不透明度)。源颜色乘以的系数称为“源因子”(源颜色的不透明度),目标颜色乘以的系数称为“目标因子”(目标颜色的不透明度),然后把两个乘积的结果相加,这样就得到了新的颜色(也可以不是相加,新版本的OpenGL可以设置运算方式,包括加、减、取两者中较大的、取两者中较小的、逻辑运算等,这些可以通过函数glBlendEquation()来实现)。7.3 指定纹理OpenGL 提供了三个函数来指定纹理,glTexImage1D() 用用来指定一维纹理,glTexImage2D()用于指定二维纹理,glTexImage3D()用于指定三维纹理。本章我们主要研究二维纹理。指定二维纹理映射的函数是:void glTexImage2D(GLenum target ,GLint level ,GLint internalFormat ,GLsizei width , glsizei height ,GLint border ,GLenum format ,GLenum type , const GLvoid *pixels ) ;现详细说明其中的参数:(1)参数target 的取值为GL_TEXTURE_2D;(2)参数level表示多级分辨率的纹理图像的级数,若只有一种分辨率,则level设为0。(3)参数 internalFormat 指定了纹理存储在显存中的内部格式,取值如表7-1所示。通常取值为:GL_RGB、GL_RGBA。为兼容 OpenGL1.0 ,internalFormat可以取值 1,2,3,4 分别对应常量LUMINANCE, LUMINANCE_ALPHA, RGB, RGBA.表7-1纹理内部格式格式注解GL_ALPHAAlpha 值GL_DEPTH_COMPONENT深度值GL_LUMINANCE灰度值GL_LUMINANCE_ALPHA灰度值和 Alpha 值GL_INTENSITY亮度值GL_RGBRed, Green, Blue三原色值GL_RGBARed, Green, Blue 和 Alpha 值(4)参数width和 height给出了纹理图像的长度和宽度,参数border为纹理边界宽度,它通常为0,width和height必须是2m +2b,其中m是整数,长和宽可以有不同的值,b是border的值。纹理映射的最大尺寸依赖于OpenGL,但它至少必须是使用64x64(若带边界为66x66),若width和height设置为0,则纹理映射有效地关闭。(5)参数 format 指定图像数组pixels的存储格式。取值见表7-2。常用的格式是:GL_RGB或GL_RGBA。表7-2图像数据数组 pixels格式格式注解GL_COLOR_INDEX颜色索引值GL_DEPTH_COMPONENT深度值GL_RED红色像素值GL_GREEN绿色像素值GL_BLUE蓝色像素值GL_ALPHAAlpha 值GL_RGBRed, Green, Blue 三原色值GL_RGBARed, Green, Blue 和 Alpha 值GL_BGRBlue, Green, Red 值GL_BGRABlue, Green, Red 和 Alpha 值GL_LUMINANCE灰度值GL_LUMINANCE_ALPHA灰度值和 Alpha 值(6)参数 type 指定参数 type 定义了图像数据数组 pixels 中的数据类型。取值取值见表7-3。常见的数据类是GL_UNSIGNED_BYTE和GL_BYTE。表7-3图像数据数组 pixels 中数据类型数据类型注解GL_BITMAP一位(0或1)GL_BYTE带符号8位整形值(一个字节)GL_UNSIGNED_BYTE不带符号8位整形值(一个字节)GL_SHORT带符号16位整形值(2个字节)GL_UNSIGNED_SHORT不带符号16未整形值(2个字节)GL_INT带符号32位整形值(4个字节)GL_UNSIGNED_INT不带符号32位整形值(4个字节)GL_FLOAT单精度浮点型(4个字节)GL_UNSIGNED_BYTE_3_3_2压缩到不带符号8位整形:R3,G3,B2GL_UNSIGNED_BYTE_2_3_REV压缩到不带符号8位整形:B2,G3,R3GL_UNSIGNED_SHORT_5_6_5压缩到不带符号16位整形:R5,G6,B5GL_UNSIGNED_SHORT_5_6_5_REV压缩到不带符号16位整形:B5,G6,R5GL_UNSIGNED_SHORT_4_4_4_4压缩到不带符号16位整形:R4,G4,B4,A4GL_UNSIGNED_SHORT_4_4_4_4_REV压缩到不带符号16位整形:A4,B4,G4,R4GL_UNSIGNED_SHORT_5_5_5_1压缩到不带符号16位整形:R5,G5,B5,A1GL_UNSIGNED_SHORT_1_5_5_5_REV压缩到不带符号16位整形:A1,B5,G5,R5GL_UNSIGNED_INT_8_8_8_8压缩到不带符号32位整形:R8,G8,B8,A8GL_UNSIGNED_INT_8_8_8_8_REV压缩到不带符号32位整形:A8,B8,G8,R8GL_UNSIGNED_INT_10_10_10_2压缩到32位整形:R10,G10,B10,A2GL_UNSIGNED_INT_2_10_10_10_REV压缩到32位整形:A2,B10,G10,R10(7)参数pixels 指向了实际的图像数据。例如: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, ImageWidth,ImageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, &Image000); glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData);7.4 纹理控制与滤波纹理图像被映射到多边形上可能会造成失真。纹理图像映射到多边形上去,屏幕上的一个点可能是纹理点的一个部分(如果视口设置的离纹理很近), 也有可能屏幕上的一个像素点是多个纹理的集合(如果视口设置的足够远). 纹理滤波就是告诉 OpenGL 在纹理到屏幕像素点的映射中如何计算最终显示的图像数据。OpenGL中的纹理控制与滤波函数是void glTexParameterifv(GLenum target,GLenum pname,TYPE param);它用来控制纹素映射到片元(fragment)时怎样对待纹理。第一个参数target可以是GL_TEXTURE_1D或GL_TEXTURE_2D或GL_TEXTURE_3D或GL_TEXTURE_CUBE_MAP,它指出是一维、二维纹理还是三维纹理等,后两个参数的可能值见表7-4。表7-4 滤波方式及其取值7.4.1 纹理坐标如同物体有空间三维坐标,纹理也有自己的坐标。区别于物体坐标(x,y,z,w),纹理坐标可包含14个分量,通常记为s、t、r、q,取值范围一般在01之间。对于二维纹理来说,s表示图像的水平方向,t指图像的垂直方向。在OpenGL中是通过指定纹理坐标来将纹理映射到多边形上去的。在纹理坐标系中, 左下角是 (0,0), 右上角是 (1,1)。2D 纹理的坐标中通过指定 (s,t) (s为x轴上,t为y轴上, 取值01)。1D、3D、4D纹理坐标系中对应的需要指定 (s)、(s,t,r)、(s,t, r,q)。纹理坐标需要通过函数glTexCoord()来设置, 该函数的原型是:void glTexCoord1234sifd(TYPE coords);void glTexCoord1234sifdv(TYPE coords);例如把2D纹理坐标设为(0.2 , 0.4),所用的语句是:glTexCoord2f( 0.2f , 0.4f ) ;每次通过glVertex()指定一个顶点时, 当前的纹理坐标会被应用到这个点上,所以每指定一个新的顶点,需要同时修改纹理坐标,如:glBegin(GL_POLYGON); glTexCoord2f(0.0f, 0.0f); glVertex3f(-0.5f, 0.5f, 0.5f);/ 左下角 glTexCoord2f(1.0f, 0.0f); glVertex3f(0.5f, 0.5f, 0.5f); / 右下角 glTexCoord2f(1.0f, 1.0f); glVertex3f(0.5f, 0.5f, -0.5f);/ 右上角 glTexCoord2f(0.0f, 1.0f); glVertex3f(-0.5f, 0.5f, -0.5f);/ 左上角 glEnd();综合实例详见【综合示例EP7-1】、【综合示例EP7-2】。7.4.2 纹理重复和截取设有如下的6464图像,把它作为二维纹理。st图7-2 6464棋盘图像作为二维纹理1、重复纹理坐标范围为0 , 1,当纹理坐标大于1时,在该纹理方向上重复。若在二维纹理的两个方向均重复,即:glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);结果如图7-3所示。 图7-3 纹理重复图7-4纹理截取2、截取纹理坐标范围为0 , 1,当纹理坐标大于1时,将其值截为1,当纹理坐标小于0时,将其值取为0。纹理的两个方向均截取的关键代码如下:glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);结果如图7-4所示。7.4.3 纹理滤波指定纹理放大滤波器需要指定参数 pname 为GL_TEXTURE_MAG_FILTER, 指定纹理缩小滤波器需要指定参数 pname 为GL_TEXTURE_MIN_FILTER.当pname指定为GL_TEXTURE_MAG_FILTER, 参数 param 取值GL_NEAREST或GL_LINEAR. 对放大滤波器而言, 使用GL_NEAREST将告诉 OpenGL 使用离像素点中心最近的纹理来渲染,称作点样(pointsampling);使用GL_LINEAR告诉 OpenGL 会使用离像素点中心最近的四个纹理的平均值来渲染,称作双线性滤波(bilinearfiltering)。对于pname为GL_TEXTURE_MIN_FILTER时,还有更多的滤波方法,如表7-4所示。设置纹理滤波的关键代码如下:glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 7.5 读入位图文件作为纹理贴图首先编辑好一幅位图,长和高均是2幂次方,如:3232、6464、3264、128128、256256等。比如在当前项目EP7-2下有一子目录,名字为Images,其下存放了设计好的位图文件CoffeeBean.bmp,如图7-5所示。图7-5 项目目录结构读入这个文件作为纹理贴图的方法和步骤是:1、读取位图文件中的图像数据我们把这个功能封装成一个函数,取名为LoadBitmap。输入参数为文件名字符串,返回值为AUX_RGBImageRec * 型的一个指针。AUX_RGBImageRec是一个复合结构,在glaux.h中定义:typedef struct _AUX_RGBImageRec GLint sizeX, sizeY; unsigned char *data; AUX_RGBImageRec;其中有三个成员,一个是读取的位图文件的宽度(图像列数),第二个是位图文件的高度(图像行数),第三个是读取的图像数据的指针。读取位图的函数为:/ 装入位图文件Loads A Bitmap ImageAUX_RGBImageRec *LoadBitmap(char *Filename)/ 声明一个文件句柄用于打开文件FILE *File=NULL;/ File Handle / 文件名不能空if (!Filename)/ Make Sure A Filename Was Givenreturn NULL;/ 以只读方式打开文件测试文件是否能够打开File=fopen(Filename,r);/ Check To See If The File Exists/ 文件是否存在if (File)/ Does The File Exist?/ 存在,则关闭文件fclose(File);/ Close The Handle/ 装入测试过已存在的文件return auxDIBImageLoad(Filename);/ Load The Bitmap And Return A Pointer/ 文件装入失败,返回NULLreturn NULL;/ If Load Failed Return NULL2、指定纹理、设置纹理属性我们把这个功能封装成一个函数,取名为LoadTexture。其完整描述为/ 装入位图文件并作为纹理贴图int LoadTexture()/ Load Bitmaps And Convert To Texturesint Status=FALSE;/ Status Indicator/ 用于纹理的数据结构,存在于glaux.h中AUX_RGBImageRec *TextureImage=NULL;if (TextureImage=LoadBitmap(ImagesCoffeeBean.bmp)Status=TRUE;/ Set The Status To TRUEglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, TextureImage-sizeX, TextureImage-sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage-data);/ 重复和截取glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);/ 指定滤波方式glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL);if (TextureImage)/ If Texture Existsif (TextureImage-data)/ If Texture Image Existsfree (TextureImage-data);/ Free The Texture Image Memoryfree(TextureImage);/ Free The Image Structurereturn Status;/ Return The Status一个相关的完整例子见【综合示例7-2】。7.6 指定纹理映射方式上面的示例中,我们都是直接把纹理图像中像素颜色直接渲染到多边形的表面。不过也可以用纹理图像中的值来调整表面原来的颜色,或把纹理图像中的值和表面原来的颜色以某种方式混合起来。使用函数glTexEnv*()来指定纹理映射方式。glTexEnv*()的函数原型是:void glTexEnvf( GLenum target, GLenum pname, GLfloat param );void glTexEnvi( GLenum target, GLenum pname, GLint param );参数target可取GL_TEXTURE_ENV。参数pname的取值可以是GL_TEXTURE_ENV_MODEGL_TEXTURE_LOD_BIASGL_COMBINE_RGBGL_COMBINE_ALPHAGL_SRC0_RGBGL_SRC1_RGBGL_SRC2_RGBGL_SRC0_ALPHAGL_SRC1_ALPHAGL_SRC2_ALPHAGL_OPERAND0_RGBGL_OPERAND1_RGBGL_OPERAND2_RGBGL_OPERAND0_ALPHAGL_OPERAND1_ALPHAGL_OPERAND2_ALPHAGL_RGB_SCALEGL_ALPHA_SCALEGL_COORD_REPLACE若参数pname是GL_TEXTURE_ENV_MODE,则参数param可以是GL_DECAL、GL_MODULATE或GL_BLEND,GL_BLEND、GL_ADD、GL_COMBINE,以说明纹理值怎样与原来表面颜色的相互作用;若参数pname是GL_TEXTURE_ENV_COLOR,则参数param是包含四个浮点数(分别是R、G、B、A分量)的数组,这些值在采用GL_BLEND纹理函数时会用到。纹理映射是以RGBA方式进行的,但有些内部格式不是RGB,表7-5说明了各种纹理格式是如何转化为RGBA颜色值的。表7-5 将种纹理值转换为颜色值纹理内部格式转换后的颜色值ALPHA值GL_ALPHA(0, 0, 0) AtGL_LUMINANCE( Lt, Lt, Lt ) 1 GL_LUMINANCE_ALPHA( Lt, Lt, Lt ) AtGL_INTENSITY( It, It, It ) ItGL_RGB( Rt, Gt, Bt ) 1 GL_RGBA( Rt, Gt, Bt ) At表7-6、表7-7列出了纹理内部格式和纹理映射方式相互作用下,颜色是如何计算的。表7-6 纹理映射方式:替换、调整、贴花纹理内部格式颜色及A值GL_REPLACE模式GL_MODULATE模式GL_DECAL模式GL_ALPHAC=CsrcCsrc未定义A=AtexAsrcAtexGL_LUMINANCEC=CtexCsrcCtex未定义A=AsrcAsrcGL_LUMINANCE_ALPHAC=CtexCsrcCtex未定义A=AtexAsrcAtexGL_INTENSITYC=CtexCsrcCtex未定义A=AtexAsrcAtexGL_RGBC=CtexCsrcCtexCtexA=AsrcAsrcAsrcGL_RGBAC=CtexCsrcCtexCsrc(1-Atex)+CtexAtexA=AtexAsrcAtexAsrc表7-6中各下标的含义:src表示片元值;tex表示据表7-5计算得到的纹理颜色值。c表示GL_TEXTURE_ENV_COLOR设定的值。表7-7 纹理映射方式:混合、相加纹理内部格式颜色及A值GL_BLEND模式GL_ADD模式GL_ALPHAC=CsrcCsrcA=Av=AsrcAtexAsrcAtexGL_LUMINANCEC=Csrc(1-Ctex)+CcCtexCsrc+CtexA=AsrcAsrcGL_LUMINANCE_ALPHAC=Csrc(1-Ctex)+CcCtexCsrc+CtexA=AsrcAtexAsrcAtexGL_INTENSITYC=Csrc(1-Ctex)+CcCtexCsrc+CtexA=Asrc(1-Atex)+AcAtexAsrc+AtexGL_RGBC=Csrc(1-Ctex)+CcCtexCsrc+CtexA=AsrcAsrcGL_RGBAC=Csrc(1-Ctex)+CcCtexCsrc+CtexA=AsrcAtexAsrcAtex表7-7中各下标的含义:src表示片元值;tex表示据表7-5计算得到的纹理颜色值。c表示GL_TEXTURE_ENV_COLOR设定的值。7.7 自动生成纹理坐标OpenGL有着强大的自动为物体生成纹理坐标的机制,生成方式是依靠glTexGen*函数,其定义如下:void glTexGenifv( GLenum coord , GLenum pname , TYPE param ) ;第一个参数coord必须是GL_S、GL_T、GL_R或GL_Q,它指出纹理坐标s,t,r,q中的哪一个要自动产生。 第二个参数pname值为GL_TEXTURE_GEN_MODE、GL_OBJECT_PLANE或 GL_EYE_PLANE。第三个参数param是一个定义纹理产生参数的指针,其值取决于第二个参数pname的设置。当pname为GL_TEXTURE_GEN_MODE时,param是一个常量,即GL_OBJECT_LINEAR、GL_EYE_LINEAR或GL_SPHERE_MAP或GL_REFLECTION_MAP或GL_NORMAL_MAP,它们决定用哪一个函数来产生纹理坐标。对于pname的其它可能值,param是一个指向参数数组的指针。7.7.1 自动生成纹理过程自动生成纹理的过程是:1、用glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,)设定生成纹理的平面参考方式。它可以是GL_EYE_LINEAR或者GL_OBJECT_LINEAR,即用视平面或者物体平面做参考。当把纹理图像映射到固定物体上时,使用物体坐标来指定参考平面最合适。所以把木纹映射到桌面时,可用如下语句:glTexGeni(GL_S , GL_TEXTURE_GEN_MODE ,GL_OBJECT_LINEAR)在移动的物体上生成动态等高线时,使用如下语句:glTexGeni(GL_S , GL_TEXTURE_GEN_MODE ,GL_EYE_LINEAR)2、用glTexGenfv(GL_S,GL_OBJECT_PLANE , param)来设定这个平面,param为p1,p2,p3,p4,最后生成纹理坐标= p1x0 + p2y0 + p3z0 + p4w0,这个param其实就是平面方程的参数。3、当glTexGenfv(GL_S,GL_EYE_PLANE , param)来设定这个平面,param为p1,p2,p3,p4,最后生成纹理坐标= ,这个param其实就是平面方程的参数。其中,视平面与物体平面的区别就是视平面中纹理坐标是相对于视坐标系的,视角变了纹理坐标也就随着变了。有关自动生成纹理的例子见【综合示例EP7-3】。7.8 多重纹理OpenGL多重纹理可以让一个场景中有多个不同纹理。其关键点是:1、定义多个纹理名称存放数组GLuinttexture5;/ Storage For One Texture 2、生成多个可用的纹理名称glGenTextures(4, &texture0);/ Create The Texture3、创建和绑定纹理对象glBindTexture(GL_TEXTURE_2D, texture0);初次使用它绑定一个纹理名时,将创建一个新的纹理对象;再次绑定一个纹理对象时,其中的数据将成为当前纹理状态(以前绑定的纹理状态将被替换掉)。多重纹理的一个例子见【综合示例EP7-4】。【综合示例EP7-1】生成一个6464的黑白棋盘图像,并把它作为纹理应用于透视环境下的四边形纹理贴图。并把默认的重复模式改为截取模式,观察结果。纹理重复模式下的运行结果如图7-5所示。图7-5 简单重复纹理#include stdafx.h/ 纹理尺寸#define checkImageWidth 64 / 宽度(二维图像的列数)#define checkImageHeight 64 / 高度(二维图像的行数)/ 纹理数组GLubyte checkImagecheckImageHeightcheckImageWidth3;int nAngleY=0;/ 沿Y轴旋转的角度int nAngleX=0;/ 沿X轴旋转的角度int nAngleZ=0;/ 沿Z轴旋转的角度/ 生成纹理函数(黑白棋盘)void makeCheckImage(void)int i, j, r, c;for (i = 0; i checkImageHeight; i+)for (j = 0; j checkImageWidth ; j+)c = (i&0x8)=0)(j&0x8)=0)*(255-i*2);checkImageij0 = (GLubyte) c;checkImageij1 = (GLubyte) c;checkImageij2 = (GLubyte) c;void CALLBACK ClockwiseRotateByX()nAngleX-;void CALLBACK CounterClockwiseRotateByX()nAngleX+;void CALLBACK ClockwiseRotateByZ()nAngleZ-;void CALLBACK CounterClockwiseRotateByZ()nAngleZ+;void CALLBACK ClockwiseRotateByY()nAngleY-;void CALLBACK CounterClockwiseRotateByY()nAngleY+;void myinit (void) /* 将背景清为白色 */glClearColor (0.0, 0.0,0.0, 1.0);glShadeModel (GL_SMOOTH);makeCheckImage(); / 点存储对齐格式glPixelStorei(GL_UNPACK_ALIGNMENT, 1); / 指定纹理glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, checkImageWidth, checkImageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, checkImage); / 重复和截取glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);/ 重复glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);/ 重复/ 指定滤波方式glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); / 纹理映射起作用glEnable(GL_TEXTURE_2D); void CALLBACK reshape(GLsizei w, GLsizei h) if (!h) return; glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity();gluPerspective(60.0, 1.0*(GLfloat)w/(GLfloat)h, 1.0, 600.0); glMatrixMode(GL_MODELVIEW);void CALLBACK display(void)glLoadIdentity(); glClear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);/清除背景glTranslatef(0,0,-260);glRotated(nAngleX,1,0,0);glRotated(nAngleY,0,1,0);glRotated(nAngleZ,0,0,1); glLineStipple(1, 0x3F07); / 指定点划格式 glEnable(GL_LINE_STIPPLE); / 进入点划模式glBegin(GL_LINES);/ X轴:红 glColor3f (1.0, 0, 0); glVertex3d(-490,0,0);glVertex3d(490,0,0);/ Y轴:绿 glColor3f (0.0, 1.0, 0); glVertex3d(0,-490,0);glVertex3d(0,490,0);/ Z轴:蓝 glColor3f (0.0, 0.0, 1); glVertex3d(0,0,-490);glVertex3d(0,0,490);glEnd(); glDisable(GL_LINE_STIPPLE);/离开点划模式glBegin(GL_QUADS); / 在纹理的两个方向上均重复四次glTexCoord2f(0.0, 0.0); glVertex3f(-200.0, -100.0, 0.0); glTexCoord2f(0.0, 4.0); glVertex3f(-200.0, 100.0, 0.0); glTexCoord2f(4.0, 4.0); glVertex3f(0.0, 100.0, 0.0); glTexCoord2f(4.0, 0.0); glVertex3f(0.0, -100.0, 0.0); / 不重复(或者说重复一次)glTexCoord2f(0.0, 0.0); glVertex3f(100.0, -100.0, 0.0); glTexCoord2f(0.0, 1.0); glVertex3f(100.0, 100.0, 0.0); glTexCoord2f(1.0, 1.0); glVertex3f(241.421, 100, -141.421); glTexCoord2f(1.0, 0.0); glVertex3f(241.421, -100,-141.421); glEnd(); auxSwapBuffers(); int _tmain(int argc, _TCHAR* argv) auxInitDisplayMode (AUX_DOUBLE | AUX_RGBA); auxInitPosition (0, 0, 1000, 700); auxInitWindow (OpenGL简单纹理贴图); myinit ();auxKeyFunc (AUX_LEFT, ClockwiseRotateByY); auxKeyFunc (AUX_RIGHT, CounterClockwiseRotateByY); auxKeyFunc (AUX_UP, ClockwiseRotateByX); auxKeyFunc (AUX_DOWN, CounterClockwiseRotateByX); auxKeyFunc (AUX_D, ClockwiseRotateByZ); auxKeyFunc (AUX_d, ClockwiseRotateByZ); auxKeyFunc (AUX_U, CounterClockwiseRotateByZ); auxKeyFunc (AUX_u, CounterClockwiseRotateByZ);auxReshapeFunc(reshape);/回调函数 auxMainLoop(display); return 0;【综合示例EP7-2】创建一个位图CoffeeBean.bmp,生成Win32控制台项目,然后在项目中创建一个子目录Images,把位图文件拷贝到该目录下。程序中读入该文件作为纹理贴图,创建一个六面体,所有面均贴上刚刚创建的纹理。完整代码如下,其中加粗部分为新学的代码:图7-4 载入位图作为纹理#include stdafx.h#include #include int nAngleY=0;/ 沿Y轴旋转的角度int nAngleX=0;/ 沿X轴旋转的角度int nAngleZ=0;/ 沿Z轴旋转的角度/ 装入位图文件Loads A Bitmap ImageAUX_RGBImageRec *LoadBitmap(char *Filename)/ 声明一个文件句柄用于打开文件FILE *File=NULL;/ File Handle / 文件名不能空if (!Filename)/ Make Sure A Filename Was Givenreturn NULL;/ 以只读方式打开文件测试文件是否能够打开File=fopen(Filename,r);/ Check To See If The File Exists/ 文件是否存在if (File)/ Does The File Exist?/ 存在,则关闭文件fclose(File);/ Close The Handle/ 装入测试过已存在的文件return auxDIBImageLoad(Filename);/ Load The Bitmap And Return A Pointer/ 文件装入失败,返回NULLreturn NULL;/ If Load Failed Return NULL/ 装入位图文件并作为纹理贴图int LoadTexture()/ Load Bitmaps And Convert To Texturesint Status=FALSE;/ Status Indicator/ 用于纹理的数据结构,存在于glaux.h中AUX_RGBImageRec *TextureImage=NULL;/ Create Storage Space For The Texture/ 变量TextureImage内部成员均清零/memset(TextureIm
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 实验小学突发停电事故应急预案10篇
- 水表井安全知识培训内容课件
- 人防物资调配与储存管理方案
- 小学五年级英语上册Unit5单元重难点知识速记与巧练(含答案)
- 氢能产业园氢能燃料电池商业化推广策略
- 隧道水文勘察与分析
- 学生宿舍节能减排技术应用方案
- 建筑工程项目施工现场卫生管理方案
- 水电站安全知识培训内容课件
- 知识点3.2造型要素设计构成设计造型75课件
- 生物制品生产工艺过程变更管理技术指导原则
- 建筑施工现场签证单(模板)
- GBZ(卫生) 49-2014职业性噪声聋的诊断
- GB/T 9729-2007化学试剂氯化物测定通用方法
- GB/T 7588.2-2020电梯制造与安装安全规范第2部分:电梯部件的设计原则、计算和检验
- GB/T 13560-2017烧结钕铁硼永磁材料
- 三视图及尺寸标注课件
- 混凝土配合比验证检验委托书模板
- 住房公积金投诉申请书
- 众辰变频器说明书3400
- 小学教师量化考核表
评论
0/150
提交评论