3

我正在使用 OpenGL 在 android 中的 GLSurfaceView 上动态渲染图像。该应用程序对于具有多个自定义 GLSurfaceView 实例的(静态)基于 XML 的布局运行得非常好。(图片左上和右上)

如果这些实例被可见性值动态交换,最后一个可见的 OpenGL 图像仍然在新的顶部。(图片左下角和右下角)

http://www.abload.de/img/appxbunc.jpg

左上图: 4 个实例,正常大小

右上图: 4个实例,大尺寸

左下图: 1 个实例,正常大小(左上图为不需要的叠加)

右下图: 1 个实例,大尺寸(左上图为不需要的叠加层)

到目前为止我尝试了什么:

  • 没有删除不需要的实例:
    • 通过 android::visibility="gone" 隐藏未使用的图像(运行不顺畅)
    • 将视图移出可见区域并将它们的大小调整为 0 x 0
    • 使用纯色而不是动态图像来简化输出
    • 通过使视图无效来强制重绘视图(我实际上尝试了视图提供的几乎所有功能)
    • 清除 onDraw() 函数中的各种缓冲区(实际上我几乎尝试了 GLSurfaceView 提供的所有函数)
    • 强制 onPause() 事件停止渲染器
    • 使用 ViewPager 在视图之间切换
  • 成功删除不需要的实例:
    • 重新进入应用重启OpenGL(不能这样用)
    • 通过 android::visibility="gone" 递归地隐藏所有其他 GLSurfaceViews(对引擎进行了窃听,因此它停止工作)

不需要的图像不会随着布局重排而改变,例如视图的可见性变化。它们仅在 GLSurfaceView 位于另一个 GLSurfaceView 上方时可见(由 android::visibility="gone" 隐藏)。如果使用 ImageView 代替,则没有问题。第一个创建的实例没有这个问题,因为它位于子堆栈的顶部(或底部?)并且位于其兄弟姐妹的顶部。

我猜android只支持一个基于OpenGL的视图,所有GLSurfaceView实例都使用它。所有实例似乎都有一些偏好(尤其是可见性),所以它不能只是关闭或移出。

GLSurfaceView 类:

public class Panel extends GLSurfaceView implements Renderer {
  private static native void nativeRender();

  public Panel(Context context) {
    super(context);

    this.setRenderer(this);
    this.setRenderMode(RENDERMODE_WHEN_DIRTY);
  }

  public void onDrawFrame(GL10 gl) {
    nativeRender();
  }

  public void onSurfaceChanged(GL10 gl, int w, int h) {
    gl.glViewport(0, 0, w, h);
  }
  public void onSurfaceCreated(GL10 gl, EGLConfig config) {
  }
  @Override
  public void surfaceDestroyed(SurfaceHolder holder) {
    super.surfaceDestroyed(holder);
  }

    public void callback() {
        this.requestRender();
    }
}

那么是否可以在彼此内部(尤其是在顶部)使用多个 OpenGL 视图?有没有更好的方法在不使用可见性值的情况下交换它们?

4

1 回答 1

1

我遇到了同样的问题并且无法解决问题,因为我终于明白,如​​果我们让另一个 GLSurfaceView 的可见性消失,一个 GLSurfaceView 将成为一个顶部,并且它不会回到屏幕顶部。但我用一个技巧解决了这个问题。我没有隐藏视图,而是将其宽度和高度更改为 1 px,它使视图对用户不可见。当我需要显示它时,我通过 LayoutParams 更改了它的宽度和高度。它部分解决了我的问题。我向你展示我的代码

    <RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">

<LinearLayout
    android:id="@+id/smallVideoRenderLayoutIncoming"
    android:layout_width="1dp"
    android:layout_height="1dp"
    android:background="@color/transparent"
    android:orientation="vertical"/>


<LinearLayout
    android:id="@+id/largeVideoRenderLayoutIncoming"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"/>

RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(ConstantFunctions.dpToPx(120),ConstantFunctions.dpToPx(170));
smallVideoRenderLayoutIncoming.setLayoutParams(layoutParams);

当我需要展示它时,我会根据需要更改它的大小。

于 2017-02-20T05:05:45.393 回答