Home Up Tutorials FAQs Downloads Web Links Newsgroups About Me Search
 

Article

Saving a Screen Shot in a Direct3D Application

Written By Microsoft MVP: Eric DeBrosse
View a C++ adaptation of this VB article written by Robert Dunlop.
Content may not be duplicated without permission.
Updated: 2-25-2002

In this article, I will explain how to save a screen shot from a Visual Basic 6 Direct3D8 application. This could be difficult to figure out on your own, since the VB SDK documentation does not mention the SaveSurfaceToFile method of the D3DX8 class. One thing that seems to cause confusion is the SrcPalette parameter. Even if you are not using indexed colors, you must still pass an un-initialized PALETTEENTRY structure to the SaveSurfaceToFile function. Passing Nothing will cause the function to fail.

Have a look at a simple function:

Public Sub SaveScreenShot(ByVal sFilename As String)
    Dim oSurface As Direct3DSurface8
    Dim SrcPalette As PALETTEENTRY
    Dim SrcRect As RECT
    Dim DispMode As D3DDISPLAYMODE

    'get display dimensions
    g_oDevice.GetDisplayMode DispMode

    'create a surface to put front buffer on,
    'GetFrontBuffer always returns D3DFMT_A8R8G8B8
    Set oSurface = g_oDevice.CreateImageSurface(DispMode.Width, _
            DispMode.Height, _
            D3DFMT_A8R8G8B8)

    'get data from front buffer
    g_oDevice.GetFrontBuffer oSurface

    'we are saving entire area of this surface
    With SrcRect
        .Left = 0
        .Right = DispMode.Width
        .Top = 0
        .Bottom = DispMode.Height
    End With

    'save this surface to a BMP file
    g_oD3DX.SaveSurfaceToFile sFilename, _
            D3DXIFF_BMP, _
            oSurface, _
            SrcPalette, _
            SrcRect
End Sub
 

The above function assumes g_oDevice is a valid Direct3DDevice8 object and g_oD3DX is a valid D3DX8 object.

First, we need to get the dimensions of the screen. If we were to use the GetViewport method to get the dimensions, it would fail on a device created with the D3DCREATE_PUREDEVICE flag. Since GetFrontBuffer() always needs an image surface the size of the screen, (even when in windowed mode) the GetDisplayMode method is used and should not be an issue with pure devices.

Next, we create a new surface using the dimensions of our screen. The surface should be created using the D3DFMT_A8R8G8B8 format, because the GetFrontBuffer method always returns this format; regardless of the current back buffer format. We are using the GetFrontBuffer method to capture our screen shot, since it is the only way to capture anti-aliased output. The final call to SaveSurfaceToFile writes the entire captured surface to the specified bitmap file.

Notes: This function does not check for any errors! You should always set up some kind of error trap in any DirectX application, it makes it so much easier to debug. You could, for instance, validate the path and filename before actually trying to save the file. The function could also be easily modified to return a result code.

 
edebrosse@mvps.org
©2009 Eric DeBrosse

www.orionengine.com

Hit Counter
Visitors since 5/21/2002