Lighting updates:
authorKester Maddock <Christopher.Maddock.1@uni.massey.ac.nz>
Mon, 7 Jun 2004 11:01:31 +0000 (11:01 +0000)
committerKester Maddock <Christopher.Maddock.1@uni.massey.ac.nz>
Mon, 7 Jun 2004 11:01:31 +0000 (11:01 +0000)
Added specular after texture.
Added Light properties: Negative, No Diffuse, No Specular, Quad, Quad2

12 files changed:
source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
source/gameengine/Converter/BL_BlenderDataConversion.cpp
source/gameengine/GamePlayer/common/GPC_RenderTools.cpp
source/gameengine/GamePlayer/common/GPC_RenderTools.h
source/gameengine/GamePlayer/ghost/GPG_Application.cpp
source/gameengine/Ketsji/KX_Light.cpp
source/gameengine/PyDoc/KX_Light.py
source/gameengine/Rasterizer/RAS_LightObject.h
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.cpp
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.h
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/mkglext.py

index 125f326..f2315fe 100644 (file)
@@ -49,6 +49,7 @@
 #include "RAS_IRasterizer.h"
 #include "RAS_LightObject.h"
 #include "RAS_ICanvas.h"
+#include "RAS_GLExtensionManager.h"
 
 
 // next two includes/dependencies come from the shadow feature
@@ -297,6 +298,9 @@ void KX_BlenderRenderTools::EnableOpenGLLights()
        glEnableClientState(GL_NORMAL_ARRAY);
 #endif //SLOWPAINT
        glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, false);
+       if (bgl::QueryExtension(bgl::_GL_EXT_separate_specular_color) || bgl::QueryVersion(1, 2))
+               glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
+
 }
        
 
@@ -352,22 +356,18 @@ int       KX_BlenderRenderTools::applyLights(int objectlayer)
        //std::vector<struct    RAS_LightObject*> m_lights;
        std::vector<struct      RAS_LightObject*>::iterator lit = m_lights.begin();
        
+       glPushMatrix();
+       glLoadMatrixf(m_viewmat);
        for (lit = m_lights.begin(), count = 0; !(lit==m_lights.end()) && count < m_numgllights; ++lit)
        {
                RAS_LightObject* lightdata = (*lit);
                if (lightdata->m_layer & objectlayer)
                {
-
-                       glPushMatrix();
-                       glLoadMatrixf(m_viewmat);
-                       
-                       
                        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);
@@ -384,9 +384,9 @@ int KX_BlenderRenderTools::applyLights(int objectlayer)
                                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, la->att2/(la->dist*la->dist)); 
+                               // 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);
@@ -402,19 +402,33 @@ int       KX_BlenderRenderTools::applyLights(int objectlayer)
                                else glLightf((GLenum)(GL_LIGHT0+count), GL_SPOT_CUTOFF, 180.0);
                        }
                        
-                       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_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();
                }
        }
+       glPopMatrix();
 
        return count;
 
index 301c811..33a048b 100644 (file)
@@ -359,7 +359,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools*
                                }
                                        
                                
-                               Material* ma = give_current_material(blenderobj, 1);
+                               Material* ma = give_current_material(blenderobj, 1 /* mface->mat_nr */);
                                const char* matnameptr = (ma ? ma->id.name : "");
                                
        
