Android Opengl 学习笔记 02——EGL环境

一、EGL创建流程(封装到一个c++类中,如 SamEglHelper.cpp):

class SamEglHelper    {

    SamEglHelper::SamEglHelper() {
       EGLDisplay mEGLDisplay=EGL_NO_DISPLAY;
       EGLSurface mEGLSurface=EGL_NO_SURFACE;
       EGLConfig  mEGLConfig=NULL;
       EGLContext mEGLContext=EGL_NO_CONTEXT;
    }

    SamEglHelper::~SamEglHelper() {

    }


    int SamEglHelper::initEgl(EGLNativeWindowType window) {

        //1、得到默认的显示设备(窗口)
        mEGLDisplay= eglGetDisplay(EGL_DEFAULT_DISPLAY);
        if(mEGLDisplay==EGL_NO_DISPLAY){
            LOGE("eglGetDisplay is error!");
            return -1;
        }

        //2、初始化默认显示设备
        EGLint version[2];
        if(!eglInitialize(mEGLDisplay,&version[0],&version[1]))
        {
            LOGE("eglInitialize is error!");
            return -1;
        }

        //3、设置显示设备的属性
        const EGLint attribs[] = {
            EGL_RED_SIZE, 8,
            EGL_GREEN_SIZE, 8,
            EGL_BLUE_SIZE, 8,
            EGL_ALPHA_SIZE, 8,
            EGL_DEPTH_SIZE, 8,
            EGL_STENCIL_SIZE, 8,
            EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
            EGL_NONE
        };

        EGLint num_config;
        if(!eglChooseConfig(mEGLDisplay, attribs, NULL, 1, &num_config))
        {
            LOGE("eglChooseConfig  error 1");
            return -1;
        }

        //4、从系统中获取对应属性的配置
        if(!eglChooseConfig(mEGLDisplay, attribs, &mEGLConfig, num_config, &num_config))
        {
            LOGE("eglChooseConfig  error 2");
            return -1;
        }

        //5、创建EglContext
        int attrib_list[] = {
            EGL_CONTEXT_CLIENT_VERSION, 2,
            EGL_NONE
        };

        mEGLContext = eglCreateContext(mEGLDisplay, mEGLConfig, EGL_NO_CONTEXT, attrib_list);

        if(mEGLContext == EGL_NO_CONTEXT)
        {
            LOGE("eglCreateContext  error");
            return -1;
        }

        //6、创建渲染的surface
        mEGLSurface = eglCreateWindowSurface(mEGLDisplay, mEGLConfig, window, NULL);
        if(mEGLSurface == EGL_NO_SURFACE)
        {
            LOGE("eglCreateWindowSurface  error");
            return -1;
        }

        //7、绑定EglContext和Surface到显示设备中
        if(!eglMakeCurrent(mEGLDisplay, mEGLSurface, mEGLSurface, mEGLContext))
        {
            LOGE("eglMakeCurrent  error");
            return -1;
        }

        LOGD("egl init success! ");
        return 0;
    }

    //8、eglSwapBuffers 刷新数据,显示渲染场景
    int SamEglHelper::swapBuffers() {
        if(mEGLDisplay != EGL_NO_DISPLAY && mEGLSurface != EGL_NO_SURFACE)
        {
            if(eglSwapBuffers(mEGLDisplay, mEGLSurface))
            {
                return 0;
            }
        }
        return -1;
    }

    void SamEglHelper::destoryEgl() {
        if(mEGLDisplay != EGL_NO_DISPLAY)
        {
            eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
        }
        if(mEGLSurface != EGL_NO_DISPLAY && mEGLSurface != EGL_NO_SURFACE)
        {
            eglDestroySurface(mEGLDisplay, mEGLSurface);
            mEGLSurface = EGL_NO_SURFACE;
        }
        if(mEGLDisplay != EGL_NO_DISPLAY && mEGLContext != EGL_NO_CONTEXT){
            eglDestroyContext(mEGLDisplay, mEGLContext);
            mEGLContext = EGL_NO_CONTEXT;
        }
        if(mEGLDisplay != EGL_NO_DISPLAY)
        {
            eglTerminate(mEGLDisplay);
            mEGLDisplay = EGL_NO_DISPLAY;
        }
    }
}

二、自定义SurfaceView并测试EGL环境

1、在java层定义NativeOpengl类来调用Native层的代码,并将java层的Surface传给Native层:

