315 lines
7.4 KiB
C++
315 lines
7.4 KiB
C++
#include "render/render_state.h"
|
|
#include "main/references.h"
|
|
#include "resource/library.h"
|
|
#include "scene/particle_system.h"
|
|
#include "ISoundSource.h"
|
|
#include "files.h"
|
|
#include "str_util.h"
|
|
#include "num_util.h"
|
|
#include <iostream>
|
|
#include <fstream>
|
|
#include <string>
|
|
|
|
namespace resource {
|
|
|
|
void Library::clear() {
|
|
foreach(mat, materials)
|
|
delete mat->second;
|
|
materials.clear();
|
|
material_names.clear();
|
|
|
|
foreach(mat, matGroups)
|
|
delete mat->second;
|
|
matGroups.clear();
|
|
|
|
foreach(sheet, spritesheets)
|
|
delete sheet->second;
|
|
spritesheets.clear();
|
|
spritesheet_names.clear();
|
|
|
|
foreach(tex, textures)
|
|
delete *tex;
|
|
textures.clear();
|
|
texture_files.clear();
|
|
clearTextures();
|
|
|
|
foreach(mesh, meshes)
|
|
if(mesh->second != errors.mesh)
|
|
delete mesh->second;
|
|
meshes.clear();
|
|
|
|
foreach(shader, shaders)
|
|
delete shader->second;
|
|
shaders.clear();
|
|
settingsShaders.clear();
|
|
|
|
foreach(program, programs)
|
|
delete program->second;
|
|
programs.clear();
|
|
|
|
foreach(font, font_list)
|
|
delete *font;
|
|
font_list.clear();
|
|
fonts.clear();
|
|
|
|
foreach(skin, skins)
|
|
delete skin->second;
|
|
skin_files.clear();
|
|
skins.clear();
|
|
|
|
foreach(sound, sounds)
|
|
delete sound->second;
|
|
sounds.clear();
|
|
|
|
clearWatchedResources();
|
|
|
|
delete errors.texture;
|
|
errors.texture = 0;
|
|
errors.material.textures[0] = 0;
|
|
|
|
delete errors.mesh;
|
|
errors.mesh = 0;
|
|
|
|
mat_indices.clear();
|
|
}
|
|
void Library::prepErrorResources() {
|
|
if(!devices.render) {
|
|
errors.material.constant = true;
|
|
errors.mesh = new ErrorMesh();
|
|
return;
|
|
}
|
|
|
|
errors.particleSystem = scene::createDummyParticleSystem();
|
|
|
|
errors.material.constant = true;
|
|
errors.material.lighting = false;
|
|
|
|
errors.skin.materialName = "~invalid_skin";
|
|
errors.mesh = devices.render->createMesh(Mesh());
|
|
|
|
render::RenderState* img2d = new render::RenderState();
|
|
img2d->baseMat = render::MAT_Alpha;
|
|
img2d->lighting = false;
|
|
img2d->depthTest = render::DT_NoDepthTest;
|
|
img2d->depthWrite = false;
|
|
img2d->constant = true;
|
|
materials["Image2D"] = img2d;
|
|
material_names.push_back("Image2D");
|
|
mat_indices[img2d] = material_names.size();
|
|
}
|
|
|
|
void Library::generateErrorResources() {
|
|
if(!devices.render)
|
|
return;
|
|
|
|
{ //Checkboard error image
|
|
Image img(64,64,FMT_RGB);
|
|
for(unsigned r = 0; r < 64; ++r)
|
|
for(unsigned x = 0; x < 64; ++x)
|
|
img.rgb[x+(r*64)] = (x/2 % 2) ^ (r/2 % 2) ? ColorRGB(0,0,0) : ColorRGB(255,0,255);
|
|
errors.texture = devices.render->createTexture(img);
|
|
errors.material.textures[0] = errors.texture;
|
|
}
|
|
|
|
{ //Tetrahedron error mesh
|
|
Mesh mesh;
|
|
mesh.vertices.push_back( Vertex(vec3f(0,1,0)) );
|
|
mesh.vertices.push_back( Vertex(vec3f(1,0,0)) );
|
|
mesh.vertices.push_back( Vertex(vec3f(-1,0,1)) );
|
|
mesh.vertices.push_back( Vertex(vec3f(-1,0,-1)) );
|
|
|
|
mesh.faces.push_back(Mesh::Face(0,1,2));
|
|
mesh.faces.push_back(Mesh::Face(0,2,3));
|
|
mesh.faces.push_back(Mesh::Face(0,3,1));
|
|
mesh.faces.push_back(Mesh::Face(1,2,3));
|
|
|
|
errors.mesh->resetToMesh(mesh);
|
|
}
|
|
}
|
|
|
|
void Library::load(ResourceType type, const std::string& filename) {
|
|
switch(type) {
|
|
case RT_Sound:
|
|
loadSounds(filename);
|
|
break;
|
|
case RT_Material:
|
|
case RT_SpriteSheet:
|
|
loadMaterials(filename);
|
|
break;
|
|
case RT_Mesh:
|
|
loadModels(filename);
|
|
break;
|
|
case RT_Font:
|
|
loadFonts(filename);
|
|
break;
|
|
case RT_Shader:
|
|
loadShaders(filename);
|
|
break;
|
|
case RT_Skin:
|
|
loadSkins(filename);
|
|
break;
|
|
case RT_ParticleSystem:
|
|
{
|
|
auto* pSys = scene::loadParticleSystem(filename);
|
|
if(pSys)
|
|
particleSystems[getBasename(filename,false)] = pSys;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
void Library::loadDirectory(ResourceType type, const std::string& filename) {
|
|
std::vector<std::string> files;
|
|
std::string dirname(filename);
|
|
|
|
listDirectory(dirname, files);
|
|
foreach(it, files) {
|
|
std::string& file = *it;
|
|
if(file.size() < 4)
|
|
continue;
|
|
if(!file.compare(file.size() - 4, 4, ".txt"))
|
|
load(type, path_join(dirname, file));
|
|
}
|
|
}
|
|
|
|
Library::ResourceAccessor Library::operator[](const char* name) const {
|
|
ResourceAccessor access;
|
|
access.source = this;
|
|
access.name = name;
|
|
return access;
|
|
}
|
|
|
|
#define access_ref(type, func) \
|
|
Library::ResourceAccessor::operator const type &() { return source->func(name); }\
|
|
Library::ResourceAccessor::operator const type *() { return &source->func(name); }
|
|
|
|
#define access_ptr(type, func) \
|
|
Library::ResourceAccessor::operator const type &() { return *source->func(name); }\
|
|
Library::ResourceAccessor::operator const type *() { return source->func(name); }
|
|
|
|
access_ref(render::RenderMesh, getMesh);
|
|
access_ref(render::RenderState, getMaterial);
|
|
access_ref(render::Font, getFont);
|
|
access_ref(render::SpriteSheet, getSpriteSheet);
|
|
access_ref(gui::skin::Skin, getSkin);
|
|
|
|
access_ptr(Sound, getSound);
|
|
access_ptr(render::Shader, getShader);
|
|
|
|
const render::RenderState& Library::getErrorMaterial() const {
|
|
return errors.material;
|
|
}
|
|
|
|
const render::Texture* Library::getErrorTexture() const {
|
|
return errors.texture;
|
|
}
|
|
|
|
const render::SpriteSheet& Library::getErrorSpriteSheet() const {
|
|
return errors.spriteSheet;
|
|
}
|
|
|
|
const render::RenderState& Library::getMaterial(const std::string& name) const {
|
|
auto mat = materials.find(name);
|
|
if(mat == materials.end())
|
|
return errors.material;
|
|
else
|
|
return *mat->second;
|
|
}
|
|
|
|
const render::MaterialGroup& Library::getMaterialGroup(const std::string& name) const {
|
|
auto mat = matGroups.find(name);
|
|
if(mat == matGroups.end())
|
|
return errors.group;
|
|
else
|
|
return *mat->second;
|
|
}
|
|
|
|
const render::SpriteSheet& Library::getSpriteSheet(const std::string& name) const {
|
|
auto sheet = spritesheets.find(name);
|
|
if(sheet == spritesheets.end())
|
|
return errors.spriteSheet;
|
|
else
|
|
return *sheet->second;
|
|
}
|
|
|
|
const render::RenderMesh& Library::getMesh(const std::string& name) const {
|
|
auto mesh = meshes.find(name);
|
|
if(mesh == meshes.end())
|
|
return *errors.mesh;
|
|
else
|
|
return *mesh->second;
|
|
}
|
|
|
|
const gui::skin::Skin& Library::getSkin(const std::string& name) const {
|
|
auto skin = skins.find(name);
|
|
if(skin == skins.end())
|
|
return errors.skin;
|
|
else
|
|
return *skin->second;
|
|
}
|
|
|
|
const scene::ParticleSystemDesc* Library::getParticleSystem(const std::string& name) const {
|
|
auto sys = particleSystems.find(name);
|
|
if(sys == particleSystems.end())
|
|
return errors.particleSystem;
|
|
else
|
|
return sys->second;
|
|
}
|
|
|
|
|
|
//TODO: Decide how to handle the error font (it should still render some text)
|
|
const render::Font& Library::getFont(const std::string& name) const {
|
|
auto font = fonts.find(name);
|
|
if(font == fonts.end())
|
|
return *fonts.begin()->second;
|
|
else
|
|
return *font->second;
|
|
}
|
|
|
|
const render::Shader* Library::getShader(const std::string& name) const {
|
|
auto shader = shaders.find(name);
|
|
if(shader == shaders.end())
|
|
return 0;
|
|
else
|
|
return shader->second;
|
|
}
|
|
|
|
const Sound* Library::getSound(const std::string& name) const {
|
|
auto sound = sounds.find(name);
|
|
if(sound == sounds.end())
|
|
return 0;
|
|
else
|
|
return sound->second;
|
|
}
|
|
|
|
render::Sprite Library::getSprite(const std::string& desc) {
|
|
render::Sprite sprt;
|
|
std::string tmp = desc;
|
|
auto pos = desc.find("*");
|
|
if(pos != std::string::npos && pos < tmp.size() - 1) {
|
|
sprt.color = toColor(trim(tmp.substr(pos+1)));
|
|
tmp = trim(tmp.substr(0, pos));
|
|
}
|
|
pos = tmp.find("::");
|
|
if(pos == std::string::npos || pos >= tmp.size() - 2) {
|
|
auto sheet = spritesheets.find(tmp);
|
|
if(sheet != spritesheets.end()) {
|
|
sprt.sheet = sheet->second;
|
|
sprt.index = 0;
|
|
}
|
|
else {
|
|
auto img = materials.find(tmp);
|
|
if(img != materials.end()) {
|
|
sprt.mat = img->second;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
sprt.sheet = &getSpriteSheet(tmp.substr(0, pos));
|
|
sprt.index = toNumber<unsigned>(tmp.substr(pos+2));
|
|
}
|
|
return sprt;
|
|
}
|
|
|
|
};
|