@@ -372,8 +372,8 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools*
        
                                if (ma)
                                {
-                                       polymat->m_specular = MT_Vector3(ma->spec * ma->specr,ma->spec * ma->specg,ma->spec * ma->specb);
-                                       polymat->m_shininess = (float)ma->har;
+                                       polymat->m_specular = MT_Vector3(ma->specr, ma->specg, ma->specb)*ma->spec;
+                                       polymat->m_shininess = (float)ma->har/4.0; // 0 < ma->har <= 512
 
                                } else
                                {
@@ -809,6 +809,7 @@ static KX_LightObject *gamelight_from_blamp(Lamp *la, unsigned int layerflag, KX
        KX_LightObject *gamelight;
        
        lightobj.m_att1 = la->att1;
+       lightobj.m_att2 = (la->mode & LA_QUAD)?la->att2:0.0;
        lightobj.m_red = la->r;
        lightobj.m_green = la->g;
        lightobj.m_blue = la->b;
@@ -818,6 +819,16 @@ static KX_LightObject *gamelight_from_blamp(Lamp *la, unsigned int layerflag, KX
        lightobj.m_spotblend = la->spotblend;
        lightobj.m_spotsize = la->spotsize;
        
+       lightobj.m_nodiffuse = (la->mode & LA_NO_DIFF) != 0;
+       lightobj.m_nospecular = (la->mode & LA_NO_SPEC) != 0;
+       
+       if (la->mode & LA_NEG)
+       {
+               lightobj.m_red = -lightobj.m_red;
+               lightobj.m_green = -lightobj.m_green;
+               lightobj.m_blue = -lightobj.m_blue;
+       }
+               
        if (la->type==LA_SUN) {
                lightobj.m_type = RAS_LightObject::LIGHT_SUN;
        } else if (la->type==LA_SPOT) {
index 4e28bb4..743af35 100644 (file)
@@ -52,6 +52,7 @@
 #include "RAS_IRasterizer.h"
 #include "RAS_LightObject.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
@@ -153,6 +154,15 @@ int GPC_RenderTools::ProcessLighting(int layer)
        return result;
 }
 
+void GPC_RenderTools::EnableOpenGLLights()
+{
+       glEnable(GL_LIGHTING);
+       glColorMaterial(GL_FRONT_AND_BACK,GL_DIFFUSE);
+       glEnable(GL_COLOR_MATERIAL);
+       glEnableClientState(GL_NORMAL_ARRAY);
+       if (bgl::QueryExtension(bgl::_GL_EXT_separate_specular_color) || bgl::QueryVersion(1, 2))
+               glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
+}
 
 void GPC_RenderTools::RenderText2D(RAS_TEXT_RENDER_MODE mode, 
                                                                   const char* text, 
@@ -368,9 +378,9 @@ int GPC_RenderTools::applyLights(int objectlayer)
                                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, la->att2/(la->dist*la->dist)); 
+                               // 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);
@@ -386,11 +396,25 @@ int GPC_RenderTools::applyLights(int objectlayer)
                                else glLightf((GLenum)(GL_LIGHT0+count), GL_SPOT_CUTOFF, 180.0);
                        }
                        
-                       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_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));
                        
index 432bf39..9c76ccd 100644 (file)
@@ -67,13 +67,7 @@ public:
                glDisableClientState(GL_NORMAL_ARRAY);
        }
 
-       void EnableOpenGLLights()
-       {
-               glEnable(GL_LIGHTING);
-               glColorMaterial(GL_FRONT_AND_BACK,GL_DIFFUSE);
-               glEnable(GL_COLOR_MATERIAL);
-               glEnableClientState(GL_NORMAL_ARRAY);
-       }
+       void EnableOpenGLLights();
 
        int ProcessLighting(int layer);
 
index 4c3773e..868f9f1 100644 (file)
@@ -327,7 +327,7 @@ bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode)
                        return false;
                
                // SYS_WriteCommandLineInt(syshandle, "fixedtime", 0);
-               SYS_WriteCommandLineInt(syshandle, "vertexarrays",1);           
+               // SYS_WriteCommandLineInt(syshandle, "vertexarrays",1);                
                //bool properties       = (SYS_GetCommandLineInt(syshandle, "show_properties", 0) != 0);
                //bool profile = (SYS_GetCommandLineInt(syshandle, "show_profile", 0) != 0);
                bool frameRate = (SYS_GetCommandLineInt(syshandle, "show_framerate", 0) != 0);
index 9be4256..f5ec21e 100644 (file)
@@ -98,6 +98,9 @@ PyObject* KX_LightObject::_getattr(const STR_String& attr)
        if (attr == "lin_attenuation")
                return PyFloat_FromDouble(m_lightobj.m_att1);
        
+       if (attr == "quad_attenuation")
+               return PyFloat_FromDouble(m_lightobj.m_att2);
+       
        if (attr == "spotsize")
                return PyFloat_FromDouble(m_lightobj.m_spotsize);
        
@@ -165,6 +168,12 @@ int       KX_LightObject::_setattr(const STR_String& attr, PyObject *pyvalue)
                        return 0;
                }
                
