前言
前面已經講了如何繪製點、線、面,現在就來繪製一個立方體,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