#include "anki/resource/MaterialShaderProgramCreator.h" #include "anki/util/Assert.h" #include "anki/util/Exception.h" #include #include #include namespace anki { //============================================================================== MaterialShaderProgramCreator::MaterialShaderProgramCreator( const boost::property_tree::ptree& pt) { parseShaderProgramTag(pt); } //============================================================================== MaterialShaderProgramCreator::~MaterialShaderProgramCreator() {} //============================================================================== void MaterialShaderProgramCreator::parseShaderProgramTag( const boost::property_tree::ptree& pt) { using namespace boost::property_tree; BOOST_FOREACH(const ptree::value_type& v, pt) { if(v.first != "shader") { throw ANKI_EXCEPTION("Expected \"shader\" tag and not: " + v.first); } parseShaderTag(v.second); } source = srcLines.join("\n"); //std::cout << source << std::endl; } //============================================================================== void MaterialShaderProgramCreator::parseShaderTag( const boost::property_tree::ptree& pt) { using namespace boost::property_tree; // // // const std::string& type = pt.get("type"); srcLines.push_back("#pragma anki start " + type + "Shader"); // // // std::vector includeLines; const ptree& includesPt = pt.get_child("includes"); BOOST_FOREACH(const ptree::value_type& v, includesPt) { if(v.first != "include") { throw ANKI_EXCEPTION("Expected \"include\" tag and not: " + v.first); } const std::string& fname = v.second.data(); includeLines.push_back(std::string("#pragma anki include \"") + fname + "\""); } //std::sort(includeLines.begin(), includeLines.end(), compareStrings); srcLines.insert(srcLines.end(), includeLines.begin(), includeLines.end()); // // // boost::optional insPt = pt.get_child_optional("inputs"); if(insPt) { // Store the source of the uniform vars std::vector uniformsLines; BOOST_FOREACH(const ptree::value_type& v, insPt.get()) { if(v.first != "input") { throw ANKI_EXCEPTION("Expected \"input\" tag and not: " + v.first); } const ptree& inPt = v.second; std::string line; parseInputTag(inPt, line); uniformsLines.push_back(line); } // end for all ins srcLines.push_back(""); std::sort(uniformsLines.begin(), uniformsLines.end(), compareStrings); srcLines.insert(srcLines.end(), uniformsLines.begin(), uniformsLines.end()); } // // // srcLines.push_back("\nvoid main()\n{"); const ptree& opsPt = pt.get_child("operations"); BOOST_FOREACH(const ptree::value_type& v, opsPt) { if(v.first != "operation") { throw ANKI_EXCEPTION("Expected \"operation\" tag and not: " + v.first); } const ptree& opPt = v.second; parseOperationTag(opPt); } // end for all operations srcLines.push_back("}\n"); } //============================================================================== void MaterialShaderProgramCreator::parseInputTag( const boost::property_tree::ptree& pt, std::string& line) { using namespace boost::property_tree; const std::string& name = pt.get("name"); const std::string& type = pt.get("type"); line = "uniform " + type + " " + name + ";"; } //============================================================================== void MaterialShaderProgramCreator::parseOperationTag( const boost::property_tree::ptree& pt) { using namespace boost::property_tree; std::stringstream line; // int id = pt.get("id"); // boost::optional retTypeOpt = pt.get_optional("returnType"); if(retTypeOpt) { line << retTypeOpt.get() << " operationOut" << id << " = "; } // functionName const std::string& funcName = pt.get("function"); line << funcName << "("; // boost::optional argsPt = pt.get_child_optional("arguments"); StringList argsList; if(argsPt) { // Write all arguments ptree::const_iterator it = argsPt.get().begin(); for(; it != argsPt.get().end(); ++it) { const ptree::value_type& v = *it; if(v.first != "argument") { throw ANKI_EXCEPTION("Operation " + boost::lexical_cast(id) + ": Expected \"argument\" tag and not: " + v.first); } const std::string& argName = v.second.data(); argsList.push_back(argName); } line << argsList.join(", "); } line << ");"; srcLines.push_back("\t" + line.str()); } //============================================================================== bool MaterialShaderProgramCreator::compareStrings( const std::string& a, const std::string& b) { return a < b; } } // end namespace