//////////////////////////////////////////////////////////////////////////////
//
// AVP_Platform_DisplacementMap.cpp
//
// Copyright (c) 2009 Rebellion. All rights reserved.
//
//////////////////////////////////////////////////////////////////////////////

/******************************************************************************/
/* Included Files                                                             */
/******************************************************************************/

#include "Core/Asura.h"

#if defined ASURA_USE_FSFX

// Asura Platform-independent
#include "FSFX/Asura_FSFX_System.h"
#include "Rendering/Asura_Render.h"
#include "Rendering/Asura_ViewPort.h"
#include "Rendering/Asura_Overlay_Quad.h"

// Asura PS3
#include "Rendering/Shaders/Asura_PS3_GCM_Shader.h"
#include "Rendering/Asura_PS3_Graphics.h"

#include "Rendering/Asura_PS3_FrameBuffer.h"
#include "Rendering/Asura_PS3_GCM_VertexBuffer.h"
#include "Rendering/Asura_PS3_RSXProfiling.h"

// AVP Platform-independent
#include "FSFX/AVP_FSFX.h"

#include "Rendering/ShadersDefinition/vp/FSFX_Noise_VP.h"
#include "Rendering/ShadersDefinition/vd/FSFX_Noise_VD.h"
#include "Rendering/ShadersDefinition/fp/FSFX_DisplacementMap_FP.h"

static AVP_PS3_FSFX_DisplacementMap_PS*	g_pxDisplacementMapFP	= NULL;
static Asura_PS3_GCM_VertexShader*		g_pxVertexShader		= NULL;
static Asura_PS3_GCM_VertexBuffer		g_xVertexBuffer;

#if defined(ASURA_PS3_ALLOW_SHADER_RELOAD)
static bool ReloadShaders(bool bHelp)
{
	if ( bHelp )
	{
		Asura_CommandConsole::Printf("recompile & load FSFX DisplacmentMap shader");
		return true;
	}

	g_pxDisplacementMapFP->ReloadFromDisc();
	return true;
}
#endif

void AVP_FSFX_Component_DisplacementMap::Platform_Initialise(  )
{
	g_pxDisplacementMapFP = new AVP_PS3_FSFX_DisplacementMap_PS();
	g_xVertexBuffer.Initialise( NOISE_VERTEX_SIZE, 4, CELL_GCM_LOCATION_MAIN );

	const float fWidth = static_cast< float >( Asura_Viewport::GetWidth() );
	const float fHeight = static_cast< float >( Asura_Viewport::GetHeight() );

	float* pf = ( float* )g_xVertexBuffer.LockForWriting();
	pf[  0 ] = -1; pf[  1 ] = -1; pf[  2 ] =             0.5f / fWidth; pf[  3 ] =             0.5f / fHeight; 
	pf[  4 ] =  1; pf[  5 ] = -1; pf[  6 ] =  (fWidth + 0.5f) / fWidth; pf[  7 ] =             0.5f / fHeight; 
	pf[  8 ] =  1; pf[  9 ] =  1; pf[ 10 ] =  (fWidth + 0.5f) / fWidth; pf[ 11 ] = (fHeight + 0.5f) / fHeight; 
	pf[ 12 ] = -1; pf[ 13 ] =  1; pf[ 14 ] =             0.5f / fWidth; pf[ 15 ] = (fHeight + 0.5f) / fHeight; 

	g_xVertexBuffer.Unlock();



	g_pxVertexShader = new Asura_PS3_VP_Noise();

#if defined(ASURA_PS3_ALLOW_SHADER_RELOAD)
	Asura_CommandConsole::AddCmd(L"Render.ReloadShaders.FSFX.DisplacementMap", ReloadShaders, Asura_CommandConsole::REMOVE_AT_SHUTDOWN);
#endif
}

void AVP_FSFX_Component_DisplacementMap::Platform_Shutdown(  )
{
	delete g_pxDisplacementMapFP;
	g_pxDisplacementMapFP = NULL;

	g_xVertexBuffer.Destroy();
}



void AVP_FSFX_Component_DisplacementMap::Platform_Render( const float fIntensity )
{
	ASURA_PS3_RSX_PROFILE__BEGIN( ASURA_PS3_RSX_PROFILE__MISC, "FSFX: AVP - Displacement Map" );
	Asura_PS3_DeferredRendering::ResolveBackBuffer();

	Asura_PS3_DeferredRendering::BindAsSingleRT();

	g_pxDisplacementMapFP->Begin();
	g_pxDisplacementMapFP->SetTexture( AVP_PS3_FSFX_DisplacementMap_PS::FP_SceneTextureSampler, Asura_PS3_DeferredRendering::GetResolvedTexture(), true );
	g_pxDisplacementMapFP->SetTexture( AVP_PS3_FSFX_DisplacementMap_PS::FP_DisplacementMapSampler, m_iTextureID);
	float fAmount = fIntensity * m_fAmount * 0.001f;
	g_pxDisplacementMapFP->SetFloats( AVP_PS3_FSFX_DisplacementMap_PS::FP_Intensity, 1, &fAmount);

	Asura_PS3_RenderingStates::RequestTranslucencyMode( ASURA_TRANSLUCENCY_OFF );
	Asura_PS3_RenderingStates::RequestCullMode( ASURA_CULLMODE_NONE );
	Asura_PS3_RenderingStates::RequestAlphaTest( false );

	// Taken these settings out of the effect, as they were screwing up the cached states
	Asura_PS3_RenderingStates::RequestZBufferEnabled(false);
	Asura_PS3_RenderingStates::RequestZBufferWriteEnabled(false);

	g_pxVertexShader->Bind();
	g_pxDisplacementMapFP->Bind();
	g_xVertexBuffer.Bind( g_axVertexDeclarationN, VDN_ELEMENTS );
	g_xVertexBuffer.RenderQuads( 4 );
	g_pxDisplacementMapFP->End();

	ASURA_PS3_RSX_PROFILE__END( ASURA_PS3_RSX_PROFILE__MISC );
}
#endif //defined ASURA_USE_FSFX
