~diresu/blender/blender-command-port

« back to all changes in this revision

Viewing changes to source/gameengine/Ketsji/BL_Shader.cpp

  • Committer: theeth
  • Date: 2008-10-14 16:52:04 UTC
  • Revision ID: vcs-imports@canonical.com-20081014165204-r32w2gm6s0osvdhn
copy back trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
#include "GL/glew.h"
 
3
 
 
4
#include <iostream>
 
5
#include "BL_Shader.h"
 
6
#include "BL_Material.h"
 
7
 
 
8
#include "MT_assert.h"
 
9
#include "MT_Matrix4x4.h"
 
10
#include "MT_Matrix3x3.h"
 
11
#include "KX_PyMath.h"
 
12
#include "MEM_guardedalloc.h"
 
13
 
 
14
#include "RAS_GLExtensionManager.h"
 
15
#include "RAS_MeshObject.h"
 
16
#include "RAS_IRasterizer.h"
 
17
 
 
18
#define spit(x) std::cout << x << std::endl;
 
19
 
 
20
#define SORT_UNIFORMS 1
 
21
#define UNIFORM_MAX_LEN sizeof(float)*16
 
22
#define MAX_LOG_LEN 262144 // bounds
 
23
 
 
24
BL_Uniform::BL_Uniform(int data_size)
 
25
:       mLoc(-1),
 
26
        mDirty(true),
 
27
        mType(UNI_NONE),
 
28
        mTranspose(0),
 
29
        mDataLen(data_size)
 
30
{
 
31
#ifdef SORT_UNIFORMS
 
32
        MT_assert((int)mDataLen <= UNIFORM_MAX_LEN);
 
33
        mData = (void*)MEM_mallocN(mDataLen, "shader-uniform-alloc");
 
34
#endif
 
35
}
 
36
 
 
37
BL_Uniform::~BL_Uniform()
 
38
{
 
39
#ifdef SORT_UNIFORMS
 
40
        if(mData) {
 
41
                MEM_freeN(mData);
 
42
                mData=0;
 
43
        }
 
44
#endif
 
45
}
 
46
 
 
47
void BL_Uniform::Apply(class BL_Shader *shader)
 
48
{
 
49
#ifdef SORT_UNIFORMS
 
50
        MT_assert(mType > UNI_NONE && mType < UNI_MAX && mData);
 
51
 
 
52
        if(!mDirty) 
 
53
                return;
 
54
 
 
55
        switch(mType)
 
56
        {
 
57
        case UNI_FLOAT: {
 
58
                        float *f = (float*)mData;
 
59
                        glUniform1fARB(mLoc,(GLfloat)*f);
 
60
                }break;
 
61
        case UNI_INT: {
 
62
                        int *f = (int*)mData;
 
63
                        glUniform1iARB(mLoc, (GLint)*f);
 
64
                }break;
 
65
        case UNI_FLOAT2: {
 
66
                        float *f = (float*)mData;
 
67
                        glUniform2fvARB(mLoc,1, (GLfloat*)f);
 
68
                }break;
 
69
        case UNI_FLOAT3: {
 
70
                        float *f = (float*)mData;
 
71
                        glUniform3fvARB(mLoc,1,(GLfloat*)f);
 
72
                }break;
 
73
        case UNI_FLOAT4: {
 
74
                        float *f = (float*)mData;
 
75
                        glUniform4fvARB(mLoc,1,(GLfloat*)f);
 
76
                }break;
 
77
        case UNI_INT2: {
 
78
                        int *f = (int*)mData;
 
79
                        glUniform2ivARB(mLoc,1,(GLint*)f);
 
80
                }break; 
 
81
        case UNI_INT3: {
 
82
                        int *f = (int*)mData;
 
83
                        glUniform3ivARB(mLoc,1,(GLint*)f);
 
84
                }break; 
 
85
        case UNI_INT4: {
 
86
                        int *f = (int*)mData;
 
87
                        glUniform4ivARB(mLoc,1,(GLint*)f);
 
88
                }break;
 
89
        case UNI_MAT4: {
 
90
                        float *f = (float*)mData;
 
91
                        glUniformMatrix4fvARB(mLoc, 1, mTranspose?GL_TRUE:GL_FALSE,(GLfloat*)f);
 
92
                }break;
 
93
        case UNI_MAT3: {
 
94
                        float *f = (float*)mData;
 
95
                        glUniformMatrix3fvARB(mLoc, 1, mTranspose?GL_TRUE:GL_FALSE,(GLfloat*)f);
 
96
                }break;
 
97
        }
 
98
        mDirty = false;
 
99
#endif
 
100
}
 
101
 
 
102
void BL_Uniform::SetData(int location, int type,bool transpose)
 
103
{
 
104
#ifdef SORT_UNIFORMS
 
105
        mType   = type;
 
106
        mLoc    = location;
 
107
        mDirty  = true;
 
108
#endif
 
109
}
 
110
 
 
111
const bool BL_Shader::Ok()const
 
112
{
 
113
        return (mShader !=0 && mOk && mUse);
 
114
}
 
115
 
 
116
BL_Shader::BL_Shader(PyTypeObject *T)
 
117
:       PyObjectPlus(T),
 
118
        mShader(0),
 
119
        mPass(1),
 
120
        mOk(0),
 
121
        mUse(0),
 
122
        mAttr(0),
 
123
        vertProg(""),
 
124
        fragProg(""),
 
125
        mError(0),
 
126
        mDirty(true)
 
127
{
 
128
        // if !GLEW_ARB_shader_objects this class will not be used
 
129
        //for (int i=0; i<MAXTEX; i++) {
 
130
        //      mSampler[i] = BL_Sampler();
 
131
        //}
 
132
}
 
133
 
 
134
BL_Shader::~BL_Shader()
 
135
{
 
136
        //for (int i=0; i<MAXTEX; i++){
 
137
        //      if(mSampler[i].mOwn) {
 
138
        //              if(mSampler[i].mTexture)
 
139
        //                      mSampler[i].mTexture->DeleteTex();
 
140
        //      }
 
141
        //}
 
142
        ClearUniforms();
 
143
 
 
144
        if( mShader ) {
 
145
                glDeleteObjectARB(mShader);
 
146
                mShader = 0;
 
147
        }
 
148
        vertProg        = 0;
 
149
        fragProg        = 0;
 
150
        mOk                     = 0;
 
151
        glUseProgramObjectARB(0);
 
152
}
 
153
 
 
154
void BL_Shader::ClearUniforms()
 
155
{
 
156
        BL_UniformVec::iterator it = mUniforms.begin();
 
157
        while(it != mUniforms.end()){
 
158
                delete (*it);
 
159
                it++;
 
160
        }
 
161
        mUniforms.clear();
 
162
 
 
163
        
 
164
        BL_UniformVecDef::iterator itp = mPreDef.begin();
 
165
        while(itp != mPreDef.end()) {
 
166
                delete (*itp);
 
167
                itp++;
 
168
        }
 
169
        mPreDef.clear();
 
170
 
 
171
}
 
172
 
 
173
 
 
174
BL_Uniform  *BL_Shader::FindUniform(const int location)
 
