Android์—์„œ ์‹คํ–‰ํ•  SDL2 ํ”„๋กœ์ ํŠธ ์ค€๋น„

์•ˆ๋…•ํ•˜์„ธ์š” ์—ฌ๋Ÿฌ๋ถ„. ์˜ค๋Š˜์€ Android์—์„œ ๊ฒŒ์ž„์„ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•ด sdl2 ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ”„๋กœ์ ํŠธ๋ฅผ ์ค€๋น„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋จผ์ € Android Studio๋ฅผ ๋‹ค์šด๋กœ๋“œํ•˜์—ฌ ์„ค์น˜ํ•˜๊ณ  ์ด ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์— ํ•„์š”ํ•œ ๋ชจ๋“  ๊ฒƒ์„ ์„ค์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ํ˜„์žฌ Kde Neon์ด ์žˆ๊ณ  ์ด ์‹œ์Šคํ…œ์—๋Š” /etc/environment ํŒŒ์ผ์ด ์žˆ๊ณ  ๋™์ผํ•œ ํŒŒ์ผ์ด ์šฐ๋ถ„ํˆฌ์—๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—๋Š” ๋‹ค์Œ ๋ณ€์ˆ˜๋ฅผ ์ž…๋ ฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

ANDROID_HOME=/home/username/Android/Sdk
ANDROID_NDK_HOME=/home/username/ndk

๋˜ํ•œ ๊ณต์‹ ์›น์‚ฌ์ดํŠธ์—์„œ NDK๋ฅผ ๋‹ค์šด๋กœ๋“œํ•˜๊ณ  ํ™ˆ ๋””๋ ‰ํ„ฐ๋ฆฌ์— ์••์ถ•์„ ํ’€๊ณ  ์ด๋ฆ„์„ NDK๋กœ ๋ฐ”๊ฟ”์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ์œผ๋กœ ์›น์‚ฌ์ดํŠธ์—์„œ SDL2 ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋‹ค์šด๋กœ๋“œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. libsdl.org. Android์šฉ sdl2๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์ปดํ“จํ„ฐ์šฉ์œผ๋กœ ์ปดํŒŒ์ผํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ฒŒ ํ•˜๋ฉด Android์šฉ์œผ๋กœ ์ปดํŒŒ์ผ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ํ”„๋กœ์ ํŠธ๋ฅผ ์ปดํŒŒ์ผํ•˜๋ ค๋ฉด android studio์—์„œ ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๋ผ์ด์„ผ์Šค๋ฅผ ์ˆ˜๋ฝํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด SDL2๊ฐ€ ๋นŒ๋“œํ•  ๋•Œ ๋ผ์ด์„ผ์Šค๋ฅผ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค.

์ž์‚ฐ์—์„œ Android์˜ ํŒŒ์ผ์„ ์ฝ์œผ๋ ค๋ฉด SDL_RWops ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ์€ ๊ธ€๊ผด ์ž‘์—…์„ ์œ„ํ•œ ์ฝ”๋“œ ์‚ฌ์šฉ์˜ ์˜ˆ์ž…๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ FT_New_Face๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์œผ๋ฉฐ ๋Œ€์‹  FT_New_Memory_Face๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฏธ ์ฝ์€ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

#ifdef __ANDROID__
        snprintf ( path, 254, "fonts/%s", file );
        SDL_RWops *rw = SDL_RWFromFile(path, "r" );
        char *memory = ( char * ) calloc ( rw->hidden.androidio.size, 1 );
        SDL_RWread(rw, memory, 1, rw->hidden.androidio.size );

        FT_New_Memory_Face(*this->ft_library, ( const FT_Byte  * )memory, rw->hidden.androidio.size, 0, &this;->face );
        SDL_RWclose(rw);
        free ( memory );
#else
        snprintf ( path, 254, "%s/fonts/%s", DEFAULT_ASSETS, file );
        if ( access ( path, F_OK ) ) {
                fprintf ( stderr, "not found font: %sn", path );
                exit ( EXIT_FAILURE );
        }
        struct stat st;
        stat ( path, &st; );
        FILE *rw = fopen ( path, "r" );
        char *memory = ( char * ) calloc ( st.st_size, 1 );
        fread ( memory, 1, st.st_size, rw );

        FT_New_Memory_Face ( *this->ft_library, ( const FT_Byte * ) memory, st.st_size, 0, &this;->face );
        fclose ( rw );
        free ( memory );
#endif

SDL2 ํ—ค๋”๋ฅผ ์—ฐ๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ํ—ค๋” ํŒŒ์ผ๋„ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. Android์—์„œ ์ปดํŒŒ์ผ์ด ์„ฑ๊ณตํ•˜๋ ค๋ฉด NO_SDL_GLEXT๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

#ifdef __ANDROID__
#include "SDL.h"
#include "SDL_video.h"
#include "SDL_events.h"
#define NO_SDL_GLEXT 
#include "SDL_opengl.h"
#include "SDL_opengles2.h"
#else
#include <SDL2/SDL.h>
#include <SDL2/SDL_video.h>
#include <SDL2/SDL_opengl.h>
#include <SDL2/SDL_opengles2.h>
#endif

