disable game engine and gameplayer for all platforms except windows.
[blender.git] / source / gameengine / Ketsji / KX_BlenderMaterial.cpp
1 // ------------------------------------
2 // ...
3 // ------------------------------------
4 #ifdef WIN32
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_GLExtensionManager.h"
33 #include "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         mScene(scene),
77         mShader(0),
78         mUseShader(0),
79         mPass(0)
80 {
81         ///RAS_EXT_support._ARB_multitexture == true if were here
82
83         // --------------------------------
84         // RAS_IPolyMaterial variables... 
85         m_flag |=RAS_BLENDERMAT;
86         m_flag |=(mMaterial->IdMode>=ONETEX)?RAS_MULTITEX:0;
87         m_flag |=(mMaterial->ras_mode & USE_LIGHT)!=0?RAS_MULTILIGHT:0;
88         
89         // figure max
90         #ifdef GL_ARB_multitexture
91         int enabled = mMaterial->num_enabled;
92         mMaterial->num_enabled = enabled>=bgl::max_texture_units?bgl::max_texture_units:enabled;
93         #else
94         mMaterial->num_enabled=0;
95         #endif
96
97         m_enabled = mMaterial->num_enabled;
98
99         // test the sum of the various modes for equality
100         // so we can ether accept or reject this material 
101         // as being equal, this is rather important to 
102         // prevent material bleeding
103         for(int i=0; i<mMaterial->num_enabled; i++) {
104                 m_multimode     +=
105                         (mMaterial->flag[i]     +
106                          mMaterial->blend_mode[i]
107                          );
108         }
109         m_multimode += mMaterial->IdMode+mMaterial->ras_mode;
110
111 }
112
113
114 KX_BlenderMaterial::~KX_BlenderMaterial()
115 {
116         // cleanup work
117         OnExit();
118 }
119
120
121 TFace* KX_BlenderMaterial::GetTFace(void) const 
122 {
123         // fonts on polys
124         MT_assert(mMaterial->tface);
125         return mMaterial->tface;
126 }
127
128 void KX_BlenderMaterial::OnConstruction()
129 {
130         // for each unique material...
131         #ifdef GL_ARB_multitexture
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         glActiveTextureARB(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                 glUseProgramObjectARB(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                 glActiveTextureARB(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         glActiveTextureARB(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                 glActiveTextureARB(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                 glUseProgramObjectARB( 0 );
272                 DisableTexData();
273                 return;
274         }
275
276         DisableTexData();
277         glUseProgramObjectARB( 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                 glActiveTextureARB(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                 glUniform1iARB(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                 glUseProgramObjectARB( 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                         glActiveTextureARB(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                 glActiveTextureARB(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                         // should not happen
361                         // if(mTextures[i].GetTextureType() & BL_TEX2D) continue;
362
363                         glBindTexture( GL_TEXTURE_CUBE_MAP_ARB, mTextures[i] ); 
364                         glEnable(GL_TEXTURE_CUBE_MAP_ARB);
365                         setTextureEnvironment( i );
366
367                         if( mMaterial->mapping[i].mapping &USEREFL )
368                                 setEnvMap( true, true );
369                         else if(mMaterial->mapping[i].mapping &USEOBJ)
370                                 setObjectMatrixData(i);
371                         else
372                                 setTexMatrixData( i );
373                 } 
374                 // 2d textures
375                 else { 
376                 #endif//GL_ARB_texture_cube_map
377                         
378                         // should not happen
379                         //if(mTextures[i].GetTextureType() & BL_TEXCUBE) continue;
380                         //
381                         MT_assert(!(mTextures[i].GetTextureType() & BL_TEXCUBE));
382
383                         glBindTexture( GL_TEXTURE_2D, mTextures[i] );   
384                         glEnable( GL_TEXTURE_2D );
385                         setTextureEnvironment( i );
386                         
387                         if( mMaterial->mapping[i].mapping &USEREFL ){
388                                 setEnvMap( true );
389                         }
390                         else if(mMaterial->mapping[i].mapping &USEOBJ){
391                                 setObjectMatrixData(i);
392                         }
393                         else {
394                                 setTexMatrixData( i );
395                         }
396
397                 #ifdef GL_ARB_texture_cube_map
398                 }
399                 #endif//GL_ARB_texture_cube_map
400
401                 // if either unit has set blending
402                 // and its the last pass
403                 lastblend += setBlending( i ); // dry run
404                 if(lastblend >0 && i==mMaterial->num_enabled-1)
405                         setBlending( i, true );
406                 else if(lastblend == 0 && i==mMaterial->num_enabled-1)
407                         glDisable(GL_BLEND);
408         }
409         #endif//GL_ARB_multitexture
410 }
411
412 void
413 KX_BlenderMaterial::ActivatShaders(
414         RAS_IRasterizer* rasty, 
415         TCachingInfo& cachingInfo)const
416 {
417         if (GetCachingInfo() != cachingInfo) {
418                 KX_BlenderMaterial *tmp = const_cast<KX_BlenderMaterial*>(this);
419
420                 if (!cachingInfo)
421                         tmp->setShaderData( false );
422                 
423                 cachingInfo = GetCachingInfo();
424         
425                 if (rasty->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED ) {
426                         tmp->setShaderData( true );
427                         rasty->EnableTextures(true);
428                 }
429                 else {
430                         tmp->setShaderData( false );
431                         rasty->EnableTextures(false);
432                 }
433
434                 if(mMaterial->mode & RAS_IRasterizer::KX_TWOSIDE)
435                         rasty->SetCullFace(false);
436                 else
437                         rasty->SetCullFace(true);
438
439                 if (mMaterial->mode & RAS_IRasterizer::KX_LINES)
440                         rasty->SetLines(true);
441                 else
442                         rasty->SetLines(false);
443         }
444         
445         // shaders have access to the variables set here
446         // via builtin GLSL variables
447         // eg: gl_FrontMaterial.diffuse
448         // --
449         rasty->SetSpecularity(
450                 mMaterial->speccolor[0]*mMaterial->spec_f,
451                 mMaterial->speccolor[1]*mMaterial->spec_f,
452                 mMaterial->speccolor[2]*mMaterial->spec_f,
453                 mMaterial->spec_f
454         );
455
456         rasty->SetShinyness( mMaterial->hard );
457
458         rasty->SetDiffuse(
459                 mMaterial->matcolor[0]*mMaterial->ref+mMaterial->emit, 
460                 mMaterial->matcolor[1]*mMaterial->ref+mMaterial->emit,
461                 mMaterial->matcolor[2]*mMaterial->ref+mMaterial->emit,
462                 1.0f);
463
464         rasty->SetEmissive(     
465                 mMaterial->matcolor[0]*mMaterial->emit,
466                 mMaterial->matcolor[1]*mMaterial->emit,
467                 mMaterial->matcolor[2]*mMaterial->emit,
468                 1.0
469                 );
470
471         // Lagan's patch...
472         // added material factor
473         rasty->SetAmbient(mMaterial->amb);
474
475         if (mMaterial->material)
476                 rasty->SetPolygonOffset(-mMaterial->material->zoffs, 0.0);
477 }
478
479 void
480 KX_BlenderMaterial::ActivateMat( 
481         RAS_IRasterizer* rasty,  
482         TCachingInfo& cachingInfo
483         )const
484 {
485         if (GetCachingInfo() != cachingInfo) {
486                 KX_BlenderMaterial *tmp = const_cast<KX_BlenderMaterial*>(this);
487
488                 if (!cachingInfo) 
489                         tmp->setTexData( false );
490                 
491                 cachingInfo = GetCachingInfo();
492
493                 if (rasty->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED) {
494                         tmp->setTexData( true );
495                         rasty->EnableTextures(true);
496                 }
497                 else{
498                         tmp->setTexData( false );
499                         rasty->EnableTextures(false);
500                 }
501
502                 if(mMaterial->mode & RAS_IRasterizer::KX_TWOSIDE)
503                         rasty->SetCullFace(false);
504                 else
505                         rasty->SetCullFace(true);
506
507                 if (mMaterial->mode & RAS_IRasterizer::KX_LINES)
508                         rasty->SetLines(true);
509                 else
510                         rasty->SetLines(false);
511         }
512                 
513         rasty->SetSpecularity(
514                 mMaterial->speccolor[0]*mMaterial->spec_f,
515                 mMaterial->speccolor[1]*mMaterial->spec_f,
516                 mMaterial->speccolor[2]*mMaterial->spec_f,
517                 mMaterial->spec_f
518         );
519
520         rasty->SetShinyness( mMaterial->hard );
521
522         rasty->SetDiffuse(
523                 mMaterial->matcolor[0]*mMaterial->ref+mMaterial->emit, 
524                 mMaterial->matcolor[1]*mMaterial->ref+mMaterial->emit,
525                 mMaterial->matcolor[2]*mMaterial->ref+mMaterial->emit,
526                 1.0f);
527
528         rasty->SetEmissive(     
529                 mMaterial->matcolor[0]*mMaterial->emit,
530                 mMaterial->matcolor[1]*mMaterial->emit,
531                 mMaterial->matcolor[2]*mMaterial->emit,
532                 1.0
533                 );
534         
535         // Lagan's patch...
536         // added material factor
537         rasty->SetAmbient(mMaterial->amb);
538
539         if (mMaterial->material)
540                 rasty->SetPolygonOffset(-mMaterial->material->zoffs, 0.0);
541 }
542
543 bool 
544 KX_BlenderMaterial::Activate( 
545         RAS_IRasterizer* rasty,  
546         TCachingInfo& cachingInfo
547         )const
548 {
549         bool dopass = false;
550         #ifdef GL_ARB_shader_objects
551         if( RAS_EXT_support._ARB_shader_objects &&
552                 ( mShader && mShader->Ok() ) ) {
553
554                 if( (mPass++) < mShader->getNumPass() ) {
555                         ActivatShaders(rasty, cachingInfo);
556                         dopass = true;
557                         return dopass;
558                 }
559                 else {
560                         glUseProgramObjectARB( 0 );
561                         mPass = 0;
562                         dopass = false;
563                         return dopass;
564                 }
565         }
566         else {
567         #endif//GL_ARB_shader_objects
568                 switch (mPass++)
569                 {
570                         case 0:
571                                 ActivateMat(rasty, cachingInfo);
572                                 dopass = true;
573                                 break;
574                         default:
575                                 mPass = 0;
576                                 dopass = false;
577                                 break;
578                 }
579         #ifdef GL_ARB_shader_objects
580         }
581         #endif//GL_ARB_shader_objects
582         return dopass;
583 }
584
585 void KX_BlenderMaterial::setTextureEnvironment( int textureIndex )
586 {
587 #ifndef GL_ARB_texture_env_combine
588         glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
589         return;
590 #else
591         if(textureIndex == -1 || !RAS_EXT_support._ARB_texture_env_combine){
592                 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
593                 return;
594         }
595
596         glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB );
597
598         GLfloat blend_operand           = GL_SRC_COLOR;
599         GLfloat blend_operand_prev      = GL_SRC_COLOR;
600
601         // all sources here are RGB by default
602         GLenum combiner = GL_COMBINE_RGB_ARB;
603         GLenum source0 = GL_SOURCE0_RGB_ARB;
604         GLenum source1 = GL_SOURCE1_RGB_ARB;
605         GLenum source2 = GL_SOURCE2_RGB_ARB;
606         GLenum op0 = GL_OPERAND0_RGB_ARB;
607         GLenum op1 = GL_OPERAND1_RGB_ARB;
608         GLenum op2 = GL_OPERAND2_RGB_ARB;
609
610         // switch to alpha combiners
611         if( (mMaterial->flag[textureIndex] &TEXALPHA) ) {
612                 combiner = GL_COMBINE_ALPHA_ARB;
613                 source0  = GL_SOURCE0_ALPHA_ARB;
614                 source1 = GL_SOURCE1_ALPHA_ARB;
615                 source2 = GL_SOURCE2_ALPHA_ARB;
616                 op0 = GL_OPERAND0_ALPHA_ARB;
617                 op1 = GL_OPERAND1_ALPHA_ARB;
618                 op2 = GL_OPERAND2_ALPHA_ARB;
619                 blend_operand = GL_SRC_ALPHA;
620                 blend_operand_prev = GL_SRC_ALPHA;
621                 
622                 // invert
623                 if(mMaterial->flag[textureIndex] &TEXNEG) {
624                         blend_operand_prev = GL_ONE_MINUS_SRC_ALPHA;
625                         blend_operand = GL_ONE_MINUS_SRC_ALPHA;
626                 }
627         }
628         else {
629                 if(mMaterial->flag[textureIndex] &TEXNEG) {
630                         blend_operand_prev = GL_ONE_MINUS_SRC_COLOR;
631                         blend_operand = GL_ONE_MINUS_SRC_COLOR;
632                 }
633         }
634         // on Texture0 GL_PREVIOUS_ARB is the primary color
635         // on Texture1 GL_PREVIOUS_ARB is Texture0 env
636         switch( mMaterial->blend_mode[textureIndex] ) {
637                 case BLEND_MIX:
638                         {
639                                 // ------------------------------
640                                 GLfloat base_col[4];
641                                 base_col[0]      = base_col[1]  = base_col[2]  = 0.f;
642                                 base_col[3]      = 1.f-mMaterial->color_blend[textureIndex];
643                                 glTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,base_col );
644                                 glTexEnvf(      GL_TEXTURE_ENV, combiner,       GL_INTERPOLATE_ARB);
645                                 glTexEnvf(      GL_TEXTURE_ENV, source0,        GL_PREVIOUS_ARB);
646                                 glTexEnvf(      GL_TEXTURE_ENV, op0,            blend_operand_prev );
647                                 glTexEnvf(      GL_TEXTURE_ENV, source1,        GL_TEXTURE );
648                                 glTexEnvf(      GL_TEXTURE_ENV, op1,            blend_operand);
649                                 glTexEnvf(      GL_TEXTURE_ENV, source2,        GL_CONSTANT_ARB );
650                                 glTexEnvf(      GL_TEXTURE_ENV, op2,            GL_SRC_ALPHA);
651                         }break;
652                 case BLEND_MUL: 
653                         {
654                                 // ------------------------------
655                                 glTexEnvf(      GL_TEXTURE_ENV, combiner,       GL_MODULATE);
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_ADD: 
662                         {
663                                 // ------------------------------
664                                 glTexEnvf(      GL_TEXTURE_ENV, combiner,       GL_ADD_SIGNED_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_SUB: 
671                         {
672                                 // ------------------------------
673                                 glTexEnvf(      GL_TEXTURE_ENV, combiner,       GL_SUBTRACT_ARB);
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                 case BLEND_SCR: 
680                         {
681                                 // ------------------------------
682                                 glTexEnvf(      GL_TEXTURE_ENV, combiner,       GL_ADD);
683                                 glTexEnvf(      GL_TEXTURE_ENV, source0,        GL_PREVIOUS_ARB );
684                                 glTexEnvf(      GL_TEXTURE_ENV, op0,            blend_operand_prev );
685                                 glTexEnvf(      GL_TEXTURE_ENV, source1,        GL_TEXTURE );
686                                 glTexEnvf(      GL_TEXTURE_ENV, op1,            blend_operand);
687                         } break;
688         }
689 #endif //!GL_ARB_texture_env_combine
690 }
691
692 bool KX_BlenderMaterial::setBlending( int ind, bool enable) 
693 {
694         if(!enable) {
695                 if(mMaterial->flag[ind] &CALCALPHA )    return true;
696                 else if(mMaterial->flag[ind] &USEALPHA )        return true;
697                 return false;
698         }
699         else {
700                 // additive
701                 if(mMaterial->flag[ind] &CALCALPHA ) {
702                         glEnable(GL_BLEND);
703                         glBlendFunc(GL_ONE, GL_ONE);
704                         return true;
705                 }
706
707                 // use alpha channel
708                 else if(mMaterial->flag[ind] &USEALPHA ) {
709                         glEnable(GL_BLEND);
710                         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
711                         return true;
712                 }
713         }
714         return false;
715 }
716
717 bool KX_BlenderMaterial::setDefaultBlending()
718 {
719         if( mMaterial->transp &TF_ADD) {
720                 glEnable(GL_BLEND);
721                 glBlendFunc(GL_ONE, GL_ONE);
722                 return true;
723         }
724         
725         if( mMaterial->transp & TF_ALPHA ) {
726                 glEnable(GL_BLEND);
727                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
728                 return true;
729         }
730         
731         glDisable(GL_BLEND);
732         return false;
733 }
734
735 void KX_BlenderMaterial::setEnvMap(bool val, bool cube)
736 {
737         #ifdef GL_ARB_texture_cube_map
738         if( cube && RAS_EXT_support._ARB_texture_cube_map ) 
739         {
740                 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB );
741                 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB);
742                 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB);
743
744                 glEnable(GL_TEXTURE_GEN_S);
745                 glEnable(GL_TEXTURE_GEN_T);
746                 glEnable(GL_TEXTURE_GEN_R);
747         }
748         else {
749         #endif//GL_ARB_texture_cube_map
750                 if( val ) {
751                         glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
752                         glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
753                         
754                         glEnable(GL_TEXTURE_GEN_S);
755                         glEnable(GL_TEXTURE_GEN_T);
756                         glEnable(GL_TEXTURE_GEN_R);
757                 }
758                 else {
759                         glDisable(GL_TEXTURE_GEN_S);
760                         glDisable(GL_TEXTURE_GEN_T);
761                         glDisable(GL_TEXTURE_GEN_R);
762                 }
763         #ifdef GL_ARB_texture_cube_map
764         }
765         #endif//GL_ARB_texture_cube_map
766 }
767
768
769 void KX_BlenderMaterial::setTexMatrixData(int i)
770 {
771         glMatrixMode(GL_TEXTURE);
772         glLoadIdentity();
773
774         glScalef( 
775                 mMaterial->mapping[i].scale[0], 
776                 mMaterial->mapping[i].scale[1], 
777                 mMaterial->mapping[i].scale[2]
778         );
779         glTranslatef(
780                 mMaterial->mapping[i].offsets[0],
781                 mMaterial->mapping[i].offsets[1], 
782                 mMaterial->mapping[i].offsets[2]
783         );
784
785         glMatrixMode(GL_MODELVIEW);
786
787 }
788
789 static void GetProjPlane(BL_Material *mat, int index,int num, float*param)
790 {
791         param[0]=param[1]=param[2]=param[3]=0.f;
792         if( mat->mapping[index].projplane[num] == PROJX )
793                 param[0] = 1.f;
794         else if( mat->mapping[index].projplane[num] == PROJY )
795                 param[1] = 1.f;
796         else if( mat->mapping[index].projplane[num] == PROJZ)
797                 param[2] = 1.f;
798 }
799
800
801 void KX_BlenderMaterial::setObjectMatrixData(int i)
802 {
803         // will work without cubemaps
804         // but a cubemap will look the best
805         KX_GameObject *obj = 
806                 (KX_GameObject*)
807                 mScene->GetObjectList()->FindValue(mMaterial->mapping[i].objconame);
808
809         if(!obj)
810                 return;
811
812         glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
813         glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
814         glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
815
816         GLenum plane = GL_EYE_PLANE;
817
818         // figure plane gen
819         float proj[4]= {0.f,0.f,0.f,0.f};
820         GetProjPlane(mMaterial, i, 0, proj);
821         glTexGenfv(GL_S, plane, proj);
822         
823         GetProjPlane(mMaterial, i, 1, proj);
824         glTexGenfv(GL_T, plane, proj);
825
826         GetProjPlane(mMaterial, i, 2, proj);
827         glTexGenfv(GL_R, plane, proj);
828
829         glEnable(GL_TEXTURE_GEN_S);
830         glEnable(GL_TEXTURE_GEN_T);
831         glEnable(GL_TEXTURE_GEN_R);
832
833         float matr[16];
834         glGetFloatv(GL_MODELVIEW_MATRIX, matr);
835         MT_Matrix4x4 mvmat(matr);
836
837         glMatrixMode(GL_TEXTURE);
838         glLoadIdentity();
839         glScalef( 
840                 mMaterial->mapping[i].scale[0], 
841                 mMaterial->mapping[i].scale[1], 
842                 mMaterial->mapping[i].scale[2]
843         );
844
845         MT_Point3 pos = obj->NodeGetWorldPosition();
846         MT_Vector4 matmul = MT_Vector4(pos[0], pos[1], pos[2], 1.f);
847         MT_Vector4 t = mvmat*matmul;
848
849         glTranslatef( (float)(-t[0]), (float)(-t[1]), (float)(-t[2]) );
850
851         glMatrixMode(GL_MODELVIEW);
852
853 }
854
855
856 // ------------------------------------
857 void KX_BlenderMaterial::UpdateIPO(
858         MT_Vector4 rgba,
859         MT_Vector3 specrgb,
860         MT_Scalar hard,
861         MT_Scalar spec,
862         MT_Scalar ref,
863         MT_Scalar emit,
864         MT_Scalar alpha
865         )
866 {
867         // only works one deep now
868         mMaterial->speccolor[0] = (float)(specrgb)[0];
869         mMaterial->speccolor[1] = (float)(specrgb)[1];
870         mMaterial->speccolor[2] = (float)(specrgb)[2];
871         mMaterial->matcolor[0]  = (float)(rgba[0]);
872         mMaterial->matcolor[1]  = (float)(rgba[1]);
873         mMaterial->matcolor[2]  = (float)(rgba[2]);
874         mMaterial->alpha                = (float)(alpha);
875         mMaterial->hard                 = (float)(hard);
876         mMaterial->emit                 = (float)(emit);
877         mMaterial->spec_f               = (float)(spec);
878 }
879
880
881 PyMethodDef KX_BlenderMaterial::Methods[] = 
882 {
883         KX_PYMETHODTABLE( KX_BlenderMaterial, getShader ),
884         KX_PYMETHODTABLE( KX_BlenderMaterial, useShader ),
885         KX_PYMETHODTABLE( KX_BlenderMaterial, getMaterialIndex ),
886         KX_PYMETHODTABLE( KX_BlenderMaterial, getTexture ),
887         KX_PYMETHODTABLE( KX_BlenderMaterial, setTexture ),
888
889         {NULL,NULL} //Sentinel
890 };
891
892
893 PyTypeObject KX_BlenderMaterial::Type = {
894         PyObject_HEAD_INIT(&PyType_Type)
895                 0,
896                 "KX_BlenderMaterial",
897                 sizeof(KX_BlenderMaterial),
898                 0,
899                 PyDestructor,
900                 0,
901                 __getattr,
902                 __setattr,
903                 0,
904                 __repr,
905                 0
906 };
907
908
909 PyParentObject KX_BlenderMaterial::Parents[] = {
910         &PyObjectPlus::Type,
911         &KX_BlenderMaterial::Type,
912         NULL
913 };
914
915
916 PyObject* KX_BlenderMaterial::_getattr(const STR_String& attr)
917 {
918         // nodda ?
919         _getattr_up(PyObjectPlus);
920 }
921
922 int KX_BlenderMaterial::_setattr(const STR_String& attr, PyObject *pyvalue)
923 {
924         return PyObjectPlus::_setattr(attr, pyvalue);
925 }
926
927 KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getShader , "getShader()")
928 {
929         #ifdef GL_ARB_shader_objects
930         if(!RAS_EXT_support._ARB_shader_objects) {
931                 PyErr_Format(PyExc_SystemError, "GLSL not supported");
932                 return NULL;
933         }
934         else {
935                 Py_INCREF(mShader);
936                 return mShader;
937         }
938         #else
939         Py_Return;
940         #endif//GL_ARB_shader_objects
941 }
942
943 KX_PYMETHODDEF_DOC( KX_BlenderMaterial, useShader, "useShader(1:0)" )
944 {
945         #ifdef GL_ARB_shader_objects
946         if(!RAS_EXT_support._ARB_shader_objects) {
947                 PyErr_Format(PyExc_SystemError, "GLSL not supported");
948                 return NULL;
949         }
950         int use =0;
951         if(PyArg_ParseTuple(args, "i", &use)) {
952                 mUseShader = (use!= 0);
953                 Py_Return;
954         }
955         return NULL;
956         #else
957         Py_Return;
958         #endif//GL_ARB_shader_objects
959 }
960
961 KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getMaterialIndex, "getMaterialIndex()")
962 {
963         return PyInt_FromLong( mMaterial->material_index );
964 }
965
966 KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getTexture, "getTexture( index )" )
967 {
968         return NULL;
969 }
970
971 KX_PYMETHODDEF_DOC( KX_BlenderMaterial, setTexture , "setTexture( index, tex)")
972 {
973         return NULL;
974 }
975
976 #endif //WIN32