?/TD>
Microsoft DirectX 9.0

Sample Framework


The Microsoft?DirectX?9.0 and Microsoft Direct3DŽ software development kit (SDK) graphics sample framework is an evolution from the DirectX 8.0 graphics sample framework. The SDK samples are installed by default in (SDK root)\Samples\C++\Multimedia. The folders of interest are Common and Direct3D. The sample framework is contained in the Common folder and the Direct3D samples, based on the graphics framework, are contained in the Direct3D folder.

The graphics framework consists of five source modules.

Corresponding header files are located in the (SDK root)\Samples\C++\Common\Include folder.

Each sample implements a subclass of CD3DApplication, which is typically named CMyD3DApplication, and a set of overridable methods that are shown below.

// Overridable functions for the 3-D scene created by the application.
virtual HRESULT ConfirmDevice(D3DCAPS9*,DWORD,D3DFORMAT)   { return S_OK; }
virtual HRESULT OneTimeSceneInit()                         { return S_OK; }
virtual HRESULT InitDeviceObjects()                        { return S_OK; }
virtual HRESULT RestoreDeviceObjects()                     { return S_OK; }
virtual HRESULT FrameMove()                                { return S_OK; }
virtual HRESULT Render()                                   { return S_OK; }
virtual HRESULT InvalidateDeviceObjects()                  { return S_OK; }
virtual HRESULT DeleteDeviceObjects()                      { return S_OK; }
virtual HRESULT FinalCleanup()                             { return S_OK; }

/*
    The prototypes for these methods are contained in D3dapp.h in the
    CD3Dapplication class. The samples create a new 
    application and override those methods that are needed by the
    application.
*/

Derived Class Example

This example uses a subset of the overridable methods. The class CMyD3DApplication contains the following methods. Each of these methods is explained below.

class CMyD3DApplication : public CD3DApplication
{
public:
    CMyD3DApplication();
protected:
    HRESULT ConfirmDevice( D3DCAPS9*, DWORD, D3DFORMAT );
    HRESULT DeleteRestoreDeviceObjects();
    HRESULT RestoreDeviceObjects();
    HRESULT FrameMove();
    HRESULT Render();
private:
    LPDIRECT3DVERTEXBUFFER9 m_pVB;         // Vertex buffer to hold vertices

Constructor

The constructor initializes the window title, enables depth buffering and initializes the vertex buffer.

CMyD3DApplication::CMyD3DApplication()
{
    m_strWindowTitle    = _T("D3D Example");    // title bar string
    m_bUseDepthBuffer   = TRUE;                 // enable depth buffer
    m_pVB               = NULL;                 // initialize  
}

The window title is a wide character string that is visible in the title bar or the window class when the application is invoked. It is optional.

The base class contains a member variable for enabling depth buffering. The default value for this Boolean variable is FALSE, which disables depth buffering.

The window title is a TCHAR string that supports Unicode and ANSI characters. It is visible in the title bar when the application is invoked. The string will persist for the lifetime of CMyD3DApplication.

Confirm Devices

The prototype is as follows:

HRESULT ConfirmDevice(D3DCAPS *pCaps, DWORD dwBehavior,
		      D3DFORMAT fmtBackBuffer)
}

[in] pCaps - Pointer to the D3DCAPS structure for the device to be confirmed. Examine the members of this structure to determine if the required capabilities for the application are present on the proposed device.

[in] dwBehavior - Zero or more flags corresponding to the behavior flag in IDirect3D9::CreateDevice. The following flags indicate the behavior of the proposed device.

D3DCREATE_PUREDEVICE
D3DCREATE_HARDWARE_VERTEXPROCESSING
D3DCREATE_SOFTWARE_VERTEXPROCESSING
D3DCREATE_MIXED_VERTEXPROCESSING
}

CD3DApplication will attempt to confirm a device behavior in the following order.

Only devices indicating support for a pure device will be confirmed with the pure device behavior.

Only devices indicating support for hardware transform and lighting will be confirmed for hardware vertex processing.

[in] fmtBackBuffer - Proposed format of the back buffer associated with the device's default swap chain.

When overriding this method, the application should return S_OK when the proposed device capabilities, behavior and back buffer format are acceptable. Otherwise, the application should return E_FAIL.

DeleteDeviceObjects

DeleteDeviceObjects is called when the application is exiting, or if the device is being changed. You use this method to delete device dependent objects, such as the vertex buffer.

