之前在某乎看到一篇帖子,原话记不清了,大致意思是:如果只是做个普通的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();}


2.4 Dutl.cpp

#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 运行结果







更多相关文章

  1. 没有一行代码,「2020 新冠肺炎记忆」这个项目却登上了 GitHub 中
  2. 一款常用的 Squid 日志分析工具
  3. GitHub 标星 8K+!一款开源替代 ls 的工具你值得拥有!
  4. RHEL 6 下 DHCP+TFTP+FTP+PXE+Kickstart 实现无人值守安装
  5. Linux 环境下实战 Rsync 备份工具及配置 rsync+inotify 实时同步
  6. [置顶] android 基础笔试题
  7. Android搭建Ftp服务器监听文件传输状态
  8. Android组件保活,service保活
  9. Android:谈一谈安卓应用中的Toast情节(基础)

随机推荐

  1. 定制化IDE选型笔记
  2. mall在Linux环境下的部署(基于Docker容器)
  3. Webpack Loader
  4. 两个月的Java实习结束,继续努力
  5. centos7搭建NFS客户端以及NFS详细步骤
  6. 使用Dockerfile为SpringBoot应用构建Dock
  7. 【Java】广州三本秋招之路
  8. 【编测编学】接口测试面试题必背(上)
  9. ES 规范为什么总在 6 月发版?
  10. navicate premium 如何导入excel表数据