public void ExtractConstantDefs(String src, GpuProgramParameters.GpuNamedConstants defs, 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;
var currPos = src.IndexOf( "uniform" );
while (currPos != -1)
{
var def = new GpuProgramParameters.GpuConstantDefinition();
var paramName = "";
// Now check for using the word 'uniform' in a larger string & ignore
bool inLargerString = false;
if (currPos != 0)
{
var prev = src[currPos - 1];
if (prev != ' ' && prev != '\t' && prev != '\r' && prev != '\n'
&& prev != ';')
inLargerString = true;
}
if (!inLargerString && currPos + 7 < src.Length)
{
var next = src[currPos + 7];
if (next != ' ' && next != '\t' && next != '\r' && next != '\n')
inLargerString = true;
}
// skip 'uniform'
currPos += 7;
if (!inLargerString)
{
// find terminating semicolon
var endPos = src.IndexOf(';', currPos);
if (endPos == -1)
{
// problem, missing semicolon, abort
break;
}
line = src.Substring(currPos, endPos - currPos);
// Remove spaces before opening square braces, otherwise
// the following split() can split the line at inappropriate
// places (e.g. "vec3 something [3]" won't work).
for (var sqp = line.IndexOf(" ["); sqp != -1;
sqp = line.IndexOf(" ["))
line.Remove( sqp, 1 );
// Split into tokens
var parts = line.Split( ", \t\r\n".ToCharArray() );
foreach (var _i in parts)
{
var i = _i;
int typei;
if (typeEnumMap.TryGetValue( i, out typei ))
{
CompleteDefInfo(typei, def);
}
else
{
// if this is not a type, and not empty, it should be a name
i = i.Trim();
if (i == string.Empty)
continue;
var arrayStart = i.IndexOf('[');
if (arrayStart != -1)
{
// potential name (if butted up to array)
var name = i.Substring(0, arrayStart);
name = name.Trim();
if (name != string.Empty)
paramName = name;
var arrayEnd = i.IndexOf(']', arrayStart);
var arrayDimTerm = i.Substring(arrayStart + 1, arrayEnd - arrayStart - 1);
arrayDimTerm = arrayDimTerm.Trim();
// the array term might be a simple number or it might be
// an expression (e.g. 24*3) or refer to a constant expression
// we'd have to evaluate the expression which could get nasty
// TODO
def.ArraySize = int.Parse( arrayDimTerm );
}
else
{
paramName = i;
def.ArraySize = 1;
}
// Name should be after the type, so complete def and add
// We do this now so that comma-separated params will do
// this part once for each name mentioned
if (def.ConstantType == GpuProgramParameters.GpuConstantType.Unknown)
{
LogManager.Instance.Write(
"Problem parsing the following GLSL Uniform: '"
+ line + "' in file " + filename );
// next uniform
break;
}
// Complete def and add
// increment physical buffer location
def.LogicalIndex = 0; // not valid in GLSL
if (def.IsFloat)
{
def.PhysicalIndex = defs.FloatBufferSize;
defs.FloatBufferSize += /*def.ArraySize * def.ElementSize*/ 1;
}
else
{
def.PhysicalIndex = defs.IntBufferSize;
defs.IntBufferSize += /*def.ArraySize * def.ElementSize*/ 1;
}
defs.Map.Add(paramName, def);
// Axiom: This is not stable yet
//defs.GenerateConstantDefinitionArrayEntries(paramName, def);
}
}
}
// Find next one
currPos = src.IndexOf("uniform", currPos);
}
}