- 浏览: 255883 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
yzb808:
Arrays.asList(ubs)在每次调用switchCh ...
UnicodeBlock(解决中文中方块乱码) -
ejb2008:
感谢楼主,写的太详细了。谢谢分享。
UML类图几种关系的总结 -
ld1024:
很有帮助,写的很好
UML类图几种关系的总结 -
王静娜:
这篇文章写得真不错
UML类图几种关系的总结 -
binzhao88:
EditText和ImageSpan
本文主要分析如何将纹理映射到多边形和物体上,会包含几种纹理映射的方式。
准备好了纹理下面我们分析如何进行映射,将纹理数据映射到具体的物体上去。纹理坐标如下图所示。
假设图中的正方向就是我们要将纹理映射上去的物体(地面),那么我们需要按照图中的表示,为每个顶点指定一个纹理坐标,也称之为UV坐标,它的横向为s轴,纵向围t轴,如下图所示。关于st和uv坐标可以参考一些3D图形学相关知识。
那么下面我们就按照图中的指示来为地面创建一个纹理坐标数组和缓冲区,代码如下:
byte[] tcs = {0,0, 1,0, 0,1, 1,1};
tcsBuf = ByteBuffer.allocateDirect(tcs.length);
tcsBuf.put(tcs).rewind();
准备好纹理的uv坐标之后,下面是最后一步,如何绘制该物体及纹理。代码如下:
public void draw()
{
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glVertexPointer(3, GL10.GL_BYTE, 0, vertsBuf); // use floor verts
gl.glTexCoordPointer(2, GL10.GL_BYTE, 0, tcsBuf); // use tex coords
gl.glEnable(GL10.GL_TEXTURE_2D);
setTexture();
gl.glNormal3f( 0, 1.0f, 0); // facing up
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glDisable(GL10.GL_TEXTURE_2D); // switch off texturing
} // end of draw()
private void setTexture()
{
gl.glBindTexture(GL10.GL_TEXTURE_2D, texNames[0]); // use the tex name
// specify the texture for the currently bound tex name
gl.glTexImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_RGB, imWidth, imHeight, 0,
GL10.GL_RGB, GL10.GL_UNSIGNED_BYTE, texBuf);
// set the minification/magnification techniques
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
} // end of setTexture()
其中大部分代码我们已经接触过,标注为红色的是需要我们解释的,glEnableClientState函数就是允许我们设置纹理坐标数组,而函数glTexCoordPointer就是将前面准备的纹理坐标缓冲区告诉Opengl,这样在绘制图形时,Opengl会自动的对纹理进行处理,并展现出来。
运行结果如下图所示。
图中的地面就是我们绘制的一个四边形,然后给映射了一个地面的纹理贴图上去形成的。这里我们是直接将一整张图给映射上去了,那么我们是否可以只映射图像的一部分呢?答案是肯定的,我们只需要改动UV坐标即可。UV坐标对应如下图所示。
这样应该很好理解,相当于我们只是映射了图像上的0.25到0.75之间的部分(整个图像的宽度和高度为1),即图像的中间部分。当然你同样可以更改这个坐标,来调整自己需要映射的部分,这在实际的游戏开发过程中是经常使用的,尤其是一些2D游戏的开发,会将很多小的图片放置到一个大的图片之上,做成一个图片集,就可以通过这种方式来确定需要映射图片集中的哪一个小的图块。按照上图的指示,我们将代码需要改成float类型的数据即可,如下所示。
float[] tcs = {0.25f,0.25f,0.75f,0.25f,0.25f,0.75f,0.75f,0.75f};
tcsBuf = ByteBuffer.allocateDirect(tcs.length*4).asFloatBuffer();
tcsBuf.put(tcs).rewind();
/////
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, tcsBuf);
运行效果如下图所示。
和第一个效果图相比很明显的纹理只去了图像的中间一部分,上面的两种方式都是将纹理映射到一个四边形上,但是在Opengl ES中最基本的应该是三角形,我们是否可以将纹理映射到三角形上呢,同样可以,对于三角形的纹理示意图如下所示。
就这样,同样的步骤适合于几何体中任何三角形,而且你甚至可以通过非常规方式的映射来扭曲纹理,产生各种特殊的效果。总而言之,纹理上的任何一点都可以映射到多边形的任何一点。或者换而言之,你可以对任何地点(u,v)使用任何(s,t)而OpenGL ES则为你进行映射。
我们的纹理坐标系统在两个轴上都是从0.0 到 1.0,如果设置超出此范围的值会怎么样?根据视图的设置方式有两种选择。一种选择是平铺纹理。按OpenGL的术语,也叫“重复”。如果我们将第一个纹理坐标数组的所有1.0改为2.0:
float[] tcs = {0.0f,0.0f, 2.0f,0.0f, 0.0f,2.0f, 2.0f,2.0f};
在加入如下代码来设置重复的效果。
gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_WRAP_S,GL10.GL_REPEAT);
gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_WRAP_T,GL10.GL_REPEAT);
那么运行效果就会产生将多个相同的图像平铺到地面的四边形上,下如图所示。
另一种可能的选择是让OpenGL ES简单地将超过1.0的值限制为1.0,任何低于0.0的值限制为 0.0。这实际会引起边沿像素重复,从而产生奇怪的效果。将代码更改为如下所示:
gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_WRAP_S,GL10.GL_CLAMP_TO_EDGE);
gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_WRAP_T,GL10.GL_CLAMP_TO_EDGE);
运行效果如下图所示,这个表现得非常明显。
到这里,我们几乎分析完了Opengl中纹理映射的各种方式,当然也还会有其他的方式,但是原理都一样,这里就不重复了,前面介绍的也都是将纹理映射在平面物体上,在文章的最后,我们将一个纹理映射到一个立方体上去。
首先定义纹理映射坐标,如下代码所示:
private byte texCoords[] = { // 4 tex coords for each face
0,0, 1,0, 0,1, 1,1, 0,0, 1,0, 0,1, 1,1, 0,0, 1,0, 0,1, 1,1,
0,0, 1,0, 0,1, 1,1, 0,0, 1,0, 0,1, 1,1, 0,0, 1,0, 0,1, 1,1
};
tcsBuf = ByteBuffer.allocateDirect(texCoords.length);
tcsBuf.put(texCoords).rewind();
然后再绘制时加入和之前同样的代码即可,如下所示。
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glTexCoordPointer(2, GL10.GL_BYTE, 0, tcsBuf); // use tex coords
gl.glEnable(GL10.GL_TEXTURE_2D); // use texturing
指定纹理坐标缓冲区,开启纹理,运行效果就会出现一个贴了纹理的立方体,如下图所示。,
这样的渲染结果看上去比前面几个例子真实多了,这主要就是纹理的用作,因此纹理也是游戏开发中的重点,由于条件限制,大家可以测试更多种类的纹理以及其不同的映射方式。为了使游戏更加完美,下一文我们将介绍更适合游戏中物体的表现方式——模型。
发表评论
-
【Android笔记】各个屏幕的logo尺寸要求
2015-07-31 15:29 2753Android Icon Size and Location ... -
oauth2.0认证和授权原理
2015-07-01 16:02 956【转:http://www.phpddt.com/%E4%B ... -
解决Android单个dex文件不能超过65536个方法问题
2015-06-23 23:50 1783当我们的项目代码过大时,编译运行时会报Unable to e ... -
Android涉及到的设计模式
2015-06-23 18:23 597【转:http://blog.csdn.net/dengsh ... -
android camera拍照失真问题
2015-03-10 18:12 2633项目中遇到各种失真,例如图片变绿,图片曝光严重,出现两个图片 ... -
px,dp,sp
2015-03-05 17:10 8541、px 像素,1px代表屏幕上一个物理的像素点,px单位 ... -
关于build.prop原始Dalvik虚拟机设定与调整
2015-03-05 16:41 1641看了很多帖子,自己亲身实践了一下。有不足希望高手指出来,共同 ... -
android有时候相机对焦成功,照片却模糊
2014-08-07 16:42 1923急急急!!! android有的相机有时候对焦成功, ... -
Android中数据存储--采用SQLite存储数据及在SDCard中创建数据库
2014-07-11 10:57 884SQLite数据库简单的认识 ... -
android 反射的使用场景
2013-12-26 17:34 1304【转】http://mysuperbaby.iteye.co ... -
webview原始大小时如何缩小网页
2013-12-26 14:33 962webview原始大小的时候,没办法缩小。 这个如何处理, ... -
更改eclipse关联的源码(重新关联源码)
2013-12-26 14:28 1098在项目上点右键-->build path-->co ... -
webview内嵌listview
2013-11-05 16:09 1611webview的header中是一个listview。 想 ... -
default.properties的target和AndroidManifest中的android:minSdkVersion
2013-10-12 10:45 1535客户反馈,在2.X系统运行有问题。 查看工程配置。 发 ... -
自定义ProgressBar的加载效果
2013-09-24 18:19 1439【转】http://gundumw100.iteye.com ... -
sqlite cmd 控制台中文乱码
2013-09-08 15:01 973打开CMD.exe命令行窗口通过 chcp命令改变代码页,U ... -
ADT17以后关联源码方法
2013-08-26 22:37 793在libs目录下建与jar包同名(包括.jar)的prope ... -
java学习笔记:常见字符编码和编码头BOM
2013-06-28 11:00 1062ANSI(American National Standar ... -
非法字符: \65279 (utf-8 BOM标记)
2013-06-28 10:57 5515Linux先使用grep -r $'\xEF\xBB\xB ... -
如何混淆Android项目代码(ProGuard)
2013-05-09 14:33 2631ProGuard简介 ProGuard是 ...
相关推荐
注重讲解opengl纹理映射原理及实现细节,适合初学者攻读的文档
这是一本介绍OpenGL纹理映射的好资料.不下会后悔的.
注重讲解opengl纹理映射原理及实现细节,适合初学者攻读
用MFC 与opengl生成。VS2003.net运行环境。值得参考一下。
这是一篇关于用opengl对六面体进行纹理映射的代码
Qt OpenGL纹理映射Demo。配合文章https://www.cnblogs.com/tornadomeet/archive/2012/08/24/2654719.html
OpenGL纹理映射实例教程,里面有很好的例子,其中载入图片的类Texture是一个亮点,可以载入多种格式的图片,且图片大小不受限制。
opengl 中的纹理映射效果,立方体6面分别映射不同的纹理效果,可以旋转
C++ opengl纹理与映射 包含实现详细原理及三个完整贴图程序 和源代码
opengl源代码,实现了一个立方体各表面的多纹理映射
本资源适合于初学或者熟练掌握OPENGL的学者,主要是巩固对opengl中纹理映射的学习。
纹理映射基础知识 什么叫纹理映射,一开始我也不明白,感觉这个词好专业(毕竟没有学过图形学),后面经过网上查找资料和这次实验稍微理解了点。纹理映射简单的讲,就是把一个纹理(其实说白了,纹理可以理解为一幅图像...
运用C#、opengl做的三维纹理映射,比较有参考价值,希望对大家有帮助
方向键可以进行移动,按F键更改纹理,按B键添加光照。 立方体上面的是贝塞尔曲面,可以通过A键和D键进行旋转,还可以通过W和S键进行变换曲面的扭曲程度。按空格键可以时曲面的轮廓消失。 最里边是一个变幻的圆环 。 ...
通过VS2015编译,如果使用其他VS版本,请替换相应lib文件。实现简单的纹理映射。
自己结合qiliang老师的教程和C++GUIQT4教程写的一个小程序。