OpenGL ES 纹理贴图的重复与嵌位概念理解
<a target="_blank" href="http://blog.csdn.net/opengl_es">转载请保留此句:太阳火神的美丽人生 - 本博客专注于 敏捷开发及移动和物联设备研究:iOS、Android、Html5、Arduino、pcDuino,否则,出自本博客的文章拒绝转载或再转载,谢谢合作。</a>
以下有一篇转载的Android中关于纹理贴图规则的文章,很不多。
不过我这里是想要深入研究如果让贴图自动根据大小进行阵列排布,这个在 3DMax 中曾经见过,不过后来忘了,再问3D美工,就变成用坐标了,那个确实不是我想要的,但3DMax我确实不太熟悉,我了解3DMax充其量也就是为了明白三维的概念和操作方式,并不想深入去掌握3DMax这一三维美工熟练工种。
当纹理坐标小于等于1.0时,会在这张纹理贴图中取指定百分比的部分;
当纹理坐标大于1.0时,按参数指示,可以进行重复,那么大于的值如何给定呢?
这里考虑,是否可以用几何体面的宽和高与图片的宽和高进行比对来得到这个值,这样图片就会按原始尺寸比例去绘制,其它部分就进行复制重复,形成阵列效果。
但图片的尺寸是像素,几何体的尺寸是什么呢?是mm ?再或者用栅格化后的片元尺寸?这些个概念暂时还搞不清,三维到二维的尺寸如何换算?纹理贴图与三维坐标尺寸如何比较,这个可能就成为焦点问题。
本贴虽未解决问题,但至少提出了问题,同时就是找到了一个研究的方向。所谓研究,不是学习现成的资料,而是对未知方向的问题,通知分析找到去学习和有机组合的方式的过程,而没有现成的完整的资料,拿来看会了就行。所以学习和研究是有区别的。
<dl></dl>
<dt><code>GL_TEXTURE_WRAP_S</code></dt>
<dd></dd>
设置纹理坐标的包装参数为 <code>GL_CLAMP_TO_EDGE</code>, <code>GL_MIRRORED_REPEAT 或 </code> <code>GL_REPEAT。</code>
GL _CLAMP_TO_EDGE 使坐标夹紧在 这样的范围内 1 2N 1 - 12N (官方就这么写的,我也不知道是什么东西),这里 N 纹理在夹紧方向上的大小。
GL_REPEAT 使 s 坐标的整数部分被忽略; GL 只使用小数部分,从而创建一个重复构形。
GL_MIRRORED_REPEAT 在纹理坐标的整数部分是奇数时,使 s 坐标设置为纹理坐标的小数部分;如果整数部分是偶数,那么 s 坐标被设置成 1 - 小数部分,这里 s 的小数部分代表 s 的去掉整数部分后的小数部分。初始,GL_TEXTURE_WRAP_S 设为 GL_REPEAT。
Sets the wrap parameter for texture coordinate s to either <code>GL_CLAMP_TO_EDGE</code>, <code>GL_MIRRORED_REPEAT</code>,
or <code>GL_REPEAT</code>. <code>GL_CLAMP_TO_EDGE</code> causes s coordinates
to be clamped to the range 1 2N 1 - 12N , where N is the size of the texture in the direction of clamping. <code>GL_REPEAT</code> causes
the integer part of the s coordinate to be ignored; the GL uses only the fractional part, thereby creating a repeating pattern. <code>GL_MIRRORED_REPEAT</code> causes
the s coordinate to be set to the fractional part of the texture coordinate if the integer part of s is even; if the integer part of s is
odd, then the s texture coordinate is set to 1 - frac s , where frac s represents the fractional part of s.
Initially, <code>GL_TEXTURE_WRAP_S</code> is set to <code>GL_REPEAT</code>.
<dt><code>GL_TEXTURE_WRAP_T</code></dt>
t 坐标同 s 坐标。
Sets the wrap parameter for texture coordinate t to either <code>GL_CLAMP_TO_EDGE</code>, <code>GL_MIRRORED_REPEAT</code>, or <code>GL_REPEAT</code>. See the discussion under <code>GL_TEXTURE_WRAP_S</code>.
Initially,<code>GL_TEXTURE_WRAP_T</code> is set to <code>GL_REPEAT</code>.
由上面官方的资料不难看出,纹理坐标,在 0.0~1.0 之间,超出的部分也还是取小数部分,正数部分只有奇偶之分,根据奇偶来看看如何用这个小数部分,这是GL_MIRRORED_REPEAT的用法;而GL_REPEAT就没那么多说法了,直接就用小数部分。
所以,取2.0,那么就是取 1-0;取3.0,就是取0;
那么,我想知道,重复多少遍,是否可以控制呢?
原始纹理贴图拉伸以填满:
S和T坐标方向均重复两个:
S和T坐标方向均重复四个:
如下,在原接近1.0的纹理坐标上进行相应处理,加了个整数4:
结果是S和T方向都重复了五次。
按下面的方式,把所有接近1.0和0.0的坐标值都加上4:
这时 OpenGLES 也被我弄不会了,哈哈哈,它把这些整数全忽略了,按未加前的方式处理。
我们这回直给接近0.0的加上4,如下:
这时,S和T方向只重复了3次;
以上是S和T方向均使用的 GL_REPEAT ,如下:
下面再针对 GL_MIRRORED_REPEAT 进行测试:
接近0.0的值加4,如上面对应的情况,结果还是重复了3 次;
接近1.0的值加4,如上面对应的情况,结果还是重复了5 次;
以上均是加的4或2,是偶数,不知加了奇数会怎么样,初步估计:
接近0.0的值加5,结果是重复了5次;
接近1.0的值加5,结果还是重复了5次;
再辛苦一下,做一遍这个测试,不测全面了,很难从中结合官方的论述来得出一个正确的结论。如果官方说的你很清楚了,那么本文就可以忽略了。
实践证明,
接近1.0的数加5,结果一个轴重复了5次,一个轴重复了3次;
接近0.0的数加5,结果两个轴都重复了4次,而且有间隔着镜像效果的重复出现;
回看了一 遍官方的说明,其实那应该是针对一张贴图的,反反复复试了这么多了,感觉还是拿不定是怎么回事儿。
为什么官方的资料也说的这么含胡不清呢?!也许是我的三维基础知识太差的关系吧。
有时侯当你感觉到别人说的东西不清楚的时侯,其实应该是有一些前提条件,你并不了解,而对方确以为或自认为你就应该了解,但哪有那么多应该的事情,还是要实是求事,尊重事实,才不至于走弯路,做无用功。
以上未贴图,因涉及公司机密,故请见谅。
当opengl对一个四方形进行贴图时,会定义纹理贴图坐标,一串数组,相信初学openggl es者看到后会很头疼,不知道写得是什么东西。现在就将我的研究成果与大家分享下!
当纹理映射启动后绘图时,你必须为OpenGL ES提供其他数据,即顶点数组中各顶点的纹理坐标。纹理坐标定义了图像的哪一部分将被映射到多边形。它的工作方式有点奇怪。
下面看下在android平台下Opengl纹理系统坐标,左下角为原点。

