ec804228f6171fb4855ddfec266b85fb35123c62
[blender.git] / source / gameengine / Ketsji / BL_Shader.cpp
1 // ------------------------------------
2 #ifdef WIN32
3 #include <windows.h>
4 #endif // WIN32
5 #ifdef __APPLE__
6 #include <OpenGL/gl.h>
7 #include <OpenGL/glu.h>
8 #else
9 #include <GL/gl.h>
10 #include <GL/glu.h>
11 #endif
12
13
14 #include <iostream>
15 #include "BL_Shader.h"
16 #include "BL_Material.h"
17
18 #include "MT_assert.h"
19 #include "MT_Matrix4x4.h"
20 #include "MT_Matrix3x3.h"
21 #include "KX_PyMath.h"
22
23 #include "RAS_GLExtensionManager.h"
24
25 //using namespace bgl;
26 #define spit(x) std::cout << x << std::endl;
27
28
29 const bool BL_Shader::Ok()const
30 {
31         return (mShader !=0 && mOk && mUse);
32 }
33
34 BL_Shader::BL_Shader(int n, PyTypeObject *T)
35 :       PyObjectPlus(T),
36         mShader(0),
37         mVert(0),
38         mFrag(0),
39         mPass(1),
40         vertProg(""),
41         fragProg(""),
42         mOk(0),
43         mUse(0)
44 {
45         // if !RAS_EXT_support._ARB_shader_objects this class will not be used
46
47         mBlending.src   = -1;
48         mBlending.dest  = -1;
49         mBlending.const_color[0] = 0.0;
50         mBlending.const_color[1] = 0.0;
51         mBlending.const_color[2] = 0.0;
52         mBlending.const_color[3] = 1.0;
53
54         for (int i=0; i<MAXTEX; i++)
55         {
56                 mSampler[i].type = 0;
57                 mSampler[i].pass = 0;
58                 mSampler[i].unit = -1;
59                 mSampler[i].loc  = -1;
60                 mSampler[i].glTexture =0;
61         }
62 }
63
64 using namespace bgl;
65
66 BL_Shader::~BL_Shader()
67 {
68 #ifdef GL_ARB_shader_objects
69         if( mShader ) {
70                 glDeleteObjectARB(mShader);
71                 mShader = 0;
72         }
73         if( mFrag ) {
74                 glDeleteObjectARB(mFrag);
75                 mFrag = 0;
76         }
77         if( mVert ) {
78                 glDeleteObjectARB(mVert);
79                 mVert           = 0;
80         }
81
82         vertProg        = 0;
83         fragProg        = 0;
84         mOk                     = 0;
85
86         glUseProgramObjectARB(0);
87 #endif//GL_ARB_shader_objects
88 }
89
90
91 bool BL_Shader::LinkProgram()
92 {
93 #ifdef GL_ARB_shader_objects
94         if(!vertProg || !fragProg ) return false;
95
96         int vertstat,fragstat,progstat;
97         
98         // vertex prog
99         unsigned int vert = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
100         glShaderSourceARB(vert, 1, (const char**) &vertProg, 0);
101         glCompileShaderARB(vert);
102         glGetObjectParameterivARB(vert, GL_OBJECT_INFO_LOG_LENGTH_ARB, &vertstat);
103         // errors if any
104         printInfo(vert);
105         
106         // fragment prog
107         unsigned int frag = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
108         glShaderSourceARB(frag, 1,(const char**) &fragProg, 0);
109         glCompileShaderARB(frag);
110         glGetObjectParameterivARB(frag, GL_OBJECT_INFO_LOG_LENGTH_ARB, &fragstat);
111         // errors if any
112         printInfo(frag);
113         
114         if(!vertstat || !fragstat) return false;
115
116         // main prog
117         unsigned int prog = glCreateProgramObjectARB();
118         glAttachObjectARB(prog,vert);
119         glAttachObjectARB(prog,frag);
120
121         glLinkProgramARB(prog);
122         glGetObjectParameterivARB(prog, GL_OBJECT_INFO_LOG_LENGTH_ARB, &progstat);
123         // info on how it compiled &| linked
124         printInfo(prog);
125
126         if(!progstat)
127                 return false;
128
129         // assign
130         mShader = prog;
131         mVert   = vert;
132         mFrag   = frag;
133         mOk             = 1;
134         return true;
135 #else
136         return false;
137 #endif//GL_ARB_shader_objects
138 }
139
140 void BL_Shader::printInfo(unsigned int pr)
141 {
142 #ifdef GL_ARB_shader_objects
143 #ifndef GLcharARB
144 typedef char GLcharARB;
145 #endif  
146 int length=0;
147         glGetObjectParameterivARB(pr, GL_OBJECT_INFO_LOG_LENGTH_ARB, &length);
148
149         if(length > 1)
150         {
151                 GLcharARB*logger = (GLcharARB*)malloc(sizeof(GLcharARB)*length);
152                 int chars=0;
153                 
154                 glGetInfoLogARB(pr, length, &chars, logger);
155                 if(chars>0)
156                         std::cout << (logger) << std::endl;
157
158                 if(logger)
159                         free(logger);
160         }
161 #endif//GL_ARB_shader_objects
162 }
163
164 char *BL_Shader::GetVertPtr()
165 {
166         return vertProg?vertProg:0;
167 }
168
169 char *BL_Shader::GetFragPtr()
170 {
171         return fragProg?fragProg:0;
172 }
173
174 void BL_Shader::SetVertPtr( char *vert )
175 {
176         vertProg = vert;
177 }
178
179 void BL_Shader::SetFragPtr( char *frag )
180 {
181         fragProg = frag;
182 }
183
184 unsigned int BL_Shader::GetProg()
185
186         return mShader;
187 }
188
189 unsigned int BL_Shader::GetVertexShader()
190
191         return mVert;  
192 }
193
194 unsigned int BL_Shader::GetFragmentShader()
195
196         return mFrag;  
197 }
198
199 const uSampler* BL_Shader::getSampler(int i)
200 {
201         MT_assert(i<=MAXTEX);
202         return &mSampler[i];
203 }
204
205 const uBlending *BL_Shader::getBlending( int pass )
206 {
207         return &mBlending;
208 }
209
210
211
212 void BL_Shader::InitializeSampler(
213         int type,
214         int unit,
215         int pass,
216         unsigned int texture)
217 {
218         MT_assert(unit<=MAXTEX);
219         mSampler[unit].glTexture = texture;
220         mSampler[unit].loc =-1;
221         mSampler[unit].pass=0;
222         mSampler[unit].type=type;
223         mSampler[unit].unit=unit;
224 }
225
226 PyObject* BL_Shader::_getattr(const STR_String& attr)
227 {
228         _getattr_up(PyObjectPlus);
229 }
230
231
232 PyMethodDef BL_Shader::Methods[] = 
233 {
234         // creation
235         KX_PYMETHODTABLE( BL_Shader, setSource ),
236         KX_PYMETHODTABLE( BL_Shader, delSource ),
237         KX_PYMETHODTABLE( BL_Shader, getVertexProg ),
238         KX_PYMETHODTABLE( BL_Shader, getFragmentProg ),
239         KX_PYMETHODTABLE( BL_Shader, setNumberOfPasses ),
240         KX_PYMETHODTABLE( BL_Shader, validate),
241         /// access functions
242         KX_PYMETHODTABLE( BL_Shader, isValid),
243         KX_PYMETHODTABLE( BL_Shader, setUniform1f ),
244         KX_PYMETHODTABLE( BL_Shader, setUniform2f ),
245         KX_PYMETHODTABLE( BL_Shader, setUniform3f ),
246         KX_PYMETHODTABLE( BL_Shader, setUniform4f ),
247         KX_PYMETHODTABLE( BL_Shader, setUniform1i ),
248         KX_PYMETHODTABLE( BL_Shader, setUniform2i ),
249         KX_PYMETHODTABLE( BL_Shader, setUniform3i ),
250         KX_PYMETHODTABLE( BL_Shader, setUniform4i ),
251
252         KX_PYMETHODTABLE( BL_Shader, setUniformfv ),
253         KX_PYMETHODTABLE( BL_Shader, setUniformiv ),
254
255         KX_PYMETHODTABLE( BL_Shader, setSampler  ),
256         KX_PYMETHODTABLE( BL_Shader, setUniformMatrix4 ),
257         KX_PYMETHODTABLE( BL_Shader, setUniformMatrix3 ),
258         // KX_PYMETHODTABLE( BL_Shader, setBlending ),
259
260         {NULL,NULL} //Sentinel
261 };
262
263
264 PyTypeObject BL_Shader::Type = {
265         PyObject_HEAD_INIT(&PyType_Type)
266                 0,
267                 "BL_Shader",
268                 sizeof(BL_Shader),
269                 0,
270                 PyDestructor,
271                 0,
272                 __getattr,
273                 __setattr,
274                 0,
275                 __repr,
276                 0
277 };
278
279
280 PyParentObject BL_Shader::Parents[] = {
281         &PyObjectPlus::Type,
282         &BL_Shader::Type,
283         NULL
284 };
285
286
287 KX_PYMETHODDEF_DOC( BL_Shader, setSource," setSource(vertexProgram, fragmentProgram)" )
288 {
289 #ifdef GL_ARB_shader_objects
290         if(mShader !=0 && mOk  )
291         {
292                 // already set...
293                 Py_Return;
294         }
295
296         char *v,*f;
297         int apply=0;
298         if( PyArg_ParseTuple(args, "ssi", &v, &f, &apply) )
299         {
300                 vertProg = v;
301                 fragProg = f;
302                 if( LinkProgram() )
303                 {
304                         glUseProgramObjectARB( mShader );
305                         mUse = apply!=0;
306                         Py_Return;
307                 }
308                 else
309                 {
310                         vertProg = 0;
311                         fragProg = 0;
312                         mUse = 0;
313                         glUseProgramObjectARB( 0 );
314                 }
315         }
316         return NULL;
317 #else
318         Py_Return;
319 #endif
320 }
321
322
323 KX_PYMETHODDEF_DOC( BL_Shader, delSource, "delSource( )" )
324 {
325 #ifdef GL_ARB_shader_objects
326         glDeleteObjectARB(mShader);
327         glDeleteObjectARB(mFrag);
328         glDeleteObjectARB(mVert);
329         mShader         = 0;
330         mFrag           = 0;
331         mVert           = 0;
332         vertProg        = 0;
333         fragProg        = 0;
334         mOk                     = 0;
335         mUse            = 0;
336         glUseProgramObjectARB(0);
337 #endif
338         Py_Return;
339
340 }
341
342
343 KX_PYMETHODDEF_DOC( BL_Shader, isValid, "isValid()" )
344 {
345         return PyInt_FromLong( ( mShader !=0 &&  mOk ) );
346 }
347
348 KX_PYMETHODDEF_DOC( BL_Shader, getVertexProg ,"getVertexProg( )" )
349 {
350         return PyString_FromString(vertProg?vertProg:"");
351 }
352
353 KX_PYMETHODDEF_DOC( BL_Shader, getFragmentProg ,"getFragmentProg( )" )
354 {
355         return PyString_FromString(fragProg?fragProg:"");
356 }
357
358
359 KX_PYMETHODDEF_DOC( BL_Shader, validate, "validate()")
360 {
361 #ifdef GL_ARB_shader_objects
362         if(mShader==0)
363         {
364                 PyErr_Format(PyExc_TypeError, "invalid shader object");
365                 return NULL;
366         }
367
368         int stat = 0;
369         glValidateProgramARB(mShader);
370         glGetObjectParameterivARB(mShader, GL_OBJECT_VALIDATE_STATUS_ARB, &stat);
371         printInfo(mShader);
372
373         return PyInt_FromLong((stat!=0));
374 #else
375         Py_Return;
376 #endif//GL_ARB_shader_objects
377 }
378
379
380 KX_PYMETHODDEF_DOC( BL_Shader, setSampler, "setSampler(name, index)" )
381 {
382 #ifdef GL_ARB_shader_objects
383         char *uniform="";
384         int index=-1;
385         if(PyArg_ParseTuple(args, "si", &uniform, &index)) 
386         {
387                 if(mShader==0)
388                 {
389                         PyErr_Format(PyExc_ValueError, "invalid shader object");
390                         return NULL;
391                 }
392                 int loc= glGetUniformLocationARB(mShader, uniform);
393                 if( loc==-1 )
394                 {
395                         spit("Invalid uniform value: " << uniform << ".");
396                         Py_Return;
397                 }else
398                 {
399                         if(index <= MAXTEX)
400                         {
401                                 mSampler[index].loc = loc;
402                         }else
403                         {
404                                 spit("Invalid texture sample index: " << index);
405                         }
406                         Py_Return;
407                 }
408         }
409         return NULL;
410 #else
411         Py_Return;
412 #endif//GL_ARB_shader_objects
413 }
414
415 KX_PYMETHODDEF_DOC( BL_Shader, setNumberOfPasses, "setNumberOfPasses( max-pass )" )
416 {
417         int pass = 1;
418         if(!PyArg_ParseTuple(args, "i", &pass))
419                 return NULL;
420
421         mPass = pass;
422         Py_Return;
423 }
424
425 /// access functions
426 KX_PYMETHODDEF_DOC( BL_Shader, setUniform1f, "setUniform1f(name, fx)" )
427 {
428 #ifdef GL_ARB_shader_objects
429         char *uniform="";
430         float value=0;
431         if(PyArg_ParseTuple(args, "sf", &uniform, &value ))
432         {
433                 if( mShader==0 )
434                 {
435                         PyErr_Format(PyExc_ValueError, "invalid shader object");
436                         return NULL;
437                 }
438                 int loc= glGetUniformLocationARB(mShader, uniform);
439                 if( loc==-1 )
440                 {
441                         spit("Invalid uniform value: " << uniform << ".");
442                         Py_Return;
443                 }else
444                 {
445                         glUseProgramObjectARB( mShader );
446                         glUniform1fARB( loc, value );
447                         Py_Return;
448                 }
449
450         }
451         return NULL;
452 #else
453         Py_Return;
454 #endif
455 }
456
457
458 KX_PYMETHODDEF_DOC( BL_Shader, setUniform2f , "setUniform2f(name, fx, fy)")
459 {
460 #ifdef GL_ARB_shader_objects
461         char *uniform="";
462         float array[2]={ 0,0 };
463         if(PyArg_ParseTuple(args, "sff", &uniform, &array[0],&array[1] ))
464         {
465                 if( mShader==0 )
466                 {
467                         PyErr_Format(PyExc_ValueError, "invalid shader object");
468                         return NULL;
469                 }
470                 int loc= glGetUniformLocationARB(mShader , uniform);
471                 if( loc==-1 )
472                 {
473                         spit("Invalid uniform value: " << uniform << ".");
474                         Py_Return;
475                 }else
476                 {
477                         glUseProgramObjectARB( mShader );
478                         glUniform2fARB(loc, array[0],array[1] );
479                         Py_Return;
480                 }
481
482         }
483         return NULL;
484 #else
485         Py_Return;
486 #endif//GL_ARB_shader_objects
487 }
488
489
490 KX_PYMETHODDEF_DOC( BL_Shader, setUniform3f, "setUniform3f(name, fx,fy,fz) ")
491 {
492 #ifdef GL_ARB_shader_objects
493         char *uniform="";
494         float array[3]={0,0,0};
495         if(PyArg_ParseTuple(args, "sfff", &uniform, &array[0],&array[1],&array[2]))
496         {
497                 if(mShader==0)
498                 {
499                         PyErr_Format(PyExc_ValueError, "invalid shader object");
500                         return NULL;
501                 }
502                 int loc= glGetUniformLocationARB(mShader , uniform);
503                 if( loc==-1 )
504                 {
505                         spit("Invalid uniform value: " << uniform << ".");
506                         Py_Return;
507                 }else
508                 {
509                         glUseProgramObjectARB(mShader);
510                         glUniform3fARB(loc, array[0],array[1],array[2]);
511                         Py_Return;
512                 }
513
514         }
515         return NULL;
516 #else
517         Py_Return;
518 #endif//GL_ARB_shader_objects
519 }
520
521
522 KX_PYMETHODDEF_DOC( BL_Shader, setUniform4f, "setUniform4f(name, fx,fy,fz, fw) ")
523 {
524 #ifdef GL_ARB_shader_objects
525         char *uniform="";
526         float array[4]={0,0,0,0};
527         if(PyArg_ParseTuple(args, "sffff", &uniform, &array[0],&array[1],&array[2], &array[3]))
528         {
529                 if(mShader==0)
530                 {
531                         PyErr_Format(PyExc_ValueError, "invalid shader object");
532                         return NULL;
533                 }
534                 int loc= glGetUniformLocationARB(mShader , uniform);
535                 if( loc==-1 )
536                 {
537                         spit("Invalid uniform value: " << uniform << ".");
538                         Py_Return;
539                 }else
540                 {
541                         glUseProgramObjectARB(mShader);
542                         glUniform4fARB(loc, array[0],array[1],array[2], array[3]);
543                         Py_Return;
544                 }
545         }
546         return NULL;
547 #else
548         Py_Return;
549 #endif//GL_ARB_shader_objects
550 }
551
552
553 KX_PYMETHODDEF_DOC( BL_Shader, setUniform1i, "setUniform1i(name, ix)" )
554 {
555 #ifdef GL_ARB_shader_objects
556         char *uniform="";
557         int value=0;
558         if(PyArg_ParseTuple(args, "si", &uniform, &value ))
559         {
560                 if( mShader==0 )
561                 {
562                         PyErr_Format(PyExc_ValueError, "invalid shader object");
563                         return NULL;
564                 }
565                 int loc= glGetUniformLocationARB(mShader, uniform);
566                 if( loc==-1 )
567                 {
568                         spit("Invalid uniform value: " << uniform << ".");
569                         Py_Return;
570                 }else
571                 {
572                         glUseProgramObjectARB( mShader );
573                         glUniform1iARB( loc, value );
574                         Py_Return;
575                 }
576         }
577         return NULL;
578 #else
579         Py_Return;
580 #endif//GL_ARB_shader_objects
581 }
582
583
584 KX_PYMETHODDEF_DOC( BL_Shader, setUniform2i , "setUniform2i(name, ix, iy)")
585 {
586 #ifdef GL_ARB_shader_objects
587         char *uniform="";
588         int array[2]={ 0,0 };
589         if(PyArg_ParseTuple(args, "sii", &uniform, &array[0],&array[1] ))
590         {
591                 if( mShader==0 )
592                 {
593                         PyErr_Format(PyExc_ValueError, "invalid shader object");
594                         return NULL;
595                 }
596                 int loc= glGetUniformLocationARB(mShader , uniform);
597                 if( loc==-1 )
598                 {
599                         spit("Invalid uniform value: " << uniform << ".");
600                         Py_Return;
601                 }else
602                 {
603                         glUseProgramObjectARB( mShader );
604                         glUniform2iARB(loc, array[0],array[1] );
605                         Py_Return;
606                 }
607         }
608         return NULL;
609 #else
610         Py_Return;
611 #endif//GL_ARB_shader_objects
612 }
613
614
615 KX_PYMETHODDEF_DOC( BL_Shader, setUniform3i, "setUniform3i(name, ix,iy,iz) ")
616 {
617 #ifdef GL_ARB_shader_objects
618         char *uniform="";
619         int array[3]={0,0,0};
620         if(PyArg_ParseTuple(args, "siii", &uniform, &array[0],&array[1],&array[2]))
621         {
622                 if(mShader==0)
623                 {
624                         PyErr_Format(PyExc_ValueError, "invalid shader object");
625                         return NULL;
626                 }
627                 int loc= glGetUniformLocationARB(mShader , uniform);
628                 if( loc==-1 )
629                 {
630                         spit("Invalid uniform value: " << uniform << ".");
631                         Py_Return;
632                 }else
633                 {
634                         glUseProgramObjectARB(mShader);
635                         glUniform3iARB(loc, array[0],array[1],array[2]);
636                         Py_Return;
637                 }
638         }
639         return NULL;
640 #else
641         Py_Return;
642 #endif//GL_ARB_shader_objects
643 }
644
645 KX_PYMETHODDEF_DOC( BL_Shader, setUniform4i, "setUniform4i(name, ix,iy,iz, iw) ")
646 {
647 #ifdef GL_ARB_shader_objects
648         char *uniform="";
649         int array[4]={0,0,0, 0};
650         if(PyArg_ParseTuple(args, "siiii", &uniform, &array[0],&array[1],&array[2], &array[3] ))
651         {
652                 if(mShader==0)
653                 {
654                         PyErr_Format(PyExc_ValueError, "invalid shader object");
655                         return NULL;
656                 }
657                 int loc= glGetUniformLocationARB(mShader , uniform);
658                 if( loc==-1 )
659                 {
660                         spit("Invalid uniform value: " << uniform << ".");
661                         Py_Return;
662                 }else
663                 {
664                         glUseProgramObjectARB(mShader);
665                         glUniform4iARB(loc, array[0],array[1],array[2], array[3]);
666                         Py_Return;
667                 }
668         }
669         return NULL;
670 #else
671         Py_Return;
672 #endif//GL_ARB_shader_objects
673 }
674
675 KX_PYMETHODDEF_DOC( BL_Shader, setUniformfv , "setUniformfv( float (list2 or list3 or list4) )")
676 {
677 #ifdef GL_ARB_shader_objects
678         char*uniform = "";
679         PyObject *listPtr =0;
680         float array_data[4] = {0.f,0.f,0.f,0.f};
681
682         if(PyArg_ParseTuple(args, "sO", &uniform, &listPtr))
683         {
684                 if(mShader==0)
685                 {
686                         PyErr_Format(PyExc_ValueError, "invalid shader object");
687                         return NULL;
688                 }
689                 int loc= glGetUniformLocationARB(mShader , uniform);
690                 if( loc==-1 )
691                 {
692                         spit("Invalid uniform value: " << uniform << ".");
693                         Py_Return;
694                 }else
695                 {
696                         if(PySequence_Check(listPtr))
697                         {
698                                 unsigned int list_size = PySequence_Size(listPtr);
699                                 
700                                 for(unsigned int i=0; (i<list_size && i<=4); i++)
701                                 {
702                                         PyObject *item = PySequence_GetItem(listPtr, i);
703                                         array_data[i] = (float)PyFloat_AsDouble(item);
704                                         Py_DECREF(item);
705                                 }
706                                 switch(list_size)
707                                 {
708                                 case 2:
709                                         {
710                                                 glUseProgramObjectARB(mShader);
711                                                 glUniform2fARB(loc, array_data[0],array_data[1]);
712                                                 Py_Return;
713                                         } break;
714                                 case 3:
715                                         {
716                                                 glUseProgramObjectARB(mShader);
717                                                 glUniform3fARB(loc, array_data[0],array_data[1], array_data[2]);
718                                                 Py_Return;
719                                         }break;
720                                 case 4:
721                                         {
722                                                 glUseProgramObjectARB(mShader);
723                                                 glUniform4fARB(loc, array_data[0],array_data[1], array_data[2], array_data[3]);
724                                                 Py_Return;
725                                         }break;
726                                 default:
727                                         {
728                                                 PyErr_Format(PyExc_TypeError, "Invalid list size");
729                                                 return NULL;
730                                         }break;
731                                 }
732                         }
733                 }
734         }
735         return NULL;
736 #else
737         Py_Return;
738 #endif//GL_ARB_shader_objects
739
740 }
741
742 KX_PYMETHODDEF_DOC( BL_Shader, setUniformiv, "setUniformiv( int (list2 or list3 or list4) )")
743 {
744 #ifdef GL_ARB_shader_objects
745         char*uniform = "";
746         PyObject *listPtr =0;
747         int array_data[4] = {0,0,0,0};
748
749         if(PyArg_ParseTuple(args, "sO", &uniform, &listPtr))
750         {
751                 if(mShader==0)
752                 {
753                         PyErr_Format(PyExc_ValueError, "invalid shader object");
754                         return NULL;
755                 }
756                 int loc= glGetUniformLocationARB(mShader , uniform);
757                 if( loc==-1 )
758                 {
759                         spit("Invalid uniform value: " << uniform << ".");
760                         Py_Return;
761                 }else
762                 {
763                         if(PySequence_Check(listPtr))
764                         {
765                                 unsigned int list_size = PySequence_Size(listPtr);
766                                 
767                                 for(unsigned int i=0; (i<list_size && i<=4); i++)
768                                 {
769                                         PyObject *item = PySequence_GetItem(listPtr, i);
770                                         array_data[i] = PyInt_AsLong(item);
771                                         Py_DECREF(item);
772                                 }
773                                 switch(list_size)
774                                 {
775                                 case 2:
776                                         {
777                                                 glUseProgramObjectARB(mShader);
778                                                 glUniform2iARB(loc, array_data[0],array_data[1]);
779                                                 Py_Return;
780                                         } break;
781                                 case 3:
782                                         {
783                                                 glUseProgramObjectARB(mShader);
784                                                 glUniform3iARB(loc, array_data[0],array_data[1], array_data[2]);
785                                                 Py_Return;
786                                         }break;
787                                 case 4:
788                                         {
789                                                 glUseProgramObjectARB(mShader);
790                                                 glUniform4iARB(loc, array_data[0],array_data[1], array_data[2], array_data[3]);
791                                                 Py_Return;
792                                         }break;
793                                 default:
794                                         {
795                                                 PyErr_Format(PyExc_TypeError, "Invalid list size");
796                                                 return NULL;
797                                         }break;
798                                 }
799                         }
800                 }
801         }
802         return NULL;
803 #else
804         Py_Return;
805 #endif//GL_ARB_shader_objects
806 }
807
808
809 KX_PYMETHODDEF_DOC( BL_Shader, setUniformMatrix4, 
810 "setUniformMatrix4(uniform-name, mat-4x4, transpose(row-major=true, col-major=false)" )
811 {
812 #ifdef GL_ARB_shader_objects
813         float matr[16] = {
814                 1,0,0,0,
815                 0,1,0,0,
816                 0,0,1,0,
817                 0,0,0,1
818         };
819
820         char *uniform="";
821         PyObject *matrix=0;
822         int transp=1; // MT_ is row major so transpose by default....
823         if(PyArg_ParseTuple(args, "sO|i",&uniform, &matrix,&transp))
824         {
825                 if(mShader==0)
826                 {
827                         PyErr_Format(PyExc_ValueError, "invalid shader object");
828                         return NULL;
829                 }
830                 int loc= glGetUniformLocationARB(mShader , uniform);
831                 if( loc==-1 )
832                 {
833                         spit("Invalid uniform value: " << uniform << ".");
834                         Py_Return;
835                 }else
836                 {
837                         if (PyObject_IsMT_Matrix(matrix, 4))
838                         {
839                                 MT_Matrix4x4 mat;
840                                 if (PyMatTo(matrix, mat))
841                                 {
842                                         mat.getValue(matr);
843                                         glUseProgramObjectARB(mShader);
844                                         glUniformMatrix4fvARB(loc, 1, (transp!=0)?GL_TRUE:GL_FALSE, matr);
845                                         Py_Return;
846                                 }
847                         }
848                 }
849         }
850         return NULL;
851 #else
852         Py_Return;
853 #endif//GL_ARB_shader_objects
854 }
855
856
857 KX_PYMETHODDEF_DOC( BL_Shader, setUniformMatrix3,
858 "setUniformMatrix3(uniform-name, list[3x3], transpose(row-major=true, col-major=false)" )
859 {
860 #ifdef GL_ARB_shader_objects
861         float matr[9] = {
862                 1,0,0,
863                 0,1,0,
864                 0,0,1,
865         };
866
867         char *uniform="";
868         PyObject *matrix=0;
869         int transp=1; // MT_ is row major so transpose by default....
870         if(PyArg_ParseTuple(args, "sO|i",&uniform, &matrix,&transp))
871         {
872                 if(mShader==0)
873                 {
874                         PyErr_Format(PyExc_ValueError, "invalid shader object");
875                         return NULL;
876                 }
877                 int loc= glGetUniformLocationARB(mShader , uniform);
878                 if( loc==-1 )
879                 {
880                         spit("Invalid uniform value: " << uniform << ".");
881                         Py_Return;
882                 }else
883                 {
884                         if (PyObject_IsMT_Matrix(matrix, 3))
885                         {
886                                 MT_Matrix3x3 mat;
887                                 if (PyMatTo(matrix, mat))
888                                 {
889                                         mat.getValue(matr);
890                                         glUseProgramObjectARB(mShader);
891                                         glUniformMatrix3fvARB(loc, 1, (transp!=0)?GL_TRUE:GL_FALSE, matr);
892                                         Py_Return;
893                                 }
894                         }
895                 }
896         }
897         return NULL;
898 #else
899         Py_Return;
900 #endif//GL_ARB_shader_objects
901 }
902
903
904 KX_PYMETHODDEF_DOC( BL_Shader, setBlending, "setBlending(src, dest)" )
905 {
906         int src, dest;
907         if(PyArg_ParseTuple(args, "ii", &src, &dest))
908         {
909                 mBlending.src = src;
910                 mBlending.dest = dest;
911                 Py_Return;
912         }
913         return NULL;
914 }