175
{
 
176
#ifdef SORT_UNIFORMS
 
177
        BL_UniformVec::iterator it = mUniforms.begin();
 
178
        while(it != mUniforms.end()) {
 
179
                if((*it)->GetLocation() == location)
 
180
                        return (*it);
 
181
                it++;
 
182
        }
 
183
#endif
 
184
        return 0;
 
185
}
 
186
 
 
187
void BL_Shader::SetUniformfv(int location, int type, float *param,int size, bool transpose)
 
188
{
 
189
#ifdef SORT_UNIFORMS
 
190
        BL_Uniform *uni= FindUniform(location);
 
191
        if(uni) {
 
192
                memcpy(uni->getData(), param, size);
 
193
                uni->SetData(location, type, transpose);
 
194
        }
 
195
        else {
 
196
                uni = new BL_Uniform(size);
 
197
                memcpy(uni->getData(), param, size);
 
198
 
 
199
                uni->SetData(location, type, transpose);
 
200
                mUniforms.push_back(uni);
 
201
        }
 
202
        mDirty = true;
 
203
#endif
 
204
}
 
205
 
 
206
void BL_Shader::SetUniformiv(int location, int type, int *param,int size, bool transpose)
 
207
{
 
208
#ifdef SORT_UNIFORMS
 
209
        BL_Uniform *uni= FindUniform(location);
 
210
        if(uni) {
 
211
                memcpy(uni->getData(), param, size);
 
212
                uni->SetData(location, type, transpose);
 
213
        }
 
214
        else {
 
215
                uni = new BL_Uniform(size);
 
216
                memcpy(uni->getData(), param, size);
 
217
                uni->SetData(location, type, transpose);
 
218
                mUniforms.push_back(uni);
 
219
        }
 
220
        mDirty = true;
 
221
#endif
 
222
}
 
223
 
 
224
 
 
225
void BL_Shader::ApplyShader()
 
226
{
 
227
#ifdef SORT_UNIFORMS
 
228
        if(!mDirty) 
 
229
                return;
 
230
 
 
231
        for(unsigned int i=0; i<mUniforms.size(); i++)
 
232
                mUniforms[i]->Apply(this);
 
233
 
 
234
        mDirty = false;
 
235
#endif
 
236
}
 
237
 
 
238
void BL_Shader::UnloadShader()
 
239
{
 
240
        //
 
241
}
 
242
 
 
243
 
 
244
bool BL_Shader::LinkProgram()
 
245
{
 
246
        int vertlen = 0, fraglen=0, proglen=0;
 
247
        int vertstatus=0, fragstatus=0, progstatus=0;
 
248
        unsigned int tmpVert=0, tmpFrag=0, tmpProg=0;
 
249
        int char_len=0;
 
250
        char *logInf =0;
 
251
 
 
252
        if(mError)
 
253
                goto programError;
 
254
 
 
255
        if(!vertProg || !fragProg){
 
256
                spit("Invalid GLSL sources");
 
257
                return false;
 
258
        }
 
259
        if( !GLEW_ARB_fragment_shader) {
 
260
                spit("Fragment shaders not supported");
 
261
                return false;
 
262
        }
 
263
        if( !GLEW_ARB_vertex_shader) {
 
264
                spit("Vertex shaders not supported");
 
265
                return false;
 
266
        }
 
267
        
 
268
        // -- vertex shader ------------------
 
269
        tmpVert = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
 
270
        glShaderSourceARB(tmpVert, 1, (const char**)&vertProg, 0);
 
271
        glCompileShaderARB(tmpVert);
 
272
        glGetObjectParameterivARB(tmpVert, GL_OBJECT_INFO_LOG_LENGTH_ARB,(GLint*) &vertlen);
 
273
        
 
274
        // print info if any
 
275
        if( vertlen > 0 && vertlen < MAX_LOG_LEN){
 
276
                logInf = (char*)MEM_mallocN(vertlen, "vert-log");
 
277
                glGetInfoLogARB(tmpVert, vertlen, (GLsizei*)&char_len, logInf);
 
278
                if(char_len >0) {
 
279
                        spit("---- Vertex Shader Error ----");
 
280
                        spit(logInf);
 
281
                }
 
282
                MEM_freeN(logInf);
 
283
                logInf=0;
 
284
        }
 
285
        // check for compile errors
 
286
        glGetObjectParameterivARB(tmpVert, GL_OBJECT_COMPILE_STATUS_ARB,(GLint*)&vertstatus);
 
287
        if(!vertstatus) {
 
288
                spit("---- Vertex shader failed to compile ----");
 
289
                goto programError;
 
290
        }
 
291
 
 
292
        // -- fragment shader ----------------
 
293
        tmpFrag = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
 
294
        glShaderSourceARB(tmpFrag, 1,(const char**)&fragProg, 0);
 
295
        glCompileShaderARB(tmpFrag);
 
296
        glGetObjectParameterivARB(tmpFrag, GL_OBJECT_INFO_LOG_LENGTH_ARB, (GLint*) &fraglen);
 
297
        if(fraglen >0 && fraglen < MAX_LOG_LEN){
 
298
                logInf = (char*)MEM_mallocN(fraglen, "frag-log");
 
299
                glGetInfoLogARB(tmpFrag, fraglen,(GLsizei*) &char_len, logInf);
 
300
                if(char_len >0) {
 
301
                        spit("---- Fragment Shader Error ----");
 
302
                        spit(logInf);
 
303
                }
 
304
                MEM_freeN(logInf);
 
305
                logInf=0;
 
306
        }
 
307
 
 
308
        glGetObjectParameterivARB(tmpFrag, GL_OBJECT_COMPILE_STATUS_ARB, (GLint*) &fragstatus);
 
309
        if(!fragstatus){
 
310
                spit("---- Fragment shader failed to compile ----");
 
311
                goto programError;
 
312
        }
 
313
 
 
314
        
 
315
        // -- program ------------------------
 
316
        //  set compiled vert/frag shader & link
 
317
        tmpProg = glCreateProgramObjectARB();
 
318
        glAttachObjectARB(tmpProg, tmpVert);
 
319
        glAttachObjectARB(tmpProg, tmpFrag);
 
320
        glLinkProgramARB(tmpProg);
 
321
        glGetObjectParameterivARB(tmpProg, GL_OBJECT_INFO_LOG_LENGTH_ARB, (GLint*) &proglen);
 
322
        glGetObjectParameterivARB(tmpProg, GL_OBJECT_LINK_STATUS_ARB, (GLint*) &progstatus);
 
323
        
 
324
 
 
325
        if(proglen > 0 && proglen < MAX_LOG_LEN) {
 
326
                logInf = (char*)MEM_mallocN(proglen, "prog-log");
 
327
                glGetInfoLogARB(tmpProg, proglen, (GLsizei*)&char_len, logInf);
 
328
                if(char_len >0) {
 
329
                        spit("---- GLSL Program ----");
 
330
                        spit(logInf);
 
331
                }
 
332
                MEM_freeN(logInf);
 
333
                logInf=0;
 
334
        }
 
335
 
 
336
        if(!progstatus){
 
337
                spit("---- GLSL program failed to link ----");
 
338
                goto programError;
 
339
        }
 
340
 
 
341
        // set
 
342
        mShader = tmpProg;
 
343
        glDeleteObjectARB(tmpVert);
 
344
        glDeleteObjectARB(tmpFrag);
 
345
        mOk             = 1;
 
346
        mError = 0;
 
347
        return true;
 
348
 
 
349
programError:
 
350
        if(tmpVert) {
 
351
                glDeleteObjectARB(tmpVert);
 
352
                tmpVert=0;
 
353
        }
 
354
        if(tmpFrag) {
 
355
                glDeleteObjectARB(tmpFrag);
 
356
                tmpFrag=0;
 
357
        }
 
358
 
 
359
        if(tmpProg) {
 
360
                glDeleteObjectARB(tmpProg);
 
361
                tmpProg=0;
 
362
        }
 
363
 
 
364
        mOk             = 0;
 
365
        mUse    = 0;
 
366
        mError  = 1;
 
367
        return false;
 
368
}
 
