Undo revision 23130 which was a merge with 2.5, a messy one because I did something...
[blender.git] / source / gameengine / BlenderRoutines / KX_BlenderRenderTools.cpp
index 463f068..8ed36e8 100644 (file)
@@ -1,14 +1,11 @@
 /**
  * $Id$
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ * ***** BEGIN GPL LICENSE BLOCK *****
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License.  See http://www.blender.org/BL/ for information
- * about this.
+ * of the License, or (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  *
  * Contributor(s): none yet.
  *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * ***** END GPL LICENSE BLOCK *****
  */
 
-#include "KX_BlenderRenderTools.h"
-
-#ifdef WIN32
-// OpenGL gl.h needs 'windows.h' on windows platforms 
-#include <windows.h>
-#endif //WIN32
-#ifdef __APPLE__
-#define GL_GLEXT_LEGACY 1
-#include <OpenGL/gl.h>
-#else
-#include <GL/gl.h>
-#endif
+#include "GL/glew.h"
 
 #include "RAS_IRenderTools.h"
 #include "RAS_IRasterizer.h"
 #include "RAS_ICanvas.h"
 #include "RAS_GLExtensionManager.h"
 
-// next two includes/dependencies come from the shadow feature
-// it needs the gameobject and the sumo physics scene for a raycast
 #include "KX_GameObject.h"
-
-#include "KX_BlenderPolyMaterial.h"
 #include "KX_PolygonMaterial.h"
 #include "KX_BlenderMaterial.h"
+#include "KX_RayCast.h"
+#include "KX_IPhysicsController.h"
+#include "KX_Light.h"
 
-#include "Value.h"
+#include "PHY_IPhysicsEnvironment.h"
 
-#include "KX_BlenderGL.h" // for text printing
 #include "STR_String.h"
-#include "RAS_BucketManager.h" // for polymaterial (needed for textprinting)
 
-#include "KX_RayCast.h"
-#include "KX_IPhysicsController.h"
-#include "PHY_IPhysicsEnvironment.h"
-#include "KX_Scene.h"
+#include "GPU_draw.h"
+
+#include "KX_BlenderGL.h" // for text printing
+#include "KX_BlenderRenderTools.h"
+
+unsigned int KX_BlenderRenderTools::m_numgllights;
 
 KX_BlenderRenderTools::KX_BlenderRenderTools()
 {
@@ -74,61 +59,102 @@ KX_BlenderRenderTools::KX_BlenderRenderTools()
                m_numgllights = 8;
 }
 
-/**
-ProcessLighting performs lighting on objects. the layer is a bitfield that contains layer information.
-There are 20 'official' layers in blender.
-A light is applied on an object only when they are in the same layer.
-OpenGL has a maximum of 8 lights (simultaneous), so 20 * 8 lights are possible in a scene.
-*/
+KX_BlenderRenderTools::~KX_BlenderRenderTools()
+{
+}
+
+void KX_BlenderRenderTools::BeginFrame(RAS_IRasterizer* rasty)
+{
+       m_clientobject = NULL;
+       m_lastlightlayer = -1;
+       m_lastauxinfo = NULL;
+       m_lastlighting = true; /* force disable in DisableOpenGLLights() */
+       DisableOpenGLLights();
+}
 
-int    KX_BlenderRenderTools::ProcessLighting(int layer) 
+void KX_BlenderRenderTools::EndFrame(RAS_IRasterizer* rasty)
 {
-       
-       int result = false;
+}
 
