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