May 272012
 

I’m assuming you have read the introduction article (and maybe the FAQ), but if you already know about LibGDX and OpenGL it doesn’t really matter. This tutorial will also serve as a pretty good introduction to using OpenGL shaders within LibGDX.

Let’s actually do something then

We’ll start with a very simple example that draws just draws a triangle. If you want to use OpenGL ES 1.0 you should probably check this out.

Set up a new LibGDX project to work from. I’m not going to tell you how to do that, as the LibGDX wiki tells you all about it. Make sure you modify the Main.java class in the android and desktop projects to enable OpenGL 2.0:

Ok, lets start by making a new class called ‘MeshHelper’. We’re going to put all our mesh related code in here because we like to keep our shit tight. I’m not going to talk about imports because eclipse does it all automatically. Let’s start with a basic class:

This function will create a new mesh given the user supplied list of vertices (points that they want to draw). There are quite a lot of parameters given to Mesh, so I’ll explain them individually:

  1. isStatic – naturally, this determines whether or not the mesh is static; we will make it static for now as we’re only making one triangle in this tutorial.
  2. maxVertices – this is an integer value that specifies the maximum number of vertices allowed in this mesh. If you exceed this value in your vertices array you will get an error.
  3. maxIndices – this is an integer value that specifies the maximum number of indices (the lines making up your shape). We set this to 0 so that we don’t have to specify an indices array – the mesh will just use each vertex once in the order specified. Indices can be useful for more complicated shapes, I will explain these in more detail in a separate tutorial.
  4. attributes – these are values (we can give multiple VertexAttributes) that give more information about the vertex array. Here we only specify position, but it’s possible to also specify colour and texture coordinates. What this VertexAttribute actually specifies is that within the vertex array we firstly specify the position and each vertex is comprised of 2 values (the x and y, as we’re drawing a 2D mesh). The final parameter to the VertexAttribute is the label for this property, which we will use later in our shader.

Finally, we assign our vertex array to the mesh. If you want more information on meshes in LibGDX you should read the source code. That is the best source of documentation for LibGDX, so get used to it.

You will also note that we defined a ShaderProgram called meshShader. We require two shaders to render our meshes: a vertex shader, which performs operations per vertex (where to plot them, for example), and a fragment shader which performs additional operations between verticies (such as colouring).

Here we define our two shaders, and create a ShaderProgram with them.

In the vertex shader we create an attribute called “a_position” (the label we assigned in our VertexAttribute) and assign this attribute to gl_Position. gl_Position is a variable in the OpenGL Shading Language (glsl) that holds the co-ordinates for a vertex. When the mesh is being drawn it will individually assign our vertices to the a_position, getting our user specified values into OpenGL.

In the fragment shader we firstly check if we are running within Open GL ES (i.e. on an android device), and if so we set the float precision to medium (or so I assume; everyone does this, I just copied it). We then set the gl_FragColor to a 4d vector representing red, green, blue and alpha, so the colour we specify (1.0, 0.0, 0.0, 1.0) is red. This is also where we will work with textures at a shader level in later tutorials.

If you want more information on shaders/glsl read this tutorial (or do your own research you lazy fuck), it explains everything in detail.

Now that we have a mesh and a shader, we can create a function to actually draw our mesh:

This function is pretty self explanatory; we must call the begin() function of our meshShader before we can call the render method of our mesh. The only part you may not be familiar with is “GL20.GL_TRIANGLES” which tells OpenGL to just draw normal triangles from our vertex array. There are other options we can specify here, which will be covered in a later tutorial.

Putting everything together we get:

We have also added a dispose method so we can safely remove all our objects. We now need to call our MeshHelper class in Game.java:

Remember that OpenGL uses a co-ordinate system from -1 to 1.

The result:

Here it is

That’s a nice triangle isn’t it.

In part 2 we add our own colours, and even a texture too. Crazy stuff.

Here are all the projects in a nice little zip: FirstTriangle (note that originally the icon images in this project would cause your phone to crash often due to the gdx-setup-ui bundled with LibGDX 0.9.3– I have updated the files now so that shouldn’t happen anymore.)

 Posted by at 2:25 pm

  7 Responses to “Baby’s first triangle in LibGDX with OpenGL ES 2.0, Part 1”

  1. Great tutorial, thanks

  2. 2 Backslash is missing from the first createShader method.

  3. thank yout for this great tutorial!

  4. Hey man, these are awesome tuts! did you give up on libgdx? or just no time to write posts?

  5. Small fix would be


    public void createMesh(float[] vertices) {
    mesh = new Mesh(true, vertices.length, 0,
    new VertexAttribute(Usage.Position, 2, "a_position"));
    mesh.setVertices(vertices);
    }


    public void createMesh(float[] vertices) {
    mesh = new Mesh(true, vertices.length / 3, 0,
    new VertexAttribute(Usage.Position, 2, "a_position"));
    mesh.setVertices(vertices);
    }

    • Joao, you’re wrong, apparently it must be vertices.length. I’ve tried it and it throws an IllegalArgumentException when tries to copy into the created array.

      It seems to be yet another inconsequence in OpenGL ES, but this is the way it works.

 Leave a Reply

(required)

(required)

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">