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
相關文章
相關標籤/搜索