-       if (layer < 0)
-       {
-               DisableOpenGLLights();
-               result = false;
-       } else
-       {
-               if (m_clientobject)
-               {
-                       if (applyLights(layer))
-                       {
-                               EnableOpenGLLights();
-                               result = true;
-                       } else
-                       {
-                               DisableOpenGLLights();
-                               result = false;
-                       }                       
-               }
+/* ProcessLighting performs lighting on objects. the layer is a bitfield that
+ * contains layer information. There are 20 'official' layers in blender. A
+ * light is applied on an object only when they are in the same layer. OpenGL
+ * has a maximum of 8 lights (simultaneous), so 20 * 8 lights are possible in
+ * a scene. */
+
+void KX_BlenderRenderTools::ProcessLighting(RAS_IRasterizer *rasty, bool uselights, const MT_Transform& viewmat)
+{
+       bool enable = false;
+       int layer= -1;
+
+       /* find the layer */
+       if(uselights) {
+               if(m_clientobject)
+                       layer = static_cast<KX_GameObject*>(m_clientobject)->GetLayer();
        }
-       return result;
-       
-       
+
+       /* avoid state switching */
+       if(m_lastlightlayer == layer && m_lastauxinfo == m_auxilaryClientInfo)
+               return;
+
+       m_lastlightlayer = layer;
+       m_lastauxinfo = m_auxilaryClientInfo;
+
+       /* enable/disable lights as needed */
+       if(layer >= 0)
+               enable = applyLights(layer, viewmat);
+
+       if(enable)
+               EnableOpenGLLights(rasty);
+       else
+               DisableOpenGLLights();
 }
 
+void KX_BlenderRenderTools::EnableOpenGLLights(RAS_IRasterizer *rasty)
+{
+       if(m_lastlighting == true)
+               return;
 
-void KX_BlenderRenderTools::BeginFrame(RAS_IRasterizer* rasty)
+       glEnable(GL_LIGHTING);
+       glEnable(GL_COLOR_MATERIAL);
+
+       glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
+       glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
+       glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, (rasty->GetCameraOrtho())? GL_FALSE: GL_TRUE);
+       if (GLEW_EXT_separate_specular_color || GLEW_VERSION_1_2)
+               glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
+       
+       m_lastlighting = true;
+}
+
+void KX_BlenderRenderTools::DisableOpenGLLights()
 {
-       m_clientobject = NULL;
-       m_lastblenderobject = NULL;
-       m_lastblenderlights = false;
-       m_lastlayer = -1;
+       if(m_lastlighting == false)
+               return;
+
+       glDisable(GL_LIGHTING);
+       glDisable(GL_COLOR_MATERIAL);
+
        m_lastlighting = false;
-       m_modified = true;
-       DisableOpenGLLights();
+}
 
 
+void KX_BlenderRenderTools::SetClientObject(RAS_IRasterizer *rasty, void* obj)
+{
+       if (m_clientobject != obj)
+       {
+               bool ccw = (obj == NULL || !((KX_GameObject*)obj)->IsNegativeScaling());
+               rasty->SetFrontFace(ccw);
+
+               m_clientobject = obj;
+       }
 }
 
