attempt to avoid nameclashes (although it is already in a namespace) -> extension...
[blender.git] / source / gameengine / Ketsji / KX_BlenderMaterial.cpp
1
2 // ------------------------------------
3 // ...
4 // ------------------------------------
5 #ifdef HAVE_CONFIG_H
6 #include <config.h>
7 #endif
8
9 #ifdef WIN32
10 #include <windows.h>
11 #endif // WIN32
12 #ifdef __APPLE__
13 #include <OpenGL/gl.h>
14 #include <OpenGL/glu.h>
15 #else
16 #include <GL/gl.h>
17 #include <GL/glu.h>
18 #endif
19
20 #include "KX_BlenderMaterial.h"
21 #include "BL_Material.h"
22 #include "KX_Scene.h"
23 #include "KX_Light.h"
24 #include "KX_GameObject.h"
25
26 #include "MT_Vector3.h"
27 #include "MT_Vector4.h"
28 #include "MT_Matrix4x4.h"
29
30 #include "RAS_MeshObject.h"
31 #include "RAS_IRasterizer.h"
32 #include "RAS_OpenGLRasterizer/RAS_GLExtensionManager.h"
33 #include "RAS_OpenGLRasterizer/ARB_multitexture.h"
34
35 extern "C" {
36 #include "BDR_drawmesh.h"
37 }
38
39 #include "STR_HashedString.h"
40
41 // ------------------------------------
42 #include "DNA_object_types.h"
43 #include "DNA_material_types.h"
44 #include "DNA_image_types.h"
45 #include "DNA_mesh_types.h"
46 #include "BKE_mesh.h"
47 // ------------------------------------
48 using namespace bgl;
49 #define spit(x) std::cout << x << std::endl;
50
51 //static PyObject *gTextureDict = 0;
52
53 KX_BlenderMaterial::KX_BlenderMaterial(
54     KX_Scene *scene,
55         BL_Material *data,
56         bool skin,
57         int lightlayer,
58         void *clientobject,
59         PyTypeObject *T
60         )
61 :       PyObjectPlus(T),
62         RAS_IPolyMaterial(
63                 STR_String( data->texname[0] ),
64                 STR_String( data->matname ), // needed for physics!
65                 data->tile,
66                 data->tilexrep[0],
67                 data->tileyrep[0],
68                 data->mode,
69                 ((data->ras_mode &TRANSP)!=0),
70                 ((data->ras_mode &ZSORT)!=0),
71                 lightlayer,
72                 ((data->ras_mode &TRIANGLE)!=0),
73                 clientobject
74         ),
75         mMaterial(data),
76         mShader(0),
77         mScene(scene),
78         mPass(0)
79 {
80         ///RAS_EXT_support._ARB_multitexture == true if were here
81
82         // --------------------------------
83         // RAS_IPolyMaterial variables... 
84         m_flag |=RAS_BLENDERMAT;
85         m_flag |=(mMaterial->IdMode>=ONETEX)?RAS_MULTITEX:0;
86         m_flag |=(mMaterial->ras_mode & USE_LIGHT)!=0?RAS_MULTILIGHT:0;
87         
88         // figure max
89         #ifdef GL_ARB_multitexture
90         int enabled = mMaterial->num_enabled;
91         mMaterial->num_enabled = enabled>=bgl::max_texture_units?bgl::max_texture_units:enabled;
92         #else
93         mMaterial->num_enabled=0;
94         #endif
95
96         m_enabled = mMaterial->num_enabled;
97
98         // test the sum of the various modes for equality
99         // so we can ether accept or reject this material 
100         // as being equal, this is rather important to 
101         // prevent material bleeding
102         for(int i=0; i<mMaterial->num_enabled; i++) {
103                 m_multimode     +=
104                         (mMaterial->flag[i]     +
105                          mMaterial->blend_mode[i]
106                          );
107         }
108         m_multimode += mMaterial->IdMode+mMaterial->ras_mode;
109
110 }
111
112
113 KX_BlenderMaterial::~KX_BlenderMaterial()
114 {
115         // cleanup work
116         OnExit();
117 }
118
119
120 TFace* KX_BlenderMaterial::GetTFace(void) const 
121 {
122         // fonts on polys
123         MT_assert(mMaterial->tface);
124         return mMaterial->tface;
125 }
126
127 void KX_BlenderMaterial::OnConstruction()
128 {
129         // for each unique material...
130         #ifdef GL_ARB_multitexture
131 /*      will be used to switch textures
132         if(!gTextureDict)
133                 gTextureDict = PyDict_New();
134 */
135         #ifdef GL_ARB_shader_objects
136         if( RAS_EXT_support._ARB_shader_objects )
137                 mShader = new BL_Shader( mMaterial->num_enabled );
138         #endif
139
140         int i;
141         for(i=0; i<mMaterial->num_enabled; i++) {
142         bgl::blActiveTextureARB(GL_TEXTURE0_ARB+i);
143                 #ifdef GL_ARB_texture_cube_map
144                 if( mMaterial->mapping[i].mapping & USEENV ) {
145                         if(!RAS_EXT_support._ARB_texture_cube_map) {
146                                 spit("CubeMap textures not supported");
147                                 continue;
148                         }
149                         if(!mTextures[i].InitCubeMap( mMaterial->cubemap[i] ) )
150                                 spit("unable to initialize image("<<i<<") in "<< 
151                                                 mMaterial->matname<< ", image will not be available");
152
153                         if( RAS_EXT_support._ARB_shader_objects )
154                                 mShader->InitializeSampler(SAMP_CUBE, i, 0, mTextures[i]);
155                 } 
156         
157                 else {
158                 #endif//GL_ARB_texture_cube_map
159                         if( mMaterial->img[i] ) {
160                                 if( ! mTextures[i].InitFromImage(mMaterial->img[i], (mMaterial->flag[i] &MIPMAP)!=0 ))
161                                         spit("unable to initialize image("<<i<<") in "<< 
162                                                  mMaterial->matname<< ", image will not be available");
163                         
164                                 if( RAS_EXT_support._ARB_shader_objects )
165                                         mShader->InitializeSampler(SAMP_2D, i, 0, mTextures[i]);
166                         }
167                 #ifdef GL_ARB_texture_cube_map
168                 }
169                 #endif//GL_ARB_texture_cube_map
170                 /*PyDict_SetItemString(gTextureDict, mTextures[i].GetName().Ptr(), PyInt_FromLong(mTextures[i]));*/
171         }
172         #endif//GL_ARB_multitexture
173 }
174
175 void KX_BlenderMaterial::OnExit()
176 {
177         #ifdef GL_ARB_multitexture
178
179         #ifdef GL_ARB_shader_objects
180         if( RAS_EXT_support._ARB_shader_objects && mShader ) {
181                  //note, the shader here is allocated, per unique material
182                  //and this function is called per face
183                 bgl::blUseProgramObjectARB(0);
184                 delete mShader;
185                 mShader = 0;
186         }
187         #endif //GL_ARB_shader_objects
188
189         for(int i=0; i<mMaterial->num_enabled; i++) {
190                 bgl::blActiveTextureARB(GL_TEXTURE0_ARB+i);
191
192                 mTextures[i].DeleteTex();
193
194                 glMatrixMode(GL_TEXTURE);
195                 glLoadIdentity();
196                 glMatrixMode(GL_MODELVIEW);
197
198                 #ifdef GL_ARB_texture_cube_map
199                 if(RAS_EXT_support._ARB_texture_cube_map)
200                         glDisable(GL_TEXTURE_CUBE_MAP_ARB);
201                 #endif//GL_ARB_texture_cube_map
202
203                 glDisable(GL_TEXTURE_2D);
204                 glDisable(GL_TEXTURE_GEN_S);
205                 glDisable(GL_TEXTURE_GEN_T);
206                 glDisable(GL_TEXTURE_GEN_R);
207                 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
208         }
209         
210         /*if (gTextureDict) {
211                 PyDict_Clear(gTextureDict);
212                 Py_DECREF(gTextureDict);
213                 gTextureDict = 0;
214         }*/
215
216         bgl::blActiveTextureARB(GL_TEXTURE0_ARB);
217
218         #ifdef GL_ARB_texture_cube_map
219         if(RAS_EXT_support._ARB_texture_cube_map)
220                 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
221         #endif//GL_ARB_texture_cube_map
222
223         glDisable(GL_TEXTURE_2D);
224
225         #endif//GL_ARB_multitexture
226
227         // make sure multi texture units 
228         // revert back to blender...
229         // --
230         if( mMaterial->tface ) 
231                 set_tpage(mMaterial->tface);
232 }
233
234
235 void KX_BlenderMaterial::DisableTexData()
236 {
237         glDisable(GL_BLEND);
238         #ifdef GL_ARB_multitexture
239         int i=(MAXTEX>=bgl::max_texture_units?bgl::max_texture_units:MAXTEX)-1;
240         for(; i>=0; i--) {
241                 bgl::blActiveTextureARB(GL_TEXTURE0_ARB+i);
242                 glMatrixMode(GL_TEXTURE);
243                 glLoadIdentity();
244                 glMatrixMode(GL_MODELVIEW);
245
246                 #ifdef GL_ARB_texture_cube_map
247                 if(RAS_EXT_support._ARB_texture_cube_map)
248                         glDisable(GL_TEXTURE_CUBE_MAP_ARB);
249                 #endif//GL_ARB_texture_cube_map
250
251                 glDisable(GL_TEXTURE_2D);       
252                 glDisable(GL_TEXTURE_GEN_S);
253                 glDisable(GL_TEXTURE_GEN_T);
254                 glDisable(GL_TEXTURE_GEN_R);
255                 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
256         }
257         #endif//GL_ARB_multitexture
258 }
259
260
261 void KX_BlenderMaterial::setShaderData( bool enable )
262 {
263         #ifdef GL_ARB_multitexture 
264         #ifdef GL_ARB_shader_objects 
265
266         MT_assert(RAS_EXT_support._ARB_shader_objects && mShader);
267
268         int i;
269         if( !enable || !mShader->Ok() ) {
270                 // frame cleanup.
271                 bgl::blUseProgramObjectARB( 0 );
272                 DisableTexData();
273                 return;
274         }
275
276         DisableTexData();
277         bgl::blUseProgramObjectARB( mShader->GetProg() );
278         
279         // for each enabled unit
280         for(i=0; i<mMaterial->num_enabled; i++) {
281
282                 const uSampler *samp = mShader->getSampler(i);
283                 if( samp->loc == -1 || samp->glTexture == 0 ) continue;
284
285                 bgl::blActiveTextureARB(GL_TEXTURE0_ARB+i);
286
287                 #ifdef GL_ARB_texture_cube_map
288                 if( mMaterial->mapping[i].mapping &USEENV ) {
289                         glBindTexture( GL_TEXTURE_CUBE_MAP_ARB, samp->glTexture /* mTextures[i]*/ );    
290                         glEnable( GL_TEXTURE_CUBE_MAP_ARB );
291                 } 
292                 else {
293                 #endif//GL_ARB_texture_cube_map
294                         glBindTexture( GL_TEXTURE_2D, samp->glTexture   /*mTextures[i]*/ );     
295                         glEnable( GL_TEXTURE_2D );
296                 #ifdef GL_ARB_texture_cube_map
297                 }
298                 #endif//GL_ARB_texture_cube_map
299                 // use a sampler
300                 bgl::blUniform1iARB(samp->loc, i );
301         }
302         glDisable(GL_BLEND);
303
304         #endif//GL_ARB_shader_objects
305         #endif//GL_ARB_multitexture
306 }
307
308
309 void KX_BlenderMaterial::setTexData( bool enable )
310 {
311         #ifdef GL_ARB_multitexture
312         int i;
313
314         #ifdef GL_ARB_shader_objects
315         if(RAS_EXT_support._ARB_shader_objects) {
316                 // switch back to fixed func
317                 bgl::blUseProgramObjectARB( 0 );
318         }
319         #endif//GL_ARB_shader_objects
320
321         if( !enable ) {
322                  // frame cleanup.
323                 DisableTexData();
324                 return;
325         }
326         
327         DisableTexData();
328
329         if( mMaterial->IdMode == DEFAULT_BLENDER ) {
330                 setDefaultBlending();
331                 return;
332         }
333
334         if( mMaterial->IdMode == TEXFACE ) {
335
336                 // no material connected to the object
337                 if( mTextures[0] ) {
338                         if( !mTextures[0].Ok() ) return;
339                         bgl::blActiveTextureARB(GL_TEXTURE0_ARB);
340                         glBindTexture( GL_TEXTURE_2D, mTextures[0] );   
341                         glEnable(GL_TEXTURE_2D);
342                         setTextureEnvironment( -1 ); // modulate
343                         setEnvMap( (mMaterial->mapping[0].mapping &USEREFL)!=0 );
344                         setDefaultBlending(); 
345                 }
346                 return;
347         }
348
349         int lastblend = 0;
350
351         // for each enabled unit
352         for(i=0; (i<mMaterial->num_enabled); i++) {
353                 if( !mTextures[i].Ok() ) continue;
354
355                 bgl::blActiveTextureARB(GL_TEXTURE0_ARB+i);
356
357                 #ifdef GL_ARB_texture_cube_map
358                 // use environment maps
359                 if( mMaterial->mapping[i].mapping &USEENV && RAS_EXT_support._ARB_texture_cube_map ) {
360                         glBindTexture( GL_TEXTURE_CUBE_MAP_ARB, mTextures[i] ); 
361                         glEnable(GL_TEXTURE_CUBE_MAP_ARB);
362                         setTextureEnvironment( i );
363
364                         if( mMaterial->mapping[i].mapping &USEREFL )
365                                 setEnvMap( true, true );
366                         else if(mMaterial->mapping[i].mapping &USEOBJ)
367                                 setObjectMatrixData(i);
368                         else
369                                 setTexMatrixData( i );
370                 } 
371                 // 2d textures
372                 else { 
373                 #endif//GL_ARB_texture_cube_map
374                         glBindTexture( GL_TEXTURE_2D, mTextures[i] );   
375                         glEnable( GL_TEXTURE_2D );
376                         setTextureEnvironment( i );
377                         
378                         if( mMaterial->mapping[i].mapping &USEREFL ){
379                                 setEnvMap( true );
380                         }
381                         else if(mMaterial->mapping[i].mapping &USEOBJ){
382                                 setObjectMatrixData(i);
383                         }
384                         else {
385                                 setTexMatrixData( i );
386                         }
387
388                 #ifdef GL_ARB_texture_cube_map
389                 }
390                 #endif//GL_ARB_texture_cube_map
391
392                 // if either unit has set blending
393                 // and its the last pass
394                 lastblend += setBlending( i ); // dry run
395                 if(lastblend >0 && i==mMaterial->num_enabled-1)
396                         setBlending( i, true );
397                 else if(lastblend == 0 && i==mMaterial->num_enabled-1)
398                         glDisable(GL_BLEND);
399         }
400         #endif//GL_ARB_multitexture
401 }
402
403 void
404 KX_BlenderMaterial::ActivatShaders(
405         RAS_IRasterizer* rasty, 
406         TCachingInfo& cachingInfo)const
407 {
408         if (GetCachingInfo() != cachingInfo) {
409                 KX_BlenderMaterial *tmp = const_cast<KX_BlenderMaterial*>(this);
410
411                 if (!cachingInfo)
412                         tmp->setShaderData( false );
413                 
414                 cachingInfo = GetCachingInfo();
415         
416                 if (rasty->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED ) {
417                         tmp->setShaderData( true );
418                         rasty->EnableTextures(true);
419                 }
420                 else {
421                         tmp->setShaderData( false );
422                         rasty->EnableTextures(false);
423                 }
424
425                 if(mMaterial->mode & RAS_IRasterizer::KX_TWOSIDE)
426                         rasty->SetCullFace(false);
427                 else
428                         rasty->SetCullFace(true);
429
430                 if (((mMaterial->ras_mode &WIRE)!=0) || mMaterial->mode & RAS_IRasterizer::KX_LINES)
431                         rasty->SetLines(true);
432                 else
433                         rasty->SetLines(false);
434         }
435         
436         // shaders have access to the variables set here
437         // via builtin GLSL variables
438         // eg: gl_FrontMaterial.diffuse
439         // --
440         rasty->SetSpecularity(
441                 mMaterial->speccolor[0]*mMaterial->spec_f,
442                 mMaterial->speccolor[1]*mMaterial->spec_f,
443                 mMaterial->speccolor[2]*mMaterial->spec_f,
444                 mMaterial->spec_f
445         );
446
447         rasty->SetShinyness( mMaterial->hard );
448
449         rasty->SetDiffuse(
450                 mMaterial->matcolor[0]*mMaterial->ref+mMaterial->emit, 
451                 mMaterial->matcolor[1]*mMaterial->ref+mMaterial->emit,
452                 mMaterial->matcolor[2]*mMaterial->ref+mMaterial->emit,
453                 1.0f);
454
455         rasty->SetEmissive(     
456                 mMaterial->matcolor[0]*mMaterial->emit,
457                 mMaterial->matcolor[1]*mMaterial->emit,
458                 mMaterial->matcolor[2]*mMaterial->emit,
459                 1.0
460                 );
461
462         // Lagan's patch...
463         // added material factor
464         rasty->SetAmbient(mMaterial->amb);
465
466         if (mMaterial->material)
467                 rasty->SetPolygonOffset(-mMaterial->material->zoffs, 0.0);
468 }
469
470 void
471 KX_BlenderMaterial::ActivateMat( 
472         RAS_IRasterizer* rasty,  
473         TCachingInfo& cachingInfo
474         )const
475 {
476         if (GetCachingInfo() != cachingInfo) {
477                 KX_BlenderMaterial *tmp = const_cast<KX_BlenderMaterial*>(this);
478
479                 if (!cachingInfo) 
480                         tmp->setTexData( false );
481                 
482                 cachingInfo = GetCachingInfo();
483
484                 if (rasty->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED) {
485                         tmp->setTexData( true );
486                         rasty->EnableTextures(true);
487                 }
488                 else{
489                         tmp->setTexData( false );
490                         rasty->EnableTextures(false);
491                 }
492
493                 if(mMaterial->mode & RAS_IRasterizer::KX_TWOSIDE)
494                         rasty->SetCullFace(false);
495                 else
496                         rasty->SetCullFace(true);
497
498                 if (((mMaterial->ras_mode &WIRE)!=0) || mMaterial->mode & RAS_IRasterizer::KX_LINES)
499                         rasty->SetLines(true);
500                 else
501                         rasty->SetLines(false);
502         }
503                 
504         rasty->SetSpecularity(
505                 mMaterial->speccolor[0]*mMaterial->spec_f,
506                 mMaterial->speccolor[1]*mMaterial->spec_f,
507                 mMaterial->speccolor[2]*mMaterial->spec_f,
508                 mMaterial->spec_f
509         );
510
511         rasty->SetShinyness( mMaterial->hard );
512
513         rasty->SetDiffuse(
514                 mMaterial->matcolor[0]*mMaterial->ref+mMaterial->emit, 
515                 mMaterial->matcolor[1]*mMaterial->ref+mMaterial->emit,
516                 mMaterial->matcolor[2]*mMaterial->ref+mMaterial->emit,
517                 1.0f);
518
519         rasty->SetEmissive(     
520                 mMaterial->matcolor[0]*mMaterial->emit,
521                 mMaterial->matcolor[1]*mMaterial->emit,
522                 mMaterial->matcolor[2]*mMaterial->emit,
523                 1.0
524                 );
525         
526         // Lagan's patch...
527         // added material factor
528         rasty->SetAmbient(mMaterial->amb);
529
530         if (mMaterial->material)
531                 rasty->SetPolygonOffset(-mMaterial->material->zoffs, 0.0);
532 }
533
534 bool 
535 KX_BlenderMaterial::Activate( 
536         RAS_IRasterizer* rasty,  
537         TCachingInfo& cachingInfo
538         )const
539 {
540         bool dopass = false;
541         #ifdef GL_ARB_shader_objects
542         if( RAS_EXT_support._ARB_shader_objects &&
543                 ( mShader && mShader->Ok() ) ) {
544
545                 if( (mPass++) < mShader->getNumPass() ) {
546                         ActivatShaders(rasty, cachingInfo);
547                         dopass = true;
548                         return dopass;
549                 }
550                 else {
551                         bgl::blUseProgramObjectARB( 0 );
552                         mPass = 0;
553                         dopass = false;
554                         return dopass;
555                 }
556         }
557         else {
558         #endif//GL_ARB_shader_objects
559                 switch (mPass++)
560                 {
561                         case 0:
562                                 ActivateMat(rasty, cachingInfo);
563                                 dopass = true;
564                                 break;
565                         default:
566                                 mPass = 0;
567                                 dopass = false;
568                                 break;
569                 }
570         #ifdef GL_ARB_shader_objects
571         }
572         #endif//GL_ARB_shader_objects
573         return dopass;
574 }
575
576 void KX_BlenderMaterial::setTextureEnvironment( int textureIndex )
577 {
578 #ifndef GL_ARB_texture_env_combine
579         glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
580         return;
581 #else
582         if(textureIndex == -1 || !RAS_EXT_support._ARB_texture_env_combine){
583                 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
584                 return;
585         }
586
587         glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB );
588
589         GLfloat blend_operand           = GL_SRC_COLOR;
590         GLfloat blend_operand_prev      = GL_SRC_COLOR;
591
592         // all sources here are RGB by default
593         GLenum combiner = GL_COMBINE_RGB_ARB;
594         GLenum source0 = GL_SOURCE0_RGB_ARB;
595         GLenum source1 = GL_SOURCE1_RGB_ARB;
596         GLenum source2 = GL_SOURCE2_RGB_ARB;
597         GLenum op0 = GL_OPERAND0_RGB_ARB;
598         GLenum op1 = GL_OPERAND1_RGB_ARB;
599         GLenum op2 = GL_OPERAND2_RGB_ARB;
600
601         // switch to alpha combiners
602         if( (mMaterial->flag[textureIndex] &TEXALPHA) ) {
603                 combiner = GL_COMBINE_ALPHA_ARB;
604                 source0  = GL_SOURCE0_ALPHA_ARB;
605                 source1 = GL_SOURCE1_ALPHA_ARB;
606                 source2 = GL_SOURCE2_ALPHA_ARB;
607                 op0 = GL_OPERAND0_ALPHA_ARB;
608                 op1 = GL_OPERAND1_ALPHA_ARB;
609                 op2 = GL_OPERAND2_ALPHA_ARB;
610                 blend_operand = GL_SRC_ALPHA;
611                 blend_operand_prev = GL_SRC_ALPHA;
612                 
613                 // invert
614                 if(mMaterial->flag[textureIndex] &TEXNEG) {
615                         blend_operand_prev = GL_ONE_MINUS_SRC_ALPHA;
616                         blend_operand = GL_ONE_MINUS_SRC_ALPHA;
617                 }
618         }
619         else {
620                 if(mMaterial->flag[textureIndex] &TEXNEG) {
621                         blend_operand_prev = GL_ONE_MINUS_SRC_COLOR;
622                         blend_operand = GL_ONE_MINUS_SRC_COLOR;
623                 }
624         }
625         // on Texture0 GL_PREVIOUS_ARB is the primary color
626         // on Texture1 GL_PREVIOUS_ARB is Texture0 env
627         switch( mMaterial->blend_mode[textureIndex] ) {
628                 case BLEND_MIX:
629                         {
630                                 // ------------------------------
631                                 GLfloat base_col[4];
632                                 base_col[0]      = base_col[1]  = base_col[2]  = 0.f;
633                                 base_col[3]      = 1.f-mMaterial->color_blend[textureIndex];
634                                 glTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,base_col );
635                                 glTexEnvf(      GL_TEXTURE_ENV, combiner,       GL_INTERPOLATE_ARB);
636                                 glTexEnvf(      GL_TEXTURE_ENV, source0,        GL_PREVIOUS_ARB);
637                                 glTexEnvf(      GL_TEXTURE_ENV, op0,            blend_operand_prev );
638                                 glTexEnvf(      GL_TEXTURE_ENV, source1,        GL_TEXTURE );
639                                 glTexEnvf(      GL_TEXTURE_ENV, op1,            blend_operand);
640                                 glTexEnvf(      GL_TEXTURE_ENV, source2,        GL_CONSTANT_ARB );
641                                 glTexEnvf(      GL_TEXTURE_ENV, op2,            GL_SRC_ALPHA);
642                         }break;
643                 case BLEND_MUL: 
644                         {
645                                 // ------------------------------
646                                 glTexEnvf(      GL_TEXTURE_ENV, combiner,       GL_MODULATE);
647                                 glTexEnvf(      GL_TEXTURE_ENV, source0,        GL_PREVIOUS_ARB);
648                                 glTexEnvf(      GL_TEXTURE_ENV, op0,            blend_operand_prev);
649                                 glTexEnvf(      GL_TEXTURE_ENV, source1,        GL_TEXTURE );
650                                 glTexEnvf(      GL_TEXTURE_ENV, op1,            blend_operand);
651                         }break;
652                 case BLEND_ADD: 
653                         {
654                                 // ------------------------------
655                                 glTexEnvf(      GL_TEXTURE_ENV, combiner,       GL_ADD_SIGNED_ARB);
656                                 glTexEnvf(      GL_TEXTURE_ENV, source0,        GL_PREVIOUS_ARB );
657                                 glTexEnvf(      GL_TEXTURE_ENV, op0,            blend_operand_prev );
658                                 glTexEnvf(      GL_TEXTURE_ENV, source1,        GL_TEXTURE );
659                                 glTexEnvf(      GL_TEXTURE_ENV, op1,            blend_operand );
660                         }break;
661                 case BLEND_SUB: 
662                         {
663                                 // ------------------------------
664                                 glTexEnvf(      GL_TEXTURE_ENV, combiner,       GL_SUBTRACT_ARB);
665                                 glTexEnvf(      GL_TEXTURE_ENV, source0,        GL_PREVIOUS_ARB );
666                                 glTexEnvf(      GL_TEXTURE_ENV, op0,            blend_operand_prev );
667                                 glTexEnvf(      GL_TEXTURE_ENV, source1,        GL_TEXTURE );
668                                 glTexEnvf(      GL_TEXTURE_ENV, op1,            blend_operand);
669                         }break;
670                 case BLEND_SCR: 
671                         {
672                                 // ------------------------------
673                                 glTexEnvf(      GL_TEXTURE_ENV, combiner,       GL_ADD);
674                                 glTexEnvf(      GL_TEXTURE_ENV, source0,        GL_PREVIOUS_ARB );
675                                 glTexEnvf(      GL_TEXTURE_ENV, op0,            blend_operand_prev );
676                                 glTexEnvf(      GL_TEXTURE_ENV, source1,        GL_TEXTURE );
677                                 glTexEnvf(      GL_TEXTURE_ENV, op1,            blend_operand);
678                         } break;
679         }
680 #endif //!GL_ARB_texture_env_combine
681 }
682
683 bool KX_BlenderMaterial::setBlending( int ind, bool enable) 
684 {
685         if(!enable) {
686                 if(mMaterial->flag[ind] &CALCALPHA )    return true;
687                 else if(mMaterial->flag[ind] &USEALPHA )        return true;
688                 return false;
689         }
690         else {
691                 // additive
692                 if(mMaterial->flag[ind] &CALCALPHA ) {
693                         glEnable(GL_BLEND);
694                         glBlendFunc(GL_ONE, GL_ONE);
695                         return true;
696                 }
697
698                 // use alpha channel
699                 else if(mMaterial->flag[ind] &USEALPHA ) {
700                         glEnable(GL_BLEND);
701                         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
702                         return true;
703                 }
704         }
705         return false;
706 }
707
708 bool KX_BlenderMaterial::setDefaultBlending()
709 {
710         if( mMaterial->transp &TF_ADD) {
711                 glEnable(GL_BLEND);
712                 glBlendFunc(GL_ONE, GL_ONE);
713                 return true;
714         }
715         
716         if( mMaterial->transp & TF_ALPHA ) {
717                 glEnable(GL_BLEND);
718                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
719                 return true;
720         }
721         
722         glDisable(GL_BLEND);
723         return false;
724 }
725
726 void KX_BlenderMaterial::setEnvMap(bool val, bool cube)
727 {
728         #ifdef GL_ARB_texture_cube_map
729         if( cube && RAS_EXT_support._ARB_texture_cube_map ) 
730         {
731                 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB );
732                 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB);
733                 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB);
734
735                 glEnable(GL_TEXTURE_GEN_S);
736                 glEnable(GL_TEXTURE_GEN_T);
737                 glEnable(GL_TEXTURE_GEN_R);
738         }
739         else {
740         #endif//GL_ARB_texture_cube_map
741                 if( val ) {
742                         glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
743                         glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
744                         
745                         glEnable(GL_TEXTURE_GEN_S);
746                         glEnable(GL_TEXTURE_GEN_T);
747                         glEnable(GL_TEXTURE_GEN_R);
748                 }
749                 else {
750                         glDisable(GL_TEXTURE_GEN_S);
751                         glDisable(GL_TEXTURE_GEN_T);
752                         glDisable(GL_TEXTURE_GEN_R);
753                 }
754         #ifdef GL_ARB_texture_cube_map
755         }
756         #endif//GL_ARB_texture_cube_map
757 }
758
759
760 void KX_BlenderMaterial::setTexMatrixData(int i)
761 {
762         glMatrixMode(GL_TEXTURE);
763         glLoadIdentity();
764
765         glScalef( 
766                 mMaterial->mapping[i].scale[0], 
767                 mMaterial->mapping[i].scale[1], 
768                 mMaterial->mapping[i].scale[2]
769         );
770         glTranslatef(
771                 mMaterial->mapping[i].offsets[0],
772                 mMaterial->mapping[i].offsets[1], 
773                 mMaterial->mapping[i].offsets[2]
774         );
775
776         glMatrixMode(GL_MODELVIEW);
777
778 }
779
780 static void GetProjPlane(BL_Material *mat, int index,int num, float*param)
781 {
782         param[0]=param[1]=param[2]=param[3]=0.f;
783         if( mat->mapping[index].projplane[num] == PROJX )
784                 param[0] = 1.f;
785         else if( mat->mapping[index].projplane[num] == PROJY )
786                 param[1] = 1.f;
787         else if( mat->mapping[index].projplane[num] == PROJZ)
788                 param[2] = 1.f;
789 }
790
791
792 void KX_BlenderMaterial::setObjectMatrixData(int i)
793 {
794         // will work without cubemaps
795         // but a cubemap will look the best
796         KX_GameObject *obj = 
797                 (KX_GameObject*)
798                 mScene->GetObjectList()->FindValue(mMaterial->mapping[i].objconame);
799
800         if(!obj)
801                 return;
802
803         glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
804         glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
805         glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
806
807         GLenum plane = GL_EYE_PLANE;
808
809         // figure plane gen
810         float proj[4]= {0.f,0.f,0.f,0.f};
811         GetProjPlane(mMaterial, i, 0, proj);
812         glTexGenfv(GL_S, plane, proj);
813         
814         GetProjPlane(mMaterial, i, 1, proj);
815         glTexGenfv(GL_T, plane, proj);
816
817         GetProjPlane(mMaterial, i, 2, proj);
818         glTexGenfv(GL_R, plane, proj);
819
820         glEnable(GL_TEXTURE_GEN_S);
821         glEnable(GL_TEXTURE_GEN_T);
822         glEnable(GL_TEXTURE_GEN_R);
823
824         float matr[16];
825         glGetFloatv(GL_MODELVIEW_MATRIX, matr);
826         MT_Matrix4x4 mvmat(matr);
827
828         glMatrixMode(GL_TEXTURE);
829         glLoadIdentity();
830         glScalef( 
831                 mMaterial->mapping[i].scale[0], 
832                 mMaterial->mapping[i].scale[1], 
833                 mMaterial->mapping[i].scale[2]
834         );
835
836         MT_Point3 pos = obj->NodeGetWorldPosition();
837         MT_Vector4 matmul = MT_Vector4(pos[0], pos[1], pos[2], 1.f);
838         MT_Vector4 t = mvmat*matmul;
839
840         glTranslatef( (float)(-t[0]), (float)(-t[1]), (float)(-t[2]) );
841
842         glMatrixMode(GL_MODELVIEW);
843
844 }
845
846
847 // ------------------------------------
848 void KX_BlenderMaterial::UpdateIPO(
849         MT_Vector4 rgba,
850         MT_Vector3 specrgb,
851         MT_Scalar hard,
852         MT_Scalar spec,
853         MT_Scalar ref,
854         MT_Scalar emit,
855         MT_Scalar alpha
856         )
857 {
858         // only works one deep now
859         mMaterial->speccolor[0] = (float)(specrgb)[0];
860         mMaterial->speccolor[1] = (float)(specrgb)[1];
861         mMaterial->speccolor[2] = (float)(specrgb)[2];
862         mMaterial->matcolor[0]  = (float)(rgba[0]);
863         mMaterial->matcolor[1]  = (float)(rgba[1]);
864         mMaterial->matcolor[2]  = (float)(rgba[2]);
865         mMaterial->alpha                = (float)(alpha);
866         mMaterial->hard                 = (float)(hard);
867         mMaterial->emit                 = (float)(emit);
868         mMaterial->spec_f               = (float)(spec);
869 }
870
871
872 PyMethodDef KX_BlenderMaterial::Methods[] = 
873 {
874         KX_PYMETHODTABLE( KX_BlenderMaterial, getShader ),
875         KX_PYMETHODTABLE( KX_BlenderMaterial, getMaterialIndex ),
876 //      KX_PYMETHODTABLE( KX_BlenderMaterial, getTexture ),
877 //      KX_PYMETHODTABLE( KX_BlenderMaterial, setTexture ),
878
879         {NULL,NULL} //Sentinel
880 };
881
882
883 PyTypeObject KX_BlenderMaterial::Type = {
884         PyObject_HEAD_INIT(&PyType_Type)
885                 0,
886                 "KX_BlenderMaterial",
887                 sizeof(KX_BlenderMaterial),
888                 0,
889                 PyDestructor,
890                 0,
891                 __getattr,
892                 __setattr,
893                 0,
894                 __repr,
895                 0
896 };
897
898
899 PyParentObject KX_BlenderMaterial::Parents[] = {
900         &PyObjectPlus::Type,
901         &KX_BlenderMaterial::Type,
902         NULL
903 };
904
905
906 PyObject* KX_BlenderMaterial::_getattr(const STR_String& attr)
907 {
908         // nodda ?
909         _getattr_up(PyObjectPlus);
910 }
911
912 int KX_BlenderMaterial::_setattr(const STR_String& attr, PyObject *pyvalue)
913 {
914         return PyObjectPlus::_setattr(attr, pyvalue);
915 }
916
917 KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getShader , "getShader()")
918 {
919         #ifdef GL_ARB_shader_objects
920         if(!RAS_EXT_support._ARB_shader_objects) {
921                 PyErr_Format(PyExc_SystemError, "GLSL not supported");
922                 return NULL;
923         }
924         else {
925                 Py_INCREF(mShader);
926                 return mShader;
927         }
928         #else
929         Py_Return;
930         #endif//GL_ARB_shader_objects
931 }
932
933 KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getMaterialIndex, "getMaterialIndex()")
934 {
935         return PyInt_FromLong( mMaterial->material_index );
936 }
937
938 KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getTexture, "getTexture( index )" )
939 {
940         // TODO: enable python switching
941         return NULL;
942 }
943
944 KX_PYMETHODDEF_DOC( KX_BlenderMaterial, setTexture , "setTexture( index, tex)")
945 {
946         // TODO: enable python switching
947         return NULL;
948 }
949