Android OpenGL ES學習筆記之繪製一個立方體

前言

前面已經講了如何繪製點、線、面,現在就來繪製一個立方體,OpenGL ES中任何一個立體圖形都是由很多面組成的,這個面指的就是三角形,所以繪製立方體就是繪製多個三角形而組合起來。

繪製

立方體有6個面,左、右、前、後、上、下。共有8個頂點,每個面有4個頂點,代碼如下
PS:一定要注意頂點的順序,不能隨意選擇

        // 定義立方體的8個頂點  
        float[] cubeVertices = {               
                //左面 
                  -0.5f,0.5f,0.5f,
                  -0.5f,-0.5f,0.5f,
                  -0.5f,0.5f,-0.5f,
                  -0.5f,-0.5f,-0.5f,

                //右面
                  0.5f, 0.5f,0.5f,                
                  0.5f,-0.5f,0.5f,
                  0.5f,-0.5f,-0.5f,
                  0.5f,0.5f,-0.5f ,

                //前面
                 -0.5f,0.5f,0.5f,
                 -0.5f,-0.5f,0.5f,
                  0.5f,-0.5f,0.5f,
                  0.5f, 0.5f,0.5f,

                //後面 
                  0.5f,-0.5f,-0.5f,
                  0.5f,0.5f,-0.5f, 
                 -0.5f,0.5f,-0.5f,
                 -0.5f,-0.5f,-0.5f,

                //上面
                 -0.5f,0.5f,0.5f,
                  0.5f, 0.5f,0.5f,
                  0.5f,0.5f,-0.5f,
                  -0.5f,0.5f,-0.5f,

                //下面
                  -0.5f,-0.5f,0.5f,
                  0.5f,-0.5f,0.5f,
                  0.5f,-0.5f,-0.5f,
                  -0.5f,-0.5f,-0.5f
         };  

然後定義一個顏色數組

       //  顏色數組 
       float []  cubeColors = {   
                1f,0f,0f,1f ,  
                0f,1f,0f,1f,  
                0f,0f,1f,1f,  
                1f,0f,0f,1f,  

                1f,0f,0f,1f ,  
                0f,1f,0f,1f,  
                0f,0f,1f,1f,  
                1f,0f,0f,1f, 

                1f,0f,0f,1f ,  
                0f,1f,0f,1f,  
                0f,0f,1f,1f,  
                1f,0f,0f,1f, 

                1f,0f,0f,1f ,  
                0f,1f,0f,1f,  
                0f,0f,1f,1f,  
                1f,0f,0f,1f, 


                1f,0f,0f,1f ,  
                0f,1f,0f,1f,  
                0f,0f,1f,1f,  
                1f,0f,0f,1f, 

                1f,0f,0f,1f ,  
                0f,1f,0f,1f,  
                0f,0f,1f,1f,  
                1f,0f,0f,1f, 
           };    

然後是獲取浮點型緩衝數據

            //獲取浮點形緩衝數據
            VerticesBuffer = Utils.getFloatBuffer(cubeVertices);
            //獲取浮點型顏色數據
            Colorbuffer= Utils.getFloatBuffer(cubeColors);

爲了能看到立體的效果,就讓這個矩陣一直繞Y軸旋轉。因爲默認的是一直繪製的渲染模式,所以指定一個角度,每次都加1即可。另外指定繪製線的模式爲 GL_TRIANGLE_STRIP 。即相鄰三個頂點繪製一個三角形。

代碼如下


        @Override
        public void onDrawFrame(GL10 gl) { 
        // 清除屏幕緩存和深度緩存  
            gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);  
            // 啓用頂點座標數據  
            gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);  
            // 啓用頂點顏色數據  
            gl.glEnableClientState(GL10.GL_COLOR_ARRAY);  

             // 重置當前的模型視圖矩陣  
             gl.glLoadIdentity();  
             // 沿着Y軸旋轉  
             gl.glRotatef(rotate, 0f, 1f, 0f);  

             // 設置頂點的位置數據  
            gl.glVertexPointer(3, GL10.GL_FLOAT, 0, VerticesBuffer);  

            // 設置頂點的顏色數據  
            gl.glColorPointer(4, GL10.GL_FLOAT, 0, Colorbuffer);  

            //繪製三角形  
            gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP  , 0, 24); 

            gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);  
            gl.glDisableClientState(GL10.GL_COLOR_ARRAY);  

            // 旋轉角度增加1  
            rotate-=1;  
           }

效果如下:

這裏寫圖片描述

可以看到有很多三角形,那麼這並不是我們想要的效果,這時候要用到索引了。


索引繪製

索引就是讓不同的頂點按照規定的順序來繪製,這樣就不會導致各種三角形的錯亂。

首先定義一個索引數組,這裏的0,1,2等指的是頂點順序,比如0,1,2就是按照0,1,2的順序繪製三角形,0,2,3就是按照02,3的順序繪製三角形,就不會出現0,1,2 和1,2,3 以及 023都繪製的情況。

       //索引數組
       private short[] indices={  
                0,1,2,  
                0,2,3,  

                4,5,6,  
                4,6,7,  

                8,9,10,  
                8,10,11,  

                12,13,14,  
                12,14,15,  

                16,17,18,  
                16,18,19,  

                20,21,22,  
                20,22,23,  
        };  

獲取浮點型索引數據

//獲取浮點型索引數據
indexbuffer= Utils.getShortBuffer(indices);

最後在onDrawFrame方法裏,把以下去掉

     //繪製三角形  
     //gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP  , 0, 24); 

換成

gl.glDrawElements(GL10.GL_TRIANGLES, indices.length, GL10.GL_UNSIGNED_SHORT, indexbuffer);  

這裏講一下glDrawElements方法,Android OpenGL ES學習筆記之繪製點
裏講了
OpenGL ES提供了兩類方法來繪製一個空間幾何圖形:

 -public abstract void glDrawArrays(int mode, int first, int count) 使用VetexBuffer 來繪製,頂點的順序由vertexBuffer中的順序指定。


 - public abstract void glDrawElements(int mode, int count, int type, Buffer indices) ,可以重新定義頂點的順序,頂點的順序由indices Buffer 指定。

glDrawElements各個參數如下:

 - mode——指明被渲染的是哪種圖元,被允許的符號常量有GL_POINTS,GL_LINE_STRIP,GL_LINE_LOOP,GL_LINES,GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN 和GL_TRIANGLES

 - count——指明被渲染的元素個數。

 - type——指明索引指的類型,不是GL_UNSIGNED_BYTE 就是GL_UNSIGNED_SHORT。

 - indices——指明存儲索引的位置指針。

現在看下效果

這裏寫圖片描述

總結

繪製正方體就這樣完成了。
Demo地址:點擊打開
密碼:arxc

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章