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