//--------------------------------------------------------------------- void GLSLProgramManagerCommon::extractConstantDefs(const String& src, GpuNamedConstants& defs, const String& filename) { // Parse the output string and collect all uniforms // NOTE this relies on the source already having been preprocessed // which is done in GLSLProgram::loadFromSource String line; String::size_type currPos = src.find("uniform"); while (currPos != String::npos) { // Now check for using the word 'uniform' in a larger string & ignore bool inLargerString = false; if (currPos != 0) { char prev = src.at(currPos - 1); if (prev != ' ' && prev != '\t' && prev != '\r' && prev != '\n' && prev != ';') inLargerString = true; } if (!inLargerString && currPos + 7 < src.size()) { char next = src.at(currPos + 7); if (next != ' ' && next != '\t' && next != '\r' && next != '\n') inLargerString = true; } // skip 'uniform' currPos += 7; if (!inLargerString) { String::size_type endPos; GpuSharedParametersPtr blockSharedParams; // Check for a type. If there is one, then the semicolon is missing // otherwise treat as if it is a uniform block String::size_type lineEndPos = src.find_first_of("\n\r", currPos); line = src.substr(currPos, lineEndPos - currPos); StringVector parts = StringUtil::split(line, " \t"); StringToEnumMap::iterator typei = mTypeEnumMap.find(parts.front()); if (typei == mTypeEnumMap.end()) { // Gobble up the external name String externalName = parts.front(); // Now there should be an opening brace String::size_type openBracePos = src.find("{", currPos); if (openBracePos != String::npos) { currPos = openBracePos + 1; } else { LogManager::getSingleton().logMessage("Missing opening brace in GLSL Uniform Block in file " + filename); break; } // First we need to find the internal name for the uniform block String::size_type endBracePos = src.find("}", currPos); // Find terminating semicolon currPos = endBracePos + 1; endPos = src.find(";", currPos); if (endPos == String::npos) { // problem, missing semicolon, abort break; } // TODO: We don't need the internal name. Just skip over to the end of the block // But we do need to know if this is an array of blocks. Is that legal? // Find the internal name. // This can be an array. // line = src.substr(currPos, endPos - currPos); // StringVector internalParts = StringUtil::split(line, ", \t\r\n"); // String internalName = ""; // uint16 arraySize = 0; // for (StringVector::iterator i = internalParts.begin(); i != internalParts.end(); ++i) // { // StringUtil::trim(*i); // String::size_type arrayStart = i->find("[", 0); // if (arrayStart != String::npos) // { // // potential name (if butted up to array) // String name = i->substr(0, arrayStart); // StringUtil::trim(name); // if (!name.empty()) // internalName = name; // // String::size_type arrayEnd = i->find("]", arrayStart); // String arrayDimTerm = i->substr(arrayStart + 1, arrayEnd - arrayStart - 1); // StringUtil::trim(arrayDimTerm); // arraySize = StringConverter::parseUnsignedInt(arrayDimTerm); // } // else // { // internalName = *i; // } // } // // // Ok, now rewind and parse the individual uniforms in this block // currPos = openBracePos + 1; // blockSharedParams = GpuProgramManager::getSingleton().getSharedParameters(externalName); // if(blockSharedParams.isNull()) // blockSharedParams = GpuProgramManager::getSingleton().createSharedParameters(externalName); // do // { // lineEndPos = src.find_first_of("\n\r", currPos); // endPos = src.find(";", currPos); // line = src.substr(currPos, endPos - currPos); // // // TODO: Give some sort of block id // // Parse the normally structured uniform // parseIndividualConstant(src, defs, currPos, filename, blockSharedParams); // currPos = lineEndPos + 1; // } while (endBracePos > currPos); } else { // find terminating semicolon endPos = src.find(";", currPos); if (endPos == String::npos) { // problem, missing semicolon, abort break; } parseIndividualConstant(src, defs, currPos, filename, blockSharedParams); } line = src.substr(currPos, endPos - currPos); } // not commented or a larger symbol // Find next one currPos = src.find("uniform", currPos); } }
//--------------------------------------------------------------------- void GLSLESProgramManagerCommon::extractConstantDefs(const String& src, GpuNamedConstants& defs, const String& filename) { // Parse the output string and collect all uniforms // NOTE this relies on the source already having been preprocessed // which is done in GLSLESProgram::loadFromSource String line; String::size_type currPos = src.find("uniform"); while (currPos != String::npos) { GpuConstantDefinition def; String paramName; // Now check for using the word 'uniform' in a larger string & ignore bool inLargerString = false; if (currPos != 0) { char prev = src.at(currPos - 1); if (prev != ' ' && prev != '\t' && prev != '\r' && prev != '\n' && prev != ';') inLargerString = true; } if (!inLargerString && currPos + 7 < src.size()) { char next = src.at(currPos + 7); if (next != ' ' && next != '\t' && next != '\r' && next != '\n') inLargerString = true; } // skip 'uniform' currPos += 7; if (!inLargerString) { String::size_type endPos; String typeString; GpuSharedParametersPtr blockSharedParams; // Check for a type. If there is one, then the semicolon is missing // otherwise treat as if it is a uniform block String::size_type lineEndPos = src.find_first_of("\n\r", currPos); line = src.substr(currPos, lineEndPos - currPos); StringVector parts = StringUtil::split(line, " \t"); // Skip over precision keywords if(StringUtil::match((parts.front()), "lowp") || StringUtil::match((parts.front()), "mediump") || StringUtil::match((parts.front()), "highp")) typeString = parts[1]; else typeString = parts[0]; StringToEnumMap::iterator typei = mTypeEnumMap.find(typeString); if (typei == mTypeEnumMap.end()) { // Gobble up the external name String externalName = parts.front(); // Now there should be an opening brace String::size_type openBracePos = src.find("{", currPos); if (openBracePos != String::npos) { currPos = openBracePos + 1; } else { LogManager::getSingleton().logMessage("Missing opening brace in GLSL Uniform Block in file " + filename); break; } // First we need to find the internal name for the uniform block String::size_type endBracePos = src.find("}", currPos); // Find terminating semicolon currPos = endBracePos + 1; endPos = src.find(";", currPos); if (endPos == String::npos) { // problem, missing semicolon, abort break; } } else { // find terminating semicolon endPos = src.find(";", currPos); if (endPos == String::npos) { // problem, missing semicolon, abort break; } parseIndividualConstant(src, defs, currPos, filename, blockSharedParams); } line = src.substr(currPos, endPos - currPos); } // not commented or a larger symbol // Find next one currPos = src.find("uniform", currPos); } }