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