📜 ⬆️ ⬇️

Android development using the Linderdaum Engine

Hi habrasoobschestvo!

The theme of writing applications for android C ++ undeservedly forgotten. Today we will learn how to write multi-platform Android applications using the Linderdaum Engine .


Post updated to maintain compatibility with Linderdaum SDK 0.6.08
')
1. Setting up the build process

To work with Linderdaum Engine you first need to install:

In addition, to build directly under Android, you will also need the installed ones:

Install all of the above. We install the Linderdaum SDK into a folder with no spaces in the name (otherwise there will be problems with the Android NDK). The Linderdaum SDK has everything you need to build a library in a compiled form (they are in Libs.Win32 / Libs.Win64 and BuildAndroid / jni / armeabi-v7a), so you just need to update the meta information and build files. We start from the directory with the SDK, first rebuildLSD.py, and then makeconfig.py. All - now you can start writing our first multi-platform application.

2. Our HelloAndroid application

In order not to be loaded with engine details, but to dwell in more detail on multiplatform, consider the minimalistic 3D application that we put in the Apps / Test_Android / Src / Test_Android.cpp file:

#include "Linderdaum.h" sEnvironment* Env = NULL; LMatrix4 Projection; clVirtualTrackball Trackball; clGameCamera* Camera = NULL; clScene* Scene = NULL; void DrawOverlay(LEvent Event, const LEventArgs& Args) { //   LMatrix4 Trans( Trackball.GetRotationMatrix() * Camera->GetCamera().GetModelViewMatrix() ); Scene->SetCameraTransform( Trans ); Scene->SetCameraProjection( Projection ); //   Scene->SetUseOffscreenBuffer( false, false ); Scene->RenderForward(); //    bool MousePressedL = Env->Console->IsKeyPressed( LK_LBUTTON ); Env->Viewport->UpdateTrackball( &Trackball, 10.0f, MousePressedL ); } void Update( LEvent Event, const LEventArgs& Args ) { //  Args.FFloatArg  DeltaTime   } APPLICATION_ENTRY_POINT { LString CommandLine; EXTRACT_COMMAND_LINE(CommandLine); Env = new sEnvironment(); // CommonMedia    PC,         Env->DeployDefaultEnvironment( CommandLine, "..\\..\\CommonMedia" ); Env->FileSystem->Mount("GameData"); Projection = Math::Perspective( 45.0f, Env->Viewport->GetAspectRatio(), 0.4f, 2000.0f ); //        Camera = Env->Linker->Instantiate( "clGameCamera" ); Camera->GetCamera().SetPosition( LVector3(0,-10,10) ); CONNECTOBJ( L_EVENT_TIMER, &clGameCamera::Event_TIMER, Camera ); Env->Connect( L_EVENT_DRAWOVERLAY, Utils::Bind( &DrawOverlay ) ); Env->Connect( L_EVENT_TIMER, Utils::Bind( &Update ) ); //   Scene = Env->Linker->Instantiate("clScene"); //      int ID = Scene->AddGeom( Env->Resources->CreateIcosahedron( 3.0f, LVector3(0) ) ); //    clMaterial* Mtl = Env->Resources->CreateMaterial(); Mtl->SetPropertyValue( "DiffuseColor", "1.0 0.0 0.0 0" ); Mtl->SetPropertyValue( "CastShadow", "false" ); Scene->SetMtl( ID, Mtl ); //   Scene->SetLocalTransform( ID, LMatrix4::GetTranslateMatrix( LVector3( 0.0f, 0.0f, 0.0f ) ) ); Env->RunApplication( DEFAULT_CONSOLE_AUTOEXEC ); APPLICATION_EXIT_POINT( Env ); } APPLICATION_SHUTDOWN { } 


As it is not difficult to understand, this code should display a red icosahedron in the center of the screen with the ability to rotate it with the mouse. And, as we want, should do it without changes on the android device and on the PC under Windows. No sooner said than done.

3. Building under Windows

We use the Linderdaum build system and auto-generate all build files. Create empty Apps / Test_Android / makeconfig.py and Apps / Test_Android / jni / Android.mk files - they will be autogenerated (we will need the second one a bit later, therefore we will create it at the same time). Go to the root of the engine and from there run Solution / regenerateconfigs.py. Then run makeconfig.py. Voila - the .vcproj / .vcxproj files for the studio and the makefile for gcc are ready.

We load LinderdaumSDK_VS2008.sln (or LinderdaumSDK_VS2010.sln) and add the Apps / Test_Android project to the solution, not forgetting to set Dependency to it on Linderdaum Engine.

Press F5 - a window with a red icosahedron appears (see the screenshot at the bottom of the page).

PS For those who want to use gcc under Windows, it is enough to run build.py after generating makefiles and wait a bit.

4. Build the engine for Android

Now, when the way of Windows is mastered, we are ready to start assembly of the application under the Android. This is very easy, but it will require customization of our tools:



You need to build an engine for android (libLinderdaumEngineCore.a is already bundled with the SDK, so manual reassembly is needed only if you want to dig into the engine yourself). Run Cygwin Bash Shell, go to the BuildAndroid folder and say ndk-build -j4. We are waiting for a bit ... As a result, libLinderdaumEngineCore.a should appear a little more than 100 MB in size.

5. Building a project for Android

To build our mini-project for Android, several more files are needed in Apps / Test_Android. Here is what you need to write:

ant.properties
android.library.reference.1=..\\\\..\\\\BuildAndroid


project.properties
target=android-13


local.properties
sdk.dir=< Android SDK, D:\\android-sdk-windows>


