Search code examples
c++directxhookscreenshotfullscreen

Why do DirectX fullscreen applications give black screenshots?


You may know that trying to capture DirectX fullscreen applications the GDI way (using BitBlt()) gives a black screenshot.

My question is rather simple but I couldn't find any answer: why? I mean technically, why does it give a black screenshot?

I'm reading a DirectX tutorial here: http://www.directxtutorial.com/Lesson.aspx?lessonid=9-4-1. It's written:

[...] the function BeginScene() [...] does something called locking, where the buffer in the video RAM is 'locked', granting you exclusive access to this memory.

Is this the reason? VRAM is locked so GDI can't access it and it gives a black screenshot? Or is there another reason? Like DirectX directly "talks" to the graphic card and GDI doesn't get it?

Thank you.


Solution

  • The reason is simple: performance.

    The idea is to render a scene as much as possible on the GPU out of lock-step with the CPU. You use the CPU to send the rendering buffers to the GPU (vertex, indices, shaders etc), which is overall really cheap because they're small, then you do whatever you want, physics, multiplayer sync etc. The GPU can just crunch the data and render it on its own.

    If you require the scene to be drawn on the window, you have to interrupt the GPU, ask for the rendering buffer bytes (LockRect), ask for the graphics object for the window (more interference with the GPU), render it and free every lock. You just lost any sort of gain you had by rendering on the GPU out of sync with the CPU. Even worse when you think of all the different CPU cores just sitting idle because you're busy "rendering" (more like waiting on buffer transfers).

    So what graphics drivers do is they paint the rendering area with a magic color and tell the GPU the position of the scene, and the GPU takes care of overlaying the scene over the displayed screen based on the magic color pixels (sort of a multi-pass pixel shader that takes from the 2nd texture when the 1st texture has a certain color for x,y, but not that slow). You get completely out of sync rendering, but when you ask the OS for its video memory, you get the magic color where the scene is because that's what it actually uses.

    Reference: http://en.wikipedia.org/wiki/Hardware_overlay