2.50: svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r19323...
[blender.git] / source / gameengine / BlenderRoutines / KX_BlenderRenderTools.cpp
index 42ad776..9dbda3f 100644 (file)
@@ -28,6 +28,8 @@
 
 #include "GL/glew.h"
 
+#include "DNA_scene_types.h"
+
 #include "RAS_IRenderTools.h"
 #include "RAS_IRasterizer.h"
 #include "RAS_LightObject.h"
@@ -67,6 +69,7 @@ void KX_BlenderRenderTools::BeginFrame(RAS_IRasterizer* rasty)
        m_clientobject = NULL;
        m_lastlightlayer = -1;
        m_lastlighting = false;
+       m_lastauxinfo = NULL;
        DisableOpenGLLights();
 }
 
@@ -80,25 +83,27 @@ void KX_BlenderRenderTools::EndFrame(RAS_IRasterizer* rasty)
  * has a maximum of 8 lights (simultaneous), so 20 * 8 lights are possible in
  * a scene. */
 
-void KX_BlenderRenderTools::ProcessLighting(RAS_IRasterizer *rasty, int layer, const MT_Transform& viewmat)
+void KX_BlenderRenderTools::ProcessLighting(RAS_IRasterizer *rasty, bool uselights, const MT_Transform& viewmat)
 {
-       if(m_lastlightlayer == layer)
-               return;
+       bool enable = false;
+       int layer= -1;
 
-       m_lastlightlayer = layer;
+       /* find the layer */
+       if(uselights) {
+               if(m_clientobject)
+                       layer = static_cast<KX_GameObject*>(m_clientobject)->GetLayer();
+       }
 
-       bool enable = false;
+       /* avoid state switching */
+       if(m_lastlightlayer == layer && m_lastauxinfo == m_auxilaryClientInfo)
+               return;
 
-       if (layer >= 0)
-       {
-               if (m_clientobject)
-               {
-                       if (layer == RAS_LIGHT_OBJECT_LAYER)
-                               layer = static_cast<KX_GameObject*>(m_clientobject)->GetLayer();
+       m_lastlightlayer = layer;
+       m_lastauxinfo = m_auxilaryClientInfo;
 
-                       enable = applyLights(layer, viewmat);
-               }
-       }
+       /* enable/disable lights as needed */
+       if(layer >= 0)
+               enable = applyLights(layer, viewmat);
 
        if(enable)
                EnableOpenGLLights(rasty);
@@ -324,11 +329,16 @@ void KX_BlenderRenderTools::PopMatrix()
 int KX_BlenderRenderTools::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;
+
+       if(kxscene && kxscene->GetBlenderScene())
+               scenelayer = kxscene->GetBlenderScene()->lay;
        
        for(count=0; count<m_numgllights; count++)
                glDisable((GLenum)(GL_LIGHT0+count));
@@ -343,71 +353,77 @@ 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);
-               if (lightdata->m_layer & objectlayer)
-               {
-                       vec[0] = (*(lightdata->m_worldmatrix))(0,3);
-                       vec[1] = (*(lightdata->m_worldmatrix))(1,3);
-                       vec[2] = (*(lightdata->m_worldmatrix))(2,3);
-                       vec[3] = 1;
+               KX_Scene* lightscene = (KX_Scene*)lightdata->m_scene;
 
-                       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);
-                       }
+               /* 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) {
                        
-                       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;
+                       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);
                        }
-                       glLightfv((GLenum)(GL_LIGHT0+count), GL_SPECULAR, vec);
-                       glEnable((GLenum)(GL_LIGHT0+count));
-
-                       count++;
+                       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));
+
+               count++;
        }
        glPopMatrix();