目录
写在前面:假定读者已经能够实现一个Android的Include C++ support 的 Hello world程序
1、首先,准备IDE环境
2、CMakeList中加入必要的动态库
3、在C++文件中写上必要的代码,打包试验
虽然说Android提供了GLSurfaceView,但是在java层有诸多性能上的限制,在我苦苦寻找了三个礼拜之后,发现只需要加三行代码,环境就有了,以前一直觉得是这方面资料少,原来是太简单了,没人写?
网上的博客要么就是用的GLSurfaceView,要么就是eclipse年代久远,而手头的实体书也是eclipse版的
你得将C++中的Hello from c++替换为Hello world,如果你已经不知道我在说什么了,放弃吧,别读了......
AndroidStudio是大前提,你要有ndk环境,在androidStudio工具栏找到SDK manager
点开以后默认看到的是一个SDK Platform的管理界面,里边有Android的各个版本,然后进入SDK Tools选项卡
进入到SDK Tools选项卡以后确认这几个是装的,CMake,LLDB,NDK,我可能记得不对,你也可以选择暴力解决,全部安装?
至此,IDE环境已经准备好了,放鞭炮,撒花????????,耶~~
(为了这么几个字符,卡了我好久呢,主要是因为懒?????)
虽然说提到.txt我会莫名的兴奋一下,但作为渣渣的我一进到CMakeList里面便瑟瑟发抖,啥玩意儿啊,看不懂,没关系,那我们就不要管他了其他的不要动,在最底下加上这个东西,加完以后是这个样子
target_link_libraries( # Specifies the target library.
native-lib #这个库是链接的哪个动态库的名字,就是我们要生成的那个
android #引进这个我们就可以用ANativeWindow了
GLESv3 #这个是必须引入的OpenGL ES的库
EGL #这个是......额与本地窗口交互的工具,你还是自己搜去吧,引进来就是了
# Links the target library to the log library
# included in the NDK.
${log-lib})
比原来的文件仅仅多了android,GLESv3,EGL这么一点点而已。
质疑的声音:靠谱不啊,楼主你是不是忽悠我呐
看官莫急,我起初也是怀疑的,所谓实干兴邦,我们代码里面试验一下
好了我们来到了C++文件,加入头文件,并且把一些OpenGL ES的数据类型写到代码里做初始化,然后编译打包,运行,最终看看结果怎样(里边OpenGL ES的一些初始化函数摘抄自《音视频开发进阶指南》)
//C++与java交互的实现
#include
//C++的string,默认导入的,会用到的,放着吧
#include
//打log用的,下面会把这里面复杂的函数简化就是#define的那几行
#include
//这行和下边那行是用来引入ANativeWindow的
#include
//用来引入ANativeWindow的
#include
//OpenGL要用的
#include
//OpenGL要用的
#include
//OpenGL要用的
#include
//OpenGL要用的
#include
//这三行主要是用来定义LOGI和LOGE的,看到原函数多复杂了吧,用这个会疯掉的
#define LOG_TAG "ndk-build"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
bool initOpenGlES();
EGLDisplay display;
extern "C" JNIEXPORT jstring JNICALL
Java_com_qt_myopengl_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
ANativeWindow * window;
initOpenGlES();
//只要没有log错误,并且下面的字符串成功显示到界面上,就证明成功了
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
bool initOpenGlES(){
if ((display = eglGetDisplay(EGL_DEFAULT_DISPLAY)) == EGL_NO_DISPLAY) {
LOGE("eglGetDisplay returned err %d", eglGetError());
return false;
}
if (!eglInitialize(display, 0, 0)) {
LOGE("eglInitialize returned err %d", eglGetError());
return false;
}
const EGLint attribs[] = {EGL_BUFFER_SIZE, 32,
EGL_ALPHA_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_RED_SIZE, 8,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_NONE};
if (!eglChooseConfig(display, attribs, &config, 1, &numConfigs)) {
LOGE("eglChooseConfig returned err %d", eglGetError());
return false;
}
EGLint attributes[] = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE};
if (!(context = eglCreateContext(display, config, NULL, attributes))) {
LOGE("eglCreateContext returned err %d", eglGetError());
return false;
}
EGLSurface surface = NULL;
EGLint format;
if (!eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format)) {
LOGE("eglGetConfigAttrib returned err %d", eglGetError());
return false;
}
LOGI("好高兴啊,我成功了???");
return true;
}
我迫不及待的运行了一下,虽然看不到什么效果,但是程序跑起来了,有没有问题还不知道,但是这已经足够了,因为我们已经证明了OpenGL ES的库被成功引进来了,并且在C++代码中正常使用,环境搭建完毕,下边贴上我胜利的果实