Android(安卓)NDK之旅-OpenGL 初探
之前在某乎看到一篇帖子,原话记不清了,大致意思是:如果只是做个普通的Android码农,那Java够用;但如果你的理想比这个还要大一点,C++是你进阶的必备技能。
恰好之前有一点点C++ 基础,然后最近在公司业务上又涉及到openGL ,那就通过写篇帖子来学习总结一下在Android JNI 里编写一些openGL 的代码,权当一个入门吧...
1.入门必备
1.1 NDK
既然是NDK+openGL,那肯定要先了解一下这两个是什么。先简要的说下NDK(个人理解):
NDK(native development kit) 是一套工具集合,利用内置的交叉编译器通过 .mk 文件帮你把C/C++ 代码编译出适应各种 cpu 架构的 .so 库,通过 jni 标准你可以调用这些库里的方法,这样的好处是避免的多种cpu 架构的适配,把一些机密的代码用C/C++写进.so中也提高了安全性。
如果想要得到更加具体的信息,可以自行 google 这些关键字:NDK / JNI / Android.mk
1.2 openGL
openGL(open graphics library) 是一套跨平台跨语言的接口程序,是一个具有丰富的 2D/3D api的图形调用库.而openGL ES 是openGL 的 api 子集,针对嵌入式设备,如手机,pad 等。
本文中是在Android 上的Demo,用到的库当然是openGL ES(Version:ES 2.0)
1.3 Android 相关
在Android 上开发openGL ,还需补充一些Android 相关的知识,这里就不赘述了,要想讲通透会引申很多的知识点,具体可自行google 这些关键字:
Surface / SurfaceView / GLSurfaceVIew / SurfaceTexture / TextureVIew
2.编码
默认已经配置好NDK (如何配置NDK,教程太多了,可自行搜索)
以下只是作为一个Demo 展示,请忽略一下编码风格等一些问题
2.1 MainActivity xml文件
<?xml version="1.0" encoding="utf-8"?>
2.2 自定义DemoGLView 继承GLSurfaceVIew
很简单,没啥说的,关键字:GLSurfaceVIew.Render
public class DemoGLView extends GLSurfaceView { private static final int GLES_VERSION = 2; private DemoRender demoRender = null; private Context mContext; public DemoGLView(Context context) { this(context,null); } public DemoGLView(Context context, AttributeSet attrs) { super(context, attrs); this.mContext = context; initRender(); } class DemoRender implements Renderer{ @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { Log.e("Tag","onSurfaceCreated"); Dutil.initGL(); } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { } @Override public void onDrawFrame(GL10 gl) { Log.e("Tag","onDrawFrame"); Dutil.render(); } } private void initRender(){ demoRender = new DemoRender(); setEGLContextClientVersion(GLES_VERSION); setRenderer(demoRender); setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); }}
2.3 JNI 调用头文件(我把它叫做头文件,并不是C/C++ .h文件)public class Dutil { static { System.loadLibrary("Dutil"); } public static native void initGL(); public static native void render(); public static native String getAuthor();}
#include "com_xutianyi_picturefilter_picturefilter_Dutil.h"#include #include #define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR,"Dutil",__VA_ARGS__)GLuint d_glprogram;JNIEXPORT void JNICALL Java_com_xutianyi_picturefilter_picturefilter_Dutil_initGL (JNIEnv *env, jclass obj){ //init gl GLuint glProgram; GLuint vertexShader; GLuint fragmentShader; //shader code const char *shader_vertex = "uniform mediump mat4 MODELVIEWPROJECTIONMATRIX;\n" "attribute vec4 POSITION;\n" "void main(){\n" " gl_Position = POSITION;\n" "}"; const char *shader_fragment = "precision mediump float;\n" "void main(){\n" " gl_FragColor = vec4(0,0,1,1);\n" "}"; glProgram = glCreateProgram(); if(glProgram == 0){ ALOGE("init glProgram error!");// return ; } d_glprogram = glProgram;// glClearColor(0.5f, 0.5f, 0.5f, 1.0f); glClearColor ( 1.0f, 1.0f, 1.0f, 0.0f ); //vertexShader vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader,1,&shader_vertex,NULL); //fragmentShader fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader,1,&shader_fragment,NULL); glCompileShader(vertexShader); glCompileShader(fragmentShader); glAttachShader(glProgram,vertexShader); glAttachShader(glProgram,fragmentShader); glLinkProgram(glProgram);}JNIEXPORT void JNICALL Java_com_xutianyi_picturefilter_picturefilter_Dutil_render (JNIEnv *env, jclass obj){ //render glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT); //vertex array GLfloat vertexs[] = { 0.0f, 1.0f, 0.0f, -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f }; glUseProgram(d_glprogram); glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,vertexs); glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLES,0,3);}JNIEXPORT jstring JNICALL Java_com_xutianyi_picturefilter_picturefilter_Dutil_getAuthor (JNIEnv *env, jclass obj){ ALOGE("it is a log test"); jstring author = env->NewStringUTF("Author:wsz88"); return author;}
2.5 运行结果
更多相关文章
- 没有一行代码,「2020 新冠肺炎记忆」这个项目却登上了 GitHub 中
- 一款常用的 Squid 日志分析工具
- GitHub 标星 8K+!一款开源替代 ls 的工具你值得拥有!
- RHEL 6 下 DHCP+TFTP+FTP+PXE+Kickstart 实现无人值守安装
- Linux 环境下实战 Rsync 备份工具及配置 rsync+inotify 实时同步
- [置顶] android 基础笔试题
- Android搭建Ftp服务器监听文件传输状态
- Android组件保活,service保活
- Android:谈一谈安卓应用中的Toast情节(基础)