454 lines
11 KiB
C++
454 lines
11 KiB
C++
#include "assetmgr.h"
|
|
#include "tier2/ifilesystem.h"
|
|
#include "tier2/fileformats/json.h"
|
|
#include "game.h"
|
|
|
|
#define MAX_MODEL_COUNT 2048
|
|
#define MAX_MESH_COUNT 2048
|
|
#define MAX_MATERIAL_COUNT 2048
|
|
#define MAX_TEXTURE_COUNT 4096
|
|
#define MAX_SHADER_COUNT 1024
|
|
|
|
#define MAX_PHYSICS_COUNT 1024
|
|
|
|
template<typename T, uint32_t nCount>
|
|
class CAssetArc
|
|
{
|
|
struct ObjectHandle_t
|
|
{
|
|
CUtlString m_szName;
|
|
uint32_t m_uUsageCount;
|
|
T *m_pObject;
|
|
};
|
|
ObjectHandle_t m_objects[nCount] = {};
|
|
public:
|
|
uint32_t GetOrCreateObject( const char *szName, bool *pbHasBeenCreated )
|
|
{
|
|
uint32_t uFoundIndex = 1;
|
|
for ( uint32_t u = 1; u < nCount; u++ )
|
|
{
|
|
if (m_objects[u].m_pObject == NULL)
|
|
{
|
|
continue;
|
|
}
|
|
if (m_objects[u].m_szName == szName)
|
|
{
|
|
m_objects[u].m_uUsageCount++;
|
|
if (pbHasBeenCreated)
|
|
*pbHasBeenCreated = false;
|
|
return u;
|
|
}
|
|
}
|
|
for ( auto &m: m_objects)
|
|
{
|
|
if (m.m_pObject == NULL)
|
|
break;
|
|
uFoundIndex++;
|
|
}
|
|
m_objects[uFoundIndex].m_szName = szName;
|
|
m_objects[uFoundIndex].m_uUsageCount++;
|
|
m_objects[uFoundIndex].m_pObject = (T*)V_malloc(sizeof(T));
|
|
if (pbHasBeenCreated)
|
|
*pbHasBeenCreated = true;
|
|
return uFoundIndex;
|
|
}
|
|
T *GetObjectPtr( uint32_t uIndex )
|
|
{
|
|
if (uIndex >= nCount)
|
|
return 0;
|
|
return m_objects[uIndex].m_pObject;
|
|
}
|
|
void UnrefObject( uint32_t uIndex )
|
|
{
|
|
if (uIndex >= nCount)
|
|
return;
|
|
|
|
m_objects[uIndex].m_uUsageCount--;
|
|
if (m_objects[uIndex].m_uUsageCount == 0)
|
|
{
|
|
V_free(m_objects[uIndex].m_pObject);
|
|
m_objects[uIndex].m_pObject = NULL;
|
|
m_objects[uIndex].m_szName = NULL;
|
|
}
|
|
}
|
|
};
|
|
|
|
class CAssetManager: public IAssetManager
|
|
{
|
|
public:
|
|
virtual HFunnyModel LoadModel( const char *szName ) override;
|
|
virtual FunnyModel_t *GetModelByIndex( HFunnyModel hModel ) override;
|
|
virtual void UnrefModel( HFunnyModel uIndex ) override;
|
|
|
|
virtual HFunnyMesh LoadMesh( const char *szName ) override;
|
|
virtual FunnyMesh_t *GetMeshByIndex( HFunnyMesh hMesh ) override;
|
|
virtual void UnrefMesh( HFunnyMesh hMesh ) override;
|
|
|
|
virtual HFunnyMaterial LoadMaterial( const char *szName ) override;
|
|
virtual FunnyMaterial_t *GetMaterialByIndex( HFunnyMaterial hMat ) override;
|
|
virtual void UnrefMaterial( HFunnyMaterial hMat ) override;
|
|
|
|
virtual HFunnyPhysics LoadPhysics( const char *szName ) override;
|
|
virtual FunnyPhysics_t *GetPhysicsByIndex( HFunnyPhysics hPhysics ) override;
|
|
virtual void UnrefPhysics( HFunnyPhysics hPhysics ) override;
|
|
|
|
uint32_t LoadShader( const char *szName );
|
|
IShader **GetShaderByIndex( uint32_t hShader );
|
|
void UnrefShader( uint32_t hShader );
|
|
|
|
virtual HFunnyTexture LoadTexture( const char *szName ) override;
|
|
virtual FunnyTexture_t *GetTextureByIndex( HFunnyTexture hTexture ) override;
|
|
virtual void UnrefTexture( HFunnyTexture hTexture ) override;
|
|
|
|
void LoadMaterialData( CBaseMaterial *pMaterial, IJSONObject *pObj );
|
|
|
|
CAssetArc<FunnyModel_t, MAX_MODEL_COUNT> m_models = {};
|
|
CAssetArc<FunnyMesh_t, MAX_MESH_COUNT> m_meshes = {};
|
|
CAssetArc<FunnyMaterial_t, MAX_MATERIAL_COUNT> m_materials = {};
|
|
CAssetArc<FunnyTexture_t, MAX_TEXTURE_COUNT> m_textures = {};
|
|
CAssetArc<IShader*, MAX_SHADER_COUNT> m_shaders = {};
|
|
CAssetArc<FunnyPhysics_t, MAX_PHYSICS_COUNT> m_physics = {};
|
|
|
|
};
|
|
|
|
FunnyModel_t *CAssetManager::GetModelByIndex( uint32_t uIndex )
|
|
{
|
|
return m_models.GetObjectPtr(uIndex);
|
|
}
|
|
|
|
FunnyMaterial_t *CAssetManager::GetMaterialByIndex( uint32_t uIndex )
|
|
{
|
|
return m_materials.GetObjectPtr(uIndex);
|
|
}
|
|
|
|
IShader **CAssetManager::GetShaderByIndex( uint32_t uIndex )
|
|
{
|
|
return m_shaders.GetObjectPtr(uIndex);
|
|
}
|
|
|
|
FunnyMesh_t *CAssetManager::GetMeshByIndex( uint32_t uIndex )
|
|
{
|
|
return m_meshes.GetObjectPtr(uIndex);
|
|
}
|
|
|
|
|
|
uint32_t CAssetManager::LoadModel( const char *szName )
|
|
{
|
|
bool bHasBeenCreated = false;
|
|
HFunnyModel hModel = m_models.GetOrCreateObject(szName, &bHasBeenCreated);
|
|
if (!bHasBeenCreated)
|
|
return hModel;
|
|
|
|
FunnyModel_t *pModel = m_models.GetObjectPtr(hModel);
|
|
|
|
IFileHandle *pHandle = filesystem->Open(szName, FILEMODE_READ);
|
|
if (!pHandle)
|
|
return 0;
|
|
|
|
CUtlString szProperties = filesystem->ReadString(pHandle);
|
|
IJSONValue *pRoot = JSONManager()->ReadString(szProperties);
|
|
filesystem->Close(pHandle);
|
|
|
|
if (!pRoot)
|
|
return 0;
|
|
|
|
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");
|
|
IJSONValue *pPhysics = pMainObject->GetValue("Physics");
|
|
V_printf("%s\n", pMaterial->GetStringValue());
|
|
if (pMesh)
|
|
pModel->m_hMesh = LoadMesh(pMesh->GetStringValue());
|
|
if (pMaterial)
|
|
pModel->m_hMaterial = LoadMaterial(pMaterial->GetStringValue());
|
|
if (pPhysics)
|
|
pModel->m_hPhysics = LoadPhysics(pPhysics->GetStringValue());
|
|
|
|
|
|
|
|
return hModel;
|
|
}
|
|
break;
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void CAssetManager::UnrefModel( uint32_t uIndex )
|
|
{
|
|
|
|
}
|
|
|
|
void CAssetManager::LoadMaterialData( CBaseMaterial *pMaterial, IJSONObject *pObj )
|
|
{
|
|
for ( int i = 0; i < pMaterial->GetDataMap()->m_iNumFields; i++ )
|
|
{
|
|
typedescription_t desc = pMaterial->GetDataMap()->m_pData[i];
|
|
IJSONValue *pValue = pObj->GetValue(desc.m_szEditorName);
|
|
switch ( desc.m_eFieldType )
|
|
{
|
|
case FIELD_SHADER_TEXTURE:
|
|
{
|
|
FMat::XMTexture *texture = (FMat::XMTexture*)((char*)pMaterial+desc.m_iFieldOffset);
|
|
if ( pValue->GetType()
|
|
== JSON_PARAMETER_STRING )
|
|
*texture = GetTextureByIndex(LoadTexture(pValue->GetStringValue()))->m_hTexture;
|
|
break;
|
|
}
|
|
case FIELD_SHADER_COLOR_FLOAT4:
|
|
{
|
|
FMat::XMFLOAT4 *data = (FMat::XMFLOAT4*)((char*)pMaterial+desc.m_iFieldOffset);
|
|
if ( pValue->GetArray()->GetParameter(0)->GetType()
|
|
== JSON_PARAMETER_NUMBER )
|
|
data->x = pValue->GetArray()->GetParameter(0)->GetNumberValue();
|
|
if ( pValue->GetArray()->GetParameter(1)->GetType()
|
|
== JSON_PARAMETER_NUMBER )
|
|
data->y = pValue->GetArray()->GetParameter(1)->GetNumberValue();
|
|
if ( pValue->GetArray()->GetParameter(2)->GetType()
|
|
== JSON_PARAMETER_NUMBER )
|
|
data->z = pValue->GetArray()->GetParameter(2)->GetNumberValue();
|
|
if ( pValue->GetArray()->GetParameter(3)->GetType()
|
|
== JSON_PARAMETER_NUMBER )
|
|
data->w = pValue->GetArray()->GetParameter(3)->GetNumberValue();
|
|
V_printf("%s %f %f %f %f\n", desc.m_szEditorName, data->x, data->y, data->z, data->w);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
|
|
uint32_t CAssetManager::LoadMaterial( const char *szName )
|
|
{
|
|
bool bHasBeenCreated = false;
|
|
HFunnyMaterial hMaterial = m_materials.GetOrCreateObject(szName, &bHasBeenCreated);
|
|
if (!bHasBeenCreated)
|
|
return hMaterial;
|
|
FunnyMaterial_t *pMaterial = m_materials.GetObjectPtr(hMaterial);
|
|
|
|
IFileHandle *pHandle = filesystem->Open(szName, FILEMODE_READ);
|
|
if (!pHandle)
|
|
return 0;
|
|
CUtlString szProperties = filesystem->ReadString(pHandle);
|
|
IJSONValue *pRoot = JSONManager()->ReadString(szProperties);
|
|
if (!pRoot)
|
|
return 0;
|
|
|
|
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 *pRenderMaterial = CreateMaterial(szShader);
|
|
LoadMaterialData(pRenderMaterial, pMainObject);
|
|
|
|
uint32_t uShaderId = LoadShader(pRenderMaterial->GetShaderPath());
|
|
if (!uShaderId)
|
|
return 0;
|
|
|
|
IShader **ppShader = GetShaderByIndex(uShaderId);
|
|
|
|
pMaterial->m_pShaders = *ppShader;
|
|
pMaterial->m_pMaterial = g_pRenderContext->CreateMaterial(*ppShader);
|
|
pMaterial->m_pLayout = pRenderMaterial;
|
|
|
|
return hMaterial;
|
|
}
|
|
break;
|
|
default:
|
|
return 0;
|
|
}
|
|
return hMaterial;
|
|
}
|
|
|
|
void CAssetManager::UnrefMaterial( uint32_t uIndex )
|
|
{
|
|
|
|
}
|
|
|
|
HFunnyMesh CAssetManager::LoadMesh( const char *szName )
|
|
{
|
|
|
|
bool bHasBeenCreated = false;
|
|
HFunnyMesh hAsset = m_meshes.GetOrCreateObject(szName, &bHasBeenCreated);
|
|
if (!bHasBeenCreated)
|
|
return hAsset;
|
|
FunnyMesh_t *pMesh = m_meshes.GetObjectPtr(hAsset);
|
|
|
|
IFileHandle *hMesh = filesystem->Open(szName, FILEMODE_READ);
|
|
if ( hMesh == NULL )
|
|
{
|
|
V_printf("Failed to load %s\n", szName);
|
|
m_meshes.UnrefObject(hAsset);
|
|
return 0;
|
|
}
|
|
|
|
IVertexBuffer *pVertexBuffer = g_pRenderContext->CreateVertexBuffer(filesystem->Size(hMesh));
|
|
pVertexBuffer->Lock();
|
|
void *pMapped = pVertexBuffer->Map();
|
|
filesystem->Read(hMesh, pMapped, pVertexBuffer->GetSize());
|
|
pVertexBuffer->Unmap();
|
|
pVertexBuffer->Unlock();
|
|
|
|
pMesh->m_pMesh = g_pWorldRenderer->CreateMesh(szName);
|
|
pMesh->m_pMesh->SetVertices(pVertexBuffer);
|
|
|
|
return hAsset;
|
|
|
|
}
|
|
void CAssetManager::UnrefMesh( uint32_t uIndex )
|
|
{
|
|
m_meshes.UnrefObject(uIndex);
|
|
}
|
|
|
|
uint32_t CAssetManager::LoadShader( const char *szName )
|
|
{
|
|
bool bHasBeenCreated = false;
|
|
uint32_t hShader = m_shaders.GetOrCreateObject(szName, &bHasBeenCreated);
|
|
if (!bHasBeenCreated)
|
|
return hShader;
|
|
IShader **ppShader = m_shaders.GetObjectPtr(hShader);
|
|
|
|
|
|
IShader *pShader = g_pRenderContext->CreateShader(szName);
|
|
if ( pShader == NULL )
|
|
{
|
|
V_printf("Failed to load %s\n", szName);
|
|
m_shaders.UnrefObject(hShader);
|
|
return 0;
|
|
}
|
|
*ppShader = pShader;
|
|
return hShader;
|
|
}
|
|
|
|
void CAssetManager::UnrefShader( uint32_t uIndex )
|
|
{
|
|
m_shaders.UnrefObject(uIndex);
|
|
}
|
|
|
|
HFunnyTexture CAssetManager::LoadTexture( const char *szName )
|
|
{
|
|
bool bHasBeenCreated = false;
|
|
uint32_t hTexture = m_textures.GetOrCreateObject(szName, &bHasBeenCreated);
|
|
if (!bHasBeenCreated)
|
|
return hTexture;
|
|
FunnyTexture_t *pTexture = m_textures.GetObjectPtr(hTexture);
|
|
|
|
|
|
uint32_t hTex = g_pWorldRenderer->GetTextures()->LoadTexture(szName);
|
|
if ( hTex == 0 )
|
|
{
|
|
V_printf("Failed to load %s\n", szName);
|
|
m_textures.UnrefObject(hTexture);
|
|
return 0;
|
|
}
|
|
pTexture->m_hTexture = hTex;
|
|
return hTexture;
|
|
}
|
|
|
|
FunnyTexture_t *CAssetManager::GetTextureByIndex( HFunnyTexture hTexture )
|
|
{
|
|
return m_textures.GetObjectPtr(hTexture);
|
|
}
|
|
|
|
void CAssetManager::UnrefTexture( uint32_t hTexture )
|
|
{
|
|
|
|
}
|
|
|
|
|
|
HFunnyPhysics CAssetManager::LoadPhysics( const char *szName )
|
|
{
|
|
bool bHasBeenCreated = false;
|
|
HFunnyPhysics hPhysics = m_physics.GetOrCreateObject(szName, &bHasBeenCreated);
|
|
if (!bHasBeenCreated)
|
|
return hPhysics;
|
|
FunnyPhysics_t *pPhysics = m_physics.GetObjectPtr(hPhysics);
|
|
|
|
IFileHandle *pHandle = filesystem->Open(szName, FILEMODE_READ);
|
|
if (!pHandle)
|
|
return 0;
|
|
CUtlString szProperties = filesystem->ReadString(pHandle);
|
|
IJSONValue *pRoot = JSONManager()->ReadString(szProperties);
|
|
if (!pRoot)
|
|
return 0;
|
|
|
|
IJSONObject *pMainObject;
|
|
switch (pRoot->GetType())
|
|
{
|
|
case JSON_PARAMETER_OBJECT:
|
|
{
|
|
pMainObject = pRoot->GetObject();
|
|
if (!pMainObject)
|
|
{
|
|
V_printf("Failed to load properties\n");
|
|
m_physics.UnrefObject(hPhysics);
|
|
return 0;
|
|
|
|
}
|
|
IJSONValue *pTypeValue = pMainObject->GetValue("Type");
|
|
if (!pTypeValue)
|
|
{
|
|
V_printf("\"Type\" must be specified\n");
|
|
m_physics.UnrefObject(hPhysics);
|
|
return 0;
|
|
}
|
|
CUtlString szType = pTypeValue->GetStringValue();
|
|
if (szType == "Sphere")
|
|
{
|
|
pPhysics->m_hShape = g_pPhysics->CreateBall({0.1});
|
|
}
|
|
|
|
return hPhysics;
|
|
}
|
|
break;
|
|
default:
|
|
return 0;
|
|
}
|
|
|
|
return hPhysics;
|
|
}
|
|
|
|
|
|
FunnyPhysics_t *CAssetManager::GetPhysicsByIndex( HFunnyPhysics hPhysics )
|
|
{
|
|
return m_physics.GetObjectPtr(hPhysics);
|
|
}
|
|
|
|
void CAssetManager::UnrefPhysics( HFunnyPhysics hPhysics )
|
|
{
|
|
m_physics.UnrefObject(hPhysics);
|
|
}
|
|
|
|
|
|
|
|
|
|
static CAssetManager s_assetmgr;
|
|
IAssetManager *g_pAssetManager = &s_assetmgr;
|