android搭建opengles 的egl环境之前使用java已经写过,但是一般实际开发opengles的相关代码都在native层,因为native的话效率会比java高很多,步骤都是一致的,只是换一种语言写而已。之前使用java写的opengles egl环境搭建点击下面链接: https://www.jianshu.com/p/ce3496ab9e02
本文demo下载地址: https://github.com/ChinaZeng/NativeEglDemo
步骤都是一样的:
1、得到Egl实例 2、得到默认的显示设备(就是窗口) 3、初始化默认显示设备 4、设置显示设备的属性 5、从系统中获取对应属性的配置 6、创建EglContext 7、创建渲染的Surface 8、绑定EglContext和Surface到显示设备中 9、刷新数据,显示渲染场景
代码目录:
书写EglThread,顾名思义,这个类主要负责开启一个线程然后根据外部的生命周期调用EglHelper完成egl的环境搭建,并且和外部交互。
EglThread::EglThread() { pthread_mutex_init(&pthread_mutex, NULL); pthread_cond_init(&pthread_cond, NULL); } EglThread::~EglThread() { pthread_mutex_destroy(&pthread_mutex); pthread_cond_destroy(&pthread_cond); } void *eglThreadImpl(void *context) { EglThread *eglThread = static_cast<EglThread *>(context); if (!eglThread) { LOGE("eglThreadImpl eglThread is null"); return 0; } EglHelper *eglHelper = new EglHelper(); if (eglHelper->initEgl(eglThread->mANativeWindow) != 0) { LOGE("eglHelper initEgl error"); return 0; } eglThread->isExit = false; while (!eglThread->isExit) { if (eglThread->isCreate) { eglThread->isCreate = false; eglThread->onCreate(); } if (eglThread->isChange) { eglThread->isChange = false; eglThread->isStart = true; eglThread->onChange(eglThread->surfaceWidth, eglThread->surfaceHeight); } if (eglThread->isStart) { eglThread->onDraw(); //切换缓冲区,显示 eglHelper->swapBuffers(); if (eglThread->mRenderType == RENDER_MODULE_AUTO) { usleep(1000000 / 60); } else { pthread_mutex_lock(&eglThread->pthread_mutex); pthread_cond_wait(&eglThread->pthread_cond, &eglThread->pthread_mutex); pthread_mutex_unlock(&eglThread->pthread_mutex); } } } eglHelper->destroyEgl(); delete eglHelper; eglHelper = NULL; //return 0表示线程结束 return 0; } void EglThread::onSurfaceCreate(EGLNativeWindowType window) { if (mEglThread == -1) { isCreate = true; mANativeWindow = window; pthread_create(&mEglThread, NULL, eglThreadImpl, this); } } void EglThread::onSurfaceChange(int width, int height) { if (mEglThread != -1) { surfaceWidth = width; surfaceHeight = height; isChange = true; notifyRender(); } } void EglThread::setRenderModule(int renderType) { mRenderType = renderType; notifyRender(); } void EglThread::notifyRender() { pthread_mutex_lock(&pthread_mutex); pthread_cond_signal(&pthread_cond); pthread_mutex_unlock(&pthread_mutex); } void EglThread::callBackOnCreate(EglThread::OnCreate onCreate) { this->onCreate = onCreate; } void EglThread::callBackOnChange(EglThread::OnChange onChange) { this->onChange = onChange; } void EglThread::callBackOnDraw(EglThread::OnDraw onDraw) { this->onDraw = onDraw; }
NativeGLSurfaceView.java
public class NativeGLSurfaceView extends SurfaceView implements SurfaceHolder.Callback { private NationOpenGL mNationOpenGL; public NativeGLSurfaceView(Context context) { this(context, null); } public NativeGLSurfaceView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public NativeGLSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mNationOpenGL = new NationOpenGL(); getHolder().addCallback(this); } @Override public void surfaceCreated(SurfaceHolder holder) { mNationOpenGL.nativeSurfaceCreate(holder.getSurface()); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { mNationOpenGL.nativeSurfaceChanged(width, height); } @Override public void surfaceDestroyed(SurfaceHolder holder) { mNationOpenGL.nativeSurfaceDestroyed(); } }
native-lib.cpp
EglThread *eglThread = NULL; void callBackOnCreate() { LOGE("callBackOnCreate"); } void callBackOnChange(int width, int height) { glViewport(0, 0, width, height); LOGE("callBackOnChange"); } void callBackOnDraw() { glClearColor(0.0f, 1.0f, 1.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); LOGE("callBackOnDraw"); } extern "C" JNIEXPORT void JNICALL Java_com_zzw_nativeopnegldemo_opengl_NationOpenGL_nativeSurfaceCreate(JNIEnv *env, jobject instance, jobject surface) { eglThread = new EglThread(); eglThread->callBackOnCreate(callBackOnCreate); eglThread->callBackOnChange(callBackOnChange); eglThread->callBackOnDraw(callBackOnDraw); eglThread->setRenderModule(RENDER_MODULE_MANUAL); ANativeWindow *nativeWindow = ANativeWindow_fromSurface(env, surface); eglThread->onSurfaceCreate(nativeWindow); } extern "C" JNIEXPORT void JNICALL Java_com_zzw_nativeopnegldemo_opengl_NationOpenGL_nativeSurfaceChanged(JNIEnv *env, jobject instance, jint width, jint height) { if (eglThread) { eglThread->onSurfaceChange(width, height); } } extern "C" JNIEXPORT void JNICALL Java_com_zzw_nativeopnegldemo_opengl_NationOpenGL_nativeSurfaceDestroyed(JNIEnv *env, jobject instance) { if (eglThread) { eglThread->isExit = true; delete (eglThread); eglThread = NULL; } }
本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。
我来说两句