source: GTP/trunk/App/Demos/Illum/RayTraceEffects/RayTraceEffects.cpp @ 2494

Revision 2494, 93.2 KB checked in by szirmay, 18 years ago (diff)
Line 
1SHADERBOL  KIVENNI A TEXTURA HASZNALATOT
2
3#include "dxstdafx.h"
4#include "resource.h"
5
6// Define X files path
7#define BUNNY   L"Media\\Objects\\bunny.x"
8#define COLUMN  L"Media\\Objects\\column.x"
9#define ROOM    L"Media\\Objects\\room.x"
10#define SKULL   L"Media\\Objects\\skull.x"
11#define SPHERE  L"Media\\Objects\\sphere.x"
12#define TEAPOT  L"Media\\Objects\\teapot.x"
13#define TIGER   L"Media\\Objects\\tiger.x"
14
15
16//#define D3D_DEBUG_INFO
17
18//#define DEBUG_VS                                                      // Uncomment this line to debug vertex shaders
19//#define DEBUG_PS                                                      // Uncomment this line to debug pixel shaders
20
21
22// Define texture sizes
23#define CUBEMAP_SIZE            512                             // size of CubeMaps
24#define ATLASMAP_SIZE           512                             // size of Atlases (Room, Columns)
25#define SHADOWMAP_SIZE          512                             // size of ShadowMap
26#define PHOTONMAP_MAX_SIZE      256                             // The max size of the PhotonMap
27#define SNIPPET_MAX_SIZE        5                               // The max size of the snippet
28
29#define STEP                            0.1f                    // The size of a movement between two step
30#define CENTEROBJECTRADIUS      2.0f                    // radius of the center object
31#define LIGHTRADIUS                     0.3f                    // radius of the light object
32
33//--------------------------------------------------------------------------------------
34// UI control IDs
35//--------------------------------------------------------------------------------------
36
37#define IDC_TOGGLEFULLSCREEN    1
38#define IDC_TOGGLEREF           2
39#define IDC_CHANGEDEVICE        3
40#define WINDOW_SIZE_X                   640                     // Size of the screen
41#define WINDOW_SIZE_Y                   640                     // Size of the screen
42
43// HUD IDs
44#define IDC_SHADOW_CHECK_BOX                            10
45#define IDC_CAUSTICS_CHECK_BOX                          11
46#define IDC_CENTEROBJ_CHECK_BOX                         12
47#define IDC_SNIPPET_SIZE_IS_CONSTANT_CHECK_BOX  13
48#define IDC_SHOW_PHOTON_MAP_CHECK_BOX           14
49
50
51#define IDC_CLASSIC_METHOD                                      20
52#define IDC_DISTANCE_IMPOSTOR_METHOD            21
53
54#define IDC_NUMBER_OF_ITERATION_SLIDER          30
55#define IDC_FRESNEL_FACTOR_SLIDER                       31
56#define IDC_REFRACTION_INDEX_SLIDER                     32
57#define IDC_SHADOW_INTENSITY_SLIDER                     33
58#define IDC_CAUSTICS_INTENSITY_SLIDER           34
59#define IDC_PHOTON_MAP_SIZE_SLIDER                      35
60#define IDC_SNIPPET_SIZE_SLIDER                         36
61
62#define IDC_RESET_PARAMETERS_BUTTON                     40
63
64// These constants will be used as arguments for the RenderScene(..., int, ..) function
65// They are used to switch between the different shaders
66enum {  RENDER_ROOM_COLOR_DISTANCE, RENDER_ROOM_UV, RENDER_ROOM_AND_COLUMNS_SCREEN, RENDER_PHOTON_UV_MAP, RENDER_PHOTON_HIT,
67                RENDER_REFRACT_OBJECT_SCREEN, RENDER_LIGHT_SCREEN, RENDER_UMBRA, RENDER_SHADOW, RENDER_FULLSCREENQUAD, RENDER_PHOTON_MAP_SCREEN };
68
69
70// The next two float array pairs define the Snippet's light intensity and its size.
71// These values (light intensity and size) depend on the PhotonMapSize.
72// The bigger PhotonMapSize defines bigger texture and that defines more photon.
73// The more photons need smaller intensity and size.
74                    // PhotonMapSize =       1      2      4      8      16     32     64     128    256
75// Tries to fill the same area with constant intensity.
76float g_fIntensityOfSnippet[9] = { 0.05f, 0.06f, 0.08f, 0.11f, 0.185f, 0.27f, 0.53f, 1.00f, 1.65f };
77float g_fSizeOfSnippet[9]      = { 0.05f, 0.10f, 0.14f, 0.17f, 0.25f,  0.32f, 0.64f, 1.28f, 2.56f };
78
79// Tries to fill the same area with texture's size independent Snippet's size.
80float g_fIntensityOfSnippetWithIndependentSnippetSize[9] =
81                                     { 0.05f, 0.05f, 0.05f, 0.065f, 0.13f, 0.27f, 0.53f, 1.00f, 1.65f };
82float g_fSizeOfSnippetWithIndependentSnippetSize[9] =
83                                     { 0.01f, 0.02f, 0.04f, 0.08f,  0.16f, 0.32f, 0.64f, 1.28f, 2.56f };
84
85
86
87//--------------------------------------------------------------------------------------
88// Structs
89//--------------------------------------------------------------------------------------
90// Vertex structure for a photon hit (called snippet)
91D3DVERTEXELEMENT9 g_aSnippetVertex[] =
92{
93    { 0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
94        { 0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 },
95        { 0, 28, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
96    D3DDECL_END()
97};
98
99// Vertex structure for the fullscreene quad
100D3DVERTEXELEMENT9 g_aFullScreneQuadVertex[] =
101{
102    { 0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
103        D3DDECL_END()
104};
105
106// Define a snippet
107struct SnippetVertexStruct
108{
109        float x, y, z;
110        float r, g, b, a;
111        float u, v;
112};
113
114struct FullScreenQuadVertexStruct
115{
116    FLOAT x, y, z, rhw; // The transformed position for the vertex.
117};
118
119#define D3DFVF_FULLSCREENQUADVERTEX (D3DFVF_XYZRHW)
120
121FullScreenQuadVertexStruct fullscreen[] =
122{
123    { -1.0f,  -1.0f,  0.5f, 1.0f, }, // x, y, z, rhw
124    {  1.0f,  -1.0f,  0.5f, 1.0f, },
125    {  1.0f,   1.0f,  0.5f, 1.0f, },
126    { -1.0f,  -1.0f,  0.5f, 1.0f, },
127    {  1.0f,   1.0f,  0.5f, 1.0f, },
128    { -1.0f,   1.0f,  0.5f, 1.0f, },
129};
130
131
132//--------------------------------------------------------------------------------------
133// Global variables
134//--------------------------------------------------------------------------------------
135IDirect3DDevice9*                        g_pd3dDevice = NULL;                                           // RenderDevice
136
137ID3DXFont*                                       g_pFont = NULL;                                                        // Font for drawing text
138ID3DXSprite*                             g_pTextSprite = NULL;                                          // Sprite for batching draw text calls
139ID3DXEffect*                             g_pEffect = NULL;                                                      // D3DX effect interface
140
141CModelViewerCamera                       g_Camera;                                                                      // A model viewing camera
142
143CDXUTDialog                                      g_HUD;                                                                         // Dialog for sample specific controls
144
145
146// Textures
147LPDIRECT3DTEXTURE9                       g_pPhotonUVTexture = NULL;                                     // Texture where the Photon map is rendered
148LPDIRECT3DTEXTURE9                       g_pPowerOfSnippetTexelTexture = NULL;          // Texture to contain the power of the snippet Texels
149LPDIRECT3DTEXTURE9                       g_pRoomModifyTexture = NULL;                           // Room's Texture, this has viewable black edges
150LPDIRECT3DTEXTURE9                       g_pRoomLastTexture = NULL;                                     // Room's Texture, this contains the original brdf,
151                                                                                                                                                // the Caustics Effect and the shadow
152LPDIRECT3DTEXTURE9                       g_pColumnModifyTexture[4];                                     // Columns Texture
153LPDIRECT3DTEXTURE9                       g_pColumnLastTexture[5];                                       // Columns Texture, the last one contains the original brdf
154LPDIRECT3DTEXTURE9                       g_pRoomTexture = NULL;                                         // Room's original Texture (brdf)
155LPDIRECT3DTEXTURE9                       g_pShadowMapTexture = NULL;                            // Shadow map's texture. This is used for shadow generation.
156
157// Surfaces for the textures
158LPDIRECT3DSURFACE9                       g_pColumnsModifySurface[4];                            // Columns Atlas
159LPDIRECT3DSURFACE9                       g_pColumnsLastSurface[5];                                      // Columns Atlas
160LPDIRECT3DSURFACE9                       g_pRoomLastSurface                     = NULL;                 // Room's Atlas
161LPDIRECT3DSURFACE9                       g_pRoomModifySurface           = NULL;                 // Room's Atlas
162LPDIRECT3DSURFACE9                       g_pRoomSurface                         = NULL;                 // Room's Atlas
163LPDIRECT3DSURFACE9                       g_pPhotonMapDepthStencilSurface = NULL;        // Used to render Photon map
164LPDIRECT3DSURFACE9                       g_pPhotonUVMapSurface          = NULL;                 // Photon map's UV surface
165LPDIRECT3DSURFACE9                       g_pShadowMapSurface            = NULL;                 // Shadow map's surface
166LPDIRECT3DSURFACE9                   g_pShadowMapDepthStencilSSurface = NULL;   // Shadow DS's Z surface
167
168LPDIRECT3DSURFACE9                       g_pRenderTargetSurfaceOld      = NULL;                 // Store the original Screen's surface
169LPDIRECT3DSURFACE9                       g_pDepthStencilSurfaceOld      = NULL;                 // Store the original Screen's DSS
170
171// Cube map textures
172IDirect3DCubeTexture9*       g_pRoomCubeMapColorDistTexture     = NULL;         // CubeMap for store: Color + Distance
173IDirect3DCubeTexture9*       g_pRoomCubeMapUVTexture    = NULL;                 // CubeMap for store: UV + ObjectID
174
175IDirect3DSurface9*           g_pRoomCubeMapDepthStencilSurface = NULL;  // Depth-stencil buffer for rendering to cube texture
176IDirect3DSurface9*           g_pDepthStencilSurface = NULL;                             // Depth-stencil buffer for Room Texture
177
178IDirect3DVertexDeclaration9* g_pSnippetVertexDeclaration = NULL;                // Vertex declaration for the snippet
179IDirect3DVertexDeclaration9* g_pFullScreenQuadVertexDeclaration = NULL; // Vertex declaration for the fullscreen quad           
180
181LPDIRECT3DVERTEXBUFFER9          g_pFullScreenQuadVertexBuffer = NULL;          // Contains vertex data for the fullscreen quad         
182LPDIRECT3DVERTEXBUFFER9          g_bSnippetVertexBuffer = NULL;                         // Contains vertex data for the snippets
183
184// Meshes
185ID3DXMesh*                                       g_pCenterObjectMesh = NULL;                            // Mesh for the center object
186ID3DXMesh*                                       g_pRoomMesh = NULL;                                            // Mesh representing room (wall, floor, ceiling)
187ID3DXMesh*                                       g_pColumnMesh = NULL;                                          // Mesh representing one Column
188ID3DXMesh*                                       g_pLightMesh = NULL;                                           // Mesh for the light object
189
190// Flags
191bool                                             g_bShowHelp = false;                                           // If true, it renders the UI control text
192bool                                             g_bInitialization = true;                                      // Initialization is in progress
193bool                                             g_bRunGenerateCaustics = false;                        // Rerender Caustics Effect
194bool                                             g_bShadowON = true;                                            // Calculate shadow yes/no.
195bool                                             g_bCausticsON = true;                                          // Calculate caustics yes/no.
196bool                                             g_bShowVariables = true;                                       // Show the values of the algorithm's variables
197bool                                             g_bShowVariablesUserSet = true;                        // The user sets to show the variables.
198bool                                             g_bRenderCenterObjectWithBrdfON = true;        // Render Center Objectum with normal texture or diffuse color.
199bool                                             g_bShowHUD = true;                                                     // Show HUD
200bool                                             g_bSaveTexture = false;                                        // Just for debug.
201bool                                             g_bSnippetSizeIsConstant = false;                      // The fSnippetSize is independent of the size of PhotonMap.
202                                                                                                                                                // Its size is constant in world space.
203bool                                             g_bShowPhotonMap = true;                                       // Show PhotonMap on screen
204
205// Matrices
206D3DXMATRIXA16                            g_mWorldCenterObject;                                          // World matrix of the Center Object (scaling & offset)
207D3DXMATRIXA16                            g_mWorldViewLight;                                                     // Light's worldview matrix
208D3DXMATRIXA16                            g_mProjLight;                                                          // Light's projection matrix
209D3DXMATRIXA16                            g_mTexScaleBiasMat;                                            // Special texture matrix for ShadowMapping
210D3DXMATRIXA16                            g_mLightViewTexBias;                                           // Light view matrix multiplied by g_mTexScaleBiasMat
211
212
213// Floats
214float                                            g_fFresnelFactor = 0.05f;                                      // The Fresnel factor
215float                                            g_fRefractionIndex = 0.9f;                                     // The Refraction index
216float                                            g_fShadowIntensity = 0.25f;                            // The intensity of the shadow
217float                                            g_fCausticsIntensity = 0.05f;                          // The intensity of a caustics snippet
218float                                            g_fCenterObjectSize = 1.0;                                     // The scale of the CenterObject
219float                                            g_fSnippetSize = 3.0f;                                         // The size of a snippet;
220float                                            g_dDepthBias = 0.0002f;                                        // Depth bias value
221float                                            g_dBiasSlope = 2.0f;                                           // Bias slope
222
223
224// Vectors
225D3DXVECTOR3                                      g_vLightPos;                                                           // Define the position of light
226D3DXVECTOR3                                      g_vLightPosLast;                                                       // Light position at the last Caustic Effect generation
227D3DXVECTOR3                                      g_vCenterObjectPosInitial;                                     // Define the offset of the center object in the X file
228D3DXVECTOR3                                      g_vCenterObjectPos;                                            // Define the offset of the center object
229D3DXVECTOR3                                      g_vCenterObjectPosLast;                                        // CenterObj position at the last Caustic Effect generation
230
231int                                                      g_iNumberOfIteration = 10;                                     // The number of the iteration of the algorithm.
232int                                                      g_iObjectID = -1;                                                      // The identifier of the object in the scene.
233                                                                                                                                                // Every object has its own ID.
234int                                                      g_iAlgorithmMethod = 1;                                        // Here you can switch between the classical and our distance impstor method.
235int                                                      g_iPhotonMapSize = 64;                                         // Size of the PhotonMap
236
237
238//--------------------------------------------------------------------------------------
239// Forward declarations
240//--------------------------------------------------------------------------------------
241bool    CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, bool bWindowed );
242void    CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps );
243
244// This function creates the vertex buffer for the snippets,
245// controls the compiler properties,
246// loads the effect file and the meshes and
247// sets up the matrices.
248HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc );
249
250// This function contains the texture generation.
251HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc );
252
253void    CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime );
254
255// This is the most important function. It is called at every frame. Steps:
256// - some initialization
257//              At the first call we make the initialization. This runs just once, when the program starts.
258// - update caustics if necessary
259//              Then it decides whether the caustics effect should be rerendered or not.
260//              Re-rendering the caustic effect is requested if there were some major changes (movements) in the scene.
261// - render to screen
262// The last task is to render the objects of the scene to the screen.
263void    CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime );
264
265LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing );
266
267// This function handles keyboard events (user inputs).
268void    CALLBACK KeyboardProc( UINT nChar, bool bKeyDown, bool bAltDown  );
269
270// The next two functions clear the variables from the memory.
271void    CALLBACK OnLostDevice();
272void    CALLBACK OnDestroyDevice();
273
274// This function displays the values of the algorithm's variables and the help text.
275void    RenderText();
276
277// It loads a mesh from the specified X file and - after determining its size and bounding box -
278// centers it on the screen.
279HRESULT LoadMesh( WCHAR* strFileName, ID3DXMesh** ppMesh, bool bComputeBoundingBox );
280
281// This function creates the cube maps.
282// The first cube map stores color and distance values, created from the CenterObject's position. (g_pRoomCubeMapColorDistTexture)
283// The second one is created from the same position. (g_pRoomCubeMapUVTexture)
284// It stores at every pixel the viewable object's ID and UV.
285void RenderScenePreProcessing();
286
287// This function generates the caustics effect.
288// At first it creates a photon map created from the light's position.
289// This map stores the viewable ObjectID and UV at every pixel.
290// This information is gathered from the second (g_pRoomCubeMapUVTexture) CubeMap.
291// The second step is to create the shadow map (g_pShadowMapTexture). This map contains depth values.
292// This map is generated from the light's position.
293// The last step is to blend caustics snippets and generate shadow into the room's and the columns's atlases at the right places.
294void GenerateCaustics();
295
296// This function contains the GPU calls.
297// It calculates and sets up the values of the variables which are needed for the actual technique.
298void RenderScene( D3DXMATRIXA16 *mWorld, D3DXMATRIXA16 *mProj, int method );
299
300// This function binds the texture to the GPU.
301void RenderSceneInitialization();
302
303// Functions to crate different type of textures.
304IDirect3DTexture9* CreateTexture( int size, D3DFORMAT Format );
305IDirect3DCubeTexture9* CreateCubeTexture( int size, D3DFORMAT Format );
306IDirect3DSurface9* CreateDepthStencilSurface( int size );
307
308// This function creates vertex buffer.
309void    CreateVertexBuffer();
310
311void    InitializeHUD();
312void    CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl );
313
314//--------------------------------------------------------------------------------------
315// Entry point to the program. Initializes everything and goes into a message processing
316// loop. Idle time is used to render the scene.
317//--------------------------------------------------------------------------------------
318INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
319{
320    // Set the callback functions. These functions allow the sample framework to notify
321    // the application about device changes, user input, and windows messages.  The
322    // callbacks are optional so you need only set callbacks for events you're interested
323    // in. However, if you don't handle the device reset/lost callbacks then the sample
324    // framework won't be able to reset your device since the application must first
325    // release all device resources before resetting.  Likewise, if you don't handle the
326    // device created/destroyed callbacks then the sample framework won't be able to
327    // recreate your device resources.
328    DXUTSetCallbackDeviceCreated( OnCreateDevice );
329    DXUTSetCallbackDeviceReset( OnResetDevice );
330    DXUTSetCallbackDeviceLost( OnLostDevice );
331    DXUTSetCallbackDeviceDestroyed( OnDestroyDevice );
332    DXUTSetCallbackMsgProc( MsgProc );
333    DXUTSetCallbackKeyboard( KeyboardProc );
334    DXUTSetCallbackFrameRender( OnFrameRender );
335    DXUTSetCallbackFrameMove( OnFrameMove );
336
337    // Show the cursor and clip it when in full screen
338    DXUTSetCursorSettings( true, true );
339
340       
341
342    // Initialize the sample framework and create the desired Win32 window and Direct3D
343    // device for the application. Calling each of these functions is optional, but they
344    // allow you to set several options which control the behavior of the framework.
345    DXUTInit( true, true, true ); // Parse the command line, handle the default hotkeys, and show msgboxes
346    DXUTCreateWindow( L"RayTraceEffects" );
347        DXUTCreateDevice( D3DADAPTER_DEFAULT, true, WINDOW_SIZE_X, WINDOW_SIZE_Y, IsDeviceAcceptable, ModifyDeviceSettings );
348
349    // Pass control to the sample framework for handling the message pump and
350    // dispatching render calls. The sample framework will call your FrameMove
351    // and FrameRender callback when there is idle time between handling window messages.
352    DXUTMainLoop();
353
354    // Perform any application-level cleanup here. Direct3D device resources are released within the
355    // appropriate callback functions and therefore don't require any cleanup code here.
356
357    return DXUTGetExitCode();
358}
359
360//--------------------------------------------------------------------------------------
361// Initialize the app
362//--------------------------------------------------------------------------------------
363void InitializeHUD()
364{
365    // Initialize dialog
366        int posX = 350;
367        int posY = 35;
368        int sliderWidth = 120;
369        int sliderHeight = 14;
370    g_HUD.SetCallback( OnGUIEvent );
371
372        g_HUD.AddSlider( IDC_NUMBER_OF_ITERATION_SLIDER, posX, posY += 16, sliderWidth, sliderHeight,     0,
373                20, g_iNumberOfIteration );
374       
375        g_HUD.AddSlider( IDC_FRESNEL_FACTOR_SLIDER,      posX, posY += 16, sliderWidth, sliderHeight,     0,
376                100, (int)(   g_fFresnelFactor * 100.0f ) );
377       
378        g_HUD.AddSlider( IDC_REFRACTION_INDEX_SLIDER,    posX, posY += 16, sliderWidth, sliderHeight,     0,
379                100, (int)( g_fRefractionIndex * 100.0f + 1 ) );
380       
381        g_HUD.AddSlider( IDC_SHADOW_INTENSITY_SLIDER,    posX, posY += 16, sliderWidth, sliderHeight,     0,
382                100, (int)( g_fShadowIntensity * 100.0f ) );
383       
384        g_HUD.AddSlider( IDC_CAUSTICS_INTENSITY_SLIDER,  posX, posY += 16, sliderWidth, sliderHeight, -4000,
385                500, (int)( log( g_fCausticsIntensity ) / log ( 1.2f ) * 100.0f ) );
386       
387        g_HUD.AddSlider( IDC_PHOTON_MAP_SIZE_SLIDER,     posX, posY += 16, sliderWidth, sliderHeight,     0,
388                (int)( log( (float)PHOTONMAP_MAX_SIZE ) / log( 2.0f ) ), (int)( log( (float)g_iPhotonMapSize ) / log( 2.0f ) ) );
389       
390        g_HUD.AddSlider( IDC_SNIPPET_SIZE_SLIDER,        posX, posY += 16, sliderWidth, sliderHeight,     0,
391                SNIPPET_MAX_SIZE * 100, (int)( g_fSnippetSize * 100.0f ) );
392
393        // --------------------------------------------------------------------------------------------
394
395        posX = 0;
396        posY = 35;
397
398        g_HUD.AddCheckBox( IDC_SHADOW_CHECK_BOX, L"Shadow ON/OFF",                                                      posX, posY += 20, 125, 16, g_bShadowON, 'S' );
399        g_HUD.AddCheckBox( IDC_CAUSTICS_CHECK_BOX, L"Caustics ON/OFF",                                          posX, posY += 20, 125, 16, g_bCausticsON, 'C' );
400        g_HUD.AddCheckBox( IDC_CENTEROBJ_CHECK_BOX, L"CenterObj ON/OFF",                                        posX, posY += 20, 125, 16, g_bRenderCenterObjectWithBrdfON, 'X' );
401        g_HUD.AddCheckBox( IDC_SNIPPET_SIZE_IS_CONSTANT_CHECK_BOX, L"Indep. Snippet size?", posX, posY += 20, 125, 16, g_bSnippetSizeIsConstant, 'V' );
402        g_HUD.AddCheckBox( IDC_SHOW_PHOTON_MAP_CHECK_BOX, L"Show Ph.Map ON/OFF",            posX, posY += 20, 125, 16, g_bShowPhotonMap, 'M' );
403       
404
405        g_HUD.AddRadioButton( IDC_CLASSIC_METHOD, 1, L"Classic method", posX, posY += 30, 125, 16, false );
406    g_HUD.AddRadioButton( IDC_DISTANCE_IMPOSTOR_METHOD, 1, L"Dist. imp. method", posX, posY += 20, 125, 16, true );
407
408        g_HUD.AddButton( IDC_RESET_PARAMETERS_BUTTON, L"Reset parameters", posX, posY += 30, 125, 16, 'Y' );
409}
410
411
412//--------------------------------------------------------------------------------------
413// Called during device initialization, this code checks the device for some
414// minimum set of capabilities, and rejects those that don't pass by returning false.
415//--------------------------------------------------------------------------------------
416bool CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat,
417                                  D3DFORMAT BackBufferFormat, bool bWindowed )
418{
419        // Skip backbuffer formats that don't support alpha blending
420    IDirect3D9* pD3D = DXUTGetD3DObject();
421    if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType,
422                    AdapterFormat, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING,
423                    D3DRTYPE_TEXTURE, BackBufferFormat ) ) )
424        return false;
425
426    // Must support cube textures
427    if( !( pCaps->TextureCaps & D3DPTEXTURECAPS_CUBEMAP ) )
428        return false;
429
430    // Must support pixel shader 3.0
431    if( pCaps->PixelShaderVersion < D3DPS_VERSION( 3, 0 ) )
432        return false;
433
434    // need to support D3DFMT_A32B32G32R32F render target
435    if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType,
436                    AdapterFormat, D3DUSAGE_RENDERTARGET,
437                    D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F ) ) )
438                return false;
439
440    return true;
441}       
442
443
444//--------------------------------------------------------------------------------------
445// This callback function is called immediately before a device is created to allow the
446// application to modify the device settings. The supplied pDeviceSettings parameter
447// contains the settings that the framework has selected for the new device, and the
448// application can make any desired changes directly to this structure.  Note however that
449// the sample framework will not correct invalid device settings so care must be taken
450// to return valid device settings, otherwise IDirect3D9::CreateDevice() will fail. 
451//--------------------------------------------------------------------------------------
452void CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps )
453{
454        // If device doesn't support HW T&L or doesn't support 1.1 vertex shaders in HW then switch to SWVP.
455    if( (pCaps->DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == 0 ||
456         pCaps->VertexShaderVersion < D3DVS_VERSION(1,1) )
457    {
458        pDeviceSettings->BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
459    }
460    else
461    {
462        pDeviceSettings->BehaviorFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
463    }
464
465    // This application is designed to work on a pure device by not using
466    // IDirect3D9::Get*() methods, so create a pure device if supported and using HWVP.
467    if ((pCaps->DevCaps & D3DDEVCAPS_PUREDEVICE) != 0 &&
468        (pDeviceSettings->BehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING) != 0 )
469        pDeviceSettings->BehaviorFlags |= D3DCREATE_PUREDEVICE;
470
471    // Debugging vertex shaders requires either REF or software vertex processing
472    // and debugging pixel shaders requires REF. 
473#ifdef DEBUG_VS
474    if( pDeviceSettings->DeviceType != D3DDEVTYPE_REF )
475    {
476        pDeviceSettings->BehaviorFlags &= ~D3DCREATE_HARDWARE_VERTEXPROCESSING;
477        pDeviceSettings->BehaviorFlags &= ~D3DCREATE_PUREDEVICE;
478        pDeviceSettings->BehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
479    }
480#endif
481#ifdef DEBUG_PS
482    pDeviceSettings->DeviceType = D3DDEVTYPE_REF;
483#endif
484}
485
486
487
488// Creates VertexBuffer
489void CreateVertexBuffer()
490{
491        HRESULT hr;
492
493        SAFE_RELEASE( g_bSnippetVertexBuffer );
494
495        V( g_pd3dDevice->CreateVertexBuffer( (sizeof(float) * 54 * g_iPhotonMapSize * g_iPhotonMapSize ),
496                D3DUSAGE_WRITEONLY, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX0 | D3DFVF_TEXCOORDSIZE2( 2 ),
497                D3DPOOL_DEFAULT, &g_bSnippetVertexBuffer, NULL ) );
498
499    void* pData;
500        V ( g_bSnippetVertexBuffer->Lock( 0, 0, &pData, 0 ) );
501        float* pVertexBuffer = (float*)pData;
502        for ( int i = 0; i < g_iPhotonMapSize; i++ )
503        {
504                for ( int j = 0; j < g_iPhotonMapSize; j++ )
505                {
506                        // Determines the exponent of the PhotonMap size.
507                        // It is used as an index to look up from g_fSizeOfSnippet array.
508                        int iPhotonMapSizeExponent = (int)(log( (float)g_iPhotonMapSize ) / log ( 2.0f ) + 0.5f );      // 0..8
509
510                        // By default the fSnippetSize is not constant in world space
511                        float fSnippetSize = g_fSizeOfSnippet[ iPhotonMapSizeExponent ] * g_fSnippetSize / g_iPhotonMapSize;
512                        // Decides wether the Snippet size is constant in world space or not.
513                        if ( g_bSnippetSizeIsConstant )
514                                // If constant
515                                fSnippetSize = g_fSizeOfSnippetWithIndependentSnippetSize[ iPhotonMapSizeExponent ] * g_fSnippetSize / g_iPhotonMapSize;
516
517                        float number = (float)( i * g_iPhotonMapSize + j );
518
519                        float u = (float) i / g_iPhotonMapSize;
520                        float v = (float) j / g_iPhotonMapSize;
521
522                        SnippetVertexStruct snippetVertices[] =
523                        {
524                                //            x,             y, z,        r, g,b,a,   u, v,
525                                { -fSnippetSize, -fSnippetSize, 0,   number, 0,1,0,   u, v },
526                                { -fSnippetSize,  fSnippetSize, 0,   number, 0,0,0,   u, v },
527                                {  fSnippetSize,  fSnippetSize, 0,   number, 1,0,0,   u, v },
528                                {  fSnippetSize,  fSnippetSize, 0,   number, 1,0,0,   u, v },
529                                {  fSnippetSize, -fSnippetSize, 0,   number, 1,1,0,   u, v },
530                                { -fSnippetSize, -fSnippetSize, 0,   number, 0,1,0,   u, v },
531                        };
532                       
533                        memcpy( pVertexBuffer, snippetVertices, sizeof( snippetVertices ) );
534                        pVertexBuffer += 54;
535                }
536        }
537        V (g_bSnippetVertexBuffer->Unlock() );
538
539        SAFE_RELEASE( g_pPhotonMapDepthStencilSurface );
540        SAFE_RELEASE( g_pPhotonUVTexture );
541        SAFE_RELEASE( g_pPhotonUVMapSurface );
542
543        g_pPhotonMapDepthStencilSurface = CreateDepthStencilSurface( g_iPhotonMapSize );
544        g_pPhotonUVTexture      = CreateTexture( g_iPhotonMapSize, D3DFMT_A32B32G32R32F );
545        V( g_pPhotonUVTexture->GetSurfaceLevel( 0, &g_pPhotonUVMapSurface ) );
546
547        // Sends the new texture parameters to the GPU.
548        RenderSceneInitialization();
549}
550
551
552D3DXMATRIXA16 ScaleAndOffset(float fScale, D3DXVECTOR3 vOffset)
553{
554        D3DXMATRIXA16 mScale, mOffset;
555        D3DXMatrixIdentity(&mScale);
556        D3DXMatrixIdentity(&mOffset);
557
558        D3DXMatrixTranslation( &mOffset, vOffset.x, vOffset.y, vOffset.z );
559        D3DXMatrixScaling( &mScale, fScale, fScale, fScale );
560
561        return mScale * mOffset;
562}
563
564//--------------------------------------------------------------------------------------
565// This callback function will be called immediately after the Direct3D device has been
566// created, which will happen during application initialization and windowed/full screen
567// toggles. This is the best location to create D3DPOOL_MANAGED resources since these
568// resources need to be reloaded whenever the device is destroyed. Resources created 
569// here should be released in the OnDestroyDevice callback.
570//--------------------------------------------------------------------------------------
571HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc )
572{
573    HRESULT hr;
574
575        // Make the device available as a global variable.
576        g_pd3dDevice = pd3dDevice;
577
578      // Initialize the font
579    V_RETURN( D3DXCreateFont( pd3dDevice, 15, 0, FW_BOLD, 1, FALSE, DEFAULT_CHARSET,
580                         OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE,
581                         L"Arial", &g_pFont ) );
582
583    // Define DEBUG_VS and/or DEBUG_PS to debug vertex and/or pixel shaders with the
584    // shader debugger. In this case shaders will be unoptimized and forced into software. 
585        DWORD dwShaderFlags = D3DXSHADER_PREFER_FLOW_CONTROL | D3DXSHADER_SKIPOPTIMIZATION;
586    #ifdef DEBUG_VS
587        dwShaderFlags |= D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT;
588    #endif
589    #ifdef DEBUG_PS
590        dwShaderFlags |= D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT;
591    #endif
592
593    // Read the D3DX effect file
594    WCHAR str[MAX_PATH];
595    V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"RayTraceEffects.fx" ) );
596
597        ID3DXBuffer* errBuff = NULL;
598        if (FAILED(D3DXCreateEffectFromFile( pd3dDevice, str, NULL, NULL, dwShaderFlags, NULL, &g_pEffect, &errBuff )))
599        {
600                const int BufSize = 500;
601                wchar_t wbuf[BufSize];
602                mbstowcs( wbuf, (const char*)errBuff->GetBufferPointer(), BufSize );
603                MessageBox(NULL, wbuf, L".fx compilation error", MB_ICONERROR);
604                exit(-1);
605        }
606
607       
608        // --- Initialize the matrices ---------------------------------------------------------------
609
610          // World transform to identity
611        D3DXMATRIXA16 mIdent;
612        D3DXMatrixIdentity( & mIdent );
613        V_RETURN( pd3dDevice->SetTransform( D3DTS_WORLD, &mIdent ) );
614
615      // Setup the camera's view parameters
616    D3DXVECTOR3 vEyePt( -4.0f, 5.0f, -11.0f );
617    D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
618    g_Camera.SetViewParams( &vEyePt, &vLookatPt );
619       
620          // Initialize the position of light
621        g_vLightPos = D3DXVECTOR3( 0.0f, 4.9f, -4.9f );
622
623                // For shadow mapping
624        // Set special texture matrix for shadow mapping
625    float fOffsetX = 0.5f + (0.5f / (float)SHADOWMAP_SIZE);
626    float fOffsetY = 0.5f + (0.5f / (float)SHADOWMAP_SIZE);
627    float range = 1;            //note different scale in DX9!
628    //float fBias    = -0.001f * range;
629    float fBias    = 0.0f;
630    g_mTexScaleBiasMat = D3DXMATRIXA16( 0.5f,     0.0f,     0.0f,  0.0f,
631                                        0.0f,    -0.5f,     0.0f,  0.0f,
632                                        0.0f,     0.0f,     range, 0.0f,
633                                    fOffsetX, fOffsetY,     fBias, 1.0f );
634
635
636        // The matrices must be initialized before mesh loading!
637        // --- Load objects     -----------------------------------------------------------------------------------
638         
639        // load default center object
640        if( FAILED( LoadMesh( SKULL, &g_pCenterObjectMesh, true ) ) ) return DXUTERR_MEDIANOTFOUND;
641       
642        // load room
643        if( FAILED( LoadMesh( ROOM, &g_pRoomMesh, false ) ) ) return DXUTERR_MEDIANOTFOUND;
644       
645        // load light object
646        if( FAILED( LoadMesh( SPHERE, &g_pLightMesh, false ) ) ) return DXUTERR_MEDIANOTFOUND;
647
648        // load light object
649        if( FAILED( LoadMesh( COLUMN, &g_pColumnMesh, false ) ) ) return DXUTERR_MEDIANOTFOUND;
650       
651        // --- Load objects ends ------------------------------------------------------------------------------
652
653
654        g_pRoomCubeMapColorDistTexture  = CreateCubeTexture( CUBEMAP_SIZE, D3DFMT_A16B16G16R16F );      // Because 32 can not use linear filtering.
655        g_pRoomCubeMapUVTexture                 = CreateCubeTexture( CUBEMAP_SIZE, D3DFMT_A16B16G16R16F );      // Because 32 can not use linear filtering.
656       
657        g_pShadowMapTexture  = CreateTexture( SHADOWMAP_SIZE, D3DFMT_A16B16G16R16F );                           // Because we use the alpha channel.   
658        g_pRoomTexture           = CreateTexture( ATLASMAP_SIZE,  D3DFMT_A16B16G16R16F );       
659        g_pRoomModifyTexture = CreateTexture( ATLASMAP_SIZE,  D3DFMT_A16B16G16R16F );                           // Because 32 can not use BLEND function.
660        g_pRoomLastTexture       = CreateTexture( ATLASMAP_SIZE,  D3DFMT_A16B16G16R16F );                               
661       
662
663        V( g_pShadowMapTexture->GetSurfaceLevel( 0, &g_pShadowMapSurface ) );
664        V( g_pRoomTexture->GetSurfaceLevel( 0, &g_pRoomSurface ) );
665        V( g_pRoomModifyTexture->GetSurfaceLevel( 0, &g_pRoomModifySurface ) );
666        V( g_pRoomLastTexture->GetSurfaceLevel( 0, &g_pRoomLastSurface ) );
667       
668       
669        V( D3DXLoadSurfaceFromFile( g_pRoomSurface, NULL, NULL, L"Media\\Maps\\RoomTextMap.png", NULL, D3DX_FILTER_NONE, 0xFFFFFFFF, NULL ));
670
671        // Creates ColumnsTextureArray and surfaces. Load the original map from file to the last one.
672        // The last one is used always as a source.
673        for( int i = 0; i < 4; i++ )
674        {
675                g_pColumnModifyTexture[i] = CreateTexture( ATLASMAP_SIZE, D3DFMT_A16B16G16R16F );                               // Because 32 can not use BLEND function.
676                V( g_pColumnModifyTexture[i]->GetSurfaceLevel( 0, &g_pColumnsModifySurface[i] ) );
677        }
678       
679        for( int i = 0; i < 5; i++ )
680        {
681                g_pColumnLastTexture[i] = CreateTexture( ATLASMAP_SIZE, D3DFMT_A16B16G16R16F );                         // Because 32 can not use BLEND function.
682                V( g_pColumnLastTexture[i]->GetSurfaceLevel( 0, &g_pColumnsLastSurface[i] ) );
683        }
684
685        D3DXLoadSurfaceFromFile( g_pColumnsLastSurface[4], NULL, NULL, L"Media\\Maps\\ColumnMap.png", NULL, D3DX_FILTER_NONE, 0xFFFFFFFF, NULL );
686
687
688        g_pShadowMapDepthStencilSSurface  = CreateDepthStencilSurface( SHADOWMAP_SIZE );
689        g_pDepthStencilSurface = CreateDepthStencilSurface( ATLASMAP_SIZE );
690        g_pRoomCubeMapDepthStencilSurface  = CreateDepthStencilSurface( CUBEMAP_SIZE );
691
692        // Creates Snippet Texture, and loads from file
693        D3DXCreateTextureFromFile( pd3dDevice, L"Media\\Maps\\PowerOfSnippetTexel.dds", &g_pPowerOfSnippetTexelTexture);
694
695        RenderSceneInitialization();
696
697        return S_OK;
698}
699
700
701//--------------------------------------------------------------------------------------
702// LoadMesh from file
703//--------------------------------------------------------------------------------------
704HRESULT LoadMesh( WCHAR* strFileName, ID3DXMesh** ppMesh, bool bComputeBoundingBox )
705{
706    ID3DXMesh* pMesh = NULL;
707    WCHAR str[MAX_PATH];
708        D3DXVECTOR3 minPos, maxPos;
709    HRESULT hr;
710
711    // Load the mesh with D3DX and get back a ID3DXMesh*.  For this
712    // sample we'll ignore the X file's embedded materials since we know
713    // exactly the model we're loading.  See the mesh samples such as
714    // "OptimizedMesh" for a more generic mesh loading example.
715    V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, strFileName ) );
716    V_RETURN( D3DXLoadMeshFromX(str, D3DXMESH_MANAGED, g_pd3dDevice, NULL, NULL, NULL, NULL, &pMesh) );
717
718        if ( bComputeBoundingBox )
719        {
720                // Lock the vertex buffer, to generate a simple bounding box
721                IDirect3DVertexBuffer9* pMeshVB = NULL;
722                void* pVertices;
723                hr = pMesh->GetVertexBuffer( &pMeshVB );
724                if( SUCCEEDED( hr ) )
725                {
726                        hr = pMeshVB->Lock( 0, 0, &pVertices, D3DLOCK_NOSYSLOCK );
727                        if( SUCCEEDED(hr) )
728                        {
729                                D3DXComputeBoundingBox( ( D3DXVECTOR3*)pVertices, pMesh->GetNumVertices(),
730                                                                                D3DXGetFVFVertexSize( pMesh->GetFVF() ),
731                                                                                &minPos, &maxPos );
732                                pMeshVB->Unlock();
733                        }
734                        pMeshVB->Release();
735       
736                        // If an Object was previously loaded, it removes its offset from WorldCenterObject matrix.
737                        g_vCenterObjectPos += g_vCenterObjectPosInitial * g_fCenterObjectSize;
738
739                        // mesh: center-size .. center+size
740            g_vCenterObjectPosInitial = ( minPos + maxPos ) / 2.0f;
741
742                        // The size of the Center Object
743                        D3DXVECTOR3 vCenterObjectSize    = ( maxPos - minPos ) / 2.0f;
744                       
745                        // The diameter of the center object
746                        float fCenterObjectDiameter = sqrt(     vCenterObjectSize.x * vCenterObjectSize.x +
747                                                                                                vCenterObjectSize.y * vCenterObjectSize.y +
748                                                                                                vCenterObjectSize.z * vCenterObjectSize.z ) / 1.732f;
749
750                        // Center Object size
751                        g_fCenterObjectSize = (float)CENTEROBJECTRADIUS / fCenterObjectDiameter;
752
753                        // Eliminate the offset defined by the X file
754                        //g_vCenterObjectPos = D3DXVECTOR3(0,0,0);
755                        g_vCenterObjectPos -= g_vCenterObjectPosInitial * g_fCenterObjectSize;
756
757                        // Center Object scale
758                        g_mWorldCenterObject = ScaleAndOffset(g_fCenterObjectSize, g_vCenterObjectPos); 
759                        }
760        }
761 
762    DWORD *rgdwAdjacency = NULL;
763
764    // Make sure there are normals which are required for lighting
765    if( !(pMesh->GetFVF() & D3DFVF_NORMAL) )
766    {
767        ID3DXMesh* pTempMesh;
768        V( pMesh->CloneMeshFVF( pMesh->GetOptions(),
769                                  pMesh->GetFVF() | D3DFVF_NORMAL,
770                                  g_pd3dDevice, &pTempMesh ) );
771        V( D3DXComputeNormals( pTempMesh, NULL ) );
772
773        SAFE_RELEASE( pMesh );
774        pMesh = pTempMesh;
775    }
776
777    // Optimize the mesh for this graphics card's vertex cache
778    // so when rendering the mesh's triangle list the vertices will
779    // cache hit more often so it won't have to re-execute the vertex shader
780    // on those vertices so it will improve perf.     
781    rgdwAdjacency = new DWORD[pMesh->GetNumFaces() * 3];
782    if( rgdwAdjacency == NULL )
783        return E_OUTOFMEMORY;
784    V( pMesh->ConvertPointRepsToAdjacency(NULL, rgdwAdjacency) );
785    V( pMesh->OptimizeInplace(D3DXMESHOPT_VERTEXCACHE, rgdwAdjacency, NULL, NULL, NULL) );
786    delete []rgdwAdjacency;
787
788    *ppMesh = pMesh;
789
790    return S_OK;
791}
792
793//--------------------------------------------------------------------------------------
794// Util function.
795// Creates an empty texture. These textures will be used as render targets, therefore
796// the Usage flag is set to D3DUSAGE_RENDERTARGET and consequently, the assigned
797// memory pool is D3DPOOL_DEFAULT.
798// Params: size and format (eg. D3DFMT_A32B32G32R32F) of the new texture.
799//--------------------------------------------------------------------------------------
800IDirect3DTexture9* CreateTexture( int size, D3DFORMAT Format )
801{
802        HRESULT hr;
803        IDirect3DTexture9* pTexture;
804        V( g_pd3dDevice->CreateTexture( size, size, 1, D3DUSAGE_RENDERTARGET,
805                                                                        Format, D3DPOOL_DEFAULT, &pTexture, NULL ) );
806        return pTexture;
807}
808
809//--------------------------------------------------------------------------------------
810// Util function.
811// Creates an empty cubemap texture of the given resolution and format.
812//--------------------------------------------------------------------------------------
813
814IDirect3DCubeTexture9* CreateCubeTexture( int size, D3DFORMAT Format )
815{
816        HRESULT hr;
817        IDirect3DCubeTexture9* pCubeTexture;
818        V( g_pd3dDevice->CreateCubeTexture(     size, 1, D3DUSAGE_RENDERTARGET,
819                                                                                Format, D3DPOOL_DEFAULT, &pCubeTexture, NULL ) );
820        return pCubeTexture;
821}
822
823//--------------------------------------------------------------------------------------
824// Util function.
825// Creates a Depth stencil surface (DSS) of the given size.
826//--------------------------------------------------------------------------------------
827IDirect3DSurface9* CreateDepthStencilSurface( int size )
828{
829        HRESULT hr;
830        IDirect3DSurface9* pDSSurface;
831        V( g_pd3dDevice->CreateDepthStencilSurface(   size, size,
832                                                                                                DXUTGetDeviceSettings().pp.AutoDepthStencilFormat,
833                                                D3DMULTISAMPLE_NONE, 0, TRUE, &pDSSurface, NULL ) );
834        return pDSSurface;
835}
836
837
838//--------------------------------------------------------------------------------------
839// This callback function will be called immediately after the Direct3D device has been
840// reset, which will happen after a lost device scenario. This is the best location to
841// create D3DPOOL_DEFAULT resources since these resources need to be reloaded whenever
842// the device is lost. Resources created here should be released in the OnLostDevice
843// callback.
844//--------------------------------------------------------------------------------------
845HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice,
846                                const D3DSURFACE_DESC* pBackBufferSurfaceDesc )
847{
848    HRESULT hr;
849        g_pd3dDevice = pd3dDevice;
850
851    if( g_pFont )
852        V_RETURN( g_pFont->OnResetDevice() );
853    if( g_pEffect )
854        V_RETURN( g_pEffect->OnResetDevice() );
855
856    // Create a sprite to help batch calls when drawing many lines of text
857    V_RETURN( D3DXCreateSprite( pd3dDevice, &g_pTextSprite ) );
858
859
860        // --- Vertex declarations ------------------------------------------------------------------
861       
862    // Create vertex declaration for the snippets
863        V_RETURN( pd3dDevice->CreateVertexDeclaration( g_aSnippetVertex, &g_pSnippetVertexDeclaration ) );
864        CreateVertexBuffer();
865
866        // Create vertex declaration for the fullscreen quad
867        V( pd3dDevice->CreateVertexDeclaration( g_aFullScreneQuadVertex, &g_pFullScreenQuadVertexDeclaration ) );
868        V_RETURN( pd3dDevice->CreateVertexBuffer( 6 * sizeof( FullScreenQuadVertexStruct ),
869                D3DUSAGE_WRITEONLY, D3DFVF_FULLSCREENQUADVERTEX, D3DPOOL_DEFAULT, &g_pFullScreenQuadVertexBuffer, NULL ) );
870
871        void* pVertices;
872        V( g_pFullScreenQuadVertexBuffer->Lock( 0, sizeof( fullscreen ), (void**)&pVertices, 0 ) );
873        memcpy( pVertices, fullscreen, sizeof( fullscreen ) );
874        g_pFullScreenQuadVertexBuffer->Unlock();
875        // --- Vertex declarations ------------------------------------------------------------------
876
877      // Setup the camera's projection parameters
878    float fAspectRatio = pBackBufferSurfaceDesc->Width / (FLOAT)pBackBufferSurfaceDesc->Height;
879    g_Camera.SetProjParams( D3DX_PI/4, fAspectRatio, 0.1f, 1000.0f );
880    g_Camera.SetWindow( pBackBufferSurfaceDesc->Width, pBackBufferSurfaceDesc->Height );
881        g_Camera.SetButtonMasks( 0, MOUSE_WHEEL, MOUSE_LEFT_BUTTON );
882
883        g_HUD.SetLocation( 50, 0 );
884    g_HUD.SetSize( 250, 250 );
885
886        //DXUTDeviceSettings d3dSettings = DXUTGetDeviceSettings();
887        InitializeHUD();
888        RenderSceneInitialization();
889       
890        return S_OK;
891}
892
893//--------------------------------------------------------------------------------------
894// This callback function will be called once at the beginning of every frame. This is the
895// best location for your application to handle updates to the scene, but is not
896// intended to contain actual rendering calls, which should instead be placed in the
897// OnFrameRender callback. 
898//--------------------------------------------------------------------------------------
899void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime )
900{
901    // Update the camera's position based on user input
902    g_Camera.FrameMove( fElapsedTime );
903}
904
905//--------------------------------------------------------------------------------------
906// This callback function will be called at the end of every frame to perform all the
907// rendering calls for the scene, and it will also be called if the window needs to be
908// repainted. After this function has returned, the sample framework will call
909// IDirect3DDevice9::Present to display the contents of the next buffer in the swap chain
910//--------------------------------------------------------------------------------------
911void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime )
912{
913    HRESULT hr;
914        D3DXMATRIXA16 mScaleLightObjSize, mWorldViewLight, mWorldViewCausticGenerator;
915        g_pd3dDevice = pd3dDevice;
916
917        //------------------------------------------------------------------------
918        // This is an initialization. This part of the code runs just once.
919        // CubeMaps are created and basic setup is done here.
920        //------------------------------------------------------------------------
921        if ( g_bInitialization )
922        {
923                RenderSceneInitialization();
924                RenderScenePreProcessing();
925                g_bInitialization = false;
926        }
927
928        //------------------------------------------------------------------------
929        // This part of the code calculates whether the Caustics should be recalculated or not.
930        // Calculate the size of movement between the last Caustics generation and the current position
931        //------------------------------------------------------------------------
932        float fSumDist = ( abs( g_vLightPos.x  - g_vLightPosLast.x ) +
933                                           abs( g_vLightPos.y  - g_vLightPosLast.y ) +
934                                           abs( g_vLightPos.z  - g_vLightPosLast.z ) +
935                                           abs( g_vCenterObjectPos.x - g_vCenterObjectPosLast.x ) +
936                                           abs( g_vCenterObjectPos.y - g_vCenterObjectPosLast.y ) +
937                                           abs( g_vCenterObjectPos.z - g_vCenterObjectPosLast.z ) );
938       
939        float fEpsilon = 0.01f;         // Tolerance of the max move size between two Caustics generation step
940        if ( fSumDist > fEpsilon || g_bRunGenerateCaustics )
941        {
942                // If the movement is too big, or at least one property is changed
943                // the Caustic effect is recalculated
944                // Generate Caustics effect
945                GenerateCaustics();
946
947                // Refreshes Position data
948                g_vLightPosLast  = g_vLightPos;
949                g_vCenterObjectPosLast = g_vCenterObjectPos;
950
951                // Turns off the Caustics Generation
952                g_bRunGenerateCaustics = false;
953        }
954
955        //------------------------------------------------------------------------
956        // This part of the code renders the visible objects in the scene.
957        //------------------------------------------------------------------------
958        D3DXMATRIXA16 mWorldCamera = *g_Camera.GetWorldMatrix();
959        D3DXMATRIXA16 mViewCamera  = *g_Camera.GetViewMatrix();
960        D3DXMATRIXA16 mProjCamera  = *g_Camera.GetProjMatrix();
961
962        D3DXMATRIXA16 mWorldLight = ScaleAndOffset(1, g_vLightPos);
963
964        D3DXMATRIXA16 mWorldViewCamera;
965        D3DXMatrixMultiply( &mWorldViewCamera, &mWorldCamera, &mViewCamera );
966        D3DXMatrixScaling( &mScaleLightObjSize, LIGHTRADIUS, LIGHTRADIUS, LIGHTRADIUS  );
967        mWorldViewLight = mScaleLightObjSize * mWorldLight * mWorldViewCamera;
968        mWorldViewCausticGenerator = g_mWorldCenterObject * mWorldViewCamera;
969       
970        V( pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0L ) );
971
972    if( SUCCEEDED( pd3dDevice->BeginScene() ) )
973    {
974                // Renders Room and Columns objects
975                RenderScene( &mWorldViewCamera, &mProjCamera, RENDER_ROOM_AND_COLUMNS_SCREEN );
976
977                // Renders light source
978                RenderScene( &mWorldViewLight, &mProjCamera, RENDER_LIGHT_SCREEN );
979
980                // Renders CenterObject (Caustic generator)
981                RenderScene( &mWorldViewCausticGenerator, &mProjCamera, RENDER_REFRACT_OBJECT_SCREEN );
982
983                if( g_bShowPhotonMap )
984                {
985                        // Renders the PhotonMap into the screen
986                        RenderScene( &mWorldViewCausticGenerator, &mProjCamera, RENDER_PHOTON_MAP_SCREEN );
987                }
988
989        // Renders stats and help text
990                RenderText();
991
992                // Show HUD
993                if( g_bShowHUD ) g_HUD.OnRender( fElapsedTime );
994
995        pd3dDevice->EndScene();
996        }
997}
998
999// The next part will run just once ( the initialization )
1000void RenderScenePreProcessing()
1001{
1002        HRESULT hr;
1003
1004        D3DXMATRIXA16 mProj_90_Degrees;                                                 // projection matrix
1005        D3DXMATRIXA16 mWorldView;                                                               // worldview matrix
1006        D3DXMATRIXA16 mViewCubeMap;
1007        LPDIRECT3DSURFACE9 pCubeMapDistSurf, pCubeMapUVSurf;
1008
1009        D3DXMATRIXA16 g_mWorldCenterObjectMinus = ScaleAndOffset(1, -g_vCenterObjectPos);
1010
1011        // The projection matrix has a FOV of 90 degrees and asp ratio of 1
1012        D3DXMatrixPerspectiveFovLH( &mProj_90_Degrees, D3DX_PI * 0.5f, 1.0f, 0.001f, 1000.0f );
1013
1014        //----------------------------------------------------------------------------------------------
1015        // Saves original settings
1016        //----------------------------------------------------------------------------------------------
1017        V( g_pd3dDevice->GetRenderTarget( 0, &g_pRenderTargetSurfaceOld ) );
1018        if( SUCCEEDED( g_pd3dDevice->GetDepthStencilSurface( &g_pDepthStencilSurfaceOld ) ) )
1019        {
1020                // If the device has a depth-stencil buffer, use the depth stencil buffer created for the cube textures.
1021                V( g_pd3dDevice->SetDepthStencilSurface( g_pRoomCubeMapDepthStencilSurface ) );
1022        }
1023
1024        //----------------------------------------------------------------------------------------------
1025        // creates: CubeMap from the position of the CenterObject (RoomCubeMapColorDistanceTexture)
1026        // stores: COLOR(x,y,z) + DISTANCE(w)
1027        //----------------------------------------------------------------------------------------------
1028        for( int nFace = 0; nFace < 6; ++nFace )
1029        {
1030                V( g_pRoomCubeMapColorDistTexture->GetCubeMapSurface( (D3DCUBEMAP_FACES)nFace, 0, &pCubeMapDistSurf ) );
1031                V( g_pd3dDevice->SetRenderTarget( 0, pCubeMapDistSurf ) );
1032                V( g_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0L ) );
1033               
1034                if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
1035                {
1036                        mViewCubeMap = DXUTGetCubeMapViewMatrix( nFace );
1037                        mWorldView = g_mWorldCenterObjectMinus * mViewCubeMap;
1038                        RenderScene( &mWorldView, &mProj_90_Degrees, RENDER_ROOM_COLOR_DISTANCE );
1039                       
1040                        g_pd3dDevice->EndScene();
1041                }
1042                SAFE_RELEASE( pCubeMapDistSurf );
1043        }
1044
1045        //----------------------------------------------------------------------------------------------
1046        // creates: CubeMap from the position of the CenterObject (RoomCubeMapUVTexture)
1047        // stores: UV(x,y) + ObjectID(z) + 1
1048        //----------------------------------------------------------------------------------------------
1049        for( int nFace = 0; nFace < 6; ++nFace )
1050        {
1051                V( g_pRoomCubeMapUVTexture->GetCubeMapSurface( (D3DCUBEMAP_FACES)nFace, 0, &pCubeMapUVSurf ) );
1052                V( g_pd3dDevice->SetRenderTarget( 0, pCubeMapUVSurf ) );
1053                V( g_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0L ) );
1054               
1055                if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
1056                {
1057                        mViewCubeMap = DXUTGetCubeMapViewMatrix( nFace );
1058                        mWorldView = g_mWorldCenterObjectMinus * mViewCubeMap;
1059                        RenderScene( &mWorldView, &mProj_90_Degrees, RENDER_ROOM_UV );
1060                       
1061                        g_pd3dDevice->EndScene();
1062                }
1063                SAFE_RELEASE( pCubeMapUVSurf );
1064        }
1065
1066        //----------------------------------------------------------------------------------------------
1067        // Restores depth-stencil buffer and render target
1068        //----------------------------------------------------------------------------------------------
1069    if( g_pDepthStencilSurfaceOld )
1070    {
1071        V( g_pd3dDevice->SetDepthStencilSurface( g_pDepthStencilSurfaceOld ) );
1072        SAFE_RELEASE( g_pDepthStencilSurfaceOld );
1073    }
1074    V( g_pd3dDevice->SetRenderTarget( 0, g_pRenderTargetSurfaceOld ) );
1075    SAFE_RELEASE( g_pRenderTargetSurfaceOld );
1076}
1077
1078
1079void GenerateCaustics()
1080{
1081        HRESULT hr;
1082
1083
1084        //----------------------------------------------------------------------------------------------
1085        // save original settings
1086        //----------------------------------------------------------------------------------------------
1087        V( g_pd3dDevice->GetRenderTarget( 0, &g_pRenderTargetSurfaceOld ) );
1088        if( SUCCEEDED( g_pd3dDevice->GetDepthStencilSurface( &g_pDepthStencilSurfaceOld ) ) )
1089        {
1090                // If the device has a depth-stencil buffer, use the depth stencil buffer created for the cube textures.
1091                V( g_pd3dDevice->SetDepthStencilSurface( g_pRoomCubeMapDepthStencilSurface ) );
1092        }
1093
1094
1095        //----------------------------------------------------------------------------------------------
1096        // creates: PhotonMap from light position
1097        // stores: UV(x,y) + ObjectID(z) + "1"
1098        //----------------------------------------------------------------------------------------------
1099
1100        // Calculate the light's worldview transformation and take picture from there
1101        D3DXVECTOR3 vUpPt( 0.0f, 1.0f, 0.0f );
1102        D3DXMatrixLookAtLH( &g_mWorldViewLight, &g_vLightPos, &g_vCenterObjectPos, &vUpPt );
1103
1104        // Calculate FOV of the light
1105        float radiusCenter = CENTEROBJECTRADIUS * 1.03f;                                        // The radius of the CenterObject
1106
1107        D3DXVECTOR3 vDiff = g_vLightPos - g_vCenterObjectPos;   
1108        float dist = sqrt (     vDiff.x * vDiff.x +                                                             // The distance between
1109                                                vDiff.y * vDiff.y +                                                             // light source and CenterObject
1110                                                vDiff.z * vDiff.z );
1111
1112        float fovLight = atan ( radiusCenter / dist ) * 2;                                      // fov[rad]
1113               
1114        D3DXMATRIXA16 mLightProj;                                                                                       // projection matrix for the light
1115        D3DXMatrixPerspectiveFovLH( &mLightProj, fovLight, 1.0f, 0.001f, 1000.0f );
1116
1117        // Skip this part of code if Caustic effect is not used
1118        if ( g_bCausticsON )
1119        {
1120                V( g_pd3dDevice->SetDepthStencilSurface( g_pPhotonMapDepthStencilSurface ) );
1121                V( g_pd3dDevice->SetRenderTarget( 0, g_pPhotonUVMapSurface ) );
1122                V( g_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0L ) );
1123                       
1124                if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
1125                {
1126                        RenderScene( &g_mWorldViewLight, &mLightProj, RENDER_PHOTON_UV_MAP );
1127                        g_pd3dDevice->EndScene();
1128                }
1129        }
1130       
1131// -- DEBUG ----------------------------------------------------------------------------------------------
1132        if( g_bSaveTexture )
1133        {
1134                D3DXSaveSurfaceToFile( L"PhotonMap.png", D3DXIFF_PNG, g_pPhotonUVMapSurface, NULL,NULL);
1135
1136                g_bSaveTexture = false;
1137        }
1138// -- DEBUG END ----------------------------------------------------------------------------------------------
1139
1140
1141        //----------------------------------------------------------------------------------------------
1142        // creates: ShadowMap from light position
1143        // stores: Distance(x)
1144        //----------------------------------------------------------------------------------------------
1145        // Skip this part of code if Shadow is not used
1146        if ( g_bShadowON )
1147        {
1148                V( g_pd3dDevice->SetDepthStencilSurface( g_pShadowMapDepthStencilSSurface ) );
1149                V( g_pd3dDevice->SetRenderTarget( 0, g_pShadowMapSurface ) );
1150                V( g_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0L ) );
1151
1152                // Sets depth bias to a predefined value
1153                g_pd3dDevice->SetRenderState(D3DRS_DEPTHBIAS,           (DWORD)g_dDepthBias);
1154                g_pd3dDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, (DWORD)g_dBiasSlope);
1155                // The projection of the ShadowMap is 80 degree.
1156                D3DXMatrixPerspectiveFovLH( &g_mProjLight, D3DXToRadian( 80.0f ), 1.0f, 1.0f, 20.0f );
1157
1158                if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
1159                {
1160                        RenderScene( &g_mWorldViewLight, &g_mProjLight, RENDER_SHADOW );
1161                        g_pd3dDevice->EndScene();
1162                }
1163
1164                // Sets back the depth bias to "0"
1165                g_pd3dDevice->SetRenderState( D3DRS_DEPTHBIAS,           (DWORD)0.0f );
1166                g_pd3dDevice->SetRenderState( D3DRS_SLOPESCALEDEPTHBIAS, (DWORD)0.0f );
1167        }
1168
1169        //--------------------------------------------------------------------------------------------
1170        // creates: RoomLastTexture, and ColumnTexture[0,1,2,3]
1171        // They will be used as source textures when the Room and Columns are rendered in the visible scene
1172        // stores: Color(r,g,b,a)
1173        //--------------------------------------------------------------------------------------------
1174        D3DXMATRIXA16 mWorldViewCamera = *g_Camera.GetViewMatrix();
1175        D3DXMATRIXA16 mProjCamera  = *g_Camera.GetProjMatrix();
1176       
1177        // Render Room with Shadow and Caustics
1178        V( g_pd3dDevice->SetRenderTarget( 0, g_pRoomModifySurface ) );
1179        V( g_pd3dDevice->SetDepthStencilSurface( g_pDepthStencilSurface ) );
1180        V( g_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0L ) );
1181
1182        if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
1183        {
1184                // Renders Room with Shadow and Caustics
1185                g_iObjectID = -1;               // The ID of the Room Object = -1
1186                RenderScene( &mWorldViewCamera, &mProjCamera, RENDER_UMBRA );
1187                if ( g_bCausticsON )
1188                        RenderScene( &mWorldViewCamera, &mProjCamera, RENDER_PHOTON_HIT );
1189                g_pd3dDevice->EndScene();
1190        }
1191               
1192        V( g_pd3dDevice->SetRenderTarget( 0, g_pRoomLastSurface ) );
1193        V( g_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0L ) );
1194               
1195        if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
1196        {
1197                // Removes the black edges. Enlarges the usefull content of the atlas with one texel
1198                RenderScene( &mWorldViewCamera, &mProjCamera, RENDER_FULLSCREENQUAD );
1199                g_pd3dDevice->EndScene();
1200        }
1201
1202        // Renders Columns with Shadow and Caustics
1203        for (int i = 0; i < 4; i++)
1204        {
1205                // Renders one Column with Shadow and Caustics
1206                V( g_pd3dDevice->SetRenderTarget( 0, g_pColumnsModifySurface[i] ) );
1207                V( g_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0L ) );
1208
1209                if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
1210                {
1211                        g_iObjectID = i;        // The ID of a Column
1212                        RenderScene( &mWorldViewCamera, &mProjCamera, RENDER_UMBRA );
1213                        if ( g_bCausticsON )
1214                                RenderScene( &mWorldViewCamera, &mProjCamera, RENDER_PHOTON_HIT );
1215                        g_pd3dDevice->EndScene();
1216                }
1217
1218                V( g_pd3dDevice->SetRenderTarget( 0, g_pColumnsLastSurface[i] ) );
1219                V( g_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0L ) );
1220               
1221                if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
1222                {
1223                        // Removes the black edges. Enlarges the usefull content of the atlas with one texel
1224                        RenderScene( &mWorldViewCamera, &mProjCamera, RENDER_FULLSCREENQUAD );
1225                        g_pd3dDevice->EndScene();
1226                }
1227        }
1228       
1229        /*
1230
1231// -- DEBUG ----------------------------------------------------------------------------------------------
1232        if( g_bSaveTexture )
1233        {
1234                D3DXSaveSurfaceToFile( L"RoomMod.png", D3DXIFF_PNG, g_pRoomModifySurface, NULL,NULL);
1235                D3DXSaveSurfaceToFile( L"RoomLast.png", D3DXIFF_PNG, g_pRoomLastSurface, NULL,NULL);
1236
1237                D3DXSaveSurfaceToFile( L"ColumnMod0.png", D3DXIFF_PNG, g_pColumnsModifySurface[0], NULL,NULL);
1238                //D3DXSaveSurfaceToFile( L"ColumnMod1.png", D3DXIFF_PNG, g_pColumnsModifySurface[1], NULL,NULL);
1239                //D3DXSaveSurfaceToFile( L"ColumnMod2.png", D3DXIFF_PNG, g_pColumnsModifySurface[2], NULL,NULL);
1240                //D3DXSaveSurfaceToFile( L"ColumnMod3.png", D3DXIFF_PNG, g_pColumnsModifySurface[3], NULL,NULL);
1241
1242                D3DXSaveSurfaceToFile( L"ColumnLast0.png", D3DXIFF_PNG, g_pColumnsLastSurface[0], NULL,NULL);
1243                //D3DXSaveSurfaceToFile( L"ColumnLast1.png", D3DXIFF_PNG, g_pColumnsLastSurface[1], NULL,NULL);
1244                //D3DXSaveSurfaceToFile( L"ColumnLast2.png", D3DXIFF_PNG, g_pColumnsLastSurface[2], NULL,NULL);
1245                //D3DXSaveSurfaceToFile( L"ColumnLast3.png", D3DXIFF_PNG, g_pColumnsLastSurface[3], NULL,NULL);
1246
1247                g_bSaveTexture = false;
1248        }
1249// -- DEBUG END ----------------------------------------------------------------------------------------------
1250        */
1251
1252        //----------------------------------------------------------------------
1253        // Restores depth-stencil buffer and render target
1254        //---------------------------------------------------------------------
1255    if( g_pDepthStencilSurfaceOld )
1256    {
1257        V( g_pd3dDevice->SetDepthStencilSurface( g_pDepthStencilSurfaceOld ) );
1258        SAFE_RELEASE( g_pDepthStencilSurfaceOld );
1259    }
1260    V( g_pd3dDevice->SetRenderTarget( 0, g_pRenderTargetSurfaceOld ) );
1261    SAFE_RELEASE( g_pRenderTargetSurfaceOld );
1262}
1263
1264
1265// Sends texture parameters to the GPU.
1266void RenderSceneInitialization()
1267{
1268        HRESULT hr;
1269       
1270        // Bind textures
1271        V( g_pEffect->SetTexture( "g_txRoomMap",                                         g_pRoomTexture ) );
1272        V( g_pEffect->SetTexture( "g_txRoomCubeMapColorDistanceMap", g_pRoomCubeMapColorDistTexture ) );
1273        V( g_pEffect->SetTexture( "g_txRoomCubeMapUVMap",                        g_pRoomCubeMapUVTexture ) );
1274        V( g_pEffect->SetTexture( "g_txRoomModifyMap",                           g_pRoomModifyTexture ) );
1275        V( g_pEffect->SetTexture( "g_txRoomLastMap",                             g_pRoomLastTexture ) );
1276       
1277        V( g_pEffect->SetTexture( "g_txPhotonUVMap",                             g_pPhotonUVTexture ) );
1278        V( g_pEffect->SetTexture( "g_txPowerOfSnippetMap",                       g_pPowerOfSnippetTexelTexture ) );
1279
1280        V( g_pEffect->SetTexture( "g_txColumnModifyTexture0",            g_pColumnModifyTexture[0] ) );
1281        V( g_pEffect->SetTexture( "g_txColumnModifyTexture1",            g_pColumnModifyTexture[1] ) );
1282        V( g_pEffect->SetTexture( "g_txColumnModifyTexture2",            g_pColumnModifyTexture[2] ) );
1283        V( g_pEffect->SetTexture( "g_txColumnModifyTexture3",            g_pColumnModifyTexture[3] ) );
1284        V( g_pEffect->SetTexture( "g_txColumnLastTexture0",                      g_pColumnLastTexture[0] ) );
1285        V( g_pEffect->SetTexture( "g_txColumnLastTexture1",                      g_pColumnLastTexture[1] ) );
1286        V( g_pEffect->SetTexture( "g_txColumnLastTexture2",                      g_pColumnLastTexture[2] ) );
1287        V( g_pEffect->SetTexture( "g_txColumnLastTexture3",                      g_pColumnLastTexture[3] ) );
1288        V( g_pEffect->SetTexture( "g_txColumnOriginalTexture",           g_pColumnLastTexture[4] ) );
1289
1290        V( g_pEffect->SetTexture( "g_txShadowMap",                                       g_pShadowMapTexture ) );
1291}
1292
1293
1294// This function renders the Room mesh.
1295void RenderRoom(D3DXMATRIXA16 *mWorldView, D3DXMATRIXA16 *mProj)
1296{
1297        HRESULT hr;
1298        D3DXMATRIXA16 mWorldViewProjection;
1299
1300        V( g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CW ) );
1301
1302        D3DXMatrixMultiply( &mWorldViewProjection, mWorldView, mProj );
1303        V( g_pEffect->SetMatrix( "g_mWorldView",                        mWorldView ) );
1304        V( g_pEffect->SetMatrix( "g_mWorldViewProjection",      &mWorldViewProjection ) );
1305        V( g_pEffect->SetMatrix( "g_mLightViewTexBias",     &mWorldViewProjection ) );
1306        V( g_pEffect->SetInt( "g_iObjectID", -1 ) );
1307        V( g_pEffect->CommitChanges() );         
1308       
1309        V( g_pRoomMesh->DrawSubset( 0 ) );
1310       
1311        V( g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW ) );
1312}
1313
1314
1315// This function renders the Columns mesh.
1316void RenderColumns(D3DXMATRIXA16 *mWorldView, D3DXMATRIXA16 *mProj)
1317{
1318        HRESULT hr;
1319        D3DXMATRIXA16 mWorldOffset, mWorldViewProjection;
1320
1321        for (int i = 0; i < 4; i++)
1322        {
1323                if (i==0) D3DXMatrixTranslation( &mWorldOffset,  3.75f ,0 , 3.75f );
1324                if (i==1) D3DXMatrixTranslation( &mWorldOffset, -3.75f ,0 , 3.75f );
1325                if (i==2) D3DXMatrixTranslation( &mWorldOffset,  3.75f ,0 ,-3.75f );
1326                if (i==3) D3DXMatrixTranslation( &mWorldOffset, -3.75f ,0 ,-3.75f );
1327                D3DXMatrixMultiply( &mWorldOffset, &mWorldOffset, mWorldView);
1328                D3DXMatrixMultiply( &mWorldViewProjection, &mWorldOffset, mProj);
1329
1330                V( g_pEffect->SetMatrix( "g_mWorldView", &mWorldOffset ) );
1331                V( g_pEffect->SetMatrix( "g_mWorldViewProjection",      &mWorldViewProjection ) );
1332                V( g_pEffect->SetMatrix( "g_mLightViewTexBias",     &mWorldViewProjection ) );
1333                V( g_pEffect->SetInt( "g_iObjectID", i ) );
1334                V( g_pEffect->CommitChanges() );
1335
1336                V( g_pColumnMesh->DrawSubset( 0 ) );                           
1337        }
1338}
1339
1340// Sets the techniques.
1341// Calculates and sends parameters to the GPU.
1342void RenderScene(D3DXMATRIXA16 *mWorldView, D3DXMATRIXA16 *mProj, int method )
1343{
1344        HRESULT hr;
1345        UINT cPass;
1346        D3DXMATRIXA16 mWorldViewProjection, mWorldOffset;
1347
1348        D3DXMatrixMultiply( &mWorldViewProjection, mWorldView, mProj );
1349        V( g_pEffect->SetMatrix( "g_mWorldViewProjection",      &mWorldViewProjection ) );
1350        V( g_pEffect->SetMatrix( "g_mWorldView",                        mWorldView ) );
1351
1352        V( g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CW ) );
1353
1354                       
1355        //----------------------------------------------------------------------
1356        // It renders Room and Columns from the CenterObject position
1357        // and stores them in a CubeMap: g_pRoomCubeMapColorDistTexture.
1358        // Contains: COLOR(x,y,z) + Distance(w)
1359        //----------------------------------------------------------------------
1360        if ( method == RENDER_ROOM_COLOR_DISTANCE )
1361        {
1362                V( g_pEffect->SetTechnique( "RenderRoomColorDistance" ) );
1363                V( g_pEffect->Begin( &cPass, 0 ) );
1364                V( g_pEffect->BeginPass( 0 ) );
1365
1366                // Render Room
1367                RenderRoom( mWorldView, mProj );
1368
1369                // Render Columns
1370                RenderColumns( mWorldView, mProj );
1371
1372                V( g_pEffect->EndPass() );
1373                V( g_pEffect->End() );
1374        }
1375
1376
1377        //----------------------------------------------------------------------
1378        // It renders Room and Columns from the center object position
1379        // and stores them in a CubeMap: g_pRoomCubeMapUVTexture.
1380        // Contains: UV(x,y) + ObjectID(z) + "1"
1381        //----------------------------------------------------------------------
1382        if ( method == RENDER_ROOM_UV )
1383        {
1384                V( g_pEffect->SetTechnique( "RenderRoomUV" ) );
1385                V( g_pEffect->Begin( &cPass, 0 ) );
1386                V( g_pEffect->BeginPass( 0 ) );
1387                               
1388                // Render Room
1389                RenderRoom( mWorldView, mProj );
1390
1391                // Render Columns
1392                RenderColumns( mWorldView, mProj );
1393               
1394                V( g_pEffect->EndPass() );
1395                V( g_pEffect->End() );
1396        }
1397
1398
1399        //----------------------------------------------------------------------
1400        // It renders Room and Columns from the center object position
1401        // and stores them in their Atlases.
1402        // Contains: Color(r,g,b,a )
1403        //----------------------------------------------------------------------
1404        if ( method == RENDER_UMBRA )
1405        {
1406                V( g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW ) );
1407
1408                V( g_pEffect->SetTechnique( "RenderUmbra" ) );
1409                V( g_pEffect->Begin( &cPass, 0 ) );
1410
1411                g_mLightViewTexBias = g_mWorldViewLight * g_mProjLight * g_mTexScaleBiasMat;
1412                V( g_pEffect->SetMatrix( "g_mLightViewTexBias", &g_mLightViewTexBias ) );
1413                V( g_pEffect->SetBool( "g_bShadowON",                   g_bShadowON ) );
1414                V( g_pEffect->SetBool( "g_bShowHelp",                   g_bShowHelp ) );
1415                V( g_pEffect->SetFloatArray( "g_vLightPos3f",   g_vLightPos, 3 ) );
1416                V( g_pEffect->SetFloat( "g_fShadowIntensity",   1-g_fShadowIntensity ));
1417                V( g_pEffect->SetFloat( "g_fCausticsIntensity", g_fCausticsIntensity ));
1418
1419                V( g_pEffect->BeginPass( 0 ) );
1420                if (g_iObjectID == -1)
1421                {
1422                        // Render Room
1423                        V( g_pEffect->SetInt( "g_iObjectID", -1 ) );
1424                        V( g_pEffect->CommitChanges() );         
1425                        V( g_pRoomMesh->DrawSubset( 0 ) );
1426                } else
1427                {
1428                        // Render Columns
1429                        if (g_iObjectID==0) D3DXMatrixTranslation( &mWorldOffset,  3.75f ,0 , 3.75f );
1430                        if (g_iObjectID==1) D3DXMatrixTranslation( &mWorldOffset, -3.75f ,0 , 3.75f );
1431                        if (g_iObjectID==2) D3DXMatrixTranslation( &mWorldOffset,  3.75f ,0 ,-3.75f );
1432                        if (g_iObjectID==3) D3DXMatrixTranslation( &mWorldOffset, -3.75f ,0 ,-3.75f );
1433                        V( g_pEffect->SetMatrix( "g_mWorldView",        &mWorldOffset ) );
1434                        V( g_pEffect->SetInt( "g_iObjectID",            g_iObjectID ) );
1435                        V( g_pEffect->CommitChanges() );
1436                        V( g_pColumnMesh->DrawSubset( 0 ) );                           
1437                }
1438                V( g_pEffect->EndPass() );
1439                V( g_pEffect->End() );
1440        }
1441
1442
1443        //----------------------------------------------------------------------
1444        // It renders Room and Columns from the camera position
1445        // and shows them on the screen.
1446        // Contains: Color(r,g,b,a)
1447        //----------------------------------------------------------------------
1448        if ( method == RENDER_ROOM_AND_COLUMNS_SCREEN )
1449        {
1450                V( g_pEffect->SetTechnique( "RenderRoomAndColumnsScreen" ) );
1451                V( g_pEffect->Begin( &cPass, 0 ) );
1452                V( g_pEffect->BeginPass( 0 ) );
1453               
1454                // Render Room
1455                RenderRoom( mWorldView, mProj );
1456
1457                // Render Columns
1458                RenderColumns( mWorldView, mProj );
1459
1460                V( g_pEffect->EndPass() );
1461                V( g_pEffect->End() );
1462        }
1463
1464
1465        //----------------------------------------------------------------------
1466        // It renders CenterObject from the light position
1467        // and stores it in g_pPhotonUVTexture.
1468        // Contains: UV(x,y) + ObjectID(1) + "1" or "-1"
1469        //----------------------------------------------------------------------
1470        if ( method == RENDER_PHOTON_UV_MAP )
1471        {
1472                V( g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW ) );
1473
1474                if( g_iAlgorithmMethod == 0 )
1475                        // Uses classic method
1476                        V( g_pEffect->SetTechnique( "RenderPhotonUVMapClassic" ) );
1477                if( g_iAlgorithmMethod == 1 )
1478                        // Uses distance impostor
1479                        V( g_pEffect->SetTechnique( "RenderPhotonUVMap" ) );
1480
1481                D3DXMatrixMultiply( &mWorldViewProjection, mWorldView, mProj );
1482                D3DXMatrixMultiply( &mWorldViewProjection, &g_mWorldCenterObject, &mWorldViewProjection );
1483                V( g_pEffect->SetMatrix( "g_mWorldViewProjection",      &mWorldViewProjection ) );
1484                V( g_pEffect->SetMatrix( "g_mWorldCenterObject",        &g_mWorldCenterObject ) );
1485                V( g_pEffect->SetFloatArray( "g_vLightPos3f",           g_vLightPos, 3 ) );
1486                V( g_pEffect->SetInt( "g_iNumberOfIteration",           g_iNumberOfIteration) );
1487                V( g_pEffect->SetInt( "g_iPhotonMapSize",                       g_iPhotonMapSize) );
1488                V( g_pEffect->SetFloat( "g_fRefractionIndex",           g_fRefractionIndex ) );
1489                                             
1490                V( g_pEffect->Begin( &cPass, 0 ) );
1491                V( g_pEffect->BeginPass( 0 ) );
1492                V( g_pEffect->CommitChanges() );
1493
1494                V( g_pCenterObjectMesh->DrawSubset( 0 ) );
1495
1496        V( g_pEffect->EndPass() );
1497        V( g_pEffect->End() );
1498        }
1499
1500
1501        //----------------------------------------------------------------------
1502        // It renders CenterObject from the camera position
1503        // and shows it on the screen.
1504        // Contains: Color(r,g,b,a)
1505        //----------------------------------------------------------------------
1506        if ( method == RENDER_REFRACT_OBJECT_SCREEN )
1507        {
1508                V( g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW ) );
1509
1510                if( g_bRenderCenterObjectWithBrdfON )
1511                {
1512                        if( g_iAlgorithmMethod == 0 )
1513                                // Uses classic method
1514                                V( g_pEffect->SetTechnique( "RenderRefractObjectScreenClassic" ) );
1515                        if( g_iAlgorithmMethod == 1 )           
1516                                // Uses distance impostor
1517                                V( g_pEffect->SetTechnique( "RenderRefractObjectScreen" ) );
1518                }
1519                else
1520                        // Uses diffuse color
1521                        V( g_pEffect->SetTechnique( "RenderLightScreen" ) );
1522
1523                V( g_pEffect->Begin( &cPass, 0 ) );
1524
1525                D3DXVECTOR3 vWorldCameraEye = *g_Camera.GetEyePt();
1526
1527                V( g_pEffect->SetMatrix( "g_mWorldCenterObject",        &g_mWorldCenterObject ) );
1528                V( g_pEffect->SetFloatArray( "g_vCameraPos3f",          vWorldCameraEye, 3 ) );
1529                V( g_pEffect->SetInt( "g_iNumberOfIteration",           g_iNumberOfIteration));
1530                V( g_pEffect->SetFloat( "g_fFresnelFactor",                     g_fFresnelFactor));
1531                V( g_pEffect->SetFloat( "g_fRefractionIndex",           g_fRefractionIndex ));
1532               
1533                V( g_pEffect->BeginPass( 0 ) );
1534                V( g_pEffect->CommitChanges() );
1535        V( g_pCenterObjectMesh->DrawSubset( 0 ) );
1536        V( g_pEffect->EndPass() );
1537        V( g_pEffect->End() );
1538        }
1539
1540
1541        //----------------------------------------------------------------------
1542        // It renders and blends impostors into the Atlases of Room and Columns
1543        // Contains: Color(r,g,b,a)
1544        //----------------------------------------------------------------------
1545        if ( method == RENDER_PHOTON_HIT )
1546        {
1547                V( g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW ) );
1548
1549                g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
1550                g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_ONE);
1551                g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
1552        g_pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, false);
1553
1554                V( g_pEffect->SetTechnique( "RenderPhotonHit" ) );
1555                V( g_pEffect->Begin( &cPass, 0 ) );
1556                               
1557                float x = g_vLightPos.x - g_vCenterObjectPos.x;
1558                float y = g_vLightPos.y - g_vCenterObjectPos.y;
1559                float z = g_vLightPos.z - g_vCenterObjectPos.z;
1560                float gll2 = x * x + y * y + z * z;
1561
1562               
1563                //float POWER = CENTEROBJECTRADIUS * CENTEROBJECTRADIUS / 10;//45 * CENTEROBJECTRADIUS * CENTEROBJECTRADIUS * 4 / (SNIPPET_SIZE * SNIPPET_SIZE);
1564                //float POWER = 45 * CENTEROBJECTRADIUS * CENTEROBJECTRADIUS * 4 / (g_iPhotonMapSize * g_iPhotonMapSize);
1565                //float POWER = 45 * CENTEROBJECTRADIUS * CENTEROBJECTRADIUS * 4 / g_iPhotonMapSize;
1566
1567                // Determines the exponent of the PhotonMap size.
1568                // It is used as an index to look up from g_fIntensityOfSnippet array.
1569                int iPhotonMapSizeExponent = (int)( log( (float)g_iPhotonMapSize ) / log ( 2.0f ) + 0.5 );      // 0..8
1570               
1571                // By default the fSnippetSize is not constant in world space
1572                float fSnippetIntensity = g_fIntensityOfSnippet[ iPhotonMapSizeExponent ];
1573                if( g_bSnippetSizeIsConstant ) // if it is constant
1574                        fSnippetIntensity = g_fIntensityOfSnippetWithIndependentSnippetSize[ iPhotonMapSizeExponent ];
1575
1576                // The intensity value of one snippet
1577                float POWER = 10 * CENTEROBJECTRADIUS * CENTEROBJECTRADIUS /
1578                        ( g_fSnippetSize * g_fSnippetSize *
1579                          fSnippetIntensity * fSnippetIntensity );
1580
1581                V( g_pEffect->BeginPass( 0 ) );
1582                V( g_pEffect->SetInt( "g_iObjectID",                    g_iObjectID ) );
1583                V( g_pEffect->SetFloat( "g_fPower",                             POWER / gll2 ) );
1584                V( g_pEffect->SetFloat( "g_fCausticsIntensity", g_fCausticsIntensity ) );
1585                V( g_pEffect->CommitChanges() );
1586                V( g_pd3dDevice->SetVertexDeclaration( g_pSnippetVertexDeclaration ) );
1587                V( g_pd3dDevice->SetStreamSource( 0, g_bSnippetVertexBuffer, 0, (sizeof(float)* 9 ) ) );
1588                V( g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, ( g_iPhotonMapSize * g_iPhotonMapSize * 2 ) ) );
1589                V( g_pEffect->EndPass() );
1590                V( g_pEffect->End() );
1591
1592                g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
1593        }
1594
1595
1596        //----------------------------------------------------------------------
1597        // It renders Light Object from the camera position
1598        // and shows it on the screen.
1599        // Contains: Color(r,g,b,a)
1600        //----------------------------------------------------------------------
1601        if ( method == RENDER_LIGHT_SCREEN )
1602        {
1603                V( g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE ) );
1604
1605                V( g_pEffect->SetTechnique( "RenderLightScreen" ) );
1606                V( g_pEffect->Begin( &cPass, 0 ) );
1607                V( g_pEffect->BeginPass( 0 ) );
1608                V( g_pEffect->CommitChanges() );
1609
1610                V( g_pLightMesh->DrawSubset( 0 ) );
1611
1612                V( g_pEffect->EndPass() );
1613        V( g_pEffect->End() );
1614        }
1615
1616
1617        //----------------------------------------------------------------------
1618        // It renders CenterObject, Columns and Room from light position
1619        // and stores them in g_pShadowMapTexture.
1620        // Contains: Depth(x)
1621        //----------------------------------------------------------------------
1622        if ( method == RENDER_SHADOW )
1623        {
1624                V( g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE ) );
1625               
1626                V( g_pEffect->SetTechnique( "RenderShadow" ) );
1627
1628                D3DXMatrixMultiply( &mWorldViewProjection, &g_mWorldCenterObject, &mWorldViewProjection );
1629                V( g_pEffect->SetMatrix( "g_mWorldViewProjection",      &mWorldViewProjection ) );
1630                V( g_pEffect->SetMatrix( "g_mLightViewTexBias",     &mWorldViewProjection ) );
1631
1632                V( g_pEffect->Begin( &cPass, 0 ) );
1633                V( g_pEffect->BeginPass( 0 ) );
1634
1635                // Render CenterObject
1636                V( g_pEffect->CommitChanges() );
1637                V( g_pCenterObjectMesh->DrawSubset( 0 ) );
1638
1639                // Render Columns
1640                RenderColumns( mWorldView, mProj );
1641               
1642                // Render Room
1643                RenderRoom( mWorldView, mProj );
1644
1645                V( g_pEffect->EndPass() );
1646        V( g_pEffect->End() );
1647        }
1648
1649        //----------------------------------------------------------------------
1650        // It renders a fullscreen quad
1651        // and modifies the Room and Columns atlases.
1652        // Contains: Color(r,g,b,a)
1653        //----------------------------------------------------------------------
1654        if ( method == RENDER_FULLSCREENQUAD )
1655        {
1656                V( g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE ) );
1657               
1658                V( g_pEffect->SetTechnique( "FullScreenQuad" ) );
1659                V( g_pEffect->Begin( &cPass, 0 ) );
1660                V( g_pEffect->BeginPass( 0 ) );
1661
1662                V( g_pEffect->SetInt( "g_iObjectID", g_iObjectID ) );
1663                V( g_pEffect->CommitChanges() );
1664               
1665                V( g_pd3dDevice->SetVertexDeclaration( g_pFullScreenQuadVertexDeclaration ) );
1666                V( g_pd3dDevice->SetStreamSource( 0, g_pFullScreenQuadVertexBuffer, 0, sizeof(FullScreenQuadVertexStruct) ) );
1667                V( g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 2 ) );
1668
1669                V( g_pEffect->EndPass() );
1670                V( g_pEffect->End() );
1671        }
1672
1673        if ( method == RENDER_PHOTON_MAP_SCREEN )
1674        {
1675                V( g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE ) );
1676               
1677                V( g_pEffect->SetTechnique( "PhotonMapScreen" ) );
1678                V( g_pEffect->Begin( &cPass, 0 ) );
1679                V( g_pEffect->BeginPass( 0 ) );
1680                V( g_pEffect->CommitChanges() );
1681               
1682                V( g_pd3dDevice->SetVertexDeclaration( g_pFullScreenQuadVertexDeclaration ) );
1683                V( g_pd3dDevice->SetStreamSource( 0, g_pFullScreenQuadVertexBuffer, 0, sizeof(FullScreenQuadVertexStruct) ) );
1684                V( g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 2 ) );
1685
1686                V( g_pEffect->EndPass() );
1687                V( g_pEffect->End() );
1688        }
1689}
1690
1691//--------------------------------------------------------------------------------------
1692// Render the help and statistics text. This function uses the ID3DXFont interface for
1693// efficient text rendering.
1694//--------------------------------------------------------------------------------------
1695void RenderText()
1696{
1697    // The helper object simply helps keep track of text position, and color
1698    // and then it calls pFont->DrawText( m_pSprite, strMsg, -1, &rc, DT_NOCLIP, m_clr );
1699    // If NULL is passed in as the sprite object, then it will work however the
1700    // pFont->DrawText() will not be batched together.  Batching calls will improves performance.
1701    const D3DSURFACE_DESC* pd3dsdBackBuffer = DXUTGetBackBufferSurfaceDesc();
1702    CDXUTTextHelper txtHelper( g_pFont, g_pTextSprite, 16 );
1703
1704    // Output statistics
1705    txtHelper.Begin();
1706    txtHelper.SetInsertionPos( 10, 5 );
1707    txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ) );
1708
1709        /*TCHAR sz[50];
1710        sz[49] = 0;
1711        _sntprintf( sz, 50, L"%.2f fps", DXUTGetFPS() );
1712    txtHelper.DrawTextLine( sz );*/
1713
1714        txtHelper.DrawTextLine( DXUTGetFrameStats() );
1715    //txtHelper.DrawTextLine( DXUTGetDeviceStats() );
1716
1717        if (!g_bShowHelp)
1718                txtHelper.DrawTextLine( L"Press F1 for help" );
1719
1720        // Show algorithm's parameters
1721        if ( g_bShowVariables )
1722        {
1723            txtHelper.SetInsertionPos( 200, 50 );
1724
1725                txtHelper.DrawTextLine( L"Number of iteration" );
1726                txtHelper.DrawTextLine( L"Fresnel factor" );
1727                txtHelper.DrawTextLine( L"Refraction index" );
1728                txtHelper.DrawTextLine( L"Shadow intensity" );
1729                txtHelper.DrawTextLine( L"Caustics intensity" );
1730                txtHelper.DrawTextLine( L"PhotonMap size" );
1731                txtHelper.DrawTextLine( L"Snippet size" );
1732
1733            txtHelper.SetInsertionPos( 330, 50 );
1734
1735                TCHAR sz0[50], sz1[50], sz2[50], sz3[50], sz4[50], sz5[50], sz6[50];
1736                sz0[49] = sz1[49] = sz2[49] = sz3[49] = sz4[49] = sz5[49] = sz6[49] = 0;
1737               
1738                _sntprintf( sz0, 50, L"%i",   g_iNumberOfIteration );
1739                _sntprintf( sz1, 50, L"%.2f", g_fFresnelFactor );
1740                _sntprintf( sz2, 50, L"%.2f", g_fRefractionIndex );
1741                _sntprintf( sz3, 50, L"%.2f", g_fShadowIntensity );
1742                _sntprintf( sz4, 50, L"%.2f", g_fCausticsIntensity );
1743                _sntprintf( sz5, 50, L"%i",   g_iPhotonMapSize );
1744                _sntprintf( sz6, 50, L"%.2f", g_fSnippetSize );
1745               
1746                txtHelper.DrawTextLine( sz0 );
1747                txtHelper.DrawTextLine( sz1 );
1748                txtHelper.DrawTextLine( sz2 );
1749                txtHelper.DrawTextLine( sz3 );
1750                txtHelper.DrawTextLine( sz4 );
1751                txtHelper.DrawTextLine( sz5 );
1752                txtHelper.DrawTextLine( sz6 );
1753        }
1754
1755        // Draw help
1756        if ( g_bShowHelp )
1757        {
1758                const D3DSURFACE_DESC* backBufferDesc = DXUTGetBackBufferSurfaceDesc();
1759                txtHelper.SetInsertionPos( backBufferDesc->Width - 220, backBufferDesc->Height-24 * 16 );
1760
1761                txtHelper.DrawTextLine(
1762                                L"Controls (F1 to hide):\n\n"
1763                                L"____________________________\n"
1764                                L"              GENERAL CONTROLS\n"
1765                                L"Left click drag: Rotate mesh\n"
1766                                L"Mouse wheel: Zoom\n"
1767                                L"Arrow keys: Move center object\n"
1768                                L"Alt+Arrow keys: Move light object\n"
1769                                L"F2: Settings\n"
1770                                L"F3: Switch to REF device\n"
1771                                L"F4: Show parameters ON/OFF\n"
1772                                L"F5: Show HUD ON/OFF\n"
1773                                L"F8: Switch to Wireframe mode\n"
1774                                L"____________________________\n"
1775                                L"                      ALGORITHM\n"
1776                                L"1-5: Choose mesh\n"
1777                                L"C: Caustics Effect ON/OFF\n"
1778                                L"S: Shadow ON/OFF\n"
1779                                L"X: Center Objectum render ON/OFF\n"
1780                                L"D: Switch classic / dist. imp. meth.\n"
1781                                L"Y: Reset parameters\n"
1782                                L"V: Indep. Snippet size?\n"
1783                                L"M: Show PhotonMap ON/OFF\n"
1784                                L"____________________________\n"
1785                                L"                          Quit: ESC");
1786
1787                if( g_bShowHUD )
1788                        txtHelper.SetInsertionPos( 540, 50 );
1789                else
1790                        txtHelper.SetInsertionPos( 370, 50 );
1791
1792                if ( g_bShowVariables )
1793                {
1794                        txtHelper.DrawTextLine( L"Key: +, -" );
1795                        txtHelper.DrawTextLine( L"Key: Q, W" );
1796                        txtHelper.DrawTextLine( L"Key: E, R" );
1797                        txtHelper.DrawTextLine( L"Key: T, Z" );
1798                        txtHelper.DrawTextLine( L"Key: U, I" );
1799                        txtHelper.DrawTextLine( L"Key: O, P" );
1800                        txtHelper.DrawTextLine( L"Key: K, L" );
1801                        txtHelper.DrawTextLine( L"+ 'Alt' key:");
1802                        txtHelper.DrawTextLine( L"  quick change" );
1803                }
1804        }
1805
1806        // Draws the title of the PhotonMap
1807        if ( g_bShowPhotonMap )
1808        {
1809                const D3DSURFACE_DESC* backBufferDesc = DXUTGetBackBufferSurfaceDesc();
1810                txtHelper.SetInsertionPos( 65, backBufferDesc->Height - 180 );
1811                txtHelper.DrawTextLine( L"PhotonMap" );
1812        }
1813
1814    txtHelper.End();
1815}
1816
1817
1818//--------------------------------------------------------------------------------------
1819// Before handling window messages, the sample framework passes incoming windows
1820// messages to the application through this callback function. If the application sets
1821// *pbNoFurtherProcessing to TRUE, then the sample framework will not process this message.
1822//--------------------------------------------------------------------------------------
1823LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing )
1824{
1825        // Give the dialogs a chance to handle the message first
1826    *pbNoFurtherProcessing = g_HUD.MsgProc( hWnd, uMsg, wParam, lParam );
1827    if( *pbNoFurtherProcessing )
1828        return 0;
1829
1830    // Pass all remaining windows messages to camera so it can respond to user input
1831    g_Camera.HandleMessages( hWnd, uMsg, wParam, lParam );
1832
1833    return 0;
1834}
1835
1836
1837//--------------------------------------------------------------------------------------
1838// As a convenience, the sample framework inspects the incoming windows messages for
1839// keystroke messages and decodes the message parameters to pass relevant keyboard
1840// messages to the application.  The framework does not remove the underlying keystroke
1841// messages, which are still passed to the application's MsgProc callback.
1842//--------------------------------------------------------------------------------------
1843void CALLBACK KeyboardProc( UINT nChar, bool bKeyDown, bool bAltDown )
1844{
1845        HRESULT hr;
1846        D3DXVECTOR3 movement(0,0,0);
1847
1848    if( bKeyDown )
1849    {
1850        switch( nChar )
1851        {
1852                        // Save Objects Last Texture Atlas
1853                        case 'A':
1854                                g_bSaveTexture = true;
1855                                g_bRunGenerateCaustics = true;
1856                                break;
1857
1858                        // Show Help
1859            case VK_F1:
1860                                g_bShowHelp = !g_bShowHelp;
1861                                if (!g_bShowVariablesUserSet) g_bShowVariables = g_bShowHelp || g_bShowHUD;
1862                                g_bRunGenerateCaustics = true;
1863                                break;
1864                       
1865                        // Show the values of the algorithm's variables
1866                        case VK_F4:
1867                                g_bShowVariables = !g_bShowVariables;
1868                                g_bShowVariablesUserSet = !g_bShowVariablesUserSet;
1869                                break;
1870
1871                        // Show HUD
1872                        case VK_F5:
1873                                g_bShowHUD = !g_bShowHUD;
1874                                if (!g_bShowVariablesUserSet) g_bShowVariables = g_bShowHelp || g_bShowHUD;
1875                                break;
1876                       
1877                        // Change the Mesh of CenterObject
1878                        case '1':
1879                                SAFE_RELEASE( g_pCenterObjectMesh );
1880                                V( LoadMesh( SPHERE, &g_pCenterObjectMesh, true ) );
1881                                g_bRunGenerateCaustics = true;
1882                                break;
1883
1884                        case '2':
1885                                SAFE_RELEASE( g_pCenterObjectMesh );
1886                                V( LoadMesh( SKULL, &g_pCenterObjectMesh, true ) );
1887                                g_bRunGenerateCaustics = true;
1888                                break;
1889
1890                        case '3':
1891                                SAFE_RELEASE( g_pCenterObjectMesh );
1892                                V( LoadMesh( BUNNY, &g_pCenterObjectMesh, true ) );
1893                                g_bRunGenerateCaustics = true;
1894                                break;
1895
1896                        case '4':
1897                                SAFE_RELEASE( g_pCenterObjectMesh );
1898                                V( LoadMesh( TEAPOT, &g_pCenterObjectMesh, true ) );
1899                                g_bRunGenerateCaustics = true;
1900                                break;
1901
1902                        case '5':
1903                                SAFE_RELEASE( g_pCenterObjectMesh );
1904                                V( LoadMesh( TIGER, &g_pCenterObjectMesh, true ) );
1905                                g_bRunGenerateCaustics = true;
1906                                break;
1907
1908                        // Switch between the classical and our new distance impostor method
1909                        case 'D':
1910                                g_iAlgorithmMethod = 1 - g_iAlgorithmMethod;
1911
1912                                if ( g_iAlgorithmMethod == 0 )
1913                                         g_HUD.GetRadioButton( IDC_CLASSIC_METHOD )->SetChecked( true );
1914                                else g_HUD.GetRadioButton( IDC_DISTANCE_IMPOSTOR_METHOD )->SetChecked( true );
1915
1916                                g_bRunGenerateCaustics = true;
1917                                break;
1918
1919                        // Change the number of iteration.
1920                        case VK_ADD:
1921                                if( g_iNumberOfIteration < 20 ) g_iNumberOfIteration++;
1922                                g_HUD.GetSlider( IDC_NUMBER_OF_ITERATION_SLIDER )->SetValue( g_iNumberOfIteration );
1923                                g_bRunGenerateCaustics = true;
1924                                break;
1925
1926                        case VK_SUBTRACT:
1927                                if ( g_iNumberOfIteration > 0 ) g_iNumberOfIteration--;
1928                                g_HUD.GetSlider( IDC_NUMBER_OF_ITERATION_SLIDER )->SetValue( g_iNumberOfIteration );
1929                                g_bRunGenerateCaustics = true;
1930                                break;
1931
1932
1933                        // Change the intensity of the shadow
1934                        case 'Z':
1935                                g_fShadowIntensity += bAltDown ? 0.1f : 0.01f;
1936                                if ( g_fShadowIntensity > 1 ) g_fShadowIntensity = 1;
1937                                g_HUD.GetSlider( IDC_SHADOW_INTENSITY_SLIDER )->SetValue( (int)g_fShadowIntensity * 100 );
1938                                g_bRunGenerateCaustics = true;
1939                                break;
1940
1941                        case 'T':
1942                                g_fShadowIntensity -= bAltDown ? 0.1f : 0.01f;
1943                                if ( g_fShadowIntensity < 0 ) g_fShadowIntensity = 0;
1944                                g_HUD.GetSlider( IDC_SHADOW_INTENSITY_SLIDER )->SetValue( (int)g_fShadowIntensity * 100 );
1945                               
1946                                g_bRunGenerateCaustics = true;
1947                                break;
1948
1949
1950                        // Change the intensity of the caustics snippet
1951                        case 'U':
1952                                g_fCausticsIntensity -= bAltDown ? 0.1f : 0.01f;
1953                                if ( g_fCausticsIntensity < 0 ) g_fCausticsIntensity = 0;
1954
1955                                //g_fCausticsIntensity = pow ( 2.0f, g_HUD.GetSlider( IDC_CAUSTICS_INTENSITY_SLIDER )->GetValue() / 100.0f );
1956                                g_HUD.GetSlider( IDC_CAUSTICS_INTENSITY_SLIDER )->SetValue( (int)( log( g_fCausticsIntensity ) / log ( 1.2f ) ) * 100 );
1957
1958                                g_bRunGenerateCaustics = true;
1959                                break;
1960
1961                        case 'I':
1962                                g_fCausticsIntensity += bAltDown ? 0.1f : 0.01f;
1963                                g_HUD.GetSlider( IDC_CAUSTICS_INTENSITY_SLIDER )->SetValue( (int)(log( g_fCausticsIntensity ) / log ( 1.2f ) ) * 100 );
1964                                g_bRunGenerateCaustics = true;
1965                                break;
1966
1967                                       
1968                        // Change the refraction index
1969                        case 'E':
1970                                g_fRefractionIndex -= bAltDown ? 0.1f : 0.01f;
1971                                if (g_fRefractionIndex < 0) g_fRefractionIndex = 0;
1972                                g_HUD.GetSlider( IDC_REFRACTION_INDEX_SLIDER )->SetValue( (int)g_fRefractionIndex * 100 );
1973                               
1974                                g_bRunGenerateCaustics = true;
1975                                break;
1976
1977                        case 'R':
1978                                g_fRefractionIndex += bAltDown ? 0.1f : 0.01f;
1979                                if (g_fRefractionIndex > 1) g_fRefractionIndex = 1;
1980                                g_HUD.GetSlider( IDC_REFRACTION_INDEX_SLIDER )->SetValue( (int)g_fRefractionIndex * 100 );
1981                               
1982                                g_bRunGenerateCaustics = true;
1983                                break;
1984
1985
1986                        // Change Fresnel factor
1987                        case 'Q':               
1988                                g_fFresnelFactor -= bAltDown ? 0.1f : 0.01f;
1989                                if (g_fFresnelFactor < 0) g_fFresnelFactor = 0;
1990                                g_HUD.GetSlider( IDC_FRESNEL_FACTOR_SLIDER )->SetValue( (int)g_fFresnelFactor * 100 );
1991                               
1992                                g_bRunGenerateCaustics = true;
1993                                break;
1994                        case 'W':
1995                                g_fFresnelFactor += bAltDown ? 0.1f : 0.01f;
1996                                if (g_fFresnelFactor > 1) g_fFresnelFactor = 1;
1997                                g_HUD.GetSlider( IDC_FRESNEL_FACTOR_SLIDER )->SetValue( (int)g_fFresnelFactor * 100 );
1998                               
1999                                g_bRunGenerateCaustics = true;
2000                                break;
2001
2002
2003                        // Change PhotonMap size
2004                        case 'O':               
2005                                if( g_iPhotonMapSize > 1 )
2006                                {
2007                                        g_iPhotonMapSize /= 2;
2008                                        g_HUD.GetSlider( IDC_PHOTON_MAP_SIZE_SLIDER )->SetValue( (int) ( log( (float)g_iPhotonMapSize ) / log( 2.0f ) ) );
2009                                        CreateVertexBuffer();
2010                                        g_bRunGenerateCaustics = true;
2011                                }       
2012                                break;
2013
2014                        case 'P':
2015                                if( g_iPhotonMapSize < PHOTONMAP_MAX_SIZE )
2016                                {
2017                                        g_iPhotonMapSize *= 2;
2018                                        g_HUD.GetSlider( IDC_PHOTON_MAP_SIZE_SLIDER )->SetValue( (int) ( log( (float)g_iPhotonMapSize ) / log( 2.0f ) ) );
2019                                        CreateVertexBuffer();
2020                                        g_bRunGenerateCaustics = true;
2021                                }       
2022                                break;
2023
2024                        // Change the size of the snippet
2025                        case 'K':
2026                                g_fSnippetSize -= bAltDown ? 0.1f : 0.01f;
2027                                if( g_fSnippetSize < 0 ) g_fSnippetSize = 0;
2028                                g_HUD.GetSlider( IDC_SNIPPET_SIZE_SLIDER )->SetValue( (int)g_fSnippetSize * 100 );
2029
2030                                CreateVertexBuffer();
2031                                g_bRunGenerateCaustics = true;
2032                                break;
2033                        case 'L':
2034                                g_fSnippetSize += bAltDown ? 0.1f : 0.01f;
2035                                if( (int)g_fSnippetSize > SNIPPET_MAX_SIZE ) g_fSnippetSize = SNIPPET_MAX_SIZE;
2036                                g_HUD.GetSlider( IDC_SNIPPET_SIZE_SLIDER )->SetValue( (int)g_fSnippetSize * 100 );
2037
2038                                CreateVertexBuffer();
2039                                g_bRunGenerateCaustics = true;
2040                                break;
2041
2042
2043                        // Move CenterObject / Light Source
2044                        case VK_RIGHT: movement.x += STEP; break;
2045                        case VK_LEFT:  movement.x -= STEP; break;
2046                        case VK_UP:        movement.z += STEP; break;
2047                        case VK_DOWN:  movement.z -= STEP; break;
2048                        case VK_PRIOR: movement.y += STEP; break;
2049                        case VK_NEXT:  movement.y -= STEP; break;
2050        }
2051
2052                // Move Light Source
2053                if (bAltDown)
2054                {
2055                        g_vLightPos += movement;
2056                }
2057                // Move CenterObject
2058                else
2059                {
2060                        g_vCenterObjectPos += movement;
2061
2062                        // Refresh scaled World matrix of Center Mesh
2063                        g_mWorldCenterObject = ScaleAndOffset(g_fCenterObjectSize, g_vCenterObjectPos);
2064                }
2065    }
2066}
2067
2068
2069//--------------------------------------------------------------------------------------
2070// Handles the GUI events
2071//--------------------------------------------------------------------------------------
2072void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl )
2073{
2074    switch( nControlID )
2075    {
2076        case IDC_TOGGLEFULLSCREEN: DXUTToggleFullScreen(); break;
2077        case IDC_TOGGLEREF:        DXUTToggleREF(); break;
2078        case IDC_CHANGEDEVICE:     DXUTSetShowSettingsDialog( !DXUTGetShowSettingsDialog() ); break;
2079   
2080                case IDC_NUMBER_OF_ITERATION_SLIDER:
2081                        g_iNumberOfIteration = g_HUD.GetSlider( IDC_NUMBER_OF_ITERATION_SLIDER )->GetValue();
2082                        break;
2083
2084                case IDC_FRESNEL_FACTOR_SLIDER:
2085                        g_fFresnelFactor = g_HUD.GetSlider( IDC_FRESNEL_FACTOR_SLIDER )->GetValue() / 100.0f;
2086                        break;
2087
2088                case IDC_REFRACTION_INDEX_SLIDER:
2089                        g_fRefractionIndex = g_HUD.GetSlider( IDC_REFRACTION_INDEX_SLIDER )->GetValue() / 100.0f;
2090                        break;
2091
2092                case IDC_SHADOW_INTENSITY_SLIDER:
2093                        g_fShadowIntensity = g_HUD.GetSlider( IDC_SHADOW_INTENSITY_SLIDER )->GetValue() / 100.0f;
2094                        break;
2095
2096                case IDC_CAUSTICS_INTENSITY_SLIDER:
2097                        //g_fCausticsIntensity = g_HUD.GetSlider( IDC_CAUSTICS_INTENSITY_SLIDER )->GetValue() / 100.0f;
2098                        g_fCausticsIntensity = pow ( 1.2f, g_HUD.GetSlider( IDC_CAUSTICS_INTENSITY_SLIDER )->GetValue() / 100.0f );
2099                        break;
2100
2101                case IDC_SHADOW_CHECK_BOX:
2102                        g_bShadowON = ( g_HUD.GetCheckBox( IDC_SHADOW_CHECK_BOX )->GetChecked() );
2103                        break;
2104
2105                case IDC_CAUSTICS_CHECK_BOX:
2106                        g_bCausticsON = (g_HUD.GetCheckBox( IDC_CAUSTICS_CHECK_BOX )->GetChecked() );
2107                        break;
2108
2109                case IDC_CENTEROBJ_CHECK_BOX:
2110                        g_bRenderCenterObjectWithBrdfON = ( g_HUD.GetCheckBox( IDC_CENTEROBJ_CHECK_BOX )->GetChecked() );
2111                        break;
2112
2113                case IDC_SNIPPET_SIZE_IS_CONSTANT_CHECK_BOX:
2114                        g_bSnippetSizeIsConstant = ( g_HUD.GetCheckBox( IDC_SNIPPET_SIZE_IS_CONSTANT_CHECK_BOX )->GetChecked() );
2115                       
2116                        CreateVertexBuffer();
2117                        break;
2118
2119                case IDC_SHOW_PHOTON_MAP_CHECK_BOX:
2120                        g_bShowPhotonMap = ( g_HUD.GetCheckBox( IDC_SHOW_PHOTON_MAP_CHECK_BOX )->GetChecked() );
2121
2122                        break;
2123
2124                case IDC_CLASSIC_METHOD:
2125                case IDC_DISTANCE_IMPOSTOR_METHOD:
2126
2127                        if ( g_HUD.GetRadioButton( IDC_DISTANCE_IMPOSTOR_METHOD )->GetChecked() )
2128                                g_iAlgorithmMethod = 1;
2129                        else
2130                                g_iAlgorithmMethod = 0;
2131                        break;
2132
2133                case IDC_PHOTON_MAP_SIZE_SLIDER:
2134                        g_iPhotonMapSize = (int)pow( 2.0f, g_HUD.GetSlider( IDC_PHOTON_MAP_SIZE_SLIDER )->GetValue() );
2135
2136                        CreateVertexBuffer();
2137                        break;
2138
2139                case IDC_SNIPPET_SIZE_SLIDER:
2140                        g_fSnippetSize = g_HUD.GetSlider( IDC_SNIPPET_SIZE_SLIDER )->GetValue() / 100.0f;
2141
2142                        CreateVertexBuffer();
2143                        break;
2144
2145                case IDC_RESET_PARAMETERS_BUTTON:
2146                        // Reset the parameters of the algorithm
2147                        g_bShadowON = true;                                             
2148                        g_bCausticsON = true;                                   
2149                        g_bRenderCenterObjectWithBrdfON = true;
2150                        g_bShowPhotonMap = true;
2151
2152                        g_fFresnelFactor = 0.05f;               
2153                        g_fRefractionIndex = 0.9f;             
2154                        g_fShadowIntensity = 0.25f;             
2155                        g_fCausticsIntensity = 0.05f;   
2156                        g_fSnippetSize = 3.0f;                 
2157
2158                        g_iNumberOfIteration = 10;                     
2159                        g_iAlgorithmMethod = 1;                 
2160                        g_iPhotonMapSize = 64;                         
2161                       
2162                        // Reset the HUD
2163                        g_HUD.GetCheckBox( IDC_SHADOW_CHECK_BOX )->SetChecked( g_bShadowON );
2164                        g_HUD.GetCheckBox( IDC_CAUSTICS_CHECK_BOX )->SetChecked( g_bCausticsON );
2165                        g_HUD.GetCheckBox( IDC_CENTEROBJ_CHECK_BOX )->SetChecked( g_bRenderCenterObjectWithBrdfON );
2166                        g_HUD.GetCheckBox( IDC_SNIPPET_SIZE_IS_CONSTANT_CHECK_BOX )->SetChecked( g_bSnippetSizeIsConstant );
2167                        g_HUD.GetCheckBox( IDC_SHOW_PHOTON_MAP_CHECK_BOX )->SetChecked( g_bShowPhotonMap );
2168
2169                        g_HUD.GetRadioButton( IDC_DISTANCE_IMPOSTOR_METHOD )->SetChecked( true );
2170
2171                        g_HUD.GetSlider( IDC_NUMBER_OF_ITERATION_SLIDER )->SetValue( g_iNumberOfIteration );
2172                        g_HUD.GetSlider( IDC_FRESNEL_FACTOR_SLIDER )->SetValue( (int)( g_fFresnelFactor * 100 ) );
2173                        g_HUD.GetSlider( IDC_REFRACTION_INDEX_SLIDER )->SetValue( (int)( g_fRefractionIndex * 100 + 1 ) );
2174                        g_HUD.GetSlider( IDC_SHADOW_INTENSITY_SLIDER )->SetValue( (int)( g_fShadowIntensity * 100 ) );
2175                        g_HUD.GetSlider( IDC_CAUSTICS_INTENSITY_SLIDER )->SetValue( (int)( ( log( g_fCausticsIntensity ) / log ( 1.2f ) ) * 100.0f ) );
2176                        g_HUD.GetSlider( IDC_SNIPPET_SIZE_SLIDER )->SetValue( (int)g_fSnippetSize * 100 );
2177                        g_HUD.GetSlider( IDC_PHOTON_MAP_SIZE_SLIDER )->SetValue( (int)( log( (float)g_iPhotonMapSize ) / log( 2.0f ) ) );
2178
2179
2180                        CreateVertexBuffer();
2181                        g_bRunGenerateCaustics = true;
2182                        break;
2183        }
2184
2185        // Regenerate caustics to show changes
2186        g_bRunGenerateCaustics = true;
2187}
2188
2189
2190//--------------------------------------------------------------------------------------
2191// This callback function will be called immediately after the Direct3D device has
2192// entered a lost state and before IDirect3DDevice9::Reset is called. Resources created
2193// in the OnResetDevice callback should be released here, which generally includes all
2194// D3DPOOL_DEFAULT resources. See the "Lost Devices" section of the documentation for
2195// information about lost devices.
2196//--------------------------------------------------------------------------------------
2197void CALLBACK OnLostDevice()
2198{
2199    if( g_pFont )
2200        g_pFont->OnLostDevice();
2201    if( g_pEffect )
2202        g_pEffect->OnLostDevice();
2203   
2204        SAFE_RELEASE( g_pTextSprite );
2205
2206
2207        SAFE_RELEASE( g_pRoomCubeMapColorDistTexture );
2208        SAFE_RELEASE( g_pPowerOfSnippetTexelTexture );
2209        SAFE_RELEASE( g_pRoomCubeMapUVTexture );
2210        SAFE_RELEASE( g_pShadowMapTexture );
2211        SAFE_RELEASE( g_pRoomLastTexture );
2212        SAFE_RELEASE( g_pRoomModifyTexture );
2213        SAFE_RELEASE( g_pPhotonUVTexture );
2214        SAFE_RELEASE( g_pRoomTexture );
2215       
2216        for(int i = 0; i < 4; i++)
2217        {
2218                SAFE_RELEASE( g_pColumnModifyTexture[i] );
2219        }
2220        for(int i = 0; i < 5; i++)
2221        {
2222                SAFE_RELEASE( g_pColumnLastTexture[i] );
2223        }
2224         
2225        SAFE_RELEASE( g_pDepthStencilSurface );
2226        SAFE_RELEASE( g_pRoomCubeMapDepthStencilSurface );
2227        SAFE_RELEASE( g_pShadowMapDepthStencilSSurface );
2228        SAFE_RELEASE( g_pPhotonUVMapSurface );
2229        SAFE_RELEASE( g_pShadowMapSurface );
2230        SAFE_RELEASE( g_pPhotonMapDepthStencilSurface );
2231        SAFE_RELEASE( g_pRoomLastSurface );
2232        SAFE_RELEASE( g_pRoomModifySurface );
2233        SAFE_RELEASE( g_pRoomSurface );
2234       
2235        for(int i = 0; i < 4; i++)
2236        {
2237                SAFE_RELEASE( g_pColumnsModifySurface[i] );
2238        }
2239        for(int i = 0; i < 5; i++)
2240        {
2241                SAFE_RELEASE( g_pColumnsLastSurface[i] );
2242        }
2243       
2244        SAFE_RELEASE( g_pFullScreenQuadVertexDeclaration );
2245        SAFE_RELEASE( g_pFullScreenQuadVertexBuffer );
2246        SAFE_RELEASE( g_pSnippetVertexDeclaration );
2247        SAFE_RELEASE( g_bSnippetVertexBuffer );
2248}
2249
2250//--------------------------------------------------------------------------------------
2251// This callback function will be called immediately after the Direct3D device has
2252// been destroyed, which generally happens as a result of application termination or
2253// windowed/full screen toggles. Resources created in the OnCreateDevice callback
2254// should be released here, which generally includes all D3DPOOL_MANAGED resources.
2255//--------------------------------------------------------------------------------------
2256void CALLBACK OnDestroyDevice()
2257{
2258        SAFE_RELEASE( g_pFullScreenQuadVertexDeclaration );
2259        SAFE_RELEASE( g_pFullScreenQuadVertexBuffer );
2260        SAFE_RELEASE( g_pSnippetVertexDeclaration );
2261        SAFE_RELEASE( g_bSnippetVertexBuffer );
2262        SAFE_RELEASE( g_pCenterObjectMesh );
2263        SAFE_RELEASE( g_pColumnMesh );
2264        SAFE_RELEASE( g_pLightMesh );
2265        SAFE_RELEASE( g_pRoomMesh );
2266    SAFE_RELEASE( g_pEffect );
2267    SAFE_RELEASE( g_pFont );
2268}             
Note: See TracBrowser for help on using the repository browser.