我们现在讨论怎样使用这些纹理坐标。当我们指定顶点数组中的顶点时,我们需要在另一个数组中提供纹理坐标,它称为纹理坐标数组。这里需要注意定义坐标数组顺序,这很关键。
float
texCoords[] = new float[] {
// FRONT
0.0f, 0.0f,
1.0f, 0.0f,
0.0f, 1.0f,
1.0f, 1.0f,
};
效果如下:
如果我们想截取图片有上角不分做纹理,按照上面方法可获的数组
// FRONT
0.5f, 0.5f,
1f, 0.5f,
0.5f, 1f,
1f, 1f
我们看下贴图的原始文件
你会发现截屏中的图片y轴是颠倒的,其实这是android图像坐标系统与Opengl
es 坐标系统不一致导致的。最简单的修正办法将原始图片用工具翻转过来,这样会比用程序翻转节省很多性能,资源是宝贵的。
三角形纹理映射,只要按照我们的映射规则,便可以顺利完成映射。
texCoords[] = new float[] {
0.0f, 0.0f,
1.0f, 0.0f,
0.5f, 1.0f,
};
效果:
看到这里应该知道纹理坐标数组规则定义的意义了吧。
平铺与箔拉
我们的纹理坐标系统在两个轴上都是从0.0
到 1.0,如果设置超出此范围的值会怎么样?根据视图的设置方式有两种选择。
平铺(也叫重复)
一种选择是平铺纹理。按OpenGL的术语,也叫“重复”。如果我们将第一个纹理坐标数组的所有1.0改为2.0:
static const GLfloat texCoords[] = {
0.0, 2.0,
2.0, 2.0,
0.0, 0.0,
2.0, 0.0
};
我们可以通过glTexParameteri()函数设置。
glTexParameterf(GL_TEXTURE_2D,
GL_TEXTURE_WRAP_S, GL10.GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);
箝位
另一种可能的选择是让OpenGL ES简单地将超过1.0的值限制为1.0,任何低于0.0的值限制为 0.0。这实际会引起边沿像素重复。
GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
转自:http://blog.csdn.net/cjkwin/article/details/6016224