NDK开发(十) :Hello OpenGLES3

转载请以连接形式标明出处: 本文出自:103style的博客java

本文操做以 Android Studio 3.5 版本为例android

功能介绍

Demo源码连接c++


目录

  • 建立及配置工程
  • 修改JNI代码实现功能逻辑
  • 运行程序查看效果
  • 相关资源连接

建立及配置工程

  • 建立一个新工程,在 Choose your project 时选择 native c++ 模板。
  • AndroidManifest 中添加Open GL ES版本声明:
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.lxk.hellogles3">
    
        <uses-feature
            android:glEsVersion="0x00030000"
            android:required="true" />
    
        <application
            ....
        </application>
    
    </manifest>
    复制代码
  • 修改 native-lib.cppnative-gles3.cpp
  • 修改CMakeLists.txt 为如下内容:
    cmake_minimum_required(VERSION 3.4.1)
    
    ##官方标准配置
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-rtti -fno-exceptions -Wall")
    
    add_library(native-gles3
            SHARED
            native-gles3.cpp)
    
    if (${ANDROID_PLATFORM_LEVEL} LESS 11)
        message(FATAL_ERROR "OpenGL 2 is not supported before API level 11 (currently using ${ANDROID_PLATFORM_LEVEL}).")
        return()
    elseif (${ANDROID_PLATFORM_LEVEL} LESS 18)
        add_definitions("-DDYNAMIC_ES3")
        set(OPENGL_LIB GLESv2)
    else ()
        set(OPENGL_LIB GLESv3)
    endif (${ANDROID_PLATFORM_LEVEL} LESS 11)
    
    target_link_libraries(native-gles3
            android
            EGL
            ${OPENGL_LIB}
            log)
    复制代码
  • 建立修改 相关 java 文件(MainActivity、GLSurfaceView、Renderer)GLSurfaceView 必定要调用 setEGLContextClientVersion(3); 设置 OpenGL ES 的版本