369
 
 
370
const char *BL_Shader::GetVertPtr()
 
371
{
 
372
        return vertProg?vertProg:0;
 
373
}
 
374
 
 
375
const char *BL_Shader::GetFragPtr()
 
376
{
 
377
        return fragProg?fragProg:0;
 
378
}
 
379
 
 
380
void BL_Shader::SetVertPtr( char *vert )
 
381
{
 
382
        vertProg = vert;
 
383
}
 
384
 
 
385
void BL_Shader::SetFragPtr( char *frag )
 
386
{
 
387
        fragProg = frag;
 
388
}
 
389
 
 
390
unsigned int BL_Shader::GetProg()
 
391
 
392
        return mShader;
 
393
}
 
394
//
 
395
//const BL_Sampler* BL_Shader::GetSampler(int i)
 
396
//{
 
397
//      MT_assert(i<=MAXTEX);
 
398
//      return &mSampler[i];
 
399
//}
 
400
 
 
401
void BL_Shader::SetSampler(int loc, int unit)
 
402
{
 
403
        if( GLEW_ARB_fragment_shader &&
 
404
                GLEW_ARB_vertex_shader &&
 
405
                GLEW_ARB_shader_objects 
 
406
                )
 
407
        {
 
408
                glUniform1iARB(loc, unit);
 
409
        }
 
410
}
 
411
//
 
412
//void BL_Shader::InitializeSampler(int unit, BL_Texture* texture)
 
413
//{
 
414
//      MT_assert(unit<=MAXTEX);
 
415
//      mSampler[unit].mTexture = texture;
 
416
//      mSampler[unit].mLoc =-1;
 
417
//      mSampler[unit].mOwn = 0;
 
418
//}
 
419
 
 
420
void BL_Shader::SetProg(bool enable)
 
421
{
 
422
        if( GLEW_ARB_fragment_shader &&
 
423
                GLEW_ARB_vertex_shader &&
 
424
                GLEW_ARB_shader_objects 
 
425
                )
 
426
        {
 
427
                if(     mShader != 0 && mOk && enable) {
 
428
                        glUseProgramObjectARB(mShader);
 
429
                }
 
430
                else {
 
431
                        glUseProgramObjectARB(0);       
 
432
                }
 
433
        }
 
434
}
 
435
 
 
436
void BL_Shader::Update( const RAS_MeshSlot & ms, RAS_IRasterizer* rasty )
 
437
{
 
438
        if(!Ok() || !mPreDef.size()) 
 
439
                return;
 
440
 
 
441
        if( GLEW_ARB_fragment_shader &&
 
442
                GLEW_ARB_vertex_shader &&
 
443
                GLEW_ARB_shader_objects 
 
444
                )
 
445
        {
 
446
                MT_Matrix4x4 model;
 
447
                model.setValue(ms.m_OpenGLMatrix);
 
448
                const MT_Matrix4x4& view = rasty->GetViewMatrix();
 
449
 
 
450
                if(mAttr==SHD_TANGENT)
 
451
                         ms.m_mesh->SetMeshModified(true);
 
452
 
 
453
                BL_UniformVecDef::iterator it;
 
454
                for(it = mPreDef.begin(); it!= mPreDef.end(); it++)
 
455
                {
 
456
                        BL_DefUniform *uni = (*it);
 
457
                        if(uni->mLoc == -1) continue;
 
458
 
 
459
                        switch (uni->mType)
 
460
                        {
 
461
                                case MODELMATRIX:
 
462
                                        {
 
463
                                                SetUniform(uni->mLoc, model);
 
464
                                                break;
 
465
                                        }
 
466
                                case MODELMATRIX_TRANSPOSE:
 
467
                                        {
 
468
                                                SetUniform(uni->mLoc, model, true);
 
469
                                                break;
 
470
                                        }
 
471
                                case MODELMATRIX_INVERSE:
 
472
                                        {
 
473
                                                model.invert();
 
474
                                                SetUniform(uni->mLoc, model);
 
475
                                                break;
 
476
                                        }
 
477
                                case MODELMATRIX_INVERSETRANSPOSE:
 
478
                                        {
 
479
                                                model.invert();
 
480
                                                SetUniform(uni->mLoc, model, true);
 
481
                                                break;
 
482
                                        }
 
483
                                case MODELVIEWMATRIX:
 
484
                                        {
 
485
                                                SetUniform(uni->mLoc, view*model);
 
486
                                                break;
 
487
                                        }
 
488
 
 
489
                                case MODELVIEWMATRIX_TRANSPOSE:
 
490
                                        {
 
491
                                                MT_Matrix4x4 mat(view*model);
 
492
                                                SetUniform(uni->mLoc, mat, true);
 
493
                                                break;
 
494
                                        }
 
495
                                case MODELVIEWMATRIX_INVERSE:
 
496
                                        {
 
497
                                                MT_Matrix4x4 mat(view*model);
 
498
                                                mat.invert();
 
499
                                                SetUniform(uni->mLoc, mat);
 
500
                                                break;
 
501
                                        }
 
502
                                case MODELVIEWMATRIX_INVERSETRANSPOSE:
 
503
                                        {
 
504
                                                MT_Matrix4x4 mat(view*model);
 
505
                                                mat.invert();
 
506
                                                SetUniform(uni->mLoc, mat, true);
 
507
                                                break;
 
508
                                        }
 
509
                                case CAM_POS:
 
510
                                        {
 
511
                                                MT_Point3 pos(rasty->GetCameraPosition());
 
512
                                                SetUniform(uni->mLoc, pos);
 
513
                                                break;
 
514
                                        }
 
515
                                case VIEWMATRIX:
 
516
                                        {
 
517
                                                SetUniform(uni->mLoc, view);
 
518
                                                break;
 
519
                                        }
 
520
                                case VIEWMATRIX_TRANSPOSE:
 
521
                                        {
 
522
                                                SetUniform(uni->mLoc, view, true);
 
523
                                                break;
 
524
                                        }
 
525
                                case VIEWMATRIX_INVERSE:
 
526
                                        {
 
527
                                                MT_Matrix4x4 viewinv = view;
 
528
                                                viewinv.invert();
 
529
                                                SetUniform(uni->mLoc, view);
 
530
                                                break;
 
531
                                        }
 
532
                                case VIEWMATRIX_INVERSETRANSPOSE:
 
533
                                        {
 
534
                                                MT_Matrix4x4 viewinv = view;
 
535
                                                viewinv.invert();
 
536
                                                SetUniform(uni->mLoc, view, true);
 
537
                                                break;
 
538
                                        }
 
539
                                case CONSTANT_TIMER:
 
540
                                        {
 
541
                                                SetUniform(uni->mLoc, (float)rasty->GetTime());
 
542
                                                break;
 
543
                                        }
 
544
                                default:
 
545
                                        break;
 
546
                        }
 
547
                }
 
548
        }
 
549
}
 
