轉自http://www.cnblogs.com/jenry/p/4083415.html
1.什么是UV?
對於三維模型,有兩個最重要的坐標系統,一是頂點的位置(X,Y,Z)坐標,另一個就是UV坐標。什么是UV?簡單的說,就是貼圖影射到模型表面的依據。 完整的說,其實應該是UVW(因為XYZ已經用過了,所以另選三個字母表示)。U和V分別是圖片在顯示器水平、垂直方向上的坐標,取值一般都是0~1,也 就是(水平方向的第U個像素/圖片寬度,垂直方向的第V個像素/圖片高度)。那W呢?貼圖是二維的,何來三個坐標?嗯嗯,W的方向垂直於顯示器表面,一般 用於程序貼圖或者某些3D貼圖技術(記住,確實有三維貼圖這種概念!),對於游戲而言不常用到,所以一般我們就簡稱UV了。
所有的圖象文件都是二維的一個平面。水平方向是U,垂直方向是V,通過這個平面的,二維的UV坐標系。我們可以定位圖象上的任意一個象素。但是一個問題是如何把這個二維的平面貼到三維的NURBS表面和多邊形表面呢? 對於NURBS表面。由於他本身具有UV參數,盡管這個UV值是用來定位表面上的點的參數,但由於它也是二維的,所以很容易通過換算把表面上的點和平面圖象上的象素對應起來。所以把圖象貼帶NURBS是很直接的一件事。但是對於多變形模型來講,貼圖就變成一件麻煩的事了。所以多邊形為了貼圖就額外引進了一個UV坐標,以便把多邊形的頂點和圖象文件上的象素對應起來,這樣才能在多邊形表面上定位紋理貼圖。所以說多邊形的頂點除了具有三維的空間坐標外。還具有二維的UV坐標。
UV" 這里是指u,v紋理貼圖坐標的簡稱(它和空間模型的X, Y, Z軸是類似的). 它定義了圖片上每個點的位置的信息. 這些點與3D模型是相互聯系的, 以決定表面紋理貼圖的位置. UV就是將圖像上每一個點精確對應到模型物體的表面. 在點與點之間的間隙位置由軟件進行圖像光滑插值處理. 這就是所謂的UV貼圖.
那為什么用UV坐標而不是標准的投影坐標呢? 通常給物體紋理貼圖最標准的方法就是以planar(平面),cylindrical(圓柱), spherical(球形),cubic(方盒)坐標方式投影貼圖.
Planar projection(平面投影方式)是將圖像沿x,y或z軸直接投影到物體. 這種方法使用於紙張, 布告, 書的封面等 - 也就是表面平整的物體.平面投影的缺點是如果表面不平整, 或者物體邊緣彎曲, 就會產生如圖A的不理想接縫和變形. 避免這種情況需要創建帶有alpha通道的圖像, 來掩蓋臨近的平面投影接縫, 而這會是非常煩瑣的工作. 所以不要對有較大厚度的物體和不平整的表面運用平面投影方式. 對於立方體可以在x, y方向分別進行平面投影, 但是要注意邊緣接縫的融合. 或者采用無縫連續的紋理, 並使用cubic投影方式. 多數軟件有圖片自動縮放功能, 使圖像與表面吻合. 顯然, 如果你的圖像與表面形狀不同, 自動縮放就會改變圖像的比例以吻合表面. 這通常會產生不理想的效果, 所以制作貼圖前先測量你的物體尺寸.
2、uv紋理坐標設定與貼圖規則
當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,
};
效果如下:

如果我們想截取圖片有上角不分做紋理,按照上面方法可獲的數組
float texCoords[] = new float[] {
// FRONT
0.5f, 0.5f,
1f, 0.5f,
0.5f, 1f,
1f, 1f
};
效果如下:

我們看下貼圖的原始文件

你會發現截屏中的圖片y軸是顛倒的,其實這是android圖像坐標系統與Opengl es 坐標系統不一致導致的。最簡單的修正辦法將原始圖片用工具翻轉過來,這樣會比用程序翻轉節省很多性能,資源是寶貴的。
三角形紋理映射,只要按照我們的映射規則,便可以順利完成映射。
float 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。這實際會引起邊沿像素重復。
我們可以通過glTexParameteri()函數設置。
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

