在 Android 上动态显示/隐藏多个 OpenGL 视图
我正在使用 OpenGL 在 android 中的 GLSurfaceView 上动态渲染图像。 该应用程序对于具有多个自定义 GLSurfaceView 实例的(静态)基于 XML 的布局运行得非常好。 (图像的左上角和右上角)
如果这些实例通过可见性值动态交换,则最后一个可见的 OpenGL 图像仍然位于新图像的顶部。 (图像左下角和右下角)
左上图片: 4 个实例,正常尺寸
右上图片: 4 个实例,大尺寸
左下图片: 1 个实例,正常尺寸(顶部左图为不需要的覆盖)
右下图: 1 个实例,大尺寸(左上图为不需要的覆盖图)
到目前为止我尝试过的:
- 没有删除不需要的实例:
- 通过 android::visibility="gone" 隐藏未使用的图像(工作不顺利)
- 将视图移出可见区域并将其大小调整为 0 × 0
- 使用纯色而不是动态图像来简化输出
- 通过使视图无效来强制重绘视图(实际上我尝试了视图提供的几乎所有功能)
- 清除 onDraw() 函数中的各种缓冲区(实际上我尝试了 GLSurfaceView 提供的几乎所有函数)
- 强制 onPause() 事件停止渲染器
- 使用 ViewPager 在视图之间切换
- 已成功删除不需要的实例:
- 重新进入应用程序重新启动OpenGL(不能这样使用)
- 通过 android::visibility="gone" 递归隐藏所有其他 GLSurfaceView(对引擎进行窃听,因此它停止工作)
不需要的图像不会改变布局重排就像视图的可见性更改一样。 仅当 GLSurfaceView 位于另一个 GLSurfaceView 上方时(由 android::visibility="gone" 隐藏),它们才可见。 如果用ImageView代替就没有问题。 第一个创建的实例不存在此问题,因为它位于子堆栈的顶部(或底部?)并且位于其同级堆栈的顶部。
我猜 Android 只支持一种基于 OpenGL 的视图,该视图由 GLSurfaceView 的所有实例使用。 所有实例似乎都有一些偏好(尤其是可见性),因此它不能只是关闭或移出。
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();
}
}
那么是否可以在彼此内部(尤其是在顶部)使用多个 OpenGL 视图?有没有更好的方法来交换它们而不使用可见性值?
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)
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我遇到了同样的问题,但无法解决问题,因为我终于明白,如果我们使另一个 GLSurfaceView 的可见性消失,一个 GLSurfaceView 将成为顶部。它不会返回到屏幕顶部。
但我用一个技巧解决了这个问题。我没有隐藏视图,而是将其宽度和高度更改为 1 px,这使得视图对用户不可见。当我需要显示它时,我改变了它的宽度和宽度。通过 LayoutParams 的高度。它部分解决了我的问题。我正在向您展示我的代码
当我需要显示它时,我根据需要更改了它的大小。
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
When i need to show it, i changed it's size as i needed.