📜 ⬆️ ⬇️

Making OpenGL ES LiveWallpaper on Linderdaum Engine for Android

Hi Habr!

The theme of creating a LiveWallpaper for Android is already well run: there are tutorials on pure Java, there are tutorials on Java with OpenGL ES 1.0 / 2.0, there is ... yes, but not at all!

Today we will see how to quickly make LiveWallpaper under Android in C ++ using the Linderdaum Engine and GLSL.
')


First of all, we need a customized Linderdaum Engine . About how to configure it, there was a post on Habré: http://habrahabr.ru/post/121062/

As a source of inspiration, we will use the site: http://www.chromeexperiments.com/webgl There are image-space sets of effects on WebGL that can be taken as a starting point (WebGL and OpenGL ES 2 shaders are compatible).

Let's start here with this code in C ++, which will represent our entire application:

#include "Linderdaum.h" sEnvironment* Env = NULL; clPtr<clRenderState> Background = NULL; void DrawOverlay(LEvent Event, const LEventArgs& Args) { Env->Renderer->GetCanvas()->FullscreenRect( Background ); } APPLICATION_ENTRY_POINT { Env = new sEnvironment(); Env->DeployDefaultEnvironment( NULL, "..\\..\\CommonMedia" ); Env->Connect( L_EVENT_DRAWOVERLAY, Utils::Bind( &DrawOverlay ) ); Background = Env->Resources->LoadShader( "Background.shader" ); Env->RunApplication( DEFAULT_CONSOLE_AUTOEXEC ); APPLICATION_EXIT_POINT( Env ); } APPLICATION_SHUTDOWN { Background = NULL; } 


Not much at all, right? We put it in Test_LiveWallpaper.cpp and with C ++, this is really all finished.

Getting down to shaders First, write the Background.shader :

 Object("clRenderState") { ShaderProgram "Plane.sp" } 


and Plane.sp :

 /*VERTEX_PROGRAM*/ #include Layout.sp in vec4 in_Vertex; in vec4 in_TexCoord; out vec2 Coord; void main() { gl_Position = in_ModelViewProjectionMatrix * in_Vertex; Coord = in_TexCoord.xy; } /*FRAGMENT_PROGRAM*/ in vec2 Coord; uniform float ENGINE_TIME; out vec4 out_FragColor; // Plane deformations by Anton Platonov <platosha@gmail.com> twitter.com/platosha const float TAU = 5.2832; void main( void ) { vec2 position = Coord; vec2 p = -1.0 + 2.0 * position; float alpha = -ENGINE_TIME * 0.13; float sinA = sin(alpha), cosA = cos(alpha); p = vec2(cosA*p.x+sinA*py, -sinA*p.x+cosA*py); vec2 q = p; float zr = 1.0/length(q); float zp = 1.0/abs(qy); float mc = sin(ENGINE_TIME*0.16)*.5 + .5; float z = mix(zr, zp, mc); float ur = 5.0*atan(qx*sign(qy), abs(qy))/TAU + cos(0.2*z*TAU+ENGINE_TIME*1.37) * 1.2 * sin( ENGINE_TIME * 0.21 ); float up = qx*z; float u = mix(ur, up, mc); vec2 uv = vec2(u, (1.0+mc*2.0)*z); float mv = sin(ENGINE_TIME * 0.55); uv = mix(uv, q, 0.0); float color = 0.0; color = cos(uv.x*TAU) * cos(uv.y*TAU + ENGINE_TIME*7.7); color = pow(abs(cos(color*TAU)), 3.0); float color2 = 0.0; color2 = cos(uv.x*TAU*2.0); color2 -= 0.25; float shadow = 1.0/(z*z); vec3 rc = vec3(0.9, 1.0, 0.8)*color + vec3(0.3, 0.7, 0.6)*color2; rc *= shadow; out_FragColor = vec4( rc, 1.0 ); } 


At this stage, you can already test the application under Windows. Just adding to the project and running. On the screen will be this picture:

image

In order for everything to work on Android, you will have to work a little more. The truth in Java will have to write even less. Test_LiveWallpaperService.java :

 package com.linderdaum.engine.Test_LiveWallpaper; import com.linderdaum.engine.LinderdaumEngineService; public class Test_LiveWallpaperService extends LinderdaumEngineService { @Override public LinderdaumEngineService.GLEngine onCreateEngine() { return new LinderdaumEngineService.GLEngine(); } } 


You also need the AndroidManifest.xml manifest:

 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.linderdaum.engine.Test_LiveWallpaper" android:versionCode="1" android:versionName="1.0.0"> <supports-screens android:smallScreens="false" android:normalScreens="true" android:largeScreens="true" android:anyDensity="true" /> <uses-sdk android:minSdkVersion="7" /> <uses-feature android:glEsVersion="0x00020000"/> <uses-feature android:name="android.software.live_wallpaper"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <application android:label="Test_LiveWallpaper" android:icon="@drawable/icon" android:installLocation="preferExternal" android:debuggable="false"> <service android:name="com.linderdaum.engine.Test_LiveWallpaper.Test_LiveWallpaperService" android:label="Test_LiveWallpaper" android:permission="android.permission.BIND_WALLPAPER"> <intent-filter> <action android:name="android.service.wallpaper.WallpaperService" /> </intent-filter> <meta-data android:name="android.service.wallpaper" android:resource="@xml/wallpaper" /> </service> </application> </manifest> 


Everything! The remaining files are in the normal Linderdaum project for Android. Run ndk-build and ant copy-common-media debug . You can install Test_LiveWallpaper-debug.apk on the device - new live wallpapers will appear in the list.

PS Such a shader is very heavy for a mobile GPU, so the battery will be eaten quickly enough. Experiment!

Source: https://habr.com/ru/post/161775/


All Articles