我使用TextureView
进行OpenGL渲染ScrollView
内的视图。
(请注意我使用Xamarin.Android,但相同的概念应适用于原生Android开发。)
我有一个派生类CustomView
,它继承自实现TextureView
的{{1}}。在我的TextureView.ISurfaceTextureListener
覆盖中,我构建了一个继承自标准OnSurfaceTextureAvailable
的自定义渲染器类:
Java.Lang.Thread
我的自定义public void OnSurfaceTextureAvailable(SurfaceTexture surface, int width, int height)
{
renderThread = new GLRenderer(surface);
renderThread.Start();
}
类的代码如下:
GLRenderer
这是非常标准的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();
// Draw OpenGL stuff
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
};
}
设置,用于使用OpenGL进行渲染。但是,当我旋转设备和OnSurfaceTextureUpdated时,执行TextureView
行并且在硬件上可见时呈现的部分代码称为。
我的问题是:为什么我的OpenGL视图无法在Android // Draw OpenGL stuff
中呈现,除非我旋转设备(或调用TextureView
时)?