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