//-------------------------------------------------------------------------------------- // 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 "Parameters.h" #include "ToneMap.h" const int WIDTH = 720; const int HEIGHT = 480; const int CHARBUFFER_SIZE = 200; //-------------------------------------------------------------------------------------- // Global variables //-------------------------------------------------------------------------------------- IDirect3DDevice9* g_pd3dDevice = NULL; 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 = NULL; // Font for drawing text ID3DXSprite* g_pTextSprite = NULL; // Sprite for batching draw text calls IDirect3DSurface9* g_pSaveSurface; // screenshot capturing support bool bSavingScreenshot = false; int counter = 0; // Dice mesh LPD3DXMESH g_pMesh = NULL; // Our mesh object in sysmem D3DMATERIAL9* g_pMeshMaterials = NULL; // Materials for our mesh LPDIRECT3DTEXTURE9* g_pMeshTextures = NULL; // Textures for our mesh DWORD g_dwNumMaterials = 0L; // Number of mesh materials LPD3DXBUFFER pD3DXMtrlBuffer; HRESULT hr; Parameters pp; // managing parameters of the algorithm CModelViewerCamera camera; // camera // ToneMapping object ToneMap *toneMap = new ToneMap(); //Save texture IDirect3DTexture9* pSaveTexture = NULL; // Final sourface LPDIRECT3DTEXTURE9 sourceTexture; LPDIRECT3DSURFACE9 sourceTextureSurface; LPDIRECT3DSURFACE9 targetSurface; // Original cube LPDIRECT3DTEXTURE9 CubeTexture; LPDIRECT3DSURFACE9 CubeTextureSurface; // Glow surface LPDIRECT3DTEXTURE9 CubeGlowTexture; LPDIRECT3DSURFACE9 CubeGlowTextureSurface; // Temporary sourfaces for the glow calculation LPDIRECT3DTEXTURE9 TempTexture[3]; LPDIRECT3DSURFACE9 TempTextureSurface[3]; // Glow history surface LPDIRECT3DTEXTURE9 blurTexture; LPDIRECT3DTEXTURE9 prevTexture; LPDIRECT3DSURFACE9 blurTargetSurface; LPDIRECT3DTEXTURE9 blurTargetTexture; // Fullscreen triangle D3DVERTEX_1 rttVertices[3]; LPDIRECT3DSURFACE9 rttDepthSurface; IDirect3DVertexDeclaration9* textureDecl; LPDIRECT3DVERTEXBUFFER9 pQuadVB; IDirect3DSurface9* oldRenderTarget = NULL; // Lighting D3DXVECTOR3 vecDir; D3DLIGHT9 light; // Rendering effects LPD3DXEFFECT CubeEffect; //-------------------------------------------------------------------------------------- // 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 InitApp(); void RenderText(); //-------------------------------------------------------------------------------------- // Forward declarations //-------------------------------------------------------------------------------------- void SaveCameraPosition( char* fileName ); void LoadCameraPosition( char* fileName ); int GenerateNewFileName( int& counter ); //----------------------------------------------------------------------------- // Name: InitGeometry() // Desc: Load the mesh and build the material and texture arrays //----------------------------------------------------------------------------- HRESULT InitGeometry() { // Load the mesh from the specified file if( FAILED( D3DXLoadMeshFromX( L"dobokocka.x", D3DXMESH_MANAGED, g_pd3dDevice, NULL, &pD3DXMtrlBuffer, NULL, &g_dwNumMaterials, &g_pMesh ) ) ) { // If model is not in current folder, try parent folder if( FAILED( D3DXLoadMeshFromX( L"..\\dobokocka.x", D3DXMESH_MANAGED, g_pd3dDevice, NULL, &pD3DXMtrlBuffer, NULL, &g_dwNumMaterials, &g_pMesh ) ) ) { MessageBox(NULL, L"Could not find dobokocka.x", L"Meshes.exe", MB_OK); return E_FAIL; } } // We need to extract the material properties and texture names from the // pD3DXMtrlBuffer D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer(); g_pMeshMaterials = new D3DMATERIAL9[g_dwNumMaterials]; if( g_pMeshMaterials == NULL ) return E_OUTOFMEMORY; g_pMeshTextures = new LPDIRECT3DTEXTURE9[g_dwNumMaterials]; if( g_pMeshTextures == NULL ) return E_OUTOFMEMORY; for( DWORD i=0; i 0 ) { // Create the texture if( FAILED( D3DXCreateTextureFromFileA( g_pd3dDevice, d3dxMaterials[i].pTextureFilename, &g_pMeshTextures[i] ) ) ) { // If texture is not in current folder, try parent folder const TCHAR* strPrefix = TEXT("..\\"); TCHAR strTexture[MAX_PATH]; StringCchCopy( strTexture, MAX_PATH, strPrefix ); StringCchCatA( (char*)strTexture, MAX_PATH, d3dxMaterials[i].pTextureFilename ); // If texture is not in current folder, try parent folder if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, strTexture, &g_pMeshTextures[i] ) ) ) { MessageBox(NULL, L"Could not find texture map", L"Meshes.exe", MB_OK); } } } } // Done with the material buffer //pD3DXMtrlBuffer->Release(); return S_OK; } //-------------------------------------------------------------------------------------- // 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 ); InitApp(); // 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"Glowing Dice Demo" ); DXUTCreateDevice( D3DADAPTER_DEFAULT, true, WIDTH, HEIGHT, IsDeviceAcceptable, ModifyDeviceSettings ); camera.SetButtonMasks( 0, MOUSE_WHEEL, MOUSE_LEFT_BUTTON ); DXUTMainLoop(); return DXUTGetExitCode(); } 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() {} void InitApp() { g_SettingsDlg.Init( &g_DialogResourceManager ); g_HUD.Init( &g_DialogResourceManager ); g_HUD.SetCallback( OnGUIEvent ); // Event handling pp.Setup( &g_HUD, OnReset, OnSave, OnLoad); // you can add callbacks to these actions // UI initialization pp.Add( bShowHelp, "bShowHelp", VK_F1 ); // checkboxes pp.Add( bShowHud, "Hud", VK_F2 ); pp.Add( iGain, "Gain", 800, VK_SUBTRACT, VK_ADD, myconvert ); // sliders pp.SetFloat(iGain, 0.5f); pp.Add( iPasses, "Passes", 400, VK_SUBTRACT, VK_ADD, myPassConvert ); pp.Add( iGlowPasses, "GlowPasses", 400, VK_SUBTRACT, VK_ADD, myGlowConvert ); pp.Add( iGlowGain, "GlowGain", 800, VK_SUBTRACT, VK_ADD, noconvert ); pp.Add( iStretch, "GlowStretch", 1000, VK_SUBTRACT, VK_ADD, stretchconvert ); pp.UpdateFromHUD( IDC_RESET_BUTTON ); // do a reset } //-------------------------------------------------------------------------------------- // 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; } //-------------------------------------------------------------------------------------- // Before a device is created, modify 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; } //-------------------------------------------------------------------------------------- // Create any D3DPOOL_MANAGED resources here //-------------------------------------------------------------------------------------- HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext ) { ::g_pd3dDevice = pd3dDevice; //InitGeometry(); 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 ) ); float initialEyeDist = 10; D3DXVECTOR3 vecEye(0, 0, -initialEyeDist); D3DXVECTOR3 vecAt (0.0f, 0.0f, -0.0f); camera.SetViewParams( &vecEye, &vecAt ); // Error Buffer LPD3DXBUFFER errBuff; DWORD effectCompileFlag = 0; // Shader options for debuging #ifdef DEBUG_SHADER effectCompileFlag|=D3DXSHADER_DEBUG; effectCompileFlag |= D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT; effectCompileFlag |= D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT; #endif // Create the tone mapping effect from file hr = D3DXCreateEffectFromFile(g_pd3dDevice,L"Cube.fx",NULL,NULL,effectCompileFlag,NULL,&CubeEffect,&errBuff); if(hr!=S_OK){ int BufSize = errBuff->GetBufferSize(); // displaying error message of arbitrary length wchar_t* wbuf = new wchar_t[BufSize]; mbstowcs( wbuf, (const char*)errBuff->GetBufferPointer(), BufSize ); MessageBox(NULL, wbuf, L".fx Compilation Error", MB_ICONERROR); // show error message delete wbuf; return hr; } SAFE_RELEASE(errBuff); rttVertices[0] = D3DVERTEX_1(-3,1,0,1, -1.0f, 0.0f); rttVertices[1] = D3DVERTEX_1(1,1,0,1, 1.0f, 0.0f); rttVertices[2] = D3DVERTEX_1(1, -3,0,1, 1.0f, 2.0f); //Vertex declaration D3DVERTEXELEMENT9 _texturedecl[]= { {0,0,D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,0 }, {0,16,D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,0 }, D3DDECL_END() }; V(pd3dDevice->CreateVertexDeclaration(_texturedecl,&textureDecl)); V(pd3dDevice->CreateVertexBuffer(sizeof(D3DVERTEX_1)*3,D3DUSAGE_WRITEONLY,D3DFVF_CUSTOMVERTEX,D3DPOOL_MANAGED,&pQuadVB,NULL)); void *pData; pQuadVB->Lock(0,sizeof(pData),(void**)&pData,0); memcpy(pData,rttVertices,sizeof(D3DVERTEX_1)*3); pQuadVB->Unlock(); // fixed function lighting ZeroMemory( &light, sizeof(light) ); light.Type = D3DLIGHT_DIRECTIONAL; light.Diffuse.r = 0.0f; light.Diffuse.g = 0.0f; light.Diffuse.b = 1.0f; return S_OK; } //-------------------------------------------------------------------------------------- // Release resources created in the OnCreateDevice callback here //-------------------------------------------------------------------------------------- void CALLBACK OnDestroyDevice( void* pUserContext ) { g_DialogResourceManager.OnDestroyDevice(); g_SettingsDlg.OnDestroyDevice(); SAFE_RELEASE(g_pFont); SAFE_RELEASE(CubeEffect); SAFE_RELEASE(textureDecl); SAFE_RELEASE(pQuadVB); } //-------------------------------------------------------------------------------------- // Create any D3DPOOL_DEFAULT resources here //-------------------------------------------------------------------------------------- HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* g_pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext ) { HRESULT hr; InitGeometry(); V_RETURN( g_DialogResourceManager.OnResetDevice() ); V_RETURN( g_SettingsDlg.OnResetDevice() ); if( g_pFont ) V_RETURN( g_pFont->OnResetDevice() ); // Create a sprite to help batch calls when drawing many lines of text V_RETURN( D3DXCreateSprite( g_pd3dDevice, &g_pTextSprite ) ); // 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 ); // target description D3DSURFACE_DESC desc = *pBackBufferSurfaceDesc; //targetSurface->GetDesc(&desc); // final image g_pd3dDevice->CreateTexture(desc.Width,desc.Height,0,D3DUSAGE_RENDERTARGET,D3DFMT_A16B16G16R16F,D3DPOOL_DEFAULT,&sourceTexture,NULL); sourceTexture->GetSurfaceLevel(0,&sourceTextureSurface); // dice g_pd3dDevice->CreateTexture(desc.Width,desc.Height,0,D3DUSAGE_RENDERTARGET,D3DFMT_A16B16G16R16F,D3DPOOL_DEFAULT,&CubeTexture,NULL); CubeTexture->GetSurfaceLevel(0,&CubeTextureSurface); // glow g_pd3dDevice->CreateTexture(desc.Width / 4,desc.Height / 4,0,D3DUSAGE_RENDERTARGET,D3DFMT_A16B16G16R16F,D3DPOOL_DEFAULT,&CubeGlowTexture,NULL); CubeGlowTexture->GetSurfaceLevel(0,&CubeGlowTextureSurface); // temporary g_pd3dDevice->CreateTexture(desc.Width / 4,desc.Height / 4,0,D3DUSAGE_RENDERTARGET,D3DFMT_A16B16G16R16F,D3DPOOL_DEFAULT,&TempTexture[0],NULL); TempTexture[0]->GetSurfaceLevel(0,&TempTextureSurface[0]); g_pd3dDevice->CreateTexture(desc.Width / 4,desc.Height / 4,0,D3DUSAGE_RENDERTARGET,D3DFMT_A16B16G16R16F,D3DPOOL_DEFAULT,&TempTexture[1],NULL); TempTexture[1]->GetSurfaceLevel(0,&TempTextureSurface[1]); g_pd3dDevice->CreateTexture(desc.Width / 4,desc.Height / 4,0,D3DUSAGE_RENDERTARGET,D3DFMT_A16B16G16R16F,D3DPOOL_DEFAULT,&TempTexture[2],NULL); TempTexture[2]->GetSurfaceLevel(0,&TempTextureSurface[2]); // clear glow history V( g_pd3dDevice->GetRenderTarget(0, &oldRenderTarget) ); g_pd3dDevice->SetRenderTarget(0, TempTextureSurface[2]); g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0 ); g_pd3dDevice->SetRenderTarget(0, oldRenderTarget); V(g_pd3dDevice->CreateDepthStencilSurface(desc.Width,desc.Height,D3DFMT_D16,D3DMULTISAMPLE_NONE ,0,true,&rttDepthSurface,NULL)); CubeEffect->OnResetDevice(); // init tonemap toneMap->Init(g_pd3dDevice, sourceTexture, oldRenderTarget); return S_OK; } //-------------------------------------------------------------------------------------- // 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(); SAFE_RELEASE(g_pTextSprite); if( g_pMesh != NULL ) SAFE_RELEASE(g_pMesh); pD3DXMtrlBuffer->Release(); if( g_pMeshTextures ) { for( DWORD i = 0; i < g_dwNumMaterials; i++ ) { if( g_pMeshTextures[i] ) { SAFE_RELEASE(g_pMeshTextures[i]); } } } g_pMeshTextures = 0; SAFE_RELEASE(sourceTextureSurface); SAFE_RELEASE(sourceTexture); SAFE_RELEASE(CubeTexture); SAFE_RELEASE(CubeTextureSurface) SAFE_RELEASE(CubeGlowTexture); SAFE_RELEASE(CubeGlowTextureSurface); SAFE_RELEASE(TempTexture[0]); SAFE_RELEASE(TempTextureSurface[0]); SAFE_RELEASE(TempTexture[1]); SAFE_RELEASE(TempTextureSurface[1]); SAFE_RELEASE(TempTexture[2]); SAFE_RELEASE(TempTextureSurface[2]); SAFE_RELEASE(rttDepthSurface); SAFE_RELEASE(oldRenderTarget); toneMap->Destroy(); CubeEffect->OnLostDevice(); } 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; } //-------------------------------------------------------------------------------------- // Handle updates to the scene //-------------------------------------------------------------------------------------- void CALLBACK OnFrameMove( IDirect3DDevice9* g_pd3dDevice, double fTime, float fElapsedTime, void* pUserContext ) { camera.FrameMove( fElapsedTime ); } //-------------------------------------------------------------------------------------- // Render the scene //-------------------------------------------------------------------------------------- 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; } // ligth rotating vecDir = D3DXVECTOR3(cosf(timeGetTime()/360.0f), 0.0f, sinf(timeGetTime()/360.0f) ); D3DXVec3Normalize( (D3DXVECTOR3*)&light.Direction, &vecDir ); light.Range = 1000.0f; g_pd3dDevice->SetLight( 0, &light ); g_pd3dDevice->LightEnable( 0, TRUE); g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE ); g_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0x00202020 ); // screen shot // IDirect3DSurface9* oldRenderTarget = NULL; if (bSavingScreenshot) { // V( g_pd3dDevice->GetRenderTarget(0, &oldRenderTarget) ); V( g_pd3dDevice->SetRenderTarget(0, g_pSaveSurface) ); } // ModelViewProjection matrix D3DXMATRIXA16 mView = *camera.GetViewMatrix(); D3DXMATRIXA16 mProj = *camera.GetProjMatrix(); D3DXMATRIXA16 mMVP = mView * mProj; // Original image g_pd3dDevice->SetRenderTarget(0, CubeTextureSurface); V( g_pd3dDevice->SetDepthStencilSurface(rttDepthSurface) ); // Clear the backbuffer and the zbuffer g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0 ); if( SUCCEEDED( g_pd3dDevice->BeginScene() ) ) { UINT numberofPasses=0; D3DXHANDLE techniqueHandle = CubeEffect->GetTechniqueByName("Cube"); V(CubeEffect->SetTechnique(techniqueHandle)); V(CubeEffect->SetMatrix("modelViewProjection", &mMVP)); V(CubeEffect->Begin(&numberofPasses,0)); for(UINT i = 0; iBeginPass(i)); // Meshes are divided into subsets, one for each material. Render them in // a loop for( DWORD i=0; iSetMaterial( &g_pMeshMaterials[i] ); //g_pd3dDevice->SetTexture( 0, g_pMeshTextures[i] ); V(CubeEffect->SetTexture("SourceTexture", g_pMeshTextures[i])); CubeEffect->CommitChanges(); // Draw the mesh subset g_pMesh->DrawSubset( i ); } V(CubeEffect->EndPass()); } V(CubeEffect->End()); g_pd3dDevice->EndScene(); } // Glow texture g_pd3dDevice->SetRenderTarget(0, CubeGlowTextureSurface); V( g_pd3dDevice->SetDepthStencilSurface(rttDepthSurface) ); g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0 ); if( SUCCEEDED( g_pd3dDevice->BeginScene() ) ) { UINT numberofPasses=0; D3DXHANDLE techniqueHandle = CubeEffect->GetTechniqueByName("CubeGlow"); V(CubeEffect->SetTechnique(techniqueHandle)); V(CubeEffect->SetMatrix("modelViewProjection", &mMVP)); V(CubeEffect->Begin(&numberofPasses,0)); for(UINT i = 0; iBeginPass(i)); // Meshes are divided into subsets, one for each material. Render them in // a loop for( DWORD i=0; iSetMaterial( &g_pMeshMaterials[i] ); //g_pd3dDevice->SetTexture( 0, g_pMeshTextures[i] ); V(CubeEffect->SetTexture("SourceTexture", g_pMeshTextures[i])); CubeEffect->CommitChanges(); // Draw the mesh subset g_pMesh->DrawSubset( i ); } V(CubeEffect->EndPass()); } V(CubeEffect->End()); g_pd3dDevice->EndScene(); } // Blurring // For each passes we cycle the temporary textures // At least two passes need, one for the horizontal and one for // the vertical blur int blurPass = 2; char* blurName = "Blur_h"; for (int i = 0; i< pp.Get(iGlowPasses); i++) { switch (blurPass) { case(0) : blurTargetSurface = TempTextureSurface[1]; blurTargetTexture = TempTexture[1]; blurTexture = TempTexture[0]; blurPass = 1; blurName="Blur_h"; break; case(1) : blurTargetSurface = TempTextureSurface[0]; blurTargetTexture = TempTexture[0]; blurTexture = TempTexture[1]; blurPass = 0; blurName="Blur_v"; break; case(2) : blurTargetSurface = TempTextureSurface[0]; blurTargetTexture = TempTexture[0]; blurTexture = CubeGlowTexture; blurPass = 0; blurName="Blur_v"; break; } D3DSURFACE_DESC desc; blurTargetSurface->GetDesc(&desc); g_pd3dDevice->SetRenderTarget(0, blurTargetSurface); V( g_pd3dDevice->SetDepthStencilSurface(rttDepthSurface) ); V( g_pd3dDevice->SetVertexDeclaration(textureDecl) ); g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0 ); if( SUCCEEDED( g_pd3dDevice->BeginScene() ) ) { UINT numberofPasses=0; D3DXHANDLE techniqueHandle = CubeEffect->GetTechniqueByName(blurName); V(CubeEffect->SetTechnique(techniqueHandle)); D3DXMatrixIdentity(&mMVP); V(CubeEffect->SetMatrix("modelViewProjection", &mMVP)); V(CubeEffect->SetTexture("OldGlow", TempTexture[2])); V(CubeEffect->SetTexture("Glow", blurTexture)); V(CubeEffect->SetFloat("dsWidth", desc.Width)); V(CubeEffect->SetFloat("dsHeight", desc.Height)); V(CubeEffect->SetFloat("GlowPasses", pp.GetInt(iGlowPasses))); V(CubeEffect->SetFloat("GlowGain", pp.Get(iGlowGain))); V(CubeEffect->SetFloat("Stretch", pp.Get(iStretch))); V(CubeEffect->Begin(&numberofPasses,0)); for(UINT i = 0; iBeginPass(i)); //Render triangle. V(g_pd3dDevice->SetStreamSource(0,pQuadVB,0,sizeof(D3DVERTEX_1))); V(g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST,0,1)); V(CubeEffect->EndPass()); } V(CubeEffect->End()); g_pd3dDevice->EndScene(); } } // Final compositing // The final image is composed from the original image and // the additive glow image g_pd3dDevice->SetRenderTarget(0, sourceTextureSurface); V( g_pd3dDevice->SetDepthStencilSurface(rttDepthSurface) ); V( g_pd3dDevice->SetVertexDeclaration(textureDecl) ); g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0 ); if( SUCCEEDED( g_pd3dDevice->BeginScene() ) ) { UINT numberofPasses=0; D3DXHANDLE techniqueHandle = CubeEffect->GetTechniqueByName("Final"); V(CubeEffect->SetTechnique(techniqueHandle)); D3DXMatrixIdentity(&mMVP); V(CubeEffect->SetMatrix("modelViewProjection", &mMVP)); V(CubeEffect->SetTexture("Original", CubeTexture)); V(CubeEffect->SetTexture("Glow", blurTargetTexture)); //V(CubeEffect->SetTexture("Glow", CubeGlowTexture)); V(CubeEffect->Begin(&numberofPasses,0)); for(UINT i = 0; iBeginPass(i)); //Render triangle. V(g_pd3dDevice->SetStreamSource(0,pQuadVB,0,sizeof(D3DVERTEX_1))); V(g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST,0,1)); V(CubeEffect->EndPass()); } V(CubeEffect->End()); g_pd3dDevice->EndScene(); } // Saving the blur history g_pd3dDevice->StretchRect(blurTargetSurface, NULL, TempTextureSurface[2], NULL, D3DTEXF_LINEAR); // Tone mapping toneMap->SetSource(sourceTexture); g_pd3dDevice->SetRenderTarget(0, oldRenderTarget); toneMap->SetGain(pp.Get(iGain)); toneMap->SetPasses(pp.Get(iPasses)); toneMap->Map(); // Screen shot if (!bSavingScreenshot && pp.Get(bShowHud)) { RenderText(); V( g_HUD.OnRender( fElapsedTime ) ); } 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; } } 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; } //-------------------------------------------------------------------------------------- // The framework does not remove the underlying keystroke messages, // which are still passed to the application's MsgProc callback. //-------------------------------------------------------------------------------------- void CALLBACK KeyboardProc( UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext ) { } 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); } 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); } //-------------------------------------------------------------------------------------- // Util function. // Creates an empty texture. These textures will be used as render targets, therefore // the Usage flag is set to D3DUSAGE_RENDERTARGET and consequently, the assigned // memory pool is D3DPOOL_DEFAULT. // Params: size and format (eg. D3DFMT_A32B32G32R32F) of the new texture. //-------------------------------------------------------------------------------------- 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; } //-------------------------------------------------------------------------------------- // Util function. // Creates an empty cubemap texture of the given resolution and format. //-------------------------------------------------------------------------------------- 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; } //-------------------------------------------------------------------------------------- // Render the help and statistics text. //-------------------------------------------------------------------------------------- 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( 5, 140 ); txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ) ); if ( pp.Get( bShowHelp ) ) { txtHelper.SetInsertionPos( backBufferDesc->Width - 260, backBufferDesc->Height-24*15 ); txtHelper.DrawTextLine( L"Controls (F1 to hide):\n\n" L"___________________________________\n" L" GENERAL CONTROLS\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"Add and Subtract: adjust gain\n" L"___________________________________\n" L" Quit: ESC"); } else { txtHelper.DrawTextLine( L"Press F1 for help" ); } txtHelper.End(); }