I use TextureViewfor OpenGL displaying a view inside ScrollView.
(Please note that I am using Xamarin.Android , but the same concept should apply to development on native Android.)
I have a derived class CustomViewthat inherits from TextureViewwhich implements TextureView.ISurfaceTextureListener. In my redefinition, OnSurfaceTextureAvailableI create my own visualization class that inherits from the standard Java.Lang.Thread:
public void OnSurfaceTextureAvailable(SurfaceTexture surface, int width, int height)
{
renderThread = new GLRenderer(surface);
renderThread.Start();
}
The code for my custom class is GLRendererprovided as follows:
private class GLRenderer : Thread
{
private bool finished = false;
private SurfaceTexture surfaceTexture;
private IEGL10 gl;
private EGLDisplay display;
private EGLConfig config;
private EGLContext context;
private EGLSurface surface;
private const int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
private const int EGL_OPENGL_ES2_BIT = 4;
public PlotRenderer(SurfaceTexture surfaceTexture)
{
if (surfaceTexture == null)
throw new ArgumentNullException("surfaceTexture");
this.surfaceTexture = surfaceTexture;
}
public override void Run()
{
InitializeGL();
while (!finished)
{
MakeCurrent();
SwapBuffers();
}
FinalizeGL();
}
public void Finish()
{
Interrupt();
finished = true;
}
private void InitializeGL()
{
gl = EGLContext.EGL.JavaCast<IEGL10>();
display = gl.EglGetDisplay(EGL10.EglDefaultDisplay);
if (display == EGL10.EglNoDisplay)
throw new Exception("Failed to get default display.");
if (!gl.EglInitialize(display, new int[2]))
throw new Exception("Failed to initialize EGL display.");
config = ChooseEGLConfig();
if (config == null)
throw new Exception("EGL config is null", new ArgumentNullException("config"));
context = gl.EglCreateContext(display, config, EGL10.EglNoContext, defaultAttribList);
surface = gl.EglCreateWindowSurface(display, config, surfaceTexture, null);
if (surface == null || surface == EGL10.EglNoSurface)
throw new Exception("Failed to create EGL window surface.");
MakeCurrent();
}
private void FinalizeGL()
{
gl.EglDestroyContext(display, context);
gl.EglDestroySurface(display, surface);
}
private EGLConfig ChooseEGLConfig()
{
var configsCount = new int[1];
var configs = new EGLConfig[1];
if (!gl.EglChooseConfig(display, defaultConfigSpec, configs, 1, configsCount))
throw new Exception("Failed to choose EGL config.");
return configsCount[0] > 0 ? configs[0] : null;
}
private void MakeCurrent()
{
if (!context.Equals(gl.EglGetCurrentContext()) || !surface.Equals(gl.EglGetCurrentSurface(EGL10.EglDraw)))
{
if (!gl.EglMakeCurrent(display, surface, surface, context))
throw new Exception("Failed to EGL make current.");
}
}
private void SwapBuffers()
{
if (!gl.EglSwapBuffers(display, surface))
throw new Exception("Failed to EGL swap buffers.");
}
private static int[] defaultConfigSpec =
{
EGL10.EglRenderableType, EGL_OPENGL_ES2_BIT,
EGL10.EglRedSize, 8,
EGL10.EglGreenSize, 8,
EGL10.EglBlueSize, 8,
EGL10.EglAlphaSize, 8,
EGL10.EglDepthSize, 8,
EGL10.EglStencilSize, 0,
EGL10.EglSamples, 4,
EGL10.EglNone
};
private static int[] defaultAttribList =
{
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL10.EglNone
};
}
TextureView, OpenGL. , , , // Draw OpenGL stuff , OnSurfaceTextureUpdated.
: OpenGL- Android TextureView, ( OnSurfaceTextureUpdated)?