Portando um aplicativo C++ SDL para Android

Neste post descreverei minha experiência de portar um protótipo de editor 3D Cube Art Projectno Android.
Primeiro, vejamos o resultado; um editor com um cursor de cubo 3D vermelho está sendo executado no emulador:

Para uma montagem bem-sucedida, você deve fazer o seguinte:

  1. Instale o Android SDK e o NDK mais recentes (quanto mais recente a versão do NDK, melhor).
  2. Baixe o código-fonte do SDL2 e pegue o modelo de lá para construir o aplicativo Android.
  3. Adicione imagem SDL e misturador SDL à montagem.
  4. Adicionar as bibliotecas do meu mecanismo de jogo e kit de ferramentas, suas dependências (GLM, JSON para C++ moderno)
  5. Adaptar arquivos assembly para Gradle.
  6. Adaptar código C++ para compatibilidade com Android, alterações nos componentes dependentes da plataforma afetados (OpenGL ES, inicialização de contexto gráfico)
  7. Crie e teste o projeto no emulador.

Modelo de projeto

Carregando fontes SDL, SDL Image, SDL Mixer:
https://www.libsdl.org/download-2.0.php
A pasta docs contém instruções detalhadas para trabalhar com o modelo de projeto Android; copie o diretório android-project para uma pasta separada, crie um link simbólico ou copie a pasta SDL para android-project/app/jni.
Substituímos o identificador correto pelo sinalizador avd, iniciamos o emulador Android no diretório Sdk:

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

Especifique os caminhos no script, monte o projeto:

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

O modelo de projeto SDL com código C do arquivo deve ser montado

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

Dependências

Baixe o código-fonte em arquivos para SDL_image, SDL_mixer:
https://www.libsdl.org/projects/SDL_image/
https://www.libsdl.org/projects/SDL_mixer/

Carregando as dependências do seu projeto, por exemplo minhas bibliotecas compartilhadas:
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

Fazemos upload de tudo isso para app/jni, cada “módulo” em uma pasta separada, por exemplo app/jni/FSGL. A seguir, você tem a opção de encontrar geradores funcionais para os arquivos Application.mk e Android.mk, não os encontrei, mas talvez haja uma solução simples baseada no CMake. Siga os links e comece a se familiarizar com o formato de arquivo assembly para Android NDK:
https://developer.android.com/ndk/guides/application_mk
https://developer.android.com/ndk/guides/android_mk

Você também deve ler sobre diferentes implementações de APP_STL no NDK:
https://developer.android.com/ndk/guides/cpp-support.html

Após a familiarização, criamos um arquivo Android.mk para cada “módulo”, seguido de um exemplo de arquivo assembly da biblioteca compartilhada 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)

Qualquer usuário experiente do CMake entenderá essa configuração desde as primeiras linhas, os formatos são muito semelhantes, o Android.mk não possui GLOB_RECURSIVE, então você deve procurar recursivamente os arquivos de origem usando a função walk.

Alteramos Application.mk, Android.mk para criar código C++ e não C:

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

Renomeie YourSourceHere.c -> YourSourceHere.cpp, faça grep nas entradas, altere o caminho na montagem, por exemplo:

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

Em seguida, tente construir o projeto, se você encontrar erros do compilador sobre a ausência de cabeçalhos, verifique a exatidão dos caminhos em Android.mk; Se houver erros do vinculador como “referência indefinida”, verifique se os arquivos de código-fonte nos assemblies estão especificados corretamente. As listas podem ser rastreadas especificando $(info $(FILE_LIST)) no arquivo Android.mk; Não se esqueça do mecanismo de ligação dupla, usando módulos na chave LOCAL_SHARED_LIBRARIES e ligação correta através de LD, por exemplo para FSGL:

LOCAL_LDLIBS := -lEGL -lGLESv2

Adaptação e lançamento