HRESULT CVShader1::DeleteDeviceObjects()
{
    m_pQuadVB->Release();
    m_pQuadVB = NULL;
    return S_OK;

RestoreDeviceObjects

This method is called when the application needs to restore device memory objects and device states. This is required after a DirectX device is created or resized. This method does most of the work of creating objects and initializing render states.

HRESULT CMyD3DApplication::RestoreDeviceObjects()
{
    // Create the vertex buffer. Allocate enough memory (from the default pool) 
	//   to hold the custom vertices. Specify the flexible vertex format (FVF),
    //   so the vertex buffer knows what data it contains.
    if( FAILED( m_pd3dDevice->CreateVertexBuffer(
                          NUM_VERTS*sizeof(CUSTOMVERTEX),
                          0,
                          D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &m_pVB ) ) )
    {
        return E_FAIL;
    }
    // Fill the vertex buffer. First, lock the vertex buffer to get access to
    //   the vertices. This mechanism is required because vertex buffers 
    //   may be in device memory. Then use memcpy to do a fast data copy.
    VOID* pVertices;
    if( FAILED( m_pVB->Lock( 0, sizeof(g_Vertices), 
     (BYTE**)&pVertices, 0 ) ) )
        return E_FAIL;
    memcpy( pVertices, g_Vertices, sizeof(g_Vertices) );
    m_pVB->Unlock();

    // Set the projection matrix. The size of the back buffer comes from the
    //   base class.
    D3DXMATRIX matProj;
    FLOAT fAspect = m_d3dsdBackBuffer.Width / 
                    (FLOAT)m_d3dsdBackBuffer.Height;
    D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, fAspect, 
                                 1.0f, 100.0f );
    m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );

    // Set up the view matrix. A view matrix can be defined from an eye 
    //   point, a look-at point, and an up-direction vector. In this example, 
    //   the eye position is (0,1,-4) the look-at point is (0,0,0) and the 
    //   up vector is (0,1,0).
    D3DXMATRIX matView;
    D3DXMatrixLookAtLH( &matView, &D3DXVECTOR3( 0.0f, 1.0f,-4.0f ),
                                  &D3DXVECTOR3( 0.0f, 0.0f, 0.0f ),
                                  &D3DXVECTOR3( 0.0f, 1.0f, 0.0f ) );
    m_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );

    // Set up default texture states.
    // Set up render states (this is only one example render state).
    m_pd3dDevice->SetRenderState( D3DRS_CULLMODE,     D3DCULL_NONE );

    return S_OK;

This method creates the vertex buffer and copies the vertex data into it. It creates the view and projection matrices, which define the camera orientation to the object in the vertex buffer. Texture stage states can be set in this method although none are present in this example. Render states that are not likely to change are set. These determine how the scene renders.

FrameMove

This method contains actions that happen every frame, such as animation. In this example, it adds a y-axis rotation to the world transform.

HRESULT CMyD3DApplication::FrameMove()
{
    // For our world matrix, just rotate the object about the y-axis.
    D3DXMATRIX matWorld;
    D3DXMatrixRotationY( &matWorld, ::TimeGetTime()/150.0f );
    m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );

    return S_OK;
}

The Windows method ::TimeGetTime returns the current time. When it is divided by 150, it generates an incremental angle to rotate the object.

Render

This method is called when it is time to render the output. It clears the view port and renders the scene and state changes.

HRESULT CMyD3DApplication::Render()
{
    // Clear the viewport.
    m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 
		D3DCOLOR_XRGB(0,0,0), 1.0f, 0L );

    // Begin the scene.
    if( SUCCEEDED( m_pd3dDevice->BeginScene() ) )
    {
        m_pd3dDevice->SetStreamSource( 0, m_pVB, sizeof(CUSTOMVERTEX) );
	    m_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
        m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, NUM_TRIS );
        m_pd3dDevice->EndScene();
    }

    return S_OK;
}

The Render method first clears the viewport using Clear. Then, within the BeginScene/EndScene pair, it uses SetStreamSource to inform the runtime that it uses vertex buffer m_pVB with a stride of the size of the custom vertex type. This method next informs the runtime that it uses a flexible vertex format (FVF) shader, the simplest type. Finally, it invokes DrawPrimitive to render the quad.

Other Functions

DeleteDeviceObjects is called when the application exits or if the device changes. Use this method to delete device-dependent objects.

ConfirmDevice checks the device for some minimum set of capabilities. It is called during the device initialization.

InvalidateDeviceObjects is called when the device dependent objects might be removed. Device dependent objects such as vertex buffers are usually added to this method.

OneTimeSceneInit is provided for code that needs to run during the initial application startup.

Discussion List

Where do you find other developers working with graphics? One place is the DirectX developer's mailing list. It is a technical discussion forum for DirectX developers covering the areas of graphics, networking, and input. Archives of the mailing list can be found at DirectX Dev World Wide Web link. Like any mailing list, this is not a technical support forum. However, it is a good source for information about DirectX.



© 2002 Microsoft Corporation. All rights reserved.