RenderTexture example: make a Fire texture with particles

  ... tutorials on how to use AndEngine.

RenderTexture example: make a Fire texture with particles

Postby Mip » Wed Dec 19, 2012 1:39 am

Hello !
First sorry again for my english !

RenderTexture is a good way to make things simplest or to optimize your game and keep some precious FPS.

RenderTexture described by Nicolas:

  • Render something into a Texture and use that texture for Sprites. (i.e. useful when rendering some complex mesh once and then efficiently drawing it again as a sprite.)
  • Post-Processing effects

The principle seems quite simple and usefull, but implementation was hard to me (couple hours of testings) !
The best documentation I found was talking about shaders.
So I made this tutorial to help (I hope ! :oops: ) others indies !




Example used for this tutorial : a generated fire texture.

Good to know : The simplest way I found to use rendertexture is to make an entity with childs, then override the onmanageddraw method.

To make this, I will start from the SimpleParticleExample.
I run the original example : 45 FPS (just add a yellow background uh)

Image

We start by making a FireEntity class extending Entity
Add a RenderTexture field and its getter.
In the constructor, Initialize the fireTexture (We will use it after but it’s important to set the texture to prevent null pointer exceptions) and make our Fire ParticleSystem by using Nicolas exemple :

I also move the particle emitter at the bottom left corner, I will explain it later.

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.         // ===========================================================
  2.         // Inner and Anonymous Classes
  3.         // ===========================================================
  4.         public class FireEntity extends Entity{
  5.                 private RenderTexture fireTexture;
  6.                 public TextureRegion  getFireTexture(){
  7.                         return TextureRegionFactory.extractFromTexture(fireTexture);
  8.                 }
  9.                 public FireEntity(){
  10.                         fireTexture = new RenderTexture(ParticleSystemSimpleExample.this.getTextureManager(), 400, 400);
  11.                        
  12.                         final float centerX = 200;
  13.                         final float centerY = 100;
  14.                        
  15.                         final CircleOutlineParticleEmitter particleEmitter = new CircleOutlineParticleEmitter(centerX, centerY, 80);
  16.                         final BatchedPseudoSpriteParticleSystem particleSystem = new BatchedPseudoSpriteParticleSystem(particleEmitter, 160, 160, 1000, ParticleSystemSimpleExample.this.mParticleTextureRegion, ParticleSystemSimpleExample.this.getVertexBufferObjectManager());
  17.  
  18.                         particleSystem.setBlendFunction(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_ALPHA);
  19.                        
  20.                         particleSystem.addParticleInitializer(new ColorParticleInitializer<Entity>(1, 0, 0));
  21.                         particleSystem.addParticleInitializer(new AlphaParticleInitializer<Entity>(0));
  22.                         particleSystem.addParticleInitializer(new VelocityParticleInitializer<Entity>(-2, 2, 10, 20));
  23.                         particleSystem.addParticleInitializer(new RotationParticleInitializer<Entity>(0.0f, 360.0f));
  24.                         particleSystem.addParticleInitializer(new ExpireParticleInitializer<Entity>(6));
  25.  
  26.                         particleSystem.addParticleModifier(new ScaleParticleModifier<Entity>(0, 5, 1.0f, 2.0f));
  27.                         particleSystem.addParticleModifier(new ColorParticleModifier<Entity>(0, 3, 1, 1, 0, 0.5f, 0, 0));
  28.                         particleSystem.addParticleModifier(new ColorParticleModifier<Entity>(4, 6, 1, 1, 0.5f, 1, 0, 1));
  29.                         particleSystem.addParticleModifier(new AlphaParticleModifier<Entity>(0, 1, 0, 1));
  30.                         particleSystem.addParticleModifier(new AlphaParticleModifier<Entity>(5, 6, 1, 0));
  31.                        
  32.                         this.attachChild(particleSystem);
  33.                 }
  34.         }
  35.  
Parsed in 0.015 seconds, using GeSHi 1.0.8.4



Now, we add two field to our ParticleSystemSimpleExample activity :

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. private FireEntity fire;
  2. private LowMemorySpriteVertexBufferObject msharedVertex = null;
  3.  
Parsed in 0.010 seconds, using GeSHi 1.0.8.4


Good to know : if sprites are identical, use a sharedVertexBuffer !

