-
初始化EGL环境
kotlin// 创建带 EGL 环境的 GL 线程 class GLThread : HandlerThread("GLThread") { private lateinit var eglDisplay: EGLDisplay private lateinit var eglContext: EGLContext private lateinit var handler: Handler override fun onLooperPrepared() { super.onLooperPrepared() initEGL() handler = Handler(looper) } private fun initEGL() { // 1. 获取 EGL Display eglDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY) // 2. 初始化 EGL val version = IntArray(2) EGL14.eglInitialize(eglDisplay, version, 0, version, 1) // 3. 选择配置 val configs = arrayOfNulls<EGLConfig>(1) val configAttribs = intArrayOf( EGL14.EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT, EGL14.EGL_RED_SIZE, 8, EGL14.EGL_GREEN_SIZE, 8, EGL14.EGL_BLUE_SIZE, 8, EGL14.EGL_NONE ) EGL14.eglChooseConfig(eglDisplay, configAttribs, 0, configs, 0, 1, intArrayOf(0), 0) // 4. 创建 EGL Context val contextAttribs = intArrayOf( EGL14.EGL_CONTEXT_CLIENT_VERSION, 2, EGL14.EGL_NONE ) eglContext = EGL14.eglCreateContext( eglDisplay, configs[0], EGL14.EGL_NO_CONTEXT, contextAttribs, 0 ) // 5. 创建虚拟 Surface (离屏渲染) val surfaceAttribs = intArrayOf(EGL14.EGL_WIDTH, 1, EGL14.EGL_HEIGHT, 1, EGL14.EGL_NONE) val eglSurface = EGL14.eglCreatePbufferSurface(eglDisplay, configs[0], surfaceAttribs, 0) // 6. 绑定上下文 EGL14.eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext) } fun runOnGLThread(runnable: Runnable) { handler.post { // 确保在当前线程绑定上下文 EGL14.eglMakeCurrent(eglDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, eglContext) runnable.run() } } }
-
在 GL 线程中初始化 SurfaceTexture
kotlin// 创建 GL 线程 val glThread = GLThread().apply { start() } // 等待线程准备就绪 Thread.sleep(300) // 简化的等待机制,实际应用中应使用回调 // 在 GL 线程中创建 SurfaceTexture lateinit var mSurfaceTexture: SurfaceTexture glThread.runOnGLThread { // 在有效的 GL 环境中创建纹理 val textureIds = IntArray(1) GLES30.glGenTextures(1, textureIds, 0) GLES30.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textureIds[0]) // 创建绑定到纹理的 SurfaceTexture mSurfaceTexture = SurfaceTexture(textureIds[0]).apply { setDefaultBufferSize(width, height) // 注意:监听器内部操作将在 GL 线程执行 setOnFrameAvailableListener({ surfaceTexture -> Log.i(TAG, "onFrameAvailable in GL context") try { surfaceTexture.updateTexImage() // 现在可以安全调用 // 可选:获取变换矩阵 val transformMatrix = FloatArray(16) surfaceTexture.getTransformMatrix(transformMatrix) // 处理帧数据... } catch (e: Exception) { Log.e(TAG, "Error updating texture", e) } }, null) // 不指定 Handler,使用当前线程 } }
-
在 Camera 配置中使用 Surface
kotlin// 创建 Surface 供相机使用 val mSurface = Surface(mSurfaceTexture) // 配置相机输出目标 mCaptureRequestBuild?.addTarget(mSurface) outputConfiguration.add(OutputConfiguration(mSurface))
-
注意事项
-
SurfaceTexture 的创建和销毁必须在同一个线程
-
updateTexImage() 必须在创建 SurfaceTexture 的线程调用
-
资源释放
kotlinfun release() { glThread.runOnGLThread { mSurfaceTexture.release() // 释放 EGL 资源 EGL14.eglDestroyContext(glThread.eglDisplay, glThread.eglContext) } glThread.quitSafely() }
-
Android Camera2 + OpenGL离屏渲染示例
菠萝加点糖2025-07-07 15:50
相关推荐
jyan_敬言2 小时前
【C++】string类(二)相关接口介绍及其使用程序员老刘3 小时前
Android 16开发者全解读福柯柯4 小时前
Android ContentProvider的使用不想迷路的小男孩4 小时前
Android Studio 中Palette跟Component Tree面板消失怎么恢复正常餐桌上的王子4 小时前
Android 构建可管理生命周期的应用(一)用户2018792831674 小时前
🌟 童话:四大Context徽章诞生记yzpyzp4 小时前
Android studio在点击运行按钮时执行过程中输出的compileDebugKotlin 这个任务是由gradle执行的吗aningxiaoxixi4 小时前
安卓之serviceTeleostNaCl5 小时前
Android 应用开发 | 一种限制拷贝速率解决因 IO 过高导致系统卡顿的方法