//解析一段shader语句的编辑类型 public static void ParseEditorLineType(string line, ref EditorLineType lineType, ref int start, ref int end) { lineType = EditorLineType.NONE; start = -1; end = -1; Array linetypes = Enum.GetValues(typeof(EditorLineType)); for (int i = 0; i < linetypes.Length; i++) { EditorLineType curtype = (EditorLineType)linetypes.GetValue(i); if (curtype == EditorLineType.NONE) { continue; } else { string findKey = GetEditorLineTypeString(curtype); start = line.IndexOf(findKey); if (start >= 0) { lineType = GetEditorLineType(findKey); end = start + findKey.Length; } } } }
//根据语句的编辑类型返回标志文本 public static string GetEditorLineTypeString(EditorLineType lineType) { switch (lineType) { case EditorLineType.COMMENT_MARK: return(PRAGMA_COMMENT_MARK); case EditorLineType.DISABLED_MARK: return(PRAGMA_DISABLED_MARK); default: return(""); } }
//解析shader文本 public static void ScanShader(ref StripShader shader) { //重置shader shader.passes.Clear(); shader.keywords.Clear(); shader.hasBackup = File.Exists(shader.path + BACKUP_SUFFIX); shader.pendingChanges = false; shader.editedByShaderControl = false; //读取shader文本 string[] shaderLines = File.ReadAllLines(shader.path); string[] separator = new string[] { " " }; StripShaderPass currentPass = new StripShaderPass(); StripShaderPass basePass = null; int pass = -1; bool blockComment = false; StripKeywordLine keywordLine = new StripKeywordLine(); for (int k = 0; k < shaderLines.Length; k++) { //删除字符串头部和尾部的空格 string line = shaderLines[k].Trim(); if (line.Length == 0) { continue; } //是否是注释行 IsBlockCommentLine(line, ref blockComment); if (blockComment) { continue; } string lineUPPER = line.ToUpper(); if (lineUPPER.Equals("PASS") || lineUPPER.StartsWith("PASS ")) { if (pass >= 0) { currentPass.pass = pass; if (basePass != null) { currentPass.Add(basePass.keywordLines); } shader.Add(currentPass); } else if (currentPass.keywordCount > 0) { basePass = currentPass; } currentPass = new StripShaderPass(); pass++; continue; } //第一个注释符号 //的位置 int lineCommentIndex = CommentLineIndex(line); //编辑器添加的语句行信息 EditorLineType editorLine = EditorLineType.NONE; int editorStartIndex = -1; int editorEndIndex = -1; ParseEditorLineType(line, ref editorLine, ref editorStartIndex, ref editorEndIndex); //该行是注释行 并且不是被主动编辑的 跳过 if (lineCommentIndex == 0 && editorLine == EditorLineType.NONE) { continue; // 跳过注释 } //shader关键字语句行信息 ShaderLineType shaderLine = ShaderLineType.NONE; int keyStartIndex = -1; int keyEndIndex = -1; ParseShaderLineType(line, ref shaderLine, ref keyStartIndex, ref keyEndIndex); //并非是被程序编辑过的 if (editorLine == EditorLineType.NONE) { //如果是手写输入的关键字 if (IsInputShortcut(shaderLine)) { keyStartIndex = Mathf.Max(0, keyStartIndex); keyEndIndex = Mathf.Max(0, keyEndIndex); //检查PRAGMA 关键字之后的字符串是否包含注释 int commentindex = CommentLineIndex(line, keyStartIndex + keyEndIndex); if (commentindex < 0) { commentindex = line.Length; } int length = commentindex - (keyStartIndex + keyEndIndex); //用空格分割 PRAGMA语句到//注释符号之间的语句 string[] splitedKeys = line.Substring(keyStartIndex + keyEndIndex, length).Split(separator, StringSplitOptions.RemoveEmptyEntries); if (splitedKeys.Length > 0) { keywordLine = new StripKeywordLine(); //是剔除字段 bool isSkip = shaderLine == ShaderLineType.SKIP_VARIANTS; currentPass.hasSkipKeyword = isSkip?isSkip:currentPass.hasSkipKeyword; //添加手写关键字 for (int i = 0; i < splitedKeys.Length; i++) { splitedKeys[i] = splitedKeys[i].Trim(); StripKeyword keyword = keywordLine.GetKeyword(splitedKeys[i]); if (keyword == null) { keyword = new StripKeyword(splitedKeys[i]); } keyword.enabled = true; keyword.isSkip = isSkip; keywordLine.Add(keyword); } keywordLine.editorLineType = editorLine; keywordLine.shaderLineType = shaderLine; currentPass.Add(keywordLine); } } else //添加缩写marco的内置关键字 if (IsBuiltinShortcut(shaderLine)) { keywordLine = new StripKeywordLine(); string[] buildinkeys = GetShortcutKeywords(shaderLine); for (int i = 0; i < buildinkeys.Length; i++) { StripKeyword keyword = keywordLine.GetKeyword(buildinkeys[i]); if (keyword == null) { keyword = new StripKeyword(buildinkeys[i]); } keyword.enabled = true; keyword.isSkip = false; keywordLine.Add(keyword); } keywordLine.editorLineType = editorLine; keywordLine.shaderLineType = shaderLine; currentPass.Add(keywordLine); } } } currentPass.pass = Mathf.Max(pass, 0); if (basePass != null) { currentPass.Add(basePass.keywordLines); } shader.Add(currentPass); shader.UpdateVariantCount(); }