创建跨平台 OpenGL 离屏上下文

Posted

技术标签:

【中文标题】创建跨平台 OpenGL 离屏上下文【英文标题】:Creating cross platform OpenGL off-screen context 【发布时间】:2013-01-10 08:16:08 【问题描述】:

我的任务是在 C++ 中为 Window 和 Linux 实现屏幕外 OpenGL 渲染器。我已经使用 LWJGL lib 用 Ja​​va 编写了这样一个版本。我使用了 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 离屏上下文的主要内容,如果未能解决你的问题,请参考以下文章

离屏渲染

iOS离屏渲染

QXcbIntegration:无法创建平台 OpenGL 上下文,GLX 和 EGL 均未启用

Yocto/Qt5.6:QXcbIntegration:无法创建平台 OpenGL 上下文

专业名词解释

使用 OpenGL 和来自不同线程的输入