550
 
 
551
 
 
552
int BL_Shader::GetAttribLocation(const STR_String& name)
 
553
{
 
554
        if( GLEW_ARB_fragment_shader &&
 
555
                GLEW_ARB_vertex_shader &&
 
556
                GLEW_ARB_shader_objects 
 
557
                )
 
558
        {
 
559
                return glGetAttribLocationARB(mShader, name.ReadPtr());
 
560
        }
 
561
 
 
562
        return -1;
 
563
}
 
564
 
 
565
void BL_Shader::BindAttribute(const STR_String& attr, int loc)
 
566
{
 
567
        if( GLEW_ARB_fragment_shader &&
 
568
                GLEW_ARB_vertex_shader &&
 
569
                GLEW_ARB_shader_objects 
 
570
                )
 
571
        {
 
572
                glBindAttribLocationARB(mShader, loc, attr.ReadPtr());
 
573
        }
 
574
}
 
575
 
 
576
int BL_Shader::GetUniformLocation(const STR_String& name)
 
577
{
 
578
        if( GLEW_ARB_fragment_shader &&
 
579
                GLEW_ARB_vertex_shader &&
 
580
                GLEW_ARB_shader_objects 
 
581
                )
 
582
        {
 
583
                MT_assert(mShader!=0);
 
584
                int location = glGetUniformLocationARB(mShader, name.ReadPtr());
 
585
                if(location == -1)
 
586
                        spit("Invalid uniform value: " << name.ReadPtr() << ".");
 
587
                return location;
 
588
        }
 
589
 
 
590
        return -1;
 
591
}
 
592
 
 
593
void BL_Shader::SetUniform(int uniform, const MT_Tuple2& vec)
 
594
{
 
595
        if( GLEW_ARB_fragment_shader &&
 
596
                GLEW_ARB_vertex_shader &&
 
597
                GLEW_ARB_shader_objects 
 
598
                )
 
599
        {
 
600
                float value[2];
 
601
                vec.getValue(value);
 
602
                glUniform2fvARB(uniform, 1, value);
 
603
        }
 
604
 
 
605
}
 
606
 
 
607
void BL_Shader::SetUniform(int uniform, const MT_Tuple3& vec)
 
608
{
 
609
        if( GLEW_ARB_fragment_shader &&
 
610
                GLEW_ARB_vertex_shader &&
 
611
                GLEW_ARB_shader_objects 
 
612
                )
 
613
        {       
 
614
                float value[3];
 
615
                vec.getValue(value);
 
616
                glUniform3fvARB(uniform, 1, value);
 
617
        }
 
618
}
 
619
 
 
620
void BL_Shader::SetUniform(int uniform, const MT_Tuple4& vec)
 
621
{
 
622
        if( GLEW_ARB_fragment_shader &&
 
623
                GLEW_ARB_vertex_shader &&
 
624
                GLEW_ARB_shader_objects 
 
625
                )
 
626
        {
 
627
                float value[4];
 
628
                vec.getValue(value);
 
629
                glUniform4fvARB(uniform, 1, value);
 
630
        }
 
631
}
 
632
 
 
633
void BL_Shader::SetUniform(int uniform, const unsigned int& val)
 
634
{
 
635
        if( GLEW_ARB_fragment_shader &&
 
636
                GLEW_ARB_vertex_shader &&
 
637
                GLEW_ARB_shader_objects 
 
638
                )
 
639
        {
 
640
                glUniform1iARB(uniform, val);
 
641
        }
 
642
}
 
643
 
 
644
void BL_Shader::SetUniform(int uniform, const int val)
 
645
{
 
646
        if( GLEW_ARB_fragment_shader &&
 
647
                GLEW_ARB_vertex_shader &&
 
648
                GLEW_ARB_shader_objects 
 
649
                )
 
650
        {
 
651
                glUniform1iARB(uniform, val);
 
652
        }
 
653
}
 
654
 
 
655
void BL_Shader::SetUniform(int uniform, const float& val)
 
656
{
 
657
        if( GLEW_ARB_fragment_shader &&
 
658
                GLEW_ARB_vertex_shader &&
 
659
                GLEW_ARB_shader_objects 
 
660
                )
 
661
        {
 
662
                glUniform1fARB(uniform, val);
 
663
        }
 
664
}
 
665
 
 
666
void BL_Shader::SetUniform(int uniform, const MT_Matrix4x4& vec, bool transpose)
 
667
{
 
668
        if( GLEW_ARB_fragment_shader &&
 
669
                GLEW_ARB_vertex_shader &&
 
670
                GLEW_ARB_shader_objects 
 
671
                )
 
672
        {
 
673
                float value[16];
 
674
                // note: getValue gives back column major as needed by OpenGL
 
675
                vec.getValue(value);
 
676
                glUniformMatrix4fvARB(uniform, 1, transpose?GL_TRUE:GL_FALSE, value);
 
677
        }
 
678
}
 
679
 
 
680
void BL_Shader::SetUniform(int uniform, const MT_Matrix3x3& vec, bool transpose)
 
681
{
 
682
        if( GLEW_ARB_fragment_shader &&
 
683
                GLEW_ARB_vertex_shader &&
 
684
                GLEW_ARB_shader_objects 
 
685
                )
 
686
        {
 
687
                float value[9];
 
688
                value[0] = (float)vec[0][0]; value[1] = (float)vec[1][0]; value[2] = (float)vec[2][0]; 
 
689
                value[3] = (float)vec[0][1]; value[4] = (float)vec[1][1]; value[5] = (float)vec[2][1]; 
 
690
                value[6] = (float)vec[0][2]; value[7] = (float)vec[1][2]; value[7] = (float)vec[2][2]; 
 
691
                glUniformMatrix3fvARB(uniform, 1, transpose?GL_TRUE:GL_FALSE, value);
 
692
        }
 
693
}
 
694
 
 
695
void BL_Shader::SetUniform(int uniform, const float* val, int len)
 
696
{
 
697
        if( GLEW_ARB_fragment_shader &&
 
698
                GLEW_ARB_vertex_shader &&
 
699
                GLEW_ARB_shader_objects 
 
700
                )
 
701
        {
 
702
                if(len == 2) 
 
703
                        glUniform2fvARB(uniform, 1,(GLfloat*)val);
 
704
                else if (len == 3)
 
705
                        glUniform3fvARB(uniform, 1,(GLfloat*)val);
 
706
                else if (len == 4)
 
707
                        glUniform4fvARB(uniform, 1,(GLfloat*)val);
 
708
                else
 
709
                        MT_assert(0);
 
710
        }
 
711
}
 
712
 
 
713
void BL_Shader::SetUniform(int uniform, const int* val, int len)
 
