博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
安卓下多线程OpenGL共享Context (三)
阅读量:5249 次
发布时间:2019-06-14

本文共 3503 字,大约阅读时间需要 11 分钟。

      在中我们介绍了多线程OpenGL绘制方案,但是如果需要在Java线程不断修改纹理数据,会由于并发访问导致Unity线程出现访问非法内存而崩溃。因此,考虑在Java线程加载数据,然后在unity线程调用OpenGL操作更新纹理。这样所有的OpenGL操作都在Unity绘制线程完成,从而避免了多线程OpenGL引入的各种问题。为了能够从Java线程切换到Unity线程执行,我们获取到Unity线程的Looper,然后使用该Looper实例化一个Handler,这样就可以通过往上发送消息或者Runnable在Unity线程执行任务了。Java代码如下:

1 package com.thornbirds.unity; 2  3 import android.graphics.Bitmap; 4 import android.graphics.BitmapFactory; 5 import android.opengl.GLES10; 6 import android.opengl.GLES11Ext; 7 import android.opengl.GLES20; 8 import android.opengl.GLUtils; 9 import android.os.Handler;10 import android.os.Looper;11 import android.util.Log;12 13 import java.util.concurrent.ExecutorService;14 import java.util.concurrent.Executors;15 16 public class PluginTexture {17     private static final String TAG = "PluginTexture";18 19     private int mTextureID = 0;20     private int mTextureWidth = 0;21     private int mTextureHeight = 0;22 23     // 创建单线程池,用于加载图片资源24     private final ExecutorService mJavaThread = Executors.newSingleThreadExecutor();25     // 使用Unity线程Looper的Handler,用于执行Java层的OpenGL操作26     private Handler mUnityRenderHandler;27 28     public int getStreamTextureWidth() {29         return mTextureWidth;30     }31 32     public int getStreamTextureHeight() {33         return mTextureHeight;34     }35 36     public int getStreamTextureID() {37         return mTextureID;38     }39 40     public PluginTexture() {41     }42 43     private void glLogE(String msg) {44         Log.e(TAG, msg + ", err=" + GLES10.glGetError());45     }46 47     public void setupOpenGL() {48         // 注意:该调用一定是从Unity绘制线程发起49         if (Looper.myLooper() == null) {50             Looper.prepare();51         }52         mUnityRenderHandler = new Handler(Looper.myLooper());53         // 生成OpenGL纹理ID54         int textures[] = new int[1];55         GLES20.glGenTextures(1, textures, 0);56         if (textures[0] == 0) {57             glLogE("glGenTextures failed");58             return;59         }60         mTextureID = textures[0];61         mTextureWidth = 640;62         mTextureHeight = 360;63     }64 65     public void updateTexture() {66         mJavaThread.execute(new Runnable() {67             @Override68             public void run() {69                 // 加载图片资源70                 String imageFilePath = "/sdcard/test/image.png";71                 final Bitmap bitmap = BitmapFactory.decodeFile(imageFilePath);72                 // 切换到Unity绘制线程更新纹理73                 mUnityRenderHandler.post(new Runnable() {74                     @Override75                     public void run() {76                         GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureID);77                         GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);78                         GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);79                         GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);80                         GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);81                         bitmap.recycle();82                     }83                 });84             }85         });86     }87 88     public void destroy() {89         mJavaThread.shutdownNow();90         mUnityRenderHandler.removeCallbacksAndMessages(null);91     }92 }

     至此,我们完整介绍了Unity3D开发中在Android Java Plugin中进行纹理更新的方案和实现方法。基于相同的原理,我们可以很方便地给出iOS Object-C Plugin的实现,此处不在赘述。

转载于:https://www.cnblogs.com/moderate-fish/p/6902817.html

你可能感兴趣的文章
使用 SharedPreferences 分类: Andro...
查看>>
TLA+(待续...)
查看>>
题解: [GXOI/GZOI2019]与或和
查看>>
MacOS copy图标shell脚本
查看>>
国外常见互联网盈利创新模式
查看>>
Oracle-05
查看>>
linux grep 搜索查找
查看>>
Not enough free disk space on disk '/boot'(转载)
查看>>
android 签名
查看>>
vue项目中使用百度统计
查看>>
android:scaleType属性
查看>>
SuperEPC
查看>>
mysql-5.7 innodb 的并行任务调度详解
查看>>
shell脚本
查看>>
Upload Image to .NET Core 2.1 API
查看>>
Js时间处理
查看>>
Java项目xml相关配置
查看>>
三维变换概述
查看>>
第三次作业
查看>>
vue route 跳转
查看>>