二维纹理映射_第1页
二维纹理映射_第2页
二维纹理映射_第3页
二维纹理映射_第4页
二维纹理映射_第5页
已阅读5页,还剩2页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、二维纹理映射实验目的和要求掌握纹理映射的基本原理,利用 VC+ OpenG吹现纹理映射技术。实验原理纹理映射是真实感图形制作的一个重要部分,运用纹理映射可以方面地制作真实感图形,而不必花更多的时间去考虑物体的表面纹理。如一张木制桌子其表面的木纹是不规范的,看上去又是那么自然, 如果在图形制作中不用纹理映射,那么只是这张桌面纹理的设计,就要花费很大精力,而且设计结果也未必能像现实中那么自然。如果运用纹理映射就非常方便,可以用扫描仪将这样的一张桌子扫成一个位图。然后的具体的操作中,只需把桌面形状用多边形画出来,把桌面纹理贴上去就可以了。另外,纹理映射能够在多边形进行变换时仍保证纹理的图案与多边形保

2、持一致性。例如,以透视投影方式观察墙面时,远端的砖会变小,而近处的砖就会大一些。此外,纹理映射也可以用于其他方面。例如,使用一大片植被的图像映射到一些连续的多边形上,以模拟地貌,或者以大理石、木纹等自然物质的图像作为纹理映射到相应的多边形上,作为物体的真实表面。在OpenG冲提供了一系列完整的纹理操作函数,用户可以用它们构造理想的物体表面,可以对光照物体进行处理,使其映射出所处环境的景象,可以用不同方式应用到曲面上,而且可以随几何物体的几何属性变换而变化,从而使制作的三维场景和三维物体更真实更自然。在OpenG冲要实现纹理映射,需要经历创建纹理、指定纹理应用方式、启用纹理映射、使用纹理坐标和几

3、何坐标绘制场景几个过程。用于指定一维、二维和三维纹理的函数分别为: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,

4、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_2BSL_TEXTURE_3D分别与一维、二维和三维的纹理相对应。参数 Level表示纹理多

