Resource manager refactoring

This commit is contained in:
2014-04-13 03:42:12 +02:00
parent 14feb3659b
commit e4e5068727
7 changed files with 74 additions and 203 deletions
+2 -3
View File
@@ -5,9 +5,8 @@ void GameWorld::Initialize()
{
World::Initialize();
m_ResourceManager.RegisterResource("Model", "Models/Placeholders/PhysicsTest/Plane.obj");
m_ResourceManager.RegisterResource("Model", "Models/Placeholders/PhysicsTest/ArrowCube.obj");
m_ResourceManager.PreCache();
m_ResourceManager.Preload("Model", "Models/Placeholders/PhysicsTest/Plane.obj");
m_ResourceManager.Preload("Model", "Models/Placeholders/PhysicsTest/ArrowCube.obj");
RegisterComponents();
+4 -140
View File
@@ -1,13 +1,7 @@
#include "PrecompiledHeader.h"
#include "Model.h"
Model::Model(const char* path)
{
Loadobj(path, Vertices, Normals, TextureCoords);
CreateBuffers(Vertices, Normals, TextureCoords);
}
Model::Model(OBJ &obj)
Model::Model(OBJ &obj, ResourceManager* rm)
{
OBJ::MaterialInfo* currentMaterial = nullptr;
TextureGroup* currentTexGroup = nullptr;
@@ -24,7 +18,7 @@ Model::Model(OBJ &obj)
{
currentMaterial = face.Material;
// Load texture
std::shared_ptr<Texture> texture = std::make_shared<Texture>(currentMaterial->TextureFile);
auto texture = std::shared_ptr<Texture>(rm->Load<Texture>("Texture", currentMaterial->TextureFile));
// TODO: Load material parameters
// Create new texture group (start index of new group is upcoming index)
TextureGroup texGroup = { texture, index, index };
@@ -63,142 +57,12 @@ Model::Model(OBJ &obj)
{
CreateBuffers(Vertices, Normals, TextureCoords);
}
}
bool Model::Loadobj(const char* path, std::vector <glm::vec3> &out_vertices, std::vector <glm::vec3> &out_normals, std::vector <glm::vec2> &out_TextureCoords)
{
std::vector< unsigned int > vertexIndices, TextureCoordIndices, normalIndices;
std::vector< glm::vec3 > temp_vertices;
std::vector< glm::vec2 > temp_TextureCoords;
std::vector< glm::vec3 > temp_normals;
FILE* file = fopen(path, "r");
LOG_INFO("Loading .obj file");
if( file == NULL )
else
{
LOG_INFO("Load .obj file: failed");
return false;
LOG_WARNING("Loaded OBJ with no vertices!");
}
char lineHeader[512];
while(true)
{
//read the first word of the line
int res = fscanf(file, "%s", lineHeader);
if( res == EOF ) // EOF - End Of File
{
for( unsigned int i = 0; i < vertexIndices.size(); i++ )
{
unsigned int vertexIndex = vertexIndices[i];
glm::vec3 vertex = temp_vertices[ vertexIndex-1];
out_vertices.push_back(vertex);
}
for( unsigned int i = 0; i < TextureCoordIndices.size(); i++ )
{
unsigned int TextureCoordIndex = TextureCoordIndices[i];
glm::vec2 TextureCoord = temp_TextureCoords[ TextureCoordIndex-1];
out_TextureCoords.push_back(TextureCoord);
}
for( unsigned int i = 0; i < normalIndices.size(); i++ )
{
unsigned int normalIndex = normalIndices[i];
glm::vec3 normal = temp_normals[ normalIndex-1];
out_normals.push_back(normal);
}
LOG_INFO("Model Loaded\n");
break;
}
if( strcmp( lineHeader, "v" ) == 0 ) // vertex
{
glm::vec3 vertex;
fscanf(file, "%f %f %f\n", &vertex.x, &vertex.y, &vertex.z);
temp_vertices.push_back(vertex);
}
else if ( strcmp( lineHeader, "vt" ) == 0 ) // texture coordinate
{
glm::vec2 TextureCoord;
fscanf(file, "%f %f\n", &TextureCoord.x, &TextureCoord.y );
temp_TextureCoords.push_back(TextureCoord);
}
else if( strcmp( lineHeader, "vn" ) == 0 ) // normal
{
glm::vec3 normal;
fscanf(file, "%f %f %f\n", &normal.x, &normal.y, &normal.z );
temp_normals.push_back(normal);
}
else if( strcmp( lineHeader, "f" ) == 0)
{
unsigned int vertexIndex[3], TextureCoordIndex[3], normalIndex[3];
int matches = fscanf(file, "%d/%d/%d %d/%d/%d %d/%d/%d\n", &vertexIndex[0], &TextureCoordIndex[0], &normalIndex[0], &vertexIndex[1], &TextureCoordIndex[1], &normalIndex[1],&vertexIndex[2], &TextureCoordIndex[2], &normalIndex[2]);
if(matches != 9)
{
printf("File can't be read, try exporting with other options\n");
return false;
}
vertexIndices.push_back(vertexIndex[0]);
vertexIndices.push_back(vertexIndex[1]);
vertexIndices.push_back(vertexIndex[2]);
TextureCoordIndices.push_back(TextureCoordIndex[0]);
TextureCoordIndices.push_back(TextureCoordIndex[1]);
TextureCoordIndices.push_back(TextureCoordIndex[2]);
normalIndices.push_back(normalIndex[0]);
normalIndices.push_back(normalIndex[1]);
normalIndices.push_back(normalIndex[2]);
}
else if ( strcmp( lineHeader, "mtllib" ) == 0 )
{
char fileName[512];
fscanf(file, "%s\n", &fileName);
FILE* mtlfile = fopen(fileName, "r");
LOG_INFO("Loading .mtl file");
if( mtlfile == NULL )
{
LOG_INFO("Load .mtl file: failed");
return false;
}
char mtllineHeader[512];
//read the first word of the line
while (true)
{
int mtlres = fscanf(mtlfile, "%s", mtllineHeader);
if( mtlres == EOF ) // EOF - End Of File
{
break;
}
else if ( strcmp( mtllineHeader, "map_Kd" ) == 0 )
{
char textureFileName[512];
fscanf(mtlfile, "%s", textureFileName);
texture.push_back(std::make_shared<Texture>(textureFileName));
LOG_INFO("Texture Loaded\n");
}
}
}
}
return true;
}
void Model::CreateBuffers( std::vector<glm::vec3> vertices, std::vector<glm::vec3> normals, std::vector<glm::vec2>textureCoords)
{
+1 -2
View File
@@ -17,8 +17,7 @@
class Model : public Resource
{
public:
Model(OBJ &obj);
Model(const char* path);
Model(OBJ &obj, ResourceManager* rm);
struct TextureGroup
{
+34 -35
View File
@@ -3,49 +3,48 @@
Resource* ResourceManager::CreateResource(std::string resourceType, std::string resourceName)
{
auto it = m_FactoryFunctions.find(resourceType);
if (it != m_FactoryFunctions.end())
{
return it->second(resourceName);
}
else
auto facIt = m_FactoryFunctions.find(resourceType);
if (facIt == m_FactoryFunctions.end())
{
LOG_ERROR("Failed to load resource \"%s\" of type \"%s\": Type not registered", resourceName.c_str(), resourceType.c_str());
return nullptr;
}
}
void ResourceManager::PreCache()
{
LOG_INFO("Pre-caching resources...");
for (auto pair : m_RegisteredResources)
{
std::string name = pair.first;
std::string type = pair.second;
auto resIt = m_ResourceCache.find(resourceName);
if (resIt != m_ResourceCache.end())
return resIt->second;
// Call the factory function
Resource* resource = facIt->second(resourceName);
// Store IDs
resource->TypeID = GetTypeID(resourceType);
resource->ResourceID = GetNewResourceID(resource->TypeID);
// Cache
m_ResourceCache[resourceName] = resource;
Resource* resource = CreateResource(type, name);
if (resource == nullptr)
{
LOG_WARNING("Failed to pre-cache %s resource \"%s\": Resource not registered!", type.c_str(), name.c_str());
continue;
}
unsigned int typeID = m_ResourceTypeIDs[type];
unsigned int resourceID = m_ResourceCount[typeID]++;
resource->TypeID = typeID;
resource->ResourceID = resourceID;
m_ResourceIDs[name] = resourceID;
m_ResourceCache[name] = resource;
}
}
void ResourceManager::RegisterResource(std::string resourceType, std::string resourceName)
{
m_RegisteredResources[resourceName] = resourceType;
m_ResourceTypeIDs[resourceName] = m_ResourceTypeCount++;
return resource;
}
void ResourceManager::RegisterType(std::string resourceType, std::function<Resource*(std::string)> factoryFunction)
{
m_FactoryFunctions[resourceType] = factoryFunction;
}
void ResourceManager::Preload(std::string resourceType, std::string resourceName)
{
CreateResource(resourceType, resourceName);
}
unsigned int ResourceManager::GetTypeID(std::string resourceType)
{
if (m_ResourceTypeIDs.find(resourceType) == m_ResourceTypeIDs.end())
{
m_ResourceTypeIDs[resourceType] = m_CurrentResourceTypeID++;
}
return m_ResourceTypeIDs[resourceType];
}
unsigned int ResourceManager::GetNewResourceID(unsigned int typeID)
{
return m_ResourceCount[typeID]++;
}
+25 -13
View File
@@ -21,34 +21,46 @@ public:
// Registers the factory function of a resource type
void RegisterType(std::string resourceType, std::function<Resource*(std::string)> factoryFunction);
// Registers a future instance of a resource
void RegisterResource(std::string resourceType, std::string resourceName);
// Loads all registered resources and caches them
void PreCache();
// Loads a resource and caches it for future use
void Preload(std::string resourceType, std::string resourceName);
template <typename T>
// Hot-loads a resource and caches it for future use
T* Load(std::string resourceType, std::string resourceName);
template <typename T>
// Fetches a preloaded resource
T* Fetch(std::string resourceName) const;
private:
unsigned int m_ResourceTypeCount = 0;
std::unordered_map<std::string, unsigned int> m_ResourceTypeIDs;
std::unordered_map<unsigned int, unsigned int> m_ResourceCount;
std::unordered_map<std::string, unsigned int> m_ResourceIDs;
std::unordered_map<std::string, std::function<Resource*(std::string)>> m_FactoryFunctions; // type -> factory function
std::unordered_map<std::string, std::string> m_RegisteredResources; // name -> type
std::unordered_map<std::string, Resource*> m_ResourceCache; // name -> resource
// TODO: Getters for IDs
unsigned int m_CurrentResourceTypeID = 0;
std::unordered_map<std::string, unsigned int> m_ResourceTypeIDs;
// Number of resources of a type. Doubles as local ID.
std::unordered_map<unsigned int, unsigned int> m_ResourceCount;
unsigned int GetTypeID(std::string resourceType);
unsigned int GetNewResourceID(unsigned int typeID);
// Internal: Create a resource and cache it
Resource* CreateResource(std::string resourceType, std::string resourceName);
};
template <typename T>
T* ResourceManager::Load(std::string resourceType, std::string resourceName)
{
return static_cast<T*>(CreateResource(resourceType, resourceName));
}
template <typename T>
T* ResourceManager::Fetch(std::string resourceName) const
{
if (m_ResourceCache.find(resourceName) == m_ResourceCache.end())
{
LOG_ERROR("Failed to load resource \"%s\": Resource not precached!", resourceName.c_str());
LOG_ERROR("Failed to fetch resource \"%s\": Resource not loaded!", resourceName.c_str());
return nullptr;
}
else
+7 -9
View File
@@ -20,16 +20,14 @@ void Systems::RenderSystem::UpdateEntity(double dt, EntityID entity, EntityID pa
auto modelComponent = m_World->GetComponent<Components::Model>(entity, "Model");
if (modelComponent != nullptr)
{
if (m_CachedModels.find(modelComponent->ModelFile) == m_CachedModels.end())
auto model = m_World->GetResourceManager()->Load<Model>("Model", modelComponent->ModelFile);
if (model != nullptr)
{
m_CachedModels[modelComponent->ModelFile] = std::make_shared<Model>(OBJ(modelComponent->ModelFile));
glm::vec3 position = m_TransformSystem->AbsolutePosition(entity);
glm::quat orientation = m_TransformSystem->AbsoluteOrientation(entity);
glm::vec3 scale = m_TransformSystem->AbsoluteScale(entity);
m_Renderer->AddModelToDraw(model, position, orientation, scale, modelComponent->Visible, modelComponent->ShadowCaster);
}
auto model = m_World->GetResourceManager()->Fetch<Model>(modelComponent->ModelFile);
glm::vec3 position = m_TransformSystem->AbsolutePosition(entity);
glm::quat orientation = m_TransformSystem->AbsoluteOrientation(entity);
glm::vec3 scale = m_TransformSystem->AbsoluteScale(entity);
m_Renderer->AddModelToDraw(model, position, orientation, scale, modelComponent->Visible, modelComponent->ShadowCaster);
}
auto pointLightComponent = m_World->GetComponent<Components::PointLight>(entity, "PointLight");
@@ -74,8 +72,8 @@ void Systems::RenderSystem::RegisterComponents(ComponentFactory* cf)
void Systems::RenderSystem::RegisterResourceTypes(ResourceManager* rm)
{
rm->RegisterType("Model", [rm](std::string resourceName) { return new Model(OBJ(resourceName), rm); });
rm->RegisterType("Texture", [](std::string resourceName) { return new Texture(resourceName); });
rm->RegisterType("Model", [](std::string resourceName) { return new Model(OBJ(resourceName)); });
}
+1 -1
View File
@@ -72,7 +72,7 @@ public:
std::unordered_map<EntityID, EntityID>* GetEntities() { return &m_EntityParents; }
const ResourceManager* GetResourceManager() const { return &m_ResourceManager; }
ResourceManager* GetResourceManager() { return &m_ResourceManager; }
protected:
SystemFactory m_SystemFactory;