Blender V2.61 - r43446
|
00001 00005 #include "GL/glew.h" 00006 00007 #include <iostream> 00008 #include "BL_Shader.h" 00009 #include "BL_Material.h" 00010 00011 #include "MT_assert.h" 00012 #include "MT_Matrix4x4.h" 00013 #include "MT_Matrix3x3.h" 00014 #include "KX_PyMath.h" 00015 #include "MEM_guardedalloc.h" 00016 00017 #include "RAS_GLExtensionManager.h" 00018 #include "RAS_MeshObject.h" 00019 #include "RAS_IRasterizer.h" 00020 00021 #define spit(x) std::cout << x << std::endl; 00022 00023 #define SORT_UNIFORMS 1 00024 #define UNIFORM_MAX_LEN (int)sizeof(float)*16 00025 #define MAX_LOG_LEN 262144 // bounds 00026 00027 BL_Uniform::BL_Uniform(int data_size) 00028 : mLoc(-1), 00029 mDirty(true), 00030 mType(UNI_NONE), 00031 mTranspose(0), 00032 mDataLen(data_size) 00033 { 00034 #ifdef SORT_UNIFORMS 00035 MT_assert((int)mDataLen <= UNIFORM_MAX_LEN); 00036 mData = (void*)MEM_mallocN(mDataLen, "shader-uniform-alloc"); 00037 #endif 00038 } 00039 00040 BL_Uniform::~BL_Uniform() 00041 { 00042 #ifdef SORT_UNIFORMS 00043 if(mData) { 00044 MEM_freeN(mData); 00045 mData=0; 00046 } 00047 #endif 00048 } 00049 00050 void BL_Uniform::Apply(class BL_Shader *shader) 00051 { 00052 #ifdef SORT_UNIFORMS 00053 MT_assert(mType > UNI_NONE && mType < UNI_MAX && mData); 00054 00055 if(!mDirty) 00056 return; 00057 00058 switch(mType) 00059 { 00060 case UNI_FLOAT: { 00061 float *f = (float*)mData; 00062 glUniform1fARB(mLoc,(GLfloat)*f); 00063 }break; 00064 case UNI_INT: { 00065 int *f = (int*)mData; 00066 glUniform1iARB(mLoc, (GLint)*f); 00067 }break; 00068 case UNI_FLOAT2: { 00069 float *f = (float*)mData; 00070 glUniform2fvARB(mLoc,1, (GLfloat*)f); 00071 }break; 00072 case UNI_FLOAT3: { 00073 float *f = (float*)mData; 00074 glUniform3fvARB(mLoc,1,(GLfloat*)f); 00075 }break; 00076 case UNI_FLOAT4: { 00077 float *f = (float*)mData; 00078 glUniform4fvARB(mLoc,1,(GLfloat*)f); 00079 }break; 00080 case UNI_INT2: { 00081 int *f = (int*)mData; 00082 glUniform2ivARB(mLoc,1,(GLint*)f); 00083 }break; 00084 case UNI_INT3: { 00085 int *f = (int*)mData; 00086 glUniform3ivARB(mLoc,1,(GLint*)f); 00087 }break; 00088 case UNI_INT4: { 00089 int *f = (int*)mData; 00090 glUniform4ivARB(mLoc,1,(GLint*)f); 00091 }break; 00092 case UNI_MAT4: { 00093 float *f = (float*)mData; 00094 glUniformMatrix4fvARB(mLoc, 1, mTranspose?GL_TRUE:GL_FALSE,(GLfloat*)f); 00095 }break; 00096 case UNI_MAT3: { 00097 float *f = (float*)mData; 00098 glUniformMatrix3fvARB(mLoc, 1, mTranspose?GL_TRUE:GL_FALSE,(GLfloat*)f); 00099 }break; 00100 } 00101 mDirty = false; 00102 #endif 00103 } 00104 00105 void BL_Uniform::SetData(int location, int type,bool transpose) 00106 { 00107 #ifdef SORT_UNIFORMS 00108 mType = type; 00109 mLoc = location; 00110 mDirty = true; 00111 #endif 00112 } 00113 00114 bool BL_Shader::Ok()const 00115 { 00116 return (mShader !=0 && mOk && mUse); 00117 } 00118 00119 BL_Shader::BL_Shader() 00120 : PyObjectPlus(), 00121 mShader(0), 00122 mPass(1), 00123 mOk(0), 00124 mUse(0), 00125 mAttr(0), 00126 vertProg(""), 00127 fragProg(""), 00128 mError(0), 00129 mDirty(true) 00130 { 00131 // if !GLEW_ARB_shader_objects this class will not be used 00132 //for (int i=0; i<MAXTEX; i++) { 00133 // mSampler[i] = BL_Sampler(); 00134 //} 00135 } 00136 00137 BL_Shader::~BL_Shader() 00138 { 00139 //for (int i=0; i<MAXTEX; i++){ 00140 // if(mSampler[i].mOwn) { 00141 // if(mSampler[i].mTexture) 00142 // mSampler[i].mTexture->DeleteTex(); 00143 // } 00144 //} 00145 ClearUniforms(); 00146 00147 if( mShader ) { 00148 glDeleteObjectARB(mShader); 00149 mShader = 0; 00150 } 00151 vertProg = 0; 00152 fragProg = 0; 00153 mOk = 0; 00154 glUseProgramObjectARB(0); 00155 } 00156 00157 void BL_Shader::ClearUniforms() 00158 { 00159 BL_UniformVec::iterator it = mUniforms.begin(); 00160 while(it != mUniforms.end()){ 00161 delete (*it); 00162 it++; 00163 } 00164 mUniforms.clear(); 00165 00166 00167 BL_UniformVecDef::iterator itp = mPreDef.begin(); 00168 while(itp != mPreDef.end()) { 00169 delete (*itp); 00170 itp++; 00171 } 00172 mPreDef.clear(); 00173 00174 } 00175 00176 00177 BL_Uniform *BL_Shader::FindUniform(const int location) 00178 { 00179 #ifdef SORT_UNIFORMS 00180 BL_UniformVec::iterator it = mUniforms.begin(); 00181 while(it != mUniforms.end()) { 00182 if((*it)->GetLocation() == location) 00183 return (*it); 00184 it++; 00185 } 00186 #endif 00187 return 0; 00188 } 00189 00190 void BL_Shader::SetUniformfv(int location, int type, float *param,int size, bool transpose) 00191 { 00192 #ifdef SORT_UNIFORMS 00193 BL_Uniform *uni= FindUniform(location); 00194 if(uni) { 00195 memcpy(uni->getData(), param, size); 00196 uni->SetData(location, type, transpose); 00197 } 00198 else { 00199 uni = new BL_Uniform(size); 00200 memcpy(uni->getData(), param, size); 00201 00202 uni->SetData(location, type, transpose); 00203 mUniforms.push_back(uni); 00204 } 00205 mDirty = true; 00206 #endif 00207 } 00208 00209 void BL_Shader::SetUniformiv(int location, int type, int *param,int size, bool transpose) 00210 { 00211 #ifdef SORT_UNIFORMS 00212 BL_Uniform *uni= FindUniform(location); 00213 if(uni) { 00214 memcpy(uni->getData(), param, size); 00215 uni->SetData(location, type, transpose); 00216 } 00217 else { 00218 uni = new BL_Uniform(size); 00219 memcpy(uni->getData(), param, size); 00220 uni->SetData(location, type, transpose); 00221 mUniforms.push_back(uni); 00222 } 00223 mDirty = true; 00224 #endif 00225 } 00226 00227 00228 void BL_Shader::ApplyShader() 00229 { 00230 #ifdef SORT_UNIFORMS 00231 if(!mDirty) 00232 return; 00233 00234 for(unsigned int i=0; i<mUniforms.size(); i++) 00235 mUniforms[i]->Apply(this); 00236 00237 mDirty = false; 00238 #endif 00239 } 00240 00241 void BL_Shader::UnloadShader() 00242 { 00243 // 00244 } 00245 00246 00247 bool BL_Shader::LinkProgram() 00248 { 00249 int vertlen = 0, fraglen=0, proglen=0; 00250 int vertstatus=0, fragstatus=0, progstatus=0; 00251 unsigned int tmpVert=0, tmpFrag=0, tmpProg=0; 00252 int char_len=0; 00253 char *logInf =0; 00254 00255 if(mError) 00256 goto programError; 00257 00258 if(!vertProg || !fragProg){ 00259 spit("Invalid GLSL sources"); 00260 return false; 00261 } 00262 if( !GLEW_ARB_fragment_shader) { 00263 spit("Fragment shaders not supported"); 00264 return false; 00265 } 00266 if( !GLEW_ARB_vertex_shader) { 00267 spit("Vertex shaders not supported"); 00268 return false; 00269 } 00270 00271 // -- vertex shader ------------------ 00272 tmpVert = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB); 00273 glShaderSourceARB(tmpVert, 1, (const char**)&vertProg, 0); 00274 glCompileShaderARB(tmpVert); 00275 glGetObjectParameterivARB(tmpVert, GL_OBJECT_INFO_LOG_LENGTH_ARB,(GLint*) &vertlen); 00276 00277 // print info if any 00278 if( vertlen > 0 && vertlen < MAX_LOG_LEN){ 00279 logInf = (char*)MEM_mallocN(vertlen, "vert-log"); 00280 glGetInfoLogARB(tmpVert, vertlen, (GLsizei*)&char_len, logInf); 00281 if(char_len >0) { 00282 spit("---- Vertex Shader Error ----"); 00283 spit(logInf); 00284 } 00285 MEM_freeN(logInf); 00286 logInf=0; 00287 } 00288 // check for compile errors 00289 glGetObjectParameterivARB(tmpVert, GL_OBJECT_COMPILE_STATUS_ARB,(GLint*)&vertstatus); 00290 if(!vertstatus) { 00291 spit("---- Vertex shader failed to compile ----"); 00292 goto programError; 00293 } 00294 00295 // -- fragment shader ---------------- 00296 tmpFrag = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB); 00297 glShaderSourceARB(tmpFrag, 1,(const char**)&fragProg, 0); 00298 glCompileShaderARB(tmpFrag); 00299 glGetObjectParameterivARB(tmpFrag, GL_OBJECT_INFO_LOG_LENGTH_ARB, (GLint*) &fraglen); 00300 if(fraglen >0 && fraglen < MAX_LOG_LEN){ 00301 logInf = (char*)MEM_mallocN(fraglen, "frag-log"); 00302 glGetInfoLogARB(tmpFrag, fraglen,(GLsizei*) &char_len, logInf); 00303 if(char_len >0) { 00304 spit("---- Fragment Shader Error ----"); 00305 spit(logInf); 00306 } 00307 MEM_freeN(logInf); 00308 logInf=0; 00309 } 00310 00311 glGetObjectParameterivARB(tmpFrag, GL_OBJECT_COMPILE_STATUS_ARB, (GLint*) &fragstatus); 00312 if(!fragstatus){ 00313 spit("---- Fragment shader failed to compile ----"); 00314 goto programError; 00315 } 00316 00317 00318 // -- program ------------------------ 00319 // set compiled vert/frag shader & link 00320 tmpProg = glCreateProgramObjectARB(); 00321 glAttachObjectARB(tmpProg, tmpVert); 00322 glAttachObjectARB(tmpProg, tmpFrag); 00323 glLinkProgramARB(tmpProg); 00324 glGetObjectParameterivARB(tmpProg, GL_OBJECT_INFO_LOG_LENGTH_ARB, (GLint*) &proglen); 00325 glGetObjectParameterivARB(tmpProg, GL_OBJECT_LINK_STATUS_ARB, (GLint*) &progstatus); 00326 00327 00328 if(proglen > 0 && proglen < MAX_LOG_LEN) { 00329 logInf = (char*)MEM_mallocN(proglen, "prog-log"); 00330 glGetInfoLogARB(tmpProg, proglen, (GLsizei*)&char_len, logInf); 00331 if(char_len >0) { 00332 spit("---- GLSL Program ----"); 00333 spit(logInf); 00334 } 00335 MEM_freeN(logInf); 00336 logInf=0; 00337 } 00338 00339 if(!progstatus){ 00340 spit("---- GLSL program failed to link ----"); 00341 goto programError; 00342 } 00343 00344 // set 00345 mShader = tmpProg; 00346 glDeleteObjectARB(tmpVert); 00347 glDeleteObjectARB(tmpFrag); 00348 mOk = 1; 00349 mError = 0; 00350 return true; 00351 00352 programError: 00353 if(tmpVert) { 00354 glDeleteObjectARB(tmpVert); 00355 tmpVert=0; 00356 } 00357 if(tmpFrag) { 00358 glDeleteObjectARB(tmpFrag); 00359 tmpFrag=0; 00360 } 00361 00362 if(tmpProg) { 00363 glDeleteObjectARB(tmpProg); 00364 tmpProg=0; 00365 } 00366 00367 mOk = 0; 00368 mUse = 0; 00369 mError = 1; 00370 return false; 00371 } 00372 00373 const char *BL_Shader::GetVertPtr() 00374 { 00375 return vertProg?vertProg:0; 00376 } 00377 00378 const char *BL_Shader::GetFragPtr() 00379 { 00380 return fragProg?fragProg:0; 00381 } 00382 00383 void BL_Shader::SetVertPtr( char *vert ) 00384 { 00385 vertProg = vert; 00386 } 00387 00388 void BL_Shader::SetFragPtr( char *frag ) 00389 { 00390 fragProg = frag; 00391 } 00392 00393 unsigned int BL_Shader::GetProg() 00394 { 00395 return mShader; 00396 } 00397 // 00398 //const BL_Sampler* BL_Shader::GetSampler(int i) 00399 //{ 00400 // MT_assert(i<=MAXTEX); 00401 // return &mSampler[i]; 00402 //} 00403 00404 void BL_Shader::SetSampler(int loc, int unit) 00405 { 00406 if( GLEW_ARB_fragment_shader && 00407 GLEW_ARB_vertex_shader && 00408 GLEW_ARB_shader_objects 00409 ) 00410 { 00411 glUniform1iARB(loc, unit); 00412 } 00413 } 00414 // 00415 //void BL_Shader::InitializeSampler(int unit, BL_Texture* texture) 00416 //{ 00417 // MT_assert(unit<=MAXTEX); 00418 // mSampler[unit].mTexture = texture; 00419 // mSampler[unit].mLoc =-1; 00420 // mSampler[unit].mOwn = 0; 00421 //} 00422 00423 void BL_Shader::SetProg(bool enable) 00424 { 00425 if( GLEW_ARB_fragment_shader && 00426 GLEW_ARB_vertex_shader && 00427 GLEW_ARB_shader_objects 00428 ) 00429 { 00430 if( mShader != 0 && mOk && enable) { 00431 glUseProgramObjectARB(mShader); 00432 } 00433 else { 00434 glUseProgramObjectARB(0); 00435 } 00436 } 00437 } 00438 00439 void BL_Shader::Update( const RAS_MeshSlot & ms, RAS_IRasterizer* rasty ) 00440 { 00441 if(!Ok() || !mPreDef.size()) 00442 return; 00443 00444 if( GLEW_ARB_fragment_shader && 00445 GLEW_ARB_vertex_shader && 00446 GLEW_ARB_shader_objects 00447 ) 00448 { 00449 MT_Matrix4x4 model; 00450 model.setValue(ms.m_OpenGLMatrix); 00451 const MT_Matrix4x4& view = rasty->GetViewMatrix(); 00452 00453 if(mAttr==SHD_TANGENT) 00454 ms.m_mesh->SetMeshModified(true); 00455 00456 BL_UniformVecDef::iterator it; 00457 for(it = mPreDef.begin(); it!= mPreDef.end(); it++) 00458 { 00459 BL_DefUniform *uni = (*it); 00460 if(uni->mLoc == -1) continue; 00461 00462 switch (uni->mType) 00463 { 00464 case MODELMATRIX: 00465 { 00466 SetUniform(uni->mLoc, model); 00467 break; 00468 } 00469 case MODELMATRIX_TRANSPOSE: 00470 { 00471 SetUniform(uni->mLoc, model, true); 00472 break; 00473 } 00474 case MODELMATRIX_INVERSE: 00475 { 00476 model.invert(); 00477 SetUniform(uni->mLoc, model); 00478 break; 00479 } 00480 case MODELMATRIX_INVERSETRANSPOSE: 00481 { 00482 model.invert(); 00483 SetUniform(uni->mLoc, model, true); 00484 break; 00485 } 00486 case MODELVIEWMATRIX: 00487 { 00488 SetUniform(uni->mLoc, view*model); 00489 break; 00490 } 00491 00492 case MODELVIEWMATRIX_TRANSPOSE: 00493 { 00494 MT_Matrix4x4 mat(view*model); 00495 SetUniform(uni->mLoc, mat, true); 00496 break; 00497 } 00498 case MODELVIEWMATRIX_INVERSE: 00499 { 00500 MT_Matrix4x4 mat(view*model); 00501 mat.invert(); 00502 SetUniform(uni->mLoc, mat); 00503 break; 00504 } 00505 case MODELVIEWMATRIX_INVERSETRANSPOSE: 00506 { 00507 MT_Matrix4x4 mat(view*model); 00508 mat.invert(); 00509 SetUniform(uni->mLoc, mat, true); 00510 break; 00511 } 00512 case CAM_POS: 00513 { 00514 MT_Point3 pos(rasty->GetCameraPosition()); 00515 SetUniform(uni->mLoc, pos); 00516 break; 00517 } 00518 case VIEWMATRIX: 00519 { 00520 SetUniform(uni->mLoc, view); 00521 break; 00522 } 00523 case VIEWMATRIX_TRANSPOSE: 00524 { 00525 SetUniform(uni->mLoc, view, true); 00526 break; 00527 } 00528 case VIEWMATRIX_INVERSE: 00529 { 00530 MT_Matrix4x4 viewinv = view; 00531 viewinv.invert(); 00532 SetUniform(uni->mLoc, view); 00533 break; 00534 } 00535 case VIEWMATRIX_INVERSETRANSPOSE: 00536 { 00537 MT_Matrix4x4 viewinv = view; 00538 viewinv.invert(); 00539 SetUniform(uni->mLoc, view, true); 00540 break; 00541 } 00542 case CONSTANT_TIMER: 00543 { 00544 SetUniform(uni->mLoc, (float)rasty->GetTime()); 00545 break; 00546 } 00547 default: 00548 break; 00549 } 00550 } 00551 } 00552 } 00553 00554 00555 int BL_Shader::GetAttribLocation(const STR_String& name) 00556 { 00557 if( GLEW_ARB_fragment_shader && 00558 GLEW_ARB_vertex_shader && 00559 GLEW_ARB_shader_objects 00560 ) 00561 { 00562 return glGetAttribLocationARB(mShader, name.ReadPtr()); 00563 } 00564 00565 return -1; 00566 } 00567 00568 void BL_Shader::BindAttribute(const STR_String& attr, int loc) 00569 { 00570 if( GLEW_ARB_fragment_shader && 00571 GLEW_ARB_vertex_shader && 00572 GLEW_ARB_shader_objects 00573 ) 00574 { 00575 glBindAttribLocationARB(mShader, loc, attr.ReadPtr()); 00576 } 00577 } 00578 00579 int BL_Shader::GetUniformLocation(const STR_String& name) 00580 { 00581 if( GLEW_ARB_fragment_shader && 00582 GLEW_ARB_vertex_shader && 00583 GLEW_ARB_shader_objects 00584 ) 00585 { 00586 MT_assert(mShader!=0); 00587 int location = glGetUniformLocationARB(mShader, name.ReadPtr()); 00588 if(location == -1) 00589 spit("Invalid uniform value: " << name.ReadPtr() << "."); 00590 return location; 00591 } 00592 00593 return -1; 00594 } 00595 00596 void BL_Shader::SetUniform(int uniform, const MT_Tuple2& vec) 00597 { 00598 if( GLEW_ARB_fragment_shader && 00599 GLEW_ARB_vertex_shader && 00600 GLEW_ARB_shader_objects 00601 ) 00602 { 00603 float value[2]; 00604 vec.getValue(value); 00605 glUniform2fvARB(uniform, 1, value); 00606 } 00607 00608 } 00609 00610 void BL_Shader::SetUniform(int uniform, const MT_Tuple3& vec) 00611 { 00612 if( GLEW_ARB_fragment_shader && 00613 GLEW_ARB_vertex_shader && 00614 GLEW_ARB_shader_objects 00615 ) 00616 { 00617 float value[3]; 00618 vec.getValue(value); 00619 glUniform3fvARB(uniform, 1, value); 00620 } 00621 } 00622 00623 void BL_Shader::SetUniform(int uniform, const MT_Tuple4& vec) 00624 { 00625 if( GLEW_ARB_fragment_shader && 00626 GLEW_ARB_vertex_shader && 00627 GLEW_ARB_shader_objects 00628 ) 00629 { 00630 float value[4]; 00631 vec.getValue(value); 00632 glUniform4fvARB(uniform, 1, value); 00633 } 00634 } 00635 00636 void BL_Shader::SetUniform(int uniform, const unsigned int& val) 00637 { 00638 if( GLEW_ARB_fragment_shader && 00639 GLEW_ARB_vertex_shader && 00640 GLEW_ARB_shader_objects 00641 ) 00642 { 00643 glUniform1iARB(uniform, val); 00644 } 00645 } 00646 00647 void BL_Shader::SetUniform(int uniform, const int val) 00648 { 00649 if( GLEW_ARB_fragment_shader && 00650 GLEW_ARB_vertex_shader && 00651 GLEW_ARB_shader_objects 00652 ) 00653 { 00654 glUniform1iARB(uniform, val); 00655 } 00656 } 00657 00658 void BL_Shader::SetUniform(int uniform, const float& val) 00659 { 00660 if( GLEW_ARB_fragment_shader && 00661 GLEW_ARB_vertex_shader && 00662 GLEW_ARB_shader_objects 00663 ) 00664 { 00665 glUniform1fARB(uniform, val); 00666 } 00667 } 00668 00669 void BL_Shader::SetUniform(int uniform, const MT_Matrix4x4& vec, bool transpose) 00670 { 00671 if( GLEW_ARB_fragment_shader && 00672 GLEW_ARB_vertex_shader && 00673 GLEW_ARB_shader_objects 00674 ) 00675 { 00676 float value[16]; 00677 // note: getValue gives back column major as needed by OpenGL 00678 vec.getValue(value); 00679 glUniformMatrix4fvARB(uniform, 1, transpose?GL_TRUE:GL_FALSE, value); 00680 } 00681 } 00682 00683 void BL_Shader::SetUniform(int uniform, const MT_Matrix3x3& vec, bool transpose) 00684 { 00685 if( GLEW_ARB_fragment_shader && 00686 GLEW_ARB_vertex_shader && 00687 GLEW_ARB_shader_objects 00688 ) 00689 { 00690 float value[9]; 00691 value[0] = (float)vec[0][0]; value[1] = (float)vec[1][0]; value[2] = (float)vec[2][0]; 00692 value[3] = (float)vec[0][1]; value[4] = (float)vec[1][1]; value[5] = (float)vec[2][1]; 00693 value[6] = (float)vec[0][2]; value[7] = (float)vec[1][2]; value[8] = (float)vec[2][2]; 00694 glUniformMatrix3fvARB(uniform, 1, transpose?GL_TRUE:GL_FALSE, value); 00695 } 00696 } 00697 00698 void BL_Shader::SetUniform(int uniform, const float* val, int len) 00699 { 00700 if( GLEW_ARB_fragment_shader && 00701 GLEW_ARB_vertex_shader && 00702 GLEW_ARB_shader_objects 00703 ) 00704 { 00705 if(len == 2) 00706 glUniform2fvARB(uniform, 1,(GLfloat*)val); 00707 else if (len == 3) 00708 glUniform3fvARB(uniform, 1,(GLfloat*)val); 00709 else if (len == 4) 00710 glUniform4fvARB(uniform, 1,(GLfloat*)val); 00711 else 00712 MT_assert(0); 00713 } 00714 } 00715 00716 void BL_Shader::SetUniform(int uniform, const int* val, int len) 00717 { 00718 if( GLEW_ARB_fragment_shader && 00719 GLEW_ARB_vertex_shader && 00720 GLEW_ARB_shader_objects 00721 ) 00722 { 00723 if(len == 2) 00724 glUniform2ivARB(uniform, 1, (GLint*)val); 00725 else if (len == 3) 00726 glUniform3ivARB(uniform, 1, (GLint*)val); 00727 else if (len == 4) 00728 glUniform4ivARB(uniform, 1, (GLint*)val); 00729 else 00730 MT_assert(0); 00731 } 00732 } 00733 00734 #ifdef WITH_PYTHON 00735 00736 PyMethodDef BL_Shader::Methods[] = 00737 { 00738 // creation 00739 KX_PYMETHODTABLE( BL_Shader, setSource ), 00740 KX_PYMETHODTABLE( BL_Shader, delSource ), 00741 KX_PYMETHODTABLE( BL_Shader, getVertexProg ), 00742 KX_PYMETHODTABLE( BL_Shader, getFragmentProg ), 00743 KX_PYMETHODTABLE( BL_Shader, setNumberOfPasses ), 00744 KX_PYMETHODTABLE( BL_Shader, validate), 00746 KX_PYMETHODTABLE( BL_Shader, isValid), 00747 KX_PYMETHODTABLE( BL_Shader, setUniform1f ), 00748 KX_PYMETHODTABLE( BL_Shader, setUniform2f ), 00749 KX_PYMETHODTABLE( BL_Shader, setUniform3f ), 00750 KX_PYMETHODTABLE( BL_Shader, setUniform4f ), 00751 KX_PYMETHODTABLE( BL_Shader, setUniform1i ), 00752 KX_PYMETHODTABLE( BL_Shader, setUniform2i ), 00753 KX_PYMETHODTABLE( BL_Shader, setUniform3i ), 00754 KX_PYMETHODTABLE( BL_Shader, setUniform4i ), 00755 KX_PYMETHODTABLE( BL_Shader, setAttrib ), 00756 00757 KX_PYMETHODTABLE( BL_Shader, setUniformfv ), 00758 KX_PYMETHODTABLE( BL_Shader, setUniformiv ), 00759 KX_PYMETHODTABLE( BL_Shader, setUniformDef ), 00760 00761 KX_PYMETHODTABLE( BL_Shader, setSampler ), 00762 KX_PYMETHODTABLE( BL_Shader, setUniformMatrix4 ), 00763 KX_PYMETHODTABLE( BL_Shader, setUniformMatrix3 ), 00764 00765 {NULL,NULL} //Sentinel 00766 }; 00767 00768 PyAttributeDef BL_Shader::Attributes[] = { 00769 { NULL } //Sentinel 00770 }; 00771 00772 PyTypeObject BL_Shader::Type = { 00773 PyVarObject_HEAD_INIT(NULL, 0) 00774 "BL_Shader", 00775 sizeof(PyObjectPlus_Proxy), 00776 0, 00777 py_base_dealloc, 00778 0, 00779 0, 00780 0, 00781 0, 00782 py_base_repr, 00783 0,0,0,0,0,0,0,0,0, 00784 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, 00785 0,0,0,0,0,0,0, 00786 Methods, 00787 0, 00788 0, 00789 &PyObjectPlus::Type, 00790 0,0,0,0,0,0, 00791 py_base_new 00792 }; 00793 00794 KX_PYMETHODDEF_DOC( BL_Shader, setSource," setSource(vertexProgram, fragmentProgram)" ) 00795 { 00796 if(mShader !=0 && mOk ) 00797 { 00798 // already set... 00799 Py_RETURN_NONE; 00800 } 00801 char *v,*f; 00802 int apply=0; 00803 if( PyArg_ParseTuple(args, "ssi:setSource", &v, &f, &apply) ) 00804 { 00805 vertProg = v; 00806 fragProg = f; 00807 if( LinkProgram() ) { 00808 glUseProgramObjectARB( mShader ); 00809 mUse = apply!=0; 00810 Py_RETURN_NONE; 00811 } 00812 vertProg = 0; 00813 fragProg = 0; 00814 mUse = 0; 00815 Py_RETURN_NONE; 00816 } 00817 return NULL; 00818 } 00819 00820 00821 KX_PYMETHODDEF_DOC( BL_Shader, delSource, "delSource( )" ) 00822 { 00823 ClearUniforms(); 00824 glUseProgramObjectARB(0); 00825 00826 glDeleteObjectARB(mShader); 00827 mShader = 0; 00828 mOk = 0; 00829 mUse = 0; 00830 Py_RETURN_NONE; 00831 } 00832 00833 KX_PYMETHODDEF_DOC( BL_Shader, isValid, "isValid()" ) 00834 { 00835 return PyLong_FromSsize_t( ( mShader !=0 && mOk ) ); 00836 } 00837 00838 KX_PYMETHODDEF_DOC( BL_Shader, getVertexProg ,"getVertexProg( )" ) 00839 { 00840 return PyUnicode_FromString(vertProg?vertProg:""); 00841 } 00842 00843 KX_PYMETHODDEF_DOC( BL_Shader, getFragmentProg ,"getFragmentProg( )" ) 00844 { 00845 return PyUnicode_FromString(fragProg?fragProg:""); 00846 } 00847 00848 KX_PYMETHODDEF_DOC( BL_Shader, validate, "validate()") 00849 { 00850 if(mError) { 00851 Py_RETURN_NONE; 00852 } 00853 if(mShader==0) { 00854 PyErr_SetString(PyExc_TypeError, "shader.validate(): BL_Shader, invalid shader object"); 00855 return NULL; 00856 } 00857 int stat = 0; 00858 glValidateProgramARB(mShader); 00859 glGetObjectParameterivARB(mShader, GL_OBJECT_VALIDATE_STATUS_ARB,(GLint*) &stat); 00860 00861 00862 if(stat > 0 && stat < MAX_LOG_LEN) { 00863 int char_len=0; 00864 char *logInf = (char*)MEM_mallocN(stat, "validate-log"); 00865 00866 glGetInfoLogARB(mShader, stat,(GLsizei*) &char_len, logInf); 00867 if(char_len >0) { 00868 spit("---- GLSL Validation ----"); 00869 spit(logInf); 00870 } 00871 MEM_freeN(logInf); 00872 logInf=0; 00873 } 00874 Py_RETURN_NONE; 00875 } 00876 00877 00878 KX_PYMETHODDEF_DOC( BL_Shader, setSampler, "setSampler(name, index)" ) 00879 { 00880 if(mError) { 00881 Py_RETURN_NONE; 00882 } 00883 00884 const char *uniform=""; 00885 int index=-1; 00886 if(PyArg_ParseTuple(args, "si:setSampler", &uniform, &index)) 00887 { 00888 int loc = GetUniformLocation(uniform); 00889 if(loc != -1) { 00890 if(index >= MAXTEX || index < 0) 00891 spit("Invalid texture sample index: " << index); 00892 00893 #ifdef SORT_UNIFORMS 00894 SetUniformiv(loc, BL_Uniform::UNI_INT, &index, (sizeof(int)) ); 00895 #else 00896 SetUniform(loc, index); 00897 #endif 00898 //if(index <= MAXTEX) 00899 // mSampler[index].mLoc = loc; 00900 //else 00901 // spit("Invalid texture sample index: " << index); 00902 } 00903 Py_RETURN_NONE; 00904 } 00905 return NULL; 00906 } 00907 00908 KX_PYMETHODDEF_DOC( BL_Shader, setNumberOfPasses, "setNumberOfPasses( max-pass )" ) 00909 { 00910 int pass = 1; 00911 if(!PyArg_ParseTuple(args, "i:setNumberOfPasses", &pass)) 00912 return NULL; 00913 00914 mPass = 1; 00915 Py_RETURN_NONE; 00916 } 00917 00919 KX_PYMETHODDEF_DOC( BL_Shader, setUniform1f, "setUniform1f(name, fx)" ) 00920 { 00921 if(mError) { 00922 Py_RETURN_NONE; 00923 } 00924 00925 const char *uniform=""; 00926 float value=0; 00927 if(PyArg_ParseTuple(args, "sf:setUniform1f", &uniform, &value )) 00928 { 00929 int loc = GetUniformLocation(uniform); 00930 if(loc != -1) 00931 { 00932 #ifdef SORT_UNIFORMS 00933 SetUniformfv(loc, BL_Uniform::UNI_FLOAT, &value, sizeof(float)); 00934 #else 00935 SetUniform( loc, (float)value ); 00936 #endif 00937 } 00938 Py_RETURN_NONE; 00939 } 00940 return NULL; 00941 } 00942 00943 00944 KX_PYMETHODDEF_DOC( BL_Shader, setUniform2f , "setUniform2f(name, fx, fy)") 00945 { 00946 if(mError) { 00947 Py_RETURN_NONE; 00948 } 00949 const char *uniform=""; 00950 float array[2]={ 0,0 }; 00951 if(PyArg_ParseTuple(args, "sff:setUniform2f", &uniform, &array[0],&array[1] )) 00952 { 00953 int loc = GetUniformLocation(uniform); 00954 if(loc != -1) 00955 { 00956 #ifdef SORT_UNIFORMS 00957 SetUniformfv(loc, BL_Uniform::UNI_FLOAT2, array, (sizeof(float)*2) ); 00958 #else 00959 SetUniform(loc, array, 2); 00960 #endif 00961 } 00962 Py_RETURN_NONE; 00963 } 00964 return NULL; 00965 } 00966 00967 00968 KX_PYMETHODDEF_DOC( BL_Shader, setUniform3f, "setUniform3f(name, fx,fy,fz) ") 00969 { 00970 if(mError) { 00971 Py_RETURN_NONE; 00972 } 00973 const char *uniform=""; 00974 float array[3]={0,0,0}; 00975 if(PyArg_ParseTuple(args, "sfff:setUniform3f", &uniform, &array[0],&array[1],&array[2])) 00976 { 00977 int loc = GetUniformLocation(uniform); 00978 if(loc != -1) 00979 { 00980 #ifdef SORT_UNIFORMS 00981 SetUniformfv(loc, BL_Uniform::UNI_FLOAT3, array, (sizeof(float)*3) ); 00982 #else 00983 SetUniform(loc, array, 3); 00984 #endif 00985 } 00986 Py_RETURN_NONE; 00987 00988 } 00989 return NULL; 00990 } 00991 00992 00993 KX_PYMETHODDEF_DOC( BL_Shader, setUniform4f, "setUniform4f(name, fx,fy,fz, fw) ") 00994 { 00995 if(mError) { 00996 Py_RETURN_NONE; 00997 } 00998 const char *uniform=""; 00999 float array[4]={0,0,0,0}; 01000 if(PyArg_ParseTuple(args, "sffff:setUniform4f", &uniform, &array[0],&array[1],&array[2], &array[3])) 01001 { 01002 int loc = GetUniformLocation(uniform); 01003 if(loc != -1) 01004 { 01005 #ifdef SORT_UNIFORMS 01006 SetUniformfv(loc, BL_Uniform::UNI_FLOAT4, array, (sizeof(float)*4) ); 01007 #else 01008 SetUniform(loc, array, 4); 01009 #endif 01010 } 01011 Py_RETURN_NONE; 01012 } 01013 return NULL; 01014 } 01015 01016 01017 KX_PYMETHODDEF_DOC( BL_Shader, setUniform1i, "setUniform1i(name, ix)" ) 01018 { 01019 if(mError) { 01020 Py_RETURN_NONE; 01021 } 01022 const char *uniform=""; 01023 int value=0; 01024 if(PyArg_ParseTuple(args, "si:setUniform1i", &uniform, &value )) 01025 { 01026 int loc = GetUniformLocation(uniform); 01027 if(loc != -1) 01028 { 01029 #ifdef SORT_UNIFORMS 01030 SetUniformiv(loc, BL_Uniform::UNI_INT, &value, sizeof(int)); 01031 #else 01032 SetUniform(loc, (int)value); 01033 #endif 01034 } 01035 Py_RETURN_NONE; 01036 } 01037 return NULL; 01038 } 01039 01040 01041 KX_PYMETHODDEF_DOC( BL_Shader, setUniform2i , "setUniform2i(name, ix, iy)") 01042 { 01043 if(mError) { 01044 Py_RETURN_NONE; 01045 } 01046 const char *uniform=""; 01047 int array[2]={ 0,0 }; 01048 if(PyArg_ParseTuple(args, "sii:setUniform2i", &uniform, &array[0],&array[1] )) 01049 { 01050 int loc = GetUniformLocation(uniform); 01051 if(loc != -1) 01052 { 01053 #ifdef SORT_UNIFORMS 01054 SetUniformiv(loc, BL_Uniform::UNI_INT2, array, sizeof(int)*2); 01055 #else 01056 SetUniform(loc, array, 2); 01057 #endif 01058 } 01059 Py_RETURN_NONE; 01060 } 01061 return NULL; 01062 } 01063 01064 01065 KX_PYMETHODDEF_DOC( BL_Shader, setUniform3i, "setUniform3i(name, ix,iy,iz) ") 01066 { 01067 if(mError) { 01068 Py_RETURN_NONE; 01069 } 01070 01071 const char *uniform=""; 01072 int array[3]={0,0,0}; 01073 if(PyArg_ParseTuple(args, "siii:setUniform3i", &uniform, &array[0],&array[1],&array[2])) 01074 { 01075 int loc = GetUniformLocation(uniform); 01076 if(loc != -1) 01077 { 01078 #ifdef SORT_UNIFORMS 01079 SetUniformiv(loc, BL_Uniform::UNI_INT3, array, sizeof(int)*3); 01080 #else 01081 SetUniform(loc, array, 3); 01082 #endif 01083 } 01084 Py_RETURN_NONE; 01085 } 01086 return NULL; 01087 } 01088 01089 KX_PYMETHODDEF_DOC( BL_Shader, setUniform4i, "setUniform4i(name, ix,iy,iz, iw) ") 01090 { 01091 if(mError) { 01092 Py_RETURN_NONE; 01093 } 01094 const char *uniform=""; 01095 int array[4]={0,0,0, 0}; 01096 if(PyArg_ParseTuple(args, "siiii:setUniform4i", &uniform, &array[0],&array[1],&array[2], &array[3] )) 01097 { 01098 int loc = GetUniformLocation(uniform); 01099 if(loc != -1) 01100 { 01101 #ifdef SORT_UNIFORMS 01102 SetUniformiv(loc, BL_Uniform::UNI_INT4, array, sizeof(int)*4); 01103 #else 01104 SetUniform(loc, array, 4); 01105 #endif 01106 } 01107 Py_RETURN_NONE; 01108 } 01109 return NULL; 01110 } 01111 01112 KX_PYMETHODDEF_DOC( BL_Shader, setUniformfv , "setUniformfv( float (list2 or list3 or list4) )") 01113 { 01114 if(mError) { 01115 Py_RETURN_NONE; 01116 } 01117 const char *uniform = ""; 01118 PyObject *listPtr =0; 01119 float array_data[4] = {0.f,0.f,0.f,0.f}; 01120 01121 if(PyArg_ParseTuple(args, "sO:setUniformfv", &uniform, &listPtr)) 01122 { 01123 int loc = GetUniformLocation(uniform); 01124 if(loc != -1) 01125 { 01126 if(PySequence_Check(listPtr)) 01127 { 01128 unsigned int list_size = PySequence_Size(listPtr); 01129 01130 for(unsigned int i=0; (i<list_size && i<4); i++) 01131 { 01132 PyObject *item = PySequence_GetItem(listPtr, i); 01133 array_data[i] = (float)PyFloat_AsDouble(item); 01134 Py_DECREF(item); 01135 } 01136 01137 switch(list_size) 01138 { 01139 case 2: 01140 { 01141 float array2[2] = { array_data[0],array_data[1] }; 01142 #ifdef SORT_UNIFORMS 01143 SetUniformfv(loc, BL_Uniform::UNI_FLOAT2, array2, sizeof(float)*2); 01144 #else 01145 SetUniform(loc, array2, 2); 01146 #endif 01147 Py_RETURN_NONE; 01148 } break; 01149 case 3: 01150 { 01151 float array3[3] = { array_data[0],array_data[1],array_data[2] }; 01152 #ifdef SORT_UNIFORMS 01153 SetUniformfv(loc, BL_Uniform::UNI_FLOAT3, array3, sizeof(float)*3); 01154 #else 01155 SetUniform(loc, array3, 3); 01156 #endif 01157 Py_RETURN_NONE; 01158 }break; 01159 case 4: 01160 { 01161 float array4[4] = { array_data[0],array_data[1],array_data[2],array_data[3] }; 01162 #ifdef SORT_UNIFORMS 01163 SetUniformfv(loc, BL_Uniform::UNI_FLOAT4, array4, sizeof(float)*4); 01164 #else 01165 SetUniform(loc, array4, 4); 01166 #endif 01167 Py_RETURN_NONE; 01168 }break; 01169 default: 01170 { 01171 PyErr_SetString(PyExc_TypeError, "shader.setUniform4i(name, ix,iy,iz, iw): BL_Shader. invalid list size"); 01172 return NULL; 01173 }break; 01174 } 01175 } 01176 } 01177 } 01178 return NULL; 01179 } 01180 01181 KX_PYMETHODDEF_DOC( BL_Shader, setUniformiv, "setUniformiv( uniform_name, (list2 or list3 or list4) )") 01182 { 01183 if(mError) { 01184 Py_RETURN_NONE; 01185 } 01186 const char *uniform = ""; 01187 PyObject *listPtr =0; 01188 int array_data[4] = {0,0,0,0}; 01189 01190 if(!PyArg_ParseTuple(args, "sO:setUniformiv", &uniform, &listPtr)) 01191 return NULL; 01192 01193 int loc = GetUniformLocation(uniform); 01194 01195 if(loc == -1) { 01196 PyErr_SetString(PyExc_TypeError, "shader.setUniformiv(...): BL_Shader, first string argument is not a valid uniform value"); 01197 return NULL; 01198 } 01199 01200 if(!PySequence_Check(listPtr)) { 01201 PyErr_SetString(PyExc_TypeError, "shader.setUniformiv(...): BL_Shader, second argument is not a sequence"); 01202 return NULL; 01203 } 01204 01205 unsigned int list_size = PySequence_Size(listPtr); 01206 01207 for(unsigned int i=0; (i<list_size && i<4); i++) 01208 { 01209 PyObject *item = PySequence_GetItem(listPtr, i); 01210 array_data[i] = PyLong_AsSsize_t(item); 01211 Py_DECREF(item); 01212 } 01213 01214 if(PyErr_Occurred()) { 01215 PyErr_SetString(PyExc_TypeError, "shader.setUniformiv(...): BL_Shader, one or more values in the list is not an int"); 01216 return NULL; 01217 } 01218 01219 /* Sanity checks done! */ 01220 01221 switch(list_size) 01222 { 01223 case 2: 01224 { 01225 int array2[2] = { array_data[0],array_data[1]}; 01226 #ifdef SORT_UNIFORMS 01227 SetUniformiv(loc, BL_Uniform::UNI_INT2, array2, sizeof(int)*2); 01228 #else 01229 SetUniform(loc, array2, 2); 01230 #endif 01231 Py_RETURN_NONE; 01232 } break; 01233 case 3: 01234 { 01235 int array3[3] = { array_data[0],array_data[1],array_data[2] }; 01236 #ifdef SORT_UNIFORMS 01237 SetUniformiv(loc, BL_Uniform::UNI_INT3, array3, sizeof(int)*3); 01238 01239 #else 01240 SetUniform(loc, array3, 3); 01241 #endif 01242 Py_RETURN_NONE; 01243 }break; 01244 case 4: 01245 { 01246 int array4[4] = { array_data[0],array_data[1],array_data[2],array_data[3] }; 01247 #ifdef SORT_UNIFORMS 01248 SetUniformiv(loc, BL_Uniform::UNI_INT4, array4, sizeof(int)*4); 01249 01250 #else 01251 SetUniform(loc, array4, 4); 01252 #endif 01253 Py_RETURN_NONE; 01254 }break; 01255 default: 01256 { 01257 PyErr_SetString(PyExc_TypeError, "shader.setUniformiv(...): BL_Shader, second argument, invalid list size, expected an int list between 2 and 4"); 01258 return NULL; 01259 }break; 01260 } 01261 01262 Py_RETURN_NONE; 01263 } 01264 01265 01266 KX_PYMETHODDEF_DOC( BL_Shader, setUniformMatrix4, 01267 "setUniformMatrix4(uniform_name, mat-4x4, transpose(row-major=true, col-major=false)" ) 01268 { 01269 if(mError) { 01270 Py_RETURN_NONE; 01271 } 01272 01273 float matr[16] = { 01274 1,0,0,0, 01275 0,1,0,0, 01276 0,0,1,0, 01277 0,0,0,1 01278 }; 01279 01280 const char *uniform=""; 01281 PyObject *matrix=0; 01282 int transp=0; // python use column major by default, so no transpose.... 01283 01284 if(!PyArg_ParseTuple(args, "sO|i:setUniformMatrix4",&uniform, &matrix,&transp)) 01285 return NULL; 01286 01287 int loc = GetUniformLocation(uniform); 01288 01289 if(loc == -1) { 01290 PyErr_SetString(PyExc_TypeError, "shader.setUniformMatrix4(...): BL_Shader, first string argument is not a valid uniform value"); 01291 return NULL; 01292 } 01293 01294 MT_Matrix4x4 mat; 01295 01296 if (!PyMatTo(matrix, mat)) { 01297 PyErr_SetString(PyExc_TypeError, "shader.setUniformMatrix4(...): BL_Shader, second argument cannot be converted into a 4x4 matrix"); 01298 return NULL; 01299 } 01300 01301 /* Sanity checks done! */ 01302 01303 #ifdef SORT_UNIFORMS 01304 mat.getValue(matr); 01305 SetUniformfv(loc, BL_Uniform::UNI_MAT4, matr, (sizeof(float)*16), (transp!=0) ); 01306 #else 01307 SetUniform(loc,mat,(transp!=0)); 01308 #endif 01309 Py_RETURN_NONE; 01310 } 01311 01312 01313 KX_PYMETHODDEF_DOC( BL_Shader, setUniformMatrix3, 01314 "setUniformMatrix3(uniform_name, list[3x3], transpose(row-major=true, col-major=false)" ) 01315 { 01316 if(mError) { 01317 Py_RETURN_NONE; 01318 } 01319 01320 float matr[9] = { 01321 1,0,0, 01322 0,1,0, 01323 0,0,1, 01324 }; 01325 01326 const char *uniform=""; 01327 PyObject *matrix=0; 01328 int transp=0; // python use column major by default, so no transpose.... 01329 if(!PyArg_ParseTuple(args, "sO|i:setUniformMatrix3",&uniform, &matrix,&transp)) 01330 return NULL; 01331 01332 int loc = GetUniformLocation(uniform); 01333 01334 if(loc == -1) { 01335 PyErr_SetString(PyExc_TypeError, "shader.setUniformMatrix3(...): BL_Shader, first string argument is not a valid uniform value"); 01336 return NULL; 01337 } 01338 01339 01340 MT_Matrix3x3 mat; 01341 01342 if (!PyMatTo(matrix, mat)) { 01343 PyErr_SetString(PyExc_TypeError, "shader.setUniformMatrix3(...): BL_Shader, second argument cannot be converted into a 3x3 matrix"); 01344 return NULL; 01345 } 01346 01347 01348 #ifdef SORT_UNIFORMS 01349 mat.getValue(matr); 01350 SetUniformfv(loc, BL_Uniform::UNI_MAT3, matr, (sizeof(float)*9), (transp!=0) ); 01351 #else 01352 SetUniform(loc,mat,(transp!=0)); 01353 #endif 01354 Py_RETURN_NONE; 01355 } 01356 01357 KX_PYMETHODDEF_DOC( BL_Shader, setAttrib, "setAttrib(enum)" ) 01358 { 01359 if(mError) { 01360 Py_RETURN_NONE; 01361 } 01362 01363 int attr=0; 01364 01365 if(!PyArg_ParseTuple(args, "i:setAttrib", &attr)) 01366 return NULL; 01367 01368 attr= SHD_TANGENT; /* user input is ignored for now, there is only 1 attr */ 01369 01370 if(mShader==0) { 01371 PyErr_SetString(PyExc_ValueError, "shader.setAttrib() BL_Shader, invalid shader object"); 01372 return NULL; 01373 } 01374 01375 mAttr= attr; 01376 glUseProgramObjectARB(mShader); 01377 glBindAttribLocationARB(mShader, mAttr, "Tangent"); 01378 Py_RETURN_NONE; 01379 } 01380 01381 01382 KX_PYMETHODDEF_DOC( BL_Shader, setUniformDef, "setUniformDef(name, enum)" ) 01383 { 01384 if(mError) { 01385 Py_RETURN_NONE; 01386 } 01387 01388 const char *uniform=""; 01389 int nloc=0; 01390 if(PyArg_ParseTuple(args, "si:setUniformDef",&uniform, &nloc)) 01391 { 01392 int loc = GetUniformLocation(uniform); 01393 if(loc != -1) 01394 { 01395 bool defined = false; 01396 BL_UniformVecDef::iterator it = mPreDef.begin(); 01397 while(it != mPreDef.end()) { 01398 if((*it)->mLoc == loc) { 01399 defined = true; 01400 break; 01401 } 01402 it++; 01403 } 01404 if(defined) 01405 { 01406 Py_RETURN_NONE; 01407 } 01408 01409 BL_DefUniform *uni = new BL_DefUniform(); 01410 uni->mLoc = loc; 01411 uni->mType = nloc; 01412 uni->mFlag = 0; 01413 mPreDef.push_back(uni); 01414 Py_RETURN_NONE; 01415 } 01416 } 01417 return NULL; 01418 } 01419 01420 #endif // WITH_PYTHON 01421 01422 // eof