/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
- //--------------------------------------------------------------------------------
- // This file is a portion of the Hieroglyph 3 Rendering Engine. It is distributed
- // under the MIT License, available in the root of this distribution and
- // at the following URL:
- //
- // http://www.opensource.org/licenses/mit-license.php
- //
- // Copyright (c) 2003-2010 Jason Zink
- //--------------------------------------------------------------------------------
- #include "App.h"
- #include "Log.h"
-
- #include <sstream>
-
- #include "EventManager.h"
- #include "EvtFrameStart.h"
- #include "EvtChar.h"
- #include "EvtKeyUp.h"
- #include "EvtKeyDown.h"
-
- #include "ScriptManager.h"
-
- #include "SwapChainConfigDX11.h"
- #include "Texture2dConfigDX11.h"
-
- #include "GeometryGeneratorDX11.h"
- #include "RenderEffectDX11.h"
-
- #include "IParameterManager.h"
-
- using namespace Glyph3;
- //--------------------------------------------------------------------------------
- App AppInstance; // Provides an instance of the application
- //--------------------------------------------------------------------------------
-
-
- //--------------------------------------------------------------------------------
- App::App()
- {
- m_bSaveScreenshot = false;
- }
- //--------------------------------------------------------------------------------
- bool App::ConfigureEngineComponents()
- {
- int width = 640;
- int height = 480;
- bool windowed = true;
-
- // Set the render window parameters and initialize the window
- m_pWindow = new Win32RenderWindow();
- m_pWindow->SetPosition( 25, 25 );
- m_pWindow->SetSize( width, height );
- m_pWindow->SetCaption( GetName() );
- m_pWindow->Initialize( this );
-
-
- // Create the renderer and initialize it for the desired device
- // type and feature level.
-
- m_pRenderer11 = new RendererDX11();
-
- if ( !m_pRenderer11->Initialize( D3D_DRIVER_TYPE_HARDWARE, D3D_FEATURE_LEVEL_11_0 ) )
- {
- Log::Get().Write( L"Could not create hardware device, trying to create the reference device..." );
-
- if ( !m_pRenderer11->Initialize( D3D_DRIVER_TYPE_REFERENCE, D3D_FEATURE_LEVEL_11_0 ) )
- {
- ShowWindow( m_pWindow->GetHandle(), SW_HIDE );
- 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 );
- RequestTermination();
- return( false );
- }
-
- // If using the reference device, utilize a fixed time step for any animations.
- m_pTimer->SetFixedTimeStep( 1.0f / 10.0f );
- }
-
-
- // Create a swap chain for the window that we started out with. This
- // demonstrates using a configuration object for fast and concise object
- // creation.
-
- SwapChainConfigDX11 Config;
- Config.SetWidth( m_pWindow->GetWidth() );
- Config.SetHeight( m_pWindow->GetHeight() );
- Config.SetOutputWindow( m_pWindow->GetHandle() );
- m_iSwapChain = m_pRenderer11->CreateSwapChain( &Config );
- m_pWindow->SetSwapChain( m_iSwapChain );
-
- // We'll keep a copy of the render target index to use in later examples.
-
- m_RenderTarget = m_pRenderer11->GetSwapChainResource( m_iSwapChain );
-
-
- // Next we create a depth buffer for use in the traditional rendering
- // pipeline.
-
- Texture2dConfigDX11 DepthConfig;
- DepthConfig.SetDepthBuffer( width, height );
- m_DepthTarget = m_pRenderer11->CreateTexture2D( &DepthConfig, 0 );
-
-
- // Bind the swap chain render target and the depth buffer for use in
- // rendering.
-
- m_pRenderer11->pImmPipeline->ClearRenderTargets();
- m_pRenderer11->pImmPipeline->OutputMergerStage.DesiredState.SetRenderTarget( 0, m_RenderTarget->m_iResourceRTV );
- m_pRenderer11->pImmPipeline->OutputMergerStage.DesiredState.SetDepthStencilTarget( m_DepthTarget->m_iResourceDSV );
- m_pRenderer11->pImmPipeline->ApplyRenderTargets();
-
-
- // Create a view port to use on the scene. This basically selects the
- // entire floating point area of the render target.
-
- D3D11_VIEWPORT viewport;
- viewport.Width = static_cast< float >( width );
- viewport.Height = static_cast< float >( height );
- viewport.MinDepth = 0.0f;
- viewport.MaxDepth = 1.0f;
- viewport.TopLeftX = 0;
- viewport.TopLeftY = 0;
-
- int ViewPort = m_pRenderer11->CreateViewPort( viewport );
- m_pRenderer11->pImmPipeline->RasterizerStage.DesiredState.SetViewportCount( 1 );
- m_pRenderer11->pImmPipeline->RasterizerStage.DesiredState.SetViewport( 0, ViewPort );
-
- return( true );
- }
- //--------------------------------------------------------------------------------
- void App::ShutdownEngineComponents()
- {
- if ( m_pRenderer11 )
- {
- m_pRenderer11->Shutdown();
- delete m_pRenderer11;
- }
-
- if ( m_pWindow )
- {
- m_pWindow->Shutdown();
- delete m_pWindow;
- }
- }
- //--------------------------------------------------------------------------------
- void App::Initialize()
- {
- // Here we load our desired texture, and create a shader resource view to
- // use for input to the compute shader. By specifying null for the
- // configuration, the view is created from the default resource configuration.
-
- m_Texture = m_pRenderer11->LoadTexture( L"Outcrop.png" );
-
-
- // Create the texture for output of the compute shader.
- Texture2dConfigDX11 FilteredConfig;
- FilteredConfig.SetColorBuffer( 640, 480 );
- FilteredConfig.SetBindFlags( D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE );
-
- m_Output = m_pRenderer11->CreateTexture2D( &FilteredConfig, 0 );
-
- // Create RenderEffectDX11 instances to utilize the DX11 pipeline for
- // processing data. Both the standard rendering pipeline and the compute
- // shader pipeline use the RenderEffect to configure itself.
-
- m_pFilterEffect = new RenderEffectDX11();
- m_pFilterEffect->m_iComputeShader =
- m_pRenderer11->LoadShader( COMPUTE_SHADER,
- std::wstring( L"InvertColorCS.hlsl" ),
- std::wstring( L"CSMAIN" ),
- std::wstring( L"cs_5_0" ) );
-
- m_pTextureEffect = new RenderEffectDX11();
- m_pTextureEffect->m_iVertexShader =
- m_pRenderer11->LoadShader( VERTEX_SHADER,
- std::wstring( L"TextureVS.hlsl" ),
- std::wstring( L"VSMAIN" ),
- std::wstring( L"vs_5_0" ) );
- m_pTextureEffect->m_iPixelShader =
- m_pRenderer11->LoadShader( PIXEL_SHADER,
- std::wstring( L"TexturePS.hlsl" ),
- std::wstring( L"PSMAIN" ),
- std::wstring( L"ps_5_0" ) );
-
- // Create a full screen quad for rendering the texture to the backbuffer.
-
- m_pFullScreen = GeometryPtr( new GeometryDX11() );
- GeometryGeneratorDX11::GenerateFullScreenQuad( m_pFullScreen );
-
- m_pFullScreen->GenerateInputLayout( m_pTextureEffect->m_iVertexShader );
- m_pFullScreen->LoadToBuffers();
-
- // Specify the bindings for the resources. These take as input a parameter
- // name and a resource proxy object created above. This will connect these
- // resources with the appropriate shader variables at rendering time. The
- // resource proxy object contains the needed 'ResourceView' instances.
-
- m_pRenderer11->m_pParamMgr->SetShaderResourceParameter( L"InputMap", m_Texture );
- m_pRenderer11->m_pParamMgr->SetUnorderedAccessParameter( L"OutputMap", m_Output );
- m_pRenderer11->m_pParamMgr->SetShaderResourceParameter( L"ColorMap00", m_Output );
- }
- //--------------------------------------------------------------------------------
- void App::Update()
- {
- // Update the timer to determine the elapsed time since last frame. This can
- // then used for animation during the frame.
-
- m_pTimer->Update();
-
- // Send an event to everyone that a new frame has started. This will be used
- // in later examples for using the material system with render views.
-
- EventManager::Get()->ProcessEvent( new EvtFrameStart( *m_pTimer ) );
-
- // Perform the filtering with the compute shader. The assumption in this case
- // is that the texture is 640x480 - if there is a different size then the
- // dispatch call can be modified accordingly.
-
- m_pRenderer11->pImmPipeline->Dispatch( *m_pFilterEffect, 32, 24, 1, m_pRenderer11->m_pParamMgr );
-
- m_pRenderer11->pImmPipeline->ClearPipelineResources();
- m_pRenderer11->pImmPipeline->ApplyPipelineResources();
-
- // Render the texture to the backbuffer.
-
- m_pRenderer11->pImmPipeline->ClearBuffers( Vector4f( 0.0f, 0.0f, 0.0f, 0.0f ), 1.0f );
- m_pRenderer11->pImmPipeline->Draw( *m_pTextureEffect, m_pFullScreen, m_pRenderer11->m_pParamMgr );
-
- // Present the results to the window.
-
- m_pRenderer11->Present( m_pWindow->GetHandle(), m_pWindow->GetSwapChain() );
-
- // Save a screenshot if desired. This is done by pressing the 's' key, which
- // demonstrates how an event is sent and handled by an event listener (which
- // in this case is the application object itself).
-
- if ( m_bSaveScreenshot )
- {
- m_bSaveScreenshot = false;
- m_pRenderer11->pImmPipeline->SaveTextureScreenShot( 0, GetName(), D3DX11_IFF_BMP );
- }
- }
- //--------------------------------------------------------------------------------
- void App::Shutdown()
- {
- m_pFullScreen = NULL;
-
- // Print the framerate out for the log before shutting down.
-
- std::wstringstream out;
- out << L"Max FPS: " << m_pTimer->MaxFramerate();
- Log::Get().Write( out.str() );
- }
- //--------------------------------------------------------------------------------
- bool App::HandleEvent( IEvent* pEvent )
- {
- eEVENT e = pEvent->GetEventType();
-
- if ( e == SYSTEM_KEYBOARD_KEYDOWN )
- {
- EvtKeyDown* pKeyDown = (EvtKeyDown*)pEvent;
-
- unsigned int key = pKeyDown->GetCharacterCode();
-
- return( true );
- }
- else if ( e == SYSTEM_KEYBOARD_KEYUP )
- {
- EvtKeyUp* pKeyUp = (EvtKeyUp*)pEvent;
-
- unsigned int key = pKeyUp->GetCharacterCode();
-
- if ( key == VK_ESCAPE ) // 'Esc' Key - Exit the application
- {
- this->RequestTermination();
- return( true );
- }
- else if ( key == 0x53 ) // 'S' Key - Save a screen shot for the next frame
- {
- m_bSaveScreenshot = true;
- return( true );
- }
- else
- {
- return( false );
- }
- }
-
- // Call the parent class's event handler if we haven't handled the event.
-
- return( Application::HandleEvent( pEvent ) );
- }
- //--------------------------------------------------------------------------------
- std::wstring App::GetName( )
- {
- return( std::wstring( L"BasicComputeShader" ) );
- }
- //--------------------------------------------------------------------------------