在线程中执行OpenGL绘图

4
我一直在将核心OpenGL功能包装在Delphi VCL自定义控件中。目前,我正在使用在此控件中创建的TTimer进行循环。我强烈感觉使用计时器完全是错误的,因为绘图可能会重叠并且有延迟。相反,我想将这个绘制循环放在一个线程中。请参考我的原始问题,其中涉及闪烁问题 - 我将责任归咎于我正在使用的TTimer
问题:
在线程内部使用OpenGL是否安全?我应该注意什么?我计划从此线程内外都调用OpenGL API。它本质上是一个连续的循环,在完成绘制后,它将立即开始再次绘制。目前,使用定时器取决于等待定时器间隔到达。例如,如果定时器间隔设置为100毫秒,而绘图仅需要20毫秒,则会等待80毫秒才能再次绘制。使用线程将消除此延迟。我应该如何从此线程内部进行这样的调用?
背景:

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


只是为了澄清 - 如果您在任何地方使用 Forms 单元,则正在使用 VCL。如果您以任何方式创建任何形式而不是直接的 WinAPI 调用(RegisterClassCreateWindow),则正在使用 VCL。如果您正在使用 VCL,则从 VCL 中的线程绘制是不安全的。您原始的代码(上面链接的)引用了至少五个单元(Vcl.Graphics、Vcl.Controls、Vcl.Forms、Vcl.Dialogs、Vcl.ExtCtrls),它们都是 VCL - 请注意 Vcl 命名空间。 - Ken White
那不是原始的原始版本 - 在那之前,它是一个演示应用程序,我从某个地方下载的,所有代码都在项目文件中编写,没有表单 - 表单是使用纯Windows API创建/销毁的。 - Jerry Dodge
1
这将会对你有所帮助:http://www.google.com/m?q=opengl+draw+thread - David Heffernan
1个回答

5

一个OpenGL上下文只能在一个给定的线程中处于当前(活动)状态。因此,您必须正确地在您的线程中解绑/重新绑定当前上下文,或者使用共享数据的两个上下文。我强烈建议重构您的设计,仅使用单个线程执行OpenGL调用。更多背景资料可在http://www.equalizergraphics.com/documentation/parallelOpenGLFAQ.html找到。


+1 所以,理论上,我可以在这个线程中完成所有的OpenGL调用,而不需要在外部进行任何调用...对吗?它需要任何类型的线程初始化,比如CoInitialize()吗? - Jerry Dodge
是的,正确的。OpenGL不需要任何线程初始化,但其他库可能需要,例如Unix上的XInitThreads。 - eile

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接