From f7fda94ec9d2e9aa7b49549411062f95c90df7c5 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 3 May 2016 15:45:21 +0200 Subject: [PATCH] - changed model data to store models and textures by index instead of by pointer. The indices are needed for efficient precaching and actual changes to the logic are minor so that this was the best option overall. --- src/gl/models/gl_models.cpp | 87 +++++++++++++++------------------ src/gl/models/gl_models.h | 32 +++++++++--- src/gl/models/gl_models_md2.cpp | 8 +-- src/gl/models/gl_models_md3.cpp | 8 +-- src/gl/models/gl_voxels.cpp | 3 +- 5 files changed, 73 insertions(+), 65 deletions(-) diff --git a/src/gl/models/gl_models.cpp b/src/gl/models/gl_models.cpp index 6b586706a..88c179567 100644 --- a/src/gl/models/gl_models.cpp +++ b/src/gl/models/gl_models.cpp @@ -73,32 +73,17 @@ EXTERN_CVAR(Int, gl_fogmode) extern TDeletingArray Voxels; extern TDeletingArray VoxelDefs; - -class DeletingModelArray : public TArray -{ -public: - -#if 1 - ~DeletingModelArray() - { - for(unsigned i=0;i= 0; i--) { Models[i]->BuildVertexBuffer(); } + */ } void gl_FlushModels() @@ -327,6 +312,9 @@ static void DeleteModelHash() static int FindGFXFile(FString & fn) { + int lump = Wads.CheckNumForFullName(fn); // if we find something that matches the name plus the extension, return it and do not enter the substitution logic below. + if (lump != -1) return lump; + int best = -1; int dot = fn.LastIndexOf('.'); int slash = fn.LastIndexOf('/'); @@ -349,7 +337,7 @@ static int FindGFXFile(FString & fn) // //=========================================================================== -FTexture * LoadSkin(const char * path, const char * fn) +FTextureID LoadSkin(const char * path, const char * fn) { FString buffer; @@ -358,11 +346,11 @@ FTexture * LoadSkin(const char * path, const char * fn) int texlump = FindGFXFile(buffer); if (texlump>=0) { - return TexMan.FindTexture(Wads.GetLumpFullName(texlump), FTexture::TEX_Any, FTextureManager::TEXMAN_TryAny); + return TexMan.CheckForTexture(Wads.GetLumpFullName(texlump), FTexture::TEX_Any, FTextureManager::TEXMAN_TryAny); } else { - return nullptr; + return FNullTextureID(); } } @@ -393,7 +381,7 @@ static int ModelFrameHash(FSpriteModelFrame * smf) // //=========================================================================== -static FModel * FindModel(const char * path, const char * modelfile) +static unsigned FindModel(const char * path, const char * modelfile) { FModel * model = nullptr; FString fullname; @@ -404,12 +392,12 @@ static FModel * FindModel(const char * path, const char * modelfile) if (lump<0) { Printf("FindModel: '%s' not found\n", fullname.GetChars()); - return nullptr; + return -1; } - for(int i = 0; i< (int)Models.Size(); i++) + for(unsigned i = 0; i< Models.Size(); i++) { - if (!Models[i]->mFileName.CompareNoCase(fullname)) return Models[i]; + if (!Models[i]->mFileName.CompareNoCase(fullname)) return i; } int len = Wads.LumpLength(lump); @@ -434,7 +422,7 @@ static FModel * FindModel(const char * path, const char * modelfile) if (!model->Load(path, lump, buffer, len)) { delete model; - return nullptr; + return -1; } } else @@ -448,13 +436,12 @@ static FModel * FindModel(const char * path, const char * modelfile) else { Printf("LoadModel: Unknown model format in '%s'\n", fullname.GetChars()); - return nullptr; + return -1; } } // The vertex buffer cannot be initialized here because this gets called before OpenGL is initialized model->mFileName = fullname; - Models.Push(model); - return model; + return Models.Push(model); } //=========================================================================== @@ -493,8 +480,9 @@ void gl_InitModels() { FVoxelModel *md = (FVoxelModel*)Models[VoxelDefs[i]->Voxel->VoxelIndex]; memset(&smf, 0, sizeof(smf)); - smf.models[0] = md; - smf.skins[0] = md->GetPaletteTexture(); + smf.modelIDs[1] = smf.modelIDs[2] = smf.modelIDs[3] = -1; + smf.modelIDs[0] = VoxelDefs[i]->Voxel->VoxelIndex; + smf.skinIDs[0] = md->GetPaletteTexture(); smf.xscale = smf.yscale = smf.zscale = VoxelDefs[i]->Scale; smf.angleoffset = VoxelDefs[i]->AngleOffset.Degrees; if (VoxelDefs[i]->PlacedSpin != 0) @@ -523,6 +511,7 @@ void gl_InitModels() } memset(&smf, 0, sizeof(smf)); + smf.modelIDs[0] = smf.modelIDs[1] = smf.modelIDs[2] = smf.modelIDs[3] = -1; while ((Lump = Wads.FindLump("MODELDEF", &lastLump)) != -1) { FScanner sc(Lump); @@ -532,6 +521,7 @@ void gl_InitModels() { sc.MustGetString(); memset(&smf, 0, sizeof(smf)); + smf.modelIDs[1] = smf.modelIDs[2] = smf.modelIDs[3] = -1; smf.xscale=smf.yscale=smf.zscale=1.f; smf.type = PClass::FindClass(sc.String); @@ -554,15 +544,15 @@ void gl_InitModels() else if (sc.Compare("model")) { sc.MustGetNumber(); - index=sc.Number; - if (index<0 || index>=MAX_MODELS_PER_FRAME) + index = sc.Number; + if (index < 0 || index >= MAX_MODELS_PER_FRAME) { sc.ScriptError("Too many models in %s", smf.type->TypeName.GetChars()); } sc.MustGetString(); FixPathSeperator(sc.String); - smf.models[index] = FindModel(path.GetChars(), sc.String); - if (!smf.models[index]) + smf.modelIDs[index] = FindModel(path.GetChars(), sc.String); + if (smf.modelIDs[index] == -1) { Printf("%s: model not found in %s\n", sc.String, path.GetChars()); } @@ -570,11 +560,11 @@ void gl_InitModels() else if (sc.Compare("scale")) { sc.MustGetFloat(); - smf.xscale=sc.Float; + smf.xscale = sc.Float; sc.MustGetFloat(); - smf.yscale=sc.Float; + smf.yscale = sc.Float; sc.MustGetFloat(); - smf.zscale=sc.Float; + smf.zscale = sc.Float; } // [BB] Added zoffset reading. // Now it must be considered deprecated. @@ -680,12 +670,12 @@ void gl_InitModels() FixPathSeperator(sc.String); if (sc.Compare("")) { - smf.skins[index]=nullptr; + smf.skinIDs[index]=FNullTextureID(); } else { - smf.skins[index]=LoadSkin(path.GetChars(), sc.String); - if (smf.skins[index] == nullptr) + smf.skinIDs[index] = LoadSkin(path.GetChars(), sc.String); + if (!smf.skinIDs[index].isValid()) { Printf("Skin '%s' not found in '%s'\n", sc.String, smf.type->TypeName.GetChars()); @@ -727,9 +717,10 @@ void gl_InitModels() if (isframe) { sc.MustGetString(); - if (smf.models[index]!=nullptr) + if (smf.modelIDs[index] != -1) { - smf.modelframes[index] = smf.models[index]->FindFrame(sc.String); + FModel *model = Models[smf.modelIDs[index]]; + smf.modelframes[index] = model->FindFrame(sc.String); if (smf.modelframes[index]==-1) sc.ScriptError("Unknown frame '%s' in %s", sc.String, smf.type->TypeName.GetChars()); } else smf.modelframes[index] = -1; @@ -888,17 +879,17 @@ void gl_RenderFrameModels( const FSpriteModelFrame *smf, for(int i=0; imodels[i]; - - if (mdl!=nullptr) + if (smf->modelIDs[i] != -1) { + FModel * mdl = Models[smf->modelIDs[i]]; + FTexture *tex = smf->skinIDs[i].isValid()? TexMan(smf->skinIDs[i]) : nullptr; mdl->BuildVertexBuffer(); gl_RenderState.SetVertexBuffer(mdl->mVBuf); if ( smfNext && smf->modelframes[i] != smfNext->modelframes[i] ) - mdl->RenderFrame(smf->skins[i], smf->modelframes[i], smfNext->modelframes[i], inter, translation); + mdl->RenderFrame(tex, smf->modelframes[i], smfNext->modelframes[i], inter, translation); else - mdl->RenderFrame(smf->skins[i], smf->modelframes[i], smf->modelframes[i], 0.f, translation); + mdl->RenderFrame(tex, smf->modelframes[i], smf->modelframes[i], 0.f, translation); gl_RenderState.SetVertexBuffer(GLRenderer->mVBO); } @@ -998,7 +989,7 @@ void gl_RenderModel(GLSprite * spr) gl_RenderState.mModelMatrix.rotate(-smf->rolloffset, 1, 0, 0); // consider the pixel stretching. For non-voxels this must be factored out here - float stretch = (smf->models[0] != nullptr ? smf->models[0]->getAspectFactor() : 1.f) / glset.pixelstretch; + float stretch = (smf->modelIDs[0] != -1 ? Models[smf->modelIDs[0]]->getAspectFactor() : 1.f) / glset.pixelstretch; gl_RenderState.mModelMatrix.scale(1, stretch, 1); diff --git a/src/gl/models/gl_models.h b/src/gl/models/gl_models.h index a99f81322..70379a3d2 100644 --- a/src/gl/models/gl_models.h +++ b/src/gl/models/gl_models.h @@ -1,6 +1,7 @@ #ifndef __GL_MODELS_H_ #define __GL_MODELS_H_ +#include "tarray.h" #include "gl/utility/gl_geometric.h" #include "gl/data/gl_vertexbuffer.h" #include "p_pspr.h" @@ -16,7 +17,7 @@ enum { VX, VZ, VY }; #define MD3_MAGIC 0x33504449 #define NUMVERTEXNORMALS 162 -FTexture * LoadSkin(const char * path, const char * fn); +FTextureID LoadSkin(const char * path, const char * fn); class FModel @@ -124,7 +125,7 @@ protected: int mLumpNum; DMDHeader header; DMDInfo info; - FTexture ** skins; + FTextureID * skins; ModelFrame * frames; bool allowTexComp; // Allow texture compression with this. @@ -201,7 +202,7 @@ class FMD3Model : public FModel int numTriangles; int numSkins; - FTexture ** skins; + FTextureID * skins; MD3Triangle * tris; MD3TexCoord * texcoords; MD3Vertex * vertices; @@ -295,7 +296,7 @@ class FVoxelModel : public FModel protected: FVoxel *mVoxel; bool mOwningVoxel; // if created through MODELDEF deleting this object must also delete the voxel object - FTexture *mPalette; + FTextureID mPalette; unsigned int mNumIndices; TArray mVertices; TArray mIndices; @@ -311,7 +312,7 @@ public: void Initialize(); virtual int FindFrame(const char * name); virtual void RenderFrame(FTexture * skin, int frame, int frame2, double inter, int translation=0); - FTexture *GetPaletteTexture() const { return mPalette; } + FTextureID GetPaletteTexture() const { return mPalette; } void BuildVertexBuffer(); float getAspectFactor(); }; @@ -338,8 +339,8 @@ enum struct FSpriteModelFrame { - FModel * models[MAX_MODELS_PER_FRAME]; - FTexture * skins[MAX_MODELS_PER_FRAME]; + int modelIDs[MAX_MODELS_PER_FRAME]; + FTextureID skinIDs[MAX_MODELS_PER_FRAME]; int modelframes[MAX_MODELS_PER_FRAME]; float xscale, yscale, zscale; // [BB] Added zoffset, rotation parameters and flags. @@ -368,4 +369,21 @@ void gl_RenderModel(GLSprite * spr); void gl_RenderHUDModel(pspdef_t *psp, float ofsx, float ofsy); bool gl_IsHUDModelForPlayerAvailable (player_t * player); + +class DeletingModelArray : public TArray +{ +public: + + ~DeletingModelArray() + { + for (unsigned i = 0; iOfs_Shaders)); - s->skins = new FTexture *[s->numSkins]; + s->skins = new FTextureID[s->numSkins]; for (int i = 0; i < s->numSkins; i++) { // [BB] According to the MD3 spec, Name is supposed to include the full path. s->skins[i] = LoadSkin("", shader[i].Name); // [BB] Fall back and check if Name is relative. - if (s->skins[i] == nullptr) + if (!s->skins[i].isValid()) s->skins[i] = LoadSkin(path, shader[i].Name); } } @@ -344,8 +344,8 @@ void FMD3Model::RenderFrame(FTexture * skin, int frameno, int frameno2, double i FTexture *surfaceSkin = skin; if (!surfaceSkin) { - if (surf->numSkins==0) return; - surfaceSkin = surf->skins[0]; + if (surf->numSkins==0 || !surf->skins[0].isValid()) return; + surfaceSkin = TexMan(surf->skins[0]); if (!surfaceSkin) return; } diff --git a/src/gl/models/gl_voxels.cpp b/src/gl/models/gl_voxels.cpp index 2fdb8e162..babb62d10 100644 --- a/src/gl/models/gl_voxels.cpp +++ b/src/gl/models/gl_voxels.cpp @@ -213,7 +213,7 @@ FVoxelModel::FVoxelModel(FVoxel *voxel, bool owned) { mVoxel = voxel; mOwningVoxel = owned; - mPalette = new FVoxelTexture(voxel); + mPalette = TexMan.AddTexture(new FVoxelTexture(voxel)); } //=========================================================================== @@ -224,7 +224,6 @@ FVoxelModel::FVoxelModel(FVoxel *voxel, bool owned) FVoxelModel::~FVoxelModel() { - delete mPalette; if (mOwningVoxel) delete mVoxel; }