Resource *Loader::loadModel(const conftree::Node &node, const string &name) { Resource *mesh = load(node.at("mesh").value()); if(mesh->type() != Resource::MESH) throw ResourceException(m_datafile.name(), name, mesh->name() + " is not a mesh!"); Resource *shader = load(node.at("shader").value()); if(shader->type() != Resource::SHADER_PROGRAM) throw ResourceException(m_datafile.name(), name, shader->name() + " is not a shader program!"); Model::SamplerTextures textures; conftree::Node texnodes = node.opt("textures"); for(unsigned int i=0;i<texnodes.items();++i) { const conftree::Node &n = texnodes.at(i); Resource *tr = load(n.at("texture").value()); if(tr->type() != Resource::TEXTURE) throw ResourceException(m_datafile.name(), name, shader->name() + " is not a texture!"); textures.push_back(Model::SamplerTexture( n.at("sampler").value(), static_cast<Texture*>(tr) )); } bool blend = node.opt("blend").value("false") == "true"; return Model::make( name, static_cast<Mesh*>(mesh), static_cast<Program*>(shader), textures, blend ); }
Loader::Loader(fs::DataFile& datafile, const string& filename) : m_datafile(datafile) { // Load configuration file std::vector<conftree::Node> nodes = conftree::parseMultiDocYAML(datafile, filename); // Sanity checks if(nodes.empty()) throw ResourceException(datafile.name(), filename, "Not a YAML file!"); if(nodes.size() > 2) throw ResourceException(datafile.name(), filename, "Resource file should contain at most two documents!"); if(nodes[0].type() != conftree::Node::MAP) throw ResourceException(datafile.name(), filename, "Resource file should contain a Map!"); if(nodes.size() > 1) { // Header present m_node = nodes[1]; parseHeader(datafile, nodes[0]); } else { // No header m_node = nodes[0]; } }
GraphPtr loadGraph( const std::string & fileName ) throw ( ResourceException ) { Resource * rsrc = ResourceManager::getResource( fileName, &Graph::load, Graph::LABEL ); if ( rsrc == 0x0 ) { logger << Logger::ERR_MSG << "No resource available\n"; throw ResourceException(); } Graph * graph = dynamic_cast< Graph * >( rsrc ); if ( graph == 0x0 ) { logger << Logger::ERR_MSG << "Resource with name " << fileName << " is not a Graph\n"; throw ResourceException(); } return GraphPtr( graph ); }
Resource *Loader::loadMesh(const conftree::Node &node, const string &name) { conftree::Node srcnode = node.at("src"); std::unordered_map<string, string> sources; switch(srcnode.type()) { case conftree::Node::SCALAR: sources["0"] = srcnode.value(); break; case conftree::Node::MAP: for(const string &mesh : srcnode.itemSet()) sources[mesh] = srcnode.at(mesh).value(); break; default: throw ResourceException(m_datafile.name(), name, "src must be a scalar or a map!"); } glm::vec3 offset = node2vec3(node.opt("offset")); glm::vec3 scale = node2vec3(node.opt("scale"), glm::vec3(1.0f)); return Mesh::load( name, m_datafile, sources, offset, scale ); }
/** * Find a given file in the search paths * * @param file Filename to find in path * * @return The complete file path or the empty string if file is not found in path */ string DirectoryManager::FindFileInPath(string file) { // looking in path cache for file -> fullpath map<string, string>::iterator thefile = pathcache.find(file); if (thefile != pathcache.end()) return thefile->second; // file not found in cache, looking it up! list<string> possibles; // check for a global path as well if (File::Exists(file)) possibles.push_back(file); for (list<string>::iterator itr = paths.begin(); itr != paths.end(); itr++) { string p = (*itr) + file; if (File::Exists(p)) { possibles.push_back(p); } } if (possibles.size() == 1) { pathcache[file] = *possibles.begin(); return *possibles.begin(); } else if (possibles.size() > 1) { string s = *possibles.begin(); logger.warning << "Found more then one file matching the name given: " << file << logger.end; for (list<string>::iterator itr = possibles.begin(); itr != possibles.end(); itr++) { logger.warning << (*itr) << logger.end; } pathcache[file] = s; return s; } throw ResourceException("Could not locate: " + file); }
Font *Font::load( const string& name, fs::DataFile &datafile, const string &descfile, Texture *texture, Program *program) { // Load font description string fontdesc; { fs::DataStream ds(datafile, descfile); fontdesc = string( (std::istreambuf_iterator<char>(ds)), std::istreambuf_iterator<char>()); } CharMap charmap; try { charmap = parseFontDescription(fontdesc); } catch(const ResourceException &ex) { throw ResourceException(datafile.name(), descfile, ex.error()); } // Private implementation class handles the rest FontImpl *impl = new FontImpl(charmap, texture, program); Font *res = new Font(name, impl); Resources::getInstance().registerResource(res); return res; }
Resource *Loader::loadFont(const conftree::Node &node, const string &name) { Resource *texture = load(node.at("texture").value()); if(texture->type() != Resource::TEXTURE) throw ResourceException(m_datafile.name(), name, texture->name() + " is not a texture!"); Resource *shader = load(node.at("shader").value()); if(shader->type() != Resource::SHADER_PROGRAM) throw ResourceException(m_datafile.name(), name, shader->name() + " is not a shader program!"); return Font::load( name, m_datafile, node.at("description").value(), static_cast<Texture*>(texture), static_cast<Program*>(shader)); }
void CEffect::Load() { EffectParser parser; if(!parser.Parse(mUrl.Name.c_str(), &mDesc, &mEffectFile)) { ASSERT_SOFT(false); LogErrorAlways("Failed to load effect: %s", mUrl.Name.c_str()); throw ResourceException("Failed to load effect"); } }
Resource *Loader::load(const string& name) { // First step: see if the resource has already been loaded try { return Resources::getInstance().getResource(name); } catch(const NotFound &ex) { // not loaded yet } conftree::Node resnode; try { resnode = m_node.at(name); } catch(const conftree::BadNode &ex) { throw NotFound(m_datafile.name(), name); } // Check resource type and dispatch to relevant handler string type; try { type = resnode.at("type").value(); } catch(const conftree::BadNode &ex) { throw ResourceException(m_datafile.name(), name, "missing resource type!"); } if(type=="program") return loadProgram(resnode, name); else if(type=="shader") return loadShader(resnode, name); else if(type=="texture") return loadTexture(resnode, name); else if(type=="mesh") return loadMesh(resnode, name); else if(type=="model") return loadModel(resnode, name); else if(type=="font") return loadFont(resnode, name); else throw ResourceException(m_datafile.name(), name, "Unknown resource type: " + type); }
void SampleResourceManager::loadWAVMemory(const ubyte* memory, ALenum& format, ubyte*& data, uint& size, uint& freq) { WaveHeader wavHeader; std::memcpy(&wavHeader, memory, sizeof(WaveHeader)); // check vital fields of WAV file for validation if(wavHeader.fmt.format != 1) { throw ResourceException("Error loading WAV: Non-PCM format WAV"); } if(wavHeader.riff.chunkID != WaveHeader::RIFF) { throw ResourceException("Error loading WAV: Invalid RIFF chunk."); } if(wavHeader.riff.format != WaveHeader::WAVE) { throw ResourceException("Error loading WAV: Invalid WAVE header."); } if(wavHeader.fmt.chunkID != WaveHeader::FMT) { throw ResourceException("Error loading WAV: Invalid FMT chunk."); } if(wavHeader.chunkID != WaveHeader::DATA) { throw ResourceException("Error loading WAV: Invalid DATA chunk."); } // set OpenAL format based on channels & bitsPerSample if(wavHeader.fmt.numChannels == 1 && wavHeader.fmt.bitsPerSample == 8) { format = AL_FORMAT_MONO8; } else if(wavHeader.fmt.numChannels == 1 && wavHeader.fmt.bitsPerSample == 16) { format = AL_FORMAT_MONO16; } else if(wavHeader.fmt.numChannels == 2 && wavHeader.fmt.bitsPerSample == 8) { format = AL_FORMAT_STEREO8; } else if(wavHeader.fmt.numChannels == 2 && wavHeader.fmt.bitsPerSample == 16) { format = AL_FORMAT_STEREO16; } else { throw ResourceException("Error loading WAV: Invalid audio format."); } // copy size and frequency size = wavHeader.dataSize; freq = wavHeader.fmt.sampleRate; // allocate space and copy data data = new ubyte[size]; std::memcpy(data, memory+sizeof(WaveHeader), size); }
void MeshResource::_remove_resource(const std::string& fileName) { if (_resources.find(fileName) == _resources.end()) { throw ResourceException("No mesh resource named " + fileName + " found."); } _resources.at(fileName).get()->decreaseRefCout(); if (_resources.at(fileName).get()->hasNoReference()) { _resources.erase(fileName); } }
/** * Run init script. * @throws ResourceException when data are not available */ void Application::customizeGame() { Path initfile = Path::dataReadPath("script/init.lua"); if (initfile.exists()) { ScriptAgent::agent()->scriptInclude(initfile); } else { throw ResourceException(ExInfo("init file not found") .addInfo("path", initfile.getNative()) .addInfo("systemdir", OptionAgent::agent()->getParam("systemdir")) .addInfo("userdir", OptionAgent::agent()->getParam("userdir")) .addInfo("hint", "try command line option \"systemdir=path/to/data\"")); } }
Resource *Loader::loadShader(const conftree::Node &node, const string &name) { string stype = node.at("subtype").value(); Resource::Type type; if(stype == "vertex") type = Resource::VERTEX_SHADER; else if(stype == "fragment") type = Resource::FRAGMENT_SHADER; else if(stype == "geometry") type = Resource::GEOMETRY_SHADER; else throw ResourceException(m_datafile.name(), name, "Unrecognized shader type: " + stype); return Shader::load( name, m_datafile, node.at("src").value(), type ); }
void CCubeTexture::Load() { IDirect3DCubeTexture9* tex; if(D3DXCreateCubeTextureFromFileA(((CD3DRenderer*)g_Renderer)->GetDevice(), mUrl.Name.c_str(), &tex) != S_OK) { LogErrorAlways("Failed to load cube texture data from %s", mUrl.Name.c_str()); throw ResourceException("Resource loading failed"); } mTexture = tex; // Reload params D3DSURFACE_DESC desc; memset(&desc, 0, sizeof(D3DSURFACE_DESC)); HR(tex->GetLevelDesc(0, &desc)); mSurfaceDesc.Width = desc.Width; mSurfaceDesc.Height = desc.Height; mSurfaceDesc.Format = FromDXFormat(desc.Format); mSurfaceDesc.Type = SFC_CUBETEXTURE; }
void ResourceManager::LoadMesh(const std::string& fileName, Mesh& mesh) { std::vector<std::string> splits; int split_length = 0; split_length = _split_string(fileName, std::string("."), splits); IndexedModel *model; if (splits[split_length - 1] == "obj") { model = new ObjModel(fileName); model->loadToMesh(&mesh); delete model; } else { throw ResourceException("Mesh loading for file type " + splits[split_length - 1] + " not implemented yet"); } }
void ResourceManager::loadAudio(const std::string& fileName, AudioResource *resource) { std::vector<std::string> splits; int split_length = 0; split_length = _split_string(fileName, std::string("."), splits); AudioModel *model; if (splits[split_length - 1] == "wav") { // Parse model = new WavModel(std::string(fileName)); model->loadToAudio(resource); delete model; } else { throw ResourceException("Audio loading for file " + fileName + " not implemented yet."); } }
void ResourceManager::LoadShader(const std::string& fileName, std::string& shader_string) { shader_string.clear(); // Find path of the file - for later use std::string path; _get_path(fileName, path); std::ifstream file; file.open(fileName.c_str()); std::string line; if (file.is_open()) { while (file.good()) { std::getline(file, line); if (line.find(INCLUDE_KEYWORD) != std::string::npos) { // Parse included files std::vector<std::string> include_file; _split_string(line, " ", include_file); std::string included_file_string; LoadShader(path + include_file[1].substr(1, include_file[1].length() - 2), included_file_string); shader_string.append(included_file_string + "\n"); } else { shader_string.append(line + "\n"); } } } else { throw ResourceException("Unable to load shader: " + fileName); } }
Resource *Loader::loadProgram(const conftree::Node &node, const string &name) { Program *pr = Program::make(name); const conftree::Node &shaders = node.at("shaders"); for(unsigned int i=0;i<shaders.items();++i) { const conftree:: Node &n = shaders.at(i); Resource *sr = load(n.value()); if(!sr) { Resources::getInstance().unloadResource(pr->name()); return nullptr; } else if(!dynamic_cast<Shader*>(sr)) { throw ResourceException(m_datafile.name(), sr->name(), "resource is not a shader!"); } pr->addShader(static_cast<Shader*>(sr)); } pr->link(); return pr; }
ImageReader::ImageHandle ImageReader::getImage(text::string_hash id) { if (hasProduct(id)) return getProduct(id); // Image is not in cache, load it. const std::string& url = text::get(id); INFO_OUT(TAG, "Loading image %s", url.c_str()); FILE* fp = fopen(url.c_str(), "rb"); if (fp == NULL) throw ResourceException("Cannot open file."); if ( !isPNGFile(fp) ) { fclose(fp); throw ResourceException("File is not PNG."); } png_structp pngStruct = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); if (!pngStruct) { fclose(fp); throw ResourceException("[LIBPNG] Error creating read struct."); } png_infop pngInfo = png_create_info_struct(pngStruct); if (!pngInfo) { png_destroy_read_struct(&pngStruct, nullptr, nullptr); fclose(fp); throw ResourceException("[LIBPNG] Error creating info struct."); } if ( setjmp(png_jmpbuf(pngStruct)) ) { png_destroy_read_struct(&pngStruct, &pngInfo, nullptr); fclose(fp); throw ResourceException("Error while reading file."); } png_init_io(pngStruct, fp); png_set_sig_bytes(pngStruct, pngHeaderCheckSize); // FIXME Write directly to buffer, don't copy. png_read_png(pngStruct, pngInfo, PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING | PNG_TRANSFORM_EXPAND, NULL); struct { png_uint_32 width; png_uint_32 height; png_byte bitsPerPixel; png_byte colorType; png_size_t rowSize; } imageData; imageData.width = png_get_image_width(pngStruct, pngInfo); imageData.height = png_get_image_height(pngStruct, pngInfo); imageData.bitsPerPixel = png_get_bit_depth(pngStruct, pngInfo); imageData.colorType = png_get_color_type(pngStruct, pngInfo); imageData.rowSize = png_get_rowbytes(pngStruct, pngInfo); // FIXME Let PixelFormat decide what format is suitable. gr::PixelFormat fmt; if (imageData.colorType == PNG_COLOR_TYPE_RGBA) fmt = gr::PixelFormat::R8G8B8A8; else fmt = gr::PixelFormat::R8G8B8; unsigned char* pixels = new unsigned char[imageData.rowSize * imageData.height]; png_bytepp rowPointers = png_get_rows(pngStruct, pngInfo); for (unsigned int i = 0; i < imageData.height; i++) memcpy(pixels + (imageData.rowSize * (imageData.height - 1 - i)), rowPointers[i], imageData.rowSize); png_destroy_read_struct(&pngStruct, &pngInfo, NULL); fclose(fp); return addProduct(id, gr::Image((unsigned int) imageData.width, (unsigned int) imageData.height, fmt, 1u, pixels)); }
void TextureResourceManager::loadResourceData(TextureResource &res, const ResourceDescriptor& path) { corona::Image *image(0); util::FileBuffer buf(path.path); corona::File *file; // load via FileBuffer to allow loading of archived content std::vector<ubyte> data = buf.getData(); file = corona::CreateMemoryFile((ubyte*)&data[0],data.size()); if(!file) { throw APIError("corona::CreateMemoryFile failed"); } image = corona::OpenImage(file,corona::PF_R8G8B8A8); delete file; if(!image) { throw ResourceException("Invalid image format."); } res.width = image->getWidth(); res.height = image->getHeight(); //size to allocate = w*h*4 = size of bitmap * bytes per pixel res.pixels = new ubyte[res.width*res.height*4]; std::memcpy(res.pixels,image->getPixels(),res.width*res.height*4); delete image; //no longer need image // implementation of the color key if(colorKey_.alpha == 0) //ck alpha == 0, means colorkey on { ubyte r,g,b; ubyte *pxl=res.pixels; // go through all pixels (width*height = numPixels) for(uint i=0; i < res.width*res.height; ++i) { r = *pxl++; // get red component g = *pxl++; // get green component b = *pxl++; // get blue component //set current pixel alpha = 0 if each component matches the colorKey if(r == colorKey_.red && g == colorKey_.green && b == colorKey_.blue) { *pxl = 0; // make transparent } *pxl++; // go to next pixel } } // actually bind the OpenGL texture glGenTextures(1,&res.texID); glBindTexture(GL_TEXTURE_2D,res.texID); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR); gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, res.width, res.height, GL_RGBA, GL_UNSIGNED_BYTE, res.pixels); }
void FontLoader::onAsset(Ptr<Font> font) { // Load either an SDF font (no appended size) or a true-type rendered font // for a specific size (appended size) after the #. // FreeType measures font size in 1/64ths of pixels. So we multiply the // height by 64 to get the right size GLuint const ratio = font->loadSize() / font->size(); GLuint const border = 8; // Border around each glyph in the atlas GLuint const dpi = 96; FT_Face face = (FT_Face)font->face(); FT_Set_Char_Size(face, font->loadSize() << 6, font->loadSize() << 6, dpi, dpi); FT_GlyphSlot glyph = face->glyph; GLuint atlasHeight = 0; GLuint atlasWidth = 0; // Estimate the size of the texture atlas for (GLubyte i = 32; i < 128; i++) { if (FT_Load_Char(face, i, FT_LOAD_RENDER)) { throw ResourceException("could not load font glyph: "+font->name()); } atlasWidth += glyph->bitmap.width/ratio+2*border; atlasHeight = std::max(atlasHeight, glyph->bitmap.rows/ratio+2*border); } glBindTexture(GL_TEXTURE_2D, font->id()); glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, atlasWidth, atlasHeight, 0, GL_RED, GL_UNSIGNED_BYTE, 0); // Generate the texture atlas GLuint x = 0; for (GLubyte i = 32; i < 128; i++) { if (FT_Load_Char(face, i, FT_LOAD_RENDER)) { throw ResourceException("could not load font glyph: "+font->name()); } FT_Bitmap bitmap = glyph->bitmap; GLuint const width = bitmap.width / ratio + 2*border; GLuint const height = bitmap.rows / ratio + 2*border; Glyph fontGlyph; fontGlyph.texX = (GLfloat)(x+border)/(GLfloat)atlasWidth; fontGlyph.texY = (GLfloat)(0+border)/(GLfloat)atlasHeight; fontGlyph.texWidth = (GLfloat)(width-2*border)/(GLfloat)atlasWidth; fontGlyph.texHeight = (GLfloat)(height-2*border)/(GLfloat)atlasHeight; fontGlyph.advanceX = (GLfloat)(glyph->advance.x >> 6)/(GLfloat)font->loadSize(); fontGlyph.advanceY = (GLfloat)(glyph->advance.y >> 6)/(GLfloat)font->loadSize(); fontGlyph.width = (GLfloat)bitmap.width/(GLfloat)font->loadSize(); // ?? fontGlyph.height = (GLfloat)bitmap.rows/(GLfloat)font->loadSize(); // ?? fontGlyph.x = (GLfloat)glyph->bitmap_left/(GLfloat)font->loadSize(); // ?? fontGlyph.y = (GLfloat)(glyph->bitmap_top-bitmap.rows)/(GLfloat)font->loadSize(); // ?? font->glyphIs(i, fontGlyph); if (font->type() == Font::SDF) { std::vector<GLubyte> buffer(width * height); distanceField(bitmap, ratio, border, &buffer[0]); glTexSubImage2D(GL_TEXTURE_2D, 0, x, 0, width, height, GL_RED, GL_UNSIGNED_BYTE, &buffer[0]); } else { glTexSubImage2D(GL_TEXTURE_2D, 0, x+border, border, bitmap.width, bitmap.rows, GL_RED, GL_UNSIGNED_BYTE, bitmap.buffer); } if (glyph->advance.y != 0) { throw ResourceException("invalid font: non-zero y-advance"); } x += bitmap.width/ratio+2*border; } glGenerateMipmap(GL_TEXTURE_2D); }