《opengl计算机三维图形程序设计》纹理.pptx
OpenGL纹理(经典)
OpenGL纹理目录12.1 基本步骤12.2 纹理定义12.3 纹理控制12.4 映射方式12.5 纹理坐标在三维图形中,纹理映射(Texture Mapping)的方法运用得很广,尤其描述具有真实感的物体。
比如绘制一面砖墙,就可以用一幅真实的砖墙图像或照片作为纹理贴到一个矩形上,这样,一面逼真的砖墙就画好了。
如果不用纹理映射的方法,则墙上的每一块砖都必须作为一个独立的多边形来画。
另外,纹理映射能够保证在变换多边形时,多边形上的纹理图案也随之变化。
例如,以透视投影方式观察墙面时,离视点远的砖块的尺寸就会缩小,而离视点较近的就会大些。
此外,纹理映射也常常运用在其他一些领域,如飞行仿真中常把一大片植被的图像映射到一些大多边形上用以表示地面,或用大理石、木材、布匹等自然物质的图像作为纹理映射到多边形上表示相应的物体。
纹理映射有许多种情况。
例如,任意一块纹理可以映射到平面或曲面上,且对光亮的物体进行纹理映射,其表面可以映射出周围环境的景象;纹理还可按不同的方式映射到曲面上,一是可以直接画上去(或称移画印花法),二是可以调整曲面颜色或把纹理颜色与曲面颜色混合;纹理不仅可以是二维的,也可以是一维或其它维的。
本章将详细介绍OpenGL纹理映射有关的内容:基本步骤、纹理定义、纹理控制、映射方式和纹理坐标等。
12.1 基本步骤纹理映射是一个相当复杂的过程,这节只简单地叙述一下最基本的执行纹理映射所需的步骤。
基本步骤如下:1)定义纹理、2)控制滤波、3)说明映射方式、4)绘制场景,给出顶点的纹理坐标和几何坐标。
注意:纹理映射只能在RGBA方式下执行,不能运用于颜色表方式。
下面举出一个最简单的纹理映射应用例子:例12-1 简单纹理映射应用例程(texsmpl.c)#include "glos.h"#include <GL/gl.h>#include <GL/glu.h>#include <GL/glaux.h>void myinit(void);void makeImage(void);void CALLBACK myReshape(GLsizei w, GLsizei h);void CALLBACK display(void);/* 创建纹理 */#define ImageWidth 64#define ImageHeight 64GLubyte Image[ImageWidth][ImageHeight][3];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;Image[i][j][0] = (GLubyte) r;Image[i][j][1] = (GLubyte) g;Image[i][j][2] = (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, &Image[0][0][0]);/* 控制滤波 */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 CALLBACK display(void){glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);/* 设置纹理坐标和物体几何坐标 */glBegin(GL_QUADS);glTexCoord2f(0.0, 0.0); glVertex3f(-2.0, -1.0, 0.0);glTexCoord2f(0.0, 1.0); glVertex3f(-2.0, 1.0, 0.0);glTexCoord2f(1.0, 1.0); glVertex3f(0.0, 1.0, 0.0);glTexCoord2f(1.0, 0.0); glVertex3f(0.0, -1.0, 0.0);glTexCoord2f(0.0, 0.0); glVertex3f(1.0, -1.0, 0.0);glTexCoord2f(0.0, 1.0); glVertex3f(1.0, 1.0, 0.0);glTexCoord2f(1.0, 1.0); glVertex3f(2.41421, 1.0, -1.41421); glTexCoord2f(1.0, 0.0); glVertex3f(2.41421, -1.0, -1.41421); glEnd();glFlush();}void CALLBACK myReshape(GLsizei w, GLsizei h){glViewport(0, 0, w, h);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(60.0, 1.0*(GLfloat)w/(GLfloat)h, 1.0, 30.0); glMatrixMode(GL_MODELVIEW);glLoadIdentity();glTranslatef(0.0, 0.0, -3.6);}void main(void){auxInitDisplayMode (AUX_SINGLE | AUX_RGBA);auxInitPosition (0, 0, 500, 500);auxInitWindow ("Simple Texture Map");myinit();auxReshapeFunc (myReshape);auxMainLoop(display);}图12-1 简单纹理映射以上程序运行结果是将一块纹理映射到两个正方形上去。
计算机图形学课件 8第八章 OpenGL程序设计基础
第八章 OpenGL程序设计基础一、通过GLUT使用窗口系统二、几何图元与场景表达三、OpenGL中的变换四、OpenGL中的照明五、在OpenGL中使用纹理一、通过GLUT使用窗口系统OpenGL本身不涉及具体的窗口系统,但一个完整的图形程序又离不开窗口系统。
GLUT(The OpenGL Utility Toolkit)是一个独立于窗口系统的工具包。
使用它可以摆脱对具体窗口系统的依赖,直接学习OpenGL的核心内容。
1、本课程需要用到的GLUT函数void glutInit(int *argc, char **argv);void glutInitDisplayMode(unsigned int mode);void glutInitWindowSize(int width, int height);void glutInitWindowPosition(int x, int y);int glutCreateWindow(char *name); //返回值用于多窗口,本课程不涉及void glutDisplayFunc(void (*func)(void));void glutReshapeFunc(void (*func)(int width, int height));一、通过GLUT使用窗口系统void glutMouseFunc(void (*func)(int button, int state, int x, int y));void glutMotionFunc(void (*func)(int x, int y));void glutKeyboardFunc(void (*func)(unsigned int key, int x, int y);void glutIdleFunc(void (*func)(void));void glutMainLoop(void);void glutSwapBuffers(void);void glutPostRedisplay(void);注:这些函数都非常简单,在例子中看到即会,在红宝书中也有说明。
“计算机图形学课件-OpenGL基础”
OpenGL的帧缓存:双缓存和 多重采样缓存
双缓存
为避免屏幕出现闪烁和拉伸等现象,通常使用双缓存技术。
多重采样缓存
用于提高渲染质量,避免出现棱边、走样等问题。
模型矩阵
用于设置物体的位置、大小、 旋转等属性。
视图矩阵
定义了摄像机的位置和方向, 使得透视校正可以应用到场 景中的物体。
投影矩阵
用于将三维场景投影到二维 视口上,包括透视投影和正 交投影。
OpenGL的剪切与裁剪
剪切测试
用于决定是否绘制部分可见的 图形,提高渲染效率。
裁剪平面
使用裁剪平面来剔除不在视锥 体内的图形,避免不必要的渲 染操作。
计算机图形学课件—— OpenGL基础
计算机图形学是探索计算机如何生成、处理和显示图形的学科。本课件将介 绍OpenGL基础,包括历史、基本概念和常用功能。
OpenGL是什么?
OpenGL是跨平台的、开放源代码的图形库,用于开 发各种图形应用程序。
OpenGL支持2D和3D图形,能够创建高性能的交互 式应用程序。
2000年至今
OpenGL被广泛应用于游戏、虚拟现实、工业和科学领域等,迎来了历史性的变革。
OpenGL的版本和兼容性
OpenGL版本
当前最新版本是4.6版,最早 的版本是1.0版。
OpenGL兼容性
OpenGL的兼容性很广,支 持多种操作系统、程序语言 和硬件平台。
OpenGL ES
OpenGL ES是OpenGL的移 动版,支持嵌入式平台和移 动设备,提供比较小的API和 功能。
顶点着色器
处理顶点的位置和颜色等信息。
几何着色器
处理三角形内外和相邻三角形之间的关 系。
十三讲OpenGL技术简介ppt课件
首先,用时需要在project-settings-linkobject/library中加入 opengl32.lib glu32.lib glaux.lib 三个库。
• 如果是MFC程序
在视图类或OpenGL显示类中加入头文件 gl/glaux.h, gl/gl.h 及gl/glu.h三个头文件。
• 库类型
gl代表基本库,glu代表实用库,aux代表辅助库, wgl代表Windows专用库 。
• 函数参数信息
指明该函数有多少个参数,参数都是什么类型,如i 表示int,s表示short,f表示float,d表示double,v 表示参数为向量(即数组)。
OpenGL的工作流程
• 作为一个图形应用程序开发标准,OpenGL 具有软硬件平台无关性,它采用了 Client/Server的工作方式,其工作流程如下:
说明:将一个旋转矩阵与当前矩阵相乘,该矩阵将 物体绕原点到点(x,y,z)直线逆时针旋转angle 度
• glScale*(TYPE x, TYPE y, TYPE z)
说明:将物体缩放或沿坐标轴反射物体,物体上的 每个点坐标都分别乘以参数x、y、z。
• glMultMatrix*(const TYPE *m)
• OpenGL是什么?
Open Graphics Library,SGI公司推出的开放式图形 程序库(API),现已成为广泛接受的图形应用程序 开发标准。
• OpenGL跟其他图形库相同吗?
具有其他流行图形系统的大部分特点。
• 通过OpenGL编程能获得什么?
能更深入地理解图形学中所学的知识,若要掌握
• 2.剪裁
场景被渲染到矩形窗口中,所以要剪掉位于窗口之 外的物体。பைடு நூலகம்
最新计算机图形学OpenGL(第三版)第一章PPT
•教学与培训
• 科学计算可视化(ScientificVisualization)
–“科程学中家数们据不的仅变需化要” 分析由计算机得出的计算数据,而且需要了解在计算过 –海的量迫的切数性据与使日得俱人增们对数据的分析和处理变得越来越难,用图形来表示数据 –1986年,美国科学基金会(NSF)专门召开了一次研讨会,会上提出了“科
折线可用顶点列表定义,(x0, y0), (x1, y1), (x2, 2), ...., (xn, yn) ,画折线程序类似于:drawPolyline( poly), 其中poly为顶点列表。
1.3.2 文本
一些图形设备有两种显示模式,文本模式和图形模式。 --文本模式用于字符的简单输入/输出,用来控制操作系统或者 编写代码。这种方式显示的文本采用嵌入式的字符发生器。 --图形模式提供了更丰富的字符形状,字符能够被随意放置。
文本属性:
1.3.3 填充区域
填充图元是指填充时的颜色或图案。填充区域的边界经常是一个 多边形。填充多边形的语句类似于:fillPolygon(poly, pattern);
其中poly保存多边形的数据,变量pattern是填充图案的描述。
1.3.4 光栅图像
计算机图形学 OpenGL(第三版)第一章
PPT
课程简介
第一章 概述(4学时) 第六章 使用多边形网格建模(
第二章 OpenGL绘图入门 8学时)
(6学时)
第七章 曲线和曲面设计
第三章 更多的绘图工具 (4学时)
(8学时)
第四章 图形学中的向量 第八章 三维观察(4学时)
工具(6学时)
第五章 物体变换(6学时 )
前一页 休息
2
前一页 休息
计算机图形学OpenGL(第三版)课件
REPORTING
• 计算机图形学概述 • OpenGL基础知识 • 3D图形绘制 • 动画与交互 • 高级技术与应用 • 案例与实践
目录
PART 01
计算机图形学概述
REPORTING
计算机图形学的定义与分类
计算机图形学是一门研究计算机生成 和操作图形的科学,它通过数学算法 和计算机程序实现二维和三维图形的 生成、渲染和交互。
虚拟现实中的图形渲染技术
3D场景构建
利用OpenGL的3D图形渲染能力,构建逼真的虚拟现实场景,提供 沉浸式的体验。
实时交互与动态渲染
在虚拟现实中实现实时交互,如人物移动、视角变换等,同时根据 用户行为动态调整渲染效果,提高虚拟现实的真实感和沉浸感。
虚拟现实应用开发
结合OpenGL技术,开发各种虚拟现实应用,如虚拟旅游、虚拟展览 、虚拟教育等,拓展虚拟现实技术的应用领域。
OpenGL库(如GLUT或GLEW )。
对于Linux系统,需要安装 OpenGL库(如GLUT或SDL) 和相应的编译器。
开发者还需要了解如何配置项 目以包含OpenGL头文件和链 接OpenGL库。
OpenGL基本操作
01
02
03
04
05
初始化OpenGL 上下文
绘制基本图形
变换和投影
光照和材质
纹理映射
创建窗口,设置窗口回调 函数,创建渲染上下文等 。
使用OpenGL提供的函数绘 制点、线、多边形等基本 图形。
理解并使用平移、旋转、 缩放等变换以及投影矩阵 。
设置光源、材质属性以及 光照模型。
加载和绑定纹理,对几何 图形进行纹理映射。
计算机图形学(OpenGL总结)PPT课件
编辑版pppt
void display() {
glClear( GL_COLOR_BUFFER_BIT); // Clear the frame buffer
glColor3f( 0.0, 1.0, 0.0); // Set current color to green
glBegin( GL_POLYGON); the triangle
• 颜色缓存:用于存储每个像素点的颜色,包括左 前、(左后、右前、右后)和辅助颜色缓存。
• 深度缓存:用于存储每个像素点的深度值。 • 模板缓存:用于将作图限制在屏幕中的某些部分。 • 累积缓存:在RGBA模式中,用于将一系列图像
累加成一幅图像。
• 3、建立OpenGL控制台应用程序(.NET)
编辑版pppt
视区的高height。 • 输出参数:无 • 返回值:无
编辑版pppt
28
三、图形变换
• 3、裁剪变换
– void glClipPlane(GLenum plane,const GLdouble *equation);
• 函数功能:定义附加裁剪平面。 • 输入参数: 参数plane表示裁剪平面索引号
编辑版pppt
21
三、图形变换
– 正射投影
top far
left right
view direction bottom
near
编辑版pppt
22
三、图形变换
– 正射投影矩阵
编辑版pppt
23
三、图形变换
– void gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar);
OpenGL中的三维纹理操作
OpenGL中的三维纹理操作#define _CRT_SECURE_NO_WARNINGS#include <gl/glut.h>#include <stdio.h>#include <stdlib.h>#define WindowWidth 400#define WindowHeight 400#define WindowTitle "OpenGL纹理测试"/* 函数grab* 抓取窗⼝中的像素* 假设窗⼝宽度为WindowWidth,⾼度为WindowHeight*/#define BMP_Header_Length 54void grab(void){FILE* pDummyFile;FILE* pWritingFile;GLubyte* pPixelData;GLubyte BMP_Header[BMP_Header_Length];GLint i, j;GLint PixelDataLength;// 计算像素数据的实际长度i = WindowWidth * 3; // 得到每⼀⾏的像素数据长度while( i%4 != 0 ) // 补充数据,直到i是的倍数++i; // 本来还有更快的算法,// 但这⾥仅追求直观,对速度没有太⾼要求PixelDataLength = i * WindowHeight;// 分配内存和打开⽂件pPixelData = (GLubyte*)malloc(PixelDataLength);if( pPixelData == 0 )exit(0);pDummyFile = fopen("dummy.bmp", "rb");if( pDummyFile == 0 )exit(0);pWritingFile = fopen("grab.bmp", "wb");if( pWritingFile == 0 )exit(0);// 把dummy.bmp的⽂件头复制为新⽂件的⽂件头fread(BMP_Header, sizeof(BMP_Header), 1, pDummyFile);fwrite(BMP_Header, sizeof(BMP_Header), 1, pWritingFile);fseek(pWritingFile, 0x0012, SEEK_SET);i = WindowWidth;j = WindowHeight;fwrite(&i, sizeof(i), 1, pWritingFile);fwrite(&j, sizeof(j), 1, pWritingFile);// 读取像素,写⼊像素数据glPixelStorei(GL_UNPACK_ALIGNMENT, 4);glReadPixels(0, 0, WindowWidth, WindowHeight,GL_BGR_EXT, GL_UNSIGNED_BYTE, pPixelData);fseek(pWritingFile, 0, SEEK_END);fwrite(pPixelData, PixelDataLength, 1, pWritingFile);// 释放内存和关闭⽂件fclose(pDummyFile);fclose(pWritingFile);free(pPixelData);}// 判断是否为偶数int power_of_two(int n){if( n <= 0 )return 0;return (n & (n-1)) == 0;}/* 函数load_texture读取⼀个BMP⽂件作为纹理如果失败,返回0,如果成功,返回纹理编号*/GLuint load_texture(const char* file_name){GLint width, height, total_bytes;GLubyte *pixels = 0;GLint last_texture_ID;GLuint texture_ID = 0;// 打开⽂件,如果失败,返回FILE *pFile = fopen(file_name, "rb");if( pFile == 0 )return 0;// 读取⽂件中图像的宽度和⾼度fseek(pFile, 0x0012, SEEK_SET);fread(&width, 4, 1, pFile);fread(&height, 4, 1, pFile);fseek(pFile, BMP_Header_Length, SEEK_SET);// 计算每⾏像素所占字节数,并根据此数据计算总像素字节数{GLint line_bytes = width * 3;while( line_bytes % 4 != 0 )++line_bytes;total_bytes = line_bytes * height;}// 根据总像素字节数分配内存pixels = (GLubyte*)malloc(total_bytes);if( pixels == 0 ){fclose(pFile);return 0;}// 读取像素数据if( fread(pixels, total_bytes, 1, pFile) <= 0 ){free(pixels);fclose(pFile);return 0;}// 在旧版本的OpenGL中、如果图像的宽度和⾼度不是的整数次⽅,则需要进⾏缩放// 这⾥并没有检查OpenGL版本,出于对版本兼容性的考虑,按旧版本处理// 另外,⽆论是旧版本还是新版本,当图像的宽度和⾼度超过当前OpenGL实现所⽀持的最⼤值时,也要进⾏缩放 GLint max;glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max);if( !power_of_two(width)|| !power_of_two(height)|| width > max || height > max ){const GLint new_width = 256;const GLint new_height = 256; // 规定缩放后新的⼤⼩为边长的正⽅形GLint new_line_bytes, new_total_bytes;GLubyte* new_pixels = 0;// 计算每⾏需要的字节数和总字节数new_line_bytes = new_width * 3;while( new_line_bytes % 4 != 0 )++new_line_bytes;new_total_bytes = new_line_bytes * new_height;// 分配内存new_pixels = (GLubyte*)malloc(new_total_bytes);if( new_pixels == 0 ){free(pixels);fclose(pFile);return 0;}// 进⾏像素缩放gluScaleImage(GL_RGB, width, height, GL_UNSIGNED_BYTE, pixels,new_width, new_height, GL_UNSIGNED_BYTE, new_pixels);// 释放原来的像素数据,把pixels指向新的像素数据,并重新设置width和heightfree(pixels);pixels = new_pixels;width = new_width;height = new_height;}// 分配⼀个新的纹理编号glGenTextures(1, &texture_ID);if( texture_ID == 0 ){free(pixels);fclose(pFile);return 0;}// 绑定新的纹理,载⼊纹理并设置纹理参数.glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture_ID);//在绑定前,先获得原来绑定的纹理编号,以便在最后进⾏恢复glBindTexture(GL_TEXTURE_2D, texture_ID);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);//指当纹理图像被使⽤到⼀个⼤于它的形状上时,应该如何处理 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, pixels);glBindTexture(GL_TEXTURE_2D, last_texture_ID);// 之前为pixels分配的内存可在使⽤glTexImage2D以后释放// 因为此时像素数据已经被OpenGL另⾏保存了⼀份(可能被保存到专门的图形硬件中)free(pixels);return texture_ID;}/* 两个纹理对象的编号*/GLuint texGround;GLuint texWall;void display(void){// 清除屏幕glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// 设置视⾓glMatrixMode(GL_PROJECTION);glLoadIdentity();//在进⾏变换前,将当前矩阵变为单位矩阵gluPerspective(75, 1, 1, 21);glMatrixMode(GL_MODELVIEW);glLoadIdentity();gluLookAt(1, 5, 5, 0, 0, 0, 0, 0, 1);//前三个参数表⽰了观察点的位置,中间三个参数表⽰了观察⽬标的位置,//最后三个参数代表从(0,0,0)到(x,y,z)的直线,它表⽰了观察者认为的“上”⽅向// 使⽤“地”纹理绘制⼟地glBindTexture(GL_TEXTURE_2D, texGround);glBegin(GL_QUADS);glTexCoord2f(0.0f, 0.0f); glVertex3f(-8.0f, -8.0f, 0.0f);glTexCoord2f(0.0f, 5.0f); glVertex3f(-8.0f, 8.0f, 0.0f);glTexCoord2f(5.0f, 5.0f); glVertex3f(8.0f, 8.0f, 0.0f);glTexCoord2f(5.0f, 0.0f); glVertex3f(8.0f, -8.0f, 0.0f);glEnd();// 使⽤“墙”纹理绘制栅栏glBindTexture(GL_TEXTURE_2D, texWall);glBegin(GL_QUADS);glTexCoord2f(0.0f, 0.0f); glVertex3f(-6.0f, -3.0f, 0.0f);glTexCoord2f(0.0f, 1.0f); glVertex3f(-6.0f, -3.0f, 1.5f);glTexCoord2f(5.0f, 1.0f); glVertex3f(6.0f, -3.0f, 1.5f);glTexCoord2f(5.0f, 0.0f); glVertex3f(6.0f, -3.0f, 0.0f);glEnd();// 旋转后再绘制⼀个glRotatef(-90, 0, 0, 1);glBegin(GL_QUADS);glTexCoord2f(0.0f, 0.0f); glVertex3f(-6.0f, -3.0f, 0.0f);glTexCoord2f(0.0f, 1.0f); glVertex3f(-6.0f, -3.0f, 1.5f);glTexCoord2f(5.0f, 1.0f); glVertex3f(6.0f, -3.0f, 1.5f);glTexCoord2f(5.0f, 0.0f); glVertex3f(6.0f, -3.0f, 0.0f);glEnd();// 交换缓冲区,并保存像素数据到⽂件glutSwapBuffers();grab();}int main(int argc, char* argv[]){// GLUT初始化glutInit(&argc, argv);glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);glutInitWindowPosition(100, 100);glutInitWindowSize(WindowWidth, WindowHeight); glutCreateWindow(WindowTitle);glutDisplayFunc(&display);// 在这⾥做⼀些初始化glEnable(GL_DEPTH_TEST);glEnable(GL_TEXTURE_2D);texGround = load_texture("ground.bmp");texWall = load_texture("wall.bmp");// 开始显⽰glutMainLoop();return 0;}搬家于CSDN 2014-01-24的⽂章。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
2013.11.19
纹理映射
纹理(texture)通常指物体的表面细节
2
纹理映射
纹理映射技术给出了定义表面上任意点属性的 一种方式
漫反射率 镜面反射率 透明度 折射率 …
I d Kd I e cos
3
纹理映射
两类最常使用的纹理
颜色纹理
几何纹理
4
颜色纹理
确定表面上颜色纹理的两种方法
预先建立表面的纹理模型 纹理映射:建立表面上的每一点和一已知图像上的 点的对应关系,取图像上相应点的颜色值作为表面 上各点的颜色值
方法
物体表面S由参数方程S=S(u,v) 表示
S上的任意一点(u,v)的法向n=Su×Sv
沿着表面S的法线方向叠加一个微小的扰动量P(u,v)
定义了一张新的表面S’
S' S(u, v) P(u, v)
n
n
11
凹凸映射
方法(cont.)
新表面的法向可用 n’=Su’×Sv’ 计算
n' n Pu (n Sv ) Pv (S u n)
映射阶段(cont.)
27
Mipmap效果
无Mipmap
有Mipmap
28
纹理反走样效果对比
未进行反走样处理
Mipmap
超采样
超采样+Mipmap
29
纹理映射实例程序
利用OpenGL实现纹理映射的三个主要步骤
生成纹理数据 将纹理数据载入纹理内存 将纹理数据映射到物体表面
30
纹理映射实例程序
讲解光盘中所附的程序
n
n
在计算表n,生成物体表面的凹凸效果
扰动函数P(u,v)既可解析定义,也可通过二维图像 定义
12
凹凸映射
示例
13
凹凸映射
示例
(a)
(b)
(c)
(d)
(e)
14
纹理反走样
纹理走样示例
走样
15
纹理反走样
纹理走样原因
欠采样
16
纹理反走样
23
Mipmap方法
预处理
平均
原始图像 (a)
新图像
1:1
4:1
16:1 64:1
(b)
24
Mipmap方法
映射阶段
屏幕上的每一像素内的可见表面区域被映射到原始 纹理图像上的一块区域 估计该区域所覆盖的原始纹理图像中像素的个数并 以此作为选取适当分辨度的纹理图像版本的一种测 度
25
Mipmap方法
9
几何纹理
位移映射(displacement mapping)
依据与表面上点所对应的纹理值,沿表面法向偏移 该点的几何位置 能产生很强的深度感
➢ 自遮挡 ➢ 自阴影 ➢ 轮廓
计算代价大
➢ 与凹凸映射、法向映射相比
10
凹凸映射
思想
在应用光照明模型计算景物表面光亮度时,对景物表面 法向进行微小的扰动
… unsigned char *imageData = NULL; …. imageData = (unsigned char*)getData (s, size, imageBits); /* no image data */ if (imageData == NULL)
returnError (s, TGA_BAD_DATA); …. }
22
Mipmap方法
预处理:生成一个由不同分辨率图像构成的纹 理图像序列
从原始纹理图像出发,生成一个其分辨率为原始图 像1/4的新的纹理图像版本
➢ 新版本中的每一个像素值取为原始图像中相对应的四个像 素颜色值的平均
类似地基于所得到的新纹理图像版本生成一个更低 分辨率的、尺寸更小的纹理图像版本 这一过程一直持续到最后生成的纹理图像仅包含一 个像素为止
利用法向纹理保证高质量的表面细节复现
位移映射(displacement mapping)
利用纹理改变物体表面上点的几何位置,获得很强的深 度感和细节
8
几何纹理
法向映射(Normal mapping)
借助低精度模型和一个法向纹理,获得高精度模型 的绘制效果 先计算高精度模型的法向,将其保存在法向纹理中, 再将法向纹理映射到低精度模型上进行光照计算
5
纹理映射
采用景物表面的参数化表 示来确立表面的纹理映射 坐标,即可实现纹理图像 在景物表面的映射
景物表面的参数化表示为f(u,v) 纹理图像表示为T(s,t) 建立景物表面参数空间(u,v) 和纹理图像参数空间(s,t)之
间的一一对应关系
6
纹理映射
示例
u=0,v=1
u=1,v=1
s=1,t=0
走样
前置滤波
19
纹理反走样
超采样方法
将屏幕像素P的四个角点分别映射到纹理空间,得 到四个纹理像素值 将上述四个纹理颜色值取平均作为像素P所对应的 可见表面区域的纹理颜色
超采样
20
纹理反走样
超采样方法效果
走样
超采样
21
纹理反走样
Mipmap方法
MIP来源于 拉丁语“multum in parvo”,意为 “many things in a small place” 目前应用最广的纹理反走样算法之一 通过预先计算并存贮原始 纹理图像的一组多分辨率 版本,能显著地节省纹理 反走样的计算量
映射阶段(cont.)
从预先构造的纹理图像序列中找出其压缩率最接近 当前纹理像素与屏幕像素比率的两个纹理图像 在相邻分辨率的两纹理图像上计算当前屏幕像素映 射点的纹理颜色值 根据两纹理图像对原始图像的压缩率在所得到的两 个纹理颜色值间取加权平均,作为当前屏幕像素可 见表面区域的颜色值
26
Mipmap方法
常用纹理反走样方法
前置滤波方法 超采样方法 Mipmap方法
17
纹理反走样
前置滤波方法
确定屏幕像素P上可见的景物表面区域A
将区域A直接映射到纹理空间区域T
取区域T内的所有纹理像素颜色值的平均作为景物表 面区域A的平均纹理颜色
代入光照明模型,计算出 像素P应显示的光亮度值
前置滤波
18
纹理反走样
前置滤波效果
DEMO
31
纹理映射实例程序
Step1:生成纹理数据
void glInit (void) {
… if (!loadTGA ("texture.tga", 13))
printf ("texture.tga not found!\n"); }
int loadTGA (char *name, int id) {
s=1,t=1 s=0,t=1
u=0,v=0
u=1 ,v=0
(a) 纹理空间
s=0,t=0 (b) 景物空间的曲面片
(c) 纹理映射后的曲面片
7
几何纹理
凹凸映射(bump mapping)
在不改变物体宏观几何的前提下,模拟物体表面粗糙的、 褶皱的、凹凸不平的光照效果
法向映射(normal mapping)