科技行者

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

知识库

知识库 安全导航

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

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

  • 扫一扫
    分享文章到微信

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

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

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

关键字:

  • 评论
  • 分享微博
  • 分享邮件
 /**
  * Transforms the cube with the given parameters.
  *
  * @param transformation transformation (rotate, translate, scale)
  * @param axis axis of translation (x, y, z)
  * @param positiveDirection true for increase, false for decreasing
  *             value.
  */
  protected void transform(int transformation, int axis,
  boolean positiveDirection)
  {
  if (transformation == TRANSFORMATION_ROTATE)
  {
  float amount = 10.0f * (positiveDirection ? 1 : -1);
  
  switch (axis)
  {
  case TRANSFORMATION_X_AXIS:
  _cubeTransform.postRotate(amount, 1.0f, 0.0f, 0.0f);
  break;
  
  case TRANSFORMATION_Y_AXIS:
  _cubeTransform.postRotate(amount, 0.0f, 1.0f, 0.0f);
  break;
  
  case TRANSFORMATION_Z_AXIS:
  _cubeTransform.postRotate(amount, 0.0f, 0.0f, 1.0f);
  break;
  
  // no default
  }
  }
  else if (transformation == TRANSFORMATION_SCALE)
  {
  float amount = positiveDirection ? 1.2f : 0.8f;
  
  switch (axis)
  {
  case TRANSFORMATION_X_AXIS:
  _cubeTransform.postScale(amount, 1.0f, 1.0f);
  break;
  
  case TRANSFORMATION_Y_AXIS:
  _cubeTransform.postScale(1.0f, amount, 1.0f);
  break;
  
  case TRANSFORMATION_Z_AXIS:
  _cubeTransform.postScale(1.0f, 1.0f, amount);
  break;
  
  // no default
  }
  }
  else if (transformation == TRANSFORMATION_TRANSLATE)
  {
  float amount = 0.2f * (positiveDirection ? 1 : -1);
  
  switch (axis)
  {
  case TRANSFORMATION_X_AXIS:
  _cubeTransform.postTranslate(amount, 0.0f, 0.0f);
  break;
  
  case TRANSFORMATION_Y_AXIS:
  _cubeTransform.postTranslate(0.0f, amount, 0.0f);
  break;
  
  case TRANSFORMATION_Z_AXIS:
  _cubeTransform.postTranslate(0.0f, 0.0f, amount);
  break;
  
  // no default
  }
  }
  }
  
  paint() 方法现有一个 Transform 对象 _cubeTransform,该对象是 _graphics3d.render() 调用的第 4 个参数。改进的 keyPressed() 方法中包含使用 transform() 交互地更改转换的代码。GAME_C 键在旋转、平移和缩放立方体之间切换。UP/DOWN 键更改当前转换的 x 轴,LEFT/RIGHT 更改 y 轴,GAME_A/GAME_B 更改 z 轴。按 FIRE 可将立方体重新设置为初始位置。您可以在 TransformationsSample.java 中找到完整的源代码。
  
  
图 5. 示例立方体:a) 旋转;b) 平移;c) 缩放
   

  深度缓冲和投影
  
  这里我想介绍两个在使用转换时已用到但未说明过的概念:投影,定义了将 3D 对象映射到 2D 屏幕的方法;深度缓冲,是根据对象与摄像机之间的距离正确渲染对象的一种方法。
  
  要从摄像机的观察点观察渲染后的图像,您必须考虑摄像机的位置和方位,将 3D 世界转换为摄像机空间。在前面的示例代码中,我用 Camera 和 Transform 对象调用了 Graphics3D.setCamera()。可将后者视为摄像机转换或告诉 MSG 如何从世界坐标转换为摄像机坐标的指令 —— 两种定义都是正确的。最后,三维对象被显示在二维屏幕上。到这里,Camera.setPerspective() 告诉了 M3G 在将 3D 转换为 2D 空间时实现透视投影。
  
  透视投影与真实世界中的情况比较类似:当您俯视一条又长又直的道路时,道路两边看上去似乎在地平线处交汇了。距离摄像机越远,路旁的对象看起来也就越小。您也可以忽略透视,以相同大小绘制所有对象,不管它们离得多远。这对于某些应用程序,如 CAD 程序来说是很有意义的,因为没有透视可更容易地将精力集中在绘图上。要禁用透视投影,可用 Camera.setParallel() 替换 Camera.setPerspective()。
  
  在摄像机空间中,对象的 z 坐标表示其与摄像机之间的距离。如果渲染一些具有不同 z 坐标的 3D 对象,那么您当然希望距离摄像机较近的对象比远处的对象清晰。通过使用深度缓冲,对象可得到正确的渲染。深度缓冲与屏幕有着相同的宽和高,但用 z 坐标取代颜色值。它存储着绘制在屏幕上的所有像素与摄像机之间的距离。然而,M3G 仅在一个像素比现有同一位置上的像素距离摄像机近时,才将其绘制出来。通过将进入的像素的 z 坐标与深度缓冲中的值相比较,就可以验证这一点。因此,启用深度缓冲可根据对象的 3D 位置渲染对象,而不受 Graphics3D.render() 命令顺序的影响。反之,如果您禁用了深度缓冲,那么必须在绘制 3D 对象的顺序上付出一定精力。在将目标图像绑定到 Graphics3D 时,可启用深度缓冲,也可不启用。在使用接受一个参数的 bindTarget() 重载版本时,默认为启用深度缓冲。在使用带有三个参数的 bindTarget() 时,您可以通过作为第二个参数的布尔值显式切换深度缓冲的开关状态。
  
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

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

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