Android OpenGL探索之纯色背景绘制

简介

本系列主要介绍OpenGL在Android平台上的应用。

绘制纯色背景

GLSurfaceView 类提供了一些辅助类来管理 EGL contexts,通过实现GLSurfaceView.Renderer接口可以实现纯色背景的绘制

1.纯JAVA方式

public class OpenGLTest1Activity extends Activity {
    private static final String TAG = "OpenGLTest1Activity";
    private GLSurfaceView mGLSurfaceView;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //新建GLSurfaceView并set到Activity的ContentView
        mGLSurfaceView = new GLSurfaceView(this);
        setContentView(mGLSurfaceView);
        //设置OpenGL版本为3.0
        mGLSurfaceView.setEGLContextClientVersion(3);
        //新建一个渲染器ColorRenderer ColorRenderer如下代码段
        GLSurfaceView.Renderer renderer = new ColorRenderer(Color.RED);
        mGLSurfaceView.setRenderer(renderer);
    }
}
复制代码

渲染器ColorRenderer

public class ColorRenderer implements GLSurfaceView.Renderer {

    private int color;

    public ColorRenderer(int color) {
        this.color = color;
    }

    @Override
    public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {
        float redF = (float) Color.red(color) / 255;
        float greenF = (float) Color.green(color) / 255;
        float blueF = (float) Color.blue(color) / 255;
        float alphaF = (float) Color.alpha(color) / 255;
        GLES30.glClearColor(redF, greenF, blueF, alphaF);
    }

    @Override
    public void onSurfaceChanged(GL10 gl10, int width, int height) {
    GLES30.glViewport(0, 0, width, height);
    }

    @Override
    public void onDrawFrame(GL10 gl10) {
    GLES30.glClear(GL10.GL_COLOR_BUFFER_BIT);
    }
}
复制代码

渲染器的都是在子线程回调的,不会影响到主线程的操作。

onSurfaceCreated:在view被创建时回调

onSurfaceChanged:在窗口变换时回调

onDrawFrame:每16ms刷新一次,与View不同GLSurfaceView属于被动刷新。接收到vsyn信号时进行刷新

其中涉及到的几个API

glClearColor(float var0, float var1, float var2, float var3);
    设置颜色缓存的清除值,可以理解为默认颜色 但是注意这个时候还并没有应用到这个颜色,只是设置了
    参数说明:前三个参数为颜色值RGB 最后一个参数是透明度A

glViewport(int var0, int var1, int var2, int var3);
    设置渲染区域 注意:OpenGL使用的窗口坐标和Android窗口中的坐标是不一样的之后文章会详细介绍
    参数说明:前两个参数是左下角的坐标值一般是 0  后两个参数分别是宽度和高度
    

glClear(int var0);
    做清除操作,可以理解为reset还原的意思
    参数说明:还原类型的标示
    GL_COLOR_BUFFER_BIT	指定当前被激活为写操作的颜色缓存
    GL_DEPTH_BUFFER_BIT	指定深度缓存
    GL_ACCUM_BUFFER_BIT	指定累加缓存
    GL_STENCIL_BUFFER_BIT	指定模板缓存
复制代码

2、C++实现

首先配置CMakeList.txt 引入GLESv3库

cmake_minimum_required(VERSION 3.4.1)

add_library( 
             native-color
             SHARED
             src/main/cpp/native-color.cpp)


target_link_libraries(
                       native-color
                        #链接GLESv3库到共享库中
                       GLESv3
                       android
                       EGL
                       log
                       m)
复制代码

编写native-color.h 头文件

//
// Created by 吴新禹 on 2019/3/10.
//
#include 


#ifndef AVDEMO_NATIVE_COLOR_H
#define AVDEMO_NATIVE_COLOR_H
#ifdef __cplusplus
extern "C" {
#endif

JNIEXPORT void JNICALL surfaceCreated(JNIEnv *, jobject, jint);

JNIEXPORT void JNICALL surfaceChanged(JNIEnv *, jobject, jint, jint);

JNIEXPORT void JNICALL onDrawFrame(JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif
复制代码

编写native-color.cpp 源文件

//
// Created by 吴新禹 on 2019/3/10.
//
#include 
#include 
#include 

#include "native_color.h"

/**
 * 动态注册
 */
JNINativeMethod methods[] = {
        {
     "surfaceCreated", "(I)V",  (void *) surfaceCreated},
        {
     "surfaceChanged", "(II)V", (void *) surfaceChanged},
        {
     "onDrawFrame",    "()V",   (void *) onDrawFrame}
};

/**
 * 动态注册
 * @param env
 * @return
 */
jint registerNativeMethod(JNIEnv *env) {
    jclass cl = env->FindClass("com/av/avdemo/opengl/NativeColorRenderer");
    if ((env->RegisterNatives(cl, methods, sizeof(methods) / sizeof(methods[0]))) < 0) {
        return -1;
    }
    return 0;
}

/**
 * 加载默认回调
 * @param vm
 * @param reserved
 * @return
 */
jint JNI_OnLoad(JavaVM *vm, void *reserved) {
    JNIEnv *env = NULL;
    if (vm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) {
        return -1;
    }
    //注册方法
    if (registerNativeMethod(env) != JNI_OK) {
        return -1;
    }
    return JNI_VERSION_1_6;
}

JNIEXPORT void JNICALL surfaceCreated(JNIEnv *env, jobject obj, jint color) {
    //分离RGBA的百分比
    GLfloat redF = ((color >> 16) & 0xFF) * 1.0f / 255;
    GLfloat greenF = ((color >> 8) & 0xFF) * 1.0f / 255;
    GLfloat blueF = (color & 0xFF) * 1.0f / 255;
    GLfloat alphaF = ((color >> 24) & 0xFF) * 1.0f / 255;
    glClearColor(redF, greenF, blueF, alphaF);
}

JNIEXPORT void JNICALL surfaceChanged(JNIEnv *env, jobject obj, jint width, jint height) {
    glViewport(0, 0, width, height);
}

JNIEXPORT void JNICALL onDrawFrame(JNIEnv *env, jobject obj) {
    //把颜色缓冲区设置为我们预设的颜色
    glClear(GL_COLOR_BUFFER_BIT);
}
复制代码

编写Native渲染器引用Native代码

public class NativeColorRenderer implements GLSurfaceView.Renderer {

    static {
        System.loadLibrary("native-color");
    }

    public native void surfaceCreated(int color);

    public native void surfaceChanged(int width, int height);

    public native void onDrawFrame();

    private int color;

    public NativeColorRenderer(int color) {
        this.color = color;
    }

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        surfaceCreated(color);
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        surfaceChanged(width, height);
    }

    @Override
    public void onDrawFrame(GL10 gl) {
        onDrawFrame();
    }
}
复制代码

最后的效果

你可能感兴趣的:(移动开发,c/c++,java)