Exemple #1
0
//-----------------------------------------------------------------------------
// Name: Render()
// Desc: Called once per frame, the call is the entry point for 3d
//       rendering. This function sets up render states, clears the
//       viewport, and renders the scene.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::Render()
{
    // Clear the viewport
    m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
                         0x00000000, 1.0f, 0L );

    // Begin the scene
    if( SUCCEEDED( m_pd3dDevice->BeginScene() ) )
    {
        // Draw the quad, with the volume texture
        m_pd3dDevice->SetTexture( 0, m_pTexture );
//        m_pd3dDevice->SetVertexShader( D3DFVF_VERTEX );
        m_pd3dDevice->SetStreamSource( 0, m_pVB, sizeof(VERTEX) );
        m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2);

        // Output statistics
        m_pFont->DrawText( 2,  0, D3DCOLOR_ARGB(255,255,255,0), m_strFrameStats );
        m_pFont->DrawText( 2, 20, D3DCOLOR_ARGB(255,255,255,0), m_strDeviceStats );

        // End the scene.
        m_pd3dDevice->EndScene();
    }

    return S_OK;
}
Exemple #2
0
//-----------------------------------------------------------------------------
// Name: Render()
// Desc: Called once per frame, the call is the entry point for 3d
//       rendering. This function sets up render states, clears the
//       viewport, and renders the scene.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::Render()
{
    // Clear the viewport
    m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0L );

    // Begin the scene
    if( SUCCEEDED( m_pd3dDevice->BeginScene() ) )
    {
        // Render the Skybox
        {
            // Center view matrix for skybox and disable zbuffer
            D3DXMATRIX matView, matViewSave;
            m_pd3dDevice->GetTransform( D3DTS_VIEW, &matViewSave );
            matView = matViewSave;
            matView._41 = 0.0f; matView._42 = -0.3f; matView._43 = 0.0f;
            m_pd3dDevice->SetTransform( D3DTS_VIEW,      &matView );
            m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, FALSE );
            // Some cards do not disable writing to Z when 
            // D3DRS_ZENABLE is FALSE. So do it explicitly
            m_pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );

            // Render the skybox
            m_pSkyBox->Render( m_pd3dDevice );

            // Restore the render states
            m_pd3dDevice->SetTransform( D3DTS_VIEW,      &matViewSave );
            m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
            m_pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE);
        }

        // Draw the terrain
        m_pTerrain->Render( m_pd3dDevice );

        // Draw the trees
        DrawTrees();

        // Output statistics
        m_pFont->DrawText( 2,  0, D3DCOLOR_ARGB(255,255,255,0), m_strFrameStats );
        m_pFont->DrawText( 2, 20, D3DCOLOR_ARGB(255,255,255,0), m_strDeviceStats );

        // End the scene.
        m_pd3dDevice->EndScene();
    }

    return S_OK;
}
Exemple #3
0
//-----------------------------------------------------------------------------
// Name: Render()
// Desc: Called once per frame, the call is the entry point for 3d
//       rendering. This function sets up render states, clears the
//       viewport, and renders the scene.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::Render()
{
    // Clear the backbuffer
    m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
                         0x00000000, 1.0f, 0L );

    // Begin the scene 
    if( FAILED( m_pd3dDevice->BeginScene() ) )
        return S_OK;

    // Stage 0 is the base texture, with the height map in the alpha channel
    m_pd3dDevice->SetTexture( 0, m_pEmbossTexture );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP,   D3DTOP_SELECTARG1 );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
    
    if( m_bShowEmbossMethod )
    {
        // Stage 1 passes through the RGB channels (SELECTARG2 = CURRENT), and 
        // does a signed add with the inverted alpha channel. The texture coords
        // associated with Stage 1 are the shifted ones, so the result is:
        //    (height - shifted_height) * tex.RGB * diffuse.RGB
        m_pd3dDevice->SetTexture( 1, m_pEmbossTexture );
        m_pd3dDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 1 );
        m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_SELECTARG2 );
        m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE );
        m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_CURRENT );
        m_pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_ADDSIGNED );
        m_pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE|D3DTA_COMPLEMENT );
        m_pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAARG2, D3DTA_CURRENT );

        // Set up the alpha blender to multiply the alpha channel (monochrome emboss)
        // with the src color (lighted texture)
        m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
        m_pd3dDevice->SetRenderState( D3DRS_SRCBLEND,  D3DBLEND_SRCALPHA );
        m_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ZERO );
    }

    // Render the object
    m_pObject->Render( m_pd3dDevice );
    
    // Restore render states
    m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
    m_pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
    m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );

    // Draw some text
    m_pFont->DrawText(   2,  0, D3DCOLOR_ARGB(255,255,255,0), m_strFrameStats );
    m_pFont->DrawText(   2, 20, D3DCOLOR_ARGB(255,255,255,0), m_strDeviceStats );
    m_pFont->DrawText(   2, 40, 0xffffff00, _T("Move the light with the mouse") );
    m_pFont->DrawText(   2, 60, 0xffffff00, _T("Emboss-mode:") );
    m_pFont->DrawText( 130, 60, 0xffffffff, m_bShowEmbossMethod ? _T("ON") : _T("OFF") );

    // End the scene.
    m_pd3dDevice->EndScene();

    return S_OK;
}
Exemple #4
0
//-----------------------------------------------------------------------------
// Name: Render()
// Desc: Called once per frame, the call is the entry point for 3d
//       rendering. This function sets up render states, clears the
//       viewport, and renders the scene.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::Render()
{
    // Begin the scene
    if( FAILED( m_pd3dDevice->BeginScene() ) )
        return S_OK;

    // Render the background
    m_pd3dDevice->SetTexture( 0, m_pBackgroundTexture );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_SELECTARG1 );
    m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP,   D3DTOP_DISABLE );

    m_pd3dDevice->SetVertexShader( D3DFVF_BACKGROUNDVERTEX );
    m_pd3dDevice->SetStreamSource( 0, m_pBackgroundVB, sizeof(BACKGROUNDVERTEX) );
    m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );

    // Render the lens
    m_pd3dDevice->SetTexture( 0, m_pBumpMapTexture );
    m_pd3dDevice->SetTexture( 1, m_pBackgroundTexture );

    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_BUMPENVMAP );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP,   D3DTOP_DISABLE );

    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_BUMPENVMAT00,   F2DW(0.2f) );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_BUMPENVMAT01,   F2DW(0.0f) );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_BUMPENVMAT10,   F2DW(0.0f) );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_BUMPENVMAT11,   F2DW(0.2f) );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_BUMPENVLSCALE,  F2DW(1.0f) );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_BUMPENVLOFFSET, F2DW(0.0f) );

    m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP,   D3DTOP_SELECTARG1 );
    m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE );
    m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_CURRENT );
    m_pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP,   D3DTOP_DISABLE );

    // Generate texture coords depending on objects camera space position
    D3DXMATRIX mat;
    mat._11 = 0.5f; mat._12 = 0.0f;
    mat._21 = 0.0f; mat._22 =-0.5f;
    mat._31 = 0.0f; mat._32 = 0.0f;
    mat._41 = 0.5f; mat._42 = 0.5f;

    // Scale-by-z here
    D3DXMATRIX matView, matProj;
    m_pd3dDevice->GetTransform( D3DTS_VIEW,       &matView );
    m_pd3dDevice->GetTransform( D3DTS_PROJECTION, &matProj );
    D3DXVECTOR3 vEyePt( matView._41, matView._42, matView._43 );
    FLOAT       z = D3DXVec3Length( &vEyePt );
    mat._11 *= ( matProj._11 / ( matProj._33 * z + matProj._34 ) );
    mat._22 *= ( matProj._22 / ( matProj._33 * z + matProj._34 ) );

    m_pd3dDevice->SetTransform( D3DTS_TEXTURE1, &mat );
    m_pd3dDevice->SetTextureStageState( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 );
    m_pd3dDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION | 1);

    // Position the lens
    D3DXMATRIX matWorld;
    D3DXMatrixTranslation( &matWorld, 0.7f * (1000.0f-256.0f)*m_fLensX,
                                      0.7f * (1000.0f-256.0f)*m_fLensY,
                                      0.0f );
    m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );

    m_pd3dDevice->SetVertexShader( D3DFVF_BUMPVERTEX );
    m_pd3dDevice->SetStreamSource( 0, m_pLensVB, sizeof(BUMPVERTEX) );

    // Verify that the texture operations are possible on the device
    DWORD dwNumPasses;
    if( FAILED( m_pd3dDevice->ValidateDevice( &dwNumPasses ) ) )
    {
        // The right thing to do when device validation fails is to try
        // a different rendering technique.  This sample just warns the user.
        m_bDeviceValidationFailed = TRUE;
    }

    // Render the lens
    m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );

    // Output statistics
    m_pFont->DrawText( 2,  0, D3DCOLOR_ARGB(255,255,255,0), m_strFrameStats );
    m_pFont->DrawText( 2, 20, D3DCOLOR_ARGB(255,255,255,0), m_strDeviceStats );

    if( m_bDeviceValidationFailed )
    {
        m_pFont->DrawText( 2, 40, D3DCOLOR_ARGB(255,255,0,0), 
            _T("Warning: Device validation failed.  Rendering may not look right.") );
    }

    // End the scene.
    m_pd3dDevice->EndScene();

    return S_OK;
}
Exemple #5
0
//-----------------------------------------------------------------------------
// Name: Render()
// Desc: Called once per frame, the call is the entry point for 3d
//       rendering. This function sets up render states, clears the
//       viewport, and renders the scene.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::Render()
{
    // Begin the scene
    if( SUCCEEDED( m_pd3dDevice->BeginScene() ) )
    {
        // Render the Skybox
        {
            D3DXMATRIX matWorld;
            D3DXMatrixScaling( &matWorld, 10.0f, 10.0f, 10.0f );

            D3DXMATRIX matView(m_matView);
            matView._41 = matView._42 = matView._43 = 0.0f;

            m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
            m_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
            m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &m_matProject );

            m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
            m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_SELECTARG1 );
            m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
            m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
            m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ADDRESSU,  D3DTADDRESS_MIRROR );
            m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ADDRESSV,  D3DTADDRESS_MIRROR );

            // Always pass Z-test, so we can avoid clearing color and depth buffers
            m_pd3dDevice->SetRenderState( D3DRS_ZFUNC, D3DCMP_ALWAYS );
            m_pSkyBox->Render( m_pd3dDevice );
            m_pd3dDevice->SetRenderState( D3DRS_ZFUNC, D3DCMP_LESSEQUAL );
        }


        // Render the environment-mapped ShinyTeapot
        {
            // Set transform state
            D3DXMATRIX matViewProject;
            D3DXMatrixMultiply( &matViewProject, &m_matView, &m_matProject );

            D3DXMATRIX matViewInv;
            D3DXMatrixInverse( &matViewInv, NULL, &m_matView );
            D3DXVECTOR4 vecPosition( matViewInv._41, matViewInv._42, matViewInv._43, 1.0f );


            m_pEffect->SetMatrix( "matWorld", &m_matWorld );
            m_pEffect->SetMatrix( "matViewProject", &matViewProject );
            m_pEffect->SetVector( "vecPosition", &vecPosition );


            // Draw teapot
            LPDIRECT3DVERTEXBUFFER8 pVB;
            LPDIRECT3DINDEXBUFFER8 pIB;

            m_pShinyTeapot->m_pLocalMesh->GetVertexBuffer( &pVB );
            m_pShinyTeapot->m_pLocalMesh->GetIndexBuffer( &pIB );

            m_pd3dDevice->SetStreamSource( 0, pVB, sizeof(ENVMAPPEDVERTEX) );
            m_pd3dDevice->SetIndices( pIB, 0 );

            UINT uPasses;
            m_pEffect->Begin( &uPasses, 0 );

            for( UINT iPass = 0; iPass < uPasses; iPass++ )
            {
                m_pEffect->Pass( iPass );

                m_pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 
                    0, m_pShinyTeapot->m_pLocalMesh->GetNumVertices(),
                    0, m_pShinyTeapot->m_pLocalMesh->GetNumFaces() );

            }

            m_pEffect->End();

            SAFE_RELEASE( pVB );
            SAFE_RELEASE( pIB );
        }


        // Output statistics
        m_pFont->DrawText( 2,  0, D3DCOLOR_ARGB(255,255,255,0), m_strFrameStats );
        m_pFont->DrawText( 2, 20, D3DCOLOR_ARGB(255,255,255,0), m_strDeviceStats );


        // End the scene.
        m_pd3dDevice->EndScene();
    }

    return S_OK;
}
Exemple #6
0
//-----------------------------------------------------------------------------
// Name: Render
// Desc:
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::Render()
{   
    HRESULT hr;

    if(FAILED(hr = m_pd3dDevice->BeginScene()))
        return hr;

    // Draw Environment
    FLOAT fAspectRatio = (FLOAT)m_d3dsdBackBuffer.Width / (FLOAT)m_d3dsdBackBuffer.Height;
    D3DXMatrixPerspectiveFovRH(&m_matProjection, D3DXToRadian(60.0f), fAspectRatio, 0.1f, 2000.0f);
    m_pd3dDevice->SetTransform(D3DTS_PROJECTION, &m_matProjection);    

    if(m_bDrawEnvironment)
    {
        D3DXMATRIX mat(m_matView);
        mat._41 = mat._42 = mat._43 = 0.0f;
        m_pd3dDevice->SetTransform(D3DTS_VIEW, &mat);

        m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
        m_pd3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);

        m_Environment.Draw();

        m_pd3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
        m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE);
    }
    else
    {
        m_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
    }

    m_pd3dDevice->SetTransform(D3DTS_VIEW, &m_matView);

    // Draw water
    if(m_bDrawWater)
    {
        // Setup matrices
        if(m_pEffect->IsParameterUsed("mENV"))
        {
            D3DXMATRIX matP(m_matPosition);
            matP._41 = matP._42 = matP._43 = 0.0f;

            D3DXMATRIX mat;
            D3DXMatrixScaling(&mat, 1.0f, 1.0f, -1.0f);

            D3DXMatrixMultiply(&mat, &matP, &mat);

            // matCube
            m_pEffect->SetMatrix("mENV", &mat);
        }

        // Draw water
        UINT uPasses;
        m_pEffect->Begin(&uPasses, 0);

        for(UINT uPass = 0; uPass < uPasses; uPass++)
        {
            m_pEffect->Pass(uPass);
            m_Water.DrawSurface();
        }

        m_pEffect->End();
    }

    // Show info
    m_pFont->DrawText( 2,  0, D3DCOLOR_ARGB(255,255,255,0), m_strFrameStats );
    m_pFont->DrawText( 2, 20, D3DCOLOR_ARGB(255,255,255,0), m_strDeviceStats );

    TCHAR szText[100];
    wsprintf( szText, _T("Using Technique %d"), m_iTechnique );
    m_pFontSmall->DrawText( 2, 40, D3DCOLOR_ARGB(255,255,100,100), szText );
    
    if( m_bShowHelp )
    {
        m_pFontSmall->DrawText(  2, 60, D3DCOLOR_ARGB(255,100,100,200),
                                _T("Keyboard controls:") );
        m_pFontSmall->DrawText( 20, 80, D3DCOLOR_ARGB(255,100,100,200),
                                _T("Add Drop\n")
                                _T("Next Technique\n")
                                _T("Next Tech. (no validate)\n")
                                _T("Prev Technique\n")
                                _T("Prev Tech. (no validate)\n")
                                _T("Move\nTurn\nPitch\nSlide\n")
                                _T("Help\nChange device\nExit") );
        m_pFontSmall->DrawText( 210, 80, D3DCOLOR_ARGB(255,100,100,200),
                                _T("D\n")
                                _T("PageDn\nShift-PageDn\n")
                                _T("PageUp\nShift-PageUp\n")
                                _T("W,S\nE,Q\nA,Z\nArrow keys\n")
                                _T("F1\nF2\nEsc") );
    }
    else
    {
        m_pFontSmall->DrawText(  2, 60, D3DCOLOR_ARGB(255,100,100,200), 
                           _T("Press F1 for help") );
    }


    if(FAILED(hr = m_pd3dDevice->EndScene()))
        return hr;

    return S_OK;
}
Exemple #7
0
//-----------------------------------------------------------------------------
// Name: Render()
// Desc: Called once per frame, the call is the entry point for 3d
//       rendering. This function sets up render states, clears the
//       viewport, and renders the scene.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::Render()
{
    DWORD xOffset;
    DWORD yOffset;
    D3DXMATRIX matWorld;
    D3DXMATRIX matTemp;
    DWORD cTriangles = 0;
    FLOAT fTrisPerSec;
    TCHAR strInfo[120];
    TCHAR *szOptString;

    // Clear the scene
    m_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
                         0x000000ff, 1.0f, 0x00000000 );

    // Draw scene
    if( SUCCEEDED( m_pd3dDevice->BeginScene() ) )
    {
        for (xOffset = 0; xOffset < m_cObjectsPerSide; xOffset++)
        {
            for (yOffset = 0; yOffset < m_cObjectsPerSide; yOffset++)
            {
                D3DXMatrixTranslation( &matTemp, m_fObjectRadius * xOffset * 2,
                                                  m_fObjectRadius * yOffset * 2,
                                                  0 );
                D3DXMatrixMultiply( &matWorld, &m_matWorld, &matTemp );
                m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );

                if (m_bShowVertexCacheOptimized)
                    DrawMeshData(&m_MeshVertexCacheOptimized);
                else if (m_bShowStripReordered)
                    DrawMeshData(&m_MeshStripReordered);
                else
                    DrawMeshData(&m_MeshAttrSorted);
            }
        }

        // Calculate and show triangles per sec, a reasonable throughput number
        if (m_MeshAttrSorted.m_pMesh != NULL)
            cTriangles = m_MeshAttrSorted.m_pMesh->GetNumFaces() * m_cObjectsPerSide * m_cObjectsPerSide;
        else
            cTriangles = 0;

        fTrisPerSec = m_fFPS * cTriangles;

        if (m_bShowVertexCacheOptimized)
            szOptString = _T("VCache Optimized");
        else if (m_bShowStripReordered)
            szOptString = _T("Strip Reordered");
        else
            szOptString = _T("Unoptimized");

        // Output statistics
        wsprintf( strInfo, _T("%s, %ld tris per sec, %ld triangles"),
                                    szOptString, (DWORD)fTrisPerSec, cTriangles);

        m_pFont->DrawText( 2, 0, D3DCOLOR_ARGB(255,255,255,0), m_strFrameStats );
        m_pFont->DrawText( 2, 20, D3DCOLOR_ARGB(255,255,255,0), m_strDeviceStats );
        m_pFont->DrawText( 2, 40, D3DCOLOR_ARGB(255,255,255,0), strInfo);


        m_pd3dDevice->EndScene();
    }

    return S_OK;
}