Blender V2.61 - r43446

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