//////////////////////////////////////////////////////////////////////////////
//
// Asura_PS3_Botanicals.cpp
//
// Copyright (c) 2006 Rebellion. All rights reserved.
//
//////////////////////////////////////////////////////////////////////////////

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

#include "Core/Asura.h"

#include "Botanicals/Asura_PS3_Botanicals.h"

// Asura Platform-independent
#include "Camera/Asura_Camera.h"
#include "Core/Memory/Asura_Mem.h"
#include "Core/Asura_MaterialFlags.h"
#include "Core/Asura_Material_System.h"
#include "Rendering/Asura_Module.h"
#include "Rendering/Asura_Render.h"
#include "Core/Asura_MaterialResponse_System.h"

// Asura PS3
#include "Rendering/Asura_PS3_Graphics.h"
#include "Rendering/Asura_PS3_TextureManagement.h"

/******************************************************************************/
/* Asura_PS3_Botanicals_System Static Class Functions                     */
/******************************************************************************/

////////////////////////////////////////////////////////////////////////////////
//
// Asura_PS3_Botanicals_System::SetMaterial()
//
// Sets up shader params for a given effect+material
//
// Supports a fair a bit of current (soon-obsolete) Asura Materials - but not
// everything. In particular, no dual-texturing or self-illumination
// 
// Return value:	None
//
////////////////////////////////////////////////////////////////////////////////
#if 0
void Asura_PS3_Botanicals_System::SetMaterial(Asura_PS3_Effect *pxEffect, Asura_PS3_MaterialResponse_Handles *pxHandles, uint32 uMaterialResponseHashID)
{
	const Asura_MaterialResponse *pxMaterial = Asura_MaterialResponse_System::GetMaterialByHashID(uMaterialResponseHashID);

	if (pxMaterial)
	{
		Asura_PS3_MaterialResponse_System::SetEffectParameters(pxMaterial, NULL, NULL, *pxHandles, *pxEffect);
	}
	else
	{
		Asura_Assert(false, "Botanical has missing material response!");
	}

	// Now using the mat response system


	//Asura_MaterialResponse_System:: uMaterialResponeHashID	
/*
	const int iTextureID = Asura_Material_System::GetTextureID( iMaterial );
	Asura_PS3_Texture* const pxTexture = Asura_PS3_TextureManagement::GetTexture( iTextureID );

	pxEffect->GetInterface()->SetSampler(pxHandles->m_xTextureHandle, pxTexture->GetD3DTexture() );

	// Set up normal map
	if (Asura_Material_System::IsMaterialNormalMapped(iMaterial))
	{	
		const int iNormalMapID = Asura_Material_System::GetNormalMapID(iMaterial);
		Asura_PS3_Texture* const pxNormalMap = Asura_PS3_TextureManagement::GetTexture( iNormalMapID );
		pxEffect->GetInterface()->SetSampler(pxHandles->m_xNormalMapHandle, pxNormalMap->GetD3DTexture() );
		pxEffect->GetInterface()->SetBool(pxHandles->m_xNormalMapEnabledHandle,true);
	}
	else
	{
		pxEffect->GetInterface()->SetBool(pxHandles->m_xNormalMapEnabledHandle,false);
	}

	// Do we want parallax mapping?
	pxEffect->GetInterface()->SetBool(pxHandles->m_xParallaxMapEnabledHandle,Asura_Material_System::IsMaterialParallaxMapping(iMaterial));

	// Set up specular map
	if (Asura_Material_System::IsMaterialSpecularMapped(iMaterial))
	{	
		const int iSpecularMapID = Asura_Material_System::GetSpecularMapID(iMaterial);
		Asura_PS3_Texture* const pxSpecularMap = Asura_PS3_TextureManagement::GetTexture( iSpecularMapID );
		pxEffect->GetInterface()->SetSampler(pxHandles->m_xSpecularMapHandle, pxSpecularMap->GetD3DTexture() );
		pxEffect->GetInterface()->SetBool(pxHandles->m_xSpecularMapEnabledHandle,true);
	}
	else
	{
		pxEffect->GetInterface()->SetBool(pxHandles->m_xSpecularMapEnabledHandle,false);
	}
*/
}
#endif

