2

在 OpenGL Renderer 中,onDrawFrame 被多次调用,直到页面被完全渲染。我找不到我的页面完全渲染的事件,以便拍摄 OpenGL 页面的快照并为其设置动画。

我有在动画触发器(特定按钮)处拍摄快照的解决方案,但这将意味着特定的延迟,直到创建位图,例如我想在内存中保留每个页面的可变副本。

你知道用渲染内容为 GLSurfaceView 设置动画的其他方法吗?

用于触发快照的片段。

 glSurfaceView.queueEvent(new Runnable() {

                @Override
                public void run() {
                    glSurfaceView.getRenderer().takeGlSnapshot();
                }
            });

EGLContext 用于传递 GL11 对象。

    public void takeGlSnapshot() {
         EGL10 egl = (EGL10) EGLContext.getEGL();
         GL11 gl = (GL11) egl.eglGetCurrentContext().getGL();
         takeSnapshot(gl);

}

onDrawFrame(Gl10 gl) {
 //is last call for this page event ???????????? 
4

1 回答 1

2

不存在这样的事件,我将在下面解释。

OpenGL 被设计为客户端/服务器架构,两者异步运行。在现代实现中,您通常可以将客户端视为用于发出命令的 API 前端,将服务器视为 GPU/驱动程序后端。API 调用将做一些工作来验证输入参数等,但除了一些异常(例如glReadPixels (...))之外,它们会缓冲命令供服务器稍后执行。你永远不会真正知道你的命令何时完成,除非你明确地调用glFinish (...).

glFinish (...)在每一帧结束时调用是一个糟糕的主意,因为它会创建一个 CPU/GPU 同步点,并取消 CPU 和 GPU 异步运行的好处。但是,如果您只是想每隔一段时间截取当前glFinish (...)帧的屏幕截图,那么可能是一种可以接受的做法。

要考虑的另一件事是,如果您使用双缓冲渲染,您可以通过读取前缓冲区来访问最后一个 完全渲染的帧。然而,这是特定于实现的行为,因为某些系统设计为在缓冲区交换操作后丢弃前端缓冲区的内容,而其他系统则将读取其内容作为未定义的操作。在任何情况下,如果您尝试此解决方案,请注意返回的图像将有 1 帧延迟(但是,读取它的过程不需要您完成当前帧),这可能是不可接受的。

于 2013-11-04T22:56:30.150 回答