Tive que mudar algumas coisas, por exemplo, remover o GLEW das compilações para iOS e Android, renomear algumas das chamadas OpenGL, adicionar o postfix EOS (glGenVertexArrays -> glGenVertexArraysOES), incluir uma macro para as funções de depuração modernas ausentes , a cereja do bolo é a inclusão implícita de cabeçalhos GLES2 indicando macro GL_GLEXT_PROTOTYPES 1:

#define GL_GLEXT_PROTOTYPES 1
#include "SDL_opengles2.h"

Também observei uma tela preta nas primeiras inicializações com um erro do tipo “E/libEGL: validar_display:255 erro 3008 (EGL_BAD_DISPLAY)”, alterei a inicialização da janela SDL, o perfil OpenGL e tudo funcionou:

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 );

No emulador, o aplicativo é instalado por padrão com o ícone SDL e o nome “Jogo”.

Só tenho que explorar a possibilidade de gerar automaticamente arquivos assembly baseados no CMake, ou migrar assemblies de todas as plataformas para Gradle; no entanto, o CMake continua sendo a escolha de fato para o desenvolvimento contínuo de C++.

Código fonte

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

Fontes

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: Criando um jogo no Android. Nós torcemos a terra. Rajawali

No princípio Deus criou o céu e a terra.

Este é o segundo vídeo em que estamos fazendo um jogo para Android. Vamos mover a terra!
Entre em contato comigo se tiver alguma dúvida ou se quiser acrescentar algo a este curso.
Vídeo baseado no artigo Configuração básica e configuração básica do Rajawali. Esfera (Maven):
http://www.clintonmedbery.com/basic-rajawali3d-tutorial-for-android/

Mecanismo Rajawali: https://github.com/Rajawali/Rajawali

Plano, comandos, links:
1. Instale VirtualBox Adiçõespara convidados

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

2. Adicionar biblioteca Rajawali ao projeto
Arquivobuild.gradle (Projeto: Caverna do Demônio)
Adicione mavenCentral() < /span>para a seção buildscript/repositories
Adicione
maven { url< /span> “https://oss.sonatype.org/content/repositories/snapshots/” } para a seção todos os projetos/repositórios

Arquivo build.gradle (Módulo: app)
Adicionar compilar ‘org.rajawali3d:rajawali:1.0.306-SNAPSHOT@aar& #8217; para a seção dependências

3. Crie uma classe Renderer, inicialize a cena, adicione uma esfera e gire!
Código fonte da classe Renderer.java:
https://github.com/clintonmedbery/RajawaliBasicProject/blob/master/app/src/main/java/com/clintonmedbery/rajawalibasicproject/Renderer.java

4. Adicione a classe Renderer a MainActivity
Código fonte MainActivity.java:
https://github.com/clintonmedbery/RajawaliBasicProject/blob/master/app/src/main/java/com/clintonmedbery/rajawalibasicproject/MainActivity.java

Textura do solo:
http://www.clintonmedbery.com/wp-content/uploads/2015/04/earthtruecolor_nasa_big.jpg

Tutorial: Criando um jogo no Android

‘Aprender é luz, e ignorância é escuridão

Demon’s Cave chegará ao Android em breve.
Comecei a gravar um curso sobre como portar um jogo para Android porque tem muita gente realmente interessada no processo de desenvolvimento.
Entre em contato comigo se tiver alguma dúvida ou se quiser acrescentar algo a este curso.
Você também pode adicionar legendas para outros idiomas: http://www.youtube.com/ timedtext_video?ref=share&v=rx7NYkAJB2I

Plano, comandos, links:
1. Instalando o VirtualBox https://www.virtualbox.org/wiki/Downloads
2. Instalando o Xubuntu http://xubuntu.org/getxubuntu/
3. Instalando o Oracle Java 7

sudo add-apt-repository ppa:webupd8team/javasudo apt-get atualizaçãosudo apt-get install oracle-java7-installer

4. Instalando bibliotecas de 32 bits

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

5. Instalando o Chromium

sudo apt-get install chromium-browser

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