前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >NDK开发(十) :Hello OpenGLES3

NDK开发(十) :Hello OpenGLES3

作者头像
103style
发布2022-12-19 13:38:58
4040
发布2022-12-19 13:38:58
举报
文章被收录于专栏:Android开发经验分享

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

本文操作以 Android Studio 3.5 版本为例


NDK开发文章汇总


功能介绍

Demo源码链接

相关资料:OpenGL ES 3.0 相关介绍汇总


目录

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

创建及配置工程

创建一个新工程,在 Choose your project 时选择 native c++ 模板。

AndroidManifest 中添加Open GL ES版本声明:

代码语言:javascript
复制
<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 为以下内容:

代码语言:javascript
复制
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代码实现功能逻辑

导入相关头文件:

代码语言:javascript
复制
#include <jni.h>
#include <string>

#include <GLES3/gl3.h>
#include <GLES3/gl3ext.h>

#include <android/log.h>
#include "LogUtils.h"

LogUtils.h

选中 GLES3Render 中报红的 native 方法,按 alt + enter 快速创建 C 方法。

编写 顶点着色器片段着色器 源码:

代码语言:javascript
复制
/**
 * 顶点着色器源码
 */
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";

编写编译着色器源码的方法:

代码语言:javascript
复制
/**
 * 编译着色器源码
 * @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;
}

编写链接着色器程序的代码:

代码语言:javascript
复制
/**
 * 链接着色器程序
 */
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中编译链接着色器程序:

代码语言:javascript
复制
/**
 * 着色器程序
 */
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);
}

设置三角形的顶点坐标数组 :

代码语言:javascript
复制
/**
 * 顶点坐标
 */
const GLfloat vVertex[] = {
        0.0f, 0.5f, 0.0f,
        -0.5f, -0.5f, 0.0f,
        0.5f, -0.5f, 0.0f
};

设置 RGB颜色值:

代码语言:javascript
复制
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中绘制三角形以及改变背景色:

代码语言:javascript
复制
/**
 * 顶点属性索引
 */
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);
}

运行程序

效果图如下:

效果图
效果图

相关资源链接


以上

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-08-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 功能介绍
  • 目录
  • 创建及配置工程
  • 修改JNI代码实现功能逻辑
  • 运行程序
  • 相关资源链接
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档