Greetings!

The main purpose of this website is to support Android indie game developers with tutorials, reviews and promotion of their games. The main difficulty for the developers is not to make the game, but to get exposure. To get it out there. If you find anything useful here, please spread the word. Like my page on Facebook, follow me on Google+ or Twitter. Thank you!

Google+ Facebook Twitter

× close

Monday, 2 December 2013

Advanced AndEngine Examples - Render Texture and Fragment Shaders

First I have to warn you, the articles in the Advanced AndEngine Examples series are not step-by-step tutorials for beginners. These articles are meant for more advanced AndEngine users who already know how to use AndEngine.

AndEngine has a lot of advanced features. The more advanced something gets, the less tutorials there are and even less practical examples. Today I am going to show you two features that not many people know about and even less people use: rendering to a texture and fragment shaders.

Render Texture

AndEngine allows you to render your scene to the screen. But what if you want to render something as a picture for later use? That's where render texture comes in.

First you render something to a texture. Same type of texture you would load to memory from a file, but this one is empty and you let the engine "draw" on it. Then use it as any other texture. For example on a Sprite.

What do you need this for? Well, you can make cool polaroid photo effect like in Dirt Rider Mayhem. I believe Nazgee used something similar to create it. See the example:


The "polaroid" is a screenshot, cropped and framed. With some sepia-like effect and extra text. Pretty smart! So how can you recreate such effect? It's fairly simple. Here is a great render texture tutorial from another AndEngine forum member Mip.

The whole trick is in the onManagedDraw method. See the linked tutorial for explanation!.

I took Mip's code and created an Entity with render texture. Everything attached to the entity will be rendered to a texture. After that you can apply this texture to an arbitrary number of sprites!

But of course just taking a picture and immediatelly showing it would look quite plain. And that's why we need:

Shaders

If you want to know more about Shaders in AndEngine, I recommend reading this AndEngine shaders tutorial  from ltmon. The shaders there are very well explained including a basic introduction to GLSL language.

What I did was to create a black and white fragment shader. If you've read the linked forum post, you now know that fragments are more or less pixels. So what I did I simply set red, green and blue values of each fragment to the intensity value. Calculated as 30% red, 59% green and 11% blue, which roughly corresponds to human vision perception of these colors. Creating a sepia effect is actually similar to this approach, but you have to use different color weights.

Anyway as a base, I used PositionTextureCoordinatesShaderProgram class from AndEngine which takes a pixel from texture (after transforms) and draws its exact color on screen. I just changed the exact color to intensity.

Here's the relevant part:


  public static final String FRAGMENTSHADER =
      "precision lowp float;\n" +
      "uniform sampler2D " + ShaderProgramConstants.UNIFORM_TEXTURE_0 + ";\n" +
      "varying mediump vec2 " + ShaderProgramConstants.VARYING_TEXTURECOORDINATES + ";\n" +
      "void main() {\n" +
      " vec4 myColor = texture2D(" + ShaderProgramConstants.UNIFORM_TEXTURE_0 + ", " + ShaderProgramConstants.VARYING_TEXTURECOORDINATES + ");\n" +
      " gl_FragColor.r = dot(myColor.rgb, vec3(.3, .59, .11));\n" +
      " gl_FragColor.g = dot(myColor.rgb, vec3(.3, .59, .11));\n" +
      " gl_FragColor.b = dot(myColor.rgb, vec3(.3, .59, .11));\n" +   
      " gl_FragColor.a = myColor.a;\n" +
      "}";

Putting it all together

As a next step I have attached a Sprite with badge texture to the RenderEntity - it gets rendered to a texture. Then I attached two Sprites to the scene. One of the shows the rendered texture unchanged and the second shows the texture with the black and white shader applied. And here is the result:


Different uses of these techniques

The render texture can help you speed things up and shaders are just great and useful for many things. Combining these two techniques you can create really cool effects like game event photos - as seen in Dirt Rider Mayhem. Which was my main motivation ;) Or you can use it to apply fullscreen shaders. Simply render everything to a texture and then apply shaders!

Source code

The code is pretty simple and it's basically just copy&paste from the sources above but if you want it, let me know. It's just a bit more work so I want to know if it is worth putting any effort to it.

I got a few requests half a year after this tutorial :) I posted the sources in a new article.
Martin Varga is a Czech software developer who likes pygmy owls (hence Kulíš), running, ramen, travelling and living in foreign countries. He is also known as smartus or sm4 on the internet (read as smartass, but there are too many of them). He currently tries to make games in AndEngine like Mr. Dandelion's Adventures and hangs around a lot at the AndEngine forums.