博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android下基于SDL的位图渲染(二)理论篇
阅读量:6583 次
发布时间:2019-06-24

本文共 2884 字,大约阅读时间需要 9 分钟。

理论篇

中介绍了如何将SDL2源码应用到Android渲染中,实际上SDL本身提供的android-project实现了基于android的c运行时环境,通过上面实践篇的介绍,就是完成这个环境搭建的过程。

这样就不需要过多关注Android的Activity框架及图像渲染机制。
更加详细关于这部分的介绍建议参考。
其中最关键的部分在于org.libsdl.app.SDLActivity的实现,当然涉及视频渲染需要SurfaceView支持,所有代码位于SDLActivity.java,SDLSurface就是继承与此。我们的最终的main函数的调用时通过class SDLMain实现的。
其基本调用流程是SDLSurface.surfaceChanged()启动SDLMain线程,SDLMain的线程函数执行SDLActivity的nativeInit()。这样就把java层的代码和渲染工作转交给c/c++层去实现,其他Android事件处理由SDL完成。
我们看下SDLActivity.nativeInit()的代码(位于SDL2-src/src/main/android/SDL_android_main.c中)

#include 
/* Called before SDL_main() to initialize JNI bindings in SDL library */extern void SDL_Android_Init(JNIEnv* env, jclass cls);/* Start up the SDL app */JNIEXPORT int JNICALL Java_org_libsdl_app_SDLActivity_nativeInit(JNIEnv* env, jclass cls, jobject array){ int i; int argc; int status; /* This interface could expand with ABI negotiation, callbacks, etc. */ SDL_Android_Init(env, cls); SDL_SetMainReady(); /* Prepare the arguments. */ int len = (*env)->GetArrayLength(env, array); char* argv[1 + len + 1]; argc = 0; /* Use the name "app_process" so PHYSFS_platformCalcBaseDir() works. https://bitbucket.org/MartinFelis/love-android-sdl2/issue/23/release-build-crash-on-start */ argv[argc++] = SDL_strdup("app_process"); for (i = 0; i < len; ++i) { const char* utf; char* arg = NULL; jstring string = (*env)->GetObjectArrayElement(env, array, i); if (string) { utf = (*env)->GetStringUTFChars(env, string, 0); if (utf) { arg = SDL_strdup(utf); (*env)->ReleaseStringUTFChars(env, string, utf); } (*env)->DeleteLocalRef(env, string); } if (!arg) { arg = SDL_strdup(""); } argv[argc++] = arg; } argv[argc] = NULL; /* Run the application. */ status = SDL_main(argc, argv); /* Release the arguments. */ for (i = 0; i < argc; ++i) { SDL_free(argv[i]); } /* Do not issue an exit or the whole application will terminate instead of just the SDL thread */ /* exit(status); */ return status;}

功能很简单,初始化SDL在Android下的参数,获取命令行参数,执行SDL_main()。

也许大家会感觉比较奇怪,在main.c中命名写的main函数啊,SDL_main为何物?
这个问题我也纠结了一段时间,直接找不到SDL_main的实现,哪就源码中全局搜索SDL_main吧。看看结果:

sdl2/CMakeLists.txt:1146:    set(SDL_CFLAGS "${SDL_CFLAGS} -Dmain=SDL_main")sdl2/configure.in:3123:        SDL_CFLAGS="$SDL_CFLAGS -Dmain=SDL_main"

其他全是关于SDL_main的调用或者声明,只有这两个靠谱点。查查GCC的命令,-Dmain=SDL_main,这个就是编译的时候定义宏,等价于:

#define SDL_main main

好了,到这里就搞清楚了,SDL2提供的android-project如何把Activity和c的main通过JNI串联起来的。

最后说一点,为什么我们写的c的main函数退出了,对应的Activity也退出了呢?

这就是SDL_Quit通过内部消息机制,主动通知Activity退出的。当然具体的实现可能涉及太多SDL内部的内容,有兴趣的可以直接查看SDL_Quit的实现部分。

关于SDL渲染BMP的原理,我之前写过,原理是类似的。这里不赘述了,代码也相对简单。

附加说明

本文主要参考以下部分:

  • 这篇文章是基于Eclipse的,条理不是很清楚,让人感觉比较迷糊,本文也是参考这个基础上整理的。

源码下载

本文中涉及所有源码可以从我的,下载之后需要切换到bmp_render的tag即可。

转载地址:http://zyino.baihongyu.com/

你可能感兴趣的文章
git最最最最...常用命令
查看>>
复杂recyclerView封装库
查看>>
使用Redis构建文章投票网站(Java)
查看>>
见微知著 —— Redis 字符串内部结构源码分析
查看>>
Command './js-ant' failed to execute
查看>>
阿里云NFS NAS数据保护实战
查看>>
Spring cloud配置客户端
查看>>
产品研发项目管理软件哪个好?
查看>>
【阿里云北京峰会】一图看懂机器学习PAI如何帮助企业应用智能化升级
查看>>
ansible playbook使用总结
查看>>
Android API中文文档(111) —— MailTo
查看>>
Linux 中如何卸载已安装的软件
查看>>
thinkphp 3.2 增加每页显示条数
查看>>
oracle日常简单数据备份与还原
查看>>
我的友情链接
查看>>
黑马程序员__反射总结
查看>>
Scala学习笔记(5)-类和方法
查看>>
Quartz原理
查看>>
完全卸载oracle|oracle卸载|彻底卸载oracle
查看>>
垃圾收集基础
查看>>