创建跨平台 OpenGL 离屏上下文
Posted
技术标签:
【中文标题】创建跨平台 OpenGL 离屏上下文【英文标题】:Creating cross platform OpenGL off-screen context 【发布时间】:2013-01-10 08:16:08 【问题描述】:我的任务是在 C++ 中为 Window 和 Linux 实现屏幕外 OpenGL 渲染器。我已经使用 LWJGL lib 用 Java 编写了这样一个版本。我使用了 PBuffer 对象,它在引擎盖下根据使用的创建 Pbuffers操作系统。首先我想重新实现完整的 PBuffer 创建逻辑,就像我在 LWJGL 的本机源代码中所做的那样。然后我阅读了 ***.com 上的 this 帖子,建议使用标准上下文创建,假设使用 @ 987654323@(这是跨平台的)但不是创建实际的窗口。这是正确的方法吗?在这种情况下,与使用 Pbuffer 相比有什么优缺点?
更新: 我只想强调我使用 FBO 来渲染帧,所以我的问题不是如何在屏幕外模式下渲染,而是如何在 Windows 和 Linux 操作系统中创建没有窗口的上下文。
【问题讨论】:
【参考方案1】:我强烈建议不要再使用PBuffers,而是使用Frame Buffer Objects (FBOs)。 FBO 提供了更好的性能,因为使用它们不需要上下文切换并且它们有 several other advantages。
LWJGL supports FBOs,但GLFW“只是”用于 OpenGL 和not for rendering 的跨平台设置。为了方便跨平台 FBO 使用,我建议在 GLFW 之上使用像 OGLplus 这样的库。有关渲染到纹理的示例,请参见 here。
【讨论】:
没错,我假设使用 FBO。但 FBO 不会创建 GL 上下文,这就是我问这个问题的原因。 如果您想要硬件加速,至少在 Windows 上,您必须先创建(隐藏)窗口才能创建 OpenGL 上下文。这是因为wglCreateContext 需要设备上下文 (DC),并且只有窗口的 DC 可以分配硬件加速像素格式。特别是你cannot render with hardware accelerated OpenGL into a memory DC。 那么你的意思是 Windows 版本的 LWJGL 中的 PBuffer 无论如何都会创建窗口然后将其删除? 我的意思是 Windows 上的任何硬件加速 OpenGL 应用程序都会创建一个(可能隐藏的)窗口,无论它是否使用 PBuffers、FBO 或根本不使用屏幕外渲染。 @MichaelIV:OpenGL 上下文创建始终取决于平台是否在窗口上。有 EGL API,但尚未得到广泛支持。【参考方案2】:Simple DirectMedia Layer (SDL) 库值得一试。它简化了跨平台的 OpenGL 上下文创建,能够使用内存表面进行离屏渲染。
您唯一需要做的就是根据您的平台将来自不同位置的 OpenGL 和 SDL 标头包含在内。这可以通过简单的预处理器指令来完成。
【讨论】:
【参考方案3】:据我所知,没有跨平台的方式来创建上下文,您必须创建自己的抽象,然后为每个平台实现它。
在 Windows 上,我使用以下代码创建了第二个上下文以在后台线程中加载内容(该程序使用 GLFW,但这不重要):
void Program::someFunction()
HDC hdc = wglGetCurrentDC();
HGLRC hglrc = wglGetCurrentContext();
HGLRC hglrc_new = wglCreateContext(hdc);
wglShareLists(hglrc, hglrc_new);
loadThread = boost::thread(&Program::loadFunc, this, hdc, hglrc_new);
/**
* Imports all our assets. Supposed to run in its own thread with its own OpenGL context.
* @param hdc The current device context.
* @param hglrc A OpenGL context thats shares its display list with the main rendering context.
*/
void Program::loadFunc(HDC hdc, HGLRC hglrc)
wglMakeCurrent(hdc, hglrc);
//Do stuff...
wglMakeCurrent(NULL, NULL);
wglDeleteContext(hglrc);
【讨论】:
在这种情况下,我最感兴趣的是 Linux 设置。以上是关于创建跨平台 OpenGL 离屏上下文的主要内容,如果未能解决你的问题,请参考以下文章
QXcbIntegration:无法创建平台 OpenGL 上下文,GLX 和 EGL 均未启用