【问题标题】:Reading OpenGL's default framebuffer in a windowless GLX program在无窗口 GLX 程序中读取 OpenGL 的默认帧缓冲区
【发布时间】:2017-04-18 03:02:55
【问题描述】:

我想在我的 Debian 机器上执行一些 3D 渲染并将结果带入客户端内存。

我创建了一个不需要窗口的基于 C++、GLX 和 GLEW 的应用程序。我得到一个带有glXOpenDisplay 的显示器,用它找到一个带有glXChooseFBConfig 的适当帧缓冲区(通过显示器的DefaultScreen),用glXGetVisualFromFBConfig 获得视觉信息,并将相关信息传递给glXCreateContext。我将该上下文设为当前并初始化 GLEW。

作为开始测试,我只是用各种颜色清除默认帧缓冲区;我现在想逐像素查询结果,大概是glReadPixels

但这似乎是我从根本上误解的地方:默认帧缓冲区的尺寸是多少?我从来没有为它定义初始高度或宽度,而且我没有看到这样做的方法。

Answers such as this one 暗示窗口“定义”了尺寸。在我的应用程序中,DefaultScreen 是否定义了尺寸?如果是这种情况,我该怎么做才能使默认帧缓冲区大于特别小的屏幕?

【问题讨论】:

    标签: c++ opengl glx


    【解决方案1】:

    并将相关信息传递给glXCreateContext。然后我初始化 GLEW。

    仅仅因为你有一个上下文并不意味着你可以立即使用它。考虑一下如果你有多个上下文会发生什么。在进行 OpenGL 调用之前,您必须使用glXMakeCurrentglXMakeContextCurrent 在当前线程上激活上下文。如果您查看这些功能的签名,您会发现除了 OpenGL 上下文之外,它们还采用 Drawable 作为参数。所以你也需要那个。

    对于无窗口操作,GLX 提供 PBuffers,它提供无窗口可绘制对象。或者,您可以使用未映射到屏幕的窗口。 PBuffers 允许在不使用帧缓冲区对象的情况下进行屏幕外渲染,但是使用它们的主帧缓冲区有点挑剔。我的建议是使用 0×0 大小的 PBuffer 和帧缓冲区对象。

    【讨论】:

    • 我正在使上下文成为最新的,但在我的描述中省略了它。更新以反映。 PBuffers 正是我正在寻找的,谢谢!
    • 碰巧的是,从 OpenGL 3.0 开始,您可以将None 作为可绘制对象传递给glXMakeCurrent,以对用户指定的帧缓冲区执行“离屏渲染”。不需要 PBuffer 和窗口。
    【解决方案2】:

    您需要使用帧缓冲对象。这些使用您指定尺寸的纹理。例如:

    // Generate framebuffer ID
    GLuint fb;
    glGenFramebuffers(1, &fb);
    
    // Make framebuffer active
    glBindFramebuffer(GL_FRAMEBUFFER, fb);
    
    // Attach color and depth textures (must have same dimensions)
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color_tex, 0);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_tex, 0);
    
    // Check framebuffer is valid
    assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
    

    【讨论】:

    • 如果我在创建上下文之前初始化了一个像素缓冲区会怎样?经过一些进一步的研究,这似乎是我正在寻找的更多。这样我仍然可以使用默认的帧缓冲区。
    • @Litty 您可以使用像素缓冲区对象作为将像素数据从帧缓冲区传输到应用程序的更有效方式,但您仍然需要帧缓冲区。
    • 我相信这些不同于 OpenGL 的 PBO。我不正确吗? khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/…
    • @Litty 正如 datenwolf 所描述的,您可以使用 0x0 pbuffer 作为利用上下文或创建隐藏窗口的一种方式。确实,您不必为了使用上下文而创建渲染目标,但是 OpenGL 既古老又古怪。我建议在 pbuffers 上使用帧缓冲区,因为它们是跨平台的,可能更灵活,而且不太可能出现错误。显然,如果您的目标是可能不支持 OpenGL 3 或帧缓冲区扩展的非常旧的硬件,您将不得不使用 pbuffers。
    • 事后我也得出了同样的结论;很好的推荐,谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-19
    • 1970-01-01
    • 2014-06-26
    • 1970-01-01
    • 2021-11-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多