์ด์ œ ํ”„๋กœ์ ํŠธ๊ฐ€ ์ค€๋น„๋˜์—ˆ์œผ๋ฉฐ ์…ฐ์ด๋”๋Š” OpenGL Es 3.0์„ ์œ„ํ•œ ์ค€๋น„๊ฐ€ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ ์•ˆ๋“œ๋กœ์ด๋“œ ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ ค๋ฉด SDL2 ์•„์นด์ด๋ธŒ์˜ ์••์ถ•์„ ํ‘ธ์„ธ์š”. ๋นŒ๋“œ ์Šคํฌ๋ฆฝํŠธ๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์šฐ๋ฆฌ๋Š” ์ด๋ ‡๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

./androidbuild.sh com.xverizex.test main.cpp

๋‹ค์Œ ๋ฉ”์‹œ์ง€๊ฐ€ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค.

To build and install to a device for testing, run the following:
cd /home/cf/programs/SDL2-2.0.10/build/com.xverizex.test
./gradlew installDebug

com.xverizex.test๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค. com.xverizex.test/app/jni/src๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๊ฒŒ์ž„ ํ”„๋กœ์ ํŠธ๋ฅผ ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  Android.mk ํŒŒ์ผ์„ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค. ์ œ ๊ฒฝ์šฐ์—๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := main

SDL_PATH := ../SDL
FREETYPE_PATH := ../Freetype2

LOCAL_C_INCLUDES := $(LOCAL_PATH)/$(SDL_PATH)/include $(LOCAL_PATH)/$(FREETYPE_PATH)/include

# Add your application source files here...
LOCAL_SRC_FILES := ./engine/lang.cpp ./engine/actor.cpp ./engine/sprite.cpp ./engine/shaders.cpp ./engine/box.cpp ./engine/menubox.cpp ./engine/load_manager.cpp ./engine/main.cpp ./engine/font.cpp ./engine/model.cpp ./engine/button.cpp ./theme.cpp ./level_manager.cpp ./menu/menu.cpp

LOCAL_SHARED_LIBRARIES := SDL2 Freetype2

LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -llog 

include $(BUILD_SHARED_LIBRARY)

์ด๋ฏธ ์•Œ๊ณ  ๊ณ„์‹œ๊ฒ ์ง€๋งŒ Freetype2 ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋„ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. Android์šฉ github์—์„œ ๊ธฐ์„ฑํ’ˆ์„ ์ฐพ์•˜์ง€๋งŒ ์ž‘๋™ํ•˜์ง€ ์•Š์•„์„œ ๋ญ”๊ฐ€๋ฅผ ๋ณ€๊ฒฝํ•ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ app/src/main/assets ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์—ฌ๊ธฐ์— ๋ฆฌ์†Œ์Šค(๊ธ€๊ผด, ์Šคํ”„๋ผ์ดํŠธ, 3D ๋ชจ๋ธ)๋ฅผ ๋ฐฐ์น˜ํ•ฉ๋‹ˆ๋‹ค.

์ด์ œ Android์šฉ Freetype2๋ฅผ ๊ตฌ์„ฑํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋‚ด github์—์„œ ๋‹ค์šด๋กœ๋“œ (๋งํฌ)์„ ํด๋ฆญํ•˜๊ณ  Freetype2 ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ app/jni/ ๋””๋ ‰ํ„ฐ๋ฆฌ์— ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ๊ฒƒ์ด ์ค€๋น„๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ com.xverizex.test์—์„œ ./gradlew installDebug ๋ช…๋ น์„ ์‹คํ–‰ํ•˜์„ธ์š”. ์ด ๊ฒŒ์ž„์„ Android์— ์ถ”๊ฐ€ํ•˜๋ ค๋ฉด Android์—์„œ ๋””๋ฒ„๊น…์„ ํ™œ์„ฑํ™”ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ ค๋ฉด ์„ค์ •์œผ๋กœ ์ด๋™ํ•˜์—ฌ "์‹œ์Šคํ…œ", "ํƒœ๋ธ”๋ฆฟ ์ •๋ณด"๋กœ ์ด๋™ํ•˜์—ฌ "๋นŒ๋“œ ๋ฒˆํ˜ธ" ์˜ต์…˜์„ ์•ฝ XNUMX๋ฒˆ ํด๋ฆญํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ๋Œ์•„๊ฐ€๋ฉด ๊ฐœ๋ฐœ์ž์šฉ ์˜ต์…˜์ด ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค. ๋“ค์–ด๊ฐ€์„œ ์ผœ๊ณ  "USB ๋””๋ฒ„๊น…"์˜ต์…˜๋„ ์ผœ์‹ญ์‹œ์˜ค. ์ด์ œ ํƒœ๋ธ”๋ฆฟ์šฉ ํ‚ค๋ฅผ ๊ฐ€์ ธ์™€์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ ค๋ฉด adb ํ”„๋กœ๊ทธ๋žจ์„ ์„ค์น˜ํ•˜์„ธ์š”. ์ฝ˜์†”์—์„œ adb ์…ธ์„ ์‹คํ–‰ํ•˜๋ฉด ์ˆ˜๋ฝํ•ด์•ผ ํ•˜๋Š” ํ‚ค๊ฐ€ ํƒœ๋ธ”๋ฆฟ์— ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค. ์ด์ œ ๊ฒŒ์ž„์„ ํƒœ๋ธ”๋ฆฟ์— ๋‹ค์šด๋กœ๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€