PageRenderTime 40ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

/trunk/Hieroglyph3/Applications/BasicComputeShader/App.cpp

#
C++ | 297 lines | 171 code | 66 blank | 60 comment | 15 complexity | 36c2b7c5a612ab80009b8b73ad2232d4 MD5 | raw file
Possible License(s): MIT
  1. //--------------------------------------------------------------------------------
  2. // This file is a portion of the Hieroglyph 3 Rendering Engine. It is distributed
  3. // under the MIT License, available in the root of this distribution and
  4. // at the following URL:
  5. //
  6. // http://www.opensource.org/licenses/mit-license.php
  7. //
  8. // Copyright (c) 2003-2010 Jason Zink
  9. //--------------------------------------------------------------------------------
  10. #include "App.h"
  11. #include "Log.h"
  12. #include <sstream>
  13. #include "EventManager.h"
  14. #include "EvtFrameStart.h"
  15. #include "EvtChar.h"
  16. #include "EvtKeyUp.h"
  17. #include "EvtKeyDown.h"
  18. #include "ScriptManager.h"
  19. #include "SwapChainConfigDX11.h"
  20. #include "Texture2dConfigDX11.h"
  21. #include "GeometryGeneratorDX11.h"
  22. #include "RenderEffectDX11.h"
  23. #include "IParameterManager.h"
  24. using namespace Glyph3;
  25. //--------------------------------------------------------------------------------
  26. App AppInstance; // Provides an instance of the application
  27. //--------------------------------------------------------------------------------
  28. //--------------------------------------------------------------------------------
  29. App::App()
  30. {
  31. m_bSaveScreenshot = false;
  32. }
  33. //--------------------------------------------------------------------------------
  34. bool App::ConfigureEngineComponents()
  35. {
  36. int width = 640;
  37. int height = 480;
  38. bool windowed = true;
  39. // Set the render window parameters and initialize the window
  40. m_pWindow = new Win32RenderWindow();
  41. m_pWindow->SetPosition( 25, 25 );
  42. m_pWindow->SetSize( width, height );
  43. m_pWindow->SetCaption( GetName() );
  44. m_pWindow->Initialize( this );
  45. // Create the renderer and initialize it for the desired device
  46. // type and feature level.
  47. m_pRenderer11 = new RendererDX11();
  48. if ( !m_pRenderer11->Initialize( D3D_DRIVER_TYPE_HARDWARE, D3D_FEATURE_LEVEL_11_0 ) )
  49. {
  50. Log::Get().Write( L"Could not create hardware device, trying to create the reference device..." );
  51. if ( !m_pRenderer11->Initialize( D3D_DRIVER_TYPE_REFERENCE, D3D_FEATURE_LEVEL_11_0 ) )
  52. {
  53. ShowWindow( m_pWindow->GetHandle(), SW_HIDE );
  54. MessageBox( m_pWindow->GetHandle(), L"Could not create a hardware or software Direct3D 11 device - the program will now abort!", L"Hieroglyph 3 Rendering", MB_ICONEXCLAMATION | MB_SYSTEMMODAL );
  55. RequestTermination();
  56. return( false );
  57. }
  58. // If using the reference device, utilize a fixed time step for any animations.
  59. m_pTimer->SetFixedTimeStep( 1.0f / 10.0f );
  60. }
  61. // Create a swap chain for the window that we started out with. This
  62. // demonstrates using a configuration object for fast and concise object
  63. // creation.
  64. SwapChainConfigDX11 Config;
  65. Config.SetWidth( m_pWindow->GetWidth() );
  66. Config.SetHeight( m_pWindow->GetHeight() );
  67. Config.SetOutputWindow( m_pWindow->GetHandle() );
  68. m_iSwapChain = m_pRenderer11->CreateSwapChain( &Config );
  69. m_pWindow->SetSwapChain( m_iSwapChain );
  70. // We'll keep a copy of the render target index to use in later examples.
  71. m_RenderTarget = m_pRenderer11->GetSwapChainResource( m_iSwapChain );
  72. // Next we create a depth buffer for use in the traditional rendering
  73. // pipeline.
  74. Texture2dConfigDX11 DepthConfig;
  75. DepthConfig.SetDepthBuffer( width, height );
  76. m_DepthTarget = m_pRenderer11->CreateTexture2D( &DepthConfig, 0 );
  77. // Bind the swap chain render target and the depth buffer for use in
  78. // rendering.
  79. m_pRenderer11->pImmPipeline->ClearRenderTargets();
  80. m_pRenderer11->pImmPipeline->OutputMergerStage.DesiredState.SetRenderTarget( 0, m_RenderTarget->m_iResourceRTV );
  81. m_pRenderer11->pImmPipeline->OutputMergerStage.DesiredState.SetDepthStencilTarget( m_DepthTarget->m_iResourceDSV );
  82. m_pRenderer11->pImmPipeline->ApplyRenderTargets();
  83. // Create a view port to use on the scene. This basically selects the
  84. // entire floating point area of the render target.
  85. D3D11_VIEWPORT viewport;
  86. viewport.Width = static_cast< float >( width );
  87. viewport.Height = static_cast< float >( height );
  88. viewport.MinDepth = 0.0f;
  89. viewport.MaxDepth = 1.0f;
  90. viewport.TopLeftX = 0;
  91. viewport.TopLeftY = 0;
  92. int ViewPort = m_pRenderer11->CreateViewPort( viewport );
  93. m_pRenderer11->pImmPipeline->RasterizerStage.DesiredState.SetViewportCount( 1 );
  94. m_pRenderer11->pImmPipeline->RasterizerStage.DesiredState.SetViewport( 0, ViewPort );
  95. return( true );
  96. }
  97. //--------------------------------------------------------------------------------
  98. void App::ShutdownEngineComponents()
  99. {
  100. if ( m_pRenderer11 )
  101. {
  102. m_pRenderer11->Shutdown();
  103. delete m_pRenderer11;
  104. }
  105. if ( m_pWindow )
  106. {
  107. m_pWindow->Shutdown();
  108. delete m_pWindow;
  109. }
  110. }
  111. //--------------------------------------------------------------------------------
  112. void App::Initialize()
  113. {
  114. // Here we load our desired texture, and create a shader resource view to
  115. // use for input to the compute shader. By specifying null for the
  116. // configuration, the view is created from the default resource configuration.
  117. m_Texture = m_pRenderer11->LoadTexture( L"Outcrop.png" );
  118. // Create the texture for output of the compute shader.
  119. Texture2dConfigDX11 FilteredConfig;
  120. FilteredConfig.SetColorBuffer( 640, 480 );
  121. FilteredConfig.SetBindFlags( D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE );
  122. m_Output = m_pRenderer11->CreateTexture2D( &FilteredConfig, 0 );
  123. // Create RenderEffectDX11 instances to utilize the DX11 pipeline for
  124. // processing data. Both the standard rendering pipeline and the compute
  125. // shader pipeline use the RenderEffect to configure itself.
  126. m_pFilterEffect = new RenderEffectDX11();
  127. m_pFilterEffect->m_iComputeShader =
  128. m_pRenderer11->LoadShader( COMPUTE_SHADER,
  129. std::wstring( L"InvertColorCS.hlsl" ),
  130. std::wstring( L"CSMAIN" ),
  131. std::wstring( L"cs_5_0" ) );
  132. m_pTextureEffect = new RenderEffectDX11();
  133. m_pTextureEffect->m_iVertexShader =
  134. m_pRenderer11->LoadShader( VERTEX_SHADER,
  135. std::wstring( L"TextureVS.hlsl" ),
  136. std::wstring( L"VSMAIN" ),
  137. std::wstring( L"vs_5_0" ) );
  138. m_pTextureEffect->m_iPixelShader =
  139. m_pRenderer11->LoadShader( PIXEL_SHADER,
  140. std::wstring( L"TexturePS.hlsl" ),
  141. std::wstring( L"PSMAIN" ),
  142. std::wstring( L"ps_5_0" ) );
  143. // Create a full screen quad for rendering the texture to the backbuffer.
  144. m_pFullScreen = GeometryPtr( new GeometryDX11() );
  145. GeometryGeneratorDX11::GenerateFullScreenQuad( m_pFullScreen );
  146. m_pFullScreen->GenerateInputLayout( m_pTextureEffect->m_iVertexShader );
  147. m_pFullScreen->LoadToBuffers();
  148. // Specify the bindings for the resources. These take as input a parameter
  149. // name and a resource proxy object created above. This will connect these
  150. // resources with the appropriate shader variables at rendering time. The
  151. // resource proxy object contains the needed 'ResourceView' instances.
  152. m_pRenderer11->m_pParamMgr->SetShaderResourceParameter( L"InputMap", m_Texture );
  153. m_pRenderer11->m_pParamMgr->SetUnorderedAccessParameter( L"OutputMap", m_Output );
  154. m_pRenderer11->m_pParamMgr->SetShaderResourceParameter( L"ColorMap00", m_Output );
  155. }
  156. //--------------------------------------------------------------------------------
  157. void App::Update()
  158. {
  159. // Update the timer to determine the elapsed time since last frame. This can
  160. // then used for animation during the frame.
  161. m_pTimer->Update();
  162. // Send an event to everyone that a new frame has started. This will be used
  163. // in later examples for using the material system with render views.
  164. EventManager::Get()->ProcessEvent( new EvtFrameStart( *m_pTimer ) );
  165. // Perform the filtering with the compute shader. The assumption in this case
  166. // is that the texture is 640x480 - if there is a different size then the
  167. // dispatch call can be modified accordingly.
  168. m_pRenderer11->pImmPipeline->Dispatch( *m_pFilterEffect, 32, 24, 1, m_pRenderer11->m_pParamMgr );
  169. m_pRenderer11->pImmPipeline->ClearPipelineResources();
  170. m_pRenderer11->pImmPipeline->ApplyPipelineResources();
  171. // Render the texture to the backbuffer.
  172. m_pRenderer11->pImmPipeline->ClearBuffers( Vector4f( 0.0f, 0.0f, 0.0f, 0.0f ), 1.0f );
  173. m_pRenderer11->pImmPipeline->Draw( *m_pTextureEffect, m_pFullScreen, m_pRenderer11->m_pParamMgr );
  174. // Present the results to the window.
  175. m_pRenderer11->Present( m_pWindow->GetHandle(), m_pWindow->GetSwapChain() );
  176. // Save a screenshot if desired. This is done by pressing the 's' key, which
  177. // demonstrates how an event is sent and handled by an event listener (which
  178. // in this case is the application object itself).
  179. if ( m_bSaveScreenshot )
  180. {
  181. m_bSaveScreenshot = false;
  182. m_pRenderer11->pImmPipeline->SaveTextureScreenShot( 0, GetName(), D3DX11_IFF_BMP );
  183. }
  184. }
  185. //--------------------------------------------------------------------------------
  186. void App::Shutdown()
  187. {
  188. m_pFullScreen = NULL;
  189. // Print the framerate out for the log before shutting down.
  190. std::wstringstream out;
  191. out << L"Max FPS: " << m_pTimer->MaxFramerate();
  192. Log::Get().Write( out.str() );
  193. }
  194. //--------------------------------------------------------------------------------
  195. bool App::HandleEvent( IEvent* pEvent )
  196. {
  197. eEVENT e = pEvent->GetEventType();
  198. if ( e == SYSTEM_KEYBOARD_KEYDOWN )
  199. {
  200. EvtKeyDown* pKeyDown = (EvtKeyDown*)pEvent;
  201. unsigned int key = pKeyDown->GetCharacterCode();
  202. return( true );
  203. }
  204. else if ( e == SYSTEM_KEYBOARD_KEYUP )
  205. {
  206. EvtKeyUp* pKeyUp = (EvtKeyUp*)pEvent;
  207. unsigned int key = pKeyUp->GetCharacterCode();
  208. if ( key == VK_ESCAPE ) // 'Esc' Key - Exit the application
  209. {
  210. this->RequestTermination();
  211. return( true );
  212. }
  213. else if ( key == 0x53 ) // 'S' Key - Save a screen shot for the next frame
  214. {
  215. m_bSaveScreenshot = true;
  216. return( true );
  217. }
  218. else
  219. {
  220. return( false );
  221. }
  222. }
  223. // Call the parent class's event handler if we haven't handled the event.
  224. return( Application::HandleEvent( pEvent ) );
  225. }
  226. //--------------------------------------------------------------------------------
  227. std::wstring App::GetName( )
  228. {
  229. return( std::wstring( L"BasicComputeShader" ) );
  230. }
  231. //--------------------------------------------------------------------------------