Porting a C++ SDL application to Android

In this note I will describe my experience of porting the prototype of the 3D editor Cube Art Project to Android.
First, let’s look at the result, the emulator runs an editor with a red 3D cube cursor:

For a successful build, you had to do the following:

  1. Install the latest Android SDK and NDK (the newer the NDK version, the better).
  2. Download the SDL2 source code, take from there a template for building an android application.
  3. Add SDL Image, SDL Mixer to the build.
  4. Add my game engine and toolkit libraries, their dependencies (GLM, JSON for Modern C++)
  5. Adapt build files for Gradle.
  6. Adapt C++ code for compatibility with Android, changes affected platform-dependent components (OpenGL ES, initialization of the graphics context)
  7. Build and test the project on the emulator.

Project template

Download SDL, SDL Image, SDL Mixer sources:
https://www.libsdl.org/download-2.0.php
The docs folder contains detailed instructions on working with the android project template; copy the android-project directory to a separate folder, make a symlink or copy the SDL folder to android-project/app/jni.
We substitute the correct identifier for the avd flag, launch the android emulator from the Sdk directory:

cd ~/Android/Sdk/emulator
./emulator -avd Pixel_2_API_24

We specify the paths in the script, build the project:

rm -rf app/build || true
export ANDROID_HOME=/home/demensdeum/Android/Sdk/
export ANDROID_NDK_HOME=/home/demensdeum/Android/android-ndk-r21-beta2/
./gradlew clean build
./gradlew installDebug

The SDL project template should build with the C code from the file

android-sdl-test-app/cube-art-project-android/app/jni/src/YourSourceHere.c

Dependencies

Download the source code in the archives for SDL_image, SDL_mixer:
https://www.libsdl.org/projects/SDL_image/
https://www.libsdl.org/projects/SDL_mixer/

Load your project’s dependencies, for example my shared libraries:
https://gitlab.com/demensdeum/FlameSteelCore/
https://gitlab.com/demensdeum/FlameSteelCommonTraits
https://gitlab.com/demensdeum/FlameSteelBattleHorn
https://gitlab.com/demensdeum/FlameSteelEngineGameToolkit/
https://gitlab.com/demensdeum/FlameSteelEngineGameToolkitFSGL
https://gitlab.com/demensdeum/FSGL
https://gitlab.com/demensdeum/cube-art-project

We unload all this into app/jni, each “module” into a separate folder, for example app/jni/FSGL. Next, you have the option of finding working generators for the Application.mk and Android.mk files, I did not find any, but perhaps there is a simple solution based on CMake. Follow the links and begin to get acquainted with the build file format for Android NDK:
https://developer.android.com/ndk/guides/application_mk
https://developer.android.com/ndk/guides/android_mk

You should also read about the different APP_STL implementations in the NDK:
https://developer.android.com/ndk/guides/cpp-support.html

After reviewing, we create an Android.mk file for each “module”, then an example of a shared library assembly file Cube-Art-Project:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

APP_STL := c++_static
APP_CPPFLAGS := -fexceptions
LOCAL_MODULE := CubeArtProject
LOCAL_C_INCLUDES := $(LOCAL_PATH)/src $(LOCAL_PATH)/../include $(LOCAL_PATH)/../include/FlameSteelCommonTraits/src/FlameSteelCommonTraits
LOCAL_EXPORT_C_INCLUDES = $(LOCAL_PATH)/src/

