advancedLightManager.cpp
Engine/source/lighting/advanced/advancedLightManager.cpp
Public Defines
define
ADD_LIGHT_FIELD(field, type, var, desc) ( field, type, 0, \ &Dummy::_set##var##Field, &Dummy::_get##var##Field, desc )
define
DEFINE_LIGHT_FIELD(var, type, enum_) static inline char* _get##var##Field( *obj, char *data ) \ { \ *p = _getShadowMapParams( obj ); \ ( p ) \ return ( type, &p->var, 0, enum_ ); \ else \ return ""; \ } \ \ static inline bool _set##var##Field( *object, char *index, char *data ) \ { \ *p = _getShadowMapParams( object ); \ ( p ) \ { \ ( type, &p->var, 0, 1, &data, enum_ ); \ p->_validate(); \ } \ return false; \ }
define
DEFINE_LIGHTMAP_FIELD(var, type, enum_) static inline char* _get##var##Field( *obj, char *data ) \ { \ *p = _getLightMapParams( obj ); \ ( p ) \ return ( type, &p->var, 0, enum_ ); \ else \ return ""; \ } \ \ static inline bool _set##var##Field( *object, char *index, char *data ) \ { \ *p = _getLightMapParams( object ); \ ( p ) \ { \ ( type, &p->var, 0, 1, &data, enum_ ); \ } \ return false; \ }
Public Variables
Public Functions
DefineEngineFunction(setShadowVizLight , const char * , (const char *name) , ("") , "" )
ImplementEnumType(ShadowType , "\n\n" "@ingroup AdvancedLighting" )
Detailed Description
Public Defines
ADD_LIGHT_FIELD(field, type, var, desc) ( field, type, 0, \ &Dummy::_set##var##Field, &Dummy::_get##var##Field, desc )
DEFINE_LIGHT_FIELD(var, type, enum_) static inline char* _get##var##Field( *obj, char *data ) \ { \ *p = _getShadowMapParams( obj ); \ ( p ) \ return ( type, &p->var, 0, enum_ ); \ else \ return ""; \ } \ \ static inline bool _set##var##Field( *object, char *index, char *data ) \ { \ *p = _getShadowMapParams( object ); \ ( p ) \ { \ ( type, &p->var, 0, 1, &data, enum_ ); \ p->_validate(); \ } \ return false; \ }
DEFINE_LIGHTMAP_FIELD(var, type, enum_) static inline char* _get##var##Field( *obj, char *data ) \ { \ *p = _getLightMapParams( obj ); \ ( p ) \ return ( type, &p->var, 0, enum_ ); \ else \ return ""; \ } \ \ static inline bool _set##var##Field( *object, char *index, char *data ) \ { \ *p = _getLightMapParams( object ); \ ( p ) \ { \ ( type, &p->var, 0, 1, &data, enum_ ); \ } \ return false; \ }
Public Variables
EndImplementEnumType
Public Functions
DefineEngineFunction(setShadowVizLight , const char * , (const char *name) , ("") , "" )
ImplementEnumType(ShadowType , "\n\n" "@ingroup AdvancedLighting" )
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#include "platform/platform.h" 25#include "lighting/advanced/advancedLightManager.h" 26 27#include "lighting/advanced/advancedLightBinManager.h" 28#include "lighting/advanced/advancedLightingFeatures.h" 29#include "lighting/shadowMap/shadowMapManager.h" 30#include "lighting/shadowMap/lightShadowMap.h" 31#include "lighting/common/sceneLighting.h" 32#include "lighting/common/lightMapParams.h" 33#include "core/util/safeDelete.h" 34#include "renderInstance/renderDeferredMgr.h" 35#include "materials/materialManager.h" 36#include "math/util/sphereMesh.h" 37#include "console/consoleTypes.h" 38#include "console/engineAPI.h" 39#include "scene/sceneRenderState.h" 40#include "gfx/gfxCardProfile.h" 41#include "gfx/gfxTextureProfile.h" 42 43#ifndef TORQUE_BASIC_LIGHTING 44F32 AdvancedLightManager::smProjectedShadowFilterDistance = 40.0f; 45#endif 46 47ImplementEnumType( ShadowType, 48 "\n\n" 49 "@ingroup AdvancedLighting" ) 50 { ShadowType_Spot, "Spot" }, 51 { ShadowType_PSSM, "PSSM" }, 52 { ShadowType_DualParaboloidSinglePass, "DualParaboloidSinglePass" }, 53 { ShadowType_DualParaboloid, "DualParaboloid" }, 54 { ShadowType_CubeMap, "CubeMap" }, 55EndImplementEnumType; 56 57 58AdvancedLightManager AdvancedLightManager::smSingleton; 59 60 61AdvancedLightManager::AdvancedLightManager() 62 : LightManager( "Advanced Lighting", "ADVLM" ) 63{ 64 mLightBinManager = NULL; 65 mLastShader = NULL; 66 mLastConstants = NULL; 67 mSpherePrimitiveCount = 0; 68 mConePrimitiveCount = 0; 69 mAvailableSLInterfaces = NULL; 70} 71 72AdvancedLightManager::~AdvancedLightManager() 73{ 74 mLastShader = NULL; 75 mLastConstants = NULL; 76 77 for (LightConstantMap::Iterator i = mConstantLookup.begin(); i != mConstantLookup.end(); i++) 78 { 79 if (i->value) 80 SAFE_DELETE(i->value); 81 } 82 mConstantLookup.clear(); 83} 84 85bool AdvancedLightManager::isCompatible() const 86{ 87 // TODO: We need at least 3.0 shaders at the moment 88 // but this should be relaxed to 2.0 soon. 89 if ( GFX->getPixelShaderVersion() < 3.0 ) 90 return false; 91 92 // TODO: Test for the necessary texture formats! 93 bool autoMips; 94 if(!GFX->getCardProfiler()->checkFormat(GFXFormatR16F, &GFXRenderTargetProfile, autoMips)) 95 return false; 96 97 return true; 98} 99 100void AdvancedLightManager::activate( SceneManager *sceneManager ) 101{ 102 Parent::activate( sceneManager ); 103 104 GFXShader::addGlobalMacro( "TORQUE_ADVANCED_LIGHTING" ); 105 106 sceneManager->setPostEffectFog( true ); 107 108 SHADOWMGR->activate(); 109 110 // Find a target format that supports blending... 111 // we prefer the floating point format if it works. 112 Vector<GFXFormat> formats; 113 formats.push_back( GFXFormatR16G16B16A16F ); 114 //formats.push_back( GFXFormatR16G16B16A16 ); 115 GFXFormat blendTargetFormat = GFX->selectSupportedFormat( &GFXRenderTargetProfile, 116 formats, 117 true, 118 true, 119 false ); 120 121 // First look for the deferred bin... 122 RenderDeferredMgr *deferredBin = _findDeferredRenderBin(); 123 124 // If we didn't find the deferred bin then add one. 125 if (!deferredBin) 126 { 127 deferredBin = new RenderDeferredMgr(true, blendTargetFormat); 128 deferredBin->assignName("AL_DeferredBin"); 129 deferredBin->registerObject(); 130 getSceneManager()->getDefaultRenderPass()->addManager(deferredBin); 131 mDeferredRenderBin = deferredBin; 132 } 133 134 mLightBinManager = new AdvancedLightBinManager( this, SHADOWMGR, blendTargetFormat ); 135 mLightBinManager->assignName( "AL_LightBinMgr" ); 136 137 // Tell the material manager that deferred is enabled. 138 MATMGR->setDeferredEnabled( true ); 139 140 // Insert our light bin manager. 141 mLightBinManager->setRenderOrder( deferredBin->getRenderOrder() + 0.01f ); 142 getSceneManager()->getDefaultRenderPass()->addManager( mLightBinManager ); 143 144 AdvancedLightingFeatures::registerFeatures(mDeferredRenderBin->getTargetFormat(), blendTargetFormat); 145 146 // Last thing... let everyone know we're active. 147 smActivateSignal.trigger( getId(), true ); 148} 149 150void AdvancedLightManager::deactivate() 151{ 152 Parent::deactivate(); 153 154 GFXShader::removeGlobalMacro( "TORQUE_ADVANCED_LIGHTING" ); 155 156 // Release our bin manager... it will take care of 157 // removing itself from the render passes. 158 if( mLightBinManager ) 159 { 160 mLightBinManager->MRTLightmapsDuringDeferred(false); 161 mLightBinManager->deleteObject(); 162 } 163 mLightBinManager = NULL; 164 165 if ( mDeferredRenderBin ) 166 mDeferredRenderBin->deleteObject(); 167 mDeferredRenderBin = NULL; 168 169 SHADOWMGR->deactivate(); 170 171 mLastShader = NULL; 172 mLastConstants = NULL; 173 174 for (LightConstantMap::Iterator i = mConstantLookup.begin(); i != mConstantLookup.end(); i++) 175 { 176 if (i->value) 177 SAFE_DELETE(i->value); 178 } 179 mConstantLookup.clear(); 180 181 mSphereGeometry = NULL; 182 mSphereIndices = NULL; 183 mConeGeometry = NULL; 184 mConeIndices = NULL; 185 186 AdvancedLightingFeatures::unregisterFeatures(); 187 188 // Now let everyone know we've deactivated. 189 smActivateSignal.trigger( getId(), false ); 190} 191 192void AdvancedLightManager::_addLightInfoEx( LightInfo *lightInfo ) 193{ 194 lightInfo->addExtended( new ShadowMapParams( lightInfo ) ); 195 lightInfo->addExtended( new LightMapParams( lightInfo ) ); 196} 197 198 199void AdvancedLightManager::_initLightFields() 200{ 201 #define DEFINE_LIGHT_FIELD( var, type, enum_ ) \ 202 static inline const char* _get##var##Field( void *obj, const char *data ) \ 203 { \ 204 ShadowMapParams *p = _getShadowMapParams( obj ); \ 205 if ( p ) \ 206 return Con::getData( type, &p->var, 0, enum_ ); \ 207 else \ 208 return ""; \ 209 } \ 210 \ 211 static inline bool _set##var##Field( void *object, const char *index, const char *data ) \ 212 { \ 213 ShadowMapParams *p = _getShadowMapParams( object ); \ 214 if ( p ) \ 215 { \ 216 Con::setData( type, &p->var, 0, 1, &data, enum_ ); \ 217 p->_validate(); \ 218 } \ 219 return false; \ 220 } 221 222 #define DEFINE_LIGHTMAP_FIELD( var, type, enum_ ) \ 223 static inline const char* _get##var##Field( void *obj, const char *data ) \ 224 { \ 225 LightMapParams *p = _getLightMapParams( obj ); \ 226 if ( p ) \ 227 return Con::getData( type, &p->var, 0, enum_ ); \ 228 else \ 229 return ""; \ 230 } \ 231 \ 232 static inline bool _set##var##Field( void *object, const char *index, const char *data ) \ 233 { \ 234 LightMapParams *p = _getLightMapParams( object ); \ 235 if ( p ) \ 236 { \ 237 Con::setData( type, &p->var, 0, 1, &data, enum_ ); \ 238 } \ 239 return false; \ 240 } 241 242 #define ADD_LIGHT_FIELD( field, type, var, desc ) \ 243 ConsoleObject::addProtectedField( field, type, 0, \ 244 &Dummy::_set##var##Field, &Dummy::_get##var##Field, desc ) 245 246 // Our dummy adaptor class which we hide in here 247 // to keep from poluting the global namespace. 248 class Dummy 249 { 250 protected: 251 252 static inline ShadowMapParams* _getShadowMapParams( void *obj ) 253 { 254 ISceneLight *sceneLight = dynamic_cast<ISceneLight*>( (SimObject*)obj ); 255 if ( sceneLight ) 256 { 257 LightInfo *lightInfo = sceneLight->getLight(); 258 if ( lightInfo ) 259 return lightInfo->getExtended<ShadowMapParams>(); 260 } 261 return NULL; 262 } 263 264 static inline LightMapParams* _getLightMapParams( void *obj ) 265 { 266 ISceneLight *sceneLight = dynamic_cast<ISceneLight*>( (SimObject*)obj ); 267 if ( sceneLight ) 268 { 269 LightInfo *lightInfo = sceneLight->getLight(); 270 if ( lightInfo ) 271 return lightInfo->getExtended<LightMapParams>(); 272 } 273 return NULL; 274 } 275 276 public: 277 278 DEFINE_LIGHT_FIELD( attenuationRatio, TypePoint3F, NULL ); 279 DEFINE_LIGHT_FIELD( shadowType, TYPEID< ShadowType >(), ConsoleBaseType::getType( TYPEID< ShadowType >() )->getEnumTable() ); 280 DEFINE_LIGHT_FIELD( texSize, TypeS32, NULL ); 281 DEFINE_LIGHT_FIELD( cookie, TypeStringFilename, NULL ); 282 DEFINE_LIGHT_FIELD( numSplits, TypeS32, NULL ); 283 DEFINE_LIGHT_FIELD( logWeight, TypeF32, NULL ); 284 DEFINE_LIGHT_FIELD( overDarkFactor, TypePoint4F, NULL); 285 DEFINE_LIGHT_FIELD( shadowDistance, TypeF32, NULL ); 286 DEFINE_LIGHT_FIELD( shadowSoftness, TypeF32, NULL ); 287 DEFINE_LIGHT_FIELD( fadeStartDist, TypeF32, NULL ); 288 DEFINE_LIGHT_FIELD( lastSplitTerrainOnly, TypeBool, NULL ); 289 290 DEFINE_LIGHTMAP_FIELD( representedInLightmap, TypeBool, NULL ); 291 DEFINE_LIGHTMAP_FIELD( shadowDarkenColor, TypeColorF, NULL ); 292 DEFINE_LIGHTMAP_FIELD( includeLightmappedGeometryInShadow, TypeBool, NULL ); 293 }; 294 295 ConsoleObject::addGroup( "Advanced Lighting" ); 296 297 ADD_LIGHT_FIELD( "attenuationRatio", TypePoint3F, attenuationRatio, 298 "The proportions of constant, linear, and quadratic attenuation to use for " 299 "the falloff for point and spot lights." ); 300 301 ADD_LIGHT_FIELD( "shadowType", TYPEID< ShadowType >(), shadowType, 302 "The type of shadow to use on this light." ); 303 304 ADD_LIGHT_FIELD( "cookie", TypeStringFilename, cookie, 305 "A custom pattern texture which is projected from the light." ); 306 307 ADD_LIGHT_FIELD( "texSize", TypeS32, texSize, 308 "The texture size of the shadow map." ); 309 310 ADD_LIGHT_FIELD( "overDarkFactor", TypePoint4F, overDarkFactor, 311 "The ESM shadow darkening factor"); 312 313 ADD_LIGHT_FIELD( "shadowDistance", TypeF32, shadowDistance, 314 "The distance from the camera to extend the PSSM shadow." ); 315 316 ADD_LIGHT_FIELD( "shadowSoftness", TypeF32, shadowSoftness, 317 "" ); 318 319 ADD_LIGHT_FIELD( "numSplits", TypeS32, numSplits, 320 "The logrithmic PSSM split distance factor." ); 321 322 ADD_LIGHT_FIELD( "logWeight", TypeF32, logWeight, 323 "The logrithmic PSSM split distance factor." ); 324 325 ADD_LIGHT_FIELD( "fadeStartDistance", TypeF32, fadeStartDist, 326 "Start fading shadows out at this distance. 0 = auto calculate this distance."); 327 328 ADD_LIGHT_FIELD( "lastSplitTerrainOnly", TypeBool, lastSplitTerrainOnly, 329 "This toggles only terrain being rendered to the last split of a PSSM shadow map."); 330 331 ConsoleObject::endGroup( "Advanced Lighting" ); 332 333 ConsoleObject::addGroup( "Advanced Lighting Lightmap" ); 334 335 ADD_LIGHT_FIELD( "representedInLightmap", TypeBool, representedInLightmap, 336 "This light is represented in lightmaps (static light, default: false)"); 337 338 ADD_LIGHT_FIELD( "shadowDarkenColor", TypeColorF, shadowDarkenColor, 339 "The color that should be used to multiply-blend dynamic shadows onto lightmapped geometry (ignored if 'representedInLightmap' is false)"); 340 341 ADD_LIGHT_FIELD( "includeLightmappedGeometryInShadow", TypeBool, includeLightmappedGeometryInShadow, 342 "This light should render lightmapped geometry during its shadow-map update (ignored if 'representedInLightmap' is false)"); 343 344 ConsoleObject::endGroup( "Advanced Lighting Lightmap" ); 345 346 #undef DEFINE_LIGHT_FIELD 347 #undef ADD_LIGHT_FIELD 348} 349 350void AdvancedLightManager::setLightInfo( ProcessedMaterial *pmat, 351 const Material *mat, 352 const SceneData &sgData, 353 const SceneRenderState *state, 354 U32 pass, 355 GFXShaderConstBuffer *shaderConsts) 356{ 357 // Skip this if we're rendering from the deferred bin. 358 if ( sgData.binType == SceneData::DeferredBin ) 359 return; 360 361 PROFILE_SCOPE(AdvancedLightManager_setLightInfo); 362 363 LightingShaderConstants *lsc = getLightingShaderConstants(shaderConsts); 364 365 LightShadowMap *lsm = SHADOWMGR->getCurrentShadowMap(); 366 367 LightInfo *light; 368 if (lsm) 369 light = lsm->getLightInfo(); 370 else 371 { 372 light = sgData.lights[0]; 373 if ( !light ) 374 light = getDefaultLight(); 375 } 376 377 // NOTE: If you encounter a crash from this point forward 378 // while setting a shader constant its probably because the 379 // mConstantLookup has bad shaders/constants in it. 380 // 381 // This is a known crash bug that can occur if materials/shaders 382 // are reloaded and the light manager is not reset. 383 // 384 // We should look to fix this by clearing the table. 385 386 // Update the forward shading light constants. 387 _update4LightConsts( sgData, 388 lsc->mLightPositionSC, 389 lsc->mLightDiffuseSC, 390 lsc->mLightAmbientSC, 391 lsc->mLightConfigDataSC, 392 lsc->mLightSpotDirSC, 393 lsc->mLightSpotParamsSC, 394 lsc->mHasVectorLightSC, 395 lsc->mVectorLightDirectionSC, 396 lsc->mVectorLightColorSC, 397 lsc->mVectorLightBrightnessSC, 398 shaderConsts ); 399 400 // Static 401 if (lsm && light->getCastShadows()) 402 { 403 if ( lsc->mWorldToLightProjSC->isValid() ) 404 shaderConsts->set( lsc->mWorldToLightProjSC, 405 lsm->getWorldToLightProj(), 406 lsc->mWorldToLightProjSC->getType() ); 407 408 if ( lsc->mViewToLightProjSC->isValid() ) 409 { 410 // TODO: Should probably cache these results and 411 // not do this mul here on every material that needs 412 // this transform. 413 414 shaderConsts->set( lsc->mViewToLightProjSC, 415 lsm->getWorldToLightProj() * state->getCameraTransform(), 416 lsc->mViewToLightProjSC->getType() ); 417 } 418 419 shaderConsts->setSafe( lsc->mShadowMapSizeSC, 1.0f / (F32)lsm->getTexSize() ); 420 421 // Do this last so that overrides can properly override parameters previously set 422 lsm->setShaderParameters(shaderConsts, lsc); 423 } 424 else 425 { 426 if ( lsc->mViewToLightProjSC->isValid() ) 427 { 428 // TODO: Should probably cache these results and 429 // not do this mul here on every material that needs 430 // this transform. 431 MatrixF proj; 432 light->getWorldToLightProj( &proj ); 433 434 shaderConsts->set( lsc->mViewToLightProjSC, 435 proj * state->getCameraTransform(), 436 lsc->mViewToLightProjSC->getType() ); 437 } 438 } 439} 440 441void AdvancedLightManager::registerGlobalLight(LightInfo *light, SimObject *obj) 442{ 443 Parent::registerGlobalLight( light, obj ); 444 445 // Pass the volume lights to the bin manager. 446 if ( mLightBinManager && 447 ( light->getType() == LightInfo::Point || 448 light->getType() == LightInfo::Spot ) ) 449 mLightBinManager->addLight( light ); 450} 451 452void AdvancedLightManager::unregisterAllLights() 453{ 454 Parent::unregisterAllLights(); 455 456 if ( mLightBinManager ) 457 mLightBinManager->clearAllLights(); 458} 459 460bool AdvancedLightManager::setTextureStage( const SceneData &sgData, 461 const U32 currTexFlag, 462 const U32 textureSlot, 463 GFXShaderConstBuffer *shaderConsts, 464 ShaderConstHandles *handles ) 465{ 466 LightShadowMap* lsm = SHADOWMGR->getCurrentShadowMap(); 467 468 // Assign Shadowmap, if it exists 469 LightingShaderConstants* lsc = getLightingShaderConstants(shaderConsts); 470 if ( !lsc ) 471 return false; 472 473 if ( currTexFlag == Material::DynamicLight ) 474 { 475 // Static 476 if ( lsm && lsm->getLightInfo()->getCastShadows() ) 477 return lsm->setTextureStage( currTexFlag, lsc ); 478 479 S32 reg = lsc->mShadowMapSC->getSamplerRegister(); 480 if ( reg != -1 ) 481 GFX->setTexture( reg, GFXTexHandle::ONE ); 482 483 return true; 484 } 485 else if ( currTexFlag == Material::DynamicLightMask ) 486 { 487 S32 reg = lsc->mCookieMapSC->getSamplerRegister(); 488 if ( reg != -1 && sgData.lights[0] ) 489 { 490 ShadowMapParams *p = sgData.lights[0]->getExtended<ShadowMapParams>(); 491 492 if ( lsc->mCookieMapSC->getType() == GFXSCT_SamplerCube ) 493 GFX->setCubeTexture( reg, p->getCookieCubeTex() ); 494 else 495 GFX->setTexture( reg, p->getCookieTex() ); 496 } 497 498 return true; 499 } 500 501 return false; 502} 503 504LightingShaderConstants* AdvancedLightManager::getLightingShaderConstants(GFXShaderConstBuffer* buffer) 505{ 506 if ( !buffer ) 507 return NULL; 508 509 PROFILE_SCOPE( AdvancedLightManager_GetLightingShaderConstants ); 510 511 GFXShader* shader = buffer->getShader(); 512 513 // Check to see if this is the same shader, we'll get hit repeatedly by 514 // the same one due to the render bin loops. 515 if ( mLastShader.getPointer() != shader ) 516 { 517 LightConstantMap::Iterator iter = mConstantLookup.find(shader); 518 if ( iter != mConstantLookup.end() ) 519 { 520 mLastConstants = iter->value; 521 } 522 else 523 { 524 LightingShaderConstants* lsc = new LightingShaderConstants(); 525 mConstantLookup[shader] = lsc; 526 527 mLastConstants = lsc; 528 } 529 530 // Set our new shader 531 mLastShader = shader; 532 } 533 534 // Make sure that our current lighting constants are initialized 535 if (!mLastConstants->mInit) 536 mLastConstants->init(shader); 537 538 return mLastConstants; 539} 540 541GFXVertexBufferHandle<AdvancedLightManager::LightVertex> AdvancedLightManager::getSphereMesh(U32 &outNumPrimitives, GFXPrimitiveBuffer *&outPrimitives) 542{ 543 static SphereMesh sSphereMesh; 544 545 if( mSphereGeometry.isNull() ) 546 { 547 const SphereMesh::TriangleMesh * sphereMesh = sSphereMesh.getMesh(3); 548 S32 numPoly = sphereMesh->numPoly; 549 mSpherePrimitiveCount = 0; 550 mSphereGeometry.set(GFX, numPoly*3, GFXBufferTypeStatic); 551 mSphereGeometry.lock(); 552 S32 vertexIndex = 0; 553 554 for (S32 i=0; i<numPoly; i++) 555 { 556 mSpherePrimitiveCount++; 557 558 mSphereGeometry[vertexIndex].point = sphereMesh->poly[i].pnt[0]; 559 mSphereGeometry[vertexIndex].color = ColorI::WHITE; 560 vertexIndex++; 561 562 mSphereGeometry[vertexIndex].point = sphereMesh->poly[i].pnt[1]; 563 mSphereGeometry[vertexIndex].color = ColorI::WHITE; 564 vertexIndex++; 565 566 mSphereGeometry[vertexIndex].point = sphereMesh->poly[i].pnt[2]; 567 mSphereGeometry[vertexIndex].color = ColorI::WHITE; 568 vertexIndex++; 569 } 570 mSphereGeometry.unlock(); 571 } 572 573 outNumPrimitives = mSpherePrimitiveCount; 574 outPrimitives = NULL; // For now 575 return mSphereGeometry; 576} 577 578GFXVertexBufferHandle<AdvancedLightManager::LightVertex> AdvancedLightManager::getConeMesh(U32 &outNumPrimitives, GFXPrimitiveBuffer *&outPrimitives ) 579{ 580 static const Point2F circlePoints[] = 581 { 582 Point2F(0.707107f, 0.707107f), 583 Point2F(0.923880f, 0.382683f), 584 Point2F(1.000000f, 0.000000f), 585 Point2F(0.923880f, -0.382684f), 586 Point2F(0.707107f, -0.707107f), 587 Point2F(0.382683f, -0.923880f), 588 Point2F(0.000000f, -1.000000f), 589 Point2F(-0.382683f, -0.923880f), 590 Point2F(-0.707107f, -0.707107f), 591 Point2F(-0.923880f, -0.382684f), 592 Point2F(-1.000000f, 0.000000f), 593 Point2F(-0.923879f, 0.382684f), 594 Point2F(-0.707107f, 0.707107f), 595 Point2F(-0.382683f, 0.923880f), 596 Point2F(0.000000f, 1.000000f), 597 Point2F(0.382684f, 0.923879f) 598 }; 599 const S32 numPoints = sizeof(circlePoints)/sizeof(Point2F); 600 601 if ( mConeGeometry.isNull() ) 602 { 603 mConeGeometry.set(GFX, numPoints + 1, GFXBufferTypeStatic); 604 mConeGeometry.lock(); 605 606 mConeGeometry[0].point = Point3F(0.0f,0.0f,0.0f); 607 608 for (S32 i=1; i<numPoints + 1; i++) 609 { 610 S32 imod = (i - 1) % numPoints; 611 mConeGeometry[i].point = Point3F(circlePoints[imod].x*1.1,circlePoints[imod].y*1.1, -1.0f); 612 mConeGeometry[i].color = ColorI::WHITE; 613 } 614 mConeGeometry.unlock(); 615 616 mConePrimitiveCount = numPoints * 2 - 1; 617 618 // Now build the index buffer 619 mConeIndices.set(GFX, mConePrimitiveCount * 3, mConePrimitiveCount, GFXBufferTypeStatic); 620 621 U16 *idx = NULL; 622 mConeIndices.lock( &idx ); 623 // Build the cone 624 U32 idxIdx = 0; 625 for( U32 i = 1; i < numPoints + 1; i++ ) 626 { 627 idx[idxIdx++] = 0; // Triangles on cone start at top point 628 idx[idxIdx++] = i; 629 idx[idxIdx++] = ( i + 1 > numPoints ) ? 1 : i + 1; 630 } 631 632 // Build the bottom of the cone (reverse winding order) 633 for( U32 i = 1; i < numPoints - 1; i++ ) 634 { 635 idx[idxIdx++] = 1; 636 idx[idxIdx++] = i + 2; 637 idx[idxIdx++] = i + 1; 638 } 639 mConeIndices.unlock(); 640 } 641 642 outNumPrimitives = mConePrimitiveCount; 643 outPrimitives = mConeIndices.getPointer(); 644 return mConeGeometry; 645} 646 647LightShadowMap* AdvancedLightManager::findShadowMapForObject( SimObject *object ) 648{ 649 if ( !object ) 650 return NULL; 651 652 ISceneLight *sceneLight = dynamic_cast<ISceneLight*>( object ); 653 if ( !sceneLight || !sceneLight->getLight() ) 654 return NULL; 655 656 return sceneLight->getLight()->getExtended<ShadowMapParams>()->getShadowMap(); 657} 658 659DefineEngineFunction( setShadowVizLight, const char*, (const char* name), (""), "") 660{ 661 static const String DebugTargetName( "AL_ShadowVizTexture" ); 662 663 NamedTexTarget *target = NamedTexTarget::find( DebugTargetName ); 664 if ( target ) 665 target->unregister(); 666 667 AdvancedLightManager *lm = dynamic_cast<AdvancedLightManager*>( LIGHTMGR ); 668 if ( !lm ) 669 return 0; 670 671 SimObject *object; 672 Sim::findObject( name, object ); 673 LightShadowMap *lightShadowMap = lm->findShadowMapForObject( object ); 674 if ( !lightShadowMap || !lightShadowMap->getTexture() ) 675 return 0; 676 677 lightShadowMap->setDebugTarget( DebugTargetName ); 678 679 GFXTextureObject *texObject = lightShadowMap->getTexture(); 680 const Point3I &size = texObject->getSize(); 681 F32 aspect = (F32)size.x / (F32)size.y; 682 683 static const U32 bufSize = 64; 684 char *result = Con::getReturnBuffer( bufSize ); 685 dSprintf( result, bufSize, "%d %d %g", size.x, size.y, aspect ); 686 return result; 687} 688 689