JSR 184 (Mobile 3D Graphics API, M3G) 為 Java ME 引入輕量級 3D 能力,基於 OpenGL ES 子集,運行於 CLDC 1.1+/MIDP 1.0+,完整實現 < 150KB。本文系統介紹 M3G 架構、兩種渲染模式、資源載入、核心類別,並附帶可在 WTK 2.2 模擬器運行的旋轉金字塔完整代碼。
| 類別/介面 | 角色 | 說明 |
|---|---|---|
Graphics3D | 渲染入口 | Singleton,綁定 Graphics 目標,執行 render() |
World | 場景根節點 | 包含 Camera、Lights、Background、子節點樹 |
Camera | 觀察者 | 投影矩陣、視口、視錐體 |
Mesh | 幾何體 | 頂點、法線、紋理座標、三角形索引 |
Appearance | 材質外觀 | 材質、紋理、混合模式、多通道 |
Loader | 資源載入器 | 從 .m3g 檔一次性讀入整個場景圖 |
Graphics3D.render(mesh...),控制精細、效能高、代碼繁瑣。World 場景圖,調用 g3d.render(world) 自動遍歷繪製,適合複雜場景、動畫插值。/res/ 目錄,Loader.load("/res/scene.m3g") 載入。import javax.microedition.m3g.*;
import javax.microedition.lcdui.*;
public class PyramidMIDlet extends MIDlet implements Runnable {
private Graphics3D g3d;
private World world;
private Mesh pyramid;
private Display display;
public void startApp() {
display = Display.getDisplay(this);
Canvas3D canvas = new Canvas3D();
display.setCurrent(canvas);
new Thread(this).start();
}
class Canvas3D extends Canvas {
public void paint(Graphics g) {
try {
g3d.bindTarget(g);
g3d.render(world);
} finally {
g3d.releaseTarget();
}
}
}
public void run() {
// 1. 取得 Graphics3D 實例
g3d = Graphics3D.getInstance();
// 2. 建立 World 與 Camera
world = new World();
Camera cam = new Camera();
world.addChild(cam);
float w = getWidth(), h = getHeight();
cam.setPerspective(60f, w/h, 0.1f, 50f);
world.setActiveCamera(cam);
// 3. 程序化建立金字塔 Mesh
pyramid = createPyramid();
pyramid.translate(0, 0, -3f); // 移入視野
world.addChild(pyramid);
// 4. 幀循環
Graphics g = getGraphics();
while (true) {
pyramid.postRotate(3f, 0f, 1f, 0f); // 繞 Y 軸旋轉 3°
g3d.bindTarget(g);
g3d.render(world);
g3d.releaseTarget();
flushGraphics();
try { Thread.sleep(16); } catch (Exception ignore) {}
}
}
private Mesh createPyramid() {
// 頂點:底面 4 點 + 頂點
short[] verts = { -1,-1,-1, 1,-1,-1, 1,1,-1, -1,1,-1, 0,0,1 };
byte[] indices = { 0,1,2, 0,2,3, 0,4,1, 1,4,2, 2,4,3, 3,4,0 };
VertexArray va = new VertexArray(5, 3, 2); // 5 頂點, 3 分量, 2 bytes
va.set(0, 5, verts);
TriangleStripArray tsa = new TriangleStripArray(4, indices); // 4 條帶
return new Mesh(va, tsa, new Appearance());
}
// 其他生命週期方法省略
}