Mobile 3D Graphics API 保留模式答应操作 3D 世界的场景图表示。本文是此系列两部分中的第 2 部分,讨论保留模式这种轻松地治理 3D 对象的方式。
在这个系列的第 1 部分中,解释了如何使用 Mobile 3D Graphics API(M3G,在 JSR 184 中定义)的快速模式 创建 3D 场景,这种模式答应将 3D 对象快速地渲染到屏幕上。可以把快速模式看成对 3D 功能的低级访问。
对于更复杂的任务,在内存中建立 3D 世界的表示是有帮助的,这样就可以以结构化的方式治理数据。对于 M3G,这种方式称为保留模式。在保留模式中,要定义和显示整个 3D 对象世界,包括关于对象外观的信息。可以把保留模式看成一种更抽象但是更舒适的显示 3D 对象的方式。
假如在建模工具中创建 3D 场景并将数据导入应用程序,那么保留模式尤其方便。在本文中,将解释具体做法。
快速模式与保留模式
为了展示快速模式和保留模式之间的差异,我将 本系列的第 1 部分 中的一个快速模式示例转换为保留模式。还记得第 1 部分中的 白色立方体 吗?在一个继续自 Canvas 的类中,我创建了一个立方体,它有 8 个顶点,其中心在坐标系的原点上。还定义了一个三角形带,让 M3G 知道如何连接顶点来建立立方体的几何结构。一个采用透视投影的摄像机获取了立方体的快照,这个快照最后在 paint() 中进行渲染。在这个方法中,调用了 Graphics3D.render() 并以顶点数据和三角形带作为参数。
针对保留模式的修改出现在 init() 和 paint() 中。清单 1 显示了这些方法的实现。
清单 1. 保留模式中的简单立方体
/**
* Initializes the sample.
*/
protected void init()
{
// Get the singleton for 3D rendering and create a World.
_graphics3d = Graphics3D.getInstance();
_world = new World();
// Create vertex data.
VertexBuffer cubeVertexData = new VertexBuffer();
VertexArray verteXPositions =
new VertexArray(VERTEX_POSITIONS.length/3, 3, 1);
vertexPositions.set(0, VERTEX_POSITIONS.length/3, VERTEX_POSITIONS);
cubeVertexData.setPositions(vertexPositions, 1.0f, null);
// Create the triangles that define the cube; the indices point to
// vertices in VERTEX_POSITIONS.
TriangleStripArray cubeTriangles = new TriangleStripArray(
TRIANGLE_INDICES, new int[] {TRIANGLE_INDICES.length});
// Create a Mesh that represents the cube.
Mesh cubeMesh = new Mesh(cubeVertexData, cubeTriangles, new Appearance());
_world.addChild(cubeMesh);
// Create a camera with perspective projection.
Camera camera = new Camera();
float ASPect = (float) getWidth() / (float) getHeight();
camera.setPerspective(30.0f, aspect, 1.0f, 1000.0f);
camera.setTranslation(0.0f, 0.0f, 10.0f);
_world.addChild(camera);
_world.setActiveCamera(camera);
}
/**
* Renders the sample on the screen.
*
* @param graphics the graphics object to draw on.
*/
protected void paint(Graphics graphics)
{
_graphics3d.bindTarget(graphics);
_graphics3d.render(_world);
_graphics3d.releaseTarget();
}
首先,获得 3D 图形上下文并创建一个新的 World 对象,它代表 3D 场景。VertexBuffer 和 TriangleStrip 的初始化与快速模式一样,但不是使用两个对象进行渲染,而是将它们赋给一个 Mesh 实例。这个世界(World 对象)有两个孩子:刚创建的网格和一个用透视投影进行初始化的摄像机。_world.setActiveCamera() 让 M3G 使用刚添加的摄像机进行渲染。paint() 方法变得非常简单,它只是将世界渲染到图形上下文上。完整的类清单在 VerticesRetainedSample.Java 中。