svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r22717:22875
[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         for(int i=0; i<MAXTEX; i++) {
388                 if(GLEW_ARB_multitexture)
389                         glActiveTextureARB(GL_TEXTURE0_ARB+i);
390
391                 glMatrixMode(GL_TEXTURE);
392                 glLoadIdentity();
393                 glMatrixMode(GL_MODELVIEW);
394                 glDisable(GL_TEXTURE_2D);       
395                 glDisable(GL_TEXTURE_GEN_S);
396                 glDisable(GL_TEXTURE_GEN_T);
397                 glDisable(GL_TEXTURE_GEN_R);
398                 glDisable(GL_TEXTURE_GEN_Q);
399                 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
400         }
401
402         if(GLEW_ARB_multitexture)
403                 glActiveTextureARB(GL_TEXTURE0_ARB);
404 }
405
406
407 void BL_Texture::ActivateTexture()
408 {
409         if(GLEW_ARB_multitexture)
410                 glActiveTextureARB(GL_TEXTURE0_ARB+mUnit);
411
412         if (mType == GL_TEXTURE_CUBE_MAP_ARB && GLEW_ARB_texture_cube_map)
413         {
414                 glBindTexture( GL_TEXTURE_CUBE_MAP_ARB, mTexture );     
415                 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
416         }
417         else {
418                 if(GLEW_ARB_texture_cube_map )
419                         glDisable(GL_TEXTURE_CUBE_MAP_ARB);
420
421                 glBindTexture( GL_TEXTURE_2D, mTexture );       
422                 glEnable(GL_TEXTURE_2D);
423         }
424 }
425
426 void BL_Texture::SetMapping(int mode)
427 {
428
429         if(!(mode &USEREFL)) {
430                 glDisable(GL_TEXTURE_GEN_S);
431                 glDisable(GL_TEXTURE_GEN_T);
432                 glDisable(GL_TEXTURE_GEN_R);
433                 glDisable(GL_TEXTURE_GEN_Q);
434                 return;
435         }
436
437         if( mType == GL_TEXTURE_CUBE_MAP_ARB && 
438                 GLEW_ARB_texture_cube_map &&
439                 mode &USEREFL) 
440         {
441                 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB );
442                 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB );
443                 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB );
444                 
445                 glEnable(GL_TEXTURE_GEN_S);
446                 glEnable(GL_TEXTURE_GEN_T);
447                 glEnable(GL_TEXTURE_GEN_R);
448                 glDisable(GL_TEXTURE_GEN_Q);
449                 return;
450         }
451         else
452         {
453                 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
454                 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
455
456                 glEnable(GL_TEXTURE_GEN_S);
457                 glEnable(GL_TEXTURE_GEN_T);
458                 glDisable(GL_TEXTURE_GEN_R);
459                 glDisable(GL_TEXTURE_GEN_Q);
460         }
461 }
462
463
464 void BL_Texture::setTexEnv(BL_Material *mat, bool modulate)
465 {
466         if(modulate || !GLEW_ARB_texture_env_combine){
467                 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
468                 return;
469         }
470
471         if(glIsList(mEnvState))
472         {
473                 glCallList(mEnvState);
474                 return;
475         }
476         if(!mEnvState)
477                 mEnvState = glGenLists(1);
478
479         glNewList(mEnvState, GL_COMPILE_AND_EXECUTE);
480
481         glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB );
482
483         GLfloat blend_operand           = GL_SRC_COLOR;
484         GLfloat blend_operand_prev  = GL_SRC_COLOR;
485         GLfloat alphaOp                         = GL_SRC_ALPHA;
486
487         GLenum combiner = GL_COMBINE_RGB_ARB;
488         GLenum source0  = GL_SOURCE0_RGB_ARB;
489         GLenum source1  = GL_SOURCE1_RGB_ARB;
490         GLenum source2  = GL_SOURCE2_RGB_ARB;
491         GLenum op0              = GL_OPERAND0_RGB_ARB;
492         GLenum op1              = GL_OPERAND1_RGB_ARB;
493         GLenum op2              = GL_OPERAND2_RGB_ARB;
494
495         // switch to alpha combiners
496         if( mat->flag[mUnit]  &TEXALPHA ) {
497                 combiner = GL_COMBINE_ALPHA_ARB;
498                 source0 = GL_SOURCE0_ALPHA_ARB;
499                 source1 = GL_SOURCE1_ALPHA_ARB;
500                 source2 = GL_SOURCE2_ALPHA_ARB;
501                 op0 = GL_OPERAND0_ALPHA_ARB;
502                 op1 = GL_OPERAND1_ALPHA_ARB;
503                 op2 = GL_OPERAND2_ALPHA_ARB;
504                 blend_operand = GL_SRC_ALPHA;
505                 blend_operand_prev = GL_SRC_ALPHA;
506                 // invert
507                 if(mat->flag[mUnit] &TEXNEG) {
508                         blend_operand_prev = GL_ONE_MINUS_SRC_ALPHA;
509                         blend_operand = GL_ONE_MINUS_SRC_ALPHA;
510                 }
511         }
512         else {
513                 if(mat->flag[mUnit] &TEXNEG) {
514                         blend_operand_prev=GL_ONE_MINUS_SRC_COLOR;
515                         blend_operand = GL_ONE_MINUS_SRC_COLOR;
516                 }
517         }
518         bool using_alpha = false;
519
520         if(mat->flag[mUnit]  &USEALPHA){
521                 alphaOp = GL_ONE_MINUS_SRC_ALPHA;
522                 using_alpha=true;
523         }
524         else if(mat->flag[mUnit]  &USENEGALPHA){
525                 alphaOp = GL_SRC_ALPHA;
526                 using_alpha = true;
527         }
528
529         switch( mat->blend_mode[mUnit] ) {
530                 case BLEND_MIX:
531                         {
532                                 // ------------------------------
533                                 if(!using_alpha) {
534                                         GLfloat base_col[4];
535                                         base_col[0]      = base_col[1]  = base_col[2]  = 0.f;
536                                         base_col[3]      = 1.f-mat->color_blend[mUnit];
537                                         glTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,base_col );
538                                 }
539                                 glTexEnvf(      GL_TEXTURE_ENV, combiner,       GL_INTERPOLATE_ARB);
540                                 glTexEnvf(      GL_TEXTURE_ENV, source0,        GL_PREVIOUS_ARB);
541                                 glTexEnvf(      GL_TEXTURE_ENV, op0,            blend_operand_prev );
542                                 glTexEnvf(      GL_TEXTURE_ENV, source1,        GL_TEXTURE );
543                                 glTexEnvf(      GL_TEXTURE_ENV, op1,            blend_operand);
544                                 if(!using_alpha)
545                                         glTexEnvf(      GL_TEXTURE_ENV, source2,        GL_CONSTANT_ARB );
546                                 else
547                                         glTexEnvf(      GL_TEXTURE_ENV, source2,        GL_TEXTURE );
548
549                                 glTexEnvf(      GL_TEXTURE_ENV, op2,            alphaOp);
550                         }break;
551                 case BLEND_MUL: 
552                         {
553                                 // ------------------------------
554                                 glTexEnvf(      GL_TEXTURE_ENV, combiner,       GL_MODULATE);
555                                 glTexEnvf(      GL_TEXTURE_ENV, source0,        GL_PREVIOUS_ARB);
556                                 glTexEnvf(      GL_TEXTURE_ENV, op0,            blend_operand_prev);
557                                 glTexEnvf(      GL_TEXTURE_ENV, source1,        GL_TEXTURE );
558                                 if(using_alpha)
559                                         glTexEnvf(      GL_TEXTURE_ENV, op1,            alphaOp);
560                                 else
561                                         glTexEnvf(      GL_TEXTURE_ENV, op1,            blend_operand);
562                         }break;
563                 case BLEND_ADD: 
564                         {
565                                 // ------------------------------
566                                 glTexEnvf(      GL_TEXTURE_ENV, combiner,       GL_ADD_SIGNED_ARB);
567                                 glTexEnvf(      GL_TEXTURE_ENV, source0,        GL_PREVIOUS_ARB );
568                                 glTexEnvf(      GL_TEXTURE_ENV, op0,            blend_operand_prev );
569                                 glTexEnvf(      GL_TEXTURE_ENV, source1,        GL_TEXTURE );
570                                 if(using_alpha)
571                                         glTexEnvf(      GL_TEXTURE_ENV, op1,            alphaOp);
572                                 else
573                                         glTexEnvf(      GL_TEXTURE_ENV, op1,            blend_operand);
574                         }break;
575                 case BLEND_SUB: 
576                         {
577                                 // ------------------------------
578                                 glTexEnvf(      GL_TEXTURE_ENV, combiner,       GL_SUBTRACT_ARB);
579                                 glTexEnvf(      GL_TEXTURE_ENV, source0,        GL_PREVIOUS_ARB );
580                                 glTexEnvf(      GL_TEXTURE_ENV, op0,            blend_operand_prev );
581                                 glTexEnvf(      GL_TEXTURE_ENV, source1,        GL_TEXTURE );
582                                 glTexEnvf(      GL_TEXTURE_ENV, op1,            blend_operand);
583                         }break;
584                 case BLEND_SCR: 
585                         {
586                                 // ------------------------------
587                                 glTexEnvf(      GL_TEXTURE_ENV, combiner,       GL_ADD);
588                                 glTexEnvf(      GL_TEXTURE_ENV, source0,        GL_PREVIOUS_ARB );
589                                 glTexEnvf(      GL_TEXTURE_ENV, op0,            blend_operand_prev );
590                                 glTexEnvf(      GL_TEXTURE_ENV, source1,        GL_TEXTURE );
591                                 if(using_alpha)
592                                         glTexEnvf(      GL_TEXTURE_ENV, op1,            alphaOp);
593                                 else
594                                         glTexEnvf(      GL_TEXTURE_ENV, op1,            blend_operand);
595                         } break;
596         }
597         glTexEnvf(      GL_TEXTURE_ENV, GL_RGB_SCALE_ARB,       1.0);
598
599         glEndList();
600 }
601
602 int BL_Texture::GetPow2(int n)
603 {
604         if(!is_pow2(n))
605                 n = smaller_pow2(n);
606
607         return n;
608 }
609
610 void BL_Texture::SplitEnvMap(EnvMap *map)
611 {
612         if (!map || !map->ima || (map->ima && !map->ima->ok)) return;
613         ImBuf *ibuf= BKE_image_get_ibuf(map->ima, NULL);
614         if (ibuf)
615                 my_envmap_split_ima(map, ibuf);
616 }
617
618 unsigned int BL_Texture::mDisableState = 0;
619
620 extern "C" {
621
622 void my_envmap_split_ima(EnvMap *env, ImBuf *ibuf)
623 {
624         int dx, part;
625         
626         my_free_envmapdata(env);        
627         
628         dx= ibuf->y;
629         dx/= 2;
630         if(3*dx != ibuf->x) {
631                 printf("Incorrect envmap size\n");
632                 env->ok= 0;
633                 env->ima->ok= 0;
634         }
635         else {
636                 for(part=0; part<6; part++) {
637                         env->cube[part]= IMB_allocImBuf(dx, dx, 24, IB_rect, 0);
638                 }
639                 IMB_rectcpy(env->cube[0], ibuf, 
640                         0, 0, 0, 0, dx, dx);
641                 IMB_rectcpy(env->cube[1], ibuf, 
642                         0, 0, dx, 0, dx, dx);
643                 IMB_rectcpy(env->cube[2], ibuf, 
644                         0, 0, 2*dx, 0, dx, dx);
645                 IMB_rectcpy(env->cube[3], ibuf, 
646                         0, 0, 0, dx, dx, dx);
647                 IMB_rectcpy(env->cube[4], ibuf, 
648                         0, 0, dx, dx, dx, dx);
649                 IMB_rectcpy(env->cube[5], ibuf, 
650                         0, 0, 2*dx, dx, dx, dx);
651
652                 env->ok= 2;// ENV_OSA
653         }
654 }
655
656
657 void my_free_envmapdata(EnvMap *env)
658 {
659         unsigned int part;
660         
661         for(part=0; part<6; part++) {
662                 ImBuf *ibuf= env->cube[part];
663                 if(ibuf) {
664                         IMB_freeImBuf(ibuf);
665                         env->cube[part]= NULL;
666                 }
667         }
668         env->ok= 0;
669 }
670
671
672 } // extern C
673