- 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.
This commit is contained in:
Christoph Oelckers 2016-05-03 15:45:21 +02:00
parent 0e14f00b51
commit f7fda94ec9
5 changed files with 73 additions and 65 deletions

View file

@ -73,32 +73,17 @@ EXTERN_CVAR(Int, gl_fogmode)
extern TDeletingArray<FVoxel *> Voxels; extern TDeletingArray<FVoxel *> Voxels;
extern TDeletingArray<FVoxelDef *> VoxelDefs; extern TDeletingArray<FVoxelDef *> VoxelDefs;
class DeletingModelArray : public TArray<FModel *>
{
public:
#if 1
~DeletingModelArray()
{
for(unsigned i=0;i<Size();i++)
{
delete (*this)[i];
}
}
#endif
};
DeletingModelArray Models; DeletingModelArray Models;
void gl_LoadModels() void gl_LoadModels()
{ {
/*
for (int i = Models.Size() - 1; i >= 0; i--) for (int i = Models.Size() - 1; i >= 0; i--)
{ {
Models[i]->BuildVertexBuffer(); Models[i]->BuildVertexBuffer();
} }
*/
} }
void gl_FlushModels() void gl_FlushModels()
@ -327,6 +312,9 @@ static void DeleteModelHash()
static int FindGFXFile(FString & fn) 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 best = -1;
int dot = fn.LastIndexOf('.'); int dot = fn.LastIndexOf('.');
int slash = 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; FString buffer;
@ -358,11 +346,11 @@ FTexture * LoadSkin(const char * path, const char * fn)
int texlump = FindGFXFile(buffer); int texlump = FindGFXFile(buffer);
if (texlump>=0) 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 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; FModel * model = nullptr;
FString fullname; FString fullname;
@ -404,12 +392,12 @@ static FModel * FindModel(const char * path, const char * modelfile)
if (lump<0) if (lump<0)
{ {
Printf("FindModel: '%s' not found\n", fullname.GetChars()); 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); 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)) if (!model->Load(path, lump, buffer, len))
{ {
delete model; delete model;
return nullptr; return -1;
} }
} }
else else
@ -448,13 +436,12 @@ static FModel * FindModel(const char * path, const char * modelfile)
else else
{ {
Printf("LoadModel: Unknown model format in '%s'\n", fullname.GetChars()); 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 // The vertex buffer cannot be initialized here because this gets called before OpenGL is initialized
model->mFileName = fullname; model->mFileName = fullname;
Models.Push(model); return Models.Push(model);
return model;
} }
//=========================================================================== //===========================================================================
@ -493,8 +480,9 @@ void gl_InitModels()
{ {
FVoxelModel *md = (FVoxelModel*)Models[VoxelDefs[i]->Voxel->VoxelIndex]; FVoxelModel *md = (FVoxelModel*)Models[VoxelDefs[i]->Voxel->VoxelIndex];
memset(&smf, 0, sizeof(smf)); memset(&smf, 0, sizeof(smf));
smf.models[0] = md; smf.modelIDs[1] = smf.modelIDs[2] = smf.modelIDs[3] = -1;
smf.skins[0] = md->GetPaletteTexture(); smf.modelIDs[0] = VoxelDefs[i]->Voxel->VoxelIndex;
smf.skinIDs[0] = md->GetPaletteTexture();
smf.xscale = smf.yscale = smf.zscale = VoxelDefs[i]->Scale; smf.xscale = smf.yscale = smf.zscale = VoxelDefs[i]->Scale;
smf.angleoffset = VoxelDefs[i]->AngleOffset.Degrees; smf.angleoffset = VoxelDefs[i]->AngleOffset.Degrees;
if (VoxelDefs[i]->PlacedSpin != 0) if (VoxelDefs[i]->PlacedSpin != 0)
@ -523,6 +511,7 @@ void gl_InitModels()
} }
memset(&smf, 0, sizeof(smf)); 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) while ((Lump = Wads.FindLump("MODELDEF", &lastLump)) != -1)
{ {
FScanner sc(Lump); FScanner sc(Lump);
@ -532,6 +521,7 @@ void gl_InitModels()
{ {
sc.MustGetString(); sc.MustGetString();
memset(&smf, 0, sizeof(smf)); memset(&smf, 0, sizeof(smf));
smf.modelIDs[1] = smf.modelIDs[2] = smf.modelIDs[3] = -1;
smf.xscale=smf.yscale=smf.zscale=1.f; smf.xscale=smf.yscale=smf.zscale=1.f;
smf.type = PClass::FindClass(sc.String); smf.type = PClass::FindClass(sc.String);
@ -554,15 +544,15 @@ void gl_InitModels()
else if (sc.Compare("model")) else if (sc.Compare("model"))
{ {
sc.MustGetNumber(); sc.MustGetNumber();
index=sc.Number; index = sc.Number;
if (index<0 || index>=MAX_MODELS_PER_FRAME) if (index < 0 || index >= MAX_MODELS_PER_FRAME)
{ {
sc.ScriptError("Too many models in %s", smf.type->TypeName.GetChars()); sc.ScriptError("Too many models in %s", smf.type->TypeName.GetChars());
} }
sc.MustGetString(); sc.MustGetString();
FixPathSeperator(sc.String); FixPathSeperator(sc.String);
smf.models[index] = FindModel(path.GetChars(), sc.String); smf.modelIDs[index] = FindModel(path.GetChars(), sc.String);
if (!smf.models[index]) if (smf.modelIDs[index] == -1)
{ {
Printf("%s: model not found in %s\n", sc.String, path.GetChars()); Printf("%s: model not found in %s\n", sc.String, path.GetChars());
} }
@ -570,11 +560,11 @@ void gl_InitModels()
else if (sc.Compare("scale")) else if (sc.Compare("scale"))
{ {
sc.MustGetFloat(); sc.MustGetFloat();
smf.xscale=sc.Float; smf.xscale = sc.Float;
sc.MustGetFloat(); sc.MustGetFloat();
smf.yscale=sc.Float; smf.yscale = sc.Float;
sc.MustGetFloat(); sc.MustGetFloat();
smf.zscale=sc.Float; smf.zscale = sc.Float;
} }
// [BB] Added zoffset reading. // [BB] Added zoffset reading.
// Now it must be considered deprecated. // Now it must be considered deprecated.
@ -680,12 +670,12 @@ void gl_InitModels()
FixPathSeperator(sc.String); FixPathSeperator(sc.String);
if (sc.Compare("")) if (sc.Compare(""))
{ {
smf.skins[index]=nullptr; smf.skinIDs[index]=FNullTextureID();
} }
else else
{ {
smf.skins[index]=LoadSkin(path.GetChars(), sc.String); smf.skinIDs[index] = LoadSkin(path.GetChars(), sc.String);
if (smf.skins[index] == nullptr) if (!smf.skinIDs[index].isValid())
{ {
Printf("Skin '%s' not found in '%s'\n", Printf("Skin '%s' not found in '%s'\n",
sc.String, smf.type->TypeName.GetChars()); sc.String, smf.type->TypeName.GetChars());
@ -727,9 +717,10 @@ void gl_InitModels()
if (isframe) if (isframe)
{ {
sc.MustGetString(); 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()); if (smf.modelframes[index]==-1) sc.ScriptError("Unknown frame '%s' in %s", sc.String, smf.type->TypeName.GetChars());
} }
else smf.modelframes[index] = -1; else smf.modelframes[index] = -1;
@ -888,17 +879,17 @@ void gl_RenderFrameModels( const FSpriteModelFrame *smf,
for(int i=0; i<MAX_MODELS_PER_FRAME; i++) for(int i=0; i<MAX_MODELS_PER_FRAME; i++)
{ {
FModel * mdl = smf->models[i]; if (smf->modelIDs[i] != -1)
if (mdl!=nullptr)
{ {
FModel * mdl = Models[smf->modelIDs[i]];
FTexture *tex = smf->skinIDs[i].isValid()? TexMan(smf->skinIDs[i]) : nullptr;
mdl->BuildVertexBuffer(); mdl->BuildVertexBuffer();
gl_RenderState.SetVertexBuffer(mdl->mVBuf); gl_RenderState.SetVertexBuffer(mdl->mVBuf);
if ( smfNext && smf->modelframes[i] != smfNext->modelframes[i] ) 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 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); gl_RenderState.SetVertexBuffer(GLRenderer->mVBO);
} }
@ -998,7 +989,7 @@ void gl_RenderModel(GLSprite * spr)
gl_RenderState.mModelMatrix.rotate(-smf->rolloffset, 1, 0, 0); gl_RenderState.mModelMatrix.rotate(-smf->rolloffset, 1, 0, 0);
// consider the pixel stretching. For non-voxels this must be factored out here // 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); gl_RenderState.mModelMatrix.scale(1, stretch, 1);

View file

@ -1,6 +1,7 @@
#ifndef __GL_MODELS_H_ #ifndef __GL_MODELS_H_
#define __GL_MODELS_H_ #define __GL_MODELS_H_
#include "tarray.h"
#include "gl/utility/gl_geometric.h" #include "gl/utility/gl_geometric.h"
#include "gl/data/gl_vertexbuffer.h" #include "gl/data/gl_vertexbuffer.h"
#include "p_pspr.h" #include "p_pspr.h"
@ -16,7 +17,7 @@ enum { VX, VZ, VY };
#define MD3_MAGIC 0x33504449 #define MD3_MAGIC 0x33504449
#define NUMVERTEXNORMALS 162 #define NUMVERTEXNORMALS 162
FTexture * LoadSkin(const char * path, const char * fn); FTextureID LoadSkin(const char * path, const char * fn);
class FModel class FModel
@ -124,7 +125,7 @@ protected:
int mLumpNum; int mLumpNum;
DMDHeader header; DMDHeader header;
DMDInfo info; DMDInfo info;
FTexture ** skins; FTextureID * skins;
ModelFrame * frames; ModelFrame * frames;
bool allowTexComp; // Allow texture compression with this. bool allowTexComp; // Allow texture compression with this.
@ -201,7 +202,7 @@ class FMD3Model : public FModel
int numTriangles; int numTriangles;
int numSkins; int numSkins;
FTexture ** skins; FTextureID * skins;
MD3Triangle * tris; MD3Triangle * tris;
MD3TexCoord * texcoords; MD3TexCoord * texcoords;
MD3Vertex * vertices; MD3Vertex * vertices;
@ -295,7 +296,7 @@ class FVoxelModel : public FModel
protected: protected:
FVoxel *mVoxel; FVoxel *mVoxel;
bool mOwningVoxel; // if created through MODELDEF deleting this object must also delete the voxel object bool mOwningVoxel; // if created through MODELDEF deleting this object must also delete the voxel object
FTexture *mPalette; FTextureID mPalette;
unsigned int mNumIndices; unsigned int mNumIndices;
TArray<FModelVertex> mVertices; TArray<FModelVertex> mVertices;
TArray<unsigned int> mIndices; TArray<unsigned int> mIndices;
@ -311,7 +312,7 @@ public:
void Initialize(); void Initialize();
virtual int FindFrame(const char * name); virtual int FindFrame(const char * name);
virtual void RenderFrame(FTexture * skin, int frame, int frame2, double inter, int translation=0); 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(); void BuildVertexBuffer();
float getAspectFactor(); float getAspectFactor();
}; };
@ -338,8 +339,8 @@ enum
struct FSpriteModelFrame struct FSpriteModelFrame
{ {
FModel * models[MAX_MODELS_PER_FRAME]; int modelIDs[MAX_MODELS_PER_FRAME];
FTexture * skins[MAX_MODELS_PER_FRAME]; FTextureID skinIDs[MAX_MODELS_PER_FRAME];
int modelframes[MAX_MODELS_PER_FRAME]; int modelframes[MAX_MODELS_PER_FRAME];
float xscale, yscale, zscale; float xscale, yscale, zscale;
// [BB] Added zoffset, rotation parameters and flags. // [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); void gl_RenderHUDModel(pspdef_t *psp, float ofsx, float ofsy);
bool gl_IsHUDModelForPlayerAvailable (player_t * player); bool gl_IsHUDModelForPlayerAvailable (player_t * player);
class DeletingModelArray : public TArray<FModel *>
{
public:
~DeletingModelArray()
{
for (unsigned i = 0; i<Size(); i++)
{
delete (*this)[i];
}
}
};
extern DeletingModelArray Models;
#endif #endif

View file

@ -159,7 +159,7 @@ bool FDMDModel::Load(const char * path, int lumpnum, const char * buffer, int le
} }
// Allocate and load in the data. // Allocate and load in the data.
skins = new FTexture *[info.numSkins]; skins = new FTextureID[info.numSkins];
for (i = 0; i < info.numSkins; i++) for (i = 0; i < info.numSkins; i++)
{ {
@ -364,8 +364,8 @@ void FDMDModel::RenderFrame(FTexture * skin, int frameno, int frameno2, double i
if (!skin) if (!skin)
{ {
if (info.numSkins == 0) return; if (info.numSkins == 0 || !skins[0].isValid()) return;
skin = skins[0]; skin = TexMan(skins[0]);
if (!skin) return; if (!skin) return;
} }
@ -469,7 +469,7 @@ bool FMD2Model::Load(const char * path, int lumpnum, const char * buffer, int le
return false; return false;
} }
skins = new FTexture *[info.numSkins]; skins = new FTextureID[info.numSkins];
for (i = 0; i < info.numSkins; i++) for (i = 0; i < info.numSkins; i++)
{ {

View file

@ -179,14 +179,14 @@ bool FMD3Model::Load(const char * path, int lumpnum, const char * buffer, int le
// copy shaders (skins) // copy shaders (skins)
md3_shader_t * shader = (md3_shader_t*)(((char*)ss) + LittleLong(ss->Ofs_Shaders)); md3_shader_t * shader = (md3_shader_t*)(((char*)ss) + LittleLong(ss->Ofs_Shaders));
s->skins = new FTexture *[s->numSkins]; s->skins = new FTextureID[s->numSkins];
for (int i = 0; i < s->numSkins; i++) for (int i = 0; i < s->numSkins; i++)
{ {
// [BB] According to the MD3 spec, Name is supposed to include the full path. // [BB] According to the MD3 spec, Name is supposed to include the full path.
s->skins[i] = LoadSkin("", shader[i].Name); s->skins[i] = LoadSkin("", shader[i].Name);
// [BB] Fall back and check if Name is relative. // [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); 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; FTexture *surfaceSkin = skin;
if (!surfaceSkin) if (!surfaceSkin)
{ {
if (surf->numSkins==0) return; if (surf->numSkins==0 || !surf->skins[0].isValid()) return;
surfaceSkin = surf->skins[0]; surfaceSkin = TexMan(surf->skins[0]);
if (!surfaceSkin) return; if (!surfaceSkin) return;
} }

View file

@ -213,7 +213,7 @@ FVoxelModel::FVoxelModel(FVoxel *voxel, bool owned)
{ {
mVoxel = voxel; mVoxel = voxel;
mOwningVoxel = owned; mOwningVoxel = owned;
mPalette = new FVoxelTexture(voxel); mPalette = TexMan.AddTexture(new FVoxelTexture(voxel));
} }
//=========================================================================== //===========================================================================
@ -224,7 +224,6 @@ FVoxelModel::FVoxelModel(FVoxel *voxel, bool owned)
FVoxelModel::~FVoxelModel() FVoxelModel::~FVoxelModel()
{ {
delete mPalette;
if (mOwningVoxel) delete mVoxel; if (mOwningVoxel) delete mVoxel;
} }