diff --git a/src/graphics/core/device.h b/src/graphics/core/device.h
index 38bc4638..4c1189c6 100644
--- a/src/graphics/core/device.h
+++ b/src/graphics/core/device.h
@@ -240,6 +240,9 @@ public:
     //! Provides a hook to debug graphics code (implementation-specific)
     virtual void DebugHook() = 0;
 
+    //! Displays light positions to aid in debuggings
+    virtual void DebugLights() = 0;
+
     //! Initializes the device, setting the initial state
     virtual bool Create() = 0;
     //! Destroys the device, releasing every acquired resource
diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp
index 3423864c..669ea425 100644
--- a/src/graphics/engine/engine.cpp
+++ b/src/graphics/engine/engine.cpp
@@ -128,6 +128,9 @@ CEngine::CEngine(CApplication *app)
 
     m_interfaceMode = false;
 
+    m_debugLights = false;
+    m_debugDumpLights = false;
+
     m_mice[ENG_MOUSE_NORM]    = EngineMouse( 0,  1, 32, ENG_RSTATE_TTEXTURE_WHITE, ENG_RSTATE_TTEXTURE_BLACK, Math::Point( 1.0f,  1.0f));
     m_mice[ENG_MOUSE_WAIT]    = EngineMouse( 2,  3, 33, ENG_RSTATE_TTEXTURE_WHITE, ENG_RSTATE_TTEXTURE_BLACK, Math::Point( 8.0f, 12.0f));
     m_mice[ENG_MOUSE_HAND]    = EngineMouse( 4,  5, 34, ENG_RSTATE_TTEXTURE_WHITE, ENG_RSTATE_TTEXTURE_BLACK, Math::Point( 7.0f,  2.0f));
@@ -325,7 +328,22 @@ bool CEngine::ProcessEvent(const Event &event)
     if (event.type == EVENT_KEY_DOWN)
     {
         if (event.key.key == KEY(F12))
+        {
             m_showStats = !m_showStats;
+            return false;
+        }
+
+        if (event.key.key == KEY(F11))
+        {
+            m_debugLights = !m_debugLights;
+            return false;
+        }
+
+        if (event.key.key == KEY(F10))
+        {
+            m_debugDumpLights = true;
+            return false;
+        }
     }
 
     // By default, pass on all events
@@ -3293,6 +3311,15 @@ void CEngine::Draw3DScene()
 
     m_lightMan->UpdateDeviceLights(ENG_OBJTYPE_TERRAIN);
 
+    if (m_debugLights)
+        m_device->DebugLights();
+
+    if (m_debugDumpLights)
+    {
+        m_debugDumpLights = false;
+        m_lightMan->DebugDumpLights();
+    }
+
     if (m_waterMode)
     {
         m_app->StartPerformanceCounter(PCNT_RENDER_WATER);
diff --git a/src/graphics/engine/engine.h b/src/graphics/engine/engine.h
index 207ae270..5ecde8fe 100644
--- a/src/graphics/engine/engine.h
+++ b/src/graphics/engine/engine.h
@@ -1437,6 +1437,9 @@ protected:
 
     //! True when drawing 2D UI
     bool            m_interfaceMode;
+
+    bool            m_debugLights;
+    bool            m_debugDumpLights;
 };
 
 
diff --git a/src/graphics/engine/lightman.cpp b/src/graphics/engine/lightman.cpp
index cbb85099..3e512d83 100644
--- a/src/graphics/engine/lightman.cpp
+++ b/src/graphics/engine/lightman.cpp
@@ -71,6 +71,7 @@ void LightProgression::SetTarget(float value)
 
 DynamicLight::DynamicLight()
 {
+    rank = 0;
     used = enabled = false;
     priority = LIGHT_PRI_LOW;
     includeType = excludeType = ENG_OBJTYPE_NULL;
@@ -98,6 +99,61 @@ void CLightManager::SetDevice(CDevice* device)
     m_lightMap = std::vector<int>(m_device->GetMaxLightCount(), -1);
 }
 
