关于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;
}