From c4202fbd43c7b91c8705fcea7191f82b64a28bca Mon Sep 17 00:00:00 2001 From: Charlie Carley Date: Sat, 13 Jan 2007 08:30:08 +0000 Subject: [PATCH] First commit! Small bug fix for cube map crashing in the player. Cube maps don't display correctly in the player at the moment too.. something to do with regenerating/loading the images --- .../Converter/BL_BlenderDataConversion.cpp | 27 +- source/gameengine/Ketsji/BL_Texture.cpp | 271 ++++++++++-------- source/gameengine/Ketsji/BL_Texture.h | 16 +- .../gameengine/Ketsji/KX_BlenderMaterial.cpp | 1 - 4 files changed, 165 insertions(+), 150 deletions(-) diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index 0d9ad087c05..86fc2267c64 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -432,21 +432,19 @@ BL_Material* ConvertMaterial( else if(mttmp->tex->type == TEX_ENVMAP) { if( mttmp->tex->env->stype == ENV_LOAD ) { - material->mtexname[i]= mttmp->tex->id.name; - material->cubemap[i] = mttmp->tex->env; - if(material->cubemap[i]->ima) { - material->texname[i] = material->cubemap[i]->ima->id.name; + material->mtexname[i] = mttmp->tex->id.name; + EnvMap *env = mttmp->tex->env; + env->ima = mttmp->tex->ima; + material->cubemap[i] = env; + + if (material->cubemap[i]) + { + if (!material->cubemap[i]->cube[0]) + BL_Texture::SplitEnvMap(material->cubemap[i]); + + material->texname[i]= material->cubemap[i]->ima->id.name; material->mapping[i].mapping |= USEENV; } - else { - // in the player, we need to split it our self - material->cubemap[i]->ima = mttmp->tex->ima; - if(material->cubemap[i]->ima) { - material->texname[i] = material->cubemap[i]->ima->id.name; - material->mapping[i].mapping |= USEENV; - } - // - } } } material->flag[i] |= (mat->ipo!=0)?HASIPO:0; @@ -1098,9 +1096,6 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* } meshobj->UpdateMaterialList(); - - - // ----------------------------------- // pre calculate texture generation for(RAS_MaterialBucket::Set::iterator mit = meshobj->GetFirstMaterial(); mit != meshobj->GetLastMaterial(); ++ mit) { diff --git a/source/gameengine/Ketsji/BL_Texture.cpp b/source/gameengine/Ketsji/BL_Texture.cpp index 0867b41d9ae..6841bb2f959 100644 --- a/source/gameengine/Ketsji/BL_Texture.cpp +++ b/source/gameengine/Ketsji/BL_Texture.cpp @@ -12,6 +12,7 @@ #endif #include +#include #include "BL_Material.h" #include "BL_Texture.h" @@ -30,6 +31,7 @@ #include "KX_GameObject.h" + using namespace bgl; #define spit(x) std::cout << x << std::endl; @@ -39,7 +41,7 @@ using namespace bgl; extern "C" { // envmaps #include "IMB_imbuf.h" - void my_envmap_split_ima(EnvMap *env); + void my_envmap_split_ima(EnvMap *env, ImBuf *ibuf); void my_free_envmapdata(EnvMap *env); } @@ -53,9 +55,20 @@ static int smaller_pow2(int num) { return num; } +// Place holder for a full texture manager +class BL_TextureObject +{ +public: + unsigned int gl_texture; + void* ref_buffer; +}; + +typedef std::map BL_TextureMap; +static BL_TextureMap g_textureManager; + + BL_Texture::BL_Texture() : mTexture(0), - mError(0), mOk(0), mNeedsDeleted(0), mType(0), @@ -87,31 +100,37 @@ void BL_Texture::DeleteTex() glDeleteLists((GLuint)mDisableState, 1); mDisableState =0; } + + g_textureManager.clear(); } bool BL_Texture::InitFromImage(int unit, Image *img, bool mipmap) { - ImBuf *ibuf; - - if(!img || img->ok==0 ) { - mError = true; - mOk = false; - return mOk; - } - ibuf= BKE_image_get_ibuf(img, NULL); - if( ibuf==NULL ) { - img->ok = 0; - mError = true; - mOk = false; - return mOk; - } - mTexture = img->bindcode; + ImBuf *ibuf; + if (!img || img->ok==0) + { + mOk = false; + return mOk; + } + + ibuf= BKE_image_get_ibuf(img, NULL); + if (ibuf==NULL) + { + img->ok = 0; + mOk = false; + return mOk; + } + + + mTexture = img->bindcode; mType = GL_TEXTURE_2D; mUnit = unit; - // smoke em if we got em + ActivateUnit(mUnit); + + if (mTexture != 0) { glBindTexture(GL_TEXTURE_2D, mTexture ); Validate(); @@ -120,6 +139,11 @@ bool BL_Texture::InitFromImage(int unit, Image *img, bool mipmap) mNeedsDeleted = 1; glGenTextures(1, (GLuint*)&mTexture); InitGLTex(ibuf->rect, ibuf->x, ibuf->y, mipmap); + + + + glDisable(GL_TEXTURE_2D); + ActivateUnit(0); Validate(); return mOk; } @@ -172,68 +196,88 @@ void BL_Texture::InitNonPow2Tex(unsigned int *pix,int x,int y,bool mipmap) } -bool BL_Texture::InitCubeMap(int unit, EnvMap *cubemap ) +bool BL_Texture::InitCubeMap(int unit, EnvMap *cubemap) { #ifdef GL_ARB_texture_cube_map - if(!RAS_EXT_support._ARB_texture_cube_map) { + + if (!RAS_EXT_support._ARB_texture_cube_map) + { spit("cubemaps not supported"); - mError = true; mOk = false; return mOk; } - - else if(!cubemap || cubemap->ima->ok==0 ) { - mError = true; - mOk = false; - return mOk; - } - ImBuf *ibuf= BKE_image_get_ibuf(cubemap->ima, NULL); - if( ibuf==0 ) { - cubemap->ima->ok = 0; - mError = true; + else if (!cubemap || cubemap->ima->ok==0) + { + mOk = false; + return mOk; + } + + ImBuf *ibuf= BKE_image_get_ibuf(cubemap->ima, NULL); + if (ibuf==0) + { + cubemap->ima->ok = 0; mOk = false; return mOk; } - EnvMap *CubeMap = cubemap; mNeedsDeleted = 1; mType = GL_TEXTURE_CUBE_MAP_ARB; mTexture = 0; mUnit = unit; + ActivateUnit(mUnit); - glGenTextures(1, (GLuint*)&mTexture); - glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mTexture ); - bool needs_split = false; - - if(!CubeMap->cube[0]) needs_split = true; - - if(needs_split){ - // split it - my_envmap_split_ima(CubeMap); + BL_TextureMap::iterator mapLook = g_textureManager.find(cubemap->ima->id.name); + if (mapLook != g_textureManager.end()) + { + if (mapLook->second.gl_texture != 0 && mapLook->second.ref_buffer == cubemap->ima) + { + mTexture = mapLook->second.gl_texture; + glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mTexture); + mOk = IsValid(); + return mOk; + } } - // ----------------------------------- - int x = CubeMap->cube[0]->x; - int y = CubeMap->cube[0]->y; - // check the first image, and assume the rest - if (!is_pow2(x) || !is_pow2(y)) { + glGenTextures(1, (GLuint*)&mTexture); + glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mTexture); + + + // track created units + BL_TextureObject obj; + obj.gl_texture = mTexture; + obj.ref_buffer = cubemap->ima; + g_textureManager.insert(std::make_pair(cubemap->ima->id.name, obj)); + + + bool needs_split = false; + if (!cubemap->cube[0]) + { + needs_split = true; + spit ("Re-Generating texture buffer"); + } + + if (needs_split) + my_envmap_split_ima(cubemap, ibuf); + + + if (!is_pow2(cubemap->cube[0]->x) || !is_pow2(cubemap->cube[0]->y)) + { spit("invalid envmap size please render with CubeRes @ power of two"); - my_free_envmapdata(CubeMap); - mError = true; + + my_free_envmapdata(cubemap); mOk = false; return mOk; } - /* - */ -#define SetCubeMapFace(face, num) \ + +#define SetCubeMapFace(face, num) \ glTexImage2D(face, 0,GL_RGBA, \ - CubeMap->cube[num]->x, \ - CubeMap->cube[num]->y, \ - 0, GL_RGBA, GL_UNSIGNED_BYTE, \ - CubeMap->cube[num]->rect) + cubemap->cube[num]->x, \ + cubemap->cube[num]->y, \ + 0, GL_RGBA, GL_UNSIGNED_BYTE, \ + cubemap->cube[num]->rect) SetCubeMapFace(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, 5); SetCubeMapFace(GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, 3); @@ -246,19 +290,23 @@ bool BL_Texture::InitCubeMap(int unit, EnvMap *cubemap ) glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); - - - if(needs_split) { - cubemap->ima = CubeMap->ima; - my_free_envmapdata(CubeMap); - } + #ifdef GL_VERSION_1_2 + glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE ); + #endif + + if (needs_split) + my_free_envmapdata(cubemap); + + + + glDisable(GL_TEXTURE_CUBE_MAP_ARB); + ActivateUnit(0); mOk = IsValid(); return mOk; #else - mError = true; mOk = false; return mOk; @@ -303,26 +351,17 @@ int BL_Texture::GetMaxUnits() void BL_Texture::ActivateFirst() { #ifdef GL_ARB_multitexture - if(RAS_EXT_support._ARB_multitexture) { + if(RAS_EXT_support._ARB_multitexture) bgl::blActiveTextureARB(GL_TEXTURE0_ARB); - //if(mVertexArray) - // bgl::blClientActiveTextureARB(GL_TEXTURE0_ARB); - } - #endif } void BL_Texture::ActivateUnit(int unit) { #ifdef GL_ARB_multitexture - if(RAS_EXT_support._ARB_multitexture) { + if(RAS_EXT_support._ARB_multitexture) if(unit <= MAXTEX) - { bgl::blActiveTextureARB(GL_TEXTURE0_ARB+unit); - //if(mVertexArray) - // bgl::blClientActiveTextureARB(GL_TEXTURE0_ARB+unit); - } - } #endif } @@ -330,21 +369,26 @@ void BL_Texture::ActivateUnit(int unit) void BL_Texture::DisableUnit() { #ifdef GL_ARB_multitexture - if(RAS_EXT_support._ARB_multitexture){ + if(RAS_EXT_support._ARB_multitexture) bgl::blActiveTextureARB(GL_TEXTURE0_ARB+mUnit); - //if(mVertexArray) - // bgl::blClientActiveTextureARB(GL_TEXTURE0_ARB+mUnit); - } + #endif + + glMatrixMode(GL_TEXTURE); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); -#ifdef GL_ARB_texture_cube_map - if(RAS_EXT_support._ARB_texture_cube_map) + #ifdef GL_ARB_texture_cube_map + if(RAS_EXT_support._ARB_texture_cube_map && glIsEnabled(GL_TEXTURE_CUBE_MAP_ARB)) glDisable(GL_TEXTURE_CUBE_MAP_ARB); -#endif - glDisable(GL_TEXTURE_2D); + else + #endif + { + if (glIsEnabled(GL_TEXTURE_2D)) + glDisable(GL_TEXTURE_2D); + } + glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); glDisable(GL_TEXTURE_GEN_R); @@ -356,30 +400,14 @@ void BL_Texture::DisableUnit() void BL_Texture::DisableAllTextures() { #ifdef GL_ARB_multitexture - if(mDisableState != 0 && glIsList(mDisableState)) { - glCallList(mDisableState); - return; - } - if(!mDisableState) - mDisableState = glGenLists(1); - - glNewList(mDisableState, GL_COMPILE_AND_EXECUTE); - glDisable(GL_BLEND); for(int i=0; iima || map->ima && !map->ima->ok) return; + ImBuf *ibuf= BKE_image_get_ibuf(map->ima, NULL); + if (ibuf) + my_envmap_split_ima(map, ibuf); +} unsigned int BL_Texture::mDisableState = 0; extern "C" { -void my_envmap_split_ima(EnvMap *env) +void my_envmap_split_ima(EnvMap *env, ImBuf *ibuf) { - ImBuf *ibuf; int dx, part; my_free_envmapdata(env); @@ -635,19 +670,19 @@ void my_envmap_split_ima(EnvMap *env) env->cube[part]= ibuf= IMB_allocImBuf(dx, dx, 24, IB_rect, 0); } IMB_rectcpy(env->cube[0], ibuf, - 0, 0, 0, 0, dx, dx); + 0, 0, 0, 0, dx, dx); IMB_rectcpy(env->cube[1], ibuf, - 0, 0, dx, 0, dx, dx); + 0, 0, dx, 0, dx, dx); IMB_rectcpy(env->cube[2], ibuf, - 0, 0, 2*dx, 0, dx, dx); + 0, 0, 2*dx, 0, dx, dx); IMB_rectcpy(env->cube[3], ibuf, - 0, 0, 0, dx, dx, dx); + 0, 0, 0, dx, dx, dx); IMB_rectcpy(env->cube[4], ibuf, - 0, 0, dx, dx, dx, dx); + 0, 0, dx, dx, dx, dx); IMB_rectcpy(env->cube[5], ibuf, - 0, 0, 2*dx, dx, dx, dx); - - env->ok= 2; + 0, 0, 2*dx, dx, dx, dx); + + env->ok= 2;// ENV_OSA } } diff --git a/source/gameengine/Ketsji/BL_Texture.h b/source/gameengine/Ketsji/BL_Texture.h index 0c12b11b12b..0d0c7a277f2 100644 --- a/source/gameengine/Ketsji/BL_Texture.h +++ b/source/gameengine/Ketsji/BL_Texture.h @@ -20,16 +20,13 @@ class RAS_ICanvas; class BL_Texture { private: - // ----------------------------------- unsigned int mTexture; // Bound texture unit data - bool mError; // Errors bool mOk; // ... bool mNeedsDeleted; // If generated unsigned int mType; // enum TEXTURE_2D | CUBE_MAP int mUnit; // Texture unit associated with mTexture unsigned int mEnvState; // cache textureEnv static unsigned int mDisableState; // speed up disabling calls - // ----------------------------------- void InitNonPow2Tex(unsigned int *p,int x,int y,bool mipmap ); void InitGLTex(unsigned int *p,int x,int y,bool mipmap ); @@ -55,14 +52,8 @@ public: static void ActivateUnit(int unit); static int GetMaxUnits(); static int GetPow2(int x); + static void SplitEnvMap(EnvMap *map); - /** todo - void CreateRenderTexture(RAS_Rect r, RTData d); - void ReadDepth(RAS_Rect r, RTData d); - static void BeginDepth(RAS_ICanvas *can, RTData d); - static void EndDepth(RAS_ICanvas *can,RTData d); - void SetDepthMapping(MT_Matrix4x4& p, MT_Matrix4x4& m); - */ void ActivateTexture(); void SetMapping(int mode); @@ -70,9 +61,4 @@ public: void setTexEnv(BL_Material *mat, bool modulate=false); }; -/* Render to texture support, managed by the scene - TODO -*/ - - #endif//__BL_TEXTURE_H__ diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp index d8c2f2fd40c..426a3a1aab5 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp @@ -136,7 +136,6 @@ void KX_BlenderMaterial::OnConstruction() // for each unique material... int i; for(i=0; inum_enabled; i++) { - BL_Texture::ActivateUnit(i); if( mMaterial->mapping[i].mapping & USEENV ) { if(!RAS_EXT_support._ARB_texture_cube_map) { spit("CubeMap textures not supported");