bool Material::parseTechnique(Properties* techniqueProperties) { auto technique = Technique::create(this); _techniques.pushBack(technique); // first one is the default one if (!_currentTechnique) _currentTechnique = technique; // name technique->setName(techniqueProperties->getId()); // passes auto space = techniqueProperties->getNextNamespace(); while (space) { const char* name = space->getNamespace(); if (strcmp(name, "pass") == 0) { parsePass(technique, space); } else if (strcmp(name, "renderState") == 0) { parseRenderState(this, space); } space = techniqueProperties->getNextNamespace(); } return true; }
Ref<Material> Material::read(RenderContext& context, const std::string& name) { initializeMaps(); if (Material* cached = context.cache().find<Material>(name)) return cached; const Path path = context.cache().findFile(name); if (path.isEmpty()) { logError("Failed to find material %s", name.c_str()); return nullptr; } pugi::xml_document document; const pugi::xml_parse_result result = document.load_file(path.name().c_str()); if (!result) { logError("Failed to load material %s: %s", name.c_str(), result.description()); return nullptr; } pugi::xml_node root = document.child("material"); if (!root || root.attribute("version").as_uint() != MATERIAL_XML_VERSION) { logError("Material file format mismatch in %s", name.c_str()); return nullptr; } Ref<Material> material = Material::create(ResourceInfo(context.cache(), name, path), context); for (auto pn : root.children("pass")) { const std::string phaseName(pn.attribute("phase").value()); if (!phaseMap.hasKey(phaseName)) { logError("Invalid render phase %s in material %s", phaseName.c_str(), name.c_str()); return nullptr; } if (!parsePass(context, material->pass(phaseMap[phaseName]), pn)) { logError("Failed to parse pass for material %s", name.c_str()); return nullptr; } } return material; }