LibGDX

LibGDX图形模块之网格

2017-09-24  本文已影响8人  天神Deity

网格是一组顶点(和可选的索引)的组合,它们描述了用于渲染的几何图形。 顶点以顶点缓冲对象(VBOs)的形式保存在VRAM中或以顶点数组形式保存在RAM。 VBOs更快,如果提供硬件支持,则默认使用VBOs。 像纹理一样,网格被管理,并且在上下文丢失时将被自动重新加载。

网格由Libgdx中的许多核心图形类使用,如SpriteBatch和DecalBatch以及各种3D格式的加载器。 Libgdx的一个关键设计原则是将几何存储在网格中,以便将所有顶点信息批量上传到渲染中。 特别是在移动平台上,通过减少单个绘图调用的开销使性能显著提升。

Creating a Mesh

有时,使用程序网格比使用3D建模应用程序的导入模型更为方便。 以下代码创建一个简单的全屏四边形,通常用于基于帧的着色器效果:

public Mesh createFullScreenQuad() {

  float[] verts = new float[20];
  int i = 0;

  verts[i++] = -1; // x1
  verts[i++] = -1; // y1
  verts[i++] = 0;
  verts[i++] = 0f; // u1
  verts[i++] = 0f; // v1

  verts[i++] = 1f; // x2
  verts[i++] = -1; // y2
  verts[i++] = 0;
  verts[i++] = 1f; // u2
  verts[i++] = 0f; // v2

  verts[i++] = 1f; // x3
  verts[i++] = 1f; // y2
  verts[i++] = 0;
  verts[i++] = 1f; // u3
  verts[i++] = 1f; // v3

  verts[i++] = -1; // x4
  verts[i++] = 1f; // y4
  verts[i++] = 0;
  verts[i++] = 0f; // u4
  verts[i++] = 1f; // v4

  Mesh mesh = new Mesh( true, 4, 0,  // static mesh with 4 vertices and no indices
    new VertexAttribute( Usage.Position, 3, ShaderProgram.POSITION_ATTRIBUTE ),
    new VertexAttribute( Usage.TextureCoordinates, 2, ShaderProgram.TEXCOORD_ATTRIBUTE+"0" ) );

  mesh.setVertices( verts );
  return mesh;
}
// original code by kalle_h

注意使用简单的float数组来构建基本的顶点信息。 我们定义四个顶点,每个顶点由窗口坐标中的位置以及纹理坐标构成。 接下来,我们告诉网格构造函数,这将是一个具有4个顶点和无索引的静态网格。 我们定义两个顶点属性,说明它们各自的大小,并使用内置的用于常见属性类型的Libgdx常量来描述其属性。 使用常数告诉Libgdx如何解释每个浮点值,以便在渲染时可以将OpenGL指向正确的数据。 请注意,在OpenGL ES2中,使用着色器确实可以在顶点中包含其他类型的属性(即,在烘烤的顶点照明情况下的顶点照明值,或者甚至物理属性,如基于风的顶点动画的网格弹性)。 最后,我们使用我们以前构建的float数组来设置网格顶点。

还要注意使用ShaderProgram常量来命名属性。 虽然不是强制性的,但对于常见属性(如顶点位置,法线或纹理坐标)的着色器属性来说,保持相同的名称可能是有用的,因为这些是通用Libgdx着色器使用的名称。 当想要在相同的网格上交换着色器时,这个命名均匀性可以有所帮助。 有关更多信息,请参阅Shaders

Rendering

要渲染网格,只需设置环境并使用所需的图元类型调用渲染。 为了渲染上述全屏四面体,我们使用三角形风扇(因为这是我们如何构造顶点位置):

mesh.render( GL10.GL_TRIANGLE_FAN );

更典型地,您将使用其他渲染构造:

mesh.render( GL10.GL_TRIANGLES );           // OpenGL ES1.0/1.1

mesh.render( shader, GL20.GL_TRIANGLES );   // OpenGL ES2 requires a shader

mesh.render( shader, GL20.GL_LINES );       // renders lines instead

默认情况下,在调用render()时,网格会自动绑定其数据。 在调用render()之前,您将需要绑定纹理并设置模型转换,如果使用OpenGL ES2,则需要绑定适当的着色器并传递所需的任何信息。

上一篇 下一篇

猜你喜欢

热点阅读