res \ values ​​\ strings.xml
 <?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">Test_Android</string> </resources> 


jni \ Application.mk
APP_OPTIM := release
APP_PLATFORM := android-7
APP_STL := gnustl_static
APP_CPPFLAGS += -frtti
APP_CPPFLAGS += -fexceptions
APP_CPPFLAGS += -DANDROID
APP_ABI := armeabi-v7a


To use tools from the Android SDK, we need the AndroidManifest.xml manifest. For example, like this:

 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.linderdaum.engine.myfirstandroidapp" android:versionCode="1" android:versionName="0.6.00" android:installLocation="auto"> <!--require Android 2.1 and higher--> <uses-sdk android:minSdkVersion="7" /> <uses-sdk android:targetSdkVersion="9" /> <supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:anyDensity="true" /> <uses-feature android:glEsVersion="0x00020000"/> <uses-feature android:name="android.hardware.telephony" android:required="false" /> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <application android:label="@string/app_name" android:installLocation="preferExternal" android:debuggable="false"> <activity android:name="com.linderdaum.engine.LinderdaumEngineActivity" android:launchMode="singleTask" android:theme="@android:style/Theme.NoTitleBar.Fullscreen" android:screenOrientation="landscape" android:configChanges="orientation|keyboardHidden" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> 


In the future, do not forget to change the string package = "com.linderdaum.engine.myfirstandroidapp" in different applications.

After we go to Apps \ Test_Android and run ndk-build from Cygwin, the following should appear:

 $ ndk-build Compile++ thumb : LinderdaumEngine <= LAndroid.cpp Compile thumb : LinderdaumEngine <= LJNI.c Compile++ thumb : LinderdaumEngine <= Test_Android.cpp Prebuilt : libLinderdaumEngineCore.a <= jni/../../../BuildAndroid/obj/local/armeabi-v7a/ Prebuilt : libFreeImage.a <= jni/../../../BuildAndroid/jni/armeabi-v7a/ Prebuilt : libFreeType.a <= jni/../../../BuildAndroid/jni/armeabi-v7a/ Prebuilt : libVorbis.a <= jni/../../../BuildAndroid/jni/armeabi-v7a/ Prebuilt : libOGG.a <= jni/../../../BuildAndroid/jni/armeabi-v7a/ Prebuilt : libOpenAL.a <= jni/../../../BuildAndroid/jni/armeabi-v7a/ Prebuilt : libModPlug.a <= jni/../../../BuildAndroid/jni/armeabi-v7a/ Prebuilt : libstdc++.a <= <NDK>/sources/cxx-stl/gnu-libstdc++/libs/armeabi-v7a/ SharedLibrary : libLinderdaumEngine.so Install : libLinderdaumEngine.so => libs/armeabi-v7a/libLinderdaumEngine.so 


We ended up with the C ++ part of our project. It remains to finish off Java and build the distribution in .apk. For this we need the following build.xml:

 <?xml version="1.0" encoding="UTF-8"?> <project name="Asteroids" default="help"> <import file="../../BuildAndroid/CommonMedia.xml"/> <property file="local.properties" /> <property file="ant.properties" /> <loadproperties srcFile="project.properties" /> <fail message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through an env var" unless="sdk.dir" /> <target name="copy-game-data"> <!-- Game data --> <delete dir="assets"/> <copy todir="assets/Data"> <fileset dir="GameData"> </fileset> </copy> <copy todir="assets/Data"> <fileset dir="Data"> </fileset> </copy> </target> <import file="${sdk.dir}/tools/ant/build.xml" /> </project> 


Run ant copy-common-media debug and get the ready-made distribution in Apps \ Test_Android \ bin \ Test_Android-debug.apk. It can be installed on the device with the command:

adb install Test_Android-debug.apk

and run the application. It should appear like this:

image

Immediately I answer some supposed questions:

1. Is it possible to create applications for Windows, specifically for the desktop version? MacOS?
You can create applications under Windows XP / Vista / 7, both for 32-bit and 64-bit versions. And the application will not require any changes to the game code when building for Android, everything will work - and the graphics, and sound, and everything else. Version of the engine for MacOS yet.
2. Is there / will / when support WP7?
Not at the moment. Support for WP7 will be discussed after the release of the C ++ API for this platform from Microsoft.
3. What is the situation with Android 2.1 / 2.2 / 2.3 / 3.0 from the side of the engine? Differences?
C ++ and Java engine parts support Androids starting from 2.1 and up. There may be differences if you want to write Java code for a game that will not work with 2.1 / 2.2.
4. To implement the engine on Android, use the NDK or is the engine code written in Java?
The engine is written in C ++ with a wrapper in Java and uses the Android NDK to build. C ++ code works under all supported platforms.
5. How good are “wrappers” over input devices, multitouch, instant / buffered input?
Supported multitouch. Buffering and recognition of gestures will have to do yourself.
6. For 2D / 3D, only fixed-function is used, or is it possible to use shaders?
The engine is based on OpenGL 3 / OpenGL ES 2 and uses only shaders. Fixed-function cannot be used.
7. What applications are already written on the engine?
market.android.com/details?id=com.linderdaum.engine.puzzL
market.android.com/details?id=com.linderdaum.engine.multibricks_free
8. Why are there so many letters to create an application?
For academic purposes. All of the above can be done in 5 clicks using the ProjectWizard of the Linderdaum SDK.

Addition

To quickly make an Android application even faster, run the Project Wizard, select there:

Other options are left by default and click Generate Project. Everything! Do not forget to set the path to your Android SDK in local.properties.

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


All Articles