mesh is a collection of vertices (and optionally indices) which describe a batch of geometry for rendering. The vertices are held either in VRAM in form of vertex buffer objects (VBOs) or in RAM in form of vertex arrays. VBOs are faster and are used by default if the hardware supports it. Like Textures, meshes are managed and will be automatically reloaded when the context is lost. SpriteBatch and DecalBatch as well as the various 3D format loaders. A key design principle of libGDX is in storing geometry in a mesh in order to upload all vertex information in one batch for rendering. Especially on mobile platforms, there are significant performance gains in batching by reducing the overhead of individual draw calls.

Creating a Mesh

Sometimes a procedural mesh is preferred over the use of an imported model from a 3D modeling application. The following code creates a simple full screen quad often useful for frame-based shader effects:

  1. 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 array to build the basic vertex information. We define four vertices each composed of a position in window coordinates as well as a texture coordinate. Next we tell the mesh constructor this will be a static mesh with 4 vertices and no indices. We define two vertex attributes, stating their respective sizes and describing their properties using the built-in libGDX constants for common attribute types. The usage constants tell libGDX how to interpret each of the float values so that it can point OpenGL at the proper data when rendering. Note that in OpenGL ES2, the use of Shaders does free one up to include other types of attributes in vertices (ie. vertex illumination values in a baked vertex-lighting situation, or even physical properties like mesh flexibility for simple wind based vertex animation). Finally we set the the mesh vertices using our previously built float array. Shaders for more information.

Rendering

To render a mesh, simply set up the environment and call render with the desired primitive type. To render the above full-screen quad, we use a triangle fan (because that was how we structured the vertex positions):

  1. mesh.render( GL10.GL_TRIANGLE_FAN );

More typically you will render with other primitives:

  1. mesh.render( GL10.GL_TRIANGLES ); // OpenGL ES1.0/1.1mesh.render( shader, GL20.GL_TRIANGLES ); // OpenGL ES2 requires a shadermesh.render( shader, GL20.GL_LINES ); // renders lines instead

render(). Prior to calling render(), you will need to bind the texture and set model transformations and if using OpenGL ES2 you will need bind an appropriate Shaders and pass whatever uniforms it requires.