protected override async Task OnReferencedRNameChangedOverride(ResourceInfo referencedResInfo, EngineNS.RName newRName, EngineNS.RName oldRName) { if (referencedResInfo.ResourceType == EngineNS.Editor.Editor_RNameTypeAttribute.Texture) { ReferenceRNameList.Remove(oldRName); ReferenceRNameList.Add(referencedResInfo.ResourceName); await Save(); // mat bool bFinded = false; var mat = await EngineNS.CEngine.Instance.MaterialManager.GetMaterialAsync(EngineNS.CEngine.Instance.RenderContext, ResourceName); foreach (var param in mat.ParamList) { if (param.VarType == EngineNS.EShaderVarType.SVT_Texture && param.TextureRName.Equals(oldRName)) { param.SetValueStr(referencedResInfo.ResourceName); bFinded = true; } } mat.SaveMaterial(); // link if (bFinded) { var xndHolder = await EngineNS.IO.XndHolder.LoadXND(ResourceName.Address + EngineNS.Graphics.CGfxMaterial.ShaderLinkExtension); if (xndHolder != null) { var container = new CodeGenerateSystem.Base.NodesContainer(); await container.Load(xndHolder.Node); xndHolder.Node.TryReleaseHolder(); foreach (var node in container.CtrlNodeList) { if (node is Controls.TextureControl) { var tc = node as Controls.TextureControl; if (tc.TextureRName == oldRName) { tc.TextureRName = referencedResInfo.ResourceName; } } } var saveHolder = EngineNS.IO.XndHolder.NewXNDHolder(); container.Save(saveHolder.Node); EngineNS.IO.XndHolder.SaveXND(ResourceName.Address + EngineNS.Graphics.CGfxMaterial.ShaderLinkExtension, saveHolder); } } } }
protected override async Task <bool> InitializeContextMenuOverride(ContextMenu contextMenu) { await EngineNS.Thread.AsyncDummyClass.DummyFunc(); var textSeparatorStyle = Application.Current.MainWindow.TryFindResource(new ComponentResourceKey(typeof(ResourceLibrary.CustomResources), "TextMenuSeparatorStyle")) as System.Windows.Style; var menuItemStyle = Application.Current.MainWindow.TryFindResource(new ComponentResourceKey(typeof(ResourceLibrary.CustomResources), "MenuItem_Default")) as System.Windows.Style; contextMenu.Items.Add(new ResourceLibrary.Controls.Menu.TextSeparator() { Text = "Common", Style = textSeparatorStyle, }); var ciMenuItem = new MenuItem() { Name = "MatResInfo_CreateMatIns", Header = "创建材质实例", Style = menuItemStyle, }; ciMenuItem.Click += async(object sender, RoutedEventArgs e) => { var resInfo = new MaterialInstanceResourceInfo(); var win = new EditorCommon.Controls.ResourceBrowser.CreateResDialog(); win.Title = $"创建材质实例"; win.ResourceName = EditorCommon.Program.GetValidName(ResourceName.GetDirectory(), ResourceName.PureName() + "_ins", EngineNS.CEngineDesc.MaterialInstanceExtension); var data = new MaterialInstanceResourceCreateData() { ResourceName = win.ResourceName, ParentMaterial = this.ResourceName, }; win.ResCreateData = data; data.HostDialog = win; if (win.ShowDialog((value, cultureInfo) => { if (value == null) { return(new ValidationResult(false, "内容不合法")); } return(resInfo.ResourceNameAvailable(ResourceName.GetDirectory(), value.ToString())); }) == false) { return; } var createData = win.GetCreateData(); createData.RNameType = ResourceName.RNameType; var resourceInfo = await resInfo.CreateEmptyResource(ResourceName.GetDirectory(), ResourceName.GetRootFolder(), createData); var pro = resourceInfo.GetType().GetProperty("ResourceType"); pro?.SetValue(resourceInfo, EngineNS.Editor.Editor_RNameTypeAttribute.MaterialInstance); resourceInfo.ParentBrowser = this.ParentBrowser; await resourceInfo.Save(true); this.ParentBrowser.AddResourceInfo(resourceInfo); this.ParentBrowser.SelectResourceInfo(resourceInfo); await resourceInfo.InitializeContextMenu(); }; ResourceLibrary.Controls.Menu.MenuAssist.SetIcon(ciMenuItem, new BitmapImage(new System.Uri("pack://application:,,,/ResourceLibrary;component/Icons/Icons/AssetIcons/MaterialInstanceConstant_64x.png", UriKind.Absolute))); contextMenu.Items.Add(ciMenuItem); var duplicateMenuItem = new MenuItem() { Name = "MatResInfo_Duplicate", Header = $"复制", Style = menuItemStyle, }; duplicateMenuItem.Click += async(object sender, RoutedEventArgs e) => { var dir = ResourceName.GetDirectory(); var inputWin = new InputWindow.InputWindow(); inputWin.Title = $"复制{ResourceName.PureName()}"; inputWin.Description = "输入材质名称"; inputWin.Value = EditorCommon.Program.GetValidName(dir, ResourceName.PureName(), EngineNS.CEngineDesc.MaterialExtension); if (inputWin.ShowDialog((value, cultureInfo) => { if (value == null) { return(new ValidationResult(false, "内容不合法")); } return(ResourceNameAvailable(dir, value.ToString())); }) == false) { return; } var rc = EngineNS.CEngine.Instance.RenderContext; var tagRName = EngineNS.RName.EditorOnly_GetRNameFromAbsFile(dir + inputWin.Value + EngineNS.CEngineDesc.MaterialExtension); // mat var mat = await EngineNS.CEngine.Instance.MaterialManager.GetMaterialAsync(rc, ResourceName); var matCopy = EngineNS.CEngine.Instance.MaterialManager.NewMaterial(tagRName); mat.CopyTo(matCopy); matCopy.SaveMaterial(); // link var xndHolder = await EngineNS.IO.XndHolder.LoadXND(ResourceName.Address + EngineNS.Graphics.CGfxMaterial.ShaderLinkExtension); if (xndHolder != null) { var container = new CodeGenerateSystem.Base.NodesContainer(); await container.Load(xndHolder.Node); xndHolder.Node.TryReleaseHolder(); Controls.MaterialControl matCtrl = null; foreach (var node in container.OrigionNodeControls) { if (node is Controls.MaterialControl) { node.Id = Guid.NewGuid(); matCtrl = node as Controls.MaterialControl; } } System.IO.TextWriter codeFile, varFile; CodeGenerator.GenerateCode(container, matCtrl, out codeFile, out varFile); // var System.IO.File.WriteAllText(tagRName.Address + EngineNS.Graphics.CGfxMaterial.ShaderDefineExtension, varFile.ToString()); // code System.IO.File.WriteAllText(tagRName.Address + EngineNS.Graphics.CGfxMaterial.ShaderIncludeExtension, codeFile.ToString()); // link var tagHolder = EngineNS.IO.XndHolder.NewXNDHolder(); container.Save(tagHolder.Node); EngineNS.IO.XndHolder.SaveXND(tagRName.Address + EngineNS.Graphics.CGfxMaterial.ShaderLinkExtension, tagHolder); } // resInfo var copyedRInfo = new MaterialResourceInfo(); copyedRInfo.ResourceName = tagRName; await CopyResource(copyedRInfo); await copyedRInfo.Save(); // snapshot EngineNS.CEngine.Instance.FileManager.CopyFile(ResourceName.Address + EditorCommon.Program.SnapshotExt, tagRName.Address + EditorCommon.Program.SnapshotExt, true); await copyedRInfo.InitializeContextMenu(); ParentBrowser.AddResourceInfo(copyedRInfo); ParentBrowser.SelectResourceInfo(copyedRInfo); }; ResourceLibrary.Controls.Menu.MenuAssist.SetIcon(duplicateMenuItem, new BitmapImage(new System.Uri("pack://application:,,,/ResourceLibrary;component/Icons/Icons/icon_Edit_Duplicate_40x.png", UriKind.Absolute))); contextMenu.Items.Add(duplicateMenuItem); var menuItem = new MenuItem() { Name = "MatResInfo_Delete", Header = "删除", Style = menuItemStyle, }; menuItem.Click += async(object sender, RoutedEventArgs e) => { await DeleteResource(); EngineNS.CEngine.Instance.MaterialManager.Materials.Remove(ResourceName); }; ResourceLibrary.Controls.Menu.MenuAssist.SetIcon(menuItem, new BitmapImage(new System.Uri("pack://application:,,,/ResourceLibrary;component/Icons/Icons/icon_delete_16px.png", UriKind.Absolute))); contextMenu.Items.Add(menuItem); return(true); }
public static bool GenerateCode(CodeGenerateSystem.Base.NodesContainer container, Controls.MaterialControl setValueCtrl, out System.IO.TextWriter codeFile, out System.IO.TextWriter varFile) { codeFile = new System.IO.StringWriter(); varFile = new System.IO.StringWriter(); // #include... //string includeString = ""; //foreach (var node in container.CtrlNodeList) //{ // if (node is Controls.Operation.Function) // { // var funcCtrl = node as Controls.Operation.Function; // if (!includeString.Contains(funcCtrl.Include)) // includeString += "#include \"" + funcCtrl.Include + "\"\r\n"; // //tw.WriteLine("#include \"" + funcCtrl.Include + "\""); // } //} //codeFile.WriteLine(includeString); codeFile.WriteLine(""); // value Dictionary <EngineNS.EShaderVarType, List <Controls.BaseNodeControl_ShaderVar> > varNodeDic = new Dictionary <EngineNS.EShaderVarType, List <Controls.BaseNodeControl_ShaderVar> >(); foreach (var node in container.CtrlNodeList) { if (node is Controls.BaseNodeControl_ShaderVar) { var ctrl = node as Controls.BaseNodeControl_ShaderVar; if (ctrl.IsInConstantBuffer) { EngineNS.EShaderVarType varType = EngineNS.EShaderVarType.SVT_Unknown; var valueTypeStr = ctrl.GCode_GetTypeString(null, null); switch (valueTypeStr) { case "int": varType = EngineNS.EShaderVarType.SVT_Int1; break; case "int2": varType = EngineNS.EShaderVarType.SVT_Int2; break; case "int3": varType = EngineNS.EShaderVarType.SVT_Int3; break; case "int4": varType = EngineNS.EShaderVarType.SVT_Int4; break; case "float": case "float1": varType = EngineNS.EShaderVarType.SVT_Float1; break; case "float2": varType = EngineNS.EShaderVarType.SVT_Float2; break; case "float3": varType = EngineNS.EShaderVarType.SVT_Float3; break; case "float4": varType = EngineNS.EShaderVarType.SVT_Float4; break; } List <Controls.BaseNodeControl_ShaderVar> varList; if (!varNodeDic.TryGetValue(varType, out varList)) { varList = new List <Controls.BaseNodeControl_ShaderVar>(); varNodeDic[varType] = varList; } varList.Add(ctrl); //varFile.Write(ctrl.GetValueDefine()); } else { codeFile.Write(ctrl.GetValueDefine()); } } } codeFile.WriteLine(""); // 字节对齐 List <Controls.BaseNodeControl_ShaderVar> tempList; if (varNodeDic.TryGetValue(EngineNS.EShaderVarType.SVT_Float4, out tempList)) { foreach (var ctrl in tempList) { varFile.Write(ctrl.GetValueDefine()); } } if (varNodeDic.TryGetValue(EngineNS.EShaderVarType.SVT_Int4, out tempList)) { foreach (var ctrl in tempList) { varFile.Write(ctrl.GetValueDefine()); } } List <Controls.BaseNodeControl_ShaderVar> float1List; varNodeDic.TryGetValue(EngineNS.EShaderVarType.SVT_Float1, out float1List); if (float1List == null) { float1List = new List <Controls.BaseNodeControl_ShaderVar>(); } List <Controls.BaseNodeControl_ShaderVar> int1List; varNodeDic.TryGetValue(EngineNS.EShaderVarType.SVT_Int1, out int1List); if (int1List == null) { int1List = new List <Controls.BaseNodeControl_ShaderVar>(); } if (varNodeDic.TryGetValue(EngineNS.EShaderVarType.SVT_Float3, out tempList)) { foreach (var ctrl in tempList) { varFile.Write(ctrl.GetValueDefine()); if (float1List.Count > 0) { var floatVar = float1List[0]; varFile.Write(floatVar.GetValueDefine()); float1List.RemoveAt(0); } else if (int1List.Count > 0) { var intVar = int1List[0]; varFile.Write(intVar.GetValueDefine()); int1List.RemoveAt(0); } else { // 补位 var varName = ctrl.GCode_GetValueName(null, null); varFile.Write("float " + varName + "_fill;\r\n"); } } } if (varNodeDic.TryGetValue(EngineNS.EShaderVarType.SVT_Int3, out tempList)) { foreach (var ctrl in tempList) { varFile.Write(ctrl.GetValueDefine()); if (float1List.Count > 0) { var floatVar = float1List[0]; varFile.Write(floatVar.GetValueDefine()); float1List.RemoveAt(0); } else if (int1List.Count > 0) { var intVar = int1List[0]; varFile.Write(intVar.GetValueDefine()); int1List.RemoveAt(0); } else { // 补位 var varName = ctrl.GCode_GetValueName(null, null); varFile.Write("int1 " + varName + "_fill;\r\n"); } } } if (varNodeDic.TryGetValue(EngineNS.EShaderVarType.SVT_Float2, out tempList)) { foreach (var ctrl in tempList) { varFile.Write(ctrl.GetValueDefine()); } if ((tempList.Count % 2) != 0) { int float2fillCount = 2; while (float2fillCount > 0) { if (float1List.Count > 0) { var floatVar = float1List[0]; varFile.Write(floatVar.GetValueDefine()); float1List.RemoveAt(0); float2fillCount--; } else { break; } } while (float2fillCount > 0) { if (int1List.Count > 0) { var intVar = int1List[0]; varFile.Write(intVar.GetValueDefine()); int1List.RemoveAt(0); float2fillCount--; } else { break; } } if (float2fillCount > 0) { varFile.Write($"float{float2fillCount} SV_{EngineNS.Editor.Assist.GetValuedGUIDString(System.Guid.NewGuid())}_Fill;\r\n"); } } } if (varNodeDic.TryGetValue(EngineNS.EShaderVarType.SVT_Int2, out tempList)) { foreach (var ctrl in tempList) { varFile.Write(ctrl.GetValueDefine()); } if ((tempList.Count % 2) != 0) { int int2fillCount = 2; while (int2fillCount > 0) { if (float1List.Count > 0) { var floatVar = float1List[0]; varFile.Write(floatVar.GetValueDefine()); float1List.RemoveAt(0); int2fillCount--; } else { break; } } while (int2fillCount > 0) { if (int1List.Count > 0) { var intVar = int1List[0]; varFile.Write(intVar.GetValueDefine()); int1List.RemoveAt(0); int2fillCount--; } else { break; } } if (int2fillCount > 0) { varFile.Write($"int{int2fillCount} SV_{EngineNS.Editor.Assist.GetValuedGUIDString(System.Guid.NewGuid())}_Fill;\r\n"); } } } var fillCount = (float1List.Count + int1List.Count) % 4; var idxCount = float1List.Count + int1List.Count - fillCount; int idx = 0; if (idx < idxCount) { for (int i = float1List.Count - 1; i >= 0; i--) { var ctrl = float1List[i]; varFile.Write(ctrl.GetValueDefine()); float1List.RemoveAt(i); idx++; if (idx >= idxCount) { break; } } } if (idx < idxCount) { for (int i = int1List.Count - 1; i >= 0; i--) { var ctrl = int1List[i]; varFile.Write(ctrl.GetValueDefine()); int1List.RemoveAt(i); idx++; if (idx >= idxCount) { break; } } } if (fillCount > 0) { varFile.Write($"float{4 - fillCount} SV_{EngineNS.Editor.Assist.GetValuedGUIDString(System.Guid.NewGuid())}_FinalFill;\r\n"); } foreach (var ctrl in float1List) { varFile.Write(ctrl.GetValueDefine()); } foreach (var ctrl in int1List) { varFile.Write(ctrl.GetValueDefine()); } var idStr = EngineNS.Editor.Assist.GetValuedGUIDString(setValueCtrl.Id); // VS codeFile.WriteLine($"void DoVSMaterial_{idStr}(in PS_INPUT input, inout MTL_OUTPUT mtl)"); codeFile.WriteLine("{"); string strSegment = ""; string strDefinitionSegment = ""; setValueCtrl.GCode_GenerateCode_VS(ref strDefinitionSegment, ref strSegment, 1, null); codeFile.WriteLine(strDefinitionSegment + "\r\n"); codeFile.WriteLine(strSegment); codeFile.WriteLine("}"); // PS codeFile.WriteLine($"void DoPSMaterial_{idStr}(in PS_INPUT input, inout MTL_OUTPUT mtl)"); codeFile.WriteLine("{"); strSegment = ""; strDefinitionSegment = ""; setValueCtrl.GCode_GenerateCode_PS(ref strDefinitionSegment, ref strSegment, 1, null); codeFile.WriteLine(strDefinitionSegment + "\r\n"); codeFile.WriteLine(strSegment); codeFile.WriteLine("}"); codeFile.WriteLine($"#define DO_VS_MATERIAL DoVSMaterial_{idStr}"); codeFile.WriteLine($"#define DO_PS_MATERIAL DoPSMaterial_{idStr}"); return(true); }