目标:一个简单的app程序,基于SDL开源库,实现加载一张bmp图片,并且显示的功能。
环境要求:
1. 一个可用的android studio开发环境;本次用的是android studio 2.3.0 ;
2.SDL源码,下载地址 SDL官网下载;
3.编译好的libSDL2.so动态库; 可以参考前面的文章《 linux下交叉编译android版本的libSDL2.so》;
4.Demo程序下载地址: https://github.com/zhuxian2009/MySDLDemo
第一步:创建一个支持C++的android工程;
注意一,将packet设为
org.libsdl.app
因为SDL开源库中的android样例,也是用这个packet,这样会省去很多麻烦。
注意二,讲MainActive改为SDLActive,原因是SDL样例用的是SDLActive,可以为你的第一个Demo省去很多麻烦。老司机可以无视...
其他都是默认。
第二步:将编译好的libSDL2.so和头文件,放入指定位置;
2.1 将armeabi-v7a\libSDL2.so,放入app\libs
2.2 从SDL开源代码中提取头文件,提取SDL2\include;全部放入放入app\src\main\cpp\include;
2.3 将SDL2\src\dynapi;放入app\src\main\cpp\include;
2.4 将SDL2\src\目录最外层的所有文件放入sdlmain,放入app\src\main\cpp\include
第三步:将SDL开源工程中的SDL_android_main.c文件,放入app\src\main\cpp\
第四步:修改native-lib.cpp,实现调用SDL接口,加载图片,显示图片的功能:
#include
#include
#include "SDL.h"
extern "C"
JNIEXPORT jstring JNICALL
Java_org_libsdl_app_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
struct SBMPInfo
{
SDL_Texture* texture;
Uint16 w;
Uint16 h;
} ;
/* Adapted from SDL's testspriteminimal.c */
SBMPInfo LoadBMP(const char* file, SDL_Renderer* renderer)
{
SBMPInfo result;
result.texture = NULL;
result.w = 0;
result.h = 0;
SDL_Surface* temp;
/* Load the sprite image */
temp = SDL_LoadBMP(file);
if (temp == NULL)
{
fprintf(stderr, "Couldn't load %s: %s\n", file, SDL_GetError());
return result;
}
result.w = temp->w;
result.h = temp->h;
/* Create texture from the image */
result.texture = SDL_CreateTextureFromSurface(renderer, temp);
if (!result.texture) {
fprintf(stderr, "Couldn't create texture: %s\n", SDL_GetError());
SDL_FreeSurface(temp);
return result;
}
SDL_FreeSurface(temp);
return result;
}
void draw(SDL_Window* window, SDL_Renderer* renderer, const SBMPInfo tagBMP)
{
int w, h;
SDL_GetWindowSize(window, &w, &h);
SDL_Rect destRect = {w/2 - tagBMP.w/2, h/2 - tagBMP.h/2, tagBMP.w, tagBMP.h};
/* Blit the sprite onto the screen */
SDL_RenderCopy(renderer, tagBMP.texture, NULL, &destRect);
}
int main(int argc, char *argv[])
{
SDL_Window *window;
SDL_Renderer *renderer;
if(SDL_CreateWindowAndRenderer(0, 0, 0, &window, &renderer) < 0)
exit(2);
SBMPInfo tagBMP = LoadBMP("logo.bmp", renderer);
if(tagBMP.texture == NULL)
exit(2);
/* Main render loop */
Uint8 done = 0;
SDL_Event event;
while(!done)
{
/* Check for events */
while(SDL_PollEvent(&event))
{
if(event.type == SDL_QUIT || event.type == SDL_KEYDOWN || event.type == SDL_FINGERDOWN)
{
done = 1;
}
}
/* Draw a gray background */
SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF);
SDL_RenderClear(renderer);
draw(window, renderer, tagBMP);
/* Update the screen! */
SDL_RenderPresent(renderer);
SDL_Delay(10);
}
exit(0);
}
第五步:修改CMakeList.txt,指定头文件和库的加载
cmake_minimum_required(VERSION 3.4.1)
set(lib_src_DIR ${CMAKE_SOURCE_DIR}/libs/armeabi-v7a)
include_directories(
${CMAKE_SOURCE_DIR}/src/main/cpp/include
)
add_library(sdl2_lib SHARED IMPORTED)
set_target_properties(sdl2_lib PROPERTIES IMPORTED_LOCATION
${lib_src_DIR}/libSDL2.so)
#add_library(sdlmain_lib SHARED IMPORTED)
#set_target_properties(sdlmain_lib PROPERTIES IMPORTED_LOCATION
# ${lib_src_DIR}/libmain.so)
add_library( native-lib SHARED
src/main/cpp/native-lib.cpp
src/main/cpp/SDL_android_main.c
)
find_library(log-lib log )
find_library(GLESv1_CM-lib GLESv1_CM )
find_library(GLESv2-lib GLESv2 )
target_link_libraries( native-lib
${log-lib}
${GLESv1_CM-lib}
${GLESv2-lib}
sdl2_lib
# sdlmain_lib
)
修改app下的build.gradle,将
externalNativeBuild {
cmake {
cppFlags ""
}
}
改为
ndk {
abiFilters 'armeabi-v7a'
}
在android标签下,加入
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
第七步:将SDL开源库中的SDLActive.java,替换掉studio自动生成的app\src\main\java\org\libsdl\app\SDLActive.java
第八步:将bmp图片copy到app\src\main\assets\logo.bmp;
rebuild-->run,结果如下: