text: //--------------------------------------------------------------------------------------
  // File: SimpleSample9.cpp
  //
  // Basic starting point for new Direct3D 9 samples
  //
  // Copyright (c) Microsoft Corporation. All rights reserved.
  //--------------------------------------------------------------------------------------
  #include "DXUT.h"
  #include "DXUTgui.h"
  #include "DXUTmisc.h"
  #include "DXUTCamera.h"
  #include "DXUTSettingsDlg.h"
  #include "SDKmisc.h"
  #include "SDKmesh.h"
  #include "resource.h"
  
  //#define DEBUG_VS   // Uncomment this line to debug D3D9 vertex shaders 
  //#define DEBUG_PS   // Uncomment this line to debug D3D9 pixel shaders 
  
  
  //--------------------------------------------------------------------------------------
  // Global variables
  //--------------------------------------------------------------------------------------
  extern CModelViewerCamera           g_Camera;               // A model viewing camera
  extern CDXUTDialogResourceManager   g_DialogResourceManager; // manager for shared resources of dialogs
  extern CD3DSettingsDlg              g_SettingsDlg;          // Device settings dialog
  extern CDXUTTextHelper*             g_pTxtHelper;
  extern CDXUTDialog                  g_HUD;                  // dialog for standard controls
  extern CDXUTDialog                  g_SampleUI;             // dialog for sample specific controls
  
  // Direct3D 9 resources
  ID3DXFont*                          g_pFont9 = NULL;
  ID3DXSprite*                        g_pSprite9 = NULL;
  ID3DXEffect*                        g_pEffect9 = NULL;
  D3DXHANDLE                          g_hmWorldViewProjection;
  D3DXHANDLE                          g_hmWorld;
  D3DXHANDLE                          g_hfTime;
  
  //--------------------------------------------------------------------------------------
  // Forward declarations 
  //--------------------------------------------------------------------------------------
  extern LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing,
                                   void* pUserContext );
  extern void CALLBACK OnKeyboard( UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext );
  extern void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext );
  extern void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void* pUserContext );
  extern bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, void* pUserContext );
  
  bool CALLBACK IsD3D9DeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat,
                                        bool bWindowed, void* pUserContext );
  HRESULT CALLBACK OnD3D9CreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc,
                                       void* pUserContext );
  HRESULT CALLBACK OnD3D9ResetDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc,
                                      void* pUserContext );
  void CALLBACK OnD3D9FrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext );
  void CALLBACK OnD3D9LostDevice( void* pUserContext );
  void CALLBACK OnD3D9DestroyDevice( void* pUserContext );
  
  extern void RenderText();
  
  
  //--------------------------------------------------------------------------------------
  // Rejects any D3D9 devices that aren't acceptable to the app by returning false
  //--------------------------------------------------------------------------------------
  bool CALLBACK IsD3D9DeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat,
                                        D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext )
  {
      // Skip backbuffer formats that don't support alpha blending
      IDirect3D9* pD3D = DXUTGetD3D9Object();
      if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType,
                                           AdapterFormat, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING,
                                           D3DRTYPE_TEXTURE, BackBufferFormat ) ) )
          return false;
  
      // No fallback defined by this app, so reject any device that 
      // doesn't support at least ps2.0
      if( pCaps->PixelShaderVersion < D3DPS_VERSION( 2, 0 ) )
          return false;
  
      return true;
  }
  
  
  //--------------------------------------------------------------------------------------
  // Create any D3D9 resources that will live through a device reset (D3DPOOL_MANAGED)
  // and aren't tied to the back buffer size
  //--------------------------------------------------------------------------------------
  HRESULT CALLBACK OnD3D9CreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc,
                                       void* pUserContext )
  {
      HRESULT hr;
  
      V_RETURN( g_DialogResourceManager.OnD3D9CreateDevice( pd3dDevice ) );
      V_RETURN( g_SettingsDlg.OnD3D9CreateDevice( pd3dDevice ) );
  
      V_RETURN( D3DXCreateFont( pd3dDevice, 15, 0, FW_BOLD, 1, FALSE, DEFAULT_CHARSET,
                                OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE,
                                L"Arial", &g_pFont9 ) );
  
      // Read the D3DX effect file
      WCHAR str[MAX_PATH];
      DWORD dwShaderFlags = D3DXFX_NOT_CLONEABLE | D3DXFX_LARGEADDRESSAWARE;
  #ifdef DEBUG_VS
          dwShaderFlags |= D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT;
      #endif
  #ifdef DEBUG_PS
          dwShaderFlags |= D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT;
      #endif
      V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"SimpleSample.fx" ) );
      V_RETURN( D3DXCreateEffectFromFile( pd3dDevice, str, NULL, NULL, dwShaderFlags,
                                          NULL, &g_pEffect9, NULL ) );
  
      g_hmWorldViewProjection = g_pEffect9->GetParameterByName( NULL, "g_mWorldViewProjection" );
      g_hmWorld = g_pEffect9->GetParameterByName( NULL, "g_mWorld" );
      g_hfTime = g_pEffect9->GetParameterByName( NULL, "g_fTime" );
  
      // Setup the camera's view parameters
      D3DXVECTOR3 vecEye( 0.0f, 0.0f, -5.0f );
      D3DXVECTOR3 vecAt ( 0.0f, 0.0f, -0.0f );
      g_Camera.SetViewParams( &vecEye, &vecAt );
  
      return S_OK;
  }
  
  
  //--------------------------------------------------------------------------------------
  // Create any D3D9 resources that won't live through a device reset (D3DPOOL_DEFAULT) 
  // or that are tied to the back buffer size 
  //--------------------------------------------------------------------------------------
  HRESULT CALLBACK OnD3D9ResetDevice( IDirect3DDevice9* pd3dDevice,
                                      const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
  {
      HRESULT hr;
  
      V_RETURN( g_DialogResourceManager.OnD3D9ResetDevice() );
      V_RETURN( g_SettingsDlg.OnD3D9ResetDevice() );
  
      if( g_pFont9 ) V_RETURN( g_pFont9->OnResetDevice() );
      if( g_pEffect9 ) V_RETURN( g_pEffect9->OnResetDevice() );
  
      V_RETURN( D3DXCreateSprite( pd3dDevice, &g_pSprite9 ) );
      g_pTxtHelper = new CDXUTTextHelper( g_pFont9, g_pSprite9, NULL, NULL, 15 );
  
      // Setup the camera's projection parameters
      float fAspectRatio = pBackBufferSurfaceDesc->Width / ( FLOAT )pBackBufferSurfaceDesc->Height;
      g_Camera.SetProjParams( D3DX_PI / 4, fAspectRatio, 0.1f, 1000.0f );
      g_Camera.SetWindow( pBackBufferSurfaceDesc->Width, pBackBufferSurfaceDesc->Height );
  
      g_HUD.SetLocation( pBackBufferSurfaceDesc->Width - 170, 0 );
      g_HUD.SetSize( 170, 170 );
      g_SampleUI.SetLocation( pBackBufferSurfaceDesc->Width - 170, pBackBufferSurfaceDesc->Height - 350 );
      g_SampleUI.SetSize( 170, 300 );
  
      return S_OK;
  }
  
  
  //--------------------------------------------------------------------------------------
  // Render the scene using the D3D9 device
  //--------------------------------------------------------------------------------------
  void CALLBACK OnD3D9FrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
  {
      HRESULT hr;
      D3DXMATRIXA16 mWorld;
      D3DXMATRIXA16 mView;
      D3DXMATRIXA16 mProj;
      D3DXMATRIXA16 mWorldViewProjection;
  
      // If the settings dialog is being shown, then render it instead of rendering the app's scene
      if( g_SettingsDlg.IsActive() )
      {
          g_SettingsDlg.OnRender( fElapsedTime );
          return;
      }
  
      // Clear the render target and the zbuffer 
      V( pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB( 0, 45, 50, 170 ), 1.0f, 0 ) );
  
      // Render the scene
      if( SUCCEEDED( pd3dDevice->BeginScene() ) )
      {
          // Get the projection & view matrix from the camera class
          mWorld = *g_Camera.GetWorldMatrix();
          mProj = *g_Camera.GetProjMatrix();
          mView = *g_Camera.GetViewMatrix();
  
          mWorldViewProjection = mWorld * mView * mProj;
  
          // Update the effect's variables.  Instead of using strings, it would 
          // be more efficient to cache a handle to the parameter by calling 
          // ID3DXEffect::GetParameterByName
          V( g_pEffect9->SetMatrix( g_hmWorldViewProjection, &mWorldViewProjection ) );
          V( g_pEffect9->SetMatrix( g_hmWorld, &mWorld ) );
          V( g_pEffect9->SetFloat( g_hfTime, ( float )fTime ) );
  
          DXUT_BeginPerfEvent( DXUT_PERFEVENTCOLOR, L"HUD / Stats" ); // These events are to help PIX identify what the code is doing
          RenderText();
          V( g_HUD.OnRender( fElapsedTime ) );
          V( g_SampleUI.OnRender( fElapsedTime ) );
          DXUT_EndPerfEvent();
  
          V( pd3dDevice->EndScene() );
      }
  }
  
  
  //--------------------------------------------------------------------------------------
  // Release D3D9 resources created in the OnD3D9ResetDevice callback 
  //--------------------------------------------------------------------------------------
  void CALLBACK OnD3D9LostDevice( void* pUserContext )
  {
      g_DialogResourceManager.OnD3D9LostDevice();
      g_SettingsDlg.OnD3D9LostDevice();
      if( g_pFont9 ) g_pFont9->OnLostDevice();
      if( g_pEffect9 ) g_pEffect9->OnLostDevice();
      SAFE_RELEASE( g_pSprite9 );
      SAFE_DELETE( g_pTxtHelper );
  }
  
  
  //--------------------------------------------------------------------------------------
  // Release D3D9 resources created in the OnD3D9CreateDevice callback 
  //--------------------------------------------------------------------------------------
  void CALLBACK OnD3D9DestroyDevice( void* pUserContext )
  {
      g_DialogResourceManager.OnD3D9DestroyDevice();
      g_SettingsDlg.OnD3D9DestroyDevice();
      SAFE_RELEASE( g_pEffect9 );
      SAFE_RELEASE( g_pFont9 );
  }
  
  