714
{
 
715
        if( GLEW_ARB_fragment_shader &&
 
716
                GLEW_ARB_vertex_shader &&
 
717
                GLEW_ARB_shader_objects 
 
718
                )
 
719
        {
 
720
                if(len == 2) 
 
721
                        glUniform2ivARB(uniform, 1, (GLint*)val);
 
722
                else if (len == 3)
 
723
                        glUniform3ivARB(uniform, 1, (GLint*)val);
 
724
                else if (len == 4)
 
725
                        glUniform4ivARB(uniform, 1, (GLint*)val);
 
726
                else
 
727
                        MT_assert(0);
 
728
        }
 
729
}
 
730
 
 
731
 
 
732
PyObject* BL_Shader::_getattr(const STR_String& attr)
 
733
{
 
734
        _getattr_up(PyObjectPlus);
 
735
}
 
736
 
 
737
 
 
738
PyMethodDef BL_Shader::Methods[] = 
 
739
{
 
740
        // creation
 
741
        KX_PYMETHODTABLE( BL_Shader, setSource ),
 
742
        KX_PYMETHODTABLE( BL_Shader, delSource ),
 
743
        KX_PYMETHODTABLE( BL_Shader, getVertexProg ),
 
744
        KX_PYMETHODTABLE( BL_Shader, getFragmentProg ),
 
745
        KX_PYMETHODTABLE( BL_Shader, setNumberOfPasses ),
 
746
        KX_PYMETHODTABLE( BL_Shader, validate),
 
747
        /// access functions
 
748
        KX_PYMETHODTABLE( BL_Shader, isValid),
 
749
        KX_PYMETHODTABLE( BL_Shader, setUniform1f ),
 
750
        KX_PYMETHODTABLE( BL_Shader, setUniform2f ),
 
751
        KX_PYMETHODTABLE( BL_Shader, setUniform3f ),
 
752
        KX_PYMETHODTABLE( BL_Shader, setUniform4f ),
 
753
        KX_PYMETHODTABLE( BL_Shader, setUniform1i ),
 
754
        KX_PYMETHODTABLE( BL_Shader, setUniform2i ),
 
755
        KX_PYMETHODTABLE( BL_Shader, setUniform3i ),
 
756
        KX_PYMETHODTABLE( BL_Shader, setUniform4i ),
 
757
        KX_PYMETHODTABLE( BL_Shader, setAttrib ),
 
758
 
 
759
        KX_PYMETHODTABLE( BL_Shader, setUniformfv ),
 
760
        KX_PYMETHODTABLE( BL_Shader, setUniformiv ),
 
761
        KX_PYMETHODTABLE( BL_Shader, setUniformDef ),
 
762
 
 
763
        KX_PYMETHODTABLE( BL_Shader, setSampler  ),
 
764
        KX_PYMETHODTABLE( BL_Shader, setUniformMatrix4 ),
 
765
        KX_PYMETHODTABLE( BL_Shader, setUniformMatrix3 ),
 
766
 
 
767
        {NULL,NULL} //Sentinel
 
768
};
 
769
 
 
770
 
 
771
PyTypeObject BL_Shader::Type = {
 
772
        PyObject_HEAD_INIT(&PyType_Type)
 
773
                0,
 
774
                "BL_Shader",
 
775
                sizeof(BL_Shader),
 
776
                0,
 
777
                PyDestructor,
 
778
                0,
 
779
                __getattr,
 
780
                __setattr,
 
781
                0,
 
782
                __repr,
 
783
                0
 
784
};
 
785
 
 
786
 
 
787
PyParentObject BL_Shader::Parents[] = {
 
788
        &PyObjectPlus::Type,
 
789
        &BL_Shader::Type,
 
790
        NULL
 
791
};
 
792
 
 
793
 
 
794
KX_PYMETHODDEF_DOC( BL_Shader, setSource," setSource(vertexProgram, fragmentProgram)" )
 
795
{
 
796
        if(mShader !=0 && mOk  )
 
797
        {
 
798
                // already set...
 
799
                Py_Return;
 
800
        }
 
801
        char *v,*f;
 
802
        int apply=0;
 
803
        if( PyArg_ParseTuple(args, "ssi", &v, &f, &apply) )
 
804
        {
 
805
                vertProg = v;
 
806
                fragProg = f;
 
807
                if( LinkProgram() ) {
 
808
                        glUseProgramObjectARB( mShader );
 
809
                        mUse = apply!=0;
 
810
                        Py_Return;
 
811
                }
 
812
                vertProg = 0;
 
813
                fragProg = 0;
 
814
                mUse = 0;
 
815
                Py_Return;
 
816
        }
 
817
        return NULL;
 
818
}
 
819
 
 
820
 
 
821
KX_PYMETHODDEF_DOC( BL_Shader, delSource, "delSource( )" )
 
822
{
 
823
        ClearUniforms();
 
824
        glUseProgramObjectARB(0);
 
825
 
 
826
        glDeleteObjectARB(mShader);
 
827
        mShader         = 0;
 
828
        mOk                     = 0;
 
829
        mUse            = 0;
 
830
        Py_Return;
 
831
}
 
832
 
 
833
KX_PYMETHODDEF_DOC( BL_Shader, isValid, "isValid()" )
 
834
{
 
835
        return PyInt_FromLong( ( mShader !=0 &&  mOk ) );
 
836
}
 
837
 
 
838
KX_PYMETHODDEF_DOC( BL_Shader, getVertexProg ,"getVertexProg( )" )
 
839
{
 
840
        return PyString_FromString(vertProg?vertProg:"");
 
841
}
 
842
 
 
843
KX_PYMETHODDEF_DOC( BL_Shader, getFragmentProg ,"getFragmentProg( )" )
 
844
{
 
845
        return PyString_FromString(fragProg?fragProg:"");
 
846
}
 
847
 
 
848
KX_PYMETHODDEF_DOC( BL_Shader, validate, "validate()")
 
849
{
 
850
        if(mError) {
 
851
                Py_RETURN_NONE;
 
852
        }
 
853
        if(mShader==0) {
 
854
                PyErr_Format(PyExc_TypeError, "invalid shader object");
 
855
                return NULL;
 
856
        }
 
857
        int stat = 0;
 
858
        glValidateProgramARB(mShader);
 
859
        glGetObjectParameterivARB(mShader, GL_OBJECT_VALIDATE_STATUS_ARB,(GLint*) &stat);
 
860
 
 
861
 
 
862
        if(stat > 0 && stat < MAX_LOG_LEN) {
 
863
                int char_len=0;
 
864
                char *logInf = (char*)MEM_mallocN(stat, "validate-log");
 
865
 
 
866
                glGetInfoLogARB(mShader, stat,(GLsizei*) &char_len, logInf);
 
867
                if(char_len >0) {
 
868
                        spit("---- GLSL Validation ----");
 
869
                        spit(logInf);
 
870
                }
 
871
                MEM_freeN(logInf);
 
872
                logInf=0;
 
873
        }
 
874
        Py_Return;
 
875
}
 
876
 
 
877
 
 
878
KX_PYMETHODDEF_DOC( BL_Shader, setSampler, "setSampler(name, index)" )
 
