diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-06-09 17:51:32 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-06-09 17:51:32 +0400 |
commit | e29c9bc4da59a8e8db933e1a53a181e396f4706b (patch) | |
tree | f77ce5061bd6d019a8b95d05b49eb96fdba52ee3 /source/gameengine | |
parent | 20eaa1466dbb530e583699e189c9f8b8597b7eb4 (diff) |
Fix for bug #18900: game engine lights in non-glsl mode did move
anymore, missing matrix update. Also move some code to KX_LightObject
to avoid duplication with player.
Diffstat (limited to 'source/gameengine')
-rw-r--r-- | source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp | 88 | ||||
-rw-r--r-- | source/gameengine/GamePlayer/common/GPC_RenderTools.cpp | 88 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_Light.cpp | 97 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_Light.h | 5 | ||||
-rw-r--r-- | source/gameengine/Rasterizer/RAS_LightObject.h | 4 |
5 files changed, 111 insertions, 171 deletions
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp index 17d1bf65ca4..ffff7185fe4 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp @@ -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) diff --git a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp index 02f23a8431b..96e50e651c0 100644 --- a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp +++ b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp @@ -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) diff --git a/source/gameengine/Ketsji/KX_Light.cpp b/source/gameengine/Ketsji/KX_Light.cpp index fe575384a35..274d8f26d78 100644 --- a/source/gameengine/Ketsji/KX_Light.cpp +++ b/source/gameengine/Ketsji/KX_Light.cpp @@ -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) diff --git a/source/gameengine/Ketsji/KX_Light.h b/source/gameengine/Ketsji/KX_Light.h index 35f25515e3b..358c705080a 100644 --- a/source/gameengine/Ketsji/KX_Light.h +++ b/source/gameengine/Ketsji/KX_Light.h @@ -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(); diff --git a/source/gameengine/Rasterizer/RAS_LightObject.h b/source/gameengine/Rasterizer/RAS_LightObject.h index 6b63a891981..b45a35e4266 100644 --- a/source/gameengine/Rasterizer/RAS_LightObject.h +++ b/source/gameengine/Rasterizer/RAS_LightObject.h @@ -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; |