本文是此系列两部分中的第 1 部分,介绍了 Mobile 3D Graphics API (JSR 184) 的有关内容。作者将带领您进入 Java 移动设备的 3D 编程世界,并展示了处理光线、摄像机和材质的方法。
您可以更改两个属性:深度缓冲与投影,如清单 7 所示:
清单 7. 深度缓冲与投影
/**
* Initializes the sample.
*/
protected void init()
{
// Get the singleton for 3D rendering.
_graphics3d = Graphics3D.getInstance();
// Create vertex data.
_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.
_cubeTriangles = new TriangleStripArray(TRIANGLE_INDICES,
new int[] {TRIANGLE_INDICES.length});
// Create parallel and perspective cameras.
_cameraPerspective = new Camera();
float aspect = (float) getWidth() / (float) getHeight();
_cameraPerspective.setPerspective(30.0f, aspect, 1.0f, 1000.0f);
_cameraTransform = new Transform();
_cameraTransform.postTranslate(0.0f, 0.0f, 10.0f);
_cameraParallel = new Camera();
_cameraParallel.setParallel(5.0f, aspect, 1.0f, 1000.0f);
_graphics3d.setCamera(_cameraPerspective, _cameraTransform);
_isPerspective = true;
// Enable depth buffer.
_isDepthBufferEnabled = true;
}
/**
* Renders the sample on the screen.
*
* @param graphics the graphics object to draw on.
*/
protected void paint(Graphics graphics)
{
// Create transformation objects for the cubes.
Transform origin = new Transform();
Transform behindOrigin = new Transform(origin);
behindOrigin.postTranslate(-1.0f, 0.0f, -1.0f);
Transform inFrontOfOrigin = new Transform(origin);
inFrontOfOrigin.postTranslate(1.0f, 0.0f, 1.0f);
// Disable or enable depth buffering when target is bound.
_graphics3d.bindTarget(graphics, _isDepthBufferEnabled, 0);
_graphics3d.clear(null);
// Draw cubes front to back. If the depth buffer is enabled,
// they will be drawn according to their z coordinate. Otherwise,
// according to the order of rendering.
_cubeVertexData.setDefaultColor(0x00FF0000);
_graphics3d.render(_cubeVertexData, _cubeTriangles,
new Appearance(), inFrontOfOrigin);
_cubeVertexData.setDefaultColor(0x0000FF00);
_graphics3d.render(_cubeVertexData, _cubeTriangles,
new Appearance(), origin);
_cubeVertexData.setDefaultColor(0x000000FF);
_graphics3d.render(_cubeVertexData, _cubeTriangles,
new Appearance(), behindOrigin);
_graphics3d.releaseTarget();
drawMenu(graphics);
}
/**
* Handles key presses.
*
* @param keyCode key code.
*/
protected void keyPressed(int keyCode)
{
switch (getGameAction(keyCode))
{
case GAME_A:
_isPerspective = !_isPerspective;
if (_isPerspective)
{
_graphics3d.setCamera(_cameraPerspective, _cameraTransform);
}
else
{
_graphics3d.setCamera(_cameraParallel, _cameraTransform);
}
break;
case GAME_B:
_isDepthBufferEnabled = !_isDepthBufferEnabled;
break;
case FIRE:
init();
break;
// no default
}
repaint();
}
使用 GAME_A 键可在透视投影与平行投影之间切换。GAME_B 可启用或禁用深度缓冲。完整的源代码包含在 DepthBufferProjectionSample.java 中。图 6 展示了不同设置下的效果。
图 6. 立方体:a) 启用深度缓冲,根据与摄像机之间的距离进行渲染;b) 禁用深度缓冲,根据绘图操作的顺序进行渲染;c) 使用平行投影而非透视投影进行渲染