-bool KX_BlenderRenderTools::RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal, void * const data)
+bool KX_BlenderRenderTools::RayHit(KX_ClientObjectInfo* client, KX_RayCast* result, void * const data)
 {
        double* const oglmatrix = (double* const) data;
-       MT_Point3 resultpoint(hit_point);
-       MT_Vector3 resultnormal(hit_normal);
+       MT_Point3 resultpoint(result->m_hitPoint);
+       MT_Vector3 resultnormal(result->m_hitNormal);
        MT_Vector3 left(oglmatrix[0],oglmatrix[1],oglmatrix[2]);
        MT_Vector3 dir = -(left.cross(resultnormal)).safe_normalized();
        left = (dir.cross(resultnormal)).safe_normalized();
@@ -175,7 +201,7 @@ void KX_BlenderRenderTools::applyTransform(RAS_IRasterizer* rasty,double* oglmat
                MT_Vector3 dir = (campos - objpos).safe_normalized();
                MT_Vector3 up(0,0,1.0);
 
-               KX_GameObject* gameobj = (KX_GameObject*) this->m_clientobject;
+               KX_GameObject* gameobj = (KX_GameObject*)m_clientobject;
                // get scaling of halo object
                MT_Vector3  size = gameobj->GetSGNode()->GetLocalScale();
                
@@ -211,7 +237,7 @@ void KX_BlenderRenderTools::applyTransform(RAS_IRasterizer* rasty,double* oglmat
                {
                        // shadow must be cast to the ground, physics system needed here!
                        MT_Point3 frompoint(oglmatrix[12],oglmatrix[13],oglmatrix[14]);
-                       KX_GameObject *gameobj = (KX_GameObject*) this->m_clientobject;
+                       KX_GameObject *gameobj = (KX_GameObject*)m_clientobject;
                        MT_Vector3 direction = MT_Vector3(0,0,-1);
 
                        direction.normalize();
@@ -229,13 +255,18 @@ void KX_BlenderRenderTools::applyTransform(RAS_IRasterizer* rasty,double* oglmat
                        if (parent)
                                parent->Release();
                                
-                       MT_Point3 resultpoint;
-                       MT_Vector3 resultnormal;
-                       if (!KX_RayCast::RayTest(physics_controller, physics_environment, frompoint, topoint, resultpoint, resultnormal, KX_RayCast::Callback<KX_BlenderRenderTools>(this, oglmatrix)))
+                       KX_RayCast::Callback<KX_BlenderRenderTools> callback(this, physics_controller, oglmatrix);
+                       if (!KX_RayCast::RayTest(physics_environment, frompoint, topoint, callback))
                        {
                                // couldn't find something to cast the shadow on...
                                glMultMatrixd(oglmatrix);
                        }
+                       else
+                       { // we found the "ground", but the cast matrix doesn't take
+                         // scaling in consideration, so we must apply the object scale
+                               MT_Vector3  size = gameobj->GetSGNode()->GetLocalScale();
+                               glScalef(size[0], size[1], size[2]);
+                       }
                } else
                {
 
@@ -246,14 +277,30 @@ void KX_BlenderRenderTools::applyTransform(RAS_IRasterizer* rasty,double* oglmat
 }
 
 
-/**
-Render Text renders text into a (series of) polygon, using a texture font,
-Each character consists of one polygon (one quad or two triangles)
-*/
-void   KX_BlenderRenderTools::RenderText(int mode,RAS_IPolyMaterial* polymat,float v1[3],float v2[3],float v3[3],float v4[3])
+void KX_BlenderRenderTools::RenderText2D(RAS_TEXT_RENDER_MODE mode,
+                                                                                const char* text,
+                                                                                int xco,
+                                                                                int yco,                                                                        
+                                                                                int width,
+                                                                                int height)
 {
-               
-       STR_String mytext = ((CValue*)m_clientobject)->GetPropertyText("Text");
+       STR_String tmpstr(text);
+
+       if(mode == RAS_IRenderTools::RAS_TEXT_PADDED)
+               BL_print_gamedebug_line_padded(tmpstr.Ptr(), xco, yco, width, height);
+       else
+               BL_print_gamedebug_line(tmpstr.Ptr(), xco, yco, width, height);
+}
+
+/* Render Text renders text into a (series of) polygon, using a texture font,
+ * Each character consists of one polygon (one quad or two triangles) */
+
+void KX_BlenderRenderTools::RenderText(
+       int mode,
+       RAS_IPolyMaterial* polymat,
+       float v1[3], float v2[3], float v3[3], float v4[3], int glattrib)
+{
+       const STR_String& mytext = ((CValue*)m_clientobject)->GetPropertyText("Text");
        
        const unsigned int flag = polymat->GetFlag();
        struct MTFace* tface = 0;
@@ -269,67 +316,9 @@ void       KX_BlenderRenderTools::RenderText(int mode,RAS_IPolyMaterial* polymat,float
                col = blenderpoly->GetMCol();
        }
        
-       BL_RenderText( mode,mytext,mytext.Length(),tface,col,v1,v2,v3,v4);
-       
-}
-
-
-
-KX_BlenderRenderTools::~KX_BlenderRenderTools()
-{
-};
-       
-       
-void   KX_BlenderRenderTools::EndFrame(RAS_IRasterizer* rasty)
-{
-}
-       
-
-       
-void KX_BlenderRenderTools::DisableOpenGLLights()
-{
-       glDisable(GL_LIGHTING);
-       glDisable(GL_COLOR_MATERIAL);
+       GPU_render_text(tface, mode, mytext, mytext.Length(), col, v1, v2, v3, v4, glattrib);
 }
 
-       
-void KX_BlenderRenderTools::EnableOpenGLLights()
-{
-       glEnable(GL_LIGHTING);
-       
-       glEnable(GL_COLOR_MATERIAL);
-       glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
-       glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, true);
-       if (bgl::QueryExtension(bgl::_GL_EXT_separate_specular_color) || bgl::QueryVersion(1, 2))
-               glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
-
-}
-       
-
-/**
- * Rendering text using 2D bitmap functionality.  
- */
-void KX_BlenderRenderTools::RenderText2D(RAS_TEXT_RENDER_MODE mode,
-                                                                                const char* text,
-                                                                                int xco,
-                                                                                int yco,                                                                        
-                                                                                int width,
-                                                                                int height)
-{
-       switch (mode) {
-       case RAS_IRenderTools::RAS_TEXT_PADDED: {
-               STR_String tmpstr(text);
-               BL_print_gamedebug_line_padded(tmpstr.Ptr(),xco,yco,width,height);
-               break;
-       }
-       default: {
-               STR_String tmpstr(text);
-               BL_print_gamedebug_line(tmpstr.Ptr(),xco,yco,width,height);
-       }
-       }
-}
-
-       
 
 void KX_BlenderRenderTools::PushMatrix()
 {
@@ -342,114 +331,32 @@ void KX_BlenderRenderTools::PopMatrix()
 }
 
 
-
-int    KX_BlenderRenderTools::applyLights(int objectlayer)
+int KX_BlenderRenderTools::applyLights(int objectlayer, const MT_Transform& viewmat)
 {
-// taken from blender source, incompatibility between Blender Object / GameObject      
-       
+       // taken from blender source, incompatibility between Blender Object / GameObject       
+       KX_Scene* kxscene = (KX_Scene*)m_auxilaryClientInfo;
+       float glviewmat[16];
        unsigned int count;
-       float vec[4];
-               
-       vec[3]= 1.0;
-       
+       std::vector<struct      RAS_LightObject*>::iterator lit = m_lights.begin();
+
        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);
        
        glPushMatrix();
-       glLoadMatrixf(m_viewmat);
+       glLoadMatrixf(glviewmat);
        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;
-
-                       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;
 
+               if(kxlight->ApplyLight(kxscene, objectlayer, count))
                        count++;
-                       
-               }
        }
        glPopMatrix();
 
        return count;
-
-}
-
-
-
-RAS_IPolyMaterial* KX_BlenderRenderTools::CreateBlenderPolyMaterial(
-               const STR_String &texname,
-               bool ba,const STR_String& matname,int tile,int tilexrep,int tileyrep,int mode,bool transparant,bool zsort, int lightlayer
-               ,bool bIsTriangle,void* clientobject,void* tface)
-{
-       assert(!"Deprecated");
-/*     return new KX_BlenderPolyMaterial(
-
-               texname,
-               ba,matname,tile,tilexrep,tileyrep,mode,transparant,zsort, lightlayer
-               ,bIsTriangle,clientobject,(struct MTFace*)tface);*/
-       return NULL;
 }
 
 void KX_BlenderRenderTools::MotionBlur(RAS_IRasterizer* rasterizer)
@@ -475,4 +382,12 @@ void KX_BlenderRenderTools::MotionBlur(RAS_IRasterizer* rasterizer)
        }
 }
 
-unsigned int KX_BlenderRenderTools::m_numgllights;
+void KX_BlenderRenderTools::Update2DFilter(vector<STR_String>& propNames, void* gameObj, RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text)
+{
+       m_filtermanager.EnableFilter(propNames, gameObj, filtermode, pass, text);
+}
+
+void KX_BlenderRenderTools::Render2DFilters(RAS_ICanvas* canvas)
+{
+       m_filtermanager.RenderFilters(canvas);
+}
\ No newline at end of file