/** \file \brief Performs DirectX initialization via DXUT callback functions. Adds some additional helper functions to \brief support screenshot capturing. - Performs DirectX initialization via DXUT callback functions - Adds some additional helper functions to support screenshot capturing. \author Istvan Lazanyi, TU Budapest \date 2006-04-26 */ //-------------------------------------------------------------------------------------- // Main.cpp: // - DirectX initialization // - create resources (textures) //-------------------------------------------------------------------------------------- #include "dxstdafx.h" #include "resource.h" #include #include #include //#define DEBUG_VS // Uncomment this line to debug vertex shaders //#define DEBUG_PS // Uncomment this line to debug pixel shaders #include "Cube.h" #include "Mesh.h" #include "Parameters.h" #include "EnvMap.h" const int WIDTH = 640; const int HEIGHT = 640; const int CHARBUFFER_SIZE = 200; //-------------------------------------------------------------------------------------- // Global variables //-------------------------------------------------------------------------------------- IDirect3DDevice9* g_pd3dDevice; ID3DXEffect* g_pEffect; CDXUTDialogResourceManager g_DialogResourceManager; ///< Manager for shared resources of dialogs CD3DSettingsDlg g_SettingsDlg; ///< Device settings dialog CDXUTDialog g_HUD; ///< Dialog for sample specific controls ID3DXFont* g_pFont; ///< Font for drawing text ID3DXSprite* g_pTextSprite; ///< Sprite for batching draw text calls IDirect3DSurface9* g_pSaveSurface; ///< surface for screenshot capturing bool bSavingScreenshot = false; ///< boolean for screenshot capturing int counter = 0; ///< counter for screenshots (see GenerateNewFileName()) HRESULT hr; EnvMap* envmapRenderer = new EnvMap(); ///< problem-specific stuff Parameters pp; ///< managing parameters of the algorithm CModelViewerCamera camera; ///< camera //-------------------------------------------------------------------------------------- // Forward declarations (CALLBACK) //-------------------------------------------------------------------------------------- bool CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext ); bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps, void* pUserContext ); HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* g_pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext ); HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* g_pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext ); void CALLBACK OnFrameMove( IDirect3DDevice9* g_pd3dDevice, double fTime, float fElapsedTime, void* pUserContext ); void CALLBACK OnFrameRender( IDirect3DDevice9* g_pd3dDevice, double fTime, float fElapsedTime, void* pUserContext ); LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing, void* pUserContext ); void CALLBACK KeyboardProc( UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext ); void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext ); void CALLBACK OnLostDevice( void* pUserContext ); void CALLBACK OnDestroyDevice( void* pUserContext ); void InitParams(); void RenderText(); //-------------------------------------------------------------------------------------- // Forward declarations //-------------------------------------------------------------------------------------- void SaveCameraPosition( char* fileName ); void LoadCameraPosition( char* fileName ); int GenerateNewFileName( int& counter ); //-------------------------------------------------------------------------------------- /// \brief Entry point to the program. /// /// Initializes everything and goes into a message processing loop. Idle time is used to render the scene. //-------------------------------------------------------------------------------------- INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int ) { // Enable run-time memory check for debug builds. #if defined(DEBUG) | defined(_DEBUG) _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); #endif DXUTSetCallbackDeviceCreated( OnCreateDevice ); DXUTSetCallbackDeviceReset( OnResetDevice ); DXUTSetCallbackDeviceLost( OnLostDevice ); DXUTSetCallbackDeviceDestroyed( OnDestroyDevice ); DXUTSetCallbackMsgProc( MsgProc ); DXUTSetCallbackKeyboard( KeyboardProc ); DXUTSetCallbackFrameRender( OnFrameRender ); DXUTSetCallbackFrameMove( OnFrameMove ); InitParams(); // Show the cursor and clip it when in full screen DXUTSetCursorSettings( true, true ); DXUTInit( true, true, true ); // Parse the command line, handle the default hotkeys, and show msgboxes DXUTCreateWindow( L"Environment Mapping Demo" ); DXUTCreateDevice( D3DADAPTER_DEFAULT, true, WIDTH, HEIGHT, IsDeviceAcceptable, ModifyDeviceSettings ); camera.SetButtonMasks( 0, MOUSE_WHEEL, MOUSE_LEFT_BUTTON ); DXUTMainLoop(); return DXUTGetExitCode(); } /// \brief DXUT callback (called by the framework in case of GUI events). void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext ) { pp.UpdateFromHUD( nControlID ); } void OnLoad() { LoadCameraPosition( ".matrix" ); } void OnSave() { SaveCameraPosition( ".matrix" ); bSavingScreenshot = true; } void OnReset() {} float Exponent(float f) { return 0.01f * pow(50.0f, 2*f); } void OnChangeCubeMap() { //bool bEnable = !pp.Get( bUseIrradianceMap ) && !pp.Get( bCubeMapFromFile ) ; //pp.SetEnabled( bUseImpostors, bEnable ); envmapRenderer->InvalidateCubeMap(); } void OnChangeShininess() { envmapRenderer->InvalidateShininess(); } //-------------------------------------------------------------------------------------- /// \brief Defines application-specific parameters and creates GUI controls (sliders, checkboxes) for them. /// /// Finally, loads initial values for the parameters from file called .params0 (Reset). //-------------------------------------------------------------------------------------- void InitParams() { g_SettingsDlg.Init( &g_DialogResourceManager ); g_HUD.Init( &g_DialogResourceManager ); g_HUD.SetCallback( OnGUIEvent ); // Event handling //pp.Setup( &g_HUD ); pp.Setup( &g_HUD, OnReset, OnSave, OnLoad ); // you can add callbacks to these actions //typedef enum { bShowHelp, bUseImpostors, LAST_BOOL } bool_t; //typedef enum { iShowCubeMap, sFresnel, refractionIndex, /*iLoadedCenterObjectMeshID,LAST_NUMBER } number_t; pp.Add( bShowHelp, "Help [F1]", VK_F1 ); // checkboxes pp.Add( bCubeMapFromFile, "CubeMapFrom[F]ile", 'F', OnChangeCubeMap ); pp.Add( bAutoGenCubeMap, "[A]utoGenCubeMap", 'A' ); //pp.Add( bLocalize, "L[O]CALIZE LOOKUPS", 'O' ); //pp.Add( bUseCosTexture, "[G]eometric factor with texture lookup", 'O' /*, OnChangeCubeMap*/ ); pp.Add( iWhichMethod, "WhichMethod [TAB,Q]", 4, VK_TAB, 'Q', noconvert, OnChangeCubeMap ); // sliders pp.Add( iWhichMetal, "WhichMetal [M]", 4, 'M' ); // sliders pp.Add( iShowCubeMap, "ShowCubeMap [C]", 3, 'C' ); // sliders pp.Add( sFresnel, "Fresnel [W,E]", 100, 'W', 'E' ); pp.Add( refractionIndex, "RefractionIndex [I,O]", 100, 'I', 'O' ); pp.Add( fIntensity, "Intensity [+,-]", 100, VK_SUBTRACT, VK_ADD, Exponent ); pp.Add( iShininess, "shininess [/,*]", 30, VK_DIVIDE, VK_MULTIPLY, noconvert, OnChangeShininess ); //pp.SetEnabled( bUseImpostors, false ); //pp.SetEnabled( sFresnel, false ); pp.UpdateFromHUD( IDC_RESET_BUTTON ); // do a reset } //-------------------------------------------------------------------------------------- /// \brief DXUT callback (Rejects any devices that aren't acceptable by returning false) /// /// DXUT callback. Rejects any devices that aren't acceptable by returning false. //-------------------------------------------------------------------------------------- bool CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext ) { // Skip backbuffer formats that don't support alpha blending IDirect3D9* pD3D = DXUTGetD3DObject(); if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType, AdapterFormat, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, BackBufferFormat ) ) ) return false; return true; } //-------------------------------------------------------------------------------------- /// \brief DXUT callback (Before a device is created, modifies the device settings as needed) //-------------------------------------------------------------------------------------- bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps, void* pUserContext ) { // VSync off pDeviceSettings->pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; // If device doesn't support HW T&L or doesn't support 1.1 vertex shaders in HW // then switch to SWVP. if( (pCaps->DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == 0 || pCaps->VertexShaderVersion < D3DVS_VERSION(1,1) ) pDeviceSettings->BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING; else pDeviceSettings->BehaviorFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING; // This application is designed to work on a pure device by not using // IDirect3D9::Get*() methods, so create a pure device if supported and using HWVP. if ((pCaps->DevCaps & D3DDEVCAPS_PUREDEVICE) != 0 && (pDeviceSettings->BehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING) != 0 ) pDeviceSettings->BehaviorFlags |= D3DCREATE_PUREDEVICE; // Debugging vertex shaders requires either REF or software vertex processing // and debugging pixel shaders requires REF. #ifdef DEBUG_VS if( pDeviceSettings->DeviceType != D3DDEVTYPE_REF ) { pDeviceSettings->BehaviorFlags &= ~D3DCREATE_HARDWARE_VERTEXPROCESSING; pDeviceSettings->BehaviorFlags &= ~D3DCREATE_PUREDEVICE; pDeviceSettings->BehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING; } #endif #ifdef DEBUG_PS pDeviceSettings->DeviceType = D3DDEVTYPE_REF; #endif // For the first device created if its a REF device, optionally display a warning dialog box static bool s_bFirstTime = true; if( s_bFirstTime ) { s_bFirstTime = false; if( pDeviceSettings->DeviceType == D3DDEVTYPE_REF ) DXUTDisplaySwitchingToREFWarning(); } return true; } //-------------------------------------------------------------------------------------- /// @brief DXUT callback (You should create any D3DPOOL_MANAGED resources here) /// /// Compiles the effect file (EnvMap.fx) and displays error message if compilation fails. /// Finally, forwards call to EnvMap::OnCreateDevice. //-------------------------------------------------------------------------------------- HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext ) { ::g_pd3dDevice = pd3dDevice; HRESULT hr; V_RETURN( g_DialogResourceManager.OnCreateDevice( g_pd3dDevice ) ); V_RETURN( g_SettingsDlg.OnCreateDevice( g_pd3dDevice ) ); // Initialize the font V_RETURN( D3DXCreateFont( g_pd3dDevice, 15, 0, FW_BOLD, 1, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, L"Arial", &g_pFont ) ); // ----------- fx compilation options ----------- LPCWSTR fileName = L"EnvMap.fx"; DWORD dwShaderFlags = 0; #ifdef DEBUG_VS dwShaderFlags |= D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT; #endif #ifdef DEBUG_PS dwShaderFlags |= D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT; #endif dwShaderFlags |= D3DXSHADER_SKIPOPTIMIZATION; // ----------- compiling fx file ----------- long clock1 = clock(); ID3DXBuffer* errBuff; // buffer for error message if (FAILED(hr = D3DXCreateEffectFromFile( g_pd3dDevice, fileName, NULL, NULL, dwShaderFlags, NULL, &g_pEffect, &errBuff ))) // if compilation error occurs { int BufSize = errBuff->GetBufferSize(); wchar_t* wbuf = new wchar_t[BufSize]; mbstowcs( wbuf, (const char*)errBuff->GetBufferPointer(), BufSize ); MessageBox(NULL, wbuf, L".fx Compilation Error", MB_ICONERROR); // error message delete wbuf; exit(-1); } long clock2 = clock(); float tb = (float)(clock2-clock1)/CLOCKS_PER_SEC; wchar_t wbuf[100]; swprintf( wbuf, L"Compilation took %f sec", tb ); //MessageBox(NULL, wbuf, L"Info", MB_ICONINFORMATION); envmapRenderer->OnCreateDevice( g_pd3dDevice, g_pEffect ); float initialEyeDist = 6.82; D3DXVECTOR3 vecEye(0, 0, -initialEyeDist); D3DXVECTOR3 vecAt (0.0f, 0.0f, -0.0f); camera.SetViewParams( &vecEye, &vecAt ); return S_OK; } //-------------------------------------------------------------------------------------- /// \brief DXUT callback (You should release resources created in the OnCreateDevice callback here) /// /// Forwards call to EnvMap::OnDestroyDevice. //-------------------------------------------------------------------------------------- void CALLBACK OnDestroyDevice( void* pUserContext ) { g_DialogResourceManager.OnDestroyDevice(); g_SettingsDlg.OnDestroyDevice(); SAFE_RELEASE(g_pEffect); SAFE_RELEASE(g_pFont); envmapRenderer->OnDestroyDevice(); } //-------------------------------------------------------------------------------------- /// \brief DXUT callback (You should create any D3DPOOL_DEFAULT resources here) /// /// Resets camera and HUD elements. Initializes #g_pSaveSurface according to the /// current screen resolution. /// Then it forwards call to EnvMap::OnResetDevice. //-------------------------------------------------------------------------------------- HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* g_pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext ) { HRESULT hr; V_RETURN( g_DialogResourceManager.OnResetDevice() ); V_RETURN( g_SettingsDlg.OnResetDevice() ); if( g_pFont ) V_RETURN( g_pFont->OnResetDevice() ); if( g_pEffect ) V_RETURN( g_pEffect->OnResetDevice() ); // Create a sprite to help batch calls when drawing many lines of text V_RETURN( D3DXCreateSprite( g_pd3dDevice, &g_pTextSprite ) ); // Create a surface to save screenshots IDirect3DTexture9* pSaveTexture = NULL; V( D3DXCreateTexture( g_pd3dDevice, pBackBufferSurfaceDesc->Width, pBackBufferSurfaceDesc->Height, 1, //V( D3DXCreateTexture( g_pd3dDevice, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pSaveTexture) ); pSaveTexture->GetSurfaceLevel( 0, &g_pSaveSurface ); SAFE_RELEASE( pSaveTexture ); // Setup the camera's projection parameters float fAspectRatio = pBackBufferSurfaceDesc->Width / (FLOAT)pBackBufferSurfaceDesc->Height; camera.SetProjParams( D3DX_PI/4, fAspectRatio, 0.1, 100 ); camera.SetWindow( pBackBufferSurfaceDesc->Width, pBackBufferSurfaceDesc->Height ); envmapRenderer->OnResetDevice(); // Position the on-screen dialog g_HUD.SetLocation( 0, 0 ); g_HUD.SetSize( pBackBufferSurfaceDesc->Width, pBackBufferSurfaceDesc->Height ); return S_OK; } //-------------------------------------------------------------------------------------- /// DXUT callback (You should release resources created in the OnResetDevice callback here) //-------------------------------------------------------------------------------------- void CALLBACK OnLostDevice( void* pUserContext ) { g_DialogResourceManager.OnLostDevice(); g_SettingsDlg.OnLostDevice(); if( g_pFont ) g_pFont->OnLostDevice(); if( g_pEffect ) g_pEffect->OnLostDevice(); SAFE_RELEASE( g_pTextSprite ); SAFE_RELEASE( g_pSaveSurface ); envmapRenderer->OnLostDevice(); } //-------------------------------------------------------------------------------------- /// \brief DXUT callback (Message processing). /// /// Forwards messages to the DirectX settings window, the GUI controls or the camera, respecively. //-------------------------------------------------------------------------------------- LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing, void* pUserContext ) { // Always allow dialog resource manager calls to handle global messages // so GUI state is updated correctly *pbNoFurtherProcessing = g_DialogResourceManager.MsgProc( hWnd, uMsg, wParam, lParam ); if( *pbNoFurtherProcessing ) return 0; if( g_SettingsDlg.IsActive() ) { g_SettingsDlg.MsgProc( hWnd, uMsg, wParam, lParam ); return 0; } // Give the dialogs a chance to handle the message first *pbNoFurtherProcessing = g_HUD.MsgProc( hWnd, uMsg, wParam, lParam ); if( *pbNoFurtherProcessing ) return 0; // Pass all remaining windows messages to camera so it can respond to user input camera.HandleMessages( hWnd, uMsg, wParam, lParam ); return 0; } //-------------------------------------------------------------------------------------- /// \brief DXUT callback (Handle updates to the scene) //-------------------------------------------------------------------------------------- void CALLBACK OnFrameMove( IDirect3DDevice9* g_pd3dDevice, double fTime, float fElapsedTime, void* pUserContext ) { camera.FrameMove( fElapsedTime ); } //-------------------------------------------------------------------------------------- /// \brief DXUT callback (Render the scene). Also responsible for screenshot taking. /// /// If a screenshot is being taken (#bSavingScreenshot), sets #g_pSaveSurface as the render target /// and saves it to a non-existent file (GenerateNewFileName()). Also saves current camera parameters (SaveCameraPosition()). /// /// To perform actual rendering, it forwards call to EnvMap::OnFrameRender with current camera matrices. //-------------------------------------------------------------------------------------- void CALLBACK OnFrameRender( IDirect3DDevice9* g_pd3dDevice, double fTime, float fElapsedTime, void* pUserContext ) { // If the settings dialog is being shown, then // render it instead of rendering the app's scene if( g_SettingsDlg.IsActive() ) { g_SettingsDlg.OnRender( fElapsedTime ); return; } IDirect3DSurface9* oldRenderTarget = NULL; if (bSavingScreenshot) { V( g_pd3dDevice->GetRenderTarget(0, &oldRenderTarget) ); V( g_pd3dDevice->SetRenderTarget(0, g_pSaveSurface) ); } V( g_pd3dDevice->BeginScene() ); D3DXMATRIXA16 mView = *camera.GetViewMatrix(); D3DXMATRIXA16 mProj = *camera.GetProjMatrix(); envmapRenderer->camera = &camera; envmapRenderer->OnFrameRender( g_pd3dDevice, mView, mProj ); if (!bSavingScreenshot) { RenderText(); V( g_HUD.OnRender( fElapsedTime ) ); } V( g_pd3dDevice->EndScene() ); if (bSavingScreenshot) { // saving surface char buf[CHARBUFFER_SIZE]; wchar_t wbuf[CHARBUFFER_SIZE]; GenerateNewFileName( counter ); sprintf(buf, "shots\\%03i.png", counter); mbstowcs( wbuf, buf, CHARBUFFER_SIZE ); D3DXSaveSurfaceToFileW(wbuf, D3DXIFF_PNG, g_pSaveSurface, NULL, NULL); sprintf(buf, "shots\\%03i", counter); pp.SaveToFile( buf ); sprintf(buf, "shots\\%03i.matrix", counter); SaveCameraPosition( buf ); g_pd3dDevice->SetRenderTarget(0, oldRenderTarget); bSavingScreenshot = false; } } //-------------------------------------------------------------------------------------- /// \brief Generates a non-existing filename to store the screenshot in the shots directory. /// /// Generated file names are shots/000.png, shots/001.png, ... //-------------------------------------------------------------------------------------- int GenerateNewFileName( int& counter ) { char buf[CHARBUFFER_SIZE]; FILE* f; do { sprintf(buf, "shots\\%03i.png", counter); if ( (f = fopen(buf, "rt")) != NULL ) { fclose( f ); counter++; } } while (f != NULL); return counter; } //-------------------------------------------------------------------------------------- /// \brief DXUT callback (Keystroke messages) //-------------------------------------------------------------------------------------- void CALLBACK KeyboardProc( UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext ) { envmapRenderer->KeyboardProc( nChar, bKeyDown, bAltDown ); } //-------------------------------------------------------------------------------------- /// \brief Writes current camera settings to file. /// /// Writes current #camera settings (world matrix and camera position) to file. /// Useful when capturing multiple screenshots from the same view. /// \param fileName the name of the file to be created //-------------------------------------------------------------------------------------- void SaveCameraPosition( char* fileName ) { // save parameters to file: // world matrix (4x4) // camera position (3) // save world matrix D3DXMATRIXA16 W = *camera.GetViewMatrix(); FILE* f; if ((f = fopen(fileName, "wt")) == NULL) { wchar_t wbuf[CHARBUFFER_SIZE]; mbstowcs( wbuf, fileName, CHARBUFFER_SIZE ); MessageBox(NULL, wbuf, L"File creation failed!", MB_ICONEXCLAMATION); return; } fprintf(f, "\n"); fprintf(f, "World matrix:\n"); fprintf(f, "%10.4g %10.4g %10.4g %10.4g\n", W._11, W._12, W._13, W._14); fprintf(f, "%10.4g %10.4g %10.4g %10.4g\n", W._21, W._22, W._23, W._24); fprintf(f, "%10.4g %10.4g %10.4g %10.4g\n", W._31, W._32, W._33, W._34); fprintf(f, "%10.4g %10.4g %10.4g %10.4g\n", W._41, W._42, W._43, W._44); // save camera position fprintf(f, "\n"); fprintf(f, "Camera position:\n"); const D3DXVECTOR3* eye = camera.GetEyePt(); fprintf(f, "%10g %10g %10g", eye->x, eye->y, eye->z); fprintf(f, "\n"); fclose(f); } //-------------------------------------------------------------------------------------- /// \brief Loads camera settings from file. /// /// Loads #camera settings (world matrix and camera position) from an existing file. /// Useful when capturing multiple screenshots from the same view. /// \param fileName the name of the file to load from. //-------------------------------------------------------------------------------------- void LoadCameraPosition( char* fileName ) { FILE* f; if ((f = fopen(fileName, "rt")) == NULL) { wchar_t wbuf[CHARBUFFER_SIZE]; mbstowcs( wbuf, fileName, CHARBUFFER_SIZE ); MessageBox(NULL, wbuf, L"File not found!", MB_ICONEXCLAMATION); return; } const int BufSize = 500; // size of char buffers char buf[BufSize]; D3DXMATRIXA16 W; fgets(buf, BufSize, f); // skip comment fgets(buf, BufSize, f); // skip comment fgets(buf, BufSize, f); sscanf(buf, "%f %f %f %f", &W._11, &W._12, &W._13, &W._14); fgets(buf, BufSize, f); sscanf(buf, "%f %f %f %f", &W._21, &W._22, &W._23, &W._24); fgets(buf, BufSize, f); sscanf(buf, "%f %f %f %f", &W._31, &W._32, &W._33, &W._34); fgets(buf, BufSize, f); sscanf(buf, "%f %f %f %f", &W._41, &W._42, &W._43, &W._44); // load camera position D3DXVECTOR3 vecAt(0.0f, 0.0f, 0.0f); D3DXVECTOR3 vecEye; fgets(buf, BufSize, f); // skip comment fgets(buf, BufSize, f); // skip comment fgets(buf, BufSize, f); sscanf(buf, "%f %f %f", &vecEye.x, &vecEye.y, &vecEye.z); fclose(f); camera.SetViewParams( &vecEye, &vecAt ); D3DXQUATERNION q; D3DXQuaternionRotationMatrix(&q, &W); camera.SetViewQuat(q); } //-------------------------------------------------------------------------------------- /// \brief Util function. Creates an empty texture that shall be used as render target. /// /// Note that render targets (D3DUSAGE_RENDERTARGET) must be created in the default memory pool (D3DPOOL_DEFAULT). /// @param size size of the new texture /// @param format format of the new texture (eg. D3DFMT_A32B32G32R32F) //-------------------------------------------------------------------------------------- IDirect3DTexture9* CreateTexture( int size, D3DFORMAT Format ) { HRESULT hr; IDirect3DTexture9* pTexture; V( g_pd3dDevice->CreateTexture( size, size, // dimensions 1, // mipmap levels D3DUSAGE_RENDERTARGET, // usage Format, D3DPOOL_DEFAULT,// memory pool &pTexture, NULL ) ); return pTexture; } //-------------------------------------------------------------------------------------- /// \brief Util function. Creates an empty cubemap texture that shall be used as render target. /// /// @param size size of the new texture /// @param format format of the new texture (eg. D3DFMT_A32B32G32R32F) //-------------------------------------------------------------------------------------- IDirect3DCubeTexture9* CreateCubeTexture( int size, D3DFORMAT Format ) { HRESULT hr; IDirect3DCubeTexture9* pCubeTexture; V( g_pd3dDevice->CreateCubeTexture( size, 1, D3DUSAGE_RENDERTARGET, Format, D3DPOOL_DEFAULT, &pCubeTexture, NULL ) ); return pCubeTexture; } //-------------------------------------------------------------------------------------- /// \brief Renders help and statistics text and displays algorithmic-specific parameters. /// /// - Statistics: FPS value, screen resolution /// /// - Help: displays avaliable keyboard shortcuts after the user presses F1. /// /// - Algorithmic-specific parameters: describes the currently selected method and /// displays its most important parameters. //-------------------------------------------------------------------------------------- void RenderText() { const D3DSURFACE_DESC* backBufferDesc = DXUTGetBackBufferSurfaceDesc(); CDXUTTextHelper txtHelper( g_pFont, g_pTextSprite, 15 ); txtHelper.Begin(); txtHelper.SetInsertionPos( 5, 5 ); txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 0.0f, 1.0f ) ); txtHelper.DrawFormattedTextLine( L"%.2f fps @ %i x %i", DXUTGetFPS(), backBufferDesc->Width, backBufferDesc->Height ); //txtHelper.DrawTextLine( DXUTGetFrameStats() ); txtHelper.DrawTextLine( DXUTGetDeviceStats() ); txtHelper.DrawTextLine( L"" ); txtHelper.SetInsertionPos( 30, 180 ); txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ) ); switch (pp.GetInt( iWhichMethod )) { case IDEAL: case IDEAL_LOCALIZED: if ( pp.GetInt( iWhichMethod ) == IDEAL ) { txtHelper.DrawFormattedTextLine( L"Method : Ideal reflection / refr."); break; } else if (!pp.Get( bCubeMapFromFile )) txtHelper.DrawFormattedTextLine( L"Method : Ideal reflection / refr. using depth impostors"); else txtHelper.DrawFormattedTextLine( L"Method : Ideal reflection / refr. (no depth info. available from file!)"); break; case DIFFUSE_SPECULAR: if (pp.GetInt( iShininess ) > 0) txtHelper.DrawFormattedTextLine( L"Method : Specular reflections"); else txtHelper.DrawFormattedTextLine( L"Method : Diffuse reflections"); break; case DIFFUSE_SPECULAR_LOCALIZED: if (pp.GetInt( iShininess ) > 0) txtHelper.DrawFormattedTextLine( L"Method : Specular reflections with localization"); else txtHelper.DrawFormattedTextLine( L"Method : Diffuse reflections with localization"); break; case DIFFUSE_SPECULAR_LOCALIZED_COSTEX: if (pp.GetInt( iShininess ) > 0) txtHelper.DrawFormattedTextLine( L"Method : Specular reflections with localization and cos.texture"); else txtHelper.DrawFormattedTextLine( L"Method : Diffuse reflections with localization and cos.texture"); break; } txtHelper.DrawFormattedTextLine( L"IOR : %.2f Fresnel : %.2f", pp.Get( refractionIndex ), pp.Get( sFresnel )); txtHelper.DrawFormattedTextLine( L"Shininess (s) : %i Intensity multiplier : %.2f", pp.GetInt( iShininess ), pp.Get( fIntensity )); D3DXVECTOR3 ref = envmapRenderer->GetReferencePos(); txtHelper.DrawFormattedTextLine( L"Reference_pos: %.2g %.2g %.2g", ref.x, ref.y, ref.z); if (pp.GetInt( iWhichMethod ) == IDEAL) { switch (pp.GetInt( iWhichMetal )) { case 0: txtHelper.DrawFormattedTextLine( L""); break; case 1: txtHelper.DrawFormattedTextLine( L"Metal: COPPER"); break; case 2: txtHelper.DrawFormattedTextLine( L"Metal: GOLD"); break; case 3: txtHelper.DrawFormattedTextLine( L"Metal: SILVER"); break; case 4: txtHelper.DrawFormattedTextLine( L"Metal: ALUMINUM"); break; } } else txtHelper.DrawFormattedTextLine( L""); txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 0.0f, 1.0f ) ); if ( pp.Get( bShowHelp ) ) { txtHelper.SetInsertionPos( backBufferDesc->Width - 260, backBufferDesc->Height-24*15 ); txtHelper.DrawTextLine( L"Controls (F1 to hide):\n" L"___________________________________\n" L" GENERAL CONTROLS\n" L"Left click drag: Rotate mesh\n" L"Mouse wheel: Zoom\n" L"Arrow keys: Move object\n" //L"F2: Settings\n" //L"F3: Switch to REF device\n" L"F8: Switch to Wireframe mode\n" L"___________________________________\n" L" ALGORITHM\n" L"0-9: choose object mesh\n" L"TAB,Q: choose shading method\n" L"C: choose visualized cube map\n" L"A: refresh cube maps for every frame\n" L"L: LOCALIZE cube map lookups\n" L"SPACE: refresh cube maps MANUALLY\n" L"I,O: adjust Index of refraction (IOR)\n" L"W,E: adjust Fresnel term\n" L"gray +,-: adjust intensity\n" L"gray /,*: adjust specular shininess\n" L"___________________________________\n" L" UTILITIES\n" L"L: [L]oad params\n" L"S: [S]ave params & take SCREENSHOT\n" L"R: [R]eset params\n" L"___________________________________\n" L" Quit: ESC"); } else { txtHelper.DrawTextLine( L"Press F1 for help" ); } txtHelper.End(); }