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