鍍金池/ 教程/ Android/ 繪制一個 20 面體
繪制線段 Line Segment
投影變換 Projection
繪制迷你太陽系
繪制一個球體
繪制三角形 Triangle
OpenGL 光照模型
三維坐標系及坐標變換初步
定義 3D 模型的前面和后面
繪制一個 20 面體
顏色 Color
Depth Buffer
材質(zhì)及光照示例
基本幾何圖形定義
關(guān)于EGL
導(dǎo)言
Viewing 和 Modeling(MODELVIEW) 變換
FrameBuffer
設(shè)置光照效果 Set Lighting
Viewport 變換
階段小結(jié)
繪制點 Point
OpenGL ES API 命名習(xí)慣
通用的矩陣變換指令
關(guān)于 OpenGL ES
創(chuàng)建實例應(yīng)用 OpenGLDemos 程序框架
OpenGL ES 管道(Pipeline)
GLSurfaceView

繪制一個 20 面體

前面介紹了 OpenGL ES 所有能夠繪制的基本圖形,點,線段和三角形。其它所有復(fù)雜的 2D 或 3D 圖形都是由這些基本圖形構(gòu)成。

本例介紹如何使用三角形構(gòu)造一個正20面體。一個正 20 面體,有 12 個頂點,20 個面,30 條邊構(gòu)成:

http://wiki.jikexueyuan.com/project/opengl-es-guide/images/60.png" alt="" />

創(chuàng)建一個 DrawIcosahedron Activity,定義 20 面體的 12 個頂點,和 20 個面如下:

static final float X=.525731112119133606f;
static final float Z=.850650808352039932f;
static float vertices[] = new float[]{
 -X, 0.0f, Z, X, 0.0f, Z, -X, 0.0f, -Z, X, 0.0f, -Z,
 0.0f, Z, X, 0.0f, Z, -X, 0.0f, -Z, X, 0.0f, -Z, -X,
 Z, X, 0.0f, -Z, X, 0.0f, Z, -X, 0.0f, -Z, -X, 0.0f
 };
static short indices[] = new short[]{
 0,4,1, 0,9,4, 9,5,4, 4,5,8, 4,8,1,
 8,10,1, 8,3,10, 5,3,8, 5,2,3, 2,7,3,
 7,10,3, 7,6,10, 7,11,6, 11,0,6, 0,1,6,
 6,1,10, 9,0,11, 9,11,2, 9,2,5, 7,2,11 };  

OpenGL ES 缺省使用同一種顏色來繪制圖形,為了能夠更好的顯示3D效果,我們?yōu)槊總€頂點隨機定義一些顏色如下:

float[] colors = {
 0f, 0f, 0f, 1f,
 0f, 0f, 1f, 1f,
 0f, 1f, 0f, 1f,
 0f, 1f, 1f, 1f,
 1f, 0f, 0f, 1f,
 1f, 0f, 1f, 1f,
 1f, 1f, 0f, 1f,
 1f, 1f, 1f, 1f,
 1f, 0f, 0f, 1f,
 0f, 1f, 0f, 1f,
 0f, 0f, 1f, 1f,
 1f, 0f, 1f, 1f
};  

添加顏色可以參見 Android OpenGL ES 簡明開發(fā)教程五:添加顏色 以后也會有詳細說明。

將頂點,面,顏色存放到 Buffer 中以提高性能:

private FloatBuffer vertexBuffer;
private FloatBuffer colorBuffer;
private ShortBuffer indexBuffer;
ByteBuffer vbb
= ByteBuffer.allocateDirect(vertices.length * 4);
vbb.order(ByteOrder.nativeOrder());
vertexBuffer = vbb.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
ByteBuffer cbb
= ByteBuffer.allocateDirect(colors.length * 4);
cbb.order(ByteOrder.nativeOrder());
colorBuffer = cbb.asFloatBuffer();
colorBuffer.put(colors);
colorBuffer.position(0);
ByteBuffer ibb
= ByteBuffer.allocateDirect(indices.length * 2);
ibb.order(ByteOrder.nativeOrder());
indexBuffer = ibb.asShortBuffer();
indexBuffer.put(indices);
indexBuffer.position(0);  

看一看 DrawScene 代碼:

public void DrawScene(GL10 gl) {
 super.DrawScene(gl);
 gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
 gl.glLoadIdentity();
 gl.glTranslatef(0, 0, -4);
 gl.glRotatef(angle, 0, 1, 0);
 gl.glFrontFace(GL10.GL_CCW);
 gl.glEnable(GL10.GL_CULL_FACE);
 gl.glCullFace(GL10.GL_BACK);
 gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
 gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
 gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
 gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorBuffer);
 gl.glDrawElements(GL10.GL_TRIANGLES, indices.length,
 GL10.GL_UNSIGNED_SHORT, indexBuffer);
 gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
 gl.glDisable(GL10.GL_CULL_FACE);
 angle++;
}  

用來繪制 20 面體使用了 gl.glDrawElements:

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

本例會顯示一個繞 Y 軸不斷旋轉(zhuǎn)的 20 面體,如何旋轉(zhuǎn)模型將在后面的坐標系統(tǒng)和坐標變換中介紹。

http://wiki.jikexueyuan.com/project/opengl-es-guide/images/59.png" alt="" />

DrawLine,DrawTriangle,及本例下載