OpenGL中的纹理映射-纹理环境void glTexEnv{if}[v](GLenum target
OPENGL中文教程 OPENGL-5-纹理
4、绘制带纹理三棱锥NeHe SDK是把Nehe的教程中所介绍的所有功能,以面向对象的形式,提供给编程人员快速开发的一套编程接口。
在下面的教程中,我将按NeHe SDK源码的功能分类,一步一步把这套api介绍给大家。
如果你觉得有更好的学习方法,或者有其他有益的建议,请联系我。
zhouwei02@,zhouwei506@程序结构:我们在第三课程序的基础上添加一下功能:1.创建一个全局的纹理类2.利用纹理类载入纹理文件3.创建绘制带纹理坐标的三棱锥的函数4. 设置当前的纹理并启用它,绘制带纹理坐标的三棱锥 为了使用纹理类,我们需要包含下面的头文件(texture.h),并声明一个全局的视口变量text2D 。
我们在主程序文件和绘制文件中添加如下的代码:/*************************************新增的代码:包含纹理类的声明****************************/ #include "texture.h" // 包含纹理类的声明/**********************************新增的代码:包含纹理类的声明:结束**************************//*************************************新增的代码:创建Texture 类****************************/ Texture tex; // 使用全局变量Texture 类的实例 int texID; // 使用全局变量texID ,保存加载的纹理ID/**********************************新增的代码:创建Text2D 类:结束**************************/2、利用纹理类载入纹理文件我们在IniScene 函数中完成这个工作,首先调用纹理类的Load 函数载入base.bmp 图像文件,接着检查是否成功,如果不成功则弹出对话框,提示载入失败。
基于OpenGL的纹理映射技术
人工智能及识别技术本栏目责任编辑:李桂瑾电脑知识与技术1引言纹理映射技术产生上个世纪七十年代,是模拟自然景物表面细节的一种有效方法,在生成真实感图形中得到了大量的应用。
在过去的几十年中,人们一直通过建模的方法仿真客观世界,由于客观世界千变万化、错综复杂,要把客观世界的各种细微结构直接用几何模型表示出来,不仅模型难以建立,而且计算量庞大,难以满足实时显示的要求。
因此,在实际应用中,为了获得比较高的显示速度,往往以牺牲图形的真实感为代价。
尽管这样,显示一幅较复杂的图形往往需要好几个小时,并且能满足实时性要求的几何模型一直没有找到。
于是,人们就想象是否可以用“贴”墙纸的方法将反映物体表面细节的图案贴到物体表面上,从而开辟了一个新的研究领域———纹理映射(texturemapping)。
2OpenGL简述OpenGL是由SGI公司推出的独立于操作系统和硬件环境的开放式三维图形库,作为一种用于实时3D图形的工业标准API(ApplicationProgramminInterface)已经得到了广泛的认可和接受。
OpenGL提供了155个图形函数,开发人员可以利用这些函数来构造景物模型,开发三维图形实时交互软件。
OpenGL具有强大的图形功能和良好的跨平台移植能力,目前已被广泛应用于可视化技术、实体造型、CAD/CAM、模拟仿真等诸多领域。
纹理映射技术是OpenGL的一个重要的技术,在进行模型转换和投影转换都能执行操作,可用到所有的图元:点、线、多边形、位图和图像上。
3纹理的定义和分类我们可以从自然角度、运算角度及分析角度分别给出纹理的定义:从自然角度来看,纹理是在某一确定的图象区域中,以近乎周期的种类和方式重复其自身的局部基本模式元。
这一定义由Pratt给出,它适合应用于确定类型的线条模式。
基于运算角度,纹理是在某一运算表达式规定下,为近乎不变或者近乎周期性的数量表达。
此定义由Sklansky给出,它适合于根据数学的分析方法抽取纹理特征以实现纹理区域分类的应用领域。
高级计算机图形学OpenGL纹理映射
GLboolean glIsTexture(GLuint textureName);
• •
void glBindTexture(GLenum target, GLuint textureName); void glDeleteTextures(GLsizei n, const GLuint *textureNames);
• GLubyte • •
my_texels[512][512][3];
定义纹理图像所用的像素图
扫描图像 由应用程序代码创建
激活纹理映射
• glEnable(GL_TEXTURE_2D); • OpenGL支持一至四维纹理映射
9
把图像定义为纹理
void glTexImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
本节只讨论从二维纹理到曲面的映射
4
基本策略
应用纹理需要下面三个步骤
•
•
•
• • •
• •
指定纹理
读入或生成图像 赋给纹理 激活纹理映射功能
由应用程序建立适当的映射函数 环绕(wrapping), 滤波(filtering)
5
给每个顶点赋纹理坐标 指定纹理参数
纹理映射
几何体
屏幕
图像
6
纹理示例
mipmapped 的线性滤波
23
opengl基础6
纹理一般定义在单位正方形域0s1,0t1上,称为纹理
空间
t
1
0
0
1
s
1.1 纹理映射
纹理模式
纹理函数 定义在纹理空间中的函数。例如: b [ s 8 ] [ t 8 ]为 奇 数 g (s, t) a [ s 8 ] [ t 8 ]为 偶 数
第七章
纹理映射
Introduction of Computer Graphics
前 言
上讲内容
简单光照模型
光源 环境光 漫反射 镜面反射 光强衰减 颜色 透明度 阴影
前 言
上讲内容
面的明暗处理
平面明暗处理 Gouraud明暗处理 Phong明暗处理 光线跟踪算法 辐射度光照模型 BRDF光照模型
s 2u / ,
Y X
将投影像素区映射到纹理空间
对每个投影像素区所覆盖的纹理图案中的
光强值取平均,得到像素的光强度
1.2 环境映射
Environment Mapping,将空间光照模型作为纹理映射到物体 表面 首先定义一个描述单个或一组物体周围环境的光强度数组 (即环境纹理,包括光源强度、天空和其他背景物体),将 环境纹理映射到一个封闭环境中表面; 然后根据观察方向将环境空间表面的环境纹理映射至物体表 面,实现全局镜面反射和漫反射效果; 环境映射的封闭空间可以是球体,更经常使用立方体或圆柱 体形状的封闭空间。
纹理空间: (s,t) 数组坐标
-1 MTMT
对象空间: (u,v) 表面参数
基于OpenGL纹理映射技术的纸盒贴图功能的实现方法
收稿日期:2006Ο06Ο16作者简介:赵荣丽(1979-),女,广东工业大学助教,主要从事包装结构、包装C AD 、包装印刷等的教学和科研。
基于OpenG L 纹理映射技术的纸盒贴图功能的实现方法赵荣丽1,谢利2,和克智2,白莉1(1.广东工业大学,广州510006;2.西安理工大学,西安710048)摘要:根据纸盒结构的面片特性,利用OpenG L 的纹理映射技术,提取纸盒的装潢图片,建立其与纸盒结构的对应关系,实现纸盒CAD 系统中的贴图功能以及三维效果图的展示。
关键词:纹理映射;纸盒;三维效果图中图分类号:T B482.1;TP391.72 文献标识码:A 文章编号:1001-3563(2006)05-0061-03Cart on Mapp ing Technique Based on OpenG L’s Texture Mapp ingZHAO R ong 2li 1,X IE L i 2,HE Ke 2zhi 2,BA I L i1(1.Guangdong University of technol ogy,Guangzhou 510006,China;2.Xi’a n University of technol ogy,Xi’an 710048,China )Abstract:According t o the characteristic of cart on,OpenG L ’s texture mapp ing was used t o distill the up 2holstering p icture,and the corres ponding connecti on bet w een the upholstering p icture and the cart on structure was set up.The cart on mapp ing functi on of cart on CAD and the expositi on of cart on 3D effect graph was real 2ized by this technol ogy .Key words:texture mapp ing;cart on;3D effect graph 纹理映射技术是为了简化模拟真实世界的过程而诞生的一项技术,即采用物体的真实纹理图形映射到绘制的三维图形表面,使其呈现出更加逼真的效果。
《opengl计算机三维图形程序设计》纹理.pptx
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)既可解析定义,也可通过二维图像 定义
opengl纹理映射(下)
齐次坐标
齐次坐标(homogeneous coordinates)
是对普通坐标的扩展 二维平面点(x,y)的齐次坐标表示为(x, y,w)
(x,y,w)→(x/w,y/w)
三维空间点(x,y,z)的齐次坐标表示为 (x,y,z,w)
(x,y,z,w)→(x/w,y/w,z/w)
齐次坐标
两个重要性质
驻留纹理
驻留策略
为纹理对象指定驻留优先级
void glPrioritizeTextures(GLsizei n, const GLuint *textureNames, const GLclampf *priorities) 优先级范围在[0.0,1.0]之间,0最低,1最高
为当前绑定纹理指定优先级
GL_NEAREST_MIPMAP_NEAREST GL_LINEAR_MIPMAP_NEAREST GL_NEAREST_MIPMAP_LINEAR GL_LINEAR_MIPMAP_LINEAR
mipmap下的过滤处理
GL_NEAREST_MIPMAP_NEAREST
寻找最合适的一层mipmap,再应用GL_NEAREST规则寻找合适 的纹元
OpenGL三维图形编程
纹理映射(下)
纹理高级技术
一维纹理 纹理代理 驻留纹理 自动纹理坐标 环境映射 纹理矩阵 齐次坐标 细节多层次(mipmap)
一维纹理
与二维纹理相关函数类似,target参数使用 GL_TEXTURE_1D
从内存纹理数据定义纹理 从帧缓存数据创建纹理 使用内存数据替换纹理图像 使用帧缓存数据替换纹理图像 ……
查询多个纹理的驻留情况
GLboolean glAreTexturesResident(GLsizei n, const GLuint*textureNames, GLboolean *residences) 纹理全部驻留,返回GL_TRUE,residences不变 纹理部分驻留,返回GL_FALSE,residences相应改变
opengl算法学习---纹理映射
opengl算法学习---纹理映射纹理映射纹理映射(Texture Mapping),⼜称纹理贴图,是将纹理空间中的纹理像素映射到屏幕空间中的像素的过程。
简单来说,就是把⼀幅图像贴到三维物体的表⾯上来增强真实感,可以和光照计算、图像混合等技术结合起来形成许多⾮常漂亮的效果。
纹理纹理可看成是⼀个或多个变量的函数,因此根据纹理定义域的不同,纹理可分为⼀维纹理、⼆维纹理、三维纹理和⾼维纹理。
基于纹理的表现形式,纹理⼜可分为颜⾊纹理、⼏何纹理两⼤类。
颜⾊纹理指的是呈现在物体表⾯上的各种花纹、图案和⽂字等,即通过颜⾊⾊彩或明暗度的变化体现出来的细节。
如⼤理⽯墙⾯、墙上贴的字画器⽫上的图案等。
⼏何纹理(也可称为凹凸纹理)是指基于景物表⾯微观⼏何形状的表⾯纹理,如桔⼦、树⼲、岩⽯、⼭脉等表⾯呈现的凸凹不平的纹理细节。
⽣成颜⾊纹理的⼀般⽅法是在⼀个平⾯区域(即纹理空间)上预先定义纹理图案,然后建⽴物体表⾯的点与纹理空间的点之间的对应—即映射。
以纹理空间的对应点的值乘以亮度值,就可把纹理图案附到物体表⾯上⽤类似的⽅法给物体表⾯产⽣凹凸不平的外观或称凹凸纹理。
普通纹理映射常见的2D纹理映射实际上是从纹理平⾯到三维物体表⾯的⼀个映射。
凹凸纹理映射前述各种纹理映射技术只能在光滑表⾯上描述各种事先定义的花纹图案,但不能表现由于表⾯的微观⼏何形状凹凸不平⽽呈现出来的粗糙质感,如布纹,植物和⽔果的表⽪等1978年Blinn提出了⼀种⽆需修改表⾯⼏何模型,即能模拟表⾯凹凸不平效果的有效⽅法⼀⼏何(凹凸)纹理映射(bump mapping)技术⼀个好的扰动⽅法应使得扰动后的法向量与表⾯的⼏何变换⽆关,不论表⾯如何运动或观察者从哪⼀⽅向观察表⾯,扰动后的表⾯法向量保持不变。
Blinn表⾯法⽮扰动法在表⾯任⼀点处沿其法向附加⼀微⼩增量,从⽽⽣成⼀张新的表⾯,计算新⽣成表⾯的法⽮量以取代原表⾯上相应点的法⽮量。
透明效果与混合光学原理:透射,折射,反射颜⾊调和法设a为透明体的不透明度,0≤a≤1,则I=αI a+(1−α)I ba=1,完全不透明a=0,完全透明alpha融合技术BlendingRGBA(a)不透明度a表⽰穿透该表⾯光线的数量a=1,完全不透明;a=0,完全透明gl.blendFunc(src_ factor,dst factor)混合后颜⾊=源颜⾊src_factor+⽬标颜⾊dst_factor源颜⾊:当前对象⽬标颜⾊:帧缓存像素透明与Z-Buffer消隐当对象A是透明的,即B透过A是部分可见时先画B再画A,可以处理先画A再画B,深度缓冲会从B取⼀个像素,同时注意到⼰经绘制了⼀个更近的像素(A),然后它的选择是不绘制BZ-Buffer消隐不能很好处理透明的物体,需要修正才⾏开启深度测试gl.enable(gl.DEPTH_TEST);绘制所有不透明物体(a=1.0)锁定深度缓冲区gl.depthMask(false);按从后向前次序绘制所有半透明物体释放深度缓冲区gl.depthMask(true);光线跟踪光线跟踪算法[WH1T80]是⽣成⾼度真实感图形的主要算法之⼀。
OpenGL高级课题与纹理映射技术讲述
高级成像
成像子集
◦ 只有当GL_ARB_imaging有定义时才有效
颜色矩阵 卷积 颜色表 直方图 MinMax 高级混合
立即模式、显示列表和保留模 式
立即模式(immediate mode)
◦ 图元直接发送到绘制流水线并显示 ◦ 不需要显卡内存
显示列表(display list)
◦ 图元保存在显示列表中、显示列表保存在 显卡中
保留模式(retained mode)
◦ 所有数据预先置入显存
立即模式与显示列表
立即模式
多项式 求值器
顶点操作 和
图元组装
显示
CPU
列表
列出显示
象素 操作
光栅化
纹理 内存
象素 操作
帧 缓冲
显示列表
创建显示列表
GLuint id;
void init( void ) {
在缩放过程中进行插值和滤波
设定纹理的其他方法
将帧缓冲器的内容设定为纹理图像的来源 ◦ glCopyTexImage1D(...) ◦ glCopyTexImage2D(...)
设置某个纹理的一部分 ◦ glTexSubImage1D(...) ◦ glTexSubImage2D(...) ◦ glTexSubImage3D(...)
创建模板
glInitDisplayMode( …|GLUT_STENCIL|… ); glEnable( GL_STENCIL_TEST ); glClearStencil( 0x0 );
glStencilFunc( GL_ALWAYS, 0x1, 0x1 ); glStencilOp( GL_REPLACE, GL_REPLACE,
包围盒外的象素被裁剪掉
OpenGL教程009_纹理映射
纹理映射(Texture Mapping,/wiki/Texture_mapping)是⼀一种中等难度的渲染⽅方法。
其基本思路是将⼀一张或者⼏几张图⽚片作为纹理,将其贴在模型表⾯面。
纹理映射的算法实在是⾮非常简单。
⽤用OpenGL实现纹理映射,最⼤大的难度不在于OpenGL,⽽而在于如何加载图⽚片!⽤用C++读取图⽚片有很多库可以选择,例如CImg、ImageStone和OpenCV之类的。
这些库都是跨平台的,但使⽤用起来过于复杂。
于是我找了⼀一个简单的库EasyBMP(/projects/easybmp/?source=directory),只能读取BMP 数据,够⽤用也跨平台。
所需要的就是将纹理图全部转换为BMP格式,⽤用图像处理软件很容易做到这⼀一点。
我们引⼊入⼀一个新的函数来加载纹理://加载纹理GLuint const char//使⽤用EasyBMP加载纹理图⽚片//使⽤用什么库没有关系,最终纹理需要⽣生成⼀一个数组,数组的格式如下://{r1,g1,b1,r2,g2,b2,...,rn,gn,bn},其中ri,gi,bi表⽰示i位置的//像素点的rgb值。
如果图像由alpha值,数组的格式如下://{r1,g1,b1,a1,r2,g2,b2,a2,...,rn,gn,bn,an}BMPReadFromFileint TellWidthint TellHeightunsigned char new unsignedchar3int0for int0for int0row col Redrow col Greenrow col Blue//创建纹理,并将纹理数据传递给OpenGLGLuint1glGenTextures1glBindTexture GL_TEXTURE_2D0//设置纹理参数glTexParameteri GL_TEXTURE_2D GL_TEXTURE_WRAP_S GL_REPEATglTexParameteri GL_TEXTURE_2D GL_TEXTURE_WRAP_T GL_REPEATglTexParameteri GL_TEXTURE_2D GL_TEXTURE_MAG_FILTERGL_LINEARglTexParameteri GL_TEXTURE_2D GL_TEXTURE_MIN_FILTERGL_LINEAR//传输数据glTexImage2D GL_TEXTURE_2D0GL_RGB0GL_RGB GL_UNSIGNED_BYTE deletereturn0加载纹理通常分为以下⼏几个步骤:(1)⽤用图像处理库(这⾥里是EasyBMP)读取纹理⽂文件。
OpenGL高级课题与纹理映射技术教程
保留模式(retained mode)
◦ 所有数据预先置入显存
立即模式与显示列表
立即模式 多项式 求值器 顶点操作 和 图元组装
CPU
列出显示
显示 列表
光栅化
象素 操作
帧 缓冲
纹理 内存 象素 操作
显示列表
创建显示列表
GLuint id;
void init( void ) { id = glGenLists( 1 ); glNewList( id, GL_COMPILE ); /* other OpenGL routines */ glEndList(); }
抖动
glEnable( GL_DITHER );
抖动用于加强视觉效果
◦ 用于模拟更多颜色
打印设置
目前,该功能ቤተ መጻሕፍቲ ባይዱ少被用到
象素上的逻辑操作
使用位逻辑操作结合多个象素值
glLogicOp( mode );
命令模式
GL_XOR GL_AND
目前,该功能很少被用到
累积缓冲器
颜色缓冲器合成的问题
◦ 有限颜色分辨率
截断 精度损失
◦ 累积缓冲区扮演着“浮点”颜色缓冲区的 角色
合成到积累缓冲区 将结果转换到帧缓冲区
累积缓冲区存取
glAccum( op, value )
◦ 操作
在积累缓冲区中的操作: GL_ADD, GL_MULT 读缓冲区操作: GL_ACCUM, GL_LOAD 写缓冲区操作: GL_RETURN
景深
沿平行焦平面的方向移动视点
纹理映射
• 使用指定的颜色,响应光照条件(纹理单元的颜色值与纹理环境颜色值混合) 20
➢ 设置纹理环境
• 设置纹理环境函数
void glTexEnv{if}(GLenum target, GLenum pname, TYPE param); void glTexEnv{if}v(GLenum target, GLenum pname, TYPE *param);
参数说明
target 必须设置为GL_TEXTURE_2D
width和 height 给定二维纹理的尺寸,必须为2m+2b( width和 height可分别对应不同的m值)
width和 height为0,纹理映射无效ຫໍສະໝຸດ 12➢ 定义三维纹理
– 使用glTexImage3D()函数定义三维纹理
void glTexImage3D(GLenum target, GLint internalFormat, GLsizei width, GLsizei height , GLsizei depth, GLint border, GLenum format ,GLenum type, const GLvoid *texels)
11
➢ 定义二维纹理
– 使用glTexImage2D()函数定义二维纹理
void glTexImage2D( GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixel)
18
➢ 纹理的创建
OpenGL纹理贴图
1.6纹理贴图在三维图形中,纹理映射(Texture Mapping)的方法运用得很广,尤其描述具有真实感的物体。
比如绘制一面砖墙,就可以用一幅真实的砖墙图像或照片作为纹理贴到一个矩形上,这样,一面逼真的砖墙就画好了。
如果不用纹理映射的方法,则墙上的每一块砖都必须作为一个独立的多边形来画。
另外,纹理映射能够保证在变换多边形时,多边形上的纹理图案也随之变化。
例如,以透视投影方式观察墙面时,离视点远的砖块的尺寸就会缩小,而离视点较近的就会大些。
此外,纹理映射也常常运用在其他一些领域,如飞行仿真中常把一大片植被的图像映射到一些大多边形上用以表示地面,或用大理石、木材、布匹等自然物质的图像作为纹理映射到多边形上表示相应的物体。
纹理映射有许多种情况。
例如,任意一块纹理可以映射到平面或曲面上,且对光亮的物体进行纹理映射,其表面可以映射出周围环境的景象;纹理还可按不同的方式映射到曲面上,一是可以直接画上去(或称移画印花法),二是可以调整曲面颜色或把纹理颜色与曲面颜色混合;纹理不仅可以是二维的,也可以是一维或其它维的。
我们这里重点研究二维纹理贴在三维物体表面上的方法。
2D纹理就是一张平面图片,它是由平面上的像素点(称纹素Texel)组成,因此每个点的在纹理内部只有二位的相对坐标(贴在物体上后就有三维的实际坐标了)。
定义1、修改TITLE#define TITLE "5DG'S 2D Texture Mapping!" // 定义窗口标题2、定义常量#define MAXTEXTURE 2 // 定义最大的纹理数目(new) 定义需要开辟的纹理空间为2,每个空间存储一个二维纹理。
3、定义全局变量GLfloat angle; // 控制物体的旋转角度GLuint texture[MAXTEXTURE]; // 纹理数组,保存纹理名称angle用来控制坐标系的旋转角度。
texture[MAXTEXTURE]为纹理数组,保存MAXTEXTURE个纹理的名称。
《高效学习OpenGL》之纹理对象glGenTextures(),glIsTexture(。。。
view plaincopyprint? view plaincopyprint? view plaincopyprint? view plaincopyprint? view plaincopyprint?19. for (j = 0; j < checkImageWidth; j++) {20. c = ((((i&0x8)==0)^((j&0x8))==0))*255;21. checkImage[i][j][0] = (GLubyte) c;22. checkImage[i][j][1] = (GLubyte) c;23. checkImage[i][j][2] = (GLubyte) c;24. checkImage[i][j][3] = (GLubyte) 255;25. c = ((((i&0x10)==0)^((j&0x10))==0))*255;26. otherImage[i][j][0] = (GLubyte) c;27. otherImage[i][j][1] = (GLubyte) 0;28. otherImage[i][j][2] = (GLubyte) 0;29. otherImage[i][j][3] = (GLubyte) 255;30. }31. }32. }33.34. void init(void)35. {36. glClearColor (0.0, 0.0, 0.0, 0.0);37. glShadeModel(GL_FLAT);38. glEnable(GL_DEPTH_TEST);39.40. makeCheckImages();41. glPixelStorei(GL_UNPACK_ALIGNMENT, 1);42.43. glGenTextures(2, texName);44. glBindTexture(GL_TEXTURE_2D, texName[0]);45. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);46. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);47. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,48. GL_NEAREST);49. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,50. GL_NEAREST);51. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, checkImageWidth,52. checkImageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,53. checkImage);54.55. glBindTexture(GL_TEXTURE_2D, texName[1]);56. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);57. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);58. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);59. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);60. glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);61. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, checkImageWidth,62. checkImageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,63. otherImage);64.65. glEnable(GL_TEXTURE_2D);66. }67.68. void display(void)69. {70. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);71. glBindTexture(GL_TEXTURE_2D, texName[0]);72. glBegin(GL_QUADS);73. glTexCoord2f(0.0, 0.0); glVertex3f(-2.0, -1.0, 0.0);74. glTexCoord2f(0.0, 1.0); glVertex3f(-2.0, 1.0, 0.0);75. glTexCoord2f(1.0, 1.0); glVertex3f(0.0, 1.0, 0.0);76. glTexCoord2f(1.0, 0.0); glVertex3f(0.0, -1.0, 0.0);77. glEnd();78. glBindTexture(GL_TEXTURE_2D, texName[1]);79. glBegin(GL_QUADS);80. glTexCoord2f(0.0, 0.0); glVertex3f(1.0, -1.0, 0.0);81. glTexCoord2f(0.0, 1.0); glVertex3f(1.0, 1.0, 0.0);82. glTexCoord2f(1.0, 1.0); glVertex3f(2.41421, 1.0, -1.41421);83. glTexCoord2f(1.0, 0.0); glVertex3f(2.41421, -1.0, -1.41421);84. glEnd();85. glFlush();86. }87.88. void reshape(int w, int h)89. {90. glViewport(0, 0, (GLsizei) w, (GLsizei) h);91. glMatrixMode(GL_PROJECTION);92. glLoadIdentity();93. gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 30.0);94. glMatrixMode(GL_MODELVIEW);95. glLoadIdentity();96. glTranslatef(0.0, 0.0, -3.6);97. }98.99. void keyboard(unsigned char key, int x, int y)100. {101. switch (key) {102. case 27:103. exit(0);104. break;105. }106. }107.108. int main(int argc, char** argv)109. {110. glutInit(&argc, argv);111. glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);112. glutInitWindowSize(250, 250);113. glutInitWindowPosition(100, 100);114. glutCreateWindow(argv[0]);115. init();116. glutReshapeFunc(reshape);117. glutDisplayFunc(display);118. glutKeyboardFunc (keyboard);119. glutMainLoop();120. return 0;121. }122. #else123. int main(int argc, char** argv)124. {125. fprintf (stderr, "This program demonstrates a feature which is not in OpenGL Version 1.0.\n"); 126. fprintf (stderr, "If your implementation of OpenGL Version 1.0 has the right extensions,\n"); 127. fprintf (stderr, "you may be able to modify this program to make it run.\n");128. return 0;129. }130. #endif运⾏结果:。
OpenGL参数曲面纹理映射的实现
OpenGL参数曲面纹理映射的实现的1.0。
8坐标的范围为从+Y轴的0.0处开始,到+X轴的0.25,再到一y轴的0.5,再到一X轴的0.75,最后返回到+Y轴的1.0处。
如图2,就是利用Opengl中由二次工具生成的纹理坐标的圆柱面的纹理映射。
图2圆柱面纹理映射3.NURBS曲面纹理映射(1)NURBS曲线的定义NURBS曲线为一分段的有理多项式函数,其表达式5为:…∑B“(u)EKP(1‘)=上0_——一∑B“(u)Ei=0(5)式中K为控制点,职为权因子,B“(u)为||}次日样条基函数,由递推公式定义为式6:蹦Ⅱ):f㈠t辄引ML0others删加掣+虹掣(6)(t。
.I≤址≤t。
+I,k>O)式(6)中k为幂次,‰(i=0,1,…,m)为节点,形成节点矢量U=[U0,“l’.”,u。
]。
当节点数为m+1,控制点数为n+l,幂次为k时,有关系式ltn=Ⅱ+1。
(2)NURBS曲面的定义NUP,BS曲面定义如下:∑∑Bi.。
(“)B(”)』.1职JKJP(u,∥)=上¥专—————一u,”∈[o,1](7)∑∑Bi.。
(“)曰(叱吒式(7)中KJ为控制点,职J为权因子,Bu(H),易.。
(u)分别为沿“向的k次和沿”向的t次B样条基函数。
(3)OPENGL中曲面纹理映射的实现在OpenGL中,为了绘制一条样条曲线或曲面必须先定义求值器,才能计算曲线上点的坐标并完成绘制。
对于样条曲线,OpenGL使用一维基函数,并且只使用如下形式的多项式:【40研(n)=f?k1一“)州,f=0,…?,n(8)多项式(8)称为n次或/7,+1阶Bezier多项式。
设Pj表示控制点,则c(u)=∑87(u)P,(9)这样,C(u)就是样条曲线的求值器。
u的取值范围为[0,1]。
如果u的取值范围为[u。
%],则求值器为?36?c伫二丝1(10)、%一Ul/对于曲面,求值器除了使用两个参数u和”外,其余与一维求值器基本相同。
第五章 纹理映射基础
也可以定义一维或三维纹理,函数分别是 GLTexImage1D()和GLTexImage3D()
2.2 控制纹理
控制纹理:控制纹理图像的纹理如何对应到屏幕上的像素, 怎样通过纹理贴图实现纹理缩放和纹理重复等 函数: void glTexParameter{if}[v](GLenum target, GLenum pname,TYPE param) 该函数控制设置几个纹理参数,这些参数绑定到当前的纹 理状态,可以通过glBindTexture设置为当前状态 target——指定的纹理目标 pname——将要设置的纹理参数 param——pname所指定的参数值
GL_LINEAR线性过滤: 将纹理坐标周围的纹理单元的加权平均值 应用到这个纹理坐标上(线性插补) 特点:纹理被拉伸时出现"失真",但是, 和最邻近过滤相比,这种"失真"更真实, 没有人工操作的痕迹
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR)
GL_REPEAT:在纹理坐标超过1.0的方向上对纹 理进行重复
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_REPEAT) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_REPEAT)
2.5 分配纹理坐标
几何坐标决定顶点在屏幕上绘制的位置,纹理坐标 决定纹理图像中哪个像素赋予该顶点 纹理坐标:定义成一,二,三四维坐标,称为s,t,r,q 坐标,以区别于几何坐标(x,y,z,w) 一维纹理用s坐标表示,二维纹理用(s,t)坐标表 示,q坐标像w一样,一般取值为1 ,用于建立齐次坐 标
glGenTextures
glGenTexturesvoid glGenTextures(GLsizei n, GLuint *texture);该函数⽤来产⽣纹理名称。
这⾥纹理名称GLuint *texture是整型的,因此也可以理解为这个函数为这n个纹理指定了n个不同的ID。
在⽤GL渲染的时候,纹理是很常见的东西。
使⽤纹理之前,必须执⾏这句命令为你的texture分配⼀个ID,然后绑定这个纹理,加载纹理图像,这之后,这个纹理才可以使⽤。
加载纹理的代码如下:BOOL LoadTextures(IplImage *pImage, GLuint *pTexture){int Status=FALSE;if(pImage != NULL){Status=TRUE;glGenTextures(1, &pTexture[0]); //注意这⾥glBindTexture(GL_TEXTURE_2D, pTexture[0]);glTexImage2D(GL_TEXTURE_2D, 0, 3,pImage->width, pImage->height,0, GL_BGR, GL_UNSIGNED_BYTE, (unsigned char *)pImage->imageData);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);}return Status;}使⽤上⾯这个函数时需要⼩⼼,这个函数只能放在循环外⾯使⽤!如果你想在循环中重复利⽤这个texture[0],给它加载不同的纹理(⽐如,你想在窗⼝中显⽰序列图像),⽽把这个函数放在循环内部调⽤的话,那么当程序循环⾜够多次之后,你的电脑将变得巨慢⽆⽐,甚⾄导致死机。
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 简单纹理映射以上程序运行结果是将一块纹理映射到两个正方形上去。
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)。
GL_TEXTURE_2D
18
OpenGL中的纹理映射-纹理启用与关闭
glEnable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
19
void setTexture2(void) { FILE* fd; GLubyte ch; int i,j,k; fd=fopen("../HongKong.256.256.raw","r"); for (i=0;i<TEX_WIDTH;i++) { for (j=0; j<TEX_HEIGHT;j++) { for (k=0;k<3;k++) { fread(&ch,1,1,fd); texImage[i][j][k]=(GLubyte)ch; } } } fclose(fd); }
进行纹理映射
建立纹理与三维物体之间的对应关系 扰动法向量
6
纹理空间
纹理定义在单位正方形区域 (0 u 1, 0 v 1) 之上,称为纹理空间
纹理函数是定义在此空间上的函数 纹理空间也可用其他方法定义
用参数曲面的参数域作为纹理空间 2D 用辅助平面、圆柱、球定义纹理空间 2D 用三维直角坐标作为纹理空间 3D
15
OpenGL中的纹理映射-纹理环境
void glTexEnv{if}[v](GLenum target,GLenum pname,TYPE param); 可以用纹理中的值Ct来调整多边形(曲面) 原来的颜色Cf,或用纹理图像中的颜色与多 边形(曲面)原来的颜色进行混合。
GL_DECAL Ct GL_MODULATE Ct Cf GL_BLEND Cf (1-Ct)
13
OpenGL中的纹理映射-纹理定义
void glTexImage2D (GLenum target,GL_TEXTURE_2D GLint level,只有一种分辨率,则level设为0 GLint components, 3表示选择了R、G、B三个分量 GLsizei width,纹理图像的长度宽度 glsizei height, GLint border,纹理图像的边界宽度,通常为0 GLenum format,纹理映射的格式和数据类型 GLenum type,纹理映射的数据类型 const GLvoid *pixels);纹理图像数据
12
OpenGL中的纹理映射figure8.3.c
基本步骤如下:
定义纹理;glTexImage2D 控制纹理; glTexParameter{if}[v] 纹理环境;void glTexEnv{if}[v] 绘制场景,给出顶点的纹理坐标和几何坐标。
纹理映射只能用于RGBA颜色模式。
二维纹理域,三维图形场景物体,二维纹理 映射是一种非线性映射
纹理变形 不能保证纹理连续性
纹理空间定义在三维空间上,与物体空间是 同维的,通过物体空间坐标(x,y,z)来计算 纹理坐标(u,v,w) 把场景中的物体变换到纹理空间的局部坐标 系中去
11
几何纹理
几何纹理方法-对物体表面几何性质作微小 扰动,产生凹凸不平的细节效果,给物体表 面图象加上一个粗糙的外观
颜色纹理
一维纹理,
二维纹理,物体表面花纹、图案 三维纹理,
几何纹理,基于物体表面的微观几何形状
法向扰动
5
纹理映射
纹理映射是把纹理图象值映射到三维物体的表面的技术,以 便于使用简单的几何图产生丰富逼真的视觉效果图像 纹理映射的问题
纹理定义方法:
图象纹理:将二维纹理图案映射到三维物体表面,绘制物体 表面上一点时,采用相应的纹理图案中相应点的颜色值。 函数纹理:用数学函数定义简单的二维纹理图案,如方格地 毯。或用数学函数定义随机高度场,生成表面粗糙纹理即几 何纹理
14
OpenGL中的纹理映射-纹理控制
void glTexParameter{if}[v] (GLenum target,GLenum pname, TYPE param); ______________________________________________ 参 数 值 ______________________________________________ GL_TEXTURE_WRAP_S GL_TEXTURE_WRAP_T GL_CLAMP 大于1的纹素值都置为1,小于0的置为0 GL_REPEAT 重复映射
7
二维纹理映射
二维纹理映射技术:贴墙纸
三个空间
纹理空间:二维图像 景物空间:物体 图像空间:屏幕
两个映射关系
纹理空间与景物空间的映射? 景物空间与图像空间的映射:一旦确定相机参数, 即可由取景变换及其逆变换确定
8
二维纹理映射示意图
9
参数映射
10
三维纹理域的映射
GL_TEXTURE_MAG_FILTER 放大滤波方法 GL_TEXTURE_MIN_FILTER 缩小滤波方法 GL_NEAREST 最靠近象素中心的纹素 GL_LINEAR 最靠近象素中心的四个象素的加权平均值 ______________________________________________
第8章 纹理映射
解决计算机生成真实感图象缺乏现实物体表 面细节的问题
1
纹理例子
2
纹理的概述
用简单光照明模型生成真实感图象,由于表 面过于光滑单调,反而显得不真实 现实物体表面有各种表面细节-纹理
木材表面的木纹 建筑物墙壁上的装饰图案 桔子皮表面的皱纹
3示例4源自理 纹理是物体表面的细小结构 纹理类型
16
OpenGL中的纹理映射-纹理坐标
坐标定义
void glTexCoord{1234}{sifd}[v] (TYPE coords);
17
OpenGL中的纹理映射-多个纹理
void glGenTextures( GLsizei n, GLuint *textures ); void glBindTexture( GLenum target, GLuint texture );