879
{
 
880
        if(mError) {
 
881
                Py_RETURN_NONE;
 
882
        }
 
883
 
 
884
        const char *uniform="";
 
885
        int index=-1;
 
886
        if(PyArg_ParseTuple(args, "si", &uniform, &index)) 
 
887
        {
 
888
                int loc = GetUniformLocation(uniform);
 
889
                if(loc != -1) {
 
890
                        if(index >= MAXTEX &&  index < 0)
 
891
                                spit("Invalid texture sample index: " << index);
 
892
 
 
893
#ifdef SORT_UNIFORMS
 
894
                        SetUniformiv(loc, BL_Uniform::UNI_INT, &index, (sizeof(int)) );
 
895
#else
 
896
                        SetUniform(loc, index);
 
897
#endif
 
898
                        //if(index <= MAXTEX)
 
899
                        //      mSampler[index].mLoc = loc;
 
900
                        //else
 
901
                        //      spit("Invalid texture sample index: " << index);
 
902
                }
 
903
                Py_RETURN_NONE;
 
904
        }
 
905
        return NULL;
 
906
}
 
907
 
 
908
KX_PYMETHODDEF_DOC( BL_Shader, setNumberOfPasses, "setNumberOfPasses( max-pass )" )
 
909
{
 
910
        int pass = 1;
 
911
        if(!PyArg_ParseTuple(args, "i", &pass))
 
912
                return NULL;
 
913
 
 
914
        mPass = 1;
 
915
        Py_Return;
 
916
}
 
917
 
 
918
/// access functions
 
919
KX_PYMETHODDEF_DOC( BL_Shader, setUniform1f, "setUniform1f(name, fx)" )
 
920
{
 
921
        if(mError) {
 
922
                Py_RETURN_NONE;
 
923
        }
 
924
 
 
925
        const char *uniform="";
 
926
        float value=0;
 
927
        if(PyArg_ParseTuple(args, "sf", &uniform, &value ))
 
928
        {
 
929
                int loc = GetUniformLocation(uniform);
 
930
                if(loc != -1)
 
931
                {
 
932
#ifdef SORT_UNIFORMS
 
933
                        SetUniformfv(loc, BL_Uniform::UNI_FLOAT, &value, sizeof(float));
 
934
#else                   
 
935
                        SetUniform( loc, (float)value );
 
936
#endif
 
937
                }
 
938
                Py_Return;
 
939
        }
 
940
        return NULL;
 
941
}
 
942
 
 
943
 
 
944
KX_PYMETHODDEF_DOC( BL_Shader, setUniform2f , "setUniform2f(name, fx, fy)")
 
945
{
 
946
        if(mError) {
 
947
                Py_RETURN_NONE;
 
948
        }
 
949
        const char *uniform="";
 
950
        float array[2]={ 0,0 };
 
951
        if(PyArg_ParseTuple(args, "sff", &uniform, &array[0],&array[1] ))
 
952
        {
 
953
                int loc = GetUniformLocation(uniform);
 
954
                if(loc != -1)
 
955
                {
 
956
#ifdef SORT_UNIFORMS
 
957
                        SetUniformfv(loc, BL_Uniform::UNI_FLOAT2, array, (sizeof(float)*2) );
 
958
#else
 
959
                        SetUniform(loc, array, 2);
 
960
#endif
 
961
                }
 
962
                Py_Return;
 
963
        }
 
964
        return NULL;
 
965
}
 
966
 
 
967
 
 
968
KX_PYMETHODDEF_DOC( BL_Shader, setUniform3f, "setUniform3f(name, fx,fy,fz) ")
 
969
{
 
970
        if(mError) {
 
971
                Py_RETURN_NONE;
 
972
        }
 
973
        const char *uniform="";
 
974
        float array[3]={0,0,0};
 
975
        if(PyArg_ParseTuple(args, "sfff", &uniform, &array[0],&array[1],&array[2]))
 
976
        {
 
977
                int loc = GetUniformLocation(uniform);
 
978
                if(loc != -1)
 
979
                {
 
980
#ifdef SORT_UNIFORMS
 
981
                        SetUniformfv(loc, BL_Uniform::UNI_FLOAT3, array, (sizeof(float)*3) );
 
982
#else
 
983
                        SetUniform(loc, array, 3);
 
984
#endif
 
985
                }
 
986
                Py_Return;
 
987
 
 
988
        }
 
989
        return NULL;
 
990
}
 
991
 
 
992
 
 
993
KX_PYMETHODDEF_DOC( BL_Shader, setUniform4f, "setUniform4f(name, fx,fy,fz, fw) ")
 
994
{
 
995
        if(mError) {
 
996
                Py_RETURN_NONE;
 
997
        }
 
998
        const char *uniform="";
 
999
        float array[4]={0,0,0,0};
 
1000
        if(PyArg_ParseTuple(args, "sffff", &uniform, &array[0],&array[1],&array[2], &array[3]))
 
1001
        {
 
1002
                int loc = GetUniformLocation(uniform);
 
1003
                if(loc != -1)
 
1004
                {
 
1005
#ifdef SORT_UNIFORMS
 
1006
                        SetUniformfv(loc, BL_Uniform::UNI_FLOAT4, array, (sizeof(float)*4) );
 
1007
#else
 
1008
                        SetUniform(loc, array, 4);
 
1009
#endif
 
1010
                }
 
1011
                Py_Return;
 
1012
        }
 
1013
        return NULL;
 
1014
}
 
1015
 
 
1016
 
 
1017
KX_PYMETHODDEF_DOC( BL_Shader, setUniform1i, "setUniform1i(name, ix)" )
 
1018
{
 
1019
        if(mError) {
 
1020
                Py_RETURN_NONE;
 
1021
        }
 
1022
        const char *uniform="";
 
1023
        int value=0;
 
1024
        if(PyArg_ParseTuple(args, "si", &uniform, &value ))
 
1025
        {
 
1026
                int loc = GetUniformLocation(uniform);
 
1027
                if(loc != -1)
 
1028
                {
 
1029
#ifdef SORT_UNIFORMS
 
1030
                        SetUniformiv(loc, BL_Uniform::UNI_INT, &value, sizeof(int));
 
1031
#else
 
1032
                        SetUniform(loc, (int)value);
 
1033
#endif
 
1034
                }
 
1035
                Py_Return;
 
1036
        }
 
1037
        return NULL;
 
1038
}
 
1039
 
 
1040
 
 
1041
KX_PYMETHODDEF_DOC( BL_Shader, setUniform2i , "setUniform2i(name, ix, iy)")
 
1042
{
 
1043
        if(mError) {
 
1044
                Py_RETURN_NONE;
 
1045
        }
 
1046
        const char *uniform="";
 
1047
        int array[2]={ 0,0 };
 
1048
        if(PyArg_ParseTuple(args, "sii", &uniform, &array[0],&array[1] ))
 
1049
        {
 
1050
                int loc = GetUniformLocation(uniform);
 
1051
                if(loc != -1)
 
1052
                {
 
1053
#ifdef SORT_UNIFORMS
 
1054
                        SetUniformiv(loc, BL_Uniform::UNI_INT2, array, sizeof(int)*2);
 
1055
#else
 
1056
                        SetUniform(loc, array, 2);
 
1057
#endif
 
1058
                }
 
1059
                Py_Return;
 
1060
        }
 
1061
        return NULL;
 
1062
}
 
