【问题标题】:Android ImageView overlay over Opengl ES unexpected behaviorAndroid ImageView 覆盖在 Opengl ES 上的意外行为
【发布时间】: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


    【解决方案1】:

    我不确定您想要实现什么 - 如果两个渲染都使用 OpenGL 完成会不会更好?假设没有其他方法,我建议创建一个FrameLayout 并将两个视图添加到其中(GLSurfaceViewImageView)。如果您需要更改 UI 元素,您必须从 UI 线程执行,从 GL 线程更改元素会导致错误;所以请务必在runOnUiThread Runnable 中进行任何更改。

    【讨论】:

    • 嗨 MichalisB,这几乎就是我最终要走的路,但我可能会回到纯粹的 opengl。我试图构建一个需要在低端和高端设备上快速运行的动态 ui 重型 opengl 应用程序。 HTC Desire 经历了相当大的帧速率下降,推动了太多的四边形,因此覆盖了我只需每 1/5 秒更新一次的画布在当时似乎是个好主意。目前,它会更新每一帧作为 android looper 的一部分,这会将性能降低一半,但稍后我会看到我能用它做什么。谢谢
    • 我不知道你是如何进行 2D 渲染的,所以如果你已经这样做了,这可能是多余的,但是你尝试过优化它吗?例如,不要使用纹理图集更改纹理和/或使用退化三角形条带仅通过一次绘制调用绘制整个 UI?
    • 我的主要问题是不仅界面发生了变化,而且它们本身的标签显示的数字数据也在不断变化。我创建了一个数字 tex 数组/显示包装类,因此我可以轻松地将浮点值显示到 x 小数位等。比我最初基准测试的 alt 更快,但随着需求的增长,现在意味着每帧数百个 tex 绑定和四边形绘制操作仅此而已。我的另一种想法是我可以有一个位图并使用画布工具。对于很多动态文本,它似乎可以更好地扩展,但初始开销很大。
    猜你喜欢
    • 2014-01-15
    • 2021-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-16
    • 1970-01-01
    相关资源
    最近更新 更多