static std::string FixShaderCode(char *text, int textLength, const UniformRules &uniformsRename, bool vertexShader) { struct ReplacePair { ReplacePair(const char *pat, const char *rep) : pattern(boost::xpressive::sregex::compile(pat, (boost::xpressive::regex_constants::ECMAScript | boost::xpressive::regex_constants::optimize))), replace(rep) { } boost::xpressive::sregex pattern; std::string replace; }; static const ReplacePair sFixPairs[] = { ReplacePair("\\.0+E\\+0+\\b", ".0"), ReplacePair("0*E\\+0+\\b", ""), ReplacePair("(\\d+)\\.([0-9][1-9])0*E\\+0+2\\b", "$1$2.0"), ReplacePair("(\\d+)\\.([1-9])0*E\\+0+1\\b", "$1$2.0"), ReplacePair("(\\d+)\\.0+E\\-0+1\\b", "0.$1"), ReplacePair("(\\d+)\\.00+E(\\+\\d+)\\b", "$1.0E$2"), ReplacePair("ATI_draw_buffers", "ARB_draw_buffers"), ReplacePair("\\:require\\n", ":enable\n"), ReplacePair("#version \\d+", ""), }; static const boost::xpressive::sregex structPattern(boost::xpressive::sregex::compile("\\bstruct\\s+(\\w+)\\s*{[^}]*};", (boost::xpressive::regex_constants::ECMAScript | boost::xpressive::regex_constants::optimize))); static const int subs[] = {1}; std::string newtext(text, textLength); // Find all the struct declarations std::list<std::string> structsList; boost::xpressive::sregex_token_iterator cur(newtext.begin(), newtext.end(), structPattern, subs); boost::xpressive::sregex_token_iterator end; for(; cur != end; ++cur ) { structsList.push_back(*cur); } // Remove unused struct declarations if (!structsList.empty()) { const std::list<std::string>::const_iterator itEnd(structsList.end()); for (std::list<std::string>::const_iterator it = structsList.begin(); it != itEnd; ++it) { const std::string &structName(*it); boost::xpressive::sregex_iterator cur(newtext.begin(), newtext.end(), (boost::xpressive::_b >> structName >> boost::xpressive::_b)); boost::xpressive::sregex_iterator end; int count = 0; for(; cur != end; ++cur, ++count) { } if (1 >= count) { const boost::xpressive::sregex removeStructPattern(boost::xpressive::sregex::compile("\\bstruct\\s+" + structName + "\\s*{[^}]*};")); newtext = regex_replace(newtext, removeStructPattern, std::string("")); } } structsList.clear(); } // Fix numbers and GLSL 'require's const size_t numPairs = sizeof(sFixPairs) / sizeof(ReplacePair); for (size_t n = 0; n < numPairs; n++) { newtext = regex_replace(newtext, sFixPairs[n].pattern, sFixPairs[n].replace); } // Fix names of uniform values const UniformRules::const_iterator itEnd(uniformsRename.end()); for (UniformRules::const_iterator it = uniformsRename.begin(); it != itEnd; ++it) { newtext = regex_replace(newtext, (it->first), (it->second)); } // Fix vertex attributes if (vertexShader) { struct AttributeReplaceRule { AttributeReplaceRule(const char *src, const char *dst, const char *tn) : re(boost::xpressive::_b >> src >> boost::xpressive::_b), replace(dst), typeName(tn) { } boost::xpressive::sregex re; std::string replace; const char *typeName; }; static const AttributeReplaceRule sAttributeReplaceRules[] = { AttributeReplaceRule("gl_Vertex", "ATTR0", "vec4"), AttributeReplaceRule("gl_Normal", "ATTR2", "vec3"), AttributeReplaceRule("gl_Color", "ATTR3", "vec4"), AttributeReplaceRule("gl_SecondaryColor", "ATTR4", "vec4"), AttributeReplaceRule("gl_FogCoord", "ATTR5", "float"), AttributeReplaceRule("gl_MultiTexCoord0", "ATTR8", "vec4"), AttributeReplaceRule("gl_MultiTexCoord1", "ATTR9", "vec4"), AttributeReplaceRule("gl_MultiTexCoord2", "ATTR10", "vec4"), AttributeReplaceRule("gl_MultiTexCoord3", "ATTR11", "vec4"), AttributeReplaceRule("gl_MultiTexCoord4", "ATTR12", "vec4"), AttributeReplaceRule("gl_MultiTexCoord5", "ATTR13", "vec4"), AttributeReplaceRule("gl_MultiTexCoord6", "ATTR14", "vec4"), AttributeReplaceRule("gl_MultiTexCoord7", "ATTR15", "vec4") }; const size_t numRules = sizeof(sAttributeReplaceRules) / sizeof(AttributeReplaceRule); for (size_t n = numRules; n--; ) { const AttributeReplaceRule &rule(sAttributeReplaceRules[n]); if (regex_search(newtext, rule.re)) { newtext = regex_replace(newtext, rule.re, rule.replace); newtext = std::string("attribute ") + rule.typeName + " " + rule.replace + ";" + newtext; } } }
std::string Regex::Match::replace(std::string rep, unsigned int index) { ReplaceMap tmp; tmp.insert(ReplacePair(index,rep)); return replace(tmp); }