繁体   English   中英

OpenGL异步渲染场景需要花费几秒钟

[英]OpenGL asynchronous render of scene that takes several seconds

我已经使用wxWidgets和OpenGL实现了Mandelbrot分形生成器。 计算是在片段着色器内部执行的,而我正在使用wxGLCanvas小部件显示结果。 它运行良好,但是当我要执行高分辨率导出时,线程锁定了几秒钟,这冻结了UI。

最初,我尝试将所有渲染代码(和上下文创建)移到一个单独的渲染线程中,但是我发现,锁定的不仅仅是渲染线程,而是所有线程。 这可以通过在执行仅在循环中将消息打印到stdout的渲染之前生成一个新线程来容易地演示。 在冻结之前,它将打印多达1条消息,然后在渲染完成后恢复。

为了执行文件导出,我首先渲染为纹理,然后使用glGetTexImage将像素读入主存储器。 渲染与您期望的异步进行,但是glGetTexImage函数将阻止(再次达到预期)。 因此,我尝试将glFenceSync与glGetSynciv结合使用,仅在达到围栏指示已完成渲染时才调用glGetTexImage。

我可以确认绘图调用立即返回,但是当我返回到wxWidgets事件循环以等待渲染完成时,应用程序中的所有线程都将冻结。 我认为wxWidgets正在进行强制进行同步的OpenGL调用(wxGLCanvas中可能有问题)-我相当确定这不是我的代码中的问题。

我不确定为什么所有线程都阻塞glGetTexImage调用,而不仅仅是渲染线程。 我以为这可能是我的设置(硬件,驱动程序,操作系统等)的怪癖,但在完全不同的平台上却得到了相同的结果。

我能想到的唯一剩下的选择是使用自己的OpenGL上下文在另一个进程中进行导出渲染。 如果仍要使用wxGLCanvas设置上下文,则可能需要在屏幕上显示一个可见窗口,这并不理想。 同样,如果用户在渲染过程中尝试关闭窗口,它将无响应。

有任何想法吗?

与其说是解决方案,不如说是一种解决方法(由注释中的derhass建议)是将渲染分为几个较小的渲染。 我将图像绘制成水平条纹,每个条纹高10像素,并在每个条纹之间调用wxSafeYield(),以使UI保持一定的响应速度(如果绘制时间太长,用户可以中止渲染)。

另一个好处是,GPU过载的危险较小。 在执行此操作之前,我曾经启动过长时间的渲染,导致显示器关闭,因此必须进行强制重启。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM