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 / Example1 / GameClass.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2005-10-30  |  19.5 KB  |  580 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.  
  22. #include "RNReplicaNet\Inc\ReplicaNet.h"
  23. #include "RNXPURL\Inc\XPURL.h"
  24. #include "RNPlatform\Inc\PlatformHeap.h"
  25.  
  26.  
  27. CD3DMesh*     gpAirplaneMesh;
  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_pTerrainObject  = new CD3DMesh();
  197.     m_pShadowVolume   = NULL;
  198.     m_pBigSquareVB    = NULL;
  199.  
  200.     gpAirplaneMesh = m_pAirplane;
  201. }
  202.  
  203.  
  204. //-----------------------------------------------------------------------------
  205. // Name: OneTimeSceneInit()
  206. // Desc: Called during initial app startup, this function performs all the
  207. //       permanent initialization.
  208. //-----------------------------------------------------------------------------
  209. HRESULT CMyD3DApplication::OneTimeSceneInit()
  210. {
  211.     // Construct a shadow volume object;
  212. //    m_pShadowVolume = new ShadowVolume();
  213.  
  214.     // Set cursor to indicate that user can move the object with the mouse
  215. #ifdef _WIN64
  216.     SetClassLongPtr( m_hWnd, GCLP_HCURSOR, (LONG_PTR)LoadCursor( NULL, IDC_SIZEALL ) );
  217. #else
  218.     SetClassLong( m_hWnd, GCL_HCURSOR, (LONG)LoadCursor( NULL, IDC_SIZEALL ) );
  219. #endif
  220.     return S_OK;
  221. }
  222.  
  223.  
  224.  
  225. //-----------------------------------------------------------------------------
  226. // Name: RenderShadow()
  227. // Desc:
  228. //-----------------------------------------------------------------------------
  229. HRESULT CMyD3DApplication::RenderShadow()
  230. {
  231.     // Disable z-buffer writes (note: z-testing still occurs), and enable the
  232.     // stencil-buffer
  233.     m_pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE,  FALSE );
  234.     m_pd3dDevice->SetRenderState( D3DRS_STENCILENABLE, TRUE );
  235.  
  236.     // Dont bother with interpolating color
  237.     m_pd3dDevice->SetRenderState( D3DRS_SHADEMODE,     D3DSHADE_FLAT );
  238.  
  239.     // Set up stencil compare fuction, reference value, and masks.
  240.     // Stencil test passes if ((ref & mask) cmpfn (stencil & mask)) is true.
  241.     // Note: since we set up the stencil-test to always pass, the STENCILFAIL
  242.     // renderstate is really not needed.
  243.     m_pd3dDevice->SetRenderState( D3DRS_STENCILFUNC,  D3DCMP_ALWAYS );
  244.     m_pd3dDevice->SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP );
  245.     m_pd3dDevice->SetRenderState( D3DRS_STENCILFAIL,  D3DSTENCILOP_KEEP );
  246.  
  247.     // If ztest passes, inc/decrement stencil buffer value
  248.     m_pd3dDevice->SetRenderState( D3DRS_STENCILREF,       0x1 );
  249.     m_pd3dDevice->SetRenderState( D3DRS_STENCILMASK,      0xffffffff );
  250.     m_pd3dDevice->SetRenderState( D3DRS_STENCILWRITEMASK, 0xffffffff );
  251.     m_pd3dDevice->SetRenderState( D3DRS_STENCILPASS,      D3DSTENCILOP_INCR );
  252.  
  253.     // Make sure that no pixels get drawn to the frame buffer
  254.     m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
  255.     m_pd3dDevice->SetRenderState( D3DRS_SRCBLEND,  D3DBLEND_ZERO );
  256.     m_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );
  257.  
  258.     // Draw front-side of shadow volume in stencil/z only
  259.     m_pd3dDevice->SetTransform( D3DTS_WORLD, &m_matObjectMatrix );
  260.     m_pShadowVolume->Render( m_pd3dDevice );
  261.  
  262.     // Now reverse cull order so back sides of shadow volume are written.
  263.     m_pd3dDevice->SetRenderState( D3DRS_CULLMODE,   D3DCULL_CW );
  264.  
  265.     // Decrement stencil buffer value
  266.     m_pd3dDevice->SetRenderState( D3DRS_STENCILPASS, D3DSTENCILOP_DECR );
  267.  
  268.     // Draw back-side of shadow volume in stencil/z only
  269.     m_pd3dDevice->SetTransform( D3DTS_WORLD, &m_matObjectMatrix );
  270.     m_pShadowVolume->Render( m_pd3dDevice );
  271.  
  272.     // Restore render states
  273.     m_pd3dDevice->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_GOURAUD );
  274.     m_pd3dDevice->SetRenderState( D3DRS_CULLMODE,  D3DCULL_CCW );
  275.     m_pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE,     TRUE );
  276.     m_pd3dDevice->SetRenderState( D3DRS_STENCILENABLE,    FALSE );
  277.     m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
  278.  
  279.     return S_OK;
  280. }
  281.  
  282.  
  283.  
  284.  
  285. //-----------------------------------------------------------------------------
  286. // Name: DrawShadow()
  287. // Desc: Draws a big gray polygon over scene according to the mask in the
  288. //       stencil buffer. (Any pixel with stencil==1 is in the shadow.)
  289. //-----------------------------------------------------------------------------
  290. HRESULT CMyD3DApplication::DrawShadow()
  291. {
  292.     // Set renderstates (disable z-buffering, enable stencil, disable fog, and
  293.     // turn on alphablending)
  294.     m_pd3dDevice->SetRenderState( D3DRS_ZENABLE,          FALSE );
  295.     m_pd3dDevice->SetRenderState( D3DRS_STENCILENABLE,    TRUE );
  296.     m_pd3dDevice->SetRenderState( D3DRS_FOGENABLE,        FALSE );
  297.     m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
  298.     m_pd3dDevice->SetRenderState( D3DRS_SRCBLEND,  D3DBLEND_SRCALPHA );
  299.     m_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
  300.  
  301.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  302.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
  303.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE );
  304.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
  305.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
  306.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP,   D3DTOP_MODULATE );
  307.  
  308.     // Only write where stencil val >= 1 (count indicates # of shadows that
  309.     // overlap that pixel)
  310.     m_pd3dDevice->SetRenderState( D3DRS_STENCILREF,  0x1 );
  311.     m_pd3dDevice->SetRenderState( D3DRS_STENCILFUNC, D3DCMP_LESSEQUAL );
  312.     m_pd3dDevice->SetRenderState( D3DRS_STENCILPASS, D3DSTENCILOP_KEEP );
  313.  
  314.     // Draw a big, gray square
  315.     m_pd3dDevice->SetVertexShader( D3DFVF_SHADOWVERTEX );
  316.     m_pd3dDevice->SetStreamSource( 0, m_pBigSquareVB, sizeof(SHADOWVERTEX) );
  317.     m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
  318.  
  319.     // Restore render states
  320.     m_pd3dDevice->SetRenderState( D3DRS_ZENABLE,          TRUE );
  321.     m_pd3dDevice->SetRenderState( D3DRS_STENCILENABLE,    FALSE );
  322.     m_pd3dDevice->SetRenderState( D3DRS_FOGENABLE,        TRUE );
  323.     m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
  324.  
  325.     return S_OK;
  326. }
  327.  
  328.  
  329.  
  330.  
  331.  
  332.  
  333. //-----------------------------------------------------------------------------
  334. // Name: InitDeviceObjects()
  335. // Desc: Initialize scene objects.
  336. //-----------------------------------------------------------------------------
  337. HRESULT CMyD3DApplication::InitDeviceObjects()
  338. {
  339.     // Initialize the font's internal textures
  340.     m_pFont->InitDeviceObjects( m_pd3dDevice );
  341.  
  342.     // Load an object to cast the shadow
  343.     if( FAILED( m_pAirplane->Create( m_pd3dDevice, _T("airplane 2.x") ) ) )
  344.         return D3DAPPERR_MEDIANOTFOUND;
  345.  
  346.     // Load some terrain
  347.     if( FAILED( m_pTerrainObject->Create( m_pd3dDevice, _T("SeaFloor.x") ) ) )
  348.         return D3DAPPERR_MEDIANOTFOUND;
  349.  
  350.     // Set a reasonable vertex type
  351.     m_pAirplane->SetFVF( m_pd3dDevice, D3DFVF_VERTEX );
  352.     m_pTerrainObject->SetFVF( m_pd3dDevice, D3DFVF_VERTEX );
  353.  
  354.     // Tweak the terrain vertices
  355.     {
  356.         LPDIRECT3DVERTEXBUFFER8 pVB;
  357.         VERTEX* pVertices;
  358.         DWORD   dwNumVertices = m_pTerrainObject->GetSysMemMesh()->GetNumVertices();
  359.  
  360.         // Lock the vertex buffer to access the terrain geometry
  361.         m_pTerrainObject->GetSysMemMesh()->GetVertexBuffer( &pVB );
  362.         pVB->Lock( 0, 0, (BYTE**)&pVertices, 0 );
  363.  
  364.         // Add some more bumpiness to the terrain object
  365.         for( DWORD i=0; i<dwNumVertices; i++ )
  366.         {
  367.             pVertices[i].p.y  += 1*(rand()/(FLOAT)RAND_MAX);
  368.             pVertices[i].p.y  += 2*(rand()/(FLOAT)RAND_MAX);
  369.             pVertices[i].p.y  += 1*(rand()/(FLOAT)RAND_MAX);
  370.         }
  371.  
  372.         // Release the vertex buffer
  373.         pVB->Unlock();
  374.         pVB->Release();
  375.     }
  376.  
  377.     // Create a big square for rendering the stencilbuffer contents
  378. //    if( FAILED( m_pd3dDevice->CreateVertexBuffer( 4*sizeof(SHADOWVERTEX),
  379. //                                       D3DUSAGE_WRITEONLY, D3DFVF_SHADOWVERTEX,
  380. //                                       D3DPOOL_MANAGED, &m_pBigSquareVB ) ) )
  381. //        return E_FAIL;
  382.  
  383.     return S_OK;
  384. }
  385.  
  386.  
  387.  
  388.  
  389. //-----------------------------------------------------------------------------
  390. // Name: RestoreDeviceObjects()
  391. // Desc: Restore device-memory objects and state after a device is created or
  392. //       resized.
  393. //-----------------------------------------------------------------------------
  394. HRESULT CMyD3DApplication::RestoreDeviceObjects()
  395. {
  396.     m_pFont->RestoreDeviceObjects();
  397.  
  398.     // Initialize the vertex buffers for the file-based objects
  399.     m_pAirplane->RestoreDeviceObjects( m_pd3dDevice );
  400.     m_pTerrainObject->RestoreDeviceObjects( m_pd3dDevice );
  401.  
  402.     // Create and set up the shine materials w/ textures
  403.     D3DMATERIAL8 mtrl;
  404.     D3DUtil_InitMaterial( mtrl, 1.0f, 1.0f, 1.0f );
  405.     m_pd3dDevice->SetMaterial( &mtrl );
  406.  
  407.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  408.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
  409.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE );
  410.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
  411.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
  412.  
  413.     m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
  414.     m_pd3dDevice->SetRenderState( D3DRS_DITHERENABLE, TRUE );
  415.     m_pd3dDevice->SetRenderState( D3DRS_SPECULARENABLE, FALSE );
  416.  
  417.     // Set the transform matrices
  418.     D3DXVECTOR3 vEyePt    = D3DXVECTOR3( 0.0f, 10.0f, -20.0f );
  419.     D3DXVECTOR3 vLookatPt = D3DXVECTOR3( 0.0f,  0.0f,   0.0f  );
  420.     D3DXVECTOR3 vUpVec    = D3DXVECTOR3( 0.0f,  1.0f,   0.0f  );
  421.     D3DXMATRIX matWorld, matView, matProj;
  422.  
  423.     D3DXMatrixIdentity( &matWorld );
  424.     D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
  425.     FLOAT fAspect = m_d3dsdBackBuffer.Width / (FLOAT)m_d3dsdBackBuffer.Height;
  426.     D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, fAspect, 1.0f, 100.0f );
  427.  
  428.     m_pd3dDevice->SetTransform( D3DTS_WORLD,      &matWorld );
  429.     m_pd3dDevice->SetTransform( D3DTS_VIEW,       &matView );
  430.     m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
  431.  
  432.     // Turn on fog
  433.     FLOAT fFogStart =  30.0f;
  434.     FLOAT fFogEnd   =  100.0f;
  435.     m_pd3dDevice->SetRenderState( D3DRS_FOGENABLE,      TRUE );
  436.     m_pd3dDevice->SetRenderState( D3DRS_FOGCOLOR,       0xff0000ff );
  437.     m_pd3dDevice->SetRenderState( D3DRS_FOGTABLEMODE,   D3DFOG_NONE );
  438.     m_pd3dDevice->SetRenderState( D3DRS_FOGVERTEXMODE,  D3DFOG_LINEAR );
  439.     m_pd3dDevice->SetRenderState( D3DRS_RANGEFOGENABLE, FALSE );
  440.     m_pd3dDevice->SetRenderState( D3DRS_FOGSTART,       FtoDW(fFogStart) );
  441.     m_pd3dDevice->SetRenderState( D3DRS_FOGEND,         FtoDW(fFogEnd) );
  442.  
  443.     // Set the ArcBall parameters
  444.     m_ArcBall.SetWindow( m_d3dsdBackBuffer.Width, m_d3dsdBackBuffer.Height, 2.0f );
  445.     m_ArcBall.SetRadius( 5.0f );
  446.  
  447.     m_pd3dDevice->LightEnable( 0, TRUE );
  448.     m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
  449.     m_pd3dDevice->SetRenderState( D3DRS_AMBIENT,  0x00303030 );
  450.  
  451.     // Set the size of the big square shadow
  452.     SHADOWVERTEX* v = 0;
  453.     FLOAT sx = (FLOAT)m_d3dsdBackBuffer.Width;
  454.     FLOAT sy = (FLOAT)m_d3dsdBackBuffer.Height;
  455. #if 0
  456.     m_pBigSquareVB->Lock( 0, 0, (BYTE**)&v, 0 );
  457.     v[0].p = D3DXVECTOR4(  0, sy, 0.0f, 1.0f );
  458.     v[1].p = D3DXVECTOR4(  0,  0, 0.0f, 1.0f );
  459.     v[2].p = D3DXVECTOR4( sx, sy, 0.0f, 1.0f );
  460.     v[3].p = D3DXVECTOR4( sx,  0, 0.0f, 1.0f );
  461.     v[0].color = 0x7f000000;
  462.     v[1].color = 0x7f000000;
  463.     v[2].color = 0x7f000000;
  464.     v[3].color = 0x7f000000;
  465.     m_pBigSquareVB->Unlock();
  466. #endif
  467.  
  468.     return S_OK;
  469. }
  470.  
  471.  
  472.  
  473.  
  474. //-----------------------------------------------------------------------------
  475. // Name: InvalidateDeviceObjects()
  476. // Desc: Called when the device-dependent objects are about to be lost.
  477. //-----------------------------------------------------------------------------
  478. HRESULT CMyD3DApplication::InvalidateDeviceObjects()
  479. {
  480.     m_pFont->InvalidateDeviceObjects();
  481.     m_pAirplane->InvalidateDeviceObjects();
  482.     m_pTerrainObject->InvalidateDeviceObjects();
  483.     return S_OK;
  484. }
  485.  
  486.  
  487.  
  488.  
  489. //-----------------------------------------------------------------------------
  490. // Name: DeleteDeviceObjects()
  491. // Desc: Called when the app is exiting, or the device is being changed,
  492. //       this function deletes any device dependent objects.
  493. //-----------------------------------------------------------------------------
  494. HRESULT CMyD3DApplication::DeleteDeviceObjects()
  495. {
  496.     m_pFont->DeleteDeviceObjects();
  497.     m_pAirplane->Destroy();
  498.     m_pTerrainObject->Destroy();
  499.  
  500.     SAFE_RELEASE( m_pBigSquareVB );
  501.  
  502.     return S_OK;
  503. }
  504.  
  505.  
  506.  
  507.  
  508. //-----------------------------------------------------------------------------
  509. // Name: FinalCleanup()
  510. // Desc: Called before the app exits, this function gives the app the chance
  511. //       to cleanup after itself.
  512. //-----------------------------------------------------------------------------
  513. HRESULT CMyD3DApplication::FinalCleanup()
  514. {
  515.     // This demonstrates the nice way to disconnect from a network session
  516.     // None of this is strictly required by ReplicaNet because using delete on the ReplicaNet class also disconnects,
  517.     // however it does perform a very graceful disconnect.
  518.  
  519.     // First disconnect
  520.     gNetwork->Disconnect();
  521.  
  522.     // After deleteing ReplicaNet it is not a good idea to use ReplicaNet functions on ReplicaObject derived classes
  523.     delete gNetwork;
  524.     gNetwork = 0;
  525.  
  526.     // We can shutdown the network here. Not strictly necessary but it demonstrates the graceful shutdown procedure.
  527.     RNReplicaNet::XPURL::ShutdownNetwork();
  528.  
  529.     // This force frees all remaining, one time allocated memory, from the ReplicaNet library. This memory usually exists
  530.     // for the lifetime of the application.
  531.     RNReplicaNet::PlatformHeap::ForceFree();
  532.  
  533.     return S_OK;
  534. }
  535.  
  536.  
  537.  
  538.  
  539. //-----------------------------------------------------------------------------
  540. // Name: ConfirmDevice()
  541. // Desc: Called during device intialization, this code checks the device
  542. //       for some minimum set of capabilities
  543. //-----------------------------------------------------------------------------
  544. HRESULT CMyD3DApplication::ConfirmDevice( D3DCAPS8* pCaps, DWORD dwBehavior,
  545.                                           D3DFORMAT Format )
  546. {
  547.     // Make sure device supports point lights
  548.     if( (dwBehavior & D3DCREATE_HARDWARE_VERTEXPROCESSING ) ||
  549.         (dwBehavior & D3DCREATE_MIXED_VERTEXPROCESSING ) )
  550.     {
  551.         if( 0 == ( pCaps->VertexProcessingCaps & D3DVTXPCAPS_POSITIONALLIGHTS ) )
  552.             return E_FAIL;
  553.     }
  554.  
  555.     return S_OK;
  556. }
  557.  
  558.  
  559.  
  560.  
  561. //-----------------------------------------------------------------------------
  562. // Name: MsgProc()
  563. // Desc: Message proc function to handle key and menu input
  564. //-----------------------------------------------------------------------------
  565. LRESULT CMyD3DApplication::MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam,
  566.                                     LPARAM lParam )
  567. {
  568.     // Pass mouse messages to the ArcBall so it can build internal matrices
  569.     m_ArcBall.HandleMouseMessages( hWnd, uMsg, wParam, lParam );
  570.  
  571.     // Trap the context menu
  572.     if( WM_CONTEXTMENU == uMsg )
  573.         return 0;
  574.  
  575.     return CD3DApplication::MsgProc( hWnd, uMsg, wParam, lParam );
  576. }
  577.  
  578.  
  579.  
  580.