How to render OpenGL in Flutter for Android?
Asked Answered
T

1

24
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.

Tiro answered 23/10, 2019 at 22:21 Comment(1)
you can try pub.dev/packages/flutter_opengl_viewFluctuant
M
1

On the Android side, call id() method on instance of TextureRegistry.SurfaceTextureEntry, to get texture id. On flutter side, use Texture widget. This widget accepts textureId as a param.

Mayo answered 24/1 at 10:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.