BGE Python API cleanup - no functionality changes
[blender.git] / source / gameengine / Ketsji / KX_BlenderMaterial.cpp
index 0f445a9f32e97d044fc93ca519ba26949f45470e..6722cd232fe8c8a3392a8414585001ed25992bbb 100644 (file)
 #include "MT_Vector4.h"
 #include "MT_Matrix4x4.h"
 
+#include "RAS_BucketManager.h"
 #include "RAS_MeshObject.h"
 #include "RAS_IRasterizer.h"
 #include "RAS_OpenGLRasterizer/RAS_GLExtensionManager.h"
 
-extern "C" {
-#include "BDR_drawmesh.h"
-}
+#include "GPU_draw.h"
 
 #include "STR_HashedString.h"
 
@@ -38,6 +37,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;
@@ -47,7 +47,6 @@ KX_BlenderMaterial::KX_BlenderMaterial(
        BL_Material *data,
        bool skin,
        int lightlayer,
-       void *clientobject,
        PyTypeObject *T
        )
 :      PyObjectPlus(T),
@@ -58,11 +57,10 @@ KX_BlenderMaterial::KX_BlenderMaterial(
                data->tilexrep[0],
                data->tileyrep[0],
                data->mode,
-               ((data->ras_mode &TRANSP)!=0),
+               data->transp,
+               ((data->ras_mode &ALPHA)!=0),
                ((data->ras_mode &ZSORT)!=0),
-               lightlayer,
-               ((data->ras_mode &TRIANGLE)!=0),
-               clientobject
+               lightlayer
        ),
        mMaterial(data),
        mShader(0),
@@ -76,10 +74,10 @@ KX_BlenderMaterial::KX_BlenderMaterial(
 {
        // --------------------------------
        // RAS_IPolyMaterial variables... 
-       m_flag |=RAS_BLENDERMAT;
-       m_flag |=(mMaterial->IdMode>=ONETEX)?RAS_MULTITEX:0;
-       m_flag |=(mMaterial->ras_mode & USE_LIGHT)!=0?RAS_MULTILIGHT:0;
-       m_flag |=(mMaterial->ras_mode &ALPHA_TEST)!=0?RAS_FORCEALPHA:0;
+       m_flag |= RAS_BLENDERMAT;
+       m_flag |= (mMaterial->IdMode>=ONETEX)? RAS_MULTITEX: 0;
+       m_flag |= ((mMaterial->ras_mode & USE_LIGHT)!=0)? RAS_MULTILIGHT: 0;
+       m_flag |= (mMaterial->glslmat)? RAS_BLENDERGLSL: 0;
 
        // figure max
        int enabled = mMaterial->num_enabled;
@@ -96,7 +94,7 @@ KX_BlenderMaterial::KX_BlenderMaterial(
                          mMaterial->blend_mode[i]
                         );
        }
-       m_multimode += mMaterial->IdMode+mMaterial->ras_mode;
+       m_multimode += mMaterial->IdMode+ (mMaterial->ras_mode & ~(COLLIDER|USE_LIGHT));
 
 }
 
@@ -158,12 +156,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;
        }
@@ -186,7 +201,7 @@ void KX_BlenderMaterial::OnExit()
        }
 
        if( mMaterial->tface ) 
-               set_tpage(mMaterial->tface);
+               GPU_set_tpage(mMaterial->tface);
 }
 
 
@@ -197,13 +212,19 @@ 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;
+               }
+
+               ras->SetBlendingMode(TF_SOLID);
                BL_Texture::DisableAllTextures();
                return;
        }
 
        BL_Texture::DisableAllTextures();
        mShader->SetProg(true);
+       mLastShader = mShader;
        
        BL_Texture::ActivateFirst();
 
@@ -217,9 +238,12 @@ void KX_BlenderMaterial::setShaderData( bool enable, RAS_IRasterizer *ras)
        }
 
        if(!mUserDefBlend) {
-               setDefaultBlending();
+               ras->SetBlendingMode(mMaterial->transp);
        }
        else {
+               ras->SetBlendingMode(TF_SOLID);
+               ras->SetBlendingMode(-1); // indicates custom mode
+
                // tested to be valid enums
                glEnable(GL_BLEND);
                glBlendFunc(mBlendFunc[0], mBlendFunc[1]);
@@ -229,39 +253,45 @@ void KX_BlenderMaterial::setShaderData( bool enable, RAS_IRasterizer *ras)
 void KX_BlenderMaterial::setBlenderShaderData( bool enable, RAS_IRasterizer *ras)
 {
        if( !enable || !mBlenderShader->Ok() ) {
+               ras->SetBlendingMode(TF_SOLID);
+
                // frame cleanup.
                if(mLastBlenderShader) {
                        mLastBlenderShader->SetProg(false);
                        mLastBlenderShader= NULL;
                }
-               BL_Texture::DisableAllTextures();
+               else
+                       BL_Texture::DisableAllTextures();
+
                return;
        }
 
        if(!mBlenderShader->Equals(mLastBlenderShader)) {
-               BL_Texture::DisableAllTextures();
+               ras->SetBlendingMode(mMaterial->transp);
 
                if(mLastBlenderShader)
                        mLastBlenderShader->SetProg(false);
+               else
+                       BL_Texture::DisableAllTextures();
 
-               mBlenderShader->SetProg(true);
+               mBlenderShader->SetProg(true, ras->GetTime());
                mLastBlenderShader= mBlenderShader;
        }
 }
 
 void KX_BlenderMaterial::setTexData( bool enable, RAS_IRasterizer *ras)
 {
-       if(GLEW_ARB_shader_objects && mShader) 
-               mShader->SetProg(false);
-
        BL_Texture::DisableAllTextures();
-       if( !enable )
+
+       if( !enable ) {
+               ras->SetBlendingMode(TF_SOLID);
                return;
+       }
 
        BL_Texture::ActivateFirst();
 
        if( mMaterial->IdMode == DEFAULT_BLENDER ) {
-               setDefaultBlending();
+               ras->SetBlendingMode(mMaterial->transp);
                return;
        }
 
@@ -271,7 +301,7 @@ void KX_BlenderMaterial::setTexData( bool enable, RAS_IRasterizer *ras)
                        mTextures[0].ActivateTexture();
                        mTextures[0].setTexEnv(0, true);
                        mTextures[0].SetMapping(mMaterial->mapping[0].mapping);
-                       setDefaultBlending(); 
+                       ras->SetBlendingMode(mMaterial->transp);
                }
                return;
        }
@@ -294,9 +324,12 @@ void KX_BlenderMaterial::setTexData( bool enable, RAS_IRasterizer *ras)
        }
 
        if(!mUserDefBlend) {
-               setDefaultBlending();
+               ras->SetBlendingMode(mMaterial->transp);
        }
        else {
+               ras->SetBlendingMode(TF_SOLID);
+               ras->SetBlendingMode(-1); // indicates custom mode
+
                glEnable(GL_BLEND);
                glBlendFunc(mBlendFunc[0], mBlendFunc[1]);
        }
@@ -321,21 +354,22 @@ KX_BlenderMaterial::ActivatShaders(
        if (GetCachingInfo() != cachingInfo) {
 
                if (!cachingInfo)
-                       tmp->setShaderData( false, rasty);
+                       tmp->setShaderData(false, rasty);
                
                cachingInfo = GetCachingInfo();
        
                if(rasty->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED)
-                       tmp->setShaderData( true, rasty);
+                       tmp->setShaderData(true, rasty);
                else
-                       tmp->setShaderData( false, rasty);
+                       tmp->setShaderData(false, rasty);
 
                if(mMaterial->mode & RAS_IRasterizer::KX_TWOSIDE)
                        rasty->SetCullFace(false);
                else
                        rasty->SetCullFace(true);
 
-               if (((mMaterial->ras_mode &WIRE)!=0) || mMaterial->mode & RAS_IRasterizer::KX_LINES)
+               if (((mMaterial->ras_mode &WIRE)!=0) || (mMaterial->mode & RAS_IRasterizer::KX_LINES) ||
+                   (rasty->GetDrawingMode() <= RAS_IRasterizer::KX_WIREFRAME))
                {               
                        if((mMaterial->ras_mode &WIRE)!=0) 
                                rasty->SetCullFace(false);
@@ -356,31 +390,29 @@ KX_BlenderMaterial::ActivateBlenderShaders(
 {
        KX_BlenderMaterial *tmp = const_cast<KX_BlenderMaterial*>(this);
 
-       // reset... 
-       if(tmp->mMaterial->IsShared()) 
-               cachingInfo =0;
-       
+       if(mLastShader) {
+               mLastShader->SetProg(false);
+               mLastShader= NULL;
+       }
+
        if (GetCachingInfo() != cachingInfo) {
                if (!cachingInfo)
                        tmp->setBlenderShaderData(false, rasty);
                
                cachingInfo = GetCachingInfo();
        
-               if(rasty->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED) {
+               if(rasty->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED)
                        tmp->setBlenderShaderData(true, rasty);
-                       rasty->EnableTextures(true);
-               }
-               else {
+               else
                        tmp->setBlenderShaderData(false, rasty);
-                       rasty->EnableTextures(false);
-               }
 
                if(mMaterial->mode & RAS_IRasterizer::KX_TWOSIDE)
                        rasty->SetCullFace(false);
                else
                        rasty->SetCullFace(true);
 
-               if (((mMaterial->ras_mode &WIRE)!=0) || mMaterial->mode & RAS_IRasterizer::KX_LINES)
+               if (((mMaterial->ras_mode & WIRE)!=0) || (mMaterial->mode & RAS_IRasterizer::KX_LINES) ||
+                   (rasty->GetDrawingMode() <= RAS_IRasterizer::KX_WIREFRAME))
                {               
                        if((mMaterial->ras_mode &WIRE)!=0) 
                                rasty->SetCullFace(false);
@@ -388,10 +420,10 @@ KX_BlenderMaterial::ActivateBlenderShaders(
                }
                else
                        rasty->SetLines(false);
-       }
 
-       ActivatGLMaterials(rasty);
-       mBlenderShader->SetAttribs(rasty, mMaterial);
+               ActivatGLMaterials(rasty);
+               mBlenderShader->SetAttribs(rasty, mMaterial);
+       }
 }
 
 void
@@ -402,6 +434,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;
@@ -423,7 +460,8 @@ KX_BlenderMaterial::ActivateMat(
                else
                        rasty->SetCullFace(true);
 
-               if (((mMaterial->ras_mode &WIRE)!=0) || mMaterial->mode & RAS_IRasterizer::KX_LINES)
+               if (((mMaterial->ras_mode &WIRE)!=0) || (mMaterial->mode & RAS_IRasterizer::KX_LINES) ||
+                   (rasty->GetDrawingMode() <= RAS_IRasterizer::KX_WIREFRAME))
                {               
                        if((mMaterial->ras_mode &WIRE)!=0) 
                                rasty->SetCullFace(false);
@@ -443,46 +481,40 @@ KX_BlenderMaterial::Activate(
        TCachingInfo& cachingInfo
        )const
 {
-       bool dopass = false;
-       if( GLEW_ARB_shader_objects && ( mShader && mShader->Ok() ) ) {
-               if( (mPass++) < mShader->getNumPass() ) {
+       if(GLEW_ARB_shader_objects && (mShader && mShader->Ok())) {
+               if((mPass++) < mShader->getNumPass() ) {
                        ActivatShaders(rasty, cachingInfo);
-                       dopass = true;
-                       return dopass;
+                       return true;
                }
                else {
-                       mShader->SetProg(false);
+                       if(mShader == mLastShader) {
+                               mShader->SetProg(false);
+                               mLastShader = NULL;
+                       }
                        mPass = 0;
-                       dopass = false;
-                       return dopass;
+                       return false;
                }
        }
-       else if( GLEW_ARB_shader_objects && ( mBlenderShader && mBlenderShader->Ok() ) ) {
-               if( (mPass++) == 0 ) {
+       else if( GLEW_ARB_shader_objects && (mBlenderShader && mBlenderShader->Ok() ) ) {
+               if(mPass++ == 0) {
                        ActivateBlenderShaders(rasty, cachingInfo);
-                       dopass = true;
-                       return dopass;
+                       return true;
                }
                else {
                        mPass = 0;
-                       dopass = false;
-                       return dopass;
+                       return false;
                }
        }
        else {
-               switch (mPass++)
-               {
-                       case 0:
-                               ActivateMat(rasty, cachingInfo);
-                               dopass = true;
-                               break;
-                       default:
-                               mPass = 0;
-                               dopass = false;
-                               break;
+               if(mPass++ == 0) {
+                       ActivateMat(rasty, cachingInfo);
+                       return true;
+               }
+               else {
+                       mPass = 0;
+                       return false;
                }
        }
-       return dopass;
 }
 
 bool KX_BlenderMaterial::UsesLighting(RAS_IRasterizer *rasty) const
@@ -490,19 +522,32 @@ bool KX_BlenderMaterial::UsesLighting(RAS_IRasterizer *rasty) const
        if(!RAS_IPolyMaterial::UsesLighting(rasty))
                return false;
 
-       if(mShader && mShader->Ok());
+       if(mShader && mShader->Ok())
+               return true;
        else if(mBlenderShader && mBlenderShader->Ok())
                return false;
-       
-       return true;
+       else
+               return true;
 }
 
-void KX_BlenderMaterial::ActivateMeshSlot(const KX_MeshSlot & ms, RAS_IRasterizer* rasty) const
+void KX_BlenderMaterial::ActivateMeshSlot(const RAS_MeshSlot & ms, RAS_IRasterizer* rasty) const
 {
-       if(mShader && GLEW_ARB_shader_objects)
+       if(mShader && GLEW_ARB_shader_objects) {
                mShader->Update(ms, rasty);
-       else if(mBlenderShader && GLEW_ARB_shader_objects)
+       }
+       else if(mBlenderShader && GLEW_ARB_shader_objects) {
+               int blendmode;
+
                mBlenderShader->Update(ms, rasty);
+
+               /* we do blend modes here, because they can change per object
+                * with the same material due to obcolor/obalpha */
+               blendmode = mBlenderShader->GetBlendMode();
+               if((blendmode == TF_SOLID || blendmode == TF_ALPHA) && mMaterial->transp != TF_SOLID)
+                       blendmode = mMaterial->transp;
+
+               rasty->SetBlendingMode(blendmode);
+       }
 }
 
 void KX_BlenderMaterial::ActivatGLMaterials( RAS_IRasterizer* rasty )const
@@ -575,36 +620,7 @@ void KX_BlenderMaterial::ActivateTexGen(RAS_IRasterizer *ras) const
                        else 
                                ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_DISABLE, i);
                }
-
-               ras->EnableTextures(true);
        }
-       else
-               ras->EnableTextures(false);
-}
-
-bool KX_BlenderMaterial::setDefaultBlending()
-{
-       if( mMaterial->transp &TF_ADD) {
-               glEnable(GL_BLEND);
-               glBlendFunc(GL_ONE, GL_ONE);
-               glDisable ( GL_ALPHA_TEST );
-               return true;
-       }
-       
-       if( mMaterial->transp & TF_ALPHA ) {
-               glEnable(GL_BLEND);
-               glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-               glDisable ( GL_ALPHA_TEST );
-               return true;
-       }
-       
-       if( mMaterial->transp & TF_CLIP ) {
-               glDisable(GL_BLEND); 
-               glEnable ( GL_ALPHA_TEST );
-               glAlphaFunc(GL_GREATER, 0.5f);
-               return false;
-       }
-       return false;
 }
 
 void KX_BlenderMaterial::setTexMatrixData(int i)
@@ -679,8 +695,7 @@ void KX_BlenderMaterial::setObjectMatrixData(int i, RAS_IRasterizer *ras)
        glEnable(GL_TEXTURE_GEN_T);
        glEnable(GL_TEXTURE_GEN_R);
 
-       MT_Matrix4x4 mvmat;
-       ras->GetViewMatrix(mvmat);
+       const MT_Matrix4x4& mvmat = ras->GetViewMatrix();
 
        glMatrixMode(GL_TEXTURE);
        glLoadIdentity();
@@ -733,38 +748,45 @@ PyMethodDef KX_BlenderMaterial::Methods[] =
        {NULL,NULL} //Sentinel
 };
 
+PyAttributeDef KX_BlenderMaterial::Attributes[] = {
+       { NULL }        //Sentinel
+};
 
 PyTypeObject KX_BlenderMaterial::Type = {
-       PyObject_HEAD_INIT(&PyType_Type)
+       PyObject_HEAD_INIT(NULL)
                0,
                "KX_BlenderMaterial",
-               sizeof(KX_BlenderMaterial),
+               sizeof(PyObjectPlus_Proxy),
                0,
-               PyDestructor,
+               py_base_dealloc,
                0,
-               __getattr,
-               __setattr,
                0,
-               __repr,
-               0
+               0,
+               0,
+               py_base_repr,
+               0,0,0,0,0,0,
+               py_base_getattro,
+               py_base_setattro,
+               0,0,0,0,0,0,0,0,0,
+               Methods
 };
 
 
 PyParentObject KX_BlenderMaterial::Parents[] = {
-       &PyObjectPlus::Type,
        &KX_BlenderMaterial::Type,
+       &PyObjectPlus::Type,
        NULL
 };
 
 
-PyObject* KX_BlenderMaterial::_getattr(const STR_String& attr)
+PyObject* KX_BlenderMaterial::py_getattro(PyObject *attr)
 {
-       _getattr_up(PyObjectPlus);
+       py_getattro_up(PyObjectPlus);
 }
 
-int KX_BlenderMaterial::_setattr(const STR_String& attr, PyObject *pyvalue)
+int KX_BlenderMaterial::py_setattro(PyObject *attr, PyObject *pyvalue)
 {
-       return PyObjectPlus::_setattr(attr, pyvalue);
+       return PyObjectPlus::py_setattro(attr, pyvalue);
 }
 
 
@@ -775,7 +797,7 @@ KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getShader , "getShader()")
                        spit("Fragment shaders not supported");
        
                mModified = true;
-               Py_Return;
+               Py_RETURN_NONE;
        }
 
        if( !GLEW_ARB_vertex_shader) {
@@ -783,14 +805,14 @@ KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getShader , "getShader()")
                        spit("Vertex shaders not supported");
 
                mModified = true;
-               Py_Return;
+               Py_RETURN_NONE;
        }
 
        if(!GLEW_ARB_shader_objects)  {
                if(!mModified)
                        spit("GLSL not supported");
                mModified = true;
-               Py_Return;
+               Py_RETURN_NONE;
        }
        else {
                // returns Py_None on error
@@ -802,9 +824,10 @@ KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getShader , "getShader()")
                }
 
                if(mShader && !mShader->GetError()) {
+                       m_flag &= ~RAS_BLENDERGLSL;
                        mMaterial->SetSharedMaterial(true);
-                       Py_INCREF(mShader);
-                       return mShader;
+                       mScene->GetBucketManager()->ReleaseDisplayLists(this);
+                       return mShader->GetProxy();
                }else
                {
                        // decref all references to the object
@@ -812,16 +835,11 @@ KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getShader , "getShader()")
                        // We will then go back to fixed functionality
                        // for this material
                        if(mShader) {
-                               if(mShader->ob_refcnt > 1) {
-                                       Py_DECREF(mShader);
-                               }
-                               else {
-                                       delete mShader;
-                                       mShader=0;
-                               }
+                               delete mShader; /* will handle python de-referencing */
+                               mShader=0;
                        }
                }
-               Py_Return;
+               Py_RETURN_NONE;
        }
        PyErr_Format(PyExc_ValueError, "GLSL Error");
        return NULL;
@@ -831,7 +849,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;
@@ -873,7 +891,7 @@ static unsigned int GL_array[11] = {
 KX_PYMETHODDEF_DOC( KX_BlenderMaterial, setBlending , "setBlending( GameLogic.src, GameLogic.dest)")
 {
        unsigned int b[2];
-       if(PyArg_ParseTuple(args, "ii", &b[0], &b[1]))
+       if(PyArg_ParseTuple(args, "ii:setBlending", &b[0], &b[1]))
        {
                bool value_found[2] = {false, false};
                for(int i=0; i<11; i++)
@@ -893,7 +911,7 @@ KX_PYMETHODDEF_DOC( KX_BlenderMaterial, setBlending , "setBlending( GameLogic.sr
                        return NULL;
                }
                mUserDefBlend = true;
-               Py_Return;
+               Py_RETURN_NONE;
        }
        return NULL;
 }