////////////////////////////////////////////////////////////////////////////////
//
// Asura_PS3_Botanicals_System::RenderGeometry()
//
// Renders a batch of geometry-type botanicals instances. Bind a stream of instances
// before calling this function
//
// Parameters:		xLOD - Specific LOD to render
//					uFirstInstance - Index of first instance in the stream
//					uNumInstances - Number of instances in the stream
//
// Return value:	None
//
////////////////////////////////////////////////////////////////////////////////

#if 0
void Asura_PS3_Botanicals_System::RenderGeometry( const Asura_PS3_Botanicals_LOD_Geometry& xLOD, const u_int uFirstInstance, const u_int uNumInstances, bool bDoubleSided )
{	
	SetMaterial(s_pxGeometryEffect, &g_xGeometryMaterialResponseHandles, xLOD.m_uMaterialResponseHashID);

	s_pxGeometryEffect->GetInterface()->SetFloat( s_xGeometryInstanceSizeHandle, static_cast< float >( xLOD.m_uNumIndices ) );
	s_pxGeometryEffect->GetInterface()->SetFloat( s_xGeometryFirstInstanceHandle, static_cast< float >( uFirstInstance ) );
	s_pxGeometryEffect->GetInterface()->SetInt(   s_xGeometryCullModeHandle, bDoubleSided ? D3DCULL_NONE : D3DCULL_CW );

	Asura_PS3_Graphics::GetDevice()->SetVertexDeclaration( s_pxGeometryVD );
	Asura_PS3_RenderingStates::RequestTranslucencyMode( ASURA_TRANSLUCENCY_OFF );

	xLOD.m_xVB.Bind(0);
	xLOD.m_xIB.Bind(1);

	s_pxGeometryEffect->Begin();
	s_pxGeometryEffect->Commit();

	Asura_PS3_Graphics::GetDevice()->DrawVertices( D3DPT_TRIANGLELIST, 0, xLOD.m_uNumIndices * uNumInstances );
	Asura_Render::AddToTrianglesRendered( xLOD.m_uNumTriangles * uNumInstances );
	s_uNumTrianglesRendered += xLOD.m_uNumTriangles * uNumInstances;

	s_pxGeometryEffect->End();
}
#endif

////////////////////////////////////////////////////////////////////////////////
//
// Asura_PS3_Botanicals_System::RenderBillboards()
//
// Renders a batch of billboards-type botanicals instances. Bind a stream of instances
// before calling this function
//
// Parameters:		xLOD - Specific LOD to render
//					uFirstInstance - Index of first instance in the stream
//					uNumInstances - Number of instances in the stream
//
// Return value:	None
//
////////////////////////////////////////////////////////////////////////////////

#if 0
void Asura_PS3_Botanicals_System::RenderBillboards( const Asura_PS3_Botanicals_LOD_Billboards& xLOD, const u_int uFirstInstance, const u_int uNumInstances )
{		
	SetMaterial(s_pxBillboardsEffect, &g_xBillboardsMaterialResponseHandles, xLOD.m_uMaterialResponseHashID);

	Asura_Vector_3 xCameraUp, xCameraRight, xCameraForwards;
	Asura_Camera::GetUpVector( xCameraUp);
	Asura_Camera::GetRightVector( xCameraRight);
	Asura_Camera::GetForwardVector( xCameraForwards);

	xCameraUp.Normalise();
	xCameraRight.Normalise();
	xCameraForwards.Normalise();

	s_pxBillboardsEffect->GetInterface()->SetVectorF( s_xBillboardsCameraUpHandle,      (float *)&xCameraUp );
	s_pxBillboardsEffect->GetInterface()->SetVectorF( s_xBillboardsCameraRightHandle,   (float *)&xCameraRight );
	s_pxBillboardsEffect->GetInterface()->SetVectorF( s_xBillboardsCameraForwardsHandle,(float *)&xCameraForwards );	

	s_pxBillboardsEffect->GetInterface()->SetFloat( s_xBillboardsInstanceSizeHandle, static_cast< float >( xLOD.m_uNumVertices ) );
	s_pxBillboardsEffect->GetInterface()->SetFloat( s_xBillboardsFirstInstanceHandle, static_cast< float >( uFirstInstance ) );

	Asura_PS3_Graphics::GetDevice()->SetVertexDeclaration( s_pxBillboardsVD );

	Asura_PS3_RenderingStates::RequestTranslucencyMode( ASURA_TRANSLUCENCY_OFF );

	xLOD.m_xVertexVB.Bind(0);
	xLOD.m_xBillboardVB.Bind(1);

	s_pxBillboardsEffect->Begin();
	s_pxBillboardsEffect->Commit();

	Asura_PS3_Graphics::GetDevice()->DrawVertices( D3DPT_QUADLIST, 0, xLOD.m_uNumVertices * uNumInstances );
	Asura_Render::AddToTrianglesRendered( (xLOD.m_uNumVertices / 2) * uNumInstances );
	s_uNumTrianglesRendered += (xLOD.m_uNumVertices / 2) * uNumInstances;

	s_pxBillboardsEffect->End();
}
#endif