public class NativeOpengl {
    static {
        System.loadLibrary("native-lib");//加载native库
    }

    public native void surfaceCreate(Surface surface);//定义native层方法 对EGL环境进行测试

}

2、在Java层自定义SurfaceView:

public class SamSurfaceView extends SurfaceView implements SurfaceHolder.Callback{

    //初始化 NativeOpengl 的实例对象
    private NativeOpengl nativeOpengl;
    public void setNativeOpengl(NativeOpengl nativeOpengl) {
        this.nativeOpengl = nativeOpengl;
    }


    //继承SurfaceView
    public SamSurfaceView(Context context){
        this(context,null);
    }

    public SamSurfaceView(Context context,AttributeSet attrs){
        this(context, attrs, 0);
    }

    public SamSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        getHolder().addCallback(this);
    }


    //实现SurfaceHoler的Callback接口
    @Override
    public void surfaceCreated(SurfaceHolder surfaceHolder) {
       if(nativeOpengl!=null){
           //向NativeOpengl的surfaceCreate方法传参Surface类型,该参数可在Native层转换为EGLNativeWindowType类型
           nativeOpengl.surfaceCreate(surfaceHolder.getSurface());
       }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {

    }
}

3、在Java层的MainActivity的布局中引入自定义SurfaceView,并在代码中初始化nativeOpengl:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

   <com.sam.opengl.SamSurfaceView
       android:id="@+id/id_samSurfaceView"
       android:layout_width="match_parent"
       android:layout_height="match_parent"/>

</RelativeLayout>
public class MainActivity extends AppCompatActivity {
    private SamSurfaceView samSurfaceView;
    private NativeOpengl nativeOpengl;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        samSurfaceView=findViewById(R.id.id_samSurfaceView);
        nativeOpengl=new NativeOpengl();
        samSurfaceView.setNativeOpengl(nativeOpengl);
    }
}

4、在native层对前面封装的SamEglHelper类进行测试:

#include <jni.h>
#include <string>

#include "egl/SamEglHelper.h"
#include "android/native_window.h"
#include "android/native_window_jni.h"
#include "GLES2/gl2.h"

SamEglHelper* samEglHelper=NULL;
ANativeWindow *nativeWindow = NULL;


extern "C"
JNIEXPORT void JNICALL
包名_NativeOpengl_surfaceCreate(JNIEnv *env, jobject thiz, jobject surface) {

    //将java层传递过来的surface转化为native层的ANativeWindowType
    nativeWindow = ANativeWindow_fromSurface(env, surface);

    samEglHelper=new SamEglHelper();//初始化实例对象
    samEglHelper->initEgl(nativeWindow);//开始EGL环境的创建

    //在EGL线程中创建surface并写入buffer
    glViewport(0, 0, 720, 1280);
    glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    //由于EGL线程运行在UI线程中,所以EGL线程中不能有耗时操作,需要单独创建EGL工作线程,
    //此处只是测试封装的EGL创建类,方便起见没有创建EGL单独的工作线程.

    //刷新buffer显示surface
    samEglHelper->swapBuffers();

}

三、EGL线程-创建

1、创建egl线程类(SamEglThread.cpp):

class SamEglThread{
    SamEglThread::SamEglThread() {

        pthread_t eglThread = -1;
        ANativeWindow *nativeWindow = NULL;

        bool isCreate = false;
        bool isChange = false;
        bool isExit = false;
        bool isStart = false;

        int surfaceWidth = 0;
        int surfaceHeight = 0;
    }

    SamEglThread::~SamEglThread() {

    }

    //线程回调方法,并传参void* context
    void * eglThreadImpl(void *context)
    {
        //将当前线程context转化为SamEglThread实例对象指针
        SamEglThread *samEglThread = static_cast<SamEglThread *>(context);

        if(samEglThread != NULL)
        {
            SamEglHelper* samEglHelper=new SamEglHelper();//初始化EGL实例对象
            samEglHelper->initEgl(samEglThread->nativeWindow);//开始EGL环境的创建
            samEglThread->isExit = false;

            while(true)
            {
                if(samEglThread->isCreate)
                {
                    LOGD("eglthread call surfaceCreate");
                    samEglThread->isCreate = false;
                }

                if(samEglThread->isChange)
                {
                    LOGD("eglthread call surfaceChange");
                    samEglThread->isChange = false;
                    glViewport(0, 0, 720, 1280);
                    samEglThread->isStart = true;
                }

                //
                LOGD("draw");
                if(samEglThread->isStart)
                {
                    glClearColor(0.0f, 1.0f, 1.0f, 1.0f);
                    glClear(GL_COLOR_BUFFER_BIT);
                    samEglHelper->swapBuffers();
                }

                usleep(1000000 / 60);//60FPS

                if(samEglThread->isExit)
                {
                    break;
                }
            }
        }

    //  pthread_exit(&SamEglThread->eglThread);
        return 0;
    }

