科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件Java移动设备D图形:M3G快速模式(组图)

Java移动设备D图形:M3G快速模式(组图)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

  本文是此系列两部分中的第 1 部分,介绍了 Mobile 3D Graphics API (JSR 184) 的有关内容。作者将带领您进入 Java 移动设备的 3D 编程世界,并展示了处理光线、摄像机和材质的方法。

作者:builder.com.cn 2007年8月24日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
 键位映射
  
  示例中使用了 MIDP 的动作游戏作为处理按键事件的范例。其控制游戏动作的物理键映射到运行示例的设备上。Sun 的 Java Wireless Toolkit 将 LEFT、RIGHT、UP、DOWN 和 FIRE 映射为游戏操纵杆。GAME_A 映射为 1 键、GAME_B 映射为 3 键、GAME_C 映射为 7 键、GAME_D 映射为 9 键。
  
  按下相应的键更改以下三个属性之一:渲染模式(平面着色渲染模式或光影渲染模式)、背景拣出(看见的是立方体的外面还是里面)、环绕(逆时针三角形表示的是正面还是背面)。图 4 展示了这些选项。VertexColorsSample.java 中包含该示例的完整源代码。
  
  
图 4. 经着色的立方体:a) 光影渲染模式;b) 平面着色渲染模式,背面被拣出;c) 正面被拣出,逆时针环绕
   

  转换
  
  在本文开始处,我曾经使用了一个 Transform 对象将摄像机向后移动,以便查看整个立方体。通过同样的方式可以转换任意 3D 对象。
  
  您可以通过数学方式将转换表示为矩阵操作。一个向量 —— 例如,摄像机位置 —— 乘以恰当的平移矩阵从而得到相应移动的向量。Transform 对象就表示了这样的一个矩阵。对于绝大多数普通转换来说,M3G 提供了 3 种便于使用的接口,隐藏了底层的数学计算:
  
  Transform.postScale(float sx, float sy, float sz):在 x、y、z 方向伸缩 3D 对象。大于 1 的值将按照给定因数扩大对象;0 和 1 之间的值将缩小对象。负值则同时执行伸缩和镜像操作。
  Transform.postTranslate(float tx, float ty, float tz):通过为 x、y 和 z 坐标增加指定值移动 3D 对象。负值则表示向负轴方向移动对象。
  Transform.postRotate(float angle, float ax, float ay, float az):按给定角度绕穿过(0, 0, 0)和(ax, ay, az)的轴旋转对象。角度为正值,则表示若您顺着正旋转轴方向观察,对象是按顺时针旋转的。例如,postRotate(30, 1, 0, 0) 将绕 x 轴将对象旋转 30 度。
  所有操作名都是以 "post" 开头的,表示当前 Transform 对象是从右边与给定转换矩阵相乘的 —— 矩阵操作的顺序是非常重要的。如果您向右旋转 90 度,然后走两步,这时您所处的位置显然与先走两步再转身不同。您可以在各步行指令之后调用两个 post 方法 postRotate() 和 postTranslate(),从而获得上面的步行指令。调用顺序决定了所获得的步行指令。由于使用的是后乘,所以您最后使用的转换会首先应用。
  
  M3G 有一个 Transform 类和一个 Transformable 接口。所有快速模式的 API 均可接受 Transform 对象作为参数,用于修改其关联的 3D 对象。另外,在保留模式下使用 Transformable 接口来转换作为 3D 世界一部分的节点。在本系列的第 2 部分中将就此详细讨论。
  
  清单 6 的示例展示了转换。
  
  清单 6. 转换
  
  /**
  * Renders the sample on the screen.
  *
  * @param graphics the graphics object to draw on.
  */
  protected void paint(Graphics graphics)
  {
  _graphics3d.bindTarget(graphics);
  _graphics3d.clear(null);
  _graphics3d.render(_cubeVertexData, _cubeTriangles,
  new Appearance(), _cubeTransform);
  _graphics3d.releaseTarget();
  
  drawMenu(graphics);
  }
  
  /**
  * Handles key presses.
  *
  * @param keyCode key code.
  */
  protected void keyPressed(int keyCode)
  {
  switch (getGameAction(keyCode))
  {
  case UP:
  transform(_transformation, TRANSFORMATION_X_AXIS, false);
  break;
  
  case DOWN:
  transform(_transformation, TRANSFORMATION_X_AXIS, true);
  break;
  
  case LEFT:
  transform(_transformation, TRANSFORMATION_Y_AXIS, false);
  break;
  
  case RIGHT:
  transform(_transformation, TRANSFORMATION_Y_AXIS, true);
  break;
  
  case GAME_A:
  transform(_transformation, TRANSFORMATION_Z_AXIS, false);
  break;
  
  case GAME_B:
  transform(_transformation, TRANSFORMATION_Z_AXIS, true);
  break;
  
  case FIRE:
  init();
  break;
  
  case GAME_C:
  _transformation++;
  _transformation %= 3;
  break;
  
  // no default
  }
  
  repaint();
  }
  
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章