Subversion Repository Public Repository

Divide-Framework

This repository has no backups
This repository's network speed is throttled to 100KB/sec

Diff Revisions 167 vs 168 for /trunk/Source Code/Managers/LightManager.cpp

Diff revisions: vs.
  @@ -9,22 +9,18 @@
9 9 #include "Hardware/Video/Buffers/FrameBufferObject/Headers/FrameBufferObject.h"
10 10
11 11 LightManager::LightManager() : FrameListener(),
12 - _previewShadowMaps(false),
13 - _dominantLight(NULL),
14 12 _shadowMapsEnabled(true),
15 - _shadowArrayOffset(-1),
16 - _shadowCubeOffset(-1)
13 + _previewShadowMaps(false),
14 + _dominantLight(NULL)
17 15 {
18 16 }
19 17
20 - LightManager::~LightManager(){
18 + LightManager::~LightManager()
19 + {
21 20 clear();
22 21 }
23 22
24 23 void LightManager::init(){
25 - I32 baseOffset = ParamHandler::getInstance().getParam<I32>("GFX_DEVICE.maxTextureCombinedUnits",16);
26 - _shadowArrayOffset = baseOffset - 2;
27 - _shadowCubeOffset = baseOffset - 1;
28 24 REGISTER_FRAME_LISTENER(&(this->getInstance()));
29 25 }
30 26
  @@ -34,16 +30,18 @@
34 30 //in case we had some light hanging
35 31 RemoveResource(it.second);
36 32 }
33 +
37 34 _lights.clear();
38 - if(_lights.empty()) return true;
39 - else return false;
35 +
36 + return _lights.empty();
40 37 }
41 38
42 39 bool LightManager::addLight(Light* const light){
43 - if(light->getId() == 0){
40 + if(light->getId() == 0)
44 41 light->setId(generateNewID());
45 - }
42 +
46 43 light->addShadowMapInfo(New ShadowMapInfo(light));
44 +
47 45 if(_lights.find(light->getId()) != _lights.end()){
48 46 ERROR_FN(Locale::get("ERROR_LIGHT_MANAGER_DUPLICATE"),light->getId());
49 47 return false;
  @@ -54,12 +52,13 @@
54 52 }
55 53
56 54 bool LightManager::removeLight(U32 lightId){
57 - LightMap::iterator it = _lights.find(lightId);
55 + LightMap::const_iterator it = _lights.find(lightId);
58 56
59 57 if(it == _lights.end()){
60 58 ERROR_FN(Locale::get("ERROR_LIGHT_MANAGER_REMOVE_LIGHT"),lightId);
61 59 return false;
62 60 }
61 +
63 62 (it->second)->removeShadowMapInfo();
64 63 _lights.erase(lightId); //remove it from the map
65 64 return true;
  @@ -67,18 +66,18 @@
67 66
68 67 U32 LightManager::generateNewID(){
69 68 U32 tempId = _lights.size();
70 - while(!checkId(tempId)){
69 +
70 + while(!checkId(tempId))
71 71 tempId++;
72 - }
72 +
73 73 return tempId;
74 74 }
75 75
76 76 bool LightManager::checkId(U32 value){
77 - for_each(LightMap::value_type& it, _lights){
78 - if(it.second->getId() == value){
77 + for_each(LightMap::value_type& it, _lights)
78 + if(it.second->getId() == value)
79 79 return false;
80 - }
81 - }
80 +
82 81 return true;
83 82 }
84 83
  @@ -104,12 +103,13 @@
104 103 ///When pre-rendering is done, the Light Manager will generate the shadow maps
105 104 /// Returning false in any of the FrameListener methods will exit the entire application!
106 105 bool LightManager::framePreRenderEnded(const FrameEvent& evt){
107 - if(!_shadowMapsEnabled) return true;
106 + if(!_shadowMapsEnabled)
107 + return true;
108 +
108 109 //Stop if we have shadows disabled
109 - _lightProjectionMatricesCache.resize(MAX_SHADOW_CASTING_LIGHTS_PER_NODE);
110 + _lightProjectionMatricesCache.resize(Config::MAX_SHADOW_CASTING_LIGHTS_PER_NODE);
110 111 //Tell the engine that we are drawing to depth maps
111 - //Remember the previous render stage type
112 - RenderStage prev = GFX_DEVICE.getRenderStage();
112 + RenderStage previousRS = GFX_DEVICE.getRenderStage();
113 113 //set the current render stage to SHADOW_STAGE
114 114 GFX_DEVICE.setRenderStage(SHADOW_STAGE);
115 115 // if we have a dominant light, generate only it's shadows
  @@ -123,91 +123,101 @@
123 123 }
124 124 }
125 125 //Revert back to the previous stage
126 - GFX_DEVICE.setRenderStage(prev);
126 + GFX_DEVICE.setRenderStage(previousRS);
127 127
128 128 return true;
129 129 }
130 130
131 - void LightManager::previewShadowMaps(Light* light){
131 + void LightManager::previewShadowMaps(Light* light) {
132 132 //Stop if we have shadows disabled
133 - if(_shadowMapsEnabled && _previewShadowMaps && GFX_DEVICE.isCurrentRenderStage(DISPLAY_STAGE)){
134 - Light* localLight = light;
135 - if(_dominantLight){
136 - localLight = _dominantLight;
137 - }else{
138 - if(localLight == NULL) localLight = _lights[0];
139 - }
140 - if(!localLight->castsShadows()) return;
133 + if(!_shadowMapsEnabled || !_previewShadowMaps || !GFX_DEVICE.isCurrentRenderStage(DISPLAY_STAGE))
134 + return;
141 135
142 - localLight->getShadowMapInfo()->getShadowMap()->previewShadowMaps();
143 - }
144 - }
136 + Light* localLight = light;
145 137
146 - vectorImpl<I32> LightManager::getDepthMapResolution() const{
147 - vectorImpl<I32 > shadowMapResolution;
148 - shadowMapResolution.reserve(MAX_SHADOW_CASTING_LIGHTS_PER_NODE);
149 - U8 counter = 0;
150 - for_each(Light* light, _currLightsPerNode){
151 - if(++counter > MAX_SHADOW_CASTING_LIGHTS_PER_NODE) break;
152 - if(light->castsShadows()){
153 - shadowMapResolution.push_back(light->getShadowMapInfo()->getShadowMap()->resolution());
154 - }
138 + if(_dominantLight){
139 + localLight = _dominantLight;
140 + }else{
141 + if(localLight == NULL)
142 + localLight = _lights[0];
155 143 }
156 - return shadowMapResolution;
144 +
145 + if(!localLight->castsShadows())
146 + return;
147 +
148 + localLight->getShadowMapInfo()->getShadowMap()->previewShadowMaps();
157 149 }
158 150
159 151 //If we have computed shadowmaps, bind them before rendering any geometry;
160 - //Always bind shadowmaps to slots 8, 9, 10, 11, 12, 13;
152 + //Always bind shadowmaps to slots Config::MAX_TEXTURE_STORAGE, Config::MAX_TEXTURE_STORAGE+1, Config::MAX_TEXTURE_STORAGE+2 ...
161 153 void LightManager::bindDepthMaps(Light* light, U8 lightIndex, U8 offset, bool overrideDominant){
162 154 //Skip applying shadows if we are rendering to depth map, or we have shadows disabled
163 - if(!_shadowMapsEnabled ||_lightProjectionMatricesCache.empty()) return;
155 + if(!_shadowMapsEnabled || _lightProjectionMatricesCache.empty())
156 + return;
157 +
164 158 Light* lightLocal = light;
165 159 ///If we have a dominant light, then both shadow casting lights are the same = the dominant one
166 160 ///Shadow map binding has a failsafe check for this, so it's ok to call bind twice
167 - if(_dominantLight && !overrideDominant){
161 + if(_dominantLight && !overrideDominant)
168 162 lightLocal = _dominantLight;
169 - }
170 -
171 - if(!lightLocal->castsShadows()) return;
172 -
173 - if(lightLocal->getLightType() == LIGHT_TYPE_DIRECTIONAL){
174 - offset = (U8)_shadowArrayOffset;
175 - }
176 - if(lightLocal->getLightType() == LIGHT_TYPE_POINT){
177 - offset = (U8)_shadowCubeOffset;
178 - }
163 +
164 + if(!lightLocal->castsShadows())
165 + return;
166 +
167 + if(lightLocal->getLightType() == LIGHT_TYPE_DIRECTIONAL)
168 + offset = Config::MAX_TEXTURE_STORAGE + Config::MAX_SHADOW_CASTING_LIGHTS_PER_NODE;
169 +
170 + if(lightLocal->getLightType() == LIGHT_TYPE_POINT)
171 + offset = Config::MAX_TEXTURE_STORAGE + Config::MAX_SHADOW_CASTING_LIGHTS_PER_NODE + 1;
172 +
179 173 _lightProjectionMatricesCache[lightIndex] = lightLocal->getLightProjectionMatrix();
174 +
180 175 lightLocal->getShadowMapInfo()->getShadowMap()->Bind(offset);
181 176 }
182 177
183 178 void LightManager::unbindDepthMaps(Light* light, U8 offset, bool overrideDominant){
184 - if(!_shadowMapsEnabled || _lightProjectionMatricesCache.empty()) return;
179 + if(!_shadowMapsEnabled || _lightProjectionMatricesCache.empty())
180 + return;
185 181
186 182 Light* lightLocal = light;
187 - if(_dominantLight && !overrideDominant){
188 - lightLocal = _dominantLight;
189 - }
190 -
191 - if(!lightLocal->castsShadows()) return;
192 183
193 - if(lightLocal->getLightType() == LIGHT_TYPE_DIRECTIONAL){
194 - offset = (U8)_shadowArrayOffset;
195 - }
196 - if(lightLocal->getLightType() == LIGHT_TYPE_POINT){
197 - offset = (U8)_shadowCubeOffset;
198 - }
184 + if(_dominantLight && !overrideDominant)
185 + lightLocal = _dominantLight;
186 +
187 + if(!lightLocal->castsShadows())
188 + return;
189 +
190 + if(lightLocal->getLightType() == LIGHT_TYPE_DIRECTIONAL)
191 + offset = Config::MAX_TEXTURE_STORAGE + Config::MAX_SHADOW_CASTING_LIGHTS_PER_NODE;
192 +
193 + if(lightLocal->getLightType() == LIGHT_TYPE_POINT)
194 + offset = Config::MAX_TEXTURE_STORAGE + Config::MAX_SHADOW_CASTING_LIGHTS_PER_NODE + 1;
195 +
199 196 lightLocal->getShadowMapInfo()->getShadowMap()->Unbind(offset);
200 197 }
201 198
202 199 bool LightManager::shadowMappingEnabled() const {
203 - if(!_shadowMapsEnabled) return false;
200 + if(!_shadowMapsEnabled)
201 + return false;
204 202
205 203 for_each(LightMap::value_type light, _lights){
206 - if(!light.second->castsShadows()) continue;
207 - ShadowMap* sm = light.second->getShadowMapInfo()->getShadowMap();
208 - if(!sm) continue; ///<no shadow info;
209 - if(sm->getDepthMap()) return true;
204 + if(!light.second->castsShadows())
205 + continue;
206 +
207 + ShadowMapInfo* smi = light.second->getShadowMapInfo();
208 + //no shadow info;
209 + if(!smi)
210 + continue;
211 +
212 + ShadowMap* sm = smi->getShadowMap();
213 + //no shadow map;
214 + if(!sm)
215 + continue;
216 +
217 + if(sm->getDepthMap())
218 + return true;
210 219 }
220 +
211 221 return false;
212 222 }
213 223
  @@ -219,53 +229,67 @@
219 229
220 230 U8 LightManager::findLightsForSceneNode(SceneGraphNode* const node, LightType typeFilter){
221 231 const vec3<F32> lumDot( 0.2125f, 0.7154f, 0.0721f );
222 - vectorImpl<Light* > tempLights;
223 - tempLights.reserve(_lights.size());
232 + F32 luminace = 0.0f;
233 + F32 dist = 0.0f;
234 + F32 weight = 1.0f; // later
235 + U8 i = 0;
236 + vec3<F32> distToLight;
237 + // Reset light buffer
238 + _tempLightsPerNode.resize(_lights.size());
224 239 _currLightsPerNode.resize(0);
225 240 _currLightTypes.resize(0);
226 241 _currLightsEnabled.resize(0);
227 242 _currShadowLights.resize(0);
228 -
243 + // loop over every light in the scene
244 + // ToDo: add a grid based light search system? -Ionut
229 245 for_each(LightMap::value_type& lightIt, _lights){
230 246 Light* light = lightIt.second;
231 - if(!light->getEnabled()) continue;
232 - F32 luminace = 0.0f;
233 - F32 dist = 0.0f;
234 - F32 weight = 1.0f; ///<later
235 - if ( light->getLightType() != LIGHT_TYPE_DIRECTIONAL ) {
236 - // Get the luminosity.
247 + if(!light->getEnabled())
248 + continue;
249 +
250 + LightType lType = light->getLightType();
251 + if(lType != LIGHT_TYPE_DIRECTIONAL ) {
252 + // get the luminosity.
237 253 luminace = vec3<F32>(light->getVProperty(LIGHT_PROPERTY_DIFFUSE)).dot(lumDot);
238 254 luminace *= light->getFProperty(LIGHT_PROPERTY_BRIGHTNESS);
239 255
240 - // Get the distance to the light... score it 1 to 0 near to far.
241 - vec3<F32> len = node->getBoundingBox().getCenter();
242 - len -= vec3<F32>(light->getPosition());
243 - F32 lenSq = len.lengthSquared();
244 - F32 radiusSq = squared( light->getFProperty(LIGHT_PROPERTY_RANGE) + node->getBoundingSphere().getRadius());
245 - F32 distSq = radiusSq - lenSq;
246 -
247 - if ( distSq > 0.0f )
248 - dist = distSq /( 1000.0f * 1000.0f );
249 - CLAMP<F32>(dist,0.0f, 1.0f );
250 - }else{///directional
251 - dist = 1.0f;
252 - luminace = 1.0f;
256 + F32 radiusSq = squared(light->getFProperty(LIGHT_PROPERTY_RANGE) + node->getBoundingSphere().getRadius());
257 + // get the distance to the light... score it 1 to 0 near to far.
258 + distToLight = node->getBoundingBox().getCenter() - light->getPosition();
259 + F32 distSq = radiusSq - distToLight.lengthSquared();
260 +
261 + if ( distSq > 0.0f )
262 + {
263 + dist = distSq /( 1000.0f * 1000.0f );
264 + CLAMP<F32>(dist, 0.0f, 1.0f );
265 + }
266 + light->setScore( luminace * weight * dist );
267 +
268 + }else{// directional
269 + light->setScore( weight );
253 270 }
254 - light->setScore( luminace * weight * dist );
255 - ///Use type filter
256 - if((typeFilter != LIGHT_TYPE_PLACEHOLDER && light->getLightType() == typeFilter) ||
257 - typeFilter == LIGHT_TYPE_PLACEHOLDER){
258 - tempLights.push_back(light);
271 +
272 + // use type filter
273 + if((typeFilter != LIGHT_TYPE_PLACEHOLDER && lType == typeFilter) || //< wether we have the correct light type
274 + typeFilter == LIGHT_TYPE_PLACEHOLDER){ //< or we did not specify a type filter
275 + _tempLightsPerNode[i++] = light;
259 276 }
260 277 }
261 - std::sort(tempLights.begin(), tempLights.end(), scoreCmpFnc());
262 - I32 maxLights = tempLights.size();
263 - CLAMP<I32>(maxLights, 0, MAX_LIGHTS_PER_SCENE_NODE);
278 +
279 + // sort the lights by score
280 + std::sort(_tempLightsPerNode.begin(),
281 + _tempLightsPerNode.end(),
282 + scoreCmpFnc());
283 +
284 + // create the light buffer for the specified node
285 + I32 maxLights = _tempLightsPerNode.size();
286 + CLAMP<I32>(maxLights, 0, Config::MAX_LIGHTS_PER_SCENE_NODE);
264 287 for(U8 i = 0; i < maxLights; i++){
265 - _currLightsPerNode.push_back(tempLights[i]);
266 - _currLightTypes.push_back(tempLights[i]->getLightType());
267 - _currLightsEnabled.push_back(tempLights[i]->getEnabled() ? 1 : 0);
268 - _currShadowLights.push_back(tempLights[i]->castsShadows() ? 1 : 0);
288 + _currLightsPerNode.push_back(_tempLightsPerNode[i]);
289 + _currLightTypes.push_back(_tempLightsPerNode[i]->getLightType());
290 + _currLightsEnabled.push_back(_tempLightsPerNode[i]->getEnabled() ? 1 : 0);
291 + _currShadowLights.push_back(_tempLightsPerNode[i]->castsShadows() ? 1 : 0);
269 292 }
293 +
270 294 return maxLights;
271 295 }