在无窗口 GLX 程序中读取 OpenGL 的默认帧缓冲区

Reading OpenGL's default framebuffer in a windowless GLX program

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

我创建了一个基于 C++、GLX 和 GLEW 的应用程序,不需要 window。我用 glXOpenDisplay 得到一个显示器,用它来用 glXChooseFBConfig 找到合适的帧缓冲区(传递显示器的 DefaultScreen),用 glXGetVisualFromFBConfig 获取视觉信息,然后传递相关信息到glXCreateContext。我使该上下文成为当前上下文并初始化 GLEW。

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

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

表示 window "defines" 维度。在我的应用程序中,DefaultScreen 是否定义了尺寸?如果是这样,我该怎么做才能使默认帧缓冲区大于特别小的屏幕?

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

// 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);

and pass the relevant information to glXCreateContext. I then initialize GLEW.

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

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