+               if (attr == "quad_attenuation")
+               {
+                       m_lightobj.m_att2 = value;
+                       return 0;
+               }
+               
                if (attr == "spotsize")
                {
                        m_lightobj.m_spotsize = value;
index 39b10a8..ff0cf07 100644 (file)
@@ -23,13 +23,19 @@ class KX_Light(KX_GameObject):
        @ivar NORMAL: A point light source. See attribute 'type'
        
        @ivar type:            The type of light - must be SPOT, SUN or NORMAL
-       @ivar layer:           The layer mask that this light affects object on. (bitfield)
-       @ivar energy:          The brightness of this light. (float)
-       @ivar distance:        The maximum distance this light can illuminate. (float) (SPOT and NORMAL lights only)
+       @ivar layer:           The layer mask that this light affects object on.
+       @type layer:           bitfield
+       @ivar energy:          The brightness of this light. 
+       @type energy:          float
+       @ivar distance:        The maximum distance this light can illuminate. (SPOT and NORMAL lights only)
+       @type distance:        float
        @ivar colour:          The colour of this light. Black = [0.0, 0.0, 0.0], White = [1.0, 1.0, 1.0]
        @type colour:          list [r, g, b]
        @ivar color:           Synonym for colour.
-       @ivar lin_attenuation: The linear component of this lights attenuation. (SPOT and NORMAL lights only)
+       @ivar lin_attenuation: The linear component of this light's attenuation. (SPOT and NORMAL lights only)
+       @type lin_attenuation: float
+       @ivar quad_attenuation: The quadratic component of this light's attenuation (SPOT and NORMAL lights only)
+       @type quad_attenuation: float
        @ivar spotsize:        The cone angle of the spot light, in degrees. (float) (SPOT lights only)
                               0.0 <= spotsize <= 180.0. Spotsize = 360.0 is also accepted. 
        @ivar spotblend:       Specifies the intensity distribution of the spot light. (float) (SPOT lights only)
index 0c313df..2c22a58 100644 (file)
@@ -42,7 +42,7 @@ struct RAS_LightObject
                LIGHT_NORMAL
        };
        bool    m_modified;
-       int             m_layer;
+       int     m_layer;
        
        float   m_energy;
        float   m_distance;
@@ -52,12 +52,15 @@ struct RAS_LightObject
        float   m_blue;
 
        float   m_att1;
+       float   m_att2;
        float   m_spotsize;
        float   m_spotblend;
 
        LightType       m_type;
        MT_CmMatrix4x4* m_worldmatrix;
        
+       bool    m_nodiffuse;
+       bool    m_nospecular;
 };
 
 #endif //__RAS_LIGHTOBJECT_H
index 2c7112e..26727b1 100644 (file)
@@ -265,7 +265,10 @@ bool QueryVersion(int major, int minor)
        
        if (gl_major == 0)
        {
-               STR_String gl_version = STR_String((const char *) glGetString(GL_VERSION));
+               const char *gl_version_str = (const char *) glGetString(GL_VERSION);
+               if (!gl_version_str)
+                       return false;
+               STR_String gl_version = STR_String(gl_version_str);
                int i = gl_version.Find('.');
                gl_major = gl_version.Left(i).ToInt();
                gl_minor = gl_version.Mid(i+1, gl_version.FindOneOf(". ", i+1) - i - 1).ToInt();
@@ -308,6 +311,11 @@ to their source.  Cunning like a weasel.
 
  ******************************************************************************/
 
+#if defined(GL_ATI_pn_triangles)
+PFNGLPNTRIANGLESIATIPROC glPNTrianglesiATI;
+PFNGLPNTRIANGLESFATIPROC glPNTrianglesfATI;
+#endif
+
 
 
 } // namespace bgl
@@ -327,6 +335,28 @@ static void LinkExtensions()
        static bool doDebugMessages = m_debug;
        extensions = STR_String((const char *) glGetString(GL_EXTENSIONS)).Explode(' ');
 
