SimpleSample.cpp
上传用户:junlon
上传日期:2022-01-05
资源大小:39075k
文件大小:30k
源码类别:

DirextX编程

开发平台:

Visual C++

  1. //--------------------------------------------------------------------------------------
  2. // File: SimpleSample.cpp
  3. //
  4. // Basic starting point for new Direct3D samples
  5. //
  6. // Copyright (c) Microsoft Corporation. All rights reserved.
  7. //--------------------------------------------------------------------------------------
  8. #include "dxstdafx.h"
  9. #include "resource.h"
  10. #include "object.h"
  11. #include "plane.h"
  12. //#define DEBUG_VS   // Uncomment this line to debug vertex shaders 
  13. //#define DEBUG_PS   // Uncomment this line to debug pixel shaders 
  14. //--------------------------------------------------------------------------------------
  15. // Global variables
  16. //--------------------------------------------------------------------------------------
  17. ID3DXFont*              g_pFont = NULL;         // Font for drawing text
  18. ID3DXSprite*            g_pTextSprite = NULL;   // Sprite for batching draw text calls
  19. ID3DXEffect*            g_pEffect = NULL;       // D3DX effect interface
  20. CModelViewerCamera      g_Camera;               // A model viewing camera
  21. bool                    g_bShowHelp = true;     // If true, it renders the UI control text
  22. CDXUTDialogResourceManager g_DialogResourceManager; // manager for shared resources of dialogs
  23. CD3DSettingsDlg         g_SettingsDlg;          // Device settings dialog
  24. CDXUTDialog             g_HUD;                  // dialog for standard controls
  25. CDXUTDialog             g_SampleUI;             // dialog for sample specific controls
  26. CSpotLight g_spotLight;
  27. CPlane g_plane( 2, 2, D3DXVECTOR3( -4.0f, -1.0f, -4.0f ), D3DXVECTOR3( 12.4f, -1.0f, 12.4f ) );
  28. IDirect3DVertexShader9* g_pVertexShader = NULL;
  29. IDirect3DPixelShader9*  g_pPixelShader  = NULL;
  30. //int g_iDevCreate = 0;
  31. //int g_iDevLost = 0;
  32. //int g_iDevReset = 0;
  33. //--------------------------------------------------------------------------------------
  34. // UI control IDs
  35. //--------------------------------------------------------------------------------------
  36. #define IDC_TOGGLEFULLSCREEN    1
  37. #define IDC_TOGGLEREF           2
  38. #define IDC_CHANGEDEVICE        3
  39. //--------------------------------------------------------------------------------------
  40. // Forward declarations 
  41. //--------------------------------------------------------------------------------------
  42. bool    CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext );
  43. bool    CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps, void* pUserContext );
  44. HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext );
  45. HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext );
  46. void    CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext );
  47. void    CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext );
  48. LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing, void* pUserContext );
  49. void    CALLBACK KeyboardProc( UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext );
  50. void    CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext );
  51. void    CALLBACK OnLostDevice( void* pUserContext );
  52. void    CALLBACK OnDestroyDevice( void* pUserContext );
  53. void    InitApp();
  54. void    RenderText( IDirect3DDevice9* pd3dDevice );
  55. //--------------------------------------------------------------------------------------
  56. // Entry point to the program. Initializes everything and goes into a message processing 
  57. // loop. Idle time is used to render the scene.
  58. //--------------------------------------------------------------------------------------
  59. INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
  60. {
  61.     // Enable run-time memory check for debug builds.
  62. #if defined(DEBUG) | defined(_DEBUG)
  63.     _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
  64. #endif
  65.     // Set the callback functions. These functions allow DXUT to notify
  66.     // the application about device changes, user input, and windows messages.  The 
  67.     // callbacks are optional so you need only set callbacks for events you're interested 
  68.     // in. However, if you don't handle the device reset/lost callbacks then the sample 
  69.     // framework won't be able to reset your device since the application must first 
  70.     // release all device resources before resetting.  Likewise, if you don't handle the 
  71.     // device created/destroyed callbacks then DXUT won't be able to 
  72.     // recreate your device resources.
  73.     DXUTSetCallbackDeviceCreated( OnCreateDevice );
  74.     DXUTSetCallbackDeviceReset( OnResetDevice );
  75.     DXUTSetCallbackDeviceLost( OnLostDevice );
  76.     DXUTSetCallbackDeviceDestroyed( OnDestroyDevice );
  77.     DXUTSetCallbackMsgProc( MsgProc );
  78.     DXUTSetCallbackKeyboard( KeyboardProc );
  79.     DXUTSetCallbackFrameRender( OnFrameRender );
  80.     DXUTSetCallbackFrameMove( OnFrameMove );
  81.     // Show the cursor and clip it when in full screen
  82.     DXUTSetCursorSettings( true, true );
  83.     InitApp();
  84.     // Initialize DXUT and create the desired Win32 window and Direct3D 
  85.     // device for the application. Calling each of these functions is optional, but they
  86.     // allow you to set several options which control the behavior of the framework.
  87.     DXUTInit( true, true, true ); // Parse the command line, handle the default hotkeys, and show msgboxes
  88.     DXUTCreateWindow( L"SimpleSample" );
  89.     DXUTCreateDevice( D3DADAPTER_DEFAULT, true, 640, 480, IsDeviceAcceptable, ModifyDeviceSettings );
  90.     // Pass control to DXUT for handling the message pump and 
  91.     // dispatching render calls. DXUT will call your FrameMove 
  92.     // and FrameRender callback when there is idle time between handling window messages.
  93.     DXUTMainLoop();
  94.     // Perform any application-level cleanup here. Direct3D device resources are released within the
  95.     // appropriate callback functions and therefore don't require any cleanup code here.
  96.     return DXUTGetExitCode();
  97. }
  98. //--------------------------------------------------------------------------------------
  99. // Initialize the app 
  100. //--------------------------------------------------------------------------------------
  101. void InitApp()
  102. {
  103.     // Initialize dialogs
  104.     g_SettingsDlg.Init( &g_DialogResourceManager );
  105.     g_HUD.Init( &g_DialogResourceManager );
  106.     g_SampleUI.Init( &g_DialogResourceManager );
  107.     g_HUD.SetCallback( OnGUIEvent ); int iY = 10; 
  108.     g_HUD.AddButton( IDC_TOGGLEFULLSCREEN, L"Toggle full screen", 35, iY, 125, 22 );
  109.     g_HUD.AddButton( IDC_TOGGLEREF, L"Toggle REF (F3)", 35, iY += 24, 125, 22 );
  110.     g_HUD.AddButton( IDC_CHANGEDEVICE, L"Change device (F2)", 35, iY += 24, 125, 22, VK_F2 );
  111.     g_SampleUI.SetCallback( OnGUIEvent ); iY = 10; 
  112. /*
  113.     TODO: add UI controls as needed
  114.     g_SampleUI.AddComboBox( 19, 35, iY += 24, 125, 22 );
  115.     g_SampleUI.GetComboBox( 19 )->AddItem( L"Text1", NULL );
  116.     g_SampleUI.GetComboBox( 19 )->AddItem( L"Text2", NULL );
  117.     g_SampleUI.GetComboBox( 19 )->AddItem( L"Text3", NULL );
  118.     g_SampleUI.GetComboBox( 19 )->AddItem( L"Text4", NULL );
  119.     g_SampleUI.AddCheckBox( 21, L"Checkbox1", 35, iY += 24, 125, 22 );
  120.     g_SampleUI.AddCheckBox( 11, L"Checkbox2", 35, iY += 24, 125, 22 );
  121.     g_SampleUI.AddRadioButton( 12, 1, L"Radio1G1", 35, iY += 24, 125, 22 );
  122.     g_SampleUI.AddRadioButton( 13, 1, L"Radio2G1", 35, iY += 24, 125, 22 );
  123.     g_SampleUI.AddRadioButton( 14, 1, L"Radio3G1", 35, iY += 24, 125, 22 );
  124.     g_SampleUI.GetRadioButton( 14 )->SetChecked( true ); 
  125.     g_SampleUI.AddButton( 17, L"Button1", 35, iY += 24, 125, 22 );
  126.     g_SampleUI.AddButton( 18, L"Button2", 35, iY += 24, 125, 22 );
  127.     g_SampleUI.AddRadioButton( 15, 2, L"Radio1G2", 35, iY += 24, 125, 22 );
  128.     g_SampleUI.AddRadioButton( 16, 2, L"Radio2G3", 35, iY += 24, 125, 22 );
  129.     g_SampleUI.GetRadioButton( 16 )->SetChecked( true );
  130.     g_SampleUI.AddSlider( 20, 50, iY += 24, 100, 22 );
  131.     g_SampleUI.GetSlider( 20 )->SetRange( 0, 100 );
  132.     g_SampleUI.GetSlider( 20 )->SetValue( 50 );
  133.     g_SampleUI.AddEditBox( 20, L"Test", 35, iY += 24, 125, 32 );
  134. */
  135. }
  136. //--------------------------------------------------------------------------------------
  137. // Called during device initialization, this code checks the device for some 
  138. // minimum set of capabilities, and rejects those that don't pass by returning false.
  139. //--------------------------------------------------------------------------------------
  140. bool CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, 
  141.                                   D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext )
  142. {
  143.     // Skip backbuffer formats that don't support alpha blending
  144.     IDirect3D9* pD3D = DXUTGetD3DObject(); 
  145.     if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType,
  146.                     AdapterFormat, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, 
  147.                     D3DRTYPE_TEXTURE, BackBufferFormat ) ) )
  148.         return false;
  149.     return true;
  150. }
  151. //--------------------------------------------------------------------------------------
  152. // This callback function is called immediately before a device is created to allow the 
  153. // application to modify the device settings. The supplied pDeviceSettings parameter 
  154. // contains the settings that the framework has selected for the new device, and the 
  155. // application can make any desired changes directly to this structure.  Note however that 
  156. // DXUT will not correct invalid device settings so care must be taken 
  157. // to return valid device settings, otherwise IDirect3D9::CreateDevice() will fail.  
  158. //--------------------------------------------------------------------------------------
  159. bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps, void* pUserContext )
  160. {
  161.     // If device doesn't support HW T&L or doesn't support 1.1 vertex shaders in HW 
  162.     // then switch to SWVP.
  163.     if( (pCaps->DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == 0 ||
  164.          pCaps->VertexShaderVersion < D3DVS_VERSION(1,1) )
  165.     {
  166.         pDeviceSettings->BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
  167.     }
  168.     // Debugging vertex shaders requires either REF or software vertex processing 
  169.     // and debugging pixel shaders requires REF.  
  170. #ifdef DEBUG_VS
  171.     if( pDeviceSettings->DeviceType != D3DDEVTYPE_REF )
  172.     {
  173.         pDeviceSettings->BehaviorFlags &= ~D3DCREATE_HARDWARE_VERTEXPROCESSING;
  174.         pDeviceSettings->BehaviorFlags &= ~D3DCREATE_PUREDEVICE;
  175.         pDeviceSettings->BehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
  176.     }
  177. #endif
  178. #ifdef DEBUG_PS
  179.     pDeviceSettings->DeviceType = D3DDEVTYPE_REF;
  180. #endif
  181.     // For the first device created if its a REF device, optionally display a warning dialog box
  182.     static bool s_bFirstTime = true;
  183.     if( s_bFirstTime )
  184.     {
  185.         s_bFirstTime = false;
  186.         if( pDeviceSettings->DeviceType == D3DDEVTYPE_REF )
  187.             DXUTDisplaySwitchingToREFWarning();
  188.     }
  189.     return true;
  190. }
  191. //--------------------------------------------------------------------------------------
  192. // This callback function will be called immediately after the Direct3D device has been 
  193. // created, which will happen during application initialization and windowed/full screen 
  194. // toggles. This is the best location to create D3DPOOL_MANAGED resources since these 
  195. // resources need to be reloaded whenever the device is destroyed. Resources created  
  196. // here should be released in the OnDestroyDevice callback. 
  197. //--------------------------------------------------------------------------------------
  198. HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
  199. {
  200. // g_iDevCreate ++ ;
  201.     HRESULT hr;
  202.     V_RETURN( g_DialogResourceManager.OnCreateDevice( pd3dDevice ) );
  203.     V_RETURN( g_SettingsDlg.OnCreateDevice( pd3dDevice ) );
  204.     
  205.     // Initialize the font
  206.     V_RETURN( D3DXCreateFont( pd3dDevice, 15, 0, FW_BOLD, 1, FALSE, DEFAULT_CHARSET, 
  207.                          OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, 
  208.                          L"Arial", &g_pFont ) );
  209. // 创建台灯模型
  210. V_RETURN( g_spotLight.OnCreateDevice( pd3dDevice ) );
  211. // 初始化台灯光
  212. D3DVECTOR position, direction, upVec;
  213. position.x  = 0.0f;   position.y = 0.0f;   position.z = 0.0f;
  214. direction.x = 0.0f;  direction.y = -1.0f;  direction.z = 0.0f;
  215. upVec.x = 0.0f; upVec.y = 0.0f; upVec.z = 1.0f;
  216. g_spotLight.InitLight( position, direction, upVec );
  217. // 创建平面
  218. V_RETURN( g_plane.OnCreateDevice( pd3dDevice ) );
  219.     // Define DEBUG_VS and/or DEBUG_PS to debug vertex and/or pixel shaders with the 
  220.     // shader debugger. Debugging vertex shaders requires either REF or software vertex 
  221.     // processing, and debugging pixel shaders requires REF.  The 
  222.     // D3DXSHADER_FORCE_*_SOFTWARE_NOOPT flag improves the debug experience in the 
  223.     // shader debugger.  It enables source level debugging, prevents instruction 
  224.     // reordering, prevents dead code elimination, and forces the compiler to compile 
  225.     // against the next higher available software target, which ensures that the 
  226.     // unoptimized shaders do not exceed the shader model limitations.  Setting these 
  227.     // flags will cause slower rendering since the shaders will be unoptimized and 
  228.     // forced into software.  See the DirectX documentation for more information about 
  229.     // using the shader debugger.
  230.     DWORD dwShaderFlags = D3DXFX_NOT_CLONEABLE;
  231.     #ifdef DEBUG_VS
  232.         dwShaderFlags |= D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT;
  233.     #endif
  234.     #ifdef DEBUG_PS
  235.         dwShaderFlags |= D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT;
  236.     #endif
  237.     // Read the D3DX effect file
  238.     WCHAR str[MAX_PATH];
  239.     V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"SimpleSample.fx" ));
  240.     // If this fails, there should be debug output as to 
  241.     // they the .fx file failed to compile
  242.     V_RETURN( D3DXCreateEffectFromFile( pd3dDevice, str, NULL, NULL, dwShaderFlags, 
  243.                                         NULL, &g_pEffect, NULL ) );
  244.     // Setup the camera's view parameters
  245.     D3DXVECTOR3 vecEye(0.0f, 0.0f, -5.0f);
  246.     D3DXVECTOR3 vecAt (0.0f, 0.0f, -0.0f);
  247.     g_Camera.SetViewParams( &vecEye, &vecAt );
  248. // Create vertex shader
  249. ID3DXBuffer* pShaderBuffer, *pErrorBuffer;
  250. hr = D3DXAssembleShaderFromFileA( "vertex.vsd", NULL, NULL, D3DXSHADER_DEBUG, &pShaderBuffer, &pErrorBuffer );
  251. if( FAILED(hr) )
  252. {
  253. MessageBoxA(NULL, "Assemble vertex shader failed!", "Running Error!", MB_OK );
  254. return hr;
  255. }
  256. hr = pd3dDevice->CreateVertexShader( (DWORD*)(pShaderBuffer->GetBufferPointer()), &g_pVertexShader );
  257. if( FAILED(hr) )
  258. {
  259. MessageBoxA(NULL, "Create vertex shader failed!", "Running Error!", MB_OK );
  260. return hr;
  261. }
  262. // Create pixel shader
  263. hr = D3DXAssembleShaderFromFileA( "pixel.psd", NULL, NULL, D3DXSHADER_DEBUG, &pShaderBuffer, &pErrorBuffer );
  264. if( FAILED(hr) )
  265. {
  266. MessageBoxA(NULL, "Assemble pixel shader failed!", "Running Error!", MB_OK );
  267. return hr;
  268. }
  269. hr = pd3dDevice->CreatePixelShader( (DWORD*)(pShaderBuffer->GetBufferPointer()), &g_pPixelShader );
  270. if( FAILED(hr) )
  271. {
  272. switch (hr)
  273. {
  274. case D3DERR_INVALIDCALL:
  275. break;
  276. case D3DERR_OUTOFVIDEOMEMORY:
  277. break;
  278. case E_OUTOFMEMORY:
  279. break;
  280. default:
  281. break;
  282. }
  283. MessageBoxA(NULL, "Create pixel shader failed!", "Running Error!", MB_OK );
  284. return hr;
  285. }
  286. pShaderBuffer->Release();
  287.     return S_OK;
  288. }
  289. //--------------------------------------------------------------------------------------
  290. // This callback function will be called immediately after the Direct3D device has been 
  291. // reset, which will happen after a lost device scenario. This is the best location to 
  292. // create D3DPOOL_DEFAULT resources since these resources need to be reloaded whenever 
  293. // the device is lost. Resources created here should be released in the OnLostDevice 
  294. // callback. 
  295. //--------------------------------------------------------------------------------------
  296. HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice, 
  297.                                 const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
  298. {
  299. // g_iDevReset ++ ;
  300.     HRESULT hr;
  301.     V_RETURN( g_DialogResourceManager.OnResetDevice() );
  302.     V_RETURN( g_SettingsDlg.OnResetDevice() );
  303.     if( g_pFont )
  304.         V_RETURN( g_pFont->OnResetDevice() );
  305.     if( g_pEffect )
  306.         V_RETURN( g_pEffect->OnResetDevice() );
  307.     // Create a sprite to help batch calls when drawing many lines of text
  308.     V_RETURN( D3DXCreateSprite( pd3dDevice, &g_pTextSprite ) );
  309.     // Setup the camera's projection parameters
  310.     float fAspectRatio = pBackBufferSurfaceDesc->Width / (FLOAT)pBackBufferSurfaceDesc->Height;
  311.     g_Camera.SetProjParams( D3DX_PI/4, fAspectRatio, 0.1f, 1000.0f );
  312.     g_Camera.SetWindow( pBackBufferSurfaceDesc->Width, pBackBufferSurfaceDesc->Height );
  313.     g_HUD.SetLocation( pBackBufferSurfaceDesc->Width-170, 0 );
  314.     g_HUD.SetSize( 170, 170 );
  315.     g_SampleUI.SetLocation( pBackBufferSurfaceDesc->Width-170, pBackBufferSurfaceDesc->Height-350 );
  316.     g_SampleUI.SetSize( 170, 300 );
  317.     return S_OK;
  318. }
  319. //--------------------------------------------------------------------------------------
  320. // This callback function will be called once at the beginning of every frame. This is the
  321. // best location for your application to handle updates to the scene, but is not 
  322. // intended to contain actual rendering calls, which should instead be placed in the 
  323. // OnFrameRender callback.  
  324. //--------------------------------------------------------------------------------------
  325. void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
  326. {
  327.     // Update the camera's position based on user input 
  328.     g_Camera.FrameMove( fElapsedTime );
  329. g_spotLight.FrameMove( fElapsedTime );
  330. }
  331. //--------------------------------------------------------------------------------------
  332. // This callback function will be called at the end of every frame to perform all the 
  333. // rendering calls for the scene, and it will also be called if the window needs to be 
  334. // repainted. After this function has returned, DXUT will call 
  335. // IDirect3DDevice9::Present to display the contents of the next buffer in the swap chain
  336. //--------------------------------------------------------------------------------------
  337. void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
  338. {
  339.     HRESULT hr;
  340.     D3DXMATRIXA16 mWorld;
  341.     D3DXMATRIXA16 mView;
  342.     D3DXMATRIXA16 mProj;
  343.     D3DXMATRIXA16 mWorldViewProjection, mWorldViewProjectionT;
  344.     
  345.     // If the settings dialog is being shown, then
  346.     // render it instead of rendering the app's scene
  347.     if( g_SettingsDlg.IsActive() )
  348.     {
  349.         g_SettingsDlg.OnRender( fElapsedTime );
  350.         return;
  351.     }
  352.     // Clear the render target and the zbuffer 
  353.     V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 45, 50, 170), 1.0f, 0) );
  354.     // Render the scene
  355.     if( SUCCEEDED( pd3dDevice->BeginScene() ) )
  356.     {
  357.         // Get the projection & view matrix from the camera class
  358.         mWorld = *g_Camera.GetWorldMatrix();
  359.         mProj = *g_Camera.GetProjMatrix();
  360.         mView = *g_Camera.GetViewMatrix();
  361. // set transform
  362. pd3dDevice->SetTransform( D3DTS_VIEW, &mView );
  363. pd3dDevice->SetTransform( D3DTS_PROJECTION, &mProj );
  364.         mWorldViewProjection = mWorld * mView * mProj;
  365.         // Update the effect's variables.  Instead of using strings, it would 
  366.         // be more efficient to cache a handle to the parameter by calling 
  367.         // ID3DXEffect::GetParameterByName
  368.         V( g_pEffect->SetMatrix( "g_mWorldViewProjection", &mWorldViewProjection ) );
  369.         V( g_pEffect->SetMatrix( "g_mWorld", &mWorld ) );
  370.         V( g_pEffect->SetFloat( "g_fTime", (float)fTime ) );
  371.         DXUT_BeginPerfEvent( DXUT_PERFEVENTCOLOR, L"HUD / Stats" ); // These events are to help PIX identify what the code is doing
  372.         RenderText( pd3dDevice );
  373. // 设置环境光
  374. /*D3DLIGHT9 light;
  375. ZeroMemory( &light, sizeof(light) );
  376. light.Type = D3DLIGHT_DIRECTIONAL;
  377. light.Diffuse.r = 1.0f;
  378. light.Diffuse.g = 1.0f;
  379. light.Diffuse.b = 1.0f;
  380. light.Diffuse.a = 1.0f;
  381. light.Direction.x = light.Direction.y = 1.0f; light.Direction.z = 0.0f;
  382. pd3dDevice->SetLight( 0, &light );
  383. pd3dDevice->LightEnable( 0, TRUE );*/
  384. pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
  385. pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0xff202020 );
  386. // 渲染台灯模型
  387. g_spotLight.OnRender();
  388. // 渲染平面
  389. pd3dDevice->SetLight( 0, &g_spotLight.m_light );
  390. pd3dDevice->LightEnable( 0, TRUE );
  391. // Set vertex constants
  392. D3DXMATRIXA16 planeWorld, planeWorldViewProjection, planeWorldT, planeWorldViewProjectionT;
  393. D3DXMatrixIdentity( &planeWorld );
  394. D3DXMatrixTranspose( &planeWorldT, &planeWorld);
  395. pd3dDevice->SetVertexShaderConstantF( 8, (float*)&planeWorldT, 4 );
  396. planeWorldViewProjection = planeWorld * mView * mProj;
  397. D3DXMatrixTranspose( &planeWorldViewProjectionT, &planeWorldViewProjection);
  398. pd3dDevice->SetVertexShaderConstantF( 0, (float*)&planeWorldViewProjectionT, 4 );
  399. D3DXVECTOR4 ambientLight( 0.12f, 0.12f, 0.12f, 1.0f );
  400. pd3dDevice->SetVertexShaderConstantF( 4, (float*)&ambientLight, 1 );
  401. // Set pixel constants
  402. D3DVECTOR vecPos = g_spotLight.m_light.Position;
  403. D3DVECTOR vecDirection = g_spotLight.m_light.Direction;
  404. D3DXVECTOR4 lightPos( (float)vecPos.x, (float)vecPos.y, (float)vecPos.z, 1.0f );
  405. pd3dDevice->SetPixelShaderConstantF( 0, (float*)&lightPos, 1 );
  406. D3DXVECTOR4 lightDirection( (float)vecDirection.x, (float)vecDirection.y, (float)vecDirection.z,
  407. 0.0f );
  408. // Normalize the lightDirection vector
  409. D3DXVec4Normalize( &lightDirection, &lightDirection );
  410. // Set the spotlight's Phi_angle
  411. #define Phi_angle 0.3f
  412. lightDirection.w = 1.0f - Phi_angle;
  413. pd3dDevice->SetPixelShaderConstantF( 1, (float*)&lightDirection, 1 );
  414. // Set shader
  415. pd3dDevice->SetVertexShader(g_pVertexShader);
  416. pd3dDevice->SetPixelShader( g_pPixelShader);
  417. g_plane.OnRender( pd3dDevice );
  418. pd3dDevice->SetVertexShader(NULL);
  419. pd3dDevice->SetPixelShader(NULL);
  420.         V( g_HUD.OnRender( fElapsedTime ) );
  421.         V( g_SampleUI.OnRender( fElapsedTime ) );
  422.         DXUT_EndPerfEvent();
  423.         V( pd3dDevice->EndScene() );
  424.     }
  425. }
  426. //--------------------------------------------------------------------------------------
  427. // Render the help and statistics text. This function uses the ID3DXFont interface for 
  428. // efficient text rendering.
  429. //--------------------------------------------------------------------------------------
  430. void RenderText( IDirect3DDevice9* pd3dDevice )
  431. {
  432.     // The helper object simply helps keep track of text position, and color
  433.     // and then it calls pFont->DrawText( m_pSprite, strMsg, -1, &rc, DT_NOCLIP, m_clr );
  434.     // If NULL is passed in as the sprite object, then it will work however the 
  435.     // pFont->DrawText() will not be batched together.  Batching calls will improves performance.
  436.     CDXUTTextHelper txtHelper( g_pFont, g_pTextSprite, 15 );
  437. WCHAR szDevInfo[60];
  438. memset( szDevInfo, 0, 120 );
  439.     // Output statistics
  440.     txtHelper.Begin();
  441.     txtHelper.SetInsertionPos( 5, 5 );
  442.     txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 0.0f, 1.0f ) );
  443.     txtHelper.DrawTextLine( DXUTGetFrameStats(true) );
  444.     txtHelper.DrawTextLine( DXUTGetDeviceStats() );
  445. /*memset( szDevInfo, 0, 120 );
  446. wsprintf( szDevInfo, L"Ever create device %d times", g_iDevCreate );
  447. txtHelper.DrawTextLine( szDevInfo );
  448. memset( szDevInfo, 0, 120 );
  449. wsprintf( szDevInfo, L"Ever lost device %d times", g_iDevLost );
  450. txtHelper.DrawTextLine( szDevInfo );
  451. memset( szDevInfo, 0, 120 );
  452. wsprintf( szDevInfo, L"Ever reset device %d times", g_iDevReset );
  453. txtHelper.DrawTextLine( szDevInfo );
  454. memset( szDevInfo, 0, 120 );
  455. wsprintf( szDevInfo, L"the value of pd3dDevice is %x", (int)pd3dDevice );
  456. txtHelper.DrawTextLine( szDevInfo );*/
  457. /*static int addDevice = 0;
  458. memset( szDevInfo, 0, 120 );
  459. if( addDevice != 0 )
  460. {
  461. if( addDevice == (int)pd3dDevice )
  462. wsprintf( szDevInfo, L"Device never changed");
  463. else
  464. wsprintf( szDevInfo, L"Device ever changed");
  465. txtHelper.DrawTextLine( szDevInfo );
  466. }
  467. addDevice = (int)pd3dDevice;*/
  468. /*
  469.     TODO: add UI text as needed
  470.     txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ) );
  471.     txtHelper.DrawTextLine( L"Put whatever misc status here" );
  472.     
  473.     // Draw help
  474.     const D3DSURFACE_DESC* pd3dsdBackBuffer = DXUTGetBackBufferSurfaceDesc();
  475.     if( g_bShowHelp )
  476.     {
  477.         txtHelper.SetInsertionPos( 10, pd3dsdBackBuffer->Height-15*6 );
  478.         txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 0.75f, 0.0f, 1.0f ) );
  479.         txtHelper.DrawTextLine( L"Controls (F1 to hide):" );
  480.         txtHelper.SetInsertionPos( 40, pd3dsdBackBuffer->Height-15*5 );
  481.         txtHelper.DrawTextLine( L"Quit: ESC" );
  482.     }
  483.     else
  484.     {
  485.         txtHelper.SetInsertionPos( 10, pd3dsdBackBuffer->Height-15*2 );
  486.         txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ) );
  487.         txtHelper.DrawTextLine( L"Press F1 for help" );
  488.     }
  489. */
  490.     txtHelper.End();
  491. }
  492. //--------------------------------------------------------------------------------------
  493. // Before handling window messages, DXUT passes incoming windows 
  494. // messages to the application through this callback function. If the application sets 
  495. // *pbNoFurtherProcessing to TRUE, then DXUT will not process this message.
  496. //--------------------------------------------------------------------------------------
  497. LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing, void* pUserContext )
  498. {
  499.     // Always allow dialog resource manager calls to handle global messages
  500.     // so GUI state is updated correctly
  501.     *pbNoFurtherProcessing = g_DialogResourceManager.MsgProc( hWnd, uMsg, wParam, lParam );
  502.     if( *pbNoFurtherProcessing )
  503.         return 0;
  504.     if( g_SettingsDlg.IsActive() )
  505.     {
  506.         g_SettingsDlg.MsgProc( hWnd, uMsg, wParam, lParam );
  507.         return 0;
  508.     }
  509.     // Give the dialogs a chance to handle the message first
  510.     *pbNoFurtherProcessing = g_HUD.MsgProc( hWnd, uMsg, wParam, lParam );
  511.     if( *pbNoFurtherProcessing )
  512.         return 0;
  513.     *pbNoFurtherProcessing = g_SampleUI.MsgProc( hWnd, uMsg, wParam, lParam );
  514.     if( *pbNoFurtherProcessing )
  515.         return 0;
  516.     // Pass all remaining windows messages to camera so it can respond to user input
  517.     g_Camera.HandleMessages( hWnd, uMsg, wParam, lParam );
  518. g_spotLight.HandleMessages( hWnd, uMsg, wParam, lParam );
  519.     return 0;
  520. }
  521. //--------------------------------------------------------------------------------------
  522. // As a convenience, DXUT inspects the incoming windows messages for
  523. // keystroke messages and decodes the message parameters to pass relevant keyboard
  524. // messages to the application.  The framework does not remove the underlying keystroke 
  525. // messages, which are still passed to the application's MsgProc callback.
  526. //--------------------------------------------------------------------------------------
  527. void CALLBACK KeyboardProc( UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext )
  528. {
  529.     if( bKeyDown )
  530.     {
  531.         switch( nChar )
  532.         {
  533.             case VK_F1: g_bShowHelp = !g_bShowHelp; break;
  534.         }
  535.     }
  536. }
  537. //--------------------------------------------------------------------------------------
  538. // Handles the GUI events
  539. //--------------------------------------------------------------------------------------
  540. void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext )
  541. {
  542.     switch( nControlID )
  543.     {
  544.         case IDC_TOGGLEFULLSCREEN: DXUTToggleFullScreen(); break;
  545.         case IDC_TOGGLEREF:        DXUTToggleREF(); break;
  546.         case IDC_CHANGEDEVICE:     g_SettingsDlg.SetActive( !g_SettingsDlg.IsActive() ); break;
  547.     }
  548. }
  549. //--------------------------------------------------------------------------------------
  550. // This callback function will be called immediately after the Direct3D device has 
  551. // entered a lost state and before IDirect3DDevice9::Reset is called. Resources created
  552. // in the OnResetDevice callback should be released here, which generally includes all 
  553. // D3DPOOL_DEFAULT resources. See the "Lost Devices" section of the documentation for 
  554. // information about lost devices.
  555. //--------------------------------------------------------------------------------------
  556. void CALLBACK OnLostDevice( void* pUserContext )
  557. {
  558. // g_iDevLost ++ ;
  559.     g_DialogResourceManager.OnLostDevice();
  560.     g_SettingsDlg.OnLostDevice();
  561.     if( g_pFont )
  562.         g_pFont->OnLostDevice();
  563.     if( g_pEffect )
  564.         g_pEffect->OnLostDevice();
  565.     SAFE_RELEASE( g_pTextSprite );
  566. }
  567. //--------------------------------------------------------------------------------------
  568. // This callback function will be called immediately after the Direct3D device has 
  569. // been destroyed, which generally happens as a result of application termination or 
  570. // windowed/full screen toggles. Resources created in the OnCreateDevice callback 
  571. // should be released here, which generally includes all D3DPOOL_MANAGED resources. 
  572. //--------------------------------------------------------------------------------------
  573. void CALLBACK OnDestroyDevice( void* pUserContext )
  574. {
  575.     g_DialogResourceManager.OnDestroyDevice();
  576.     g_SettingsDlg.OnDestroyDevice();
  577. g_spotLight.OnDestroyDevice();
  578. g_plane.OnDestroyDevice();
  579. SAFE_RELEASE( g_pVertexShader );
  580. SAFE_RELEASE( g_pPixelShader );
  581.     SAFE_RELEASE( g_pEffect );
  582.     SAFE_RELEASE( g_pFont );
  583. }