| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 |
- #include "anki/resource/MaterialShaderProgramCreator.h"
- #include "anki/util/Assert.h"
- #include "anki/util/Exception.h"
- #include <boost/foreach.hpp>
- #include <boost/property_tree/ptree.hpp>
- #include <boost/lexical_cast.hpp>
- 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;
- //
- // <type></type>
- //
- const std::string& type = pt.get<std::string>("type");
- srcLines.push_back("#pragma anki start " + type + "Shader");
- //
- // <includes></includes>
- //
- std::vector<std::string> 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());
- //
- // <inputs></inputs>
- //
- boost::optional<const ptree&> insPt = pt.get_child_optional("inputs");
- if(insPt)
- {
- // Store the source of the uniform vars
- std::vector<std::string> 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());
- }
- //
- // <operations></operations>
- //
- 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<std::string>("name");
- const std::string& type = pt.get<std::string>("type");
- line = "uniform " + type + " " + name + ";";
- }
- //==============================================================================
- void MaterialShaderProgramCreator::parseOperationTag(
- const boost::property_tree::ptree& pt)
- {
- using namespace boost::property_tree;
-
- std::stringstream line;
- // <id></id>
- int id = pt.get<int>("id");
-
- // <returnType></returnType>
- boost::optional<std::string> retTypeOpt =
- pt.get_optional<std::string>("returnType");
-
- if(retTypeOpt)
- {
- line << retTypeOpt.get() << " operationOut" << id << " = ";
- }
-
- // <function>functionName</function>
- const std::string& funcName = pt.get<std::string>("function");
-
- line << funcName << "(";
-
- // <arguments></arguments>
- boost::optional<const ptree&> 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<std::string>(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
|