我正在尝试向Android opengl ES应用程序添加叠加层,目前我正在指定一个ImageView并使用SurfaceViewOverlay API Demo处理代码,有效地合并了我编写的两个应用程序,一个是基于canvas的应用程序,另一个是opengl ES
由于合并了两个项目,涉及大量的复制粘贴,导致我意外地使用了空表面支架。令人惊讶的是,这有效,但却发出了大量警告。然而,将其更改为opengl面板的曲面支架会导致应用程序挂起,并且不会显示来自opengl或ImageView的内容。
我玩了代码,以确保我没有初始化任何其他地方并确认HTC Desire和三星Galaxy(两者都运行2.2)的行为
Canvas c = null;
SurfaceHolder surfaceHolder2D = null; // this works but throws occational Null Pointer exceptions on the first canvas.drawText
//SurfaceHolder surfaceHolder2D = rsurfaceHolder; // this locks the application.
//rsurfaceHolder is initialized with getHolder() in the opengl class and this worked with both when they where separate.
//The change to ImageView was to get around issues with multiple SurfaceViews in an application having indeterminate Z order
try
{
if (Global.RUNNING == 1)
{
c = surfaceHolder2D.lockCanvas(null); // when canvas is null this line can be ommited and it still works
synchronized (surfaceHolder2D)
{
rpanel2D.onDraw(c);
}
}
else
sleep(1000);
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
if (c != null)
{
surfaceHolder2D.unlockCanvasAndPost(c);
}
}
那么到底发生了什么以及执行此操作的正确方法是什么?我假设当我写入空画布时,编译器正在做某事并将其发送到正确的位置,无论如何。
保持原样,实际上不是一个选项,因为有几个原因,包括不相信这可以在多个版本的android上运行,它会在日志中充斥着一连串警告,并且帧速率下降很明显如果onDraw在每次通话时失效。
对于onDraw函数,这只是使用canvas.drawText和this.invalidate()
奇怪地创建一个新画布并绘制到该画布并尝试使setImageResource无效(使用new或null)会抛出“CalledFromWrongThreadException:只有创建视图层次结构的原始线程可以触及其视图”,但绘制时不会到一个空画布。作为回应,我将其从openGL线程调用,但是在ImageView停止更新后不久,这可以工作几秒钟。因为我放置在那里的计数器确认它是递增的,所以它仍然被调用,即使显示器没有。隐藏和取消隐藏叠加会导致它再次工作几秒钟。
非常感谢任何帮助。如果我完全走错了轨道,请告诉我。我的另一种方法是将其呈现给BMP,创建一个新的纹理并将其绘制成四边形,但我想这会导致一分钟创建数千个纹理的问题。
提前致谢。 -K
答案 0 :(得分:1)
我不确定你想要实现的目标 - 如果两个渲染都是使用OpenGL完成的话会不会更好?假设没有其他方法,我建议创建FrameLayout并向其添加两个视图(GLSurfaceView
和ImageView
)。如果您需要更改UI元素,您必须从UI线程更改它,更改GL线程中的元素将导致错误;所以请确保在runOnUiThread Runnable内进行任何更改。