clinuxopenglhookglx

OpenGL Hooking -- Rendering to an arbitrarily-sized FBO


So I'm trying to make an OpenGL application render at a higher resolution than it normally would. I've already created a shared library that hooks most of the relevant GLX/OpenGL functions. Here's my current approach (at a high-level):

When my hooked SwapBuffers() is called
    Unbind my FBO
    Call the (original/unhooked) SwapBuffers()
    Bind my FBO
    Set the viewport to (0, 0, HIGH_RES_X, HIGH_RES_Y)
    Set the scissor region to (0, 0, HIGH_RES_X, HIGH_RES_Y)
    return

This approach doesn't seem to work for (most) applications. I suspect that is because some applications perform texture lookups (for screen-space operations) by dividing glFragCoord.xy by a uniform that represents their screen resolution (to convert from screen space to texture coordinates).

If resizing the output isn't possible, I wonder if it is possible to obtain the contents drawn onto the default framebuffer (i.e both the color and the depth buffer) without using glReadPixels. Ideally there would be a way to access this data in the form of a texture (so it's already on the GPU). I've heard things about Pixel Buffer Objects -- would using one of these prevent a pipeline stall?


Solution

  • The technique I proposed actually works for a handful of applications, but most of the time it just doesn't work.

    If you just want to extract the color/depth buffer, you can either use a pool of PBOs with glReadPixels or use glBlitFramebuffer. The former is not an option if latency is a concern; the latter works fairly well (see this example from the reshade project)