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.