#include "assetmgr.h" #include "tier2/ifilesystem.h" #include "tier2/fileformats/json.h" #include "game.h" struct FunnyShader_t { CUtlString m_szName; IShader *m_pShader; }; #define MAX_MODEL_COUNT 2048 #define MAX_MATERIAL_COUNT 2048 #define MAX_SHADER_COUNT 1024 class CAssetManager: public IAssetManager { public: virtual uint32_t LoadModel( const char *szName ) override; virtual uint32_t LoadMaterial( const char *szName ) override; virtual FunnyModel_t *GetModelByIndex( uint32_t uIndex ) override; virtual FunnyMaterial_t *GetMaterialByIndex( uint32_t uIndex ) override; virtual void UnrefModel( uint32_t uIndex ) override; virtual void UnrefMaterial( uint32_t uIndex ) override; FunnyModel_t *LoadModelFromParams( const char *szMesh, const char *szMaterial ); uint32_t LoadShader( const char *szName ); FunnyShader_t *GetShaderByIndex( uint32_t uIndex ); void UnrefShader( uint32_t uIndex ); FunnyModel_t *m_models[MAX_MODEL_COUNT] = {}; uint32_t m_modelUsages[MAX_MODEL_COUNT] = {}; FunnyMaterial_t *m_materials[MAX_MATERIAL_COUNT] = {}; uint32_t m_materialsUsages[MAX_MATERIAL_COUNT] = {}; FunnyShader_t *m_shaders[MAX_SHADER_COUNT] = {}; uint32_t m_shaderUsages[MAX_SHADER_COUNT] = {}; }; FunnyModel_t *CAssetManager::GetModelByIndex( uint32_t uIndex ) { return m_models[uIndex]; } FunnyMaterial_t *CAssetManager::GetMaterialByIndex( uint32_t uIndex ) { return m_materials[uIndex]; } FunnyShader_t *CAssetManager::GetShaderByIndex( uint32_t uIndex ) { return m_shaders[uIndex]; } uint32_t CAssetManager::LoadModel( const char *szName ) { uint32_t u = 0; uint32_t uFoundIndex = 1; for ( auto &m: m_models) { if (m == NULL) { u++; continue; } if (m->m_szName == szName) { m_modelUsages[uFoundIndex]++; return u; } u++; } for ( auto &m: m_models) { if (m == NULL) break; uFoundIndex++; } IFileHandle *pHandle = filesystem->Open(szName, FILEMODE_READ); CUtlString szProperties = filesystem->ReadString(pHandle); IJSONValue *pRoot = JSONManager()->ReadString(szProperties); IJSONObject *pMainObject; CUtlString szMeshData; IVertexBuffer *pVertices; switch (pRoot->GetType()) { case JSON_PARAMETER_OBJECT: { pMainObject = pRoot->GetObject(); if (!pMainObject) { V_printf("Failed to load properties\n"); return 0; } IJSONValue *pMesh = pMainObject->GetValue("mesh"); IJSONValue *pMaterial = pMainObject->GetValue("material"); CUtlString szMesh = pMesh->GetStringValue(); CUtlString szMaterial = pMaterial->GetStringValue(); m_models[uFoundIndex] = LoadModelFromParams(szMesh, szMaterial); m_modelUsages[uFoundIndex]++; return uFoundIndex; } break; default: return 0; } } void CAssetManager::UnrefModel( uint32_t uIndex ) { } uint32_t CAssetManager::LoadMaterial( const char *szName ) { uint32_t u = 0; uint32_t uFoundIndex = 1; for ( auto &m: m_materials) { if (m == NULL) { u++; continue; } if (m->m_szName == szName) { m_materialsUsages[uFoundIndex]++; return u; } u++; } for ( auto &m: m_materials) { if (m == NULL) break; uFoundIndex++; } IFileHandle *pHandle = filesystem->Open(szName, FILEMODE_READ); CUtlString szProperties = filesystem->ReadString(pHandle); IJSONValue *pRoot = JSONManager()->ReadString(szProperties); IJSONObject *pMainObject; switch (pRoot->GetType()) { case JSON_PARAMETER_OBJECT: { pMainObject = pRoot->GetObject(); if (!pMainObject) { V_printf("Failed to load properties\n"); return 0; } IJSONValue *pShaderValue = pMainObject->GetValue("shader"); CUtlString szShader = pShaderValue->GetStringValue(); CBaseMaterial *pMaterial = CreateMaterial(szShader); uint32_t uShaderId = LoadShader(pMaterial->GetShaderPath()); FunnyShader_t *pShader = GetShaderByIndex(uShaderId); m_materials[uFoundIndex] = new FunnyMaterial_t; m_materials[uFoundIndex]->m_pShaders = pShader->m_pShader; m_materials[uFoundIndex]->m_pMaterial = g_pRenderContext->CreateMaterial(pShader->m_pShader); m_materials[uFoundIndex]->m_pLayout = pMaterial; m_materialsUsages[uFoundIndex]++; return uFoundIndex; } break; default: return 0; } return uFoundIndex; } void CAssetManager::UnrefMaterial( uint32_t uIndex ) { } FunnyModel_t *CAssetManager::LoadModelFromParams( const char *szMesh, const char *szMaterial ) { IFileHandle *hMesh = filesystem->Open(szMesh, FILEMODE_READ); if ( hMesh == NULL ) { V_printf("Failed to load %s\n", szMesh); return NULL; } IVertexBuffer *pVertexBuffer = g_pRenderContext->CreateVertexBuffer(filesystem->Size(hMesh)); pVertexBuffer->Lock(); void *pMapped = pVertexBuffer->Map(); filesystem->Read(hMesh, pMapped, pVertexBuffer->GetSize()); pVertexBuffer->Unmap(); pVertexBuffer->Unlock(); FunnyModel_t *pModel = new FunnyModel_t; pModel->m_szName = szMesh; pModel->m_pMesh = g_pWorldRenderer->CreateMesh(szMesh); pModel->m_pMesh->SetVertices(pVertexBuffer); uint32_t uMaterial = LoadMaterial(szMaterial); pModel->m_pFunnyMaterial = GetMaterialByIndex(uMaterial); return pModel; } uint32_t CAssetManager::LoadShader( const char *szName ) { uint32_t u = 0; uint32_t uFoundIndex = 1; for ( auto &s: m_shaders) { if (s == NULL) { u++; continue; } if ( s->m_szName == szName ) { return u; } u++; } for ( auto &m: m_models) { if (m == NULL) break; uFoundIndex++; } IShader *pShader = g_pRenderContext->CreateShader(szName); if ( pShader == NULL ) { V_printf("Failed to load %s\n", szName); return 0; } FunnyShader_t *pFunnyShader = new FunnyShader_t; pFunnyShader->m_szName = szName; pFunnyShader->m_pShader = pShader; m_shaders[uFoundIndex] = pFunnyShader; return uFoundIndex; } void CAssetManager::UnrefShader( uint32_t uIndex ) { } static CAssetManager s_assetmgr; IAssetManager *g_pAssetManager = &s_assetmgr;