前几课我们绘制的是平面的图形,下面我们要绘制一个立体的图形——六棱柱,这里我们使用了顶点索引,这是一个新的概念,它是一个指明了顶点绘制顺序的ByteBuffer,还有就是这里我们使用的是二维的顶点数组,其中第二维中所有的顶点是同一个平面上的点,所以我们是一个面一个面的绘制,Polygon 类改动的代码较多,其他类基本不变,下面一一描述:
public class Polygon {
// 保存每一个平面的顶点索引的ByteBuffer数组
private ByteBuffer[] indexBuffer;
// 保存每一个平面的顶点坐标的FloatBuffer数组
private FloatBuffer[] faceVertexBuffer;
// 保存每一个平面的顶点坐标的二维数组
private float[][] faceVertices = { new float[] { -0.5f, -0.816f, 1.0f,// bottom
// left
// 0
0.5f, -0.816f, 1.0f,// bottom right 1
-1.0f, 0.0f, 1.0f,// middle left 2
1.0f, 0.0f, 1.0f,// middle right 3
-0.5f, 0.816f, 1.0f, // top left 4
0.5f, 0.816f, 1.0f // top right 5
},// front face
new float[] { -0.5f, -0.816f, -1.0f,// bottom left 6
0.5f, -0.816f, -1.0f,// bottom right 7
-1.0f, 0.0f, -1.0f,// middle left 8
1.0f, 0.0f, -1.0f,// middle right 9
-0.5f, 0.816f, -1.0f, // top left 10
0.5f, 0.816f, -1.0f // top right 11
},// back face
new float[] { -0.5f, -0.816f, -1.0f,// bottom left 6
0.5f, -0.816f, -1.0f,// bottom right 7
-0.5f, -0.816f, 1.0f,// bottom left 0
0.5f, -0.816f, 1.0f // bottom right 1
},// bottom face
new float[] { -1.0f, 0.0f, -1.0f,// middle left 8
-0.5f, -0.816f, -1.0f,// bottom left 6
-1.0f, 0.0f, 1.0f,// middle left 2
-0.5f, -0.816f, 1.0f // bottom left 0
},// bottom left face
new float[] { 0.5f, -0.816f, -1.0f,// bottom right 7
1.0f, 0.0f, -1.0f,// middle right 9
0.5f, -0.816f, 1.0f,// bottom right 1
1.0f, 0.0f, 1.0f // middle right 3
},// bottom right face
new float[] { 0.5f, 0.816f, -1.0f, // top right 11
1.0f, 0.0f, -1.0f,// middle right 9
0.5f, 0.816f, 1.0f,// top right 5
1.0f, 0.0f, 1.0f // middle right 3
},// top right face
new float[] { -0.5f, 0.816f, -1.0f, // top left 10
0.5f, 0.816f, -1.0f, // top right 11
-0.5f, 0.816f, 1.0f,// top left 4
0.5f, 0.816f, 1.0f // top right 5
},// top face
new float[] { -0.5f, 0.816f, -1.0f, // top left 10
-1.0f, 0.0f, -1.0f,// middle left 8
-0.5f, 0.816f, 1.0f, // top left 4
-1.0f, 0.0f, 1.0f // middle left 2
} // top left face
};
// 定义每一个平面颜色的数组
private float[] colors = { 1.0f, 0.0f, 0.0f, 1.0f, // 0
0.0f, 1.0f, 0.0f, 1.0f,// 1
0.0f, 0.0f, 1.0f, 1.0f, // 2
1.0f, 1.0f, 1.0f, 1.0f, // 3
1.0f, 1.0f, 0.0f, 1.0f,// 4
1.0f, 0.0f, 1.0f, 1.0f,// 5
0.0f, 1.0f, 1.0f, 1.0f,// 6
0.5f, 0.5f, 0.5f, 1.0f, // 7
};
// 保存每一个平面的顶点索引的二维数组
private byte[][] indies = {
new byte[] { 0, 1, 2, 1, 3, 2, 2, 3, 4, 3, 5, 4 },// front face
new byte[] { 0, 1, 2, 1, 3, 2, 2, 3, 4, 3, 5, 4 },// back face
new byte[] { 0, 1, 2, 1, 3, 2 },// bottom face
new byte[] { 0, 1, 2, 1, 3, 2 },// bottom left face
new byte[] { 0, 1, 2, 1, 3, 2 },// bottom right face
new byte[] { 0, 1, 2, 1, 3, 2 },// top right face
new byte[] { 0, 1, 2, 1, 3, 2 },// top face
new byte[] { 0, 1, 2, 1, 3, 2 } // top left face
};
public Polygon() {
// 利用循环初始化顶点坐标faceVertexBuffer数组和顶点索引indexBuffer数组
ByteBuffer bb;
faceVertexBuffer = new FloatBuffer[8];
for (int i = 0; i < faceVertices.length; i++) {
bb = ByteBuffer.allocateDirect(faceVertices[i].length * 4);
bb.order(ByteOrder.nativeOrder());
faceVertexBuffer[i] = bb.asFloatBuffer();
faceVertexBuffer[i].put(faceVertices[i]);
faceVertexBuffer[i].position(0);
}
indexBuffer = new ByteBuffer[8];
for (int i = 0; i < indies.length; i++) {
indexBuffer[i] = ByteBuffer.allocateDirect(indies[i].length);
indexBuffer[i].put(indies[i]);
indexBuffer[i].position(0);
}
}
public void draw(GL10 gl) {
// 利用循环绘制六棱柱的每一个面,并给不同的面设置不同的颜色
gl.glFrontFace(GL10.GL_CW);
for (int i = 0; i < 8; i++) {
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, faceVertexBuffer[i]);
gl.glColor4f(colors[4 * i + 0], colors[4 * i + 1],
colors[4 * i + 2], colors[4 * i + 3]);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDrawElements(GL10.GL_TRIANGLES, indies[i].length,
GL10.GL_UNSIGNED_BYTE, indexBuffer[i]);// 另一种绘制的方法glDrawElements
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
}
}