1063
 
 
1064
 
 
1065
KX_PYMETHODDEF_DOC( BL_Shader, setUniform3i, "setUniform3i(name, ix,iy,iz) ")
 
1066
{
 
1067
        if(mError) {
 
1068
                Py_RETURN_NONE;
 
1069
        }
 
1070
 
 
1071
        const char *uniform="";
 
1072
        int array[3]={0,0,0};
 
1073
        if(PyArg_ParseTuple(args, "siii", &uniform, &array[0],&array[1],&array[2]))
 
1074
        {
 
1075
                int loc = GetUniformLocation(uniform);
 
1076
                if(loc != -1)
 
1077
                {
 
1078
#ifdef SORT_UNIFORMS
 
1079
                        SetUniformiv(loc, BL_Uniform::UNI_INT3, array, sizeof(int)*3);
 
1080
#else
 
1081
                        SetUniform(loc, array, 3);
 
1082
#endif
 
1083
                }
 
1084
                Py_Return;
 
1085
        }
 
1086
        return NULL;
 
1087
}
 
1088
 
 
1089
KX_PYMETHODDEF_DOC( BL_Shader, setUniform4i, "setUniform4i(name, ix,iy,iz, iw) ")
 
1090
{
 
1091
        if(mError) {
 
1092
                Py_RETURN_NONE;
 
1093
        }
 
1094
        const char *uniform="";
 
1095
        int array[4]={0,0,0, 0};
 
1096
        if(PyArg_ParseTuple(args, "siiii", &uniform, &array[0],&array[1],&array[2], &array[3] ))
 
1097
        {
 
1098
                int loc = GetUniformLocation(uniform);
 
1099
                if(loc != -1)
 
1100
                {
 
1101
#ifdef SORT_UNIFORMS
 
1102
                        SetUniformiv(loc, BL_Uniform::UNI_INT4, array, sizeof(int)*4);
 
1103
#else
 
1104
                        SetUniform(loc, array, 4);
 
1105
#endif
 
1106
                }
 
1107
                Py_Return;
 
1108
        }
 
1109
        return NULL;
 
1110
}
 
1111
 
 
1112
KX_PYMETHODDEF_DOC( BL_Shader, setUniformfv , "setUniformfv( float (list2 or list3 or list4) )")
 
1113
{
 
1114
        if(mError) {
 
1115
                Py_RETURN_NONE;
 
1116
        }
 
1117
        const char *uniform = "";
 
1118
        PyObject *listPtr =0;
 
1119
        float array_data[4] = {0.f,0.f,0.f,0.f};
 
1120
 
 
1121
        if(PyArg_ParseTuple(args, "sO", &uniform, &listPtr))
 
1122
        {
 
1123
                int loc = GetUniformLocation(uniform);
 
1124
                if(loc != -1)
 
1125
                {
 
1126
                        if(PySequence_Check(listPtr))
 
1127
                        {
 
1128
                                unsigned int list_size = PySequence_Size(listPtr);
 
1129
                                
 
1130
                                for(unsigned int i=0; (i<list_size && i<4); i++)
 
1131
                                {
 
1132
                                        PyObject *item = PySequence_GetItem(listPtr, i);
 
1133
                                        array_data[i] = (float)PyFloat_AsDouble(item);
 
1134
                                        Py_DECREF(item);
 
1135
                                }
 
1136
 
 
1137
                                switch(list_size)
 
1138
                                {
 
1139
                                case 2:
 
1140
                                        {
 
1141
                                                float array2[2] = { array_data[0],array_data[1] };
 
1142
#ifdef SORT_UNIFORMS
 
1143
                                                SetUniformfv(loc, BL_Uniform::UNI_FLOAT2, array2, sizeof(float)*2);
 
1144
#else
 
1145
                                                SetUniform(loc, array2, 2);                                             
 
1146
#endif
 
1147
                                                Py_Return;
 
1148
                                        } break;
 
1149
                                case 3:
 
1150
                                        {
 
1151
                                                float array3[3] = { array_data[0],array_data[1],array_data[2] };
 
1152
#ifdef SORT_UNIFORMS
 
1153
                                                SetUniformfv(loc, BL_Uniform::UNI_FLOAT3, array3, sizeof(float)*3);
 
1154
#else
 
1155
                                                SetUniform(loc, array3, 3);     
 
1156
#endif
 
1157
                                                Py_Return;
 
1158
                                        }break;
 
1159
                                case 4:
 
1160
                                        {
 
1161
                                                float array4[4] = { array_data[0],array_data[1],array_data[2],array_data[3] };
 
1162
#ifdef SORT_UNIFORMS
 
1163
                                                SetUniformfv(loc, BL_Uniform::UNI_FLOAT4, array4, sizeof(float)*4);
 
1164
#else
 
1165
                                                SetUniform(loc, array4, 4);     
 
1166
#endif
 
1167
                                                Py_Return;
 
1168
                                        }break;
 
1169
                                default:
 
1170
                                        {
 
1171
                                                PyErr_Format(PyExc_TypeError, "Invalid list size");
 
1172
                                                return NULL;
 
1173
                                        }break;
 
1174
                                }
 
1175
                        }
 
1176
                }
 
1177
        }
 
1178
        return NULL;
 
1179
}
 
1180
 
 
1181
KX_PYMETHODDEF_DOC( BL_Shader, setUniformiv, "setUniformiv( int (list2 or list3 or list4) )")
 
1182
{
 
1183
        if(mError) {
 
1184
                Py_RETURN_NONE;
 
1185
        }
 
1186
        const char *uniform = "";
 
1187
        PyObject *listPtr =0;
 
1188
        int array_data[4] = {0,0,0,0};
 
1189
 
 
1190
        if(PyArg_ParseTuple(args, "sO", &uniform, &listPtr))
 
1191
        {
 
1192
                int loc = GetUniformLocation(uniform);
 
1193
                if(loc != -1)
 
1194
                {
 
1195
                        if(PySequence_Check(listPtr))
 
1196
                        {
 
1197
                                unsigned int list_size = PySequence_Size(listPtr);
 
1198
                                
 
1199
                                for(unsigned int i=0; (i<list_size && i<4); i++)
 
1200
                                {
 
1201
                                        PyObject *item = PySequence_GetItem(listPtr, i);
 
1202
                                        array_data[i] = PyInt_AsLong(item);
 
1203
                                        Py_DECREF(item);
 
1204
                                }
 
1205
                                switch(list_size)
 
1206
                                {
 
1207
                                case 2:
 
1208
                                        {
 
1209
                                                int array2[2] = { array_data[0],array_data[1]};
 
1210
#ifdef SORT_UNIFORMS
 
1211
                                                SetUniformiv(loc, BL_Uniform::UNI_INT2, array2, sizeof(int)*2);
 
1212
#else
 
1213
                                                SetUniform(loc, array2, 2);                                             
 
1214
#endif
 
1215
                                                Py_Return;
 
1216
                                        } break;
 
1217
                                case 3:
 
1218
                                        {
 
1219
                                                int array3[3] = { array_data[0],array_data[1],array_data[2] };
 
1220
#ifdef SORT_UNIFORMS
 
1221
                                                SetUniformiv(loc, BL_Uniform::UNI_INT3, array3, sizeof(int)*3);
 
1222
                                                
 
1223
#else
 
1224
                                                SetUniform(loc, array3, 3);     
 
1225
#endif
 
1226
                                                Py_Return;
 
1227
                                        }break;
 
1228
                                case 4:
 
1229
                                        {
 
1230
                                                int array4[4] = { array_data[0],array_data[1],array_data[2],array_data[3] };
 
1231
#ifdef SORT_UNIFORMS
 
1232
                                                SetUniformiv(loc, BL_Uniform::UNI_INT4, array4, sizeof(int)*4);
 
1233
                                                
 
1234
#else
 
1235
                                                SetUniform(loc, array4, 4);     
 
1236
#endif
 
1237
                                                Py_Return;
 
1238
                                        }break;
 
1239
                                default:
 
1240
                                        {
 
1241
                                                PyErr_Format(PyExc_TypeError, "Invalid list size");
 
1242
                                                return NULL;
 
1243
                                        }break;
 
1244
                                }
 
1245
                        }
 
1246
                }
 
1247
        }
 
1248
        return NULL;
 
1249
}
 