Then, we change the onCreateScene method from the example to use our fire entity. Also, we’ll change the onSceneTouchEvent to add a new Sprite on touch using the RenderTexture (black for the moment uh :)) and the sharedbuffer.

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. @Override
  2.         protected Scene onCreateScene() {
  3.                 this.mEngine.registerUpdateHandler(new FPSLogger());
  4.                 final Scene scene = new Scene();
  5.                 scene.setBackground(new Background(1,1,0));
  6.                 fire = new FireEntity();
  7.                 scene.attachChild(fire);
  8.                 scene.setOnSceneTouchListener(new IOnSceneTouchListener() {
  9.                         @Override
  10.                         public boolean onSceneTouchEvent(final Scene pScene, final TouchEvent pSceneTouchEvent) {
  11.                                 if(pSceneTouchEvent.isActionUp())
  12.                                 {
  13.                                         if(msharedVertex  == null)
  14.                                                 msharedVertex = new LowMemorySpriteVertexBufferObject(ParticleSystemSimpleExample.this.getVertexBufferObjectManager(), Sprite.SPRITE_SIZE, DrawType.STATIC, true, Sprite.VERTEXBUFFEROBJECTATTRIBUTES_DEFAULT);
  15.                                         Sprite newfire = new Sprite(pSceneTouchEvent.getX(), pSceneTouchEvent.getY(), fire.getFireTexture(), msharedVertex);
  16.                                         newfire.setAlpha(0.8f);
  17.                                         scene.attachChild(newfire);
  18.                                 }
  19.                                 return true;
  20.                         }
  21.                 });
  22.                 return scene;
  23.         }
Parsed in 0.011 seconds, using GeSHi 1.0.8.4




If we run this we will see the fire (fire0).
When touching, we add some black 400*400 square. The RenderTexture is empty !
Image
Let’s fill it !

override the FireEntity onManagedDraw method :

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.                 @Override
  2.                 protected void onManagedDraw(GLState pGLState, Camera pCamera) {
  3.                         if (!fireTexture.isInitialized()) {
  4.                                 fireTexture.init(pGLState);
  5.                         }
  6.                         fireTexture.begin(pGLState, false, true, Color.TRANSPARENT);
  7.                         {
  8.                                 super.onManagedDraw(pGLState, pCamera);
  9.                         }
  10.                         fireTexture.end(pGLState);
  11.                 }
  12.  
Parsed in 0.010 seconds, using GeSHi 1.0.8.4


Here, we ask the engine to render this entity out of the screen : on the fireTexture.
All FireEntity’s childs but only FireEntity’s childs will be rendered in the texture :

Image

Good to know : if your RenderTexture’s size is smallest than your camera’s one, make sure your entity is positioned bottom-left of your screen.

ok, that’s all falk !
Now you should see one new same fire at each click !

Image

FPS from the original example : 45
FPS with 10 fireentity without rendertexture : 5
FPS with 10 sprites using fireTexture : 35
Attachments
ParticleSystemSimpleExample.zip
(2.02 KiB) Downloaded 354 times
New release : A-Kart Paperboy -Wanna help ? Click !
Image

My previous games : Candy RubiX MatchUp - War Of Wizards - Memory Temple
User avatar
Mip
 
Posts: 126
Joined: Thu Nov 29, 2012 12:13 pm

Re: RenderTexture example: make a Fire texture with particle

Postby almill » Tue Jul 23, 2013 11:14 pm

First off, thanks so much for this post! It's very hard to get information on implementing rendertextures in andengine.

The thing I don't understand is where that fire sprite comes from. I see you creating it from the texture extracted from your RenderTexture, but I wonder how the image gets linked to your sprite. You must have an explosion.png file somewhere!

I want to create a sprite into which I can punch holes and see through. Should I create that Sprite normally (with standard texture atlas and texture region approach) and then render it into a RenderTexture and attach transparent Sprites as children? I'm quite lost.

Thanks again for the awesome tutorial, sorry for being too thick to get it all working.
almill
 
Posts: 11
Joined: Mon Jun 17, 2013 5:29 pm

Re: RenderTexture example: make a Fire texture with particle

Postby smartus » Mon Dec 02, 2013 5:37 pm

Awesome tutorial, thanks a lot. I used it to recreate effect from Nazgee's Dirt Raider Mayhem in combination with shaders! I linked this tutorial from my article:

http://android.kul.is/2013/12/advanced- ... art-1.html
User avatar
smartus
 
Posts: 510
Joined: Fri May 10, 2013 4:17 pm


Return to Tutorials

Who is online

Users browsing this forum: No registered users and 3 guests