现在的位置: 首页 > 综合 > 正文

OpenGL 纹理

2013年01月02日 ⁄ 综合 ⁄ 共 4631字 ⁄ 字号 评论关闭

大概步骤:

1.创建纹理对象,并为他指定一个纹理.

2.确定纹理如何应用到每个像素上.

3.启用纹理贴图

4.绘制场景,提供纹理和几何坐标

过滤:由于我们提供的纹理图像很少能和最终的屏幕坐标形成对应,大小不同,所以需要设置过滤项目.允许我们进行插值或者匀和,指定放大缩小的函数.glTexParameter*(),使用过滤模式GL_NEAREST那么纹理单位最邻近的将被使用,GL_LINEAR那么就用2*2的包含纹理数据的数组加权组作为纹理;

命名纹理对象:glGenTexures(GLSize n,Gluint *textureNames); n为产生n个未使用的对象值,textureNames为纹理名字数组,你可能有几个纹理需要使用,这个数组来区分.

1.你需要载入图片时候的纹理定义

void glTexImage2D( GLenum target, GLint level, GLint components,GLsizei width, GLsizei height, GLint border,GLenum format, GLenum type, const GLvoid *pixels );

定义一个二维纹理映射。target是常数 GL_TEXTURE_2D, level表示多级分辨率的纹理图象的级数。若只有一种分辨率,level为0。components是从1到4的整数,1:选择R;2:选择R A;3:选择R G B;

源文档 <http://www.pinxue.net/OpenGL/credbook/chapter9_textuer.htm>

绑定纹理对象:glBindTexture(Glenum target,Gluint,glTexImage*),将把数据存储到这个纹理对象中,如果需要纹理图像的颜色和物体表面的颜色进行组合,不是直接贴图,那么就需要glTexEvn*()函数.

确定纹理坐标:glTexCoord2f(1of1Of)glVertex3f(1Of1Of0Of);比如这一句话.对于设置纹理贴图的坐标和绘图坐标的确定问题.一般的情况假设纹理和图片都是正方形的,那么我们希望纹理映射到整个物体上面,这个时候纹理坐标按照逆时针放心依次(0,0),(1,0),(1,1),(0,1),其中的四个坐标只是代表的向量,并不是真实的坐标,如果是要一半贴到物体上就应该是0.5的值了,假如你给的纹理坐标大于1,那么将会贴多个纹理,比如值为2的时候,会有4个纹理贴图.

概述

     概括的说, 纹理映射机制允许你将一个图像关联到一个多边形上,从而呈现出真实视觉效果。例如, 你可以将书的封面图像应用到一个方形上, 这样这个方形看起来就像是一本书了。 你可以将地球的地图通过纹理映射应用到一个球体上, 那么这个球体就是一个3D的具真实感的地球了。纹理映射在当今的3D图形应用上处处皆是。游戏都是通过纹理映射来作为虚拟真实的第一个步骤。

    纹理映射是一个二维的数组。数组中的每一项称之为纹理点texel ) 虽然这个数组是二维的, 但是可以映射到非二维的对象上, 如球体或者其他的 3D 对象模型上。

    比较常见的是, 开发者在他们的图形应用中运用二维纹理, 当然一维或者三维的纹理也并非未闻。二维纹理有宽度和高度决定二维。一维纹理也有宽度和高度, 只是高度被设为值 1(单位:像素 pixel). 而三维纹理不仅具有宽度和高度, 还有深度, 所以三维为纹理又称为立体纹理。我们讨论的主要是二维纹理。

预备知识: 纹理坐标

     OpenGl 中是通过指定纹理坐标来将纹理映射到多边形上去的在纹理坐标系中左下角是 (0,0), 右上角是 (1,1).
2D 
纹理的坐标中通过指定 (s,t) (sx轴上,ty轴上取值0~1).
1D, 3D, 4D
纹理坐标系中对应的需要指定 (s), (s,t,r), (s,t, r,q).

    纹理坐标需要通过函数 glTexCoord() 来设置此函数:

void glTexCoord{1234}{sifd}(TYPE coords);

void glTexCoord{1234}{sifd}v(TYPE coords);

   

    如将 2D 纹理坐标设为 (0.2,
0.4):

1

glTexCoord2f(0.2f,0.4f);

    每次通过 glVertex() 指定一个顶点时当前的纹理坐标会被应用到这个点上所以每指定一个新的顶点需要同时修改纹理坐标:

1

2

3

4

5

6

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();

    至此我们知道了纹理坐标如何赋值.且看如何创建纹理:

