public static PoiToonHeader Foldout(ShaderHeader header) { var style = new GUIStyle("ShurikenModuleTitle"); style.font = new GUIStyle(EditorStyles.label).font; style.border = new RectOffset(15, 7, 4, 4); style.fixedHeight = 22; style.contentOffset = new Vector2(20f, -2f); style.margin.left = 30 * header.xOffset; var rect = GUILayoutUtility.GetRect(16f + 20f, 22f, style); GUI.Box(rect, header.name, style); var e = Event.current; var toggleRect = new Rect(rect.x + 4f, rect.y + 2f, 13f, 13f); if (e.type == EventType.Repaint) { EditorStyles.foldout.Draw(toggleRect, false, false, header.header.getState(), false); } if (e.type == EventType.MouseDown && rect.Contains(e.mousePosition)) { header.header.Toggle(); e.Use(); } return(header.header); }
//function to handle the drawing of header or property void drawShaderPart(ShaderPart part, MaterialEditor materialEditor) { if (part is ShaderHeader) { ShaderHeader header = (ShaderHeader)part; drawShaderHeader(header, materialEditor); } else { ShaderProperty property = (ShaderProperty)part; drawShaderProperty(property, materialEditor); } }
void drawShaderHeader(ShaderHeader header, MaterialEditor materialEditor) { header.header = PoiToonUI.Foldout(header); if (header.header.getState()) { EditorGUILayout.Space(); foreach (ShaderPart part in header.parts) { drawShaderPart(part, materialEditor); } EditorGUILayout.Space(); } }
//draw header void drawShaderHeader(ShaderHeader header, MaterialEditor materialEditor) { //header.header = PoiToonUI.Foldout(header); header.guiElement.Foldout(header.xOffset, header.name, this); if (header.guiElement.getState()) { EditorGUILayout.Space(); foreach (ShaderPart part in header.parts) { drawShaderPart(part, materialEditor); } EditorGUILayout.Space(); } }
//-------------Init functions-------------------- //finds all properties and headers and stores them in correct order private void CollectAllProperties(MaterialProperty[] props, MaterialEditor materialEditor) { shaderparts = new ShaderHeader(); Stack <ShaderHeader> headerStack = new Stack <ShaderHeader>(); headerStack.Push(shaderparts); headerStack.Push(shaderparts); footer = new List <string>(); textureFieldsCount = 0; int headerCount = 0; for (int i = 0; i < props.Length; i++) { if (props[i].name.StartsWith("m_end") && props[i].flags == MaterialProperty.PropFlags.HideInInspector) { headerStack.Pop(); headerCount--; } else if (props[i].name.StartsWith("m_start") && props[i].flags == MaterialProperty.PropFlags.HideInInspector) { headerCount++; ShaderHeader newHeader = new ShaderHeader(props[i], materialEditor, headerCount); headerStack.Peek().addPart(newHeader); headerStack.Push(newHeader); } else if (props[i].name.StartsWith("m_") && props[i].flags == MaterialProperty.PropFlags.HideInInspector) { ShaderHeader newHeader = new ShaderHeader(props[i], materialEditor, headerCount); headerStack.Pop(); headerStack.Peek().addPart(newHeader); headerStack.Push(newHeader); } else if (props[i].name.StartsWith("footer_") && props[i].flags == MaterialProperty.PropFlags.HideInInspector) { footer.Add(props[i].displayName); } else if (props[i].flags != MaterialProperty.PropFlags.HideInInspector) { int extraOffset = 0; extraOffset = PoiHelper.propertyOptionToInt(EXTRA_OFFSET_OPTION, props[i]); string displayName = props[i].displayName.Replace("-" + EXTRA_OFFSET_OPTION + "=" + extraOffset, ""); ShaderProperty newPorperty = new ShaderProperty(props[i], displayName, headerCount + extraOffset); headerStack.Peek().addPart(newPorperty); if (props[i].type == MaterialProperty.PropType.Texture) { textureFieldsCount++; } } } }
public ShaderConfig(ShaderHeader header, IGpuAccessor gpuAccessor, TranslationFlags flags) { Stage = header.Stage; OutputTopology = header.OutputTopology; MaxOutputVertices = header.MaxOutputVertexCount; LocalMemorySize = header.ShaderLocalMemoryLowSize + header.ShaderLocalMemoryHighSize; ImapTypes = header.ImapTypes; OmapTargets = header.OmapTargets; OmapSampleMask = header.OmapSampleMask; OmapDepth = header.OmapDepth; GpuAccessor = gpuAccessor; Flags = flags; Size = 0; UsedFeatures = FeatureFlags.None; }
private void CollectAllProperties(MaterialProperty[] props, MaterialEditor materialEditor) { shaderparts = new ShaderHeader(null); Stack <ShaderHeader> headerStack = new Stack <ShaderHeader>(); headerStack.Push(shaderparts); headerStack.Push(shaderparts); int headerCount = 0; for (int i = 0; i < props.Length; i++) { //Debug.Log("Name: "+ props[i].name +",Display Name: " +props[i].displayName+ ",flags: "+ props[i].flags+",type: "+props[i].type); if (props[i].name.StartsWith("m_end") && props[i].flags == MaterialProperty.PropFlags.HideInInspector) { headerStack.Pop(); headerCount--; } else if (props[i].name.StartsWith("m_start") && props[i].flags == MaterialProperty.PropFlags.HideInInspector) { //Debug.Log("Header: " + props[i].displayName); headerCount++; ShaderHeader newHeader = new ShaderHeader(props[i], materialEditor, headerCount); headerStack.Peek().addPart(newHeader); headerStack.Push(newHeader); } else if (props[i].name.StartsWith("m_") && props[i].flags == MaterialProperty.PropFlags.HideInInspector) { //Debug.Log("Header: " + props[i].displayName); ShaderHeader newHeader = new ShaderHeader(props[i], materialEditor, headerCount); headerStack.Pop(); headerStack.Peek().addPart(newHeader); headerStack.Push(newHeader); } else if (props[i].flags != MaterialProperty.PropFlags.HideInInspector) { //Debug.Log("Property: " + props[i].displayName); int extraOffset = 0; extraOffset = propertyOptionToInt(EXTRA_OFFSET_OPTION, props[i]); string displayName = props[i].displayName.Replace("-" + EXTRA_OFFSET_OPTION + "=" + extraOffset, ""); ShaderProperty newPorperty = new ShaderProperty(props[i], displayName, headerCount + extraOffset); headerStack.Peek().addPart(newPorperty); } } }
//finds all properties and headers and stores them in correct order private void CollectAllProperties() { //load display names from file if it exists MaterialProperty[] props = current.properties; Dictionary <string, string> labels = LoadDisplayNamesFromFile(); LoadLocales(); current.propertyDictionary = new Dictionary <string, ShaderProperty>(); shaderparts = new ShaderHeader(); //init top object that all Shader Objects are childs of Stack <ShaderGroup> headerStack = new Stack <ShaderGroup>(); //header stack. used to keep track if current header to parent new objects to headerStack.Push(shaderparts); //add top object as top object to stack headerStack.Push(shaderparts); //add top object a second time, because it get's popped with first actual header item footer = new List <ButtonData>(); //init footer list int headerCount = 0; Type materialPropertyDrawerType = typeof(UnityEditor.Editor).Assembly.GetType("UnityEditor.MaterialPropertyHandler"); MethodInfo getPropertyHandlerMethod = materialPropertyDrawerType.GetMethod("GetShaderPropertyHandler", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy); PropertyInfo drawerProperty = materialPropertyDrawerType.GetProperty("propertyDrawer"); Type materialToggleDrawerType = typeof(UnityEditor.Editor).Assembly.GetType("UnityEditor.MaterialToggleDrawer"); FieldInfo keyWordField = materialToggleDrawerType.GetField("keyword", BindingFlags.Instance | BindingFlags.NonPublic); for (int i = 0; i < props.Length; i++) { string displayName = props[i].displayName; if (locale != null) { foreach (string key in locale.GetAllKeys()) { if (displayName.Contains("locale::" + key)) { displayName = displayName.Replace("locale::" + key, locale.Get(key)); } } } displayName = Regex.Replace(displayName, @"''", "\""); if (labels.ContainsKey(props[i].name)) { displayName = labels[props[i].name]; } PropertyOptions options = ExtractExtraOptionsFromDisplayName(ref displayName); int offset = options.offset + headerCount; //Handle keywords object propertyHandler = getPropertyHandlerMethod.Invoke(null, new object[] { current.shader, props[i].name }); //if has custom drawer if (propertyHandler != null) { object propertyDrawer = drawerProperty.GetValue(propertyHandler, null); //if custom drawer exists if (propertyDrawer != null) { if (propertyDrawer.GetType().ToString() == "UnityEditor.MaterialToggleDrawer") { object keyword = keyWordField.GetValue(propertyDrawer); if (keyword != null) { foreach (Material m in current.materials) { if (m.GetFloat(props[i].name) == 1) { m.EnableKeyword((string)keyword); } else { m.DisableKeyword((string)keyword); } } } } } } ThryPropertyType type = GetPropertyType(props[i], options); switch (type) { case ThryPropertyType.header: headerStack.Pop(); break; case ThryPropertyType.header_start: offset = options.offset + ++headerCount; break; case ThryPropertyType.header_end: headerStack.Pop(); headerCount--; break; case ThryPropertyType.on_swap_to: on_swap_to_actions = options.actions; break; } ShaderProperty newPorperty = null; switch (type) { case ThryPropertyType.master_label: masterLabelText = displayName; break; case ThryPropertyType.footer: footer.Add(Parser.ParseToObject <ButtonData>(displayName)); break; case ThryPropertyType.header: case ThryPropertyType.header_start: ShaderHeader newHeader = new ShaderHeader(props[i], current.editor, displayName, offset, options); headerStack.Peek().addPart(newHeader); headerStack.Push(newHeader); break; case ThryPropertyType.group_start: ShaderGroup new_group = new ShaderGroup(options); headerStack.Peek().addPart(new_group); headerStack.Push(new_group); break; case ThryPropertyType.group_end: headerStack.Pop(); break; case ThryPropertyType.none: case ThryPropertyType.property: DrawingData.lastPropertyUsedCustomDrawer = false; current.editor.GetPropertyHeight(props[i]); bool forceOneLine = props[i].type == MaterialProperty.PropType.Vector && !DrawingData.lastPropertyUsedCustomDrawer; if (props[i].type == MaterialProperty.PropType.Texture) { newPorperty = new TextureProperty(props[i], displayName, offset, options, props[i].flags != MaterialProperty.PropFlags.NoScaleOffset, !DrawingData.lastPropertyUsedCustomDrawer); } else { newPorperty = new ShaderProperty(props[i], displayName, offset, options, forceOneLine); } break; case ThryPropertyType.lightmap_flags: newPorperty = new GIProperty(props[i], displayName, offset, options, false); break; case ThryPropertyType.dsgi: newPorperty = new DSGIProperty(props[i], displayName, offset, options, false); break; case ThryPropertyType.instancing: newPorperty = new InstancingProperty(props[i], displayName, offset, options, false); break; case ThryPropertyType.locale: newPorperty = new LocaleProperty(props[i], displayName, offset, options, false); break; } if (newPorperty != null) { if (current.propertyDictionary.ContainsKey(props[i].name)) { continue; } current.propertyDictionary.Add(props[i].name, newPorperty); if (type != ThryPropertyType.none) { headerStack.Peek().addPart(newPorperty); } } } }
//finds all properties and headers and stores them in correct order private void CollectAllProperties() { //load display names from file if it exists MaterialProperty[] props = current.properties; Dictionary <string, string> labels = LoadDisplayNamesFromFile(); current.propertyDictionary = new Dictionary <string, ShaderProperty>(); shaderparts = new ShaderHeader(); //init top object that all Shader Objects are childs of Stack <ShaderHeader> headerStack = new Stack <ShaderHeader>(); //header stack. used to keep track if current header to parent new objects to headerStack.Push(shaderparts); //add top object as top object to stack headerStack.Push(shaderparts); //add top object a second time, because it get's popped with first actual header item footer = new List <ButtonData>(); //init footer list int headerCount = 0; for (int i = 0; i < props.Length; i++) { string displayName = props[i].displayName; displayName = Regex.Replace(displayName, @"''", "\""); if (labels.ContainsKey(props[i].name)) { displayName = labels[props[i].name]; } PropertyOptions options = ExtractExtraOptionsFromDisplayName(ref displayName); int offset = options.offset + headerCount; ThryPropertyType type = GetPropertyType(props[i]); switch (type) { case ThryPropertyType.header: headerStack.Pop(); break; case ThryPropertyType.header_start: offset = options.offset + ++headerCount; break; case ThryPropertyType.header_end: headerStack.Pop(); headerCount--; break; } switch (type) { case ThryPropertyType.footer: footer.Add(Parser.ParseToObject <ButtonData>(displayName)); break; case ThryPropertyType.header: case ThryPropertyType.header_start: ShaderHeader newHeader = new ShaderHeader(props[i], current.editor, displayName, offset, options); headerStack.Peek().addPart(newHeader); headerStack.Push(newHeader); break; case ThryPropertyType.property: ShaderProperty newPorperty = null; DrawingData.lastPropertyUsedCustomDrawer = false; current.editor.GetPropertyHeight(props[i]); bool forceOneLine = props[i].type == MaterialProperty.PropType.Vector && !DrawingData.lastPropertyUsedCustomDrawer; if (props[i].type == MaterialProperty.PropType.Texture) { newPorperty = new TextureProperty(props[i], displayName, offset, options, props[i].flags != MaterialProperty.PropFlags.NoScaleOffset, !DrawingData.lastPropertyUsedCustomDrawer); } else { newPorperty = new ShaderProperty(props[i], displayName, offset, options, forceOneLine); } headerStack.Peek().addPart(newPorperty); current.propertyDictionary.Add(props[i].name, newPorperty); break; case ThryPropertyType.lightmap_flags: current.draw_material_option_lightmap = true; break; case ThryPropertyType.dsgi: current.draw_material_option_dsgi = true; break; case ThryPropertyType.instancing: current.draw_material_option_instancing = true; break; } } }
//-------------Init functions-------------------- //finds all properties and headers and stores them in correct order private void CollectAllProperties() { //load display names from file if it exists MaterialProperty label_file_property = null; MaterialProperty[] props = current.properties; foreach (MaterialProperty m in props) { if (m.name == "shader_properties_label_file") { label_file_property = m; } } Dictionary <string, string> labels = new Dictionary <string, string>(); if (label_file_property != null) { string[] guids = AssetDatabase.FindAssets(label_file_property.displayName); if (guids.Length == 0) { Debug.LogError("Label File could not be found"); } string path = AssetDatabase.GUIDToAssetPath(guids[0]); string[] data = Regex.Split(Helper.ReadFileIntoString(path), @"\r?\n"); foreach (string d in data) { string[] set = Regex.Split(d, ":="); if (set.Length > 1) { labels[set[0]] = set[1]; } } } shaderparts = new ShaderHeader(); //init top object that all Shader Objects are childs of Stack <ShaderHeader> headerStack = new Stack <ShaderHeader>(); //header stack. used to keep track if current header to parent new objects to headerStack.Push(shaderparts); //add top object as top object to stack headerStack.Push(shaderparts); //add top object a second time, because it get's popped with first actual header item footer = new List <string>(); //init footer list int headerCount = 0; for (int i = 0; i < props.Length; i++) { //if property is a footer add to footer list if (props[i].name.StartsWith("footer_") && props[i].flags == MaterialProperty.PropFlags.HideInInspector) { footer.Add(props[i].displayName); //if property is end if a header block pop the top header } else if (props[i].name.StartsWith("m_end") && props[i].flags == MaterialProperty.PropFlags.HideInInspector) { headerStack.Pop(); headerCount--; } else //else add new object under current header { //get the display name out of property or file string displayName = props[i].displayName; if (labels.ContainsKey(props[i].name)) { displayName = labels[props[i].name]; } string ogDisplayName = displayName; //extract offset int extraOffset = Helper.propertyOptionToInt(EXTRA_OFFSET_OPTION, ogDisplayName); int offset = extraOffset + headerCount; displayName = displayName.Replace(EXTRA_OPTION_PREFIX + EXTRA_OFFSET_OPTION + EXTRA_OPTION_INFIX + extraOffset, ""); //extract on hover string onHover = Helper.getPropertyOptionValue(HOVER_OPTION, ogDisplayName); displayName = displayName.Replace(EXTRA_OPTION_PREFIX + HOVER_OPTION + EXTRA_OPTION_INFIX + onHover, ""); //extract alt click string altClick = Helper.getPropertyOptionValue(ON_ALT_CLICK_OPTION, ogDisplayName); displayName = displayName.Replace(EXTRA_OPTION_PREFIX + ON_ALT_CLICK_OPTION + EXTRA_OPTION_INFIX + altClick, ""); //if property is submenu add 1 extra offset if (props[i].name.StartsWith("m_start") && props[i].flags == MaterialProperty.PropFlags.HideInInspector) { offset = extraOffset + ++headerCount; } //if property is normal menu pop out if old header else if (props[i].name.StartsWith("m_") && props[i].flags == MaterialProperty.PropFlags.HideInInspector) { headerStack.Pop(); } //if proeprty is submenu or normal menu push in header stack if (props[i].name.StartsWith("m_") && props[i].flags == MaterialProperty.PropFlags.HideInInspector) { ShaderHeader newHeader = new ShaderHeader(props[i], current.editor, displayName, offset, onHover, altClick); headerStack.Peek().addPart(newHeader); headerStack.Push(newHeader); } //if property is actual property and not hidden add under current header else if (props[i].flags != MaterialProperty.PropFlags.HideInInspector) { ShaderProperty newPorperty = null; DrawingData.lastPropertyUsedCustomDrawer = false; current.editor.GetPropertyHeight(props[i]); if (props[i].type == MaterialProperty.PropType.Texture) { newPorperty = new TextureProperty(props[i], displayName, offset, onHover, altClick, !DrawingData.lastPropertyUsedCustomDrawer); } else { newPorperty = new ShaderProperty(props[i], displayName, offset, onHover, altClick); } headerStack.Peek().addPart(newPorperty); } } } }