home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Game Programming for Teens / VBGPFT.cdr / DirectX8 / dx8a_sdk.exe / samples / multimedia / direct3d / mfcfog / fog.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-11-04  |  35.5 KB  |  1,037 lines

  1. //-----------------------------------------------------------------------------
  2. // File: Fog.cpp
  3. //
  4. // Desc: Example code showing how to do fog in D3D
  5. //
  6. // Copyright (c) 1997-2000 Microsoft Corporation. All rights reserved.
  7. //-----------------------------------------------------------------------------
  8. #define STRICT
  9. #include "stdafx.h"
  10. #include <tchar.h>
  11. #include <math.h>
  12. #include <D3DX8.h>
  13. #include "resource.h"
  14. #include "D3DApp.h"
  15. #include "D3DUtil.h"
  16. #include "DXUtil.h"
  17. #include "fog.h"
  18.  
  19.  
  20.  
  21.  
  22. //-----------------------------------------------------------------------------
  23. // Structures and Macros
  24. //-----------------------------------------------------------------------------
  25. inline DWORD FtoDW( FLOAT f ) { return *((DWORD*)&f); }
  26.  
  27. struct FOGVERTEX
  28. {
  29.         D3DXVECTOR3 p;
  30.         D3DXVECTOR3 n;
  31.         FLOAT       tu, tv;
  32. };
  33.  
  34. #define D3DFVF_FOGVERTEX (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1)
  35.  
  36. #define FAR_PLANE (150.0f)
  37. #define NEAR_PLANE (1.0f)
  38.  
  39.  
  40.  
  41.  
  42. //-----------------------------------------------------------------------------
  43. // Application globals
  44. //-----------------------------------------------------------------------------
  45. TCHAR*        g_strAppTitle       = _T( "MFCFog: D3D Fog Sample Using MFC" );
  46. CApp          g_App;
  47. CAppForm*     g_AppFormView = NULL;
  48.  
  49.  
  50.  
  51.  
  52. //-----------------------------------------------------------------------------
  53. // The MFC macros are all listed here
  54. //-----------------------------------------------------------------------------
  55. IMPLEMENT_DYNCREATE( CAppDoc,      CDocument )
  56. IMPLEMENT_DYNCREATE( CAppFrameWnd, CFrameWnd )
  57. IMPLEMENT_DYNCREATE( CAppForm,     CFormView )
  58.  
  59.  
  60.  
  61.  
  62. BEGIN_MESSAGE_MAP( CApp, CWinApp )
  63.     //{{AFX_MSG_MAP(CApp)
  64.     //}}AFX_MSG_MAP
  65. END_MESSAGE_MAP()
  66.  
  67.  
  68.  
  69.  
  70. BEGIN_MESSAGE_MAP( CAppForm, CFormView )
  71.     //{{AFX_MSG_MAP(CAppForm)
  72.     ON_COMMAND(    IDC_VIEWFULLSCREEN, OnToggleFullScreen )
  73.     ON_COMMAND(    IDM_CHANGEDEVICE,   OnChangeDevice )
  74.     ON_WM_HSCROLL()
  75.     ON_BN_CLICKED( IDC_FOGCOLOR,       OnFogColor )
  76.     ON_BN_CLICKED( IDC_RANGEBASEDFOG,  OnRangeBasedFog )
  77.     ON_BN_CLICKED( IDC_VERTEXFOG,      OnVertexFog )
  78.     ON_BN_CLICKED( IDC_TABLEFOG,       OnTableFog )
  79.     ON_BN_CLICKED( IDC_LINEARFOGMODE,  OnFogMode )
  80.     ON_BN_CLICKED( IDC_LORESTERRAIN,   OnTerrainResolution)
  81.     ON_BN_CLICKED( IDM_CHANGEDEVICE,   OnChangeDevice )
  82.     ON_BN_CLICKED( IDC_EXPFOGMODE,     OnFogMode )
  83.     ON_BN_CLICKED( IDC_EXP2FOGMODE,    OnFogMode )
  84.     ON_BN_CLICKED( IDC_HIRESTERRAIN,   OnTerrainResolution)
  85.     //}}AFX_MSG_MAP
  86. END_MESSAGE_MAP()
  87.  
  88.  
  89.  
  90.  
  91. //-----------------------------------------------------------------------------
  92. // Name: InitInstance()
  93. // Desc: This is the main entry point for the application. The MFC window stuff
  94. //       is initialized here. See also the main initialization routine for the
  95. //       CAppForm class, which is called indirectly from here.
  96. //-----------------------------------------------------------------------------
  97. BOOL CApp::InitInstance()
  98. {
  99.     // Asscociate the MFC app with the frame window and doc/view classes
  100.     AddDocTemplate( new CSingleDocTemplate( IDR_MAINFRAME,
  101.                                             RUNTIME_CLASS(CAppDoc),
  102.                                             RUNTIME_CLASS(CAppFrameWnd),
  103.                                             RUNTIME_CLASS(CAppForm) ) );
  104.  
  105.     // Dispatch commands specified on the command line (req'd by MFC). This
  106.     // also initializes the the CAppDoc, CAppFrameWnd, and CAppForm classes.
  107.     CCommandLineInfo cmdInfo;
  108.     ParseCommandLine( cmdInfo );
  109.     if( !ProcessShellCommand( cmdInfo ) )
  110.         return FALSE;
  111.  
  112.     if( !g_AppFormView->IsReady() )
  113.         return FALSE;
  114.  
  115.     // The formview window has been initialized, so show and update it.
  116.     m_pMainWnd->MoveWindow( 0, 0, 590, 370, TRUE );
  117.     m_pMainWnd->SetWindowText( g_strAppTitle );
  118.     m_pMainWnd->UpdateWindow();
  119.  
  120.     return TRUE;
  121. }
  122.  
  123.  
  124.  
  125.  
  126. //-----------------------------------------------------------------------------
  127. // Name: OnIdle()
  128. // Desc: Uses idle time to render the 3D scene.
  129. //-----------------------------------------------------------------------------
  130. BOOL CApp::OnIdle( LONG )
  131. {
  132.     // Do not render if the app is minimized
  133.     if( m_pMainWnd->IsIconic() )
  134.         return FALSE;
  135.  
  136.     TCHAR strStatsPrev[200];
  137.  
  138.     lstrcpy(strStatsPrev, g_AppFormView->PstrFrameStats());
  139.  
  140.     // Update and render a frame
  141.     if( g_AppFormView->IsReady() )
  142.     {
  143.         g_AppFormView->CheckForLostFullscreen();
  144.         g_AppFormView->RenderScene();
  145.         if (lstrcmp(strStatsPrev, g_AppFormView->PstrFrameStats()) != 0)
  146.             g_AppFormView->GetDlgItem(IDC_FPS_TEXT)->SetWindowText(g_AppFormView->PstrFrameStats());
  147.     }
  148.  
  149.     // Keep requesting more idle time
  150.     return TRUE;
  151. }
  152.  
  153.  
  154.  
  155.  
  156. //-----------------------------------------------------------------------------
  157. // Name: PreCreateWindow()
  158. // Desc: Change the window style (so it cannot maximize or be sized) before
  159. //       the main frame window is created.
  160. //-----------------------------------------------------------------------------
  161. BOOL CAppFrameWnd::PreCreateWindow( CREATESTRUCT& cs )
  162. {
  163.     cs.style = WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX;
  164.  
  165.     return CFrameWnd::PreCreateWindow( cs );
  166. }
  167.  
  168.  
  169.  
  170.  
  171. //-----------------------------------------------------------------------------
  172. // Name: CAppForm()
  173. // Desc: Constructor for the dialog resource form
  174. //-----------------------------------------------------------------------------
  175. CAppForm::CAppForm()
  176.          :CFormView( IDD_FORMVIEW )
  177. {
  178.     g_AppFormView          = this;
  179.     m_bHiResTerrain        = FALSE;
  180.     m_bHiResTerrainOld     = FALSE;
  181.     m_dwFogColor           = 0x00b5b5ff;
  182.     m_dwFogMode            = D3DFOG_LINEAR;
  183.     m_bCanDoTableFog       = FALSE;
  184.     m_bCanDoVertexFog      = FALSE;
  185.     m_bCanDoWFog           = FALSE;
  186.     m_bDeviceUsesWFog      = FALSE;
  187.     m_bRangeBasedFog       = FALSE;
  188.     m_bUsingTableFog       = FALSE;
  189.     m_fFogStartSlider      = 0.0f;
  190.     m_fFogEndSlider        = 1.0f;
  191.     m_fFogStartValue       = 0.0f;
  192.     m_fFogEndValue         = 1.0f;
  193.     m_fFogDensity          = 0.0f;
  194.     m_hwndRenderWindow     = NULL;
  195.     m_hwndRenderFullScreen = NULL;
  196.     m_pFloorTexture        = NULL;
  197.     m_pTerrainVB           = NULL;
  198.     m_dwNumTerrainVertices = 0L;
  199.     m_pColumnVB            = NULL;
  200.     m_dwNumColumnVertices  = 0L;
  201.  
  202.     // Override some CD3DApplication defaults:
  203.     m_bUseDepthBuffer      = TRUE;
  204. }
  205.  
  206.  
  207.  
  208.  
  209. //-----------------------------------------------------------------------------
  210. // Name: ~CAppForm()
  211. // Desc: Destructor for the dialog resource form. Shuts down the app
  212. //-----------------------------------------------------------------------------
  213. CAppForm::~CAppForm()
  214. {
  215.     Cleanup3DEnvironment();
  216. }
  217.  
  218.  
  219.  
  220.  
  221. //-----------------------------------------------------------------------------
  222. // Name: OnToggleFullScreen()
  223. // Desc: Called when user toggles the fullscreen mode
  224. //-----------------------------------------------------------------------------
  225. void CAppForm::OnToggleFullScreen()
  226. {
  227.     ToggleFullscreen();
  228. }
  229.  
  230.  
  231.  
  232.  
  233. //-----------------------------------------------------------------------------
  234. // Name: OnChangeDevice()
  235. // Desc: Use hit the "Change Device.." button. Display the dialog for the user
  236. //       to select a new device/mode, and call Change3DEnvironment to
  237. //       use the new device/mode.
  238. //-----------------------------------------------------------------------------
  239. VOID CAppForm::OnChangeDevice()
  240. {
  241.     UserSelectNewDevice();
  242.  
  243.     // Update UI, and device's fog parameters
  244.     UpdateUIForDeviceCapabilites();
  245.     SetFogParameters();
  246. }
  247.  
  248.  
  249.  
  250.  
  251. //-----------------------------------------------------------------------------
  252. // Name: AdjustWindowForChange()
  253. // Desc: Adjusts the window properties for windowed or fullscreen mode
  254. //-----------------------------------------------------------------------------
  255. HRESULT CAppForm::AdjustWindowForChange()
  256. {
  257.     if( m_bWindowed )
  258.     {
  259.         ::ShowWindow( m_hwndRenderFullScreen, SW_HIDE );
  260.         CD3DApplication::m_hWnd = m_hwndRenderWindow;
  261.     }
  262.     else
  263.     {
  264.         if( ::IsIconic( m_hwndRenderFullScreen ) )
  265.             ::ShowWindow( m_hwndRenderFullScreen, SW_RESTORE );
  266.         ::ShowWindow( m_hwndRenderFullScreen, SW_SHOW );
  267.         CD3DApplication::m_hWnd = m_hwndRenderFullScreen;
  268.     }
  269.     return S_OK;
  270. }
  271.  
  272.  
  273.  
  274.  
  275. //-----------------------------------------------------------------------------
  276. // Name: FullScreenWndProc()
  277. // Desc: The WndProc funtion used when the app is in fullscreen mode. This is
  278. //       needed simply to trap the ESC key.
  279. //-----------------------------------------------------------------------------
  280. LRESULT CALLBACK FullScreenWndProc( HWND hWnd, UINT msg, WPARAM wParam,
  281.                                     LPARAM lParam )
  282. {
  283.     if( msg == WM_CLOSE )
  284.     {
  285.         // User wants to exit, so go back to windowed mode and exit for real
  286.         g_AppFormView->OnToggleFullScreen();
  287.         g_App.GetMainWnd()->PostMessage( WM_CLOSE, 0, 0 );
  288.     }
  289.  
  290.     else if( msg == WM_SETCURSOR )
  291.     {
  292.         SetCursor( NULL );
  293.     }
  294.  
  295.     else if( msg == WM_KEYUP && wParam == VK_ESCAPE )
  296.     {
  297.         // User wants to leave fullscreen mode
  298.         g_AppFormView->OnToggleFullScreen();
  299.     }
  300.     return DefWindowProc( hWnd, msg, wParam, lParam );
  301. }
  302.  
  303.  
  304.  
  305.  
  306. //-----------------------------------------------------------------------------
  307. // Name: CheckForLostFullscreen()
  308. // Desc: If fullscreen and device was lost (probably due to alt-tab), 
  309. //       automatically switch to windowed mode
  310. //-----------------------------------------------------------------------------
  311. HRESULT CAppForm::CheckForLostFullscreen()
  312. {
  313.     HRESULT hr;
  314.  
  315.     if( m_bWindowed )
  316.         return S_OK;
  317.  
  318.     if( FAILED( hr = m_pd3dDevice->TestCooperativeLevel() ) )
  319.         ForceWindowed();
  320.  
  321.     return S_OK;
  322. }
  323.  
  324.  
  325.  
  326.  
  327. //-----------------------------------------------------------------------------
  328. // Name: OnTerrainResolution()
  329. // Desc: Called when the user selects the terrain resolution
  330. //-----------------------------------------------------------------------------
  331. VOID CAppForm::OnTerrainResolution()
  332. {
  333.     m_bHiResTerrain = ((CButton*)GetDlgItem(IDC_HIRESTERRAIN))->GetCheck();
  334.  
  335.     SetFogParameters();
  336. }
  337.  
  338.  
  339.  
  340.  
  341. //-----------------------------------------------------------------------------
  342. // Name: OnHScroll()
  343. // Desc: Called when the user moves any scroll bar. Check which scrollbar was
  344. //       moved, and extract the appropiate value to a global variable.
  345. //-----------------------------------------------------------------------------
  346. void CAppForm::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
  347. {
  348.     // Get the new fog parameters
  349.     m_fFogStartSlider = ((CSliderCtrl*)GetDlgItem(IDC_FOGSTART_SLIDER))->GetPos()/100.0f;
  350.     m_fFogEndSlider   = ((CSliderCtrl*)GetDlgItem(IDC_FOGEND_SLIDER))->GetPos()/100.0f;
  351.     m_fFogDensity     = ((CSliderCtrl*)GetDlgItem(IDC_FOGDENSITY_SLIDER))->GetPos()/100.0f;
  352.  
  353.     if( m_fFogEndSlider < m_fFogStartSlider )
  354.     {
  355.         ((CSliderCtrl*)GetDlgItem(IDC_FOGEND_SLIDER))->SetPos((INT)(m_fFogStartSlider*100.0f));
  356.         m_fFogEndSlider = m_fFogStartSlider;
  357.     }
  358.     
  359.     SetFogParameters();
  360.  
  361.     CFormView::OnHScroll(nSBCode, nPos, pScrollBar);
  362. }
  363.  
  364.  
  365.  
  366.  
  367. //-----------------------------------------------------------------------------
  368. // Name: OnFogColor()
  369. // Desc: Called when the user hits the "fog color..." button. Display a color
  370. //       selection dialog box, and set the global fog color variable.
  371. //-----------------------------------------------------------------------------
  372. void CAppForm::OnFogColor()
  373. {
  374.     CColorDialog dlg;
  375.  
  376.     if( IDOK == dlg.DoModal() )
  377.     {
  378.         m_dwFogColor = ((((DWORD)dlg.GetColor())&0x000000ff)<<16) +
  379.                        ((((DWORD)dlg.GetColor())&0x0000ff00)) +
  380.                        ((((DWORD)dlg.GetColor())&0x00ff0000)>>16);
  381.         SetFogParameters();
  382.     }
  383. }
  384.  
  385.  
  386.  
  387.  
  388. //-----------------------------------------------------------------------------
  389. // Name: OnRangeBasedFog()
  390. // Desc: Toggle the boolean variable for whether RangeBasedFog is enabled.
  391. //-----------------------------------------------------------------------------
  392. void CAppForm::OnRangeBasedFog()
  393. {
  394.     m_bRangeBasedFog = ((CButton*)GetDlgItem(IDC_RANGEBASEDFOG))->GetCheck();
  395.  
  396.     SetFogParameters();
  397. }
  398.  
  399.  
  400.  
  401.  
  402. //-----------------------------------------------------------------------------
  403. // Name: OnVertexFog()
  404. // Desc: User selected vertex fog. Upadte the global variables as appropiate.
  405. //-----------------------------------------------------------------------------
  406. void CAppForm::OnVertexFog()
  407. {
  408.     // Note: We always assume range fog is available if doing vertex fog
  409.     GetDlgItem(IDC_RANGEBASEDFOG)->EnableWindow(TRUE);
  410.  
  411.     GetDlgItem(IDC_LINEARFOGMODE)->EnableWindow(TRUE);
  412.     GetDlgItem(IDC_EXPFOGMODE)->EnableWindow(FALSE);
  413.     GetDlgItem(IDC_EXP2FOGMODE)->EnableWindow(FALSE);
  414.     ((CButton*)GetDlgItem(IDC_LINEARFOGMODE))->SetCheck(TRUE);
  415.     ((CButton*)GetDlgItem(IDC_EXPFOGMODE))->SetCheck(FALSE);
  416.     ((CButton*)GetDlgItem(IDC_EXP2FOGMODE))->SetCheck(FALSE);
  417.  
  418.     GetDlgItem(IDC_FOGSTARTMIN_TEXT)->SetWindowText( _T("near (1.0)") );
  419.     GetDlgItem(IDC_FOGSTARTMAX_TEXT)->SetWindowText( _T("far (150.0)") );
  420.     GetDlgItem(IDC_FOGENDMIN_TEXT)->SetWindowText( _T("near (1.0)") );
  421.     GetDlgItem(IDC_FOGENDMAX_TEXT)->SetWindowText( _T("far (150.0)") );
  422.  
  423.     m_bUsingTableFog = FALSE;
  424.     OnFogMode();
  425. }
  426.  
  427.  
  428.  
  429.  
  430. //-----------------------------------------------------------------------------
  431. // Name: OnTableFog()
  432. // Desc: User selected table fog. Upadte the global variables as appropiate.
  433. //-----------------------------------------------------------------------------
  434. void CAppForm::OnTableFog()
  435. {
  436.     // Note: We only assume range fog is available if doing vertex fog
  437.     GetDlgItem(IDC_RANGEBASEDFOG)->EnableWindow(FALSE);
  438.     ((CButton*)GetDlgItem(IDC_RANGEBASEDFOG))->SetCheck(FALSE);
  439.  
  440.     GetDlgItem(IDC_LINEARFOGMODE)->EnableWindow(TRUE);
  441.     GetDlgItem(IDC_EXPFOGMODE)->EnableWindow(TRUE);
  442.     GetDlgItem(IDC_EXP2FOGMODE)->EnableWindow(TRUE);
  443.  
  444.     if( m_bCanDoWFog )
  445.     {
  446.         GetDlgItem(IDC_FOGSTARTMIN_TEXT)->SetWindowText( _T("near (1.0)") );
  447.         GetDlgItem(IDC_FOGSTARTMAX_TEXT)->SetWindowText( _T("far (150.0)") );
  448.         GetDlgItem(IDC_FOGENDMIN_TEXT)->SetWindowText( _T("near (1.0)") );
  449.         GetDlgItem(IDC_FOGENDMAX_TEXT)->SetWindowText( _T("far (150.0)") );
  450.     }
  451.     else
  452.     {
  453.         GetDlgItem(IDC_FOGSTARTMIN_TEXT)->SetWindowText( _T("near (0.0)") );
  454.         GetDlgItem(IDC_FOGSTARTMAX_TEXT)->SetWindowText( _T("far (1.0)") );
  455.         GetDlgItem(IDC_FOGENDMIN_TEXT)->SetWindowText( _T("near (0.0)") );
  456.         GetDlgItem(IDC_FOGENDMAX_TEXT)->SetWindowText( _T("far (1.0)") );
  457.     }
  458.  
  459.     m_bUsingTableFog = TRUE;
  460.     OnFogMode();
  461. }
  462.  
  463.  
  464.  
  465.  
  466. //-----------------------------------------------------------------------------
  467. // Name: OnFogMode()
  468. // Desc: User changed the fog mode. Update the UI and global variables, as many
  469. //       controls are mutually exclusive.
  470. //-----------------------------------------------------------------------------
  471. void CAppForm::OnFogMode()
  472. {
  473.     if( ((CButton*)GetDlgItem(IDC_LINEARFOGMODE))->GetCheck() )
  474.     {
  475.         m_dwFogMode = D3DFOG_LINEAR;
  476.  
  477.         GetDlgItem(IDC_FOGSTART_TEXT)->EnableWindow(TRUE);
  478.         GetDlgItem(IDC_FOGSTARTMIN_TEXT)->EnableWindow(TRUE);
  479.         GetDlgItem(IDC_FOGSTARTMAX_TEXT)->EnableWindow(TRUE);
  480.         GetDlgItem(IDC_FOGSTART_SLIDER)->EnableWindow(TRUE);
  481.         GetDlgItem(IDC_FOGEND_TEXT)->EnableWindow(TRUE);
  482.         GetDlgItem(IDC_FOGENDMIN_TEXT)->EnableWindow(TRUE);
  483.         GetDlgItem(IDC_FOGENDMAX_TEXT)->EnableWindow(TRUE);
  484.         GetDlgItem(IDC_FOGEND_SLIDER)->EnableWindow(TRUE);
  485.         GetDlgItem(IDC_FOGDENSITY_TEXT)->EnableWindow(FALSE);
  486.         GetDlgItem(IDC_FOGDENSITYMIN_TEXT)->EnableWindow(FALSE);
  487.         GetDlgItem(IDC_FOGDENSITYMAX_TEXT)->EnableWindow(FALSE);
  488.         GetDlgItem(IDC_FOGDENSITY_SLIDER)->EnableWindow(FALSE);
  489.     }
  490.     else
  491.     {
  492.         GetDlgItem(IDC_FOGSTART_TEXT)->EnableWindow(FALSE);
  493.         GetDlgItem(IDC_FOGSTARTMIN_TEXT)->EnableWindow(FALSE);
  494.         GetDlgItem(IDC_FOGSTARTMAX_TEXT)->EnableWindow(FALSE);
  495.         GetDlgItem(IDC_FOGSTART_SLIDER)->EnableWindow(FALSE);
  496.         GetDlgItem(IDC_FOGEND_TEXT)->EnableWindow(FALSE);
  497.         GetDlgItem(IDC_FOGENDMIN_TEXT)->EnableWindow(FALSE);
  498.         GetDlgItem(IDC_FOGENDMAX_TEXT)->EnableWindow(FALSE);
  499.         GetDlgItem(IDC_FOGEND_SLIDER)->EnableWindow(FALSE);
  500.         GetDlgItem(IDC_FOGDENSITY_TEXT)->EnableWindow(TRUE);
  501.         GetDlgItem(IDC_FOGDENSITYMIN_TEXT)->EnableWindow(TRUE);
  502.         GetDlgItem(IDC_FOGDENSITYMAX_TEXT)->EnableWindow(TRUE);
  503.         GetDlgItem(IDC_FOGDENSITY_SLIDER)->EnableWindow(TRUE);
  504.  
  505.         if( ((CButton*)GetDlgItem(IDC_EXPFOGMODE))->GetCheck() )
  506.             m_dwFogMode = D3DFOG_EXP;
  507.         if( ((CButton*)GetDlgItem(IDC_EXP2FOGMODE))->GetCheck() )
  508.             m_dwFogMode = D3DFOG_EXP2;
  509.     }
  510.  
  511.     SetFogParameters();
  512. }
  513.  
  514.  
  515.  
  516.  
  517. //-----------------------------------------------------------------------------
  518. // Name: UpdateUIForDeviceCapabilites()
  519. // Desc: Whenever we get a new device, call this function to enable/disable the
  520. //       appropiate UI controls to match the device's capabilities.
  521. //-----------------------------------------------------------------------------
  522. VOID CAppForm::UpdateUIForDeviceCapabilites()
  523. {
  524.     // Check the capabilities of the device
  525.     DWORD dwCaps = m_d3dCaps.RasterCaps;
  526.     m_bCanDoTableFog  = (dwCaps&D3DPRASTERCAPS_FOGTABLE) &&
  527.                         ((dwCaps&D3DPRASTERCAPS_ZFOG) || (dwCaps&D3DPRASTERCAPS_WFOG))    
  528.                                                           ? TRUE : FALSE;
  529.     m_bCanDoVertexFog = (dwCaps&D3DPRASTERCAPS_FOGVERTEX) ? TRUE : FALSE;
  530.     m_bCanDoWFog      = (dwCaps&D3DPRASTERCAPS_WFOG)      ? TRUE : FALSE;
  531.  
  532.     // Update the UI checkbox states
  533.     ((CButton*)GetDlgItem(IDC_TABLEFOG))->EnableWindow(m_bCanDoTableFog);
  534.     ((CButton*)GetDlgItem(IDC_VERTEXFOG))->EnableWindow(m_bCanDoVertexFog);
  535.  
  536.     if( m_bCanDoWFog )
  537.         GetDlgItem(IDC_USINGWFOG)->SetWindowText( _T("Device using W-fog") );
  538.     else
  539.         GetDlgItem(IDC_USINGWFOG)->SetWindowText( _T("Device using Z-fog") );
  540.  
  541.     if( m_bUsingTableFog && m_bCanDoTableFog )
  542.     {
  543.         ((CButton*)GetDlgItem(IDC_VERTEXFOG))->SetCheck(FALSE);
  544.         ((CButton*)GetDlgItem(IDC_TABLEFOG))->SetCheck(TRUE);
  545.     }
  546.     else if( m_bCanDoVertexFog )
  547.     {
  548.         ((CButton*)GetDlgItem(IDC_VERTEXFOG))->SetCheck(TRUE);
  549.         ((CButton*)GetDlgItem(IDC_TABLEFOG))->SetCheck(FALSE);
  550.     }
  551.     else
  552.     {
  553.         ((CButton*)GetDlgItem(IDC_VERTEXFOG))->SetCheck(FALSE);
  554.         ((CButton*)GetDlgItem(IDC_TABLEFOG))->SetCheck(m_bCanDoTableFog);
  555.     }
  556.  
  557.     // Set up table or vertex mode, as appropiate
  558.     if( ((CButton*)GetDlgItem(IDC_TABLEFOG))->GetCheck() )
  559.         OnTableFog();
  560.     if( ((CButton*)GetDlgItem(IDC_VERTEXFOG))->GetCheck() )
  561.         OnVertexFog();
  562. }
  563.  
  564.  
  565.  
  566.  
  567. //-----------------------------------------------------------------------------
  568. // Name: OnInitialUpdate()
  569. // Desc: When the AppForm object is created, this function is called to
  570. //       initialize it. Here we getting access ptrs to some of the controls,
  571. //       and setting the initial state of some of them as well.
  572. //-----------------------------------------------------------------------------
  573. VOID CAppForm::OnInitialUpdate()
  574. {
  575.     // Update the UI
  576.     CFormView::OnInitialUpdate();
  577.     ((CSliderCtrl*)GetDlgItem( IDC_FOGSTART_SLIDER ))->SetRange(0,100,TRUE);
  578.     ((CSliderCtrl*)GetDlgItem( IDC_FOGSTART_SLIDER ))->SetPos(0);
  579.     ((CSliderCtrl*)GetDlgItem( IDC_FOGEND_SLIDER ))->SetRange(0,100,TRUE);
  580.     ((CSliderCtrl*)GetDlgItem( IDC_FOGEND_SLIDER ))->SetPos(100);
  581.     ((CSliderCtrl*)GetDlgItem( IDC_FOGDENSITY_SLIDER ))->SetRange(0,100,TRUE);
  582.     ((CSliderCtrl*)GetDlgItem( IDC_FOGDENSITY_SLIDER ))->SetPos(0);
  583.     ((CButton*)GetDlgItem( IDC_LORESTERRAIN ))->SetCheck(TRUE);
  584.     ((CButton*)GetDlgItem(IDC_VERTEXFOG))->SetCheck(TRUE);
  585.  
  586.     // Save static reference to the render window
  587.     m_hwndRenderWindow = GetDlgItem(IDC_RENDERVIEW)->GetSafeHwnd();
  588.  
  589.     // Register a class for a fullscreen window
  590.     WNDCLASS wndClass = { CS_HREDRAW | CS_VREDRAW, FullScreenWndProc, 0, 0, NULL,
  591.                           NULL, NULL, (HBRUSH)GetStockObject(WHITE_BRUSH), NULL,
  592.                           _T("Fullscreen Window") };
  593.     RegisterClass( &wndClass );
  594.  
  595.     // We create the fullscreen window (not visible) at startup, so it can
  596.     // be the focus window.  The focus window can only be set at CreateDevice
  597.     // time, not in a Reset, so ToggleFullscreen wouldn't work unless we have
  598.     // already set up the fullscreen focus window.
  599.     m_hwndRenderFullScreen = CreateWindow( _T("Fullscreen Window"), NULL,
  600.                                            WS_POPUP, CW_USEDEFAULT,
  601.                                            CW_USEDEFAULT, 100, 100,
  602.                                            GetTopLevelParent()->GetSafeHwnd(), 0L, NULL, 0L );
  603.  
  604.     // Note that for the MFC samples, the device window and focus window
  605.     // are not the same.
  606.     CD3DApplication::m_hWnd = m_hwndRenderWindow;
  607.     CD3DApplication::m_hWndFocus = m_hwndRenderFullScreen;
  608.     CD3DApplication::Create( AfxGetInstanceHandle() );
  609.  
  610.     // Update UI, and device's fog parameters
  611.     OnVertexFog();
  612.     UpdateUIForDeviceCapabilites();
  613.     SetFogParameters();
  614. }
  615.  
  616.  
  617.  
  618.  
  619. //----------------------------------------------------------------------------
  620. // Name: GenerateTerrainDisk()
  621. // Desc: Generates a trianglestrip for a disk
  622. //----------------------------------------------------------------------------
  623. HRESULT CAppForm::GenerateTerrainDisk( LPDIRECT3DDEVICE8 pd3dDevice, DWORD dwNumSegments,
  624.                                        FLOAT fScale )
  625. {
  626.     HRESULT hr;
  627.  
  628.     m_dwNumTerrainVertices = 2 * dwNumSegments * (dwNumSegments);
  629.  
  630.     // Destroy the old vertex buffer, if any
  631.     SAFE_RELEASE( m_pTerrainVB );
  632.  
  633.     // Create a vertex buffer
  634.     hr = pd3dDevice->CreateVertexBuffer( m_dwNumTerrainVertices*sizeof(FOGVERTEX),
  635.                                          D3DUSAGE_WRITEONLY, D3DFVF_FOGVERTEX,
  636.                                          D3DPOOL_MANAGED, &m_pTerrainVB );
  637.     if( FAILED(hr) )
  638.         return hr;
  639.  
  640.     FOGVERTEX* pVertices = NULL;
  641.     hr = m_pTerrainVB->Lock( 0, m_dwNumTerrainVertices*sizeof(FOGVERTEX),
  642.                              (BYTE**)&pVertices, 0 );
  643.     if( FAILED(hr) )
  644.         return hr;
  645.  
  646.     // Generate a spiralized trianglestrip
  647.     for( DWORD ring = 0; ring < dwNumSegments; ring++ )
  648.     {
  649.         for( DWORD seg=0; seg < dwNumSegments; seg++ )
  650.         {
  651.             FLOAT fTheta = (seg*2*D3DX_PI) / dwNumSegments;
  652.             FLOAT r0     = (ring + fTheta/(2*D3DX_PI))*fScale/dwNumSegments;
  653.             FLOAT r1     = r0 + fScale/dwNumSegments;
  654.  
  655.             FLOAT x   = (FLOAT)sin( fTheta );
  656.             FLOAT z   = (FLOAT)cos( fTheta );
  657.  
  658.             FLOAT y0  =  (FLOAT)sin(r0*z*z+r0*x*x);
  659.             FLOAT nx0 = -(FLOAT)cos(r0*z*z+r0*x*x)*r0*2*x;
  660.             FLOAT ny0 = 1.0f;
  661.             FLOAT nz0 = -(FLOAT)cos(r0*z*z+r0*x*x)*r0*2*z;
  662.  
  663.             FLOAT y1  =  (FLOAT)sin(r1*z*z+r1*x*x);
  664.             FLOAT nx1 = -(FLOAT)cos(r1*z*z+r1*x*x)*r1*2*x;
  665.             FLOAT ny1 = 1.0f;
  666.             FLOAT nz1 = -(FLOAT)cos(r1*z*z+r1*x*x)*r1*2*z;
  667.  
  668.             // Add two vertices to the strip at each step
  669.             pVertices->p.x = r0*x;
  670.             pVertices->p.y = y0;
  671.             pVertices->p.z = r0*z;
  672.             pVertices->n.x = nx0;
  673.             pVertices->n.y = ny0;
  674.             pVertices->n.z = nz0;
  675.             pVertices->tu  = (r0*x)/fScale;
  676.             pVertices->tv  = (r0*z)/fScale;
  677.             pVertices++;
  678.  
  679.             pVertices->p.x = r1*x;
  680.             pVertices->p.y = y1;
  681.             pVertices->p.z = r1*z;
  682.             pVertices->n.x = nx1;
  683.             pVertices->n.y = ny1;
  684.             pVertices->n.z = nz1;
  685.             pVertices->tu  = (r1*x)/fScale;
  686.             pVertices->tv  = (r1*z)/fScale;
  687.             pVertices++;
  688.         }
  689.     }
  690.  
  691.     m_pTerrainVB->Unlock();
  692.  
  693.     return S_OK;
  694. }
  695.  
  696.  
  697.  
  698.  
  699. //----------------------------------------------------------------------------
  700. // Name: GenerateColumn()
  701. // Desc: Generates a trianglestrip for a column
  702. //----------------------------------------------------------------------------
  703. HRESULT CAppForm::GenerateColumn( LPDIRECT3DDEVICE8 pd3dDevice, DWORD dwNumSegments,
  704.                                   FLOAT fRadius, FLOAT fHeight )
  705. {
  706.     HRESULT hr;
  707.  
  708.     m_dwNumColumnVertices = 2 * (dwNumSegments+1);
  709.  
  710.     // Destroy the old vertex buffer, if any
  711.     SAFE_RELEASE( m_pColumnVB );
  712.  
  713.     // Create a vertex buffer
  714.     hr = pd3dDevice->CreateVertexBuffer( m_dwNumColumnVertices*sizeof(FOGVERTEX),
  715.                                          D3DUSAGE_WRITEONLY, D3DFVF_FOGVERTEX,
  716.                                          D3DPOOL_MANAGED, &m_pColumnVB );
  717.     if( FAILED(hr) )
  718.         return hr;
  719.  
  720.     FOGVERTEX* pVertices = NULL;
  721.     hr = m_pColumnVB->Lock( 0, m_dwNumColumnVertices*sizeof(FOGVERTEX),
  722.                              (BYTE**)(&pVertices), 0 );
  723.     if( FAILED(hr) )
  724.         return hr;
  725.  
  726.     // Generate a trianglestrip
  727.     for( DWORD seg=0; seg<=dwNumSegments; seg++ )
  728.     {
  729.         FLOAT fTheta = (2*D3DX_PI*seg)/dwNumSegments;
  730.         FLOAT nx     = (FLOAT)sin(fTheta);
  731.         FLOAT nz     = (FLOAT)cos(fTheta);
  732.         FLOAT r      = fRadius;
  733.         FLOAT u      = (1.0f*seg)/dwNumSegments;
  734.  
  735.         // Add two vertices to the strip at each step
  736.         pVertices->p.x = r*nx;
  737.         pVertices->p.y = fHeight;
  738.         pVertices->p.z = r*nz;
  739.         pVertices->n.x = nx;
  740.         pVertices->n.y = 0;
  741.         pVertices->n.z = nz;
  742.         pVertices->tu  = u;
  743.         pVertices->tv  = 1;
  744.         pVertices++;
  745.  
  746.         pVertices->p.x = r*nx;
  747.         pVertices->p.y = -1;
  748.         pVertices->p.z = r*nz;
  749.         pVertices->n.x = nx;
  750.         pVertices->n.y = 0;
  751.         pVertices->n.z = nz;
  752.         pVertices->tu  = u;
  753.         pVertices->tv  = 0;
  754.         pVertices++;
  755.     }
  756.  
  757.     m_pColumnVB->Unlock();
  758.  
  759.     return S_OK;
  760. }
  761.  
  762.  
  763.  
  764.  
  765. //-----------------------------------------------------------------------------
  766. // Name: CAppForm::OneTimeSceneInit()
  767. // Desc: Called during initial app startup, this function performs all the
  768. //       permanent initialization.
  769. //-----------------------------------------------------------------------------
  770. HRESULT CAppForm::OneTimeSceneInit()
  771. {
  772.     return S_OK;
  773. }
  774.  
  775.  
  776.  
  777.  
  778. //-----------------------------------------------------------------------------
  779. // Name: CAppForm::FrameMove()
  780. // Desc: Called once per frame, the call is the entry point for animating
  781. //       the scene.
  782. //-----------------------------------------------------------------------------
  783. HRESULT CAppForm::FrameMove()
  784. {
  785.     // Move the camera along an ellipse
  786.     D3DXVECTOR3 from( 50*sinf(m_fTime/2), 5.0f, 60*cosf(m_fTime/2) );
  787.     D3DXVECTOR3 at( 50*sinf(m_fTime/2+1.5f), 4.0f, 60*cosf(m_fTime/2+1.5f) );
  788.     D3DXVECTOR3 up( 0.0f, 1.0f, 0.0f );
  789.  
  790.     D3DXMATRIX matView;
  791.     D3DXMatrixLookAtLH( &matView, &from, &at, &up );
  792.     m_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
  793.     return S_OK;
  794. }
  795.  
  796.  
  797.  
  798.  
  799. //-----------------------------------------------------------------------------
  800. // Name: CAppForm::Render()
  801. // Desc: Called once per frame, the call is the entry point for 3d
  802. //       rendering. This function sets up render states, clears the
  803. //       viewport, and renders the scene.
  804. //-----------------------------------------------------------------------------
  805. HRESULT CAppForm::Render()
  806. {
  807.     // Clear the viewport
  808.     m_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
  809.                        m_dwFogColor, 1.0f, 0L );
  810.  
  811.     m_pd3dDevice->SetRenderState( D3DRS_FOGENABLE, TRUE );
  812.     m_pd3dDevice->SetRenderState( D3DRS_FOGCOLOR,  m_dwFogColor );
  813.  
  814.     m_pd3dDevice->SetRenderState( D3DRS_FOGSTART,   FtoDW(m_fFogStartValue) );
  815.     m_pd3dDevice->SetRenderState( D3DRS_FOGEND,     FtoDW(m_fFogEndValue) );
  816.     m_pd3dDevice->SetRenderState( D3DRS_FOGDENSITY, FtoDW(m_fFogDensity) );
  817.  
  818.     if( m_bUsingTableFog )
  819.     {
  820.         m_pd3dDevice->SetRenderState( D3DRS_FOGVERTEXMODE,  D3DFOG_NONE );
  821.         m_pd3dDevice->SetRenderState( D3DRS_FOGTABLEMODE,   m_dwFogMode );
  822.     }
  823.     else
  824.     {
  825.         m_pd3dDevice->SetRenderState( D3DRS_FOGTABLEMODE,   D3DFOG_NONE );
  826.         m_pd3dDevice->SetRenderState( D3DRS_FOGVERTEXMODE,  m_dwFogMode );
  827.         m_pd3dDevice->SetRenderState( D3DRS_RANGEFOGENABLE, m_bRangeBasedFog );
  828.     }
  829.  
  830.     // Begin the scene
  831.     if( SUCCEEDED( m_pd3dDevice->BeginScene() ) )
  832.     {
  833.         // Reset the world matrix
  834.         D3DXMATRIX matWorld;
  835.         D3DXMatrixIdentity( &matWorld );
  836.         m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
  837.  
  838.         // Draw the terrain
  839.         m_pd3dDevice->SetVertexShader( D3DFVF_FOGVERTEX );
  840.         m_pd3dDevice->SetStreamSource( 0, m_pTerrainVB, sizeof(FOGVERTEX) );
  841.         m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP,
  842.                                    0, m_dwNumTerrainVertices-2 );
  843.  
  844.         // Draw the columns
  845.         for( DWORD i=0; i<20; i++ )
  846.         {
  847.             FLOAT tx = (i%10)*20.0f - 100.0f;
  848.             FLOAT ty =  0.0f;
  849.             FLOAT tz = (i<=10) ? 40.0f : -40.0f;
  850.  
  851.             D3DXMatrixTranslation( &matWorld, tx, ty, tz );
  852.             m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
  853.  
  854.             m_pd3dDevice->SetVertexShader( D3DFVF_FOGVERTEX );
  855.             m_pd3dDevice->SetStreamSource( 0, m_pColumnVB, sizeof(FOGVERTEX) );
  856.             m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP,
  857.                                          0, m_dwNumColumnVertices-2 );
  858.         }
  859.  
  860.         // End the scene.
  861.         m_pd3dDevice->EndScene();
  862.     }
  863.  
  864.     return S_OK;
  865. }
  866.  
  867.  
  868.  
  869.  
  870. //-----------------------------------------------------------------------------
  871. // Name: CAppForm::InitDeviceObjects()
  872. // Desc: Initialize scene objects.
  873. //-----------------------------------------------------------------------------
  874. HRESULT CAppForm::InitDeviceObjects()
  875. {
  876.     // Get the device caps
  877.     D3DCAPS8 d3dCaps;
  878.     m_pd3dDevice->GetDeviceCaps( &d3dCaps );
  879.  
  880.     if( d3dCaps.RasterCaps & D3DPRASTERCAPS_WFOG )
  881.         m_bDeviceUsesWFog = TRUE;
  882.     else
  883.         m_bDeviceUsesWFog = FALSE;
  884.  
  885.     // Create the floor texture
  886.     if( FAILED( D3DUtil_CreateTexture( m_pd3dDevice, _T("SeaFloor.bmp"),
  887.                                        &m_pFloorTexture, D3DFMT_R5G6B5 ) ) )
  888.         return E_FAIL;
  889.  
  890.     // Generate some geometry for the app
  891.     if( m_bHiResTerrain )
  892.         GenerateTerrainDisk( m_pd3dDevice, 80, 100.0f );
  893.     else
  894.         GenerateTerrainDisk( m_pd3dDevice, 5, 100.0f );
  895.     GenerateColumn( m_pd3dDevice, 30, 1.0f, 10.0f );
  896.  
  897.     return S_OK;
  898. }
  899.  
  900.  
  901.  
  902.  
  903. //-----------------------------------------------------------------------------
  904. // Name: CAppForm::RestoreDeviceObjects()
  905. // Desc: Initialize scene objects.
  906. //-----------------------------------------------------------------------------
  907. HRESULT CAppForm::RestoreDeviceObjects()
  908. {
  909.     // Set up the object material
  910.     D3DMATERIAL8 mtrl;
  911.     D3DUtil_InitMaterial( mtrl, 1.0f, 1.0f, 1.0f );
  912.     m_pd3dDevice->SetMaterial( &mtrl );
  913.     m_pd3dDevice->SetRenderState( D3DRS_AMBIENT,  0x44444444 );
  914.  
  915.     // Set up a texture
  916.     m_pd3dDevice->SetTexture( 0, m_pFloorTexture );
  917.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  918.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
  919.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE );
  920.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
  921.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
  922.  
  923.     m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
  924.  
  925.     // Set the transform matrices
  926.     D3DXMATRIX matWorld, matProj;
  927.     D3DXMatrixIdentity( &matWorld );
  928.     D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4.0f, 1.0f, NEAR_PLANE, FAR_PLANE );
  929.     m_pd3dDevice->SetTransform( D3DTS_WORLD,      &matWorld );
  930.     m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
  931.  
  932.     // Set up the light
  933.     D3DLIGHT8 light;
  934.     D3DUtil_InitLight( light, D3DLIGHT_POINT, 0.0f, 50.0f, 0.0f );
  935.     light.Attenuation0 =  0.1f;
  936.     light.Range        = 200.0f;
  937.     m_pd3dDevice->SetLight( 0, &light );
  938.     m_pd3dDevice->LightEnable( 0, TRUE );
  939.     m_pd3dDevice->SetRenderState( D3DRS_LIGHTING,    TRUE );
  940.  
  941.     m_pd3dDevice->SetRenderState( D3DRS_ZENABLE,            TRUE );
  942.     m_pd3dDevice->SetRenderState( D3DRS_DITHERENABLE,       TRUE );
  943.     m_pd3dDevice->SetRenderState( D3DRS_SPECULARENABLE,     FALSE );
  944.  
  945.     return S_OK;
  946. }
  947.  
  948.  
  949.  
  950.  
  951. //-----------------------------------------------------------------------------
  952. // Name: CAppForm::InvalidateDeviceObjects()
  953. // Desc: Called when the device-dependent objects are about to be lost.
  954. //-----------------------------------------------------------------------------
  955. HRESULT CAppForm::InvalidateDeviceObjects()
  956. {
  957.     return S_OK;
  958. }
  959.  
  960.  
  961.  
  962.  
  963. //-----------------------------------------------------------------------------
  964. // Name: CAppForm::DeleteDeviceObjects()
  965. // Desc: Called when the app is exiting, or the device is being changed,
  966. //       this function deletes any device dependent objects.
  967. //-----------------------------------------------------------------------------
  968. HRESULT CAppForm::DeleteDeviceObjects()
  969. {
  970.     SAFE_RELEASE( m_pColumnVB );
  971.     SAFE_RELEASE( m_pTerrainVB );
  972.     SAFE_RELEASE( m_pFloorTexture );
  973.     return S_OK;
  974. }
  975.  
  976.  
  977.  
  978.  
  979. //-----------------------------------------------------------------------------
  980. // Name: CAppForm::FinalCleanup()
  981. // Desc: Called before the app exits, this function gives the app the chance
  982. //       to cleanup after itself.
  983. //-----------------------------------------------------------------------------
  984. HRESULT CAppForm::FinalCleanup()
  985. {
  986.     return S_OK;
  987. }
  988.  
  989.  
  990.  
  991.  
  992. //-----------------------------------------------------------------------------
  993. // Name: CAppForm::ConfirmDevice()
  994. // Desc: Called during device intialization, this code checks the device
  995. //       for some minimum set of capabilities
  996. //-----------------------------------------------------------------------------
  997. HRESULT CAppForm::ConfirmDevice( D3DCAPS8* pCaps, DWORD dwBehavior, 
  998.                                  D3DFORMAT Format )
  999. {
  1000.     if( pCaps->RasterCaps & D3DPRASTERCAPS_FOGVERTEX )
  1001.         return S_OK;
  1002.  
  1003.     return E_FAIL;
  1004. }
  1005.  
  1006.  
  1007.  
  1008.  
  1009. //-----------------------------------------------------------------------------
  1010. // Name: SetFogParameters()
  1011. // Desc: Sets the apps parameters for rendering the scene
  1012. //-----------------------------------------------------------------------------
  1013. VOID CAppForm::SetFogParameters()
  1014. {
  1015.     m_fFogStartValue = ( m_fFogStartSlider*(FAR_PLANE-NEAR_PLANE) ) + NEAR_PLANE;
  1016.     m_fFogEndValue   = ( m_fFogEndSlider*(FAR_PLANE-NEAR_PLANE) ) + NEAR_PLANE;
  1017.  
  1018.     // Set fog start and end values for table (pixel) fog mode on devices that
  1019.     // do not use WFOG. These devices expect fog between 0.0 and 1.0.
  1020.     if( (FALSE==m_bDeviceUsesWFog) && (TRUE==m_bUsingTableFog) )
  1021.     {
  1022.         m_fFogStartValue = m_fFogStartSlider;
  1023.         m_fFogEndValue   = m_fFogEndSlider;
  1024.     }
  1025.  
  1026.     // Adjust terrain if necessary
  1027.     if( m_bHiResTerrainOld != m_bHiResTerrain )
  1028.     {
  1029.         m_bHiResTerrainOld  = m_bHiResTerrain;
  1030.  
  1031.         if( m_bHiResTerrain )
  1032.             GenerateTerrainDisk( m_pd3dDevice, 80, 100.0f );
  1033.         else
  1034.             GenerateTerrainDisk( m_pd3dDevice, 5, 100.0f );
  1035.     }
  1036. }
  1037.