安卓下多線程OpenGL共用Context (三)

來源:互聯網
上載者:User

標籤:www   unity3d   rate   private   並發   imp   ack   glut   remove   

      在上一節中我們介紹了多線程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的實現,此處不在贅述。

安卓下多線程OpenGL共用Context (三)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.