First commit! Small bug fix for cube map crashing in the player.
[blender-staging.git] / source / gameengine / Ketsji / BL_Texture.cpp
1 // ------------------------------------
2 #ifdef WIN32
3 #include <windows.h>
4 #endif // WIN32
5 #ifdef __APPLE__
6 #define GL_GLEXT_LEGACY 1
7 #include <OpenGL/gl.h>
8 #include <OpenGL/glu.h>
9 #else
10 #include <GL/gl.h>
11 #include <GL/glu.h>
12 #endif
13
14 #include <iostream>
15 #include <map>
16
17 #include "BL_Material.h"
18 #include "BL_Texture.h"
19 #include "MT_assert.h"
20
21 #include "DNA_texture_types.h"
22 #include "DNA_image_types.h"
23 #include "IMB_imbuf_types.h"
24 #include "BKE_image.h"
25 #include "BLI_blenlib.h"
26
27 #include "RAS_OpenGLRasterizer/RAS_GLExtensionManager.h"
28 #include "RAS_OpenGLRasterizer/ARB_multitexture.h"
29 #include "RAS_ICanvas.h"
30 #include "RAS_Rect.h"
31
32 #include "KX_GameObject.h"
33
34
35 using namespace bgl;
36
37 #define spit(x) std::cout << x << std::endl;
38
39 #include "MEM_guardedalloc.h"
40
41 extern "C" {
42         // envmaps
43         #include "IMB_imbuf.h"
44         void my_envmap_split_ima(EnvMap *env, ImBuf *ibuf);
45         void my_free_envmapdata(EnvMap *env);
46 }
47
48 // (n&(n-1)) zeros the least significant bit of n 
49 static int is_pow2(int num) {
50         return ((num)&(num-1))==0;
51 }
52 static int smaller_pow2(int num) {
53         while (!is_pow2(num))
54                 num= num&(num-1);
55         return num;     
56 }
57
58 // Place holder for a full texture manager
59 class BL_TextureObject
60 {
61 public:
62         unsigned int    gl_texture;
63         void*                   ref_buffer;
64 };
65
66 typedef std::map<char*, BL_TextureObject> BL_TextureMap;
67 static BL_TextureMap g_textureManager;
68
69
70 BL_Texture::BL_Texture()
71 :       mTexture(0),
72         mOk(0),
73         mNeedsDeleted(0),
74         mType(0),
75         mUnit(0),
76         mEnvState(0)
77 {
78         // --
79 }
80
81 BL_Texture::~BL_Texture()
82 {
83         // --
84 }
85
86 void BL_Texture::DeleteTex()
87 {
88         if( mNeedsDeleted ) {
89                 glDeleteTextures(1, (GLuint*)&mTexture);
90                 mNeedsDeleted = 0;
91                 mOk = 0;
92         }
93
94         if(mEnvState) {
95                 glDeleteLists((GLuint)mEnvState, 1);
96                 mEnvState =0;
97         }
98
99         if(mDisableState) {
100                 glDeleteLists((GLuint)mDisableState, 1);
101                 mDisableState =0;
102         }
103
104         g_textureManager.clear();
105 }
106
107
108 bool BL_Texture::InitFromImage(int unit,  Image *img, bool mipmap)
109 {
110
111         ImBuf *ibuf;
112         if (!img || img->ok==0) 
113         {
114                 mOk = false;
115                 return mOk;
116         }
117
118         ibuf= BKE_image_get_ibuf(img, NULL);
119         if (ibuf==NULL)
120         {
121                 img->ok = 0;
122                 mOk = false;
123                 return mOk;
124         }
125
126
127         mTexture = img->bindcode;
128         mType = GL_TEXTURE_2D;
129         mUnit = unit;
130
131         ActivateUnit(mUnit);
132
133
134         if (mTexture != 0) {
135                 glBindTexture(GL_TEXTURE_2D, mTexture );
136                 Validate();
137                 return mOk;
138         }
139         mNeedsDeleted = 1;
140         glGenTextures(1, (GLuint*)&mTexture);
141         InitGLTex(ibuf->rect, ibuf->x, ibuf->y, mipmap);
142         
143
144
145         glDisable(GL_TEXTURE_2D);
146         ActivateUnit(0);
147         Validate();
148         return mOk;
149 }
150
151 void BL_Texture::InitGLTex(unsigned int *pix,int x,int y,bool mipmap)
152 {
153         if (!is_pow2(x) || !is_pow2(y) ) {
154                 InitNonPow2Tex(pix, x,y,mipmap);
155                 return;
156         }
157
158         glBindTexture(GL_TEXTURE_2D, mTexture );
159         if( mipmap ) {
160                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
161                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
162                 gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGBA, x, y, GL_RGBA, GL_UNSIGNED_BYTE, pix );
163         } 
164         else {
165                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
166                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
167                 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, pix );
168         }
169
170         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
171 }
172
173
174 void BL_Texture::InitNonPow2Tex(unsigned int *pix,int x,int y,bool mipmap)
175 {
176         int nx= smaller_pow2(x);
177         int ny= smaller_pow2(y);
178
179         unsigned int *newPixels = (unsigned int *)malloc(nx*ny*sizeof(unsigned int));
180         
181         gluScaleImage(GL_RGBA, x, y, GL_UNSIGNED_BYTE, pix, nx,ny, GL_UNSIGNED_BYTE, newPixels);
182         glBindTexture(GL_TEXTURE_2D, mTexture );
183
184         if( mipmap ) {
185                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
186                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
187                 gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGBA, nx, ny, GL_RGBA, GL_UNSIGNED_BYTE, newPixels );
188         }
189         else {
190                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
191                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
192                 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, nx, ny, 0, GL_RGBA, GL_UNSIGNED_BYTE, newPixels );
193         }
194         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
195         free(newPixels);
196 }
197
198
199 bool BL_Texture::InitCubeMap(int unit,  EnvMap *cubemap)
200 {
201 #ifdef GL_ARB_texture_cube_map
202
203         if (!RAS_EXT_support._ARB_texture_cube_map)
204         {
205                 spit("cubemaps not supported");
206                 mOk = false;
207                 return mOk;
208         }
209         else if (!cubemap || cubemap->ima->ok==0) 
210         {
211                 mOk = false;
212                 return mOk;
213         }
214
215         ImBuf *ibuf= BKE_image_get_ibuf(cubemap->ima, NULL);
216         if (ibuf==0)
217         {
218                 cubemap->ima->ok = 0;
219                 mOk = false;
220                 return mOk;
221         }
222
223         mNeedsDeleted = 1;
224         mType = GL_TEXTURE_CUBE_MAP_ARB;
225         mTexture = 0;
226         mUnit = unit;
227
228         ActivateUnit(mUnit);
229
230         BL_TextureMap::iterator mapLook = g_textureManager.find(cubemap->ima->id.name);
231         if (mapLook != g_textureManager.end())
232         {
233                 if (mapLook->second.gl_texture != 0 && mapLook->second.ref_buffer == cubemap->ima)
234                 {
235                         mTexture = mapLook->second.gl_texture;
236                         glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mTexture);
237                         mOk = IsValid();
238                         return mOk;
239                 }
240         }
241
242
243         glGenTextures(1, (GLuint*)&mTexture);
244         glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mTexture);
245
246
247         // track created units
248         BL_TextureObject obj;
249         obj.gl_texture = mTexture;
250         obj.ref_buffer = cubemap->ima;
251         g_textureManager.insert(std::make_pair(cubemap->ima->id.name, obj));
252
253
254         bool needs_split = false;
255         if (!cubemap->cube[0]) 
256         {
257                 needs_split = true;
258                 spit ("Re-Generating texture buffer");
259         }
260
261         if (needs_split)
262                 my_envmap_split_ima(cubemap, ibuf);
263
264
265         if (!is_pow2(cubemap->cube[0]->x) || !is_pow2(cubemap->cube[0]->y))
266         {
267                 spit("invalid envmap size please render with CubeRes @ power of two");
268
269                 my_free_envmapdata(cubemap);
270                 mOk = false;
271                 return mOk;
272         }
273
274
275 #define SetCubeMapFace(face, num)   \
276         glTexImage2D(face, 0,GL_RGBA,   \
277         cubemap->cube[num]->x,          \
278         cubemap->cube[num]->y,          \
279         0, GL_RGBA, GL_UNSIGNED_BYTE,   \
280         cubemap->cube[num]->rect)
281
282         SetCubeMapFace(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, 5);
283         SetCubeMapFace(GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, 3);
284         SetCubeMapFace(GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, 0);
285         SetCubeMapFace(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, 1);
286         SetCubeMapFace(GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, 2);
287         SetCubeMapFace(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, 4);
288
289         glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
290         glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
291         glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S,     GL_CLAMP_TO_EDGE );
292         glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T,     GL_CLAMP_TO_EDGE );
293         #ifdef GL_VERSION_1_2
294         glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_R,     GL_CLAMP_TO_EDGE );
295         #endif
296
297         if (needs_split)
298                 my_free_envmapdata(cubemap);
299
300
301
302         glDisable(GL_TEXTURE_CUBE_MAP_ARB);
303         ActivateUnit(0);
304
305         mOk = IsValid();
306         return mOk;
307
308 #else
309
310         mOk = false;
311         return mOk;
312
313 #endif//GL_ARB_texture_cube_map
314 }
315
316 bool BL_Texture::IsValid()
317 {
318         return (mTexture!= 0)?glIsTexture(mTexture)!=0:false;
319 }
320
321
322 void BL_Texture::Validate()
323 {
324         mOk = IsValid();
325 }
326
327
328 bool BL_Texture::Ok()
329 {
330         return  (mTexture!= 0); 
331 }
332
333
334 unsigned int BL_Texture::GetTextureType() const
335 {
336         return mType;
337 }
338
339 int BL_Texture::GetMaxUnits()
340 {
341         GLint unit=0;
342 #ifdef GL_ARB_multitexture
343         if(RAS_EXT_support._ARB_multitexture) {
344                 glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &unit);
345                 return (MAXTEX>=unit?unit:MAXTEX);
346         }
347 #endif
348         return 0;
349 }
350
351 void BL_Texture::ActivateFirst()
352 {
353 #ifdef GL_ARB_multitexture
354         if(RAS_EXT_support._ARB_multitexture)
355                 bgl::blActiveTextureARB(GL_TEXTURE0_ARB);
356 #endif
357 }
358
359 void BL_Texture::ActivateUnit(int unit)
360 {
361 #ifdef GL_ARB_multitexture
362         if(RAS_EXT_support._ARB_multitexture)
363                 if(unit <= MAXTEX)
364                         bgl::blActiveTextureARB(GL_TEXTURE0_ARB+unit);
365 #endif
366 }
367
368
369 void BL_Texture::DisableUnit()
370 {
371 #ifdef GL_ARB_multitexture
372         if(RAS_EXT_support._ARB_multitexture)
373                 bgl::blActiveTextureARB(GL_TEXTURE0_ARB+mUnit);
374
375 #endif
376
377
378         glMatrixMode(GL_TEXTURE);
379         glLoadIdentity();
380         glMatrixMode(GL_MODELVIEW);
381
382         #ifdef GL_ARB_texture_cube_map
383         if(RAS_EXT_support._ARB_texture_cube_map && glIsEnabled(GL_TEXTURE_CUBE_MAP_ARB))
384                 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
385         else
386         #endif
387         {
388                 if (glIsEnabled(GL_TEXTURE_2D))
389                         glDisable(GL_TEXTURE_2D);
390         }
391
392         glDisable(GL_TEXTURE_GEN_S);
393         glDisable(GL_TEXTURE_GEN_T);
394         glDisable(GL_TEXTURE_GEN_R);
395         glDisable(GL_TEXTURE_GEN_Q);
396         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
397 }
398
399
400 void BL_Texture::DisableAllTextures()
401 {
402 #ifdef GL_ARB_multitexture
403         glDisable(GL_BLEND);
404         for(int i=0; i<MAXTEX; i++) {
405                 if(RAS_EXT_support._ARB_multitexture)
406                         bgl::blActiveTextureARB(GL_TEXTURE0_ARB+i);
407
408                 glMatrixMode(GL_TEXTURE);
409                 glLoadIdentity();
410                 glMatrixMode(GL_MODELVIEW);
411                 glDisable(GL_TEXTURE_2D);       
412                 glDisable(GL_TEXTURE_GEN_S);
413                 glDisable(GL_TEXTURE_GEN_T);
414                 glDisable(GL_TEXTURE_GEN_R);
415                 glDisable(GL_TEXTURE_GEN_Q);
416                 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
417         }
418         if(RAS_EXT_support._ARB_multitexture)
419                 bgl::blActiveTextureARB(GL_TEXTURE0_ARB);
420
421 #endif
422 }
423
424
425 void BL_Texture::ActivateTexture()
426 {
427 #ifdef GL_ARB_multitexture
428         if(RAS_EXT_support._ARB_multitexture)
429                 bgl::blActiveTextureARB(GL_TEXTURE0_ARB+mUnit);
430
431 #ifdef GL_ARB_texture_cube_map
432         if (mType == GL_TEXTURE_CUBE_MAP_ARB && RAS_EXT_support._ARB_texture_cube_map)
433         {
434                 glBindTexture( GL_TEXTURE_CUBE_MAP_ARB, mTexture );     
435                 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
436         }
437         else
438 #endif
439         {
440
441                 #ifdef GL_ARB_texture_cube_map
442                 if(RAS_EXT_support._ARB_texture_cube_map )
443                         glDisable(GL_TEXTURE_CUBE_MAP_ARB);
444                 #endif
445
446                 glBindTexture( GL_TEXTURE_2D, mTexture );       
447                 glEnable(GL_TEXTURE_2D);
448         }
449 #endif
450 }
451
452 void BL_Texture::SetMapping(int mode)
453 {
454
455         if(!(mode &USEREFL)) {
456                 glDisable(GL_TEXTURE_GEN_S);
457                 glDisable(GL_TEXTURE_GEN_T);
458                 glDisable(GL_TEXTURE_GEN_R);
459                 glDisable(GL_TEXTURE_GEN_Q);
460                 return;
461         }
462
463 #ifdef GL_ARB_texture_cube_map
464         if( mType == GL_TEXTURE_CUBE_MAP_ARB && 
465                 RAS_EXT_support._ARB_texture_cube_map &&
466                 mode &USEREFL) 
467         {
468                 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB );
469                 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB );
470                 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB );
471                 
472                 glEnable(GL_TEXTURE_GEN_S);
473                 glEnable(GL_TEXTURE_GEN_T);
474                 glEnable(GL_TEXTURE_GEN_R);
475                 glDisable(GL_TEXTURE_GEN_Q);
476                 return;
477         }
478         else
479 #endif
480         {
481                 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
482                 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
483
484                 glEnable(GL_TEXTURE_GEN_S);
485                 glEnable(GL_TEXTURE_GEN_T);
486                 glDisable(GL_TEXTURE_GEN_R);
487                 glDisable(GL_TEXTURE_GEN_Q);
488         }
489 }
490
491
492 void BL_Texture::setTexEnv(BL_Material *mat, bool modulate)
493 {
494 #ifndef GL_ARB_texture_env_combine
495         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
496         return;
497 #else
498         if(modulate || !RAS_EXT_support._ARB_texture_env_combine){
499                 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
500                 return;
501         }
502
503         if(glIsList(mEnvState))
504         {
505                 glCallList(mEnvState);
506                 return;
507         }
508         if(!mEnvState)
509                 mEnvState = glGenLists(1);
510
511         glNewList(mEnvState, GL_COMPILE_AND_EXECUTE);
512
513         glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB );
514
515         GLfloat blend_operand           = GL_SRC_COLOR;
516         GLfloat blend_operand_prev  = GL_SRC_COLOR;
517         GLfloat alphaOp                         = GL_SRC_ALPHA;
518
519         GLenum combiner = GL_COMBINE_RGB_ARB;
520         GLenum source0  = GL_SOURCE0_RGB_ARB;
521         GLenum source1  = GL_SOURCE1_RGB_ARB;
522         GLenum source2  = GL_SOURCE2_RGB_ARB;
523         GLenum op0              = GL_OPERAND0_RGB_ARB;
524         GLenum op1              = GL_OPERAND1_RGB_ARB;
525         GLenum op2              = GL_OPERAND2_RGB_ARB;
526
527         // switch to alpha combiners
528         if( mat->flag[mUnit]  &TEXALPHA ) {
529                 combiner = GL_COMBINE_ALPHA_ARB;
530                 source0 = GL_SOURCE0_ALPHA_ARB;
531                 source1 = GL_SOURCE1_ALPHA_ARB;
532                 source2 = GL_SOURCE2_ALPHA_ARB;
533                 op0 = GL_OPERAND0_ALPHA_ARB;
534                 op1 = GL_OPERAND1_ALPHA_ARB;
535                 op2 = GL_OPERAND2_ALPHA_ARB;
536                 blend_operand = GL_SRC_ALPHA;
537                 blend_operand_prev = GL_SRC_ALPHA;
538                 // invert
539                 if(mat->flag[mUnit] &TEXNEG) {
540                         blend_operand_prev = GL_ONE_MINUS_SRC_ALPHA;
541                         blend_operand = GL_ONE_MINUS_SRC_ALPHA;
542                 }
543         }
544         else {
545                 if(mat->flag[mUnit] &TEXNEG) {
546                         blend_operand_prev=GL_ONE_MINUS_SRC_COLOR;
547                         blend_operand = GL_ONE_MINUS_SRC_COLOR;
548                 }
549         }
550         bool using_alpha = false;
551
552         if(mat->flag[mUnit]  &USEALPHA){
553                 alphaOp = GL_ONE_MINUS_SRC_ALPHA;
554                 using_alpha=true;
555         }
556         else if(mat->flag[mUnit]  &USENEGALPHA){
557                 alphaOp = GL_SRC_ALPHA;
558                 using_alpha = true;
559         }
560
561         switch( mat->blend_mode[mUnit] ) {
562                 case BLEND_MIX:
563                         {
564                                 // ------------------------------
565                                 if(!using_alpha) {
566                                         GLfloat base_col[4];
567                                         base_col[0]      = base_col[1]  = base_col[2]  = 0.f;
568                                         base_col[3]      = 1.f-mat->color_blend[mUnit];
569                                         glTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,base_col );
570                                 }
571                                 glTexEnvf(      GL_TEXTURE_ENV, combiner,       GL_INTERPOLATE_ARB);
572                                 glTexEnvf(      GL_TEXTURE_ENV, source0,        GL_PREVIOUS_ARB);
573                                 glTexEnvf(      GL_TEXTURE_ENV, op0,            blend_operand_prev );
574                                 glTexEnvf(      GL_TEXTURE_ENV, source1,        GL_TEXTURE );
575                                 glTexEnvf(      GL_TEXTURE_ENV, op1,            blend_operand);
576                                 if(!using_alpha)
577                                         glTexEnvf(      GL_TEXTURE_ENV, source2,        GL_CONSTANT_ARB );
578                                 else
579                                         glTexEnvf(      GL_TEXTURE_ENV, source2,        GL_TEXTURE );
580
581                                 glTexEnvf(      GL_TEXTURE_ENV, op2,            alphaOp);
582                         }break;
583                 case BLEND_MUL: 
584                         {
585                                 // ------------------------------
586                                 glTexEnvf(      GL_TEXTURE_ENV, combiner,       GL_MODULATE);
587                                 glTexEnvf(      GL_TEXTURE_ENV, source0,        GL_PREVIOUS_ARB);
588                                 glTexEnvf(      GL_TEXTURE_ENV, op0,            blend_operand_prev);
589                                 glTexEnvf(      GL_TEXTURE_ENV, source1,        GL_TEXTURE );
590                                 if(using_alpha)
591                                         glTexEnvf(      GL_TEXTURE_ENV, op1,            alphaOp);
592                                 else
593                                         glTexEnvf(      GL_TEXTURE_ENV, op1,            blend_operand);
594                         }break;
595                 case BLEND_ADD: 
596                         {
597                                 // ------------------------------
598                                 glTexEnvf(      GL_TEXTURE_ENV, combiner,       GL_ADD_SIGNED_ARB);
599                                 glTexEnvf(      GL_TEXTURE_ENV, source0,        GL_PREVIOUS_ARB );
600                                 glTexEnvf(      GL_TEXTURE_ENV, op0,            blend_operand_prev );
601                                 glTexEnvf(      GL_TEXTURE_ENV, source1,        GL_TEXTURE );
602                                 if(using_alpha)
603                                         glTexEnvf(      GL_TEXTURE_ENV, op1,            alphaOp);
604                                 else
605                                         glTexEnvf(      GL_TEXTURE_ENV, op1,            blend_operand);
606                         }break;
607                 case BLEND_SUB: 
608                         {
609                                 // ------------------------------
610                                 glTexEnvf(      GL_TEXTURE_ENV, combiner,       GL_SUBTRACT_ARB);
611                                 glTexEnvf(      GL_TEXTURE_ENV, source0,        GL_PREVIOUS_ARB );
612                                 glTexEnvf(      GL_TEXTURE_ENV, op0,            blend_operand_prev );
613                                 glTexEnvf(      GL_TEXTURE_ENV, source1,        GL_TEXTURE );
614                                 glTexEnvf(      GL_TEXTURE_ENV, op1,            blend_operand);
615                         }break;
616                 case BLEND_SCR: 
617                         {
618                                 // ------------------------------
619                                 glTexEnvf(      GL_TEXTURE_ENV, combiner,       GL_ADD);
620                                 glTexEnvf(      GL_TEXTURE_ENV, source0,        GL_PREVIOUS_ARB );
621                                 glTexEnvf(      GL_TEXTURE_ENV, op0,            blend_operand_prev );
622                                 glTexEnvf(      GL_TEXTURE_ENV, source1,        GL_TEXTURE );
623                                 if(using_alpha)
624                                         glTexEnvf(      GL_TEXTURE_ENV, op1,            alphaOp);
625                                 else
626                                         glTexEnvf(      GL_TEXTURE_ENV, op1,            blend_operand);
627                         } break;
628         }
629         glTexEnvf(      GL_TEXTURE_ENV, GL_RGB_SCALE_ARB,       1.0);
630
631         glEndList();
632 #endif //!GL_ARB_texture_env_combine
633 }
634
635 int BL_Texture::GetPow2(int n)
636 {
637         if(!is_pow2(n))
638                 n = smaller_pow2(n);
639
640         return n;
641 }
642
643 void BL_Texture::SplitEnvMap(EnvMap *map)
644 {
645         if (!map || !map->ima || map->ima && !map->ima->ok) return;
646         ImBuf *ibuf= BKE_image_get_ibuf(map->ima, NULL);
647         if (ibuf)
648                 my_envmap_split_ima(map, ibuf);
649 }
650
651 unsigned int BL_Texture::mDisableState = 0;
652
653 extern "C" {
654
655 void my_envmap_split_ima(EnvMap *env, ImBuf *ibuf)
656 {
657         int dx, part;
658         
659         my_free_envmapdata(env);        
660         
661         dx= ibuf->y;
662         dx/= 2;
663         if(3*dx != ibuf->x) {
664                 printf("Incorrect envmap size\n");
665                 env->ok= 0;
666                 env->ima->ok= 0;
667         }
668         else {
669                 for(part=0; part<6; part++) {
670                         env->cube[part]= ibuf= IMB_allocImBuf(dx, dx, 24, IB_rect, 0);
671                 }
672                 IMB_rectcpy(env->cube[0], ibuf, 
673                         0, 0, 0, 0, dx, dx);
674                 IMB_rectcpy(env->cube[1], ibuf, 
675                         0, 0, dx, 0, dx, dx);
676                 IMB_rectcpy(env->cube[2], ibuf, 
677                         0, 0, 2*dx, 0, dx, dx);
678                 IMB_rectcpy(env->cube[3], ibuf, 
679                         0, 0, 0, dx, dx, dx);
680                 IMB_rectcpy(env->cube[4], ibuf, 
681                         0, 0, dx, dx, dx, dx);
682                 IMB_rectcpy(env->cube[5], ibuf, 
683                         0, 0, 2*dx, dx, dx, dx);
684
685                 env->ok= 2;// ENV_OSA
686         }
687 }
688
689
690 void my_free_envmapdata(EnvMap *env)
691 {
692         unsigned int part;
693         
694         for(part=0; part<6; part++) {
695                 ImBuf *ibuf= env->cube[part];
696                 if(ibuf) {
697                         IMB_freeImBuf(ibuf);
698                         env->cube[part]= NULL;
699                 }
700         }
701         env->ok= 0;
702 }
703
704
705 } // extern C
706