summaryrefslogtreecommitdiffstats
path: root/src/graphics/engine
diff options
context:
space:
mode:
authorPiotr Dziwinski <piotrdz@gmail.com>2013-02-25 21:58:01 +0100
committerPiotr Dziwinski <piotrdz@gmail.com>2013-02-25 21:58:01 +0100
commitb0d86ebe5a3c2330307a5c383f0136377338336c (patch)
tree358d9f002de1478eefce00e7f81f02d71403b648 /src/graphics/engine
parent3a594dc3a814cff4ae4db02985f4b1ce643a0604 (diff)
downloadcolobot-b0d86ebe5a3c2330307a5c383f0136377338336c.tar.gz
colobot-b0d86ebe5a3c2330307a5c383f0136377338336c.tar.bz2
colobot-b0d86ebe5a3c2330307a5c383f0136377338336c.zip
Better light sorting
Should fix lighting issue (#62)
Diffstat (limited to 'src/graphics/engine')
-rw-r--r--src/graphics/engine/engine.h6
-rw-r--r--src/graphics/engine/lightman.cpp79
-rw-r--r--src/graphics/engine/lightman.h21
3 files changed, 58 insertions, 48 deletions
diff --git a/src/graphics/engine/engine.h b/src/graphics/engine/engine.h
index 0647fbd..f9dfd45 100644
--- a/src/graphics/engine/engine.h
+++ b/src/graphics/engine/engine.h
@@ -729,7 +729,7 @@ public:
//@{
//! Management of game pause mode
void SetPause(bool pause);
- bool GetPause();
+ TEST_VIRTUAL bool GetPause();
//@}
//@{
@@ -1170,9 +1170,9 @@ public:
//! Returns the view matrix
const Math::Matrix& GetMatView();
//! Returns the camera center point
- Math::Vector GetEyePt();
+ TEST_VIRTUAL Math::Vector GetEyePt();
//! Returns the camera target point
- Math::Vector GetLookatPt();
+ TEST_VIRTUAL Math::Vector GetLookatPt();
//! Returns the horizontal direction angle of view
float GetEyeDirH();
//! Returns the vertical direction angle of view
diff --git a/src/graphics/engine/lightman.cpp b/src/graphics/engine/lightman.cpp
index 4a8fd60..628ebf5 100644
--- a/src/graphics/engine/lightman.cpp
+++ b/src/graphics/engine/lightman.cpp
@@ -26,6 +26,7 @@
#include <cmath>
+#include <algorithm>
// Graphics module namespace
@@ -386,39 +387,10 @@ void CLightManager::UpdateDeviceLights(EngineObjectType type)
for (int i = 0; i < static_cast<int>( m_lightMap.size() ); ++i)
m_lightMap[i] = -1;
- // High priority
- for (int i = 0; i < static_cast<int>( m_dynLights.size() ); i++)
- {
- if (! m_dynLights[i].used)
- continue;
- if (! m_dynLights[i].enabled)
- continue;
- if (Math::IsZero(m_dynLights[i].intensity.current))
- continue;
- if (m_dynLights[i].priority == LIGHT_PRI_LOW)
- continue;
-
- bool enabled = true;
- if (m_dynLights[i].includeType != ENG_OBJTYPE_NULL)
- enabled = (m_dynLights[i].includeType == type);
-
- if (m_dynLights[i].excludeType != ENG_OBJTYPE_NULL)
- enabled = (m_dynLights[i].excludeType != type);
-
- if (enabled)
- {
- for (int j = 0; j < static_cast<int>( m_lightMap.size() ); ++j)
- {
- if (m_lightMap[j] == -1)
- {
- m_lightMap[j] = i;
- break;
- }
- }
- }
- }
+ std::vector<DynamicLight> sortedLights = m_dynLights;
+ std::sort(sortedLights.begin(), sortedLights.end(), LightsComparator(m_engine->GetEyePt(), type));
- // Low priority
+ int lightMapIndex = 0;
for (int i = 0; i < static_cast<int>( m_dynLights.size() ); i++)
{
if (! m_dynLights[i].used)
@@ -427,8 +399,6 @@ void CLightManager::UpdateDeviceLights(EngineObjectType type)
continue;
if (m_dynLights[i].intensity.current == 0.0f)
continue;
- if (m_dynLights[i].priority == LIGHT_PRI_HIGH)
- continue;
bool enabled = true;
if (m_dynLights[i].includeType != ENG_OBJTYPE_NULL)
@@ -439,15 +409,12 @@ void CLightManager::UpdateDeviceLights(EngineObjectType type)
if (enabled)
{
- for (int j = 0; j < static_cast<int>( m_lightMap.size() ); ++j)
- {
- if (m_lightMap[j] == -1)
- {
- m_lightMap[j] = i;
- break;
- }
- }
+ m_lightMap[lightMapIndex] = i;
+ ++lightMapIndex;
}
+
+ if (lightMapIndex >= static_cast<int>( m_lightMap.size() ))
+ break;
}
for (int i = 0; i < static_cast<int>( m_lightMap.size() ); ++i)
@@ -465,5 +432,33 @@ void CLightManager::UpdateDeviceLights(EngineObjectType type)
}
}
+// -----------
+
+CLightManager::LightsComparator::LightsComparator(Math::Vector eyePos, EngineObjectType objectType)
+{
+ m_eyePos = eyePos;
+ m_objectType = objectType;
+}
+
+float CLightManager::LightsComparator::GetLightWeight(const DynamicLight& dynLight)
+{
+ bool enabled = true;
+ if (!dynLight.used || !dynLight.enabled || dynLight.intensity.current == 0.0f)
+ enabled = false;
+ else if (dynLight.includeType != ENG_OBJTYPE_NULL)
+ enabled = dynLight.includeType == m_objectType;
+ else if (dynLight.excludeType != ENG_OBJTYPE_NULL)
+ enabled = dynLight.excludeType != m_objectType;
+
+ return enabled ? ( (dynLight.light.position - m_eyePos).Length() * dynLight.priority ) : 10000.0f;
+}
+
+bool CLightManager::LightsComparator::operator()(const DynamicLight& left, const DynamicLight& right)
+{
+ float leftWeight = GetLightWeight(left);
+ float rightWeight = GetLightWeight(right);
+
+ return leftWeight >= rightWeight;
+}
} // namespace Gfx
diff --git a/src/graphics/engine/lightman.h b/src/graphics/engine/lightman.h
index 07dfe6a..ab66524 100644
--- a/src/graphics/engine/lightman.h
+++ b/src/graphics/engine/lightman.h
@@ -71,8 +71,8 @@ struct LightProgression
*/
enum LightPriority
{
- LIGHT_PRI_HIGH,
- LIGHT_PRI_LOW
+ LIGHT_PRI_HIGH = 1,
+ LIGHT_PRI_LOW = 2
};
/**
@@ -189,6 +189,21 @@ public:
void UpdateDeviceLights(EngineObjectType type);
protected:
+ class LightsComparator
+ {
+ public:
+ LightsComparator(Math::Vector eyePos, EngineObjectType objectType);
+
+ bool operator()(const DynamicLight& left, const DynamicLight& right);
+
+ private:
+ float GetLightWeight(const DynamicLight& dynLight);
+
+ Math::Vector m_eyePos;
+ EngineObjectType m_objectType;
+ };
+
+protected:
CEngine* m_engine;
CDevice* m_device;
@@ -196,7 +211,7 @@ protected:
float m_time;
//! List of dynamic lights
std::vector<DynamicLight> m_dynLights;
- //! Map of current light allotment: graphics light -> dynamic light
+ //! Map of current light allocation: graphics light -> dynamic light
std::vector<int> m_lightMap;
};