void ForwardRenderer::DrawScreenQuad()
{
    float blendFactor[] = { 0.0f, 0.0f, 0.0f, 0.0f };

    XMMATRIX view = XMLoadFloat4x4( RendererCore::Instance()->GetView() );
    XMMATRIX proj = XMLoadFloat4x4( RendererCore::Instance()->GetProj() );

    int iCount = m_vDrawScreenElements.size();
    for ( int i = 0; i < iCount; ++i )
    {
        DrawElement* pElem = m_vDrawScreenElements[i];
        if ( !pElem )
            continue;

        UINT stride = pElem->stride;
        UINT offset = pElem->offset;

        ID3D11Buffer* pVB = pElem->m_spVB->GetVB();

        GetD3D11DeviceImmContext()->IASetInputLayout( pElem->m_pInputLayout );
        GetD3D11DeviceImmContext()->IASetPrimitiveTopology( pElem->ePrimitiveTopology );
        GetD3D11DeviceImmContext()->IASetVertexBuffers( 0, 1, &pVB, &stride, &offset );
        GetD3D11DeviceImmContext()->IASetIndexBuffer( pElem->m_spIB->GetIB(), DXGI_FORMAT_R32_UINT, 0 );


        if ( pElem->m_pRasterS )
            GetD3D11DeviceImmContext()->RSSetState( pElem->m_pRasterS );
        if ( pElem->m_pBlendS )
            GetD3D11DeviceImmContext()->OMSetBlendState( pElem->m_pBlendS, blendFactor, 0xffffffff );
        if ( pElem->m_pDepthStencilS )
            GetD3D11DeviceImmContext()->OMSetDepthStencilState( pElem->m_pDepthStencilS, pElem->m_uiStencilRef );



        for ( auto itor = pElem->m_vecSubElement.begin(); itor != pElem->m_vecSubElement.end(); ++itor )
        {
            ID3DX11EffectTechnique* pTech = pElem->m_spShader->GetTech( (*itor).m_iTechIndex );
            if ( !pTech )
                continue;

            D3DX11_TECHNIQUE_DESC techDesc;
            pTech->GetDesc( &techDesc );

            TexturePtr spDiffuseMap = (*itor).m_spDiffuseMap;

            for ( UINT p = 0; p < techDesc.Passes; ++p )
            {
                XMMATRIX worldViewProj = XMLoadFloat4x4( &(*itor).m_World );

                pElem->m_spShader->SetWorldViewProj( worldViewProj );
                pElem->m_spShader->SetDiffuseMap( spDiffuseMap->GetSRV() );

                pTech->GetPassByIndex( p )->Apply( 0, GetD3D11DeviceImmContext() );
                GetD3D11DeviceImmContext()->DrawIndexed( 6, 0, 0 );
            }
        }
    }

}
void ForwardRenderer::DrawScene()
{
    DrawShadowMap();

    RendererCore::Instance()->SetOriginalRenderTargetDepth();

    float blendFactor[] = { 0.0f, 0.0f, 0.0f, 0.0f };

    // Set constants
    XMMATRIX view = XMLoadFloat4x4( RendererCore::Instance()->GetView() );
    XMMATRIX proj = XMLoadFloat4x4( RendererCore::Instance()->GetProj() );

    XMMATRIX shadowTransform = XMLoadFloat4x4( &m_ShadowTransform );


    int iCount = m_vDrawElements.size();
    for ( int i = 0; i < iCount; ++i )
    {
        DrawElement* pElem = m_vDrawElements[i];
        if ( !pElem )
            continue;

        UINT stride = pElem->stride;
        UINT offset = pElem->offset;

        GetD3D11DeviceImmContext()->IASetInputLayout( pElem->m_pInputLayout );
        GetD3D11DeviceImmContext()->IASetPrimitiveTopology( pElem->ePrimitiveTopology );

        pElem->m_spShader->SetDirLight( m_DirLights[0] );
        pElem->m_spShader->SetDirLights( m_DirLights );
        pElem->m_spShader->SetPointLight( m_PointLight );
        pElem->m_spShader->SetSpotLight( m_SpotLight );
        pElem->m_spShader->SetEyePosW( RendererCore::Instance()->GetEyePosW() );
        pElem->m_spShader->SetFogStart( 15.0f );
        pElem->m_spShader->SetFogRange( 300.0f );
        pElem->m_spShader->SetFogColor( Colors::Silver );

        for ( auto itor = pElem->m_vecSubElement.begin(); itor != pElem->m_vecSubElement.end() ; ++itor )
        {
            ID3DX11EffectTechnique* pTech = pElem->m_spShader->GetTech( (*itor).m_iTechIndex );
            if ( !pTech )
                continue;


            ID3D11Buffer* pVB = pElem->m_spVB->GetVB();
            GetD3D11DeviceImmContext()->IASetVertexBuffers( 0, 1, &pVB, &stride, &offset );

            if ( pElem->m_spIB )
                GetD3D11DeviceImmContext()->IASetIndexBuffer( pElem->m_spIB->GetIB(), DXGI_FORMAT_R32_UINT, 0 );

            if ( pElem->m_pRasterS )
                GetD3D11DeviceImmContext()->RSSetState( pElem->m_pRasterS );
            if ( pElem->m_pBlendS )
                GetD3D11DeviceImmContext()->OMSetBlendState( pElem->m_pBlendS, blendFactor, 0xffffffff );
            if ( pElem->m_pDepthStencilS )
                GetD3D11DeviceImmContext()->OMSetDepthStencilState( pElem->m_pDepthStencilS, pElem->m_uiStencilRef );

            XMMATRIX world;
            XMFLOAT3 oldLightDirections;
            if ( pElem->m_bStencilReflect )
            {
                XMVECTOR mirrorPlane = XMVectorSet( 0.0f, 0.0f, 1.0f, 0.0f ); // xy plane
                XMMATRIX R = XMMatrixReflect( mirrorPlane );
                world = XMLoadFloat4x4( &pElem->m_vecSubElement[0].m_World ) * R;

                oldLightDirections = m_DirLights[0].Direction;

                XMVECTOR lightDir = XMLoadFloat3( &m_DirLights[0].Direction );
                XMVECTOR reflectedLightDir = XMVector3TransformNormal( lightDir, R );
                XMStoreFloat3( &m_DirLights[0].Direction, reflectedLightDir );

                //ÀӽùæÆí
                pElem->m_spShader->SetDirLight( m_DirLights[0] );
            }
            else if ( pElem->m_bShadowmap )
            {
                XMVECTOR shadowPlane = XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f ); // xz plane
                XMVECTOR toMainLight = -XMLoadFloat3( &m_DirLights[0].Direction );
                XMMATRIX S = XMMatrixShadow( shadowPlane, toMainLight );
                XMMATRIX shadowOffsetY = XMMatrixTranslation( 0.0f, 0.001f, 0.0f );

                world = XMLoadFloat4x4( &pElem->m_vecSubElement[0].m_World )*S*shadowOffsetY;
            }
            else
            {
                world = XMLoadFloat4x4( &pElem->m_vecSubElement[0].m_World );
            }

            TexturePtr spDiffuseMap = (*itor).m_spDiffuseMap;
            TexturePtr spCubeMap = (*itor).m_spCubeMap;
            TexturePtr spNormalMap = (*itor).m_spNormalMap;
            TexturePtr spShadowMap = (*itor).m_spShadowMap;

            world = XMLoadFloat4x4( &(*itor).m_World );

            XMMATRIX worldInvTranspose = MathHelper::InverseTranspose( world );
            XMMATRIX viewProj = view*proj;
            XMMATRIX worldViewProj = world*view*proj;

            XMMATRIX texTransform = XMLoadFloat4x4( &(*itor).m_TexTransform );

            D3DX11_TECHNIQUE_DESC techDesc;
            pTech->GetDesc( &techDesc );

            for ( UINT p = 0; p < techDesc.Passes; ++p )
            {

                pElem->m_spShader->SetWorld( world );
                pElem->m_spShader->SetWorldViewProj( worldViewProj );
                pElem->m_spShader->SetViewProj( viewProj );
                pElem->m_spShader->SetWorldInvTranspose( worldInvTranspose );
                pElem->m_spShader->SetTexTransform( texTransform );
                pElem->m_spShader->SetShadowTransform( world*shadowTransform );
                pElem->m_spShader->SetMaterial( (*itor).m_mat );

                if ( spDiffuseMap )
                {
                    if ( !spDiffuseMap->IsArray() )
                        pElem->m_spShader->SetDiffuseMap( spDiffuseMap->GetSRV() );
                    else
                        pElem->m_spShader->SetDiffuseMapArray( spDiffuseMap->GetSRV() );
                }

                if ( spCubeMap )
                {
                    pElem->m_spShader->SetCubeMap( spCubeMap->GetSRV() );
                }

                if ( spNormalMap )
                {
                    pElem->m_spShader->SetNormalMap( spNormalMap->GetSRV() );
                }

                if ( spShadowMap )
                {
                    pElem->m_spShader->SetShadowMap( spShadowMap->GetSRV() );
                }

                pTech->GetPassByIndex( p )->Apply( 0, GetD3D11DeviceImmContext() );

                if ( pElem->m_bDrawIndex )
                {

                    GetD3D11DeviceImmContext()->DrawIndexed( (*itor).m_IndexCount, (*itor).m_StartIndexLocation, (*itor).m_BaseVertexLocation );
                }
                else
                {
                    GetD3D11DeviceImmContext()->Draw( (*itor).m_VertexCount, (*itor).m_StartVertexLocation );
                }
            }


            if ( pElem->m_bStencilReflect )
            {
                m_DirLights[0].Direction = oldLightDirections;
            }
        }
    }

    DrawScreenQuad();
}
void ForwardRenderer::DrawShadowMap()
{
    float blendFactor[] = { 0.0f, 0.0f, 0.0f, 0.0f };


    if ( !m_spDepthStencilTex )
    {
        m_spDepthStencilTex = dynamic_pointer_cast<DepthStencilTexture, Texture>(RendererCore::Instance()->GetTexture( "depthstencil" ));

        m_spShadowMapShader = dynamic_pointer_cast<BuildShadowMapShader, FXShader>(RendererCore::Instance()->GetShader( "BuildShadowMap" ));
    }

    m_spDepthStencilTex->BindDsvAndSetNullRenderTarget();

    XMMATRIX view = XMLoadFloat4x4( &m_LightView );
    XMMATRIX proj = XMLoadFloat4x4( &m_LightProj );
    XMMATRIX viewProj = XMMatrixMultiply( view, proj );

    m_spShadowMapShader->SetEyePosW( RendererCore::Instance()->GetEyePosW() );
    m_spShadowMapShader->SetViewProj( viewProj );

    // These properties could be set per object if needed.
    m_spShadowMapShader->SetHeightScale( 0.07f );
    m_spShadowMapShader->SetMaxTessDistance( 1.0f );
    m_spShadowMapShader->SetMinTessDistance( 25.0f );
    m_spShadowMapShader->SetMinTessFactor( 1.0f );
    m_spShadowMapShader->SetMaxTessFactor( 5.0f );

    int iCount = m_vDrawShadowElements.size();
    for ( int i = 0; i < iCount; ++i )
    {
        DrawElement* pShadowElem = m_vDrawShadowElements[i];
        if ( !pShadowElem )
            continue;

        UINT stride = pShadowElem->stride;
        UINT offset = pShadowElem->offset;

        GetD3D11DeviceImmContext()->IASetInputLayout( pShadowElem->m_pInputLayout );
        GetD3D11DeviceImmContext()->IASetPrimitiveTopology( pShadowElem->ePrimitiveTopology );

        m_spShadowMapShader->SetDirLight( m_DirLights[0] );
        m_spShadowMapShader->SetDirLights( m_DirLights );
        m_spShadowMapShader->SetPointLight( m_PointLight );
        m_spShadowMapShader->SetSpotLight( m_SpotLight );
        m_spShadowMapShader->SetEyePosW( RendererCore::Instance()->GetEyePosW() );
        m_spShadowMapShader->SetFogStart( 15.0f );
        m_spShadowMapShader->SetFogRange( 300.0f );
        m_spShadowMapShader->SetFogColor( Colors::Silver );


        for ( auto itor = pShadowElem->m_vecSubElement.begin(); itor != pShadowElem->m_vecSubElement.end(); ++itor )
        {
            ID3DX11EffectTechnique* pTech = m_spShadowMapShader->GetTech( (*itor).m_iTechIndex );
            if ( !pTech )
                continue;

            D3DX11_TECHNIQUE_DESC techDesc;
            pTech->GetDesc( &techDesc );

            ID3D11Buffer* pVB = pShadowElem->m_spVB->GetVB();
            GetD3D11DeviceImmContext()->IASetVertexBuffers( 0, 1, &pVB, &stride, &offset );

            if ( pShadowElem->m_spIB )
                GetD3D11DeviceImmContext()->IASetIndexBuffer( pShadowElem->m_spIB->GetIB(), DXGI_FORMAT_R32_UINT, 0 );

            if ( pShadowElem->m_pRasterS )
                GetD3D11DeviceImmContext()->RSSetState( pShadowElem->m_pRasterS );
            if ( pShadowElem->m_pBlendS )
                GetD3D11DeviceImmContext()->OMSetBlendState( pShadowElem->m_pBlendS, blendFactor, 0xffffffff );
            if ( pShadowElem->m_pDepthStencilS )
                GetD3D11DeviceImmContext()->OMSetDepthStencilState( pShadowElem->m_pDepthStencilS, pShadowElem->m_uiStencilRef );

            TexturePtr spDiffuseMap = (*itor).m_spDiffuseMap;
            TexturePtr spCubeMap = (*itor).m_spCubeMap;
            TexturePtr spNormalMap = (*itor).m_spNormalMap;
            TexturePtr spShadowMap = (*itor).m_spShadowMap;

            XMMATRIX world = XMLoadFloat4x4( &(*itor).m_World );

            XMMATRIX worldInvTranspose = MathHelper::InverseTranspose( world );
            XMMATRIX viewProj = view*proj;
            XMMATRIX worldViewProj = world*view*proj;

            XMMATRIX texTransform = XMLoadFloat4x4( &(*itor).m_TexTransform );

            for ( UINT p = 0; p < techDesc.Passes; ++p )
            {
                m_spShadowMapShader->SetWorld( world );
                m_spShadowMapShader->SetWorldViewProj( worldViewProj );
                m_spShadowMapShader->SetViewProj( viewProj );
                m_spShadowMapShader->SetWorldInvTranspose( worldInvTranspose );
                //				m_spShadowMapShader->SetTexTransform(texTransform);
                //				m_spShadowMapShader->SetShadowTransform(world*shadowTransform);
                m_spShadowMapShader->SetMaterial( (*itor).m_mat );

                if ( spDiffuseMap )
                {
                    if ( !spDiffuseMap->IsArray() )
                        m_spShadowMapShader->SetDiffuseMap( spDiffuseMap->GetSRV() );
                    else
                        m_spShadowMapShader->SetDiffuseMapArray( spDiffuseMap->GetSRV() );
                }

                pTech->GetPassByIndex( p )->Apply( 0, GetD3D11DeviceImmContext() );

                if ( pShadowElem->m_bDrawIndex )
                {

                    GetD3D11DeviceImmContext()->DrawIndexed( (*itor).m_IndexCount, (*itor).m_StartIndexLocation, (*itor).m_BaseVertexLocation );
                }
                else
                {
                    GetD3D11DeviceImmContext()->Draw( (*itor).m_VertexCount, (*itor).m_StartVertexLocation );
                }
            }
        }
    }

}