1250
 
 
1251
 
 
1252
KX_PYMETHODDEF_DOC( BL_Shader, setUniformMatrix4, 
 
1253
"setUniformMatrix4(uniform-name, mat-4x4, transpose(row-major=true, col-major=false)" )
 
1254
{
 
1255
        if(mError) {
 
1256
                Py_RETURN_NONE;
 
1257
        }
 
1258
 
 
1259
        float matr[16] = {
 
1260
                1,0,0,0,
 
1261
                0,1,0,0,
 
1262
                0,0,1,0,
 
1263
                0,0,0,1
 
1264
        };
 
1265
 
 
1266
        const char *uniform="";
 
1267
        PyObject *matrix=0;
 
1268
        int transp=1; // MT_ is row major so transpose by default....
 
1269
        if(PyArg_ParseTuple(args, "sO|i",&uniform, &matrix,&transp))
 
1270
        {
 
1271
                int loc = GetUniformLocation(uniform);
 
1272
                if(loc != -1)
 
1273
                {
 
1274
                        if (PyObject_IsMT_Matrix(matrix, 4))
 
1275
                        {
 
1276
                                MT_Matrix4x4 mat;
 
1277
                                if (PyMatTo(matrix, mat))
 
1278
                                {
 
1279
#ifdef SORT_UNIFORMS
 
1280
                                        mat.getValue(matr);
 
1281
                                        SetUniformfv(loc, BL_Uniform::UNI_MAT4, matr, (sizeof(float)*16), (transp!=0) );
 
1282
#else
 
1283
                                        SetUniform(loc,mat,(transp!=0));
 
1284
#endif
 
1285
                                        Py_Return;
 
1286
                                }
 
1287
                        }
 
1288
                }
 
1289
        }
 
1290
        return NULL;
 
1291
}
 
1292
 
 
1293
 
 
1294
KX_PYMETHODDEF_DOC( BL_Shader, setUniformMatrix3,
 
1295
"setUniformMatrix3(uniform-name, list[3x3], transpose(row-major=true, col-major=false)" )
 
1296
{
 
1297
        if(mError) {
 
1298
                Py_RETURN_NONE;
 
1299
        }
 
1300
 
 
1301
        float matr[9] = {
 
1302
                1,0,0,
 
1303
                0,1,0,
 
1304
                0,0,1,
 
1305
        };
 
1306
 
 
1307
        const char *uniform="";
 
1308
        PyObject *matrix=0;
 
1309
        int transp=1; // MT_ is row major so transpose by default....
 
1310
        if(PyArg_ParseTuple(args, "sO|i",&uniform, &matrix,&transp))
 
1311
        {
 
1312
                int loc = GetUniformLocation(uniform);
 
1313
                if(loc != -1)
 
1314
                {
 
1315
                        if (PyObject_IsMT_Matrix(matrix, 3))
 
1316
                        {
 
1317
                                MT_Matrix3x3 mat;
 
1318
                                if (PyMatTo(matrix, mat))
 
1319
                                {
 
1320
#ifdef SORT_UNIFORMS
 
1321
                                        mat.getValue(matr);
 
1322
                                        SetUniformfv(loc, BL_Uniform::UNI_MAT3, matr, (sizeof(float)*9), (transp!=0) );
 
1323
#else
 
1324
                                        SetUniform(loc,mat,(transp!=0));
 
1325
#endif
 
1326
                                        Py_Return;
 
1327
 
 
1328
                                }
 
1329
                        }
 
1330
                }
 
1331
        }
 
1332
        return NULL;
 
1333
}
 
1334
 
 
1335
KX_PYMETHODDEF_DOC( BL_Shader, setAttrib, "setAttrib(enum)" )
 
1336
{
 
1337
        if(mError) {
 
1338
                Py_RETURN_NONE;
 
1339
        }
 
1340
        int attr=0;
 
1341
        if(PyArg_ParseTuple(args, "i", &attr )) {
 
1342
                if(mShader==0) {
 
1343
                        PyErr_Format(PyExc_ValueError, "invalid shader object");
 
1344
                        return NULL;
 
1345
                }
 
1346
                mAttr=SHD_TANGENT;
 
1347
                glUseProgramObjectARB(mShader);
 
1348
                glBindAttribLocationARB(mShader, mAttr, "Tangent");
 
1349
                Py_Return;
 
1350
        }
 
1351
        return NULL;
 
1352
}
 
1353
 
 
1354
 
 
1355
KX_PYMETHODDEF_DOC( BL_Shader, setUniformDef, "setUniformDef(name, enum)" )
 
1356
{
 
1357
        if(mError) {
 
1358
                Py_RETURN_NONE;
 
1359
        }
 
1360
 
 
1361
        const char *uniform="";
 
1362
        int nloc=0;
 
1363
        if(PyArg_ParseTuple(args, "si",&uniform, &nloc))
 
1364
        {
 
1365
                int loc = GetUniformLocation(uniform);
 
1366
                if(loc != -1)
 
1367
                {
 
1368
                        bool defined = false;
 
1369
                        BL_UniformVecDef::iterator it = mPreDef.begin();
 
1370
                        while(it != mPreDef.end()) {
 
1371
                                if((*it)->mLoc == loc) {
 
1372
                                        defined = true;
 
1373
                                        break;
 
1374
                                }
 
1375
                                it++;
 
1376
                        }
 
1377
                        if(defined)
 
1378
                        {
 
1379
                                Py_Return;
 
1380
                        }
 
1381
 
 
1382
                        BL_DefUniform *uni = new BL_DefUniform();
 
1383
                        uni->mLoc = loc;
 
1384
                        uni->mType = nloc;
 
1385
                        uni->mFlag = 0;
 
1386
                        mPreDef.push_back(uni);
 
1387
                        Py_Return;
 
1388
                }
 
1389
        }
 
1390
        return NULL;
 
1391
}
 
1392
 
 
1393
// eof