mirror of
https://github.com/AxioDL/PrimeWorldEditor.git
synced 2025-12-21 02:39:17 +00:00
Added shader sharing mechanism; added "cook all dirty packages" button; other various tweaks and fixes
This commit is contained in:
@@ -49,7 +49,7 @@ void CPackage::Cook()
|
||||
CPackageDependencyListBuilder Builder(this);
|
||||
std::list<CAssetID> AssetList;
|
||||
Builder.BuildDependencyList(true, AssetList);
|
||||
Log::Write(TString::FromInt32(AssetList.size(), 0, 10) + " assets in pak");
|
||||
Log::Write(TString::FromInt32(AssetList.size(), 0, 10) + " assets in " + Name() + ".pak");
|
||||
|
||||
// Get named resources
|
||||
std::list<const SNamedResource*> NamedResources;
|
||||
@@ -207,6 +207,9 @@ void CPackage::Cook()
|
||||
mNeedsRecook = false;
|
||||
Save();
|
||||
Log::Write("Finished writing " + PakPath.ToUTF8());
|
||||
|
||||
// Update resource store in case we recooked any assets
|
||||
mpProject->ResourceStore()->ConditionalSaveStore();
|
||||
}
|
||||
|
||||
void CPackage::CompareOriginalAssetList(const std::list<CAssetID>& rkNewList)
|
||||
|
||||
@@ -214,6 +214,8 @@ bool CResourceEntry::Save(bool SkipCacheSave /*= false*/)
|
||||
}
|
||||
|
||||
// Resource has been saved; now make sure dependencies, cache data, and packages are all up to date
|
||||
mFlags |= eREF_HasBeenModified;
|
||||
|
||||
UpdateDependencies();
|
||||
mpStore->SetCacheDataDirty();
|
||||
|
||||
@@ -257,7 +259,11 @@ bool CResourceEntry::Cook()
|
||||
bool Success = CResourceCooker::CookResource(this, File);
|
||||
|
||||
if (Success)
|
||||
mFlags.ClearFlag(eREF_NeedsRecook);
|
||||
{
|
||||
mFlags &= ~eREF_NeedsRecook;
|
||||
mFlags |= eREF_HasBeenModified;
|
||||
mpStore->SetCacheDataDirty();
|
||||
}
|
||||
|
||||
return Success;
|
||||
}
|
||||
@@ -281,6 +287,7 @@ CResource* CResourceEntry::Load()
|
||||
|
||||
CXMLReader Reader(RawAssetPath());
|
||||
mpResource->Serialize(Reader);
|
||||
mpStore->TrackLoadedResource(this);
|
||||
|
||||
gpResourceStore = pOldStore;
|
||||
}
|
||||
|
||||
@@ -19,8 +19,9 @@ enum EResEntryFlag
|
||||
eREF_Transient = 0x00000002, // Resource is transient (not part of a game project resource DB)
|
||||
eREF_Hidden = 0x00000004, // Resource is hidden, doesn't show up in resource browser
|
||||
eREF_HasBeenModified = 0x00000008, // Resource has been modified and resaved by the user
|
||||
eREF_IsUserResource = 0x00000010, // Resource was created by the user (i.e. isn't a Retro Studios asset)
|
||||
// Flags that save to the cache file
|
||||
eREF_SavedFlags = eREF_NeedsRecook | eREF_Hidden | eREF_HasBeenModified
|
||||
eREF_SavedFlags = eREF_NeedsRecook | eREF_Hidden | eREF_HasBeenModified | eREF_IsUserResource
|
||||
};
|
||||
DECLARE_FLAGS(EResEntryFlag, FResEntryFlags)
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ using namespace tinyxml2;
|
||||
CResourceStore *gpResourceStore = nullptr;
|
||||
CResourceStore *gpEditorStore = nullptr;
|
||||
|
||||
// Constructor for editor store
|
||||
CResourceStore::CResourceStore(const TWideString& rkDatabasePath)
|
||||
: mpProj(nullptr)
|
||||
, mGame(eUnknownGame)
|
||||
@@ -26,6 +27,7 @@ CResourceStore::CResourceStore(const TWideString& rkDatabasePath)
|
||||
mDatabaseName = rkDatabasePath.GetFileName();
|
||||
}
|
||||
|
||||
// Constructor for game exporter
|
||||
CResourceStore::CResourceStore(CGameProject *pProject, CGameExporter *pExporter, const TWideString& rkRawDir, const TWideString& rkCookedDir, EGame Game)
|
||||
: mpProj(nullptr)
|
||||
, mGame(Game)
|
||||
@@ -38,6 +40,7 @@ CResourceStore::CResourceStore(CGameProject *pProject, CGameExporter *pExporter,
|
||||
SetProject(pProject);
|
||||
}
|
||||
|
||||
// Main constructor for game projects
|
||||
CResourceStore::CResourceStore(CGameProject *pProject)
|
||||
: mpProj(nullptr)
|
||||
, mGame(eUnknownGame)
|
||||
|
||||
@@ -13,12 +13,14 @@ u64 gFailedCompileCount = 0;
|
||||
u64 gSuccessfulCompileCount = 0;
|
||||
|
||||
CShader* CShader::spCurrentShader = nullptr;
|
||||
int CShader::smNumShaders = 0;
|
||||
|
||||
CShader::CShader()
|
||||
{
|
||||
mVertexShaderExists = false;
|
||||
mPixelShaderExists = false;
|
||||
mProgramExists = false;
|
||||
smNumShaders++;
|
||||
}
|
||||
|
||||
CShader::CShader(const char *pkVertexSource, const char *pkPixelSource)
|
||||
@@ -26,6 +28,7 @@ CShader::CShader(const char *pkVertexSource, const char *pkPixelSource)
|
||||
mVertexShaderExists = false;
|
||||
mPixelShaderExists = false;
|
||||
mProgramExists = false;
|
||||
smNumShaders++;
|
||||
|
||||
CompileVertexSource(pkVertexSource);
|
||||
CompilePixelSource(pkPixelSource);
|
||||
@@ -39,6 +42,7 @@ CShader::~CShader()
|
||||
if (mProgramExists) glDeleteProgram(mProgram);
|
||||
|
||||
if (spCurrentShader == this) spCurrentShader = 0;
|
||||
smNumShaders--;
|
||||
}
|
||||
|
||||
bool CShader::CompileVertexSource(const char* pkSource)
|
||||
|
||||
@@ -23,6 +23,7 @@ class CShader
|
||||
GLint mTextureUniforms[8];
|
||||
GLint mNumLightsUniform;
|
||||
|
||||
static int smNumShaders;
|
||||
static CShader* spCurrentShader;
|
||||
|
||||
public:
|
||||
@@ -45,6 +46,8 @@ public:
|
||||
static CShader* CurrentShader();
|
||||
static void KillCachedShader();
|
||||
|
||||
inline static int NumShaders() { return smNumShaders; }
|
||||
|
||||
private:
|
||||
void CacheCommonUniforms();
|
||||
void DumpShaderSource(GLuint Shader, const TString& rkOut);
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
u64 CMaterial::sCurrentMaterial = 0;
|
||||
CColor CMaterial::sCurrentTint = CColor::skWhite;
|
||||
std::map<u64, CMaterial::SMaterialShader> CMaterial::smShaderMap;
|
||||
|
||||
CMaterial::CMaterial()
|
||||
: mpShader(nullptr)
|
||||
@@ -64,7 +65,7 @@ CMaterial::~CMaterial()
|
||||
for (u32 iPass = 0; iPass < mPasses.size(); iPass++)
|
||||
delete mPasses[iPass];
|
||||
|
||||
delete mpShader;
|
||||
ClearShader();
|
||||
}
|
||||
|
||||
CMaterial* CMaterial::Clone()
|
||||
@@ -93,13 +94,65 @@ CMaterial* CMaterial::Clone()
|
||||
|
||||
void CMaterial::GenerateShader(bool AllowRegen /*= true*/)
|
||||
{
|
||||
HashParameters(); // Calling HashParameters() may change mShaderStatus so call it before checking
|
||||
|
||||
if (mShaderStatus != eShaderExists || AllowRegen)
|
||||
{
|
||||
delete mpShader;
|
||||
mpShader = CShaderGenerator::GenerateShader(*this);
|
||||
auto Find = smShaderMap.find(mParametersHash);
|
||||
|
||||
if (!mpShader->IsValidProgram()) mShaderStatus = eShaderFailed;
|
||||
else mShaderStatus = eShaderExists;
|
||||
if (Find != smShaderMap.end())
|
||||
{
|
||||
SMaterialShader& rShader = Find->second;
|
||||
|
||||
if (rShader.pShader == mpShader)
|
||||
return;
|
||||
|
||||
ClearShader();
|
||||
mpShader = rShader.pShader;
|
||||
rShader.NumReferences++;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
ClearShader();
|
||||
mpShader = CShaderGenerator::GenerateShader(*this);
|
||||
|
||||
if (!mpShader->IsValidProgram())
|
||||
{
|
||||
mShaderStatus = eShaderFailed;
|
||||
delete mpShader;
|
||||
mpShader = nullptr;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
mShaderStatus = eShaderExists;
|
||||
smShaderMap[mParametersHash] = SMaterialShader { 1, mpShader };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CMaterial::ClearShader()
|
||||
{
|
||||
if (mpShader)
|
||||
{
|
||||
auto Find = smShaderMap.find(mParametersHash);
|
||||
ASSERT(Find != smShaderMap.end());
|
||||
|
||||
SMaterialShader& rShader = Find->second;
|
||||
ASSERT(rShader.pShader == mpShader);
|
||||
|
||||
rShader.NumReferences--;
|
||||
|
||||
if (rShader.NumReferences == 0)
|
||||
{
|
||||
delete mpShader;
|
||||
smShaderMap.erase(Find);
|
||||
}
|
||||
|
||||
mpShader = nullptr;
|
||||
mShaderStatus = eNoShader;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,7 +259,12 @@ u64 CMaterial::HashParameters()
|
||||
for (u32 iPass = 0; iPass < mPasses.size(); iPass++)
|
||||
mPasses[iPass]->HashParameters(Hash);
|
||||
|
||||
mParametersHash = Hash.GetHash64();
|
||||
u64 NewHash = Hash.GetHash64();
|
||||
|
||||
if (mParametersHash != NewHash)
|
||||
ClearShader();
|
||||
|
||||
mParametersHash = NewHash;
|
||||
mRecalcHash = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -72,6 +72,14 @@ private:
|
||||
|
||||
std::vector<CMaterialPass*> mPasses;
|
||||
|
||||
// Reuse shaders between materials that have identical TEV setups
|
||||
struct SMaterialShader
|
||||
{
|
||||
int NumReferences;
|
||||
CShader *pShader;
|
||||
};
|
||||
static std::map<u64, SMaterialShader> smShaderMap;
|
||||
|
||||
public:
|
||||
CMaterial();
|
||||
CMaterial(EGame Version, FVertexDescription VtxDesc);
|
||||
@@ -79,6 +87,7 @@ public:
|
||||
|
||||
CMaterial* Clone();
|
||||
void GenerateShader(bool AllowRegen = true);
|
||||
void ClearShader();
|
||||
bool SetCurrent(FRenderOptions Options);
|
||||
u64 HashParameters();
|
||||
void Update();
|
||||
|
||||
@@ -26,6 +26,7 @@ CScene::CScene()
|
||||
CScene::~CScene()
|
||||
{
|
||||
ClearScene();
|
||||
delete mpSceneRootNode;
|
||||
}
|
||||
|
||||
bool CScene::IsNodeIDUsed(u32 ID) const
|
||||
|
||||
Reference in New Issue
Block a user