define walk
$(wildcard $(1)) $(foreach e, $(wildcard $(1)/*), $(call walk, $(e)))
endef

ALLFILES = $(call walk, $(LOCAL_PATH)/src)
FILE_LIST := $(filter %.cpp, $(ALLFILES))
$(info CubeArtProject source code files list)
$(info $(FILE_LIST))
LOCAL_SRC_FILES := $(FILE_LIST:$(LOCAL_PATH)/%=%)

LOCAL_SHARED_LIBRARIES += FlameSteelCore
LOCAL_SHARED_LIBRARIES += FlameSteelBattleHorn
LOCAL_SHARED_LIBRARIES += FlameSteelCommonTraits
LOCAL_SHARED_LIBRARIES += FlameSteelEngineGameToolkit
LOCAL_SHARED_LIBRARIES += FlameSteelEngineGameToolkitFSGL
LOCAL_SHARED_LIBRARIES += FSGL
LOCAL_SHARED_LIBRARIES += SDL2
LOCAL_SHARED_LIBRARIES += SDL2_image

LOCAL_LDFLAGS := -static-libstdc++
include $(BUILD_SHARED_LIBRARY)

Any experienced CMake user will understand this config from the first lines, the formats are very similar, Android.mk lacks GLOB_RECURSIVE, so you have to recursively search for source files using the walk function.

Change Application.mk, Android.mk so-but for building C++ and not C code:

APP_ABI := armeabi-v7a arm64-v8a x86 x86_64
APP_PLATFORM=android-16
APP_STL := c++_static
APP_CPPFLAGS := -fexceptions

Rename YourSourceHere.c -> YourSourceHere.cpp, grep for occurrences, change the path in the assembly, for example:

app/jni/src/Android.mk:LOCAL_SRC_FILES := YourSourceHere.cpp

Then try to build the project, if you see errors from the compiler about the absence of headers, then check the correctness of the paths in Android.mk; if there are errors from the linker of the type “undefined reference”, then check the correctness of the source code files in the assemblies, you can trace the lists by specifying $(info $(FILE_LIST)) in the Android.mk file. Do not forget about the dual linking mechanism, using modules in the LOCAL_SHARED_LIBRARIES key and correct linking via LD, for example for FSGL:

LOCAL_LDLIBS := -lEGL -lGLESv2

Adaptation and launch

I had to change some things, for example remove GLEW from the iOS and Android builds, rename some OpenGL calls, adding the EOS postfix (glGenVertexArrays -> glGenVertexArraysOES), include a macro for missing modern debug functions, the cherry on the cake is the implicit inclusion of GLES2 headers with the GL_GLEXT_PROTOTYPES 1: macro.

#define GL_GLEXT_PROTOTYPES 1
#include "SDL_opengles2.h"

I also observed a black screen on the first launches with an error like “E/libEGL: validate_display:255 error 3008 (EGL_BAD_DISPLAY)”, I changed the initialization of the SDL window, the OpenGL profile and everything worked:

SDL_DisplayMode mode;
SDL_GetDisplayMode(0,0,&mode);
int width = mode.w;
int height = mode.h;

window = SDL_CreateWindow(
            title,
            0,
            0,
            width,
            height,
            SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN | SDL_WINDOW_RESIZABLE
        );

SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES );

On the emulator, the application is installed by default with the SDL icon and the name “Game”.

I’m left to explore the possibility of automatically generating build files based on CMake, or migrating builds for all platforms to Gradle; however, CMake remains the de facto choice for current C++ development.

Source code

https://gitlab.com/demensdeum/android- sdl-test-app
https://gitlab.com/demensdeum/android-sdl-test-app/tree/master/cube-art-project-android

Sources

https://developer.android.com/ ndk/guides/cpp-support.html
https://developer.android.com/ndk/guides/application_mk
https://developer.android.com/ndk/guides/android_mk
https://lazyfoo.net/tutorials/SDL/52_hello_mobile/android_windows/index.php
https://medium.com/androiddevelopers/getting-started-with-c-and-android-native-activities-2213b402ffff

Tutorial: Making a Game for Android. Spinning the Earth. Rajawali

In the beginning God created the heaven and the earth.

This is the second video in which we make a game for Android. Let’s spin the earth!
Please write to me if you have any questions or if you would like to add something to this course.
Video based on the article Rajawali Basic Setup & Sphere (Maven):
http://www.clintonmedbery.com/basic-rajawali3d-tutorial-for-android/

Rajawali Engine: https://github.com/Rajawali/Rajawali

Plan, commands, links:
1. Install VirtualBox Guest Additions

sudo apt-get install dkmssudo apt-get install linux-headers-$(uname -r)

2. Add Rajawali library to the project
Filebuild.gradle (Project: Demon’s Cave)
Add mavenCentral() < /span>to the buildscript/repositories
sectionAdd
maven { url< /span> “https://oss.sonatype.org/content/repositories/snapshots/” } to the allprojects/repositories section

File build.gradle (Module: app)
Add compile ‘org.rajawali3d:rajawali:1.0.306-SNAPSHOT@aar& #8217; to the dependencies
section

3. Create a Renderer class, initialize the scene, add a sphere and spin!
Source code of class Renderer.java:
https://github.com/clintonmedbery/RajawaliBasicProject/blob/master/app/src/main/java/com/clintonmedbery/rajawalibasicproject/Renderer.java

4. Add Renderer class to MainActivity
Source code of MainActivity.java:
https://github.com/clintonmedbery/RajawaliBasicProject/blob/master/app/src/main/java/com/clintonmedbery/rajawalibasicproject/MainActivity.java

Ground texture:
http://www.clintonmedbery.com/wp-content/uploads/2015/04/earthtruecolor_nasa_big.jpg

Tutorial: Making a Game for Android

‘Learning is light, but ignorance is darkness‘

Demon’s Cave is coming to Android soon.
I started recording a course on porting a game to Android because there are a lot of people who are really interested in the development process.
Please write to me if you have any questions or if you would like to add something to this course.
You can also add subtitles for other languages: http://www.youtube.com/timedtext_video?ref=share&v=rx7NYkAJB2I

Plan, commands, links:
1. Installing VirtualBox https://www.virtualbox.org/wiki/Downloads
2. Installing Xubuntu http://xubuntu.org/getxubuntu/
3. Installing Oracle Java 7

sudo add-apt-repository ppa:webupd8team/javasudo apt-get updatesudo apt-get install oracle-java7-installer

4. Installing 32-bit libraries

sudo apt-get install lib32ncurses5 lib32stdc++6 zlib1g:i386

5. Installing Chromium

sudo apt-get install chromium-browser

6. Installing Android Studio http://developer.android.com/sdk/index.html< /p>