【问题标题】:Performing OpenGL Drawing from within a Thread从线程中执行 OpenGL 绘图
【发布时间】:2023-03-31 11:29:01
【问题描述】:

我一直在 Delphi VCL 自定义控件中封装核心 OpenGL 功能。目前,我正在使用在此控件中创建的TTimer 进行循环。我强烈认为使用计时器是完全错误的,因为绘图可能会重叠并有延迟。相反,我想把这个绘图循环放在一个线程中。请参考我的 original question 与一些闪烁问题 - 我将责任归咎于我正在使用的 TTimer

问题

在线程内部使用 OpenGL 是否安全?我应该注意什么?我计划从这个线程的内部和外部进行 OpenGL API 调用。它本质上是一个连续的循环,一旦完成绘制,它将立即重新开始绘制。目前,使用定时器,它取决于等待定时器的时间间隔达到。因此,例如,如果 Timer 的间隔设置为 100 毫秒,而绘图只需要 20 毫秒,那么将有 80 毫秒的等待时间,直到它再次绘图。使用线程将消除这种延迟。我应该如何从这个线程内部进行这样的调用?

背景

我基于所有 API 调用的原始示例项目使用应用程序的主线程,实际上根本没有使用 VCL。显示图像的窗口是使用纯 Windows API 调用动态创建的,并且在应用程序主线程的连续循环中重复绘制。这就是为什么我相信使用线程可以解决我的许多问题——特别是闪烁。

【问题讨论】:

  • 澄清一下——如果您在任何地方使用Forms 单元,那么您使用的是VCL。如果您以除直接 WinAPI 调用(RegisterClassCreateWindow)以外的任何方式创建任何表单,那么您正在使用 VCL。如果您使用的是 VCL,则从 VCL 中任何内容的线程中绘图都不是线程安全的。您的原始代码(上面链接)引用了至少五个 VCL 单元(Vcl.Graphics、Vcl.Controls、Vcl.Forms、Vcl.Dialogs、Vcl.ExtCtrls) - 请注意 Vcl 命名空间。
  • 那不是原来的原件——在此之前它是我从某个地方下载的一个演示应用程序,它全部编码在项目文件中,没有表单——并且表单是使用纯 Windows API 创建/销毁的。

标签: multithreading delphi opengl custom-controls delphi-xe2


【解决方案1】:

一个 OpenGL 上下文只能在一个给定线程中是当前的(活动的)。所以要么你必须在你的线程中正确地取消绑定/重新绑定当前上下文,要么你必须使用两个上下文共享数据。我强烈建议重组你的设计,只使用一个线程进行 OpenGL 调用。更多背景可以在http://www.equalizergraphics.com/documentation/parallelOpenGLFAQ.html找到。

【讨论】:

  • +1 所以,理论上,我可以在这个线程中进行所有的 OpenGL 调用,而不是在它之外......对吗?是否需要任何类型的线程初始化,例如CoInitialize()
  • 是的,正确的。 OpenGL 不需要任何线程初始化,但其他库可能,例如 Unix 上的 XInitThreads。
猜你喜欢
  • 2017-10-08
  • 2017-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-21
  • 1970-01-01
  • 2013-09-10
相关资源
最近更新 更多