lightManager.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "platform/platform.h"
  23. #include "lighting/lightManager.h"
  24. #include "console/console.h"
  25. #include "console/consoleTypes.h"
  26. #include "core/util/safeDelete.h"
  27. #include "console/sim.h"
  28. #include "console/simSet.h"
  29. #include "scene/sceneManager.h"
  30. #include "materials/materialManager.h"
  31. #include "materials/sceneData.h"
  32. #include "lighting/lightInfo.h"
  33. #include "lighting/lightingInterfaces.h"
  34. #include "T3D/gameBase/gameConnection.h"
  35. #include "gfx/gfxStringEnumTranslate.h"
  36. #include "console/engineAPI.h"
  37. #include "renderInstance/renderDeferredMgr.h"
  38. Signal<void(const char*,bool)> LightManager::smActivateSignal;
  39. LightManager *LightManager::smActiveLM = NULL;
  40. LightManager::LightManager( const char *name, const char *id )
  41. : mName( name ),
  42. mId( id ),
  43. mIsActive( false ),
  44. mDefaultLight( NULL ),
  45. mSceneManager( NULL ),
  46. mCullPos( Point3F::Zero ),
  47. mAvailableSLInterfaces( NULL )
  48. {
  49. _getLightManagers().insert( mName, this );
  50. dMemset( &mSpecialLights, 0, sizeof( mSpecialLights ) );
  51. }
  52. LightManager::~LightManager()
  53. {
  54. _getLightManagers().erase( mName );
  55. SAFE_DELETE( mAvailableSLInterfaces );
  56. SAFE_DELETE( mDefaultLight );
  57. }
  58. LightManagerMap& LightManager::_getLightManagers()
  59. {
  60. static LightManagerMap lightManagerMap;
  61. return lightManagerMap;
  62. }
  63. LightManager* LightManager::findByName( const char *name )
  64. {
  65. LightManagerMap &lightManagers = _getLightManagers();
  66. LightManagerMap::Iterator iter = lightManagers.find( name );
  67. if ( iter != lightManagers.end() )
  68. return iter->value;
  69. return NULL;
  70. }
  71. void LightManager::getLightManagerNames( String *outString )
  72. {
  73. LightManagerMap &lightManagers = _getLightManagers();
  74. LightManagerMap::Iterator iter = lightManagers.begin();
  75. for ( ; iter != lightManagers.end(); iter++ )
  76. *outString += iter->key + "\t";
  77. // TODO!
  78. //outString->rtrim();
  79. }
  80. LightInfo* LightManager::createLightInfo(LightInfo* light /* = NULL */)
  81. {
  82. LightInfo *outLight = (light != NULL) ? light : new LightInfo;
  83. LightManagerMap &lightManagers = _getLightManagers();
  84. LightManagerMap::Iterator iter = lightManagers.begin();
  85. for ( ; iter != lightManagers.end(); iter++ )
  86. {
  87. LightManager *lm = iter->value;
  88. lm->_addLightInfoEx( outLight );
  89. }
  90. return outLight;
  91. }
  92. void LightManager::initLightFields()
  93. {
  94. LightManagerMap &lightManagers = _getLightManagers();
  95. LightManagerMap::Iterator iter = lightManagers.begin();
  96. for ( ; iter != lightManagers.end(); iter++ )
  97. {
  98. LightManager *lm = iter->value;
  99. lm->_initLightFields();
  100. }
  101. }
  102. IMPLEMENT_GLOBAL_CALLBACK( onLightManagerActivate, void, ( const char *name ), ( name ),
  103. "A callback called by the engine when a light manager is activated.\n"
  104. "@param name The name of the light manager being activated.\n"
  105. "@ingroup Lighting\n" );
  106. void LightManager::activate( SceneManager *sceneManager )
  107. {
  108. AssertFatal( sceneManager, "LightManager::activate() - Got null scene manager!" );
  109. AssertFatal( mIsActive == false, "LightManager::activate() - Already activated!" );
  110. AssertFatal( smActiveLM == NULL, "LightManager::activate() - A previous LM is still active!" );
  111. mIsActive = true;
  112. mSceneManager = sceneManager;
  113. smActiveLM = this;
  114. onLightManagerActivate_callback( getName() );
  115. }
  116. IMPLEMENT_GLOBAL_CALLBACK( onLightManagerDeactivate, void, ( const char *name ), ( name ),
  117. "A callback called by the engine when a light manager is deactivated.\n"
  118. "@param name The name of the light manager being deactivated.\n"
  119. "@ingroup Lighting\n" );
  120. void LightManager::deactivate()
  121. {
  122. AssertFatal( mIsActive == true, "LightManager::deactivate() - Already deactivated!" );
  123. AssertFatal( smActiveLM == this, "LightManager::activate() - This isn't the active light manager!" );
  124. if( Sim::getRootGroup() ) // To protect against shutdown.
  125. onLightManagerDeactivate_callback( getName() );
  126. mIsActive = false;
  127. mSceneManager = NULL;
  128. smActiveLM = NULL;
  129. // Just in case... make sure we're all clear.
  130. unregisterAllLights();
  131. }
  132. LightInfo* LightManager::getDefaultLight()
  133. {
  134. // The sun is always our default light when
  135. // when its registered.
  136. if ( mSpecialLights[ LightManager::slSunLightType ] )
  137. return mSpecialLights[ LightManager::slSunLightType ];
  138. // Else return a dummy special light.
  139. if ( !mDefaultLight )
  140. mDefaultLight = createLightInfo();
  141. return mDefaultLight;
  142. }
  143. LightInfo* LightManager::getSpecialLight( LightManager::SpecialLightTypesEnum type, bool useDefault )
  144. {
  145. if ( mSpecialLights[type] )
  146. return mSpecialLights[type];
  147. if ( useDefault )
  148. return getDefaultLight();
  149. return NULL;
  150. }
  151. void LightManager::setSpecialLight( LightManager::SpecialLightTypesEnum type, LightInfo *light )
  152. {
  153. if ( light && type == slSunLightType )
  154. {
  155. // The sun must be specially positioned and ranged
  156. // so that it can be processed like a point light
  157. // in the stock light shader used by Basic Lighting.
  158. light->setPosition( mCullPos - ( light->getDirection() * 10000.0f ) );
  159. light->setRange( 2000000.0f );
  160. }
  161. mSpecialLights[type] = light;
  162. registerGlobalLight( light, NULL );
  163. }
  164. void LightManager::registerGlobalLights( const Frustum *frustum, bool staticLighting, bool enableZoneLightCulling)
  165. {
  166. PROFILE_SCOPE( LightManager_RegisterGlobalLights );
  167. // TODO: We need to work this out...
  168. //
  169. // 1. Why do we register and unregister lights on every
  170. // render when they don't often change... shouldn't we
  171. // just register once and keep them?
  172. //
  173. // 2. If we do culling of lights should this happen as part
  174. // of registration or somewhere else?
  175. //
  176. // Grab the lights to process.
  177. Vector<SceneObject*> activeLights;
  178. const U32 lightMask = LightObjectType;
  179. if ( staticLighting || !frustum )
  180. {
  181. // We're processing static lighting or want all the lights
  182. // in the container registerd... so no culling.
  183. getSceneManager()->getContainer()->findObjectList( lightMask, &activeLights );
  184. }
  185. else
  186. {
  187. // Cull the lights using the frustum.
  188. getSceneManager()->getContainer()->findObjectList(*frustum, lightMask, &activeLights);
  189. /*
  190. for (U32 i = 0; i < activeLights.size(); ++i)
  191. {
  192. for (U32 i = 0; i < activeLights.size(); ++i)
  193. {
  194. if (!getSceneManager()->mRenderedObjectsList.contains(activeLights[i]))
  195. {
  196. activeLights.erase(i);
  197. --i;
  198. }
  199. }
  200. }
  201. */
  202. // Store the culling position for sun placement
  203. // later... see setSpecialLight.
  204. mCullPos = frustum->getPosition();
  205. // HACK: Make sure the control object always gets
  206. // processed as lights mounted to it don't change
  207. // the shape bounds and can often get culled.
  208. GameConnection *conn = GameConnection::getConnectionToServer();
  209. if (conn->getControlObject())
  210. {
  211. GameBase *conObject = conn->getControlObject();
  212. activeLights.push_back_unique(conObject);
  213. }
  214. }
  215. // Let the lights register themselves.
  216. for ( U32 i = 0; i < activeLights.size(); i++ )
  217. {
  218. ISceneLight *lightInterface = dynamic_cast<ISceneLight*>( activeLights[i] );
  219. if ( lightInterface )
  220. lightInterface->submitLights( this, staticLighting );
  221. }
  222. }
  223. void LightManager::registerGlobalLight( LightInfo *light, SimObject *obj )
  224. {
  225. AssertFatal( !mRegisteredLights.contains( light ),
  226. "LightManager::registerGlobalLight - This light is already registered!" );
  227. mRegisteredLights.push_back( light );
  228. }
  229. void LightManager::unregisterGlobalLight( LightInfo *light )
  230. {
  231. mRegisteredLights.unregisterLight( light );
  232. // If this is the sun... clear the special light too.
  233. if ( light == mSpecialLights[slSunLightType] )
  234. dMemset( mSpecialLights, 0, sizeof( mSpecialLights ) );
  235. }
  236. void LightManager::registerLocalLight( LightInfo *light )
  237. {
  238. // TODO: What should we do here?
  239. }
  240. void LightManager::unregisterLocalLight( LightInfo *light )
  241. {
  242. // TODO: What should we do here?
  243. }
  244. void LightManager::unregisterAllLights()
  245. {
  246. dMemset( mSpecialLights, 0, sizeof( mSpecialLights ) );
  247. mRegisteredLights.clear();
  248. }
  249. void LightManager::getAllUnsortedLights( Vector<LightInfo*> *list ) const
  250. {
  251. list->merge( mRegisteredLights );
  252. }
  253. void LightManager::_update4LightConsts( const SceneData &sgData,
  254. GFXShaderConstHandle *lightPositionSC,
  255. GFXShaderConstHandle *lightDiffuseSC,
  256. GFXShaderConstHandle *lightAmbientSC,
  257. GFXShaderConstHandle *lightConfigDataSC,
  258. GFXShaderConstHandle *lightSpotDirSC,
  259. GFXShaderConstHandle *lightSpotParamsSC,
  260. GFXShaderConstHandle* hasVectorLightSC,
  261. GFXShaderConstHandle* vectorLightDirectionSC,
  262. GFXShaderConstHandle* vectorLightColorSC,
  263. GFXShaderConstHandle* vectorLightBrightnessSC,
  264. GFXShaderConstBuffer *shaderConsts )
  265. {
  266. PROFILE_SCOPE( LightManager_Update4LightConsts );
  267. // Skip over gathering lights if we don't have to!
  268. if ( lightPositionSC->isValid() ||
  269. lightDiffuseSC->isValid() ||
  270. lightConfigDataSC->isValid() ||
  271. lightSpotDirSC->isValid() ||
  272. lightSpotParamsSC->isValid() )
  273. {
  274. PROFILE_SCOPE( LightManager_Update4LightConsts_setLights );
  275. //new setup
  276. const U32 MAX_FORWARD_LIGHTS = 4;
  277. static AlignedArray<Point4F> lightPositions(MAX_FORWARD_LIGHTS, sizeof(Point4F));
  278. static AlignedArray<Point4F> lightSpotDirs(MAX_FORWARD_LIGHTS, sizeof(Point4F));
  279. static AlignedArray<Point4F> lightColors(MAX_FORWARD_LIGHTS, sizeof(Point4F));
  280. static AlignedArray<Point4F> lightConfigData(MAX_FORWARD_LIGHTS, sizeof(Point4F)); //type, brightness, range, invSqrRange : rgba
  281. static AlignedArray<Point2F> lightSpotParams(MAX_FORWARD_LIGHTS, sizeof(Point2F));
  282. dMemset(lightPositions.getBuffer(), 0, lightPositions.getBufferSize());
  283. dMemset(lightSpotDirs.getBuffer(), 0, lightSpotDirs.getBufferSize());
  284. dMemset(lightColors.getBuffer(), 0, lightColors.getBufferSize());
  285. dMemset(lightConfigData.getBuffer(), 0, lightConfigData.getBufferSize());
  286. dMemset(lightSpotParams.getBuffer(), 0, lightSpotParams.getBufferSize());
  287. //sun-only
  288. F32 vectorLightBrightness;
  289. static Point4F vectorLightDirection;
  290. static Point4F vectorLightColor;
  291. static Point4F vectorLightAmbientColor;
  292. int hasVectorLight = 0;
  293. vectorLightBrightness = 0;
  294. vectorLightDirection = Point4F::Zero;
  295. vectorLightColor = Point4F::Zero;
  296. vectorLightAmbientColor = Point4F::Zero;
  297. // Gather the data for the first 4 lights.
  298. const LightInfo* light;
  299. for (U32 i = 0; i < MAX_FORWARD_LIGHTS; i++)
  300. {
  301. light = sgData.lights[i];
  302. if (!light)
  303. break;
  304. if (light->getType() == LightInfo::Vector)
  305. {
  306. if (hasVectorLight != 0)
  307. continue;
  308. vectorLightBrightness = light->getBrightness();
  309. vectorLightDirection = light->getDirection();
  310. vectorLightColor = Point4F(light->getColor());
  311. vectorLightAmbientColor = Point4F(light->getAmbient());
  312. hasVectorLight = 1;
  313. continue;
  314. }
  315. // The light positions and spot directions are
  316. // in SoA order to make optimal use of the GPU.
  317. const Point3F& lightPos = light->getPosition();
  318. lightPositions[i].x = lightPos.x;
  319. lightPositions[i].y = lightPos.y;
  320. lightPositions[i].z = lightPos.z;
  321. lightPositions[i].w = 0;
  322. const VectorF& lightDir = light->getDirection();
  323. lightSpotDirs[i].x = lightDir.x;
  324. lightSpotDirs[i].y = lightDir.y;
  325. lightSpotDirs[i].z = lightDir.z;
  326. lightSpotDirs[i].w = 0;
  327. lightColors[i] = Point4F(light->getColor());
  328. if (light->getType() == LightInfo::Point)
  329. {
  330. lightConfigData[i].x = 0;
  331. }
  332. else if (light->getType() == LightInfo::Spot)
  333. {
  334. lightConfigData[i].x = 1;
  335. const F32 outerCone = light->getOuterConeAngle();
  336. const F32 innerCone = getMin(light->getInnerConeAngle(), outerCone);
  337. const F32 outerCos = mCos(mDegToRad(outerCone / 2.0f));
  338. const F32 innerCos = mCos(mDegToRad(innerCone / 2.0f));
  339. Point2F spotParams(outerCos, innerCos - outerCos);
  340. lightSpotParams[i].x = spotParams.x;
  341. lightSpotParams[i].y = spotParams.y;
  342. }
  343. lightConfigData[i].y = light->getBrightness();
  344. F32 range = light->getRange().x;
  345. lightConfigData[i].z = range;
  346. lightConfigData[i].w = 1.0f / (range * range);
  347. }
  348. shaderConsts->setSafe(lightPositionSC, lightPositions);
  349. shaderConsts->setSafe(lightDiffuseSC, lightColors);
  350. shaderConsts->setSafe(lightSpotDirSC, lightSpotDirs);
  351. shaderConsts->setSafe(lightConfigDataSC, lightConfigData);
  352. shaderConsts->setSafe(lightSpotParamsSC, lightSpotParams);
  353. shaderConsts->setSafe(hasVectorLightSC, (int)hasVectorLight);
  354. shaderConsts->setSafe(vectorLightDirectionSC, vectorLightDirection);
  355. shaderConsts->setSafe(vectorLightColorSC, vectorLightColor);
  356. shaderConsts->setSafe(vectorLightBrightnessSC, vectorLightBrightness);
  357. //================================================================
  358. //old setup
  359. /*static AlignedArray<Point4F> lightPositions( 3, sizeof( Point4F ) );
  360. static AlignedArray<Point4F> lightSpotDirs( 3, sizeof( Point4F ) );
  361. static AlignedArray<Point4F> lightColors( 4, sizeof( Point4F ) );
  362. static Point4F lightInvRadiusSq;
  363. static Point4F lightSpotAngle;
  364. static Point4F lightSpotFalloff;
  365. F32 range;
  366. // Need to clear the buffers so that we don't leak
  367. // lights from previous passes or have NaNs.
  368. dMemset( lightPositions.getBuffer(), 0, lightPositions.getBufferSize() );
  369. dMemset( lightSpotDirs.getBuffer(), 0, lightSpotDirs.getBufferSize() );
  370. dMemset( lightColors.getBuffer(), 0, lightColors.getBufferSize() );
  371. lightInvRadiusSq = Point4F::Zero;
  372. lightSpotAngle.set( -1.0f, -1.0f, -1.0f, -1.0f );
  373. lightSpotFalloff.set( F32_MAX, F32_MAX, F32_MAX, F32_MAX );
  374. // Gather the data for the first 4 lights.
  375. const LightInfo *light;
  376. for ( U32 i=0; i < MAX_FORWARD_LIGHTS; i++ )
  377. {
  378. light = sgData.lights[i];
  379. if ( !light )
  380. break;
  381. // The light positions and spot directions are
  382. // in SoA order to make optimal use of the GPU.
  383. const Point3F &lightPos = light->getPosition();
  384. lightPositions[0][i] = lightPos.x;
  385. lightPositions[1][i] = lightPos.y;
  386. lightPositions[2][i] = lightPos.z;
  387. const VectorF &lightDir = light->getDirection();
  388. lightSpotDirs[0][i] = lightDir.x;
  389. lightSpotDirs[1][i] = lightDir.y;
  390. lightSpotDirs[2][i] = lightDir.z;
  391. if ( light->getType() == LightInfo::Spot )
  392. {
  393. lightSpotAngle[i] = mCos( mDegToRad( light->getOuterConeAngle() / 2.0f ) );
  394. lightSpotFalloff[i] = 1.0f / getMax( F32_MIN, mCos( mDegToRad( light->getInnerConeAngle() / 2.0f ) ) - lightSpotAngle[i] );
  395. }
  396. // Prescale the light color by the brightness to
  397. // avoid doing this in the shader.
  398. lightColors[i] = Point4F(light->getColor()) * light->getBrightness();
  399. // We need 1 over range^2 here.
  400. range = light->getRange().x;
  401. lightInvRadiusSq[i] = 1.0f / ( range * range );
  402. }
  403. shaderConsts->setSafe( lightPositionSC, lightPositions );
  404. shaderConsts->setSafe( lightDiffuseSC, lightColors );
  405. shaderConsts->setSafe( lightInvRadiusSqSC, lightInvRadiusSq );
  406. shaderConsts->setSafe( lightSpotDirSC, lightSpotDirs );
  407. shaderConsts->setSafe( lightSpotAngleSC, lightSpotAngle );
  408. shaderConsts->setSafe( lightSpotFalloffSC, lightSpotFalloff );*/
  409. }
  410. // Setup the ambient lighting from the first
  411. // light which is the directional light if
  412. // one exists at all in the scene.
  413. if ( lightAmbientSC->isValid() )
  414. shaderConsts->set( lightAmbientSC, sgData.ambientLightColor );
  415. }
  416. AvailableSLInterfaces* LightManager::getSceneLightingInterface()
  417. {
  418. if ( !mAvailableSLInterfaces )
  419. mAvailableSLInterfaces = new AvailableSLInterfaces();
  420. return mAvailableSLInterfaces;
  421. }
  422. bool LightManager::lightScene( const char* callback, const char* param )
  423. {
  424. BitSet32 flags = 0;
  425. if ( param )
  426. {
  427. if ( !dStricmp( param, "forceAlways" ) )
  428. flags.set( SceneLighting::ForceAlways );
  429. else if ( !dStricmp(param, "forceWritable" ) )
  430. flags.set( SceneLighting::ForceWritable );
  431. else if ( !dStricmp(param, "loadOnly" ) )
  432. flags.set( SceneLighting::LoadOnly );
  433. }
  434. // The SceneLighting object will delete itself
  435. // once the lighting process is complete.
  436. SceneLighting* sl = new SceneLighting( getSceneLightingInterface() );
  437. return sl->lightScene( callback, flags );
  438. }
  439. RenderDeferredMgr* LightManager::_findDeferredRenderBin()
  440. {
  441. RenderPassManager* rpm = getSceneManager()->getDefaultRenderPass();
  442. for( U32 i = 0; i < rpm->getManagerCount(); i++ )
  443. {
  444. RenderBinManager *bin = rpm->getManager( i );
  445. if( bin->getRenderInstType() == RenderDeferredMgr::RIT_Deferred )
  446. {
  447. return ( RenderDeferredMgr* ) bin;
  448. }
  449. }
  450. return NULL;
  451. }
  452. DefineEngineFunction( setLightManager, bool, ( const char *name ),,
  453. "Finds and activates the named light manager.\n"
  454. "@return Returns true if the light manager is found and activated.\n"
  455. "@ingroup Lighting\n" )
  456. {
  457. return gClientSceneGraph->setLightManager( name );
  458. }
  459. DefineEngineFunction( lightScene, bool, ( const char *completeCallbackFn, const char *mode ), ( nullAsType<const char*>(), nullAsType<const char*>() ),
  460. "Will generate static lighting for the scene if supported by the active light manager.\n\n"
  461. "If mode is \"forceAlways\", the lightmaps will be regenerated regardless of whether "
  462. "lighting cache files can be written to. If mode is \"forceWritable\", then the lightmaps "
  463. "will be regenerated only if the lighting cache files can be written.\n"
  464. "@param completeCallbackFn The name of the function to execute when the lighting is complete.\n"
  465. "@param mode One of \"forceAlways\", \"forceWritable\" or \"loadOnly\".\n"
  466. "@return Returns true if the scene lighting process was started.\n"
  467. "@ingroup Lighting\n" )
  468. {
  469. if ( !LIGHTMGR )
  470. return false;
  471. return LIGHTMGR->lightScene( completeCallbackFn, mode );
  472. }
  473. DefineEngineFunction( getLightManagerNames, String, (),,
  474. "Returns a tab seperated list of light manager names.\n"
  475. "@ingroup Lighting\n" )
  476. {
  477. String names;
  478. LightManager::getLightManagerNames( &names );
  479. return names;
  480. }
  481. DefineEngineFunction( getActiveLightManager, const char*, (),,
  482. "Returns the active light manager name.\n"
  483. "@ingroup Lighting\n" )
  484. {
  485. if ( !LIGHTMGR )
  486. return NULL;
  487. return LIGHTMGR->getName();
  488. }
  489. DefineEngineFunction( resetLightManager, void, (),,
  490. "@brief Deactivates and then activates the currently active light manager."
  491. "This causes most shaders to be regenerated and is often used when global "
  492. "rendering changes have occured.\n"
  493. "@ingroup Lighting\n" )
  494. {
  495. LightManager *lm = LIGHTMGR;
  496. if ( !lm )
  497. return;
  498. SceneManager *sm = lm->getSceneManager();
  499. lm->deactivate();
  500. lm->activate( sm );
  501. }