• 07/02/02 12:07 PM
    Sign in to follow this  

    Generating a Screenshot in DirectX 8.1

    Graphics and GPU Programming

    Myopic Rhino
    This article is about how to take a screen shot in DirectX 8.1 by reading data from the front buffer. This is the [b]only[/b] way to take a screen shot that has anti aliasing. It is recommended that you have a good understanding of C++ and DirectX 8 before reading this, but is not necessary.

    I'm going to start off by reviewing how double buffering works, so those of you who are already comfortable with it can skip this paragraph. Almost all games these days use a technique called double buffering when presenting game data on the screen. This is done by drawing the current scene in an offscreen memory location known as the back buffer. After the drawing is done the back buffer is then flipped or swapped with the buffer that's currently visible (the front buffer). A frame ends when one of these swaps/flips occur. Triple buffering is also used occasional and the only difference between this and double buffering is that there are two offscreen memory locations instead of just one.

    Now that you know what double buffering is I will explain why this is important to us. When taking a screen shot you want to get exactly what the user is seeing and write it to a file. You don't want the image to have only part of the scene in it and no anti aliasing (if FSAA is enabled). The front buffer holds the image that is exactly what the user is currently seeing. This makes it the ideal location to get our screen shot from.

    Taking the actual screen shot is pretty straightforward. You create a surface, copy the front buffer to it, write it to a file, and then release it.

    [indent][code]void TakeScreenShot(IDirect3DDevice8* device, char* file_name, int screenx, int screeny)
    {
    IDirect3DSurface8* frontbuf; //this is our pointer to the memory location containing our copy of the
    //front buffer

    //now we create the image that our screen shot will be copied into
    //NOTE: Surface format of the front buffer is D3DFMT_A8R8G8B8 when it is returned
    device->CreateImageSurface(screenx, screeny, D3DFMT_A8R8G8B8, &frontbuf);

    //now we copy the front buffer into our surface
    HRESULT hr = device->GetFrontBuffer(frontbuf);

    //error checking
    if(hr != D3D_OK)
    {
    //do error handling etc...
    frontbuf->Release(); //release the surface so there is no memory leak
    return;
    }

    //now write our screen shot to a bitmap file
    //the last 2 params are NULL because we want the entire front buffer and no palette
    D3DXSaveSurfaceToFile(file_name, D3DXIFF_BMP, frontbuf, NULL, NULL);

    //release the surface so there is no memory leak
    frontbuf->Release();
    }[/code][/indent] On a further note, you can get fancy with this. After you have a copy of the front buffer you can do whatever image processing you want with it before you write it to a file (such as putting a watermark of your company logo in the image).

    If you have any questions, comments, or errors to report please email me at [email="bob_corillian@hotmail.com"]bob_corillian@hotmail.com[/email]

    -Keith Newton, [url="http://www.agarthi.net/avatar/ak-studios/news.htm"]http://www.agarthi.n...tudios/news.htm[/url]


      Report Article
    Sign in to follow this  


    User Feedback

    Create an account or sign in to leave a review

    You need to be a member in order to leave a review

    Create an account

    Sign up for a new account in our community. It's easy!

    Register a new account

    Sign in

    Already have an account? Sign in here.

    Sign In Now

    There are no reviews to display.