OpenGL ES之GLSurfaceView学习四:Android Demo里的Cube分析

关于android中Cube的绘制,可以看出一个3D图像的绘制机制。本文分析了Cube对象。

需要用到两张图片:第一张是立方体顶点顺序和位置图,第二张是三角面示例图。

立方体顶点图

三角面示例图

package com.example.android.apis.graphics; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.IntBuffer; import javax.microedition.khronos.opengles.GL10; /** * A vertex shaded cube. */ class Cube { public Cube() { int one = 0x10000; //每一个顶点都是由x/y/z三个坐标表示的。对于一个立方体,有八个顶点。 //每个顶点的位置是先下到上,在每一层是由里到外逆时针方向标识 int vertices[] = { -one, -one, -one, one, -one, -one, one, one, -one, -one, one, -one, -one, -one, one, one, -one, one, one, one, one, -one, one, one, }; //每个顶点的颜色由四个数字表示:RED/GREEN/BLUE/ALPHA,最后一个透明度是可选的 int colors[] = { 0, 0, 0, one, one, 0, 0, one, one, one, 0, one, 0, one, 0, one, 0, 0, one, one, one, 0, one, one, one, one, one, one, 0, one, one, one, }; //这里有点复杂,每个数字对应于正方体中的每个特定的点。比如0代表立方体原点,就是立方体下面一层中最后面的那个点。 //那么0,4,5对应的就是立方体侧面上的一个三角,每个面都有两个三角组成。 //这样,整个立方体有六个面,就有12个三角面了。 //注意:点的排列顺序对于显示效果有很大的影响。比如:0,4,5和0,5,4就不一样。 //之所以会这样的原因是因为,调用了gl.glFrontFace(gl.GL_CW). //这样我们需要以顺时针的顺序来指定可视的三角面。 byte indices[] = { 0, 4, 5, 0, 5, 1, 1, 5, 6, 1, 6, 2, 2, 6, 7, 2, 7, 3, 3, 7, 4, 3, 4, 0, 4, 7, 6, 4, 6, 5, 3, 0, 1, 3, 1, 2 }; //这里使用ByteBuffer来做缓冲处理。必须通过ByteBuffer.allocateDirect()方法来实例化ByteBuffer对象 //这些buffer必须放到本地堆栈中,以使垃圾回收器不能移除它们 //这些缓冲将作为参数传入到gl*Pointer()方法中 //对于不同原数据类型的Buffers需要将byte设置成对应的顺序 //int类型的是每个点式四个字节。 ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4); vbb.order(ByteOrder.nativeOrder()); mVertexBuffer = vbb.asIntBuffer(); mVertexBuffer.put(vertices); mVertexBuffer.position(0); ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length*4); cbb.order(ByteOrder.nativeOrder()); mColorBuffer = cbb.asIntBuffer(); mColorBuffer.put(colors); mColorBuffer.position(0); mIndexBuffer = ByteBuffer.allocateDirect(indices.length); mIndexBuffer.put(indices); mIndexBuffer.position(0); } //让Cube来绘制自己,传入GL10g //GL10里包含很多绘制3D图刑的接口 public void draw(GL10 gl) { gl.glFrontFace(gl.GL_CW); gl.glVertexPointer(3, gl.GL_FIXED, 0, mVertexBuffer); gl.glColorPointer(4, gl.GL_FIXED, 0, mColorBuffer); gl.glDrawElements(gl.GL_TRIANGLES, 36, gl.GL_UNSIGNED_BYTE, mIndexBuffer); } private IntBuffer mVertexBuffer; private IntBuffer mColorBuffer; private ByteBuffer mIndexBuffer; }