import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.game.GameCanvas;
import javax.microedition.m3g.Appearance;
import javax.microedition.m3g.Camera;
import javax.microedition.m3g.Graphics3D;
import javax.microedition.m3g.Transform;
import javax.microedition.m3g.TriangleStripArray;
import javax.microedition.m3g.VertexArray;
import javax.microedition.m3g.VertexBuffer;
/**
*
* @author Himi
*
*/
public class My3DWorld extends GameCanvas implements Runnable {
private Thread th;
/**
* @author Himi
*
* @VERTEX_POSITIONS 以三角形带形式定义一个装入了立方体所有的顶点数组
*
* @VERTEX_COLORS 以三角形带形式定义了颜色数组
*
* @TRIANGLE_INDICES 以三角形带形式装入了立方体的所有面
*
* @VertexArray 此类作用: 虽然VERTEX_POSITIONS 定义了顶点数组但是不是空间的点,
* 所以此类将顶点数组保存成空间顶点坐标信息、保存法线信息、
* 保存帖图信息、保存 颜色信息等
*
* @VertexBuffer 此类对象通过保存设置空间顶点位置、发现、帖图信息,来建立图形
* (这个类才是保存多边形的框架信息的类) 设定顶点属性
* ,包括的位置,法线,色彩,纹理坐标
*
* @Transform 对立方体进行一系列操作,例如反转 、平移、缩放
*
* @Camera 3d空间中的摄像机 设置投影、观察视角等
*
* @TriangleStripArray 此类按三角形带方式将面串成立方体
*/
private static final byte[] VERTEX_POSITIONS = { -1, -1, 1, 1, -1, 1, -1,
1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1 };
// @备注1
private static final byte[] VERTEX_COLORS = { 0, (byte) 255, 0, 0,
(byte) 255, (byte) 255, (byte) 255, 0, 0, (byte) 255, 0,
(byte) 255, (byte) 255, (byte) 255, 0, (byte) 255, (byte) 255,
(byte) 255, 0, 0, (byte) 128, 0, 0, (byte) 255, };
private static int[] TRIANGLE_INDICES = { 0, 1, 2, 3, 7, 1, 5, 4, 7, 6, 2,
4, 0, 1 };
private Graphics3D g3d;
private VertexArray va_vertex;
private VertexBuffer vb;
private VertexArray va_color;
private Transform tf;
private Camera camera;
private TriangleStripArray tsa;
public My3DWorld(boolean suppressKeyEvents) {
super(suppressKeyEvents);
th = new Thread(this);
g3d = Graphics3D.getInstance(); // 得到一个g3d实例
vb = new VertexBuffer();
camera = new Camera();
tf = new Transform();
tsa = new TriangleStripArray(TRIANGLE_INDICES,
new int[] { TRIANGLE_INDICES.length });
// 参数1 传入一个三角形形式的面数组,第二参数代表将参数一的数组复制到新的数组里
// 把三角带处理成正常的三点一面的形式
va_vertex = new VertexArray(VERTEX_POSITIONS.length / 3, 3, 1);
// 这里是定义空间顶点数组,第一个参数代表顶点的个数
// 第二个参数表示几个点成一个空间点;第三个参数表示每个顶点占得字节数
va_vertex.set(0, VERTEX_POSITIONS.length / 3, VERTEX_POSITIONS);
// 此方法是将一开始定义的顶点数组VERTEX_POSITIONS 设置成空间顶点(与顶点数组一一对应)
// 第一参数可以理解成从第一个顶点数组下标为0开始,
//第二参数封装的空间顶点数个数有POINTS.length/3个,
// 第三 参数传入需要转换成空间顶点的数组
va_color = new VertexArray(VERTEX_COLORS.length / 3, 3, 1);
// 这里是定义空间颜色顶点数组,第一个参数代表颜色顶点的个数(与顶点数组一一对应)
// 第二个参数表示几个点成一个空间点;第三个参数表示每个顶点占得字节数
va_color.set(0, VERTEX_COLORS.length / 3, VERTEX_COLORS);
// 此方法是将一开始定义的顶点数组VERTEX_COLORS 设置成空间顶点颜色数组
// 第一参数可以理解成从第一个顶点数组下标为0开始,
//第二参数封装的空间顶点颜色数个数有POINTS.length/3个,
// 第三 参数传入需要转换成空间顶点颜色的数组
float pc[] = { 0, 0, 1 };
vb.setPositions(va_vertex, 1.0f, pc);// @备注2
// 设定顶点位置 第一个参数 传入顶点空间数组
// 第二个参数标识对缩放大小1.0不缩放
// 第三个参数标识偏差 ,详细看下文解释的@备注2
vb.setColors(va_color);
// 设定空间颜色数组
camera.setPerspective(30, (float) this.getWidth()
/ (float) this.getHeight(), 1, 1000); // @备注3
// 设定透视投影
// 详细解释看@备注3
Transform transform = new Transform(); // @备注4
// 详细解释看@备注4
transform.postTranslate(0, 0, 10);
// 这里是设置摄像机投影位置
g3d.setCamera(camera, transform);
// 用3d画笔设定3d空间摄像机
th.start();// 启动线程
}
public void draw(Graphics g) {
try {
g3d.bindTarget(g);// @备注5
// 将画笔绑定在3d空间画笔
g3d.clear(null);
// 清屏 参数null 标识默认刷屏方式
g3d.render(vb, tsa, new Appearance(), tf);// @备注6
// 渲染 第一个参数传入一个建立图形所需要的信息,包括法线、顶点信息,颜色等
// 第二个参数标识 立体图形所需的三角形带面信息
// 第三个信息标识外观的设定这里默认,后续文章会有学习
} catch (Exception e) {
System.out.println("draw -> Error!! ");
} finally {
g3d.releaseTarget();// @备注7
}
}
public void keyPressed(int key) {
if (key == -1 || key == -3)
tf.postRotate(10, 1, 0, 0);// @备注8
else if (key == -2 || key == -4)
tf.postRotate(10, 0, 1, 0);// @备注8
}
protected void keyRepeated(int key) {
keyPressed(key);
}
public void run() {
while (true) {
try {
draw(this.getGraphics());
flushGraphics();// midp2.0 刷新画笔
Thread.sleep(100); // 休眠线程
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}