Switch-Toolbox/Switch_FileFormatsMain/GUI/BFRES/BfresMaterialEditor.cs
KillzXGaming 716d1c4520 More clean up and additions
- Starting to make all texture classes use STGenericTexture. This will make all functions usable between each one and converting through other classes much easier.
- Many bug fixes to the texture importer like duped texture importing, dds opening the window, index out of range issues, etc.
- Start on titlebar information.
- Start on ASTC texture format support.
- Support TGA images.
- Support FTEX importing and saving properly.
- Export models properly along with textures (with generic classes). Todo, support rigs and bones.
2018-12-10 18:48:51 -05:00

579 lines
21 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using WeifenLuo.WinFormsUI.Docking;
using Syroot.NintenTools.NSW.Bfres;
using OpenTK;
using Switch_Toolbox.Library;
using Bfres.Structs;
namespace FirstPlugin
{
public partial class FMATEditor : UserControl
{
public FMAT material;
public ImageList textureImageList;
public string SelectedMatParam = "";
public ImageList il = new ImageList();
public FMATEditor()
{
InitializeComponent();
textureImageList = new ImageList()
{
ColorDepth = ColorDepth.Depth32Bit,
ImageSize = new Size(70, 70),
};
if (!Runtime.IsDebugMode)
{
textBoxShaderArchive.ReadOnly = true;
textBoxShaderModel.ReadOnly = true;
}
shaderOptionsListView.ListViewItemSorter = new Sorter();
}
private void listView_DrawItem(object sender, DrawListViewItemEventArgs e)
{
}
public void LoadMaterial(FMAT mat)
{
material = mat;
textBoxMaterialName.Text = material.Text;
SetActiveGameByShader(material.shaderassign.ShaderArchive, material.shaderassign.ShaderModel);
chkboxVisible.Checked = mat.Enabled;
FillForm();
}
private void SetActiveGameByShader(string ShaderName, string ShaderMdlName)
{
textBoxShaderArchive.Text = ShaderName;
textBoxShaderModel.Text = ShaderMdlName;
}
public void FillForm()
{
InitializeTextureListView(material);
InitializeRenderInfoList(material);
InitializeShaderParamList(material);
InitializeShaderOptionList(material);
}
private string SetValueToString(object values)
{
if (values is float[])
return string.Join(" , ", values as float[]);
else if (values is bool[])
return string.Join(" , ", values as bool[]);
else if (values is int[])
return string.Join(" , ", values as int[]);
else if (values is uint[])
return string.Join(" , ", values as uint[]);
else
return "";
}
private void InitializeShaderOptionList(FMAT material)
{
shaderOptionsListView.Items.Clear();
foreach (var option in material.shaderassign.options)
{
shaderOptionsListView.Items.Add(option.Key).SubItems.Add(option.Value);
}
}
private void InitializeShaderParamList(FMAT material)
{
listView1.Items.Clear();
int CurParam = 0;
foreach (var prm in material.matparam.Values)
{
string DisplayValue = "";
var item = new ListViewItem(prm.Name);
Color SetColor = Color.FromArgb(40, 40, 40);
Vector4 col = new Vector4();
bool IsColor = prm.Name.Contains("Color") ||
prm.Name.Contains("color") ||
prm.Name.Contains("konst0") ||
prm.Name.Contains("konst1") ||
prm.Name.Contains("konst2") ||
prm.Name.Contains("konst3");
switch (prm.Type)
{
case ShaderParamType.Float:
case ShaderParamType.Float2:
case ShaderParamType.Float2x2:
case ShaderParamType.Float2x3:
case ShaderParamType.Float2x4:
case ShaderParamType.Float3x2:
case ShaderParamType.Float3x3:
case ShaderParamType.Float3x4:
case ShaderParamType.Float4x2:
case ShaderParamType.Float4x3:
case ShaderParamType.Float4x4:
DisplayValue = SetValueToString(prm.ValueFloat);
break;
case ShaderParamType.Float3:
DisplayValue = SetValueToString(prm.ValueFloat);
col = new Vector4(prm.ValueFloat[0], prm.ValueFloat[1], prm.ValueFloat[2], 1);
break;
case ShaderParamType.Float4:
DisplayValue = SetValueToString(prm.ValueFloat);
col = new Vector4(prm.ValueFloat[0], prm.ValueFloat[1], prm.ValueFloat[2], prm.ValueFloat[3]);
break;
}
if (IsColor)
{
int someIntX = (int)Math.Ceiling(col.X * 255);
int someIntY = (int)Math.Ceiling(col.Y * 255);
int someIntZ = (int)Math.Ceiling(col.Z * 255);
int someIntW = (int)Math.Ceiling(col.W * 255);
if (someIntX <= 255 && someIntY <= 255 && someIntZ <= 255 && someIntW <= 255)
{
Console.WriteLine($"{prm.Name} R {someIntX} G {someIntY} B {someIntZ}");
SetColor = Color.FromArgb(
255,
someIntX,
someIntY,
someIntZ
);
}
}
item.UseItemStyleForSubItems = false;
item.SubItems.Add(DisplayValue);
item.SubItems.Add("");
item.SubItems[2].BackColor = SetColor;
listView1.View = View.Details;
listView1.Items.Add(item);
CurParam++;
}
il.ImageSize = new Size(10, 10);
listView1.SmallImageList = il;
listView1.FullRowSelect = true;
}
public void InitializeTextureListView(FMAT material)
{
textureRefListView.Items.Clear();
textureRefListView.SmallImageList = textureImageList;
textureRefListView.FullRowSelect = true;
foreach (MatTexture tex in material.TextureMaps)
{
ListViewItem item = new ListViewItem();
item.Text = tex.Name;
item.SubItems.Add(tex.SamplerName);
if (material.shaderassign.samplers.ContainsValue(tex.SamplerName))
{
var FragSampler = material.shaderassign.samplers.FirstOrDefault(x => x.Value == tex.SamplerName).Key;
item.SubItems.Add(FragSampler.ToString());
}
textureRefListView.Items.Add(item);
}
textureImageList.Images.Clear();
int CurTex = 0;
if (PluginRuntime.bntxContainers.Count == 0 &&
PluginRuntime.ftexContainers.Count == 0)
{
foreach (ListViewItem item in textureRefListView.Items)
{
AddBlankTexture(item, item.Text, CurTex++);
}
}
bool FoundTexture = false;
foreach (ListViewItem item in textureRefListView.Items)
{
foreach (BNTX bntx in PluginRuntime.bntxContainers)
{
if (bntx.Textures.ContainsKey(item.Text))
{
FoundTexture = true;
TextureData tex = bntx.Textures[item.Text];
TextureData.BRTI_Texture renderedTex = tex.renderedGLTex;
Bitmap temp = tex.GLTextureToBitmap(renderedTex, renderedTex.display);
textureImageList.Images.Add(tex.Text, temp);
item.ImageIndex = CurTex++;
var dummy = textureImageList.Handle;
temp.Dispose();
}
}
foreach (FTEXContainer ftexCont in PluginRuntime.ftexContainers)
{
if (ftexCont.Textures.ContainsKey(item.Text))
{
FoundTexture = true;
FTEX tex = ftexCont.Textures[item.Text];
FTEX.RenderableTex renderedTex = tex.renderedTex;
Bitmap temp = tex.GLTextureToBitmap(renderedTex, renderedTex.display);
textureImageList.Images.Add(tex.Text, temp);
item.ImageIndex = CurTex++;
var dummy = textureImageList.Handle;
temp.Dispose();
}
}
if (FoundTexture == false)
{
AddBlankTexture(item, item.Text, CurTex++);
}
}
}
private void AddBlankTexture(ListViewItem item, string Name, int ImageIndex)
{
Bitmap temp = new Bitmap(Properties.Resources.TextureError);
textureImageList.Images.Add(Name, temp);
item.ImageIndex = ImageIndex;
var dummy = textureImageList.Handle;
temp.Dispose();
}
private void InitializeRenderInfoList(FMAT material)
{
renderInfoListView.Items.Clear();
foreach (var rnd in material.renderinfo)
{
ListViewItem item = new ListViewItem();
item.Text = rnd.Name;
string Value = "";
switch (rnd.Type)
{
case RenderInfoType.Int32:
Value = string.Join(",", rnd.ValueInt);
break;
case RenderInfoType.Single:
Value = string.Join(",", rnd.ValueFloat);
break;
case RenderInfoType.String:
Value = string.Join(",", rnd.ValueString);
break;
}
item.SubItems.Add(Value);
item.SubItems.Add(rnd.Type.ToString());
renderInfoListView.Items.Add(item);
}
renderInfoListView.FullRowSelect = true;
}
private void textureRefListView_DrawItem(object sender, DrawListViewItemEventArgs e)
{
e.DrawDefault = true;
if ((e.ItemIndex % 2) == 1)
{
e.Item.BackColor = Color.FromArgb(50, 50, 50);
e.Item.UseItemStyleForSubItems = true;
}
}
private void FSHPEditor_DockStateChanged(object sender, EventArgs e)
{
DockContent doc = sender as DockContent;
if (doc != null)
{
PluginRuntime.FSHPDockState = doc.DockState;
Console.WriteLine(doc.DockState);
Console.WriteLine(doc);
if (doc.DockState != DockState.Unknown)
Config.Save();
}
}
private void textureMapTab_DoubleClick(object sender, EventArgs e)
{
}
private void textureRefListView_DoubleClick(object sender, EventArgs e)
{
Console.WriteLine("click");
int index = textureRefListView.SelectedIndices[0];
Texture_Selector tex = new Texture_Selector();
tex.LoadTexture(material.GetResFileU() != null);
if (tex.ShowDialog() == DialogResult.OK)
{
material.TextureMaps[index].Name = tex.GetSelectedTexture();
InitializeTextureListView(material);
material.UpdateTextureMaps();
}
}
private void textureRefListView_DrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e)
{
using (SolidBrush backBrush = new SolidBrush(Color.FromArgb(50, 50, 50)))
{
e.Graphics.FillRectangle(backBrush, e.Bounds);
}
using (SolidBrush foreBrush = new SolidBrush(Color.FromArgb(255, 255, 255)))
{
e.Graphics.DrawString(e.Header.Text, e.Font, foreBrush, e.Bounds);
}
}
private void listView1_DoubleClick(object sender, EventArgs e)
{
if (listView1.SelectedItems.Count > 0)
{
if (material.matparam.ContainsKey(listView1.SelectedItems[0].Text))
{
int index = listView1.SelectedIndices[0];
SetParamDialog paramDialog = new SetParamDialog();
paramDialog.LoadParam(material.matparam[listView1.SelectedItems[0].Text]);
if (paramDialog.ShowDialog() == DialogResult.OK)
{
paramDialog.SetValues();
InitializeShaderParamList(material);
listView1.Items[index].Selected = true;
}
}
}
}
private void smallToolStripMenuItem_Click(object sender, EventArgs e)
{
/*Font normalfont = new Font("Microsoft Sans Serif", 10f);
foreach (ListViewItem lvi in listView1.Items) lvi.Font = normalfont;
foreach (ListViewItem lvi in listView1.Items) lvi.SubItems[0].Font = normalfont;
SetHeight(listView1, 11);*/
}
private void SetHeight(ListView listView, int height)
{
ImageList imgList = new ImageList();
imgList.ImageSize = new Size(1, height);
listView.SmallImageList = imgList;
}
private void mediumToolStripMenuItem_Click(object sender, EventArgs e)
{
}
private void largeToolStripMenuItem_Click(object sender, EventArgs e)
{
}
private void renderInfoListView_DoubleClick(object sender, EventArgs e)
{
int ActiveInfoIndex = renderInfoListView.SelectedIndices[0];
if (renderInfoListView.SelectedItems.Count > 0)
{
foreach (var info in material.renderinfo)
{
if (info.Name == renderInfoListView.SelectedItems[0].Text)
{
RenderInfoValueEditor editor = new RenderInfoValueEditor();
editor.LoadValues(info);
if (editor.ShowDialog() == DialogResult.OK)
{
info.ValueFloat = editor.valueFloats.ToArray();
info.ValueString = editor.valueStrings.ToArray();
info.ValueInt = editor.valueInts.ToArray();
ListViewItem item = new ListViewItem();
item.Text = info.Name;
string Value = "";
switch (info.Type)
{
case RenderInfoType.Int32:
Value = string.Join(",", info.ValueInt);
break;
case RenderInfoType.Single:
Value = string.Join(",", info.ValueFloat);
break;
case RenderInfoType.String:
Value = string.Join(",", info.ValueString);
break;
}
item.SubItems.Add(Value);
item.SubItems.Add(info.Type.ToString());
// renderInfoListView.Items[ActiveInfoIndex] = item;
// InitializeRenderInfoList(material);
}
}
}
}
}
private void btnExportParams_Click(object sender, EventArgs e)
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "Material Params|*.xml;";
sfd.DefaultExt = ".xml";
sfd.FileName = material.Text + ".MatParams";
if (sfd.ShowDialog() == DialogResult.OK)
{
FMAT2XML.Save(material, sfd.FileName, true);
}
}
private void btnReplaceParams_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "Material Params|*.xml;";
ofd.DefaultExt = ".xml";
ofd.FileName = material.Text + ".MatParams";
if (ofd.ShowDialog() == DialogResult.OK)
{
FMAT2XML.Read(material, ofd.FileName, true);
}
}
private void shaderOptionsListView_DoubleClick(object sender, EventArgs e)
{
int ActiveIndex = shaderOptionsListView.SelectedIndices[0];
if (shaderOptionsListView.SelectedItems.Count > 0)
{
string Key = shaderOptionsListView.SelectedItems[0].Text;
string Value = shaderOptionsListView.SelectedItems[0].SubItems[1].Text;
BfresShaderOptionsEditor edtior = new BfresShaderOptionsEditor();
edtior.LoadOption(Key, Value);
if (edtior.ShowDialog() == DialogResult.OK)
{
material.shaderassign.options[shaderOptionsListView.SelectedItems[0].Text] = edtior.textBoxValue.Text;
InitializeShaderOptionList(material);
shaderOptionsListView.Items[ActiveIndex].Selected = true;
shaderOptionsListView.Select();
}
}
}
private void chkboxVisible_CheckedChanged(object sender, EventArgs e)
{
material.Enabled = chkboxVisible.Checked;
}
private void btnSamplerEditor_Click(object sender, EventArgs e)
{
if (textureRefListView.SelectedItems.Count <= 0)
return;
SamplerEditor samplerEditor = new SamplerEditor();
foreach (MatTexture tex in material.TextureMaps)
{
if (tex.Name == textureRefListView.SelectedItems[0].Text)
{
samplerEditor.LoadSampler(tex);
}
}
if (samplerEditor.ShowDialog() == DialogResult.OK)
{
}
}
private void textureRefListView_SelectedIndexChanged(object sender, EventArgs e)
{
if (textureRefListView.SelectedItems.Count > 0)
btnSamplerEditor.Enabled = true;
else
btnSamplerEditor.Enabled = false;
}
private void shaderOptionsListView_ColumnClick(object sender, ColumnClickEventArgs e)
{
Sorter s = (Sorter)shaderOptionsListView.ListViewItemSorter;
s.Column = e.Column;
if (s.Order == SortOrder.Ascending)
{
s.Order = SortOrder.Descending;
}
else
{
s.Order = SortOrder.Ascending;
}
shaderOptionsListView.Sort();
}
class Sorter : System.Collections.IComparer
{
public int Column = 0;
public System.Windows.Forms.SortOrder Order = SortOrder.Ascending;
public int Compare(object x, object y) // IComparer Member
{
if (!(x is ListViewItem))
return (0);
if (!(y is ListViewItem))
return (0);
ListViewItem l1 = (ListViewItem)x;
ListViewItem l2 = (ListViewItem)y;
if (l1.ListView.Columns[Column].Tag == null)
{
l1.ListView.Columns[Column].Tag = "Text";
}
if (l1.ListView.Columns[Column].Tag.ToString() == "Numeric")
{
float fl1 = float.Parse(l1.SubItems[Column].Text);
float fl2 = float.Parse(l2.SubItems[Column].Text);
if (Order == SortOrder.Ascending)
{
return fl1.CompareTo(fl2);
}
else
{
return fl2.CompareTo(fl1);
}
}
else
{
string str1 = l1.SubItems[Column].Text;
string str2 = l2.SubItems[Column].Text;
if (Order == SortOrder.Ascending)
{
return str1.CompareTo(str2);
}
else
{
return str2.CompareTo(str1);
}
}
}
}
}
}