source: GTP/trunk/App/Demos/Illum/Glow/Main.cpp @ 846

Revision 846, 36.2 KB checked in by szirmay, 18 years ago (diff)
Line 
1//--------------------------------------------------------------------------------------
2// Main.cpp:
3// - DirectX initialization
4// - create resources (textures)
5//--------------------------------------------------------------------------------------
6
7#include "dxstdafx.h"
8#include "resource.h"
9#include <math.h>
10#include <stdio.h>
11#include <D3dx9math.h>
12
13//#define DEBUG_VS   // Uncomment this line to debug vertex shaders
14//#define DEBUG_PS   // Uncomment this line to debug pixel shaders 
15
16#include "Parameters.h"
17#include "ToneMap.h"
18
19const int WIDTH = 720;
20const int HEIGHT = 480;
21const int CHARBUFFER_SIZE = 200;
22
23//--------------------------------------------------------------------------------------
24// Global variables
25//--------------------------------------------------------------------------------------
26
27IDirect3DDevice9*                       g_pd3dDevice = NULL;
28
29CDXUTDialogResourceManager      g_DialogResourceManager;        // manager for shared resources of dialogs
30CD3DSettingsDlg                         g_SettingsDlg;                          // Device settings dialog
31CDXUTDialog                                     g_HUD;                                          // Dialog for sample specific controls
32
33ID3DXFont*                                      g_pFont = NULL;                         // Font for drawing text
34ID3DXSprite*                            g_pTextSprite = NULL;           // Sprite for batching draw text calls
35
36IDirect3DSurface9*                      g_pSaveSurface;                         // screenshot capturing support
37bool                                            bSavingScreenshot = false;
38int                                                     counter = 0;
39// Dice mesh
40LPD3DXMESH              g_pMesh          = NULL; // Our mesh object in sysmem
41D3DMATERIAL9*           g_pMeshMaterials = NULL; // Materials for our mesh
42LPDIRECT3DTEXTURE9*     g_pMeshTextures  = NULL; // Textures for our mesh
43DWORD                   g_dwNumMaterials = 0L;   // Number of mesh materials
44LPD3DXBUFFER                    pD3DXMtrlBuffer;
45
46
47HRESULT hr;
48
49Parameters pp;                                                  // managing parameters of the algorithm
50CModelViewerCamera camera;                              // camera
51
52// ToneMapping object
53ToneMap *toneMap = new ToneMap();
54//Save texture
55IDirect3DTexture9* pSaveTexture = NULL;
56
57// Final sourface
58LPDIRECT3DTEXTURE9 sourceTexture;
59LPDIRECT3DSURFACE9 sourceTextureSurface;
60LPDIRECT3DSURFACE9 targetSurface;
61
62// Original cube
63LPDIRECT3DTEXTURE9 CubeTexture;
64LPDIRECT3DSURFACE9 CubeTextureSurface;
65
66// Glow surface
67LPDIRECT3DTEXTURE9 CubeGlowTexture;
68LPDIRECT3DSURFACE9 CubeGlowTextureSurface;
69
70// Temporary sourfaces for the glow calculation
71LPDIRECT3DTEXTURE9 TempTexture[3];
72LPDIRECT3DSURFACE9 TempTextureSurface[3];
73
74// Glow history surface
75LPDIRECT3DTEXTURE9 blurTexture;
76LPDIRECT3DTEXTURE9 prevTexture;
77LPDIRECT3DSURFACE9 blurTargetSurface;
78LPDIRECT3DTEXTURE9 blurTargetTexture;
79
80// Fullscreen triangle
81D3DVERTEX_1 rttVertices[3];
82LPDIRECT3DSURFACE9 rttDepthSurface;
83IDirect3DVertexDeclaration9* textureDecl;
84LPDIRECT3DVERTEXBUFFER9 pQuadVB;
85
86IDirect3DSurface9* oldRenderTarget = NULL;
87
88// Lighting
89D3DXVECTOR3 vecDir;
90D3DLIGHT9 light;
91
92
93// Rendering effects
94LPD3DXEFFECT CubeEffect;
95
96//--------------------------------------------------------------------------------------
97// Forward declarations (CALLBACK)
98//--------------------------------------------------------------------------------------
99bool    CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext );
100bool    CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps, void* pUserContext );
101HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* g_pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext );
102HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* g_pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext );
103void    CALLBACK OnFrameMove( IDirect3DDevice9* g_pd3dDevice, double fTime, float fElapsedTime, void* pUserContext );
104void    CALLBACK OnFrameRender( IDirect3DDevice9* g_pd3dDevice, double fTime, float fElapsedTime, void* pUserContext );
105LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing, void* pUserContext );
106void    CALLBACK KeyboardProc( UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext );
107void    CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext );
108void    CALLBACK OnLostDevice( void* pUserContext );
109void    CALLBACK OnDestroyDevice( void* pUserContext );
110void    InitApp();
111void    RenderText();
112
113//--------------------------------------------------------------------------------------
114// Forward declarations
115//--------------------------------------------------------------------------------------
116
117void SaveCameraPosition( char* fileName );
118void LoadCameraPosition( char* fileName );
119int GenerateNewFileName( int& counter );
120
121//-----------------------------------------------------------------------------
122// Name: InitGeometry()
123// Desc: Load the mesh and build the material and texture arrays
124//-----------------------------------------------------------------------------
125HRESULT InitGeometry()
126{   
127    // Load the mesh from the specified file
128        if( FAILED( D3DXLoadMeshFromX( L"dobokocka.x", D3DXMESH_MANAGED,
129                                   g_pd3dDevice, NULL,
130                                   &pD3DXMtrlBuffer, NULL, &g_dwNumMaterials,
131                                   &g_pMesh ) ) )
132    {
133        // If model is not in current folder, try parent folder
134        if( FAILED( D3DXLoadMeshFromX( L"..\\dobokocka.x", D3DXMESH_MANAGED,
135                                    g_pd3dDevice, NULL,
136                                    &pD3DXMtrlBuffer, NULL, &g_dwNumMaterials,
137                                    &g_pMesh ) ) )
138        {
139            MessageBox(NULL, L"Could not find dobokocka.x", L"Meshes.exe", MB_OK);
140            return E_FAIL;
141        }
142    }
143       
144
145    // We need to extract the material properties and texture names from the
146    // pD3DXMtrlBuffer
147    D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer();
148    g_pMeshMaterials = new D3DMATERIAL9[g_dwNumMaterials];
149    if( g_pMeshMaterials == NULL )
150        return E_OUTOFMEMORY;
151    g_pMeshTextures  = new LPDIRECT3DTEXTURE9[g_dwNumMaterials];
152    if( g_pMeshTextures == NULL )
153        return E_OUTOFMEMORY;
154
155    for( DWORD i=0; i<g_dwNumMaterials; i++ )
156    {
157        // Copy the material
158        g_pMeshMaterials[i] = d3dxMaterials[i].MatD3D;
159
160        // Set the ambient color for the material (D3DX does not do this)
161        g_pMeshMaterials[i].Ambient = g_pMeshMaterials[i].Diffuse;
162
163        g_pMeshTextures[i] = NULL;
164        if( d3dxMaterials[i].pTextureFilename != NULL &&
165            lstrlenA(d3dxMaterials[i].pTextureFilename) > 0 )
166        {
167            // Create the texture
168            if( FAILED( D3DXCreateTextureFromFileA( g_pd3dDevice,
169                                                d3dxMaterials[i].pTextureFilename,
170                                                &g_pMeshTextures[i] ) ) )
171            {
172                // If texture is not in current folder, try parent folder
173                const TCHAR* strPrefix = TEXT("..\\");
174                TCHAR strTexture[MAX_PATH];
175                StringCchCopy( strTexture, MAX_PATH, strPrefix );
176                StringCchCatA( (char*)strTexture, MAX_PATH, d3dxMaterials[i].pTextureFilename );
177                // If texture is not in current folder, try parent folder
178                if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice,
179                                                    strTexture,
180                                                    &g_pMeshTextures[i] ) ) )
181                {
182                    MessageBox(NULL, L"Could not find texture map", L"Meshes.exe", MB_OK);
183                }
184            }
185        }
186    }
187
188    // Done with the material buffer
189    //pD3DXMtrlBuffer->Release();
190
191    return S_OK;
192}
193
194//--------------------------------------------------------------------------------------
195// Entry point to the program. Initializes everything and goes into a message processing
196// loop. Idle time is used to render the scene.
197//--------------------------------------------------------------------------------------
198INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
199{
200    // Enable run-time memory check for debug builds.
201#if defined(DEBUG) | defined(_DEBUG)
202    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
203#endif
204
205    DXUTSetCallbackDeviceCreated( OnCreateDevice );
206    DXUTSetCallbackDeviceReset( OnResetDevice );
207    DXUTSetCallbackDeviceLost( OnLostDevice );
208    DXUTSetCallbackDeviceDestroyed( OnDestroyDevice );
209    DXUTSetCallbackMsgProc( MsgProc );
210    DXUTSetCallbackKeyboard( KeyboardProc );
211    DXUTSetCallbackFrameRender( OnFrameRender );
212    DXUTSetCallbackFrameMove( OnFrameMove );
213
214        InitApp();
215
216        // Show the cursor and clip it when in full screen
217    DXUTSetCursorSettings( true, true );
218
219        DXUTInit( true, true, true ); // Parse the command line, handle the default hotkeys, and show msgboxes
220    DXUTCreateWindow( L"Glowing Dice Demo" );
221    DXUTCreateDevice( D3DADAPTER_DEFAULT, true, WIDTH, HEIGHT, IsDeviceAcceptable, ModifyDeviceSettings );
222
223        camera.SetButtonMasks( 0, MOUSE_WHEEL, MOUSE_LEFT_BUTTON );
224
225    DXUTMainLoop();
226    return DXUTGetExitCode();
227}
228
229void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext )
230{
231        pp.UpdateFromHUD( nControlID );
232}
233
234void OnLoad() {
235        LoadCameraPosition( ".matrix" );
236}
237
238void OnSave() {
239        SaveCameraPosition( ".matrix" );
240        bSavingScreenshot = true;
241}
242
243void OnReset() {}
244
245void InitApp()
246{
247        g_SettingsDlg.Init( &g_DialogResourceManager );
248        g_HUD.Init( &g_DialogResourceManager );
249        g_HUD.SetCallback( OnGUIEvent );        // Event handling
250
251        pp.Setup( &g_HUD, OnReset, OnSave, OnLoad);     // you can add callbacks to these actions
252
253        // UI initialization
254        pp.Add( bShowHelp, "bShowHelp", VK_F1 );                                // checkboxes
255        pp.Add( bShowHud, "Hud", VK_F2 );
256       
257        pp.Add( iGain, "Gain", 800, VK_SUBTRACT, VK_ADD, myconvert );   // sliders
258        pp.SetFloat(iGain, 0.5f);
259        pp.Add( iPasses, "Passes", 400, VK_SUBTRACT, VK_ADD, myPassConvert );
260        pp.Add( iGlowPasses, "GlowPasses", 400, VK_SUBTRACT, VK_ADD, myGlowConvert );
261        pp.Add( iGlowGain, "GlowGain", 800, VK_SUBTRACT, VK_ADD, noconvert );
262        pp.Add( iStretch, "GlowStretch", 1000, VK_SUBTRACT, VK_ADD, stretchconvert );
263       
264        pp.UpdateFromHUD( IDC_RESET_BUTTON );   // do a reset
265}
266
267//--------------------------------------------------------------------------------------
268// Rejects any devices that aren't acceptable by returning false
269//--------------------------------------------------------------------------------------
270bool CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat,
271                                  D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext )
272{
273    // Skip backbuffer formats that don't support alpha blending
274    IDirect3D9* pD3D = DXUTGetD3DObject();
275    if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType,
276                    AdapterFormat, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING,
277                    D3DRTYPE_TEXTURE, BackBufferFormat ) ) )
278        return false;
279
280    return true;
281}
282
283//--------------------------------------------------------------------------------------
284// Before a device is created, modify the device settings as needed
285//--------------------------------------------------------------------------------------
286bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps, void* pUserContext )
287{
288        // VSync off
289        pDeviceSettings->pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
290
291    // If device doesn't support HW T&L or doesn't support 1.1 vertex shaders in HW
292    // then switch to SWVP.
293    if( (pCaps->DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == 0 ||
294         pCaps->VertexShaderVersion < D3DVS_VERSION(1,1) )
295                pDeviceSettings->BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
296    else
297                pDeviceSettings->BehaviorFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
298
299    // This application is designed to work on a pure device by not using
300    // IDirect3D9::Get*() methods, so create a pure device if supported and using HWVP.
301    if ((pCaps->DevCaps & D3DDEVCAPS_PUREDEVICE) != 0 &&
302        (pDeviceSettings->BehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING) != 0 )
303        pDeviceSettings->BehaviorFlags |= D3DCREATE_PUREDEVICE;
304
305    // Debugging vertex shaders requires either REF or software vertex processing
306    // and debugging pixel shaders requires REF. 
307#ifdef DEBUG_VS
308    if( pDeviceSettings->DeviceType != D3DDEVTYPE_REF )
309    {
310        pDeviceSettings->BehaviorFlags &= ~D3DCREATE_HARDWARE_VERTEXPROCESSING;
311        pDeviceSettings->BehaviorFlags &= ~D3DCREATE_PUREDEVICE;                           
312        pDeviceSettings->BehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
313    }
314#endif
315#ifdef DEBUG_PS
316    pDeviceSettings->DeviceType = D3DDEVTYPE_REF;
317#endif
318
319        // For the first device created if its a REF device, optionally display a warning dialog box
320    static bool s_bFirstTime = true;
321    if( s_bFirstTime )
322    {
323        s_bFirstTime = false;
324        if( pDeviceSettings->DeviceType == D3DDEVTYPE_REF )
325            DXUTDisplaySwitchingToREFWarning();
326    }
327        return true;
328}
329
330//--------------------------------------------------------------------------------------
331// Create any D3DPOOL_MANAGED resources here
332//--------------------------------------------------------------------------------------
333HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
334{
335        ::g_pd3dDevice = pd3dDevice;
336
337        //InitGeometry();
338
339    HRESULT hr;
340
341    V_RETURN( g_DialogResourceManager.OnCreateDevice( g_pd3dDevice ) );
342    V_RETURN( g_SettingsDlg.OnCreateDevice( g_pd3dDevice ) );
343
344    // Initialize the font
345    V_RETURN( D3DXCreateFont( g_pd3dDevice, 15, 0, FW_BOLD, 1, FALSE, DEFAULT_CHARSET,
346                         OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE,
347                         L"Arial", &g_pFont ) );
348
349        float initialEyeDist = 10;
350        D3DXVECTOR3 vecEye(0, 0, -initialEyeDist);
351        D3DXVECTOR3 vecAt (0.0f, 0.0f, -0.0f);
352        camera.SetViewParams( &vecEye, &vecAt );
353
354        // Error Buffer
355        LPD3DXBUFFER errBuff;
356        DWORD effectCompileFlag = 0;
357
358        // Shader options for debuging
359        #ifdef DEBUG_SHADER
360        effectCompileFlag|=D3DXSHADER_DEBUG;
361        effectCompileFlag |= D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT;
362        effectCompileFlag |= D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT;
363        #endif
364
365        // Create the tone mapping effect from file
366        hr = D3DXCreateEffectFromFile(g_pd3dDevice,L"Cube.fx",NULL,NULL,effectCompileFlag,NULL,&CubeEffect,&errBuff);
367        if(hr!=S_OK){
368                int BufSize = errBuff->GetBufferSize();
369
370                // displaying error message of arbitrary length
371                wchar_t* wbuf = new wchar_t[BufSize];
372                mbstowcs( wbuf, (const char*)errBuff->GetBufferPointer(), BufSize );
373                MessageBox(NULL, wbuf, L".fx Compilation Error", MB_ICONERROR);         // show error message
374
375                delete wbuf;
376                return hr;
377        }
378        SAFE_RELEASE(errBuff);
379
380        rttVertices[0] = D3DVERTEX_1(-3,1,0,1, -1.0f, 0.0f);
381        rttVertices[1] = D3DVERTEX_1(1,1,0,1, 1.0f, 0.0f);
382        rttVertices[2] = D3DVERTEX_1(1, -3,0,1, 1.0f, 2.0f);
383
384        //Vertex declaration
385        D3DVERTEXELEMENT9 _texturedecl[]=
386        {
387                {0,0,D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,0 },
388                {0,16,D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,0 },
389                D3DDECL_END()
390        };
391        V(pd3dDevice->CreateVertexDeclaration(_texturedecl,&textureDecl));
392        V(pd3dDevice->CreateVertexBuffer(sizeof(D3DVERTEX_1)*3,D3DUSAGE_WRITEONLY,D3DFVF_CUSTOMVERTEX,D3DPOOL_MANAGED,&pQuadVB,NULL));
393        void *pData;
394
395        pQuadVB->Lock(0,sizeof(pData),(void**)&pData,0);
396        memcpy(pData,rttVertices,sizeof(D3DVERTEX_1)*3);
397        pQuadVB->Unlock();
398
399        // fixed function lighting
400        ZeroMemory( &light, sizeof(light) );
401        light.Type = D3DLIGHT_DIRECTIONAL;
402        light.Diffuse.r = 0.0f;
403        light.Diffuse.g = 0.0f;
404        light.Diffuse.b = 1.0f;
405
406        return S_OK;
407}
408
409//--------------------------------------------------------------------------------------
410// Release resources created in the OnCreateDevice callback here
411//--------------------------------------------------------------------------------------
412void CALLBACK OnDestroyDevice( void* pUserContext )
413{
414   g_DialogResourceManager.OnDestroyDevice();
415     g_SettingsDlg.OnDestroyDevice();
416        SAFE_RELEASE(g_pFont);
417       
418    SAFE_RELEASE(CubeEffect);
419
420        SAFE_RELEASE(textureDecl);
421        SAFE_RELEASE(pQuadVB);
422}
423
424
425//--------------------------------------------------------------------------------------
426// Create any D3DPOOL_DEFAULT resources here
427//--------------------------------------------------------------------------------------
428HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* g_pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
429{
430    HRESULT hr;
431
432        InitGeometry();
433       
434    V_RETURN( g_DialogResourceManager.OnResetDevice() );
435   V_RETURN( g_SettingsDlg.OnResetDevice() );
436
437    if( g_pFont )   V_RETURN( g_pFont->OnResetDevice() );
438
439    // Create a sprite to help batch calls when drawing many lines of text
440    V_RETURN( D3DXCreateSprite( g_pd3dDevice, &g_pTextSprite ) );
441       
442        // Setup the camera's projection parameters
443    float fAspectRatio = pBackBufferSurfaceDesc->Width / (FLOAT)pBackBufferSurfaceDesc->Height;
444
445        camera.SetProjParams( D3DX_PI/4, fAspectRatio, 0.1, 100 );
446    camera.SetWindow( pBackBufferSurfaceDesc->Width, pBackBufferSurfaceDesc->Height );
447
448        // target description
449        D3DSURFACE_DESC desc = *pBackBufferSurfaceDesc;
450        //targetSurface->GetDesc(&desc);
451
452        // final image
453        g_pd3dDevice->CreateTexture(desc.Width,desc.Height,0,D3DUSAGE_RENDERTARGET,D3DFMT_A16B16G16R16F,D3DPOOL_DEFAULT,&sourceTexture,NULL);
454        sourceTexture->GetSurfaceLevel(0,&sourceTextureSurface);
455
456        // dice
457        g_pd3dDevice->CreateTexture(desc.Width,desc.Height,0,D3DUSAGE_RENDERTARGET,D3DFMT_A16B16G16R16F,D3DPOOL_DEFAULT,&CubeTexture,NULL);
458        CubeTexture->GetSurfaceLevel(0,&CubeTextureSurface);
459
460        // glow
461        g_pd3dDevice->CreateTexture(desc.Width / 4,desc.Height / 4,0,D3DUSAGE_RENDERTARGET,D3DFMT_A16B16G16R16F,D3DPOOL_DEFAULT,&CubeGlowTexture,NULL);
462        CubeGlowTexture->GetSurfaceLevel(0,&CubeGlowTextureSurface);
463
464        // temporary
465        g_pd3dDevice->CreateTexture(desc.Width / 4,desc.Height / 4,0,D3DUSAGE_RENDERTARGET,D3DFMT_A16B16G16R16F,D3DPOOL_DEFAULT,&TempTexture[0],NULL);
466        TempTexture[0]->GetSurfaceLevel(0,&TempTextureSurface[0]);
467        g_pd3dDevice->CreateTexture(desc.Width / 4,desc.Height / 4,0,D3DUSAGE_RENDERTARGET,D3DFMT_A16B16G16R16F,D3DPOOL_DEFAULT,&TempTexture[1],NULL);
468        TempTexture[1]->GetSurfaceLevel(0,&TempTextureSurface[1]);
469        g_pd3dDevice->CreateTexture(desc.Width / 4,desc.Height / 4,0,D3DUSAGE_RENDERTARGET,D3DFMT_A16B16G16R16F,D3DPOOL_DEFAULT,&TempTexture[2],NULL);
470        TempTexture[2]->GetSurfaceLevel(0,&TempTextureSurface[2]);
471
472        // clear glow history
473       
474        V( g_pd3dDevice->GetRenderTarget(0, &oldRenderTarget) );       
475        g_pd3dDevice->SetRenderTarget(0, TempTextureSurface[2]);
476        g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
477                         D3DCOLOR_XRGB(0,0,0), 1.0f, 0 );
478        g_pd3dDevice->SetRenderTarget(0, oldRenderTarget);
479       
480       
481        V(g_pd3dDevice->CreateDepthStencilSurface(desc.Width,desc.Height,D3DFMT_D16,D3DMULTISAMPLE_NONE ,0,true,&rttDepthSurface,NULL));
482
483        CubeEffect->OnResetDevice();
484       
485        // init tonemap
486        toneMap->Init(g_pd3dDevice, sourceTexture, oldRenderTarget);
487       
488
489    return S_OK;
490}
491
492//--------------------------------------------------------------------------------------
493// Release resources created in the OnResetDevice callback here
494//--------------------------------------------------------------------------------------
495void CALLBACK OnLostDevice( void* pUserContext )
496{
497   g_DialogResourceManager.OnLostDevice();
498    g_SettingsDlg.OnLostDevice();
499
500     if( g_pFont )      g_pFont->OnLostDevice();
501         SAFE_RELEASE(g_pTextSprite);
502
503        if( g_pMesh != NULL )
504        SAFE_RELEASE(g_pMesh);
505
506        pD3DXMtrlBuffer->Release();
507
508    if( g_pMeshTextures )
509    {
510        for( DWORD i = 0; i < g_dwNumMaterials; i++ )
511        {
512            if( g_pMeshTextures[i] )
513                        {
514                SAFE_RELEASE(g_pMeshTextures[i]);
515                        }
516        }
517    }
518        g_pMeshTextures = 0;
519 
520        SAFE_RELEASE(sourceTextureSurface);
521        SAFE_RELEASE(sourceTexture);
522
523        SAFE_RELEASE(CubeTexture);
524        SAFE_RELEASE(CubeTextureSurface)
525
526        SAFE_RELEASE(CubeGlowTexture);
527        SAFE_RELEASE(CubeGlowTextureSurface);
528
529        SAFE_RELEASE(TempTexture[0]);
530        SAFE_RELEASE(TempTextureSurface[0]);
531        SAFE_RELEASE(TempTexture[1]);
532        SAFE_RELEASE(TempTextureSurface[1]);
533        SAFE_RELEASE(TempTexture[2]);
534        SAFE_RELEASE(TempTextureSurface[2]);
535
536        SAFE_RELEASE(rttDepthSurface);
537
538        SAFE_RELEASE(oldRenderTarget);
539
540        toneMap->Destroy();
541        CubeEffect->OnLostDevice();
542}
543
544LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing, void* pUserContext )
545{
546    // Always allow dialog resource manager calls to handle global messages
547    // so GUI state is updated correctly
548    *pbNoFurtherProcessing = g_DialogResourceManager.MsgProc( hWnd, uMsg, wParam, lParam );
549    if( *pbNoFurtherProcessing )
550        return 0;
551
552    if( g_SettingsDlg.IsActive() )
553    {
554        g_SettingsDlg.MsgProc( hWnd, uMsg, wParam, lParam );
555        return 0;
556    }
557
558        // Give the dialogs a chance to handle the message first
559    *pbNoFurtherProcessing = g_HUD.MsgProc( hWnd, uMsg, wParam, lParam );
560    if( *pbNoFurtherProcessing )
561        return 0;
562
563    // Pass all remaining windows messages to camera so it can respond to user input
564        camera.HandleMessages( hWnd, uMsg, wParam, lParam );
565
566    return 0;
567}
568
569//--------------------------------------------------------------------------------------
570// Handle updates to the scene
571//--------------------------------------------------------------------------------------
572void CALLBACK OnFrameMove( IDirect3DDevice9* g_pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
573{
574    camera.FrameMove( fElapsedTime );
575}
576
577//--------------------------------------------------------------------------------------
578// Render the scene
579//--------------------------------------------------------------------------------------
580void CALLBACK OnFrameRender( IDirect3DDevice9* g_pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
581{
582    // If the settings dialog is being shown, then
583    // render it instead of rendering the app's scene
584    if( g_SettingsDlg.IsActive() )
585    {
586        g_SettingsDlg.OnRender( fElapsedTime );
587        return;
588    }
589
590        // ligth rotating
591        vecDir = D3DXVECTOR3(cosf(timeGetTime()/360.0f),
592                     0.0f,
593                     sinf(timeGetTime()/360.0f) );
594        D3DXVec3Normalize( (D3DXVECTOR3*)&light.Direction, &vecDir );
595        light.Range = 1000.0f;
596        g_pd3dDevice->SetLight( 0, &light );
597        g_pd3dDevice->LightEnable( 0, TRUE);
598        g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
599        g_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0x00202020 );
600       
601        // screen shot
602        //      IDirect3DSurface9* oldRenderTarget = NULL;
603        if (bSavingScreenshot) {
604        //      V( g_pd3dDevice->GetRenderTarget(0, &oldRenderTarget) );       
605                V( g_pd3dDevice->SetRenderTarget(0, g_pSaveSurface) );
606        }
607
608        // ModelViewProjection matrix
609                        D3DXMATRIXA16 mView = *camera.GetViewMatrix();
610                        D3DXMATRIXA16 mProj = *camera.GetProjMatrix();
611                        D3DXMATRIXA16 mMVP = mView * mProj;
612
613                        // Original image
614                        g_pd3dDevice->SetRenderTarget(0, CubeTextureSurface);
615                        V( g_pd3dDevice->SetDepthStencilSurface(rttDepthSurface) );
616       
617                        // Clear the backbuffer and the zbuffer
618                        g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
619                         D3DCOLOR_XRGB(0,0,0), 1.0f, 0 );       
620
621                        if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
622                    {
623                                UINT numberofPasses=0;
624                                D3DXHANDLE techniqueHandle = CubeEffect->GetTechniqueByName("Cube");
625                                V(CubeEffect->SetTechnique(techniqueHandle));
626                               
627                                V(CubeEffect->SetMatrix("modelViewProjection", &mMVP));
628                                V(CubeEffect->Begin(&numberofPasses,0));
629                                for(UINT i = 0; i<numberofPasses; i++ )
630                                {
631                                V(CubeEffect->BeginPass(i));
632                       
633                                // Meshes are divided into subsets, one for each material. Render them in
634                                // a loop
635                                for( DWORD i=0; i<g_dwNumMaterials; i++ )
636                                {
637                                        // Set the material and texture for this subset
638                                        g_pd3dDevice->SetMaterial( &g_pMeshMaterials[i] );
639                                        //g_pd3dDevice->SetTexture( 0, g_pMeshTextures[i] );
640                                        V(CubeEffect->SetTexture("SourceTexture", g_pMeshTextures[i]));
641                                        CubeEffect->CommitChanges();
642                   
643                                        // Draw the mesh subset
644                                        g_pMesh->DrawSubset( i );
645                                }
646                       
647                                V(CubeEffect->EndPass());
648                        }
649                        V(CubeEffect->End());
650                        g_pd3dDevice->EndScene();
651    }
652
653                        // Glow texture
654                        g_pd3dDevice->SetRenderTarget(0, CubeGlowTextureSurface);
655                        V( g_pd3dDevice->SetDepthStencilSurface(rttDepthSurface) );
656                        g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
657                         D3DCOLOR_XRGB(0,0,0), 1.0f, 0 );
658                        if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
659                    {
660                                UINT numberofPasses=0;
661                                D3DXHANDLE techniqueHandle = CubeEffect->GetTechniqueByName("CubeGlow");
662                                V(CubeEffect->SetTechnique(techniqueHandle));
663                               
664                                V(CubeEffect->SetMatrix("modelViewProjection", &mMVP));
665                                V(CubeEffect->Begin(&numberofPasses,0));
666                                for(UINT i = 0; i<numberofPasses; i++ )
667                                {
668                                V(CubeEffect->BeginPass(i));
669                       
670                                // Meshes are divided into subsets, one for each material. Render them in
671                                // a loop
672                                for( DWORD i=0; i<g_dwNumMaterials; i++ )
673                                {
674                                        // Set the material and texture for this subset
675                                        g_pd3dDevice->SetMaterial( &g_pMeshMaterials[i] );
676                                        //g_pd3dDevice->SetTexture( 0, g_pMeshTextures[i] );
677                                        V(CubeEffect->SetTexture("SourceTexture", g_pMeshTextures[i]));
678                                        CubeEffect->CommitChanges();
679                   
680                                        // Draw the mesh subset
681                                        g_pMesh->DrawSubset( i );
682                                }
683                       
684                                V(CubeEffect->EndPass());
685                        }
686                        V(CubeEffect->End());
687                        g_pd3dDevice->EndScene();
688    }
689
690        // Blurring
691        // For each passes we cycle the temporary textures
692        // At least two passes need, one for the horizontal and one for
693        // the vertical blur
694                        int blurPass = 2;
695                        char* blurName = "Blur_h";
696
697                        for (int i = 0; i< pp.Get(iGlowPasses); i++) {
698                                switch (blurPass) {
699                                        case(0) : blurTargetSurface = TempTextureSurface[1];
700                                                          blurTargetTexture = TempTexture[1];
701                                                          blurTexture = TempTexture[0];
702                                                          blurPass = 1;
703                                                          blurName="Blur_h";
704                                                          break;
705                                        case(1) : blurTargetSurface = TempTextureSurface[0];
706                                                          blurTargetTexture = TempTexture[0];
707                                                          blurTexture = TempTexture[1];
708                                                          blurPass = 0;
709                                                          blurName="Blur_v";
710                                                          break;
711
712                                        case(2) : blurTargetSurface = TempTextureSurface[0];
713                                                          blurTargetTexture = TempTexture[0];
714                                                          blurTexture = CubeGlowTexture;
715                                                          blurPass = 0;
716                                                          blurName="Blur_v";
717                                                          break;
718                                }
719
720
721                        D3DSURFACE_DESC desc;
722                        blurTargetSurface->GetDesc(&desc);
723
724                        g_pd3dDevice->SetRenderTarget(0, blurTargetSurface);
725                        V( g_pd3dDevice->SetDepthStencilSurface(rttDepthSurface) );
726                        V( g_pd3dDevice->SetVertexDeclaration(textureDecl) );
727                        g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
728                         D3DCOLOR_XRGB(0,0,0), 1.0f, 0 );
729                        if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
730                    {
731                                UINT numberofPasses=0;
732                                D3DXHANDLE techniqueHandle = CubeEffect->GetTechniqueByName(blurName);
733                                V(CubeEffect->SetTechnique(techniqueHandle));
734                               
735                                D3DXMatrixIdentity(&mMVP);
736                                V(CubeEffect->SetMatrix("modelViewProjection", &mMVP));
737                                V(CubeEffect->SetTexture("OldGlow", TempTexture[2]));
738                                V(CubeEffect->SetTexture("Glow", blurTexture));
739                                V(CubeEffect->SetFloat("dsWidth", desc.Width));
740                                V(CubeEffect->SetFloat("dsHeight", desc.Height));
741                                V(CubeEffect->SetFloat("GlowPasses", pp.GetInt(iGlowPasses)));
742                                V(CubeEffect->SetFloat("GlowGain", pp.Get(iGlowGain)));
743                                V(CubeEffect->SetFloat("Stretch", pp.Get(iStretch)));
744                                V(CubeEffect->Begin(&numberofPasses,0));
745                                for(UINT i = 0; i<numberofPasses; i++ )
746                                {
747                                V(CubeEffect->BeginPass(i));
748                       
749                                //Render triangle.
750                                V(g_pd3dDevice->SetStreamSource(0,pQuadVB,0,sizeof(D3DVERTEX_1)));
751                                V(g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST,0,1));
752                       
753                                V(CubeEffect->EndPass());
754                        }
755                        V(CubeEffect->End());
756                        g_pd3dDevice->EndScene();
757                        }
758                        }
759
760
761
762        // Final compositing
763        // The final image is composed from the original image and
764        // the additive glow image
765                        g_pd3dDevice->SetRenderTarget(0, sourceTextureSurface);
766                        V( g_pd3dDevice->SetDepthStencilSurface(rttDepthSurface) );
767                        V( g_pd3dDevice->SetVertexDeclaration(textureDecl) );
768                        g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
769                         D3DCOLOR_XRGB(0,0,0), 1.0f, 0 );
770                        if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
771                    {
772                                UINT numberofPasses=0;
773                                D3DXHANDLE techniqueHandle = CubeEffect->GetTechniqueByName("Final");
774                                V(CubeEffect->SetTechnique(techniqueHandle));
775                               
776                                D3DXMatrixIdentity(&mMVP);
777                                V(CubeEffect->SetMatrix("modelViewProjection", &mMVP));
778                                V(CubeEffect->SetTexture("Original", CubeTexture));
779                                V(CubeEffect->SetTexture("Glow", blurTargetTexture));
780                                //V(CubeEffect->SetTexture("Glow", CubeGlowTexture));
781                                V(CubeEffect->Begin(&numberofPasses,0));
782                                for(UINT i = 0; i<numberofPasses; i++ )
783                                {
784                                V(CubeEffect->BeginPass(i));
785                       
786                                //Render triangle.
787                                V(g_pd3dDevice->SetStreamSource(0,pQuadVB,0,sizeof(D3DVERTEX_1)));
788                                V(g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST,0,1));
789                       
790                                V(CubeEffect->EndPass());
791                        }
792                        V(CubeEffect->End());
793                        g_pd3dDevice->EndScene();
794    }
795                        // Saving the blur history
796                        g_pd3dDevice->StretchRect(blurTargetSurface, NULL, TempTextureSurface[2], NULL, D3DTEXF_LINEAR);
797       
798                        // Tone mapping
799                        toneMap->SetSource(sourceTexture);
800                        g_pd3dDevice->SetRenderTarget(0, oldRenderTarget);
801                        toneMap->SetGain(pp.Get(iGain));
802                        toneMap->SetPasses(pp.Get(iPasses));
803                        toneMap->Map();
804
805                        // Screen shot
806                        if (!bSavingScreenshot && pp.Get(bShowHud))
807                        {
808                                RenderText();
809                                V( g_HUD.OnRender( fElapsedTime ) );
810                        }
811
812        if (bSavingScreenshot)
813        {
814                // saving surface
815                char buf[CHARBUFFER_SIZE];
816                wchar_t wbuf[CHARBUFFER_SIZE];
817
818                GenerateNewFileName( counter );
819                sprintf(buf, "shots\\%03i.png", counter);
820                mbstowcs( wbuf, buf, CHARBUFFER_SIZE );
821
822                D3DXSaveSurfaceToFileW(wbuf, D3DXIFF_PNG, g_pSaveSurface, NULL, NULL);
823
824                sprintf(buf, "shots\\%03i", counter);
825                pp.SaveToFile( buf );
826
827                sprintf(buf, "shots\\%03i.matrix", counter);
828                SaveCameraPosition( buf );
829
830                g_pd3dDevice->SetRenderTarget(0, oldRenderTarget);
831                bSavingScreenshot = false;
832        }
833}
834
835int GenerateNewFileName( int& counter )
836{
837        char buf[CHARBUFFER_SIZE];
838        FILE* f;
839        do {
840                sprintf(buf, "shots\\%03i.png", counter);
841                if ( (f = fopen(buf, "rt")) != NULL )
842                {
843                        fclose( f );
844                        counter++;
845                }
846        } while (f != NULL);
847        return counter;
848}
849
850//--------------------------------------------------------------------------------------
851// The framework does not remove the underlying keystroke messages,
852// which are still passed to the application's MsgProc callback.
853//--------------------------------------------------------------------------------------
854void CALLBACK KeyboardProc( UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext )
855{
856
857}
858
859void SaveCameraPosition( char* fileName )
860{
861        // save parameters to file:
862        // world matrix (4x4)
863        // camera position (3)
864
865        // save world matrix
866        D3DXMATRIXA16 W = *camera.GetViewMatrix();
867
868        FILE* f;
869
870        if ((f = fopen(fileName, "wt")) == NULL)
871        {
872                wchar_t wbuf[CHARBUFFER_SIZE];
873                mbstowcs( wbuf, fileName, CHARBUFFER_SIZE );
874        MessageBox(NULL, wbuf, L"File creation failed!", MB_ICONEXCLAMATION);
875                return;
876        }
877
878        fprintf(f, "\n");
879        fprintf(f, "World matrix:\n");
880        fprintf(f, "%10.4g %10.4g %10.4g %10.4g\n", W._11, W._12, W._13, W._14);
881        fprintf(f, "%10.4g %10.4g %10.4g %10.4g\n", W._21, W._22, W._23, W._24);
882        fprintf(f, "%10.4g %10.4g %10.4g %10.4g\n", W._31, W._32, W._33, W._34);
883        fprintf(f, "%10.4g %10.4g %10.4g %10.4g\n", W._41, W._42, W._43, W._44);
884
885        // save camera position
886        fprintf(f, "\n");
887        fprintf(f, "Camera position:\n");
888        const D3DXVECTOR3* eye = camera.GetEyePt();
889        fprintf(f, "%10g %10g %10g", eye->x, eye->y, eye->z);
890        fprintf(f, "\n");
891
892        fclose(f);
893}
894
895void LoadCameraPosition( char* fileName )
896{
897        FILE* f;
898
899        if ((f = fopen(fileName, "rt")) == NULL) {
900                wchar_t wbuf[CHARBUFFER_SIZE];
901                mbstowcs( wbuf, fileName, CHARBUFFER_SIZE );
902        MessageBox(NULL, wbuf, L"File not found!", MB_ICONEXCLAMATION);
903                return;
904        }
905
906        const int BufSize = 500;        // size of char buffers
907        char buf[BufSize];
908        D3DXMATRIXA16 W;
909
910        fgets(buf, BufSize, f);         // skip comment
911        fgets(buf, BufSize, f);         // skip comment
912        fgets(buf, BufSize, f);         sscanf(buf, "%f %f %f %f", &W._11, &W._12, &W._13, &W._14);
913        fgets(buf, BufSize, f);         sscanf(buf, "%f %f %f %f", &W._21, &W._22, &W._23, &W._24);
914        fgets(buf, BufSize, f);         sscanf(buf, "%f %f %f %f", &W._31, &W._32, &W._33, &W._34);
915        fgets(buf, BufSize, f);         sscanf(buf, "%f %f %f %f", &W._41, &W._42, &W._43, &W._44);
916
917        // load camera position
918        D3DXVECTOR3 vecAt(0.0f, 0.0f, 0.0f);
919        D3DXVECTOR3 vecEye;
920        fgets(buf, BufSize, f);         // skip comment
921        fgets(buf, BufSize, f);         // skip comment
922        fgets(buf, BufSize, f);         sscanf(buf, "%f %f %f", &vecEye.x, &vecEye.y, &vecEye.z);
923
924        fclose(f);
925
926        camera.SetViewParams( &vecEye, &vecAt );
927
928        D3DXQUATERNION q;
929        D3DXQuaternionRotationMatrix(&q, &W);
930        camera.SetViewQuat(q);
931}
932
933//--------------------------------------------------------------------------------------
934// Util function.
935// Creates an empty texture. These textures will be used as render targets, therefore
936// the Usage flag is set to D3DUSAGE_RENDERTARGET and consequently, the assigned
937// memory pool is D3DPOOL_DEFAULT.
938// Params: size and format (eg. D3DFMT_A32B32G32R32F) of the new texture.
939//--------------------------------------------------------------------------------------
940IDirect3DTexture9* CreateTexture( int size, D3DFORMAT Format )
941{
942        HRESULT hr;
943        IDirect3DTexture9* pTexture;
944        V( g_pd3dDevice->CreateTexture( size, size,             // dimensions
945                                                                        1,                              // mipmap levels
946                                                                        D3DUSAGE_RENDERTARGET, // usage
947                                                                        Format,                 
948                                                                        D3DPOOL_DEFAULT,// memory pool
949                                                                        &pTexture, NULL ) );
950        return pTexture;
951}
952
953//--------------------------------------------------------------------------------------
954// Util function.
955// Creates an empty cubemap texture of the given resolution and format.
956//--------------------------------------------------------------------------------------
957
958IDirect3DCubeTexture9* CreateCubeTexture( int size, D3DFORMAT Format )
959{
960        HRESULT hr;
961        IDirect3DCubeTexture9* pCubeTexture;
962        V( g_pd3dDevice->CreateCubeTexture(     size, 1, D3DUSAGE_RENDERTARGET,
963                                                                                Format, D3DPOOL_DEFAULT, &pCubeTexture, NULL ) );
964        return pCubeTexture;
965}
966
967
968//--------------------------------------------------------------------------------------
969// Render the help and statistics text.
970//--------------------------------------------------------------------------------------
971void RenderText()
972{
973        const D3DSURFACE_DESC* backBufferDesc = DXUTGetBackBufferSurfaceDesc();
974
975    CDXUTTextHelper txtHelper( g_pFont, g_pTextSprite, 15 );
976    txtHelper.Begin();
977
978        txtHelper.SetInsertionPos( 5, 5 );
979        txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 0.0f, 1.0f ) );
980
981        txtHelper.DrawFormattedTextLine( L"%.2f fps @ %i x %i",
982                DXUTGetFPS(), backBufferDesc->Width, backBufferDesc->Height );
983        //txtHelper.DrawTextLine( DXUTGetFrameStats() );
984        txtHelper.DrawTextLine( DXUTGetDeviceStats() );
985        txtHelper.DrawTextLine( L"" );
986       
987        txtHelper.SetInsertionPos( 5, 140 );
988        txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ) );
989
990        if ( pp.Get( bShowHelp ) )
991        {
992                txtHelper.SetInsertionPos( backBufferDesc->Width - 260, backBufferDesc->Height-24*15 );
993
994                txtHelper.DrawTextLine(
995                                L"Controls (F1 to hide):\n\n"
996                                L"___________________________________\n"
997                                L"                     GENERAL CONTROLS\n"     
998                                L"F2: Settings\n"
999                                L"F3: Switch to REF device\n"
1000                                L"F8: Switch to Wireframe mode\n"
1001                                L"___________________________________\n"
1002                                L"                             ALGORITHM\n"
1003                                L"Add and Subtract: adjust gain\n"     
1004                                L"___________________________________\n"
1005                                L"                             Quit: ESC");
1006        }
1007        else
1008        {
1009                txtHelper.DrawTextLine( L"Press F1 for help" );
1010        }
1011
1012        txtHelper.End();
1013}
Note: See TracBrowser for help on using the repository browser.