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

我的任务是在 C++ 中为 Window 和 Linux 实现屏幕外 OpenGL 渲染器。我已经使用 LWJGL lib 用 Ja​​va 编写了这样一个版本。我使用了 PBuffer 对象,它在引擎盖下根据使用的创建 Pbuffers操作系统。首先我想重新实现完整的 PBuffer 创建逻辑,就像我在 LWJGL 的本机源代码中所做的那样。然后我阅读了 StackOverflow.com 上的 this 帖子,建议使用标准上下文创建,假设使用 @ 987654323@(这是跨平台的)但不是创建实际的窗口。这是正确的方法吗?在这种情况下,与使用 Pbuffer 相比有什么优缺点?

更新: 我只想强调我使用 FBO 来渲染帧,所以我的问题不是如何在屏幕外模式下渲染,而是如何在 Windows 和 Linux 操作系统中创建没有窗口的上下文。

【问题讨论】:

    标签: c++ opengl


    【解决方案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 设置。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-23
      • 1970-01-01
      相关资源
      最近更新 更多