13,097
社区成员
发帖
与我相关
我的任务
分享import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Display;
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.IndexBuffer;
import javax.microedition.m3g.Light;
import javax.microedition.m3g.Mesh;
import javax.microedition.m3g.PolygonMode;
import javax.microedition.m3g.Transform;
import javax.microedition.m3g.TriangleStripArray;
import javax.microedition.m3g.VertexArray;
import javax.microedition.m3g.VertexBuffer;
import javax.microedition.m3g.World;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
class CubesCanvas extends GameCanvas implements Runnable {
//场景是把9个一样尺寸的立方体排成一个3*3的方阵,以下常数是具体的尺寸参数:
static final short CUBE_SIZE = 50; //:立方体的边长
static final short PANEL_PADDING = 10; //:相邻立方体的间距
static final short PANEL_SIZE = 4*PANEL_PADDING + 3*CUBE_SIZE; //:整个方阵的边长
Graphics3D g3d = null;
Camera camera = new Camera();
Transform camTrans = new Transform();//:摄影机的变换矩阵
Light light = new Light();//:灯光
World world = new World();
public void run() {
while(true) {
try {
input(); //:处理按键
repaint();
try{ Thread.sleep(30); } catch(Exception e) {}
}
catch(Exception e) {
System.out.println(e.getMessage());
System.out.println(e);
e.printStackTrace();
}
}
}
public void paint(Graphics g)
{
try
{
g3d = Graphics3D.getInstance();
g3d.bindTarget(g, true, Graphics3D.TRUE_COLOR | Graphics3D.DITHER);
g3d.render(world);
}
catch(Exception e)
{
System.out.println(e.getMessage());
System.out.println(e);
e.printStackTrace();
g3d.releaseTarget();
}
finally
{
g3d.releaseTarget();
}
}
/**
* 处理按键输入:左/右/上/下是调整摄影机朝向,开火键向前推,GAME_A(模拟器上是1)向后拉:
*/
protected void input()
{
int keys = getKeyStates();
if ((keys & GameCanvas.FIRE_PRESSED) != 0)
camTrans.postTranslate(0.0f, 0.0f, -20.0f);
if ((keys & GameCanvas.GAME_A_PRESSED) != 0)
camTrans.postTranslate(0.0f, 0.0f, 20.0f);
if ((keys & GameCanvas.UP_PRESSED) != 0)
camTrans.postRotate(5, 1.0f, 0.0f, 0.0f);
if ((keys & GameCanvas.DOWN_PRESSED) != 0)
camTrans.postRotate(-5, 1.0f, 0.0f, 0.0f);
if ((keys & GameCanvas.LEFT_PRESSED) != 0)
camTrans.postRotate(5, 0.0f, 1.0f, 0.0f);
if ((keys & GameCanvas.RIGHT_PRESSED) != 0)
camTrans.postRotate(-5, 0.0f, 1.0f, 0.0f);
camera.setTransform(camTrans) ;
/*
float[] matrix = new float[16];
camTrans.get(matrix);
System.out.println("-------");
for (int i=0; i<matrix.length; i++) System.out.println(matrix[i]);
System.out.println("-------");
//*/
}
/*此变换矩阵代表着经实测得知可以暴露问题的一个摄像机角度。前后推拉可以看出问题*/
static float[] matrix = {
-0.6884168f,
0.414644f,
-0.5951051f,
-140.52567f,
-0.2546693f,
-0.90642345f,
-0.3369556f,
-64.57297f,
-0.67913395f,
-0.08041051f,
0.7295947f,
190.07216f,
0.0f,
0.0f,
0.0f,
1.0f,
};
//*/
// 创建整个场景:
public CubesCanvas() {
super(true);
setFullScreenMode(true);
g3d = Graphics3D.getInstance();
Mesh[][] cubes = new Mesh[3][3];
float x0 = PANEL_PADDING - (PANEL_SIZE - CUBE_SIZE) / 2;
float z0 = PANEL_PADDING - (PANEL_SIZE - CUBE_SIZE) / 2;
for (int x=0; x<3; x++)
for (int z=0; z<3; z++) {
//创建立方体:
cubes[x][z] = createCube(CUBE_SIZE, CUBE_SIZE, CUBE_SIZE);
//摆放:
cubes[x][z].translate(x0 + x * (CUBE_SIZE + PANEL_PADDING),
CUBE_SIZE/2, z0 + z * (CUBE_SIZE + PANEL_PADDING));
//设置一个userID:
cubes[x][z].setUserID(x * 3 + z);
world.addChild(cubes[x][z]);
}
//设置灯光:
light.setMode(Light.AMBIENT);
light.setIntensity(1.0f);
light.translate(0.0f, 0.0f, -45f);
light.setOrientation(-30,1,0,0);
light.setColor(0xFFFFFF);
g3d.resetLights();
g3d.addLight(light, null);
world.addChild(light);
//创建并设置摄影机:
camera = new Camera();
float aspect = (float) getWidth() / (float) getHeight();
camera.setPerspective(60.0f, aspect, 0.001f, 100000.0f);
camTrans.set(matrix);
camera.setTransform(camTrans);
world.addChild(camera);
world.setActiveCamera(camera);
Thread t = new Thread(this);
t.start();
}
static IndexBuffer indexBuffer;
static VertexBuffer vertexBuffer;
static PolygonMode polygonMode;
/** 立方体的坐标 */
static byte []POINTS = new byte[] {
-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, -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, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, // 顶
-1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1 // 底
};
/** 法线向量 */
static byte[] NORMALS = {
0, 0, 127, 0, 0, 127, 0, 0, 127, 0, 0, 127, // front
0, 0, -128, 0, 0, -128, 0, 0, -128, 0, 0, -128, // back
127, 0, 0, 127, 0, 0, 127, 0, 0, 127, 0, 0, // right
-128, 0, 0, -128, 0, 0, -128, 0, 0, -128, 0, 0, // left
0, 127, 0, 0, 127, 0, 0, 127, 0, 0, 127, 0, // top
0, -128, 0, 0, -128, 0, 0, -128, 0, 0, -128, 0, // bottom
};
/** 顶点颜色 */
static byte[] COLORS = new byte[] {
0, 0, (byte) 128, 0, 0, (byte) 255, 0, (byte) 255, 0, 0, (byte) 255, (byte) 255,
(byte) 255, 0, (byte)255, ( byte) 255,0, 0, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, 0,
0, 0, (byte) 255, (byte) 255, 0, 0, 0, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255,
(byte) 255, 0, 0,0, 0, (byte) 128,(byte) 255, (byte) 255, 0, 0, (byte) 255, 0,
0, (byte) 255, 0, 0, 0, (byte) 128, (byte) 255, (byte) 255, 0, 0, (byte) 255, 0,
(byte) 255, 0, 0, (byte) 255, 0, (byte) 255, 0, 0, (byte) 128, 0, 0, (byte) 255
};
/** 顶点索引 */
static int []INDICES = new int[]{
0, 1,2, 3, // 前
4, 5, 6, 7, // 后
8, 9, 10, 11, // 右
12, 13, 14, 15, // 左
16, 17, 18, 19, // 顶
20, 21, 22, 23, // 底
};
// 三角带长度数组
static int[] LENGTH = new int[] {4, 4, 4, 4, 4, 4};
public static Mesh createCube(short width, short height, short depth) {
/**
* 原代码中为节省存储空间,当indexBuffer==null时才重新创建,
* 否则直接用之前创建好的indexBuffer和vertexBuffer来创建立方体。
* 这里为了保险起见,每次都全部重新创建
*/
///if (indexBuffer == null) {
// 设置顶点缓冲:
VertexArray POSITION_ARRAY, COLOR_ARRAY;
POSITION_ARRAY = new VertexArray(POINTS.length / 3, 3, 1);
POSITION_ARRAY.set(0, POINTS.length / 3, POINTS);
COLOR_ARRAY = new VertexArray(COLORS.length / 3, 3, 1);
COLOR_ARRAY.set(0, COLORS.length / 3, COLORS);
VertexArray NORMAL_ARRAY = new VertexArray(NORMALS.length/3, 3, 1);
NORMAL_ARRAY.set(0, NORMALS.length / 3, NORMALS);
vertexBuffer = new VertexBuffer();
vertexBuffer.setPositions(POSITION_ARRAY, 1.0f, null);
vertexBuffer.setColors(COLOR_ARRAY);
vertexBuffer.setNormals(NORMAL_ARRAY);
// 索引缓冲:
indexBuffer = new TriangleStripArray(INDICES, LENGTH);
polygonMode = new PolygonMode();
polygonMode.setPerspectiveCorrectionEnable(true);
polygonMode.setWinding(PolygonMode.WINDING_CCW);
polygonMode.setCulling(PolygonMode.CULL_BACK);
polygonMode.setShading(PolygonMode.SHADE_SMOOTH);
///}
Appearance appearance = new Appearance();
appearance.setPolygonMode(polygonMode);
Mesh cubeMesh = new Mesh(vertexBuffer, indexBuffer, appearance);
cubeMesh.scale((float)width/2.0f, (float)height/2.0f, (float)depth/2.0f);
return cubeMesh;
}
}
public class TestM3G extends MIDlet {
Canvas canvas;
protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
}
protected void pauseApp() {
}
protected void startApp() throws MIDletStateChangeException {
//canvas = new MainCanvas();
canvas = new CubesCanvas();
//canvas = new M3GCanvas();
Display.getDisplay(this).setCurrent(canvas);
}
}