    void SamEglThread::onSurfaceCreate(EGLNativeWindowType window) {
        if(eglThread == -1)
        {
            isCreate = true;
            nativeWindow = window;
            
            //创建egl线程,并在线程中回调eglThreadImpl方法
            pthread_create(&eglThread, NULL, eglThreadImpl, this);
        }
    }

    void SamEglThread::onSurfaceChange(int width, int height) {
        isChange = true;
        surfaceWidth = width;
        surfaceHeight = height;
    }
}

2、在自定义NativeOpengl.java中添加surfaceChange(int width,int height)方法:

public class NativeOpengl {
    static {
        System.loadLibrary("native-lib");//加载native库
    }

    //定义native层方法 对EGL环境进行测试
    public native void surfaceCreate(Surface surface);

    //向native层传递surface的width,height
    public native void surfaceChange(int width, int height);

}

3、在SamSurfaceView.java中实现surfaceChanged回调方法:

public class SamSurfaceView extends SurfaceView implements SurfaceHolder.Callback{

    //初始化 NativeOpengl 的实例对象
    private NativeOpengl nativeOpengl;
    public void setNativeOpengl(NativeOpengl nativeOpengl) {
        this.nativeOpengl = nativeOpengl;
    }


    //继承SurfaceView
    public SamSurfaceView(Context context){
        this(context,null);
    }

    public SamSurfaceView(Context context,AttributeSet attrs){
        this(context, attrs, 0);
    }

