source: GTP/trunk/App/Demos/Illum/EnvMap/Main.cpp @ 1672

Revision 1672, 30.0 KB checked in by szirmay, 18 years ago (diff)
Line 
1/**
2  \file
3  \brief Performs DirectX initialization via DXUT callback functions.
4  \brief Adds some additional helper functions to support screenshot capturing.
5
6  \author Istvan Lazanyi, TU Budapest
7  \date   2006-04-26
8*/
9
10#include "dxstdafx.h"
11#include "resource.h"
12#include <math.h>
13#include <stdio.h>
14#include <time.h>
15
16//#define DEBUG_VS   // Uncomment this line to debug vertex shaders
17//#define DEBUG_PS   // Uncomment this line to debug pixel shaders 
18
19/// File containing the shader code.
20#define FX_FILENAME L"EnvMap.fx"
21
22#include "Cube.h"
23#include "Mesh.h"
24#include "Parameters.h"
25#include "EnvMap.h"
26
27const int WIDTH = 800;                          ///< screen width
28const int HEIGHT = 800;                         ///< screen height
29const int CHARBUFFER_SIZE = 200;        ///< length of the buffer (one line to be saved to file)
30
31/// This struct was created to easily navigate to Main.cpp.
32struct DXUT_Manager {
33};
34
35//--------------------------------------------------------------------------------------
36// Global variables
37//--------------------------------------------------------------------------------------
38
39IDirect3DDevice9*                       g_pd3dDevice;                           ///< THE D3D DEVICE
40ID3DXEffect*                            g_pEffect;                                      ///< THE EFFECT FILE
41EnvMap*                                         envmapRenderer;                         ///< PROBLEM-SPECIFIC CLASS
42Parameters                                      pp;                                                     ///< HELPER CLASS TO MANAGE VARIOUS PARAMETERS
43
44CDXUTDialogResourceManager      g_DialogResourceManager;        ///< Manager for shared resources of dialogs
45CD3DSettingsDlg                         g_SettingsDlg;                          ///< Device settings dialog
46CDXUTDialog                                     g_HUD;                                          ///< Dialog for sample specific controls
47
48ID3DXFont*                                      g_pFont;                                        ///< Font for drawing text
49ID3DXSprite*                            g_pTextSprite;                          ///< Sprite for batching draw text calls
50
51IDirect3DSurface9*                      g_pSaveSurface;                         ///< surface for screenshot capturing
52bool                                            bSavingScreenshot = false;      ///< boolean for screenshot capturing
53int                                                     counter = 0;                            ///< counter for screenshots (see GenerateNewFileName())
54
55HRESULT hr;
56
57CModelViewerCamera camera;                                                              ///< the camera
58
59
60//--------------------------------------------------------------------------------------
61// Forward declarations (CALLBACK)
62//--------------------------------------------------------------------------------------
63bool    CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext );
64bool    CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps, void* pUserContext );
65HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* g_pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext );
66HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* g_pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext );
67void    CALLBACK OnFrameMove( IDirect3DDevice9* g_pd3dDevice, double fTime, float fElapsedTime, void* pUserContext );
68void    CALLBACK OnFrameRender( IDirect3DDevice9* g_pd3dDevice, double fTime, float fElapsedTime, void* pUserContext );
69LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing, void* pUserContext );
70void    CALLBACK KeyboardProc( UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext );
71void    CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext );
72void    CALLBACK OnLostDevice( void* pUserContext );
73void    CALLBACK OnDestroyDevice( void* pUserContext );
74void    InitParams();
75void    RenderText();
76
77//--------------------------------------------------------------------------------------
78// Forward declarations
79//--------------------------------------------------------------------------------------
80void SaveCameraPosition( char* fileName );
81void LoadCameraPosition( char* fileName );
82int GenerateNewFileName( int& counter );
83
84//--------------------------------------------------------------------------------------
85/// \brief Entry point to the program.
86///
87/// Initializes everything and goes into a message processing loop. Idle time is used to render the scene.
88//--------------------------------------------------------------------------------------
89
90INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
91{
92    // Enable run-time memory check for debug builds.
93#if defined(DEBUG) | defined(_DEBUG)
94    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
95#endif
96
97    DXUTSetCallbackDeviceCreated( OnCreateDevice );
98    DXUTSetCallbackDeviceReset( OnResetDevice );
99    DXUTSetCallbackDeviceLost( OnLostDevice );
100    DXUTSetCallbackDeviceDestroyed( OnDestroyDevice );
101    DXUTSetCallbackMsgProc( MsgProc );
102    DXUTSetCallbackKeyboard( KeyboardProc );
103    DXUTSetCallbackFrameRender( OnFrameRender );
104    DXUTSetCallbackFrameMove( OnFrameMove );
105
106        envmapRenderer = new EnvMap();
107        InitParams();
108
109        // Show the cursor and clip it when in full screen
110    DXUTSetCursorSettings( true, true );
111
112        DXUTInit( true, true, true ); // Parse the command line, handle the default hotkeys, and show msgboxes
113    DXUTCreateWindow( L"Environment Mapping Demo" );
114    DXUTCreateDevice( D3DADAPTER_DEFAULT, true, WIDTH, HEIGHT, IsDeviceAcceptable, ModifyDeviceSettings );
115
116        camera.SetButtonMasks( 0, MOUSE_WHEEL, MOUSE_LEFT_BUTTON );
117
118    DXUTMainLoop();
119
120    return DXUTGetExitCode();
121}
122
123/// \brief DXUT callback (called by the framework in case of GUI events).
124/// Forwards GUI event to the parameter-manager class #Parameters (see #pp).
125/// \param nControlID id of the adjusted GUI control
126void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext )
127{
128        pp.UpdateFromHUD( nControlID );
129}
130
131/// (Load, Save, Reset are default buttons.)
132void OnLoad() {
133        LoadCameraPosition( ".matrix" );
134}
135
136/// (Load, Save, Reset are default buttons.)
137void OnSave() {
138        SaveCameraPosition( ".matrix" );
139        bSavingScreenshot = true;
140}
141
142/// (Load, Save, Reset are default buttons.)
143void OnReset() {}
144
145/// Callback of type #CONVERTER.
146float Exponent(float f) {
147        return 0.012f * pow(50.0f, 2*f);
148}
149
150/// Actions to be taken when the cubemaps get invalid. Callback of type #ONCHANGE_CALLBACK.
151void OnChangeCubeMap() {
152        envmapRenderer->InvalidateCubeMap();
153}
154
155/// Actions to be taken when the central mesh object is changed. Callback of type #ONCHANGE_CALLBACK.
156void OnChangeMesh() {
157
158        envmapRenderer->ChooseMesh( pp.GetInt( iWhichMesh ));
159}
160
161/// Actions to be taken when the size of the central mesh is to change. Callback of type #ONCHANGE_CALLBACK.
162void OnChangeMeshSize() {
163
164        envmapRenderer->SetMeshSize( pp.Get( fMeshScale )*2);
165}
166
167/// Actions to be taken when the shininess is to change. Callback of type #ONCHANGE_CALLBACK.
168void OnChangeShininess() {
169
170        envmapRenderer->InvalidateShininess();
171}
172
173/// Actions to be taken when the resolution is to change. Callback of type #ONCHANGE_CALLBACK.
174void OnChangeResolution() {
175
176        envmapRenderer->InvalidateResolution();
177}
178
179//--------------------------------------------------------------------------------------
180/// \brief Defines application-specific parameters and creates GUI controls (sliders, checkboxes) for them.
181/// \brief Finally, loads initial values for the parameters from file called <b>.params0</b> (Reset).
182/// Use Parameters::Add to create GUI controls.
183//--------------------------------------------------------------------------------------
184void InitParams()
185{
186        g_SettingsDlg.Init( &g_DialogResourceManager );
187        g_HUD.Init( &g_DialogResourceManager );
188        g_HUD.SetCallback( OnGUIEvent );        // Event handling
189
190        //pp.Setup( &g_HUD );
191        pp.Setup( &g_HUD, OnReset, OnSave, OnLoad );    // you can add callbacks to these actions
192
193        // CHECKBOXES
194        pp.Add( bShowHelp, "Help [F1]", VK_F1 );                               
195        //pp.Add( bAutoGenCubeMap, "[A]utoGenCubeMap", 'A' );
196        pp.Add( bShowFireballs, "[F]ireballs", 'F', OnChangeCubeMap );
197        pp.Add( bMultipleObjects, "Multiple [O]bjects", 'O' );
198        pp.Add( bConfineToRoom, "Between [W]alls only", 'W' );
199
200        // SLIDERS
201        pp.Add( iWhichMethod, "WhichMethod [TAB,Q]", 5, VK_TAB, 'Q', noconvert, OnChangeCubeMap );     
202        pp.Add( iWhichMesh, "WhichMesh [Home,End]", 9, VK_HOME, VK_END, noconvert, OnChangeMesh );     
203        pp.Add( fMeshScale, "Mesh size [Ins,Del]", 100, VK_DELETE, VK_INSERT, noconvert, OnChangeMeshSize );   
204        pp.Add( iResolution, "Resolution [M]", 3, 'N', 'M', noconvert, OnChangeResolution );   
205        pp.Add( iShowCubeMap, "ShowCubeMap [C]", 3, 'C' );     
206        pp.Add( fIntensity, "Intensity [+,-]", 100, VK_SUBTRACT, VK_ADD, Exponent );
207        pp.Add( iShininess, "shininess [/,*]", 30, VK_DIVIDE, VK_MULTIPLY, noconvert, OnChangeShininess );
208
209        pp.UpdateFromHUD( IDC_RESET_BUTTON );   // do a reset
210}
211
212//--------------------------------------------------------------------------------------
213/// \brief DXUT callback (Rejects any devices that aren't acceptable by returning false)
214///
215/// DXUT callback. Rejects any devices that aren't acceptable by returning false.
216//--------------------------------------------------------------------------------------
217bool CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat,
218                                  D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext )
219{
220    // Skip backbuffer formats that don't support alpha blending
221    IDirect3D9* pD3D = DXUTGetD3DObject();
222    if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType,
223                    AdapterFormat, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING,
224                    D3DRTYPE_TEXTURE, BackBufferFormat ) ) )
225        return false;
226
227    return true;
228}
229
230//--------------------------------------------------------------------------------------
231/// \brief DXUT callback (Before a device is created, modifies the device settings as needed)
232//--------------------------------------------------------------------------------------
233bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps, void* pUserContext )
234{
235        // VSync off
236        pDeviceSettings->pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
237
238    // If device doesn't support HW T&L or doesn't support 1.1 vertex shaders in HW
239    // then switch to SWVP.
240    if( (pCaps->DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == 0 ||
241         pCaps->VertexShaderVersion < D3DVS_VERSION(1,1) )
242                pDeviceSettings->BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
243    else
244                pDeviceSettings->BehaviorFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
245
246    // This application is designed to work on a pure device by not using
247    // IDirect3D9::Get*() methods, so create a pure device if supported and using HWVP.
248    if ((pCaps->DevCaps & D3DDEVCAPS_PUREDEVICE) != 0 &&
249        (pDeviceSettings->BehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING) != 0 )
250        pDeviceSettings->BehaviorFlags |= D3DCREATE_PUREDEVICE;
251
252    // Debugging vertex shaders requires either REF or software vertex processing
253    // and debugging pixel shaders requires REF. 
254#ifdef DEBUG_VS
255    if( pDeviceSettings->DeviceType != D3DDEVTYPE_REF )
256    {
257        pDeviceSettings->BehaviorFlags &= ~D3DCREATE_HARDWARE_VERTEXPROCESSING;
258        pDeviceSettings->BehaviorFlags &= ~D3DCREATE_PUREDEVICE;                           
259        pDeviceSettings->BehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
260    }
261#endif
262#ifdef DEBUG_PS
263    pDeviceSettings->DeviceType = D3DDEVTYPE_REF;
264#endif
265
266        // For the first device created if its a REF device, optionally display a warning dialog box
267    static bool s_bFirstTime = true;
268    if( s_bFirstTime )
269    {
270        s_bFirstTime = false;
271        if( pDeviceSettings->DeviceType == D3DDEVTYPE_REF )
272            DXUTDisplaySwitchingToREFWarning();
273    }
274        return true;
275}
276
277//--------------------------------------------------------------------------------------
278/// @brief DXUT callback (You should create any D3DPOOL_MANAGED resources here)
279///
280/// Compiles the effect file (EnvMap.fx) and displays error message if compilation fails.
281/// Finally, forwards call to EnvMap::OnCreateDevice.
282//--------------------------------------------------------------------------------------
283HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
284{
285        ::g_pd3dDevice = pd3dDevice;
286
287        HRESULT hr;
288
289    V_RETURN( g_DialogResourceManager.OnCreateDevice( g_pd3dDevice ) );
290    V_RETURN( g_SettingsDlg.OnCreateDevice( g_pd3dDevice ) );
291
292    // Initialize the font
293    V_RETURN( D3DXCreateFont( g_pd3dDevice, 15, 0, FW_BOLD, 1, FALSE, DEFAULT_CHARSET,
294                         OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE,
295                         L"Arial", &g_pFont ) );
296
297        // ----------- fx compilation options -----------
298
299        DWORD dwShaderFlags = 0;
300    #ifdef DEBUG_VS
301        dwShaderFlags |= D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT;
302    #endif
303    #ifdef DEBUG_PS
304        dwShaderFlags |= D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT;
305    #endif
306
307        //dwShaderFlags |= D3DXSHADER_SKIPOPTIMIZATION;
308
309        // ----------- compiling fx file -----------
310
311        ID3DXBuffer* errBuff;   // buffer for error message
312
313        if (FAILED(hr = D3DXCreateEffectFromFile( g_pd3dDevice, FX_FILENAME, NULL, NULL, dwShaderFlags,
314                                        NULL, &g_pEffect, &errBuff )))  // if compilation error occurs
315        {
316                int BufSize = errBuff->GetBufferSize();
317
318                wchar_t* wbuf = new wchar_t[BufSize];
319                mbstowcs( wbuf, (const char*)errBuff->GetBufferPointer(), BufSize );
320                MessageBox(NULL, wbuf, L".fx Compilation Error", MB_ICONERROR);         // error message
321
322                delete wbuf;
323                exit(-1);
324        }
325
326        envmapRenderer->OnCreateDevice( g_pd3dDevice, g_pEffect );
327
328        float initialEyeDist = 6.82;
329        D3DXVECTOR3 vecEye(0, 0, -initialEyeDist);
330        D3DXVECTOR3 vecAt (0.0f, 0.0f, -0.0f);
331        camera.SetViewParams( &vecEye, &vecAt );
332
333        return S_OK;
334}
335
336//--------------------------------------------------------------------------------------
337/// \brief DXUT callback (You should release resources created in the OnCreateDevice callback here)
338///
339/// Forwards call to EnvMap::OnDestroyDevice.
340//--------------------------------------------------------------------------------------
341void CALLBACK OnDestroyDevice( void* pUserContext )
342{
343    g_DialogResourceManager.OnDestroyDevice();
344    g_SettingsDlg.OnDestroyDevice();
345
346    SAFE_RELEASE(g_pEffect);
347    SAFE_RELEASE(g_pFont);
348
349        envmapRenderer->OnDestroyDevice();
350}
351
352
353//--------------------------------------------------------------------------------------
354/// \brief DXUT callback (You should create any D3DPOOL_DEFAULT resources here)
355///
356/// Resets camera and HUD elements. Initializes #g_pSaveSurface according to the
357/// current screen resolution.
358/// Then it forwards call to EnvMap::OnResetDevice.
359//--------------------------------------------------------------------------------------
360HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* g_pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
361{
362    HRESULT hr;
363
364    V_RETURN( g_DialogResourceManager.OnResetDevice() );
365    V_RETURN( g_SettingsDlg.OnResetDevice() );
366
367    if( g_pFont )   V_RETURN( g_pFont->OnResetDevice() );
368    if( g_pEffect ) V_RETURN( g_pEffect->OnResetDevice() );
369
370    // Create a sprite to help batch calls when drawing many lines of text
371    V_RETURN( D3DXCreateSprite( g_pd3dDevice, &g_pTextSprite ) );
372
373        // Create a surface to save screenshots
374        IDirect3DTexture9* pSaveTexture = NULL;
375
376        V( D3DXCreateTexture( g_pd3dDevice, pBackBufferSurfaceDesc->Width, pBackBufferSurfaceDesc->Height, 1,
377                D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pSaveTexture) );
378        pSaveTexture->GetSurfaceLevel( 0, &g_pSaveSurface );
379        SAFE_RELEASE( pSaveTexture );
380
381        // Setup the camera's projection parameters
382    float fAspectRatio = pBackBufferSurfaceDesc->Width / (FLOAT)pBackBufferSurfaceDesc->Height;
383
384        camera.SetProjParams( D3DX_PI/4, fAspectRatio, 0.1, 100 );
385    camera.SetWindow( pBackBufferSurfaceDesc->Width, pBackBufferSurfaceDesc->Height );
386
387        envmapRenderer->OnResetDevice();
388
389    // Position the on-screen dialog
390    g_HUD.SetLocation( 0, 0 );
391    g_HUD.SetSize( pBackBufferSurfaceDesc->Width, pBackBufferSurfaceDesc->Height );
392
393    return S_OK;
394}
395
396//--------------------------------------------------------------------------------------
397/// DXUT callback (You should release resources created in the OnResetDevice callback here)
398//--------------------------------------------------------------------------------------
399void CALLBACK OnLostDevice( void* pUserContext )
400{
401    g_DialogResourceManager.OnLostDevice();
402    g_SettingsDlg.OnLostDevice();
403
404    if( g_pFont )       g_pFont->OnLostDevice();
405    if( g_pEffect )     g_pEffect->OnLostDevice();
406
407    SAFE_RELEASE( g_pTextSprite );
408        SAFE_RELEASE( g_pSaveSurface );
409
410        envmapRenderer->OnLostDevice();
411}
412
413//--------------------------------------------------------------------------------------
414/// \brief DXUT callback (Message processing).
415///
416/// Forwards messages to the DirectX settings window, the GUI controls or the camera, respecively.
417//--------------------------------------------------------------------------------------
418LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing, void* pUserContext )
419{
420    // Always allow dialog resource manager calls to handle global messages
421    // so GUI state is updated correctly
422    *pbNoFurtherProcessing = g_DialogResourceManager.MsgProc( hWnd, uMsg, wParam, lParam );
423    if( *pbNoFurtherProcessing )
424        return 0;
425
426    if( g_SettingsDlg.IsActive() )
427    {
428        g_SettingsDlg.MsgProc( hWnd, uMsg, wParam, lParam );
429        return 0;
430    }
431
432        // Give the dialogs a chance to handle the message first
433    *pbNoFurtherProcessing = g_HUD.MsgProc( hWnd, uMsg, wParam, lParam );
434    if( *pbNoFurtherProcessing )
435        return 0;
436
437    // Pass all remaining windows messages to camera so it can respond to user input
438        camera.HandleMessages( hWnd, uMsg, wParam, lParam );
439
440    return 0;
441}
442
443//--------------------------------------------------------------------------------------
444/// \brief DXUT callback (Handle updates to the scene)
445//--------------------------------------------------------------------------------------
446void CALLBACK OnFrameMove( IDirect3DDevice9* g_pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
447{
448    camera.FrameMove( fElapsedTime );
449}
450
451//--------------------------------------------------------------------------------------
452/// \brief <b>DXUT callback (Render the scene). Also responsible for screenshot taking.</b>
453///
454/// If a screenshot is being taken (#bSavingScreenshot), sets #g_pSaveSurface as the render target
455/// and saves it to a non-existent file (GenerateNewFileName()). Also saves current camera parameters (SaveCameraPosition()).
456///
457/// To perform actual rendering, it forwards call to EnvMap::OnFrameRender with current camera matrices.
458//--------------------------------------------------------------------------------------
459void CALLBACK OnFrameRender( IDirect3DDevice9* g_pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
460{
461    // If the settings dialog is being shown, then
462    // render it instead of rendering the app's scene
463    if( g_SettingsDlg.IsActive() )
464    {
465        g_SettingsDlg.OnRender( fElapsedTime );
466        return;
467    }
468
469        // ------------------------------------------------------------
470        // if screenshot is being taken - preparation
471        // ------------------------------------------------------------
472        IDirect3DSurface9* oldRenderTarget = NULL;
473        if (bSavingScreenshot) {
474                V( g_pd3dDevice->GetRenderTarget(0, &oldRenderTarget) );
475                V( g_pd3dDevice->SetRenderTarget(0, g_pSaveSurface) );
476        }
477
478        // ------------------------------------------------------------
479        // rendering
480        // ------------------------------------------------------------
481        V( g_pd3dDevice->BeginScene() );
482
483                D3DXMATRIXA16 mView = *camera.GetViewMatrix();
484                D3DXMATRIXA16 mProj = *camera.GetProjMatrix();
485
486                envmapRenderer->SetCamera( &camera );
487                envmapRenderer->OnFrameRender( g_pd3dDevice, mView, mProj );
488               
489                if (!bSavingScreenshot)
490                {
491                        RenderText();
492                        V( g_HUD.OnRender( fElapsedTime ) );
493                }
494
495        V( g_pd3dDevice->EndScene() );
496
497        // ------------------------------------------------------------
498        // if screenshot is being taken - saving
499        // ------------------------------------------------------------
500        if (bSavingScreenshot) {
501
502                // create file name
503                char buf[CHARBUFFER_SIZE];
504                wchar_t wbuf[CHARBUFFER_SIZE];
505                GenerateNewFileName( counter );
506                sprintf(buf, "shots\\%03i.png", counter);
507                mbstowcs( wbuf, buf, CHARBUFFER_SIZE );
508
509                // save surface
510                D3DXSaveSurfaceToFileW(wbuf, D3DXIFF_PNG, g_pSaveSurface, NULL, NULL);
511
512                // save parameters
513                sprintf(buf, "shots\\%03i", counter);
514                pp.SaveToFile( buf );
515
516                // save camera position
517                sprintf(buf, "shots\\%03i.matrix", counter);
518                SaveCameraPosition( buf );
519
520                g_pd3dDevice->SetRenderTarget(0, oldRenderTarget);
521                bSavingScreenshot = false;
522        }
523}
524
525//--------------------------------------------------------------------------------------
526/// \brief Generates a non-existing filename to store the screenshot in the <b>shots</b> directory.
527///
528/// Generated file names are shots/000.png, shots/001.png, ...
529//--------------------------------------------------------------------------------------
530
531int GenerateNewFileName( int& counter )
532{
533        char buf[CHARBUFFER_SIZE];
534        FILE* f;
535        do {
536                sprintf(buf, "shots\\%03i.png", counter);
537                if ( (f = fopen(buf, "rt")) != NULL )
538                {
539                        fclose( f );
540                        counter++;
541                }
542        } while (f != NULL);
543        return counter;
544}
545
546//--------------------------------------------------------------------------------------
547/// \brief DXUT callback (Keystroke messages)
548//--------------------------------------------------------------------------------------
549void CALLBACK KeyboardProc( UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext )
550{
551        envmapRenderer->KeyboardProc( nChar, bKeyDown, bAltDown );
552}
553
554//--------------------------------------------------------------------------------------
555/// \brief Writes current camera settings to file.
556///
557/// Writes current #camera settings (world matrix and camera position) to file.
558/// Useful when capturing multiple screenshots from the same view.
559/// \param fileName the name of the file to be created
560//--------------------------------------------------------------------------------------
561
562void SaveCameraPosition( char* fileName )
563{
564        // save parameters to file:
565        // world matrix (4x4)
566        // camera position (3)
567
568        // save world matrix
569        D3DXMATRIXA16 W = *camera.GetViewMatrix();
570
571        FILE* f;
572
573        if ((f = fopen(fileName, "wt")) == NULL)
574        {
575                wchar_t wbuf[CHARBUFFER_SIZE];
576                mbstowcs( wbuf, fileName, CHARBUFFER_SIZE );
577        MessageBox(NULL, wbuf, L"File creation failed!", MB_ICONEXCLAMATION);
578                return;
579        }
580
581        fprintf(f, "\n");
582        fprintf(f, "World matrix:\n");
583        fprintf(f, "%10.4g %10.4g %10.4g %10.4g\n", W._11, W._12, W._13, W._14);
584        fprintf(f, "%10.4g %10.4g %10.4g %10.4g\n", W._21, W._22, W._23, W._24);
585        fprintf(f, "%10.4g %10.4g %10.4g %10.4g\n", W._31, W._32, W._33, W._34);
586        fprintf(f, "%10.4g %10.4g %10.4g %10.4g\n", W._41, W._42, W._43, W._44);
587
588        // save camera position
589        fprintf(f, "\n");
590        fprintf(f, "Camera position:\n");
591        const D3DXVECTOR3* eye = camera.GetEyePt();
592        fprintf(f, "%10g %10g %10g", eye->x, eye->y, eye->z);
593        fprintf(f, "\n");
594
595        // save mesh position
596        fprintf(f, "\n");
597        fprintf(f, "Mesh position:\n");
598        D3DXVECTOR3 pos = envmapRenderer->GetMeshPosition();
599        fprintf(f, "%10g %10g %10g", pos.x, pos.y, pos.z);
600        fprintf(f, "\n");
601
602        fclose(f);
603}
604
605//--------------------------------------------------------------------------------------
606/// \brief Loads camera settings from file.
607///
608/// Loads #camera settings (world matrix and camera position) from an existing file.
609/// Useful when capturing multiple screenshots from the same view.
610/// \param fileName the name of the file to load from.
611//--------------------------------------------------------------------------------------
612
613void LoadCameraPosition( char* fileName )
614{
615        FILE* f;
616
617        if ((f = fopen(fileName, "rt")) == NULL) {
618                wchar_t wbuf[CHARBUFFER_SIZE];
619                mbstowcs( wbuf, fileName, CHARBUFFER_SIZE );
620        MessageBox(NULL, wbuf, L"File not found!", MB_ICONEXCLAMATION);
621                return;
622        }
623
624        const int BufSize = 500;        // size of char buffers
625        char buf[BufSize];
626        D3DXMATRIXA16 W;
627
628        fgets(buf, BufSize, f);         // skip comment
629        fgets(buf, BufSize, f);         // skip comment
630        fgets(buf, BufSize, f);         sscanf(buf, "%f %f %f %f", &W._11, &W._12, &W._13, &W._14);
631        fgets(buf, BufSize, f);         sscanf(buf, "%f %f %f %f", &W._21, &W._22, &W._23, &W._24);
632        fgets(buf, BufSize, f);         sscanf(buf, "%f %f %f %f", &W._31, &W._32, &W._33, &W._34);
633        fgets(buf, BufSize, f);         sscanf(buf, "%f %f %f %f", &W._41, &W._42, &W._43, &W._44);
634
635        // load camera position
636        D3DXVECTOR3 vecAt(0.0f, 0.0f, 0.0f);
637        D3DXVECTOR3 vecEye;
638        fgets(buf, BufSize, f);         // skip comment
639        fgets(buf, BufSize, f);         // skip comment
640        fgets(buf, BufSize, f);         sscanf(buf, "%f %f %f", &vecEye.x, &vecEye.y, &vecEye.z);
641
642        // load mesh position
643        D3DXVECTOR3 pos(0.0f, 0.0f, 0.0f);
644        fgets(buf, BufSize, f);         // skip comment
645        fgets(buf, BufSize, f);         // skip comment
646        fgets(buf, BufSize, f);         sscanf(buf, "%f %f %f", &pos.x, &pos.y, &pos.z);
647
648        fclose(f);
649
650        envmapRenderer->SetMeshPosition( pos );
651
652        camera.SetViewParams( &vecEye, &vecAt );
653
654        D3DXQUATERNION q;
655        D3DXQuaternionRotationMatrix(&q, &W);
656        camera.SetViewQuat(q);
657}
658
659//--------------------------------------------------------------------------------------
660/// \brief Renders help and statistics text and displays algorithmic-specific parameters.
661///
662/// - Statistics: FPS value, screen resolution
663///
664/// - Help: displays avaliable keyboard shortcuts after the user presses F1.
665///
666/// - Algorithmic-specific parameters: describes the currently selected method and
667/// displays its most important parameters.
668//--------------------------------------------------------------------------------------
669void RenderText()
670{
671        const D3DSURFACE_DESC* backBufferDesc = DXUTGetBackBufferSurfaceDesc();
672
673    CDXUTTextHelper txtHelper( g_pFont, g_pTextSprite, 15 );
674    txtHelper.Begin();
675
676        txtHelper.SetInsertionPos( 5, 5 );
677        txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 0.0f, 1.0f ) );
678
679        txtHelper.DrawFormattedTextLine( L"%.2f fps @ %i x %i",
680                DXUTGetFPS(), backBufferDesc->Width, backBufferDesc->Height );
681        //txtHelper.DrawTextLine( DXUTGetFrameStats() );
682        txtHelper.DrawTextLine( DXUTGetDeviceStats() );
683        txtHelper.DrawTextLine( L"" );
684       
685        txtHelper.SetInsertionPos( 30, 200 );
686        txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ) );
687       
688        switch (pp.GetInt( iWhichMethod )) {
689                case DIFFUSE_SPECULAR_CLASSIC: 
690                        if (pp.GetInt( iShininess ) > 0)
691                                txtHelper.DrawFormattedTextLine( L"Method : CLASSIC (specular, s=%i)",
692                                        pp.GetInt( iShininess ));
693                        else
694                                txtHelper.DrawFormattedTextLine( L"Method : CLASSIC (diffuse)");
695                        break;
696                case DIFFUSE_SPECULAR_LOCALIZED:
697                        if (pp.GetInt( iShininess ) > 0)
698                                txtHelper.DrawFormattedTextLine( L"Method : Our method (specular, s=%i)",
699                                        pp.GetInt( iShininess ));
700                        else
701                                txtHelper.DrawFormattedTextLine( L"Method : Our method (diffuse)");
702                        break;         
703                case DIFFUSE_SPECULAR_LOCALIZED_5TEX:
704                        if (pp.GetInt( iShininess ) > 0)
705                                txtHelper.DrawFormattedTextLine( L"Method : Our method (specular, s=%i), 5 TEXEL ONLY",
706                                        pp.GetInt( iShininess ));
707                        else
708                                txtHelper.DrawFormattedTextLine( L"Method : Our method (diffuse), 5 TEXEL ONLY");
709                        break;
710                case DIFFUSE_SPECULAR_LOCALIZED_NEW:
711                                txtHelper.DrawFormattedTextLine( L"Method : Our method New (diffuse)");
712                        break;
713                case DIFFUSE_SPECULAR_LOCALIZED_P2P:
714                                txtHelper.DrawFormattedTextLine( L"Method : Point-to-point form factor (diffuse)");
715                        break;
716        }
717
718        //txtHelper.DrawFormattedTextLine( L"IOR : %.2f Fresnel : %.2f", pp.Get( refractionIndex ), pp.Get( sFresnel ));
719        txtHelper.DrawFormattedTextLine( L"Intensity multiplier : %.2f", pp.Get( fIntensity ));
720
721        switch (pp.GetInt( iShowCubeMap )) {
722                case 0: txtHelper.DrawFormattedTextLine( L"" ); break;
723                case 1: txtHelper.DrawFormattedTextLine( L"SHOW HI-RES CUBEMAP on the walls" ); break;
724                case 2: txtHelper.DrawFormattedTextLine( L"SHOW LO-RES CUBEMAP on the walls" ); break;
725                case 3: txtHelper.DrawFormattedTextLine( L"SHOW PRECONVOLVED CUBEMAP on the walls" ); break;
726        }
727
728        int exp = pp.GetInt( iResolution ) + 1; // 1..4
729        int LR_CUBEMAP_SIZE = pow( 2, exp );
730        txtHelper.DrawFormattedTextLine( L"Resolution: %i x %i", LR_CUBEMAP_SIZE, LR_CUBEMAP_SIZE);
731
732        txtHelper.DrawFormattedTextLine( L"" );
733        //D3DXVECTOR3 ref = envmapRenderer->GetReferencePos();
734        //txtHelper.DrawFormattedTextLine( L"Reference_pos: %.2g %.2g %.2g", ref.x, ref.y, ref.z);
735        txtHelper.SetForegroundColor( D3DXCOLOR( 0.7f, 0.7f, 1.0f, 1.0f ) );
736
737        if ( !pp.Get( bShowHelp ) )
738        {
739                txtHelper.DrawTextLine( L"Press F1 for help" );
740        }
741        else // show help
742        {
743                txtHelper.SetInsertionPos( backBufferDesc->Width - 260, backBufferDesc->Height-24*22 );
744
745                txtHelper.DrawTextLine(
746                                L"Controls (F1 to hide):\n"
747                                L"___________________________________\n"
748                                L"      APPLICATION CONTROLS\n"
749                                L"\n"
750                                L"Left click+drag: Rotate mesh\n"
751                                L"Mouse wheel: Zoom\n"
752                                L"Arrow keys: Move object\n"
753                                L"F1: Help\n"
754                                L"Quit: ESC\n"
755                                L"F8: Switch to Wireframe mode\n"
756                                L"\n"
757                                L"L: [L]oad params\n"
758                                L"S: [S]ave params & take SCREENSHOT\n"
759                                L"R: [R]eset params\n"
760                                L"___________________________________\n"
761                                L"      MESH OBJECT CONTROLS\n"
762                                L"\n"
763                                L"O: show 3 mesh [O]bjects\n"
764                                L"F: show [F]ireballs\n"
765                                L"Ins, Del: scale mesh object\n"
766                                L"Home, End, or 0-9: choose mesh object\n"
767                                L"gray +,-: adjust intensity\n"
768                                L"gray /,*: adjust specular shininess\n"
769                                L"___________________________________\n"
770                                L"    ALGORITHM-SPECIFIC CONTROLS\n"
771                                L"\n"
772                                L"TAB,Q: choose shading method\n"
773                                L"N,M: choose cube map resolution\n"
774//                              L"A: refresh cube maps for every frame\n"
775//                              L"SPACE: refresh cube maps MANUALLY\n"
776                                L"C: choose visualized [C]ube map\n"
777                                L"___________________________________\n"
778                                L"            Quit: ESC");
779        }
780
781        txtHelper.End();
782}
Note: See TracBrowser for help on using the repository browser.