5、分辨率层数,通常取值为0,表示只有一种分辨率。参数components的可能取值为14的整数以及多种符号常量 (如GL_RGBA)表示纹理元素中存储的哪些分量(RGB颜色、深度等)在纹理映射中被使用,1表示使用 赫色分量,2表示使用M口A颜色分量,3表示使用RG颜色分量,4表示使用RGBAM色分量。参数width , height , depth分别指定纹理的宽度、高度、深 度。参数format和type表示给出的图像数据的数据格式和数据类型,这两个参数的取值都是符号常量(比如format指定为GL_RGBA,typ&f定为GL_UNSIGNED_BYT以数texels指向内存中指定的

6、纹理图像数据。在定义了纹理之后,需要启用纹理的函数: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.

7、0);glTexCoord2f(1.0, 0.0); glVertex2f(30.0, 0.0);glEnd();其图元内部点的纹理坐标利用顶点处的纹理坐标采用线性插值的方法计算出来。在OpenG冲,纹理坐标的范围被指定在0,1之间,而在使用映射函数进行纹理坐标计算时,有可能得到不在0,1之间的坐标。此时 OpenGLt两种处理方式,一种是截断,另一种是重复,它们被称为环绕模式。在截断模式(GL_CLAMP中,将大于1.0的纹理坐标设置为1.0,将小于0.0的纹理坐标设置 为0.0。在重复模式(GL_REPEAT中,如果纹理坐标不在0,1之间,则将纹理坐标值的整数部分舍弃, 只使用小数部分,这

8、样使纹理图像在物体表面重复出现。例如,使用下面的函数:glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);分别指定二维纹理中s坐标采用截断或重复处理方式。另外,在变换和纹理映射后,屏幕上的一个像素可能对应纹理元素的一小部分(放大),也可能对应大量的处理元素(缩小)。在OpenG仲,允许指定多种方式来决定如何完成像素与纹理元素对应的计 算方法(滤波)。比如,下面的函数可以指定放大和缩小的滤波方法:glTexP

9、arameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);其中,glTexParameteri函数的第一个参数指定使用的是一维、二维或三维纹理;第二个参数为GL_TEXTURE_MAG_FILTEGL_TEXTURE_MIN_FILTE R旨出要指定缩小还是放大滤波算法;最后一个参数指定滤波的方法。补充:透视投影函数void gluPerspective(GLdouble fovy, GLdouble

10、aspect, GLdouble zNear, GLdouble zFar);它也创建一个对称透视视景体,但它的参数定义于前面的不同。其操作是创建一个对称的透视投影矩阵,并且用这个矩阵乘以当前矩阵。参数fovy定义视野在X-Z平面的角度,范围是0.0,180.0;参数aspect是投影平面宽度与高度的比率;参数zNear和Far分别是远近裁剪面沿 Z负轴到视点的距离,它们总为正值。三、实验内容在OpenGL中纹理映射所使用的纹理数据,既可以是程序生成的一组数据,也可以从 外部文件中直接读取,参考示范代码完成以下两项内容:源码(/ cgtest.cpp : Defines the entry p

11、oint for the console application./ test.cpp :定义控制台应用程序的入口点/#include <stdio.h>#include "glut.h"#include <math.h>#include <Windows.h>这是一个点的类,用于存储其中点的坐标class Pointpublic:int x, y;void setxy(int _x, int _y) x = _x;y = _y;);/点的数量static int POINTSNUM = 0;用于存储点的集合,因为绘制的都是4个点的贝塞尔

12、曲线,所以数组大小为static Point points4;初始化函数void init(void)glClearColor(1.0, 1.0, 1.0, 0); /校定背景为黑色glColor3f(0.0, 0.0, 0.0); 绘图颜色为白色glPointSize(2.0); /股定点的大小为2*2像素的glMatrixMode(GL_PROJECTION); /校定合适的矩阵glLoadIdentity(); /是一个无参的无信函数,其功能是用一个4X4的单位矩阵来替 换当前矩阵,实际上就是对当前矩阵进行初始化。也就是说,无论以前进行了多少次矩阵 变换,在该命令执行后,当前矩阵均恢复成

13、一个单位矩阵,即相当于没有进行任何矩阵变 换状态gluOrtho2D(0.0, 600.0, 0.0, 480.0); /平行投影,四个参数分别是 x,y范围/绘制点void setPoint(Point p) glBegin(GL_POINTS);glVertex2f(p.x, p.y);glEnd();glFlush();/绘制直线void setline(Point p1, Point p2) glBegin(GL_LINES);glVertex2f(p1.x, p1.y);glVertex2f(p2.x, p2.y);glEnd();glFlush();/绘制贝塞尔曲线Point se

14、tBezier(Point p1, Point p2, Point p3, Point p4, double t) Point p;double a1 = pow(1 - t), 3);double a2 = pow(1 - t), 2) * 3 * t;double a3 = 3 * t*t*(1 - t);double a4 = t*t*t;p.x = a1*p1.x + a2*p2.x + a3*p3.x + a4*p4.x;p.y = a1*p1.y + a2*p2.y + a3*p3.y + a4*p4.y;return p;)/display 函数void display()glC

15、lear(GL_COLOR_BUFFER_BIT);glFlush();)/鼠标事件void mymouseFunction(int button, int state, int x, int y) if (state = GLUT_DOWN) 如果鼠标按下,不区分左右键的pointsPOINTSNUM.setxy(x, 480 - y); 这里求鼠标点的坐标的时候/设置点的颜色,绘制点glColor3f(1.0, 0.0, 0.0);setPoint(pointsPOINTSNUM);/设置线的颜色,绘制线glColor3f(1.0, 0.0, 0.0);if (POINTSNUM >

16、 0) setline(pointsPOINTSNUM - 1, pointsPOINTSNUM);如果达到了 4个绘制贝塞尔曲线,并在之后给计数器清零 if (POINTSNUM = 3) 绘制贝塞尔曲线glColor3f(0.0, 0.0, 1.0); /设定贝塞尔曲线的颜色Point p_current = points0; / 设为起点 for (double t = 0.0; t <= 1.0; t += 0.05) Point P = setBezier(points0, points1, points2, points3, t); setline(p_current, P);p_current = P;POINTSNUM = 0;else POINTSNUM+;int main(int argc, char *argv)glutInit(&argc, argv); / 固定格式glutInitDisplayMode(GLUT_RGB | GLUT_SING

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论