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