Jun 042012
 

I’m assuming you have read part 1 of this series so I’ll just jump right in.

Let’s colour this fucker

First we need to add a colour VertexAttribute to our Mesh. We will use Usage.ColorPacked as it means we can represent a colour in a single float, making our vertices array more compact and our shader more simple. All this does is pass the value from your vertex array to the shader as “a_color“.

The main thing we need to change is our shaders. First the vertex shader:

I’ve highlighted the modified lines for you because I’m nice like that. All we are doing here is adding a variable to hold colour information. The “a_color” attribute is the one we get from our VertexAttributes , which we have to assign to a varying vec4 so that it can be accessed fragment shader. These can be modified in the vertex shader and are read only in the fragment shader, so this is how we pass our colour information along.

Now the fragment shader:

Here we create the v_color vec4 again, which magically gets the value from the other shader. We then assign the variable to the gl_FragColor and BOOM we’re shading like kings.

We also need to add colours for each point in our vertex array (in Game.java):

And the fruits of our labour:

Here he is. The man himself.

One nice thing OpenGL does is merge colours in between points, that’s why we’ve got that mixture in the middle.

“But I want to add a texture to my mesh!!”

Texture time

To add a texture as well as colour we need to make a few more modifications. First let’s add a new VertexAttribute to our mesh:

This bad man will naturally hold our texture co-ordinates (I’ll explain them later when we add them to our vertices array). Now let’s modify our shaders to use our new attribute:

We simply add two new vectors “a_texCoords” and “v_texCoords” the same as we did for “a_color“. Nothing particularly interesting.

Here we add a new variable we haven’t seen before — a uniform  sampler2D called “u_texture“. This guy tells OpenGL which texture we want to use. We pass that value and our texture co-ordinates to a function called texture2D, the result of which we multiply by our colour, mixing the two together.

Finally we need to adjust our vertex array in Game.java to add our texture co-ordinates:

The co-ordinates might be confusing due to the inverted y-axis; the texture’s upper-left corner lies at (0, 0), upper-right at (1, 0), lower-left (0, 1), lower-right (1, 1).

Now our shaders are mentally and physically prepared to draw a texture, we need to firstly create a texture for it to render. You can use this one if you want, I don’t mind. Pop that in your assets folder, then modify the MeshHelper class to create a new texture:

We also need to make a few modifications to drawMesh:

We firstly enable 2D texturing, and set the first Openl GL texture (GL_TEXTURE0) to the active texture, where we will put our marble texture to be used by the shader. After we begin the shader we set “u_texture” to 0, telling our fragment shader to use GL_TEXTURE0 (it is possible to use multiple textures but I won’t go into that here). Finally we have to call the bind function on our texture, which binds it to GL_TEXTURE0. If we were dealing with multiple textures, bind can also take an integer corresponding to the GL_TEXTURE you want it to be bound to.

The result:

WHOA

There you have it. Good job buddy. Here are the project files (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), and just the source if you can’t be bothered to download them:

Game.java

MeshHelper.java

Next time we’ll use framebuffers to generate textures from meshes.

 Posted by at 10:50 pm
May 272012
 

I’m going to be repeating some stuff here but it doesnt really matter. Before you read anything read this tutorial. It has a lot of useful information.

Note: Nobody actually even asked me any of these questions.

What is a Texture?
A texture is the representation of an image (or whatever) that is stored/used by the GPU. This is the base thing that everything else uses pretty much, they are important. They also use a lot of memory. Also dont forget that in gl10 they must be a power of two size.

What is a TextureRegion?
A TextureRegion is exactly what you might think– a specific region of a texture. This object is a reference to a texture, so dont delete the underlying texture unless you’re literally insane.

What is a Sprite?
A Sprite inherits from a TextureRegion, but adds some additional methods (the key ones being position and rotation) making it easier to manipulate a texture. You can do all this with sprite batch methods on a normal texture, but if its something you’re going to be moving often (e.g. a main character) or resizing a lot, then you’re better off using a sprite.

