How to render OpenGL in Flutter for Android?

5,096

Texture works well on Android Emulator and devices, but only on iOS device, not iOS Simulator.

hey I found some useful links for you i think this solve your issue

check out : OpenGL with Texture widget

Share:
5,096
PPP
Author by

PPP

Updated on December 15, 2022

Comments

  • PPP
    PPP over 1 year
    if (call.method.equals("createVideoRenderer")) {
                TextureRegistry.SurfaceTextureEntry entry = textures.createSurfaceTexture();
                SurfaceTexture surfaceTexture = entry.surfaceTexture();
                this.surfaceTexture = surfaceTexture;
    

    This is my java method call that creates my SurfaceTexture and saves it into my class instance. I've been reading about SurfaceTexture's class and this is how I understand it:

    I need to call surfaceTexture.setOnFrameAvailableListener(SurfaceTexture.OnFrameAvailableListener listener) to pass an instance of SurfaceTexture.OnFrameAvailableListener that defines the function onFrameAvailable(SurfaceTexture surfaceTexture). If I understood correctly, this function is called by updateTexImage(). So I think onFrameAvailable is supposed to grab the image and render it? If so, how can I call OpenGL functions inside it? Where's the OpenGL context?

    I'm totally lost on how to render it. All Android OpenGL examples that I find use surface views or something like that. I need to know how to create a pure opengl context.

    I also think that when onFrameAvailable is called, the surfaceTexture's texture is bound to the OpenGL context, so I don't need to create shaders, tune texture parameters, etc. I just need to render to it, perhaps calling glTexImage2D.

    So how to render something as simple as a red square with glTexImage2D using this SurfaceTexture that Flutter gives me?

    UPDATE:

    I found this: https://github.com/mogol/opengl_texture_widget_example

    and I successfully rendered a color by using

    GLES20.glClearColor(0f, green, 0f, 1f);
    
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
    

    However, I want to use glTeximage2D. I tried simply adding

    GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, 100, 100,
                    0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, buffer);
    

    But it didn't work

    UPDATE:

    I did some research and discovered (I think) that android uses gl external textures, so I tried:

        buffer = ByteBuffer.allocate(bufferSize);
        for (int i = 0; i < bufferSize; i = i+=4) {
            buffer.put((byte)255);
        }
        for (int i = 1; i < bufferSize-1; i = i+=4) {
            buffer.put((byte)0);
        }
        for (int i = 2; i < bufferSize-2; i = i+=4) {
            buffer.put((byte)0);
        }
        for (int i = 3; i < bufferSize-3; i = i+4) {
            buffer.put((byte)255);
        }
       buffer.rewind();
        GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
        GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
        GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
        GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
        GLES20.glTexImage2D(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 0, GLES11Ext.GL_RGB8_OES, 100, 100, 0, GLES11Ext.GL_RGB8_OES, GLES20.GL_UNSIGNED_BYTE, buffer);
    

    I should see a red image, but I see nothing.

    I also tries using GLES20.RGBA8 in glTexImage2D but it didn't work. I also tried GLES11Ext.glEGLImageTargetTexture2DOES( GL_TEXTURE_EXTERNAL_OES, buffer ) in place of glTexImage2D and it also didn't work.