diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2008-07-15 03:26:38 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2008-07-15 03:26:38 +0400 |
commit | 95fbf8342319baa202269d6f2674e482888761c7 (patch) | |
tree | 70fbb4fa91b2330bc33cbb57a6ef2a9fbfa67c08 /source/gameengine/Ketsji | |
parent | a1fea54c185527a13aad3c3e5da81786fae3e13d (diff) |
Apricot: GLSL
=============
* Added options to disable lights, shaders, shadows, ramps,
nodes and textures other than col/alpha for GLSL, in the
Game menu.
* These have python access too to switch them in game, but
it doesn't work correct yet with display lists enabled.
* Fix issue with light lagging behind, debug stats drawing in
wrong color, and a number of other small fixes.
Diffstat (limited to 'source/gameengine/Ketsji')
-rw-r--r-- | source/gameengine/Ketsji/BL_BlenderShader.cpp | 68 | ||||
-rw-r--r-- | source/gameengine/Ketsji/BL_BlenderShader.h | 10 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_BlenderMaterial.cpp | 51 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_BlenderMaterial.h | 7 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_Light.cpp | 27 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_Light.h | 10 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_Scene.cpp | 2 |
7 files changed, 137 insertions, 38 deletions
diff --git a/source/gameengine/Ketsji/BL_BlenderShader.cpp b/source/gameengine/Ketsji/BL_BlenderShader.cpp index fd9c9778305..e4072686fcc 100644 --- a/source/gameengine/Ketsji/BL_BlenderShader.cpp +++ b/source/gameengine/Ketsji/BL_BlenderShader.cpp @@ -1,6 +1,10 @@ #include "DNA_customdata_types.h" #include "DNA_material_types.h" +#include "DNA_scene_types.h" + +#include "BKE_global.h" +#include "BKE_main.h" #include "BL_BlenderShader.h" #include "BL_Material.h" @@ -10,35 +14,59 @@ #include "RAS_MeshObject.h" #include "RAS_IRasterizer.h" + + /* this is evil, but we need the scene to create materials with + * lights from the correct scene .. */ +static struct Scene *GetSceneForName(const STR_String& scenename) +{ + Scene *sce; + + for (sce= (Scene*)G.main->scene.first; sce; sce= (Scene*)sce->id.next) + if (scenename == (sce->id.name+2)) + return sce; + + return (Scene*)G.main->scene.first; +} const bool BL_BlenderShader::Ok()const { - return (mGPUMat != 0); + return (mMat && mMat->gpumaterial); } -BL_BlenderShader::BL_BlenderShader(struct Material *ma, int lightlayer) +BL_BlenderShader::BL_BlenderShader(KX_Scene *scene, struct Material *ma, int lightlayer) : - mGPUMat(0), + mMat(ma), + mGPUMat(NULL), mBound(false), mLightLayer(lightlayer) { - if(ma) { - GPU_material_from_blender(ma); - mGPUMat = ma->gpumaterial; - } + mScene = GetSceneForName(scene->GetName()); + VerifyShader(); + mModified = false; } BL_BlenderShader::~BL_BlenderShader() { - if(mGPUMat) { - GPU_material_unbind(mGPUMat); - mGPUMat = 0; + if(mMat && mMat->gpumaterial) + GPU_material_unbind(mMat->gpumaterial); +} + +bool BL_BlenderShader::VerifyShader() +{ + if(mMat && !mMat->gpumaterial) + GPU_material_from_blender(mScene, mMat); + + if(mMat && mMat->gpumaterial != mGPUMat) { + mGPUMat = mMat->gpumaterial; + mModified = true; } + + return (mMat && mGPUMat); } void BL_BlenderShader::SetProg(bool enable) { - if(mGPUMat) { + if(VerifyShader()) { if(enable) { GPU_material_bind(mGPUMat, mLightLayer); mBound = true; @@ -55,7 +83,7 @@ int BL_BlenderShader::GetAttribNum() GPUVertexAttribs attribs; int i, enabled = 0; - if(!mGPUMat) + if(!VerifyShader()) return enabled; GPU_material_vertex_attributes(mGPUMat, &attribs); @@ -77,7 +105,7 @@ void BL_BlenderShader::SetAttribs(RAS_IRasterizer* ras, const BL_Material *mat) ras->SetAttribNum(0); - if(!mGPUMat) + if(!VerifyShader()) return; if(ras->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED) { @@ -123,9 +151,21 @@ void BL_BlenderShader::Update( const KX_MeshSlot & ms, RAS_IRasterizer* rasty ) { float obmat[4][4], viewmat[4][4], viewinvmat[4][4]; + VerifyShader(); + + if(mModified) { +#if 0 + /* TODO: we need to free display lists, this isn't sufficient, it + * doesn't set all meshes as modified, only the first one .. */ + if(ms.m_mesh) + ms.m_mesh->SetMeshModified(true); +#endif + mModified = false; + } + if(!mGPUMat || !mBound) return; - + MT_Matrix4x4 model; model.setValue(ms.m_OpenGLMatrix); MT_Matrix4x4 view; diff --git a/source/gameengine/Ketsji/BL_BlenderShader.h b/source/gameengine/Ketsji/BL_BlenderShader.h index fd52af24407..0b2ca3bd3ed 100644 --- a/source/gameengine/Ketsji/BL_BlenderShader.h +++ b/source/gameengine/Ketsji/BL_BlenderShader.h @@ -12,7 +12,10 @@ #include "RAS_IPolygonMaterial.h" +#include "KX_Scene.h" + struct Material; +struct Scene; class BL_Material; #define BL_MAX_ATTRIB 16 @@ -24,12 +27,17 @@ class BL_Material; class BL_BlenderShader { private: + struct Scene *mScene; + struct Material *mMat; GPUMaterial *mGPUMat; bool mBound; + bool mModified; int mLightLayer; + bool VerifyShader(); + public: - BL_BlenderShader(struct Material *ma, int lightlayer); + BL_BlenderShader(KX_Scene *scene, struct Material *ma, int lightlayer); virtual ~BL_BlenderShader(); const bool Ok()const; diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp index 0f445a9f32e..7a5be3ee707 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp @@ -38,6 +38,7 @@ extern "C" { // ------------------------------------ #define spit(x) std::cout << x << std::endl; +BL_Shader *KX_BlenderMaterial::mLastShader = NULL; BL_BlenderShader *KX_BlenderMaterial::mLastBlenderShader = NULL; //static PyObject *gTextureDict = 0; @@ -158,12 +159,29 @@ void KX_BlenderMaterial::OnConstruction() mConstructed = true; } +void KX_BlenderMaterial::EndFrame() +{ + if(mLastBlenderShader) { + mLastBlenderShader->SetProg(false); + mLastBlenderShader = NULL; + } + + if(mLastShader) { + mLastShader->SetProg(false); + mLastShader = NULL; + } +} + void KX_BlenderMaterial::OnExit() { if( mShader ) { - //note, the shader here is allocated, per unique material - //and this function is called per face - mShader->SetProg(false); + //note, the shader here is allocated, per unique material + //and this function is called per face + if(mShader == mLastShader) { + mShader->SetProg(false); + mLastShader = NULL; + } + delete mShader; mShader = 0; } @@ -197,13 +215,17 @@ void KX_BlenderMaterial::setShaderData( bool enable, RAS_IRasterizer *ras) int i; if( !enable || !mShader->Ok() ) { // frame cleanup. - mShader->SetProg(false); + if(mShader == mLastShader) { + mShader->SetProg(false); + mLastShader = NULL; + } BL_Texture::DisableAllTextures(); return; } BL_Texture::DisableAllTextures(); mShader->SetProg(true); + mLastShader = mShader; BL_Texture::ActivateFirst(); @@ -234,6 +256,7 @@ void KX_BlenderMaterial::setBlenderShaderData( bool enable, RAS_IRasterizer *ras mLastBlenderShader->SetProg(false); mLastBlenderShader= NULL; } + BL_Texture::DisableAllTextures(); return; } @@ -251,9 +274,6 @@ void KX_BlenderMaterial::setBlenderShaderData( bool enable, RAS_IRasterizer *ras void KX_BlenderMaterial::setTexData( bool enable, RAS_IRasterizer *ras) { - if(GLEW_ARB_shader_objects && mShader) - mShader->SetProg(false); - BL_Texture::DisableAllTextures(); if( !enable ) return; @@ -356,6 +376,11 @@ KX_BlenderMaterial::ActivateBlenderShaders( { KX_BlenderMaterial *tmp = const_cast<KX_BlenderMaterial*>(this); + if(mLastShader) { + mLastShader->SetProg(false); + mLastShader= NULL; + } + // reset... if(tmp->mMaterial->IsShared()) cachingInfo =0; @@ -402,6 +427,11 @@ KX_BlenderMaterial::ActivateMat( { KX_BlenderMaterial *tmp = const_cast<KX_BlenderMaterial*>(this); + if(mLastShader) { + mLastShader->SetProg(false); + mLastShader= NULL; + } + if(mLastBlenderShader) { mLastBlenderShader->SetProg(false); mLastBlenderShader= NULL; @@ -451,7 +481,10 @@ KX_BlenderMaterial::Activate( return dopass; } else { - mShader->SetProg(false); + if(mShader == mLastShader) { + mShader->SetProg(false); + mLastShader = NULL; + } mPass = 0; dopass = false; return dopass; @@ -831,7 +864,7 @@ KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getShader , "getShader()") void KX_BlenderMaterial::SetBlenderGLSLShader(void) { if(!mBlenderShader) - mBlenderShader = new BL_BlenderShader(mMaterial->material, m_lightlayer); + mBlenderShader = new BL_BlenderShader(mScene, mMaterial->material, m_lightlayer); if(!mBlenderShader->Ok()) { delete mBlenderShader; diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h index bf6d2095e7c..ef9bf9f18ba 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.h +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h @@ -90,11 +90,12 @@ public: // -------------------------------- // pre calculate to avoid pops/lag at startup virtual void OnConstruction( ); + + static void EndFrame(); private: BL_Material* mMaterial; BL_Shader* mShader; BL_BlenderShader* mBlenderShader; - static BL_BlenderShader *mLastBlenderShader; KX_Scene* mScene; BL_Texture mTextures[MAXTEX]; // texture array bool mUserDefBlend; @@ -123,6 +124,10 @@ private: // cleanup stuff void OnExit(); + // shader chacing + static BL_BlenderShader *mLastBlenderShader; + static BL_Shader *mLastShader; + mutable int mPass; }; diff --git a/source/gameengine/Ketsji/KX_Light.cpp b/source/gameengine/Ketsji/KX_Light.cpp index d6e5e6323d4..cb4c4dcf624 100644 --- a/source/gameengine/Ketsji/KX_Light.cpp +++ b/source/gameengine/Ketsji/KX_Light.cpp @@ -42,12 +42,13 @@ #include "KX_PyMath.h" +#include "DNA_object_types.h" #include "GPU_material.h" KX_LightObject::KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks, class RAS_IRenderTools* rendertools, const RAS_LightObject& lightobj, - GPULamp *gpulamp, + Object *gpulampob, PyTypeObject* T ) : @@ -57,7 +58,10 @@ KX_LightObject::KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks, m_lightobj = lightobj; m_lightobj.m_worldmatrix = GetOpenGLMatrixPtr(); m_rendertools->AddLight(&m_lightobj); - m_gpulamp = gpulamp; + m_gpulampob = gpulampob; + + if(m_gpulampob) + GPU_lamp_from_blender(m_gpulampob, (struct Lamp*)m_gpulampob->data); }; @@ -82,9 +86,14 @@ CValue* KX_LightObject::GetReplica() return replica; } +bool KX_LightObject::VerifyShader() +{ + return (m_gpulampob && m_gpulampob->gpulamp); +} + void KX_LightObject::Update() { - if(m_gpulamp) { + if(VerifyShader()) { float obmat[4][4]; double *dobmat = GetOpenGLMatrixPtr()->getPointer(); @@ -92,19 +101,19 @@ void KX_LightObject::Update() for(int j=0; j<4; j++, dobmat++) obmat[i][j] = (float)*dobmat; - GPU_lamp_update(m_gpulamp, obmat); + GPU_lamp_update(m_gpulampob->gpulamp, obmat); } } bool KX_LightObject::HasShadowBuffer() { - return (m_gpulamp && GPU_lamp_has_shadow_buffer(m_gpulamp)); + return (VerifyShader() && GPU_lamp_has_shadow_buffer(m_gpulampob->gpulamp)); } int KX_LightObject::GetShadowLayer() { - if(m_gpulamp) - return GPU_lamp_shadow_layer(m_gpulamp); + if(VerifyShader()) + return GPU_lamp_shadow_layer(m_gpulampob->gpulamp); else return 0; } @@ -115,7 +124,7 @@ void KX_LightObject::BindShadowBuffer(RAS_IRasterizer *ras, KX_Camera *cam, MT_T int winsize; /* bind framebuffer */ - GPU_lamp_shadow_buffer_bind(m_gpulamp, viewmat, &winsize, winmat); + GPU_lamp_shadow_buffer_bind(m_gpulampob->gpulamp, viewmat, &winsize, winmat); /* setup camera transformation */ MT_Matrix4x4 modelviewmat((float*)viewmat); @@ -139,7 +148,7 @@ void KX_LightObject::BindShadowBuffer(RAS_IRasterizer *ras, KX_Camera *cam, MT_T void KX_LightObject::UnbindShadowBuffer(RAS_IRasterizer *ras) { - GPU_lamp_shadow_buffer_unbind(m_gpulamp); + GPU_lamp_shadow_buffer_unbind(m_gpulampob->gpulamp); } PyObject* KX_LightObject::_getattr(const STR_String& attr) diff --git a/source/gameengine/Ketsji/KX_Light.h b/source/gameengine/Ketsji/KX_Light.h index 62eb26c61a8..1adc6793aec 100644 --- a/source/gameengine/Ketsji/KX_Light.h +++ b/source/gameengine/Ketsji/KX_Light.h @@ -32,7 +32,7 @@ #include "RAS_LightObject.h" #include "KX_GameObject.h" -struct GPULamp; +struct Object; class KX_Camera; class RAS_IRasterizer; class RAS_IRenderTools; @@ -44,11 +44,13 @@ class KX_LightObject : public KX_GameObject protected: RAS_LightObject m_lightobj; class RAS_IRenderTools* m_rendertools; //needed for registering and replication of lightobj - struct GPULamp *m_gpulamp; - static char doc[]; + struct Object *m_gpulampob; + static char doc[]; + + bool VerifyShader(); public: - KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks,class RAS_IRenderTools* rendertools,const struct RAS_LightObject& lightobj, struct GPULamp *gpulamp, PyTypeObject *T = &Type); + KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks,class RAS_IRenderTools* rendertools,const struct RAS_LightObject& lightobj, struct Object *gpulampob, PyTypeObject *T = &Type); virtual ~KX_LightObject(); virtual CValue* GetReplica(); RAS_LightObject* GetLightData() { return &m_lightobj;} diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index 065800379d8..718bf4f93db 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -37,6 +37,7 @@ #include "MT_assert.h" #include "KX_KetsjiEngine.h" +#include "KX_BlenderMaterial.h" #include "RAS_IPolygonMaterial.h" #include "ListValue.h" #include "SCA_LogicManager.h" @@ -1249,6 +1250,7 @@ void KX_Scene::RenderBuckets(const MT_Transform & cameratransform, class RAS_IRenderTools* rendertools) { m_bucketmanager->Renderbuckets(cameratransform,rasty,rendertools); + KX_BlenderMaterial::EndFrame(); } |