diff options
author | Erwin Coumans <blender@erwincoumans.com> | 2006-01-18 09:04:11 +0300 |
---|---|---|
committer | Erwin Coumans <blender@erwincoumans.com> | 2006-01-18 09:04:11 +0300 |
commit | 85c58bfa8a486d801420e9a2021018f3070d90ec (patch) | |
tree | 50390c5dc765bc113e96c35ec0ac1f88dfaca767 /source/gameengine | |
parent | 41007941537bd6269ff134db1bb8425fd4c8b079 (diff) |
attempt to fix reported problems with glsl shader on OS X (and other platforms). instead of continuous printing errors, it should just print once, and delete the shaders.
also, disabled the asynchronous logicbrick update, it reportedly causes jitter.
Diffstat (limited to 'source/gameengine')
-rw-r--r-- | source/gameengine/Ketsji/BL_Shader.cpp | 213 | ||||
-rw-r--r-- | source/gameengine/Ketsji/BL_Shader.h | 8 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_BlenderMaterial.cpp | 70 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_BlenderMaterial.h | 1 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_KetsjiEngine.cpp | 4 |
5 files changed, 215 insertions, 81 deletions
diff --git a/source/gameengine/Ketsji/BL_Shader.cpp b/source/gameengine/Ketsji/BL_Shader.cpp index 981f96928d5..5c173c4e6b4 100644 --- a/source/gameengine/Ketsji/BL_Shader.cpp +++ b/source/gameengine/Ketsji/BL_Shader.cpp @@ -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, diff --git a/source/gameengine/Ketsji/BL_Shader.h b/source/gameengine/Ketsji/BL_Shader.h index 004fd33b651..25db6a0b9f4 100644 --- a/source/gameengine/Ketsji/BL_Shader.h +++ b/source/gameengine/Ketsji/BL_Shader.h @@ -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); diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp index ace68a823a8..429a9ea7a65 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp @@ -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()") diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h index 1af4b2550a9..a250dcf81c4 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.h +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h @@ -85,6 +85,7 @@ private: bool mUserDefBlend; unsigned int mBlendFunc[2]; + bool mModified; // message centers void setTexData( bool enable ); diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index 09521376c4c..41bece58e84 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -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. |