当前位置: 首页> 汽车> 维修 > 免费开网店的平台有哪些_杭州做网站推广公司推荐_百度关键词搜索引擎_常德seo招聘

免费开网店的平台有哪些_杭州做网站推广公司推荐_百度关键词搜索引擎_常德seo招聘

时间:2025/7/11 22:52:49来源:https://blog.csdn.net/sunshine_guo/article/details/147068776 浏览次数: 0次
免费开网店的平台有哪些_杭州做网站推广公司推荐_百度关键词搜索引擎_常德seo招聘

SurfaceView + 自定义EGL实现OpenGL渲染

Android开发中,当需要灵活控制OpenGL渲染或在多个Surface间共享EGL上下文时,自定义EGL环境是必要的选择

核心实现流程

+--------------------+     +--------------------+     +--------------------+
| 1. 创建SurfaceView | --> | 2. 初始化EGL环境   | --> | 3. 渲染线程管理    |
+--------------------+     +--------------------+     +--------------------+

1. 创建SurfaceView

继承SurfaceView并实现SurfaceHolder.Callback接口,管理Surface生命周期:

class MySurfaceView(context: Context, attrs: AttributeSet) : SurfaceView(context, attrs), SurfaceHolder.Callback {init {holder.addCallback(this)}private var mEGLHelper = MyEGLHelper()private var mEGLRender = MyEGLRender(context)private var mEGLThread: MyEGLThread? = nulloverride fun surfaceCreated(holder: SurfaceHolder) {// 创建并启动渲染线程mEGLThread = MyEGLThread(holder.surface).apply {start()}}override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {mEGLThread?.changeSize(width, height)}override fun surfaceDestroyed(holder: SurfaceHolder) {mEGLThread?.release()}// 渲染线程实现inner class MyEGLThread(private val mSurface: Surface) : Thread() {private var mWidth = 0private var mHeight = 0@Volatileprivate var mRunning = true@Volatileprivate var mSizeChanged = falseoverride fun run() {super.run()try {mEGLHelper.initEGL(mSurface)mEGLRender.onSurfaceCreated()while (mRunning) {// 宽高变化,回调渲染器的onSurfaceChanged方法if (mSizeChanged) {mEGLRender.onSurfaceChanged(mWidth, mHeight)mSizeChanged = false}// 渲染一帧, 回调渲染器的onDrawFrame方法mEGLRender.onDrawFrame()mEGLHelper.swapBuffer()}} catch (e: Exception) {Log.e("yang", "EGL thread error ${e.message}")}}fun changeSize(width: Int, height: Int) {mWidth = widthmHeight = heightmSizeChanged = true}fun release() {mRunning = falsemEGLRender.onSurfaceDestroyed()mEGLHelper.releaseEGL()interrupt()}}

2. 初始化EGL环境

负责EGL环境的初始化、配置和销毁:

class MyEGLHelper {private lateinit var mEGL: EGL10private lateinit var mEGLDisplay: EGLDisplayprivate lateinit var mEGLContext: EGLContextprivate lateinit var mEGLSurface: EGLSurface// 初始化EGLfun initEGL(surface: Surface) {if (::mEGL.isInitialized &&::mEGLDisplay.isInitialized &&::mEGLContext.isInitialized &&::mEGLSurface.isInitialized) {Log.e("yang", "EGL already initialized")return}// 1. 获取EGL实例mEGL = EGLContext.getEGL() as EGL10// 2. 获取默认的显示设备(就是窗口)mEGLDisplay = mEGL.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY)takeIf { mEGLDisplay == EGL10.EGL_NO_DISPLAY }?.apply {throw RuntimeException("eglGetDisplay failed")}// 3. 初始化默认显示设备val version = IntArray(2)takeIf { !mEGL.eglInitialize(mEGLDisplay, version) }?.apply {throw RuntimeException("eglInitialize failed")}// 4. 设置显示设备的属性val display_attribute_list = intArrayOf(EGL_RED_SIZE, 8,EGL_GREEN_SIZE, 8,EGL_BLUE_SIZE, 8,EGL_ALPHA_SIZE, 8,EGL_DEPTH_SIZE, 8,EGL_STENCIL_SIZE, 4,EGL_NONE)// 5. 查找配置并进行 attribute_list 的匹配, 匹配成功返回一个数组val num_config = IntArray(1)takeIf {!mEGL.eglChooseConfig(mEGLDisplay,display_attribute_list,null,0,num_config)}?.apply {throw RuntimeException("eglChooseConfig failed")}// 匹配是否成功takeIf { num_config[0] <= 0 }?.apply {throw RuntimeException("eglChooseConfig#1 failed")}val eglConfigs = arrayOfNulls<EGLConfig>(num_config[0])takeIf {!mEGL.eglChooseConfig(mEGLDisplay,display_attribute_list,eglConfigs,num_config[0],num_config)}?.apply {throw RuntimeException("eglChooseConfig#2 failed")}// 6. 创建EGLContextval context_display_list = intArrayOf(EGL_CONTEXT_CLIENT_VERSION, 3,EGL_NONE)takeIf { ::mEGLContext.isInitialized == false }?.apply {mEGLContext = mEGL.eglCreateContext(mEGLDisplay,eglConfigs[0],EGL10.EGL_NO_CONTEXT,context_display_list)}takeIf { mEGLContext == EGL10.EGL_NO_CONTEXT }?.apply {throw RuntimeException("eglCreateContext failed")}// 7. 创建EGLSurfacetakeIf { ::mEGLSurface.isInitialized == false }?.apply {mEGLSurface = mEGL.eglCreateWindowSurface(mEGLDisplay, eglConfigs[0], surface, null)}takeIf { mEGLSurface == EGL10.EGL_NO_SURFACE }?.apply {throw RuntimeException("eglCreateWindowSurface failed")}// 8. 绑定EGLContext和EGLSurfacetakeIf { !mEGL.eglMakeCurrent(mEGLDisplay, mEGLSurface, mEGLSurface, mEGLContext) }?.apply {throw RuntimeException("eglMakeCurrent failed")}}// 释放EGLfun releaseEGL() {takeIf { ::mEGL.isInitialized }?.apply {// 解绑EGLContext和EGLSurfacemEGL.eglMakeCurrent(mEGLDisplay,EGL10.EGL_NO_SURFACE,EGL10.EGL_NO_SURFACE,EGL10.EGL_NO_CONTEXT)// 释放EGLSurfacemEGL.eglDestroySurface(mEGLDisplay, mEGLSurface)// 释放EGLContextmEGL.eglDestroyContext(mEGLDisplay, mEGLContext)// 释放EGLDisplaymEGL.eglTerminate(mEGLDisplay)}}// 交换渲染数据fun swapBuffer() {takeIf { ::mEGL.isInitialized && ::mEGLDisplay.isInitialized }?.apply {takeIf { !mEGL.eglSwapBuffers(mEGLDisplay, mEGLSurface) }?.apply {throw RuntimeException("eglSwapBuffers failed")}}}
}

3. 渲染线程管理

在独立线程中处理渲染循环:

inner class MyEGLThread(private val mSurface: Surface) : Thread() {private var mWidth = 0private var mHeight = 0@Volatileprivate var mRunning = true@Volatileprivate var mSizeChanged = falseoverride fun run() {super.run()try {mEGLHelper.initEGL(mSurface)mEGLRender.onSurfaceCreated()while (mRunning) {// 宽高变化,回调渲染器的onSurfaceChanged方法if (mSizeChanged) {mEGLRender.onSurfaceChanged(mWidth, mHeight)mSizeChanged = false}// 渲染一帧, 回调渲染器的onDrawFrame方法mEGLRender.onDrawFrame()mEGLHelper.swapBuffer()}} catch (e: Exception) {Log.e("yang", "EGL thread error ${e.message}")}}fun changeSize(width: Int, height: Int) {mWidth = widthmHeight = heightmSizeChanged = true}fun release() {mRunning = falsemEGLRender.onSurfaceDestroyed()mEGLHelper.releaseEGL()interrupt()}}

4. 渲染器接口

定义渲染器接口,类似于GLSurfaceView.Renderer

interface EGLRender {fun onSurfaceCreated()  // Surface创建时调用fun onSurfaceChanged(width: Int, height: Int)  // Surface尺寸变化时调用fun onDrawFrame()  // 每帧渲染时调用fun onSurfaceDestroyed()  // Surface销毁时调用
}

5. 渲染器实现

实现渲染器接口,处理具体的OpenGL渲染逻辑:

class MyEGLRender(private val mContext: Context) : EGLRender {override fun onSurfaceCreated() {GLES30.glClearColor(0.0f, 0.5f, 0.5f, 1.0f)// 加载纹理...// 初始化顶点缓冲区...// 初始化着色器程序...}override fun onSurfaceChanged(width: Int, height: Int) {GLES30.glViewport(0, 0, width, height)// 改变渲染数据的宽高...}override fun onDrawFrame() {GLES30.glEnable(GLES30.GL_DEPTH_TEST)GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT or GLES30.GL_DEPTH_BUFFER_BIT)// 具体绘制方法...}override fun onSurfaceDestroyed() {// 销毁渲染数据...}
}

完整流程图

整体渲染流程图

+----------------------+     +----------------------+
| SurfaceView创建      | --> | 注册SurfaceHolder    |
| MySurfaceView构造函数|     | Callback回调        |
+----------------------+     +----------------------+|v
+----------------------+     +----------------------+     +----------------------+
| Surface创建          | --> | 创建渲染线程        | --> | 初始化EGL环境        |
| surfaceCreated回调   |     | MyEGLThread.start() |     | mEGLHelper.initEGL() |
+----------------------+     +----------------------+     +----------------------+|                                                        ||                                                        v
+----------------------+     +----------------------+     +----------------------+
| Surface尺寸变化      | --> | 通知渲染线程        |     | 初始化渲染器         |
| surfaceChanged回调   |     | changeSize()        |     | onSurfaceCreated()   |
+----------------------+     +----------------------+     +----------------------+|                                                        ||                                                        v
+----------------------+                                 +----------------------+
| Surface销毁          |                                 | 渲染循环开始         |
| surfaceDestroyed回调 |                                 | 循环检查尺寸变化     |
+----------------------+                                 +----------------------+|                                                        |v                                                        v
+----------------------+     +----------------------+     +----------------------+
| 停止渲染线程        | <-- | 释放OpenGL资源       | <-- | 执行渲染操作        |
| mEGLThread.release() |     | onSurfaceDestroyed() |     | onDrawFrame()       |
+----------------------+     +----------------------+     +----------------------+|                                                        |v                                                        v
+----------------------+     +----------------------+     +----------------------+
| 释放EGL资源         |     | 线程退出            |     | 交换缓冲区          |
| mEGLHelper.releaseEGL()|     | 渲染循环结束        |     | swapBuffer()        |
+----------------------+     +----------------------+     +----------------------+

EGL初始化流程图

+------------------+     +------------------+     +------------------+
| 获取EGL实例      | --> | 获取显示设备     | --> | 初始化显示设备   |
| mEGL = EGLContext|     | eglGetDisplay    |     | eglInitialize    |
| .getEGL()        |     |                  |     |                  |
+------------------+     +------------------+     +------------------+|                                                 |v                                                 v
+------------------+     +------------------+     +------------------+
| 设置EGL属性      | --> | 选择EGL配置      | --> | 创建EGL上下文    |
| RGB/Alpha/Depth  |     | eglChooseConfig  |     | eglCreateContext |
+------------------+     +------------------+     +------------------+|                                                 |v                                                 v
+------------------+     +------------------+
| 创建渲染Surface  | --> | 绑定EGL组件      |
| eglCreateWindow  |     | eglMakeCurrent   |
| Surface          |     |                  |
+------------------+     +------------------+
渲染线程管理流程图
+------------------+     +------------------+     +------------------+
| 线程启动         | --> | 初始化EGL环境    | --> | 初始化渲染器     |
| Thread.start()   |     | initEGL(surface) |     | onSurfaceCreated |
+------------------+     +------------------+     +------------------+|                                                 |v                                                 v
+------------------+     +------------------+     +------------------+
| 渲染循环         | --> | 检查尺寸变化     | --> | 执行渲染         |
| while(mRunning)  |     | if(mSizeChanged) |     | onDrawFrame()    |
+------------------+     +------------------+     +------------------+|                          |                      ||                          v                      v|              +------------------+     +------------------+|              | 更新视口         |     | 交换缓冲区       ||              | onSurfaceChanged |     | swapBuffer()     ||              +------------------+     +------------------+|                                                 |v                                                 v
+------------------+     +------------------+     +------------------+
| 接收释放信号     | --> | 通知渲染器销毁   | --> | 释放EGL资源      |
| release()调用    |     | onSurfaceDestroy |     | releaseEGL()     |
+------------------+     +------------------+     +------------------+|v
+------------------+
| 线程结束         |
| interrupt()      |
+------------------+
关键字:免费开网店的平台有哪些_杭州做网站推广公司推荐_百度关键词搜索引擎_常德seo招聘

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: