-
初始化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
相关推荐
叶羽西6 分钟前
Android15 Media框架JNI Interface调试spencer_tseng16 分钟前
anti-screenshot (Android + iOS)程序员Android25 分钟前
Android 相机MFNR 拍照trace 分析2501_9159184126 分钟前
基于Mach-O文件的动态库与静态库归属方案及API扫描实践踏雪羽翼26 分钟前
android 实现google 订阅支付2501_9151063229 分钟前
iOS 证书无法跨电脑使用?签名迁移方法一文讲透Kapaseker33 分钟前
Window 内外藏机巧 旧岗新页见真章谪星·阿凯42 分钟前
从XXE遗留疑问到Upload-Labs全通关:文件上传漏洞的溯源与实战突破星轨初途42 分钟前
C++ 类和对象(下):初始化列表、static 成员与编译器优化深度剖析恋猫de小郭1 小时前
Flutter 的 build_runner 已经今非昔比,看看 build_runner 2.13 有什么特别?