修改JNI代码实现功能逻辑

  • 导入相关头文件:git

    #include <jni.h>
    #include <string>
    
    #include <GLES3/gl3.h>
    #include <GLES3/gl3ext.h>
    
    #include <android/log.h>
    #include "LogUtils.h"
    复制代码

    LogUtils.hgithub

  • 选中 GLES3Render 中报红的 native 方法,按 alt + enter 快速建立 C 方法。数组

  • 编写 顶点着色器片断着色器 源码:bash

    /**
     * 顶点着色器源码
     */
    auto gl_vertexShader_source =
            "#version 300 es\n"
            "layout(location = 0) in vec4 vPosition;\n"
            "void main() {\n"
            " gl_Position = vPosition;\n"
            "}\n";
    /**
     * 片断着色器源码
     */
    auto gl_fragmentShader_source =
            "#version 300 es\n"
            "precision mediump float;\n"
            "out vec4 fragColor;\n"
            "void main() {\n"
            " fragColor = vec4(1.0,1.0,0.0,1.0);\n"
            "}\n";
    复制代码
  • 编写编译着色器源码的方法:app

    /**
     * 编译着色器源码
     * @param shaderType 着色器类型
     * @param shaderSource  源码
     * @return
     */
    GLuint compileShader(GLenum shaderType, const char *shaderSource) {
        //建立着色器对象
        GLuint shader = glCreateShader(shaderType);
        if (!shader) {
            return 0;
        }
        //加载着色器源程序
        glShaderSource(shader, 1, &shaderSource, nullptr);
        //编译着色器程序
        glCompileShader(shader);
    
        //获取编译状态
        GLint compileRes;
        glGetShaderiv(shader, GL_COMPILE_STATUS, &compileRes);
    
        if (!compileRes) {
            //获取日志长度
            GLint infoLen = 0;
            glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
    
            if (infoLen > 0) {
                char *infoLog = static_cast<char *>(malloc(sizeof(char) * infoLen));
                //获取日志信息
                glGetShaderInfoLog(shader, infoLen, nullptr, infoLog);
                LOGE("compile shader error : %s", infoLog);
                free(infoLog);
            }
            //删除着色器
            glDeleteShader(shader);
            return 0;
        }
        return shader;
    }
    复制代码
  • 编写连接着色器程序的代码:ui

    /**
     * 连接着色器程序
     */
    GLuint linkProgram(GLuint vertexShader, GLuint fragmentShader) {
        //建立程序
        GLuint programObj = glCreateProgram();
        if (programObj == 0) {
            LOGE("create program error");
            return 0;
        }
        //加载着色器载入程序
        glAttachShader(programObj, vertexShader);
        glAttachShader(programObj, fragmentShader);
    
        //连接着色器程序
        glLinkProgram(programObj);
    
        //检查程序连接状态
        GLint linkRes;
        glGetProgramiv(programObj, GL_LINK_STATUS, &linkRes);
    
        if (!linkRes) {//连接失败
            //获取日志长度
            GLint infoLen;
            glGetProgramiv(programObj, GL_INFO_LOG_LENGTH, &infoLen);
            if (infoLen > 1) {
                //获取并输出日志
                char *infoLog = static_cast<char *>(malloc(sizeof(char) * infoLen));
                glGetProgramInfoLog(programObj, infoLen, nullptr, infoLog);
                LOGE("Error link program : %s", infoLog);
                free(infoLog);
            }
            //删除着色器程序
            glDeleteProgram(programObj);
            return 0;
        }
        return programObj;
    }
    复制代码
  • Java_com_lxk_hellogles3_GLES3Render_surfaceChanged中编译连接着色器程序:spa

    /**
     * 着色器程序
     */
    GLuint program;
    
    extern "C"
    JNIEXPORT void JNICALL
    Java_com_lxk_hellogles3_GLES3Render_surfaceChanged(JNIEnv *env, jobject thiz, jint w, jint h) {
        printGLString("Version", GL_VERSION);
        printGLString("Vendor", GL_VENDOR);
        printGLString("Renderer", GL_RENDERER);
        printGLString("Extension", GL_EXTENSIONS);
    
        LOGD("surfaceChange(%d,%d)", w, h);
    
        //编译着色器源码
        GLuint vertexShader = compileShader(GL_VERTEX_SHADER, gl_vertexShader_source);
        GLuint fragmentShader = compileShader(GL_FRAGMENT_SHADER, gl_fragmentShader_source);
        //连接着色器程序
        program = linkProgram(vertexShader, fragmentShader);
    
        if (!program) {
            LOGE("linkProgram error");
            return;
        }
    
        //设置程序窗口
        glViewport(0, 0, w, h);
    }
    复制代码
  • 设置三角形的顶点坐标数组 :

    /**
     * 顶点坐标
     */
    const GLfloat vVertex[] = {
            0.0f, 0.5f, 0.0f,
            -0.5f, -0.5f, 0.0f,
            0.5f, -0.5f, 0.0f
    };
    复制代码
  • 设置 RGB颜色值:

    static float r;
    static float g;
    static float b;
    
    /**
     * 修改背景颜色
     */
    void changeBg() {
        r += 0.01f;
        if (r > 1.0f) {
            g += 0.01f;
            if (g > 1.0f) {
                b += 0.01f;
                if (b > 1.0f) {
                    r = 0.01f;
                    g = 0.01f;
                    b = 0.01f;
                }
            }
        }
    }
    复制代码
  • Java_com_lxk_hellogles3_GLES3Render_drawFrame中绘制三角形以及改变背景色:

    /**
     * 顶点属性索引
     */
    GLuint vertexIndex = 0;
    
    extern "C"
    JNIEXPORT void JNICALL
    Java_com_lxk_hellogles3_GLES3Render_drawFrame(JNIEnv *env, jobject thiz) {
        //改变颜色值
        changeBg();
    
        glClearColor(r, g, b, 1.0f);
        //清空颜色缓冲区
        glClear(GL_COLOR_BUFFER_BIT);
    
        //设置为活动程序
        glUseProgram(program);
    
        //加载顶点坐标
        glVertexAttribPointer(vertexIndex, 3, GL_FLOAT, GL_FALSE, 0, vVertex);   
        //启用通用顶点属性数组
        glEnableVertexAttribArray(vertexIndex);
        //绘制三角形
        glDrawArrays(GL_TRIANGLES, 0, 3);
        //禁用通用顶点属性数组
        glDisableVertexAttribArray(vertexIndex);
    }
    复制代码

运行程序

效果图以下:

效果图


相关资源连接

若是以为不错的话,请帮忙点个赞呗。

以上


扫描下面的二维码,关注个人公众号 Android1024, 点关注,不迷路。

Android1024
相关文章
相关标签/搜索