+void CLightManager::DebugDumpLights()
+{
+    CLogger* l = GetLogger();
+
+    l->Debug("Dynamic lights:\n");
+
+    for (int i = 0; i < static_cast<int>( m_dynLights.size() ); ++i)
+    {
+        const DynamicLight& dynLight = m_dynLights[i];
+        if (!dynLight.used)
+            continue;
+
+        int deviceLight = -1;
+        for (int j = 0; j < m_lightMap.size(); ++j)
+        {
+            if (m_lightMap[j] == i)
+            {
+                deviceLight = j;
+                break;
+            }
+        }
+
+        l->Debug(" light %d\n", i);
+        l->Debug("  enabled = %s\n", dynLight.enabled ? "true" : "false");
+        l->Debug("  priority = %d\n", dynLight.priority);
+        l->Debug("  device light = %d\n", deviceLight);
+        l->Debug("  light:\n");
+
+        const Light& light = dynLight.light;
+        std::string str;
+
+        l->Debug("   type = %d\n", light.type);
+        str = light.ambient.ToString();
+        l->Debug("   ambient = %s\n", str.c_str());
+        str = light.diffuse.ToString();
+        l->Debug("   diffuse = %s\n", str.c_str());
+        str = light.specular.ToString();
+        l->Debug("   specular = %s\n", str.c_str());
+        str = light.position.ToString();
+        l->Debug("   position = %s\n", str.c_str());
+        str = light.direction.ToString();
+        l->Debug("   direction = %s\n", str.c_str());
+        l->Debug("   attenuation0 = %s\n", light.attenuation0);
+        l->Debug("   attenuation1 = %s\n", light.attenuation1);
+        l->Debug("   attenuation2 = %s\n", light.attenuation2);
+        l->Debug("   spotAngle = %s\n", light.spotAngle);
+        l->Debug("   spotIntensity = %s\n", light.spotIntensity);
+
+        l->Debug(" intensity: %f\n", dynLight.intensity.current);
+        l->Debug(" color: %f %f %f\n", dynLight.colorRed.current, dynLight.colorGreen.current, dynLight.colorBlue.current);
+        l->Debug(" includeType: %d\n", dynLight.includeType);
+        l->Debug(" excludeType: %d\n", dynLight.excludeType);
+    }
+}
+
 void CLightManager::FlushLights()
 {
     m_dynLights.clear();
@@ -117,6 +173,7 @@ int CLightManager::CreateLight(LightPriority priority)
         m_dynLights.push_back(DynamicLight());
 
     m_dynLights[index] = DynamicLight();
+    m_dynLights[index].rank     = index;
     m_dynLights[index].used     = true;
     m_dynLights[index].enabled  = true;
     m_dynLights[index].priority = priority;
@@ -411,7 +468,7 @@ void CLightManager::UpdateDeviceLights(EngineObjectType type)
 
         if (enabled)
         {
-            m_lightMap[lightMapIndex] = i;
+            m_lightMap[lightMapIndex] = sortedLights[i].rank;
             ++lightMapIndex;
         }
 
@@ -424,8 +481,9 @@ void CLightManager::UpdateDeviceLights(EngineObjectType type)
         int rank = m_lightMap[i];
         if (rank != -1)
         {
-            sortedLights[rank].light.ambient = Gfx::Color(0.2f, 0.2f, 0.2f);
-            m_device->SetLight(i, sortedLights[rank].light);
+            Light light = m_dynLights[rank].light;
+            light.ambient = Gfx::Color(0.2f, 0.2f, 0.2f);
+            m_device->SetLight(i, light);
             m_device->SetLightEnabled(i, true);
         }
         else
diff --git a/src/graphics/engine/lightman.h b/src/graphics/engine/lightman.h
index 171299c3..d0ac338d 100644
--- a/src/graphics/engine/lightman.h
+++ b/src/graphics/engine/lightman.h
@@ -84,6 +84,9 @@ enum LightPriority
  */
 struct DynamicLight
 {
+    //! Rank (index)
+    int rank;
+
     //! Whether the light is used
     bool used;
     //! Whether the light is turned on
@@ -136,6 +139,9 @@ public:
     //! Sets the device to be used
     void            SetDevice(CDevice* device);
 
+    //! Prints debug info
+    void DebugDumpLights();
+
     //! Clears and disables all lights
     void            FlushLights();
     //! Creates a new dynamic light and returns its index (lightRank)
diff --git a/src/graphics/engine/pyro.cpp b/src/graphics/engine/pyro.cpp
index 93198ece..7c518291 100644
--- a/src/graphics/engine/pyro.cpp
+++ b/src/graphics/engine/pyro.cpp
@@ -2398,6 +2398,7 @@ void CPyro::LightOperFrame(float rTime)
     {
         if ( m_progress < m_lightOper[i].progress )
         {
+            assert(i > 0); // TODO: if assert fails, fix the code
             float progress = (m_progress-m_lightOper[i-1].progress) / (m_lightOper[i].progress-m_lightOper[i-1].progress);
 
             float intensity = m_lightOper[i-1].intensity + (m_lightOper[i].intensity-m_lightOper[i-1].intensity)*progress;
diff --git a/src/graphics/opengl/gldevice.cpp b/src/graphics/opengl/gldevice.cpp
index 4bfc5428..534a13f2 100644
--- a/src/graphics/opengl/gldevice.cpp
+++ b/src/graphics/opengl/gldevice.cpp
@@ -79,6 +79,106 @@ void CGLDevice::DebugHook()
     glColor3i(0, 0, 0);
 }
 
+void CGLDevice::DebugLights()
+{
+    Gfx::ColorHSV color(0.0, 1.0, 1.0);
+
+    glLineWidth(3.0f);
+    glDisable(GL_LIGHTING);
+    glDepthMask(GL_FALSE);
+    glDisable(GL_BLEND);
+
+    Math::Matrix saveWorldMat = m_worldMat;
+    m_worldMat.LoadIdentity();
+    UpdateModelviewMatrix();
+
+    for (int i = 0; i < m_lights.size(); ++i)
+    {
+        color.h = static_cast<float>(i) / static_cast<float>(m_lights.size());
+        if (m_lightsEnabled[i])
+        {
+            const Light& l = m_lights[i];
+            if (l.type == LIGHT_DIRECTIONAL)
+            {
+                Gfx::VertexCol v[2];
+                v[0].coord = -Math::Normalize(l.direction) * 100.0f + Math::Vector(0.0f, 0.0f, 1.0f) * i;
+                v[0].color = HSV2RGB(color);
+                v[1].coord =  Math::Normalize(l.direction) * 100.0f + Math::Vector(0.0f, 0.0f, 1.0f) * i;
+                v[1].color = HSV2RGB(color);
+                while (v[0].coord.y < 60.0f && v[0].coord.y < 60.0f)
+                {
+                    v[0].coord.y += 10.0f;
+                    v[1].coord.y += 10.0f;
+                }
+                DrawPrimitive(PRIMITIVE_LINES, v, 2);
+
+                v[0].coord = v[1].coord + Math::Normalize(v[0].coord - v[1].coord) * 50.0f;
+
+                glLineWidth(10.0f);
+                DrawPrimitive(PRIMITIVE_LINES, v, 2);
+                glLineWidth(3.0f);
+            }
+            else  if (l.type == LIGHT_POINT)
+            {
+                Gfx::VertexCol v[8];
+                for (int i = 0; i < 8; ++i)
+                    v[i].color = HSV2RGB(color);
+
+                v[0].coord = l.position + Math::Vector(-1.0f, -1.0f, -1.0f) * 4.0f;
+                v[1].coord = l.position + Math::Vector( 1.0f, -1.0f, -1.0f) * 4.0f;
+                v[2].coord = l.position + Math::Vector( 1.0f,  1.0f, -1.0f) * 4.0f;
+                v[3].coord = l.position + Math::Vector(-1.0f,  1.0f, -1.0f) * 4.0f;
+                v[4].coord = l.position + Math::Vector(-1.0f, -1.0f, -1.0f) * 4.0f;
+                DrawPrimitive(PRIMITIVE_LINE_STRIP, v, 5);
+
+                v[0].coord = l.position + Math::Vector(-1.0f, -1.0f,  1.0f) * 4.0f;
+                v[1].coord = l.position + Math::Vector( 1.0f, -1.0f,  1.0f) * 4.0f;
+                v[2].coord = l.position + Math::Vector( 1.0f,  1.0f,  1.0f) * 4.0f;
+                v[3].coord = l.position + Math::Vector(-1.0f,  1.0f,  1.0f) * 4.0f;
+                v[4].coord = l.position + Math::Vector(-1.0f, -1.0f,  1.0f) * 4.0f;
+                DrawPrimitive(PRIMITIVE_LINE_STRIP, v, 5);
+
+                v[0].coord = l.position + Math::Vector(-1.0f, -1.0f, -1.0f) * 4.0f;
+                v[1].coord = l.position + Math::Vector(-1.0f, -1.0f,  1.0f) * 4.0f;
+                v[2].coord = l.position + Math::Vector( 1.0f, -1.0f, -1.0f) * 4.0f;
+                v[3].coord = l.position + Math::Vector( 1.0f, -1.0f,  1.0f) * 4.0f;
+                v[4].coord = l.position + Math::Vector( 1.0f,  1.0f, -1.0f) * 4.0f;
+                v[5].coord = l.position + Math::Vector( 1.0f,  1.0f,  1.0f) * 4.0f;
+                v[6].coord = l.position + Math::Vector(-1.0f,  1.0f, -1.0f) * 4.0f;
+                v[7].coord = l.position + Math::Vector(-1.0f,  1.0f,  1.0f) * 4.0f;
+                DrawPrimitive(PRIMITIVE_LINES, v, 8);
+            }
+            else if (l.type == LIGHT_SPOT)
+            {
+                Gfx::VertexCol v[5];
+                for (int i = 0; i < 5; ++i)
+                    v[i].color = HSV2RGB(color);
+
+                v[0].coord = l.position + Math::Vector(-1.0f,  0.0f, -1.0f) * 4.0f;
+                v[1].coord = l.position + Math::Vector( 1.0f,  0.0f, -1.0f) * 4.0f;
+                v[2].coord = l.position + Math::Vector( 1.0f,  0.0f,  1.0f) * 4.0f;
+                v[3].coord = l.position + Math::Vector(-1.0f,  0.0f,  1.0f) * 4.0f;
+                v[4].coord = l.position + Math::Vector(-1.0f,  0.0f, -1.0f) * 4.0f;
+                DrawPrimitive(PRIMITIVE_LINE_STRIP, v, 5);
+
+                v[0].coord = l.position;
+                v[1].coord = l.position + Math::Normalize(l.direction) * 100.0f;
+                glEnable(GL_LINE_STIPPLE);
+                glLineStipple(3.0, 0xFF);
+                DrawPrimitive(PRIMITIVE_LINES, v, 2);
+                glDisable(GL_LINE_STIPPLE);
+            }
+        }
+    }
+
+    glLineWidth(1.0f);
+    glEnable(GL_LIGHTING);
+    glDepthMask(GL_TRUE);
+    glEnable(GL_BLEND);
+    m_worldMat = saveWorldMat;
+    UpdateModelviewMatrix();
+}
+
 bool CGLDevice::Create()
 {
     GetLogger()->Info("Creating CDevice\n");
diff --git a/src/graphics/opengl/gldevice.h b/src/graphics/opengl/gldevice.h
index 004a18ba..c648161c 100644
--- a/src/graphics/opengl/gldevice.h
+++ b/src/graphics/opengl/gldevice.h
@@ -93,6 +93,7 @@ public:
     virtual ~CGLDevice();
 
     virtual void DebugHook();
+    virtual void DebugLights();
 
     virtual bool Create();
     virtual void Destroy();
diff --git a/src/math/matrix.h b/src/math/matrix.h
index a13f8231..f139517a 100644
--- a/src/math/matrix.h
+++ b/src/math/matrix.h
@@ -97,8 +97,8 @@ struct Matrix
 
     //! Sets value in given row and col
     /**
-     * \param row row (0 to 3)
-     * \param col column (0 to 3)
+     * \param row row (1 to 4)
+     * \param col column (1 to 4)
      * \param value value
      */
     inline void Set(int row, int col, float value)
@@ -108,8 +108,8 @@ struct Matrix
 
     //! Returns the value in given row and col
     /**
-     * \param row row (0 to 3)
-     * \param col column (0 to 3)
+     * \param row row (1 to 4)
+     * \param col column (1 to 4)
      * \returns value
      */
     inline float Get(int row, int col)
diff --git a/test/envs/opengl/CMakeLists.txt b/test/envs/opengl/CMakeLists.txt
index 0bcb43d5..c52b8b44 100644
--- a/test/envs/opengl/CMakeLists.txt
+++ b/test/envs/opengl/CMakeLists.txt
@@ -12,6 +12,7 @@ else()
 endif()
 
 set(TEXTURE_SOURCES
+${SRC_DIR}/graphics/core/color.cpp
 ${SRC_DIR}/graphics/opengl/gldevice.cpp
 ${SRC_DIR}/common/logger.cpp
 ${SRC_DIR}/common/image.cpp
@@ -19,6 +20,7 @@ texture_test.cpp
 )
 
 set(MODEL_SOURCES
+${SRC_DIR}/graphics/core/color.cpp
 ${SRC_DIR}/graphics/opengl/gldevice.cpp
 ${SRC_DIR}/graphics/engine/modelfile.cpp
 ${SRC_DIR}/common/logger.cpp
@@ -30,6 +32,7 @@ model_test.cpp
 )
 
 set(TRANSFORM_SOURCES
+${SRC_DIR}/graphics/core/color.cpp
 ${SRC_DIR}/graphics/opengl/gldevice.cpp
 ${SRC_DIR}/common/logger.cpp
 ${SRC_DIR}/common/image.cpp
@@ -39,6 +42,7 @@ transform_test.cpp
 )
 
 set(LIGHT_SOURCES
+${SRC_DIR}/graphics/core/color.cpp
 ${SRC_DIR}/graphics/opengl/gldevice.cpp
 ${SRC_DIR}/common/logger.cpp
 ${SRC_DIR}/common/image.cpp
diff --git a/test/unit/graphics/core/device_mock.h b/test/unit/graphics/core/device_mock.h
index 80e214fe..9e75daff 100644
--- a/test/unit/graphics/core/device_mock.h
+++ b/test/unit/graphics/core/device_mock.h
@@ -10,6 +10,7 @@ public:
     CDeviceMock() {}
 
     MOCK_METHOD0(DebugHook, void());
+    MOCK_METHOD0(DebugLights, void());
 
     MOCK_METHOD0(Create, bool());
     MOCK_METHOD0(Destroy, void());