LightRenderer::LightRenderer(IRenderer& renderer, IShaderProgram& directionnalShader, IShaderProgram& pointShader) : _renderer(renderer) { int nbDirectionnalShadowMap = 4; this->_directionnal.shader = &directionnalShader; this->_directionnal.normalDepth = &this->_directionnal.shader->GetParameter("normalDepth"); this->_directionnal.direction = &this->_directionnal.shader->GetParameter("lightDirection"); this->_directionnal.ambientColor = &this->_directionnal.shader->GetParameter("lightAmbientColor"); this->_directionnal.diffuseColor = &this->_directionnal.shader->GetParameter("lightDiffuseColor"); this->_directionnal.specularColor = &this->_directionnal.shader->GetParameter("lightSpecularColor"); this->_directionnal.screenModelViewProjection = &this->_directionnal.shader->GetParameter("screenWorldViewProjection"); this->_directionnal.shadowMap = &this->_directionnal.shader->GetParameter("lightShadowMap"); this->_directionnal.lightViewProjection = &this->_directionnal.shader->GetParameter("lightViewProjection"); this->_directionnal.screen.reset(new Image(renderer)); this->_directionnal.modelViewProjection = glm::ortho(-0.5f, 0.5f, 0.5f, -0.5f) * glm::translate(0.0f, 0.0f, 1.0f); for (int i = 0; i < nbDirectionnalShadowMap; ++i) { auto ptr = renderer.CreateRenderTarget(glm::uvec2(512, 512)); ptr->PushRenderTarget(PixelFormat::R32f, RenderTargetUsage::Color); ptr->PushRenderTarget(PixelFormat::Depth24Stencil8, RenderTargetUsage::DepthStencil); this->_directionnal.shadowMaps.push_back(std::make_pair(glm::mat4(), std::move(ptr))); } this->_point.shader = &pointShader; this->_point.normalDepth = &this->_point.shader->GetParameter("normalDepth"); this->_point.position = &this->_point.shader->GetParameter("lightPosition"); this->_point.range = &this->_point.shader->GetParameter("lightRange"); this->_point.diffuseColor = &this->_point.shader->GetParameter("lightDiffuseColor"); this->_point.specularColor = &this->_point.shader->GetParameter("lightSpecularColor"); this->_point.sphere.reset(new Sphere(renderer)); }
//-------------------------------------------------------------------------------------- // Name: Downsample4x4Texture() // Desc: Scale down pSrcTexture by 1/4 x 1/4 and place the result in pDstTexture //-------------------------------------------------------------------------------------- VOID PostProcess::Downsample4x4Texture( LPDIRECT3DTEXTURE9 pSrcTexture, LPDIRECT3DTEXTURE9 pDstTexture ) { // Make sure that the required shaders and objects exist assert( m_pDownScale4x4PS ); assert( pSrcTexture && pDstTexture ); XGTEXTURE_DESC SrcDesc; XGGetTextureDesc( pSrcTexture, 0, &SrcDesc ); // Create and set a render target PushRenderTarget( 0L, CreateRenderTarget( pDstTexture ) ); // Get the sample offsets used within the pixel shader XMVECTOR avSampleOffsets[MAX_SAMPLES]; GetSampleOffsets_DownScale4x4( SrcDesc.Width, SrcDesc.Height, avSampleOffsets ); g_pd3dDevice->SetPixelShaderConstantF( PSCONST_avSampleOffsets, ( FLOAT* )avSampleOffsets, MAX_SAMPLES ); g_pd3dDevice->SetPixelShader( m_pDownScale4x4PS ); g_pd3dDevice->SetTexture( 0, pSrcTexture ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_POINT ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP ); // Draw a fullscreen quad DrawFullScreenQuad(); g_pd3dDevice->Resolve( D3DRESOLVE_RENDERTARGET0, NULL, pDstTexture, NULL, 0, 0, NULL, 1.0f, 0L, NULL ); // Cleanup and return PopRenderTarget( 0L )->Release(); g_pd3dDevice->SetPixelShader( NULL ); }
//-------------------------------------------------------------------------------------- // Name: SampleLuminance() // Desc: Measure the average log luminance in the scene. //-------------------------------------------------------------------------------------- VOID PostProcess::SampleLuminance( LPDIRECT3DTEXTURE9 pSrcTexture, BOOL bInitial, LPDIRECT3DTEXTURE9 pDstTexture ) { // Make sure that the required shaders and objects exist assert( m_pSampleLumInitialPS ); assert( m_pSampleLumFinalPS ); assert( pSrcTexture && pDstTexture ); XGTEXTURE_DESC SrcDesc; XGGetTextureDesc( pSrcTexture, 0, &SrcDesc ); // Create and set a render target PushRenderTarget( 0L, CreateRenderTarget( pDstTexture ) ); // Sample initial luminance if( bInitial ) { // Initialize the sample offsets for the initial luminance pass. XMVECTOR avSampleOffsets[MAX_SAMPLES]; GetSampleOffsets_DownScale3x3( SrcDesc.Width, SrcDesc.Height, avSampleOffsets ); g_pd3dDevice->SetPixelShaderConstantF( PSCONST_avSampleOffsets, ( FLOAT* )avSampleOffsets, MAX_SAMPLES ); g_pd3dDevice->SetPixelShader( m_pSampleLumInitialPS ); g_pd3dDevice->SetTexture( 0, pSrcTexture ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP ); } else // ( bIntial == FALSE ) { // Perform the final pass of the average luminance calculation. This pass // performs an exp() operation to return a single texel cooresponding to the // average luminance of the scene in m_pToneMapTexture. XMVECTOR avSampleOffsets[MAX_SAMPLES]; GetSampleOffsets_DownScale4x4( SrcDesc.Width, SrcDesc.Height, avSampleOffsets ); g_pd3dDevice->SetPixelShaderConstantF( PSCONST_avSampleOffsets, ( FLOAT* )avSampleOffsets, MAX_SAMPLES ); g_pd3dDevice->SetPixelShader( m_pSampleLumFinalPS ); g_pd3dDevice->SetTexture( 0, pSrcTexture ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_POINT ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP ); } // Draw a fullscreen quad to sample the RT DrawFullScreenQuad(); g_pd3dDevice->Resolve( D3DRESOLVE_RENDERTARGET0, NULL, pDstTexture, NULL, 0, 0, NULL, 1.0f, 0L, NULL ); // Cleanup and return PopRenderTarget( 0L )->Release(); g_pd3dDevice->SetPixelShader( NULL ); }
//-------------------------------------------------------------------------------------- // Name: RenderStarLine() // Desc: Merge the ppSrcTextures and place the result in pDstTexture //-------------------------------------------------------------------------------------- VOID PostProcess::RenderStarLine( LPDIRECT3DTEXTURE9 pSrcTexture, DWORD dwNumSamples, FLOAT fAttenuation, FLOAT fAttnPowScale, XMVECTOR* colors, DWORD pass, FLOAT fStepU, FLOAT fStepV, LPDIRECT3DTEXTURE9 pDstTexture ) { // Make sure that the required shaders and objects exist assert( m_pStarPS ); assert( pSrcTexture && pDstTexture ); // Create and set a render target PushRenderTarget( 0L, CreateRenderTarget( pDstTexture ) ); XMVECTOR avSampleOffsets[MAX_SAMPLES]; XMVECTOR avSampleWeights[MAX_SAMPLES]; // Sampling configration for each stage for( DWORD i = 0; i < dwNumSamples; i++ ) { FLOAT lum = powf( fAttenuation, fAttnPowScale * i ); avSampleWeights[i] = colors[i] * lum * ( pass + 1.0f ) * 0.5f; // Offset of sampling coordinate avSampleOffsets[i].x = fStepU * i; avSampleOffsets[i].y = fStepV * i; if( fabs( avSampleOffsets[i].x ) >= 0.9f || fabs( avSampleOffsets[i].y ) >= 0.9f ) { avSampleOffsets[i].x = 0.0f; avSampleOffsets[i].y = 0.0f; avSampleWeights[i] *= 0.0f; } } g_pd3dDevice->SetPixelShader( m_pStarPS ); g_pd3dDevice->SetPixelShaderConstantF( PSCONST_avSampleOffsets, ( FLOAT* )avSampleOffsets, MAX_SAMPLES ); g_pd3dDevice->SetPixelShaderConstantF( PSCONST_avSampleWeights, ( FLOAT* )avSampleWeights, MAX_SAMPLES ); g_pd3dDevice->SetTexture( 0, pSrcTexture ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP ); // Draw a fullscreen quad to sample the RT DrawFullScreenQuad(); g_pd3dDevice->Resolve( D3DRESOLVE_RENDERTARGET0, NULL, pDstTexture, NULL, 0, 0, NULL, 1.0f, 0L, NULL ); // Cleanup and return PopRenderTarget( 0L )->Release(); g_pd3dDevice->SetPixelShader( NULL ); }
//-------------------------------------------------------------------------------------- // Name: CopyTexture() // Desc: Copy the src texture to the dst texture. The scale can (and should) be changed. //-------------------------------------------------------------------------------------- VOID PostProcess::CopyTexture( LPDIRECT3DTEXTURE9 pSrcTexture, LPDIRECT3DTEXTURE9 pDstTexture, LPDIRECT3DPIXELSHADER9 pPixelShader, DWORD dwEdramOffset ) { if( NULL == pPixelShader ) pPixelShader = m_pCopyTexturePS; // Make sure that the required shaders and objects exist assert( pPixelShader ); assert( pSrcTexture && pDstTexture ); XGTEXTURE_DESC SrcDesc; XGGetTextureDesc( pSrcTexture, 0, &SrcDesc ); // Create and set a render target D3DSURFACE_PARAMETERS surfaceParams = { 0 }; surfaceParams.Base = dwEdramOffset; PushRenderTarget( 0L, CreateRenderTarget( pDstTexture, &surfaceParams ) ); // Scale and copy the src texture g_pd3dDevice->SetPixelShader( pPixelShader ); g_pd3dDevice->SetTexture( 0, pSrcTexture ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP ); // Draw a fullscreen quad to sample the RT DrawFullScreenQuad(); XGTEXTURE_DESC DstDesc; XGGetTextureDesc( pDstTexture, 0, &DstDesc ); DWORD ColorExpBias = 0; if( DstDesc.Format == D3DFMT_G16R16_SIGNED_INTEGER ) ColorExpBias = ( DWORD ) D3DRESOLVE_EXPONENTBIAS( 10 ); else if( DstDesc.Format == D3DFMT_A16B16G16R16_SIGNED_INTEGER ) ColorExpBias = ( DWORD ) D3DRESOLVE_EXPONENTBIAS( 10 ); g_pd3dDevice->Resolve( D3DRESOLVE_RENDERTARGET0 | ColorExpBias, NULL, pDstTexture, NULL, 0, 0, NULL, 1.0f, 0L, NULL ); // Cleanup and return PopRenderTarget( 0L )->Release(); g_pd3dDevice->SetPixelShader( NULL ); }
//-------------------------------------------------------------------------------------- // Name: BuildMipMaps() // Desc: Generate mip maps from the base texture //-------------------------------------------------------------------------------------- VOID PostProcess::BuildMipMaps( LPDIRECT3DTEXTURE9 pTexture ) { // Make sure that the required shaders and objects exist assert( m_pCopyTexturePS ); assert( pTexture ); DWORD dwNumMipLevels = pTexture->GetLevelCount(); // Create and set a render target PushRenderTarget( 0L, CreateRenderTarget( pTexture ) ); // Scale and copy the src texture g_pd3dDevice->SetPixelShader( m_pCopyTexturePS ); g_pd3dDevice->SetTexture( 0, pTexture ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP ); D3DVIEWPORT9 vp; g_pd3dDevice->GetViewport( &vp ); for( DWORD i = 1; i < dwNumMipLevels; i++ ) { XGTEXTURE_DESC Desc; XGGetTextureDesc( pTexture, i, &Desc ); vp.Width = Desc.Width; vp.Height = Desc.Height; g_pd3dDevice->SetViewport( &vp ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINMIPLEVEL, i - 1 ); // Draw a fullscreen quad to sample the RT DrawFullScreenQuad(); DWORD ColorExpBias = 0; if( Desc.Format == D3DFMT_G16R16_SIGNED_INTEGER ) ColorExpBias = (DWORD) D3DRESOLVE_EXPONENTBIAS(10); else if( Desc.Format == D3DFMT_A16B16G16R16_SIGNED_INTEGER ) ColorExpBias = (DWORD) D3DRESOLVE_EXPONENTBIAS(10); g_pd3dDevice->Resolve( D3DRESOLVE_RENDERTARGET0 | ColorExpBias, NULL, pTexture, NULL, i, 0, NULL, 1.0f, 0L, NULL ); } // Cleanup and return g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINMIPLEVEL, 13 ); PopRenderTarget( 0L )->Release(); g_pd3dDevice->SetPixelShader( NULL ); }
//-------------------------------------------------------------------------------------- // Name: BloomTexture() // Desc: Bloom the pSrcTexture and place the result in pDstTexture //-------------------------------------------------------------------------------------- VOID PostProcess::BloomTexture( LPDIRECT3DTEXTURE9 pSrcTexture, BOOL bBloomAcrossWidth, LPDIRECT3DTEXTURE9 pDstTexture, FLOAT fSize, FLOAT fBrightness ) { // Make sure that the required shaders and objects exist assert( m_pBloomPS ); assert( pSrcTexture && pDstTexture ); XGTEXTURE_DESC SrcDesc; XGGetTextureDesc( pSrcTexture, 0, &SrcDesc ); // Create and set a render target PushRenderTarget( 0L, CreateRenderTarget( pDstTexture ) ); XMVECTOR avSampleOffsets[MAX_SAMPLES]; XMVECTOR avSampleWeights[MAX_SAMPLES]; if( bBloomAcrossWidth ) GetSampleOffsets_Bloom( SrcDesc.Width, SrcDesc.Height, 0.0f * XM_PIDIV2, avSampleOffsets, avSampleWeights, fSize, fBrightness ); else GetSampleOffsets_Bloom( SrcDesc.Width, SrcDesc.Height, 1.0f * XM_PIDIV2, avSampleOffsets, avSampleWeights, fSize, fBrightness ); g_pd3dDevice->SetPixelShaderConstantF( PSCONST_avSampleOffsets, ( FLOAT* )avSampleOffsets, MAX_SAMPLES ); g_pd3dDevice->SetPixelShaderConstantF( PSCONST_avSampleWeights, ( FLOAT* )avSampleWeights, MAX_SAMPLES ); g_pd3dDevice->SetPixelShader( m_pBloomPS ); g_pd3dDevice->SetTexture( 0, pSrcTexture ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_POINT ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP ); // Draw a fullscreen quad to sample the RT DrawFullScreenQuad(); g_pd3dDevice->Resolve( D3DRESOLVE_RENDERTARGET0, NULL, pDstTexture, NULL, 0, 0, NULL, 1.0f, 0L, NULL ); // Cleanup and return PopRenderTarget( 0L )->Release(); g_pd3dDevice->SetPixelShader( NULL ); }
//-------------------------------------------------------------------------------------- // Name: Downsample2x2Texture() // Desc: Scale down pSrcTexture by 1/2 x 1/2 and place the result in pDstTexture //-------------------------------------------------------------------------------------- VOID PostProcess::Downsample2x2Texture( LPDIRECT3DTEXTURE9 pSrcTexture, LPDIRECT3DTEXTURE9 pDstTexture, DWORD dwEdramOffset ) { // Make sure that the required shaders and objects exist assert( m_pDownScale2x2PS ); assert( pSrcTexture && pDstTexture ); XGTEXTURE_DESC SrcDesc; XGGetTextureDesc( pSrcTexture, 0, &SrcDesc ); // Create and set a render target D3DSURFACE_PARAMETERS surfaceParams = { 0 }; surfaceParams.Base = dwEdramOffset; PushRenderTarget( 0L, CreateRenderTarget( pDstTexture, &surfaceParams ) ); XMVECTOR avSampleOffsets[MAX_SAMPLES]; GetSampleOffsets_DownScale2x2( SrcDesc.Width, SrcDesc.Height, avSampleOffsets ); g_pd3dDevice->SetPixelShaderConstantF( PSCONST_avSampleOffsets, ( FLOAT* )avSampleOffsets, MAX_SAMPLES ); // Create an exact 1/2 x 1/2 copy of the source texture g_pd3dDevice->SetPixelShader( m_pDownScale2x2PS ); g_pd3dDevice->SetTexture( 0, pSrcTexture ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_POINT ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP ); // TODO: This should use border addressing with a black border! //m_pStarSourceTexture->Format.ClampX = GPUCLAMP_CLAMP_TO_BORDER; //m_pStarSourceTexture->Format.ClampY = GPUCLAMP_CLAMP_TO_BORDER; //m_pStarSourceTexture->Format.BorderColor = GPUBORDERCOLOR_ABGR_BLACK; //g_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER ); //g_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER ); // Draw a fullscreen quad to sample the RT DrawFullScreenQuad(); g_pd3dDevice->Resolve( D3DRESOLVE_RENDERTARGET0, NULL, pDstTexture, NULL, 0, 0, NULL, 1.0f, 0L, NULL ); // Cleanup and return PopRenderTarget( 0L )->Release(); g_pd3dDevice->SetPixelShader( NULL ); }
//-------------------------------------------------------------------------------------- // Name: BrightPassFilterTexture() // Desc: Run the bright-pass filter on m_pScaledSceneTexture and place the result // in m_pBrightPassTexture //-------------------------------------------------------------------------------------- VOID PostProcess::BrightPassFilterTexture( LPDIRECT3DTEXTURE9 pSrcTexture, LPDIRECT3DTEXTURE9 pAdaptedLuminanceTexture, FLOAT fMiddleGrayKeyValue, LPDIRECT3DTEXTURE9 pDstTexture ) { // Make sure that the required shaders and objects exist assert( m_pBrightPassFilterPS ); assert( pSrcTexture && pDstTexture ); XGTEXTURE_DESC SrcDesc; XGGetTextureDesc( pSrcTexture, 0, &SrcDesc ); // Create and set a render target PushRenderTarget( 0L, CreateRenderTarget( pDstTexture ) ); // Get the offsets to be used within the GaussBlur5x5 pixel shader XMVECTOR avSampleOffsets[MAX_SAMPLES]; XMVECTOR avSampleWeights[MAX_SAMPLES]; GetSampleOffsets_GaussBlur5x5( SrcDesc.Width, SrcDesc.Height, avSampleOffsets, avSampleWeights ); g_pd3dDevice->SetPixelShaderConstantF( PSCONST_avSampleOffsets, ( FLOAT* )avSampleOffsets, MAX_SAMPLES ); g_pd3dDevice->SetPixelShaderConstantF( PSCONST_avSampleWeights, ( FLOAT* )avSampleWeights, MAX_SAMPLES ); g_pd3dDevice->SetPixelShaderConstantF( PSCONST_fMiddleGray, &fMiddleGrayKeyValue, 1 ); g_pd3dDevice->SetPixelShader( m_pBrightPassFilterPS ); g_pd3dDevice->SetTexture( 0, pSrcTexture ); g_pd3dDevice->SetTexture( 1, pAdaptedLuminanceTexture ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_POINT ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT ); g_pd3dDevice->SetSamplerState( 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP ); g_pd3dDevice->SetSamplerState( 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP ); g_pd3dDevice->SetSamplerState( 1, D3DSAMP_MINFILTER, D3DTEXF_POINT ); g_pd3dDevice->SetSamplerState( 1, D3DSAMP_MAGFILTER, D3DTEXF_POINT ); // Draw a fullscreen quad to sample the RT DrawFullScreenQuad(); g_pd3dDevice->Resolve( D3DRESOLVE_RENDERTARGET0, NULL, pDstTexture, NULL, 0, 0, NULL, 1.0f, 0L, NULL ); // Cleanup and return PopRenderTarget( 0L )->Release(); g_pd3dDevice->SetPixelShader( NULL ); }
//-------------------------------------------------------------------------------------- // Name: GaussBlur5x5Texture() // Desc: Perform a 5x5 gaussian blur on pSrcTexture and place the result in pDstTexture //-------------------------------------------------------------------------------------- VOID PostProcess::GaussBlur5x5Texture( LPDIRECT3DTEXTURE9 pSrcTexture, LPDIRECT3DTEXTURE9 pDstTexture, DWORD dwEdramOffset ) { // Make sure that the required shaders and objects exist assert( m_pGaussBlur5x5PS ); assert( pSrcTexture && pDstTexture ); XGTEXTURE_DESC SrcDesc; XGGetTextureDesc( pSrcTexture, 0, &SrcDesc ); // Create and set a render target D3DSURFACE_PARAMETERS surfaceParams = { 0 }; surfaceParams.Base = dwEdramOffset; PushRenderTarget( 0L, CreateRenderTarget( pDstTexture, &surfaceParams ) ); XMVECTOR avSampleOffsets[MAX_SAMPLES]; XMVECTOR avSampleWeights[MAX_SAMPLES]; GetSampleOffsets_GaussBlur5x5( SrcDesc.Width, SrcDesc.Height, avSampleOffsets, avSampleWeights ); g_pd3dDevice->SetPixelShaderConstantF( PSCONST_avSampleOffsets, ( FLOAT* )avSampleOffsets, MAX_SAMPLES ); g_pd3dDevice->SetPixelShaderConstantF( PSCONST_avSampleWeights, ( FLOAT* )avSampleWeights, MAX_SAMPLES ); g_pd3dDevice->SetPixelShader( m_pGaussBlur5x5PS ); g_pd3dDevice->SetTexture( 0, pSrcTexture ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_POINT ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP ); // Draw a fullscreen quad to sample the RT DrawFullScreenQuad(); g_pd3dDevice->Resolve( D3DRESOLVE_RENDERTARGET0, NULL, pDstTexture, NULL, 0, 0, NULL, 1.0f, 0L, NULL ); // Cleanup and return PopRenderTarget( 0L )->Release(); g_pd3dDevice->SetPixelShader( NULL ); }
//-------------------------------------------------------------------------------------- // Name: AdaptLuminance() // Desc: Adapt the luminance over time and place the result in pDstTexture //-------------------------------------------------------------------------------------- VOID PostProcess::AdaptLuminance( LPDIRECT3DTEXTURE9 pAdaptedLuminanceTexture, LPDIRECT3DTEXTURE9 pToneMapTexture, FLOAT fElapsedTime, LPDIRECT3DTEXTURE9 pDstTexture ) { // Make sure that the required shaders and objects exist assert( m_pCalculateAdaptedLumPS ); assert( pAdaptedLuminanceTexture && pToneMapTexture && pDstTexture ); // Create and set a render target PushRenderTarget( 0L, CreateRenderTarget( pDstTexture ) ); // This simulates the light adaptation that occurs when moving from a dark area to // a bright area, or vice versa. The m_pTexAdaptedLuminance texture stores a single // texel cooresponding to the user's adapted level. g_pd3dDevice->SetPixelShaderConstantF( PSCONST_fElapsedTime, &fElapsedTime, 1 ); g_pd3dDevice->SetPixelShader( m_pCalculateAdaptedLumPS ); g_pd3dDevice->SetTexture( 0, pAdaptedLuminanceTexture ); g_pd3dDevice->SetTexture( 1, pToneMapTexture ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_POINT ); g_pd3dDevice->SetSamplerState( 1, D3DSAMP_MAGFILTER, D3DTEXF_POINT ); g_pd3dDevice->SetSamplerState( 1, D3DSAMP_MINFILTER, D3DTEXF_POINT ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP ); g_pd3dDevice->SetSamplerState( 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP ); g_pd3dDevice->SetSamplerState( 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP ); // Draw a fullscreen quad to sample the RT DrawFullScreenQuad(); g_pd3dDevice->Resolve( D3DRESOLVE_RENDERTARGET0, NULL, pDstTexture, NULL, 0, 0, NULL, 1.0f, 0L, NULL ); // Cleanup and return PopRenderTarget( 0L )->Release(); g_pd3dDevice->SetPixelShader( NULL ); }
//-------------------------------------------------------------------------------------- // Name: AddTextures() // Desc: Add the ppSrcTextures and place the result in pDstTexture //-------------------------------------------------------------------------------------- VOID PostProcess::AddTextures( LPDIRECT3DTEXTURE9* ppSrcTextures, DWORD dwNumSrcTextures, LPDIRECT3DTEXTURE9 pDstTexture ) { // Make sure that the required shaders and objects exist assert( m_pMergeTexturesPS[dwNumSrcTextures] ); assert( ppSrcTextures && pDstTexture ); // Create and set a render target PushRenderTarget( 0L, CreateRenderTarget( pDstTexture ) ); XMVECTOR avSampleWeights[MAX_SAMPLES]; const XMVECTOR vWhite = XMVectorSet( 1.0f, 1.0f, 1.0f, 1.0f ); for( DWORD i = 0; i < dwNumSrcTextures; i++ ) { g_pd3dDevice->SetTexture( i, ppSrcTextures[i] ); g_pd3dDevice->SetSamplerState( i, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR ); g_pd3dDevice->SetSamplerState( i, D3DSAMP_MINFILTER, D3DTEXF_LINEAR ); g_pd3dDevice->SetSamplerState( i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP ); g_pd3dDevice->SetSamplerState( i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP ); avSampleWeights[i] = vWhite; } g_pd3dDevice->SetPixelShaderConstantF( PSCONST_avSampleWeights, ( FLOAT* )avSampleWeights, dwNumSrcTextures ); g_pd3dDevice->SetPixelShader( m_pMergeTexturesPS[dwNumSrcTextures] ); // Draw a fullscreen quad to sample the RT DrawFullScreenQuad(); g_pd3dDevice->Resolve( D3DRESOLVE_RENDERTARGET0, NULL, pDstTexture, NULL, 0, 0, NULL, 1.0f, 0L, NULL ); // Cleanup and return PopRenderTarget( 0L )->Release(); g_pd3dDevice->SetPixelShader( NULL ); }
//----------------------------------------------------------------------------- // Name: ClearTexture() // Desc: Helper function for RestoreDeviceObjects to clear a texture surface //----------------------------------------------------------------------------- VOID PostProcess::ClearTexture( LPDIRECT3DTEXTURE9 pTexture, DWORD dwClearColor ) { // Make sure that the required shaders and objects exist assert( pTexture ); DWORD OldFormat = pTexture->Format.DataFormat; if( pTexture->Format.DataFormat == GPUTEXTUREFORMAT_8_8_8_8_AS_16_16_16_16 ) { pTexture->Format.DataFormat = GPUTEXTUREFORMAT_8_8_8_8; } // Create and set a render target for the texture PushRenderTarget( 0, CreateRenderTarget( pTexture ) ); g_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET, dwClearColor, 1.0f, 0L ); g_pd3dDevice->Resolve( D3DRESOLVE_RENDERTARGET0, NULL, pTexture, NULL, 0, 0, NULL, 0.0f, 0, NULL ); // Cleanup and exit PopRenderTarget( 0 )->Release(); pTexture->Format.DataFormat = OldFormat; }