+#if defined(GL_ATI_pn_triangles)
+       if (QueryExtension("GL_ATI_pn_triangles"))
+       {
+               glPNTrianglesiATI = reinterpret_cast<PFNGLPNTRIANGLESIATIPROC>(bglGetProcAddress((const GLubyte *) "glPNTrianglesiATI"));
+               glPNTrianglesfATI = reinterpret_cast<PFNGLPNTRIANGLESFATIPROC>(bglGetProcAddress((const GLubyte *) "glPNTrianglesfATI"));
+               if (glPNTrianglesiATI && glPNTrianglesfATI) {
+                       EnableExtension(_GL_ATI_pn_triangles);
+                       if (doDebugMessages)
+                               std::cout << "Enabled GL_ATI_pn_triangles" << std::endl;
+               } else {
+                       std::cout << "ERROR: GL_ATI_pn_triangles implementation is broken!" << std::endl;
+               }
+       }
+#endif
+
+        if (QueryExtension("GL_EXT_separate_specular_color"))
+        {
+                EnableExtension(_GL_EXT_separate_specular_color);
+                if (doDebugMessages)
+                        std::cout << "Detected GL_EXT_separate_specular_color" << std::endl;
+        }
+
        doDebugMessages = false;
 }
 
index 50a67ee..e43912e 100644 (file)
@@ -38,6 +38,7 @@
 #include <GL/gl.h>
 #endif
 
+#include "EXT_separate_specular_color.h"
 
 namespace bgl
 {
@@ -363,8 +364,12 @@ namespace bgl
         */
        void InitExtensions(int debug);
 
-
+#if defined(GL_ATI_pn_triangles)
+extern PFNGLPNTRIANGLESIATIPROC glPNTrianglesiATI;
+extern PFNGLPNTRIANGLESFATIPROC glPNTrianglesfATI;
+#endif
 
 } /* namespace bgl */
 
+
 #endif /* __RAS_GLEXTENSIONMANAGER_H__ */
index 3e93a7a..4cf9300 100644 (file)
@@ -48,6 +48,8 @@
 #include "MT_CmMatrix4x4.h"
 #include "RAS_IRenderTools.h" // rendering text
 
+#include "RAS_GLExtensionManager.h"
+
 
 RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas)
        :RAS_IRasterizer(canvas),
@@ -126,6 +128,7 @@ static void Myinit_gl_stuff(void)
        }
        
        glPolygonStipple(patc);
+               
 }
 
 
@@ -264,6 +267,8 @@ void RAS_OpenGLRasterizer::Exit()
        glBlendFunc(GL_ONE, GL_ZERO);
 
        glDisable(GL_LIGHTING);
+       if (bgl::QueryExtension(bgl::_GL_EXT_separate_specular_color) || bgl::QueryVersion(1, 2))
+               glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
        
        EndFrame();
 }
index 912b478..8e64ecd 100644 (file)
@@ -468,7 +468,7 @@ for i in glext_h:
                        fns = []
                        fnlist = []
        if (ext != ""):
-               line = re.search('.*(gl.*) \(.*\);', i)
+               line = re.search('.* (gl.*) \(.*\);', i)
                if (line):
                        fns += [line.group(1)]
                line = re.search('.*PFN(.*)PROC.*', i)
@@ -501,7 +501,7 @@ for i in glext_h:
                        fns = []
                        fnlist = []
        if (ext != ""):
-               line = re.search('.*(gl.*) \(.*\);', i)
+               line = re.search('.* (gl.*) \(.*\);', i)
                if (line):
                        fns += [line.group(1)]
                line = re.search('.*PFN(.*)PROC.*', i)
@@ -534,7 +534,7 @@ for i in glext_h:
                        fns = []
                        fnlist = []
        if (ext != ""):
-               line = re.search('.*(gl.*) \(.*\);', i)
+               line = re.search('.* (gl.*) \(.*\);', i)
                if (line):
                        fns += [line.group(1)]
                line = re.search('.*PFN(.*)PROC.*', i)
@@ -578,7 +578,7 @@ for i in glext_h:
                if (line):
                        defines += [(line.group(1), line.group(2))]
                
-               line = re.search('(.*)(gl.*)(\(.*\));', i) # GLAPI void APIENTRY glMultiTexCoord2f (GLenum, GLfloat, GLfloat);
+               line = re.search('(.* )(gl.*)(\(.*\));', i) # GLAPI void APIENTRY glMultiTexCoord2f (GLenum, GLfloat, GLfloat);
                if (line):
                        fns += [(line.group(1), line.group(2), line.group(3))]