In the previous section we covered the multithreaded OpenGL drawing scenario, but if you need to constantly modify texture data on a Java thread, it crashes because of concurrent access that causes the unity thread to access illegal memory. Therefore, consider loading the data in the Java line loads and then call OpenGL operations on the Unity thread to update the texture. This allows all OpenGL operations to be done on the unity drawing thread, thus avoiding the various problems introduced by multi-threaded OpenGL. In order to be able to switch from a Java thread to a unity thread, we get the looper of the unity thread and use that looper to instantiate a handler so that we can send a message up or runnable the unity thread to perform the task. The Java code is as follows:
1 Packagecom.thornbirds.unity;2 3 ImportAndroid.graphics.Bitmap;4 Importandroid.graphics.BitmapFactory;5 Importandroid.opengl.GLES10;6 Importandroid.opengl.GLES11Ext;7 Importandroid.opengl.GLES20;8 Importandroid.opengl.GLUtils;9 ImportAndroid.os.Handler;Ten ImportAndroid.os.Looper; One ImportAndroid.util.Log; A - ImportJava.util.concurrent.ExecutorService; - Importjava.util.concurrent.Executors; the - Public classPlugintexture { - Private Static FinalString TAG = "Plugintexture"; - + Private intMtextureid = 0; - Private intMtexturewidth = 0; + Private intMtextureheight = 0; A at //Create a single thread pool for loading picture resources - Private FinalExecutorservice Mjavathread =executors.newsinglethreadexecutor (); - //Use the Unity thread Looper handler to perform OpenGL operations on the Java layer - PrivateHandler Munityrenderhandler; - - Public intgetstreamtexturewidth () { in returnMtexturewidth; - } to + Public intgetstreamtextureheight () { - returnMtextureheight; the } * $ Public intGetstreamtextureid () {Panax Notoginseng returnMtextureid; - } the + Publicplugintexture () { A } the + Private voidGlloge (String msg) { -LOG.E (TAG, msg + ", err=" +gles10.glgeterror ()); $ } $ - Public voidSetupopengl () { - //Note: This call must be initiated from the Unity drawing thread the if(Looper.mylooper () = =NULL) { - Looper.prepare ();Wuyi } theMunityrenderhandler =NewHandler (Looper.mylooper ()); - //generate OpenGL Texture ID Wu intTextures[] =New int[1]; -Gles20.glgentextures (1, textures, 0); About if(Textures[0] = = 0) { $Glloge ("Glgentextures failed"); - return; - } -Mtextureid = Textures[0]; AMtexturewidth = 640; +Mtextureheight = 360; the } - $ Public voidupdatetexture () { theMjavathread.execute (NewRunnable () { the @Override the Public voidrun () { the //load a picture resource -String Imagefilepath = "/sdcard/test/image.png"; in FinalBitmap Bitmap =Bitmapfactory.decodefile (imagefilepath); the //Switch to Unity draw thread to update textures theMunityrenderhandler.post (NewRunnable () { About @Override the Public voidrun () { the gles20.glbindtexture (gles20.gl_texture_2d, Mtextureid); the Gles20.gltexparameteri (Gles11ext.gl_texture_external_oes, Gles20.gl_texture_min_filter, GLES20 . gl_nearest); + Gles20.gltexparameteri (Gles11ext.gl_texture_external_oes, Gles20.gl_texture_mag_filter, GLES20 . gl_nearest); -Glutils.teximage2d (gles20.gl_texture_2d, 0, bitmap, 0); theGles20.glbindtexture (gles20.gl_texture_2d, 0);Bayi bitmap.recycle (); the } the }); - } - }); the } the the Public voiddestroy () { the Mjavathread.shutdownnow (); -Munityrenderhandler.removecallbacksandmessages (NULL); the } the}
At this point, we have fully introduced the Unity3d development in the Android Java plugin in the texture update scheme and implementation method. Based on the same principle, we can easily give the implementation of iOS Object-c plugin, which is not mentioned here.
Multi-threaded OpenGL sharing context under Android (iii)