What is a TextureAtlas?
This is a very useful group of TextureRegions that reads from the TexturePacker file format. It is very useful as you can puta lot of your images into a single texture, and refer to them by name in the TextureAtlas. Using a TextureAtlas properly will improve performance a lot as switching textures in the GPU is quite expensive.

What is a Pixmap?
Basically a texture with the ability for you to draw shapes and stuff on to it. Pretty useful for basic things, but if you want to draw complicated shapes/modify them a lot you’re better off using a framebuffer and meshes. A Pixmap is definitely more straightforward. I’ll try and write a decent tutorial on both methods but don’t hold your breath.

What is a SpriteBatch?
Pretty much mandatory if you’re drawing textures of any kind, there are lots of examples of using this so I won’t go into any details, just read the link.

What is a SpriteCache?
As the name implies, this will create a cache for textures. It is more efficient than a SpriteBatch as textures cannot be modified once added. The textures get fired off to the GPU and stay there permanently (SpriteBatch sends them off to the GPU each time).  A good example of usage would be a tilemap, assuming your tiles don’t change.

What are Cameras?
These are useful for manipulating your drawing area, for scale/movement/etc. There are two types, orthographic and perspective. You can also use them to easily get a projection matrix. Read that link for more information.

What are Meshes?
These are essentially a group of vertices with lots of helper functions to draw polygons (generally out of triangles), which saves us all the hassle of making OpenGL calls if we want to draw complicated things. If you want to know more read my tutorials on meshes.

I should probably add some more useful questions. This will have to do you for now I’m afraid.

 

 Posted by at 3:44 pm
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
May 272012
 

If you’re doing game development on android you should  be using LibGDX; it’s the most powerful library and I think it’s also the fastest. Don’t bother using AndEngine or whatever the fuck else, either use LibGDX or learn OpenGL for real. If you are coming from Cocos2D on iOS (where everything magically works all the time and has fully working tutorials) you are in for a shock my friend. A big shock.

The libgdx library is incredibly useful for game development, but the documentation is more fragmented than the so called android “operating system”. I’m going to write some beginner tutorials in an attempt to answer all the questions I’ve spent millenia researching.

I don’t really know anything about OpenGL, and I’m too lazy to learn it. That’s why I’m using a game library, but unfortunately using LibGDX requires a little knowledge, especially if you want to do something useful. I have found the documentation surrounding LibGDX to be pretty confusing, and often not explaining things I want to know; the main reason I’m writing these bad boys is so you dont have to sift through the bowels of the internet to find instructions on simple tasks.

I’ll say right now if you’re stuck on something in particular, firstly look at the LibGDX source code for the class you’re trying to use, and failing that look in the tests folder for an example, there are loads of good ones you just have to find them.

Question time

What’s the difference between OpenGL ES 2.0 and 1.0/1.1?
I don’t really know. Gl20 is generally faster, and gives more control to the developer. What this actually means is that you have to learn more stuff because some of the nice functions from gl10/gl11 have been removed in the name of “flexibility” over the “graphics processing pipeline”. Ha. Gl20 is also only supported on android 2.2+.

The biggest practical difference (for simple tasks at least) seems to be that gl20 has custom shaders. If you want to know more go ahead and read up on shaders on the OpenGL website. If you don’t give a shit and just want to draw some sweet triangles all you need to know is that you have to create a shader before you can do so in gl20.

Which version of OpenGL should I use?
It doesn’t matter too much, they both do pretty much the same thing. Gl20 is available on less devices, but realistically anyone running a version of android below 2.2 is probably really poor and won’t be buying your wicked sick game anyway, so don’t worry too much about that.

If you want to create dynamic textures of some kind you will probably want to use gl20 as it provides framebuffers (I’ll explain these later, settle down). If you don’t need to do that you may as well stick with gl10/gl11 as its easier for a beginner and has more resources, but it doesnt really matter. I guess gl20 is ~the future~ but gl10 will always be supported. Probably.

If you want more useful information read the android pages on gl10 and gl20.

You should read this introduction page covering the basics and have a read around the whole LibGDX wiki before you do anything else.

 Posted by at 12:44 pm