mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2024-11-24 22:55:40 +00:00
This update fixes (hopefully) the last of the texture upload lags that were affecting some games, in particular Daytona 2 and Spikeout.
To achieve this UploadTextures no longer clears the model cache when called. Instead the cache is kept in-tact (which should help improve cache hits) and all textures referenced by models being rendered are (re-)decoded with every frame. To help with tracking all the unique texture references contained in a model a new class TextureRefs has been added.
This commit is contained in:
parent
aba801ebb4
commit
3b41239cfb
|
@ -90,7 +90,7 @@ endif
|
||||||
HEADERS = Src/Supermodel.h Src/Games.h Src/OSD/SDL/Types.h
|
HEADERS = Src/Supermodel.h Src/Games.h Src/OSD/SDL/Types.h
|
||||||
OBJ = $(OBJ_DIR)/PPCDisasm.o $(OBJ_DIR)/Games.o $(OBJ_DIR)/Config.o $(OBJ_DIR)/INIFile.o $(OBJ_DIR)/BlockFile.o $(OBJ_DIR)/93C46.o \
|
OBJ = $(OBJ_DIR)/PPCDisasm.o $(OBJ_DIR)/Games.o $(OBJ_DIR)/Config.o $(OBJ_DIR)/INIFile.o $(OBJ_DIR)/BlockFile.o $(OBJ_DIR)/93C46.o \
|
||||||
$(OBJ_DIR)/ROMLoad.o $(OBJ_DIR)/unzip.o $(OBJ_DIR)/ioapi.o $(OBJ_DIR)/Error.o $(OBJ_DIR)/glew.o $(OBJ_DIR)/Shader.o \
|
$(OBJ_DIR)/ROMLoad.o $(OBJ_DIR)/unzip.o $(OBJ_DIR)/ioapi.o $(OBJ_DIR)/Error.o $(OBJ_DIR)/glew.o $(OBJ_DIR)/Shader.o \
|
||||||
$(OBJ_DIR)/Real3D.o $(OBJ_DIR)/Render3D.o $(OBJ_DIR)/Models.o $(OBJ_DIR)/Render2D.o $(OBJ_DIR)/TileGen.o \
|
$(OBJ_DIR)/Real3D.o $(OBJ_DIR)/Render3D.o $(OBJ_DIR)/Models.o $(OBJ_DIR)/TextureRefs.o $(OBJ_DIR)/Render2D.o $(OBJ_DIR)/TileGen.o \
|
||||||
$(OBJ_DIR)/Model3.o $(OBJ_DIR)/ppc.o $(OBJ_DIR)/Main.o $(OBJ_DIR)/Audio.o $(OBJ_DIR)/Thread.o $(OBJ_DIR)/SoundBoard.o \
|
$(OBJ_DIR)/Model3.o $(OBJ_DIR)/ppc.o $(OBJ_DIR)/Main.o $(OBJ_DIR)/Audio.o $(OBJ_DIR)/Thread.o $(OBJ_DIR)/SoundBoard.o \
|
||||||
$(OBJ_DIR)/SCSP.o $(OBJ_DIR)/SCSPDSP.o $(OBJ_DIR)/68K.o $(OBJ_DIR)/m68kcpu.o $(OBJ_DIR)/m68kopnz.o $(OBJ_DIR)/m68kopdm.o \
|
$(OBJ_DIR)/SCSP.o $(OBJ_DIR)/SCSPDSP.o $(OBJ_DIR)/68K.o $(OBJ_DIR)/m68kcpu.o $(OBJ_DIR)/m68kopnz.o $(OBJ_DIR)/m68kopdm.o \
|
||||||
$(OBJ_DIR)/m68kopac.o $(OBJ_DIR)/m68kops.o $(OBJ_DIR)/DSB.o $(OBJ_DIR)/Z80.o \
|
$(OBJ_DIR)/m68kopac.o $(OBJ_DIR)/m68kops.o $(OBJ_DIR)/DSB.o $(OBJ_DIR)/Z80.o \
|
||||||
|
|
|
@ -92,7 +92,7 @@ endif
|
||||||
HEADERS = Src/Supermodel.h Src/Games.h Src/OSD/SDL/Types.h
|
HEADERS = Src/Supermodel.h Src/Games.h Src/OSD/SDL/Types.h
|
||||||
OBJ = $(OBJ_DIR)/PPCDisasm.o $(OBJ_DIR)/Games.o $(OBJ_DIR)/Config.o $(OBJ_DIR)/INIFile.o $(OBJ_DIR)/BlockFile.o $(OBJ_DIR)/93C46.o \
|
OBJ = $(OBJ_DIR)/PPCDisasm.o $(OBJ_DIR)/Games.o $(OBJ_DIR)/Config.o $(OBJ_DIR)/INIFile.o $(OBJ_DIR)/BlockFile.o $(OBJ_DIR)/93C46.o \
|
||||||
$(OBJ_DIR)/ROMLoad.o $(OBJ_DIR)/unzip.o $(OBJ_DIR)/ioapi.o $(OBJ_DIR)/Error.o $(OBJ_DIR)/glew.o $(OBJ_DIR)/Shader.o \
|
$(OBJ_DIR)/ROMLoad.o $(OBJ_DIR)/unzip.o $(OBJ_DIR)/ioapi.o $(OBJ_DIR)/Error.o $(OBJ_DIR)/glew.o $(OBJ_DIR)/Shader.o \
|
||||||
$(OBJ_DIR)/Real3D.o $(OBJ_DIR)/Render3D.o $(OBJ_DIR)/Models.o $(OBJ_DIR)/Render2D.o $(OBJ_DIR)/TileGen.o \
|
$(OBJ_DIR)/Real3D.o $(OBJ_DIR)/Render3D.o $(OBJ_DIR)/Models.o $(OBJ_DIR)/TextureRefs.o $(OBJ_DIR)/Render2D.o $(OBJ_DIR)/TileGen.o \
|
||||||
$(OBJ_DIR)/Model3.o $(OBJ_DIR)/ppc.o $(OBJ_DIR)/Main.o $(OBJ_DIR)/Audio.o $(OBJ_DIR)/Thread.o $(OBJ_DIR)/SoundBoard.o \
|
$(OBJ_DIR)/Model3.o $(OBJ_DIR)/ppc.o $(OBJ_DIR)/Main.o $(OBJ_DIR)/Audio.o $(OBJ_DIR)/Thread.o $(OBJ_DIR)/SoundBoard.o \
|
||||||
$(OBJ_DIR)/SCSP.o $(OBJ_DIR)/SCSPDSP.o $(OBJ_DIR)/68K.o $(OBJ_DIR)/m68kcpu.o $(OBJ_DIR)/m68kopnz.o $(OBJ_DIR)/m68kopdm.o \
|
$(OBJ_DIR)/SCSP.o $(OBJ_DIR)/SCSPDSP.o $(OBJ_DIR)/68K.o $(OBJ_DIR)/m68kcpu.o $(OBJ_DIR)/m68kopnz.o $(OBJ_DIR)/m68kopdm.o \
|
||||||
$(OBJ_DIR)/m68kopac.o $(OBJ_DIR)/m68kops.o $(OBJ_DIR)/DSB.o $(OBJ_DIR)/Z80.o \
|
$(OBJ_DIR)/m68kopac.o $(OBJ_DIR)/m68kops.o $(OBJ_DIR)/DSB.o $(OBJ_DIR)/Z80.o \
|
||||||
|
|
|
@ -115,7 +115,7 @@ endif
|
||||||
#
|
#
|
||||||
OBJ = $(OBJ_DIR)/PPCDisasm.o $(OBJ_DIR)/Games.o $(OBJ_DIR)/Config.o $(OBJ_DIR)/INIFile.o $(OBJ_DIR)/BlockFile.o $(OBJ_DIR)/93C46.o \
|
OBJ = $(OBJ_DIR)/PPCDisasm.o $(OBJ_DIR)/Games.o $(OBJ_DIR)/Config.o $(OBJ_DIR)/INIFile.o $(OBJ_DIR)/BlockFile.o $(OBJ_DIR)/93C46.o \
|
||||||
$(OBJ_DIR)/ROMLoad.o $(OBJ_DIR)/unzip.o $(OBJ_DIR)/ioapi.o $(OBJ_DIR)/Error.o $(OBJ_DIR)/glew.o $(OBJ_DIR)/Shader.o \
|
$(OBJ_DIR)/ROMLoad.o $(OBJ_DIR)/unzip.o $(OBJ_DIR)/ioapi.o $(OBJ_DIR)/Error.o $(OBJ_DIR)/glew.o $(OBJ_DIR)/Shader.o \
|
||||||
$(OBJ_DIR)/Real3D.o $(OBJ_DIR)/Render3D.o $(OBJ_DIR)/Models.o $(OBJ_DIR)/Render2D.o $(OBJ_DIR)/TileGen.o \
|
$(OBJ_DIR)/Real3D.o $(OBJ_DIR)/Render3D.o $(OBJ_DIR)/Models.o $(OBJ_DIR)/TextureRefs.o $(OBJ_DIR)/Render2D.o $(OBJ_DIR)/TileGen.o \
|
||||||
$(OBJ_DIR)/Model3.o $(OBJ_DIR)/ppc.o $(OBJ_DIR)/Main.o $(OBJ_DIR)/Audio.o $(OBJ_DIR)/Thread.o $(OBJ_DIR)/SoundBoard.o \
|
$(OBJ_DIR)/Model3.o $(OBJ_DIR)/ppc.o $(OBJ_DIR)/Main.o $(OBJ_DIR)/Audio.o $(OBJ_DIR)/Thread.o $(OBJ_DIR)/SoundBoard.o \
|
||||||
$(OBJ_DIR)/SCSP.o $(OBJ_DIR)/SCSPDSP.o $(OBJ_DIR)/68K.o $(OBJ_DIR)/m68kcpu.o $(OBJ_DIR)/m68kopnz.o $(OBJ_DIR)/m68kopdm.o \
|
$(OBJ_DIR)/SCSP.o $(OBJ_DIR)/SCSPDSP.o $(OBJ_DIR)/68K.o $(OBJ_DIR)/m68kcpu.o $(OBJ_DIR)/m68kopnz.o $(OBJ_DIR)/m68kopdm.o \
|
||||||
$(OBJ_DIR)/m68kopac.o $(OBJ_DIR)/m68kops.o $(OBJ_DIR)/DSB.o $(OBJ_DIR)/Z80.o \
|
$(OBJ_DIR)/m68kopac.o $(OBJ_DIR)/m68kops.o $(OBJ_DIR)/DSB.o $(OBJ_DIR)/Z80.o \
|
||||||
|
|
|
@ -146,7 +146,7 @@ endif
|
||||||
HEADERS = Src/Supermodel.h Src/OSD/SDL/Types.h
|
HEADERS = Src/Supermodel.h Src/OSD/SDL/Types.h
|
||||||
OBJ = $(OBJ_DIR)/PPCDisasm.obj $(OBJ_DIR)/Games.obj $(OBJ_DIR)/Config.obj $(OBJ_DIR)/INIFile.obj $(OBJ_DIR)/BlockFile.obj $(OBJ_DIR)/93C46.obj \
|
OBJ = $(OBJ_DIR)/PPCDisasm.obj $(OBJ_DIR)/Games.obj $(OBJ_DIR)/Config.obj $(OBJ_DIR)/INIFile.obj $(OBJ_DIR)/BlockFile.obj $(OBJ_DIR)/93C46.obj \
|
||||||
$(OBJ_DIR)/ROMLoad.obj $(OBJ_DIR)/unzip.obj $(OBJ_DIR)/ioapi.obj $(OBJ_DIR)/Error.obj $(OBJ_DIR)/glew.obj $(OBJ_DIR)/Shader.obj \
|
$(OBJ_DIR)/ROMLoad.obj $(OBJ_DIR)/unzip.obj $(OBJ_DIR)/ioapi.obj $(OBJ_DIR)/Error.obj $(OBJ_DIR)/glew.obj $(OBJ_DIR)/Shader.obj \
|
||||||
$(OBJ_DIR)/Real3D.obj $(OBJ_DIR)/Render3D.obj $(OBJ_DIR)/Models.obj $(OBJ_DIR)/Render2D.obj $(OBJ_DIR)/TileGen.obj \
|
$(OBJ_DIR)/Real3D.obj $(OBJ_DIR)/Render3D.obj $(OBJ_DIR)/Models.obj $(OBJ_DIR)/TextureRefs.obj $(OBJ_DIR)/Render2D.obj $(OBJ_DIR)/TileGen.obj \
|
||||||
$(OBJ_DIR)/Model3.obj $(OBJ_DIR)/ppc.obj $(OBJ_DIR)/Main.obj $(OBJ_DIR)/Audio.obj $(OBJ_DIR)/Thread.obj $(OBJ_DIR)/SoundBoard.obj \
|
$(OBJ_DIR)/Model3.obj $(OBJ_DIR)/ppc.obj $(OBJ_DIR)/Main.obj $(OBJ_DIR)/Audio.obj $(OBJ_DIR)/Thread.obj $(OBJ_DIR)/SoundBoard.obj \
|
||||||
$(OBJ_DIR)/SCSP.obj $(OBJ_DIR)/SCSPDSP.obj $(OBJ_DIR)/68K.obj $(OBJ_DIR)/m68kcpu.obj $(OBJ_DIR)/m68kopnz.obj $(OBJ_DIR)/m68kopdm.obj \
|
$(OBJ_DIR)/SCSP.obj $(OBJ_DIR)/SCSPDSP.obj $(OBJ_DIR)/68K.obj $(OBJ_DIR)/m68kcpu.obj $(OBJ_DIR)/m68kopnz.obj $(OBJ_DIR)/m68kopdm.obj \
|
||||||
$(OBJ_DIR)/m68kopac.obj $(OBJ_DIR)/m68kops.obj $(OBJ_DIR)/DSB.obj $(OBJ_DIR)/Z80.obj \
|
$(OBJ_DIR)/m68kopac.obj $(OBJ_DIR)/m68kops.obj $(OBJ_DIR)/DSB.obj $(OBJ_DIR)/Z80.obj \
|
||||||
|
|
|
@ -611,39 +611,40 @@ bool CRender3D::InsertPolygon(ModelCache *Cache, const Poly *P)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Begins caching a new model by resetting to the start of the local vertex buffer
|
// Begins caching a new model by resetting to the start of the local vertex buffer
|
||||||
bool CRender3D::BeginModel(ModelCache *Cache)
|
struct VBORef *CRender3D::BeginModel(ModelCache *Cache)
|
||||||
{
|
{
|
||||||
int m;
|
struct VBORef *Model;
|
||||||
|
|
||||||
|
unsigned m = Cache->numModels;
|
||||||
|
|
||||||
// Determine whether we've exceeded the model cache limits (caller will have to recache)
|
// Determine whether we've exceeded the model cache limits (caller will have to recache)
|
||||||
if (Cache->numModels >= Cache->maxModels)
|
if (m >= Cache->maxModels)
|
||||||
return FAIL; // too many models
|
{
|
||||||
//return ErrorLog("Too many %s models.", Cache->dynamic?"dynamic":"static");
|
//ErrorLog("Too many %s models.", Cache->dynamic?"dynamic":"static");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
m = Cache->numModels;
|
Model = &(Cache->Models[m]);
|
||||||
|
|
||||||
// Reset to the beginning of the local vertex buffer
|
// Reset to the beginning of the local vertex buffer
|
||||||
for (int i = 0; i < 2; i++)
|
for (int i = 0; i < 2; i++)
|
||||||
Cache->curVertIdx[i] = 0;
|
Cache->curVertIdx[i] = 0;
|
||||||
|
|
||||||
// Clear the VBO reference to 0
|
// Clear the VBO reference to 0 and clear texture references
|
||||||
memset(&(Cache->Models[m]), 0, sizeof(VBORef));
|
memset(Model, 0, sizeof(VBORef) - sizeof(CTextureRefs));
|
||||||
|
Model->texRefs.Clear();
|
||||||
|
|
||||||
// Record starting index of first opaque polygon in VBO (alpha poly index will be re-set in EndModel())
|
// Record starting index of first opaque polygon in VBO (alpha poly index will be re-set in EndModel())
|
||||||
Cache->Models[m].index[POLY_STATE_NORMAL] = Cache->vboCurOffset/(VBO_VERTEX_SIZE*sizeof(GLfloat));
|
Model->index[POLY_STATE_NORMAL] = Cache->vboCurOffset/(VBO_VERTEX_SIZE*sizeof(GLfloat));
|
||||||
Cache->Models[m].index[POLY_STATE_ALPHA] = Cache->Models[m].index[POLY_STATE_NORMAL];
|
Model->index[POLY_STATE_ALPHA] = Model->index[POLY_STATE_NORMAL];
|
||||||
|
|
||||||
return OKAY;
|
return Model;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uploads all vertices from the local vertex buffer to the VBO, sets up the VBO reference, updates the LUT
|
// Uploads all vertices from the local vertex buffer to the VBO, sets up the VBO reference, updates the LUT
|
||||||
struct VBORef *CRender3D::EndModel(ModelCache *Cache, int lutIdx, UINT16 texOffset)
|
void CRender3D::EndModel(ModelCache *Cache, struct VBORef *Model, int lutIdx, UINT16 texOffset)
|
||||||
{
|
{
|
||||||
struct VBORef *Model;
|
int m = Cache->numModels++;
|
||||||
int m;
|
|
||||||
|
|
||||||
m = Cache->numModels++;
|
|
||||||
Model = &(Cache->Models[m]);
|
|
||||||
|
|
||||||
// Record the number of vertices, completing the VBORef
|
// Record the number of vertices, completing the VBORef
|
||||||
for (int i = 0; i < 2; i++)
|
for (int i = 0; i < 2; i++)
|
||||||
|
@ -669,9 +670,6 @@ struct VBORef *CRender3D::EndModel(ModelCache *Cache, int lutIdx, UINT16 texOffs
|
||||||
if (Cache->lut[lutIdx] >= 0) // another texture offset state already cached
|
if (Cache->lut[lutIdx] >= 0) // another texture offset state already cached
|
||||||
Model->nextTexOffset = &(Cache->Models[Cache->lut[lutIdx]]);
|
Model->nextTexOffset = &(Cache->Models[Cache->lut[lutIdx]]);
|
||||||
Cache->lut[lutIdx] = m;
|
Cache->lut[lutIdx] = m;
|
||||||
|
|
||||||
// Return a pointer to the cached model's VBO reference
|
|
||||||
return Model;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -699,7 +697,8 @@ struct VBORef *CRender3D::CacheModel(ModelCache *Cache, int lutIdx, UINT16 texOf
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// Start constructing a new model
|
// Start constructing a new model
|
||||||
if (FAIL == BeginModel(Cache))
|
struct VBORef *Model = BeginModel(Cache);
|
||||||
|
if (NULL == Model)
|
||||||
return NULL; // too many models!
|
return NULL; // too many models!
|
||||||
|
|
||||||
// Cache all polygons
|
// Cache all polygons
|
||||||
|
@ -758,7 +757,13 @@ struct VBORef *CRender3D::CacheModel(ModelCache *Cache, int lutIdx, UINT16 texOf
|
||||||
|
|
||||||
// Decode the texture
|
// Decode the texture
|
||||||
if (texEnable)
|
if (texEnable)
|
||||||
DecodeTexture(texFormat, texBaseX, texBaseY, texWidth, texHeight);
|
{
|
||||||
|
// If model cache is static, record texture reference in model cache entry for later decoding.
|
||||||
|
// If cache is dynamic, or if it's not possible to record the texture reference (due to lack of
|
||||||
|
// memory) then decode the texture now.
|
||||||
|
if (Cache->dynamic || !Model->texRefs.AddRef(texFormat, texBaseX, texBaseY, texWidth, texHeight))
|
||||||
|
DecodeTexture(texFormat, texBaseX, texBaseY, texWidth, texHeight);
|
||||||
|
}
|
||||||
|
|
||||||
// Polygon normal is in upper 24 bits: sign + 1.22 fixed point
|
// Polygon normal is in upper 24 bits: sign + 1.22 fixed point
|
||||||
P.n[0] = (GLfloat) (((INT32)P.header[1])>>8) * (1.0f/4194304.0f);
|
P.n[0] = (GLfloat) (((INT32)P.header[1])>>8) * (1.0f/4194304.0f);
|
||||||
|
@ -826,7 +831,8 @@ struct VBORef *CRender3D::CacheModel(ModelCache *Cache, int lutIdx, UINT16 texOf
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finish model and enter it into the LUT
|
// Finish model and enter it into the LUT
|
||||||
return EndModel(Cache,lutIdx,texOffset);
|
EndModel(Cache,Model,lutIdx,texOffset);
|
||||||
|
return Model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -160,7 +160,6 @@
|
||||||
#define ISINF(x) (std::isinf(x))
|
#define ISINF(x) (std::isinf(x))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
Definitions and Constants
|
Definitions and Constants
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
@ -427,12 +426,8 @@ void CRender3D::UploadTextures(unsigned x, unsigned y, unsigned width, unsigned
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ClearModelCache(&VROMCache);
|
|
||||||
ClearModelCache(&PolyCache);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
Real3D Address Translation
|
Real3D Address Translation
|
||||||
|
|
||||||
|
@ -625,6 +620,11 @@ bool CRender3D::DrawModel(UINT32 modelAddr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If cache is static then decode all the texture references contained in the cached model
|
||||||
|
// before rendering (models in dynamic cache will have been decoded already in CacheModel)
|
||||||
|
if (!Cache->dynamic)
|
||||||
|
ModelRef->texRefs.DecodeAllTextures(this);
|
||||||
|
|
||||||
// Add to display list
|
// Add to display list
|
||||||
return AppendDisplayList(Cache, false, ModelRef);
|
return AppendDisplayList(Cache, false, ModelRef);
|
||||||
}
|
}
|
||||||
|
@ -957,10 +957,6 @@ void CRender3D::RenderViewport(UINT32 addr, int pri)
|
||||||
stackDepth = 0;
|
stackDepth = 0;
|
||||||
listDepth = 0;
|
listDepth = 0;
|
||||||
|
|
||||||
// Descend down the node link: Use stack machine to traverse display list
|
|
||||||
//ClearStack();
|
|
||||||
//StackMachine(nodeAddr);
|
|
||||||
|
|
||||||
// Descend down the node link: Use recursive traversal
|
// Descend down the node link: Use recursive traversal
|
||||||
DescendNodePtr(nodeAddr);
|
DescendNodePtr(nodeAddr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,13 +67,17 @@ struct Poly
|
||||||
* vertices: normal and alpha. Copies of the model with different texture
|
* vertices: normal and alpha. Copies of the model with different texture
|
||||||
* offsets applied are searchable via the linked list of texture offset states.
|
* offsets applied are searchable via the linked list of texture offset states.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct VBORef
|
struct VBORef
|
||||||
{
|
{
|
||||||
unsigned index[2]; // index of model polygons in VBO
|
unsigned index[2]; // index of model polygons in VBO
|
||||||
unsigned numVerts[2];// number of vertices
|
unsigned numVerts[2]; // number of vertices
|
||||||
unsigned lutIdx; // LUT index associated with this model (for fast LUT clearing)
|
unsigned lutIdx; // LUT index associated with this model (for fast LUT clearing)
|
||||||
|
|
||||||
struct VBORef *nextTexOffset; // linked list of models with different texture offset states
|
struct VBORef *nextTexOffset; // linked list of models with different texture offset states
|
||||||
UINT16 texOffset; // texture offset data for this model
|
UINT16 texOffset; // texture offset data for this model
|
||||||
|
|
||||||
|
CTextureRefs texRefs; // unique texture references contained in this model
|
||||||
};
|
};
|
||||||
|
|
||||||
// Display list items: model instances and viewport settings
|
// Display list items: model instances and viewport settings
|
||||||
|
@ -196,6 +200,8 @@ public:
|
||||||
*/
|
*/
|
||||||
class CRender3D
|
class CRender3D
|
||||||
{
|
{
|
||||||
|
friend class CTextureRefs;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*
|
/*
|
||||||
* RenderFrame(void):
|
* RenderFrame(void):
|
||||||
|
@ -315,8 +321,8 @@ private:
|
||||||
void ClearDisplayList(ModelCache *Cache);
|
void ClearDisplayList(ModelCache *Cache);
|
||||||
bool InsertPolygon(ModelCache *cache, const Poly *p);
|
bool InsertPolygon(ModelCache *cache, const Poly *p);
|
||||||
void InsertVertex(ModelCache *cache, const Vertex *v, const Poly *p, float normFlip);
|
void InsertVertex(ModelCache *cache, const Vertex *v, const Poly *p, float normFlip);
|
||||||
bool BeginModel(ModelCache *cache);
|
struct VBORef *BeginModel(ModelCache *cache);
|
||||||
struct VBORef *EndModel(ModelCache *cache, int lutIdx, UINT16 texOffset);
|
void EndModel(ModelCache *cache, struct VBORef *Model, int lutIdx, UINT16 texOffset);
|
||||||
struct VBORef *CacheModel(ModelCache *cache, int lutIdx, UINT16 texOffset, const UINT32 *data);
|
struct VBORef *CacheModel(ModelCache *cache, int lutIdx, UINT16 texOffset, const UINT32 *data);
|
||||||
struct VBORef *LookUpModel(ModelCache *cache, int lutIdx, UINT16 texOffset);
|
struct VBORef *LookUpModel(ModelCache *cache, int lutIdx, UINT16 texOffset);
|
||||||
void ClearModelCache(ModelCache *cache);
|
void ClearModelCache(ModelCache *cache);
|
||||||
|
|
329
Src/Graphics/TextureRefs.cpp
Executable file
329
Src/Graphics/TextureRefs.cpp
Executable file
|
@ -0,0 +1,329 @@
|
||||||
|
/**
|
||||||
|
** Supermodel
|
||||||
|
** A Sega Model 3 Arcade Emulator.
|
||||||
|
** Copyright 2011 Bart Trzynadlowski, Nik Henson
|
||||||
|
**
|
||||||
|
** This file is part of Supermodel.
|
||||||
|
**
|
||||||
|
** Supermodel is free software: you can redistribute it and/or modify it under
|
||||||
|
** the terms of the GNU General Public License as published by the Free
|
||||||
|
** Software Foundation, either version 3 of the License, or (at your option)
|
||||||
|
** any later version.
|
||||||
|
**
|
||||||
|
** Supermodel is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
** more details.
|
||||||
|
**
|
||||||
|
** You should have received a copy of the GNU General Public License along
|
||||||
|
** with Supermodel. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
**/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CTextureRefs.cpp
|
||||||
|
*
|
||||||
|
* Class that tracks unique texture references, eg in a cached model.
|
||||||
|
*
|
||||||
|
* Texture references are stored internally as a 27-bit field (3 bits for format, 6 bits each for x, y, width & height) to save space.
|
||||||
|
*
|
||||||
|
* A pre-allocated array is used for storing up to TEXREFS_ARRAY_SIZE texture references. When that limit is exceeded, it switches
|
||||||
|
* to using a hashset to store the texture references, but this requires extra memory allocation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Supermodel.h"
|
||||||
|
|
||||||
|
CTextureRefs::CTextureRefs() : m_size(0), m_hashCapacity(0), m_hashEntries(NULL)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
CTextureRefs::~CTextureRefs()
|
||||||
|
{
|
||||||
|
DeleteAllHashEntries();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned CTextureRefs::GetSize() const
|
||||||
|
{
|
||||||
|
return m_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTextureRefs::Clear()
|
||||||
|
{
|
||||||
|
// Delete all hash entries
|
||||||
|
DeleteAllHashEntries();
|
||||||
|
m_size = 0;
|
||||||
|
m_hashCapacity = 0;
|
||||||
|
m_hashEntries = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CTextureRefs::ContainsRef(unsigned fmt, unsigned x, unsigned y, unsigned width, unsigned height)
|
||||||
|
{
|
||||||
|
// Pack texture reference into bitfield
|
||||||
|
unsigned texRef = (fmt&7)<<24|(x&0x7E0)<<13|(y&0x7E0)<<7|(width&0x7E0)<<1|(height&0x7E0)>>5;
|
||||||
|
|
||||||
|
// Check if using array or hashset
|
||||||
|
if (m_size <= TEXREFS_ARRAY_SIZE)
|
||||||
|
{
|
||||||
|
// See if texture reference held in array
|
||||||
|
for (unsigned i = 0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
if (texRef == m_array[i])
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
// See if texture reference held in hashset
|
||||||
|
return HashContains(texRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CTextureRefs::AddRef(unsigned fmt, unsigned x, unsigned y, unsigned width, unsigned height)
|
||||||
|
{
|
||||||
|
// Pack texture reference into bitfield
|
||||||
|
unsigned texRef = (fmt&7)<<24|(x&0x7E0)<<13|(y&0x7E0)<<7|(width&0x7E0)<<1|(height&0x7E0)>>5;
|
||||||
|
|
||||||
|
// Check if using array or hashset
|
||||||
|
if (m_size <= TEXREFS_ARRAY_SIZE)
|
||||||
|
{
|
||||||
|
// See if already held in array, if so nothing to do
|
||||||
|
for (unsigned i = 0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
if (texRef == m_array[i])
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// If not, check if array is full
|
||||||
|
if (m_size == TEXREFS_ARRAY_SIZE)
|
||||||
|
{
|
||||||
|
// If so, set initial hashset capacity to 47 to initialize it
|
||||||
|
UpdateHashCapacity(47);
|
||||||
|
// Copy array into hashset
|
||||||
|
for (unsigned i = 0; i < TEXREFS_ARRAY_SIZE; i++)
|
||||||
|
AddToHash(m_array[i]);
|
||||||
|
// Add texture reference to hashset
|
||||||
|
AddToHash(texRef);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Add texture reference to array
|
||||||
|
m_array[m_size] = texRef;
|
||||||
|
m_size++;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
// Add texture reference to hashset
|
||||||
|
return AddToHash(texRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CTextureRefs::RemoveRef(unsigned fmt, unsigned x, unsigned y, unsigned width, unsigned height)
|
||||||
|
{
|
||||||
|
// Pack texture reference into bitfield
|
||||||
|
unsigned texRef = (fmt&7)<<24|(x&0x7E0)<<13|(y&0x7E0)<<7|(width&0x7E0)<<1|(height&0x7E0)>>5;
|
||||||
|
|
||||||
|
// Check if using array or hashset
|
||||||
|
if (m_size <= TEXREFS_ARRAY_SIZE)
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
if (texRef == m_array[i])
|
||||||
|
{
|
||||||
|
for (unsigned j = i + 1; j < m_size; j++)
|
||||||
|
m_array[j - 1] = m_array[j];
|
||||||
|
m_size--;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Remove texture reference from hashset
|
||||||
|
bool removed = RemoveFromHash(texRef);
|
||||||
|
|
||||||
|
// See if should switch back to array
|
||||||
|
if (m_size == TEXREFS_ARRAY_SIZE)
|
||||||
|
{
|
||||||
|
// Loop through all hash entries and copy texture references into array
|
||||||
|
unsigned j = 0;
|
||||||
|
for (unsigned i = 0; i < m_hashCapacity; i++)
|
||||||
|
{
|
||||||
|
for (HashEntry *entry = m_hashEntries[i]; entry; entry = entry->nextEntry)
|
||||||
|
m_array[j++] = entry->texRef;
|
||||||
|
}
|
||||||
|
// Delete all hash entries
|
||||||
|
DeleteAllHashEntries();
|
||||||
|
}
|
||||||
|
return removed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTextureRefs::DecodeAllTextures(CRender3D *Render3D)
|
||||||
|
{
|
||||||
|
// Check if using array or hashset
|
||||||
|
if (m_size <= TEXREFS_ARRAY_SIZE)
|
||||||
|
{
|
||||||
|
// Loop through elements in array and call CRender3D::DecodeTexture
|
||||||
|
for (unsigned i = 0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
// Unpack texture reference from bitfield
|
||||||
|
unsigned texRef = m_array[i];
|
||||||
|
unsigned fmt = texRef>>24;
|
||||||
|
unsigned x = (texRef>>13)&0x7E0;
|
||||||
|
unsigned y = (texRef>>7)&0x7E0;
|
||||||
|
unsigned width = (texRef>>1)&0x7E0;
|
||||||
|
unsigned height = (texRef<<5)&0x7E0;
|
||||||
|
Render3D->DecodeTexture(fmt, x, y, width, height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Loop through all hash entriesa and call CRender3D::DecodeTexture
|
||||||
|
for (unsigned i = 0; i < m_hashCapacity; i++)
|
||||||
|
{
|
||||||
|
for (HashEntry *entry = m_hashEntries[i]; entry; entry = entry->nextEntry)
|
||||||
|
{
|
||||||
|
// Unpack texture reference from bitfield
|
||||||
|
unsigned texRef = entry->texRef;
|
||||||
|
unsigned fmt = texRef>>24;
|
||||||
|
unsigned x = (texRef>>13)&0x7E0;
|
||||||
|
unsigned y = (texRef>>7)&0x7E0;
|
||||||
|
unsigned width = (texRef>>1)&0x7E0;
|
||||||
|
unsigned height = (texRef<<5)&0x7E0;
|
||||||
|
Render3D->DecodeTexture(fmt, x, y, width, height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CTextureRefs::UpdateHashCapacity(unsigned capacity)
|
||||||
|
{
|
||||||
|
unsigned oldCapacity = m_hashCapacity;
|
||||||
|
HashEntry **oldEntries = m_hashEntries;
|
||||||
|
// Update capacity and create new empty entries array
|
||||||
|
m_hashCapacity = capacity;
|
||||||
|
m_hashEntries = new(std::nothrow) HashEntry*[capacity];
|
||||||
|
if (!m_hashEntries)
|
||||||
|
return false;
|
||||||
|
memset(m_hashEntries, NULL, capacity * sizeof(HashEntry*));
|
||||||
|
if (oldEntries)
|
||||||
|
{
|
||||||
|
// Redistribute entries into new entries array
|
||||||
|
for (unsigned i = 0; i < oldCapacity; i++)
|
||||||
|
{
|
||||||
|
HashEntry *entry = oldEntries[i];
|
||||||
|
while (entry)
|
||||||
|
{
|
||||||
|
HashEntry *nextEntry = entry->nextEntry;
|
||||||
|
unsigned hash = entry->texRef % capacity;
|
||||||
|
entry->nextEntry = m_hashEntries[hash];
|
||||||
|
m_hashEntries[hash] = entry;
|
||||||
|
entry = nextEntry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Delete old entries array
|
||||||
|
delete[] oldEntries;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
HashEntry *CTextureRefs::CreateHashEntry(unsigned texRef, bool &hashCapacityUpdated)
|
||||||
|
{
|
||||||
|
// Update size and increase hash capacity if required
|
||||||
|
m_size++;
|
||||||
|
hashCapacityUpdated = m_size >= m_hashCapacity;
|
||||||
|
if (hashCapacityUpdated)
|
||||||
|
{
|
||||||
|
if (m_hashCapacity < 89)
|
||||||
|
UpdateHashCapacity(89); // Capacity of 89 gives good sequence of mostly prime capacities (89, 179, 359, 719, 1439, 2879 etc)
|
||||||
|
else
|
||||||
|
UpdateHashCapacity(2 * m_hashCapacity + 1);
|
||||||
|
}
|
||||||
|
return new(std::nothrow) HashEntry(texRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTextureRefs::DeleteHashEntry(HashEntry *entry)
|
||||||
|
{
|
||||||
|
// Update size and delete hash entry
|
||||||
|
m_size--;
|
||||||
|
delete entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTextureRefs::DeleteAllHashEntries()
|
||||||
|
{
|
||||||
|
if (!m_hashEntries)
|
||||||
|
return;
|
||||||
|
// Delete all hash entries and their storage
|
||||||
|
for (unsigned i = 0; i < m_hashCapacity; i++)
|
||||||
|
{
|
||||||
|
HashEntry *entry = m_hashEntries[i];
|
||||||
|
if (entry)
|
||||||
|
delete entry;
|
||||||
|
}
|
||||||
|
delete[] m_hashEntries;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CTextureRefs::AddToHash(unsigned texRef)
|
||||||
|
{
|
||||||
|
// Convert texture reference to hash value
|
||||||
|
unsigned hash = texRef % m_hashCapacity;
|
||||||
|
// Loop through linked list for hash value and see if have texture reference already
|
||||||
|
HashEntry *headEntry = m_hashEntries[hash];
|
||||||
|
HashEntry *entry = headEntry;
|
||||||
|
while (entry && texRef != entry->texRef)
|
||||||
|
entry = entry->nextEntry;
|
||||||
|
// If found, nothing to do
|
||||||
|
if (entry)
|
||||||
|
return true;
|
||||||
|
// Otherwise, create new hash entry for texture reference
|
||||||
|
bool hashCapacityUpdated;
|
||||||
|
entry = CreateHashEntry(texRef, hashCapacityUpdated);
|
||||||
|
// If couldn't create entry (ie out of memory), let caller know
|
||||||
|
if (!entry)
|
||||||
|
return false;
|
||||||
|
if (hashCapacityUpdated)
|
||||||
|
{
|
||||||
|
// If hash capacity was increased recalculate hash value
|
||||||
|
hash = texRef % m_hashCapacity;
|
||||||
|
headEntry = m_hashEntries[hash];
|
||||||
|
}
|
||||||
|
// Store hash entry in linked list for hash value
|
||||||
|
entry->nextEntry = headEntry;
|
||||||
|
m_hashEntries[hash] = entry;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CTextureRefs::RemoveFromHash(unsigned texRef)
|
||||||
|
{
|
||||||
|
// Convert texture reference to hash value
|
||||||
|
unsigned hash = texRef % m_hashCapacity;
|
||||||
|
// Loop through linked list for hash value and see if have texture reference
|
||||||
|
HashEntry *entry = m_hashEntries[hash];
|
||||||
|
HashEntry *prevEntry = NULL;
|
||||||
|
while (entry && texRef != entry->texRef)
|
||||||
|
{
|
||||||
|
prevEntry = entry;
|
||||||
|
entry = entry->nextEntry;
|
||||||
|
}
|
||||||
|
// If not found, nothing to do
|
||||||
|
if (!entry)
|
||||||
|
return false;
|
||||||
|
// Otherwise, remove entry from linked list for hash value
|
||||||
|
if (prevEntry)
|
||||||
|
prevEntry->nextEntry = entry->nextEntry;
|
||||||
|
else
|
||||||
|
m_hashEntries[hash] = entry->nextEntry;
|
||||||
|
// Delete hash entry storage
|
||||||
|
DeleteHashEntry(entry);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CTextureRefs::HashContains(unsigned texRef) const
|
||||||
|
{
|
||||||
|
// Convert texture reference to hash value
|
||||||
|
unsigned hash = texRef % m_hashCapacity;
|
||||||
|
// Loop through linked list for hash value and see if have texture reference
|
||||||
|
HashEntry *entry = m_hashEntries[hash];
|
||||||
|
while (entry && texRef != entry->texRef)
|
||||||
|
entry = entry->nextEntry;
|
||||||
|
return !!entry;
|
||||||
|
}
|
164
Src/Graphics/TextureRefs.h
Executable file
164
Src/Graphics/TextureRefs.h
Executable file
|
@ -0,0 +1,164 @@
|
||||||
|
/**
|
||||||
|
** Supermodel
|
||||||
|
** A Sega Model 3 Arcade Emulator.
|
||||||
|
** Copyright 2011 Bart Trzynadlowski, Nik Henson
|
||||||
|
**
|
||||||
|
** This file is part of Supermodel.
|
||||||
|
**
|
||||||
|
** Supermodel is free software: you can redistribute it and/or modify it under
|
||||||
|
** the terms of the GNU General Public License as published by the Free
|
||||||
|
** Software Foundation, either version 3 of the License, or (at your option)
|
||||||
|
** any later version.
|
||||||
|
**
|
||||||
|
** Supermodel is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
** more details.
|
||||||
|
**
|
||||||
|
** You should have received a copy of the GNU General Public License along
|
||||||
|
** with Supermodel. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
**/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CTextureRefs.h
|
||||||
|
*
|
||||||
|
* Class that tracks unique texture references, eg in a cached model.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INCLUDED_TEXTUREREFS_H
|
||||||
|
#define INCLUDED_TEXTUREREFS_H
|
||||||
|
|
||||||
|
#define TEXREFS_ARRAY_SIZE 12
|
||||||
|
|
||||||
|
// Hash entry that holds a texture reference in the hashset
|
||||||
|
struct HashEntry
|
||||||
|
{
|
||||||
|
const unsigned texRef; // Texture reference as a bitfield
|
||||||
|
HashEntry *nextEntry; // Next entry with the same hash
|
||||||
|
|
||||||
|
HashEntry(unsigned theTexRef) : texRef(theTexRef), nextEntry(NULL) { }
|
||||||
|
};
|
||||||
|
|
||||||
|
class CRender3D;
|
||||||
|
|
||||||
|
class CTextureRefs
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*
|
||||||
|
* CTextureRefs():
|
||||||
|
*
|
||||||
|
* Constructor.
|
||||||
|
*/
|
||||||
|
CTextureRefs();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ~CTextureRefs():
|
||||||
|
*
|
||||||
|
* Destructor.
|
||||||
|
*/
|
||||||
|
~CTextureRefs();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GetSize():
|
||||||
|
*
|
||||||
|
* Returns number of unique texture references held.
|
||||||
|
*/
|
||||||
|
unsigned GetSize() const;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Clear():
|
||||||
|
*
|
||||||
|
* Removes all texture references.
|
||||||
|
*/
|
||||||
|
void Clear();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ContainsRef(fmt, x, y, width, height):
|
||||||
|
*
|
||||||
|
* Returns true if holds the given texture reference.
|
||||||
|
*/
|
||||||
|
bool ContainsRef(unsigned fmt, unsigned x, unsigned y, unsigned width, unsigned height);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* AddRef(fmt, x, y, width, height):
|
||||||
|
*
|
||||||
|
* Adds the given texture reference. Returns false if it was not possible to add the reference (ie out of memory).
|
||||||
|
*/
|
||||||
|
bool AddRef(unsigned fmt, unsigned x, unsigned y, unsigned width, unsigned height);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RemoveRef(fmt, x, y, width, height):
|
||||||
|
*
|
||||||
|
* Removes the given texture reference. Return true if the reference was found.
|
||||||
|
*/
|
||||||
|
bool RemoveRef(unsigned fmt, unsigned x, unsigned y, unsigned width, unsigned height);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RemoveRef(fmt, x, y, width, height):
|
||||||
|
*
|
||||||
|
* Decodes all texture references held, calling CRender3D::DecodeTexture for each one.
|
||||||
|
*/
|
||||||
|
void DecodeAllTextures(CRender3D *Render3D);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Number of texture references held.
|
||||||
|
unsigned m_size;
|
||||||
|
|
||||||
|
// Pre-allocated array used to hold first TEXREFS_ARRAY_SIZE texture references.
|
||||||
|
unsigned m_array[TEXREFS_ARRAY_SIZE];
|
||||||
|
|
||||||
|
// Dynamically allocated hashset used to hold texture references when there are more than TEXREFS_ARRAY_SIZE.
|
||||||
|
unsigned m_hashCapacity;
|
||||||
|
HashEntry **m_hashEntries;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* UpdateHashCapacity(hashCapacity)
|
||||||
|
*
|
||||||
|
* Increases capacity of the hashset to given size.
|
||||||
|
*/
|
||||||
|
bool UpdateHashCapacity(unsigned hashCapacity);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CreateHashEntry(texRef, hashCapacityUpdated)
|
||||||
|
*
|
||||||
|
* Creates and returns a new hash entry, updating the capacity if required (hashCapacityUpdated is set to true).
|
||||||
|
*/
|
||||||
|
HashEntry *CreateHashEntry(unsigned texRef, bool &hashCapacityUpdated);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DeleteHashEntry(entry)
|
||||||
|
*
|
||||||
|
* Deletes the given hash entry and its storage.
|
||||||
|
*/
|
||||||
|
void DeleteHashEntry(HashEntry *entry);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DeleteAllHashEntries()
|
||||||
|
*
|
||||||
|
* Deletes all hash entries and their storage.
|
||||||
|
*/
|
||||||
|
void DeleteAllHashEntries();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* AddToHash(texRef)
|
||||||
|
*
|
||||||
|
* Adds the given texture reference (as a bitfield) to the hashset.
|
||||||
|
*/
|
||||||
|
bool AddToHash(unsigned texRef);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RemoveFromHash(texRef)
|
||||||
|
*
|
||||||
|
* Removes the given texture reference (as a bitfield) from the hashset.
|
||||||
|
*/
|
||||||
|
bool RemoveFromHash(unsigned texRef);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* HashContains(texRef)
|
||||||
|
*
|
||||||
|
* Returns true if given texture reference (as a bitfield) is held in the hashset.
|
||||||
|
*/
|
||||||
|
bool HashContains(unsigned texRef) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // INCLUDED_TEXTUREREFS_H
|
|
@ -118,6 +118,7 @@
|
||||||
#include "INIFile.h"
|
#include "INIFile.h"
|
||||||
#include "BlockFile.h"
|
#include "BlockFile.h"
|
||||||
#include "Graphics/Render2D.h"
|
#include "Graphics/Render2D.h"
|
||||||
|
#include "Graphics/TextureRefs.h"
|
||||||
#include "Graphics/Render3D.h"
|
#include "Graphics/Render3D.h"
|
||||||
#include "Graphics/Shader.h"
|
#include "Graphics/Shader.h"
|
||||||
#ifdef SUPERMODEL_DEBUGGER
|
#ifdef SUPERMODEL_DEBUGGER
|
||||||
|
|
|
@ -690,6 +690,10 @@
|
||||||
RelativePath="..\Src\Graphics\Shader.cpp"
|
RelativePath="..\Src\Graphics\Shader.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\Src\Graphics\TextureRefs.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<Filter
|
<Filter
|
||||||
Name="Shaders"
|
Name="Shaders"
|
||||||
>
|
>
|
||||||
|
@ -1824,6 +1828,10 @@
|
||||||
RelativePath="..\Src\Graphics\Shaders3D.h"
|
RelativePath="..\Src\Graphics\Shaders3D.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\Src\Graphics\TextureRefs.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="Model3"
|
Name="Model3"
|
||||||
|
|
Loading…
Reference in a new issue