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.