diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index ef3efbcec87..6a570c9e815 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -318,7 +318,8 @@ typedef struct MTF_localLayer }MTF_localLayer; // ------------------------------------ -BL_Material* ConvertMaterial( +bool ConvertMaterial( + BL_Material *material, Material *mat, MTFace* tface, const char *tfaceName, @@ -329,9 +330,7 @@ BL_Material* ConvertMaterial( MTF_localLayer *layers, bool glslmat) { - //this needs some type of manager - BL_Material *material = new BL_Material(); - + material->Initialize(); int numchan = -1, texalpha = 0; bool validmat = (mat!=0); bool validface = (tface!=0); @@ -720,7 +719,7 @@ BL_Material* ConvertMaterial( material->tface = tface; material->material = mat; - return material; + return true; } @@ -781,6 +780,13 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* meshobj->SetName(mesh->id.name); meshobj->m_sharedvertex_map.resize(totvert); + RAS_IPolyMaterial* polymat = NULL; + STR_String imastr; + // These pointers will hold persistent material structure during the conversion + // to avoid countless allocation/deallocation of memory. + BL_Material* bl_mat = NULL; + KX_BlenderMaterial* kx_blmat = NULL; + KX_PolygonMaterial* kx_polymat = NULL; for (int f=0;fGetMaterials()) { /* do Blender Multitexture and Blender GLSL materials */ @@ -852,7 +856,9 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* MT_Point2 uv[4]; /* first is the BL_Material */ - bl_mat = ConvertMaterial(ma, tface, tfaceName, mface, mcol, + if (!bl_mat) + bl_mat = new BL_Material(); + ConvertMaterial(bl_mat, ma, tface, tfaceName, mface, mcol, lightlayer, blenderobj, layers, converter->GetGLSLMaterials()); visible = ((bl_mat->ras_mode & POLY_VIS)!=0); @@ -873,13 +879,16 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* uv22 = uv[2]; uv23 = uv[3]; /* then the KX_BlenderMaterial */ - polymat = new KX_BlenderMaterial(scene, bl_mat, skinMesh, lightlayer); + if (kx_blmat == NULL) + kx_blmat = new KX_BlenderMaterial(); + kx_blmat->Initialize(scene, bl_mat, skinMesh, lightlayer); + polymat = static_cast(kx_blmat); } else { /* do Texture Face materials */ Image* bima = (tface)? (Image*)tface->tpage: NULL; - STR_String imastr = (tface)? (bima? (bima)->id.name : "" ) : ""; + imastr = (tface)? (bima? (bima)->id.name : "" ) : ""; char transp=0; short mode=0, tile=0; @@ -957,9 +966,12 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* bool alpha = (transp == TF_ALPHA || transp == TF_ADD); bool zsort = (mode & TF_ALPHASORT)? alpha: 0; - polymat = new KX_PolygonMaterial(imastr, ma, (int)mface->mat_nr, + if (kx_polymat == NULL) + kx_polymat = new KX_PolygonMaterial(); + kx_polymat->Initialize(imastr, ma, (int)mface->mat_nr, tile, tilexrep, tileyrep, mode, transp, alpha, zsort, lightlayer, tface, (unsigned int*)mcol); + polymat = static_cast(kx_polymat); if (ma) { polymat->m_specular = MT_Vector3(ma->specr, ma->specg, ma->specb)*ma->spec; @@ -984,15 +996,17 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* converter->RegisterPolyMaterial(polymat); if(converter->GetMaterials()) { converter->RegisterBlenderMaterial(bl_mat); + // the poly material has been stored in the bucket, next time we must create a new one + bl_mat = NULL; + kx_blmat = NULL; + } else { + // the poly material has been stored in the bucket, next time we must create a new one + kx_polymat = NULL; } } else { - // delete the material objects since they are no longer needed // from now on, use the polygon material from the material bucket - delete polymat; - if(converter->GetMaterials()) { - delete bl_mat; - } polymat = bucket->GetPolyMaterial(); + // keep the material pointers, they will be reused for next face } int nverts = (mface->v4)? 4: 3; @@ -1036,7 +1050,13 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* delete []layers; dm->release(dm); - + // cleanup material + if (bl_mat) + delete bl_mat; + if (kx_blmat) + delete kx_blmat; + if (kx_polymat) + delete kx_polymat; return meshobj; } diff --git a/source/gameengine/Ketsji/BL_Material.cpp b/source/gameengine/Ketsji/BL_Material.cpp index 022ed71ef7b..c63b9d55306 100644 --- a/source/gameengine/Ketsji/BL_Material.cpp +++ b/source/gameengine/Ketsji/BL_Material.cpp @@ -27,6 +27,11 @@ int getNumTexChannels( Material *mat ) } BL_Material::BL_Material() +{ + Initialize(); +} + +void BL_Material::Initialize() { rgb[0] = 0; rgb[1] = 0; diff --git a/source/gameengine/Ketsji/BL_Material.h b/source/gameengine/Ketsji/BL_Material.h index a0ce37aace0..4f572f95891 100644 --- a/source/gameengine/Ketsji/BL_Material.h +++ b/source/gameengine/Ketsji/BL_Material.h @@ -44,6 +44,7 @@ private: public: // ----------------------------------- BL_Material(); + void Initialize(); int IdMode; unsigned int ras_mode; diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp index 9f11ea11819..70907db608a 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp @@ -43,16 +43,30 @@ BL_BlenderShader *KX_BlenderMaterial::mLastBlenderShader = NULL; //static PyObject *gTextureDict = 0; KX_BlenderMaterial::KX_BlenderMaterial( - KX_Scene *scene, - BL_Material *data, - bool skin, - int lightlayer, PyTypeObject *T ) : PyObjectPlus(T), - RAS_IPolyMaterial( - STR_String( data->texname[0] ), - STR_String( data->matname ), // needed for physics! + RAS_IPolyMaterial(), + mMaterial(NULL), + mShader(0), + mBlenderShader(0), + mScene(NULL), + mUserDefBlend(0), + mModified(0), + mConstructed(false), + mPass(0) +{ +} + +void KX_BlenderMaterial::Initialize( + KX_Scene *scene, + BL_Material *data, + bool skin, + int lightlayer) +{ + RAS_IPolyMaterial::Initialize( + data->texname[0], + data->matname, data->materialindex, data->tile, data->tilexrep[0], @@ -62,17 +76,15 @@ KX_BlenderMaterial::KX_BlenderMaterial( ((data->ras_mode &ALPHA)!=0), ((data->ras_mode &ZSORT)!=0), lightlayer - ), - mMaterial(data), - mShader(0), - mBlenderShader(0), - mScene(scene), - mUserDefBlend(0), - mModified(0), - mConstructed(false), - mPass(0) - -{ + ); + mMaterial = data; + mShader = 0; + mBlenderShader = 0; + mScene = scene; + mUserDefBlend = 0; + mModified = 0; + mConstructed = false; + mPass = 0; // -------------------------------- // RAS_IPolyMaterial variables... m_flag |= RAS_BLENDERMAT; @@ -96,7 +108,6 @@ KX_BlenderMaterial::KX_BlenderMaterial( ); } m_multimode += mMaterial->IdMode+ (mMaterial->ras_mode & ~(COLLIDER|USE_LIGHT)); - } KX_BlenderMaterial::~KX_BlenderMaterial() @@ -107,7 +118,6 @@ KX_BlenderMaterial::~KX_BlenderMaterial() OnExit(); } - MTFace* KX_BlenderMaterial::GetMTFace(void) const { // fonts on polys diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h index eeb919a1bf1..d763ba3ef03 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.h +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h @@ -24,11 +24,13 @@ class KX_BlenderMaterial : public PyObjectPlus, public RAS_IPolyMaterial public: // -------------------------------- KX_BlenderMaterial( + PyTypeObject* T=&Type + ); + void Initialize( class KX_Scene* scene, BL_Material* mat, bool skin, - int lightlayer, - PyTypeObject* T=&Type + int lightlayer ); virtual ~KX_BlenderMaterial(); diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp index a8105c1e4f3..a39ff486689 100644 --- a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp +++ b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp @@ -51,23 +51,36 @@ #include "KX_PyMath.h" -KX_PolygonMaterial::KX_PolygonMaterial(const STR_String &texname, - Material *material, - int materialindex, - int tile, - int tilexrep, - int tileyrep, - int mode, - int transp, - bool alpha, - bool zsort, - int lightlayer, - struct MTFace* tface, - unsigned int* mcol, - PyTypeObject *T) +KX_PolygonMaterial::KX_PolygonMaterial(PyTypeObject *T) : PyObjectPlus(T), - RAS_IPolyMaterial(texname, - STR_String(material?material->id.name:""), + RAS_IPolyMaterial(), + + m_tface(NULL), + m_mcol(NULL), + m_material(NULL), + m_pymaterial(NULL), + m_pass(0) +{ +} + +void KX_PolygonMaterial::Initialize( + const STR_String &texname, + Material* ma, + int materialindex, + int tile, + int tilexrep, + int tileyrep, + int mode, + int transp, + bool alpha, + bool zsort, + int lightlayer, + struct MTFace* tface, + unsigned int* mcol) +{ + RAS_IPolyMaterial::Initialize( + texname, + ma?ma->id.name:"", materialindex, tile, tilexrep, @@ -76,13 +89,12 @@ KX_PolygonMaterial::KX_PolygonMaterial(const STR_String &texname, transp, alpha, zsort, - lightlayer), - m_tface(tface), - m_mcol(mcol), - m_material(material), - m_pymaterial(0), - m_pass(0) -{ + lightlayer); + m_tface = tface; + m_mcol = mcol; + m_material = ma; + m_pymaterial = 0; + m_pass = 0; } KX_PolygonMaterial::~KX_PolygonMaterial() diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.h b/source/gameengine/Ketsji/KX_PolygonMaterial.h index b6f5f373335..89ecb026da9 100644 --- a/source/gameengine/Ketsji/KX_PolygonMaterial.h +++ b/source/gameengine/Ketsji/KX_PolygonMaterial.h @@ -57,8 +57,8 @@ private: mutable int m_pass; public: - - KX_PolygonMaterial(const STR_String &texname, + KX_PolygonMaterial(PyTypeObject *T = &Type); + void Initialize(const STR_String &texname, Material* ma, int materialindex, int tile, @@ -70,8 +70,8 @@ public: bool zsort, int lightlayer, struct MTFace* tface, - unsigned int* mcol, - PyTypeObject *T = &Type); + unsigned int* mcol); + virtual ~KX_PolygonMaterial(); /** diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp index e8f451382b9..c10e4040a92 100644 --- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp +++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp @@ -36,6 +36,61 @@ #include #endif +void RAS_IPolyMaterial::Initialize( + const STR_String& texname, + const STR_String& matname, + int materialindex, + int tile, + int tilexrep, + int tileyrep, + int mode, + int transp, + bool alpha, + bool zsort, + int lightlayer) +{ + m_texturename = texname; + m_materialname = matname; + m_materialindex = materialindex; + m_tile = tile; + m_tilexrep = tilexrep; + m_tileyrep = tileyrep; + m_drawingmode = mode; + m_transp = transp; + m_alpha = alpha; + m_zsort = zsort; + m_lightlayer = lightlayer; + m_polymatid = m_newpolymatid++; + m_flag = 0; + m_multimode = 0; + m_shininess = 35.0; + m_specular.setValue(0.5,0.5,0.5); + m_specularity = 1.0; + m_diffuse.setValue(0.5,0.5,0.5); +} + +RAS_IPolyMaterial::RAS_IPolyMaterial() + : m_texturename("__Dummy_Texture_Name__"), + m_materialname("__Dummy_Material_Name__"), + m_materialindex(0), + m_tile(0), + m_tilexrep(0), + m_tileyrep(0), + m_drawingmode (0), + m_transp(0), + m_alpha(false), + m_zsort(false), + m_lightlayer(0), + m_polymatid(0), + m_flag(0), + m_multimode(0) +{ + m_shininess = 35.0; + m_specular = MT_Vector3(0.5,0.5,0.5); + m_specularity = 1.0; + m_diffuse = MT_Vector3(0.5,0.5,0.5); +} + RAS_IPolyMaterial::RAS_IPolyMaterial(const STR_String& texname, const STR_String& matname, int materialindex, diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h index dcd8b53402e..35652f528b9 100644 --- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h +++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h @@ -100,6 +100,7 @@ public: SHADOW =8192 }; + RAS_IPolyMaterial::RAS_IPolyMaterial(); RAS_IPolyMaterial(const STR_String& texname, const STR_String& matname, int materialindex, @@ -111,6 +112,17 @@ public: bool alpha, bool zsort, int lightlayer); + void Initialize(const STR_String& texname, + const STR_String& matname, + int materialindex, + int tile, + int tilexrep, + int tileyrep, + int mode, + int transp, + bool alpha, + bool zsort, + int lightlayer); virtual ~RAS_IPolyMaterial() {}; /** @@ -151,7 +163,6 @@ public: virtual void GetMaterialRGBAColor(unsigned char *rgba) const; virtual bool UsesLighting(RAS_IRasterizer *rasty) const; virtual bool UsesObjectColor() const; - /* * PreCalculate texture gen */