Blender  V2.59
BL_Texture.cpp
Go to the documentation of this file.
00001 
00004 // ------------------------------------
00005 
00006 #include "GL/glew.h"
00007 
00008 #include <iostream>
00009 #include <map>
00010 #include <stdlib.h>
00011 
00012 #include "BL_Material.h"
00013 #include "BL_Texture.h"
00014 #include "MT_assert.h"
00015 
00016 #include "DNA_texture_types.h"
00017 #include "DNA_image_types.h"
00018 #include "IMB_imbuf_types.h"
00019 #include "BKE_image.h"
00020 #include "BLI_blenlib.h"
00021 
00022 #include "RAS_OpenGLRasterizer/RAS_GLExtensionManager.h"
00023 #include "RAS_ICanvas.h"
00024 #include "RAS_Rect.h"
00025 
00026 #include "KX_GameObject.h"
00027 
00028 #define spit(x) std::cout << x << std::endl;
00029 
00030 #include "MEM_guardedalloc.h"
00031 #include "GPU_draw.h"
00032 
00033 extern "C" {
00034         // envmaps
00035         #include "IMB_imbuf.h"
00036         void my_envmap_split_ima(EnvMap *env, ImBuf *ibuf);
00037         void my_free_envmapdata(EnvMap *env);
00038 }
00039 
00040 // (n&(n-1)) zeros the least significant bit of n 
00041 static int is_pow2(int num) {
00042         return ((num)&(num-1))==0;
00043 }
00044 static int smaller_pow2(int num) {
00045         while (!is_pow2(num))
00046                 num= num&(num-1);
00047         return num;     
00048 }
00049 
00050 // Place holder for a full texture manager
00051 class BL_TextureObject
00052 {
00053 public:
00054         unsigned int    gl_texture;
00055         void*                   ref_buffer;
00056 };
00057 
00058 typedef std::map<char*, BL_TextureObject> BL_TextureMap;
00059 static BL_TextureMap g_textureManager;
00060 
00061 
00062 BL_Texture::BL_Texture()
00063 :       mTexture(0),
00064         mOk(0),
00065         mNeedsDeleted(0),
00066         mType(0),
00067         mUnit(0),
00068         mEnvState(0)
00069 {
00070         // --
00071 }
00072 
00073 BL_Texture::~BL_Texture()
00074 {
00075         // --
00076 }
00077 
00078 void BL_Texture::DeleteTex()
00079 {
00080         if( mNeedsDeleted ) {
00081                 glDeleteTextures(1, (GLuint*)&mTexture);
00082                 mNeedsDeleted = 0;
00083                 mOk = 0;
00084         }
00085 
00086         if(mEnvState) {
00087                 glDeleteLists((GLuint)mEnvState, 1);
00088                 mEnvState =0;
00089         }
00090 
00091         if(mDisableState) {
00092                 glDeleteLists((GLuint)mDisableState, 1);
00093                 mDisableState =0;
00094         }
00095         g_textureManager.clear();
00096 }
00097 
00098 
00099 bool BL_Texture::InitFromImage(int unit,  Image *img, bool mipmap)
00100 {
00101 
00102         ImBuf *ibuf;
00103         if (!img || img->ok==0) 
00104         {
00105                 mOk = false;
00106                 return mOk;
00107         }
00108 
00109         ibuf= BKE_image_get_ibuf(img, NULL);
00110         if (ibuf==NULL)
00111         {
00112                 img->ok = 0;
00113                 mOk = false;
00114                 return mOk;
00115         }
00116 
00117 
00118         mTexture = img->bindcode;
00119         mType = GL_TEXTURE_2D;
00120         mUnit = unit;
00121 
00122         ActivateUnit(mUnit);
00123 
00124         if (mTexture != 0) {
00125                 glBindTexture(GL_TEXTURE_2D, mTexture );
00126                 Validate();
00127                 return mOk;
00128         }
00129 
00130         // look for an existing gl image
00131         BL_TextureMap::iterator mapLook = g_textureManager.find(img->id.name);
00132         if (mapLook != g_textureManager.end())
00133         {
00134                 if (mapLook->second.gl_texture != 0)
00135                 {
00136                         mTexture = mapLook->second.gl_texture;
00137                         glBindTexture(GL_TEXTURE_2D, mTexture);
00138                         mOk = IsValid();
00139                         return mOk;
00140                 }
00141         }
00142 
00143         mNeedsDeleted = 1;
00144         glGenTextures(1, (GLuint*)&mTexture);
00145         InitGLTex(ibuf->rect, ibuf->x, ibuf->y, mipmap);
00146 
00147         // track created units
00148         BL_TextureObject obj;
00149         obj.gl_texture = mTexture;
00150         obj.ref_buffer = img;
00151         g_textureManager.insert(std::pair<char*, BL_TextureObject>((char*)img->id.name, obj));
00152 
00153 
00154         glDisable(GL_TEXTURE_2D);
00155         ActivateUnit(0);
00156         Validate();
00157         return mOk;
00158 }
00159 
00160 void BL_Texture::InitGLTex(unsigned int *pix,int x,int y,bool mipmap)
00161 {
00162         if (!is_pow2(x) || !is_pow2(y) ) {
00163                 InitNonPow2Tex(pix, x,y,mipmap);
00164                 return;
00165         }
00166 
00167         glBindTexture(GL_TEXTURE_2D, mTexture );
00168         if( mipmap ) {
00169                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
00170                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00171                 gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGBA, x, y, GL_RGBA, GL_UNSIGNED_BYTE, pix );
00172         } 
00173         else {
00174                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00175                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00176                 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, pix );
00177         }
00178 
00179         if (GLEW_EXT_texture_filter_anisotropic)
00180                 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, GPU_get_anisotropic());
00181         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
00182 }
00183 
00184 
00185 void BL_Texture::InitNonPow2Tex(unsigned int *pix,int x,int y,bool mipmap)
00186 {
00187         int nx= smaller_pow2(x);
00188         int ny= smaller_pow2(y);
00189 
00190         unsigned int *newPixels = (unsigned int *)malloc(nx*ny*sizeof(unsigned int));
00191         
00192         gluScaleImage(GL_RGBA, x, y, GL_UNSIGNED_BYTE, pix, nx,ny, GL_UNSIGNED_BYTE, newPixels);
00193         glBindTexture(GL_TEXTURE_2D, mTexture );
00194 
00195         if( mipmap ) {
00196                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
00197                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00198                 gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGBA, nx, ny, GL_RGBA, GL_UNSIGNED_BYTE, newPixels );
00199         }
00200         else {
00201                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00202                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00203                 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, nx, ny, 0, GL_RGBA, GL_UNSIGNED_BYTE, newPixels );
00204         }
00205 
00206         if (GLEW_EXT_texture_filter_anisotropic)
00207                 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, GPU_get_anisotropic());
00208         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
00209         free(newPixels);
00210 }
00211 
00212 
00213 bool BL_Texture::InitCubeMap(int unit,  EnvMap *cubemap)
00214 {
00215         if (!GLEW_ARB_texture_cube_map)
00216         {
00217                 spit("cubemaps not supported");
00218                 mOk = false;
00219                 return mOk;
00220         }
00221         else if (!cubemap || cubemap->ima->ok==0) 
00222         {
00223                 mOk = false;
00224                 return mOk;
00225         }
00226 
00227         ImBuf *ibuf= BKE_image_get_ibuf(cubemap->ima, NULL);
00228         if (ibuf==0)
00229         {
00230                 cubemap->ima->ok = 0;
00231                 mOk = false;
00232                 return mOk;
00233         }
00234 
00235         mNeedsDeleted = 1;
00236         mType = GL_TEXTURE_CUBE_MAP_ARB;
00237         mTexture = 0;
00238         mUnit = unit;
00239 
00240         ActivateUnit(mUnit);
00241 
00242         BL_TextureMap::iterator mapLook = g_textureManager.find(cubemap->ima->id.name);
00243         if (mapLook != g_textureManager.end())
00244         {
00245                 if (mapLook->second.gl_texture != 0 && mapLook->second.ref_buffer == cubemap->ima)
00246                 {
00247                         mTexture = mapLook->second.gl_texture;
00248                         glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mTexture);
00249                         mOk = IsValid();
00250                         return mOk;
00251                 }
00252         }
00253 
00254 
00255         glGenTextures(1, (GLuint*)&mTexture);
00256         glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mTexture);
00257 
00258 
00259         // track created units
00260         BL_TextureObject obj;
00261         obj.gl_texture = mTexture;
00262         obj.ref_buffer = cubemap->ima;
00263         g_textureManager.insert(std::pair<char*, BL_TextureObject>((char*)cubemap->ima->id.name, obj));
00264 
00265 
00266         bool needs_split = false;
00267         if (!cubemap->cube[0]) 
00268         {
00269                 needs_split = true;
00270                 spit ("Re-Generating texture buffer");
00271         }
00272 
00273         if (needs_split)
00274                 my_envmap_split_ima(cubemap, ibuf);
00275 
00276 
00277         if (!is_pow2(cubemap->cube[0]->x) || !is_pow2(cubemap->cube[0]->y))
00278         {
00279                 spit("invalid envmap size please render with CubeRes @ power of two");
00280 
00281                 my_free_envmapdata(cubemap);
00282                 mOk = false;
00283                 return mOk;
00284         }
00285 
00286 
00287 #define SetCubeMapFace(face, num)   \
00288         glTexImage2D(face, 0,GL_RGBA,   \
00289         cubemap->cube[num]->x,          \
00290         cubemap->cube[num]->y,          \
00291         0, GL_RGBA, GL_UNSIGNED_BYTE,   \
00292         cubemap->cube[num]->rect)
00293 
00294         SetCubeMapFace(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, 5);
00295         SetCubeMapFace(GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, 3);
00296         SetCubeMapFace(GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, 0);
00297         SetCubeMapFace(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, 1);
00298         SetCubeMapFace(GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, 2);
00299         SetCubeMapFace(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, 4);
00300 
00301         glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
00302         glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
00303         glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S,     GL_CLAMP_TO_EDGE );
00304         glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T,     GL_CLAMP_TO_EDGE );
00305         if(GLEW_VERSION_1_2)
00306                 glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_R,     GL_CLAMP_TO_EDGE );
00307 
00308         if (needs_split)
00309                 my_free_envmapdata(cubemap);
00310 
00311 
00312 
00313         glDisable(GL_TEXTURE_CUBE_MAP_ARB);
00314         ActivateUnit(0);
00315 
00316         mOk = IsValid();
00317         return mOk;
00318 }
00319 
00320 bool BL_Texture::IsValid()
00321 {
00322         return (mTexture!= 0)?glIsTexture(mTexture)!=0:false;
00323 }
00324 
00325 
00326 void BL_Texture::Validate()
00327 {
00328         mOk = IsValid();
00329 }
00330 
00331 
00332 bool BL_Texture::Ok()
00333 {
00334         return  (mTexture!= 0); 
00335 }
00336 
00337 
00338 unsigned int BL_Texture::GetTextureType() const
00339 {
00340         return mType;
00341 }
00342 
00343 int BL_Texture::GetMaxUnits()
00344 {
00345         GLint unit=0;
00346 
00347         if(GLEW_ARB_multitexture) {
00348                 glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &unit);
00349                 return (MAXTEX>=unit?unit:MAXTEX);
00350         }
00351 
00352         return 0;
00353 }
00354 
00355 void BL_Texture::ActivateFirst()
00356 {
00357         if(GLEW_ARB_multitexture)
00358                 glActiveTextureARB(GL_TEXTURE0_ARB);
00359 }
00360 
00361 void BL_Texture::ActivateUnit(int unit)
00362 {
00363         if(GLEW_ARB_multitexture)
00364                 if(unit <= MAXTEX)
00365                         glActiveTextureARB(GL_TEXTURE0_ARB+unit);
00366 }
00367 
00368 
00369 void BL_Texture::DisableUnit()
00370 {
00371         if(GLEW_ARB_multitexture)
00372                 glActiveTextureARB(GL_TEXTURE0_ARB+mUnit);
00373 
00374         glMatrixMode(GL_TEXTURE);
00375         glLoadIdentity();
00376         glMatrixMode(GL_MODELVIEW);
00377 
00378         if(GLEW_ARB_texture_cube_map && glIsEnabled(GL_TEXTURE_CUBE_MAP_ARB))
00379                 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
00380         else
00381         {
00382                 if (glIsEnabled(GL_TEXTURE_2D))
00383                         glDisable(GL_TEXTURE_2D);
00384         }
00385 
00386         glDisable(GL_TEXTURE_GEN_S);
00387         glDisable(GL_TEXTURE_GEN_T);
00388         glDisable(GL_TEXTURE_GEN_R);
00389         glDisable(GL_TEXTURE_GEN_Q);
00390         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
00391 }
00392 
00393 
00394 void BL_Texture::DisableAllTextures()
00395 {
00396         for(int i=0; i<MAXTEX; i++) {
00397                 if(GLEW_ARB_multitexture)
00398                         glActiveTextureARB(GL_TEXTURE0_ARB+i);
00399 
00400                 glMatrixMode(GL_TEXTURE);
00401                 glLoadIdentity();
00402                 glMatrixMode(GL_MODELVIEW);
00403                 glDisable(GL_TEXTURE_2D);       
00404                 glDisable(GL_TEXTURE_GEN_S);
00405                 glDisable(GL_TEXTURE_GEN_T);
00406                 glDisable(GL_TEXTURE_GEN_R);
00407                 glDisable(GL_TEXTURE_GEN_Q);
00408                 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
00409         }
00410 
00411         if(GLEW_ARB_multitexture)
00412                 glActiveTextureARB(GL_TEXTURE0_ARB);
00413 }
00414 
00415 
00416 void BL_Texture::ActivateTexture()
00417 {
00418         if(GLEW_ARB_multitexture)
00419                 glActiveTextureARB(GL_TEXTURE0_ARB+mUnit);
00420 
00421         if (mType == GL_TEXTURE_CUBE_MAP_ARB && GLEW_ARB_texture_cube_map)
00422         {
00423                 glBindTexture( GL_TEXTURE_CUBE_MAP_ARB, mTexture );     
00424                 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
00425         }
00426         else {
00427                 if(GLEW_ARB_texture_cube_map )
00428                         glDisable(GL_TEXTURE_CUBE_MAP_ARB);
00429 
00430                 glBindTexture( GL_TEXTURE_2D, mTexture );       
00431                 glEnable(GL_TEXTURE_2D);
00432         }
00433 }
00434 
00435 void BL_Texture::SetMapping(int mode)
00436 {
00437 
00438         if(!(mode &USEREFL)) {
00439                 glDisable(GL_TEXTURE_GEN_S);
00440                 glDisable(GL_TEXTURE_GEN_T);
00441                 glDisable(GL_TEXTURE_GEN_R);
00442                 glDisable(GL_TEXTURE_GEN_Q);
00443                 return;
00444         }
00445 
00446         if( mType == GL_TEXTURE_CUBE_MAP_ARB && 
00447                 GLEW_ARB_texture_cube_map &&
00448                 mode &USEREFL) 
00449         {
00450                 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB );
00451                 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB );
00452                 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB );
00453                 
00454                 glEnable(GL_TEXTURE_GEN_S);
00455                 glEnable(GL_TEXTURE_GEN_T);
00456                 glEnable(GL_TEXTURE_GEN_R);
00457                 glDisable(GL_TEXTURE_GEN_Q);
00458                 return;
00459         }
00460         else
00461         {
00462                 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
00463                 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
00464 
00465                 glEnable(GL_TEXTURE_GEN_S);
00466                 glEnable(GL_TEXTURE_GEN_T);
00467                 glDisable(GL_TEXTURE_GEN_R);
00468                 glDisable(GL_TEXTURE_GEN_Q);
00469         }
00470 }
00471 
00472 
00473 void BL_Texture::setTexEnv(BL_Material *mat, bool modulate)
00474 {
00475         if(modulate || !GLEW_ARB_texture_env_combine){
00476                 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
00477                 return;
00478         }
00479 
00480         if(glIsList(mEnvState))
00481         {
00482                 glCallList(mEnvState);
00483                 return;
00484         }
00485         if(!mEnvState)
00486                 mEnvState = glGenLists(1);
00487 
00488         glNewList(mEnvState, GL_COMPILE_AND_EXECUTE);
00489 
00490         glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB );
00491 
00492         GLfloat blend_operand           = GL_SRC_COLOR;
00493         GLfloat blend_operand_prev  = GL_SRC_COLOR;
00494         GLfloat alphaOp                         = GL_SRC_ALPHA;
00495 
00496         GLenum combiner = GL_COMBINE_RGB_ARB;
00497         GLenum source0  = GL_SOURCE0_RGB_ARB;
00498         GLenum source1  = GL_SOURCE1_RGB_ARB;
00499         GLenum source2  = GL_SOURCE2_RGB_ARB;
00500         GLenum op0              = GL_OPERAND0_RGB_ARB;
00501         GLenum op1              = GL_OPERAND1_RGB_ARB;
00502         GLenum op2              = GL_OPERAND2_RGB_ARB;
00503 
00504         // switch to alpha combiners
00505         if( mat->flag[mUnit]  &TEXALPHA ) {
00506                 combiner = GL_COMBINE_ALPHA_ARB;
00507                 source0 = GL_SOURCE0_ALPHA_ARB;
00508                 source1 = GL_SOURCE1_ALPHA_ARB;
00509                 source2 = GL_SOURCE2_ALPHA_ARB;
00510                 op0 = GL_OPERAND0_ALPHA_ARB;
00511                 op1 = GL_OPERAND1_ALPHA_ARB;
00512                 op2 = GL_OPERAND2_ALPHA_ARB;
00513                 blend_operand = GL_SRC_ALPHA;
00514                 blend_operand_prev = GL_SRC_ALPHA;
00515                 // invert
00516                 if(mat->flag[mUnit] &TEXNEG) {
00517                         blend_operand_prev = GL_ONE_MINUS_SRC_ALPHA;
00518                         blend_operand = GL_ONE_MINUS_SRC_ALPHA;
00519                 }
00520         }
00521         else {
00522                 if(mat->flag[mUnit] &TEXNEG) {
00523                         blend_operand_prev=GL_ONE_MINUS_SRC_COLOR;
00524                         blend_operand = GL_ONE_MINUS_SRC_COLOR;
00525                 }
00526         }
00527         bool using_alpha = false;
00528 
00529         if(mat->flag[mUnit]  &USEALPHA){
00530                 alphaOp = GL_ONE_MINUS_SRC_ALPHA;
00531                 using_alpha=true;
00532         }
00533         else if(mat->flag[mUnit]  &USENEGALPHA){
00534                 alphaOp = GL_SRC_ALPHA;
00535                 using_alpha = true;
00536         }
00537 
00538         switch( mat->blend_mode[mUnit] ) {
00539                 case BLEND_MIX:
00540                         {
00541                                 // ------------------------------
00542                                 if(!using_alpha) {
00543                                         GLfloat base_col[4];
00544                                         base_col[0]      = base_col[1]  = base_col[2]  = 0.f;
00545                                         base_col[3]      = 1.f-mat->color_blend[mUnit];
00546                                         glTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,base_col );
00547                                 }
00548                                 glTexEnvf(      GL_TEXTURE_ENV, combiner,       GL_INTERPOLATE_ARB);
00549                                 glTexEnvf(      GL_TEXTURE_ENV, source0,        GL_PREVIOUS_ARB);
00550                                 glTexEnvf(      GL_TEXTURE_ENV, op0,            blend_operand_prev );
00551                                 glTexEnvf(      GL_TEXTURE_ENV, source1,        GL_TEXTURE );
00552                                 glTexEnvf(      GL_TEXTURE_ENV, op1,            blend_operand);
00553                                 if(!using_alpha)
00554                                         glTexEnvf(      GL_TEXTURE_ENV, source2,        GL_CONSTANT_ARB );
00555                                 else
00556                                         glTexEnvf(      GL_TEXTURE_ENV, source2,        GL_TEXTURE );
00557 
00558                                 glTexEnvf(      GL_TEXTURE_ENV, op2,            alphaOp);
00559                         }break;
00560                 case BLEND_MUL: 
00561                         {
00562                                 // ------------------------------
00563                                 glTexEnvf(      GL_TEXTURE_ENV, combiner,       GL_MODULATE);
00564                                 glTexEnvf(      GL_TEXTURE_ENV, source0,        GL_PREVIOUS_ARB);
00565                                 glTexEnvf(      GL_TEXTURE_ENV, op0,            blend_operand_prev);
00566                                 glTexEnvf(      GL_TEXTURE_ENV, source1,        GL_TEXTURE );
00567                                 if(using_alpha)
00568                                         glTexEnvf(      GL_TEXTURE_ENV, op1,            alphaOp);
00569                                 else
00570                                         glTexEnvf(      GL_TEXTURE_ENV, op1,            blend_operand);
00571                         }break;
00572                 case BLEND_ADD: 
00573                         {
00574                                 // ------------------------------
00575                                 glTexEnvf(      GL_TEXTURE_ENV, combiner,       GL_ADD_SIGNED_ARB);
00576                                 glTexEnvf(      GL_TEXTURE_ENV, source0,        GL_PREVIOUS_ARB );
00577                                 glTexEnvf(      GL_TEXTURE_ENV, op0,            blend_operand_prev );
00578                                 glTexEnvf(      GL_TEXTURE_ENV, source1,        GL_TEXTURE );
00579                                 if(using_alpha)
00580                                         glTexEnvf(      GL_TEXTURE_ENV, op1,            alphaOp);
00581                                 else
00582                                         glTexEnvf(      GL_TEXTURE_ENV, op1,            blend_operand);
00583                         }break;
00584                 case BLEND_SUB: 
00585                         {
00586                                 // ------------------------------
00587                                 glTexEnvf(      GL_TEXTURE_ENV, combiner,       GL_SUBTRACT_ARB);
00588                                 glTexEnvf(      GL_TEXTURE_ENV, source0,        GL_PREVIOUS_ARB );
00589                                 glTexEnvf(      GL_TEXTURE_ENV, op0,            blend_operand_prev );
00590                                 glTexEnvf(      GL_TEXTURE_ENV, source1,        GL_TEXTURE );
00591                                 glTexEnvf(      GL_TEXTURE_ENV, op1,            blend_operand);
00592                         }break;
00593                 case BLEND_SCR: 
00594                         {
00595                                 // ------------------------------
00596                                 glTexEnvf(      GL_TEXTURE_ENV, combiner,       GL_ADD);
00597                                 glTexEnvf(      GL_TEXTURE_ENV, source0,        GL_PREVIOUS_ARB );
00598                                 glTexEnvf(      GL_TEXTURE_ENV, op0,            blend_operand_prev );
00599                                 glTexEnvf(      GL_TEXTURE_ENV, source1,        GL_TEXTURE );
00600                                 if(using_alpha)
00601                                         glTexEnvf(      GL_TEXTURE_ENV, op1,            alphaOp);
00602                                 else
00603                                         glTexEnvf(      GL_TEXTURE_ENV, op1,            blend_operand);
00604                         } break;
00605         }
00606         glTexEnvf(      GL_TEXTURE_ENV, GL_RGB_SCALE_ARB,       1.0);
00607 
00608         glEndList();
00609 }
00610 
00611 int BL_Texture::GetPow2(int n)
00612 {
00613         if(!is_pow2(n))
00614                 n = smaller_pow2(n);
00615 
00616         return n;
00617 }
00618 
00619 void BL_Texture::SplitEnvMap(EnvMap *map)
00620 {
00621         if (!map || !map->ima || (map->ima && !map->ima->ok)) return;
00622         ImBuf *ibuf= BKE_image_get_ibuf(map->ima, NULL);
00623         if (ibuf)
00624                 my_envmap_split_ima(map, ibuf);
00625 }
00626 
00627 unsigned int BL_Texture::mDisableState = 0;
00628 
00629 extern "C" {
00630 
00631 void my_envmap_split_ima(EnvMap *env, ImBuf *ibuf)
00632 {
00633         int dx, part;
00634         
00635         my_free_envmapdata(env);        
00636         
00637         dx= ibuf->y;
00638         dx/= 2;
00639         if(3*dx != ibuf->x) {
00640                 printf("Incorrect envmap size\n");
00641                 env->ok= 0;
00642                 env->ima->ok= 0;
00643         }
00644         else {
00645                 for(part=0; part<6; part++) {
00646                         env->cube[part]= IMB_allocImBuf(dx, dx, 24, IB_rect);
00647                 }
00648                 IMB_rectcpy(env->cube[0], ibuf, 
00649                         0, 0, 0, 0, dx, dx);
00650                 IMB_rectcpy(env->cube[1], ibuf, 
00651                         0, 0, dx, 0, dx, dx);
00652                 IMB_rectcpy(env->cube[2], ibuf, 
00653                         0, 0, 2*dx, 0, dx, dx);
00654                 IMB_rectcpy(env->cube[3], ibuf, 
00655                         0, 0, 0, dx, dx, dx);
00656                 IMB_rectcpy(env->cube[4], ibuf, 
00657                         0, 0, dx, dx, dx, dx);
00658                 IMB_rectcpy(env->cube[5], ibuf, 
00659                         0, 0, 2*dx, dx, dx, dx);
00660 
00661                 env->ok= 2;// ENV_OSA
00662         }
00663 }
00664 
00665 
00666 void my_free_envmapdata(EnvMap *env)
00667 {
00668         unsigned int part;
00669         
00670         for(part=0; part<6; part++) {
00671                 ImBuf *ibuf= env->cube[part];
00672                 if(ibuf) {
00673                         IMB_freeImBuf(ibuf);
00674                         env->cube[part]= NULL;
00675                 }
00676         }
00677         env->ok= 0;
00678 }
00679 
00680 
00681 } // extern C
00682