Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically show/hide multiple OpenGL-views on Android

I'm using OpenGL to dynamically render images on a GLSurfaceView within android. The application runs perfectly fine for (static) XML-based layout with multiple instances of a custom GLSurfaceView. (top left- and top right on the image)

If these instances get dynamically interchanged by the visibility value, the last visible OpenGL-image is still on top of the new one. (bottom left- and bottom right on the image)

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

top left picture: 4 instances, normal size

top right picture: 4 instances, big size

bottom left picture: 1 instance, normal size (top left picture as unwanted overlay)

bottom right picture: 1 instance, big size (top left picture as unwanted overlay)

What I tried so far:

  • did not remove the unwanted instances:
    • hide unused images by android::visibility="gone" (does not work smooth)
    • move the views out of the visible area and resize them to 0 by 0
    • use plain colors instead of dynamic images to simplify the output
    • force a redraw of the view by invalidating it (I actually tried almost every function a view offers)
    • clear various buffers in the onDraw()-function (I actually tried almost every function the GLSurfaceView offers)
    • force a onPause()-event to stop the renderer
    • use the ViewPager to switch between the views
  • removed the unwanted instances successfully:
    • restart OpenGL by reentering the app (can't be used like this)
    • recursively hide all other GLSurfaceViews by android::visibility="gone" (bugged the engine, so it stopped working)

The unwanted images does not change with layout reflows like a visibility change of a view. They are only visible if a GLSurfaceView is over another GLSurfaceView (hidden by android::visibility="gone"). There is no problem if a ImageView is used instead. The first created instance do not have this problem, because it is on top (or bottom?) of the child-stack and is on top of its siblings.

I guess android supports only one OpenGL based view which is used by all instances of GLSurfaceView. All instances seem to share some preferences (especially the visibility), so it can't just turned off or moved out.

GLSurfaceView-class:

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();
    }
}

So is it possible to use multiple OpenGL-views within (especially on top) of each other? is there a better way to interchange them without the use of the visibility value?

like image 228
user1045657 Avatar asked Apr 06 '26 17:04

user1045657


1 Answers

I was having same problem and couldn't solved the problem as i finally understand that one GLSurfaceView will be one top if we make another GLSurfaceView's visibility GONE & it won't be coming back on top of screen. But i solved the problem with a trick. Instead of hiding the view, i changed it's width and height to 1 px, it's makes the view invisible to user. And when i need to show it , i changed it width & height via LayoutParams. And it partially solved my problem. I am showing you my code

    <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);

When i need to show it, i changed it's size as i needed.

like image 81
Md. Sulayman Avatar answered Apr 08 '26 08:04

Md. Sulayman



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!