欢迎来到三一办公! | 帮助中心 三一办公31ppt.com(应用文档模板下载平台)
三一办公
全部分类
  • 办公文档>
  • PPT模板>
  • 建筑/施工/环境>
  • 毕业设计>
  • 工程图纸>
  • 教育教学>
  • 素材源码>
  • 生活休闲>
  • 临时分类>
  • ImageVerifierCode 换一换
    首页 三一办公 > 资源分类 > DOC文档下载  

    图形学实验5资料.doc

    • 资源ID:4945728       资源大小:360.14KB        全文页数:13页
    • 资源格式: DOC        下载积分:20金币
    快捷下载 游客一键下载
    会员登录下载
    三方登录下载: 微信开放平台登录 QQ登录  
    下载资源需要20金币
    邮箱/手机:
    温馨提示:
    用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP免费专享
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    图形学实验5资料.doc

    数字图像处理实验指导书3D游戏图形学实验报告书(实验五)姓名: 学号:班级:浙江理工大学二一二 年 十二 月2实验五 纹理映射实验一、实验目的和要求掌握纹理映射的基本原理,利用VC+ OpenGL实现纹理映射技术。二、 实验原理纹理映射是真实感图形制作的一个重要部分,运用纹理映射可以方面地制作真实感图形,而不必花更多的时间去考虑物体的表面纹理。如一张木制桌子其表面的木纹是不规范的,看上去又是那么自然,如果在图形制作中不用纹理映射,那么只是这张桌面纹理的设计,就要花费很大精力,而且设计结果也未必能像现实中那么自然。如果运用纹理映射就非常方便,可以用扫描仪将这样的一张桌子扫成一个位图。然后的具体的操作中,只需把桌面形状用多边形画出来,把桌面纹理贴上去就可以了。另外,纹理映射能够在多边形进行变换时仍保证纹理的图案与多边形保持一致性。例如,以透视投影方式观察墙面时,远端的砖会变小,而近处的砖就会大一些。此外,纹理映射也可以用于其他方面。例如,使用一大片植被的图像映射到一些连续的多边形上,以模拟地貌,或者以大理石、木纹等自然物质的图像作为纹理映射到相应的多边形上,作为物体的真实表面。在OpenGL中提供了一系列完整的纹理操作函数,用户可以用它们构造理想的物体表面,可以对光照物体进行处理,使其映射出所处环境的景象,可以用不同方式应用到曲面上,而且可以随几何物体的几何属性变换而变化,从而使制作的三维场景和三维物体更真实更自然。在OpenGL中要实现纹理映射,需要经历创建纹理、指定纹理应用方式、启用纹理映射、使用纹理坐标和几何坐标绘制场景几个过程。用于指定一维、二维和三维纹理的函数分别为:Void glTexImage1D(GLenum target, Glint level, Glint components, GLsizei width, Glint border, GLenum format, GLenum type, const GLvoid *texels);Void glTexImage2D(GLenum target, Glint level, Glint components, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *texels);Void glTexImage3D(GLenum target, Glint level, Glint components, GLsizei width, GLsizei height, GLsizei depth, Glint border, GLenum format, GLenum type, const GLvoid *texels);其中,参数target取值一般为GL_TEXTURE_1D, GL_TEXTURE_2D和GL_TEXTURE_3D,分别与一维、二维和三维的纹理相对应。参数Level表示纹理多分辨率层数,通常取值为0,表示只有一种分辨率。参数components的可能取值为14的整数以及多种符号常量(如GL_RGBA),表示纹理元素中存储的哪些分量(RGBA颜色、深度等)在纹理映射中被使用,1表示使用R颜色分量,2表示使用R和A颜色分量,3表示使用RGB颜色分量,4表示使用RGBA颜色分量。参数width,height,depth分别指定纹理的宽度、高度、深度。参数format和type表示给出的图像数据的数据格式和数据类型,这两个参数的取值都是符号常量(比如format指定为GL_RGBA,type指定为GL_UNSIGNED_BYTE,参数texels指向内存中指定的纹理图像数据。在定义了纹理之后,需要启用纹理的函数:glEnable(GL_TEXTURE_1D);glEnable(GL_TEXTURE_2D);glEnable(GL_TEXTURE_3D);在启用纹理之后,需要建立物体表面上点与纹理空间的对应关系,即在绘制基本图元时,在glVertex函数调用之前调用glTexCoord函数,明确指定当前顶点所对应的纹理坐标,例如:glBegin(GL_TRIANGLES); glTexCoord2f(0.0, 0.0); glVertex2f(0.0, 0.0); glTexCoord2f(1.0, 1.0); glVertex2f(15.0, 15.0);glTexCoord2f(1.0, 0.0); glVertex2f(30.0, 0.0);glEnd();其图元内部点的纹理坐标利用顶点处的纹理坐标采用线性插值的方法计算出来。在OpenGL中,纹理坐标的范围被指定在0,1之间,而在使用映射函数进行纹理坐标计算时,有可能得到不在0,1之间的坐标。此时OpenGL有两种处理方式,一种是截断,另一种是重复,它们被称为环绕模式。在截断模式(GL_CLAMP)中,将大于1.0的纹理坐标设置为1.0,将小于0.0的纹理坐标设置为0.0。在重复模式(GL_REPEAT)中,如果纹理坐标不在0,1之间,则将纹理坐标值的整数部分舍弃,只使用小数部分,这样使纹理图像在物体表面重复出现。例如,使用下面的函数:glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);分别指定二维纹理中s坐标采用截断或重复处理方式。另外,在变换和纹理映射后,屏幕上的一个像素可能对应纹理元素的一小部分(放大),也可能对应大量的处理元素(缩小)。在OpenGL中,允许指定多种方式来决定如何完成像素与纹理元素对应的计算方法(滤波)。比如,下面的函数可以指定放大和缩小的滤波方法:glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);其中,glTexParameteri函数的第一个参数指定使用的是一维、二维或三维纹理;第二个参数为GL_TEXTURE_MAG_FILTER或GL_TEXTURE_MIN_FILTER,指出要指定缩小还是放大滤波算法;最后一个参数指定滤波的方法。补充:透视投影函数void gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar);它也创建一个对称透视视景体,但它的参数定义于前面的不同。其操作是创建一个对称的透视投影矩阵,并且用这个矩阵乘以当前矩阵。参数fovy定义视野在X-Z平面的角度,范围是0.0,180.0;参数aspect是投影平面宽度与高度的比率;参数zNear和Far分别是远近裁剪面沿Z负轴到视点的距离,它们总为正值。三、 实验内容在OpenGL中纹理映射所使用的纹理数据,既可以是程序生成的一组数据,也可以从外部文件中直接读取,参考示范代码完成以下两项内容:1. 利用直接创建纹理的方法生成二维纹理并映射到四边形上。参考代码:void makeImage(void) int i, j, r,g,b; for (i = 0; i < ImageWidth; i+) for (j = 0; j < ImageHeight; j+) r=(i*j)%255;g=(4*i)%255;b=(4*j)%255;Imageij0 = (GLubyte) r;Imageij1 = (GLubyte) g;Imageij2 = (GLubyte) b; void myinit(void) glClearColor (0.0, 0.0, 0.0, 0.0); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS);/ 生成纹理数据 makeImage();/ 设置像素存储模式 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);/ 定义二维纹理映射 glTexImage2D( );/ 定义纹理映射参数 glTexParameterf(); glTexParameterf(); glTexParameterf(); glTexParameterf();/ 启用二维纹理 glEnable(GL_TEXTURE_2D); glShadeModel(GL_FLAT);void display(void)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);/绘制四边形,并完成纹理映射 glFlush();void myReshape(GLsizei w, GLsizei h) void main(int argc, char* argv) 2. 从外部文件中直接读取纹理实现正方体每个面的纹理映射,并使正方体转动。整个过程需要三个步骤:创建纹理、启用纹理映射和使用纹理坐标和几何坐标绘制,下面我们对三个过程进行阐述,并给出参考代码。1)创建纹理对象并绑定纹理纹理创建即在内存中创建保存纹理数据的数组,一般是先读入一个图像文件,将图像文件的RGBA信息存入我们创建的纹理空间中,当然图像的位图不同,创建的纹理空间结构也会有所不同。为了更加简单易懂地实现这个过程,我们使用未压缩的纹理。代码:GLuinttexture1; /创建一个纹理空间AUX_RGBImageRec *LoadBMP(CHAR *Filename) /载入位图图像FILE *File=NULL; /文件句柄if(!Filename) /确保文件名已提供return NULL;File=fopen(Filename, "r"); /尝试打开文件if(File) fclose(File); /关闭文件return auxDIBImageLoadA(Filename); /载入位图并返回指针return NULL; /如果载入失败,返回NULLint LoadGLTextures() /载入位图并转换成纹理int Status=FALSE; /状态指示器AUX_RGBImageRec *TextureImage1; /创建纹理的存储空间memset(TextureImage, 0, sizeof(void *)*1);/初始化/载入位图,检查有无错误,如果位图没找到则退出if(TextureImage0=LoadBMP("data.bmp")Status=TRUE;glGenTextures(1,&texture0); /创建纹理/使用来自位图数据生成的典型纹理glBindTexture(GL_TEXTURE_2D, texture0); /生成2D纹理glTexImage2D(GL_TEXTURE_2D,0,3,TextureImage0->sizeX,TextureImage0->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage0->data);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);if(TextureImage0) /纹理是否存在if(TextureImage0->data) /纹理图像是否存在free(TextureImage0->data); /释放纹理图像占用的内存free(TextureImage0); /释放图像结构return Status; /返回Status2)启用纹理映射操作,初始化相关参数在OpenGL中使用纹理映射之前,必须打开纹理映射。int InitGL(GLvoid)if(!LoadGLTextures() /调用纹理载入子例程return FALSE;glEnable(GL_TEXTURE_2D); /启用纹理映射glShadeModel(GL_SMOOTH); /启用阴影平滑glClearColor(0.0f, 0.0f, 0.0f, 0.5f); /黑色背景glClearDepth(1.0f); /设置深度缓存glEnable(GL_DEPTH_TEST); /启用深度测试return TRUE;3)使用纹理坐标和几何坐标绘制void DrawGLScene(void)glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);glLoadIdentity();glTranslatef(0.0f,0.0f,-5.0f);glRotatef(xrot,1.0f,0.0f,0.0f);glRotatef(yrot,0.0f,1.0f,0.0f);glRotatef(zrot,0.0f,0.0f,1.0f);/ 选择纹理glBindTexture(GL_TEXTURE_2D,texture0);/绘制一个正方体,给每个面贴上纹理,并使之转动glBegin(GL_QUADS);glEnd(); xrot+=0.3f; yrot+=0.2f; zrot+=0.4f;四、 实验代码1、利用直接创建纹理的方法生成二维纹理并映射到四边形上。#include <stdlib.h>#include <GL/glut.h> #define imageWidth 64#define imageHeight 64GLubyte imageimageWidthimageHeight3; /*绘制一个简单的二维纹理图*/void makeImage(void)int i,j,r,g,b; /*根据点的位置设置不同的颜色*/for(i = 0;i < imageWidth;i+) for(j = 0;j <imageHeight;j+) r = (i*j)%255; g = (i*i)%255; b = (j*j)%255; imageij0 = (GLubyte)r; imageij1 = (GLubyte)g; imageij2 = (GLubyte)b; void myInit(void)glClearColor(0.0,0.0,0.0,0.0);glEnable(GL_DEPTH_TEST);glDepthFunc(GL_LESS);/ 生成纹理数据makeImage();/ 设置像素存储模式glPixelStorei(GL_UNPACK_ALIGNMENT,1);/*指定二维纹理映射*/glTexImage2D(GL_TEXTURE_2D,0,3,imageWidth,imageHeight,0,GL_RGB,GL_UNSIGNED_BYTE,&image000);/纹理过滤函数/*GL_TEXTURE_2D: 操作D纹理.GL_TEXTURE_WRAP_S: S方向上的贴图模式.GL_CLAMP: 将纹理坐标限制在.0,1.0的范围之内.如果超出了会如何呢.不会错误,只是会边缘拉伸填充. GL_TEXTURE_MAG_FILTER: 放大过滤GL_LINEAR: 线性过滤, 使用距离当前渲染像素中心最近的个纹素加权平均值. GL_TEXTURE_MIN_FILTER: 缩小过滤GL_LINEAR_MIPMAP_NEAREST: 使用GL_NEAREST对最接近当前多边形的解析度的两个层级贴图进行采样,然后用这两个值进行线性插值.*/glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);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);glShadeModel(GL_FLAT);void myDisplay(void)glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);/*将纹理映射到四边形上*/glBegin(GL_QUADS);/*纹理的坐标和四边形顶点的对应*/glTexCoord2f(0.0,0.0); glVertex3f(-0.7,-0.25,0.0);glTexCoord2f(0.0,1.0); glVertex3f(-0.2,-0.25,0.0);glTexCoord2f(1.0,1.0); glVertex3f(-0.2,0.25,0.0);glTexCoord2f(1.0,0.0); glVertex3f(-0.7,0.25,0.0);glTexCoord2f(0.0,0.0); glVertex3f(0.2,-0.25,1.875);glTexCoord2f(0.0,1.0); glVertex3f(0.6,-0.25,0.0);glTexCoord2f(1.0,1.0); glVertex3f(0.6,0.25,0.125);glTexCoord2f(1.0,0.0); glVertex3f(0.2,0.25,2.0);glEnd();glFlush();void myReshape(int w,int h)glViewport(0,0,(GLsizei)w,(GLsizei)h);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(80.0,1.0-(GLfloat)w/(GLfloat)h,1.0,30.0);glMatrixMode(GL_MODELVIEW);glLoadIdentity();int main(int argc,char *argv)/*初始化*/glutInit(&argc,argv);glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);glutInitWindowSize(400,400);glutInitWindowPosition(200,200);glutCreateWindow(" Texture ");/创建窗口myInit();/绘制与显示glutReshapeFunc(myReshape);glutDisplayFunc(myDisplay);glutMainLoop();return 0;2、从外部文件中直接读取纹理实现正方体每个面的纹理映射,并使正方体转动。#include <GL/glut.h> #include <GL/glaux.h> #include <stdio.h> #include <stdlib.h> #include <windows.h> #pragma comment(lib, "openGL32.lib")#pragma comment(lib, "glu32.lib")#pragma comment(lib, "glaux.lib")#pragma comment( lib,"openGL32.lib" ) GLuint texture1;/创建纹理空间 GLfloat xRot,yRot,zRot;/控制正方体的旋转/载入位图图像 AUX_RGBImageRec *LoadBMP(CHAR *Filename) /载入位图图像FILE *File=NULL; /文件句柄if(!Filename) /确保文件名已提供return NULL;File=fopen(Filename, "r"); /尝试打开文件if(File) fclose(File); /关闭文件return auxDIBImageLoadA(Filename); /载入位图并返回指针return NULL; /如果载入失败,返回NULLint LoadGLTextures() /载入位图并转换成纹理int Status=FALSE; /状态指示器AUX_RGBImageRec *TextureImage1; /创建纹理的存储空间memset(TextureImage, 0, sizeof(void *)*1);/初始化/载入位图,检查有无错误,如果位图没找到则退出if(TextureImage0=LoadBMP("data.bmp")Status=TRUE;glGenTextures(1,&texture0); /创建纹理/使用来自位图数据生成的典型纹理glBindTexture(GL_TEXTURE_2D, texture0); /生成D纹理glTexImage2D(GL_TEXTURE_2D,0,3,TextureImage0->sizeX,TextureImage0->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage0->data);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);if(TextureImage0) /纹理是否存在if(TextureImage0->data) /纹理图像是否存在free(TextureImage0->data); /释放纹理图像占用的内存free(TextureImage0); /释放图像结构return Status; /返回Status int InitGL(GLvoid)if(!LoadGLTextures() /调用纹理载入子例程return FALSE;glEnable(GL_TEXTURE_2D); /启用纹理映射glShadeModel(GL_SMOOTH); /启用阴影平滑glClearColor(0.0f, 0.0f, 0.0f, 0.5f); /黑色背景glClearDepth(1.0f); /设置深度缓存glEnable(GL_DEPTH_TEST); /启用深度测试return TRUE; void display() glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glTranslatef(0.0f,0.0f,-5.0f); glRotatef(xRot,1.0f,0.0f,0.0f); glRotatef(yRot,0.0f,1.0f,0.0f); glRotatef(zRot,0.0f,0.0f,1.0f); /绘制正方体,贴上纹理并使之转动 glBindTexture(GL_TEXTURE_2D,texture0); /选择纹理 glBegin(GL_QUADS); /前 glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glEnd(); glBindTexture(GL_TEXTURE_2D,texture0); glBegin(GL_QUADS); /后 glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); glEnd(); glBindTexture(GL_TEXTURE_2D,texture0); glBegin(GL_QUADS); / 上 glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); glEnd(); glBindTexture(GL_TEXTURE_2D,texture0); glBegin(GL_QUADS); /下 glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); glEnd(); glBindTexture(GL_TEXTURE_2D,texture0); glBegin(GL_QUADS); /右 glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); glEnd(); glBindTexture(GL_TEXTURE_2D,texture0); glBegin(GL_QUADS); /左 glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glEnd(); glutPostRedisplay(); glutSwapBuffers(); void reshape(int w,int h) if (0 = h) h = 1; glViewport(0,0,(GLsizei)w,(GLsizei)h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0f,(GLfloat)w / (GLfloat)h,1,100); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); void spinDisplay(void) xRot += 0.2f; yRot += 0.2f; glutPostRedisplay();void mouse(int button, int state, int x, int y) /鼠标监听 switch (button) case GLUT_LEFT_BUTTON: if (state = GLUT_DOWN) glutIdleFunc(spinDisplay); /设备空闲时调用的函数 break; case GLUT_MIDDLE_BUTTON: case GLUT_RIGHT_BUTTON: if (state = GLUT_DOWN) glutIdleFunc(NULL); break; default: break; int main(int argc,char* argv) glutInit(&argc,argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize(400,400);

    注意事项

    本文(图形学实验5资料.doc)为本站会员(小飞机)主动上传,三一办公仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知三一办公(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    备案号:宁ICP备20000045号-2

    经营许可证:宁B2-20210002

    宁公网安备 64010402000987号

    三一办公
    收起
    展开