简单纹理贴图

1 纹理 Texture

纹理定义了物体表面的结构,如花纹,图案,皱纹等等。有了纹理,模型世界才会更加丰富多彩。如一个球形模型,我们给其映射足球的纹理,这就是一个足球,给其映射地球纹理,就是一个地球。另外,如果给一个四边形映射一个墙的纹理,这边是墙,否则,我们需要一块砖一块砖的构建在本节中,我们所指的是狭义的纹理: 图像纹理(对应的有函数纹理—用数学函数来定义的纹理)。

纹理实际上是一个二维数组,其元素是一些颜色值,每一元素称之为纹理像素 (texel)。 纹理对象是一个内部数据类型,存储着纹理数据。你不能直接访问纹理对象,但是可以通过一个整数的 ID 来作为其句柄跟踪之。通过此句柄,你可以作为当前使用的纹理(称之为纹理绑定),也可以从内存中删除这个纹理对象,还可以为一的纹理赋值(将一些纹理数据加载到关联的纹理中,称之为指定纹理)。

通常一个纹理映射的步骤是:

  1. 创建纹理对象。就是获得一个新的纹理句柄 ID.
  2. 指定纹理。就是将数据赋值给 ID 的纹理对象,在这一步,图像数据正式加载到了 ID 的纹理对象中。
  3. 设定过滤器。定义了opengl现实图像的效果,如纹理放大时的马赛克消除。
  4. 绑定纹理对象。就是将 ID 的纹理作为下面操作的纹理。
  5. 纹理映射。将已绑定纹理的数据绘制到屏幕上去,在这一步,就能看到贴图的效果了。

1.1 纹理坐标 和 纹理映射

一个纹理对象有其自己的一套坐标系,左下角是 (0,0) 右上角是 (1,1):

我们要将一个图像的一部分绘制到屏幕上,称之为纹理映射, 就是将图像根据上述坐标系计算出要绘制的部分的各个点的纹理坐标,然后一一对应到屏幕上的坐标中去(下图中的坐标系是左上角为原点的):

1.2 opengl 中启用纹理映射功能

在默认设置中,纹理映射是关闭的,启用的参数是 GLTEXTURE2D, 还有其他的参数: GL_TEXTURE_1D, GL_TEXTURE_3D, GL_TEXTURE_CUBE_MAP。我们只用到2D纹理,其他不再赘述。

1.3 创建纹理

创建纹理,用函数 glGenTextures() 完成,函数返回新创建的纹理的 ID。此函数可以创建 n 个纹理,并将纹理ID 放在 textures 中:


void glGenTextures (int n, IntBuffer textures)

范例:

 

?
1        
2
3
IntBuffer intBuffer = IntBuffer.allocate( 1 );
gl.glGenTextures( 1 , intBuffer);
int  textureId = intBuffer.get();  // 纹理 ID

 

1.4 指定纹理

OpenGL 提供了三个函数来指定纹理: glTexImage1D(), glTexImage2D(), glTexImage3D(). 这三个版本用于相应维数的纹理,我们用到的是 2D 版本: glTexImage2D().


void glTexImage2D (int target, int level, int internalformat, int width, int height, int border, int format, int type, Buffer pixels)

参数过多,可以使用 GLUtils 中的 texImage2D() 函数,好处是直接将 Bitmap 数据作为参数:


void texImage2D (int target, int level, Bitmap bitmap, int border)

参数:

target
操作的目标类型,设为 GL_TEXTURE_2D 即可
level
纹理的级别,本节不涉及,设为 0 即可
bitmap
图像
border
边框,一般设为0

1.5 删除纹理

删除纹理, 第三个参数指明了第二个参数 textures 数组中纹理ID 的步长,一般是紧凑顺序存放,设为0即可。


void glDeleteTextures (int n, int[] textures, int offset)

1.6 绑定纹理

绑定后,此纹理处于活动状态。在第一次绑定一个纹理对象时, 会将一系列初始值来适应你的应用。绑定比较简单,用函数 glBindTexture():


void glBindTexture (int target, int texture)

第一个参数是纹理类型,我们使用 2D 纹理,参数设为 GL_TEXTURE_2D, 第二个参数是纹理对象的 ID。

1.7 设置过滤器

有两个版本:float版和int版本。


void glTexParameterf (int target, int pname, float param) 
void glTexParameterx (int target, int pname, int param)

一般我们设置两个, 一个放大器的: GL_TEXTURE_MAG_FILTER, 一个缩小器的: GL_TEXTURE_MIN_FILTER.

下面的两行告诉OpenGL在显示图像时,当它比放大得原始的纹理大 ( GL_TEXTURE_MAG_FILTER )或缩小得比原始得纹理小( GL_TEXTURE_MIN_FILTER )时OpenGL采用的滤波方式。通常这两种情况下我都采用 GL_LINEAR 。这使得纹理从很远处到离屏幕很近时都平滑显示。使用 GL_LINEAR 需要CPU和显卡做更多的运算。如果您的机器很慢,您也许应该采用 GL_NEAREST 。过滤的纹理在放大的时候,看起来斑驳的很(马赛克)。您也可以结合这两种滤波方式。在近处时使用 GL_LINEAR ,远处时 GL_NEAREST 。

1.8 纹理映射

用函数 glTexCoordPointer 指定纹理坐标数组,


void glTexCoordPointer (int size, int type, int stride, Buffer pointer)

默认这个功能是关闭的,所以需要打开:

1          
2
3
4
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
// ... 
// 关闭
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

2 常见的几个问题

2.1 贴图呈现白色

可能的原因:

  • 未启用 GL_TEXTURE_2D 选项。请使用 glEnable() 和 glDisable() 函数进行开启和关闭。
  • 纹理对象无数据。 使用 GLUtils.texImage2D() 来指定,指定前需 glBindTexture() 激活当前纹理。

2.2 图像扭曲

可能的原因:

  • 纹理坐标和顶点坐标对应关系是否正确,调整之
  • 图像的大小不是 2 的次幂, 解决: 内部重新生成一张 2 的次幂的image,调整uv坐标
Blender是一款强大的三维建模软件,它提供了丰富的纹理贴图功能。在Blender中,你可以使用纹理贴图来为模型添加颜色、表面细节和质感。 要在Blender中使用纹理贴图,首先需要为模型创建材质。然后,你可以将纹理贴图应用到材质的不同属性上,如颜色、法线、凹凸等。 下面是一些基本的步骤来在Blender中使用纹理贴图: 1. 在Blender的“材质”选项卡中,创建一个新的材质或选择一个已存在的材质。 2. 在“材质”选项卡下方的“纹理”选项卡中,点击“新建”按钮来创建一个新的纹理。 3. 在纹理设置中选择你想要使用的纹理类型,如图像或过程生成等。 4. 如果选择了图像纹理类型,可以点击“打开”按钮来导入你的纹理图像文件。 5. 调整纹理的映射方式和坐标轴设置,以确保纹理正确地应用到模型上。 6. 在“影响”部分,选择你希望应用纹理的材质属性,如“颜色”、“凹凸”、“法线”等。 7. 根据需要,你可以调整纹理的缩放、旋转和偏移等参数,以使纹理正确地映射到模型上。 8. 在3D视图中,预览模型的纹理效果。你可以在材质视图或渲染视图中查看。 这只是一个简单的介绍,Blender提供了更多高级的纹理贴图功能,如节点编辑器和材质渲染等。你可以进一步探索Blender的文档和教程,以了解更多关于纹理贴图的技巧和技巧。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值