public void ParseConstantBuffer(String constantBufferString, int register, bool isGlobal) { m_IsGlobal = isGlobal; m_MemberConstants.Clear(); m_Register = register; char[] separator = { '\n' }; string[] lines = constantBufferString.Split(separator); CultureInfo ci = new CultureInfo("en-US", false); string types = ""; foreach (string type in ConstantTypeStrings) { types += types.Length == 0 ? type : "|" + type; } Regex variableRegex = new Regex(@"[ \t]*(" + types + @")[ \t]+(\w+);", RegexOptions.IgnoreCase); Regex paramRegex = new Regex(@"//[ \t]*Param(,[ \t]*\w+:?[ \t]*[\d\.\-]*)+", RegexOptions.IgnoreCase); Regex scriptedRegex = new Regex(@"//[ \t]*Scripted", RegexOptions.IgnoreCase); Regex paramOptionsRegex = new Regex(@",[ \t]*(\w+):?([ \t]*[\d\.\-]*)", RegexOptions.IgnoreCase); // Example /* // Param, Default: 1.0, Range:0.0-3.0, Linear */ int offset = 0; for (int it = 0; it < lines.Length; ++it) { string line = lines[it]; Match m = variableRegex.Match(line); if (m.Success) { string variableType = m.Groups[1].Value; string variableName = m.Groups[2].Value; ConstantType type = FindType(variableType); int byteSize = GetByteSizeOfType(type); // padding to next float4 int padding = Math.Min(byteSize, 16); if (offset % padding != 0) { offset += padding - offset % padding; } ConstantBufferPropertyField addedProperty = new ConstantBufferPropertyField(variableName, type, offset); Match paramMatch = paramRegex.Match(line); if (paramMatch.Success) { addedProperty.isParam = true; MatchCollection paramOptionsMatch = paramOptionsRegex.Matches(line); foreach (Match optionsMatch in paramOptionsMatch) { string optionName = optionsMatch.Groups[1].Value.ToLower(); string optionValue = optionsMatch.Groups[2].Value; switch (optionName) { case "default": { if (addedProperty.type != ConstantType.ConstantType_Float) { throw new Exception("Unsupported type yet"); } float value = Single.Parse(optionValue, ci.NumberFormat); addedProperty.paramValue = value; } break; case "gamma": { if (addedProperty.type != ConstantType.ConstantType_Float) { throw new Exception("Unsupported type yet"); } addedProperty.isGamma = true; } break; case "range": { if (addedProperty.type != ConstantType.ConstantType_Float) { throw new Exception("Unsupported type yet"); } char[] rangeSeparator = { '-' }; string[] splitStrings = optionValue.Split(rangeSeparator); float minValue = Single.Parse(splitStrings[0], ci.NumberFormat); float maxValue = Single.Parse(splitStrings[1], ci.NumberFormat); addedProperty.paramRangeMin = minValue; addedProperty.paramRangeMax = maxValue; } break; } } if (addedProperty.isGamma) { float paramValueToTransform = ((float)addedProperty.paramValue - addedProperty.paramRangeMin) / (addedProperty.paramRangeMax - addedProperty.paramRangeMin); paramValueToTransform = (float)Math.Pow((double)paramValueToTransform, 1.0 / 2.2); addedProperty.paramValue = paramValueToTransform * (addedProperty.paramRangeMax - addedProperty.paramRangeMin) + addedProperty.paramRangeMin; } } Match scriptedMatch = scriptedRegex.Match(line); if (scriptedMatch.Success) { addedProperty.isScripted = true; } m_MemberConstants.Add(variableName, addedProperty); offset += byteSize; } if (line.Contains("BEGINSCRIPT")) { string script = ""; bool finish = false; do { ++it; line = lines[it]; finish = line.Contains("ENDSCRIPT"); if (!finish) { script += line + "\n"; } } while (!finish); m_Script = script; } } // Final padding for whole buffer, after packing everything if (offset % 16 != 0) { offset += 16 - offset % 16; } m_Size = offset; }