opengl的MVP矩陣變換

假若有一個三角形,它的三個頂點是在虛擬空間中的,若是須要對這個三角形進行旋轉,縮放,平移的操做,須要用到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);//產生透視投影矩陣

 

在透視投影以後,頂點如何變化,我會在下一篇文章中作講解。

相關文章
相關標籤/搜索