Blender  V2.59
BL_Shader.cpp
Go to the documentation of this file.
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[7] = (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         if(mShader==0) {
01369                 PyErr_SetString(PyExc_ValueError, "shader.setAttrib() BL_Shader, invalid shader object");
01370                 return NULL;
01371         }
01372         mAttr=SHD_TANGENT; /* What the heck is going on here - attr is just ignored??? - Campbell */
01373         glUseProgramObjectARB(mShader);
01374         glBindAttribLocationARB(mShader, mAttr, "Tangent");
01375         Py_RETURN_NONE;
01376 }
01377 
01378 
01379 KX_PYMETHODDEF_DOC( BL_Shader, setUniformDef, "setUniformDef(name, enum)" )
01380 {
01381         if(mError) {
01382                 Py_RETURN_NONE;
01383         }
01384 
01385         const char *uniform="";
01386         int nloc=0;
01387         if(PyArg_ParseTuple(args, "si:setUniformDef",&uniform, &nloc))
01388         {
01389                 int loc = GetUniformLocation(uniform);
01390                 if(loc != -1)
01391                 {
01392                         bool defined = false;
01393                         BL_UniformVecDef::iterator it = mPreDef.begin();
01394                         while(it != mPreDef.end()) {
01395                                 if((*it)->mLoc == loc) {
01396                                         defined = true;
01397                                         break;
01398                                 }
01399                                 it++;
01400                         }
01401                         if(defined)
01402                         {
01403                                 Py_RETURN_NONE;
01404                         }
01405 
01406                         BL_DefUniform *uni = new BL_DefUniform();
01407                         uni->mLoc = loc;
01408                         uni->mType = nloc;
01409                         uni->mFlag = 0;
01410                         mPreDef.push_back(uni);
01411                         Py_RETURN_NONE;
01412                 }
01413         }
01414         return NULL;
01415 }
01416 
01417 #endif // WITH_PYTHON
01418 
01419 // eof