Rajawali Tutorial 8: More About The Initialization Phase & Lost Textures
Posted by Dennis on Feb 22, 2012 in 3D, Android, Rajawali • 5 commentsThis is done automatically now. Scene construction should be done in the initScene() method. Resources are managed by the framework.
Rajawali Tutorial 9: 2D Renderer
There’s a slight optimization that can be done during the initialization phase.
The construction of the 3D scene happens in the onSurfaceCreated() method. However, it is not necessary to re-create all our objects every time the application returns to this method.
The onSurfaceCreated() method is typically called when the application is launched for the first time. It can also be called when the OpenGL ES surface is re-created.
According to the GLSurfaceView documentation all the textures are lost when this method is called. This means that whatever objects we created are still there but the textures need to be updated.
So optimization can be done when you create a lot and/or big objects during initialization.
We could simply instantiate the objects once and re-create the textures & materials every time the onSurfaceCreated() method is called:
public RajawaliExample(Context context) {
super(context);
setFrameRate(30);
// -- this makes sure the children aren't cleared when the
// onSurfaceCreated() method is called
mClearChildren = false;
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
super.onSurfaceCreated(gl, config);
mCamera.setPosition(0, 0, -10);
// -- the textures need to be re-created every time
Bitmap particleBitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.particle);
TextureInfo particleTexture = mTextureManager.addTexture(particleBitmap);
if(!mSceneInitialized) {
// -- do this only once during the application's existence
particle = new Particle();
addChild(particle);
startRendering();
// -- set this flag so that this only runs once
mSceneInitialized = true;
}
// -- create a new material. the second parameter
// makes sure the old texture references aren't
// copied over to the new material
particle.setMaterial(new ParticleMaterial(), false);
particle.addTexture(particleTexture);
}
Simples.

[...] Rajawali Tutorial 8: More About The Initialization Phase & Lost Textures [...]
Hi Dennis,
I don’t know If you will read this comment, but anyway…
Where is the right place to change a texture ? I’m working on a wallpaper that lets the user select a texture in the preferences, but initScene() is not called after you return from the preferences activity of the wallpaper, so the user doesn’t see the background has changed until it goes back to the home screen (because when you go back to the home screen, initScene() is called again).
I’ve tried to change the texture in onSurfaceCreated(), because this method (unlike initScene()) is called when you go back from the preferences activity, but the texture seems to be mixed with the last one, instead of replacing it. So, what is the correct way to replace a texture ? TextureInfo#setTexture() ? or mTextureManager.updateTexture() ?
Thank you in advance.
Hi Robert,
mTextureManager.updateTexture() is the way to go.
Cheers
Dennis
Hi dennis,
But mTextureManager.updateTexture() doesn’t change the Bitmap of the texture, it just feeds the new one to OpenGL… no ?
I have found the only “live” way to change the texture of a material is by calling reset() on the TextureManager. Maybe it has something to do with the scene caching ? Also, where is the right place to change a texture ? onSurfaceChanged() ?
Hi Dennis,
Any news about this issue ? I’ve found that for live wallpapers, when you go to the preference activity and go back to the wallpaper preview, initScene() is only called once (before you go to the preference activity), so if you rely on initScene() to set/change your textures / object3Ds / etc… and let the users change any of those settings on PreferenceActivity, they won’t be updated when they go back from it.
As a workaround, I’ve disabled scene caching, and i’ve moved all the initialization code from initScene() to onSurfaceCreated()… but I don’t think that’s what you intended, right ?
Thanks.