mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-11 15:21:51 +00:00
- implemented model precaching.
This commit is contained in:
parent
534500f36d
commit
b6af4677f3
5 changed files with 129 additions and 29 deletions
|
@ -34,6 +34,7 @@ public:
|
||||||
virtual int FindFrame(const char * name) = 0;
|
virtual int FindFrame(const char * name) = 0;
|
||||||
virtual void RenderFrame(FTexture * skin, int frame, int frame2, double inter, int translation=0) = 0;
|
virtual void RenderFrame(FTexture * skin, int frame, int frame2, double inter, int translation=0) = 0;
|
||||||
virtual void BuildVertexBuffer() = 0;
|
virtual void BuildVertexBuffer() = 0;
|
||||||
|
virtual void AddSkins(BYTE *hitlist) = 0;
|
||||||
void DestroyVertexBuffer()
|
void DestroyVertexBuffer()
|
||||||
{
|
{
|
||||||
delete mVBuf;
|
delete mVBuf;
|
||||||
|
@ -155,6 +156,8 @@ public:
|
||||||
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);
|
||||||
virtual void LoadGeometry();
|
virtual void LoadGeometry();
|
||||||
|
virtual void AddSkins(BYTE *hitlist);
|
||||||
|
|
||||||
void UnloadGeometry();
|
void UnloadGeometry();
|
||||||
void BuildVertexBuffer();
|
void BuildVertexBuffer();
|
||||||
|
|
||||||
|
@ -260,6 +263,7 @@ public:
|
||||||
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);
|
||||||
void LoadGeometry();
|
void LoadGeometry();
|
||||||
void BuildVertexBuffer();
|
void BuildVertexBuffer();
|
||||||
|
virtual void AddSkins(BYTE *hitlist);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FVoxelVertexHash
|
struct FVoxelVertexHash
|
||||||
|
@ -312,6 +316,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);
|
||||||
|
virtual void AddSkins(BYTE *hitlist);
|
||||||
FTextureID GetPaletteTexture() const { return mPalette; }
|
FTextureID GetPaletteTexture() const { return mPalette; }
|
||||||
void BuildVertexBuffer();
|
void BuildVertexBuffer();
|
||||||
float getAspectFactor();
|
float getAspectFactor();
|
||||||
|
|
|
@ -336,7 +336,22 @@ void FDMDModel::BuildVertexBuffer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// for skin precaching
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
void FDMDModel::AddSkins(BYTE *hitlist)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < info.numSkins; i++)
|
||||||
|
{
|
||||||
|
if (skins[i].isValid())
|
||||||
|
{
|
||||||
|
hitlist[skins[i].GetIndex()] |= FTexture::TEX_Flat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
|
|
|
@ -309,6 +309,27 @@ void FMD3Model::BuildVertexBuffer()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// for skin precaching
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
void FMD3Model::AddSkins(BYTE *hitlist)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < numSurfaces; i++)
|
||||||
|
{
|
||||||
|
MD3Surface * surf = &surfaces[i];
|
||||||
|
for (int j = 0; j < surf->numSkins; j++)
|
||||||
|
{
|
||||||
|
if (surf->skins[j].isValid())
|
||||||
|
{
|
||||||
|
hitlist[surf->skins[j].GetIndex()] |= FTexture::TEX_Flat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
|
|
@ -397,6 +397,17 @@ void FVoxelModel::BuildVertexBuffer()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// for skin precaching
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
void FVoxelModel::AddSkins(BYTE *hitlist)
|
||||||
|
{
|
||||||
|
hitlist[mPalette.GetIndex()] |= FTexture::TEX_Flat;
|
||||||
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
|
|
@ -1019,23 +1019,10 @@ bool FGLInterface::UsesColormap() const
|
||||||
|
|
||||||
void FGLInterface::PrecacheTexture(FTexture *tex, int cache)
|
void FGLInterface::PrecacheTexture(FTexture *tex, int cache)
|
||||||
{
|
{
|
||||||
if (tex != NULL)
|
if (cache & (FTextureManager::HIT_Wall | FTextureManager::HIT_Flat | FTextureManager::HIT_Sky))
|
||||||
{
|
{
|
||||||
if (cache)
|
FMaterial * gltex = FMaterial::ValidateTexture(tex, false);
|
||||||
{
|
if (gltex) gltex->Precache();
|
||||||
if (gl_precache)
|
|
||||||
{
|
|
||||||
if (cache & (FTextureManager::HIT_Wall | FTextureManager::HIT_Flat | FTextureManager::HIT_Sky))
|
|
||||||
{
|
|
||||||
FMaterial * gltex = FMaterial::ValidateTexture(tex, false);
|
|
||||||
if (gltex) gltex->Precache();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (tex->gl_info.Material[0]) tex->gl_info.Material[0]->Clean(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1047,15 +1034,8 @@ void FGLInterface::PrecacheTexture(FTexture *tex, int cache)
|
||||||
|
|
||||||
void FGLInterface::PrecacheSprite(FTexture *tex, SpriteHits &hits)
|
void FGLInterface::PrecacheSprite(FTexture *tex, SpriteHits &hits)
|
||||||
{
|
{
|
||||||
if (hits.CountUsed() == 0)
|
FMaterial * gltex = FMaterial::ValidateTexture(tex, true);
|
||||||
{
|
if (gltex) gltex->PrecacheList(hits);
|
||||||
if (tex->gl_info.Material[1]) tex->gl_info.Material[1]->Clean(true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FMaterial * gltex = FMaterial::ValidateTexture(tex, true);
|
|
||||||
if (gltex) gltex->PrecacheList(hits);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -1070,6 +1050,8 @@ void FGLInterface::Precache(BYTE *texhitlist, TMap<PClassActor*, bool> &actorhit
|
||||||
SpriteHits **spritehitlist = new SpriteHits*[TexMan.NumTextures()];
|
SpriteHits **spritehitlist = new SpriteHits*[TexMan.NumTextures()];
|
||||||
TMap<PClassActor*, bool>::Iterator it(actorhitlist);
|
TMap<PClassActor*, bool>::Iterator it(actorhitlist);
|
||||||
TMap<PClassActor*, bool>::Pair *pair;
|
TMap<PClassActor*, bool>::Pair *pair;
|
||||||
|
BYTE *modellist = new BYTE[Models.Size()];
|
||||||
|
memset(modellist, 0, Models.Size());
|
||||||
memset(spritehitlist, 0, sizeof(SpriteHits**) * TexMan.NumTextures());
|
memset(spritehitlist, 0, sizeof(SpriteHits**) * TexMan.NumTextures());
|
||||||
|
|
||||||
// this isn't done by the main code so it needs to be done here first:
|
// this isn't done by the main code so it needs to be done here first:
|
||||||
|
@ -1095,6 +1077,9 @@ void FGLInterface::Precache(BYTE *texhitlist, TMap<PClassActor*, bool> &actorhit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check all used actors.
|
||||||
|
// 1. mark all sprites associated with its states
|
||||||
|
// 2. mark all model data and skins associated with its states
|
||||||
while (it.NextPair(pair))
|
while (it.NextPair(pair))
|
||||||
{
|
{
|
||||||
PClassActor *cls = pair->Key;
|
PClassActor *cls = pair->Key;
|
||||||
|
@ -1103,11 +1088,29 @@ void FGLInterface::Precache(BYTE *texhitlist, TMap<PClassActor*, bool> &actorhit
|
||||||
for (int i = 0; i < cls->NumOwnedStates; i++)
|
for (int i = 0; i < cls->NumOwnedStates; i++)
|
||||||
{
|
{
|
||||||
spritelist[cls->OwnedStates[i].sprite].Insert(gltrans, true);
|
spritelist[cls->OwnedStates[i].sprite].Insert(gltrans, true);
|
||||||
|
FSpriteModelFrame * smf = gl_FindModelFrame(cls, cls->OwnedStates[i].sprite, cls->OwnedStates[i].Frame, false);
|
||||||
|
if (smf != NULL)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < MAX_MODELS_PER_FRAME; i++)
|
||||||
|
{
|
||||||
|
if (smf->skinIDs[i].isValid())
|
||||||
|
{
|
||||||
|
texhitlist[smf->skinIDs[i].GetIndex()] |= FTexture::TEX_Flat;
|
||||||
|
}
|
||||||
|
else if (smf->modelIDs[i] != -1)
|
||||||
|
{
|
||||||
|
Models[smf->modelIDs[i]]->AddSkins(texhitlist);
|
||||||
|
}
|
||||||
|
if (smf->modelIDs[i] != -1)
|
||||||
|
{
|
||||||
|
modellist[smf->modelIDs[i]] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Precache textures (and sprites).
|
// mark all sprite textures belonging to the marked sprites.
|
||||||
|
|
||||||
for (int i = (int)(sprites.Size() - 1); i >= 0; i--)
|
for (int i = (int)(sprites.Size() - 1); i >= 0; i--)
|
||||||
{
|
{
|
||||||
if (spritelist[i].CountUsed())
|
if (spritelist[i].CountUsed())
|
||||||
|
@ -1129,14 +1132,59 @@ void FGLInterface::Precache(BYTE *texhitlist, TMap<PClassActor*, bool> &actorhit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// delete everything unused before creating any new resources to avoid memory usage peaks.
|
||||||
|
|
||||||
|
// delete unused models
|
||||||
|
for (unsigned i = 0; i < Models.Size(); i++)
|
||||||
|
{
|
||||||
|
if (!modellist[i]) Models[i]->DestroyVertexBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete unused textures
|
||||||
int cnt = TexMan.NumTextures();
|
int cnt = TexMan.NumTextures();
|
||||||
for (int i = cnt - 1; i >= 0; i--)
|
for (int i = cnt - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
PrecacheTexture(TexMan.ByIndex(i), texhitlist[i]);
|
FTexture *tex = TexMan.ByIndex(i);
|
||||||
if (spritehitlist[i] != nullptr) PrecacheSprite(TexMan.ByIndex(i), *spritehitlist[i]);
|
if (tex != nullptr)
|
||||||
|
{
|
||||||
|
if (!texhitlist[i])
|
||||||
|
{
|
||||||
|
if (tex->gl_info.Material[0]) tex->gl_info.Material[0]->Clean(true);
|
||||||
|
}
|
||||||
|
if (spritehitlist[i] == nullptr || (*spritehitlist[i]).CountUsed() == 0)
|
||||||
|
{
|
||||||
|
if (tex->gl_info.Material[1]) tex->gl_info.Material[1]->Clean(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gl_precache)
|
||||||
|
{
|
||||||
|
// cache all used textures
|
||||||
|
for (int i = cnt - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
FTexture *tex = TexMan.ByIndex(i);
|
||||||
|
if (tex != nullptr)
|
||||||
|
{
|
||||||
|
PrecacheTexture(tex, texhitlist[i]);
|
||||||
|
if (spritehitlist[i] != nullptr && (*spritehitlist[i]).CountUsed() > 0)
|
||||||
|
{
|
||||||
|
PrecacheSprite(tex, *spritehitlist[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// cache all used models
|
||||||
|
for (unsigned i = 0; i < Models.Size(); i++)
|
||||||
|
{
|
||||||
|
if (modellist[i])
|
||||||
|
Models[i]->BuildVertexBuffer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
delete[] spritehitlist;
|
delete[] spritehitlist;
|
||||||
delete[] spritelist;
|
delete[] spritelist;
|
||||||
|
delete[] modellist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue