mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-02-23 16:43:50 +00:00
Engine directory for ticket #1
This commit is contained in:
parent
352279af7a
commit
7dbfe6994d
3795 changed files with 1363358 additions and 0 deletions
671
Engine/source/lighting/advanced/advancedLightManager.cpp
Normal file
671
Engine/source/lighting/advanced/advancedLightManager.cpp
Normal file
|
|
@ -0,0 +1,671 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "lighting/advanced/advancedLightManager.h"
|
||||
|
||||
#include "lighting/advanced/advancedLightBinManager.h"
|
||||
#include "lighting/advanced/advancedLightingFeatures.h"
|
||||
#include "lighting/shadowMap/shadowMapManager.h"
|
||||
#include "lighting/shadowMap/lightShadowMap.h"
|
||||
#include "lighting/common/sceneLighting.h"
|
||||
#include "lighting/common/lightMapParams.h"
|
||||
#include "core/util/safeDelete.h"
|
||||
#include "renderInstance/renderPrePassMgr.h"
|
||||
#include "materials/materialManager.h"
|
||||
#include "math/util/sphereMesh.h"
|
||||
#include "console/consoleTypes.h"
|
||||
#include "scene/sceneRenderState.h"
|
||||
|
||||
|
||||
ImplementEnumType( ShadowType,
|
||||
"\n\n"
|
||||
"@ingroup AdvancedLighting" )
|
||||
{ ShadowType_Spot, "Spot" },
|
||||
{ ShadowType_PSSM, "PSSM" },
|
||||
{ ShadowType_Paraboloid, "Paraboloid" },
|
||||
{ ShadowType_DualParaboloidSinglePass, "DualParaboloidSinglePass" },
|
||||
{ ShadowType_DualParaboloid, "DualParaboloid" },
|
||||
{ ShadowType_CubeMap, "CubeMap" },
|
||||
EndImplementEnumType;
|
||||
|
||||
|
||||
AdvancedLightManager AdvancedLightManager::smSingleton;
|
||||
|
||||
|
||||
AdvancedLightManager::AdvancedLightManager()
|
||||
: LightManager( "Advanced Lighting", "ADVLM" )
|
||||
{
|
||||
mLightBinManager = NULL;
|
||||
mLastShader = NULL;
|
||||
mAvailableSLInterfaces = NULL;
|
||||
}
|
||||
|
||||
AdvancedLightManager::~AdvancedLightManager()
|
||||
{
|
||||
mLastShader = NULL;
|
||||
mLastConstants = NULL;
|
||||
|
||||
for (LightConstantMap::Iterator i = mConstantLookup.begin(); i != mConstantLookup.end(); i++)
|
||||
{
|
||||
if (i->value)
|
||||
SAFE_DELETE(i->value);
|
||||
}
|
||||
mConstantLookup.clear();
|
||||
}
|
||||
|
||||
bool AdvancedLightManager::isCompatible() const
|
||||
{
|
||||
// TODO: We need at least 3.0 shaders at the moment
|
||||
// but this should be relaxed to 2.0 soon.
|
||||
if ( GFX->getPixelShaderVersion() < 3.0 )
|
||||
return false;
|
||||
|
||||
// TODO: Test for the necessary texture formats!
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void AdvancedLightManager::activate( SceneManager *sceneManager )
|
||||
{
|
||||
Parent::activate( sceneManager );
|
||||
|
||||
GFXShader::addGlobalMacro( "TORQUE_ADVANCED_LIGHTING" );
|
||||
|
||||
sceneManager->setPostEffectFog( true );
|
||||
|
||||
SHADOWMGR->activate();
|
||||
|
||||
// Find a target format that supports blending...
|
||||
// we prefer the floating point format if it works.
|
||||
Vector<GFXFormat> formats;
|
||||
formats.push_back( GFXFormatR16G16B16A16F );
|
||||
formats.push_back( GFXFormatR16G16B16A16 );
|
||||
GFXFormat blendTargetFormat = GFX->selectSupportedFormat( &GFXDefaultRenderTargetProfile,
|
||||
formats,
|
||||
true,
|
||||
true,
|
||||
false );
|
||||
|
||||
mLightBinManager = new AdvancedLightBinManager( this, SHADOWMGR, blendTargetFormat );
|
||||
mLightBinManager->assignName( "AL_LightBinMgr" );
|
||||
|
||||
// First look for the prepass bin...
|
||||
RenderPrePassMgr *prePassBin = _findPrePassRenderBin();
|
||||
|
||||
// If we didn't find the prepass bin then add one.
|
||||
if ( !prePassBin )
|
||||
{
|
||||
prePassBin = new RenderPrePassMgr( true, blendTargetFormat );
|
||||
prePassBin->assignName( "AL_PrePassBin" );
|
||||
prePassBin->registerObject();
|
||||
getSceneManager()->getDefaultRenderPass()->addManager( prePassBin );
|
||||
mPrePassRenderBin = prePassBin;
|
||||
}
|
||||
|
||||
// Tell the material manager that prepass is enabled.
|
||||
MATMGR->setPrePassEnabled( true );
|
||||
|
||||
// Insert our light bin manager.
|
||||
mLightBinManager->setRenderOrder( prePassBin->getRenderOrder() + 0.01f );
|
||||
getSceneManager()->getDefaultRenderPass()->addManager( mLightBinManager );
|
||||
|
||||
AdvancedLightingFeatures::registerFeatures(mPrePassRenderBin->getTargetFormat(), mLightBinManager->getTargetFormat());
|
||||
|
||||
// Last thing... let everyone know we're active.
|
||||
smActivateSignal.trigger( getId(), true );
|
||||
}
|
||||
|
||||
void AdvancedLightManager::deactivate()
|
||||
{
|
||||
Parent::deactivate();
|
||||
|
||||
GFXShader::removeGlobalMacro( "TORQUE_ADVANCED_LIGHTING" );
|
||||
|
||||
// Release our bin manager... it will take care of
|
||||
// removing itself from the render passes.
|
||||
if( mLightBinManager )
|
||||
{
|
||||
mLightBinManager->MRTLightmapsDuringPrePass(false);
|
||||
mLightBinManager->deleteObject();
|
||||
}
|
||||
mLightBinManager = NULL;
|
||||
|
||||
if ( mPrePassRenderBin )
|
||||
mPrePassRenderBin->deleteObject();
|
||||
mPrePassRenderBin = NULL;
|
||||
|
||||
SHADOWMGR->deactivate();
|
||||
|
||||
mLastShader = NULL;
|
||||
mLastConstants = NULL;
|
||||
|
||||
for (LightConstantMap::Iterator i = mConstantLookup.begin(); i != mConstantLookup.end(); i++)
|
||||
{
|
||||
if (i->value)
|
||||
SAFE_DELETE(i->value);
|
||||
}
|
||||
mConstantLookup.clear();
|
||||
|
||||
mSphereGeometry = NULL;
|
||||
mSphereIndices = NULL;
|
||||
mConeGeometry = NULL;
|
||||
mConeIndices = NULL;
|
||||
|
||||
AdvancedLightingFeatures::unregisterFeatures();
|
||||
|
||||
// Now let everyone know we've deactivated.
|
||||
smActivateSignal.trigger( getId(), false );
|
||||
}
|
||||
|
||||
void AdvancedLightManager::_addLightInfoEx( LightInfo *lightInfo )
|
||||
{
|
||||
lightInfo->addExtended( new ShadowMapParams( lightInfo ) );
|
||||
lightInfo->addExtended( new LightMapParams( lightInfo ) );
|
||||
}
|
||||
|
||||
|
||||
void AdvancedLightManager::_initLightFields()
|
||||
{
|
||||
#define DEFINE_LIGHT_FIELD( var, type, enum_ ) \
|
||||
static inline const char* _get##var##Field( void *obj, const char *data ) \
|
||||
{ \
|
||||
ShadowMapParams *p = _getShadowMapParams( obj ); \
|
||||
if ( p ) \
|
||||
return Con::getData( type, &p->var, 0, enum_ ); \
|
||||
else \
|
||||
return ""; \
|
||||
} \
|
||||
\
|
||||
static inline bool _set##var##Field( void *object, const char *index, const char *data ) \
|
||||
{ \
|
||||
ShadowMapParams *p = _getShadowMapParams( object ); \
|
||||
if ( p ) \
|
||||
{ \
|
||||
Con::setData( type, &p->var, 0, 1, &data, enum_ ); \
|
||||
p->_validate(); \
|
||||
} \
|
||||
return false; \
|
||||
}
|
||||
|
||||
#define DEFINE_LIGHTMAP_FIELD( var, type, enum_ ) \
|
||||
static inline const char* _get##var##Field( void *obj, const char *data ) \
|
||||
{ \
|
||||
LightMapParams *p = _getLightMapParams( obj ); \
|
||||
if ( p ) \
|
||||
return Con::getData( type, &p->var, 0, enum_ ); \
|
||||
else \
|
||||
return ""; \
|
||||
} \
|
||||
\
|
||||
static inline bool _set##var##Field( void *object, const char *index, const char *data ) \
|
||||
{ \
|
||||
LightMapParams *p = _getLightMapParams( object ); \
|
||||
if ( p ) \
|
||||
{ \
|
||||
Con::setData( type, &p->var, 0, 1, &data, enum_ ); \
|
||||
} \
|
||||
return false; \
|
||||
}
|
||||
|
||||
#define ADD_LIGHT_FIELD( field, type, var, desc ) \
|
||||
ConsoleObject::addProtectedField( field, type, 0, \
|
||||
&Dummy::_set##var##Field, &Dummy::_get##var##Field, desc )
|
||||
|
||||
// Our dummy adaptor class which we hide in here
|
||||
// to keep from poluting the global namespace.
|
||||
class Dummy
|
||||
{
|
||||
protected:
|
||||
|
||||
static inline ShadowMapParams* _getShadowMapParams( void *obj )
|
||||
{
|
||||
ISceneLight *sceneLight = dynamic_cast<ISceneLight*>( (SimObject*)obj );
|
||||
if ( sceneLight )
|
||||
{
|
||||
LightInfo *lightInfo = sceneLight->getLight();
|
||||
if ( lightInfo )
|
||||
return lightInfo->getExtended<ShadowMapParams>();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline LightMapParams* _getLightMapParams( void *obj )
|
||||
{
|
||||
ISceneLight *sceneLight = dynamic_cast<ISceneLight*>( (SimObject*)obj );
|
||||
if ( sceneLight )
|
||||
{
|
||||
LightInfo *lightInfo = sceneLight->getLight();
|
||||
if ( lightInfo )
|
||||
return lightInfo->getExtended<LightMapParams>();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
DEFINE_LIGHT_FIELD( attenuationRatio, TypePoint3F, NULL );
|
||||
DEFINE_LIGHT_FIELD( shadowType, TYPEID< ShadowType >(), ConsoleBaseType::getType( TYPEID< ShadowType >() )->getEnumTable() );
|
||||
DEFINE_LIGHT_FIELD( texSize, TypeS32, NULL );
|
||||
DEFINE_LIGHT_FIELD( cookie, TypeStringFilename, NULL );
|
||||
DEFINE_LIGHT_FIELD( numSplits, TypeS32, NULL );
|
||||
DEFINE_LIGHT_FIELD( logWeight, TypeF32, NULL );
|
||||
DEFINE_LIGHT_FIELD( overDarkFactor, TypePoint4F, NULL);
|
||||
DEFINE_LIGHT_FIELD( shadowDistance, TypeF32, NULL );
|
||||
DEFINE_LIGHT_FIELD( shadowSoftness, TypeF32, NULL );
|
||||
DEFINE_LIGHT_FIELD( fadeStartDist, TypeF32, NULL );
|
||||
DEFINE_LIGHT_FIELD( lastSplitTerrainOnly, TypeBool, NULL );
|
||||
|
||||
DEFINE_LIGHTMAP_FIELD( representedInLightmap, TypeBool, NULL );
|
||||
DEFINE_LIGHTMAP_FIELD( shadowDarkenColor, TypeColorF, NULL );
|
||||
DEFINE_LIGHTMAP_FIELD( includeLightmappedGeometryInShadow, TypeBool, NULL );
|
||||
};
|
||||
|
||||
ConsoleObject::addGroup( "Advanced Lighting" );
|
||||
|
||||
ADD_LIGHT_FIELD( "attenuationRatio", TypePoint3F, attenuationRatio,
|
||||
"The proportions of constant, linear, and quadratic attenuation to use for "
|
||||
"the falloff for point and spot lights." );
|
||||
|
||||
ADD_LIGHT_FIELD( "shadowType", TYPEID< ShadowType >(), shadowType,
|
||||
"The type of shadow to use on this light." );
|
||||
|
||||
ADD_LIGHT_FIELD( "cookie", TypeStringFilename, cookie,
|
||||
"A custom pattern texture which is projected from the light." );
|
||||
|
||||
ADD_LIGHT_FIELD( "texSize", TypeS32, texSize,
|
||||
"The texture size of the shadow map." );
|
||||
|
||||
ADD_LIGHT_FIELD( "overDarkFactor", TypePoint4F, overDarkFactor,
|
||||
"The ESM shadow darkening factor");
|
||||
|
||||
ADD_LIGHT_FIELD( "shadowDistance", TypeF32, shadowDistance,
|
||||
"The distance from the camera to extend the PSSM shadow." );
|
||||
|
||||
ADD_LIGHT_FIELD( "shadowSoftness", TypeF32, shadowSoftness,
|
||||
"" );
|
||||
|
||||
ADD_LIGHT_FIELD( "numSplits", TypeS32, numSplits,
|
||||
"The logrithmic PSSM split distance factor." );
|
||||
|
||||
ADD_LIGHT_FIELD( "logWeight", TypeF32, logWeight,
|
||||
"The logrithmic PSSM split distance factor." );
|
||||
|
||||
ADD_LIGHT_FIELD( "fadeStartDistance", TypeF32, fadeStartDist,
|
||||
"Start fading shadows out at this distance. 0 = auto calculate this distance.");
|
||||
|
||||
ADD_LIGHT_FIELD( "lastSplitTerrainOnly", TypeBool, lastSplitTerrainOnly,
|
||||
"This toggles only terrain being rendered to the last split of a PSSM shadow map.");
|
||||
|
||||
ConsoleObject::endGroup( "Advanced Lighting" );
|
||||
|
||||
ConsoleObject::addGroup( "Advanced Lighting Lightmap" );
|
||||
|
||||
ADD_LIGHT_FIELD( "representedInLightmap", TypeBool, representedInLightmap,
|
||||
"This light is represented in lightmaps (static light, default: false)");
|
||||
|
||||
ADD_LIGHT_FIELD( "shadowDarkenColor", TypeColorF, shadowDarkenColor,
|
||||
"The color that should be used to multiply-blend dynamic shadows onto lightmapped geometry (ignored if 'representedInLightmap' is false)");
|
||||
|
||||
ADD_LIGHT_FIELD( "includeLightmappedGeometryInShadow", TypeBool, includeLightmappedGeometryInShadow,
|
||||
"This light should render lightmapped geometry during its shadow-map update (ignored if 'representedInLightmap' is false)");
|
||||
|
||||
ConsoleObject::endGroup( "Advanced Lighting Lightmap" );
|
||||
|
||||
#undef DEFINE_LIGHT_FIELD
|
||||
#undef ADD_LIGHT_FIELD
|
||||
}
|
||||
|
||||
void AdvancedLightManager::setLightInfo( ProcessedMaterial *pmat,
|
||||
const Material *mat,
|
||||
const SceneData &sgData,
|
||||
const SceneRenderState *state,
|
||||
U32 pass,
|
||||
GFXShaderConstBuffer *shaderConsts)
|
||||
{
|
||||
// Skip this if we're rendering from the prepass bin.
|
||||
if ( sgData.binType == SceneData::PrePassBin )
|
||||
return;
|
||||
|
||||
PROFILE_SCOPE(AdvancedLightManager_setLightInfo);
|
||||
|
||||
LightingShaderConstants *lsc = getLightingShaderConstants(shaderConsts);
|
||||
|
||||
LightShadowMap *lsm = SHADOWMGR->getCurrentShadowMap();
|
||||
|
||||
LightInfo *light;
|
||||
if ( lsm )
|
||||
light = lsm->getLightInfo();
|
||||
else
|
||||
{
|
||||
light = sgData.lights[0];
|
||||
if ( !light )
|
||||
light = getDefaultLight();
|
||||
}
|
||||
|
||||
// NOTE: If you encounter a crash from this point forward
|
||||
// while setting a shader constant its probably because the
|
||||
// mConstantLookup has bad shaders/constants in it.
|
||||
//
|
||||
// This is a known crash bug that can occur if materials/shaders
|
||||
// are reloaded and the light manager is not reset.
|
||||
//
|
||||
// We should look to fix this by clearing the table.
|
||||
|
||||
// Update the forward shading light constants.
|
||||
_update4LightConsts( sgData,
|
||||
lsc->mLightPositionSC,
|
||||
lsc->mLightDiffuseSC,
|
||||
lsc->mLightAmbientSC,
|
||||
lsc->mLightInvRadiusSqSC,
|
||||
lsc->mLightSpotDirSC,
|
||||
lsc->mLightSpotAngleSC,
|
||||
lsc->mLightSpotFalloffSC,
|
||||
shaderConsts );
|
||||
|
||||
if ( lsm && light->getCastShadows() )
|
||||
{
|
||||
if ( lsc->mWorldToLightProjSC->isValid() )
|
||||
shaderConsts->set( lsc->mWorldToLightProjSC,
|
||||
lsm->getWorldToLightProj(),
|
||||
lsc->mWorldToLightProjSC->getType() );
|
||||
|
||||
if ( lsc->mViewToLightProjSC->isValid() )
|
||||
{
|
||||
// TODO: Should probably cache these results and
|
||||
// not do this mul here on every material that needs
|
||||
// this transform.
|
||||
|
||||
shaderConsts->set( lsc->mViewToLightProjSC,
|
||||
lsm->getWorldToLightProj() * state->getCameraTransform(),
|
||||
lsc->mViewToLightProjSC->getType() );
|
||||
}
|
||||
|
||||
shaderConsts->setSafe( lsc->mShadowMapSizeSC, 1.0f / (F32)lsm->getTexSize() );
|
||||
|
||||
// Do this last so that overrides can properly override parameters previously set
|
||||
lsm->setShaderParameters(shaderConsts, lsc);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( lsc->mViewToLightProjSC->isValid() )
|
||||
{
|
||||
// TODO: Should probably cache these results and
|
||||
// not do this mul here on every material that needs
|
||||
// this transform.
|
||||
MatrixF proj;
|
||||
light->getWorldToLightProj( &proj );
|
||||
|
||||
shaderConsts->set( lsc->mViewToLightProjSC,
|
||||
proj * state->getCameraTransform(),
|
||||
lsc->mViewToLightProjSC->getType() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AdvancedLightManager::registerGlobalLight(LightInfo *light, SimObject *obj)
|
||||
{
|
||||
Parent::registerGlobalLight( light, obj );
|
||||
|
||||
// Pass the volume lights to the bin manager.
|
||||
if ( mLightBinManager &&
|
||||
( light->getType() == LightInfo::Point ||
|
||||
light->getType() == LightInfo::Spot ) )
|
||||
mLightBinManager->addLight( light );
|
||||
}
|
||||
|
||||
void AdvancedLightManager::unregisterAllLights()
|
||||
{
|
||||
Parent::unregisterAllLights();
|
||||
|
||||
if ( mLightBinManager )
|
||||
mLightBinManager->clear();
|
||||
}
|
||||
|
||||
bool AdvancedLightManager::setTextureStage( const SceneData &sgData,
|
||||
const U32 currTexFlag,
|
||||
const U32 textureSlot,
|
||||
GFXShaderConstBuffer *shaderConsts,
|
||||
ShaderConstHandles *handles )
|
||||
{
|
||||
LightShadowMap* lsm = SHADOWMGR->getCurrentShadowMap();
|
||||
|
||||
// Assign Shadowmap, if it exists
|
||||
LightingShaderConstants* lsc = getLightingShaderConstants(shaderConsts);
|
||||
if ( !lsc )
|
||||
return false;
|
||||
|
||||
if ( lsm && lsm->getLightInfo()->getCastShadows() )
|
||||
return lsm->setTextureStage( currTexFlag, lsc );
|
||||
|
||||
|
||||
if ( currTexFlag == Material::DynamicLight )
|
||||
{
|
||||
S32 reg = lsc->mShadowMapSC->getSamplerRegister();
|
||||
if ( reg != -1 )
|
||||
GFX->setTexture( reg, GFXTexHandle::ONE );
|
||||
|
||||
return true;
|
||||
}
|
||||
else if ( currTexFlag == Material::DynamicLightMask )
|
||||
{
|
||||
S32 reg = lsc->mCookieMapSC->getSamplerRegister();
|
||||
if ( reg != -1 && sgData.lights[0] )
|
||||
{
|
||||
ShadowMapParams *p = sgData.lights[0]->getExtended<ShadowMapParams>();
|
||||
|
||||
if ( lsc->mCookieMapSC->getType() == GFXSCT_SamplerCube )
|
||||
GFX->setCubeTexture( reg, p->getCookieCubeTex() );
|
||||
else
|
||||
GFX->setTexture( reg, p->getCookieTex() );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
LightingShaderConstants* AdvancedLightManager::getLightingShaderConstants(GFXShaderConstBuffer* buffer)
|
||||
{
|
||||
if ( !buffer )
|
||||
return NULL;
|
||||
|
||||
PROFILE_SCOPE( AdvancedLightManager_GetLightingShaderConstants );
|
||||
|
||||
GFXShader* shader = buffer->getShader();
|
||||
|
||||
// Check to see if this is the same shader, we'll get hit repeatedly by
|
||||
// the same one due to the render bin loops.
|
||||
if ( mLastShader.getPointer() != shader )
|
||||
{
|
||||
LightConstantMap::Iterator iter = mConstantLookup.find(shader);
|
||||
if ( iter != mConstantLookup.end() )
|
||||
{
|
||||
mLastConstants = iter->value;
|
||||
}
|
||||
else
|
||||
{
|
||||
LightingShaderConstants* lsc = new LightingShaderConstants();
|
||||
mConstantLookup[shader] = lsc;
|
||||
|
||||
mLastConstants = lsc;
|
||||
}
|
||||
|
||||
// Set our new shader
|
||||
mLastShader = shader;
|
||||
}
|
||||
|
||||
// Make sure that our current lighting constants are initialized
|
||||
if (!mLastConstants->mInit)
|
||||
mLastConstants->init(shader);
|
||||
|
||||
return mLastConstants;
|
||||
}
|
||||
|
||||
GFXVertexBufferHandle<AdvancedLightManager::LightVertex> AdvancedLightManager::getSphereMesh(U32 &outNumPrimitives, GFXPrimitiveBuffer *&outPrimitives)
|
||||
{
|
||||
static SphereMesh sSphereMesh;
|
||||
|
||||
if( mSphereGeometry.isNull() )
|
||||
{
|
||||
const SphereMesh::TriangleMesh * sphereMesh = sSphereMesh.getMesh(3);
|
||||
S32 numPoly = sphereMesh->numPoly;
|
||||
mSpherePrimitiveCount = 0;
|
||||
mSphereGeometry.set(GFX, numPoly*3, GFXBufferTypeStatic);
|
||||
mSphereGeometry.lock();
|
||||
S32 vertexIndex = 0;
|
||||
|
||||
for (S32 i=0; i<numPoly; i++)
|
||||
{
|
||||
mSpherePrimitiveCount++;
|
||||
|
||||
mSphereGeometry[vertexIndex].point = sphereMesh->poly[i].pnt[0];
|
||||
mSphereGeometry[vertexIndex].color = ColorI::WHITE;
|
||||
vertexIndex++;
|
||||
|
||||
mSphereGeometry[vertexIndex].point = sphereMesh->poly[i].pnt[1];
|
||||
mSphereGeometry[vertexIndex].color = ColorI::WHITE;
|
||||
vertexIndex++;
|
||||
|
||||
mSphereGeometry[vertexIndex].point = sphereMesh->poly[i].pnt[2];
|
||||
mSphereGeometry[vertexIndex].color = ColorI::WHITE;
|
||||
vertexIndex++;
|
||||
}
|
||||
mSphereGeometry.unlock();
|
||||
}
|
||||
|
||||
outNumPrimitives = mSpherePrimitiveCount;
|
||||
outPrimitives = NULL; // For now
|
||||
return mSphereGeometry;
|
||||
}
|
||||
|
||||
GFXVertexBufferHandle<AdvancedLightManager::LightVertex> AdvancedLightManager::getConeMesh(U32 &outNumPrimitives, GFXPrimitiveBuffer *&outPrimitives )
|
||||
{
|
||||
static const Point2F circlePoints[] =
|
||||
{
|
||||
Point2F(0.707107f, 0.707107f),
|
||||
Point2F(0.923880f, 0.382683f),
|
||||
Point2F(1.000000f, 0.000000f),
|
||||
Point2F(0.923880f, -0.382684f),
|
||||
Point2F(0.707107f, -0.707107f),
|
||||
Point2F(0.382683f, -0.923880f),
|
||||
Point2F(0.000000f, -1.000000f),
|
||||
Point2F(-0.382683f, -0.923880f),
|
||||
Point2F(-0.707107f, -0.707107f),
|
||||
Point2F(-0.923880f, -0.382684f),
|
||||
Point2F(-1.000000f, 0.000000f),
|
||||
Point2F(-0.923879f, 0.382684f),
|
||||
Point2F(-0.707107f, 0.707107f),
|
||||
Point2F(-0.382683f, 0.923880f),
|
||||
Point2F(0.000000f, 1.000000f),
|
||||
Point2F(0.382684f, 0.923879f)
|
||||
};
|
||||
const S32 numPoints = sizeof(circlePoints)/sizeof(Point2F);
|
||||
|
||||
if ( mConeGeometry.isNull() )
|
||||
{
|
||||
mConeGeometry.set(GFX, numPoints + 1, GFXBufferTypeStatic);
|
||||
mConeGeometry.lock();
|
||||
|
||||
mConeGeometry[0].point = Point3F(0.0f,0.0f,0.0f);
|
||||
|
||||
for (S32 i=1; i<numPoints + 1; i++)
|
||||
{
|
||||
S32 imod = (i - 1) % numPoints;
|
||||
mConeGeometry[i].point = Point3F(circlePoints[imod].x,circlePoints[imod].y, -1.0f);
|
||||
mConeGeometry[i].color = ColorI::WHITE;
|
||||
}
|
||||
mConeGeometry.unlock();
|
||||
|
||||
mConePrimitiveCount = numPoints * 2 - 1;
|
||||
|
||||
// Now build the index buffer
|
||||
mConeIndices.set(GFX, mConePrimitiveCount * 3, mConePrimitiveCount, GFXBufferTypeStatic);
|
||||
|
||||
U16 *idx = NULL;
|
||||
mConeIndices.lock( &idx );
|
||||
// Build the cone
|
||||
U32 idxIdx = 0;
|
||||
for( int i = 1; i < numPoints + 1; i++ )
|
||||
{
|
||||
idx[idxIdx++] = 0; // Triangles on cone start at top point
|
||||
idx[idxIdx++] = i;
|
||||
idx[idxIdx++] = ( i + 1 > numPoints ) ? 1 : i + 1;
|
||||
}
|
||||
|
||||
// Build the bottom of the cone (reverse winding order)
|
||||
for( int i = 1; i < numPoints - 1; i++ )
|
||||
{
|
||||
idx[idxIdx++] = 1;
|
||||
idx[idxIdx++] = i + 2;
|
||||
idx[idxIdx++] = i + 1;
|
||||
}
|
||||
mConeIndices.unlock();
|
||||
}
|
||||
|
||||
outNumPrimitives = mConePrimitiveCount;
|
||||
outPrimitives = mConeIndices.getPointer();
|
||||
return mConeGeometry;
|
||||
}
|
||||
|
||||
LightShadowMap* AdvancedLightManager::findShadowMapForObject( SimObject *object )
|
||||
{
|
||||
if ( !object )
|
||||
return NULL;
|
||||
|
||||
ISceneLight *sceneLight = dynamic_cast<ISceneLight*>( object );
|
||||
if ( !sceneLight || !sceneLight->getLight() )
|
||||
return NULL;
|
||||
|
||||
return sceneLight->getLight()->getExtended<ShadowMapParams>()->getShadowMap();
|
||||
}
|
||||
|
||||
ConsoleFunction( setShadowVizLight, const char*, 2, 2, "" )
|
||||
{
|
||||
static const String DebugTargetName( "AL_ShadowVizTexture" );
|
||||
|
||||
NamedTexTarget *target = NamedTexTarget::find( DebugTargetName );
|
||||
if ( target )
|
||||
target->unregister();
|
||||
|
||||
AdvancedLightManager *lm = dynamic_cast<AdvancedLightManager*>( LIGHTMGR );
|
||||
if ( !lm )
|
||||
return 0;
|
||||
|
||||
SimObject *object;
|
||||
Sim::findObject( argv[1], object );
|
||||
LightShadowMap *lightShadowMap = lm->findShadowMapForObject( object );
|
||||
if ( !lightShadowMap || !lightShadowMap->getTexture() )
|
||||
return 0;
|
||||
|
||||
lightShadowMap->setDebugTarget( DebugTargetName );
|
||||
|
||||
GFXTextureObject *texObject = lightShadowMap->getTexture();
|
||||
const Point3I &size = texObject->getSize();
|
||||
F32 aspect = (F32)size.x / (F32)size.y;
|
||||
|
||||
char *result = Con::getReturnBuffer( 64 );
|
||||
dSprintf( result, 64, "%d %d %g", size.x, size.y, aspect );
|
||||
return result;
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue