attempt to fix reported problems with glsl shader on OS X (and other platforms)....
authorErwin Coumans <blender@erwincoumans.com>
Wed, 18 Jan 2006 06:04:11 +0000 (06:04 +0000)
committerErwin Coumans <blender@erwincoumans.com>
Wed, 18 Jan 2006 06:04:11 +0000 (06:04 +0000)
also, disabled the asynchronous logicbrick update, it reportedly causes jitter.

source/gameengine/Ketsji/BL_Shader.cpp
source/gameengine/Ketsji/BL_Shader.h
source/gameengine/Ketsji/KX_BlenderMaterial.cpp
source/gameengine/Ketsji/KX_BlenderMaterial.h
source/gameengine/Ketsji/KX_KetsjiEngine.cpp

index 981f96928d5ceb2e480f790387cec4217c5fc13d..5c173c4e6b409f106de6fba5fd8a96d288e48513 100644 (file)
@@ -41,7 +41,10 @@ BL_Shader::BL_Shader(PyTypeObject *T)
        mOk(0),
        mUse(0),
        vertProg(""),
-       fragProg("")
+       fragProg(""),
+       mError(0),
+       mLog(0)
+
 {
        // if !RAS_EXT_support._ARB_shader_objects this class will not be used
 
@@ -59,6 +62,10 @@ using namespace bgl;
 BL_Shader::~BL_Shader()
 {
 #ifdef GL_ARB_shader_objects
+       if(mLog) {
+               MEM_freeN(mLog);
+               mLog=0;
+       }
        if( mShader ) {
                bgl::blDeleteObjectARB(mShader);
                mShader = 0;
@@ -84,68 +91,74 @@ BL_Shader::~BL_Shader()
 bool BL_Shader::LinkProgram()
 {
 #ifdef GL_ARB_shader_objects
-       int numchars=0;
-       char* log=0;
+       if(mError)
+               goto programError;
+
+
        int vertlen = 0, fraglen=0, proglen=0;
+       int vertstatus=0, fragstatus=0, progstatus=0;
+       unsigned int tmpVert=0, tmpFrag=0, tmpProg=0;
+       int char_len=0;
 
        if(!vertProg || !fragProg){
                spit("Invalid GLSL sources");
                return false;
        }
-       
-       // create our objects
-       unsigned int tmpVert = bgl::blCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
-       unsigned int tmpFrag = bgl::blCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
-       unsigned int tmpProg = bgl::blCreateProgramObjectARB();
-
-       if(!tmpVert || !tmpFrag || !tmpProg){
-               bgl::blDeleteObjectARB(tmpVert);
-               bgl::blDeleteObjectARB(tmpFrag);
-               bgl::blDeleteObjectARB(tmpProg);
+       if( !RAS_EXT_support._ARB_fragment_shader) {
+               spit("Fragment shaders not supported");
                return false;
        }
-       // set/compile vertex shader
+       if( !RAS_EXT_support._ARB_vertex_shader) {
+               spit("Vertex shaders not supported");
+               return false;
+       }
+       
+       // -- vertex shader ------------------
+       tmpVert = bgl::blCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
        bgl::blShaderSourceARB(tmpVert, 1, (const char**)&vertProg, 0);
        bgl::blCompileShaderARB(tmpVert);
        bgl::blGetObjectParameterivARB(tmpVert, GL_OBJECT_INFO_LOG_LENGTH_ARB, &vertlen);
-
-       if( vertlen > 0 && !PrintInfo(vertlen,tmpVert, "Vertex Shader") ){
-               spit("Vertex shader failed");
-               bgl::blDeleteObjectARB(tmpVert);
-               bgl::blDeleteObjectARB(tmpFrag);
-               bgl::blDeleteObjectARB(tmpProg);
-               mOk     = 0;
-               return false;
+       // print info if any
+       if( vertlen > 1){
+               PrintInfo(vertlen,tmpVert, &char_len);
+               goto programError;
        }
-       // set/compile fragment shader
+       // check for compile errors
+       bgl::blGetObjectParameterivARB(tmpVert, GL_OBJECT_COMPILE_STATUS_ARB, &vertstatus);
+       if(!vertstatus)
+               goto programError;
+
+       // -- fragment shader ----------------
+       tmpFrag = bgl::blCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
        bgl::blShaderSourceARB(tmpFrag, 1,(const char**)&fragProg, 0);
        bgl::blCompileShaderARB(tmpFrag);
        bgl::blGetObjectParameterivARB(tmpFrag, GL_OBJECT_INFO_LOG_LENGTH_ARB, &fraglen);
-       if(fraglen >0 && !PrintInfo(fraglen,tmpFrag, "Fragment Shader") ){
-               spit("Fragment shader failed");
-               bgl::blDeleteObjectARB(tmpVert);
-               bgl::blDeleteObjectARB(tmpFrag);
-               bgl::blDeleteObjectARB(tmpProg);
-               mOk     = 0;
-               return false;
+       if(fraglen >1 ){
+               PrintInfo(fraglen,tmpFrag, &char_len);
+               goto programError;
        }
+       bgl::blGetObjectParameterivARB(tmpFrag, GL_OBJECT_COMPILE_STATUS_ARB, &fragstatus);
+       if(!fragstatus)
+               goto programError;
 
-       // set compiled vert/frag shader & link
+       
+       // -- program ------------------------
+       //  set compiled vert/frag shader & link
+       tmpProg = bgl::blCreateProgramObjectARB();
        bgl::blAttachObjectARB(tmpProg, tmpVert);
        bgl::blAttachObjectARB(tmpProg, tmpFrag);
        bgl::blLinkProgramARB(tmpProg);
-
        bgl::blGetObjectParameterivARB(tmpProg, GL_OBJECT_INFO_LOG_LENGTH_ARB, &proglen);
-       if(proglen > 0){
-               PrintInfo(proglen,tmpProg, "GLSL Shader");
-       }
-       else{
-               spit("Program failed");
-               bgl::blDeleteObjectARB(tmpVert);
-               bgl::blDeleteObjectARB(tmpFrag);
-               bgl::blDeleteObjectARB(tmpProg);
-               mOk     = 0;
-               return false;
+       bgl::blGetObjectParameterivARB(tmpProg, GL_OBJECT_LINK_STATUS_ARB, &progstatus);
+       if(!progstatus)
+               goto programError;
+
+       if(proglen > 0) {
+               // print success
+               PrintInfo(proglen,tmpProg, &char_len);
+               if(char_len >0)
+                       spit(mLog);
+               mError = 0;
        }
 
        // set
@@ -154,34 +167,42 @@ bool BL_Shader::LinkProgram()
        mFrag   = tmpFrag;
        mOk             = 1;
        return true;
+
+programError:
+       if(tmpVert) {
+               bgl::blDeleteObjectARB(tmpVert);
+               tmpVert=0;
+       }
+       if(tmpFrag) {
+               bgl::blDeleteObjectARB(tmpFrag);
+               tmpFrag=0;
+       }
+
+       if(tmpProg) {
+               bgl::blDeleteObjectARB(tmpProg);
+               tmpProg=0;
+       }
+
+       mOk     = 0;
+       mUse=0;
+       mError = 1;
+       spit("----------");
+       spit("GLSL Error ");
+       if(mLog)
+               spit(mLog);
+       spit("--------------------");
+       return false;
 #else
        return false;
 #endif//GL_ARB_shader_objects
 }
 
-bool BL_Shader::PrintInfo(int len, unsigned int handle, const char *type)
+void BL_Shader::PrintInfo(int len, unsigned int handle, int* num)
 {
 #ifdef GL_ARB_shader_objects
-       int numchars=0;
-       char *log = (char*)MEM_mallocN(sizeof(char)*len, "print_log");
-       if(!log) {
-               spit("BL_Shader::PrintInfo() MEM_mallocN failed");
-               return false;
-       }
-       bgl::blGetInfoLogARB(handle, len, &numchars, log);
-       
-       if(numchars >0){
-               spit(type);
-               spit(log);
-               MEM_freeN(log);
-               log=0;
-               return false;
-       }
-       MEM_freeN(log);
-       log=0;
-       return true;
-#else
-       return false
+       mLog = (char*)MEM_mallocN(sizeof(char)*len, "print_log");
+       MT_assert(mLog, "Failed to create memory");
+       bgl::blGetInfoLogARB(handle, len, num, mLog);
 #endif//GL_ARB_shader_objects
 }
 
@@ -324,8 +345,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setSource," setSource(vertexProgram, fragmentProg
                vertProg = 0;
                fragProg = 0;
                mUse = 0;
-               bgl::blUseProgramObjectARB( 0 );
-               PyErr_Format(PyExc_ValueError, "GLSL Error");
+               Py_Return;
        }
        return NULL;
 #else
@@ -371,6 +391,11 @@ KX_PYMETHODDEF_DOC( BL_Shader, getFragmentProg ,"getFragmentProg( )" )
 KX_PYMETHODDEF_DOC( BL_Shader, validate, "validate()")
 {
 #ifdef GL_ARB_shader_objects
+       if(mError) {
+               Py_INCREF(Py_None);
+               return Py_None;
+       }
+
        if(mShader==0) {
                PyErr_Format(PyExc_TypeError, "invalid shader object");
                return NULL;
@@ -378,7 +403,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, validate, "validate()")
        int stat = 0;
        bgl::blValidateProgramARB(mShader);
        bgl::blGetObjectParameterivARB(mShader, GL_OBJECT_VALIDATE_STATUS_ARB, &stat);
-       return PyInt_FromLong(!PrintInfo(stat, mShader, "Validation"));
+       return PyInt_FromLong(0);
 #else
        Py_Return;
 #endif//GL_ARB_shader_objects
@@ -388,6 +413,11 @@ KX_PYMETHODDEF_DOC( BL_Shader, validate, "validate()")
 KX_PYMETHODDEF_DOC( BL_Shader, setSampler, "setSampler(name, index)" )
 {
 #ifdef GL_ARB_shader_objects
+       if(mError) {
+               Py_INCREF(Py_None);
+               return Py_None;
+       }
+
        char *uniform="";
        int index=-1;
        if(PyArg_ParseTuple(args, "si", &uniform, &index)) 
@@ -434,6 +464,11 @@ KX_PYMETHODDEF_DOC( BL_Shader, setNumberOfPasses, "setNumberOfPasses( max-pass )
 KX_PYMETHODDEF_DOC( BL_Shader, setUniform1f, "setUniform1f(name, fx)" )
 {
 #ifdef GL_ARB_shader_objects
+       if(mError) {
+               Py_INCREF(Py_None);
+               return Py_None;
+       }
+
        char *uniform="";
        float value=0;
        if(PyArg_ParseTuple(args, "sf", &uniform, &value ))
@@ -466,6 +501,10 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniform1f, "setUniform1f(name, fx)" )
 KX_PYMETHODDEF_DOC( BL_Shader, setUniform2f , "setUniform2f(name, fx, fy)")
 {
 #ifdef GL_ARB_shader_objects
+       if(mError) {
+               Py_INCREF(Py_None);
+               return Py_None;
+       }
        char *uniform="";
        float array[2]={ 0,0 };
        if(PyArg_ParseTuple(args, "sff", &uniform, &array[0],&array[1] ))
@@ -498,6 +537,10 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniform2f , "setUniform2f(name, fx, fy)")
 KX_PYMETHODDEF_DOC( BL_Shader, setUniform3f, "setUniform3f(name, fx,fy,fz) ")
 {
 #ifdef GL_ARB_shader_objects
+       if(mError) {
+               Py_INCREF(Py_None);
+               return Py_None;
+       }
        char *uniform="";
        float array[3]={0,0,0};
        if(PyArg_ParseTuple(args, "sfff", &uniform, &array[0],&array[1],&array[2]))
@@ -530,6 +573,10 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniform3f, "setUniform3f(name, fx,fy,fz) ")
 KX_PYMETHODDEF_DOC( BL_Shader, setUniform4f, "setUniform4f(name, fx,fy,fz, fw) ")
 {
 #ifdef GL_ARB_shader_objects
+       if(mError) {
+               Py_INCREF(Py_None);
+               return Py_None;
+       }
        char *uniform="";
        float array[4]={0,0,0,0};
        if(PyArg_ParseTuple(args, "sffff", &uniform, &array[0],&array[1],&array[2], &array[3]))
@@ -561,6 +608,10 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniform4f, "setUniform4f(name, fx,fy,fz, fw) "
 KX_PYMETHODDEF_DOC( BL_Shader, setUniform1i, "setUniform1i(name, ix)" )
 {
 #ifdef GL_ARB_shader_objects
+       if(mError) {
+               Py_INCREF(Py_None);
+               return Py_None;
+       }
        char *uniform="";
        int value=0;
        if(PyArg_ParseTuple(args, "si", &uniform, &value ))
@@ -592,6 +643,10 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniform1i, "setUniform1i(name, ix)" )
 KX_PYMETHODDEF_DOC( BL_Shader, setUniform2i , "setUniform2i(name, ix, iy)")
 {
 #ifdef GL_ARB_shader_objects
+       if(mError) {
+               Py_INCREF(Py_None);
+               return Py_None;
+       }
        char *uniform="";
        int array[2]={ 0,0 };
        if(PyArg_ParseTuple(args, "sii", &uniform, &array[0],&array[1] ))
@@ -623,6 +678,10 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniform2i , "setUniform2i(name, ix, iy)")
 KX_PYMETHODDEF_DOC( BL_Shader, setUniform3i, "setUniform3i(name, ix,iy,iz) ")
 {
 #ifdef GL_ARB_shader_objects
+       if(mError) {
+               Py_INCREF(Py_None);
+               return Py_None;
+       }
        char *uniform="";
        int array[3]={0,0,0};
        if(PyArg_ParseTuple(args, "siii", &uniform, &array[0],&array[1],&array[2]))
@@ -653,6 +712,10 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniform3i, "setUniform3i(name, ix,iy,iz) ")
 KX_PYMETHODDEF_DOC( BL_Shader, setUniform4i, "setUniform4i(name, ix,iy,iz, iw) ")
 {
 #ifdef GL_ARB_shader_objects
+       if(mError) {
+               Py_INCREF(Py_None);
+               return Py_None;
+       }
        char *uniform="";
        int array[4]={0,0,0, 0};
        if(PyArg_ParseTuple(args, "siiii", &uniform, &array[0],&array[1],&array[2], &array[3] ))
@@ -683,6 +746,10 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniform4i, "setUniform4i(name, ix,iy,iz, iw) "
 KX_PYMETHODDEF_DOC( BL_Shader, setUniformfv , "setUniformfv( float (list2 or list3 or list4) )")
 {
 #ifdef GL_ARB_shader_objects
+       if(mError) {
+               Py_INCREF(Py_None);
+               return Py_None;
+       }
        char*uniform = "";
        PyObject *listPtr =0;
        float array_data[4] = {0.f,0.f,0.f,0.f};
@@ -750,6 +817,10 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformfv , "setUniformfv( float (list2 or lis
 KX_PYMETHODDEF_DOC( BL_Shader, setUniformiv, "setUniformiv( int (list2 or list3 or list4) )")
 {
 #ifdef GL_ARB_shader_objects
+       if(mError) {
+               Py_INCREF(Py_None);
+               return Py_None;
+       }
        char*uniform = "";
        PyObject *listPtr =0;
        int array_data[4] = {0,0,0,0};
@@ -818,6 +889,11 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformMatrix4,
 "setUniformMatrix4(uniform-name, mat-4x4, transpose(row-major=true, col-major=false)" )
 {
 #ifdef GL_ARB_shader_objects
+       if(mError) {
+               Py_INCREF(Py_None);
+               return Py_None;
+       }
+
        float matr[16] = {
                1,0,0,0,
                0,1,0,0,
@@ -866,6 +942,11 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformMatrix3,
 "setUniformMatrix3(uniform-name, list[3x3], transpose(row-major=true, col-major=false)" )
 {
 #ifdef GL_ARB_shader_objects
+       if(mError) {
+               Py_INCREF(Py_None);
+               return Py_None;
+       }
+
        float matr[9] = {
                1,0,0,
                0,1,0,
index 004fd33b6512d2e24121d0268d1818a1bce270bf..25db6a0b9f4ac0e9304c59a6766a18eb800b9272 100644 (file)
@@ -32,9 +32,11 @@ private:
        uSampler                mSampler[MAXTEX];
        char*                   vertProg;
        char*                   fragProg;
-       bool                    LinkProgram();
-       bool                    PrintInfo(int len, unsigned int handle, const char *type);
+       bool                    mError;
+       char*                   mLog;
 
+       bool                    LinkProgram();
+       void                    PrintInfo( int len, unsigned int handle,int *num);
 public:
        BL_Shader(PyTypeObject *T=&Type);
        virtual ~BL_Shader();
@@ -47,7 +49,7 @@ public:
        // ---
        int getNumPass()        {return mPass;}
        bool use()                      {return mUse;}
-
+       bool GetError()         {return mError;}
        // ---
        // access
        const uSampler*         getSampler(int i);
index ace68a823a8cd0f210c083a2987edfd4614e7e9a..429a9ea7a6576b53b2021798dd53a3c49157180f 100644 (file)
@@ -78,6 +78,7 @@ KX_BlenderMaterial::KX_BlenderMaterial(
        mShader(0),
        mScene(scene),
        mUserDefBlend(0),
+       mModified(0),
        mPass(0)
 
 {
@@ -171,7 +172,7 @@ void KX_BlenderMaterial::OnConstruction()
 void KX_BlenderMaterial::OnExit()
 {
        #ifdef GL_ARB_multitexture
-
+       
        #ifdef GL_ARB_shader_objects
        if( RAS_EXT_support._ARB_shader_objects && mShader ) {
                 //note, the shader here is allocated, per unique material
@@ -919,15 +920,41 @@ int KX_BlenderMaterial::_setattr(const STR_String& attr, PyObject *pyvalue)
        return PyObjectPlus::_setattr(attr, pyvalue);
 }
 
+
 KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getShader , "getShader()")
 {
-       #ifdef GL_ARB_shader_objects
-       if(!RAS_EXT_support._ARB_shader_objects) {
-               PyErr_Format(PyExc_SystemError, "GLSL not supported");
-               return NULL;
+#ifdef GL_ARB_fragment_shader
+       if( !RAS_EXT_support._ARB_fragment_shader) {
+               if(!mModified)
+                       spit("Fragment shaders not supported");
+       
+               mModified = true;
+               Py_Return;
+       }
+#endif
+
+#ifdef GL_ARB_vertex_shader
+       if( !RAS_EXT_support._ARB_vertex_shader) {
+               if(!mModified)
+                       spit("Vertex shaders not supported");
+
+               mModified = true;
+               Py_Return;
+       }
+#endif
+
+#ifdef GL_ARB_shader_objects
+       if(!RAS_EXT_support._ARB_shader_objects)  {
+               if(!mModified)
+                       spit("GLSL not supported");
+               mModified = true;
+               Py_Return;
        }
        else {
-               if(!mShader) {
+               // returns Py_None on error
+               // the calling script will need to check
+
+               if(!mShader && !mModified) {
                        mShader = new BL_Shader();
                        for(int i= 0; i<mMaterial->num_enabled; i++) {
                                if(mMaterial->mapping[i].mapping & USEENV )
@@ -935,13 +962,36 @@ KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getShader , "getShader()")
                                else
                                        mShader->InitializeSampler(SAMP_2D, i, 0, mTextures[i]);
                        }
+                       mModified = true;
+               }
+
+               if(mShader && !mShader->GetError()) {
+                       Py_INCREF(mShader);
+                       return mShader;
+               }else
+               {
+                       // decref all references to the object
+                       // then delete it!
+                       // 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;
+                               }
+                       }
                }
-               Py_INCREF(mShader);
-               return mShader;
+               Py_Return;
        }
-       #else
+       PyErr_Format(PyExc_ValueError, "GLSL Error");
+       return NULL;
+
+#else
        Py_Return;
-       #endif//GL_ARB_shader_objects
+#endif//GL_ARB_shader_objects
 }
 
 KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getMaterialIndex, "getMaterialIndex()")
index 1af4b2550a95a8a10121d1d410ec7e9475e8588e..a250dcf81c4de11aa8adc942f4c8470666cd21e1 100644 (file)
@@ -85,6 +85,7 @@ private:
        
        bool                    mUserDefBlend;
        unsigned int    mBlendFunc[2];
+       bool                    mModified;
 
        // message centers
        void    setTexData( bool enable );
index 09521376c4c607db86142d8b6a8958dd6d535171..41bece58e84971285709dcc81d7c92d954fedc45 100644 (file)
@@ -457,9 +457,9 @@ void KX_KetsjiEngine::NextFrame()
                frames--;
        }
 
-       bool m_doFullFramerateBricks = true;
+       bool bUseAsyncLogicBricks= false;
 
-       if (m_doFullFramerateBricks)
+       if (bUseAsyncLogicBricks)
        {       
                // Logic update sub frame: this will let some logic bricks run at the
                // full frame rate.