source: GTP/trunk/App/Demos/Illum/SoftShadowMap/ShadowMap.cpp @ 1637

Revision 1637, 57.7 KB checked in by szirmay, 18 years ago (diff)
Line 
1#include "dxstdafx.h"
2#include "dxutmesh.h"
3#include "resource.h"
4
5#include "properties.h"
6
7//--------------------------------------------------------------------------------------
8// Entry point to the program. Initializes everything and goes into a message processing
9// loop. Idle time is used to render the scene.
10//--------------------------------------------------------------------------------------
11INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
12{
13    // Enable run-time memory check for debug builds.
14#if defined(DEBUG) | defined(_DEBUG)
15    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
16#endif
17
18    // Initialize the camera
19    g_CamCamera.SetScalers( 0.01f, 15.0f );
20    g_LightCamera.SetScalers( 0.01f, 8.0f );
21    g_CamCamera.SetRotateButtons( true, false, false );
22    g_LightCamera.SetRotateButtons( false, false, true );
23
24    // Set up the view parameters for the camera
25    D3DXVECTOR3 vFromPt   = D3DXVECTOR3( 0.0f, 5.0f, -18.0f );
26    D3DXVECTOR3 vLookatPt = D3DXVECTOR3( 0.0f, -1.0f, 0.0f );
27    g_CamCamera.SetViewParams( &vFromPt, &vLookatPt );
28
29    vFromPt = D3DXVECTOR3( 0.0f, 0.0f, -12.0f );
30    vLookatPt = D3DXVECTOR3( 0.0f, -2.0f, 1.0f );
31    g_LightCamera.SetViewParams( &vFromPt, &vLookatPt );
32
33    // Set the callback functions. These functions allow DXUT to notify
34    // the application about device changes, user input, and windows messages.  The
35    // callbacks are optional so you need only set callbacks for events you're interested
36    // in. However, if you don't handle the device reset/lost callbacks then the sample
37    // framework won't be able to reset your device since the application must first
38    // release all device resources before resetting.  Likewise, if you don't handle the
39    // device created/destroyed callbacks then DXUT won't be able to
40    // recreate your device resources.
41    DXUTSetCallbackDeviceCreated( OnCreateDevice );
42    DXUTSetCallbackDeviceReset( OnResetDevice );
43    DXUTSetCallbackDeviceLost( OnLostDevice );
44    DXUTSetCallbackDeviceDestroyed( OnDestroyDevice );
45    DXUTSetCallbackMsgProc( MsgProc );
46    DXUTSetCallbackKeyboard( KeyboardProc );
47    DXUTSetCallbackMouse( MouseProc );
48    DXUTSetCallbackFrameRender( OnFrameRender );
49    DXUTSetCallbackFrameMove( OnFrameMove );
50
51    InitializeDialogs();
52
53    // Show the cursor and clip it when in full screen
54    DXUTSetCursorSettings( true, true );
55
56    // Initialize DXUT and create the desired Win32 window and Direct3D
57    // device for the application. Calling each of these functions is optional, but they
58    // allow you to set several options which control the behavior of the framework.
59    DXUTInit( true, true, true ); // Parse the command line, handle the default hotkeys, and show msgboxes
60    DXUTCreateWindow( L"ShadowMap Techniques" );
61    DXUTCreateDevice( D3DADAPTER_DEFAULT, true, WINDOW_WIDTH, WINDOW_HEIGHT, IsDeviceAcceptable, ModifyDeviceSettings );
62
63    // Pass control to DXUT for handling the message pump and
64    // dispatching render calls. DXUT will call your FrameMove
65    // and FrameRender callback when there is idle time between handling window messages.
66    DXUTMainLoop();
67
68    // Perform any application-level cleanup here. Direct3D device resources are released within the
69    // appropriate callback functions and therefore don't require any cleanup code here.
70
71    return DXUTGetExitCode();
72}
73
74
75//--------------------------------------------------------------------------------------
76// Sets up the dialogs
77//--------------------------------------------------------------------------------------
78void InitializeDialogs()
79{
80    g_SettingsDlg.Init( &g_DialogResourceManager );
81    g_HUD.Init( &g_DialogResourceManager );
82
83    g_HUD.SetCallback( OnGUIEvent );
84       
85        // Initialize dialog
86        int posX = 0;
87        int posY = 0;
88
89        // Setup for buttons
90    g_HUD.AddButton( IDC_TOGGLEFULLSCREEN,                      L"Toggle full screen",          35, posY,                 125, 22 );
91    g_HUD.AddButton( IDC_TOGGLEREF,                                     L"Toggle REF (F3)",                     35, posY += 24, 125, 22 );
92    g_HUD.AddButton( IDC_CHANGEDEVICE,                          L"Change device (F2)",          35, posY += 24, 125, 22, VK_F2 );
93
94
95        // Setup for sliders
96        g_HUD.AddSlider( HUNDRED + 0, posX, posY += 40, 120, 14, g_iSliderMinValues[0], g_iSliderMaxValues[0], g_iFov );
97        g_HUD.AddSlider( HUNDRED + 1, posX, posY += 16, 120, 14, g_iSliderMinValues[1], g_iSliderMaxValues[1], g_iLightFov );
98        g_HUD.AddSlider( HUNDRED + 2, posX, posY += 16, 120, 14, g_iSliderMinValues[2], g_iSliderMaxValues[2], (int)( g_fLightSize * 100 ) );
99        g_HUD.AddSlider( HUNDRED + 3, posX, posY += 16, 120, 14, g_iSliderMinValues[3], g_iSliderMaxValues[3], (int)( g_fIntensity * 100 ) );
100        g_HUD.AddSlider( HUNDRED + 4, posX, posY += 16, 120, 14, g_iSliderMinValues[4], g_iSliderMaxValues[4], (int)( g_fShadowBias * 100 ) );
101        g_HUD.AddSlider( HUNDRED + 5, posX, posY += 16, 120, 14, g_iSliderMinValues[5], g_iSliderMaxValues[5], (int)( g_fBiasSlope * 100 ) );
102        g_HUD.AddSlider( HUNDRED + 6, posX, posY += 16, 120, 14, g_iSliderMinValues[6], g_iSliderMaxValues[6], g_iKernelSize );
103        g_HUD.AddSlider( HUNDRED + 7, posX, posY += 16, 120, 14, g_iSliderMinValues[7], g_iSliderMaxValues[7], (int)( log( (float)g_iShadowMapSize   ) / log( 2.0f ) ) );
104        g_HUD.AddSlider( HUNDRED + 8, posX, posY += 16, 120, 14, g_iSliderMinValues[8], g_iSliderMaxValues[8], (int)( log( (float)g_iFocusingMapSize ) / log( 2.0f ) ) );
105        g_HUD.AddSlider( HUNDRED + 9, posX, posY += 16, 120, 14, g_iSliderMinValues[9], g_iSliderMaxValues[9], (int)( g_fLightSourceSamples * 50 ) );
106
107        // Setup for checkbox
108    g_HUD.AddCheckBox( IDC_CHECKBOX,                            L"Display GUI (F1)",            35, posY += 24, 150, 22, g_bShowText, VK_F1 );
109    g_HUD.AddCheckBox( IDC_LIGHTPERSPECTIVE,            L"The light's view (V)",        35, posY += 24, 160, 22, !g_bCameraPerspective, L'V' );
110    g_HUD.AddCheckBox( IDC_PAUSE_CHECKBOX,                      L"Pause (P)",                           35, posY += 24, 160, 22, g_bPause, L'P' );
111        g_HUD.AddCheckBox( IDC_USE_TEXTURE_CHECKBOX,    L"Use texture (T)",                     35, posY += 24, 160, 22, g_bUseTexture, L'T' );
112        g_HUD.AddCheckBox( IDC_USE_FOCUSING_CHECKBOX,   L"Use focusing (F)",            35, posY += 24, 160, 22, g_bUseFocusing, L'F' );
113       
114
115        g_HUD.AddComboBox( IDC_METHOD_COMBO_BOX, 60, posY + 40, 130, 20, 0, false, &g_pTechniquesListComboBox );
116
117        g_pTechniquesListComboBox->SetDropHeight(105);
118
119        g_pTechniquesListComboBox->AddItem( L"0-Reference", NULL );
120        g_pTechniquesListComboBox->AddItem( L"6-PC soft", NULL );
121    g_pTechniquesListComboBox->AddItem( L"7-Shadow accu", NULL );
122
123        // number of items above: 0 .. 2 = 3
124        g_iNumberOfMethods = 3;
125}
126
127
128//--------------------------------------------------------------------------------------
129// Called during device initialization, this code checks the device for some
130// minimum set of capabilities, and rejects those that don't pass by returning false.
131//--------------------------------------------------------------------------------------
132bool CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat,
133                                  D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext )
134{
135    // Skip backbuffer formats that don't support alpha blending
136    IDirect3D9* pD3D = DXUTGetD3DObject();
137    if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType,
138                    AdapterFormat, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING,
139                    D3DRTYPE_TEXTURE, BackBufferFormat ) ) )
140        return false;
141
142    // Must support pixel shader 2.0
143    if( pCaps->PixelShaderVersion < D3DPS_VERSION( 2, 0 ) )
144        return false;
145
146    // Check support of the used texture formats.
147
148    // need to support D3DFMT_A8R8G8B8 format
149    if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType,
150                    AdapterFormat, D3DUSAGE_DYNAMIC,
151                    D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8 ) ) )
152        return false;
153
154        // need to support D3DFMT_A32B32G32R32F format
155    if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType,
156                    AdapterFormat, D3DUSAGE_RENDERTARGET,
157                    D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F ) ) )
158        return false;
159
160        // need to support D3DFMT_A32B32G32R32F format
161    if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType,
162                    AdapterFormat, D3DUSAGE_DYNAMIC,
163                    D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F ) ) )
164        return false;
165
166        // need to support D3DFMT_D24S8 format
167    if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType,
168                    AdapterFormat, D3DUSAGE_DEPTHSTENCIL,
169                    D3DRTYPE_TEXTURE, D3DFMT_D24S8 ) ) )
170        return false;
171
172    return true;
173}
174
175
176//--------------------------------------------------------------------------------------
177// This callback function is called immediately before a device is created to allow the
178// application to modify the device settings. The supplied pDeviceSettings parameter
179// contains the settings that the framework has selected for the new device, and the
180// application can make any desired changes directly to this structure.  Note however that
181// DXUT will not correct invalid device settings so care must be taken
182// to return valid device settings, otherwise IDirect3D9::CreateDevice() will fail. 
183//--------------------------------------------------------------------------------------
184bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps, void* pUserContext )
185{
186        // Turn off VSYNC
187        pDeviceSettings->pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
188
189
190    // If device doesn't support HW T&L or doesn't support 1.1 vertex shaders in HW
191    // then switch to SWVP.
192    if( (pCaps->DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == 0 ||
193         pCaps->VertexShaderVersion < D3DVS_VERSION(1,1) )
194    {
195        pDeviceSettings->BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
196    }
197
198    // Debugging vertex shaders requires either REF or software vertex processing
199    // and debugging pixel shaders requires REF. 
200#ifdef DEBUG_VS
201    if( pDeviceSettings->DeviceType != D3DDEVTYPE_REF )
202    {
203        pDeviceSettings->BehaviorFlags &= ~D3DCREATE_HARDWARE_VERTEXPROCESSING;
204        pDeviceSettings->BehaviorFlags &= ~D3DCREATE_PUREDEVICE;                           
205        pDeviceSettings->BehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
206    }
207#endif
208#ifdef DEBUG_PS
209    pDeviceSettings->DeviceType = D3DDEVTYPE_REF;
210#endif
211    // For the first device created if its a REF device, optionally display a warning dialog box
212    static bool s_bFirstTime = true;
213    if( s_bFirstTime )
214    {
215        s_bFirstTime = false;
216        if( pDeviceSettings->DeviceType == D3DDEVTYPE_REF )
217            DXUTDisplaySwitchingToREFWarning();
218    }
219
220    return true;
221}
222
223
224//--------------------------------------------------------------------------------------
225// This callback function will be called immediately after the Direct3D device has been
226// created, which will happen during application initialization and windowed/full screen
227// toggles. This is the best location to create D3DPOOL_MANAGED resources since these
228// resources need to be reloaded whenever the device is destroyed. Resources created 
229// here should be released in the OnDestroyDevice callback.
230//--------------------------------------------------------------------------------------
231HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
232{
233    HRESULT hr;
234
235        g_pd3dDevice = pd3dDevice;
236
237    V_RETURN( g_DialogResourceManager.OnCreateDevice( pd3dDevice ) );
238    V_RETURN( g_SettingsDlg.OnCreateDevice( pd3dDevice ) );
239
240    // Initialize the font
241    V_RETURN( D3DXCreateFont( pd3dDevice, 15, 0, FW_BOLD, 1, FALSE, DEFAULT_CHARSET,
242                         OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE,
243                         L"Arial", &g_pFont ) );
244    V_RETURN( D3DXCreateFont( pd3dDevice, 12, 0, FW_BOLD, 1, FALSE, DEFAULT_CHARSET,
245                         OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE,
246                         L"Arial", &g_pFontSmall ) );
247
248    // Define DEBUG_VS and/or DEBUG_PS to debug vertex and/or pixel shaders with the
249    // shader debugger. Debugging vertex shaders requires either REF or software vertex
250    // processing, and debugging pixel shaders requires REF.  The
251    // D3DXSHADER_FORCE_*_SOFTWARE_NOOPT flag improves the debug experience in the
252    // shader debugger.  It enables source level debugging, prevents instruction
253    // reordering, prevents dead code elimination, and forces the compiler to compile
254    // against the next higher available software target, which ensures that the
255    // unoptimized shaders do not exceed the shader model limitations.  Setting these
256    // flags will cause slower rendering since the shaders will be unoptimized and
257    // forced into software.  See the DirectX documentation for more information about
258    // using the shader debugger.
259        DWORD dwShaderFlags = D3DXFX_NOT_CLONEABLE | D3DXSHADER_PREFER_FLOW_CONTROL;
260    #ifdef DEBUG_VS
261        dwShaderFlags |= D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT;
262    #endif
263    #ifdef DEBUG_PS
264        dwShaderFlags |= D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT;
265    #endif
266
267
268    // If this fails, there should be debug output as to
269    // they the .fx file failed to compile
270
271        // Read the D3DX effect file
272        ID3DXBuffer* errBuff = NULL;
273        if( FAILED(D3DXCreateEffectFromFile( pd3dDevice, L"ShadowMap.fx", NULL, NULL, dwShaderFlags, NULL, &g_pEffect, &errBuff )))
274        {
275                int BufSize = errBuff->GetBufferSize();
276
277                // displaying error message of arbitrary length
278                wchar_t* wbuf = new wchar_t[BufSize];
279                size_t convertedChars = 0;
280//              mbstowcs_s(&convertedChars, wbuf, BufSize, (const char*)errBuff->GetBufferPointer(), _TRUNCATE);
281//              MessageBox(NULL, wbuf, L".fx Compilation Error", MB_ICONERROR);         // show error message
282
283                delete wbuf;
284                exit(-1);
285        }
286
287    // Create vertex declaration
288    V_RETURN( pd3dDevice->CreateVertexDeclaration( g_aVertDecl, &g_pVertDecl ) );
289
290    WCHAR str[MAX_PATH];
291
292    // Initialize the meshes
293    for( int i = 0; i < NUM_OBJ; ++i )
294    {
295        V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, g_aszMeshFile[i] ) );
296        if( FAILED( g_Obj[i].m_Mesh.Create( pd3dDevice, str ) ) )
297            return DXUTERR_MEDIANOTFOUND;
298        V_RETURN( g_Obj[i].m_Mesh.SetVertexDecl( pd3dDevice, g_aVertDecl ) );
299        g_Obj[i].m_mWorld = g_amInitObjWorld[i];
300    }
301
302        // Compute Room bounding box
303        void* data;
304        D3DXVECTOR3 vRoomBoundingBoxMin3f;                      // Bounding box of room min point
305        D3DXVECTOR3 vRoomBoundingBoxMax3f;                      // Bounding box of room max point
306        g_Obj[0].m_Mesh.m_pVB->Lock(0,0,&data,0);
307        D3DXVECTOR3 min,max;
308        D3DVERTEXBUFFER_DESC descriptor;
309        g_Obj[0].m_Mesh.m_pVB->GetDesc(  &descriptor);
310        UINT stride = D3DXGetFVFVertexSize(descriptor.FVF);
311        D3DXComputeBoundingBox((D3DXVECTOR3*)data, descriptor.Size / stride, stride, &vRoomBoundingBoxMin3f, &vRoomBoundingBoxMax3f);
312
313        g_fRoomRadius = (float)sqrt( pow( (double)( vRoomBoundingBoxMax3f.x - vRoomBoundingBoxMin3f.x ), 2.0 ) +
314                                                         pow( (double)( vRoomBoundingBoxMax3f.y - vRoomBoundingBoxMin3f.y ), 2.0 ) +
315                                                     pow( (double)( vRoomBoundingBoxMax3f.z - vRoomBoundingBoxMin3f.z ), 2.0 ) ) / 2.0f;
316
317    // Initialize the light mesh
318    V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"media\\objects\\spotlight.x" ) );
319    if( FAILED( g_LightMesh.Create( pd3dDevice, str ) ) )
320        return DXUTERR_MEDIANOTFOUND;
321    V_RETURN( g_LightMesh.SetVertexDecl( pd3dDevice, g_aVertDecl ) );
322
323    // World transform to identity
324    D3DXMATRIXA16 mIdent;
325    D3DXMatrixIdentity( &mIdent );
326    V_RETURN( pd3dDevice->SetTransform( D3DTS_WORLD, &mIdent ) );
327
328        // Calculates the real samples on the light source
329        g_fRealSamples = 0;
330        for( float x = 0.5f / g_fLightSourceSamples; x < g_fLightSourceSamples; x++ )
331        {
332                for( float y = 0.5f / g_fLightSourceSamples; y < g_fLightSourceSamples; y++ )
333                {
334                        if( x * x + y * y < g_fLightSourceSamples * g_fLightSourceSamples )
335                        {
336                                g_fRealSamples++;
337                        }
338                }
339        }
340        g_fRealSamples = 1.0f / g_fRealSamples;
341
342    return S_OK;
343}
344
345
346//--------------------------------------------------------------------------------------
347// This callback function will be called immediately after the Direct3D device has been
348// reset, which will happen after a lost device scenario. This is the best location to
349// create D3DPOOL_DEFAULT resources since these resources need to be reloaded whenever
350// the device is lost. Resources created here should be released in the OnLostDevice
351// callback.
352//--------------------------------------------------------------------------------------
353HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice,
354                                const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
355{
356    HRESULT hr;
357
358    V_RETURN( g_DialogResourceManager.OnResetDevice() );
359    V_RETURN( g_SettingsDlg.OnResetDevice() );
360
361    if( g_pFont )
362        V_RETURN( g_pFont->OnResetDevice() );
363    if( g_pFontSmall )
364        V_RETURN( g_pFontSmall->OnResetDevice() );
365    if( g_pEffect )
366        V_RETURN( g_pEffect->OnResetDevice() );
367
368    // Create a sprite to help batch calls when drawing many lines of text
369    V_RETURN( D3DXCreateSprite( pd3dDevice, &g_pTextSprite ) );
370
371    // Setup the camera's projection parameters
372    float fAspectRatio = pBackBufferSurfaceDesc->Width / (FLOAT)pBackBufferSurfaceDesc->Height;
373    g_CamCamera.SetProjParams( D3DX_PI/4, fAspectRatio, g_fLightFrontPlane, g_fLightBackPlane );
374    g_LightCamera.SetProjParams( D3DX_PI/4, fAspectRatio, g_fLightFrontPlane, g_fLightBackPlane );
375
376    // Create the default texture (used when a triangle does not use a texture)
377    V_RETURN( pd3dDevice->CreateTexture( 1, 1, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &g_pDefaultTexture, NULL ) );
378    D3DLOCKED_RECT lr;
379    V_RETURN( g_pDefaultTexture->LockRect( 0, &lr, NULL, 0 ) );
380    *(LPDWORD)lr.pBits = D3DCOLOR_RGBA( 255, 255, 255, 255 );
381    V_RETURN( g_pDefaultTexture->UnlockRect( 0 ) );
382
383    // Restore the scene objects
384    for( int i = 0; i < NUM_OBJ; ++i )
385        V_RETURN( g_Obj[i].m_Mesh.RestoreDeviceObjects( pd3dDevice ) );
386    V_RETURN( g_LightMesh.RestoreDeviceObjects( pd3dDevice ) );
387   
388        // Create textures
389    CreateTexture();
390       
391        // Positon the HUD
392    g_HUD.SetLocation( pBackBufferSurfaceDesc->Width-170, 0 );
393    g_HUD.SetSize( 170, pBackBufferSurfaceDesc->Height );
394
395
396        // Create vertex declaration for the fullscreen quad
397        V( pd3dDevice->CreateVertexDeclaration( g_aFullScreneQuadVertex, &g_pFullScreenQuadVertexDeclaration ) );
398        V_RETURN( pd3dDevice->CreateVertexBuffer( 6 * sizeof( FullScreenQuadVertexStruct ),
399                D3DUSAGE_WRITEONLY, D3DFVF_FULLSCREENQUADVERTEX, D3DPOOL_DEFAULT, &g_pFullScreenQuadVertexBuffer, NULL ) );
400
401        void* pVertices;
402        V( g_pFullScreenQuadVertexBuffer->Lock( 0, sizeof( fullscreen ), (void**)&pVertices, 0 ) );
403        memcpy( pVertices, fullscreen, sizeof( fullscreen ) );
404        g_pFullScreenQuadVertexBuffer->Unlock();
405
406        return S_OK;
407}
408
409//--------------------------------------------------------------------------------------
410// Creates textures
411// They can be resized on the fly
412//--------------------------------------------------------------------------------------
413void CreateTexture()
414{
415        HRESULT hr;
416   
417        SAFE_RELEASE( g_pShadowMapColorTexture );
418        SAFE_RELEASE( g_pShadowMapColorSurface );
419        SAFE_RELEASE( g_pShadowWeightTexture );
420        SAFE_RELEASE( g_pShadowWeightSurface );
421        SAFE_RELEASE( g_pShadowMapZTexture );
422        SAFE_RELEASE( g_pShadowMapZSurface );
423        SAFE_RELEASE( g_pShadowWeightZTexture );
424        SAFE_RELEASE( g_pShadowWeightZSurface );
425    SAFE_RELEASE( g_pFocusingMapColorTexture );
426        SAFE_RELEASE( g_pFocusingMapColorSurface );
427        SAFE_RELEASE( g_pMemoryMappedTexture );
428        SAFE_RELEASE( g_pMemoryMappedTextureSurface );
429
430
431        // Create the shadow map texture
432    V( g_pd3dDevice->CreateTexture( g_iShadowMapSize, g_iShadowMapSize,
433                                         1, D3DUSAGE_RENDERTARGET,
434                                         D3DFMT_A32B32G32R32F,
435                                         D3DPOOL_DEFAULT,
436                                         &g_pShadowMapColorTexture,
437                                         NULL ) );
438
439        V( g_pShadowMapColorTexture->GetSurfaceLevel( 0, &g_pShadowMapColorSurface ) );
440
441
442        V( g_pd3dDevice->CreateTexture( g_iShadowMapSize, g_iShadowMapSize,
443                                         1, D3DUSAGE_RENDERTARGET,
444                                         D3DFMT_A16B16G16R16F,
445                                                                                 //D3DFMT_A32B32G32R32F,
446                                         D3DPOOL_DEFAULT,
447                                         &g_pShadowWeightTexture,
448                                         NULL ) );
449
450        V( g_pShadowWeightTexture->GetSurfaceLevel( 0, &g_pShadowWeightSurface ) );
451
452        // Create the depth stencil texture
453    V( g_pd3dDevice->CreateTexture( g_iShadowMapSize, g_iShadowMapSize,
454                                                                                 1, D3DUSAGE_DEPTHSTENCIL,
455                                                                                 D3DFMT_D24S8,
456                                         D3DPOOL_DEFAULT,
457                                         &g_pShadowMapZTexture,
458                                         NULL ) );
459
460        V( g_pShadowMapZTexture->GetSurfaceLevel( 0, &g_pShadowMapZSurface ) );
461
462         V( g_pd3dDevice->CreateTexture( g_iShadowMapSize, g_iShadowMapSize,
463                                                                                 1, D3DUSAGE_DEPTHSTENCIL,
464                                                                                 D3DFMT_D24S8,
465                                         D3DPOOL_DEFAULT,
466                                         &g_pShadowWeightZTexture,
467                                         NULL ) );
468
469        V( g_pShadowWeightZTexture->GetSurfaceLevel( 0, &g_pShadowWeightZSurface ) );
470
471        // Create the focusing map texture
472    V( g_pd3dDevice->CreateTexture( g_iFocusingMapSize, g_iFocusingMapSize,
473                                         1, D3DUSAGE_RENDERTARGET,
474                                         D3DFMT_A32B32G32R32F,
475                                         D3DPOOL_DEFAULT,
476                                         &g_pFocusingMapColorTexture,
477                                         NULL ) );
478
479        V( g_pFocusingMapColorTexture->GetSurfaceLevel( 0, &g_pFocusingMapColorSurface ) );
480
481        // Memory mapped texture
482        V( g_pd3dDevice->CreateTexture( g_iFocusingMapSize, g_iFocusingMapSize,
483                                                                                 1, D3DUSAGE_DYNAMIC,
484                                         D3DFMT_A32B32G32R32F,
485                                         D3DPOOL_SYSTEMMEM,
486                                         &g_pMemoryMappedTexture,
487                                         NULL ) );
488
489        V( g_pMemoryMappedTexture->GetSurfaceLevel( 0, &g_pMemoryMappedTextureSurface ) );
490}
491
492//--------------------------------------------------------------------------------------
493// This callback function will be called once at the beginning of every frame. This is the
494// best location for your application to handle updates to the scene, but is not
495// intended to contain actual rendering calls, which should instead be placed in the
496// OnFrameRender callback. 
497//--------------------------------------------------------------------------------------
498void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
499{
500    // Update the camera's position based on user input
501    g_CamCamera.FrameMove( fElapsedTime );
502    g_LightCamera.FrameMove( fElapsedTime );
503
504        if( !g_bPause )
505        {
506                // Animate the plane, car and sphere meshes
507                D3DXMATRIXA16 m;
508
509                D3DXMatrixRotationY( &m, D3DX_PI * fElapsedTime / 4.0f );
510                D3DXMatrixMultiply( &g_Obj[1].m_mWorld, &g_Obj[1].m_mWorld, &m );
511                D3DXMatrixRotationY( &m, -D3DX_PI * fElapsedTime / 4.0f );
512                D3DXMatrixMultiply( &g_Obj[2].m_mWorld, &g_Obj[2].m_mWorld, &m );
513        }
514}
515
516
517//--------------------------------------------------------------------------------------
518// Renders the scene onto the current render target using the current
519// technique in the effect.
520//--------------------------------------------------------------------------------------
521void RenderScene( IDirect3DDevice9* pd3dDevice, float fElapsedTime, const D3DXMATRIX *pmView, const D3DXMATRIX *pmProj )
522{
523    HRESULT hr;
524
525    // Initialize required parameter
526        V( g_pEffect->SetTexture( "g_txShadowMapColor", g_pShadowMapColorTexture ) );
527        V( g_pEffect->SetTexture( "g_txShadowWeight", g_pShadowWeightTexture ) );
528        V( g_pEffect->SetTexture( "g_txShadowMapZ",             g_pShadowMapZTexture ) );
529
530        V( g_pEffect->SetFloat( "g_fFov",                               ( (float)g_iFov ) / 57.2958f ) );
531        V( g_pEffect->SetFloat( "g_fLightSize",                 g_fLightSize ) );
532        V( g_pEffect->SetFloat( "g_fIntensity",                 g_fIntensity ) );
533        V( g_pEffect->SetFloat( "g_fShadowBias",                g_fShadowBias ) );
534        V( g_pEffect->SetFloat( "near",                                 g_fLightFrontPlane ) );
535        V( g_pEffect->SetFloat( "far",                                  g_fLightBackPlane ) );
536        V( g_pEffect->SetFloat( "SHADOWMAP_SIZE",               (float)g_iShadowMapSize));
537        V( g_pEffect->SetFloat( "HALF_TEXEL",                   0.5f / (float)g_iShadowMapSize));
538        V( g_pEffect->SetFloat( "g_fBiasSlope",                 g_fBiasSlope) );
539        V( g_pEffect->SetFloat( "g_fRealSamples",               g_fRealSamples ) );
540        V( g_pEffect->SetInt(   "g_iKernelSize",                g_iKernelSize ) );
541       
542
543        V( g_pEffect->SetBool( "g_bRenderBaseTexture", g_bRenderBaseTexture ) );
544       
545        //set special texture matrix for shadow mapping
546    float fOffsetX = 0.5f + (0.5f / (float)g_iShadowMapSize);
547    float fOffsetY = 0.5f + (0.5f / (float)g_iShadowMapSize);
548        unsigned int range = 1;            //note different scale in DX9!
549    //float fBias    = -0.001f * (float)range;
550    float fBias    = 0.0f;
551    D3DXMATRIXA16 texScaleBiasMat(      0.5f,     0.0f,     0.0f,         0.0f,
552                                                                        0.0f,    -0.5f,     0.0f,         0.0f,
553                                                                        0.0f,     0.0f,     (float)range, 0.0f,
554                                                                        fOffsetX, fOffsetY, -g_fShadowBias/1000.0f, 1.0f );
555
556        V( g_pEffect->SetMatrix( "TexScaleBias", &texScaleBiasMat ) );
557
558
559    // Choose the right shader method
560        switch( g_iShadowMethod )
561        {
562                case 0:
563                {
564                        if( g_bRenderShadowMap )
565                        {
566                                V( g_pEffect->SetTechnique( "RenderShadowMap_0" ) );
567                        }
568                        else
569                        {
570                                V( g_pEffect->SetTechnique( "RenderSceneWithTechnique_0" ) );
571                        }
572                        break;
573                }
574                case 1:
575                {
576                        if( g_bRenderShadowMap )
577                        {
578                                V( g_pEffect->SetTechnique( "RenderShadowMap_6" ) );
579                        }
580                        else
581                        {
582                                V( g_pEffect->SetTechnique( "RenderSceneWithTechnique_6" ) );
583                        }
584                        break;
585                }
586                case 2:
587                {
588                        if( g_bRenderShadowMap )
589                        {
590                                V( g_pEffect->SetTechnique( "RenderShadowMap_7" ) );
591                        }
592                        else
593                        {
594                                V( g_pEffect->SetTechnique( "RenderSceneWithTechnique_7" ) );
595                        }
596                        break;
597                }
598        }
599
600        if( g_bRenderFocusingMap )
601        {
602                V( g_pEffect->SetTechnique( "RenderFocusingMap" ) );
603        }
604
605
606        // Begin the scene
607    if( SUCCEEDED( pd3dDevice->BeginScene() ) )
608    {   
609                if( !g_bRenderGUI )
610                {
611                        // Render the objects
612                        for( int obj = 0; obj < NUM_OBJ; ++obj )
613                        {
614                                D3DXMATRIXA16 mWorld, mWorldView, mWorldViewProj;
615                                mWorld = g_Obj[obj].m_mWorld;
616                                D3DXMatrixMultiply( &mWorldView, &mWorld, pmView );
617                                D3DXMatrixMultiply( &mWorldViewProj, &mWorldView, pmProj );
618                                V( g_pEffect->SetMatrix( "WorldViewProj", &mWorldViewProj ) );
619
620                                // Compute the view matrix for the light
621                                D3DXMATRIXA16 mLightView, WorldLight, WorldLightProj;
622                               
623                                if( g_bRenderBaseTexture )
624                                {
625                                        mLightView = *g_LightCamera.GetViewMatrix();
626                                }
627                                else
628                                {
629                                        mLightView = g_mLightView;
630                                }
631
632                                D3DXMatrixMultiply( &WorldLight, &mWorld, &mLightView );
633                                V( g_pEffect->SetMatrix( "WorldLight", &WorldLight ) );
634                               
635                                D3DXMatrixMultiply( &WorldLightProj, &WorldLight, &g_mLightProj );
636                                V( g_pEffect->SetMatrix( "WorldLightProj", &WorldLightProj ) );
637
638                                LPD3DXMESH pMesh = g_Obj[obj].m_Mesh.GetMesh();
639                                UINT cPass;
640                                V( g_pEffect->Begin( &cPass, 0 ) );
641                                for( UINT p = 0; p < cPass; ++p )
642                                {
643                                        V( g_pEffect->BeginPass( p ) );
644
645                                        for( DWORD i = 0; i < g_Obj[obj].m_Mesh.m_dwNumMaterials; ++i )
646                                        {
647                                                D3DXVECTOR4 vDif( g_Obj[obj].m_Mesh.m_pMaterials[i].Diffuse.r,
648                                                                                  g_Obj[obj].m_Mesh.m_pMaterials[i].Diffuse.g,
649                                                                                  g_Obj[obj].m_Mesh.m_pMaterials[i].Diffuse.b,
650                                                                                  g_Obj[obj].m_Mesh.m_pMaterials[i].Diffuse.a );
651                                                if( g_bUseTexture )
652                                                {
653                                                        V( g_pEffect->SetVector( "g_vMaterial", &vDif ) );
654                                                        if( g_Obj[obj].m_Mesh.m_pTextures[i] )
655                                                        {
656                                                                V( g_pEffect->SetTexture( "g_txDefaultTexture", g_Obj[obj].m_Mesh.m_pTextures[i] ) )
657                                                        }
658                                                        else
659                                                        {
660                                                                V( g_pEffect->SetTexture( "g_txDefaultTexture", g_pDefaultTexture ) )
661                                                        }
662                                                }
663                                                else
664                                                {
665                                                        V( g_pEffect->SetVector( "g_vMaterial", &D3DXVECTOR4(1,1,1,1) ) );
666                                                        V( g_pEffect->SetTexture( "g_txDefaultTexture", g_pDefaultTexture ) );
667                                                }
668                                                V( g_pEffect->CommitChanges() );
669                                                V( pMesh->DrawSubset( i ) );
670                                        }
671                                        V( g_pEffect->EndPass() );
672                                }
673                                V( g_pEffect->End() );
674                        }
675
676                        // Render light source
677                        if( !g_bRenderGUI && g_bRenderBaseTexture && !g_bRenderShadowMap && !g_bRenderFocusingMap && g_bCameraPerspective )
678                        {
679                                V( g_pEffect->SetTechnique( "RenderLight" ) );
680
681                                D3DXMATRIXA16 mWorldView = *g_LightCamera.GetWorldMatrix();
682                                D3DXMatrixMultiply( &mWorldView, &mWorldView, pmView );
683                                D3DXMatrixMultiply( &mWorldView, &mWorldView, pmProj );
684                                V( g_pEffect->SetMatrix( "WorldViewProj", &mWorldView ) );
685
686                                UINT cPass;
687                                LPD3DXMESH pMesh = g_LightMesh.GetMesh();
688                                V( g_pEffect->Begin( &cPass, 0 ) );
689                                for( UINT p = 0; p < cPass; ++p )
690                                {
691                                        V( g_pEffect->BeginPass( p ) );
692
693                                        for( DWORD i = 0; i < g_LightMesh.m_dwNumMaterials; ++i )
694                                        {                                     
695                                                V( g_pEffect->SetTexture( "g_txDefaultTexture", g_LightMesh.m_pTextures[i] ) );
696                                                V( g_pEffect->CommitChanges() );
697                                                V( pMesh->DrawSubset( i ) );
698                                        }
699                                        V( g_pEffect->EndPass() );
700                                }
701                                V( g_pEffect->End() );
702                        }
703                }
704
705                if( g_bRenderGUI && !g_bRenderShadowMap && !g_bRenderFocusingMap ){
706            // Render stats and help text
707            RenderText();
708
709                        // Render the UI elements
710            g_HUD.OnRender( fElapsedTime );
711                }
712        V( pd3dDevice->EndScene() );
713    }
714}
715
716//--------------------------------------------------------------------------------------
717// Computes the focusing matrix
718//--------------------------------------------------------------------------------------
719void ComputeFocusingMatrix( IDirect3DDevice9* g_pd3dDevice )
720{
721        float fMinU = 1.0f, fMinV = 1.0f;               // min must start from 1 to decrease
722        float fMaxU = -1.0f, fMaxV = -1.0f;             // max must start from -1 to increase
723
724        g_pd3dDevice->GetRenderTargetData( g_pFocusingMapColorSurface, g_pMemoryMappedTextureSurface );
725
726        // Calculate U and V, max and min values.
727        D3DLOCKED_RECT pmLRect;
728        g_pMemoryMappedTexture->LockRect(0, &pmLRect, NULL, D3DLOCK_DISCARD);
729        for ( long int i = 0; i < g_iFocusingMapSize * g_iFocusingMapSize ; i++)
730        {
731                fMinU = min( fMinU, ( (float*)pmLRect.pBits)[4 * i] );
732                fMaxU = max( fMaxU, ( (float*)pmLRect.pBits)[4 * i] );
733
734                fMinV = min( fMinV, ( (float*)pmLRect.pBits)[4 * i + 1] );
735                fMaxV = max( fMaxV, ( (float*)pmLRect.pBits)[4 * i + 1] );
736        }
737        g_pMemoryMappedTexture->UnlockRect(0);
738
739        g_mFocusingMatrix = D3DXMATRIXA16(  2.0f/( fMaxU - fMinU ),                             0.0f,                                                           0.0f,   0.0f,
740                                        0.0f,                                                           2.0f/( fMaxV - fMinV ),                         0.0f,   0.0f,
741                                        0.0f,                                                           0.0f,                                                           1.0f,   0.0f,
742                                                                                -(fMaxU+fMinU)/( fMaxU - fMinU ),   -(fMinV+fMaxV)/( fMaxV - fMinV ),   0.0f,   1.0f);
743}
744
745
746//--------------------------------------------------------------------------------------
747// This callback function will be called at the end of every frame to perform all the
748// rendering calls for the scene, and it will also be called if the window needs to be
749// repainted. After this function has returned, DXUT will call
750// IDirect3DDevice9::Present to display the contents of the next buffer in the swap chain
751//--------------------------------------------------------------------------------------
752void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
753{
754        // If the settings dialog is being shown, then
755    // render it instead of rendering the app's scene
756    if( g_SettingsDlg.IsActive() && g_bShowText && !g_bSaveFrame )
757    {
758        g_SettingsDlg.OnRender( fElapsedTime );
759        return;
760    }
761
762    HRESULT hr;
763
764        // Compute the view matrix for the light
765        D3DXMATRIXA16 mLightView = *g_LightCamera.GetViewMatrix();
766        D3DXVECTOR3 vLightEyePt = *g_LightCamera.GetEyePt();
767        float fLightDist = sqrt( vLightEyePt.x * vLightEyePt.x + vLightEyePt.y * vLightEyePt.y + vLightEyePt.z * vLightEyePt.z );
768
769        // The light is inside of the room
770        g_fLightFrontPlane = 0.1f;
771        g_fLightBackPlane  = 7.0f * g_fRoomRadius;
772        // 3.5 is the scale factor defined in room world matrix
773        if( 3.5f * g_fRoomRadius <= fLightDist ){
774                //  The light is outside of the room
775                g_fLightFrontPlane = fLightDist - 3.5f * g_fRoomRadius;
776                g_fLightBackPlane  = fLightDist + 3.5f * g_fRoomRadius;
777        }
778
779        D3DXMatrixPerspectiveFovLH( &g_mLightProj, D3DXToRadian(g_iLightFov), 1, g_fLightFrontPlane, g_fLightBackPlane );
780        const D3DXMATRIX *pmView = g_bCameraPerspective ? g_CamCamera.GetViewMatrix() : &mLightView;
781        const D3DXMATRIX *pmProj = g_bCameraPerspective ? g_CamCamera.GetProjMatrix() : &g_mLightProj;
782
783        // save original
784    LPDIRECT3DSURFACE9 pOldRT = NULL;
785    V( pd3dDevice->GetRenderTarget( 0, &pOldRT ) );
786        LPDIRECT3DSURFACE9 pOldDS = NULL;
787        V( SUCCEEDED( pd3dDevice->GetDepthStencilSurface( &pOldDS ) ) );
788
789       
790        V( g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW ) );
791
792        // Render: FOCUSING MAP  --------------------------------------------------------------------------------
793        if( g_bUseFocusing ){
794                pd3dDevice->SetRenderTarget( 0, g_pFocusingMapColorSurface );
795                pd3dDevice->SetDepthStencilSurface( g_pShadowMapZSurface );
796
797                g_bRenderFocusingMap = true;
798                RenderScene( pd3dDevice, fElapsedTime, g_CamCamera.GetViewMatrix(), g_CamCamera.GetProjMatrix() );
799                ComputeFocusingMatrix( pd3dDevice );
800                g_bRenderFocusingMap = false;
801
802                if( g_iShadowMethod != 2 ){  // The 2. method does not use Focusing
803                        D3DXMatrixMultiply( &g_mLightProj, &g_mLightProj, &g_mFocusingMatrix );
804                }
805        }
806        // Render: FOCUSING MAP  --------------------------------------------------------------------------------
807
808        g_mLightView = *g_LightCamera.GetViewMatrix();
809        if( g_iShadowMethod == 0 )
810        {
811                // Render: to blend - Base texture --------------------------------------------------------------------------------
812                pd3dDevice->SetRenderTarget( 0, g_pShadowWeightSurface );
813                pd3dDevice->SetDepthStencilSurface( g_pShadowWeightZSurface );
814                pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0L );
815               
816                g_bRenderBaseTexture = true;
817                RenderScene( pd3dDevice, fElapsedTime, pmView, pmProj );
818                g_bRenderBaseTexture = false;
819                // Render: to blend - Base texture --------------------------------------------------------------------------------
820
821
822                // Render: to blend - additional shadow --------------------------------------------------------------------------------
823                g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND,  D3DBLEND_ONE );
824                g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE );
825                g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
826                g_pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, false);
827               
828               
829                float partial = g_fLightSize / 2.0f;
830                float step = g_fLightSize / ( g_fLightSourceSamples * 2.0f );
831
832                for( float x = -partial + step; x < partial; x+=step )
833                {
834                        for( float y = -partial + step; y < partial; y+=step )
835                        {
836                                if( x * x + y * y < g_fLightSourceSamples * g_fLightSourceSamples )
837                                {
838                                        g_mLightView = *g_LightCamera.GetViewMatrix();
839                                        g_mLightView._41 += x;
840                                        g_mLightView._42 += y;
841
842                                        // Render: SHADOW MAP --------------------------------------------------------------------------------
843                                        pd3dDevice->SetRenderTarget( 0, g_pShadowMapColorSurface );
844                                        pd3dDevice->SetDepthStencilSurface( g_pShadowMapZSurface );
845                                        // Clear the render buffers
846                                        pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0L );
847
848                                        g_bRenderShadowMap = true;
849                                        float fTemp = 0.0f;// set depth bias
850                                        pd3dDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, *(DWORD*)&g_fBiasSlope);
851                                        RenderScene( pd3dDevice, fElapsedTime, &mLightView, &g_mLightProj );
852                                        pd3dDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, *(DWORD*)&fTemp);
853                                        g_bRenderShadowMap = false;
854                                        // Render: SHADOW MAP --------------------------------------------------------------------------------
855
856                                        pd3dDevice->SetRenderTarget( 0, g_pShadowWeightSurface );
857                                        pd3dDevice->SetDepthStencilSurface( g_pShadowWeightZSurface );
858                                        RenderScene( pd3dDevice, fElapsedTime, pmView, pmProj );
859                                }
860                        }
861                }
862               
863                g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
864                // Render: to blend - additional shadow --------------------------------------------------------------------------------
865               
866                // Render: GUI --------------------------------------------------------------------------------
867                g_bRenderGUI = true;
868                RenderScene( pd3dDevice, fElapsedTime, &mLightView, &g_mLightProj );
869                g_bRenderGUI = false;
870                // Render: GUI --------------------------------------------------------------------------------
871
872                // save frame
873                if( g_bSaveFrame ){
874               
875                        TCHAR sz[50];
876                        sz[49] = 0;
877                        StringCchPrintf( sz, 50, L"images/ShadowWeightOrig_blend.png",   g_iPictureNumber++ );
878                        D3DXSaveSurfaceToFile( sz, D3DXIFF_PNG, g_pShadowWeightSurface, NULL,NULL);
879                }
880                // Render: to blend --------------------------------------------------------------------------------
881
882                // Render: to screen - render a full screene quad --------------------------------------------------------------------------------
883                if( pOldDS )
884                {
885                        pd3dDevice->SetDepthStencilSurface( pOldDS );
886                        pOldDS->Release();
887                }
888                pd3dDevice->SetRenderTarget( 0, pOldRT );
889                pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0L );
890
891                UINT cPass;
892                if( SUCCEEDED( pd3dDevice->BeginScene() ) )
893                {       
894                        V( g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE ) );
895                       
896                        V( g_pEffect->SetTechnique( "RenderMapScreen" ) );
897                        V( g_pEffect->Begin( &cPass, 0 ) );
898                        V( g_pEffect->BeginPass( 0 ) );
899
900                        V( g_pEffect->CommitChanges() );
901                       
902                        V( g_pd3dDevice->SetVertexDeclaration( g_pFullScreenQuadVertexDeclaration ) );
903                        V( g_pd3dDevice->SetStreamSource( 0, g_pFullScreenQuadVertexBuffer, 0, sizeof(FullScreenQuadVertexStruct) ) );
904                        V( g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 2 ) );
905
906                        V( g_pEffect->EndPass() );
907                        V( g_pEffect->End() );
908
909                        V( pd3dDevice->EndScene() );
910                }
911                // Render: to screen --------------------------------------------------------------------------------
912        }
913        else
914        {
915                // Render: SHADOW MAP --------------------------------------------------------------------------------
916                pd3dDevice->SetRenderTarget( 0, g_pShadowMapColorSurface );
917                pd3dDevice->SetDepthStencilSurface( g_pShadowMapZSurface );
918                // Clear the render buffers
919                pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0L );
920
921                g_bRenderShadowMap = true;
922                float fTemp = 0.0f;// set depth bias
923                pd3dDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, *(DWORD*)&g_fBiasSlope);
924                RenderScene( pd3dDevice, fElapsedTime, &mLightView, &g_mLightProj );
925                pd3dDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, *(DWORD*)&fTemp);
926                g_bRenderShadowMap = false;
927                // Render: SHADOW MAP --------------------------------------------------------------------------------
928
929                if( pOldDS )
930                {
931                        pd3dDevice->SetDepthStencilSurface( pOldDS );
932                        pOldDS->Release();
933                }
934                pd3dDevice->SetRenderTarget( 0, pOldRT );
935                pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0L );
936
937                // Render: to screen --------------------------------------------------------------------------------
938                const D3DXMATRIX *pmView = g_bCameraPerspective ? g_CamCamera.GetViewMatrix() : &mLightView;
939                const D3DXMATRIX *pmProj = g_bCameraPerspective ? g_CamCamera.GetProjMatrix() : &g_mLightProj;
940               
941                RenderScene( pd3dDevice, fElapsedTime, pmView, pmProj );
942                g_bRenderGUI = true;
943                RenderScene( pd3dDevice, fElapsedTime, pmView, pmProj );
944                g_bRenderGUI = false;
945                // Render: to screen --------------------------------------------------------------------------------
946        }
947        SAFE_RELEASE( pOldRT );
948        g_bSaveFrame = false;
949}
950
951
952//--------------------------------------------------------------------------------------
953// Render the help and statistics text. This function uses the ID3DXFont interface for
954// efficient text rendering.
955//--------------------------------------------------------------------------------------
956void RenderText()
957{
958    // The helper object simply helps keep track of text position, and color
959    // and then it calls pFont->DrawText( m_pSprite, strMsg, -1, &rc, DT_NOCLIP, m_clr );
960    // If NULL is passed in as the sprite object, then it will work however the
961    // pFont->DrawText() will not be batched together.  Batching calls will improves performance.
962    CDXUTTextHelper txtHelper( g_pFont, g_pTextSprite, 15 );
963
964    // Output statistics
965    txtHelper.Begin();
966    txtHelper.SetInsertionPos( 5, 5 );
967   
968    // Draw help
969    if( g_bShowText && !g_bSaveFrame )
970    {
971                if( g_bUseTexture )
972                {
973                        txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ) );
974                } else
975                {
976                        txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 0.0f, 0.0f, 1.0f ) );
977                }
978                txtHelper.DrawTextLine( DXUTGetFrameStats(true) );
979                txtHelper.DrawTextLine( DXUTGetDeviceStats() );
980
981
982
983        const D3DSURFACE_DESC* pd3dsdBackBuffer = DXUTGetBackBufferSurfaceDesc();
984        txtHelper.SetInsertionPos( 10, pd3dsdBackBuffer->Height-15*8 );
985        txtHelper.DrawTextLine( L"Controls:" );
986
987        txtHelper.SetInsertionPos( 15, pd3dsdBackBuffer->Height-15*7 );
988        txtHelper.DrawFormattedTextLine(
989            L"Rotate camera\n"
990                        L"Move camera\n"
991            L"Rotate light\n"
992                        L"Move light\n"
993                        L"Modify shadow generation method\n"
994                        L"Save picture\n"
995            L"Quit" );
996        txtHelper.SetInsertionPos( 265, pd3dsdBackBuffer->Height-15*7 );
997        txtHelper.DrawTextLine(
998            L"Left drag mouse\n"
999                        L"W,S,A,D,Q,E\n"
1000            L"Right drag mouse\n"
1001                        L"W,S,A,D,Q,E while holding right mouse\n"
1002                        L"Forward:M, backward:N, directly:combo box\n"
1003                        L"Z\n"
1004            L"ESC" );
1005
1006               
1007                WCHAR sz0[50], sz1[50], sz2[50], sz3[50], sz4[50], sz5[50], sz6[50], sz7[50], sz8[50], sz9[50], sz10[50];
1008
1009                StringCchPrintf( sz0, 50, L"%i",   g_iFov );
1010                StringCchPrintf( sz1, 50, L"%i",   g_iLightFov );
1011                StringCchPrintf( sz2, 50, L"%.2f", g_fLightSize );
1012                StringCchPrintf( sz3, 50, L"%.2f", g_fIntensity );
1013                StringCchPrintf( sz4, 50, L"%.2f", g_fShadowBias );
1014                StringCchPrintf( sz5, 50, L"%.2f", g_fBiasSlope );
1015                StringCchPrintf( sz6, 50, L"%i",   g_iKernelSize );
1016                StringCchPrintf( sz7, 50, L"%i",   g_iShadowMapSize );
1017                StringCchPrintf( sz8, 50, L"%i",   g_iFocusingMapSize );
1018                StringCchPrintf( sz9, 50, L"%i",   (int)( g_fLightSourceSamples * g_fLightSourceSamples ) );
1019                StringCchPrintf( sz10,50, L"%i",   (int)( 1.0f / g_fRealSamples ) );
1020
1021                switch( g_iShadowMethod ){
1022
1023                        case 0:
1024                        {
1025                                txtHelper.SetInsertionPos( pd3dsdBackBuffer->Width - 310, 90 );
1026
1027                                txtHelper.DrawTextLine( L"" );
1028                                txtHelper.DrawTextLine( L"RealFov" );
1029                                txtHelper.DrawTextLine( L"LightSize" );
1030                                txtHelper.DrawTextLine( L"Intensity" );
1031                                txtHelper.DrawTextLine( L"g_fShadowBias" );
1032                                txtHelper.DrawTextLine( L"g_fBiasSlope" );
1033                                txtHelper.DrawTextLine( L"" );     
1034                                txtHelper.DrawTextLine( L"ShadowMapSize" );
1035                                txtHelper.DrawTextLine( L"FocusingMapSize" );
1036                                txtHelper.DrawTextLine( L"LightSSamp" );
1037                                txtHelper.DrawTextLine( L"LightSRealSamp" );
1038               
1039                                txtHelper.SetInsertionPos( pd3dsdBackBuffer->Width - 210, 90 );
1040
1041                                txtHelper.DrawTextLine( L"" );
1042                                txtHelper.DrawTextLine( sz1 );
1043                                txtHelper.DrawTextLine( sz2 );
1044                                txtHelper.DrawTextLine( sz3 );
1045                                txtHelper.DrawTextLine( sz4 );
1046                                txtHelper.DrawTextLine( sz5 );
1047                                txtHelper.DrawTextLine( L"" );
1048                                txtHelper.DrawTextLine( sz7 );
1049                                txtHelper.DrawTextLine( sz8 );
1050                                txtHelper.DrawTextLine( sz9 );
1051                                txtHelper.DrawTextLine( sz10 );
1052
1053                                break;
1054                        }
1055
1056                        case 1:
1057                        {
1058                                txtHelper.SetInsertionPos( pd3dsdBackBuffer->Width - 310, 90 );
1059
1060                                txtHelper.DrawTextLine( L"" );
1061                                txtHelper.DrawTextLine( L"RealFov" );
1062                                txtHelper.DrawTextLine( L"g_fLightSize" );
1063                                txtHelper.DrawTextLine( L"sceneScale" );
1064                                txtHelper.DrawTextLine( L"g_fShadowBias" );
1065                                txtHelper.DrawTextLine( L"g_fBiasSlope" );
1066                                txtHelper.DrawTextLine( L"g_iKernelSize" );     
1067                                txtHelper.DrawTextLine( L"ShadowMapSize" );
1068                                txtHelper.DrawTextLine( L"FocusingMapSize" );
1069
1070                                txtHelper.SetInsertionPos( pd3dsdBackBuffer->Width - 210, 90 );
1071
1072                                txtHelper.DrawTextLine( L"" );
1073                                txtHelper.DrawTextLine( sz1 );
1074                                txtHelper.DrawTextLine( sz2 );
1075                                txtHelper.DrawTextLine( sz3 );
1076                                txtHelper.DrawTextLine( sz4 );
1077                                txtHelper.DrawTextLine( sz5 );
1078                                txtHelper.DrawTextLine( sz6 );
1079                                txtHelper.DrawTextLine( sz7 );
1080                                txtHelper.DrawTextLine( sz8 );
1081
1082                                break;
1083                        }
1084
1085                        case 2:
1086                        {
1087                                txtHelper.SetInsertionPos( pd3dsdBackBuffer->Width - 310, 90 );
1088
1089                                txtHelper.DrawTextLine( L"g_iFov" );
1090                                txtHelper.DrawTextLine( L"RealFov" );
1091                                txtHelper.DrawTextLine( L"g_fLightSize" );
1092                                txtHelper.DrawTextLine( L"g_fIntensity" );
1093                                txtHelper.DrawTextLine( L"g_fShadowBias" );
1094                                txtHelper.DrawTextLine( L"AddToRR2" );
1095                                txtHelper.DrawTextLine( L"g_iKernelSize" );     
1096                                txtHelper.DrawTextLine( L"ShadowMapSize" );
1097                                txtHelper.DrawTextLine( L"FocusingMapSize" );
1098
1099                                txtHelper.SetInsertionPos( pd3dsdBackBuffer->Width - 210, 90 );
1100
1101                                txtHelper.DrawTextLine( sz0 );
1102                                txtHelper.DrawTextLine( sz1 );
1103                                txtHelper.DrawTextLine( sz2 );
1104                                txtHelper.DrawTextLine( sz3 );
1105                                txtHelper.DrawTextLine( sz4 );
1106                                txtHelper.DrawTextLine( sz5 );
1107                                txtHelper.DrawTextLine( sz6 );
1108                                txtHelper.DrawTextLine( sz7 );
1109                                txtHelper.DrawTextLine( sz8 );
1110
1111                                break;
1112                        }
1113                }
1114    }
1115    else
1116    {
1117        txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ) );
1118//        txtHelper.DrawTextLine( L"Press F1 for GUI" );
1119    }
1120    txtHelper.End();
1121}
1122
1123
1124
1125//--------------------------------------------------------------------------------------
1126// Updates the values of parameter from the slider's value.
1127//--------------------------------------------------------------------------------------
1128void UpdateParamFromSlider()
1129{
1130        int iSelectedSliderID = g_iSelectedMenuItem + 100;
1131        int iSelectedValue = g_HUD.GetSlider( iSelectedSliderID )->GetValue();
1132
1133        switch (g_iSelectedMenuItem)
1134        {
1135                case 0: g_iFov            = iSelectedValue;                     break;
1136                case 1: g_iLightFov       = iSelectedValue;                     break;
1137                case 2:
1138                       
1139                        if( g_iShadowMethod == 1 )
1140                                g_fLightSize  = (float)iSelectedValue / 10000.0f;
1141                        else
1142                                g_fLightSize  = (float)iSelectedValue / 100.0f;
1143                        break;
1144                case 3:
1145                        if( g_iShadowMethod == 1 )
1146                                g_fIntensity  = (float)iSelectedValue / 2.0f;
1147                        else
1148                                g_fIntensity  = (float)iSelectedValue / 100.0f;
1149                        break;
1150                       
1151                        g_fIntensity  = (float)iSelectedValue / 100.0f;                 break;
1152                case 4:
1153                                g_fShadowBias = (float)iSelectedValue / 100.0f;         
1154                        break;
1155
1156                case 5: g_fBiasSlope  = (float)iSelectedValue / 100.0f;                 break;
1157                case 6: g_iKernelSize = iSelectedValue;                                                 break;
1158                case 7: g_iShadowMapSize   = (int)pow( 2.0f, iSelectedValue ); CreateTexture(); break;
1159                case 8: g_iFocusingMapSize = (int)pow( 2.0f, iSelectedValue ); CreateTexture(); break;
1160                case 9:
1161                        g_fLightSourceSamples = (float)(int)( (float)iSelectedValue / 50.0f );
1162
1163                        g_fRealSamples = 0;
1164                        for( float x = 0.5f / g_fLightSourceSamples; x < g_fLightSourceSamples; x++ )
1165                        {
1166                                for( float y = 0.5f / g_fLightSourceSamples; y < g_fLightSourceSamples; y++ )
1167                                {
1168                                        if( x * x + y * y < g_fLightSourceSamples * g_fLightSourceSamples )
1169                                        {
1170                                                g_fRealSamples++;
1171                                        }
1172                                }
1173                        }
1174                        g_fRealSamples = 1.0f / g_fRealSamples;
1175                        break;
1176        }
1177}
1178
1179
1180//--------------------------------------------------------------------------------------
1181// Modify the value of the slider
1182//--------------------------------------------------------------------------------------
1183void IncrementSlider( int increment )
1184{
1185        int iSelectedSliderID = g_iSelectedMenuItem + 100;
1186        int iSelectedValue = g_HUD.GetSlider( iSelectedSliderID )->GetValue();
1187
1188        iSelectedValue += increment;
1189
1190        if( iSelectedValue < g_iSliderMinValues[g_iSelectedMenuItem] )
1191                        iSelectedValue = g_iSliderMinValues[g_iSelectedMenuItem];
1192
1193        if( iSelectedValue > g_iSliderMaxValues[g_iSelectedMenuItem] )
1194                        iSelectedValue = g_iSliderMaxValues[g_iSelectedMenuItem];
1195
1196        g_HUD.GetSlider( iSelectedSliderID )->SetValue( iSelectedValue );
1197
1198        UpdateParamFromSlider();
1199}
1200
1201
1202//--------------------------------------------------------------------------------------
1203// Before handling window messages, DXUT passes incoming windows
1204// messages to the application through this callback function. If the application sets
1205// *pbNoFurtherProcessing to TRUE, then DXUT will not process this message.
1206//--------------------------------------------------------------------------------------
1207LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing, void* pUserContext )
1208{
1209    // Always allow dialog resource manager calls to handle global messages
1210    // so GUI state is updated correctly
1211    *pbNoFurtherProcessing = g_DialogResourceManager.MsgProc( hWnd, uMsg, wParam, lParam );
1212    if( *pbNoFurtherProcessing )
1213        return 0;
1214
1215    if( g_SettingsDlg.IsActive() )
1216    {
1217        g_SettingsDlg.MsgProc( hWnd, uMsg, wParam, lParam );
1218        return 0;
1219    }
1220
1221    *pbNoFurtherProcessing = g_HUD.MsgProc( hWnd, uMsg, wParam, lParam );
1222    if( *pbNoFurtherProcessing )
1223        return 0;
1224
1225    // Pass all windows messages to camera and dialogs so they can respond to user input
1226        if( WM_KEYDOWN != uMsg || g_bRightMouseDown )
1227        g_LightCamera.HandleMessages( hWnd, uMsg, wParam, lParam );
1228
1229    if( WM_KEYDOWN != uMsg || !g_bRightMouseDown )
1230    {
1231        if( g_bCameraPerspective )
1232            g_CamCamera.HandleMessages( hWnd, uMsg, wParam, lParam );
1233        else
1234            g_LightCamera.HandleMessages( hWnd, uMsg, wParam, lParam );
1235    }
1236    return 0;
1237}
1238
1239
1240//--------------------------------------------------------------------------------------
1241// As a convenience, DXUT inspects the incoming windows messages for
1242// keystroke messages and decodes the message parameters to pass relevant keyboard
1243// messages to the application.  The framework does not remove the underlying keystroke
1244// messages, which are still passed to the application's MsgProc callback.
1245//--------------------------------------------------------------------------------------
1246void CALLBACK KeyboardProc( UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext )
1247{
1248        if( bKeyDown )
1249    {
1250        switch( nChar )
1251        {
1252                        // Change the selected shadowing method.
1253                        case 'M':
1254                        {
1255                                bool modify = g_iShadowMethod == 1;
1256                               
1257                                g_iShadowMethod = ( g_iShadowMethod + 1 ) % g_iNumberOfMethods;
1258                               
1259                                g_pTechniquesListComboBox->SetSelectedByIndex( g_iShadowMethod );
1260
1261                                if( !modify && ( g_iShadowMethod == 1 ) ){
1262                                        g_fLightSize /= 100.0f;
1263                                        g_fIntensity *= 50.0f;
1264                                }
1265                                if( modify && !( g_iShadowMethod == 1 ) ){
1266                                        g_fLightSize *= 100.0f;
1267                                        g_fIntensity /= 50.0f;
1268                                }
1269                                break;
1270                        }
1271                        case 'N':
1272                        {
1273                                bool modify = g_iShadowMethod == 1;
1274                               
1275                                g_iShadowMethod = ( g_iShadowMethod - 1 );
1276                                if( g_iShadowMethod < 0 )
1277                                {
1278                                        g_iShadowMethod += g_iNumberOfMethods;
1279                                }
1280
1281                                g_pTechniquesListComboBox->SetSelectedByIndex( g_iShadowMethod );
1282                                if( !modify && ( g_iShadowMethod == 1 ) ){
1283                                        g_fLightSize /= 100.0f;
1284                                        g_fIntensity *= 50.0f;
1285                                }
1286                                if( modify && !( g_iShadowMethod == 1 ) ){
1287                                        g_fLightSize *= 100.0f;
1288                                        g_fIntensity /= 50.0f;
1289                                }
1290                                break;
1291                        }
1292                        case 'Z':
1293                        {
1294                                g_bSaveFrame = true;
1295                                break;
1296                        }
1297                }
1298        }
1299}
1300
1301//--------------------------------------------------------------------------------------
1302// Mouse handler
1303//--------------------------------------------------------------------------------------
1304void CALLBACK MouseProc( bool bLeftButtonDown, bool bRightButtonDown, bool bMiddleButtonDown, bool bSideButton1Down, bool bSideButton2Down, int nMouseWheelDelta, int xPos, int yPos, void* pUserContext )
1305{
1306    g_bRightMouseDown = bRightButtonDown;
1307}
1308
1309
1310//--------------------------------------------------------------------------------------
1311// Handles the GUI events
1312//--------------------------------------------------------------------------------------
1313void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext )
1314{
1315        if( nControlID >= HUNDRED && nControlID <= LAST_SLIDER )
1316        {
1317                g_iSelectedMenuItem = nControlID - HUNDRED;
1318                UpdateParamFromSlider();
1319        }
1320
1321
1322    switch( nControlID )
1323    {
1324        case IDC_TOGGLEFULLSCREEN: DXUTToggleFullScreen(); break;
1325        case IDC_TOGGLEREF:        DXUTToggleREF(); break;
1326        case IDC_CHANGEDEVICE:     g_SettingsDlg.SetActive( !g_SettingsDlg.IsActive() ); break;
1327        case IDC_CHECKBOX:
1328        {
1329            CDXUTCheckBox *pCheck = (CDXUTCheckBox *)pControl;
1330            g_bShowText = pCheck->GetChecked();
1331                        g_pTechniquesListComboBox->SetVisible( g_bShowText );
1332
1333                        const D3DSURFACE_DESC* pd3dsdBackBuffer = DXUTGetBackBufferSurfaceDesc();
1334                        if( !g_bShowText )
1335                        {
1336                                g_HUD.SetLocation( pd3dsdBackBuffer->Width-170, -500 );
1337                        } else
1338                        {
1339                                g_HUD.SetLocation( pd3dsdBackBuffer->Width-170, 0 );
1340                        }
1341            break;
1342        }
1343        case IDC_LIGHTPERSPECTIVE:
1344        {
1345            CDXUTCheckBox *pCheck = (CDXUTCheckBox *)pControl;
1346            g_bCameraPerspective = !pCheck->GetChecked();
1347            if( g_bCameraPerspective )
1348            {
1349                g_CamCamera.SetRotateButtons( true, false, false );
1350                g_LightCamera.SetRotateButtons( false, false, true );
1351            } else
1352            {
1353                g_CamCamera.SetRotateButtons( false, false, false );
1354                g_LightCamera.SetRotateButtons( true, false, true );
1355            }
1356
1357            break;
1358        }
1359
1360                case IDC_PAUSE_CHECKBOX:
1361                {
1362                        CDXUTCheckBox *pCheck = (CDXUTCheckBox *)pControl;
1363            g_bPause = pCheck->GetChecked();
1364                        break;
1365                }
1366
1367                case IDC_USE_TEXTURE_CHECKBOX:
1368                {
1369                        CDXUTCheckBox *pCheck = (CDXUTCheckBox *)pControl;
1370                        g_bUseTexture = pCheck->GetChecked();
1371                        break;
1372                }
1373
1374                case IDC_METHOD_COMBO_BOX:
1375                {
1376                        bool modify = g_iShadowMethod == 1;
1377
1378                        g_iShadowMethod = g_pTechniquesListComboBox->FindItem( g_pTechniquesListComboBox->GetSelectedItem()->strText );
1379                        if( !modify && ( g_iShadowMethod == 1 ) ){
1380                                        g_fLightSize /= 100.0f;
1381                                        g_fIntensity *= 50.0f;
1382                                }
1383                        if( modify && !( g_iShadowMethod == 1 ) ){
1384                                        g_fLightSize *= 100.0f;
1385                                        g_fIntensity /= 50.0f;
1386                        }
1387                        break;
1388                }
1389
1390                case IDC_USE_FOCUSING_CHECKBOX:
1391                {
1392                        CDXUTCheckBox *pCheck = (CDXUTCheckBox *)pControl;
1393            g_bUseFocusing = pCheck->GetChecked();
1394                        break;
1395                }
1396    }
1397}
1398
1399
1400//--------------------------------------------------------------------------------------
1401// This callback function will be called immediately after the Direct3D device has
1402// entered a lost state and before IDirect3DDevice9::Reset is called. Resources created
1403// in the OnResetDevice callback should be released here, which generally includes all
1404// D3DPOOL_DEFAULT resources. See the "Lost Devices" section of the documentation for
1405// information about lost devices.
1406//--------------------------------------------------------------------------------------
1407void CALLBACK OnLostDevice( void* pUserContext )
1408{
1409    g_DialogResourceManager.OnLostDevice();
1410    g_SettingsDlg.OnLostDevice();
1411    if( g_pFont )
1412        g_pFont->OnLostDevice();
1413    if( g_pFontSmall )
1414        g_pFontSmall->OnLostDevice();
1415    if( g_pEffect )
1416        g_pEffect->OnLostDevice();
1417    SAFE_RELEASE(g_pTextSprite);
1418
1419    SAFE_RELEASE( g_pShadowMapColorTexture );
1420        SAFE_RELEASE( g_pShadowMapColorSurface );
1421        SAFE_RELEASE( g_pShadowWeightTexture );
1422        SAFE_RELEASE( g_pShadowWeightSurface );
1423        SAFE_RELEASE( g_pShadowMapZTexture );
1424        SAFE_RELEASE( g_pShadowMapZSurface );
1425        SAFE_RELEASE( g_pShadowWeightZTexture );
1426        SAFE_RELEASE( g_pShadowWeightZSurface );
1427    SAFE_RELEASE( g_pFocusingMapColorTexture );
1428        SAFE_RELEASE( g_pFocusingMapColorSurface );
1429        SAFE_RELEASE( g_pDefaultTexture );
1430        SAFE_RELEASE( g_pMemoryMappedTexture );
1431        SAFE_RELEASE( g_pMemoryMappedTextureSurface );
1432
1433    for( int i = 0; i < NUM_OBJ; ++i )
1434        g_Obj[i].m_Mesh.InvalidateDeviceObjects();
1435    g_LightMesh.InvalidateDeviceObjects();
1436
1437        SAFE_RELEASE( g_pFullScreenQuadVertexDeclaration );
1438        SAFE_RELEASE( g_pFullScreenQuadVertexBuffer );
1439}
1440
1441
1442//--------------------------------------------------------------------------------------
1443// This callback function will be called immediately after the Direct3D device has
1444// been destroyed, which generally happens as a result of application termination or
1445// windowed/full screen toggles. Resources created in the OnCreateDevice callback
1446// should be released here, which generally includes all D3DPOOL_MANAGED resources.
1447//--------------------------------------------------------------------------------------
1448void CALLBACK OnDestroyDevice( void* pUserContext )
1449{
1450    g_DialogResourceManager.OnDestroyDevice();
1451    g_SettingsDlg.OnDestroyDevice();
1452    SAFE_RELEASE( g_pEffect );
1453    SAFE_RELEASE( g_pFont );
1454    SAFE_RELEASE( g_pFontSmall );
1455    SAFE_RELEASE( g_pVertDecl );
1456
1457    SAFE_RELEASE( g_pEffect );
1458
1459    for( int i = 0; i < NUM_OBJ; ++i )
1460        g_Obj[i].m_Mesh.Destroy();
1461    g_LightMesh.Destroy();
1462}
Note: See TracBrowser for help on using the repository browser.