    public SamSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        getHolder().addCallback(this);
    }


    //实现SurfaceHoler的Callback接口,被android系统回调
    @Override
    public void surfaceCreated(SurfaceHolder surfaceHolder) {
       if(nativeOpengl!=null){
           //向NativeOpengl的surfaceCreate方法传参Surface类型,该参数可在Native层转换为EGLNativeWindowType类型
           nativeOpengl.surfaceCreate(surfaceHolder.getSurface());
       }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        if(nativeOpengl!=null){
            nativeOpengl.surfaceChange(width, height);
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {

    }
}

4、实现native层方法 surfaceCreate与surfaceChange:

#include <jni.h>
#include <string>

#include "egl/SamEglThread.h"
#include "android/native_window.h"
#include "android/native_window_jni.h"

SamEglThread *samEglThread=NULL;
ANativeWindow *nativeWindow = NULL;

extern "C"
JNIEXPORT void JNICALL
Java_包名_NativeOpengl_surfaceCreate(JNIEnv *env, jobject thiz, jobject surface) {

    //将java层传递过来的surface转化为native层的ANativeWindowType
    nativeWindow = ANativeWindow_fromSurface(env, surface);

    samEglThread=new SamEglThread();//创建SamEglThread类的实例对象
    samEglThread->onSurfaceCreate(nativeWindow);//开启egl线程
}

extern "C"
JNIEXPORT void JNICALL
Java_包名_NativeOpengl_surfaceChange(JNIEnv *env, jobject thiz, jint width, jint height) {
    // TODO: implement surfaceChange()

    if(samEglThread!=NULL){
        samEglThread->onSurfaceChange(width,height);
    }
}

四、EGL线程-绘制方法回调

1、修改SamEglThread.cpp类(将线程内绘制改为线程外回调函数绘制)

class SamEglThread {

public:
    pthread_t eglThread = -1;
    ANativeWindow *nativeWindow = NULL;

    bool isCreate = false;
    bool isChange = false;
    bool isExit = false;
    bool isStart = false;

    //定义Surface的width和height
    int surfaceWidth = 0;
    int surfaceHeight = 0;

    //定义EGL线程回调函数
    typedef void(*OnCreate)(void *);
    OnCreate onCreate;
    void *onCreteCtx;

    typedef void(*OnChange)(int width, int height, void *);
    OnChange onChange;
    void *onChangeCtx;

    typedef void(*OnDraw)(void *);
    OnDraw onDraw;
    void *onDrawCtx;

public:
    SamEglThread::SamEglThread() {

    }

    SamEglThread::~SamEglThread() {

    }

    //线程回调方法,并传参void* context
    void * eglThreadImpl(void *context)
    {
        //将当前线程context转化为SamEglThread实例对象指针
        SamEglThread *samEglThread = static_cast<SamEglThread *>(context);

        if(samEglThread != NULL)
        {
            SamEglHelper* samEglHelper=new SamEglHelper();//初始化EGL实例对象
            samEglHelper->initEgl(samEglThread->nativeWindow);//开始EGL环境的创建
            samEglThread->isExit = false;

            while(true)
            {
                if(samEglThread->isCreate)
                {
                    LOGD("eglthread call surfaceCreate");
                    samEglThread->isCreate = false;
                    //回调onCreate进行初始化
                    samEglThread->onCreate(samEglThread->onCreteCtx);
                }

                if(samEglThread->isChange)
                {
                    LOGD("eglthread call surfaceChange");
                    samEglThread->isChange = false;
                    //回调onChange进行surface大小设定
                    samEglThread->onChange(samEglThread->surfaceWidth,samEglThread->surfaceHeight,samEglThread->onChangeCtx);
                    samEglThread->isStart = true;
                }

                //
                LOGD("draw");
                if(samEglThread->isStart)
                {
                    //回调onDraw进行绘制
                    samEglThread->onDraw(samEglThread->onDrawCtx);
                    samEglHelper->swapBuffers();
                }

                usleep(1000000 / 60);//60FPS

                if(samEglThread->isExit)
                {
                    break;
                }
            }
        }

        //    pthread_exit(&SamEglThread->eglThread);
        return 0;
    }

    void SamEglThread::onSurfaceCreate(EGLNativeWindowType window) {
        if(eglThread == -1)
        {
            isCreate = true;
            nativeWindow = window;

            //创建egl线程,并在线程中回调eglThreadImpl方法
            pthread_create(&eglThread, NULL, eglThreadImpl, this);
        }
    }

    void SamEglThread::onSurfaceChange(int width, int height) {
        isChange = true;
        surfaceWidth = width;
        surfaceHeight = height;
    }

    void SamEglThread::callBackOnCreate(SamEglThread::OnCreate onCreate, void *ctx) {
        this->onCreate=onCreate;
        this->onCreteCtx=ctx;
    }

    void SamEglThread::callBackOnChange(SamEglThread::OnChange onChange, void *ctx) {
        this->onChange=onChange;
        this->onChangeCtx=ctx;
    }

    void SamEglThread::callBackOnDraw(SamEglThread::OnDraw onDraw, void *ctx) {
        this->onDraw=onDraw;
        this->onDrawCtx=ctx;
    }

}

2、修改native-lib.cpp这个native库文件

#include <jni.h>
#include <string>

#include "egl/SamEglThread.h"
#include "android/native_window.h"
#include "android/native_window_jni.h"

SamEglThread *samEglThread=NULL;
ANativeWindow *nativeWindow = NULL;

//实现EGL线程回调函数的实现
void callback_SurfaceCrete(void *ctx)
{
    LOGD("callback_SurfaceCrete");
    SamEglThread *samEglThread = static_cast<SamEglThread *>(ctx);
}

void callback_SurfacChange(int w, int h, void *ctx)
{
    LOGD("callback_SurfacChange");
    SamEglThread *samEglThread = static_cast<SamEglThread *>(ctx);
    glViewport(0, 0, w, h);
}

void callback_SurfaceDraw(void *ctx)
{
    LOGD("callback_SurfaceDraw");
    SamEglThread *samEglThread = static_cast<SamEglThread *>(ctx);
    glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
}

extern "C"
JNIEXPORT void JNICALL
Java_com_sam_opengl_NativeOpengl_surfaceCreate(JNIEnv *env, jobject thiz, jobject surface) {

    //将java层传递过来的surface转化为native层的ANativeWindowType
    nativeWindow = ANativeWindow_fromSurface(env, surface);

    samEglThread=new SamEglThread();//创建SamEglThread类的实例对象

    //通过函数回调来进行绘制
    samEglThread->callBackOnCreate(callback_SurfaceCrete,samEglThread);
    samEglThread->callBackOnChange(callback_SurfacChange,samEglThread);
    samEglThread->callBackOnDraw(callback_SurfaceDraw,samEglThread);

    samEglThread->onSurfaceCreate(nativeWindow);//开启egl线程进行绘制
}

extern "C"
JNIEXPORT void JNICALL
Java_com_sam_opengl_NativeOpengl_surfaceChange(JNIEnv *env, jobject thiz, jint width, jint height) {

    if(samEglThread!=NULL){
        samEglThread->onSurfaceChange(width,height);//设定SurfaceView的大小
    }

}

五、EGL线程-手动、自动渲染切换

1、提取SamEglThread.h头文件

#ifndef OPENGLDEMO_SAMEGLTHREAD_H
#define OPENGLDEMO_SAMEGLTHREAD_H


#include <EGL/eglplatform.h>
#include <sys/types.h>
#include "SamEglHelper.h"
#include <pthread.h>
#include <GLES2/gl2.h>
#include <unistd.h>

//定义渲染模式 1-AUTO 2-HANDLE
#define OPENGL_RENDER_AUTO 1
#define OPENGL_RENDER_HANDLE 2

class SamEglThread {

public:
    pthread_t eglThread = -1;
    ANativeWindow *nativeWindow = NULL;

    bool isCreate = false;
    bool isChange = false;
    bool isExit = false;
    bool isStart = false;

    //定义Surface的width和height
    int surfaceWidth = 0;
    int surfaceHeight = 0;

    //定义EGL线程回调函数
    typedef void(*OnCreate)(void *);
    OnCreate onCreate;
    void *onCreteCtx;

    typedef void(*OnChange)(int width, int height, void *);
    OnChange onChange;
    void *onChangeCtx;

    typedef void(*OnDraw)(void *);
    OnDraw onDraw;
    void *onDrawCtx;


    int renderType = OPENGL_RENDER_AUTO;    //定义渲染模式
    pthread_mutex_t pthread_mutex;          //定义线程锁
    pthread_cond_t pthread_cond;            //定义线程条件

public:
    SamEglThread();
    ~SamEglThread();

    void onSurfaceCreate(EGLNativeWindowType window);

    void onSurfaceChange(int width, int height);

    //初始化EGL线程回调函数
    void callBackOnCreate(OnCreate onCreate, void *ctx);

    void callBackOnChange(OnChange onChange, void *ctx);

    void callBackOnDraw(OnDraw onDraw, void *ctx);

    //设置渲染模式
    void setRenderType(int renderType);

    //唤醒线程解除线程锁阻塞
    void notifyRender();
};


#endif //OPENGLDEMO_SAMEGLTHREAD_H

2、在SamEglThread.cpp中的实现:

#include "SamEglThread.h"


SamEglThread::SamEglThread() {

    //初始化mutex,cond
    pthread_mutex_destroy(&pthread_mutex);
    pthread_cond_destroy(&pthread_cond);

}

SamEglThread::~SamEglThread() {
    //销毁mutex,cond
    pthread_mutex_destroy(&pthread_mutex);
    pthread_cond_destroy(&pthread_cond);
}

//线程回调方法,并传参void* context
void * eglThreadImpl(void *context)
{
    SamEglThread *samEglThread = static_cast<SamEglThread *>(context);//将当前线程context转化为SamEglThread实例对象指针

    if(samEglThread != NULL)
    {
        SamEglHelper* samEglHelper=new SamEglHelper();//初始化EGL实例对象
        samEglHelper->initEgl(samEglThread->nativeWindow);//开始EGL环境的创建
        samEglThread->isExit = false;

        while(true)
        {
            if(samEglThread->isCreate)
            {
                LOGD("eglthread call surfaceCreate");
                samEglThread->isCreate = false;
                //回调onCreate进行初始化
                samEglThread->onCreate(samEglThread->onCreteCtx);
            }

            if(samEglThread->isChange)
            {
                LOGD("eglthread call surfaceChange");
                samEglThread->isChange = false;
                //回调onChange进行surface大小设定
                samEglThread->onChange(samEglThread->surfaceWidth,samEglThread->surfaceHeight,samEglThread->onChangeCtx);
                samEglThread->isStart = true;
            }

            //
            LOGD("draw");
            if(samEglThread->isStart)
            {
                //回调onDraw进行绘制
                samEglThread->onDraw(samEglThread->onDrawCtx);
                samEglHelper->swapBuffers();
            }

            if(samEglThread->renderType==OPENGL_RENDER_AUTO){

                //自动渲染60fps
                usleep(1000000 / 60);

            }else{

                //手动渲染
                pthread_mutex_lock(&samEglThread->pthread_mutex);//加线程锁
                pthread_cond_wait(&samEglThread->pthread_cond, &samEglThread->pthread_mutex);//阻塞线程
                pthread_mutex_unlock(&samEglThread->pthread_mutex);//解锁

            }


            if(samEglThread->isExit)
            {
                break;
            }
        }
    }

//    pthread_exit(&SamEglThread->eglThread);
    return 0;
}

void SamEglThread::onSurfaceCreate(EGLNativeWindowType window) {
    if(eglThread == -1)
    {
        isCreate = true;
        nativeWindow = window;
        pthread_create(&eglThread, NULL, eglThreadImpl, this);//创建egl线程,并在线程中回调eglThreadImpl方法
    }
}

void SamEglThread::onSurfaceChange(int width, int height) {
    isChange = true;
    surfaceWidth = width;
    surfaceHeight = height;
    notifyRender();//刷新线程,传递过来的width,height才能赋值到surfaceWidth,surfaceHeight上
}

void SamEglThread::callBackOnCreate(SamEglThread::OnCreate onCreate, void *ctx) {
    this->onCreate=onCreate;
    this->onCreteCtx=ctx;
}

void SamEglThread::callBackOnChange(SamEglThread::OnChange onChange, void *ctx) {
    this->onChange=onChange;
    this->onChangeCtx=ctx;
}

void SamEglThread::callBackOnDraw(SamEglThread::OnDraw onDraw, void *ctx) {
    this->onDraw=onDraw;
    this->onDrawCtx=ctx;
}

void SamEglThread::setRenderType(int renderType) {
    this->renderType = renderType;
}

void SamEglThread::notifyRender() {
    pthread_mutex_lock(&pthread_mutex);//为保持线程同步加锁
    pthread_cond_signal(&pthread_cond);//发送信号
    pthread_mutex_unlock(&pthread_mutex);//解锁
}

3、在native-lib.cpp中对手动、自动两种渲染模式进行测试:

#include <jni.h>
#include <string>

#include "egl/SamEglThread.h"
#include "android/native_window.h"
#include "android/native_window_jni.h"

SamEglThread *samEglThread=NULL;
ANativeWindow *nativeWindow = NULL;

//实现EGL线程回调函数的实现
void callback_SurfaceCrete(void *ctx)
{
    LOGD("callback_SurfaceCrete");
    SamEglThread *samEglThread = static_cast<SamEglThread *>(ctx);
}

void callback_SurfacChange(int w, int h, void *ctx)
{
    LOGD("callback_SurfacChange");
    SamEglThread *samEglThread = static_cast<SamEglThread *>(ctx);
    glViewport(0, 0, w, h);
}

void callback_SurfaceDraw(void *ctx)
{
    LOGD("callback_SurfaceDraw");
    SamEglThread *samEglThread = static_cast<SamEglThread *>(ctx);
    glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
}

extern "C"
JNIEXPORT void JNICALL
Java_com_sam_opengl_NativeOpengl_surfaceCreate(JNIEnv *env, jobject thiz, jobject surface) {

    //将java层传递过来的surface转化为native层的ANativeWindowType
    nativeWindow = ANativeWindow_fromSurface(env, surface);

    samEglThread=new SamEglThread();//创建SamEglThread类的实例对象

    samEglThread->setRenderType(OPENGL_RENDER_HANDLE);//设置渲染模式为手动

//    samEglThread->setRenderType(OPENGL_RENDER_AUTO);//设置渲染模式为自动

    //通过函数回调来进行绘制
    samEglThread->callBackOnCreate(callback_SurfaceCrete,samEglThread);
    samEglThread->callBackOnChange(callback_SurfacChange,samEglThread);
    samEglThread->callBackOnDraw(callback_SurfaceDraw,samEglThread);

    samEglThread->onSurfaceCreate(nativeWindow);//开启egl线程进行绘制
}

extern "C"
JNIEXPORT void JNICALL
Java_com_sam_opengl_NativeOpengl_surfaceChange(JNIEnv *env, jobject thiz, jint width, jint height) {

    if(samEglThread!=NULL){

        samEglThread->onSurfaceChange(width,height);//设定SurfaceView的大小

        usleep(1000000);//休眠1秒后
        samEglThread->notifyRender();//唤醒线程继续渲染
    }

}
QKB
发布了5 篇原创文章 · 获赞 4 · 访问量 2183

猜你喜欢

转载自blog.csdn.net/caphpca/article/details/103943035