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

來源:互聯網
上載者:User

標籤:getc   jar包   ima   end   utils   需要   bug   width   idt   

    最近在研究Unity3D開發中使用Java Plugin進行紋理更新,想法很簡單,在Java線程更新紋理資料,然後Unity情境中的紋理將自動更新。

首先,建立Java類,定義建立紋理及擷取紋理參數的介面,並建立單線程池用於進行載入Bitmap並綁定紋理資料等OpenGL操作。Java程式碼範例:

 1 package com.thornbirds.unity; 2  3 import android.graphics.Bitmap; 4 import android.graphics.BitmapFactory; 5 import android.opengl.GLES11Ext; 6 import android.opengl.GLES20; 7 import android.opengl.GLUtils; 8 import android.util.Log; 9 10 import java.util.concurrent.ExecutorService;11 import java.util.concurrent.Executors;12 13 public class PluginTexture {14     private static final String TAG = "PluginTexture";15     private int mTextureID = 0;16     private int mTextureWidth = 0;17     private int mTextureHeight = 0;18 19     // 建立單線程池,用於處理OpenGL紋理20     private final ExecutorService mRenderThread = Executors.newSingleThreadExecutor();21 22     public int getStreamTextureWidth() {23         return mTextureWidth;24     }25 26     public int getStreamTextureHeight() {27         return mTextureHeight;28     }29 30     public int getStreamTextureID() {31         return mTextureID;32     }33 34     public PluginTexture() {35     }36 37     public void setupOpenGL() {38         mRenderThread.execute(new Runnable() {39             @Override40             public void run() {41                 // 產生OpenGL紋理ID42                 int textures[] = new int[1];43                 GLES20.glGenTextures(1, textures, 0);44                 if (textures[0] == 0) {45                     Log.e(TAG, "glGenTextures failed");46                     return;47                 }48                 mTextureID = textures[0];49                 mTextureWidth = 640;50                 mTextureHeight = 360;51             }52         });53     }54 55     public void updateTexture() {56         mRenderThread.execute(new Runnable() {57             @Override58             public void run() {59                 String imageFilePath = "/sdcard/test/image.png";60                 final Bitmap bitmap = BitmapFactory.decodeFile(imageFilePath);61 62                 GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureID);63                 GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);64                 GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);65                 GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);66                 GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);67 68                 bitmap.recycle();69             }70         });71     }72 73     public void destroy() {74         mRenderThread.shutdownNow();75     }76 }

    然後,建立C#指令碼,在指令碼中樣本化Java對象,並調用Java方法初始化OpenGL;為了展示更新紋理,需擷取到Java產生的紋理ID,並將其與指令碼當前GameObject綁定。C#程式碼範例:

 1 public class PluginTestureDemo : MonoBehaviour { 2     private AndroidJavaObject mPluginTexture;  3     private int mTextureId; 4     private int mWidth; 5     private int mHeight; 6  7     void Start () { 8         // 執行個體化com.thornbirds.unity.PluginTexture類的對象 9         mPluginTexture = new AndroidJavaObject ("com.thornbirds.unity.PluginTexture");10         // 初始化OpenGL11         mPluginTexture.Call ("setupOpenGL");12     }13 14     void BindTexture () {15         // 擷取JavaPlugin產生的紋理ID16         mTextureId = mPluginTexture.Call<int> ("getPluginTextureID");17         if (mTextureId == 0) {18             Debug.LogError ("getPluginTextureID failed");19             return;20         }21         mWidth = mPluginTexture.Call<int> ("getPluginTextureWidth");22         mHeight = mPluginTexture.Call<int> ("getPluginTextureHeight");23         // 將紋理ID與當前GameObject綁定24         GetComponent<MeshRenderer> ().material.mainTexture = Texture2D.CreateExternalTexture 25             (mWidth, mHeight, TextureFormat.ARGB32, false, false, (IntPtr) mTextureId);26         // 更新紋理資料27         mPluginTexture.Call ("updateTexture");28     }29 }

注意:C#中使用了方法名調用Java方法,因此需要防止編譯Jar包時Java類及其public方法被混淆。在Proguard檔案中加入如下代碼:

1 -keep class com.thornbirds.unity.PluginTexture {2     public *;3 }

    該方案存在一個問題,在Java線程中訪問進行OpenGL操作,會報Missing GLContext,需要為Java線程初始化OpenGL繪製環境。下回繼續。

 

安卓下多線程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.