EveryFileExplorer/NDS/UI/NSBMDViewer.cs
2015-01-08 17:24:43 +01:00

338 lines
9.4 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.Windows.Forms;
using Tao.OpenGl;
using LibEveryFileExplorer._3D;
using System.Drawing.Imaging;
using NDS.NitroSystem.G3D;
using NDS.GPU;
using LibEveryFileExplorer.Files;
using LibEveryFileExplorer;
using System.Runtime.InteropServices;
namespace NDS.UI
{
public partial class NSBMDViewer : Form, IUseOtherFiles
{
ImageList ImageL;
MDL0Viewer ModViewer = null;
NSBMD mod;
NSBTX tex = null;
public NSBMDViewer(NSBMD mod)
{
this.mod = mod;
InitializeComponent();
Win32Util.SetWindowTheme(treeView1.Handle, "explorer", null);
ImageL = new ImageList();
ImageL.ColorDepth = ColorDepth.Depth32Bit;
ImageL.ImageSize = new Size(16, 16);
ImageL.Images.Add(Resource.jar);
ImageL.Images.Add(Resource.point);
ImageL.Images.Add(Resource.fruit);
ImageL.Images.Add(Resource.molecule);
ImageL.Images.Add(Resource.image_sunset16);
ImageL.Images.Add(Resource.color_swatch);
ImageL.Images.Add(Resource.images_stack);
ImageL.Images.Add(Resource.fruit_grape);
ImageL.Images.Add(Resource.node);
ImageL.Images.Add(Resource.color_swatches);
ImageL.Images.Add(Resource.images_stack);
treeView1.ImageList = ImageL;
}
private void CGFX_Load(object sender, EventArgs e)
{
treeView1.BeginUpdate();
treeView1.Nodes.Clear();
if (mod.ModelSet != null)
{
TreeNode mdl0 = new TreeNode("MDL0", 0, 0);
mdl0.Expand();
treeView1.Nodes.Add(mdl0);
for (int i = 0; i < mod.ModelSet.models.Length; i++)
{
TreeNode mdl = new TreeNode(mod.ModelSet.dict[i].Key, 1, 1) { Tag = mod.ModelSet.models[i] };
mdl0.Nodes.Add(mdl);
if (i == 0) treeView1.SelectedNode = mdl;
var v = mod.ModelSet.models[i];
TreeNode n = new TreeNode("Nodes", 8, 8);
mdl.Nodes.Add(n);
for (int j = 0; j < v.nodes.data.Length; j++)
{
n.Nodes.Add(new TreeNode(v.nodes.dict[j].Key, 3, 3) { Tag = v.nodes.data[j] });
}
n = new TreeNode("Materials", 7, 7);
mdl.Nodes.Add(n);
for (int j = 0; j < v.materials.materials.Length; j++)
{
n.Nodes.Add(new TreeNode(v.materials.dict[j].Key, 2, 2) { Tag = v.materials.materials[j] });
}
n = new TreeNode("Textures", 10, 10);
mdl.Nodes.Add(n);
for (int j = 0; j < v.materials.dictTexToMatList.numEntry; j++)
{
n.Nodes.Add(new TreeNode(v.materials.dictTexToMatList[j].Key, 4, 4) { Tag = v.materials.dictTexToMatList[j].Value });
}
n = new TreeNode("Palettes", 9, 9);
mdl.Nodes.Add(n);
for (int j = 0; j < v.materials.dictPlttToMatList.numEntry; j++)
{
n.Nodes.Add(new TreeNode(v.materials.dictPlttToMatList[j].Key, 5, 5) { Tag = v.materials.dictPlttToMatList[j].Value });
}
}
}
if (mod.TexPlttSet != null)
{
treeView1.Nodes.Add(new TreeNode("TEX0", 6, 6));
}
treeView1.EndUpdate();
//LoadTex();
}
private void LoadTex()
{
try
{
TEX0 tt;
if (mod.TexPlttSet != null) tt = mod.TexPlttSet;
else if (tex != null) tt = tex.TexPlttSet;
else return;
for (int i = 0; i < mod.ModelSet.models.Length; i++)
{
for (int j = 0; j < mod.ModelSet.models[i].materials.materials.Length; j++)
{
TEX0.DictTexData t = null;
for (int k = 0; k < mod.ModelSet.models[i].materials.dictTexToMatList.numEntry; k++)
{
if (mod.ModelSet.models[i].materials.dictTexToMatList[k].Value.Materials.Contains((byte)j))
{
int texid = k;
for (int l = 0; l < tt.dictTex.numEntry; l++)
{
if (tt.dictTex[l].Key == mod.ModelSet.models[i].materials.dictTexToMatList[k].Key) { texid = l; break; }
}
t = tt.dictTex[texid].Value;
break;
}
}
if (t == null)
continue;
mod.ModelSet.models[i].materials.materials[j].Fmt = t.Fmt;
mod.ModelSet.models[i].materials.materials[j].origHeight = t.T;
mod.ModelSet.models[i].materials.materials[j].origWidth = t.S;
TEX0.DictPlttData p = null;
if (t.Fmt != Textures.ImageFormat.DIRECT)
{
for (int k = 0; k < mod.ModelSet.models[i].materials.dictPlttToMatList.numEntry; k++)
{
if (mod.ModelSet.models[i].materials.dictPlttToMatList[k].Value.Materials.Contains((byte)j))
{
int palid = k;
for (int l = 0; l < tt.dictPltt.numEntry; l++)
{
if (tt.dictPltt[l].Key == mod.ModelSet.models[i].materials.dictPlttToMatList[k].Key) { palid = l; break; }
}
p = tt.dictPltt[palid].Value;
break;
}
}
}
UploadTex(t.ToBitmap(p), mod.ModelSet.models[i].materials.materials[j], j + 1);//+ offset);
}
}
}
catch { }
}
private void UploadTex(Bitmap b, MDL0.Model.MaterialSet.Material m, int Id)
{
Gl.glBindTexture(Gl.GL_TEXTURE_2D, Id);
Gl.glColor3f(1, 1, 1);
BitmapData d = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA8, b.Width, b.Height, 0, Gl.GL_BGRA, Gl.GL_UNSIGNED_BYTE, d.Scan0);
b.UnlockBits(d);
Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_NEAREST);
Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_NEAREST);
bool repeatS = (m.texImageParam >> 16 & 0x1) == 1;
bool repeatT = (m.texImageParam >> 17 & 0x1) == 1;
bool flipS = (m.texImageParam >> 18 & 0x1) == 1;
bool flipT = (m.texImageParam >> 19 & 0x1) == 1;
int S;
if (repeatS && flipS)
{
S = Gl.GL_MIRRORED_REPEAT;
}
else if (repeatS)
{
S = Gl.GL_REPEAT;
}
else
{
S = Gl.GL_CLAMP;
}
int T;
if (repeatT && flipT)
{
T = Gl.GL_MIRRORED_REPEAT;
}
else if (repeatT)
{
T = Gl.GL_REPEAT;
}
else
{
T = Gl.GL_CLAMP;
}
Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_S, S);
Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_T, T);
}
private void CGFX_Resize(object sender, EventArgs e)
{
if (ModViewer != null)
{
ModViewer.Render();
ModViewer.Render();
}
}
private void CGFX_Layout(object sender, LayoutEventArgs e)
{
if (ModViewer != null)
{
ModViewer.Render();
}
}
private void tabControl1_Selecting(object sender, TabControlCancelEventArgs e)
{
if (ModViewer != null)
{
ModViewer.Render();
}
}
public void FileOpened(ViewableFile File)
{
if (!(File.FileFormat is NSBTX)) return;
ViewableFile[] v = EveryFileExplorerUtil.GetOpenFilesOfType(typeof(NSBTX));
menuItem1.MenuItems.Clear();
bool curavab = false;
foreach (var vv in v)
{
var m = menuItem1.MenuItems.Add(vv.File.Name);
if (vv.FileFormat == tex)
{
curavab = true;
m.Checked = true;
}
}
if (!curavab && v.Length != 0)
{
menuItem1.MenuItems[0].Checked = true;
tex = v[0].FileFormat;
}
LoadTex();
if (ModViewer != null)
{
ModViewer.Render();
ModViewer.Render();
}
}
public void FileClosed(ViewableFile File)
{
if (File.FileFormat is NSBTX && File.FileFormat == tex) tex = null;
ViewableFile[] v = EveryFileExplorerUtil.GetOpenFilesOfType(typeof(NSBTX));
menuItem1.MenuItems.Clear();
foreach (var vv in v)
{
menuItem1.MenuItems.Add(vv.File.Name);
}
if (v.Length != 0)
{
menuItem1.MenuItems[0].Checked = true;
tex = v[0].FileFormat;
}
LoadTex();
if (ModViewer != null)
{
ModViewer.Render();
ModViewer.Render();
}
}
private void NSBMDViewer_Activated(object sender, EventArgs e)
{
//otherwise the nsbtx menu is not refreshed!
mainMenu1.MenuItems.Clear();
mainMenu1.MenuItems.Add(menuItem1);
//render it multiple times to avoid glitches!
if (ModViewer != null)
{
for (int i = 0; i < 8; i++) ModViewer.Render();
}
}
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
switch (e.Node.ImageIndex)
{
case 1:
ModViewer = new MDL0Viewer((MDL0.Model)e.Node.Tag) { Dock = DockStyle.Fill };
ModViewer.Width = panel1.Width;
ModViewer.Height = panel1.Height;
panel1.SuspendLayout();
panel1.Controls.Add(ModViewer);
if (panel1.Controls.Count > 1) panel1.Controls.RemoveAt(0);
panel1.Invalidate();
panel1.ResumeLayout();
ModViewer.Invalidate();
LoadTex();
ModViewer.Render();
ModViewer.Render();
break;
case 2:
ModViewer = null;
panel1.SuspendLayout();
panel1.Controls.Add(new MDL0MaterialEditor((MDL0.Model.MaterialSet.Material)e.Node.Tag) { Dock = DockStyle.Fill, Width = panel1.Width, Height = panel1.Height });
if (panel1.Controls.Count > 1) panel1.Controls.RemoveAt(0);
panel1.Invalidate();
panel1.ResumeLayout();
break;
case 6:
ModViewer = null;
panel1.SuspendLayout();
panel1.Controls.Add(new TEX0Viewer(mod.TexPlttSet) { Dock = DockStyle.Fill, Width = panel1.Width, Height = panel1.Height });
if (panel1.Controls.Count > 1) panel1.Controls.RemoveAt(0);
panel1.Invalidate();
panel1.ResumeLayout();
break;
default:
ModViewer = null;
panel1.SuspendLayout();
panel1.Controls.Clear();
panel1.Invalidate();
panel1.ResumeLayout();
break;
}
}
private void splitContainer1_SplitterMoved(object sender, SplitterEventArgs e)
{
if (ModViewer != null)
{
ModViewer.Render();
}
}
}
}