【发布时间】:2011-08-08 01:38:38
【问题描述】:
我正在尝试向 Android opengl ES 应用程序添加叠加层,目前正在指定一个 ImageView 并处理 SurfaceViewOverlay API Demo 中的代码,有效地合并了我编写的两个应用程序,一个是基于画布的应用程序,一个是基于 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 无效或使用 setImageResource(使用 new 或 null)会引发“CalledFromWrongThreadException:只有创建视图层次结构的原始线程才能触摸其视图”,但在绘制时不会到一个空画布。作为回应,我将其移至从 openGL 线程调用,尽管这可以在 ImageView 停止更新后不久工作几秒钟。它仍在绘制中,因为我放置在那里的一个计数器确认它是递增的,即使显示不是。隐藏和取消隐藏覆盖会导致它再次工作几秒钟。
任何帮助将不胜感激。如果我完全走错了路,请告诉我。我的替代方法是将其渲染为 BMP,创建一个新纹理并将其绘制为四边形,但我认为这会导致一分钟创建数千个纹理的问题。
提前致谢。 -K
【问题讨论】:
标签: android opengl-es overlay android-canvas