SDL2和其 插件编译Android上的动态链接库 及其他小记
编译SDL2 动态链接库 for Android
mkdir SDL2
mv .../SDL2-2.0.16 ./SDL2
mv .../SDL2_ttf-2.0.15 ./SDL2
然后在SDL2目录下添加文件 Android.mk 如下内容
include $(call all-subdir-makefiles)
然后在命令行 SDL2目录下
export PATH=$PATH:$NDK_HOME/build
ndk-build \
NDK_PROJECT_PATH=. \
NDK_OUT=.//build/android/obj \
NDK_LIBS_OUT=./build/android/libs \
APP_BUILD_SCRIPT=Android.mk \
APP_ABI="armeabi-v7a arm64-v8a" \
APP_PLATFORM=android-21 \
NDK_DEBUG=1
ndk-build NDK_PROJECT_PATH=. NDK_OUT=./build/obj NDK_LIBS_OUT=./build/libs APP_BUILD_SCRIPT=Android.mk APP_ABI="x86_64 arm64-v8a" APP_PLATFORM=android-21 NDK_DEBUG=1
CMakeLists.txt
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html
cmake_minimum_required(VERSION 3.10.2)
project("texting" CXX)
set(CMAKE_CXX_STANDARD 17)
#SET(CMAKE_CXX_FLAGS __STDC_FORMAT_MACROS)
#SET(CMAKE_BUILD_TYPE "Debug") #"Release"
FILE(GLOB SRC_FILES "*.cpp" "*.c")
if(WIN32)
message("Windows")
# Should set CMAKE_PREFIX_PATH to find the SDL2 related dependencies
SET(CMAKE_PREFIX_PATH "F:\\Code\\VC\\SDL2-2.26.4\\cmake" "F:\\Code\\VC\\SDL2_ttf-2.20.2\\cmake" "F:\\Code\\VC\\SDL2_net-2.2.0\\cmake")
find_package(SDL2 REQUIRED)
find_package(SDL2_TTF REQUIRED)
find_package(SDL2_NET REQUIRED)
ADD_EXECUTABLE(${PROJECT_NAME} ${SRC_FILES})
target_link_libraries(${PROJECT_NAME} SDL2::SDL2main SDL2::SDL2 SDL2_ttf::SDL2_ttf SDL2_net::SDL2_net )
FILE(COPY "../assets/GNUUnifont.ttf" DESTINATION "./")
FILE(COPY "./release.sh" DESTINATION "./")
elseif(ANDROID)
message("Android")
get_filename_component(ABI ${CMAKE_BINARY_DIR} NAME)
set(SDL2_FOLDER "E:\\cygwin64\\home\\msnqw\\code\\cpp\\SDL2\\build\\android")
set(LIBS_DIR ${SDL2_FOLDER}/libs/${ABI})
find_library(M m)
find_library(Z z)
find_library(LOG log)
find_library(GLES GLESv2)
add_library(main SHARED ${SRC_FILES})
include_directories(${SDL2_FOLDER}/include)
target_link_libraries(main ${M})
target_link_libraries(main ${Z})
target_link_libraries(main ${LOG})
target_link_libraries(main ${GLES})
add_library(SDL2 SHARED IMPORTED)
SET_TARGET_PROPERTIES(SDL2 PROPERTIES IMPORTED_LOCATION ${LIBS_DIR}/libSDL2.so)
target_link_libraries(main SDL2)
add_library(SDL2_ttf SHARED IMPORTED)
SET_TARGET_PROPERTIES(SDL2_ttf PROPERTIES IMPORTED_LOCATION ${LIBS_DIR}/libSDL2_ttf.so)
target_link_libraries(main SDL2_ttf)
add_library(hidapi SHARED IMPORTED)
SET_TARGET_PROPERTIES(hidapi PROPERTIES IMPORTED_LOCATION ${LIBS_DIR}/libhidapi.so)
target_link_libraries(main hidapi)
endif()
渲染字体
我最开始是尝试用SDL2来做demo的,结果发现写出的app在Android上运行特别慢,我也没有profiling,以为真的是开了硬件加速也这么慢,是SDL2的问题。后来发现用Allegro引擎输出字体就不慢。转回头来看SDL2,发现是我的问题。我最初的想法是用SDL2_ttf的接口生成一个SDL_Surface随即就用这个SDL_Surface来创建一个SDL_Texture,前者存在于内存,后者在显卡。这样就很慢,因为没创建一个文字就要转换到显存里。
正确,或者说要想不慢,的做法是,直接把SDL_Surface贴在最终的贴图上,最后生成一个大的SDL_Texture,这个SDL_Texture是直接渲染屏幕的最后一步,而不是从一个SDL_Texture 贴到另一个SDL_Texture,这样效率很低。
CHECK_TEXTURE_MAGIC CHECK_RENDERER_MAGIC 失败
其实是由于传入的参数是null导致的。 Texture没有真正创建出来因为Surface创建失败。
应该用这个SDL_CreateRGBSurfaceWithFormat(0, w, h, 32, SDL_PIXELFORMAT_RGBA32)
而不是SDL_CreateRGBSurface
,后者需要指定mask,这个mask实际是rgba在一个四字节的int中所占的位置。
字体颜色替换
根据SDL2的文档,你可以调用 SDL_SetSurfaceColorMod
和SDL_SetSurfaceAlphaMod
来给一个SDL_Surface进行颜色转换,转换公式为 srcC = srcC * (color / 255)。这个转换只有在你调用SDL_BlitSurface贴图的时候才会生效。
结果我发现我设置了ColorMod之后不管用,发现原来我调用TTF_RenderGlyph_Solid生产的位图是8位的,只支持ColorKey,不支持RGBA模式。换做TTF_RenderGlyph_Blended,就可以返回32位的位图。
SDL2在windows上输入法的候选框不出现的问题
要去 SDL2/src/video/windows/SDL_windowskeyboard.c 添加#define SDL_DISABLE_WINDOWS_IME
然后自己build一个SDL2的库