c# - Rendering SurfaceTexture to Unity Texture2D -


i came simillar questions earlier, weren't clarified , right take advice what's wrong i'm doing in code.

so i'm trying rendering surfacetexture android plugin unity texture2d.

here's unity code:

public class androidhandler : monobehaviour {      [serializefield]     private rawimage _rawimage;      private texture2d _inputtexture;     private androidjavaobject androidstreamerobj;     private system.intptr _nativeptr;      void start () {          _rawimage.material.settexturescale("_maintex", new vector2(-1, -1));         initandroidstreamerobject();     }      private void initandroidstreamerobject()     {         androidstreamerobj = new androidjavaobject("makeitbetter.figazzz.com.vitamiousing7.androidstreamer");          int32 texptr = androidstreamerobj.call <int32> ("gettextureptr");         debug.log("texture pointer? " + texptr);         texture2d nativetexture = texture2d.createexternaltexture (128, 128, textureformat.rgba32 , false, false, new system.intptr(texptr));          _rawimage.texture = nativetexture;     }      public void startstream()     {         string streamlink = "rtmp://live.hkstv.hk.lxdns.com/live/hks"; //"rtsp://wowzaec2demo.streamlock.net/vod/mp4:bigbuckbunny_115k.mov"; //"rtmp://live.hkstv.hk.lxdns.com/live/hks";         androidstreamerobj.call("launchstream", streamlink);     }      void update()     {         androidstreamerobj.call("drawframe");     } } 

as can see it's pretty basic. i'm asking android plugin create opengltexture , i'm using pointer of brand-new texture allocate texture2d in unity.

then android plugin code:

public class androidstreamer {      private final int float_size_bytes = 4;     private final int triangle_vertices_data_stride_bytes = 5 * float_size_bytes;     private final int triangle_vertices_data_pos_offset = 0;     private final int triangle_vertices_data_uv_offset = 3;      private activity _curractivity;     private videoview _streamconnection;      private surface _cachedsurface;     private surfacetexture _cachedsurfacetexture;      private boolean isnewframe = false;      //open gl     private int texwidth = 128;     private int texheight = 128;     private float[] mmvpmatrix = new float[16];     private float[] mstmatrix = new float[16];      private int glprogram;     private int mumvpmatrixhandle;     private int mustmatrixhandle;     private int mapositionhandle;     private int matexturehandle;     private int unitytextureid = -1;     private int mtextureid = -1;   //surface texture id     private int idfbo = -1;     private int idrbo = -1;      private final float[] mtriangleverticesdata = {             // x, y, z, u, v             -1.0f, -1.0f, 0, 0.f, 0.f,             1.0f, -1.0f, 0, 1.f, 0.f,             -1.0f,  1.0f, 0, 0.f, 1.f,             1.0f,  1.0f, 0, 1.f, 1.f,     };      private floatbuffer mtrianglevertices;      private final string vertexshadercode =             "uniform mat4 umvpmatrix;\n" +                     "uniform mat4 ustmatrix;\n" +                     "attribute vec4 aposition;\n" +                     "attribute vec4 atexturecoord;\n" +                     "varying vec2 vtexturecoord;\n" +                     "void main() {\n" +                     "    gl_position = umvpmatrix * aposition;\n" +                     "    vtexturecoord = (ustmatrix * atexturecoord).xy;\n" +                     "}\n";      private final string fragmentshadercode =             "#extension gl_oes_egl_image_external : require\n" +                     "precision mediump float;\n" +      // highp here doesn't seem matter                     "varying vec2 vtexturecoord;\n" +                     "uniform samplerexternaloes stexture;\n" +                     "void main() {\n" +                     "    gl_fragcolor = texture2d(stexture, vtexturecoord);\n" +                     "}\n";      public androidstreamer() {         log.d("unity", "androidstreamer initialized");          _curractivity = unityplayer.currentactivity;         vitamio.isinitialized(_curractivity);          _curractivity.runonuithread(new runnable() {             @override             public void run() {                 _streamconnection = new videoview(_curractivity);                 _curractivity.addcontentview(_streamconnection, new framelayout.layoutparams(100, 100));             }         });          mtrianglevertices = bytebuffer.allocatedirect(                 mtriangleverticesdata.length * float_size_bytes)                 .order(byteorder.nativeorder()).asfloatbuffer();         mtrianglevertices.put(mtriangleverticesdata).position(0);         matrix.setidentitym(mstmatrix, 0);          initshaderprogram();     }      private void initshaderprogram()     {         log.d("unity", "initshaderprogram");         int vertexshader = loadshader(gles20.gl_vertex_shader, vertexshadercode);         int fragmentshader = loadshader(gles20.gl_fragment_shader, fragmentshadercode);          glprogram = gles20.glcreateprogram();         gles20.glattachshader(glprogram, vertexshader);         checkglerror("glattachvertexshader");         gles20.glattachshader(glprogram, fragmentshader);         checkglerror("glattachfragmentshader");         gles20.gllinkprogram(glprogram);         checkglerror("gllinkprogram");          mapositionhandle = gles20.glgetattriblocation(glprogram, "aposition");         checklocation(mapositionhandle, "aposition");         matexturehandle = gles20.glgetattriblocation(glprogram, "atexturecoord");         checklocation(matexturehandle, "atexturecoord");          mumvpmatrixhandle = gles20.glgetuniformlocation(glprogram, "umvpmatrix");         checklocation(mumvpmatrixhandle, "uvmpmatrix");         mustmatrixhandle = gles20.glgetuniformlocation(glprogram, "ustmatrix");         checklocation(mustmatrixhandle, "ustmatrix");     }      private int loadshader(int shadertype, string source) {         int shader = gles20.glcreateshader(shadertype);         if (shader != 0) {             gles20.glshadersource(shader, source);             gles20.glcompileshader(shader);             int[] compiled = new int[1];             gles20.glgetshaderiv(shader, gles20.gl_compile_status, compiled, 0);             if (compiled[0] == 0) {                 log.e("unity", "could not compile shader " + shadertype + ":");                 log.e("unity", gles20.glgetshaderinfolog(shader));                 gles20.gldeleteshader(shader);                 shader = 0;             }         }         return shader;     }      private void checklocation(int location, string label) {         if (location < 0) {             throw new runtimeexception("unable locate '" + label + "' in program");         }     }      private void checkglerror(string op) {         int error;         while ((error = gles20.glgeterror()) != gles20.gl_no_error) {             log.e("unity", op + ": glerror " + error);             throw new runtimeexception(op + ": glerror " + error);         }     }      private void checkframebufferstatus()     {         int status = gles20.glcheckframebufferstatus(gles20.gl_framebuffer);         checkglerror("glcheckframebufferstatus");         switch (status)         {             case gles20.gl_framebuffer_complete:                 log.d("unity", "complete");                 break;             case gles20.gl_framebuffer_incomplete_attachment:                 log.e("unity", "incomplete attachment");                 break;             case gles20.gl_framebuffer_incomplete_missing_attachment:                 log.e("unity", "incomplete missing attachment");                 break;             case gles20.gl_framebuffer_incomplete_dimensions:                 log.e("unity", "incomplete dimensions");                 break;             case gles20.gl_framebuffer_unsupported:                 log.e("unity", "framebuffer unsupported");                 break;              default : log.d("unity", "default");         }     }      private void initgltexture()     {         log.d("unity", "initgltexture");         int textures[] = new int[1];         gles20.glgentextures(1, textures, 0);         checkglerror("glgentextures initgltexture");         mtextureid = textures[0];          gles20.glactivetexture(gles20.gl_texture0);         checkglerror("glactivetexture initgltexture");         gles20.glbindtexture(gles11ext.gl_texture_external_oes, mtextureid);         checkglerror("glbindtexture initgltexture");          gles20.gltexparameterf(gles11ext.gl_texture_external_oes, gles20.gl_texture_min_filter, gles20.gl_nearest);         checkglerror("gltexparameterf initgltexture");         gles20.gltexparameterf(gles11ext.gl_texture_external_oes, gles20.gl_texture_mag_filter, gles20.gl_linear);         checkglerror("gltexparameterf initgltexture");     }      public int gettextureptr()     {         bitmap bitmap = bitmap.createbitmap(texwidth, texheight, bitmap.config.argb_8888);         for(int x = 0; x < texwidth; x++)         {             (int y = 0; y < texheight; y++)             {                 bitmap.setpixel(x, y, color.argb(155, 255, 50, 255));             }         }         log.d("unity", "bitmap is: " + bitmap);          bytebuffer buffer = bytebuffer.allocate(bitmap.getbytecount());         bitmap.copypixelstobuffer(buffer);          //gles20.glenable(gles11ext.gl_texture_external_oes);         //checkglerror("glenable gettextureptr");          int textures[] = new int[1];         gles20.glgentextures(1, textures, 0);         checkglerror("0");         unitytextureid = textures[0];          gles20.glactivetexture(gles20.gl_texture0);         checkglerror("1");         gles20.glbindtexture(gles20.gl_texture_2d, unitytextureid);         checkglerror("2");          gles20.glteximage2d(gles20.gl_texture_2d, 0, gles20.gl_rgba, texwidth, texheight, 0, gles20.gl_rgba, gles20.gl_unsigned_byte, null);         checkglerror("12");         //glutils.teximage2d(gles20.gl_texture_2d, 0, bitmap, 0);         //checkglerror("3");         gles20.gltexparameterf(gles20.gl_texture_2d, gles20.gl_texture_min_filter, gles20.gl_nearest);         checkglerror("4");         gles20.gltexparameterf(gles20.gl_texture_2d, gles20.gl_texture_mag_filter, gles20.gl_linear);         checkglerror("5");         gles20.gltexparameteri(gles20.gl_texture_2d, gles20.gl_texture_wrap_s, gles20.gl_clamp_to_edge);         checkglerror("6");         gles20.gltexparameteri(gles20.gl_texture_2d, gles20.gl_texture_wrap_t, gles20.gl_clamp_to_edge);         checkglerror("7");         gles20.glbindtexture(gles20.gl_texture_2d, 0);         checkglerror("8");          setupbuffers();         log.d("unity", "texture id returned: " + unitytextureid);          return unitytextureid;     }      private void setupbuffers()     {         log.d("unity", "setupbuffers");          //framebuffer         int buffers[] = new int[1];         gles20.glgenframebuffers(1, buffers, 0);         checkglerror("9");         idfbo = buffers[0];         gles20.glbindframebuffer(gles20.gl_framebuffer, idfbo);         checkglerror("10");          //render buffer         int rbuffers[] = new int[1];         gles20.glgenrenderbuffers(1, rbuffers, 0);         checkglerror("glgenrenderbuffers setupbuffers");         idrbo = rbuffers[0];         gles20.glbindrenderbuffer(gles20.gl_renderbuffer, idrbo);         checkglerror("glbindrenderbuffer setupbuffers");         gles20.glrenderbufferstorage(gles20.gl_renderbuffer, gles20.gl_rgba4, texwidth, texheight);         checkglerror("glrenderbufferstorage setupbuffers");          gles20.glframebufferrenderbuffer(gles20.gl_framebuffer, gles20.gl_color_attachment0, gles20.gl_renderbuffer, idrbo);         checkglerror("glframebufferrenderbuffer setupbuffers");          gles20.glframebuffertexture2d(gles20.gl_framebuffer, gles20.gl_color_attachment0, gles20.gl_texture_2d, unitytextureid, 0);         checkglerror("glframebuffertexture2d");          checkframebufferstatus();          gles20.glclearcolor(1.0f, 0.5f, 0.0f, 1.0f);         checkglerror("glclearcolor setupbuffers");         gles20.glclear(gles20.gl_color_buffer_bit);         checkglerror("glclear setupbuffers");     }      public void drawframe()     {         if(isnewframe && mstmatrix != null) {              int[] testbuffer = new int[1];             gles20.glgetintegerv(gles20.gl_framebuffer_binding, testbuffer, 0);              log.d("unity", "drawframe binded = " + testbuffer[0] + " idfbo = " + idfbo);              gles20.glbindframebuffer(gles20.gl_framebuffer, idfbo);             checkglerror("glbindframebuffer drawframe");              gles20.glclearcolor(0.0f, 1.0f, 0.2f, 1.0f);             checkglerror("glclearcolor drawframe");             gles20.glclear(gles20.gl_color_buffer_bit);             checkglerror("glclear drawframe");              gles20.gluseprogram(glprogram);             checkglerror("gluseprogram drawframe");              gles20.glactivetexture(gles20.gl_texture0);             checkglerror("glactivetexture drawframe");             gles20.glbindtexture(gles11ext.gl_texture_external_oes, mtextureid);             checkglerror("glbindtexture drawframe");              mtrianglevertices.position(triangle_vertices_data_pos_offset);             gles20.glvertexattribpointer(matexturehandle, 2, gles20.gl_float, false, triangle_vertices_data_stride_bytes, mtrianglevertices);             checkglerror("glvertexattribpointer drawframe");             gles20.glenablevertexattribarray(matexturehandle);             checkglerror("glenablevertexattribarray drawframe");              matrix.setidentitym(mmvpmatrix, 0);             gles20.gluniformmatrix4fv(mumvpmatrixhandle, 1, false, mmvpmatrix, 0);             checkglerror("gluniformmatrix4fv mvp onframeavailable");             gles20.gluniformmatrix4fv(mustmatrixhandle, 1, false, mstmatrix, 0);             checkglerror("gluniformmatrix4fv st onframeavailable");              gles20.gldrawarrays(gles20.gl_triangle_strip, 0, 4);             checkglerror("gldrawarrays onframeavailable");              gles20.glbindframebuffer(gles20.gl_framebuffer, 0);             checkglerror("glbindframebuffer 0 onframeavailable");             gles20.glbindtexture(gles11ext.gl_texture_external_oes, 0);             checkglerror("glbindtexture onframeavailable");              isnewframe = false;         }     }      public void launchstream(string streamlink) {          final string path = streamlink; //"http://dlqncdn.miaopai.com/stream/mvaux41a4lkuwlobbgugaq__.mp4"; //"rtmp://live.hkstv.hk.lxdns.com/live/hks";         log.i("unity", "hop hop1 = " + path);          _curractivity.runonuithread(new runnable() {             @override             public void run() {                  _streamconnection.setvideopath(path);                 _streamconnection.setmediacontroller(new mediacontroller(_curractivity));                 _streamconnection.requestfocus();                  _streamconnection.setonerrorlistener(new mediaplayer.onerrorlistener() {                     @override                     public boolean onerror(mediaplayer mp, int what, int extra) {                         log.i("unity", "some error, don't know. = " + + " = " + extra);                         return false;                     }                 });                  _streamconnection.setonpreparedlistener(new mediaplayer.onpreparedlistener() {                      @override                     public void onprepared(mediaplayer mediaplayer) {                         // optional need vitamio 4.0                         log.i("unity", "hop hop5");                         mediaplayer.setplaybackspeed(1.0f);                      }                 });                  initgltexture();                  _cachedsurfacetexture = new surfacetexture(mtextureid);                 _cachedsurfacetexture.setdefaultbuffersize(texwidth, texheight);                  _cachedsurfacetexture.setonframeavailablelistener(new surfacetexture.onframeavailablelistener() {                     @override                     public void onframeavailable(surfacetexture surfacetexture) {                         synchronized (this) {                             surfacetexture.updateteximage();                              mstmatrix = new float[16];                             surfacetexture.gettransformmatrix(mstmatrix);                             isnewframe = true;                         }                     }                 });                  _cachedsurface = new surface(_cachedsurfacetexture);                 _streamconnection.setsurfacetoplayer(_cachedsurface);                  log.i("unity", "you're best around!");             }         });     } } 

i decided provide code of android plugin in order give clear understanding of situation i'm having. basically, i'm trying do: 1) call method "gettextureptr" unity side, creates gl_texture_2d texture apply unity texture2d. in android side setup frame , render buffers changing color of texture. works fine because fills color perfectly. 2) call method "launchstream", creates gl_texture_external_oes texture (in "initgltexture()" method) , texture applies surfacetexture. 3) in unity update() method call android method "drawframe()" should update unity texture according surfacetexture changes.

right i'm having glerror 1282 on gles20.glbindtexture(gles11ext.gl_texture_external_oes, mtextureid); , of course texture fills green color here

gles20.glclearcolor(0.0f, 1.0f, 0.2f, 1.0f);             checkglerror("glclearcolor drawframe"); 

what i'm doing wrong?

you can't call surfacetexture.updateteximage(); in onframeavailable, call in drawframe() .

and in unity3d:

void update()     {         androidstreamerobj.call("drawframe");         gl.invalidatestate(); // add     } 

Comments

Popular posts from this blog

sublimetext3 - what keyboard shortcut is to comment/uncomment for this script tag in sublime -

java - No use of nillable="0" in SOAP Webservice -

ubuntu - Laravel 5.2 quickstart guide gives Not Found Error -