////////////////////////////////////////////////////////////////////////////////
//
// Asura_PS3_Botanicals_System::RenderImposters()
//
// Renders a batch of imposter-type botanicals instances. Bind a stream of instances
// before calling this function
//
// Parameters:		xLOD - Specific LOD to render
//					uFirstInstance - Index of first instance in the stream
//					uNumInstances - Number of instances in the stream
//
// Return value:	None
//
////////////////////////////////////////////////////////////////////////////////

#if 0
void Asura_PS3_Botanicals_System::RenderImposters( const Asura_PS3_Botanicals_LOD_Imposter& xLOD, const u_int uFirstInstance, const u_int uNumInstances )
{	
	SetMaterial(s_pxImpostersEffect, &g_xImpostersMaterialResponseHandles, xLOD.m_uMaterialResponseHashID);

	s_pxImpostersEffect->GetInterface()->SetFloat( s_xImpostersFirstInstanceHandle, static_cast< float >( uFirstInstance ) );
	s_pxImpostersEffect->GetInterface()->SetFloat( s_xImpostersNumAnglesHandle, static_cast< float >( xLOD.m_iNumImposterAngles ) );

	Asura_Vector_3 xCameraUp, xCameraRight, xCameraForwards;
	Asura_Camera::GetUpVector( xCameraUp);
	Asura_Camera::GetRightVector( xCameraRight);
	Asura_Camera::GetForwardVector( xCameraForwards);
	
	xCameraUp.Normalise();
	xCameraRight.Normalise();
	xCameraForwards.Normalise();

	s_pxImpostersEffect->GetInterface()->SetVectorF( s_xImpostersCameraUpHandle,      (float *)&xCameraUp );
	s_pxImpostersEffect->GetInterface()->SetVectorF( s_xImpostersCameraRightHandle,   (float *)&xCameraRight );
	s_pxImpostersEffect->GetInterface()->SetVectorF( s_xImpostersCameraForwardsHandle,(float *)&xCameraForwards );	

	Asura_PS3_Graphics::GetDevice()->SetVertexDeclaration( s_pxImpostersVD );

	Asura_PS3_RenderingStates::RequestTranslucencyMode( ASURA_TRANSLUCENCY_OFF );

	xLOD.m_xImposterAngleDataVB.Bind(0);

	s_pxImpostersEffect->Begin();
	s_pxImpostersEffect->Commit();

	Asura_PS3_Graphics::GetDevice()->DrawVertices( D3DPT_QUADLIST, 0, 4 * xLOD.m_iNumImposterAngles * uNumInstances );
	Asura_Render::AddToTrianglesRendered( 2* 4 * xLOD.m_iNumImposterAngles * uNumInstances );
	s_uNumTrianglesRendered += 2* 4 * xLOD.m_iNumImposterAngles * uNumInstances;

	s_pxImpostersEffect->End();
}
#endif
