I'm trying to draw on the screen using GDI calls. I can see my text but it flickers badly. How can I fix this?
This is a common problem that people encounter. It is quite easy to retrieve a
handle to the active window and obtain a device context for the screen. You can then issue standard
GDI calls and expect them to be drawn accordingly on the screen.
Unfortunately the flickering problem can’t be avoided. The issue is caused by the fact that most games are double-buffered and
GDI only supports single-buffered devices. Whenever you issue
GDI calls they are always affecting the same buffer. If the game is double buffered you will see your text half the time, if it’s triple buffered only a third. As far as I know there is no way to obtain a unique device context for the back buffers.
How can I draw my own graphics on the screen?
Unfortunately there is no simple way to draw graphics on screen. This part is therefore fairly technical. If you don’t understand some of the terms I’d recommend doing a search for the keywords on google.
Fraps works by patching directly into the underlying graphics
API. Doing things this way allows Fraps to issue graphics commands as if it were the game itself, avoiding having to do a large amount of setup beforehand. There are two techniques that can be used to hook into the
API.
The first method is referred to as “
API hooking”. Basically you want to obtain the address of the graphics function in memory, and patch this such that your code will get called whenever the game tries to use this function.
The other method is to write a “
DLL wrapper”. Here you want to write your own
DLL that exports the same functions as the graphics
DLL. The idea is to rename the original
DLL and put your
DLL in its place. Then when your
DLL is loaded, you proceed to load the original
DLL and pass any function that is called through to it. Creating a
DLL wrapper for
DirectX is reasonably easy because there are only a few functions exported from the
DLL.
OpenGL however exports ALL of its
API calls, which means that it can be very time consuming to build the stubs for all of the functions. If you want to pursue this method it may be easier to download and modify an existing
OpenGL wrapper such as GLtrace.
When you have successfully hooked into the graphics
API it is simply a matter of saving and restoring the state before and after you have issued your graphics commands. To learn how to draw graphics you should consult the
DirectX and
OpenGL SDK’s.
Other ideas that you might want to pursue if you want something up and running quickly:
If it’s only for one game, search through the game code for a function that displays text on screen. Most games have to output text at some stage, so utilising their routine may save you the hassle of implementing your own.
You could also try forcing the game to run in windowed mode. As an example, you could hook the CreateDevice function in DirectX8 and ensure that the Windowed flag is always set TRUE. With the game running in a window, you can draw in your own application alongside.
I have heard (but not verified) that it is possible to use
DirectX overlays to draw on top of the game screen. This may be an easy option if performance is not an issue. Overlay documentation can be found in the
DirectX SDK.
How do I know when a new frame has been drawn? What functions must I hook?
Hooking is currently performed on separate functions for DirectDraw, Direct3D8, and
OpenGL. These are:
Flip (for
DirectX 7 and earlier - DDRAW.DLL)
Present (for
DirectX 8 – D3D8.DLL)
wglSwapBuffers (for
OpenGL)
Note that
DirectX is class based. This means that Flip and Present are not exported from the
DLL directly. You must take the parent class and obtain the function pointers directly from an offset within the class (or subclasses). Consult the header files in the DX
SDK in order to determine the offsets of the function pointers.