Beispiel #1
0
//-----------------------------------------------------------------------------
// Name: InitDeviceObjects()
// Desc: Initialize scene objects.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::InitDeviceObjects()
{
	// Init the font
    m_pFont->InitDeviceObjects( m_pd3dDevice );

    // Load texture map. Note that this is a special textures, which has a
    // height field stored in the alpha channel
    if( FAILED( D3DUtil_CreateTexture( m_pd3dDevice, _T("emboss1.tga"), 
                                       &m_pEmbossTexture, D3DFMT_A8R8G8B8 ) ) )
        return D3DAPPERR_MEDIANOTFOUND;

    // Load geometry
    if( FAILED( m_pObject->Create( m_pd3dDevice, _T("tiger.x") ) ) )
        return D3DAPPERR_MEDIANOTFOUND;

    // Set attributes for the geometry
    m_pObject->SetFVF( m_pd3dDevice, D3DFVF_EMBOSSVERTEX );
    m_pObject->UseMeshMaterials( FALSE );

    // Compute the object's tangents and binormals, whaich are needed for the 
    // emboss-tecnhique's texture-coordinate shifting calculations
    ComputeTangentsAndBinormals();

    return S_OK;
}
Beispiel #2
0
//-----------------------------------------------------------------------------
// Name: RestoreDeviceObjects()
// Desc: Restore device-memory objects and state after a device is created or
//       resized.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::RestoreDeviceObjects()
{
    // Restore the device objects for the meshes and fonts
    m_pTerrain->RestoreDeviceObjects( m_pd3dDevice );
    m_pSkyBox->RestoreDeviceObjects( m_pd3dDevice );
    m_pFont->RestoreDeviceObjects();

    // Set the transform matrices (view and world are updated per frame)
    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 default texture states
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_SELECTARG1 );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP,   D3DTOP_SELECTARG1 );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ADDRESSU,  D3DTADDRESS_CLAMP );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ADDRESSV,  D3DTADDRESS_CLAMP );

    m_pd3dDevice->SetRenderState( D3DRS_DITHERENABLE, TRUE );
    m_pd3dDevice->SetRenderState( D3DRS_ZENABLE,      TRUE );
    m_pd3dDevice->SetRenderState( D3DRS_LIGHTING,     FALSE );

    return S_OK;
}
Beispiel #3
0
//-----------------------------------------------------------------------------
// Name: InvalidateDeviceObjects()
// Desc: Called when the device-dependent objects are about to be lost.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::InvalidateDeviceObjects()
{
    m_pFont->InvalidateDeviceObjects();
    m_pObject->InvalidateDeviceObjects();

    return S_OK;
}
Beispiel #4
0
//-----------------------------------------------------------------------------
// Name: InitDeviceObjects()
// Desc: Initialize scene objects.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::InitDeviceObjects()
{
    HRESULT hr;

    m_pFont->InitDeviceObjects( m_pd3dDevice );

	ilInit();
	iluInit();
	ilutInit();
	ilutD3D8TexFromFile(m_pd3dDevice, __argv[1], &m_pTexture);
	//D3DXCreateTextureFromFile(m_pd3dDevice, __argv[1], &m_pTexture);

    // Create a vertex buffer
    {
        if( FAILED( hr = m_pd3dDevice->CreateVertexBuffer( 4*sizeof(VERTEX),
                                           D3DUSAGE_WRITEONLY,
                                           D3DFVF_VERTEX,
                                           D3DPOOL_MANAGED, &m_pVB ) ) )
            return hr;

        VERTEX* pVertices;
        m_pVB->Lock( 0, 4*sizeof(VERTEX), (BYTE**)&pVertices, 0 );
        memcpy( pVertices, g_vVertices, sizeof(VERTEX)*4 );
        m_pVB->Unlock();
    }

    return S_OK;
}
Beispiel #5
0
void ShutdownUtils()
{
	linear_copy_sampler.reset();
	point_copy_sampler.reset();
	font.Shutdown();
	SAFE_DELETE(util_vbuf);
}
Beispiel #6
0
void InitUtils()
{
	util_vbuf = new UtilVertexBuffer(65535);

	float border[4] = { 0.f, 0.f, 0.f, 0.f };
	D3D11_SAMPLER_DESC samDesc = CD3D11_SAMPLER_DESC(D3D11_FILTER_MIN_MAG_MIP_POINT, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, 0.f, 1, D3D11_COMPARISON_ALWAYS, border, 0.f, 0.f);
	HRESULT hr = D3D::device->CreateSamplerState(&samDesc, ToAddr(point_copy_sampler));
	if (FAILED(hr)) PanicAlert("Failed to create sampler state at %s %d\n", __FILE__, __LINE__);
	else SetDebugObjectName(point_copy_sampler.get(), "point copy sampler state");

	samDesc = CD3D11_SAMPLER_DESC(D3D11_FILTER_MIN_MAG_MIP_LINEAR, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, 0.f, 1, D3D11_COMPARISON_ALWAYS, border, 0.f, 0.f);
	hr = D3D::device->CreateSamplerState(&samDesc, ToAddr(linear_copy_sampler));
	if (FAILED(hr)) PanicAlert("Failed to create sampler state at %s %d\n", __FILE__, __LINE__);
	else SetDebugObjectName(linear_copy_sampler.get(), "linear copy sampler state");

	// cached data used to avoid unnecessarily reloading the vertex buffers
	memset(&tex_quad_data, 0, sizeof(tex_quad_data));	
	memset(&draw_quad_data, 0, sizeof(draw_quad_data));
	memset(&clear_quad_data, 0, sizeof(clear_quad_data));

	// make sure to properly load the vertex data whenever the corresponding functions get called the first time
	stq_observer = stsq_observer = cq_observer = clearq_observer = true;
	util_vbuf->AddWrapObserver(&stq_observer);
	util_vbuf->AddWrapObserver(&stsq_observer);
	util_vbuf->AddWrapObserver(&cq_observer);
	util_vbuf->AddWrapObserver(&clearq_observer);

	font.Init();
}
Beispiel #7
0
//-----------------------------------------------------------------------------
// Name: DeleteDeviceObjects()
// Desc: Called when the app is exiting, or the device is being changed,
//       this function deletes any device dependent objects.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::DeleteDeviceObjects()
{
    m_pFont->DeleteDeviceObjects();
    SAFE_RELEASE( m_pTexture );
    SAFE_RELEASE( m_pVB );

    return S_OK;
}
Beispiel #8
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;
}
Beispiel #9
0
//-----------------------------------------------------------------------------
// Name: InvalidateDeviceObjects()
// Desc: Called when the device-dependent objects are about to be lost.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::InvalidateDeviceObjects()
{
    m_pTerrain->InvalidateDeviceObjects();
    m_pSkyBox->InvalidateDeviceObjects();
    m_pFont->InvalidateDeviceObjects();

    return S_OK;
}
Beispiel #10
0
//-----------------------------------------------------------------------------
// Name: InvalidateDeviceObjects()
// Desc: 
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::InvalidateDeviceObjects()
{
    m_pFont->InvalidateDeviceObjects();

    m_MeshAttrSorted.ReleaseLocalMeshes();
    m_MeshStripReordered.ReleaseLocalMeshes();
    m_MeshVertexCacheOptimized.ReleaseLocalMeshes();

    return S_OK;
}
Beispiel #11
0
//-----------------------------------------------------------------------------
// Name: DeleteDeviceObjects()
// Desc: Called when the app is exiting, or the device is being changed,
//       this function deletes any device dependent objects.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::DeleteDeviceObjects()
{
    m_pFont->DeleteDeviceObjects();
    m_pShinyTeapot->Destroy();
    m_pSkyBox->Destroy();

    SAFE_RELEASE( m_pSphereMap );
    SAFE_RELEASE( m_pEffect );
    return S_OK;
}
Beispiel #12
0
//-----------------------------------------------------------------------------
// Name: DeleteDeviceObjects()
// Desc: Called when the app is exiting, or the device is being changed,
//       this function deletes any device dependent objects.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::DeleteDeviceObjects()
{
    m_pFont->DeleteDeviceObjects();
    SAFE_RELEASE( m_pBackgroundTexture );
    SAFE_RELEASE( m_pBumpMapTexture );
    SAFE_RELEASE( m_pBackgroundVB );
    SAFE_RELEASE( m_pLensVB );

    return S_OK;
}
Beispiel #13
0
//-----------------------------------------------------------------------------
// Name: InvalidateDeviceObjects
// Desc:
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::InvalidateDeviceObjects()
{
    HRESULT hr;

    m_pFont->InvalidateDeviceObjects();
    m_pFontSmall->InvalidateDeviceObjects();

    if(FAILED(hr = m_Water.OnLostDevice()))
        return hr;

    if(FAILED(hr = m_Environment.OnLostDevice()))
        return hr;

    SAFE_RELEASE(m_pRenderToSurface);
    SAFE_RELEASE(m_pEffect);
    SAFE_RELEASE(m_pCausticSurf);
    SAFE_RELEASE(m_pCausticTex);

    return S_OK;
}
Beispiel #14
0
static bool drawUrl(float x, float y, const char* msg)
{
    CD3DFont* fnt = g_font1;
    // news text
    SIZE ts = GetTextExtent(fnt, msg);
    r3dRECT r = {x, y, (float)ts.cx, (float)ts.cy};
    r3dColor clr = r3dColor(105, 105, 105);
    
    // selection and underline
    if(insideRect(r, g_mx, g_my)) {
      clr = r3dColor(255, 255, 255);
      r3dDrawBox2D(x, y + (float)ts.cy, (float)ts.cx, 1, clr);
      if(g_mb) {
        return true;
      }
    }

    fnt->PrintF(x, y, clr, "%s", msg);
    return false;
}
Beispiel #15
0
//-----------------------------------------------------------------------------
// Name: InvalidateDeviceObjects()
// Desc: Called when the device-dependent objects are about to be lost.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::InvalidateDeviceObjects()
{
    m_pShinyTeapot->InvalidateDeviceObjects();
    m_pSkyBox->InvalidateDeviceObjects();
    m_pFont->InvalidateDeviceObjects();

    if(m_pEffect)
        m_pEffect->OnLostDevice();

    return S_OK;
}
Beispiel #16
0
//-----------------------------------------------------------------------------
// Name: DeleteDeviceObjects()
// Desc: Called when the app is exiting, or the device is being changed,
//       this function deletes any device dependent objects.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::DeleteDeviceObjects()
{
    SAFE_RELEASE( m_pEmbossTexture );

    m_pObject->Destroy();
    m_pFont->DeleteDeviceObjects();

    SAFE_DELETE_ARRAY( m_pTangents );
    SAFE_DELETE_ARRAY( m_pBinormals );

    return S_OK;
}
Beispiel #17
0
//-----------------------------------------------------------------------------
// Name: DeleteDeviceObjects
// Desc:
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::DeleteDeviceObjects()
{
    HRESULT hr;

    m_pFont->DeleteDeviceObjects();
    m_pFontSmall->DeleteDeviceObjects();

    if(FAILED(hr = m_Water.OnDestroyDevice()))
        return hr;

    if(FAILED(hr = m_Environment.OnDestroyDevice()))
        return hr;

    SAFE_RELEASE(m_pFloorTex);
    SAFE_RELEASE(m_pSkyCubeTex);

    for(UINT i = 0; i < 6; i++)
        SAFE_RELEASE(m_pSkyTex[i]);


    return S_OK;
}
Beispiel #18
0
//-----------------------------------------------------------------------------
// Name: RestoreDeviceObjects()
// Desc: Restore device-memory objects and state after a device is created or
//       resized.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::RestoreDeviceObjects()
{
    // InitDeviceObjects for file objects (build textures and vertex buffers)
    m_pShinyTeapot->RestoreDeviceObjects( m_pd3dDevice );
    m_pSkyBox->RestoreDeviceObjects( m_pd3dDevice );
    m_pFont->RestoreDeviceObjects();
    m_pEffect->OnResetDevice();
    m_pEffect->SetTexture( "texSphereMap", m_pSphereMap );

    // Set the transform matrices
    FLOAT fAspect = (FLOAT) m_d3dsdBackBuffer.Width / (FLOAT) m_d3dsdBackBuffer.Height;
    D3DXMatrixPerspectiveFovLH( &m_matProject, D3DX_PI * 0.4f, fAspect, 0.5f, 100.0f );
    return S_OK;
}
Beispiel #19
0
//-----------------------------------------------------------------------------
// Name: DeleteDeviceObjects()
// Desc: Called when the app is exiting, or the device is being changed,
//       this function deletes any device dependent objects.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::DeleteDeviceObjects()
{
    m_pFont->DeleteDeviceObjects();

    m_pTerrain->Destroy();
    m_pSkyBox->Destroy();

    for( DWORD i=0; i<NUMTREETEXTURES; i++ )
        SAFE_RELEASE( m_pTreeTextures[i] );

    SAFE_RELEASE( m_pTreeVB )

    return S_OK;
}
Beispiel #20
0
//-----------------------------------------------------------------------------
// Name: InitDeviceObjects()
// Desc: Initialize scene objects.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::InitDeviceObjects()
{
    HRESULT      hr = S_OK;
    LPD3DXMESH   pMeshSysMem = NULL;
    LPD3DXBUFFER pAdjacencyBuffer = NULL;

    // Initialize the font 
    m_pFont->InitDeviceObjects( m_pd3dDevice );

    // check current display setting
    CheckMenuItem( GetMenu(m_hWnd), ID_OPTIONS_DISPLAY1 + (m_cObjectsPerSide-1), MF_CHECKED );
    CheckMenuItem( GetMenu(m_hWnd), IDM_SHOWNONOPTIMIZEDMESH, (!m_bShowStripReordered && !m_bShowVertexCacheOptimized) ? MF_CHECKED : MF_UNCHECKED  );
    CheckMenuItem( GetMenu(m_hWnd), IDM_SHOWVCACHEOPTIMIZED, m_bShowVertexCacheOptimized ? MF_CHECKED : MF_UNCHECKED );
    CheckMenuItem( GetMenu(m_hWnd), IDM_SHOWSTRIPREORDERED, m_bShowStripReordered ? MF_CHECKED : MF_UNCHECKED );
    CheckMenuItem( GetMenu(m_hWnd), IDM_SHOWTRILIST, (!m_bShowStrips && !m_bShowSingleStrip) ? MF_CHECKED : MF_UNCHECKED );
    CheckMenuItem( GetMenu(m_hWnd), IDM_SHOWONESTRIP, m_bShowSingleStrip ? MF_CHECKED : MF_UNCHECKED );
    CheckMenuItem( GetMenu(m_hWnd), IDM_SHOWMANYSTRIPS, m_bShowStrips ? MF_CHECKED : MF_UNCHECKED );

    CheckMenuItem( GetMenu(m_hWnd), IDM_DYNAMICVB, (m_dwMemoryOptions == D3DXMESH_DYNAMIC) ? MF_CHECKED : MF_UNCHECKED );
    CheckMenuItem( GetMenu(m_hWnd), IDM_FORCE32BYTEVERTEX, m_bForce32ByteFVF ? MF_CHECKED : MF_UNCHECKED );

    hr = LoadMeshData(&pMeshSysMem, &pAdjacencyBuffer);
    if (FAILED(hr))
    {
        // ignore load errors, just draw blank screen if mesh is invalid
        hr = S_OK;
        goto End;
    }

    hr = OptimizeMeshData(pMeshSysMem, pAdjacencyBuffer, D3DXMESHOPT_ATTRSORT, &m_MeshAttrSorted);
    if (FAILED(hr))
        goto End;

    hr = OptimizeMeshData(pMeshSysMem, pAdjacencyBuffer, D3DXMESHOPT_STRIPREORDER, &m_MeshStripReordered);
    if (FAILED(hr))
        goto End;

    hr = OptimizeMeshData(pMeshSysMem, pAdjacencyBuffer, D3DXMESHOPT_VERTEXCACHE, &m_MeshVertexCacheOptimized);
    if (FAILED(hr))
        goto End;

End:
    SAFE_RELEASE( pMeshSysMem );
    SAFE_RELEASE( pAdjacencyBuffer );
   
    return hr;
}
Beispiel #21
0
//-----------------------------------------------------------------------------
// Name: RestoreDeviceObjects()
// Desc: Initialize scene objects
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::RestoreDeviceObjects()
{
    m_pFont->RestoreDeviceObjects();

    // Set the transform matrices
    D3DXVECTOR3 vEyePt    = D3DXVECTOR3( 0.0f, 0.0f, -2001.0f );
    D3DXVECTOR3 vLookatPt = D3DXVECTOR3( 0.0f, 0.0f,     0.0f );
    D3DXVECTOR3 vUpVec    = D3DXVECTOR3( 0.0f, 1.0f,     0.0f );
    D3DXMATRIX matWorld, matView, matProj;

    D3DXMatrixIdentity( &matWorld );
    D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
    FLOAT fAspect = m_d3dsdBackBuffer.Width / (FLOAT)m_d3dsdBackBuffer.Height;
    D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, fAspect, 1.0f, 3000.0f );
    m_pd3dDevice->SetTransform( D3DTS_WORLD,      &matWorld );
    m_pd3dDevice->SetTransform( D3DTS_VIEW,       &matView );
    m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );

    // Set any appropiate state
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
    m_pd3dDevice->SetTextureStageState( 1, D3DTSS_ADDRESSU,   D3DTADDRESS_CLAMP );
    m_pd3dDevice->SetTextureStageState( 1, D3DTSS_ADDRESSV,   D3DTADDRESS_CLAMP );
    m_pd3dDevice->SetTextureStageState( 1, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
    m_pd3dDevice->SetTextureStageState( 1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
    m_pd3dDevice->SetTextureStageState( 1, D3DTSS_MIPFILTER, D3DTEXF_NONE );

    // Size the background image
    BACKGROUNDVERTEX* vBackground;
    m_pBackgroundVB->Lock( 0, 0, (BYTE**)&vBackground, 0 );
    for( UINT i=0; i<4; i ++ )
    {
        vBackground[i].p = D3DXVECTOR4( 0.0f, 0.0f, 0.9f, 1.0f );
        vBackground[i].color = 0xffffffff;
    }
    vBackground[0].p.y = (FLOAT)m_d3dsdBackBuffer.Height;
    vBackground[2].p.y = (FLOAT)m_d3dsdBackBuffer.Height;
    vBackground[2].p.x = (FLOAT)m_d3dsdBackBuffer.Width;
    vBackground[3].p.x = (FLOAT)m_d3dsdBackBuffer.Width;
    vBackground[0].tu = 0.0f; vBackground[0].tv = 1.0f;
    vBackground[1].tu = 0.0f; vBackground[1].tv = 0.0f;
    vBackground[2].tu = 1.0f; vBackground[2].tv = 1.0f;
    vBackground[3].tu = 1.0f; vBackground[3].tv = 0.0f;
    m_pBackgroundVB->Unlock();

    return S_OK;
}
Beispiel #22
0
//-----------------------------------------------------------------------------
// Name: DeleteDeviceObjects()
// Desc: Called when the app is exiting, or the device is being changed,
//       this function deletes any device dependent objects.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::DeleteDeviceObjects()
{
    m_pFont->DeleteDeviceObjects();

    for( UINT i=0; i<m_dwNumMaterials; i++ )
        SAFE_RELEASE( m_pMeshTextures[i] );
    SAFE_DELETE_ARRAY( m_pMeshTextures );
    SAFE_DELETE_ARRAY( m_pMeshMaterials );

    m_MeshAttrSorted.ReleaseAll();
    m_MeshStripReordered.ReleaseAll();
    m_MeshVertexCacheOptimized.ReleaseAll();

    m_dwNumMaterials = 0;

    return S_OK;
}
Beispiel #23
0
//-----------------------------------------------------------------------------
// Name: RestoreDeviceObjects()
// Desc: Restore device-memory objects and state after a device is created or
//       resized.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::RestoreDeviceObjects()
{
    // Restore device objects
    m_pObject->RestoreDeviceObjects( m_pd3dDevice );
    m_pFont->RestoreDeviceObjects();

    // Set up the textures
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
    
    // Set the view and projection matrices
    D3DXMATRIX  matView, matProj;
    D3DXVECTOR3 vFromPt   = D3DXVECTOR3( 0.0f, 0.0f, 3.5f );
    D3DXVECTOR3 vLookatPt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
    D3DXVECTOR3 vUpVec    = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
    D3DXMatrixLookAtLH( &matView, &vFromPt, &vLookatPt, &vUpVec );
    FLOAT fAspect = m_d3dsdBackBuffer.Width / (FLOAT)m_d3dsdBackBuffer.Height;
    D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, fAspect, 1.0f, 1000.0f );
    m_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
    m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );

    // Setup a material
    D3DMATERIAL8 mtrl;
    D3DUtil_InitMaterial( mtrl, 1.0f, 1.0f, 1.0f );
    m_pd3dDevice->SetMaterial( &mtrl );

    // Set up the light
    D3DUtil_InitLight( m_Light, D3DLIGHT_POINT, 5.0f, 5.0f, -20.0f );
    m_Light.Attenuation0 = 1.0f;
    m_pd3dDevice->SetLight( 0, &m_Light );
    m_pd3dDevice->LightEnable( 0, TRUE );
    
    // Set miscellaneous render states
    m_pd3dDevice->SetRenderState( D3DRS_ZENABLE,  TRUE );
    m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
    m_pd3dDevice->SetRenderState( D3DRS_AMBIENT,  0x00444444 );

    ApplyEnvironmentMap();

    return S_OK;
}
Beispiel #24
0
//-----------------------------------------------------------------------------
// Name: InitDeviceObjects()
// Desc: Initialize scene objects
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::InitDeviceObjects()
{
    m_pFont->InitDeviceObjects( m_pd3dDevice );

    // Load the texture for the background image
    if( FAILED( D3DUtil_CreateTexture( m_pd3dDevice, _T("Lake.bmp"),
                                       &m_pBackgroundTexture ) ) )
        return E_FAIL;

    // Create the bump map texture
    if( FAILED( CreateBumpMap( 256, 256 ) ) )
       return E_FAIL;

    // Create a square for rendering the background
    if( FAILED( m_pd3dDevice->CreateVertexBuffer( 4*sizeof(BACKGROUNDVERTEX),
                                                  D3DUSAGE_WRITEONLY, D3DFVF_BACKGROUNDVERTEX,
                                                  D3DPOOL_MANAGED, &m_pBackgroundVB ) ) )
        return E_FAIL;

    // Create a square for rendering the lens
    if( FAILED( m_pd3dDevice->CreateVertexBuffer( 4*sizeof(BUMPVERTEX),
                                                  D3DUSAGE_WRITEONLY, D3DFVF_BUMPVERTEX,
                                                  D3DPOOL_MANAGED, &m_pLensVB ) ) )
        return E_FAIL;

    BUMPVERTEX* vLens;
    m_pLensVB->Lock( 0, 0, (BYTE**)&vLens, 0 );
    vLens[0].p = D3DXVECTOR3(-256.0f,-256.0f, 0.0f );
    vLens[1].p = D3DXVECTOR3(-256.0f, 256.0f, 0.0f );
    vLens[2].p = D3DXVECTOR3( 256.0f,-256.0f, 0.0f );
    vLens[3].p = D3DXVECTOR3( 256.0f, 256.0f, 0.0f );
    vLens[0].tu1 = 0.0f; vLens[0].tv1 = 1.0f;
    vLens[1].tu1 = 0.0f; vLens[1].tv1 = 0.0f;
    vLens[2].tu1 = 1.0f; vLens[2].tv1 = 1.0f;
    vLens[3].tu1 = 1.0f; vLens[3].tv1 = 0.0f;
    m_pLensVB->Unlock();

    m_bDeviceValidationFailed = FALSE;

    return S_OK;
}
Beispiel #25
0
//-----------------------------------------------------------------------------
// Name: RestoreDeviceObjects()
// Desc: Initialize scene objects.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::RestoreDeviceObjects()
{
    m_pFont->RestoreDeviceObjects();

    // Setup render state
    m_pd3dDevice->SetRenderState( D3DRS_LIGHTING,     TRUE );
    m_pd3dDevice->SetRenderState( D3DRS_DITHERENABLE, TRUE );
    m_pd3dDevice->SetRenderState( D3DRS_ZENABLE,      TRUE );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );

    // Setup the light
    D3DLIGHT8 light;
    light.Type         = D3DLIGHT_DIRECTIONAL;
    light.Diffuse.r    = light.Diffuse.g  = light.Diffuse.b  = 1.0f;
    light.Specular.r   = light.Specular.g = light.Specular.b = 0.0f;
    light.Ambient.r    = light.Ambient.g  = light.Ambient.b  = 0.3f;
    light.Position     = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
    D3DXVec3Normalize( (D3DXVECTOR3*)&light.Direction, &D3DXVECTOR3( 0.3f, -1.0f, 1.0f ) );
    light.Attenuation0 = light.Attenuation1 = light.Attenuation2 = 0.0f;
    light.Range        = sqrtf(FLT_MAX);
    m_pd3dDevice->SetLight(0, &light );
    m_pd3dDevice->LightEnable(0, TRUE );

    m_ArcBall.SetWindow( m_d3dsdBackBuffer.Width, m_d3dsdBackBuffer.Height, 0.85f );
    m_ArcBall.SetRadius( m_fObjectRadius );

    FLOAT fAspect = m_d3dsdBackBuffer.Width / (FLOAT)m_d3dsdBackBuffer.Height;

    D3DXMATRIX matProj;
    D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, fAspect, m_fObjectRadius/64.0f,
                                m_fObjectRadius*200.0f);
    m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );

    // update the local copies of the meshes
    UpdateLocalMeshes(&m_MeshAttrSorted);
    UpdateLocalMeshes(&m_MeshStripReordered);
    UpdateLocalMeshes(&m_MeshVertexCacheOptimized);

    return S_OK;
}
Beispiel #26
0
//-----------------------------------------------------------------------------
// Name: InitDeviceObjects()
// Desc: Initialize scene objects.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::InitDeviceObjects()
{
    // Load the file objects
    if( FAILED( m_pShinyTeapot->Create( m_pd3dDevice, _T("teapot.x") ) ) )
        return D3DAPPERR_MEDIANOTFOUND;
    if( FAILED( m_pSkyBox->Create( m_pd3dDevice, _T("lobby_skybox.x") ) ) )
        return D3DAPPERR_MEDIANOTFOUND;
    if( FAILED( D3DUtil_CreateTexture( m_pd3dDevice, _T("spheremap.bmp"), &m_pSphereMap ) ) )
        return D3DAPPERR_MEDIANOTFOUND;

    // Set mesh properties
    m_pShinyTeapot->SetFVF( m_pd3dDevice, D3DFVF_ENVMAPVERTEX );

    // Restore the device-dependent objects
    m_pFont->InitDeviceObjects( m_pd3dDevice );

    // Create Effect object
    if( FAILED( D3DXCreateEffect( m_pd3dDevice, g_szEffect, g_cchEffect, &m_pEffect, NULL ) ) )
        return E_FAIL;

    return S_OK;
}
Beispiel #27
0
//-----------------------------------------------------------------------------
// Name: RestoreDeviceObjects()
// Desc: Initialize scene objects.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::RestoreDeviceObjects()
{
    m_pFont->RestoreDeviceObjects();

    // Set the matrices
    D3DXVECTOR3 vEye( 0.0f, 0.0f,-3.0f );
    D3DXVECTOR3 vAt(  0.0f, 0.0f, 0.0f );
    D3DXVECTOR3 vUp(  0.0f, 1.0f, 0.0f );
    D3DXMATRIX matWorld, matView, matProj;
    D3DXMatrixIdentity( &matWorld );
    D3DXMatrixLookAtLH( &matView, &vEye,&vAt, &vUp );
    FLOAT fAspect = m_d3dsdBackBuffer.Width / (FLOAT)m_d3dsdBackBuffer.Height;
    D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, fAspect, 1.0f, 100.0f );
    m_pd3dDevice->SetTransform( D3DTS_WORLD,      &matWorld );
    m_pd3dDevice->SetTransform( D3DTS_VIEW,       &matView );
    m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );

    // Set state
    m_pd3dDevice->SetRenderState( D3DRS_DITHERENABLE, FALSE );
    m_pd3dDevice->SetRenderState( D3DRS_CLIPPING,     FALSE );
    m_pd3dDevice->SetRenderState( D3DRS_CULLMODE,     D3DCULL_NONE );
    m_pd3dDevice->SetRenderState( D3DRS_CLIPPING,     FALSE );
    m_pd3dDevice->SetRenderState( D3DRS_LIGHTING,     FALSE );
    m_pd3dDevice->SetRenderState( D3DRS_ZENABLE,      FALSE );
    m_pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );

    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_SELECTARG1 );
    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 );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );

    return S_OK;
}
Beispiel #28
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;
}
Beispiel #29
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;
}
Beispiel #30
0
//-----------------------------------------------------------------------------
// Name: InitDeviceObjects()
// Desc: This creates all device-dependent managed objects, such as managed
//       textures and managed vertex buffers.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::InitDeviceObjects()
{
    // Initialize the font's internal textures
    m_pFont->InitDeviceObjects( m_pd3dDevice );

    // Create the tree textures
    for( DWORD i=0; i<NUMTREETEXTURES; i++ )
    {
        if( FAILED( D3DUtil_CreateTexture( m_pd3dDevice, g_strTreeTextures[i],
                                           &m_pTreeTextures[i] ) ) )
            return D3DAPPERR_MEDIANOTFOUND;
    }

    // Create a quad for rendering each tree
    if( FAILED( m_pd3dDevice->CreateVertexBuffer( NUM_TREES*4*sizeof(TREEVERTEX),
                                                  D3DUSAGE_WRITEONLY, D3DFVF_TREEVERTEX,
                                                  D3DPOOL_MANAGED, &m_pTreeVB ) ) )
    {
        return E_FAIL;
    }

    // Copy tree mesh data into vertexbuffer
    TREEVERTEX* v;
    m_pTreeVB->Lock( 0, 0, (BYTE**)&v, 0 );

    INT iTree;
    DWORD dwOffset = 0;
    for( iTree = 0; iTree < NUM_TREES; iTree++ )
    {
        memcpy( &v[dwOffset], m_Trees[iTree].v, 4*sizeof(TREEVERTEX) );
        m_Trees[iTree].dwOffset = dwOffset;
        dwOffset += 4;
    }

    m_pTreeVB->Unlock();

    // Load the skybox
    if( FAILED( m_pSkyBox->Create( m_pd3dDevice, _T("SkyBox2.x") ) ) )
        return D3DAPPERR_MEDIANOTFOUND;

    // Load the terrain
    if( FAILED( m_pTerrain->Create( m_pd3dDevice, _T("SeaFloor.x") ) ) )
        return D3DAPPERR_MEDIANOTFOUND;

    // Add some "hilliness" to the terrain
    LPDIRECT3DVERTEXBUFFER8 pVB;
    if( SUCCEEDED( m_pTerrain->GetSysMemMesh()->GetVertexBuffer( &pVB ) ) )
    {
        struct VERTEX { FLOAT x,y,z,tu,tv; };
        VERTEX* pVertices;
        DWORD   dwNumVertices = m_pTerrain->GetSysMemMesh()->GetNumVertices();

        pVB->Lock( 0, 0, (BYTE**)&pVertices, 0 );

        for( DWORD i=0; i<dwNumVertices; i++ )
            pVertices[i].y = HeightField( pVertices[i].x, pVertices[i].z );

        pVB->Unlock();
        pVB->Release();
    }

    return S_OK;
}