This member has provided no bio about themself...

Report RSS LibGDX in Depth series – Entry 02

Posted by on

In our Previous post LibGDX in Depth series – Entry 01, we created our first triangle in LibGDX. Now we'll see what happens behind the scene when we run that code . Source code for previous entry is here. Explaining meshes requires more than one entry. So in this entry i'll discuss how meshes are normally sent with Opengl and in the next entry i'll continue on how LibGDX hides these details from developer.

Messing with Meshes

In OpenGL in order to draw anything we create meshes and shade them with shaders. Simple right. Mesh can be as simple as a quad or as complex as an entire city environment. Mesh class is written in com.badlogic.gdx.graphics.Mesh.java

Mesh is made of vertices and each vertex has attributes such as position (non-optional), color, texcoord ,normal,etc. These vertex attributes can be stored as vertex array (in RAM) or as Vertex Buffer Objects (in GPU RAM) .For passing each of these attributes to vertex shader as vertex array in pure OpenGL we have to

1) Get the attribute reference location for the shader program using opengl funtion glGetAttribLocation

String attribute_name="a_position";
attribute_position = glGetAttribLocation (program, attribute_name);

a_position is attribute name you give in your vertex shader. LibGDX uses "a_" attributes for attribute,
"u_" for uniforms,"v_" for varying. We'll see what each of these are in shaders section

2) Then enable vertex attribute array and point the array to the location we got previously

glEnableVertexAttribArray(attribute_position );
/* Describe our vertices array to OpenGL (it can't guess its format automatically) */
 glVertexAttribPointer( attribute_position, // attribute
 2, // number of elements per vertex, here (x,y)
GL_FLOAT, // the type of each element
GL_FALSE, // take our values as-is
0, // no extra data between each position
triangle_vertices_position // pointer to the float array );

For vertex Buffer Objects

1) Get attribute location as before

String attribute_name="a_position";
attribute_position = glGetAttribLocation (program, attribute_name);

2) We create the VBO buffer first

glGenBuffers(1, &vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(triangle_vertices_position), triangle_vertices_position, GL_STATIC_DRAW); 

The above code uses GL_STATIC _DRAW as buffer usage hint

  • GL_STATIC_DRAW is for vertex buffers that are rendered many times, and whose contents are specified once and never change.
  • GL_DYNAMIC_DRAW is for vertex buffers that are rendered many times, and whose contents change during the rendering loop.
  • GL_STREAM_DRAW is for vertex buffers that are rendered a small number of times and then discarded.

3)Point the buffer to the location we got in step 1

glEnableVertexAttribArray(attribute_position);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glVertexAttribPointer(attribute_position, 2, GL_FLOAT, GL_FALSE,
0,triangle_vertices_position));

The above code is only for position of vertices. We have to send optional attributes such as color, normals ,etc. LibGDX makes sending all these data very simple. We used 0nly 3 lines of code for doing all the above.

mesh = new Mesh(true, 3, 3, VertexAttribute.Position(), VertexAttribute.ColorUnpacked());
mesh.setVertices(new float[] {-0.5f, -0.5f, 0, 1, 0.4f, 1, 1, 0.5f, -0.5f, 0, 1, 0.2f, 0f, 1, 0.5f, 0.5f, 0,
 1, 1, 1,1}); // Interleaved vertex attributes data
mesh.setIndices(new short[] {0, 1, 2});

The Constructor for a new mesh object in LibGDX is

public Mesh (boolean isStatic, int maxVertices, int maxIndices, VertexAttribute... attributes)

Setting isStatic to true creates a VertexBufferObject/VertexBufferObjectSubData and IndexBufferObject instead of Vertex and index array.
VertexAttribute class takes care of details of which type of attribute we are specifying.

There is also managed mesh concept. I'll dive into the Mesh class in next entry.

Post a comment

Your comment will be anonymous unless you join the community. Or sign in with your social account: