假若有一個三角形,它的三個頂點是在虛擬空間中的,若是須要對這個三角形進行旋轉,縮放,平移的操做,須要用到model矩陣操做,model矩陣只對當前的這個三角形操做,不會影響其餘物體。在對一個物體進行矩陣操做以前,須要將這個矩陣作單位化操做。android
(1)矩陣的平移編程
private final float[] modelMatrix = new float[16]; //得到一個model矩陣遊戲
Matrix.setIdentityM(modelMatrix, 0); //利用android自帶的Matrix單位化矩陣
Matrix.translateM(modelMatrix, 0, 0, -1.2f, 0); //將物體向Y軸移動-1.2個單位數學
(2)矩陣的旋轉:當使用model矩陣旋轉物體時,能夠繞着X,Y,Z軸旋轉,it
Matrix.rotateM(modelMatrix, 0, rotateAngle, 1f, 0f, 0f);//繞着X軸旋轉rotateAngleio
Matrix.rotateM(modelMatrix, 0, rotateAngle, 0, 1f, 0f);//繞着Y軸旋轉rotateAngle基礎
Matrix.rotateM(modelMatrix, 0, rotateAngle, 0f, 0f, 1f);//繞着Z軸旋轉rotateAnglemodel
(2.1)可是若是要使得物體圍繞着某一個點旋轉,那該怎麼辦呢?答案是矩陣的複合操做。float
好比一個物體有一個頂點(1.1f, -1.2f, 0),我想要這個物體圍繞這個頂點旋轉。移動
1.將物體移動到原點的位置,也就是虛擬空間的原點。Matrix.translateM(modelMatrix, 0, -1.1f, 1.2f, 0);
2.旋轉該物體。Matrix.rotateM(modelMatrix, 0, rotateAngle, 1f, 0f, 0f);
3.將物體移動到(1.1f, -1.2f, 0)。Matrix.translateM(modelMatrix, 0, 1.1f, -1.2f, 0);
思路基本上這麼個思路,可是這裏有一個很容易掉進去的陷阱,矩陣操做的順序。若是按照剛纔的1,2,3的步驟,得不到想要的結果。由於這個和矩陣相乘有關係,放在最前面的矩陣最後被乘,最後面的矩陣最早被乘。這個數學關係有興趣的朋友能夠參考《[遊戲編程數學和物理基礎].(斯達樂)》這本書的6.4章節,那裏講的比較精彩。因此正確的代碼順序應該是:
Matrix.translateM(modelMatrix, 0, 1.1f, -1.2f, 0);
Matrix.rotateM(modelMatrix, 0, rotateAngle, 1f, 0f, 0f);
Matrix.translateM(modelMatrix, 0, -1.1f, 1.2f, 0);
這樣就使得一個物體圍繞着(1.1f, -1.2f, 0)這個點,在x=1.1f這個X軸上旋轉。
(3)接着來講說縮放,縮放是相對於虛擬空間的原點的。
Matrix.scaleM(modelMatrix, 0, 30f, 30f, 1);
上面的代碼讓物體沿着X軸和Y軸放大了30倍,可是並非沿着物體本身的中心點縮放的。
(3.1)讓物體以一個指定的點做爲縮放的中心點。這個其實也是矩陣的複合操做,步驟跟旋轉的複合操做比較相似,能夠參考上面的講解。
視圖矩陣:將虛擬空間中的全部的物體都作縮放,旋轉,移動的操做。視圖矩陣和model矩陣的不一樣點在於model矩陣做用於一個物體上,視圖矩陣做用於空間中全部的物體上。
private float[] viewMatrix = new float[16];
Matrix.setLookAtM(viewMatrix, 0,
0f, 0f, 1f, //眼睛的位置
0f, 0f, -1f, //眼睛看的方向
0f, 1f, 0f //視線的法線
); //得到一個視圖矩陣
Matrix.translateM(viewMatrix, 0, 0, 0, -2); //將空間中全部的物體向Z軸方向平移-2個單位。
最後,我來說講透視矩陣。在2D的屏幕上面顯示3D的圖形效果,靠的就是這麼個矩陣。使用了投影矩陣之後會產生一個視錐體,通俗點說就是遠處的東西看到的更多一些,可是比較小;近處的東西看到的少一些,可是比較大。透視投影的一個最重要的任務就是計算出W的值,用這個值爲後一步的透視除法作準備。
float fov = 120;// 基於Y軸的視野
float aspect = ((float) width / (float) height);//屏幕的寬高比
float near = 0.1f; //近平面
float far = 200f; //遠平面
Matrix.perspectiveM(projectionMatrix, 0, fov, aspect, near, far);//產生透視投影矩陣
在透視投影以後,頂點如何變化,我會在下一篇文章中作講解。