More than half a year working as a developer for Android, I decided to try to write live wallpaper using OpenGL. Having run through the network, several general purpose engines and many amateur handicrafts were discovered. Two fairly mature engines offered fast native code and good documentation:
-
Andengine ;
-
LibGDX .
Unfortunately, the first does not know how to load models and is limited to two dimensions; in the second, work with models is done in extensions and written in Java, which leads to memory overspending and slow work.
Unity3D was not considered due to its payment, and it was not sharpened for live wallpapers.
Linderdaum is made entirely in native code, but does not contain a wrapper for live wallpaper and is terribly slow; on Desire, in a simple scene, the number of frames per second ranged from 3 to 8.
Viewing small projects found
min3d and
Rajawali , the first one written for OpenGL 1.1 and not a year supported, and the second one, although it works with a more advanced version of the API, does not contain many useful features from the first one. In addition, the first does not know how to work with live wallpaper.
After reviewing the examples, I still stopped at min3d. The use of shaders is not so important for a simple scene, and the examples are written simply and easily. It remains to add support for live wallpapers and make all the fixes collected by the community since its last update.
')
In principle, there are quite a lot of add-ins over OpenGL for live wallpapers, I used code from Robert Green with the package name
net.rbgrn.opengl , which implements the service and all the necessary classes. To work with live wallpapers, min3d had to remove the hard link to the activit, after which it became possible to collect examples.
Since the author has long abandoned his brainchild, and attempts to contact him ended in nothing, the
min3d-live-wallpaper-fork project was created on Google Code, where the results of the work done were saved.
I would like to say a few words about the functioning model of live wallpaper in Android. Live wallpaper is a service performed by the system in the main stream of the launcher, so if they slow down - the interface will slow down along with it. With active live wallpaper, when the user enters the preview window, another instance of the service is created. Therefore, if the developer instructed static variables and worked very closely with the memory, interesting surprises await him. You can avoid them by carefully monitoring the completion of active threads, cleaning up bitmap images using the resource manager without static initialization.
Since min3d was initially sharpened for working with activites, we had to add a texture manager so that canceling texture loading in the preview did not remove the texture from the desktop background. In addition, initially textures could be added only in the scene initialization block; for dynamic loading, a not too elegant code was added to the waiting load command and loading it in the screen redraw cycle.
Actually, the preparatory work ends there, set the task and try to solve it. The basic concept is simple to primitiveness - display two simulated hearts, make them beat, add a nice background and maybe unpretentious particles.
I drew a model in
Blender , since the heart is symmetrical, its quarter was modeled and with the help of the modifier mirror the finished model was obtained. Since the user will see only one side of the heart, the back side has been cut off, the scene is illuminated by colored light sources, so the heart is not textured. The resulting file was 17 kilobytes, which is great for a sluggish Java model parser.

Without hesitation, a texture with a render from the same Blender was installed on the background. Due to the limited imagination of the author, it was decided to bring graceful glasses to the background. Having drawn the envelope for the glass in Inkspace, I imported a svg file into Blender, converted the curve into a polyline, and using the Screw modifier, I got a very nice glass. By cloning the object and setting up the materials a simple background was obtained:

It's time to implement all this in code. As it was already said at the beginning, all functions related to live wallpaper were rendered into separate classes. We need only to expand the already finished model. We write a class describing the service of live wallpapers.
public class TwoHeartsWallpaper extends WallpaperTemplate {
@Override
public Engine onCreateEngine() {
TwoHeartsRenderer mRenderer = new TwoHeartsRenderer(this);
return new WallpaperEngine(getBaseContext(), mRenderer.renderer);
}
public void onDestroy() {
super.onDestroy();
}
}
Here we inherit from the WallpaperTemplate class and initialize the TwoHeartsRenderer render class. It is in this class that we will draw the scene. Procurement of this class is inherited from CommonRender and contains two main overloaded methods.
initScene () - initialization scene
updateScene () - update scene
These two methods are similar to the methods of min3d, so now you can collect one of the ready-made examples and get your live wallpaper. I will solve the problem with two hearts.
The first thing we need is unloaded into a clear min3d format of the model. Moveka supports md2, obj, 3ds. Of these formats, I stopped at obj, since it is completely text-based - the easiest way to understand it. In addition, Blender contains a ready-made material exporter. After unloading the model, it must be copied to the resource folder of the raw application for Android. The point in the file name must be replaced with an underscore in order to meet the resource naming standards. Now let's load it into the code. There is a Object3dContainer format for storing data about objects in min3d, and an Iparser parser for loading models. Loading the model took only a few lines.
IParser parser = Parser.createParser(Parser.Type.OBJ, mContext.getResources(), "com.two_hearts:raw/heart_cut_obj", false);
parser.parse();
Object3dContainer mModelHeartHe = parser.getParsedObject();
mModelHeartHe.scale().x = mModelHeartHe.scale().y = mModelHeartHe.scale().z = mModelHeartHeScaleCurrent;
mModelHeartHe.position().z = 4;
mModelHeartHe.lightingEnabled(true);
The first two lines initialize the parser and set the format of the model, the path in the resources and the parameter defining the need to generate MipMap maps for textures. Next, we load the model into the mModelHeartHe variable and set its size and position. The last line includes work with lighting.
The model is loaded, to add it to the scene just run the command
_scene.addChild(mModelHeartHe);
Similarly, all objects are added to the scene; when using transparent textures, it is necessary to observe the order of addition from the far to the near object. I didn’t add a Z-Buffer sort, so it would hit hard on performance.
As I said, all operations for scene modification are performed in the updateScene () method. To rotate the model along the Z axis, simply insert the string
mModelHeartHe.rotation().z++;
After the two beating hearts were implemented with the background, the scene still looked primitive, so it was decided to reinvent the wheel and write the simplest particle system. From big hearts many small ones should have been scattered. The Particle class turned out to be somewhat ugly, so I don’t cite it here. Parameters for a particle are specified as speed, increment, gravity, friction, and color shift. More complex models would increase the load on the processor when they are updated, and simpler ones would not allow to realize the task. For the test, min3d included the classes ParticleBox.java, ParticleCommon.java, ParticleCube.java, and ParticleSprite.java, which allow you to use a cube, model, or sprite as a particle. Naturally, the fastest particles are composed of sprites.
The sprite particle particles were obtained from the same heart, smoothed and rendered in Blender with a highlight. It turned out like this
Two particle emitters with centers inside the hearts were created. Since there is no sorting of Z-buffer, the simplest way to avoid problems with transparency is used. Each subsequent particle is displayed a little higher than the previous one. This is certainly not an academic decision, but it works quickly.
After launching the emitters, the scene looks like this.


It remains to add interactive. A press message is available for live wallpapers, we divide the screen into 4 zones, by clicking in the zones of hearts we launch a stream, which accelerates the beating by one second.
For a full program, it remains to stylize the settings menu. In it, the user can adjust the number of departing particles or turn them off completely, and also indicate how much to accelerate the heartbeat. After all, everyone fights it differently. The resulting settings screen is shown below. A customized heart-shaped RatingBar control is applied.
The video of the application is available
here . The application is absolutely free and does not require any permission from the user. Available from the
Android Market .
I hope the source code of the live wallpaper on min3d is laid out to help beginners to get acquainted with 3D graphics on Android and apply their knowledge to write impressive wallpapers with low power consumption.