Fix for bug #18900: game engine lights in non-glsl mode did move
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Tue, 9 Jun 2009 13:51:32 +0000 (13:51 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Tue, 9 Jun 2009 13:51:32 +0000 (13:51 +0000)
anymore, missing matrix update. Also move some code to KX_LightObject
to avoid duplication with player.

source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
source/gameengine/GamePlayer/common/GPC_RenderTools.cpp
source/gameengine/Ketsji/KX_Light.cpp
source/gameengine/Ketsji/KX_Light.h
source/gameengine/Rasterizer/RAS_LightObject.h

index 17d1bf65ca4499dd62989cd6a9f1cd778f918fc2..ffff7185fe455f988f185aaeb213eb85ceb33153 100644 (file)
@@ -28,8 +28,6 @@
 
 #include "GL/glew.h"
 
-#include "DNA_scene_types.h"
-
 #include "RAS_IRenderTools.h"
 #include "RAS_IRasterizer.h"
 #include "RAS_LightObject.h"
@@ -41,6 +39,7 @@
 #include "KX_BlenderMaterial.h"
 #include "KX_RayCast.h"
 #include "KX_IPhysicsController.h"
+#include "KX_Light.h"
 
 #include "PHY_IPhysicsEnvironment.h"
 
@@ -330,21 +329,12 @@ int KX_BlenderRenderTools::applyLights(int objectlayer, const MT_Transform& view
 {
        // taken from blender source, incompatibility between Blender Object / GameObject       
        KX_Scene* kxscene = (KX_Scene*)m_auxilaryClientInfo;
-       int scenelayer = ~0;
        float glviewmat[16];
        unsigned int count;
-       float vec[4];
-
-       vec[3]= 1.0;
+       std::vector<struct      RAS_LightObject*>::iterator lit = m_lights.begin();
 
-       if(kxscene && kxscene->GetBlenderScene())
-               scenelayer = kxscene->GetBlenderScene()->lay;
-       
        for(count=0; count<m_numgllights; count++)
                glDisable((GLenum)(GL_LIGHT0+count));
-       
-       //std::vector<struct    RAS_LightObject*> m_lights;
-       std::vector<struct      RAS_LightObject*>::iterator lit = m_lights.begin();
 
        viewmat.getValue(glviewmat);
        
@@ -353,82 +343,14 @@ int KX_BlenderRenderTools::applyLights(int objectlayer, const MT_Transform& view
        for (lit = m_lights.begin(), count = 0; !(lit==m_lights.end()) && count < m_numgllights; ++lit)
        {
                RAS_LightObject* lightdata = (*lit);
-               KX_Scene* lightscene = (KX_Scene*)lightdata->m_scene;
-
-               /* only use lights in the same layer as the object */
-               if(!(lightdata->m_layer & objectlayer))
-                       continue;
-               /* only use lights in the same scene, and in a visible layer */
-               if(kxscene != lightscene || !(lightdata->m_layer & scenelayer))
-                       continue;
-
-               vec[0] = (*(lightdata->m_worldmatrix))(0,3);
-               vec[1] = (*(lightdata->m_worldmatrix))(1,3);
-               vec[2] = (*(lightdata->m_worldmatrix))(2,3);
-               vec[3] = 1;
-
-               if(lightdata->m_type==RAS_LightObject::LIGHT_SUN) {
-                       
-                       vec[0] = (*(lightdata->m_worldmatrix))(0,2);
-                       vec[1] = (*(lightdata->m_worldmatrix))(1,2);
-                       vec[2] = (*(lightdata->m_worldmatrix))(2,2);
-                       //vec[0]= base->object->obmat[2][0];
-                       //vec[1]= base->object->obmat[2][1];
-                       //vec[2]= base->object->obmat[2][2];
-                       vec[3]= 0.0;
-                       glLightfv((GLenum)(GL_LIGHT0+count), GL_POSITION, vec); 
-               }
-               else {
-                       //vec[3]= 1.0;
-                       glLightfv((GLenum)(GL_LIGHT0+count), GL_POSITION, vec); 
-                       glLightf((GLenum)(GL_LIGHT0+count), GL_CONSTANT_ATTENUATION, 1.0);
-                       glLightf((GLenum)(GL_LIGHT0+count), GL_LINEAR_ATTENUATION, lightdata->m_att1/lightdata->m_distance);
-                       // without this next line it looks backward compatible.
-                       //attennuation still is acceptable 
-                       glLightf((GLenum)(GL_LIGHT0+count), GL_QUADRATIC_ATTENUATION, lightdata->m_att2/(lightdata->m_distance*lightdata->m_distance)); 
-                       
-                       if(lightdata->m_type==RAS_LightObject::LIGHT_SPOT) {
-                               vec[0] = -(*(lightdata->m_worldmatrix))(0,2);
-                               vec[1] = -(*(lightdata->m_worldmatrix))(1,2);
-                               vec[2] = -(*(lightdata->m_worldmatrix))(2,2);
-                               //vec[0]= -base->object->obmat[2][0];
-                               //vec[1]= -base->object->obmat[2][1];
-                               //vec[2]= -base->object->obmat[2][2];
-                               glLightfv((GLenum)(GL_LIGHT0+count), GL_SPOT_DIRECTION, vec);
-                               glLightf((GLenum)(GL_LIGHT0+count), GL_SPOT_CUTOFF, lightdata->m_spotsize/2.0);
-                               glLightf((GLenum)(GL_LIGHT0+count), GL_SPOT_EXPONENT, 128.0*lightdata->m_spotblend);
-                       }
-                       else glLightf((GLenum)(GL_LIGHT0+count), GL_SPOT_CUTOFF, 180.0);
-               }
-               
-               if (lightdata->m_nodiffuse)
-               {
-                       vec[0] = vec[1] = vec[2] = vec[3] = 0.0;
-               } else {
-                       vec[0]= lightdata->m_energy*lightdata->m_red;
-                       vec[1]= lightdata->m_energy*lightdata->m_green;
-                       vec[2]= lightdata->m_energy*lightdata->m_blue;
-                       vec[3]= 1.0;
-               }
-               glLightfv((GLenum)(GL_LIGHT0+count), GL_DIFFUSE, vec);
-               if (lightdata->m_nospecular)
-               {
-                       vec[0] = vec[1] = vec[2] = vec[3] = 0.0;
-               } else if (lightdata->m_nodiffuse) {
-                       vec[0]= lightdata->m_energy*lightdata->m_red;
-                       vec[1]= lightdata->m_energy*lightdata->m_green;
-                       vec[2]= lightdata->m_energy*lightdata->m_blue;
-                       vec[3]= 1.0;
-               }
-               glLightfv((GLenum)(GL_LIGHT0+count), GL_SPECULAR, vec);
-               glEnable((GLenum)(GL_LIGHT0+count));
+               KX_LightObject *kxlight = (KX_LightObject*)lightdata->m_light;
 
-               count++;
+               if(kxlight->ApplyLight(kxscene, objectlayer, count))
+                       count++;
        }
        glPopMatrix();
 
        return count;
-
 }
 
 void KX_BlenderRenderTools::MotionBlur(RAS_IRasterizer* rasterizer)
index 02f23a8431b7a0cc3327a0a502f943b68a02829c..96e50e651c0761ff96ada77f6faa8f58bc3325da 100644 (file)
@@ -31,8 +31,6 @@
 
 #include "BMF_Api.h"
 
-#include "DNA_scene_types.h"
-
 #include "RAS_IRenderTools.h"
 #include "RAS_IRasterizer.h"
 #include "RAS_LightObject.h"
@@ -44,6 +42,7 @@
 #include "KX_BlenderMaterial.h"
 #include "KX_RayCast.h"
 #include "KX_IPhysicsController.h"
+#include "KX_Light.h"
 
 #include "PHY_IPhysicsEnvironment.h"
 
@@ -389,21 +388,12 @@ int GPC_RenderTools::applyLights(int objectlayer, const MT_Transform& viewmat)
 {
        // taken from blender source, incompatibility between Blender Object / GameObject       
        KX_Scene* kxscene = (KX_Scene*)m_auxilaryClientInfo;
-       int scenelayer = ~0;
        float glviewmat[16];
        unsigned int count;
-       float vec[4];
-
-       vec[3]= 1.0;
+       std::vector<struct      RAS_LightObject*>::iterator lit = m_lights.begin();
 
-       if(kxscene && kxscene->GetBlenderScene())
-               scenelayer = kxscene->GetBlenderScene()->lay;
-       
        for(count=0; count<m_numgllights; count++)
                glDisable((GLenum)(GL_LIGHT0+count));
-       
-       //std::vector<struct    RAS_LightObject*> m_lights;
-       std::vector<struct      RAS_LightObject*>::iterator lit = m_lights.begin();
 
        viewmat.getValue(glviewmat);
        
@@ -412,82 +402,14 @@ int GPC_RenderTools::applyLights(int objectlayer, const MT_Transform& viewmat)
        for (lit = m_lights.begin(), count = 0; !(lit==m_lights.end()) && count < m_numgllights; ++lit)
        {
                RAS_LightObject* lightdata = (*lit);
-               KX_Scene* lightscene = (KX_Scene*)lightdata->m_scene;
-
-               /* only use lights in the same layer as the object */
-               if(!(lightdata->m_layer & objectlayer))
-                       continue;
-               /* only use lights in the same scene, and in a visible layer */
-               if(kxscene != lightscene || !(lightdata->m_layer & scenelayer))
-                       continue;
-
-               vec[0] = (*(lightdata->m_worldmatrix))(0,3);
-               vec[1] = (*(lightdata->m_worldmatrix))(1,3);
-               vec[2] = (*(lightdata->m_worldmatrix))(2,3);
-               vec[3] = 1;
-
-               if(lightdata->m_type==RAS_LightObject::LIGHT_SUN) {
-                       
-                       vec[0] = (*(lightdata->m_worldmatrix))(0,2);
-                       vec[1] = (*(lightdata->m_worldmatrix))(1,2);
-                       vec[2] = (*(lightdata->m_worldmatrix))(2,2);
-                       //vec[0]= base->object->obmat[2][0];
-                       //vec[1]= base->object->obmat[2][1];
-                       //vec[2]= base->object->obmat[2][2];
-                       vec[3]= 0.0;
-                       glLightfv((GLenum)(GL_LIGHT0+count), GL_POSITION, vec); 
-               }
-               else {
-                       //vec[3]= 1.0;
-                       glLightfv((GLenum)(GL_LIGHT0+count), GL_POSITION, vec); 
-                       glLightf((GLenum)(GL_LIGHT0+count), GL_CONSTANT_ATTENUATION, 1.0);
-                       glLightf((GLenum)(GL_LIGHT0+count), GL_LINEAR_ATTENUATION, lightdata->m_att1/lightdata->m_distance);
-                       // without this next line it looks backward compatible.
-                       //attennuation still is acceptable 
-                       glLightf((GLenum)(GL_LIGHT0+count), GL_QUADRATIC_ATTENUATION, lightdata->m_att2/(lightdata->m_distance*lightdata->m_distance)); 
-                       
-                       if(lightdata->m_type==RAS_LightObject::LIGHT_SPOT) {
-                               vec[0] = -(*(lightdata->m_worldmatrix))(0,2);
-                               vec[1] = -(*(lightdata->m_worldmatrix))(1,2);
-                               vec[2] = -(*(lightdata->m_worldmatrix))(2,2);
-                               //vec[0]= -base->object->obmat[2][0];
-                               //vec[1]= -base->object->obmat[2][1];
-                               //vec[2]= -base->object->obmat[2][2];
-                               glLightfv((GLenum)(GL_LIGHT0+count), GL_SPOT_DIRECTION, vec);
-                               glLightf((GLenum)(GL_LIGHT0+count), GL_SPOT_CUTOFF, lightdata->m_spotsize/2.0);
-                               glLightf((GLenum)(GL_LIGHT0+count), GL_SPOT_EXPONENT, 128.0*lightdata->m_spotblend);
-                       }
-                       else glLightf((GLenum)(GL_LIGHT0+count), GL_SPOT_CUTOFF, 180.0);
-               }
-               
-               if (lightdata->m_nodiffuse)
-               {
-                       vec[0] = vec[1] = vec[2] = vec[3] = 0.0;
-               } else {
-                       vec[0]= lightdata->m_energy*lightdata->m_red;
-                       vec[1]= lightdata->m_energy*lightdata->m_green;
-                       vec[2]= lightdata->m_energy*lightdata->m_blue;
-                       vec[3]= 1.0;
-               }
-               glLightfv((GLenum)(GL_LIGHT0+count), GL_DIFFUSE, vec);
-               if (lightdata->m_nospecular)
-               {
-                       vec[0] = vec[1] = vec[2] = vec[3] = 0.0;
-               } else if (lightdata->m_nodiffuse) {
-                       vec[0]= lightdata->m_energy*lightdata->m_red;
-                       vec[1]= lightdata->m_energy*lightdata->m_green;
-                       vec[2]= lightdata->m_energy*lightdata->m_blue;
-                       vec[3]= 1.0;
-               }
-               glLightfv((GLenum)(GL_LIGHT0+count), GL_SPECULAR, vec);
-               glEnable((GLenum)(GL_LIGHT0+count));
+               KX_LightObject *kxlight = (KX_LightObject*)lightdata->m_light;
 
-               count++;
+               if(kxlight->ApplyLight(kxscene, objectlayer, count))
+                       count++;
        }
        glPopMatrix();
 
        return count;
-
 }
 
 void GPC_RenderTools::MotionBlur(RAS_IRasterizer* rasterizer)
index fe575384a35acb76f4b4042755b7f71150313232..274d8f26d785eb72690bb668c5976f8dfd2425d2 100644 (file)
@@ -35,6 +35,8 @@
 #pragma warning (disable : 4786)
 #endif
 
+#include "GL/glew.h"
+
 #include "KX_Light.h"
 #include "KX_Camera.h"
 #include "RAS_IRasterizer.h"
@@ -43,6 +45,7 @@
 #include "KX_PyMath.h"
 
 #include "DNA_object_types.h"
+#include "DNA_scene_types.h"
 #include "GPU_material.h"
  
 KX_LightObject::KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks,
@@ -56,8 +59,8 @@ KX_LightObject::KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks,
                m_rendertools(rendertools)
 {
        m_lightobj = lightobj;
-       m_lightobj.m_worldmatrix = GetOpenGLMatrixPtr();
        m_lightobj.m_scene = sgReplicationInfo;
+       m_lightobj.m_light = this;
        m_rendertools->AddLight(&m_lightobj);
        m_glsl = glsl;
        m_blenderscene = ((KX_Scene*)sgReplicationInfo)->GetBlenderScene();
@@ -84,12 +87,102 @@ CValue*            KX_LightObject::GetReplica()
 
        replica->ProcessReplica();
        
-       replica->m_lightobj.m_worldmatrix = replica->GetOpenGLMatrixPtr();
+       replica->m_lightobj.m_light = replica;
        m_rendertools->AddLight(&replica->m_lightobj);
 
        return replica;
 }
 
+bool KX_LightObject::ApplyLight(KX_Scene *kxscene, int oblayer, int slot)
+{
+       KX_Scene* lightscene = (KX_Scene*)m_lightobj.m_scene;
+       float vec[4];
+       int scenelayer = ~0;
+
+       if(kxscene && kxscene->GetBlenderScene())
+               scenelayer = kxscene->GetBlenderScene()->lay;
+       
+       /* only use lights in the same layer as the object */
+       if(!(m_lightobj.m_layer & oblayer))
+               return false;
+       /* only use lights in the same scene, and in a visible layer */
+       if(kxscene != lightscene || !(m_lightobj.m_layer & scenelayer))
+               return false;
+
+       // lights don't get their openGL matrix updated, do it now
+       if(GetSGNode()->IsDirty())
+               GetOpenGLMatrix();
+
+       MT_CmMatrix4x4& worldmatrix= *GetOpenGLMatrixPtr();
+
+       vec[0] = worldmatrix(0,3);
+       vec[1] = worldmatrix(1,3);
+       vec[2] = worldmatrix(2,3);
+       vec[3] = 1.0f;
+
+       if(m_lightobj.m_type==RAS_LightObject::LIGHT_SUN) {
+               
+               vec[0] = worldmatrix(0,2);
+               vec[1] = worldmatrix(1,2);
+               vec[2] = worldmatrix(2,2);
+               //vec[0]= base->object->obmat[2][0];
+               //vec[1]= base->object->obmat[2][1];
+               //vec[2]= base->object->obmat[2][2];
+               vec[3]= 0.0;
+               glLightfv((GLenum)(GL_LIGHT0+slot), GL_POSITION, vec); 
+       }
+       else {
+               //vec[3]= 1.0;
+               glLightfv((GLenum)(GL_LIGHT0+slot), GL_POSITION, vec); 
+               glLightf((GLenum)(GL_LIGHT0+slot), GL_CONSTANT_ATTENUATION, 1.0);
+               glLightf((GLenum)(GL_LIGHT0+slot), GL_LINEAR_ATTENUATION, m_lightobj.m_att1/m_lightobj.m_distance);
+               // without this next line it looks backward compatible.
+               //attennuation still is acceptable 
+               glLightf((GLenum)(GL_LIGHT0+slot), GL_QUADRATIC_ATTENUATION, m_lightobj.m_att2/(m_lightobj.m_distance*m_lightobj.m_distance)); 
+               
+               if(m_lightobj.m_type==RAS_LightObject::LIGHT_SPOT) {
+                       vec[0] = -worldmatrix(0,2);
+                       vec[1] = -worldmatrix(1,2);
+                       vec[2] = -worldmatrix(2,2);
+                       //vec[0]= -base->object->obmat[2][0];
+                       //vec[1]= -base->object->obmat[2][1];
+                       //vec[2]= -base->object->obmat[2][2];
+                       glLightfv((GLenum)(GL_LIGHT0+slot), GL_SPOT_DIRECTION, vec);
+                       glLightf((GLenum)(GL_LIGHT0+slot), GL_SPOT_CUTOFF, m_lightobj.m_spotsize/2.0);
+                       glLightf((GLenum)(GL_LIGHT0+slot), GL_SPOT_EXPONENT, 128.0*m_lightobj.m_spotblend);
+               }
+               else
+                       glLightf((GLenum)(GL_LIGHT0+slot), GL_SPOT_CUTOFF, 180.0);
+       }
+       
+       if (m_lightobj.m_nodiffuse) {
+               vec[0] = vec[1] = vec[2] = vec[3] = 0.0;
+       }
+       else {
+               vec[0]= m_lightobj.m_energy*m_lightobj.m_red;
+               vec[1]= m_lightobj.m_energy*m_lightobj.m_green;
+               vec[2]= m_lightobj.m_energy*m_lightobj.m_blue;
+               vec[3]= 1.0;
+       }
+
+       glLightfv((GLenum)(GL_LIGHT0+slot), GL_DIFFUSE, vec);
+       if(m_lightobj.m_nospecular)
+       {
+               vec[0] = vec[1] = vec[2] = vec[3] = 0.0;
+       }
+       else if (m_lightobj.m_nodiffuse) {
+               vec[0]= m_lightobj.m_energy*m_lightobj.m_red;
+               vec[1]= m_lightobj.m_energy*m_lightobj.m_green;
+               vec[2]= m_lightobj.m_energy*m_lightobj.m_blue;
+               vec[3]= 1.0;
+       }
+
+       glLightfv((GLenum)(GL_LIGHT0+slot), GL_SPECULAR, vec);
+       glEnable((GLenum)(GL_LIGHT0+slot));
+
+       return true;
+}
+
 GPULamp *KX_LightObject::GetGPULamp()
 {
        if(m_glsl)
index 35f25515e3b228c81bd2fc378a2a41b974e99bb7..358c705080aa732b7f0842f9a32b268704684aee 100644 (file)
@@ -54,7 +54,10 @@ public:
        virtual CValue*         GetReplica();
        RAS_LightObject*        GetLightData() { return &m_lightobj;}
 
-       /* GLSL shadow */
+       /* OpenGL Light */
+       bool ApplyLight(KX_Scene *kxscene, int oblayer, int slot);
+
+       /* GLSL Light */
        struct GPULamp *GetGPULamp();
        bool HasShadowBuffer();
        int GetShadowLayer();
index 6b63a891981399df69b18aab14f4750c75bd2cef..b45a35e4266e296dd0e5377a8ac880370bacaea0 100644 (file)
@@ -39,8 +39,9 @@ struct RAS_LightObject
                LIGHT_NORMAL
        };
        bool    m_modified;
-       int     m_layer;
+       int             m_layer;
        void    *m_scene;
+       void    *m_light;
        
        float   m_energy;
        float   m_distance;
@@ -55,7 +56,6 @@ struct RAS_LightObject
        float   m_spotblend;
 
        LightType       m_type;
-       MT_CmMatrix4x4* m_worldmatrix;
        
        bool    m_nodiffuse;
        bool    m_nospecular;