home *** CD-ROM | disk | FTP | other *** search
/ Beginning Direct3D Game Programming / Direct3D.iso / directx / dxf / samples / multimedia / direct3d / water / cwaterapp.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-11-04  |  24.6 KB  |  827 lines

  1. //-----------------------------------------------------------------------------
  2. // File: CWaterApp.cpp
  3. //
  4. // Desc: 
  5. //
  6. // Copyright (c) 1999-2000 Microsoft Corporation. All rights reserved.
  7. //-----------------------------------------------------------------------------
  8. #define STRICT
  9. #include <tchar.h>
  10. #include <stdio.h>
  11. #include <d3dx8.h>
  12. #include "D3DApp.h"
  13. #include "D3DFont.h"
  14. #include "DXUtil.h"
  15. #include "CEnvironment.h"
  16. #include "CWater.h"
  17. #include "resource.h"
  18.  
  19. #define WATER_DEPTH 20.0f
  20. #define WATER_CAUSTICS_SIZE 128
  21.  
  22. #define mID     MAKEFOURCC('m', 'I', 'D',  0 )
  23. #define mENV    MAKEFOURCC('m', 'E', 'N', 'V')
  24. #define tFLR    MAKEFOURCC('t', 'F', 'L', 'R')
  25. #define tCAU    MAKEFOURCC('t', 'C', 'A', 'U')
  26. #define tENV    MAKEFOURCC('t', 'E', 'N', 'V')
  27.  
  28.  
  29.  
  30. //-----------------------------------------------------------------------------
  31. // Name: CMyD3DApplication
  32. // Desc: 
  33. //-----------------------------------------------------------------------------
  34. class CMyD3DApplication : public CD3DApplication
  35. {
  36. public:
  37.     CMyD3DApplication();
  38.     HRESULT GetNextTechnique( DWORD dwDir, BOOL bBypassValidate );
  39.  
  40.     virtual HRESULT OneTimeSceneInit();
  41.     virtual HRESULT InitDeviceObjects();
  42.     virtual HRESULT RestoreDeviceObjects();
  43.     virtual HRESULT InvalidateDeviceObjects();
  44.     virtual HRESULT DeleteDeviceObjects();
  45.     virtual HRESULT FrameMove();
  46.     virtual HRESULT Render();
  47.  
  48.     virtual LRESULT MsgProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
  49.  
  50.  
  51. private:
  52.     // Water    
  53.     CWater                 m_Water;
  54.     CEnvironment           m_Environment;
  55.  
  56.     LPD3DXEFFECT           m_pEffect;
  57.     LPD3DXTECHNIQUE        m_pTechnique;
  58.     LPD3DXRENDERTOSURFACE  m_pRenderToSurface;
  59.     DWORD                  m_dwTechnique;
  60.  
  61.     D3DXVECTOR4            m_vecLight;
  62.     D3DXCOLOR              m_colorLight;
  63.  
  64.     LPDIRECT3DTEXTURE8     m_pFloorTex;
  65.     LPDIRECT3DTEXTURE8     m_pCausticTex;
  66.     LPDIRECT3DSURFACE8     m_pCausticSurf;
  67.     LPDIRECT3DTEXTURE8     m_pSkyTex[6];
  68.     LPDIRECT3DCUBETEXTURE8 m_pSkyCubeTex;
  69.  
  70.     CD3DFont*              m_pFont;
  71.     CD3DFont*              m_pFontSmall;
  72.  
  73.     // Interface
  74.     BYTE        m_bKey[256];
  75.  
  76.     BOOL        m_bPause;
  77.     BOOL        m_bDrawWater;
  78.     BOOL        m_bDrawCaustics;
  79.     BOOL        m_bDrawEnvironment;
  80.     BOOL        m_bShowHelp;
  81.  
  82.     FLOAT       m_fSpeed;
  83.     FLOAT       m_fAngularSpeed;
  84.     FLOAT       m_fTime;
  85.     FLOAT       m_fSecsPerFrame;
  86.  
  87.     D3DXVECTOR3 m_vecVelocity;
  88.     D3DXVECTOR3 m_vecAngularVelocity;
  89.  
  90.     D3DXMATRIX  m_matIdentity;
  91.     D3DXMATRIX  m_matView;
  92.     D3DXMATRIX  m_matPosition;
  93.     D3DXMATRIX  m_matProjection;
  94. };
  95.  
  96.  
  97.  
  98.  
  99. //-----------------------------------------------------------------------------
  100. // Name: WinMain()
  101. // Desc: Entry point to the program. Initializes everything, and goes into a
  102. //       message-processing loop. Idle time is used to render the scene.
  103. //-----------------------------------------------------------------------------
  104. INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
  105. {
  106.     CMyD3DApplication d3dApp;
  107.  
  108.     if(FAILED(d3dApp.Create(hInst)))
  109.         return 0;
  110.  
  111.     return d3dApp.Run();
  112. }
  113.  
  114.  
  115.  
  116.  
  117. //-----------------------------------------------------------------------------
  118. // Name: CMyD3DApplication
  119. // Desc:
  120. //-----------------------------------------------------------------------------
  121. CMyD3DApplication::CMyD3DApplication()
  122. {
  123.     m_strWindowTitle    = _T("Water");
  124.     m_bUseDepthBuffer   = TRUE;
  125.  
  126.     m_pFont         = new CD3DFont( _T("Arial"), 12, D3DFONT_BOLD );
  127.     m_pFontSmall    = new CD3DFont( _T("Arial"),  9, D3DFONT_BOLD );
  128.  
  129.     // Water
  130.     m_pEffect       = NULL;
  131.     m_pTechnique    = NULL;
  132.     m_dwTechnique   = 0;
  133.  
  134.     m_vecLight      = D3DXVECTOR4(0.5f, -1.0f, 1.0f, 0.0f);
  135.     m_colorLight    = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
  136.  
  137.     m_pFloorTex     = NULL;
  138.     m_pCausticTex   = NULL;
  139.     m_pCausticSurf  = NULL;
  140.     m_pSkyCubeTex   = NULL;
  141.  
  142.     for(UINT i = 0; i < 6; i++)
  143.         m_pSkyTex[i] = NULL;
  144.  
  145.     // Misc
  146.     memset(m_bKey, 0x00, sizeof(m_bKey));
  147.  
  148.     m_fSpeed        = 25.0f;
  149.     m_fAngularSpeed = 1.0f;
  150.     m_fSecsPerFrame = 0.0f;
  151.     m_fTime         = 0.0f;
  152.  
  153.     m_vecVelocity        = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
  154.     m_vecAngularVelocity = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
  155.  
  156.     D3DXMatrixIdentity(&m_matIdentity);
  157.     D3DXMatrixIdentity(&m_matView);
  158.     D3DXMatrixIdentity(&m_matPosition);
  159.     D3DXMatrixIdentity(&m_matProjection);
  160.  
  161.     m_bShowHelp         = FALSE;
  162.     m_bPause            = FALSE;
  163. }
  164.  
  165.  
  166.  
  167.  
  168. //-----------------------------------------------------------------------------
  169. // Name: GetNextTechnique
  170. // Desc:
  171. //-----------------------------------------------------------------------------
  172. HRESULT CMyD3DApplication::GetNextTechnique(DWORD dwDir, BOOL bBypassValidate)
  173. {
  174.     HRESULT hr;
  175.  
  176.     D3DXEFFECT_DESC effect;
  177.     D3DXTECHNIQUE_DESC technique;
  178.     DWORD dwTechnique = m_dwTechnique;
  179.  
  180.     m_pEffect->GetDesc(&effect);
  181.  
  182.  
  183.     for(;;)
  184.     {
  185.         dwTechnique += dwDir;
  186.  
  187.         if(dwTechnique & 0x80000000)
  188.             dwTechnique = effect.Techniques - 1;
  189.  
  190.         if(dwTechnique >= effect.Techniques)
  191.             dwTechnique = 0;
  192.  
  193.         if(dwDir && (dwTechnique == m_dwTechnique))
  194.             break;
  195.  
  196.         if(!dwDir)
  197.             dwDir = 1;
  198.  
  199.         LPD3DXTECHNIQUE pTechnique;
  200.  
  201.         if(FAILED(hr = m_pEffect->GetTechnique(dwTechnique, &pTechnique)))
  202.             return hr;
  203.  
  204.         if(bBypassValidate || (dwTechnique == effect.Techniques - 1) || 
  205.           (m_bDrawCaustics || !pTechnique->IsParameterUsed(tCAU)) && SUCCEEDED(pTechnique->Validate()))
  206.         {
  207.             SAFE_RELEASE(m_pTechnique);
  208.             m_dwTechnique = dwTechnique;
  209.             m_pTechnique = pTechnique;
  210.  
  211.             m_pTechnique->GetDesc(&technique);
  212.  
  213.  
  214.             char szText[256];
  215.             sprintf(szText, "Water - Technique %d", m_dwTechnique);
  216.             SetWindowText(m_hWnd, szText);
  217.  
  218.             return S_OK;
  219.         }
  220.  
  221.         SAFE_RELEASE(pTechnique);
  222.     }
  223.  
  224.     return E_FAIL;}
  225.  
  226.  
  227.  
  228.  
  229. //-----------------------------------------------------------------------------
  230. // Name: OneTimeSceneInit
  231. // Desc:
  232. //-----------------------------------------------------------------------------
  233. HRESULT CMyD3DApplication::OneTimeSceneInit()
  234. {
  235.     HRESULT hr;
  236.  
  237.     // Initialize Water
  238.     if(FAILED(hr = m_Water.Initialize(64.0f, WATER_DEPTH)))
  239.         return hr;
  240.  
  241.     // Initialize Environment
  242.     if(FAILED(hr = m_Environment.Initialize(1000.0f)))
  243.         return hr;
  244.  
  245.     // Misc stuff
  246.     D3DXMatrixRotationX(&m_matPosition, D3DX_PI * -0.3f);
  247.     m_matPosition._42 = 15.0f;
  248.     m_matPosition._43 = 15.0f;
  249.  
  250.     D3DXMatrixInverse(&m_matView, NULL, &m_matPosition);
  251.     return S_OK;
  252. }
  253.  
  254.  
  255.  
  256.  
  257. //-----------------------------------------------------------------------------
  258. // Name: InitDeviceObjects
  259. // Desc:
  260. //-----------------------------------------------------------------------------
  261. HRESULT CMyD3DApplication::InitDeviceObjects()
  262. {
  263.     HRESULT hr;
  264.     TCHAR sz[512];
  265.  
  266.     m_bDrawWater        = TRUE;
  267.     m_bDrawCaustics     = TRUE;
  268.     m_bDrawEnvironment  = TRUE;
  269.  
  270.  
  271.     // Initialize the font's internal textures
  272.     m_pFont->InitDeviceObjects( m_pd3dDevice );
  273.     m_pFontSmall->InitDeviceObjects( m_pd3dDevice );
  274.  
  275.     // Floor
  276.     DXUtil_FindMediaFile(sz, _T("Water.bmp"));
  277.     D3DXCreateTextureFromFileEx(m_pd3dDevice, sz, D3DX_DEFAULT, D3DX_DEFAULT, 
  278.         D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, 
  279.         D3DX_DEFAULT, 0, NULL, NULL, &m_pFloorTex);
  280.  
  281.  
  282.     // Sky
  283.     TCHAR* szSkyTex[6] =
  284.     {
  285.         _T("lobbyxpos.bmp"), _T("lobbyxneg.bmp"),
  286.         _T("lobbyypos.bmp"), _T("lobbyyneg.bmp"),
  287.         _T("lobbyzneg.bmp"), _T("lobbyzpos.bmp")
  288.     };
  289.  
  290.     for(UINT i = 0; i < 6; i++)
  291.     {
  292.         DXUtil_FindMediaFile(sz, szSkyTex[i]);
  293.         D3DXCreateTextureFromFileEx(m_pd3dDevice, sz, D3DX_DEFAULT, D3DX_DEFAULT, 
  294.             1, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 
  295.             0, NULL, NULL, &m_pSkyTex[i]);
  296.     }
  297.  
  298.     if(SUCCEEDED(D3DXCreateCubeTexture(m_pd3dDevice, 128, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, &m_pSkyCubeTex)))
  299.     {
  300.         for(UINT i = 0; i < 6; i++)
  301.         {
  302.             if(m_pSkyTex[i])
  303.             {
  304.                 IDirect3DSurface8 *pSrc;
  305.                 IDirect3DSurface8 *pDest;
  306.  
  307.                 m_pSkyTex[i]->GetSurfaceLevel(0, &pSrc);
  308.                 m_pSkyCubeTex->GetCubeMapSurface((D3DCUBEMAP_FACES) i, 0, &pDest);
  309.  
  310.                 if(pSrc && pDest)
  311.                     D3DXLoadSurfaceFromSurface(pDest, NULL, NULL, pSrc, NULL, NULL, D3DX_DEFAULT, 0);
  312.  
  313.                 SAFE_RELEASE(pDest);
  314.                 SAFE_RELEASE(pSrc);
  315.             }
  316.         }
  317.  
  318.         D3DXFilterCubeTexture(m_pSkyCubeTex, NULL, 0, D3DX_DEFAULT);
  319.     }
  320.  
  321.  
  322.  
  323.     // OnCreateDevice
  324.     if(FAILED(hr = m_Water.OnCreateDevice(m_pd3dDevice)))
  325.         return hr;
  326.  
  327.     if(FAILED(hr = m_Environment.OnCreateDevice(m_pd3dDevice)))
  328.         return hr;
  329.  
  330.     return S_OK;
  331. }
  332.  
  333.  
  334.  
  335.     
  336. //-----------------------------------------------------------------------------
  337. // Name: RestoreDeviceObjects
  338. // Desc:
  339. //-----------------------------------------------------------------------------
  340. HRESULT CMyD3DApplication::RestoreDeviceObjects()
  341. {
  342.     HRESULT hr;
  343.  
  344.     // Restore the font
  345.     m_pFont->RestoreDeviceObjects();
  346.     m_pFontSmall->RestoreDeviceObjects();
  347.  
  348.     // Create light
  349.     D3DLIGHT8 light;
  350.     ZeroMemory(&light, sizeof(light));
  351.  
  352.     light.Type        = D3DLIGHT_DIRECTIONAL;
  353.     light.Diffuse.r   = m_colorLight.r;
  354.     light.Diffuse.g   = m_colorLight.g;
  355.     light.Diffuse.b   = m_colorLight.b;
  356.     light.Diffuse.a   = m_colorLight.a;
  357.     light.Specular.r  = 1.0f;
  358.     light.Specular.g  = 1.0f;
  359.     light.Specular.b  = 1.0f;
  360.     light.Specular.a  = 0.0f;
  361.     light.Direction.x = m_vecLight.x;
  362.     light.Direction.y = m_vecLight.y;
  363.     light.Direction.z = m_vecLight.z;
  364.  
  365.     m_pd3dDevice->SetLight(0, &light);
  366.     m_pd3dDevice->LightEnable(0, TRUE);
  367.  
  368.  
  369.     // Create material
  370.     D3DMATERIAL8 material;
  371.     ZeroMemory(&material, sizeof(material));
  372.  
  373.     material.Diffuse.a  = 1.0f;
  374.     material.Specular.r = 0.5f;
  375.     material.Specular.g = 0.5f;
  376.     material.Specular.b = 0.5f;
  377.     material.Power      = 20.0f;
  378.  
  379.     m_pd3dDevice->SetMaterial(&material);
  380.  
  381.     // Setup render states
  382.     m_pd3dDevice->SetVertexShader(D3DFVF_XYZ);
  383.  
  384.     m_pd3dDevice->SetTransform(D3DTS_VIEW,  &m_matView);
  385.     m_pd3dDevice->SetTransform(D3DTS_WORLD, &m_matIdentity);
  386.  
  387.     m_pd3dDevice->SetRenderState(D3DRS_LIGHTING,       FALSE);
  388.     m_pd3dDevice->SetRenderState(D3DRS_SPECULARENABLE, FALSE);
  389.  
  390.     m_pd3dDevice->SetRenderState(D3DRS_ZFUNC,     D3DCMP_LESSEQUAL);
  391.     m_pd3dDevice->SetRenderState(D3DRS_CULLMODE,  D3DCULL_CW);
  392.     m_pd3dDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
  393.     m_pd3dDevice->SetRenderState(D3DRS_SRCBLEND,  D3DBLEND_ONE);
  394.     m_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
  395.  
  396.     m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP,   D3DTOP_DISABLE);
  397.     m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
  398.     m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
  399.     m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP,   D3DTOP_DISABLE);
  400.     m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
  401.     m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
  402.     m_pd3dDevice->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
  403.     m_pd3dDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
  404.     m_pd3dDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
  405.     m_pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
  406.  
  407.     m_pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP,   D3DTOP_DISABLE);
  408.     m_pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
  409.     m_pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
  410.     m_pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAOP,   D3DTOP_DISABLE);
  411.     m_pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
  412.     m_pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
  413.     m_pd3dDevice->SetTextureStageState(1, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
  414.     m_pd3dDevice->SetTextureStageState(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
  415.     m_pd3dDevice->SetTextureStageState(1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
  416.     m_pd3dDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0);
  417.  
  418.  
  419.  
  420.  
  421.     // Create caustic texture
  422.     D3DDISPLAYMODE mode;
  423.     m_pd3dDevice->GetDisplayMode(&mode);
  424.  
  425.     if(FAILED(hr = D3DXCreateTexture(m_pd3dDevice, WATER_CAUSTICS_SIZE, WATER_CAUSTICS_SIZE, 1, D3DUSAGE_RENDERTARGET, mode.Format, D3DPOOL_DEFAULT, &m_pCausticTex)) &&
  426.        FAILED(hr = D3DXCreateTexture(m_pd3dDevice, WATER_CAUSTICS_SIZE, WATER_CAUSTICS_SIZE, 1, 0, mode.Format, D3DPOOL_DEFAULT, &m_pCausticTex)))
  427.     {
  428.         return hr;
  429.     }
  430.  
  431.     D3DSURFACE_DESC desc;
  432.     m_pCausticTex->GetSurfaceLevel(0, &m_pCausticSurf);
  433.     m_pCausticSurf->GetDesc(&desc);
  434.  
  435.     if(FAILED(hr = D3DXCreateRenderToSurface(m_pd3dDevice, desc.Width, desc.Height, 
  436.         desc.Format, FALSE, D3DFMT_UNKNOWN, &m_pRenderToSurface)))
  437.     {
  438.         return hr;
  439.     }
  440.  
  441.  
  442.  
  443.     // Shader
  444.     TCHAR sz[512];
  445.     LPD3DXBUFFER pEffect;
  446.  
  447.     DXUtil_FindMediaFile(sz, _T("water.sha"));
  448.  
  449.     if(FAILED(hr = D3DXCompileEffectFromFile(sz, &pEffect, NULL)))
  450.         return hr;
  451.  
  452.     hr = D3DXCreateEffect(m_pd3dDevice, pEffect->GetBufferPointer(), pEffect->GetBufferSize(), 0, &m_pEffect);
  453.  
  454.     SAFE_RELEASE(pEffect);
  455.  
  456.     if(FAILED(hr))
  457.         return hr;
  458.  
  459.     m_pEffect->SetMatrix(mID,  &m_matIdentity);
  460.     m_pEffect->SetMatrix(mENV, &m_matIdentity);
  461.  
  462.     m_pEffect->SetTexture(tFLR, m_pFloorTex);
  463.     m_pEffect->SetTexture(tCAU, m_pCausticTex);
  464.     m_pEffect->SetTexture(tENV, m_pSkyCubeTex);
  465.  
  466.     if(FAILED(hr = GetNextTechnique(0, FALSE)))
  467.         return hr;
  468.  
  469.  
  470.     // Set surfaces
  471.     if(FAILED(hr = m_Environment.SetSurfaces(
  472.         m_pSkyTex[D3DCUBEMAP_FACE_NEGATIVE_X], m_pSkyTex[D3DCUBEMAP_FACE_POSITIVE_X], 
  473.         m_pSkyTex[D3DCUBEMAP_FACE_NEGATIVE_Y], m_pSkyTex[D3DCUBEMAP_FACE_POSITIVE_Y],
  474.         m_pSkyTex[D3DCUBEMAP_FACE_POSITIVE_Z], m_pSkyTex[D3DCUBEMAP_FACE_NEGATIVE_Z])))
  475.     {
  476.         return hr;
  477.     }
  478.  
  479.  
  480.     // OnResetDevice
  481.     if(FAILED(hr = m_Water.OnResetDevice()))
  482.         return hr;
  483.  
  484.     if(FAILED(hr = m_Environment.OnResetDevice()))
  485.         return hr;
  486.  
  487.     return S_OK;
  488. }
  489.  
  490.  
  491.  
  492.  
  493. //-----------------------------------------------------------------------------
  494. // Name: InvalidateDeviceObjects
  495. // Desc:
  496. //-----------------------------------------------------------------------------
  497. HRESULT CMyD3DApplication::InvalidateDeviceObjects()
  498. {
  499.     HRESULT hr;
  500.  
  501.     m_pFont->InvalidateDeviceObjects();
  502.     m_pFontSmall->InvalidateDeviceObjects();
  503.  
  504.     if(FAILED(hr = m_Water.OnLostDevice()))
  505.         return hr;
  506.  
  507.     if(FAILED(hr = m_Environment.OnLostDevice()))
  508.         return hr;
  509.  
  510.     SAFE_RELEASE(m_pRenderToSurface);
  511.     SAFE_RELEASE(m_pTechnique);
  512.     SAFE_RELEASE(m_pEffect);
  513.     SAFE_RELEASE(m_pCausticSurf);
  514.     SAFE_RELEASE(m_pCausticTex);
  515.  
  516.     return S_OK;
  517. }
  518.  
  519.  
  520.  
  521.  
  522. //-----------------------------------------------------------------------------
  523. // Name: DeleteDeviceObjects
  524. // Desc:
  525. //-----------------------------------------------------------------------------
  526. HRESULT CMyD3DApplication::DeleteDeviceObjects()
  527. {
  528.     HRESULT hr;
  529.  
  530.     m_pFont->DeleteDeviceObjects();
  531.     m_pFontSmall->DeleteDeviceObjects();
  532.  
  533.     if(FAILED(hr = m_Water.OnDestroyDevice()))
  534.         return hr;
  535.  
  536.     if(FAILED(hr = m_Environment.OnDestroyDevice()))
  537.         return hr;
  538.  
  539.     SAFE_RELEASE(m_pFloorTex);
  540.     SAFE_RELEASE(m_pSkyCubeTex);
  541.  
  542.     for(UINT i = 0; i < 6; i++)
  543.         SAFE_RELEASE(m_pSkyTex[i]);
  544.  
  545.  
  546.     return S_OK;
  547. }
  548.  
  549.  
  550.  
  551.  
  552. //-----------------------------------------------------------------------------
  553. // Name: FrameMove
  554. // Desc:
  555. //-----------------------------------------------------------------------------
  556. HRESULT CMyD3DApplication::FrameMove()
  557. {
  558.     HRESULT hr;
  559.  
  560.     //
  561.     // Process keyboard input
  562.     //
  563.  
  564.     D3DXVECTOR3 vecT(0.0f, 0.0f, 0.0f);
  565.     D3DXVECTOR3 vecR(0.0f, 0.0f, 0.0f);
  566.  
  567.     if(m_bKey[VK_NUMPAD1] || m_bKey[VK_LEFT])  vecT.x -= 1.0f; // Slide Left
  568.     if(m_bKey[VK_NUMPAD3] || m_bKey[VK_RIGHT]) vecT.x += 1.0f; // Slide Right
  569.     if(m_bKey[VK_DOWN])                        vecT.y -= 1.0f; // Slide Down
  570.     if(m_bKey[VK_UP])                          vecT.y += 1.0f; // Slide Up
  571.     if(m_bKey['W'])                            vecT.z -= 2.0f; // Move Forward
  572.     if(m_bKey['S'])                            vecT.z += 2.0f; // Move Backward
  573.     if(m_bKey['A'] || m_bKey[VK_NUMPAD8])      vecR.x -= 1.0f; // Pitch Down
  574.     if(m_bKey['Z'] || m_bKey[VK_NUMPAD2])      vecR.x += 1.0f; // Pitch Up
  575.     if(m_bKey['E'] || m_bKey[VK_NUMPAD6])      vecR.y -= 1.0f; // Turn Right
  576.     if(m_bKey['Q'] || m_bKey[VK_NUMPAD4])      vecR.y += 1.0f; // Turn Left
  577.     if(m_bKey[VK_NUMPAD9])                     vecR.z -= 2.0f; // Roll CW
  578.     if(m_bKey[VK_NUMPAD7])                     vecR.z += 2.0f; // Roll CCW
  579.  
  580.     m_vecVelocity = m_vecVelocity * 0.9f + vecT * 0.1f;
  581.     m_vecAngularVelocity = m_vecAngularVelocity * 0.9f + vecR * 0.1f;
  582.  
  583.  
  584.  
  585.     //
  586.     // Update position and view matricies
  587.     //
  588.  
  589.     D3DXMATRIX matT, matR;
  590.     D3DXQUATERNION qR;
  591.  
  592.     vecT = m_vecVelocity * m_fElapsedTime * m_fSpeed;
  593.     vecR = m_vecAngularVelocity * m_fElapsedTime * m_fAngularSpeed;
  594.  
  595.     D3DXMatrixTranslation(&matT, vecT.x, vecT.y, vecT.z);
  596.     D3DXMatrixMultiply(&m_matPosition, &matT, &m_matPosition);
  597.  
  598.     D3DXQuaternionRotationYawPitchRoll(&qR, vecR.y, vecR.x, vecR.z);
  599.     D3DXMatrixRotationQuaternion(&matR, &qR);
  600.  
  601.     D3DXMatrixMultiply(&m_matPosition, &matR, &m_matPosition);
  602.     D3DXMatrixInverse(&m_matView, NULL, &m_matPosition);
  603.  
  604.  
  605.     //
  606.     // Update simulation
  607.     //
  608.  
  609.     if(!m_bPause && m_bDrawWater)
  610.     {
  611.         BOOL bCaustics = m_bDrawCaustics && m_pTechnique->IsParameterUsed(tCAU);
  612.         D3DXVECTOR3 vecPos(m_matPosition._41, m_matPosition._42, m_matPosition._43);
  613.         D3DXVECTOR3 vecLight(0.0f, 1.0f, 0.0f);
  614.  
  615.         m_Water.Update(vecPos, vecLight, bCaustics);
  616.         m_fTime += m_fSecsPerFrame;
  617.  
  618.         if(bCaustics)
  619.         {
  620.             if(SUCCEEDED(m_pRenderToSurface->BeginScene(m_pCausticSurf, NULL)))
  621.             {
  622.                 D3DXMATRIX matProj;
  623.                 D3DXMATRIX matView;
  624.  
  625.                 D3DXMatrixOrthoRH(&matProj, 63.0f, 63.0f, 1.0f, 100.0f);
  626.                 D3DXMatrixRotationX(&matView, 0.5f * D3DX_PI);
  627.                 matView._43 = -50.0f;
  628.  
  629.                 m_pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProj);
  630.                 m_pd3dDevice->SetTransform(D3DTS_VIEW, &matView);
  631.  
  632.                 m_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0f, 0);
  633.  
  634.                 m_pd3dDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
  635.                 m_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
  636.                 m_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
  637.  
  638.                 m_Water.DrawCaustics();
  639.  
  640.                 m_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
  641.                 m_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
  642.                 m_pd3dDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
  643.  
  644.                 m_pRenderToSurface->EndScene();
  645.             }
  646.             else
  647.             {
  648.                 m_bDrawCaustics = FALSE;
  649.                 m_pEffect->SetTexture(tCAU, NULL);
  650.  
  651.                 if(FAILED(hr = GetNextTechnique(0, FALSE)))
  652.                     return hr;
  653.             }
  654.         }
  655.     }
  656.  
  657.     return S_OK;
  658. }
  659.  
  660.  
  661.  
  662.  
  663. //-----------------------------------------------------------------------------
  664. // Name: Render
  665. // Desc:
  666. //-----------------------------------------------------------------------------
  667. HRESULT CMyD3DApplication::Render()
  668. {   
  669.     HRESULT hr;
  670.  
  671.     if(FAILED(hr = m_pd3dDevice->BeginScene()))
  672.         return hr;
  673.  
  674.     // Draw Environment
  675.     FLOAT fAspectRatio = (FLOAT)m_d3dsdBackBuffer.Width / (FLOAT)m_d3dsdBackBuffer.Height;
  676.     D3DXMatrixPerspectiveFovRH(&m_matProjection, D3DXToRadian(60.0f), fAspectRatio, 0.1f, 2000.0f);
  677.     m_pd3dDevice->SetTransform(D3DTS_PROJECTION, &m_matProjection);    
  678.  
  679.     if(m_bDrawEnvironment)
  680.     {
  681.         D3DXMATRIX mat(m_matView);
  682.         mat._41 = mat._42 = mat._43 = 0.0f;
  683.         m_pd3dDevice->SetTransform(D3DTS_VIEW, &mat);
  684.  
  685.         m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
  686.         m_pd3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
  687.  
  688.         m_Environment.Draw();
  689.  
  690.         m_pd3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
  691.         m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE);
  692.     }
  693.     else
  694.     {
  695.         m_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
  696.     }
  697.  
  698.     m_pd3dDevice->SetTransform(D3DTS_VIEW, &m_matView);
  699.  
  700.     // Draw water
  701.     if(m_bDrawWater)
  702.     {
  703.         // Setup matrices
  704.         if(m_pTechnique->IsParameterUsed(mENV))
  705.         {
  706.             D3DXMATRIX matP(m_matPosition);
  707.             matP._41 = matP._42 = matP._43 = 0.0f;
  708.  
  709.             D3DXMATRIX mat;
  710.             D3DXMatrixScaling(&mat, 1.0f, 1.0f, -1.0f);
  711.  
  712.             D3DXMatrixMultiply(&mat, &matP, &mat);
  713.  
  714.             // matCube
  715.             m_pEffect->SetMatrix(mENV, &mat);
  716.         }
  717.  
  718.         // Draw water
  719.         UINT uPasses;
  720.         m_pTechnique->Begin(&uPasses);
  721.  
  722.         for(UINT uPass = 0; uPass < uPasses; uPass++)
  723.         {
  724.             m_pTechnique->Pass(uPass);
  725.             m_Water.DrawSurface();
  726.         }
  727.  
  728.         m_pTechnique->End();
  729.     }
  730.  
  731.     // Show info
  732.     m_pFont->DrawText( 2,  0, D3DCOLOR_ARGB(255,255,255,0), m_strFrameStats );
  733.     m_pFont->DrawText( 2, 20, D3DCOLOR_ARGB(255,255,255,0), m_strDeviceStats );
  734.  
  735.     TCHAR szText[100];
  736.     wsprintf( szText, _T("Using Technique %d"), m_dwTechnique );
  737.     m_pFontSmall->DrawText( 2, 40, D3DCOLOR_ARGB(255,255,100,100), szText );
  738.     
  739.     if( m_bShowHelp )
  740.     {
  741.         m_pFontSmall->DrawText(  2, 60, D3DCOLOR_ARGB(255,100,100,200),
  742.                                 _T("Keyboard controls:") );
  743.         m_pFontSmall->DrawText( 20, 80, D3DCOLOR_ARGB(255,100,100,200),
  744.                                 _T("Add Drop\n")
  745.                                 _T("Next Technique\n")
  746.                                 _T("Next Tech. (no validate)\n")
  747.                                 _T("Prev Technique\n")
  748.                                 _T("Prev Tech. (no validate)\n")
  749.                                 _T("Move\nTurn\nPitch\nSlide\n")
  750.                                 _T("Help\nChange device\nExit") );
  751.         m_pFontSmall->DrawText( 210, 80, D3DCOLOR_ARGB(255,100,100,200),
  752.                                 _T("D\n")
  753.                                 _T("PageDn\nShift-PageDn\n")
  754.                                 _T("PageUp\nShift-PageUp\n")
  755.                                 _T("W,S\nE,Q\nA,Z\nArrow keys\n")
  756.                                 _T("F1\nF2\nEsc") );
  757.     }
  758.     else
  759.     {
  760.         m_pFontSmall->DrawText(  2, 60, D3DCOLOR_ARGB(255,100,100,200), 
  761.                            _T("Press F1 for help") );
  762.     }
  763.  
  764.  
  765.     if(FAILED(hr = m_pd3dDevice->EndScene()))
  766.         return hr;
  767.  
  768.     return S_OK;
  769. }
  770.  
  771.  
  772.  
  773.  
  774. //-----------------------------------------------------------------------------
  775. // Name: MsgProc
  776. // Desc:
  777. //-----------------------------------------------------------------------------
  778. LRESULT CMyD3DApplication::MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, 
  779.                                     LPARAM lParam )
  780. {
  781.     switch( uMsg )
  782.     {
  783.         case WM_KEYDOWN:
  784.             m_bKey[wParam] = TRUE;
  785.             break;
  786.  
  787.         case WM_KEYUP:
  788.             m_bKey[wParam] = FALSE;
  789.             break;
  790.  
  791.     case WM_COMMAND:
  792.         {
  793.             switch( LOWORD(wParam) )
  794.             {
  795.             case IDM_ADDDROP:
  796.                 m_Water.Drop();
  797.                 break;
  798.  
  799.             case IDM_NEXT_TECHNIQUE:
  800.                 GetNextTechnique(1, FALSE);
  801.                 break;
  802.  
  803.             case IDM_NEXT_TECHNIQUE_NOVALIDATE:
  804.                 GetNextTechnique(1, TRUE);
  805.                 break;
  806.  
  807.             case IDM_PREV_TECHNIQUE:
  808.                 GetNextTechnique(-1, FALSE);
  809.                 break;
  810.  
  811.             case IDM_PREV_TECHNIQUE_NOVALIDATE:
  812.                 GetNextTechnique(-1, TRUE);
  813.                 break;
  814.  
  815.             case IDM_TOGGLEHELP:
  816.                 m_bShowHelp = !m_bShowHelp;
  817.                 break;
  818.             }
  819.         }
  820.  
  821.     }
  822.  
  823.     return CD3DApplication::MsgProc( hWnd, uMsg, wParam, lParam );
  824. }
  825.  
  826.  
  827.