使用纹理映射

    纹理就是应用到多边形上的图像这些图像可以从文件中加载或是在内存中生成一旦你将图像数据加载到了内存中你需要指定其为纹理映射来使用它指定其为纹理映射首先需要生成一个纹理对象其中存储着纹理的诸如图像数据如何应用等信息.

    纹理是一个OpenGL状态因而通过 glEnable()  glDisable() 来开闭, 参数是 GL_TEXTURE_1D,  GL_TEXTURE_2DGL_TEXTURE_3D,  GL_TEXTURE_CUBE_MAP.

3.1 纹理对象

    纹理对象是内部数据类型存储着纹理数据和选项等你不能直接访问它但是可以通过一个整数的 ID 来作为其句柄(handler) 来跟踪之为了分配到一个唯一的 ID,
OpenGL 
提供了glGenTextures() 函数来获取一个有效的 ID 标识值:

void glGenTexture(Glsizei n, GLuint *texture);

   

    texture 是一个数组用于存储分配到的nID在调用一次 glGenTextures() 会将分配到的 ID 标识为'已用', 虽然直到绑定后才真正为'已用'.

    分配3个纹理对象 ID:

?

1

2

unsigned inttextureObjects[3];

glGenTexture(3, textureObjects);

3.2 纹理绑定

    在第一次绑定一个纹理对象时会将一系列初始值来适应你的应用函数 glBindTexture() 用于绑定操作:

void glBindTexture(GLenum target, GLuint texture);

   

    target 指定了纹理类型GL_TEXTURE_1D,  GL_TEXTURE_2D,  GL_TEXTURE_3D,  GL_TEXTURE_CUBE_MAP
texure 
是你希望绑定的纹理对象的 ID.

    一个被绑定的纹理对象直到被删除,或被另外的纹理对象绑定到 target 上才被解除绑定当一个纹理对象绑定到 target 上后, OpenGL 的后续的纹理操作都是基于这个纹理对象的。

?

1

2

3

4

5

6

7

8

9

10

glBindTexture (GL_TEXTURE_2D, textureObject[0]);

// 后面的对 GL_TEXTURE_2D 的纹理操作影响textureObject[0]

   

glBindTexture (GL_TEXTURE_3D, textureObject[1]);

// 后面的对 GL_TEXTURE_3D 的纹理操作影响textureObject[1]

//  GL_TEXTURE_2D 的纹理操作依然影响textureObject[0]

   

glBindTexture (GL_TEXTURE_2D, textureObject[2]);

// 后面的对 GL_TEXTURE_2D 的纹理操作影响textureObject[2]

//  GL_TEXTURE_3D 的纹理操作依然影响textureObject[1]

3.3 删除纹理对象

    创建一个纹理对象后,
OpenGL
为其分配内存所以当不再使用一个纹理对象时为防止内存泄露必须删除删除纹理对象的函数glDeleteTexture() :

void glDeleteTexure(Glsizei n, Gluint *texture);

   

    texture 指定了要删除的纹理对象的 ID
(n
). 在删除后, texture 中的各个对象 ID 会置为0.

3.4 驻留纹理

    显卡有一块固定大小的内存区域专门用于存储纹理数据。当数据超量时,会将一部分纹理数据移除到系统内存中(通常是最近最少使用的纹理数据). 当这些移除的纹理被再次使用时,会影响击中率, 因为它们会被再次移入显卡的内存中。你可以查看一个纹理对象是否驻留在显卡内存中未被移出, 通过函数 glAreTexturesResident() :

GLboolean glAreTexturesResident (GLsizei n, GLuint *textures, GLboolean *residents);

   

    texture 中每一项纹理对象的驻留情况会存储在 resident 参数中返回。  textures 中有一项纹理对象不在内存驻留内存,函数会返回 GL_FALSE.

3.5 纹理优先级

    纹理的优先级是针对驻留显卡内存而言。优先级设置函数 glPrioritizeTextures() :

void glPrioritizeTextures (GLsizei n, GLuint *textures, GLclampf *priorities)

   

    前两个参数 textures  n 指定了要设置优先级的纹理对象数组。 priorities  textures 中每一项纹理对象对应的优先级,priorities 中每一项的优先级取值区间是 [0,1],
0
为优先级最低, 1 为最高。 glPrioritizeTextures() 函数会忽略掉那些未使用的和优先级要设为 0 的纹理对象。

指定纹理

    OpenGL 提供了三个函数来指定纹理glTexImage1D()glTexImage2D()glTexImage3D()这三个版本用于相应维数的纹理, 例如如果纹理是3D纹理,则需要有 glTexImage3D() 来指定。

4.1 2D 纹理

void glTexImage2D (GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* texels);

   

抱歉!评论已关闭.