home *** CD-ROM | disk | FTP | other *** search
/ Game Programming in C++ - Start to Finish / GameProgrammingS.iso / developer_install / ReplicaNetFreewareV5_4.exe / data1.cab / Program_Executable_Files / Example4 / GameClass.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2005-10-30  |  19.7 KB  |  596 lines

  1. /* START_LICENSE_HEADER
  2.  
  3. Copyright (C) 2000 Martin Piper, original design and program code
  4. Copyright (C) 2001-2005 Replica Software
  5.  
  6. This program file is copyright (C) Replica Software and can only be used under license.
  7. For more information visit: http://www.replicanet.com/
  8. Or email: info@replicanet.com
  9.  
  10. END_LICENSE_HEADER */
  11. #define STRICT
  12. #include <math.h>
  13. #include <stdio.h>
  14.  
  15. #include "Network.h"
  16.  
  17. #include "Plane.h"
  18. #include "Camera.h"
  19.  
  20. #include "GameClass.h"
  21. #include "External.h"
  22.  
  23.  
  24. CD3DMesh*     gpAirplaneMesh;
  25. CD3DMesh*     gpProjectileMesh;
  26. CD3DMesh*     gpEnemyMesh;
  27. char *gCommandLine;
  28.  
  29. HINSTANCE ghInst = 0;
  30. HINSTANCE gAppInstance = 0;
  31. HWND ghWnd = 0; 
  32.  
  33. CMyD3DApplication *mSingleton = 0;
  34.  
  35. //-----------------------------------------------------------------------------
  36. // Name: WinMain()
  37. // Desc: Entry point to the program. Initializes everything, and goes into a
  38. //       message-processing loop. Idle time is used to render the scene.
  39. //-----------------------------------------------------------------------------
  40. INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR commandline, INT )
  41. {
  42.     gAppInstance = ghInst = hInst;
  43.     gCommandLine = commandline;
  44.  
  45.     Sleep(100);
  46.  
  47.     CMyD3DApplication d3dApp;
  48.  
  49.     if( FAILED( d3dApp.Create( hInst ) ) )
  50.         return 0;
  51.  
  52.     d3dApp.DoGameStuff();
  53.  
  54.     return d3dApp.Run();
  55. }
  56.  
  57.  
  58.  
  59. //-----------------------------------------------------------------------------
  60. // Name:
  61. // Desc:
  62. //-----------------------------------------------------------------------------
  63. HRESULT ShadowVolume::Render( LPDIRECT3DDEVICE8 pd3dDevice )
  64. {
  65.     pd3dDevice->SetVertexShader( D3DFVF_XYZ );
  66.  
  67.     return pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLELIST, m_dwNumVertices/3,
  68.                                         m_pVertices, sizeof(D3DXVECTOR3) );
  69. }
  70.  
  71.  
  72.  
  73.  
  74. //-----------------------------------------------------------------------------
  75. // Name: AddEdge()
  76. // Desc: Adds an edge to a list of silohuette edges of a shadow volume.
  77. //-----------------------------------------------------------------------------
  78. VOID AddEdge( WORD* pEdges, DWORD& dwNumEdges, WORD v0, WORD v1 )
  79. {
  80.     // Remove interior edges (which appear in the list twice)
  81.     for( DWORD i=0; i < dwNumEdges; i++ )
  82.     {
  83.         if( ( pEdges[2*i+0] == v0 && pEdges[2*i+1] == v1 ) ||
  84.             ( pEdges[2*i+0] == v1 && pEdges[2*i+1] == v0 ) )
  85.         {
  86.             if( dwNumEdges > 1 )
  87.             {
  88.                 pEdges[2*i+0] = pEdges[2*(dwNumEdges-1)+0];
  89.                 pEdges[2*i+1] = pEdges[2*(dwNumEdges-1)+1];
  90.             }
  91.             dwNumEdges--;
  92.             return;
  93.         }
  94.     }
  95.  
  96.     pEdges[2*dwNumEdges+0] = v0;
  97.     pEdges[2*dwNumEdges+1] = v1;
  98.     dwNumEdges++;
  99. }
  100.  
  101.  
  102.  
  103.  
  104. //-----------------------------------------------------------------------------
  105. // Name: BuildFromMesh()
  106. // Desc: Takes a mesh as input, and uses it to build a shadowvolume. The
  107. //       technique used considers each triangle of the mesh, and adds it's
  108. //       edges to a temporary list. The edge list is maintained, such that
  109. //       only silohuette edges are kept. Finally, the silohuette edges are
  110. //       extruded to make the shadow volume vertex list.
  111. //-----------------------------------------------------------------------------
  112. HRESULT ShadowVolume::BuildFromMesh( LPD3DXMESH pMesh, D3DXVECTOR3 vLight )
  113. {
  114.     // Note: the MESHVERTEX format depends on the FVF of the mesh
  115.     struct MESHVERTEX { D3DXVECTOR3 p, n; FLOAT tu, tv; };
  116.     DWORD dwFVF = pMesh->GetFVF();
  117.  
  118.     MESHVERTEX* pVertices;
  119.     WORD*       pIndices;
  120.  
  121.     // Lock the geometry buffers
  122.     pMesh->LockVertexBuffer( 0L, (BYTE**)&pVertices );
  123.     pMesh->LockIndexBuffer( 0L, (BYTE**)&pIndices );
  124.     DWORD dwNumVertices = pMesh->GetNumVertices();
  125.     DWORD dwNumFaces    = pMesh->GetNumFaces();
  126.  
  127.     // Allocate a temporary edge list
  128.     WORD* pEdges = new WORD[dwNumFaces*6];
  129.     DWORD dwNumEdges = 0;
  130.  
  131.     // For each face
  132.     for( DWORD i=0; i<dwNumFaces; i++ )
  133.     {
  134.         WORD wFace0 = pIndices[3*i+0];
  135.         WORD wFace1 = pIndices[3*i+1];
  136.         WORD wFace2 = pIndices[3*i+2];
  137.  
  138.         D3DXVECTOR3 v0 = pVertices[wFace0].p;
  139.         D3DXVECTOR3 v1 = pVertices[wFace1].p;
  140.         D3DXVECTOR3 v2 = pVertices[wFace2].p;
  141.  
  142.         // Transform vertices or transform light?
  143.         D3DXVECTOR3 vNormal;
  144.         D3DXVec3Cross( &vNormal, &(v2-v1), &(v1-v0) );
  145.  
  146.         if( D3DXVec3Dot( &vNormal, &vLight ) >= 0.0f )
  147.         {
  148.             AddEdge( pEdges, dwNumEdges, wFace0, wFace1 );
  149.             AddEdge( pEdges, dwNumEdges, wFace1, wFace2 );
  150.             AddEdge( pEdges, dwNumEdges, wFace2, wFace0 );
  151.         }
  152.     }
  153.  
  154.     for( i=0; i<dwNumEdges; i++ )
  155.     {
  156.         D3DXVECTOR3 v1 = pVertices[pEdges[2*i+0]].p;
  157.         D3DXVECTOR3 v2 = pVertices[pEdges[2*i+1]].p;
  158.         D3DXVECTOR3 v3 = v1 - vLight*10;
  159.         D3DXVECTOR3 v4 = v2 - vLight*10;
  160.  
  161.         // Add a quad (two triangles) to the vertex list
  162.         m_pVertices[m_dwNumVertices++] = v1;
  163.         m_pVertices[m_dwNumVertices++] = v2;
  164.         m_pVertices[m_dwNumVertices++] = v3;
  165.  
  166.         m_pVertices[m_dwNumVertices++] = v2;
  167.         m_pVertices[m_dwNumVertices++] = v4;
  168.         m_pVertices[m_dwNumVertices++] = v3;
  169.     }
  170.     // Delete the temporary edge list
  171.     delete pEdges;
  172.  
  173.     // Unlock the geometry buffers
  174.     pMesh->UnlockVertexBuffer();
  175.     pMesh->UnlockIndexBuffer();
  176.  
  177.     return S_OK;
  178. }
  179.  
  180.  
  181.  
  182. CMyD3DApplication *CMyD3DApplication::mSingleton = 0;
  183.  
  184. //-----------------------------------------------------------------------------
  185. // Name: CMyD3DApplication()
  186. // Desc: Application constructor. Sets attributes for the app.
  187. //-----------------------------------------------------------------------------
  188. CMyD3DApplication::CMyD3DApplication()
  189. {
  190.     m_strWindowTitle    = _T("Example4: Pilot the planes");
  191.     m_bUseDepthBuffer   = TRUE;
  192. //    m_bUseDepthBuffer   = FALSE;
  193.     m_dwMinDepthBits    = 16;
  194.     m_dwMinStencilBits  = 4;
  195.     m_dwMinStencilBits  = 0;
  196.     m_bShowCursorWhenFullscreen = TRUE;
  197.  
  198.     m_pFont           = new CD3DFont( _T("Arial"), 8, 0 /* No bold font flag */ );
  199.     m_pAirplane       = new CD3DMesh();
  200.     m_pTerrainObject  = new CD3DMesh();
  201.     m_pShadowVolume   = NULL;
  202.     m_pBigSquareVB    = NULL;
  203.  
  204.     gpAirplaneMesh = m_pAirplane;
  205.  
  206.     gpProjectileMesh = new CD3DMesh();
  207.     gpEnemyMesh = new CD3DMesh();
  208.  
  209.     mPlayerConrolledPlane = 0;
  210.     mPlayerConrolledCamera = 0;
  211. }
  212.  
  213.  
  214. //-----------------------------------------------------------------------------
  215. // Name: OneTimeSceneInit()
  216. // Desc: Called during initial app startup, this function performs all the
  217. //       permanent initialization.
  218. //-----------------------------------------------------------------------------
  219. HRESULT CMyD3DApplication::OneTimeSceneInit()
  220. {
  221.     // Construct a shadow volume object;
  222. //    m_pShadowVolume = new ShadowVolume();
  223.     mSingleton = this;
  224.  
  225.     // Set cursor to indicate that user can move the object with the mouse
  226. #ifdef _WIN64
  227.     SetClassLongPtr( m_hWnd, GCLP_HCURSOR, (LONG_PTR)LoadCursor( NULL, IDC_SIZEALL ) );
  228. #else
  229.     SetClassLong( m_hWnd, GCL_HCURSOR, (LONG)LoadCursor( NULL, IDC_SIZEALL ) );
  230. #endif
  231.     return S_OK;
  232. }
  233.  
  234.  
  235.  
  236. //-----------------------------------------------------------------------------
  237. // Name: RenderShadow()
  238. // Desc:
  239. //-----------------------------------------------------------------------------
  240. HRESULT CMyD3DApplication::RenderShadow()
  241. {
  242.     // Disable z-buffer writes (note: z-testing still occurs), and enable the
  243.     // stencil-buffer
  244.     m_pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE,  FALSE );
  245.     m_pd3dDevice->SetRenderState( D3DRS_STENCILENABLE, TRUE );
  246.  
  247.     // Dont bother with interpolating color
  248.     m_pd3dDevice->SetRenderState( D3DRS_SHADEMODE,     D3DSHADE_FLAT );
  249.  
  250.     // Set up stencil compare fuction, reference value, and masks.
  251.     // Stencil test passes if ((ref & mask) cmpfn (stencil & mask)) is true.
  252.     // Note: since we set up the stencil-test to always pass, the STENCILFAIL
  253.     // renderstate is really not needed.
  254.     m_pd3dDevice->SetRenderState( D3DRS_STENCILFUNC,  D3DCMP_ALWAYS );
  255.     m_pd3dDevice->SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP );
  256.     m_pd3dDevice->SetRenderState( D3DRS_STENCILFAIL,  D3DSTENCILOP_KEEP );
  257.  
  258.     // If ztest passes, inc/decrement stencil buffer value
  259.     m_pd3dDevice->SetRenderState( D3DRS_STENCILREF,       0x1 );
  260.     m_pd3dDevice->SetRenderState( D3DRS_STENCILMASK,      0xffffffff );
  261.     m_pd3dDevice->SetRenderState( D3DRS_STENCILWRITEMASK, 0xffffffff );
  262.     m_pd3dDevice->SetRenderState( D3DRS_STENCILPASS,      D3DSTENCILOP_INCR );
  263.  
  264.     // Make sure that no pixels get drawn to the frame buffer
  265.     m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
  266.     m_pd3dDevice->SetRenderState( D3DRS_SRCBLEND,  D3DBLEND_ZERO );
  267.     m_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );
  268.  
  269.     // Draw front-side of shadow volume in stencil/z only
  270.     m_pd3dDevice->SetTransform( D3DTS_WORLD, &m_matObjectMatrix );
  271.     m_pShadowVolume->Render( m_pd3dDevice );
  272.  
  273.     // Now reverse cull order so back sides of shadow volume are written.
  274.     m_pd3dDevice->SetRenderState( D3DRS_CULLMODE,   D3DCULL_CW );
  275.  
  276.     // Decrement stencil buffer value
  277.     m_pd3dDevice->SetRenderState( D3DRS_STENCILPASS, D3DSTENCILOP_DECR );
  278.  
  279.     // Draw back-side of shadow volume in stencil/z only
  280.     m_pd3dDevice->SetTransform( D3DTS_WORLD, &m_matObjectMatrix );
  281.     m_pShadowVolume->Render( m_pd3dDevice );
  282.  
  283.     // Restore render states
  284.     m_pd3dDevice->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_GOURAUD );
  285.     m_pd3dDevice->SetRenderState( D3DRS_CULLMODE,  D3DCULL_CCW );
  286.     m_pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE,     TRUE );
  287.     m_pd3dDevice->SetRenderState( D3DRS_STENCILENABLE,    FALSE );
  288.     m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
  289.  
  290.     return S_OK;
  291. }
  292.  
  293.  
  294.  
  295.  
  296. //-----------------------------------------------------------------------------
  297. // Name: DrawShadow()
  298. // Desc: Draws a big gray polygon over scene according to the mask in the
  299. //       stencil buffer. (Any pixel with stencil==1 is in the shadow.)
  300. //-----------------------------------------------------------------------------
  301. HRESULT CMyD3DApplication::DrawShadow()
  302. {
  303.     // Set renderstates (disable z-buffering, enable stencil, disable fog, and
  304.     // turn on alphablending)
  305.     m_pd3dDevice->SetRenderState( D3DRS_ZENABLE,          FALSE );
  306.     m_pd3dDevice->SetRenderState( D3DRS_STENCILENABLE,    TRUE );
  307.     m_pd3dDevice->SetRenderState( D3DRS_FOGENABLE,        FALSE );
  308.     m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
  309.     m_pd3dDevice->SetRenderState( D3DRS_SRCBLEND,  D3DBLEND_SRCALPHA );
  310.     m_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
  311.  
  312.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  313.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
  314.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE );
  315.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
  316.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
  317.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP,   D3DTOP_MODULATE );
  318.  
  319.     // Only write where stencil val >= 1 (count indicates # of shadows that
  320.     // overlap that pixel)
  321.     m_pd3dDevice->SetRenderState( D3DRS_STENCILREF,  0x1 );
  322.     m_pd3dDevice->SetRenderState( D3DRS_STENCILFUNC, D3DCMP_LESSEQUAL );
  323.     m_pd3dDevice->SetRenderState( D3DRS_STENCILPASS, D3DSTENCILOP_KEEP );
  324.  
  325.     // Draw a big, gray square
  326.     m_pd3dDevice->SetVertexShader( D3DFVF_SHADOWVERTEX );
  327.     m_pd3dDevice->SetStreamSource( 0, m_pBigSquareVB, sizeof(SHADOWVERTEX) );
  328.     m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
  329.  
  330.     // Restore render states
  331.     m_pd3dDevice->SetRenderState( D3DRS_ZENABLE,          TRUE );
  332.     m_pd3dDevice->SetRenderState( D3DRS_STENCILENABLE,    FALSE );
  333.     m_pd3dDevice->SetRenderState( D3DRS_FOGENABLE,        TRUE );
  334.     m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
  335.  
  336.     return S_OK;
  337. }
  338.  
  339.  
  340.  
  341.  
  342.  
  343.  
  344. //-----------------------------------------------------------------------------
  345. // Name: InitDeviceObjects()
  346. // Desc: Initialize scene objects.
  347. //-----------------------------------------------------------------------------
  348. HRESULT CMyD3DApplication::InitDeviceObjects()
  349. {
  350.     // Initialize the font's internal textures
  351.     m_pFont->InitDeviceObjects( m_pd3dDevice );
  352.  
  353.     // Load an object to cast the shadow
  354.     if( FAILED( m_pAirplane->Create( m_pd3dDevice, _T("airplane 2.x") ) ) )
  355.         return D3DAPPERR_MEDIANOTFOUND;
  356.  
  357.     if( FAILED( gpEnemyMesh->Create( m_pd3dDevice, _T("dolphin1.x") ) ) )
  358.         return D3DAPPERR_MEDIANOTFOUND;
  359.  
  360.     if( FAILED( gpProjectileMesh->Create( m_pd3dDevice, _T("cube.x") ) ) )
  361.         return D3DAPPERR_MEDIANOTFOUND;
  362.  
  363.  
  364.     // Load some terrain
  365.     if( FAILED( m_pTerrainObject->Create( m_pd3dDevice, _T("SeaFloor.x") ) ) )
  366.         return D3DAPPERR_MEDIANOTFOUND;
  367.  
  368.     // Set a reasonable vertex type
  369.     m_pAirplane->SetFVF( m_pd3dDevice, D3DFVF_VERTEX );
  370.     gpProjectileMesh->SetFVF( m_pd3dDevice, D3DFVF_VERTEX );
  371.     m_pTerrainObject->SetFVF( m_pd3dDevice, D3DFVF_VERTEX );
  372.     gpEnemyMesh->SetFVF( m_pd3dDevice, D3DFVF_VERTEX );
  373.  
  374.     // Tweak the terrain vertices
  375.     {
  376.         LPDIRECT3DVERTEXBUFFER8 pVB;
  377.         VERTEX* pVertices;
  378.         DWORD   dwNumVertices = m_pTerrainObject->GetSysMemMesh()->GetNumVertices();
  379.  
  380.         // Lock the vertex buffer to access the terrain geometry
  381.         m_pTerrainObject->GetSysMemMesh()->GetVertexBuffer( &pVB );
  382.         pVB->Lock( 0, 0, (BYTE**)&pVertices, 0 );
  383.  
  384.         // Add some more bumpiness to the terrain object
  385.         for( DWORD i=0; i<dwNumVertices; i++ )
  386.         {
  387.             pVertices[i].p.y  += 1*(rand()/(FLOAT)RAND_MAX);
  388.             pVertices[i].p.y  += 2*(rand()/(FLOAT)RAND_MAX);
  389.             pVertices[i].p.y  += 1*(rand()/(FLOAT)RAND_MAX);
  390.         }
  391.  
  392.         // Release the vertex buffer
  393.         pVB->Unlock();
  394.         pVB->Release();
  395.     }
  396.  
  397.     // Create a big square for rendering the stencilbuffer contents
  398. //    if( FAILED( m_pd3dDevice->CreateVertexBuffer( 4*sizeof(SHADOWVERTEX),
  399. //                                       D3DUSAGE_WRITEONLY, D3DFVF_SHADOWVERTEX,
  400. //                                       D3DPOOL_MANAGED, &m_pBigSquareVB ) ) )
  401. //        return E_FAIL;
  402.  
  403.     ghWnd = m_hWnd;
  404.  
  405.     return S_OK;
  406. }
  407.  
  408.  
  409.  
  410.  
  411. //-----------------------------------------------------------------------------
  412. // Name: RestoreDeviceObjects()
  413. // Desc: Restore device-memory objects and state after a device is created or
  414. //       resized.
  415. //-----------------------------------------------------------------------------
  416. HRESULT CMyD3DApplication::RestoreDeviceObjects()
  417. {
  418.     m_pFont->RestoreDeviceObjects();
  419.  
  420.     // Initialize the vertex buffers for the file-based objects
  421.     m_pAirplane->RestoreDeviceObjects( m_pd3dDevice );
  422.     gpProjectileMesh->RestoreDeviceObjects( m_pd3dDevice );
  423.     m_pTerrainObject->RestoreDeviceObjects( m_pd3dDevice );
  424.     gpEnemyMesh->RestoreDeviceObjects( m_pd3dDevice );
  425.  
  426.     // Create and set up the shine materials w/ textures
  427.     D3DMATERIAL8 mtrl;
  428.     D3DUtil_InitMaterial( mtrl, 1.0f, 1.0f, 1.0f );
  429.     m_pd3dDevice->SetMaterial( &mtrl );
  430.  
  431.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  432.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
  433.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE );
  434.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
  435.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
  436.  
  437.     m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
  438.     m_pd3dDevice->SetRenderState( D3DRS_DITHERENABLE, TRUE );
  439.     m_pd3dDevice->SetRenderState( D3DRS_SPECULARENABLE, FALSE );
  440.  
  441.     // Set the transform matrices
  442.     D3DXVECTOR3 vEyePt    = D3DXVECTOR3( 0.0f, 10.0f, -20.0f );
  443.     D3DXVECTOR3 vLookatPt = D3DXVECTOR3( 0.0f,  0.0f,   0.0f  );
  444.     D3DXVECTOR3 vUpVec    = D3DXVECTOR3( 0.0f,  1.0f,   0.0f  );
  445.     D3DXMATRIX matWorld, matView, matProj;
  446.  
  447.     D3DXMatrixIdentity( &matWorld );
  448.     D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
  449.     FLOAT fAspect = m_d3dsdBackBuffer.Width / (FLOAT)m_d3dsdBackBuffer.Height;
  450.     D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, fAspect, 1.0f, 200.0f );
  451.  
  452.     m_pd3dDevice->SetTransform( D3DTS_WORLD,      &matWorld );
  453.     m_pd3dDevice->SetTransform( D3DTS_VIEW,       &matView );
  454.     m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
  455.  
  456.     // Turn on fog
  457.     FLOAT fFogStart =  30.0f;
  458.     FLOAT fFogEnd   =  200.0f;
  459.     m_pd3dDevice->SetRenderState( D3DRS_FOGENABLE,      TRUE );
  460.     m_pd3dDevice->SetRenderState( D3DRS_FOGCOLOR,       0xff0000ff );
  461.     m_pd3dDevice->SetRenderState( D3DRS_FOGTABLEMODE,   D3DFOG_NONE );
  462.     m_pd3dDevice->SetRenderState( D3DRS_FOGVERTEXMODE,  D3DFOG_LINEAR );
  463.     m_pd3dDevice->SetRenderState( D3DRS_RANGEFOGENABLE, FALSE );
  464.     m_pd3dDevice->SetRenderState( D3DRS_FOGSTART,       FtoDW(fFogStart) );
  465.     m_pd3dDevice->SetRenderState( D3DRS_FOGEND,         FtoDW(fFogEnd) );
  466.  
  467.     // Set the ArcBall parameters
  468.     m_ArcBall.SetWindow( m_d3dsdBackBuffer.Width, m_d3dsdBackBuffer.Height, 2.0f );
  469.     m_ArcBall.SetRadius( 5.0f );
  470.  
  471.     m_pd3dDevice->LightEnable( 0, TRUE );
  472.     m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
  473.     m_pd3dDevice->SetRenderState( D3DRS_AMBIENT,  0x00303030 );
  474.  
  475.     // Set the size of the big square shadow
  476.     SHADOWVERTEX* v = 0;
  477.     FLOAT sx = (FLOAT)m_d3dsdBackBuffer.Width;
  478.     FLOAT sy = (FLOAT)m_d3dsdBackBuffer.Height;
  479. #if 0
  480.     m_pBigSquareVB->Lock( 0, 0, (BYTE**)&v, 0 );
  481.     v[0].p = D3DXVECTOR4(  0, sy, 0.0f, 1.0f );
  482.     v[1].p = D3DXVECTOR4(  0,  0, 0.0f, 1.0f );
  483.     v[2].p = D3DXVECTOR4( sx, sy, 0.0f, 1.0f );
  484.     v[3].p = D3DXVECTOR4( sx,  0, 0.0f, 1.0f );
  485.     v[0].color = 0x7f000000;
  486.     v[1].color = 0x7f000000;
  487.     v[2].color = 0x7f000000;
  488.     v[3].color = 0x7f000000;
  489.     m_pBigSquareVB->Unlock();
  490. #endif
  491.  
  492.     return S_OK;
  493. }
  494.  
  495.  
  496.  
  497.  
  498. //-----------------------------------------------------------------------------
  499. // Name: InvalidateDeviceObjects()
  500. // Desc: Called when the device-dependent objects are about to be lost.
  501. //-----------------------------------------------------------------------------
  502. HRESULT CMyD3DApplication::InvalidateDeviceObjects()
  503. {
  504.     m_pFont->InvalidateDeviceObjects();
  505.     m_pAirplane->InvalidateDeviceObjects();
  506.     gpProjectileMesh->InvalidateDeviceObjects();
  507.     m_pTerrainObject->InvalidateDeviceObjects();
  508.     gpEnemyMesh->InvalidateDeviceObjects();
  509.     return S_OK;
  510. }
  511.  
  512.  
  513.  
  514.  
  515. //-----------------------------------------------------------------------------
  516. // Name: DeleteDeviceObjects()
  517. // Desc: Called when the app is exiting, or the device is being changed,
  518. //       this function deletes any device dependent objects.
  519. //-----------------------------------------------------------------------------
  520. HRESULT CMyD3DApplication::DeleteDeviceObjects()
  521. {
  522.     m_pFont->DeleteDeviceObjects();
  523.     m_pAirplane->Destroy();
  524.     gpProjectileMesh->Destroy();
  525.     m_pTerrainObject->Destroy();
  526.     gpEnemyMesh->Destroy();
  527.  
  528.     SAFE_RELEASE( m_pBigSquareVB );
  529.  
  530.     return S_OK;
  531. }
  532.  
  533.  
  534.  
  535.  
  536. //-----------------------------------------------------------------------------
  537. // Name: FinalCleanup()
  538. // Desc: Called before the app exits, this function gives the app the chance
  539. //       to cleanup after itself.
  540. //-----------------------------------------------------------------------------
  541. HRESULT CMyD3DApplication::FinalCleanup()
  542. {
  543.     Network::Network_Shutdown();
  544.  
  545.     return S_OK;
  546. }
  547.  
  548.  
  549.  
  550.  
  551. //-----------------------------------------------------------------------------
  552. // Name: ConfirmDevice()
  553. // Desc: Called during device intialization, this code checks the device
  554. //       for some minimum set of capabilities
  555. //-----------------------------------------------------------------------------
  556. HRESULT CMyD3DApplication::ConfirmDevice( D3DCAPS8* pCaps, DWORD dwBehavior,
  557.                                           D3DFORMAT Format )
  558. {
  559.     // Make sure device supports point lights
  560.     if( (dwBehavior & D3DCREATE_HARDWARE_VERTEXPROCESSING ) ||
  561.         (dwBehavior & D3DCREATE_MIXED_VERTEXPROCESSING ) )
  562.     {
  563.         if( 0 == ( pCaps->VertexProcessingCaps & D3DVTXPCAPS_POSITIONALLIGHTS ) )
  564.             return E_FAIL;
  565.     }
  566.  
  567.     return S_OK;
  568. }
  569.  
  570.  
  571. CMyD3DApplication *CMyD3DApplication::GetCMyD3DApplication(void)
  572. {
  573.     return mSingleton;
  574. }
  575.  
  576.  
  577. //-----------------------------------------------------------------------------
  578. // Name: MsgProc()
  579. // Desc: Message proc function to handle key and menu input
  580. //-----------------------------------------------------------------------------
  581. LRESULT CMyD3DApplication::MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam,
  582.                                     LPARAM lParam )
  583. {
  584.     // Pass mouse messages to the ArcBall so it can build internal matrices
  585.     m_ArcBall.HandleMouseMessages( hWnd, uMsg, wParam, lParam );
  586.  
  587.     // Trap the context menu
  588.     if( WM_CONTEXTMENU == uMsg )
  589.         return 0;
  590.  
  591.     return CD3DApplication::MsgProc( hWnd, uMsg, wParam, lParam );
  592. }
  593.  
  594.  
  595.  
  596.