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