#include "DynamicLightingShadow_shader.h"
#include <math.h>
#ifndef max
#define max(a,b) (((a) > (b)) ? (a) : (b))
#endif
#ifndef min
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif
#define DYNAMICLIGHTINGSHADOW__CLASS DYNAMICLIGHTING__CLASSNAME
#ifdef _MB_INTERNAL
#define DYNAMICLIGHTINGSHADOW__DESC "Dynamic Lighting & Shadow" // This is what shows up in the shader window ...
#else
#define DYNAMICLIGHTINGSHADOW__DESC "Dynamic Lighting & Shadow Plugin" // This is what shows up in the shader window ...
#endif
DYNAMICLIGHTINGSHADOW__CLASS,
DYNAMICLIGHTINGSHADOW__DESCSTR,
DYNAMICLIGHTINGSHADOW__DESC,
Graphics::ShadowMappingShader* DynamicLightingShadow::mpLightShadowShader =
NULL;
int DynamicLightingShadow::mpLightShadowShaderRefCount = 0;
bool DynamicLightingShadow::FBCreate()
{
mpLightShadowShaderRefCount++;
AffectingLights.SetFilter(FBLight::GetInternalClassId());
AffectingLights.SetSingleConnect(false);
TransparencyFactor.SetMinMax( 0.0, 1.0 );
TransparencyFactor = 1.0;
ShadowMapSize.SetMinMax( 128, 8192, true, false );
ShadowMapSize = 2048;
ShadowPCFKernelSize.SetMinMax( 1, 9, true, true );
ShadowPCFKernelSize = 9;
ShadowCasters.SetFilter(FBModel::GetInternalClassId());
ShadowCasters.SetSingleConnect(false);
ShadowStrength.SetMinMax(0.0, 1.0f, true, true );
ShadowStrength = 1.0f;
OffsetScale.SetMinMax( -10.0, 10.0 );
OffsetScale = 5.0;
OffsetBias.SetMinMax( -100000.0, 100000.0 );
OffsetBias = 0.0;
SetDrawInstancedMaximumSize(kMaxDrawInstancedSize);
return true;
}
void DynamicLightingShadow::FBDestroy()
{
mpLightShadowShaderRefCount--;
if (mpLightShadowShaderRefCount == 0)
{
delete mpLightShadowShader;
mpLightShadowShader =
NULL;
}
ParentClass::FBDestroy();
}
void DynamicLightingShadow::ShaderPassTypeBegin ( FBRenderOptions* pRenderOptions,
FBRenderingPass pPass)
{
if ( !mpLightShadowShader )
{
FBSystem lSystem;
FBString lVertexShader;
lVertexShader = lSystem.ApplicationPath ;
FBString lPixelShader;
FBString lProjVertexShader;
lPixelShader = lSystem.ApplicationPath ;
lProjVertexShader = lSystem.ApplicationPath;
#ifdef _MB_INTERNAL
lVertexShader += "/../system/shaders/LightingShadowMapVS.cg";
lPixelShader += "/../system/shaders/LightingShadowMapPS.cg";
lProjVertexShader += "/../system/shaders/LightingShadowProjVS.cg";
#else
lVertexShader += "/plugins/LightingShadowMapVS.cg";
lPixelShader += "/plugins/LightingShadowMapPS.cg";
lProjVertexShader += "/plugins/LightingShadowProjVS.cg";
#endif
mpLightShadowShader = new Graphics::ShadowMappingShader();
if( !mpLightShadowShader->Initialize(lVertexShader, lPixelShader, lProjVertexShader) )
{
return;
}
}
FBArrayTemplate<FBLight*> lAffectingLights;
FBArrayTemplate<FBModel*> lShadowCasters;
GetAffectingLights( &lAffectingLights );
GetShadowCasters( &lShadowCasters );
mpLightShadowShader->RenderShadowMaps( ShadowMapSize, pRenderOptions, OffsetScale, OffsetBias, &lAffectingLights, &lShadowCasters );
mpLightShadowShader->SetShadowPCFKernelSize( ShadowPCFKernelSize );
mpLightShadowShader->SetShadowStrength( ShadowStrength );
}
void DynamicLightingShadow::ShaderPassTypeEnd ( FBRenderOptions* pRenderOptions,
FBRenderingPass pPass)
{
}
void DynamicLightingShadow::ShaderPassInstanceBegin( FBRenderOptions* pRenderOptions,
FBRenderingPass pPass)
{
FBArrayTemplate<FBLight*> lAffectingLights;
GetAffectingLights( &lAffectingLights );
mpLightShadowShader->BeginShading(pRenderOptions, &lAffectingLights);
}
void DynamicLightingShadow::ShaderPassInstanceEnd ( FBRenderOptions* pRenderOptions,
FBRenderingPass pPass)
{
mpLightShadowShader->EndShading();
}
void DynamicLightingShadow::ShaderPassMaterialBegin( FBRenderOptions* pRenderOptions,
FBRenderingPass pPass, FBShaderModelInfo* pInfo)
{
mpLightShadowShader->SwitchMaterial(pRenderOptions, pInfo, pInfo->GetFBMaterial(), TransparencyFactor);
}
void DynamicLightingShadow::ShaderPassMaterialEnd ( FBRenderOptions* pRenderOptions,
FBRenderingPass pPass, FBShaderModelInfo* pInfo)
{
}
void DynamicLightingShadow::ShaderPassModelDraw ( FBRenderOptions* pRenderOptions,
FBRenderingPass pPass, FBShaderModelInfo* pInfo)
{
mpLightShadowShader->ShaderPassModelDraw(pRenderOptions, pPass, pInfo);
}
void DynamicLightingShadow::ShaderPassDrawShadowBegin( FBRenderOptions* pRenderOptions)
{
printf("In shadow pass\n" );
}
void DynamicLightingShadow::ShaderPassDrawShadowEnd( FBRenderOptions* pRenderOptions)
{
printf("End shadow pass\n" );
}
void DynamicLightingShadow::UploadModelViewMatrixArrayForDrawInstanced(const double* pModelViewMatrixArray, int pCount)
{
mpLightShadowShader->UploadModelViewMatrixArrayForDrawInstanced(pModelViewMatrixArray, pCount);
}
FBShaderModelInfo* DynamicLightingShadow::NewShaderModelInfo(
HKModelRenderInfo pModelRenderInfo,
int pSubRegionIndex)
{
FBShaderModelInfo* lShaderModelInfo = ParentClass::NewShaderModelInfo(pModelRenderInfo, pSubRegionIndex);
return lShaderModelInfo;
}
void DynamicLightingShadow::UpdateModelShaderInfo( FBRenderOptions* pOptions, FBShaderModelInfo* pModelRenderInfo )
{
pModelRenderInfo->UpdateModelShaderInfo(GetShaderVersion());
if (pModelRenderInfo->GetOriginalTextureFlag())
{
FBMaterial* lMaterial = pModelRenderInfo->GetFBMaterial();
if (lMaterial)
{
if (lNormalMapTexture ==
NULL)
if (lNormalMapTexture)
}
}
pModelRenderInfo->SetGeometryArrayIds(pModelRenderInfo->GetGeometryArrayIds() | lVBOFormat);
}
void DynamicLightingShadow::SetTransparencyType(
FBAlphaSource pTransparency )
{
if (Transparency != pTransparency)
{
Transparency = pTransparency;
InvalidateShaderVersion();
}
}
{
return Transparency;
}
{
DynamicLightingShadow* lShader = FBCast<DynamicLightingShadow>(pObject);
if (lShader->Transparency != pState)
{
lShader->Transparency.SetPropertyValue(pState);
}
}
int DynamicLightingShadow::GetAffectingLights( FBArrayTemplate<FBLight*>* pLights )
{
if( pLights )
{
pLights->Clear();
}
int nLights = 0;
if( AffectingLights.GetCount() > 0 )
{
int nAffectingLights = min( AffectingLights.GetCount(), Graphics::ShadowMappingShader::kMaxLight );
for(
int i = 0;
i < nAffectingLights; ++
i)
{
FBLight* lFBLight = FBCast<FBLight>(AffectingLights.GetAt(
i)->GetHIObject());
if( lFBLight )
{
if( pLights ) { pLights->Add(lFBLight); }
nLights++;
}
}
}
else
{
int nSceneLights = min( FBSystem::TheOne().Scene->Lights.GetCount(), Graphics::ShadowMappingShader::kMaxLight );
for(
int i = 0;
i < nSceneLights; ++
i )
{
FBLight* lFBLight = FBSystem::TheOne().Scene->Lights[
i];
if( lFBLight )
{
if( pLights ) { pLights->Add( lFBLight ); }
nLights++;
}
}
}
return nLights;
}
int DynamicLightingShadow::GetShadowCasters( FBArrayTemplate<FBModel*>* pShadowCasters )
{
if( pShadowCasters )
{
pShadowCasters->Clear();
}
int nShadowCasters = 0;
if( ShadowCasters.GetCount() > 0 )
{
for(
int i = 0;
i < ShadowCasters.GetCount();
i++ )
{
FBModel* lModel = FBCast<FBModel>(ShadowCasters.GetAt(
i)->GetHIObject());
bool lLightCam = lModel->Is( FBCamera::TypeInfo ) || lModel->Is( FBLight::TypeInfo ) ;
if( lModel && !lLightCam )
{
if( pShadowCasters ) { pShadowCasters->Add( lModel ); }
nShadowCasters++;
}
}
}
else
{
FBRenderer* lRenderer = FBSystem().Renderer;
for(
int i = 0;
i < lRenderer->DisplayableGeometryCount;
i++ )
{
FBModel* lModel = lRenderer->GetDisplayableGeometry(
i);
if( lModel )
{
if( pShadowCasters ) { pShadowCasters->Add( lModel ); }
nShadowCasters++;
}
}
}
return nShadowCasters;
}