以非常大的图像分辨率捕获OpenGL窗口的快照

时间:2011-06-27 09:12:10

标签: windows opengl resize

我目前正尝试使用glReadPixels拍摄各种相机位置和不同图像分辨率的OpenGL渲染3D世界的快照。我有两个实现OpenGL窗口程序的GUI库选择:Qt和freeglut。经过两次实验后,我意识到Qt并没有将QGLWidget快照的图像分辨率限制为桌面大小,但我不能对freeglut做同样的事情。

我希望我可以使用Qt进行这个快照抓取程序,但我只限于过剩,因为我的项目团队伙伴正在研究同一个程序的另一个模块,他们没有时间学习新的库和IDE(Qt Creator) 。他正在使用Visual Studio 2008。

无论如何,我是否可以创建一个不受桌面尺寸限制的过剩窗口,可以大到4000 x 2000?

2 个答案:

答案 0 :(得分:9)

使用OpenGL进行高分辨率渲染有点棘手。一个问题是像素所有权测试妨碍了。另一个是帧缓冲区(对象)的最大大小。第一个问题可以通过使用帧缓冲对象或PBuffer来克服。

第二个需要一些技巧:假设我们想要渲染大小为W×H的图像,其中W和H超过最大帧缓冲区大小;标记glGetInteger GL_MAX_VIEWPORT_SIZE,GL_MAX_TEXTURE_SIZE,GL_MAX_RENDERBUFFER_SIZE为您提供这些限制。因此,您需要做的是将目标图像分割成小于这些限制的图块,渲染这些图块然后重新组合它们。假设W_t和H_t是切片大小W_t := W / NH_t := H / M,我们有一个相应大小的PBuffer或Framebuffer对象。然后我们可以使用2循环渲染这些图块:

for m in 0 to M: for n in 0 to N:
    render_tile(n, m)

那么render_tile(n,m)怎么样?

render_tile(n,m):

显然我们将整个图块用作渲染缓冲区,所以

    glViewport(0, 0, W_t, H_t)

所以投影有什么变化。不知何故,我们要将投影与投影平面中的图块一起移动。投影平面也称为“近”平面。近平面的范围是right - lefttop - bottom,因此我们将近平面拆分为大小为(right - left) / N×(top - bottom) / M的切片,这就是我们需要使用的转移步长:

    shift_X = (right - left) / N
    shift_Y = (top - bottom) / M

    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    switch Projection:
         case Ortho:
             glOrtho( left + shift_X * n, left + shift_X * (n+1), 
                      bottom + shift_Y * m, bottom + shift_Y * (n+1),
                      near, far)
         case Perspective:
             glFrustum( left + shift_X * n, left + shift_X * (n+1), 
                      bottom + shift_Y * m, bottom + shift_Y * (n+1),
                      near, far)

    render_scene()

以防我们如何获得left, right, top, bottom观点:

right = -0.5 * tan(fov) * near
left = -right;
top = aspect * right
bottom = -top

答案 1 :(得分:4)

  

经过两次实验后,我意识到Qt并没有将QGLWidget快照的图像分辨率限制为桌面大小,但我不能对freeglut做同样的事情。

警告:如果您创建的窗口大于桌面,那些不在视图中的像素不会通过像素所有权测试。因此,这些像素的内容是 undefined 。他们可能包含您想要的内容,但可能没有。

对于任何不可见的像素都是如此,无论窗口是在桌面之外还是被另一个窗口覆盖。

无论如何,您不应该创建一个与桌面大小相同的窗口。您应该创建一个普通窗口,并创建一个包含大颜色和深度framebuffer objectrenderbuffer。对这些屏幕外缓冲区进行所有渲染。然后,您不必担心窗口的大小限制。