科技行者

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

知识库

知识库 安全导航

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

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

  • 扫一扫
    分享文章到微信

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

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

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

关键字:

  • 评论
  • 分享微博
  • 分享邮件
 在图 9 中,用全向光展示了不同的材质特征。各截图都将颜色组件设置为红色,以突出表现其效果。
  
  
图 9. 不同的颜色组件:a) 环境反射;b) 漫反射;c) 放射光;d) 镜面反射
   

  环境反射仅对环境光起作用,因此,使用全向光是无效的。漫反射材质组件会造成一种不光滑的表面,而放射光组件则制造出一种发光效果。镜面反射颜色组件强调了发亮的效果。此外,您还可以通过使用更多的三角形改进明暗对比的着色质量。
  
  纹理
  
  至此,我已经介绍了更改立方体外观的两种方式:顶点颜色和材质。但经过这两种方式处理后的立方体看起来依然很不真实。在现实世界中,应该还有更多的细节。这就是纹理的效果。纹理是像包在礼物外面的包装纸那样环绕在 3D 对象外的图像。您必须为各种情况选择恰当的包装纸,并且决定如何排列。在 3D 编程中也必须作出相同的决策。
  
  现在,您或许已经猜测到我将引入另外一种每个顶点都具备的属性。对于每个顶点而言,纹理坐标定义了使用纹理的位置。然后 M3G 会映射纹理以适应您的对象。可以这样设想,将一块有弹性的包装纸钉在礼物的各顶点上。这些坐标所引用的纹理像素就叫做 texel。图 10 展示了将 128 x 128 texel 的正方形纹理映射到立方体正面的效果。
  
  
图 10:将多边形坐标(x,y)映射为纹理坐标(s,t)
   

  将纹理坐标命名为(s,t)是为了与用于表示顶点位置的(x,y)区分开来(从文字角度来讲,(u,v)更为常用)。坐标(s,t)定义为(0,0)的地方就是纹理的左上角,而(1,1)位于右下角。相应地,如果您需要将立方体正面的左下角映射到纹理的左下角,必须将纹理坐标(0,1)指派给顶点 0。
  
  由于您定义了与纹理的角相关的纹理坐标,所以任意大小的图像都有相同的坐标。M3G 为最接近的 texel 插入 0 到 1 之间的值,例如,0.5 表示纹理的中点。如果纹理坐标超过 0~1 的范围,M3G 会提示您确认。坐标既可环绕(例如,1.5 与 0.5 的效果相同),也可采用加强方式,所谓加强,也就意味着任何小于 0 的值都按 0 使用,任何大于 1 的值都按 1 使用。纹理的宽和高可有所不同,但必须是 2 的幂,如图 1 中的 128。部件必须至少支持 256 的纹理大小,这是 M3G 的一个可选属性。
  
  Graphics3D.getProperties() 返回一个 Hashtable,其中填充了特定于部件的属性,如最大纹理维度或支持的最大光源数。getProperties() 的文档包含一个属性及其最低需求的清单。在使用超过这些值的属性之前,应该检查设备的部件是否能提供支持。
  
  清单 10 展示了纹理的使用。
  
  清单 10. 使用纹理,第 1 部分:初始化
  
  /** The cube's vertex positions (x, y, z). */
  private static final byte[] VERTEX_POSITIONS = {
  -1, -1, 1,  1, -1, 1,  -1, 1, 1,  1, 1, 1, // front
  1, -1, -1,  -1, -1, -1,  1, 1, -1,  -1, 1, -1, // back
  1, -1, 1,  1, -1, -1,  1, 1, 1,  1, 1, -1, // right
  -1, -1, -1,  -1, -1, 1,  -1, 1, -1,  -1, 1, 1, // left
  
  -1, 1, 1,  1, 1, 1,  -1, 1, -1,  1, 1, -1, // top
  -1, -1, -1,  1, -1, -1,  -1, -1, 1,  1, -1, 1 // bottom
  };
  
  /** Indices that define how to connect the vertices to build
  * triangles. */
  private static final int[] TRIANGLE_INDICES = {
  0, 1, 2, 3,  // front
  4, 5, 6, 7,  // back
  8, 9, 10, 11,  // right
  12, 13, 14, 15,  // left
  16, 17, 18, 19,  // top
  20, 21, 22, 23,  // bottom
  };
  
  /** Lengths of triangle strips in TRIANGLE_INDICES. */
  private static int[] TRIANGLE_LENGTHS = {
  4, 4, 4, 4, 4, 4
  };
  
  /** File name of the texture. */
  private static final String TEXTURE_FILE = "/texture.png";
  
  /** The texture coordinates (s, t) that define how to map the
  * texture to the cube. */
  private static final byte[] VERTEX_TEXTURE_COORDINATES = {
  0, 1,  1, 1,  0, 0,  1, 0,  // front
  0, 1,  1, 1,  0, 0,  1, 0,  // back
  0, 1,  1, 1,  0, 0,  1, 0,  // right
  0, 1,  1, 1,  0, 0,  1, 0,  // left
  0, 1,  1, 1,  0, 0,  1, 0,  // top
  0, 1,  1, 1,  0, 0,  1, 0,  // bottom
  };
  
  /** First color for blending. */
  private static final int COLOR_0 = 0x000000FF;
  
  /** Second color for blending. */
  private static final int COLOR_1 = 0x0000FF00;
  
  /**
  * 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);
  
  VertexArray vertexTextureCoordinates =
  
  new VertexArray(VERTEX_TEXTURE_COORDINATES.length/2, 2, 1);
  vertexTextureCoordinates.set(0,
  VERTEX_TEXTURE_COORDINATES.length/2, VERTEX_TEXTURE_COORDINATES);
  _cubeVertexData.setTexCoords(0, vertexTextureCoordinates, 2.0f, null);
  
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

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

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