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.
This commit is contained in:
KillzXGaming 2018-12-10 18:48:51 -05:00
parent d96f4dec43
commit 716d1c4520
71 changed files with 10692 additions and 1085 deletions

3
.gitignore vendored
View file

@ -3,3 +3,6 @@
*.resources *.resources
Debug/ Debug/
Release/ Release/
Switch_Toolbox/Lib/Syroot.NintenTools.Bfres.dll
Switch_Toolbox/Lib/Syroot.NintenTools.Bfres.pdb
Switch_Toolbox/Lib/Syroot.NintenTools.Bfres.xml

View file

@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Switch_Toolbox;
using System.Windows.Forms; using System.Windows.Forms;
using Switch_Toolbox.Library; using Switch_Toolbox.Library;

View file

@ -25,6 +25,8 @@ namespace FirstPlugin
public CompressionType CompressionType { get; set; } = CompressionType.None; public CompressionType CompressionType { get; set; } = CompressionType.None;
public byte[] Data { get; set; } public byte[] Data { get; set; }
public string FileName { get; set; } public string FileName { get; set; }
public string FilePath { get; set; }
public IFileInfo IFileInfo { get; set; } public IFileInfo IFileInfo { get; set; }
public Type[] Types public Type[] Types
@ -39,7 +41,6 @@ namespace FirstPlugin
public bool IsActive { get; set; } = false; public bool IsActive { get; set; } = false;
public bool UseEditMenu { get; set; } = false; public bool UseEditMenu { get; set; } = false;
public int Alignment { get; set; } = 0; public int Alignment { get; set; } = 0;
public string FilePath { get; set; }
public bool IsWiiU public bool IsWiiU
{ {
get get
@ -353,8 +354,8 @@ namespace FirstPlugin
{ {
string TextureName = tex.Name; string TextureName = tex.Name;
FTEX texture = new FTEX(); FTEX texture = new FTEX();
texture.Read(tex);
ftexContainer.Nodes.Add(texture); ftexContainer.Nodes.Add(texture);
texture.Read(tex);
ftexContainer.Textures.Add(texture.Text, texture); ftexContainer.Textures.Add(texture.Text, texture);
} }
PluginRuntime.ftexContainers.Add(ftexContainer); PluginRuntime.ftexContainers.Add(ftexContainer);
@ -510,8 +511,11 @@ namespace FirstPlugin
if (Nodes.ContainsKey("FTEX")) if (Nodes.ContainsKey("FTEX"))
{ {
foreach (FTEX tex in Nodes["FTEX"].Nodes) foreach (FTEX tex in Nodes["FTEX"].Nodes)
{
tex.texture.Name = tex.Text;
resFileU.Textures.Add(tex.Text, tex.texture); resFileU.Textures.Add(tex.Text, tex.texture);
} }
}
else else
throw new Exception("Failed to find textures"); throw new Exception("Failed to find textures");
@ -526,10 +530,10 @@ namespace FirstPlugin
if (!shd.attributes.ContainsValue(att.Name) && !shd.attributes.ContainsKey(att.Name)) if (!shd.attributes.ContainsValue(att.Name) && !shd.attributes.ContainsKey(att.Name))
shd.attributes.Add(att.Name, att.Name); shd.attributes.Add(att.Name, att.Name);
} }
foreach (var tex in shape.GetMaterial().textures) foreach (var tex in shape.GetMaterial().TextureMaps)
{ {
if (!shd.samplers.ContainsValue(tex.SamplerName)) if (!shd.samplers.ContainsValue(((MatTexture)tex).SamplerName))
shd.samplers.Add(tex.SamplerName, tex.SamplerName); shd.samplers.Add(((MatTexture)tex).SamplerName, ((MatTexture)tex).SamplerName);
} }
} }
@ -554,7 +558,7 @@ namespace FirstPlugin
bool ImportMissingTextures = false; bool ImportMissingTextures = false;
foreach (BNTX bntx in PluginRuntime.bntxContainers) foreach (BNTX bntx in PluginRuntime.bntxContainers)
{ {
foreach (MatTexture tex in shape.GetMaterial().textures) foreach (MatTexture tex in shape.GetMaterial().TextureMaps)
{ {
if (!bntx.Textures.ContainsKey(tex.Name)) if (!bntx.Textures.ContainsKey(tex.Name))
{ {
@ -624,8 +628,6 @@ namespace FirstPlugin
MessageBox.Show($"Error! Sampler {samp} is unlinked!"); MessageBox.Show($"Error! Sampler {samp} is unlinked!");
} }
} }
} }
} }
// ErrorList errorList = new ErrorList(); // ErrorList errorList = new ErrorList();

View file

@ -173,7 +173,6 @@ namespace Bfres.Structs
public Dictionary<string, float[]> anims = new Dictionary<string, float[]>(); public Dictionary<string, float[]> anims = new Dictionary<string, float[]>();
public Dictionary<string, int> Samplers = new Dictionary<string, int>(); public Dictionary<string, int> Samplers = new Dictionary<string, int>();
public List<MatTexture> textures = new List<MatTexture>();
public List<BfresRenderInfo> renderinfo = new List<BfresRenderInfo>(); public List<BfresRenderInfo> renderinfo = new List<BfresRenderInfo>();
public List<SamplerInfo> samplerinfo = new List<SamplerInfo>(); public List<SamplerInfo> samplerinfo = new List<SamplerInfo>();
public Dictionary<string, BfresShaderParam> matparam = new Dictionary<string, BfresShaderParam>(); public Dictionary<string, BfresShaderParam> matparam = new Dictionary<string, BfresShaderParam>();

View file

@ -307,6 +307,11 @@ namespace Bfres.Structs
switch (ext) switch (ext)
{ {
case ".bfmdl": case ".bfmdl":
if (GetResFileU() != null)
{
}
else
Model.Export(sfd.FileName, GetResFile()); Model.Export(sfd.FileName, GetResFile());
break; break;
case ".csv": case ".csv":
@ -337,8 +342,34 @@ namespace Bfres.Structs
System.IO.File.WriteAllBytes(sfd.FileName, csv.Save()); System.IO.File.WriteAllBytes(sfd.FileName, csv.Save());
break; break;
default: default:
List<STGenericTexture> surfaces = new List<STGenericTexture>();
foreach (FSHP fshp in shapes)
{
foreach (var bntx in PluginRuntime.bntxContainers)
{
foreach (var tex in fshp.GetMaterial().TextureMaps)
{
if (bntx.Textures.ContainsKey(tex.Name))
{
surfaces.Add(bntx.Textures[tex.Name]);
}
}
}
foreach (var ftex in PluginRuntime.ftexContainers)
{
foreach (var tex in fshp.GetMaterial().TextureMaps)
{
if (ftex.Textures.ContainsKey(tex.Name))
{
surfaces.Add(ftex.Textures[tex.Name]);
}
}
}
}
Console.WriteLine("tex count " + surfaces.Count);
AssimpData assimp = new AssimpData(); AssimpData assimp = new AssimpData();
assimp.SaveFromModel(this, sfd.FileName); assimp.SaveFromModel(this, sfd.FileName, surfaces);
break; break;
} }
} }
@ -510,7 +541,7 @@ namespace Bfres.Structs
fmat.Text = mat.Text; fmat.Text = mat.Text;
//Setup placeholder textures //Setup placeholder textures
//Note we can't add/remove samplers so we must fill these slots //Note we can't add/remove samplers so we must fill these slots
foreach (var t in fmat.textures) foreach (var t in fmat.TextureMaps)
{ {
t.wrapModeS = 0; t.wrapModeS = 0;
t.wrapModeT = 0; t.wrapModeT = 0;
@ -574,7 +605,7 @@ namespace Bfres.Structs
foreach (var tex in mat.TextureMaps) foreach (var tex in mat.TextureMaps)
{ {
foreach (var t in fmat.textures) foreach (var t in fmat.TextureMaps)
{ {
if (t.Type == tex.Type) if (t.Type == tex.Type)
{ {
@ -627,11 +658,14 @@ namespace Bfres.Structs
shape.BoneIndices = new List<ushort>(); shape.BoneIndices = new List<ushort>();
List<string> keyList = shapes.Select(o => o.Text).ToList(); List<string> keyList = shapes.Select(o => o.Text).ToList();
shape.Text = Utils.RenameDuplicateString(keyList, shape.Text); shape.Text = Utils.RenameDuplicateString(keyList, shape.Text);
Nodes["FshpFolder"].Nodes.Add(shape); Nodes["FshpFolder"].Nodes.Add(shape);
shapes.Add(shape); shapes.Add(shape);
} }
Console.WriteLine("Finshed Importing Model");
Cursor.Current = Cursors.Default; Cursor.Current = Cursors.Default;
} }
break; break;

View file

@ -492,7 +492,7 @@ namespace Bfres.Structs
settings.SetModelAttributes(assimp.objects[0]); settings.SetModelAttributes(assimp.objects[0]);
if (settings.ShowDialog() == DialogResult.OK) if (settings.ShowDialog() == DialogResult.OK)
{ {
GenericObject obj = selector.GetSelectedMesh(); STGenericObject obj = selector.GetSelectedMesh();
Cursor.Current = Cursors.WaitCursor; Cursor.Current = Cursors.WaitCursor;
VertexBufferIndex = obj.VertexBufferIndex; VertexBufferIndex = obj.VertexBufferIndex;
@ -512,7 +512,7 @@ namespace Bfres.Structs
UpdateVertexData(); UpdateVertexData();
} }
} }
public void CreateIndexList(GenericObject ob, FMDL mdl = null) public void CreateIndexList(STGenericObject ob, FMDL mdl = null)
{ {
BoneIndices = new List<ushort>(); BoneIndices = new List<ushort>();
@ -539,7 +539,7 @@ namespace Bfres.Structs
index++; index++;
} }
} }
public void CreateBoneList(GenericObject ob, FMDL mdl) public void CreateBoneList(STGenericObject ob, FMDL mdl)
{ {
string[] nodeArrStrings = new string[mdl.Skeleton.Node_Array.Length]; string[] nodeArrStrings = new string[mdl.Skeleton.Node_Array.Length];

View file

@ -69,6 +69,7 @@ namespace Bfres.Structs
ZROT = 0x28, ZROT = 0x28,
} }
public SkeletalAnim SkeletalAnim; public SkeletalAnim SkeletalAnim;
public ResU.SkeletalAnim SkeletalAnimU;
public BfresSkeletonAnim() public BfresSkeletonAnim()
{ {
@ -103,6 +104,11 @@ namespace Bfres.Structs
//ResourceFile -> FMDL -> Material Folder -> this //ResourceFile -> FMDL -> Material Folder -> this
return ((BFRES)Parent.Parent).resFile; return ((BFRES)Parent.Parent).resFile;
} }
public ResU.ResFile GetResFileU()
{
//ResourceFile -> FMDL -> Material Folder -> this
return ((BFRES)Parent.Parent).resFileU;
}
private void Export(object sender, EventArgs args) private void Export(object sender, EventArgs args)
{ {
SaveFileDialog sfd = new SaveFileDialog(); SaveFileDialog sfd = new SaveFileDialog();
@ -111,26 +117,108 @@ namespace Bfres.Structs
sfd.DefaultExt = ".bfska"; sfd.DefaultExt = ".bfska";
if (sfd.ShowDialog() == DialogResult.OK) if (sfd.ShowDialog() == DialogResult.OK)
{
if (GetResFileU() != null)
{
throw new Exception("Wii U unsupported!");
}
else
{ {
SkeletalAnim.Export(sfd.FileName, GetResFile()); SkeletalAnim.Export(sfd.FileName, GetResFile());
} }
} }
}
private void Replace(object sender, EventArgs args) private void Replace(object sender, EventArgs args)
{ {
OpenFileDialog ofd = new OpenFileDialog(); OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "Supported Formats|*.bfska;"; ofd.Filter = "Supported Formats|*.bfska;";
if (ofd.ShowDialog() == DialogResult.OK) if (ofd.ShowDialog() == DialogResult.OK)
{
if (GetResFileU() != null)
{
throw new Exception("Wii U unsupported!");
}
else
{ {
SkeletalAnim.Import(ofd.FileName); SkeletalAnim.Import(ofd.FileName);
} }
}
SkeletalAnim.Name = Text; SkeletalAnim.Name = Text;
} }
public static List<Animation> SkeletonAnimations = new List<Animation>(); public static List<Animation> SkeletonAnimations = new List<Animation>();
public void Read(ResU.SkeletalAnim ska, ResU.ResFile b) public void Read(ResU.SkeletalAnim ska, ResU.ResFile b)
{ {
FrameCount = ska.FrameCount;
SkeletalAnimU = ska;
foreach (ResU.BoneAnim bn in ska.BoneAnims)
{
FSKANode bonean = new FSKANode(bn);
Animation.KeyNode bone = new Animation.KeyNode("");
Bones.Add(bone);
if (ska.FlagsRotate == ResU.SkeletalAnimFlagsRotate.EulerXYZ)
bone.RotType = Animation.RotationType.EULER;
else
bone.RotType = Animation.RotationType.QUATERNION;
bone.Text = bonean.Text;
for (int Frame = 0; Frame < ska.FrameCount; Frame++)
{
if (Frame == 0)
{
if (bn.FlagsBase.HasFlag(ResU.BoneAnimFlagsBase.Scale))
{
bone.XSCA.Keys.Add(new KeyFrame() { Frame = 0, Value = bonean.sca.X });
bone.YSCA.Keys.Add(new KeyFrame() { Frame = 0, Value = bonean.sca.Y });
bone.ZSCA.Keys.Add(new KeyFrame() { Frame = 0, Value = bonean.sca.Z });
}
if (bn.FlagsBase.HasFlag(ResU.BoneAnimFlagsBase.Rotate))
{
bone.XROT.Keys.Add(new KeyFrame() { Frame = 0, Value = bonean.rot.X });
bone.YROT.Keys.Add(new KeyFrame() { Frame = 0, Value = bonean.rot.Y });
bone.ZROT.Keys.Add(new KeyFrame() { Frame = 0, Value = bonean.rot.Z });
bone.WROT.Keys.Add(new KeyFrame() { Frame = 0, Value = bonean.rot.W });
}
if (bn.FlagsBase.HasFlag(ResU.BoneAnimFlagsBase.Translate))
{
bone.XPOS.Keys.Add(new KeyFrame() { Frame = 0, Value = bonean.pos.X });
bone.YPOS.Keys.Add(new KeyFrame() { Frame = 0, Value = bonean.pos.Y });
bone.ZPOS.Keys.Add(new KeyFrame() { Frame = 0, Value = bonean.pos.Z });
}
}
foreach (FSKATrack track in bonean.tracks)
{
KeyFrame frame = new KeyFrame();
frame.InterType = Animation.InterpolationType.HERMITE;
frame.Frame = Frame;
FSKAKey left = track.GetLeft(Frame);
FSKAKey right = track.GetRight(Frame);
float value;
value = Animation.Hermite(Frame, left.frame, right.frame, 0, 0, left.unk1, right.unk1);
// interpolate the value and apply
switch (track.flag)
{
case (int)TrackType.XPOS: frame.Value = value; bone.XPOS.Keys.Add(frame); break;
case (int)TrackType.YPOS: frame.Value = value; bone.YPOS.Keys.Add(frame); break;
case (int)TrackType.ZPOS: frame.Value = value; bone.ZPOS.Keys.Add(frame); break;
case (int)TrackType.XROT: frame.Value = value; bone.XROT.Keys.Add(frame); break;
case (int)TrackType.YROT: frame.Value = value; bone.YROT.Keys.Add(frame); break;
case (int)TrackType.ZROT: frame.Value = value; bone.ZROT.Keys.Add(frame); break;
case (int)TrackType.XSCA: frame.Value = value; bone.XSCA.Keys.Add(frame); break;
case (int)TrackType.YSCA: frame.Value = value; bone.YSCA.Keys.Add(frame); break;
case (int)TrackType.ZSCA: frame.Value = value; bone.ZSCA.Keys.Add(frame); break;
}
}
}
}
} }
public void Read(SkeletalAnim ska, ResFile b) public void Read(SkeletalAnim ska, ResFile b)
{ {
@ -221,7 +309,61 @@ namespace Bfres.Structs
public Vector3 sca, pos; public Vector3 sca, pos;
public Vector4 rot; public Vector4 rot;
public List<FSKATrack> tracks = new List<FSKATrack>(); public List<FSKATrack> tracks = new List<FSKATrack>();
public FSKANode(ResU.BoneAnim b)
{
return;
Text = b.Name;
sca = new Vector3(b.BaseData.Scale.X, b.BaseData.Scale.Y, b.BaseData.Scale.Z);
rot = new Vector4(b.BaseData.Rotate.X, b.BaseData.Rotate.Y, b.BaseData.Rotate.Z, b.BaseData.Rotate.W);
pos = new Vector3(b.BaseData.Translate.X, b.BaseData.Translate.Y, b.BaseData.Translate.Z);
foreach (ResU.AnimCurve tr in b.Curves)
{
FSKATrack t = new FSKATrack();
t.flag = (int)tr.AnimDataOffset;
tracks.Add(t);
float tanscale = tr.Delta;
if (tanscale == 0)
tanscale = 1;
for (int i = 0; i < (ushort)tr.Frames.Length; i++)
{
if (tr.CurveType == ResU.AnimCurveType.Cubic)
{
int framedata = (int)tr.Frames[i];
float keydata = tr.Offset + ((tr.Keys[i, 0] * tr.Scale));
float keydata2 = tr.Offset + ((tr.Keys[i, 1] * tr.Scale));
float keydata3 = tr.Offset + ((tr.Keys[i, 2] * tr.Scale));
float keydata4 = tr.Offset + ((tr.Keys[i, 3] * tr.Scale));
}
if (tr.KeyType == ResU.AnimCurveKeyType.Int16)
{
}
else if (tr.KeyType == ResU.AnimCurveKeyType.Single)
{
}
else if (tr.KeyType == ResU.AnimCurveKeyType.SByte)
{
}
t.keys.Add(new FSKAKey()
{
frame = (int)tr.Frames[i],
unk1 = tr.Offset + ((tr.Keys[i, 0] * tr.Scale)),
unk2 = tr.Offset + ((tr.Keys[i, 1] * tr.Scale)),
unk3 = tr.Offset + ((tr.Keys[i, 2] * tr.Scale)),
unk4 = tr.Offset + ((tr.Keys[i, 3] * tr.Scale)),
});
}
}
}
public FSKANode(BoneAnim b) public FSKANode(BoneAnim b)
{ {
Text = b.Name; Text = b.Name;

View file

@ -1,10 +1,12 @@
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using Syroot.NintenTools.NSW.Bfres; using Syroot.NintenTools.NSW.Bfres;
using System.Windows.Forms; using System.Windows.Forms;
using Switch_Toolbox.Library; using Switch_Toolbox.Library;
using ResU = Syroot.NintenTools.Bfres; using ResU = Syroot.NintenTools.Bfres;
using FirstPlugin; using FirstPlugin;
using OpenTK;
namespace Bfres.Structs namespace Bfres.Structs
{ {
@ -12,6 +14,7 @@ namespace Bfres.Structs
public class FSKL : STSkeleton public class FSKL : STSkeleton
{ {
public int[] Node_Array; public int[] Node_Array;
public List<Matrix3x4> matrices = new List<Matrix3x4>();
public fsklNode node; public fsklNode node;
public class fsklNode : TreeNodeCustom public class fsklNode : TreeNodeCustom
{ {

View file

@ -21,6 +21,7 @@ namespace FirstPlugin
{ {
Model model = new Model(); Model model = new Model();
model.Name = fmdl.Text; model.Name = fmdl.Text;
model.Path = "";
model.Shapes = new List<Shape>(); model.Shapes = new List<Shape>();
model.VertexBuffers = new List<VertexBuffer>(); model.VertexBuffers = new List<VertexBuffer>();
model.Materials = new List<Material>(); model.Materials = new List<Material>();
@ -590,7 +591,7 @@ namespace FirstPlugin
} }
public static void ReadTextureRefs(this FMAT m, Material mat) public static void ReadTextureRefs(this FMAT m, Material mat)
{ {
m.textures.Clear(); m.TextureMaps.Clear();
int AlbedoCount = 0; int AlbedoCount = 0;
int id = 0; int id = 0;
@ -790,7 +791,7 @@ namespace FirstPlugin
texture.Name = TextureName; texture.Name = TextureName;
m.textures.Add(texture); m.TextureMaps.Add(texture);
id++; id++;
} }
@ -872,7 +873,7 @@ namespace FirstPlugin
mat.TextureRefs = new List<string>(); mat.TextureRefs = new List<string>();
mat.TextureRefs.Clear(); mat.TextureRefs.Clear();
foreach (var textu in m.textures) foreach (var textu in m.TextureMaps)
mat.TextureRefs.Add(textu.Name); mat.TextureRefs.Add(textu.Name);
} }

View file

@ -23,6 +23,7 @@ namespace FirstPlugin
{ {
Model model = new Model(); Model model = new Model();
model.Name = fmdl.Text; model.Name = fmdl.Text;
model.Path = "";
model.Shapes = new ResDict<Shape>(); model.Shapes = new ResDict<Shape>();
model.VertexBuffers = new List<VertexBuffer>(); model.VertexBuffers = new List<VertexBuffer>();
model.Materials = new ResDict<Material>(); model.Materials = new ResDict<Material>();
@ -39,13 +40,11 @@ namespace FirstPlugin
{ {
BFRES.CheckMissingTextures(shape); BFRES.CheckMissingTextures(shape);
SetShape(shape, shape.ShapeU); SetShape(shape, shape.ShapeU);
shape.ShapeU.SubMeshBoundingNodes = new List<BoundingNode>();
model.Shapes.Add(shape.Text, shape.ShapeU); model.Shapes.Add(shape.Text, shape.ShapeU);
model.VertexBuffers.Add(shape.VertexBufferU); model.VertexBuffers.Add(shape.VertexBufferU);
shape.ShapeU.VertexBufferIndex = (ushort)(model.VertexBuffers.Count - 1); shape.ShapeU.VertexBufferIndex = (ushort)(model.VertexBuffers.Count - 1);
BFRES.SetShaderAssignAttributes(shape.GetMaterial().shaderassign, shape); // BFRES.SetShaderAssignAttributes(shape.GetMaterial().shaderassign, shape);
} }
foreach (FMAT mat in fmdl.materials.Values) foreach (FMAT mat in fmdl.materials.Values)
@ -257,15 +256,15 @@ namespace FirstPlugin
if (fshp.VertexSkinCount == 1) if (fshp.VertexSkinCount == 1)
{ {
Matrix4 sb = model.Skeleton.bones[model.Skeleton.Node_Array[v.boneIds[0]]].transform; // Matrix4 sb = model.Skeleton.bones[model.Skeleton.Node_Array[v.boneIds[0]]].transform;
v.pos = Vector3.TransformPosition(v.pos, sb); // v.pos = Vector3.TransformPosition(v.pos, sb);
v.nrm = Vector3.TransformNormal(v.nrm, sb); // v.nrm = Vector3.TransformNormal(v.nrm, sb);
} }
if (fshp.VertexSkinCount == 0) if (fshp.VertexSkinCount == 0)
{ {
Matrix4 NoBindFix = model.Skeleton.bones[fshp.boneIndx].transform; // Matrix4 NoBindFix = model.Skeleton.bones[fshp.boneIndx].transform;
v.pos = Vector3.TransformPosition(v.pos, NoBindFix); // v.pos = Vector3.TransformPosition(v.pos, NoBindFix);
v.nrm = Vector3.TransformNormal(v.nrm, NoBindFix); // v.nrm = Vector3.TransformNormal(v.nrm, NoBindFix);
} }
fshp.vertices.Add(v); fshp.vertices.Add(v);
} }
@ -288,20 +287,32 @@ namespace FirstPlugin
RenderableSkeleton.Node_Array[nodes] = node; RenderableSkeleton.Node_Array[nodes] = node;
nodes++; nodes++;
} }
for (int i = 0; i < skeleton.Bones.Count; i++)
{
if (skeleton.InverseModelMatrices == null)
break;
if (i < skeleton.InverseModelMatrices.Count)
RenderableSkeleton.matrices.Add(Utils.ToMat3x4(skeleton.InverseModelMatrices[i]));
else
RenderableSkeleton.matrices.Add(Matrix3x4.Zero);
}
foreach (Bone bone in skeleton.Bones.Values) foreach (Bone bone in skeleton.Bones.Values)
{ {
BfresBone STBone = new BfresBone(RenderableSkeleton); BfresBone STBone = new BfresBone(RenderableSkeleton);
SetBone(STBone, bone); SetBone(STBone, bone);
STBone.BFRESRender = RenderableSkeleton.node.BFRESRender; //to update viewport on bone edits STBone.BFRESRender = RenderableSkeleton.node.BFRESRender; //to update viewport on bone edits
RenderableSkeleton.bones.Add(STBone); RenderableSkeleton.bones.Add(STBone);
if (bone.InverseMatrix != null)
RenderableSkeleton.matrices.Add(Utils.ToMat3x4(bone.InverseMatrix));
} }
RenderableSkeleton.update(); RenderableSkeleton.update();
RenderableSkeleton.reset(); RenderableSkeleton.reset();
foreach (var bone in RenderableSkeleton.bones) // foreach (var bone in RenderableSkeleton.bones)
if (bone.Parent == null) // if (bone.Parent == null)
skl.Nodes.Add(bone); // skl.Nodes.Add(bone);
Runtime.abstractGlDrawables.Add(RenderableSkeleton); Runtime.abstractGlDrawables.Add(RenderableSkeleton);
} }
@ -386,7 +397,7 @@ namespace FirstPlugin
} }
public static void ReadTextureRefs(this FMAT m, Material mat) public static void ReadTextureRefs(this FMAT m, Material mat)
{ {
m.textures.Clear(); m.TextureMaps.Clear();
int AlbedoCount = 0; int AlbedoCount = 0;
int id = 0; int id = 0;
@ -577,7 +588,7 @@ namespace FirstPlugin
} }
} }
texture.Name = TextureName; texture.Name = TextureName;
m.textures.Add(texture); m.TextureMaps.Add(texture);
id++; id++;
} }
@ -660,7 +671,7 @@ namespace FirstPlugin
mat.TextureRefs = new List<TextureRef>(); mat.TextureRefs = new List<TextureRef>();
mat.TextureRefs.Clear(); mat.TextureRefs.Clear();
foreach (var textu in m.textures) foreach (var textu in m.TextureMaps)
{ {
TextureRef texref = new TextureRef(); TextureRef texref = new TextureRef();
texref.Name = textu.Name; texref.Name = textu.Name;

View file

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FirstPlugin
{
public class BFSHA
{
}
}

View file

@ -84,7 +84,7 @@ namespace FirstPlugin
Model model = new Model(); Model model = new Model();
STGenericObject STobj = new STGenericObject(); STGenericObject STobj = new STGenericObject();
Vertex vtx = new Vertex(); Vertex vtx = new Vertex();
GenericObject.LOD_Mesh lod = new GenericObject.LOD_Mesh(); STGenericObject.LOD_Mesh lod = new STGenericObject.LOD_Mesh();
int Index = 0; int Index = 0;
int ww = 0; int ww = 0;
while (true) while (true)
@ -101,7 +101,7 @@ namespace FirstPlugin
models.Add(model); models.Add(model);
STobj.ObjectName = model.Name; STobj.ObjectName = model.Name;
lod = new GenericObject.LOD_Mesh(); lod = new STGenericObject.LOD_Mesh();
lod.IndexFormat = STIndexFormat.UInt16; lod.IndexFormat = STIndexFormat.UInt16;
lod.PrimitiveType = STPolygonType.Triangle; lod.PrimitiveType = STPolygonType.Triangle;
STobj.lodMeshes.Add(lod); STobj.lodMeshes.Add(lod);
@ -266,7 +266,7 @@ namespace FirstPlugin
if (objects[0].weightsT.Count != objects[0].vertices.Count) if (objects[0].weightsT.Count != objects[0].vertices.Count)
throw new Exception("Incorrect vertex amount"); throw new Exception("Incorrect vertex amount");
foreach (GenericObject obj in objects) foreach (STGenericObject obj in objects)
{ {
obj.lodMeshes[0].GenerateSubMesh(); obj.lodMeshes[0].GenerateSubMesh();
for (int v = 0; v < obj.vertices.Count; v++) for (int v = 0; v < obj.vertices.Count; v++)
@ -302,7 +302,7 @@ namespace FirstPlugin
using (System.IO.StreamWriter file = new System.IO.StreamWriter(mem)) using (System.IO.StreamWriter file = new System.IO.StreamWriter(mem))
{ {
foreach (GenericObject obj in objects) foreach (STGenericObject obj in objects)
{ {
file.WriteLine($"Obj Name:" + obj.ObjectName); file.WriteLine($"Obj Name:" + obj.ObjectName);
file.WriteLine($"Bone_Suport"); file.WriteLine($"Bone_Suport");

View file

@ -140,10 +140,14 @@ namespace FirstPlugin
{ {
string dir = Path.GetDirectoryName(sarc.FullName); string dir = Path.GetDirectoryName(sarc.FullName);
Console.WriteLine(sarc.FullName);
if (dir == string.Empty) if (dir == string.Empty)
sarc.FullName = sarc.Text; sarc.FullName = sarc.Text;
else else
sarc.FullName = Path.Combine(dir, sarc.Text); sarc.FullName = dir + "/" + sarc.Text;
Console.WriteLine(sarc.FullName);
sarcData.Files.Add(sarc.FullName, sarc.Data); sarcData.Files.Add(sarc.FullName, sarc.Data);
} }

View file

@ -26,10 +26,12 @@ namespace FirstPlugin
public enum BNTXImageFormat public enum BNTXImageFormat
{ {
IMAGE_FORMAT_INVALID = 0x0, IMAGE_FORMAT_INVALID = 0x0,
IMAGE_FORMAT_R8_G8_B8_A8 = 0x0b,
IMAGE_FORMAT_R5_G6_B5 = 0x07, IMAGE_FORMAT_R5_G6_B5 = 0x07,
IMAGE_FORMAT_R8 = 0x02, IMAGE_FORMAT_R8 = 0x02,
IMAGE_FORMAT_R8_G8 = 0x09, IMAGE_FORMAT_R8_G8 = 0x09,
IMAGE_FORMAT_R16 = 0x0a,
IMAGE_FORMAT_R8_G8_B8_A8 = 0x0b,
IMAGE_FORMAT_R11_G11_B11_A10 = 0x0f,
IMAGE_FORMAT_BC1 = 0x1a, IMAGE_FORMAT_BC1 = 0x1a,
IMAGE_FORMAT_BC2 = 0x1b, IMAGE_FORMAT_BC2 = 0x1b,
IMAGE_FORMAT_BC3 = 0x1c, IMAGE_FORMAT_BC3 = 0x1c,
@ -37,6 +39,20 @@ namespace FirstPlugin
IMAGE_FORMAT_BC5 = 0x1e, IMAGE_FORMAT_BC5 = 0x1e,
IMAGE_FORMAT_BC6 = 0x1f, IMAGE_FORMAT_BC6 = 0x1f,
IMAGE_FORMAT_BC7 = 0x20, IMAGE_FORMAT_BC7 = 0x20,
IMAGE_FORMAT_ASTC4x4 = 0x2d,
IMAGE_FORMAT_ASTC5x4 = 0x2e,
IMAGE_FORMAT_ASTC5x5 = 0x2f,
IMAGE_FORMAT_ASTC6x5 = 0x30,
IMAGE_FORMAT_ASTC6x6 = 0x31,
IMAGE_FORMAT_ASTC8x5 = 0x32,
IMAGE_FORMAT_ASTC8x6 = 0x33,
IMAGE_FORMAT_ASTC8x8 = 0x34,
IMAGE_FORMAT_ASTC10x5 = 0x35,
IMAGE_FORMAT_ASTC10x6 = 0x36,
IMAGE_FORMAT_ASTC10x8 = 0x37,
IMAGE_FORMAT_ASTC10x10 = 0x38,
IMAGE_FORMAT_ASTC12x10 = 0x39,
IMAGE_FORMAT_ASTC12x12 = 0x3a
}; };
public enum BNTXImageTypes public enum BNTXImageTypes
@ -57,22 +73,22 @@ namespace FirstPlugin
case (uint)BNTXImageFormat.IMAGE_FORMAT_BC5: case (uint)BNTXImageFormat.IMAGE_FORMAT_BC5:
case (uint)BNTXImageFormat.IMAGE_FORMAT_BC6: case (uint)BNTXImageFormat.IMAGE_FORMAT_BC6:
case (uint)BNTXImageFormat.IMAGE_FORMAT_BC7: case (uint)BNTXImageFormat.IMAGE_FORMAT_BC7:
case 0x2d: case (uint)BNTXImageFormat.IMAGE_FORMAT_ASTC4x4:
return 0x44; return 0x44;
case 0x2e: return 0x54; case (uint)BNTXImageFormat.IMAGE_FORMAT_ASTC5x4: return 0x54;
case 0x2f: return 0x55; case (uint)BNTXImageFormat.IMAGE_FORMAT_ASTC5x5: return 0x55;
case 0x30: return 0x65; case (uint)BNTXImageFormat.IMAGE_FORMAT_ASTC6x5: return 0x65;
case 0x31: return 0x66; case (uint)BNTXImageFormat.IMAGE_FORMAT_ASTC6x6: return 0x66;
case 0x32: return 0x85; case (uint)BNTXImageFormat.IMAGE_FORMAT_ASTC8x5: return 0x85;
case 0x33: return 0x86; case (uint)BNTXImageFormat.IMAGE_FORMAT_ASTC8x6: return 0x86;
case 0x34: return 0x88; case (uint)BNTXImageFormat.IMAGE_FORMAT_ASTC8x8: return 0x88;
case 0x35: return 0xa5; case (uint)BNTXImageFormat.IMAGE_FORMAT_ASTC10x5: return 0xa5;
case 0x36: return 0xa6; case (uint)BNTXImageFormat.IMAGE_FORMAT_ASTC10x6: return 0xa6;
case 0x37: return 0xa8; case (uint)BNTXImageFormat.IMAGE_FORMAT_ASTC10x8: return 0xa8;
case 0x38: return 0xaa; case (uint)BNTXImageFormat.IMAGE_FORMAT_ASTC10x10: return 0xaa;
case 0x39: return 0xca; case (uint)BNTXImageFormat.IMAGE_FORMAT_ASTC12x10: return 0xca;
case 0x3a: return 0xcc; case (uint)BNTXImageFormat.IMAGE_FORMAT_ASTC12x12: return 0xcc;
default: return 0x11; default: return 0x11;
} }
@ -98,19 +114,19 @@ namespace FirstPlugin
case (uint)BNTXImageFormat.IMAGE_FORMAT_BC5: case (uint)BNTXImageFormat.IMAGE_FORMAT_BC5:
case (uint)BNTXImageFormat.IMAGE_FORMAT_BC6: case (uint)BNTXImageFormat.IMAGE_FORMAT_BC6:
case (uint)BNTXImageFormat.IMAGE_FORMAT_BC7: case (uint)BNTXImageFormat.IMAGE_FORMAT_BC7:
case 0x2e: case (uint)BNTXImageFormat.IMAGE_FORMAT_ASTC5x4:
case 0x2f: case (uint)BNTXImageFormat.IMAGE_FORMAT_ASTC5x5:
case 0x30: case (uint)BNTXImageFormat.IMAGE_FORMAT_ASTC6x5:
case 0x31: case (uint)BNTXImageFormat.IMAGE_FORMAT_ASTC6x6:
case 0x32: case (uint)BNTXImageFormat.IMAGE_FORMAT_ASTC8x5:
case 0x33: case (uint)BNTXImageFormat.IMAGE_FORMAT_ASTC8x6:
case 0x34: case (uint)BNTXImageFormat.IMAGE_FORMAT_ASTC8x8:
case 0x35: case (uint)BNTXImageFormat.IMAGE_FORMAT_ASTC10x5:
case 0x36: case (uint)BNTXImageFormat.IMAGE_FORMAT_ASTC10x6:
case 0x37: case (uint)BNTXImageFormat.IMAGE_FORMAT_ASTC10x8:
case 0x38: case (uint)BNTXImageFormat.IMAGE_FORMAT_ASTC10x10:
case 0x39: case (uint)BNTXImageFormat.IMAGE_FORMAT_ASTC12x10:
case 0x3a: case (uint)BNTXImageFormat.IMAGE_FORMAT_ASTC12x12:
return 16; return 16;
default: return 0x00; default: return 0x00;
} }
@ -144,17 +160,31 @@ namespace FirstPlugin
} }
class MenuExt : IFileMenuExtension class MenuExt : IFileMenuExtension
{ {
public ToolStripItemDark[] NewFileMenuExtensions => null; public ToolStripItemDark[] NewFileMenuExtensions => newFileExt;
public ToolStripItemDark[] ToolsMenuExtensions => newFileExt; public ToolStripItemDark[] ToolsMenuExtensions => toolExt;
public ToolStripItemDark[] TitleBarExtensions => null; public ToolStripItemDark[] TitleBarExtensions => null;
public ToolStripItemDark[] CompressionMenuExtensions => null; public ToolStripItemDark[] CompressionMenuExtensions => null;
public ToolStripItemDark[] ExperimentalMenuExtensions => null; public ToolStripItemDark[] ExperimentalMenuExtensions => null;
ToolStripItemDark[] toolExt = new ToolStripItemDark[1];
ToolStripItemDark[] newFileExt = new ToolStripItemDark[1]; ToolStripItemDark[] newFileExt = new ToolStripItemDark[1];
public MenuExt() public MenuExt()
{ {
newFileExt[0] = new ToolStripItemDark("Extract BNTX"); toolExt[0] = new ToolStripItemDark("Extract BNTX");
newFileExt[0].Click += Export; toolExt[0].Click += Export;
newFileExt[0] = new ToolStripItemDark("BNTX");
newFileExt[0].Click += New;
}
private void New(object sender, EventArgs args)
{
BNTX bntx = new BNTX();
bntx.FileName = "textures.bntx";
bntx.Data = CreateNewBNTX("textures.bntx");
bntx.Load();
ObjectList.Instance.treeView1.Nodes.Add(bntx);
} }
private void Export(object sender, EventArgs args) private void Export(object sender, EventArgs args)
{ {
@ -194,6 +224,7 @@ namespace FirstPlugin
MenuItem rename = new MenuItem("Rename"); MenuItem rename = new MenuItem("Rename");
MenuItem importTex = new MenuItem("Import Texture"); MenuItem importTex = new MenuItem("Import Texture");
MenuItem exportAll = new MenuItem("Export All Textures"); MenuItem exportAll = new MenuItem("Export All Textures");
MenuItem sort = new MenuItem("Sort");
MenuItem clear = new MenuItem("Clear"); MenuItem clear = new MenuItem("Clear");
private bool hasParent; private bool hasParent;
@ -232,10 +263,6 @@ namespace FirstPlugin
FileNameText = FileName; FileNameText = FileName;
if (Data.Length == 0)
Data = CreateNewBNTX(Name);
LoadFile(Data, Name); LoadFile(Data, Name);
PluginRuntime.bntxContainers.Add(this); PluginRuntime.bntxContainers.Add(this);
@ -249,6 +276,7 @@ namespace FirstPlugin
ContextMenu.MenuItems.Add(rename); ContextMenu.MenuItems.Add(rename);
ContextMenu.MenuItems.Add(importTex); ContextMenu.MenuItems.Add(importTex);
ContextMenu.MenuItems.Add(exportAll); ContextMenu.MenuItems.Add(exportAll);
ContextMenu.MenuItems.Add(sort);
ContextMenu.MenuItems.Add(clear); ContextMenu.MenuItems.Add(clear);
save.Click += Save; save.Click += Save;
@ -256,13 +284,14 @@ namespace FirstPlugin
rename.Click += Rename; rename.Click += Rename;
importTex.Click += ImportTexture; importTex.Click += ImportTexture;
exportAll.Click += ExportAll; exportAll.Click += ExportAll;
sort.Click += SortTextures;
clear.Click += Clear; clear.Click += Clear;
} }
public void Unload() public void Unload()
{ {
foreach (TextureData tex in Textures.Values) foreach (TextureData tex in Textures.Values)
{ {
tex.mipmaps.Clear(); tex.surfaces.Clear();
tex.renderedGLTex = null; tex.renderedGLTex = null;
} }
@ -270,7 +299,7 @@ namespace FirstPlugin
Nodes.Clear(); Nodes.Clear();
} }
private byte[] CreateNewBNTX(string Name) private static byte[] CreateNewBNTX(string Name)
{ {
MemoryStream mem = new MemoryStream(); MemoryStream mem = new MemoryStream();
@ -344,6 +373,7 @@ namespace FirstPlugin
ofd.Filter = "Supported Formats|*.bftex;*.dds; *.png;*.tga;*.jpg;*.tiff|" + ofd.Filter = "Supported Formats|*.bftex;*.dds; *.png;*.tga;*.jpg;*.tiff|" +
"Binary Texture |*.bftex|" + "Binary Texture |*.bftex|" +
"Microsoft DDS |*.dds|" + "Microsoft DDS |*.dds|" +
"TGA |*.tga|" +
"Portable Network Graphics |*.png|" + "Portable Network Graphics |*.png|" +
"Joint Photographic Experts Group |*.jpg|" + "Joint Photographic Experts Group |*.jpg|" +
"Bitmap Image |*.bmp|" + "Bitmap Image |*.bmp|" +
@ -357,9 +387,11 @@ namespace FirstPlugin
{ {
BinaryTextureImporterList importer = new BinaryTextureImporterList(); BinaryTextureImporterList importer = new BinaryTextureImporterList();
List<TextureImporterSettings> settings = new List<TextureImporterSettings>(); bool UseDialog = false;
foreach (string name in ofd.FileNames) foreach (string name in ofd.FileNames)
{ {
TextureImporterSettings setting = new TextureImporterSettings();
string ext = Path.GetExtension(name); string ext = Path.GetExtension(name);
ext = ext.ToLower(); ext = ext.ToLower();
@ -367,21 +399,23 @@ namespace FirstPlugin
{ {
AddTexture(name); AddTexture(name);
} }
else if (ext == ".tga")
{
setting.LoadTGA(name, BinaryTexFile);
importer.LoadSetting(setting, this);
UseDialog = true;
}
else else
{ {
settings.Add(LoadSettings(name)); setting.LoadBitMap(name, BinaryTexFile);
importer.LoadSetting(setting, this);
if (settings.Count == 0) UseDialog = true;
{
importer.Dispose();
return;
} }
}
importer.LoadSettings(settings, this); if (UseDialog && importer.ShowDialog() == DialogResult.OK)
if (importer.ShowDialog() == DialogResult.OK)
{ {
Cursor.Current = Cursors.WaitCursor; Cursor.Current = Cursors.WaitCursor;
foreach (var setting in settings) foreach (var setting in importer.settings)
{ {
if (setting.GenerateMipmaps) if (setting.GenerateMipmaps)
{ {
@ -417,10 +451,6 @@ namespace FirstPlugin
} }
} }
} }
}
}
settings.Clear();
GC.Collect(); GC.Collect();
Cursor.Current = Cursors.Default; Cursor.Current = Cursors.Default;
} }
@ -510,6 +540,9 @@ namespace FirstPlugin
case ".dds": case ".dds":
importer.LoadDDS(name, BinaryTexFile); importer.LoadDDS(name, BinaryTexFile);
break; break;
case ".tga":
importer.LoadTGA(name, BinaryTexFile);
break;
default: default:
importer.LoadBitMap(name, BinaryTexFile); importer.LoadBitMap(name, BinaryTexFile);
break; break;
@ -595,6 +628,11 @@ namespace FirstPlugin
} }
} }
} }
bool SortedAscending;
private void SortTextures(object sender, EventArgs args)
{
SortNodes(this);
}
public byte[] Save() public byte[] Save()
{ {
BinaryTexFile.Textures.Clear(); BinaryTexFile.Textures.Clear();
@ -692,11 +730,10 @@ namespace FirstPlugin
} }
} }
public class TextureData : TreeNodeCustom public class TextureData : STGenericTexture
{ {
public Texture Texture; public Texture Texture;
public BntxFile bntxFile; public BntxFile bntxFile;
public List<List<byte[]>> mipmaps = new List<List<byte[]>>();
public BRTI_Texture renderedGLTex = new BRTI_Texture(); public BRTI_Texture renderedGLTex = new BRTI_Texture();
public bool GLInitialized = false; public bool GLInitialized = false;
@ -761,12 +798,12 @@ namespace FirstPlugin
LoadTexture(Texture); LoadTexture(Texture);
if (mipmaps.Count <= 0) if (surfaces.Count <= 0)
{ {
throw new Exception("No texture data found"); throw new Exception("No texture data found");
} }
renderedGLTex.data = mipmaps[0][0]; renderedGLTex.data = surfaces[0].mipmaps[0];
renderedGLTex.width = (int)Texture.Width; renderedGLTex.width = (int)Texture.Width;
renderedGLTex.height = (int)Texture.Height; renderedGLTex.height = (int)Texture.Height;
@ -800,7 +837,7 @@ namespace FirstPlugin
renderedGLTex.type = PixelInternalFormat.CompressedRgRgtc2; renderedGLTex.type = PixelInternalFormat.CompressedRgRgtc2;
break; break;
case SurfaceFormat.BC5_SNORM: case SurfaceFormat.BC5_SNORM:
renderedGLTex.data = DDSCompressor.DecompressBC5(mipmaps[0][0], (int)Texture.Width, (int)Texture.Height, true, true); renderedGLTex.data = DDSCompressor.DecompressBC5(surfaces[0].mipmaps[0], (int)Texture.Width, (int)Texture.Height, true, true);
renderedGLTex.type = PixelInternalFormat.Rgba; renderedGLTex.type = PixelInternalFormat.Rgba;
renderedGLTex.utype = OpenTK.Graphics.OpenGL.PixelFormat.Rgba; renderedGLTex.utype = OpenTK.Graphics.OpenGL.PixelFormat.Rgba;
break; break;
@ -987,10 +1024,10 @@ namespace FirstPlugin
{ {
return ColorComponentSelector(bitmap, ChannelType.Blue, ChannelType.Green, ChannelType.Red, ChannelType.Alpha); return ColorComponentSelector(bitmap, ChannelType.Blue, ChannelType.Green, ChannelType.Red, ChannelType.Alpha);
} }
public static byte[] CompressBlock(byte[] data, int width, int height, SurfaceFormat format) public static byte[] CompressBlock(byte[] data, int width, int height, SurfaceFormat format, float alphaRef)
{ {
if (IsCompressedFormat(format)) if (IsCompressedFormat(format))
return DDSCompressor.CompressBlock(data, width, height, GetCompressedDXGI_FORMAT(format)); return DDSCompressor.CompressBlock(data, width, height, GetCompressedDXGI_FORMAT(format), alphaRef);
else if (IsAtscFormat(format)) else if (IsAtscFormat(format))
return null; return null;
else else
@ -1092,6 +1129,7 @@ namespace FirstPlugin
ofd.Filter = "Supported Formats|*.bftex;*.dds; *.png;*.tga;*.jpg;*.tiff|" + ofd.Filter = "Supported Formats|*.bftex;*.dds; *.png;*.tga;*.jpg;*.tiff|" +
"Binary Texture |*.bftex|" + "Binary Texture |*.bftex|" +
"Microsoft DDS |*.dds|" + "Microsoft DDS |*.dds|" +
"TGA |*.tga|" +
"Portable Network Graphics |*.png|" + "Portable Network Graphics |*.png|" +
"Joint Photographic Experts Group |*.jpg|" + "Joint Photographic Experts Group |*.jpg|" +
"Bitmap Image |*.bmp|" + "Bitmap Image |*.bmp|" +
@ -1116,17 +1154,25 @@ namespace FirstPlugin
{ {
case ".bftex": case ".bftex":
Texture.Import(FileName); Texture.Import(FileName);
ApplyImportSettings(setting);
break; break;
case ".dds": case ".dds":
setting.LoadDDS(FileName, bntxFile, null, this); setting.LoadDDS(FileName, bntxFile, null, this);
ApplyImportSettings(setting);
break; break;
default: default:
setting.LoadBitMap(FileName, bntxFile); setting.LoadBitMap(FileName, bntxFile);
importer.LoadSetting(setting, (BNTX)Parent); importer.LoadSetting(setting, (BNTX)Parent);
if (importer.ShowDialog() == DialogResult.OK)
{
ApplyImportSettings(setting);
}
break; break;
} }
if (importer.ShowDialog() == DialogResult.OK) }
private void ApplyImportSettings(TextureImporterSettings setting)
{ {
Cursor.Current = Cursors.WaitCursor; Cursor.Current = Cursors.WaitCursor;
@ -1149,7 +1195,6 @@ namespace FirstPlugin
UpdateBfresTextureMapping(); UpdateBfresTextureMapping();
UpdateBNTXEditor(); UpdateBNTXEditor();
} }
}
private void UpdateBfresTextureMapping() private void UpdateBfresTextureMapping()
{ {
foreach (GL_Core.Interfaces.AbstractGlDrawable draw in Runtime.abstractGlDrawables) foreach (GL_Core.Interfaces.AbstractGlDrawable draw in Runtime.abstractGlDrawables)
@ -1193,41 +1238,22 @@ namespace FirstPlugin
case ".dds": case ".dds":
SaveDDS(FileName); SaveDDS(FileName);
break; break;
case ".astc":
SaveASTC(FileName);
break;
default: default:
SaveBitMap(FileName); SaveBitMap(FileName);
break; break;
} }
} }
internal void SaveBitMap(string FileName, int SurfaceLevel = 0, int MipLevel = 0)
{
Bitmap bitMap = DisplayTexture(MipLevel, SurfaceLevel);
bitMap.Save(FileName);
}
internal void SaveBinaryTexture(string FileName) internal void SaveBinaryTexture(string FileName)
{ {
Console.WriteLine("Test"); Console.WriteLine("Test");
Texture.Export(FileName, bntxFile); Texture.Export(FileName, bntxFile);
} }
internal void SaveDDS(string FileName)
{
DDS dds = new DDS();
dds.header = new DDS.Header();
dds.header.width = Texture.Width;
dds.header.height = Texture.Height;
dds.header.mipmapCount = (uint)mipmaps.Count;
dds.header.pitchOrLinearSize = (uint)mipmaps[0][0].Length;
if (IsCompressedFormat(Texture.Format))
dds.SetFlags(GetCompressedDXGI_FORMAT(Texture.Format));
else
dds.SetFlags(GetUncompressedDXGI_FORMAT(Texture.Format));
dds.Save(dds, FileName, mipmaps);
}
public void LoadTexture(Texture tex, int target = 1) public void LoadTexture(Texture tex, int target = 1)
{ {
mipmaps.Clear(); surfaces.Clear();
try try
{ {
@ -1259,7 +1285,7 @@ namespace FirstPlugin
mips.Add(result_); mips.Add(result_);
} }
mipmaps.Add(mips); surfaces.Add(new Surface() { mipmaps = mips });
} }
Texture = tex; Texture = tex;
@ -1275,7 +1301,7 @@ namespace FirstPlugin
{ {
LoadTexture(Texture); LoadTexture(Texture);
if (mipmaps.Count <= 0) if (surfaces.Count <= 0)
{ {
throw new Exception("No texture data found"); throw new Exception("No texture data found");
} }
@ -1283,7 +1309,7 @@ namespace FirstPlugin
uint width = (uint)Math.Max(1, Texture.Width >> DisplayMipIndex); uint width = (uint)Math.Max(1, Texture.Width >> DisplayMipIndex);
uint height = (uint)Math.Max(1, Texture.Height >> DisplayMipIndex); uint height = (uint)Math.Max(1, Texture.Height >> DisplayMipIndex);
byte[] data = mipmaps[ArrayIndex][DisplayMipIndex]; byte[] data = surfaces[ArrayIndex].mipmaps[DisplayMipIndex];
return DecodeBlock(data, width, height, Texture.Format); return DecodeBlock(data, width, height, Texture.Format);
} }

View file

@ -12,6 +12,7 @@ using OpenTK;
using OpenTK.Graphics.OpenGL; using OpenTK.Graphics.OpenGL;
using Smash_Forge.Rendering; using Smash_Forge.Rendering;
using WeifenLuo.WinFormsUI.Docking; using WeifenLuo.WinFormsUI.Docking;
using Switch_Toolbox.Library.IO;
namespace FirstPlugin namespace FirstPlugin
{ {
@ -91,9 +92,9 @@ namespace FirstPlugin
GTX.GX2Surface tex = setting.CreateGx2Texture(setting.DataBlockOutput[0]); GTX.GX2Surface tex = setting.CreateGx2Texture(setting.DataBlockOutput[0]);
FTEX ftex = new FTEX(); FTEX ftex = new FTEX();
ftex.texture = ftex.FromGx2Surface(tex, setting); ftex.texture = ftex.FromGx2Surface(tex, setting);
Nodes.Add(ftex);
ftex.Read(ftex.texture); ftex.Read(ftex.texture);
Nodes.Add(ftex);
Textures.Add(ftex.Text, ftex); Textures.Add(ftex.Text, ftex);
ftex.LoadOpenGLTexture(); ftex.LoadOpenGLTexture();
} }
@ -123,9 +124,9 @@ namespace FirstPlugin
GTX.GX2Surface tex = setting.CreateGx2Texture(setting.DataBlockOutput[0]); GTX.GX2Surface tex = setting.CreateGx2Texture(setting.DataBlockOutput[0]);
FTEX ftex = new FTEX(); FTEX ftex = new FTEX();
ftex.texture = ftex.FromGx2Surface(tex, setting); ftex.texture = ftex.FromGx2Surface(tex, setting);
Nodes.Add(ftex);
ftex.Read(ftex.texture); ftex.Read(ftex.texture);
Nodes.Add(ftex);
Textures.Add(ftex.Text, ftex); Textures.Add(ftex.Text, ftex);
ftex.LoadOpenGLTexture(); ftex.LoadOpenGLTexture();
} }
@ -200,7 +201,7 @@ namespace FirstPlugin
} }
} }
public class FTEX : TreeNodeCustom public class FTEX : STGenericTexture
{ {
public int format; public int format;
public RenderableTex renderedTex = new RenderableTex(); public RenderableTex renderedTex = new RenderableTex();
@ -222,6 +223,14 @@ namespace FirstPlugin
ContextMenu.MenuItems.Add(rename); ContextMenu.MenuItems.Add(rename);
rename.Click += Rename; rename.Click += Rename;
} }
//For determining mip map file for botw (Tex2)
public string GetFilePath()
{
if (Parent == null)
throw new Exception("Parent is null!");
return ((BFRES)Parent.Parent).FilePath;
}
private void Replace(object sender, EventArgs args) private void Replace(object sender, EventArgs args)
{ {
@ -365,26 +374,16 @@ namespace FirstPlugin
texture = tex; texture = tex;
renderedTex = new RenderableTex(); renderedTex = new RenderableTex();
renderedTex.width = (int)tex.Width; Width = tex.Width;
renderedTex.height = (int)tex.Height; Height = tex.Height;
renderedTex.width = (int)Width;
renderedTex.height = (int)Height;
format = (int)tex.Format; format = (int)tex.Format;
int swizzle = (int)tex.Swizzle; int swizzle = (int)tex.Swizzle;
int pitch = (int)tex.Pitch; int pitch = (int)tex.Pitch;
uint bpp = GTX.surfaceGetBitsPerPixel((uint)format) >> 3; uint bpp = GTX.surfaceGetBitsPerPixel((uint)format) >> 3;
Console.WriteLine(tex.Width);
Console.WriteLine(tex.Height);
Console.WriteLine(tex.Format);
Console.WriteLine(tex.Swizzle);
Console.WriteLine(tex.Pitch);
Console.WriteLine(tex.Alignment);
Console.WriteLine(tex.Depth);
Console.WriteLine(tex.Dim);
Console.WriteLine(tex.MipCount);
Console.WriteLine(tex.MipOffsets);
Console.WriteLine(tex.AAMode);
Console.WriteLine(tex.Use);
GTX.GX2Surface surf = new GTX.GX2Surface(); GTX.GX2Surface surf = new GTX.GX2Surface();
surf.bpp = bpp; surf.bpp = bpp;
surf.height = tex.Height; surf.height = tex.Height;
@ -403,8 +402,39 @@ namespace FirstPlugin
surf.tileMode = (uint)tex.TileMode; surf.tileMode = (uint)tex.TileMode;
surf.swizzle = tex.Swizzle; surf.swizzle = tex.Swizzle;
if (IsCompressedFormat(tex.Format))
Format = GetCompressedDXGI_FORMAT(tex.Format);
else
Format = GetUncompressedDXGI_FORMAT(tex.Format);
//Determine tex2 botw files to get mip maps
string Tex1 = GetFilePath();
if (Tex1.Contains(".Tex1"))
{
string Tex2 = Tex1.Replace(".Tex1", ".Tex2");
Console.WriteLine(Tex2);
if (System.IO.File.Exists(Tex2))
{
ResFile resFile2 = new ResFile(new System.IO.MemoryStream(
EveryFileExplorer.YAZ0.Decompress(Tex2)));
if (resFile2.Textures.ContainsKey(tex.Name))
{
surf.mipData = resFile2.Textures[tex.Name].MipData;
surf.mipOffset = resFile2.Textures[tex.Name].MipOffsets;
}
}
}
if (surf.mipData == null)
surf.numMips = 1;
List<byte[]> mips = GTX.Decode(surf); List<byte[]> mips = GTX.Decode(surf);
renderedTex.mipmaps.Add(mips); renderedTex.mipmaps.Add(mips);
surfaces.Add(new Surface() { mipmaps = mips });
renderedTex.data = renderedTex.mipmaps[0][0]; renderedTex.data = renderedTex.mipmaps[0][0];
@ -474,18 +504,18 @@ namespace FirstPlugin
{ {
DDS dds = new DDS(); DDS dds = new DDS();
dds.header = new DDS.Header(); dds.header = new DDS.Header();
dds.header.width = (uint)renderedTex.width; dds.header.width = Width;
dds.header.height = (uint)renderedTex.width; dds.header.height = Height;
dds.header.mipmapCount = (uint)renderedTex.mipmaps[0].Count; dds.header.mipmapCount = (uint)surfaces[0].mipmaps.Count;
dds.header.pitchOrLinearSize = (uint)renderedTex.mipmaps[0][0].Length; dds.header.pitchOrLinearSize = (uint)surfaces[0].mipmaps[0].Length;
if (IsCompressedFormat((GX2SurfaceFormat)format)) if (IsCompressedFormat((GX2SurfaceFormat)format))
dds.SetFlags(GetCompressedDXGI_FORMAT((GX2SurfaceFormat)format)); dds.SetFlags((DDS.DXGI_FORMAT)GetCompressedDXGI_FORMAT((GX2SurfaceFormat)format));
else else
dds.SetFlags(GetUncompressedDXGI_FORMAT((GX2SurfaceFormat)format)); dds.SetFlags((DDS.DXGI_FORMAT)GetUncompressedDXGI_FORMAT((GX2SurfaceFormat)format));
dds.Save(dds, FileName, renderedTex.mipmaps); dds.Save(dds, FileName, surfaces);
} }
@ -497,44 +527,49 @@ namespace FirstPlugin
switch (format) switch (format)
{ {
case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC1_UNORM): case ((int)GTX.GX2SurfaceFormat.T_BC1_UNORM):
renderedTex.pixelInternalFormat = PixelInternalFormat.CompressedRgbaS3tcDxt1Ext; renderedTex.pixelInternalFormat = PixelInternalFormat.CompressedRgbaS3tcDxt1Ext;
break; break;
case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC1_SRGB): case ((int)GTX.GX2SurfaceFormat.T_BC1_SRGB):
renderedTex.pixelInternalFormat = PixelInternalFormat.CompressedRgbaS3tcDxt1Ext; renderedTex.pixelInternalFormat = PixelInternalFormat.CompressedRgbaS3tcDxt1Ext;
break; break;
case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC2_UNORM): case ((int)GTX.GX2SurfaceFormat.T_BC2_UNORM):
renderedTex.pixelInternalFormat = PixelInternalFormat.CompressedRgbaS3tcDxt3Ext; renderedTex.pixelInternalFormat = PixelInternalFormat.CompressedRgbaS3tcDxt3Ext;
break; break;
case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC2_SRGB): case ((int)GTX.GX2SurfaceFormat.T_BC2_SRGB):
renderedTex.pixelInternalFormat = PixelInternalFormat.CompressedSrgbAlphaS3tcDxt3Ext; renderedTex.pixelInternalFormat = PixelInternalFormat.CompressedSrgbAlphaS3tcDxt3Ext;
break; break;
case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC3_UNORM): case ((int)GTX.GX2SurfaceFormat.T_BC3_UNORM):
renderedTex.pixelInternalFormat = PixelInternalFormat.CompressedRgbaS3tcDxt5Ext; renderedTex.pixelInternalFormat = PixelInternalFormat.CompressedRgbaS3tcDxt5Ext;
break; break;
case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC3_SRGB): case ((int)GTX.GX2SurfaceFormat.T_BC3_SRGB):
renderedTex.pixelInternalFormat = PixelInternalFormat.CompressedSrgbAlphaS3tcDxt5Ext; renderedTex.pixelInternalFormat = PixelInternalFormat.CompressedSrgbAlphaS3tcDxt5Ext;
break; break;
case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC4_UNORM): case ((int)GTX.GX2SurfaceFormat.T_BC4_UNORM):
renderedTex.pixelInternalFormat = PixelInternalFormat.CompressedRedRgtc1; renderedTex.pixelInternalFormat = PixelInternalFormat.CompressedRedRgtc1;
break; break;
case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC4_SNORM): case ((int)GTX.GX2SurfaceFormat.T_BC4_SNORM):
renderedTex.pixelInternalFormat = PixelInternalFormat.CompressedSignedRedRgtc1; renderedTex.pixelInternalFormat = PixelInternalFormat.CompressedSignedRedRgtc1;
break; break;
case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC5_UNORM): case ((int)GTX.GX2SurfaceFormat.T_BC5_UNORM):
renderedTex.pixelInternalFormat = PixelInternalFormat.CompressedRgRgtc2; renderedTex.pixelInternalFormat = PixelInternalFormat.CompressedRgRgtc2;
break; break;
case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC5_SNORM): case ((int)GTX.GX2SurfaceFormat.T_BC5_SNORM):
//OpenTK doesn't load BC5 SNORM textures right so I'll use the same decompress method bntx has //OpenTK doesn't load BC5 SNORM textures right so I'll use the same decompress method bntx has
renderedTex.data = DDSCompressor.DecompressBC5(renderedTex.mipmaps[0][0], (int)renderedTex.width, (int)renderedTex.height, true, true); renderedTex.data = DDSCompressor.DecompressBC5(renderedTex.mipmaps[0][0], (int)renderedTex.width, (int)renderedTex.height, true, true);
renderedTex.pixelInternalFormat = PixelInternalFormat.Rgba; renderedTex.pixelInternalFormat = PixelInternalFormat.Rgba;
renderedTex.pixelFormat = OpenTK.Graphics.OpenGL.PixelFormat.Rgba; renderedTex.pixelFormat = OpenTK.Graphics.OpenGL.PixelFormat.Rgba;
break; break;
case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM): case ((int)GTX.GX2SurfaceFormat.TCS_R8_G8_B8_A8_UNORM):
renderedTex.pixelInternalFormat = PixelInternalFormat.Rgba; renderedTex.pixelInternalFormat = PixelInternalFormat.Rgba;
renderedTex.pixelFormat = OpenTK.Graphics.OpenGL.PixelFormat.Rgba; renderedTex.pixelFormat = OpenTK.Graphics.OpenGL.PixelFormat.Rgba;
break; break;
case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_SRGB): case ((int)GTX.GX2SurfaceFormat.TCS_R8_G8_B8_A8_SRGB):
renderedTex.pixelInternalFormat = PixelInternalFormat.Rgba;
renderedTex.pixelFormat = OpenTK.Graphics.OpenGL.PixelFormat.Rgba;
break;
default:
renderedTex.data = BitmapExtension.ImageToByte(DecodeBlock(renderedTex.data, (uint)renderedTex.width, (uint)renderedTex.height, (GX2SurfaceFormat)format));
renderedTex.pixelInternalFormat = PixelInternalFormat.Rgba; renderedTex.pixelInternalFormat = PixelInternalFormat.Rgba;
renderedTex.pixelFormat = OpenTK.Graphics.OpenGL.PixelFormat.Rgba; renderedTex.pixelFormat = OpenTK.Graphics.OpenGL.PixelFormat.Rgba;
break; break;
@ -659,15 +694,22 @@ namespace FirstPlugin
if (Format == GX2SurfaceFormat.T_BC5_SNorm) if (Format == GX2SurfaceFormat.T_BC5_SNorm)
return DDSCompressor.DecompressBC5(data, (int)Width, (int)Height, true); return DDSCompressor.DecompressBC5(data, (int)Width, (int)Height, true);
if (Format == GX2SurfaceFormat.TC_R8_UNorm)
System.IO.File.WriteAllBytes("TC_R8_UNorm2.bin", data);
byte[] d = null; byte[] d = null;
if (IsCompressedFormat(Format)) if (IsCompressedFormat(Format))
d = DDSCompressor.DecompressBlock(data, (int)Width, (int)Height, GetCompressedDXGI_FORMAT(Format)); d = DDSCompressor.DecompressBlock(data, (int)Width, (int)Height, (DDS.DXGI_FORMAT)GetCompressedDXGI_FORMAT(Format));
else else
d = DDSCompressor.DecodePixelBlock(data, (int)Width, (int)Height, GetUncompressedDXGI_FORMAT(Format)); d = DDSCompressor.DecodePixelBlock(data, (int)Width, (int)Height, (DDS.DXGI_FORMAT)GetUncompressedDXGI_FORMAT(Format));
if (d != null) if (d != null)
{ {
decomp = BitmapExtension.GetBitmap(d, (int)Width, (int)Height); decomp = BitmapExtension.GetBitmap(d, (int)Width, (int)Height);
if (Format == GX2SurfaceFormat.TCS_R5_G6_B5_UNorm)
return decomp;
else
return SwapBlueRedChannels(decomp); return SwapBlueRedChannels(decomp);
} }
return BitmapExtension.GetBitmap(d, (int)Width, (int)Height);; return BitmapExtension.GetBitmap(d, (int)Width, (int)Height);;
@ -677,30 +719,30 @@ namespace FirstPlugin
throw new Exception($"Bad size from format {Format}"); throw new Exception($"Bad size from format {Format}");
} }
} }
public static byte[] CompressBlock(byte[] data, int width, int height, GTX.GX2SurfaceFormat format) public static byte[] CompressBlock(byte[] data, int width, int height, GTX.GX2SurfaceFormat format, float alphaRef)
{ {
if (IsCompressedFormat((GX2SurfaceFormat)format)) if (IsCompressedFormat((GX2SurfaceFormat)format))
return DDSCompressor.CompressBlock(data, width, height, GetCompressedDXGI_FORMAT((GX2SurfaceFormat)format)); return DDSCompressor.CompressBlock(data, width, height, (DDS.DXGI_FORMAT)GetCompressedDXGI_FORMAT((GX2SurfaceFormat)format), alphaRef);
else else
return DDSCompressor.EncodePixelBlock(data, width, height, GetUncompressedDXGI_FORMAT((GX2SurfaceFormat)format)); return DDSCompressor.EncodePixelBlock(data, width, height, (DDS.DXGI_FORMAT)GetUncompressedDXGI_FORMAT((GX2SurfaceFormat)format));
} }
private static DDS.DXGI_FORMAT GetUncompressedDXGI_FORMAT(GX2SurfaceFormat Format) private static TEX_FORMAT GetUncompressedDXGI_FORMAT(GX2SurfaceFormat Format)
{ {
switch (Format) switch (Format)
{ {
case GX2SurfaceFormat.TC_R5_G5_B5_A1_UNorm: return DDS.DXGI_FORMAT.DXGI_FORMAT_B5G5R5A1_UNORM; case GX2SurfaceFormat.TC_R5_G5_B5_A1_UNorm: return TEX_FORMAT.B5G5R5A1_UNORM;
case GX2SurfaceFormat.TC_A1_B5_G5_R5_UNorm: return DDS.DXGI_FORMAT.DXGI_FORMAT_B5G5R5A1_UNORM; case GX2SurfaceFormat.TC_A1_B5_G5_R5_UNorm: return TEX_FORMAT.B5G5R5A1_UNORM;
case GX2SurfaceFormat.TC_R4_G4_B4_A4_UNorm: return DDS.DXGI_FORMAT.DXGI_FORMAT_B4G4R4A4_UNORM; case GX2SurfaceFormat.TC_R4_G4_B4_A4_UNorm: return TEX_FORMAT.B4G4R4A4_UNORM;
case GX2SurfaceFormat.TCS_R5_G6_B5_UNorm: return DDS.DXGI_FORMAT.DXGI_FORMAT_B5G6R5_UNORM; case GX2SurfaceFormat.TCS_R5_G6_B5_UNorm: return TEX_FORMAT.B5G6R5_UNORM;
case GX2SurfaceFormat.TCS_R8_G8_B8_A8_SRGB: return DDS.DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM; case GX2SurfaceFormat.TCS_R8_G8_B8_A8_SRGB: return TEX_FORMAT.R8G8B8A8_UNORM;
case GX2SurfaceFormat.TCS_R8_G8_B8_A8_UNorm: return DDS.DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM; case GX2SurfaceFormat.TCS_R8_G8_B8_A8_UNorm: return TEX_FORMAT.R8G8B8A8_UNORM;
case GX2SurfaceFormat.TCS_R10_G10_B10_A2_UNorm: return DDS.DXGI_FORMAT.DXGI_FORMAT_R10G10B10A2_UNORM; case GX2SurfaceFormat.TCS_R10_G10_B10_A2_UNorm: return TEX_FORMAT.R10G10B10A2_UNORM;
case GX2SurfaceFormat.TC_R11_G11_B10_Float: return DDS.DXGI_FORMAT.DXGI_FORMAT_R11G11B10_FLOAT; case GX2SurfaceFormat.TC_R11_G11_B10_Float: return TEX_FORMAT.R11G11B10_FLOAT;
case GX2SurfaceFormat.TCD_R16_UNorm: return DDS.DXGI_FORMAT.DXGI_FORMAT_R16_UNORM; case GX2SurfaceFormat.TCD_R16_UNorm: return TEX_FORMAT.R16_UNORM;
case GX2SurfaceFormat.TCD_R32_Float: return DDS.DXGI_FORMAT.DXGI_FORMAT_R32_FLOAT; case GX2SurfaceFormat.TCD_R32_Float: return TEX_FORMAT.R32_FLOAT;
case GX2SurfaceFormat.T_R4_G4_UNorm: return DDS.DXGI_FORMAT.DXGI_FORMAT_B4G4R4A4_UNORM; case GX2SurfaceFormat.T_R4_G4_UNorm: return TEX_FORMAT.B4G4R4A4_UNORM;
case GX2SurfaceFormat.TC_R8_G8_UNorm: return DDS.DXGI_FORMAT.DXGI_FORMAT_R8G8_UNORM; case GX2SurfaceFormat.TC_R8_G8_UNorm: return TEX_FORMAT.R8G8_UNORM;
case GX2SurfaceFormat.TC_R8_UNorm: return DDS.DXGI_FORMAT.DXGI_FORMAT_R8_UNORM; case GX2SurfaceFormat.TC_R8_UNorm: return TEX_FORMAT.R8_UNORM;
case GX2SurfaceFormat.Invalid: throw new Exception("Invalid Format"); case GX2SurfaceFormat.Invalid: throw new Exception("Invalid Format");
default: default:
throw new Exception($"Cannot convert format {Format}"); throw new Exception($"Cannot convert format {Format}");
@ -725,20 +767,20 @@ namespace FirstPlugin
return false; return false;
} }
} }
private static DDS.DXGI_FORMAT GetCompressedDXGI_FORMAT(GX2SurfaceFormat Format) private static TEX_FORMAT GetCompressedDXGI_FORMAT(GX2SurfaceFormat Format)
{ {
switch (Format) switch (Format)
{ {
case GX2SurfaceFormat.T_BC1_UNorm: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM; case GX2SurfaceFormat.T_BC1_UNorm: return TEX_FORMAT.BC1_UNORM;
case GX2SurfaceFormat.T_BC1_SRGB: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM; case GX2SurfaceFormat.T_BC1_SRGB: return TEX_FORMAT.BC1_UNORM;
case GX2SurfaceFormat.T_BC2_UNorm: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM; case GX2SurfaceFormat.T_BC2_UNorm: return TEX_FORMAT.BC2_UNORM;
case GX2SurfaceFormat.T_BC2_SRGB: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM; case GX2SurfaceFormat.T_BC2_SRGB: return TEX_FORMAT.BC2_UNORM;
case GX2SurfaceFormat.T_BC3_UNorm: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM; case GX2SurfaceFormat.T_BC3_UNorm: return TEX_FORMAT.BC3_UNORM;
case GX2SurfaceFormat.T_BC3_SRGB: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM; case GX2SurfaceFormat.T_BC3_SRGB: return TEX_FORMAT.BC3_UNORM;
case GX2SurfaceFormat.T_BC4_UNorm: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC4_UNORM; case GX2SurfaceFormat.T_BC4_UNorm: return TEX_FORMAT.BC4_UNORM;
case GX2SurfaceFormat.T_BC4_SNorm: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC4_SNORM; case GX2SurfaceFormat.T_BC4_SNorm: return TEX_FORMAT.BC4_SNORM;
case GX2SurfaceFormat.T_BC5_UNorm: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC5_UNORM; case GX2SurfaceFormat.T_BC5_UNorm: return TEX_FORMAT.BC5_UNORM;
case GX2SurfaceFormat.T_BC5_SNorm: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC5_SNORM; case GX2SurfaceFormat.T_BC5_SNorm: return TEX_FORMAT.BC5_SNORM;
default: default:
throw new Exception($"Cannot convert format {Format}"); throw new Exception($"Cannot convert format {Format}");
} }

View file

@ -6,7 +6,6 @@ namespace FirstPlugin
public class GTX public class GTX
{ {
//Some enums and parts from https://github.com/jam1garner/Smash-Forge/blob/master/Smash%20Forge/Filetypes/Textures/GTX.cs //Some enums and parts from https://github.com/jam1garner/Smash-Forge/blob/master/Smash%20Forge/Filetypes/Textures/GTX.cs
//Todo. Add swizzling back
public class GX2Surface public class GX2Surface
{ {
public uint dim; public uint dim;
@ -110,90 +109,90 @@ namespace FirstPlugin
public enum GX2SurfaceDimension public enum GX2SurfaceDimension
{ {
GX2_SURFACE_DIM_1D = 0x0, DIM_1D = 0x0,
GX2_SURFACE_DIM_2D = 0x1, DIM_2D = 0x1,
GX2_SURFACE_DIM_3D = 0x2, DIM_3D = 0x2,
GX2_SURFACE_DIM_CUBE = 0x3, DIM_CUBE = 0x3,
GX2_SURFACE_DIM_1D_ARRAY = 0x4, DIM_1D_ARRAY = 0x4,
GX2_SURFACE_DIM_2D_ARRAY = 0x5, DIM_2D_ARRAY = 0x5,
GX2_SURFACE_DIM_2D_MSAA = 0x6, DIM_2D_MSAA = 0x6,
GX2_SURFACE_DIM_2D_MSAA_ARRAY = 0x7, DIM_2D_MSAA_ARRAY = 0x7,
GX2_SURFACE_DIM_FIRST = 0x0, DIM_FIRST = 0x0,
GX2_SURFACE_DIM_LAST = 0x7, DIM_LAST = 0x7,
}; };
public enum GX2SurfaceFormat public enum GX2SurfaceFormat
{ {
GX2_SURFACE_FORMAT_INVALID = 0x0, INVALID = 0x0,
GX2_SURFACE_FORMAT_TC_R8_UNORM = 0x1, TC_R8_UNORM = 0x1,
GX2_SURFACE_FORMAT_TC_R8_UINT = 0x101, TC_R8_UINT = 0x101,
GX2_SURFACE_FORMAT_TC_R8_SNORM = 0x201, TC_R8_SNORM = 0x201,
GX2_SURFACE_FORMAT_TC_R8_SINT = 0x301, TC_R8_SINT = 0x301,
GX2_SURFACE_FORMAT_T_R4_G4_UNORM = 0x2, T_R4_G4_UNORM = 0x2,
GX2_SURFACE_FORMAT_TCD_R16_UNORM = 0x5, TCD_R16_UNORM = 0x5,
GX2_SURFACE_FORMAT_TC_R16_UINT = 0x105, TC_R16_UINT = 0x105,
GX2_SURFACE_FORMAT_TC_R16_SNORM = 0x205, TC_R16_SNORM = 0x205,
GX2_SURFACE_FORMAT_TC_R16_SINT = 0x305, TC_R16_SINT = 0x305,
GX2_SURFACE_FORMAT_TC_R16_FLOAT = 0x806, TC_R16_FLOAT = 0x806,
GX2_SURFACE_FORMAT_TC_R8_G8_UNORM = 0x7, TC_R8_G8_UNORM = 0x7,
GX2_SURFACE_FORMAT_TC_R8_G8_UINT = 0x107, TC_R8_G8_UINT = 0x107,
GX2_SURFACE_FORMAT_TC_R8_G8_SNORM = 0x207, TC_R8_G8_SNORM = 0x207,
GX2_SURFACE_FORMAT_TC_R8_G8_SINT = 0x307, TC_R8_G8_SINT = 0x307,
GX2_SURFACE_FORMAT_TCS_R5_G6_B5_UNORM = 0x8, TCS_R5_G6_B5_UNORM = 0x8,
GX2_SURFACE_FORMAT_TC_R5_G5_B5_A1_UNORM = 0xA, TC_R5_G5_B5_A1_UNORM = 0xA,
GX2_SURFACE_FORMAT_TC_R4_G4_B4_A4_UNORM = 0xB, TC_R4_G4_B4_A4_UNORM = 0xB,
GX2_SURFACE_FORMAT_TC_A1_B5_G5_R5_UNORM = 0xC, TC_A1_B5_G5_R5_UNORM = 0xC,
GX2_SURFACE_FORMAT_TC_R32_UINT = 0x10D, TC_R32_UINT = 0x10D,
GX2_SURFACE_FORMAT_TC_R32_SINT = 0x30D, TC_R32_SINT = 0x30D,
GX2_SURFACE_FORMAT_TCD_R32_FLOAT = 0x80E, TCD_R32_FLOAT = 0x80E,
GX2_SURFACE_FORMAT_TC_R16_G16_UNORM = 0xF, TC_R16_G16_UNORM = 0xF,
GX2_SURFACE_FORMAT_TC_R16_G16_UINT = 0x10F, TC_R16_G16_UINT = 0x10F,
GX2_SURFACE_FORMAT_TC_R16_G16_SNORM = 0x20F, TC_R16_G16_SNORM = 0x20F,
GX2_SURFACE_FORMAT_TC_R16_G16_SINT = 0x30F, TC_R16_G16_SINT = 0x30F,
GX2_SURFACE_FORMAT_TC_R16_G16_FLOAT = 0x810, TC_R16_G16_FLOAT = 0x810,
GX2_SURFACE_FORMAT_D_D24_S8_UNORM = 0x11, D_D24_S8_UNORM = 0x11,
GX2_SURFACE_FORMAT_T_R24_UNORM_X8 = 0x11, T_R24_UNORM_X8 = 0x11,
GX2_SURFACE_FORMAT_T_X24_G8_UINT = 0x111, T_X24_G8_UINT = 0x111,
GX2_SURFACE_FORMAT_D_D24_S8_FLOAT = 0x811, D_D24_S8_FLOAT = 0x811,
GX2_SURFACE_FORMAT_TC_R11_G11_B10_FLOAT = 0x816, TC_R11_G11_B10_FLOAT = 0x816,
GX2_SURFACE_FORMAT_TCS_R10_G10_B10_A2_UNORM = 0x19, TCS_R10_G10_B10_A2_UNORM = 0x19,
GX2_SURFACE_FORMAT_TC_R10_G10_B10_A2_UINT = 0x119, TC_R10_G10_B10_A2_UINT = 0x119,
GX2_SURFACE_FORMAT_T_R10_G10_B10_A2_SNORM = 0x219, T_R10_G10_B10_A2_SNORM = 0x219,
GX2_SURFACE_FORMAT_TC_R10_G10_B10_A2_SNORM = 0x219, TC_R10_G10_B10_A2_SNORM = 0x219,
GX2_SURFACE_FORMAT_TC_R10_G10_B10_A2_SINT = 0x319, TC_R10_G10_B10_A2_SINT = 0x319,
GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM = 0x1A, TCS_R8_G8_B8_A8_UNORM = 0x1A,
GX2_SURFACE_FORMAT_TC_R8_G8_B8_A8_UINT = 0x11A, TC_R8_G8_B8_A8_UINT = 0x11A,
GX2_SURFACE_FORMAT_TC_R8_G8_B8_A8_SNORM = 0x21A, TC_R8_G8_B8_A8_SNORM = 0x21A,
GX2_SURFACE_FORMAT_TC_R8_G8_B8_A8_SINT = 0x31A, TC_R8_G8_B8_A8_SINT = 0x31A,
GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_SRGB = 0x41A, TCS_R8_G8_B8_A8_SRGB = 0x41A,
GX2_SURFACE_FORMAT_TCS_A2_B10_G10_R10_UNORM = 0x1B, TCS_A2_B10_G10_R10_UNORM = 0x1B,
GX2_SURFACE_FORMAT_TC_A2_B10_G10_R10_UINT = 0x11B, TC_A2_B10_G10_R10_UINT = 0x11B,
GX2_SURFACE_FORMAT_D_D32_FLOAT_S8_UINT_X24 = 0x81C, D_D32_FLOAT_S8_UINT_X24 = 0x81C,
GX2_SURFACE_FORMAT_T_R32_FLOAT_X8_X24 = 0x81C, T_R32_FLOAT_X8_X24 = 0x81C,
GX2_SURFACE_FORMAT_T_X32_G8_UINT_X24 = 0x11C, T_X32_G8_UINT_X24 = 0x11C,
GX2_SURFACE_FORMAT_TC_R32_G32_UINT = 0x11D, TC_R32_G32_UINT = 0x11D,
GX2_SURFACE_FORMAT_TC_R32_G32_SINT = 0x31D, TC_R32_G32_SINT = 0x31D,
GX2_SURFACE_FORMAT_TC_R32_G32_FLOAT = 0x81E, TC_R32_G32_FLOAT = 0x81E,
GX2_SURFACE_FORMAT_TC_R16_G16_B16_A16_UNORM = 0x1F, TC_R16_G16_B16_A16_UNORM = 0x1F,
GX2_SURFACE_FORMAT_TC_R16_G16_B16_A16_UINT = 0x11F, TC_R16_G16_B16_A16_UINT = 0x11F,
GX2_SURFACE_FORMAT_TC_R16_G16_B16_A16_SNORM = 0x21F, TC_R16_G16_B16_A16_SNORM = 0x21F,
GX2_SURFACE_FORMAT_TC_R16_G16_B16_A16_SINT = 0x31F, TC_R16_G16_B16_A16_SINT = 0x31F,
GX2_SURFACE_FORMAT_TC_R16_G16_B16_A16_FLOAT = 0x820, TC_R16_G16_B16_A16_FLOAT = 0x820,
GX2_SURFACE_FORMAT_TC_R32_G32_B32_A32_UINT = 0x122, TC_R32_G32_B32_A32_UINT = 0x122,
GX2_SURFACE_FORMAT_TC_R32_G32_B32_A32_SINT = 0x322, TC_R32_G32_B32_A32_SINT = 0x322,
GX2_SURFACE_FORMAT_TC_R32_G32_B32_A32_FLOAT = 0x823, TC_R32_G32_B32_A32_FLOAT = 0x823,
GX2_SURFACE_FORMAT_T_BC1_UNORM = 0x31, T_BC1_UNORM = 0x31,
GX2_SURFACE_FORMAT_T_BC1_SRGB = 0x431, T_BC1_SRGB = 0x431,
GX2_SURFACE_FORMAT_T_BC2_UNORM = 0x32, T_BC2_UNORM = 0x32,
GX2_SURFACE_FORMAT_T_BC2_SRGB = 0x432, T_BC2_SRGB = 0x432,
GX2_SURFACE_FORMAT_T_BC3_UNORM = 0x33, T_BC3_UNORM = 0x33,
GX2_SURFACE_FORMAT_T_BC3_SRGB = 0x433, T_BC3_SRGB = 0x433,
GX2_SURFACE_FORMAT_T_BC4_UNORM = 0x34, T_BC4_UNORM = 0x34,
GX2_SURFACE_FORMAT_T_BC4_SNORM = 0x234, T_BC4_SNORM = 0x234,
GX2_SURFACE_FORMAT_T_BC5_UNORM = 0x35, T_BC5_UNORM = 0x35,
GX2_SURFACE_FORMAT_T_BC5_SNORM = 0x235, T_BC5_SNORM = 0x235,
GX2_SURFACE_FORMAT_T_NV12_UNORM = 0x81, T_NV12_UNORM = 0x81,
GX2_SURFACE_FORMAT_FIRST = 0x1, FIRST = 0x1,
GX2_SURFACE_FORMAT_LAST = 0x83F, LAST = 0x83F,
}; };
public enum GX2AAMode public enum GX2AAMode
{ {
@ -206,17 +205,17 @@ namespace FirstPlugin
}; };
public enum GX2SurfaceUse : uint public enum GX2SurfaceUse : uint
{ {
GX2_SURFACE_USE_TEXTURE = 0x1, USE_TEXTURE = 0x1,
GX2_SURFACE_USE_COLOR_BUFFER = 0x2, USE_COLOR_BUFFER = 0x2,
GX2_SURFACE_USE_DEPTH_BUFFER = 0x4, USE_DEPTH_BUFFER = 0x4,
GX2_SURFACE_USE_SCAN_BUFFER = 0x8, USE_SCAN_BUFFER = 0x8,
GX2_SURFACE_USE_FTV = 0x80000000, USE_FTV = 0x80000000,
GX2_SURFACE_USE_COLOR_BUFFER_TEXTURE = 0x3, USE_COLOR_BUFFER_TEXTURE = 0x3,
GX2_SURFACE_USE_DEPTH_BUFFER_TEXTURE = 0x5, USE_DEPTH_BUFFER_TEXTURE = 0x5,
GX2_SURFACE_USE_COLOR_BUFFER_FTV = 0x80000002, USE_COLOR_BUFFER_FTV = 0x80000002,
GX2_SURFACE_USE_COLOR_BUFFER_TEXTURE_FTV = 0x80000003, USE_COLOR_BUFFER_TEXTURE_FTV = 0x80000003,
GX2_SURFACE_USE_FIRST = 0x1, USE_FIRST = 0x1,
GX2_SURFACE_USE_LAST = 0x8, USE_LAST = 0x8,
}; };
public enum GX2RResourceFlags public enum GX2RResourceFlags
{ {
@ -262,26 +261,26 @@ namespace FirstPlugin
}; };
public enum GX2TileMode public enum GX2TileMode
{ {
GX2_TILE_MODE_DEFAULT = 0x0, MODE_DEFAULT = 0x0,
GX2_TILE_MODE_LINEAR_SPECIAL = 0x10, MODE_LINEAR_SPECIAL = 0x10,
GX2_TILE_MODE_DEFAULT_FIX2197 = 0x20, MODE_DEFAULT_FIX2197 = 0x20,
GX2_TILE_MODE_LINEAR_ALIGNED = 0x1, MODE_LINEAR_ALIGNED = 0x1,
GX2_TILE_MODE_1D_TILED_THIN1 = 0x2, MODE_1D_TILED_THIN1 = 0x2,
GX2_TILE_MODE_1D_TILED_THICK = 0x3, MODE_1D_TILED_THICK = 0x3,
GX2_TILE_MODE_2D_TILED_THIN1 = 0x4, MODE_2D_TILED_THIN1 = 0x4,
GX2_TILE_MODE_2D_TILED_THIN2 = 0x5, MODE_2D_TILED_THIN2 = 0x5,
GX2_TILE_MODE_2D_TILED_THIN4 = 0x6, MODE_2D_TILED_THIN4 = 0x6,
GX2_TILE_MODE_2D_TILED_THICK = 0x7, MODE_2D_TILED_THICK = 0x7,
GX2_TILE_MODE_2B_TILED_THIN1 = 0x8, MODE_2B_TILED_THIN1 = 0x8,
GX2_TILE_MODE_2B_TILED_THIN2 = 0x9, MODE_2B_TILED_THIN2 = 0x9,
GX2_TILE_MODE_2B_TILED_THIN4 = 0xA, MODE_2B_TILED_THIN4 = 0xA,
GX2_TILE_MODE_2B_TILED_THICK = 0xB, MODE_2B_TILED_THICK = 0xB,
GX2_TILE_MODE_3D_TILED_THIN1 = 0xC, MODE_3D_TILED_THIN1 = 0xC,
GX2_TILE_MODE_3D_TILED_THICK = 0xD, MODE_3D_TILED_THICK = 0xD,
GX2_TILE_MODE_3B_TILED_THIN1 = 0xE, MODE_3B_TILED_THIN1 = 0xE,
GX2_TILE_MODE_3B_TILED_THICK = 0xF, MODE_3B_TILED_THICK = 0xF,
GX2_TILE_MODE_FIRST = 0x0, MODE_FIRST = 0x0,
GX2_TILE_MODE_LAST = 0x20, MODE_LAST = 0x20,
}; };
public enum AddrTileMode public enum AddrTileMode
@ -429,6 +428,10 @@ namespace FirstPlugin
public static List<byte[]> Decode(GX2Surface tex) public static List<byte[]> Decode(GX2Surface tex)
{ {
if (tex.data == null) //Some ftex will only have mip maps
throw new Exception("Data is empty! Make sure to open a Tex1.sbfres if using Tex2!");
Console.WriteLine(""); Console.WriteLine("");
Console.WriteLine("// ----- GX2Surface Decode Info ----- "); Console.WriteLine("// ----- GX2Surface Decode Info ----- ");
Console.WriteLine(" dim = " + tex.dim); Console.WriteLine(" dim = " + tex.dim);
@ -496,6 +499,9 @@ namespace FirstPlugin
Array.Copy(deswizzled, 0, result_, 0, size); Array.Copy(deswizzled, 0, result_, 0, size);
result.Add(result_); result.Add(result_);
} }
if (tex.format == (uint)GX2SurfaceFormat.TC_R8_UNORM)
System.IO.File.WriteAllBytes("TC_R8_UNorm.bin", result[0]);
return result; return result;
} }
@ -512,16 +518,16 @@ namespace FirstPlugin
{ {
switch (Format) switch (Format)
{ {
case GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC1_UNORM: case GX2SurfaceFormat.T_BC1_UNORM:
case GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC1_SRGB: case GX2SurfaceFormat.T_BC1_SRGB:
case GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC2_UNORM: case GX2SurfaceFormat.T_BC2_UNORM:
case GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC2_SRGB: case GX2SurfaceFormat.T_BC2_SRGB:
case GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC3_UNORM: case GX2SurfaceFormat.T_BC3_UNORM:
case GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC3_SRGB: case GX2SurfaceFormat.T_BC3_SRGB:
case GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC4_UNORM: case GX2SurfaceFormat.T_BC4_UNORM:
case GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC4_SNORM: case GX2SurfaceFormat.T_BC4_SNORM:
case GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC5_SNORM: case GX2SurfaceFormat.T_BC5_SNORM:
case GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC5_UNORM: case GX2SurfaceFormat.T_BC5_UNORM:
return true; return true;
default: default:
return false; return false;

View file

@ -30,7 +30,7 @@ namespace FirstPlugin
UserBlock = 0x16, UserBlock = 0x16,
} }
public class GTXFile : TreeNode, IFileFormat public class GTXFile : TreeNodeFile, IFileFormat
{ {
public bool CanSave { get; set; } = false; public bool CanSave { get; set; } = false;
public bool FileIsEdited { get; set; } = false; public bool FileIsEdited { get; set; } = false;
@ -95,12 +95,45 @@ namespace FirstPlugin
using (FileWriter writer = new FileWriter(mem)) using (FileWriter writer = new FileWriter(mem))
{ {
writer.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian; writer.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian;
header.Write(writer); header.Write(writer);
uint surfBlockType;
uint dataBlockType;
uint mipBlockType;
if (header.MajorVersion == 6)
{
surfBlockType = 0x0A;
dataBlockType = 0x0B;
mipBlockType = 0x0C;
}
else if (header.MajorVersion == 7)
{
surfBlockType = 0x0B;
dataBlockType = 0x0C;
mipBlockType = 0x0D;
}
else
throw new Exception($"Unsupported GTX version {header.MajorVersion}");
writer.Seek(header.HeaderSize, System.IO.SeekOrigin.Begin); writer.Seek(header.HeaderSize, System.IO.SeekOrigin.Begin);
foreach (var tex in textures)
{
tex.surface.Write(writer);
}
foreach (var block in blocks) foreach (var block in blocks)
{
if ((uint)block.BlockType == surfBlockType)
{
block.Write(writer); block.Write(writer);
} }
else
{
block.Write(writer);
}
}
}
return mem.ToArray(); return mem.ToArray();
} }
private void ReadGx2(FileReader reader) private void ReadGx2(FileReader reader)
@ -287,7 +320,6 @@ namespace FirstPlugin
reader.Seek(blockStart + HeaderSize, System.IO.SeekOrigin.Begin); reader.Seek(blockStart + HeaderSize, System.IO.SeekOrigin.Begin);
data = reader.ReadBytes((int)DataSize); data = reader.ReadBytes((int)DataSize);
System.IO.File.WriteAllBytes($"block {BlockType}.bin", data);
} }
public void Write(FileWriter writer) public void Write(FileWriter writer)
{ {
@ -306,7 +338,7 @@ namespace FirstPlugin
writer.Write(data); writer.Write(data);
} }
} }
public class TextureData : TreeNodeCustom public class TextureData : STGenericTexture
{ {
public SurfaceInfoParse surface; public SurfaceInfoParse surface;
public RenderableTex renderedTex = new RenderableTex(); public RenderableTex renderedTex = new RenderableTex();
@ -384,7 +416,7 @@ namespace FirstPlugin
dds.Save(dds, FileName, renderedTex.mipmaps); dds.Save(dds, FileName, surfaces);
} }
private void Replace(object sender, EventArgs args) private void Replace(object sender, EventArgs args)
{ {

View file

@ -11,7 +11,7 @@ using Switch_Toolbox.Library.Forms;
namespace FirstPlugin namespace FirstPlugin
{ {
public class NUTEXB : TreeNodeFile, IFileFormat public class NUTEXB : STGenericTexture, IFileFormat
{ {
public bool CanSave { get; set; } = false; public bool CanSave { get; set; } = false;
public bool FileIsEdited { get; set; } = false; public bool FileIsEdited { get; set; } = false;
@ -22,7 +22,6 @@ namespace FirstPlugin
public CompressionType CompressionType { get; set; } = CompressionType.None; public CompressionType CompressionType { get; set; } = CompressionType.None;
public byte[] Data { get; set; } public byte[] Data { get; set; }
public string FileName { get; set; } public string FileName { get; set; }
public TreeNodeFile EditorRoot { get; set; }
public bool IsActive { get; set; } = false; public bool IsActive { get; set; } = false;
public bool UseEditMenu { get; set; } = false; public bool UseEditMenu { get; set; } = false;
public string FilePath { get; set; } public string FilePath { get; set; }
@ -156,7 +155,7 @@ namespace FirstPlugin
{ {
Console.WriteLine("Something went wrong??"); Console.WriteLine("Something went wrong??");
} }
texture.mipmaps.Clear(); texture.surfaces.Clear();
texture = null; texture = null;
@ -175,7 +174,6 @@ namespace FirstPlugin
public NUTEXImageFormat Format; public NUTEXImageFormat Format;
public List<uint[]> mipSizes = new List<uint[]>(); public List<uint[]> mipSizes = new List<uint[]>();
public int Alignment; public int Alignment;
public List<List<byte[]>> mipmaps = new List<List<byte[]>>();
public byte[] ImageData; public byte[] ImageData;
bool IsSwizzled = true; bool IsSwizzled = true;
public string ArcOffset; //Temp for exporting in batch public string ArcOffset; //Temp for exporting in batch
@ -183,24 +181,36 @@ namespace FirstPlugin
private void Replace(object sender, EventArgs args) private void Replace(object sender, EventArgs args)
{ {
OpenFileDialog ofd = new OpenFileDialog(); OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "Supported Formats|*.dds; *.png;*.tga;*.jpg;*.tiff|" + /* ofd.Filter = "Supported Formats|*.dds; *.png;*.tga;*.jpg;*.tiff|" +
"Microsoft DDS |*.dds|" + "Microsoft DDS |*.dds|" +
"Portable Network Graphics |*.png|" + "Portable Network Graphics |*.png|" +
"Joint Photographic Experts Group |*.jpg|" + "Joint Photographic Experts Group |*.jpg|" +
"Bitmap Image |*.bmp|" + "Bitmap Image |*.bmp|" +
"Tagged Image File Format |*.tiff|" + "Tagged Image File Format |*.tiff|" +
"All files(*.*)|*.*";*/
ofd.Filter = "Supported Formats|*.dds;" +
"Microsoft DDS |*.dds" +
"All files(*.*)|*.*"; "All files(*.*)|*.*";
ofd.Multiselect = false; ofd.Multiselect = false;
if (ofd.ShowDialog() == DialogResult.OK) if (ofd.ShowDialog() == DialogResult.OK)
{ {
throw new Exception("Saving is not supported yet!");
var bntxFile = new BNTX(); var bntxFile = new BNTX();
var tex = new TextureData(); var tex = new TextureData();
tex.Replace(ofd.FileName); tex.Replace(ofd.FileName);
if (surfaces[0].mipmaps[0].Length != surfaces[0].mipmaps[0].Length)
throw new Exception("Image must be the same size!");
if (surfaces[0].mipmaps.Count != tex.surfaces[0].mipmaps.Count)
throw new Exception("Map map count must be the same!");
if (Width != tex.Texture.Width || Height != tex.Texture.Height)
throw new Exception("Image size must be the same!");
ImageData = tex.Texture.TextureData[0][0]; ImageData = tex.Texture.TextureData[0][0];
mipmaps = tex.mipmaps; surfaces = tex.surfaces;
Width = tex.Texture.Width; Width = tex.Texture.Width;
Height = tex.Texture.Height; Height = tex.Texture.Height;
@ -265,8 +275,8 @@ namespace FirstPlugin
dds.header = new DDS.Header(); dds.header = new DDS.Header();
dds.header.width = Width; dds.header.width = Width;
dds.header.height = Height; dds.header.height = Height;
dds.header.mipmapCount = (uint)mipmaps.Count; dds.header.mipmapCount = (uint)surfaces[0].mipmaps.Count;
dds.header.pitchOrLinearSize = (uint)mipmaps[0][0].Length; dds.header.pitchOrLinearSize = (uint)surfaces[0].mipmaps[0].Length;
if (IsCompressedFormat((NUTEXImageFormat)Format)) if (IsCompressedFormat((NUTEXImageFormat)Format))
dds.SetFlags(GetCompressedDXGI_FORMAT((NUTEXImageFormat)Format)); dds.SetFlags(GetCompressedDXGI_FORMAT((NUTEXImageFormat)Format));
@ -274,7 +284,7 @@ namespace FirstPlugin
dds.SetFlags(GetUncompressedDXGI_FORMAT((NUTEXImageFormat)Format)); dds.SetFlags(GetUncompressedDXGI_FORMAT((NUTEXImageFormat)Format));
dds.Save(dds, FileName, mipmaps); dds.Save(dds, FileName, surfaces);
} }
public void Read(FileReader reader) public void Read(FileReader reader)
{ {
@ -368,9 +378,9 @@ namespace FirstPlugin
if (IsSwizzled) if (IsSwizzled)
LoadTexture(); LoadTexture();
else else
mipmaps.Add(new List<byte[]>() { ImageData }); surfaces.Add(new Surface() {mipmaps = new List<byte[]>() { ImageData } } );
if (mipmaps[0].Count <= 0) if (surfaces[0].mipmaps.Count <= 0)
{ {
return BitmapExtension.GetBitmap(Properties.Resources.Black, 32, 32); return BitmapExtension.GetBitmap(Properties.Resources.Black, 32, 32);
} }
@ -380,7 +390,7 @@ namespace FirstPlugin
uint width = (uint)Math.Max(1, Width >> DisplayMipIndex); uint width = (uint)Math.Max(1, Width >> DisplayMipIndex);
uint height = (uint)Math.Max(1, Height >> DisplayMipIndex); uint height = (uint)Math.Max(1, Height >> DisplayMipIndex);
byte[] data = mipmaps[ArrayIndex][DisplayMipIndex]; byte[] data = surfaces[ArrayIndex].mipmaps[DisplayMipIndex];
return DecodeBlock(data, width, height, (NUTEXImageFormat)Format); return DecodeBlock(data, width, height, (NUTEXImageFormat)Format);
} }
@ -466,7 +476,7 @@ namespace FirstPlugin
public void LoadTexture(int target = 1) public void LoadTexture(int target = 1)
{ {
mipmaps.Clear(); surfaces.Clear();
uint blk_dim = blk_dims((byte)Format); uint blk_dim = blk_dims((byte)Format);
uint blkWidth = blk_dim >> 4; uint blkWidth = blk_dim >> 4;
@ -524,7 +534,7 @@ namespace FirstPlugin
mipOffset += (uint)MipSize; mipOffset += (uint)MipSize;
break; break;
} }
mipmaps.Add(mips); surfaces.Add(new Surface() { mipmaps = mips });
} }
} }

View file

@ -138,12 +138,15 @@ namespace FirstPlugin
shader.SetMatrix4x4("mvpMatrix", ref camMat); shader.SetMatrix4x4("mvpMatrix", ref camMat);
foreach (FMDL mdl in models) foreach (FMDL mdl in models)
{
if (mdl.Checked)
{ {
foreach (FSHP shp in mdl.shapes) foreach (FSHP shp in mdl.shapes)
{ {
DrawModel(shp, mdl, shader); DrawModel(shp, mdl, shader);
} }
} }
}
shader.DisableVertexAttributes(); shader.DisableVertexAttributes();
GL.UseProgram(0); GL.UseProgram(0);
@ -206,6 +209,8 @@ namespace FirstPlugin
private void SetRenderSettings(Shader shader) private void SetRenderSettings(Shader shader)
{ {
shader.SetBoolToInt("renderVertColor", Runtime.renderVertColor); shader.SetBoolToInt("renderVertColor", Runtime.renderVertColor);
shader.SetBoolToInt("renderTevColors", Runtime.renderTevColors);
shader.SetBoolToInt("renderMatColors", Runtime.renderMatColors);
shader.SetInt("renderType", (int)Runtime.viewportShading); shader.SetInt("renderType", (int)Runtime.viewportShading);
shader.SetBoolToInt("useNormalMap", Runtime.useNormalMap); shader.SetBoolToInt("useNormalMap", Runtime.useNormalMap);
shader.SetInt("uvChannel", (int)Runtime.uvChannel); shader.SetInt("uvChannel", (int)Runtime.uvChannel);
@ -238,6 +243,12 @@ namespace FirstPlugin
{ {
for (int i = 0; i < fmdl.Skeleton.Node_Array.Length; i++) for (int i = 0; i < fmdl.Skeleton.Node_Array.Length; i++)
{ {
/* Matrix3x4 transform3x4 = fmdl.Skeleton.matrices[fmdl.Skeleton.Node_Array[i]];
Matrix4 transform = new Matrix4(transform3x4.Row0, transform3x4.Row1,
transform3x4.Row2, new Vector4(0, 0, 0, 1));*/
Matrix4 transform = fmdl.Skeleton.bones[fmdl.Skeleton.Node_Array[i]].invert * fmdl.Skeleton.bones[fmdl.Skeleton.Node_Array[i]].transform; Matrix4 transform = fmdl.Skeleton.bones[fmdl.Skeleton.Node_Array[i]].invert * fmdl.Skeleton.bones[fmdl.Skeleton.Node_Array[i]].transform;
GL.UniformMatrix4(GL.GetUniformLocation(shader.Id, String.Format("bones[{0}]", i)), false, ref transform); GL.UniformMatrix4(GL.GetUniformLocation(shader.Id, String.Format("bones[{0}]", i)), false, ref transform);
} }
@ -258,7 +269,7 @@ namespace FirstPlugin
// shader.SetTexture("irradianceMap", RenderTools.diffusePbr, 18); // shader.SetTexture("irradianceMap", RenderTools.diffusePbr, 18);
// shader.SetTexture("specularIbl", RenderTools.specularPbr, 19); // shader.SetTexture("specularIbl", RenderTools.specularPbr, 19);
foreach (MatTexture matex in mat.textures) foreach (MatTexture matex in mat.TextureMaps)
{ {
if (matex.Type == MatTexture.TextureType.Diffuse) if (matex.Type == MatTexture.TextureType.Diffuse)
TextureUniform(shader, mat, mat.HasDiffuseMap, "DiffuseMap", matex); TextureUniform(shader, mat, mat.HasDiffuseMap, "DiffuseMap", matex);
@ -346,7 +357,7 @@ namespace FirstPlugin
SetVertexAttributes(m, shader); SetVertexAttributes(m, shader);
ApplyTransformFix(mdl, m, shader); ApplyTransformFix(mdl, m, shader);
if (m.Checked) if (m.Checked && m.Parent.Parent.Checked)
{ {
if ((m.IsSelected)) if ((m.IsSelected))
{ {
@ -452,7 +463,7 @@ namespace FirstPlugin
foreach (BNTX bntx in PluginRuntime.bntxContainers) foreach (BNTX bntx in PluginRuntime.bntxContainers)
{ {
foreach (var t in mat.textures) foreach (var t in mat.TextureMaps)
{ {
if (bntx.Textures.ContainsKey(t.Name)) if (bntx.Textures.ContainsKey(t.Name))
{ {
@ -494,6 +505,11 @@ namespace FirstPlugin
{ {
shader.SetVector4("gsys_bake_st0", new Vector4(1, 1, 0, 0)); shader.SetVector4("gsys_bake_st0", new Vector4(1, 1, 0, 0));
shader.SetVector4("gsys_bake_st1", new Vector4(1, 1, 0, 0)); shader.SetVector4("gsys_bake_st1", new Vector4(1, 1, 0, 0));
shader.SetVector4("tev_color0", new Vector4(1, 1, 0, 0));
shader.SetVector4("tev_color1", new Vector4(1, 1, 0, 0));
shader.SetVector4("mat_color0", new Vector4(1, 1, 0, 0));
shader.SetVector4("mat_color1", new Vector4(1, 1, 0, 0));
shader.SetVector4("const_color0", new Vector4(1, 1, 1, 1)); shader.SetVector4("const_color0", new Vector4(1, 1, 1, 1));
shader.SetVector4("base_color_mul_color", new Vector4(1, 1, 1, 1)); shader.SetVector4("base_color_mul_color", new Vector4(1, 1, 1, 1));
@ -504,7 +520,11 @@ namespace FirstPlugin
SetUniformData(mat, shader, "gsys_bake_st0"); SetUniformData(mat, shader, "gsys_bake_st0");
SetUniformData(mat, shader, "gsys_bake_st1"); SetUniformData(mat, shader, "gsys_bake_st1");
SetUniformData(mat, shader, "const_color0"); SetUniformData(mat, shader, "const_color0");
SetUniformData(mat, shader, "base_color_mul_color"); SetUniformData(mat, shader, "tev_color0");
SetUniformData(mat, shader, "tev_color1");
SetUniformData(mat, shader, "mat_color0");
SetUniformData(mat, shader, "mat_color1");
} }
private static void SetUniformData(FMAT mat, Shader shader, string propertyName) private static void SetUniformData(FMAT mat, Shader shader, string propertyName)
{ {

View file

@ -103,7 +103,12 @@ namespace FirstPlugin
Color SetColor = Color.FromArgb(40, 40, 40); Color SetColor = Color.FromArgb(40, 40, 40);
Vector4 col = new Vector4(); Vector4 col = new Vector4();
bool IsColor = prm.Name.Contains("Color") || prm.Name.Contains("color"); 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) switch (prm.Type)
{ {
@ -166,7 +171,7 @@ namespace FirstPlugin
textureRefListView.SmallImageList = textureImageList; textureRefListView.SmallImageList = textureImageList;
textureRefListView.FullRowSelect = true; textureRefListView.FullRowSelect = true;
foreach (MatTexture tex in material.textures) foreach (MatTexture tex in material.TextureMaps)
{ {
ListViewItem item = new ListViewItem(); ListViewItem item = new ListViewItem();
item.Text = tex.Name; item.Text = tex.Name;
@ -315,7 +320,7 @@ namespace FirstPlugin
tex.LoadTexture(material.GetResFileU() != null); tex.LoadTexture(material.GetResFileU() != null);
if (tex.ShowDialog() == DialogResult.OK) if (tex.ShowDialog() == DialogResult.OK)
{ {
material.textures[index].Name = tex.GetSelectedTexture(); material.TextureMaps[index].Name = tex.GetSelectedTexture();
InitializeTextureListView(material); InitializeTextureListView(material);
material.UpdateTextureMaps(); material.UpdateTextureMaps();
} }
@ -346,7 +351,7 @@ namespace FirstPlugin
if (paramDialog.ShowDialog() == DialogResult.OK) if (paramDialog.ShowDialog() == DialogResult.OK)
{ {
paramDialog.GetValues(); paramDialog.SetValues();
InitializeShaderParamList(material); InitializeShaderParamList(material);
listView1.Items[index].Selected = true; listView1.Items[index].Selected = true;
} }
@ -485,7 +490,7 @@ namespace FirstPlugin
return; return;
SamplerEditor samplerEditor = new SamplerEditor(); SamplerEditor samplerEditor = new SamplerEditor();
foreach (MatTexture tex in material.textures) foreach (MatTexture tex in material.TextureMaps)
{ {
if (tex.Name == textureRefListView.SelectedItems[0].Text) if (tex.Name == textureRefListView.SelectedItems[0].Text)
{ {

View file

@ -8,6 +8,8 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
using Switch_Toolbox.Library; using Switch_Toolbox.Library;
using Bfres.Structs;
using Syroot.NintenTools.NSW.Bfres;
namespace FirstPlugin namespace FirstPlugin
{ {
@ -17,7 +19,26 @@ namespace FirstPlugin
{ {
InitializeComponent(); InitializeComponent();
} }
public void SetValues(BfresShaderParam param)
{
switch (param.Type)
{
case ShaderParamType.Bool:
param.ValueBool = new bool[] { bool1.Visible};
break;
case ShaderParamType.Bool2:
param.ValueBool = new bool[] { bool1.Visible, bool2.Visible };
break;
case ShaderParamType.Bool3:
param.ValueBool = new bool[] { bool1.Visible, bool2.Visible,
bool3.Visible };
break;
case ShaderParamType.Bool4:
param.ValueBool = new bool[] { bool1.Visible, bool2.Visible,
bool3.Visible , bool4.Visible };
break;
}
}
public void LoadValues(bool[] values) public void LoadValues(bool[] values)
{ {
bool1.Visible = false; bool1.Visible = false;

View file

@ -19,13 +19,52 @@ namespace FirstPlugin
InitializeComponent(); InitializeComponent();
HideControls(); HideControls();
} }
public void GetValues(BfresShaderParam param) public void SetValues(BfresShaderParam param)
{ {
switch (param.Type) switch (param.Type)
{ {
case Syroot.NintenTools.NSW.Bfres.ShaderParamType.Float: case Syroot.NintenTools.NSW.Bfres.ShaderParamType.Float:
param.ValueFloat = new float[] { (float)ValueUD1.Value }; param.ValueFloat = new float[] { (float)ValueUD1.Value };
break; break;
case Syroot.NintenTools.NSW.Bfres.ShaderParamType.Float2:
param.ValueFloat = new float[] { (float)ValueUD1.Value, (float)ValueUD2.Value };
break;
case Syroot.NintenTools.NSW.Bfres.ShaderParamType.Float3:
param.ValueFloat = new float[] { (float)ValueUD1.Value, (float)ValueUD2.Value,
(float)ValueUD3.Value };
break;
case Syroot.NintenTools.NSW.Bfres.ShaderParamType.Float4:
param.ValueFloat = new float[] { (float)ValueUD1.Value, (float)ValueUD2.Value,
(float)ValueUD3.Value, (float)ValueUD4.Value };
break;
case Syroot.NintenTools.NSW.Bfres.ShaderParamType.UInt:
param.ValueUint = new uint[] { (uint)ValueUD1.Value };
break;
case Syroot.NintenTools.NSW.Bfres.ShaderParamType.UInt2:
param.ValueUint = new uint[] { (uint)ValueUD1.Value, (uint)ValueUD2.Value };
break;
case Syroot.NintenTools.NSW.Bfres.ShaderParamType.UInt3:
param.ValueUint = new uint[] { (uint)ValueUD1.Value, (uint)ValueUD2.Value,
(uint)ValueUD3.Value };
break;
case Syroot.NintenTools.NSW.Bfres.ShaderParamType.UInt4:
param.ValueUint = new uint[] { (uint)ValueUD1.Value, (uint)ValueUD2.Value,
(uint)ValueUD3.Value, (uint)ValueUD4.Value };
break;
case Syroot.NintenTools.NSW.Bfres.ShaderParamType.Int:
param.ValueInt = new int[] { (int)ValueUD1.Value };
break;
case Syroot.NintenTools.NSW.Bfres.ShaderParamType.Int2:
param.ValueInt = new int[] { (int)ValueUD1.Value, (int)ValueUD2.Value };
break;
case Syroot.NintenTools.NSW.Bfres.ShaderParamType.Int3:
param.ValueInt = new int[] { (int)ValueUD1.Value, (int)ValueUD2.Value,
(int)ValueUD3.Value };
break;
case Syroot.NintenTools.NSW.Bfres.ShaderParamType.Int4:
param.ValueInt = new int[] { (int)ValueUD1.Value, (int)ValueUD2.Value,
(int)ValueUD3.Value, (int)ValueUD4.Value };
break;
} }
} }
public void LoadValues(float[] values) public void LoadValues(float[] values)

View file

@ -9,6 +9,7 @@ using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
using Syroot.NintenTools.NSW.Bfres; using Syroot.NintenTools.NSW.Bfres;
using Switch_Toolbox.Library; using Switch_Toolbox.Library;
using Bfres.Structs;
namespace FirstPlugin namespace FirstPlugin
{ {
@ -19,6 +20,47 @@ namespace FirstPlugin
InitializeComponent(); InitializeComponent();
HideControls(); HideControls();
} }
public void SetValues(BfresShaderParam param)
{
switch (param.Type)
{
case ShaderParamType.TexSrt:
param.ValueTexSrt.Scaling.X = (float)scaleUDX.Value;
param.ValueTexSrt.Scaling.Y = (float)scaleUDY.Value;
param.ValueTexSrt.Rotation = (float)rotUDX.Value;
param.ValueTexSrt.Translation.X = (float)transUDX.Value;
param.ValueTexSrt.Translation.Y = (float)transUDY.Value;
param.ValueTexSrt.Mode = (TexSrtMode)modeComboBox.SelectedItem;
break;
case ShaderParamType.TexSrtEx:
param.ValueTexSrtEx.Scaling.X = (float)scaleUDX.Value;
param.ValueTexSrtEx.Scaling.Y = (float)scaleUDY.Value;
param.ValueTexSrtEx.Rotation = (float)rotUDX.Value;
param.ValueTexSrtEx.Translation.X = (float)transUDX.Value;
param.ValueTexSrtEx.Translation.Y = (float)transUDY.Value;
param.ValueTexSrtEx.Mode = (TexSrtMode)modeComboBox.SelectedItem;
param.ValueTexSrtEx.MatrixPointer = (uint)matrixPtrNumUD.Value;
break;
case ShaderParamType.Srt2D:
param.ValueSrt2D.Scaling.X = (float)scaleUDX.Value;
param.ValueSrt2D.Scaling.Y = (float)scaleUDY.Value;
param.ValueSrt2D.Rotation = (float)rotUDX.Value;
param.ValueSrt2D.Translation.X = (float)transUDX.Value;
param.ValueSrt2D.Translation.Y = (float)transUDY.Value;
break;
case ShaderParamType.Srt3D:
param.ValueSrt3D.Scaling.X = (float)scaleUDX.Value;
param.ValueSrt3D.Scaling.Y = (float)scaleUDY.Value;
param.ValueSrt3D.Scaling.Z = (float)scaleUDZ.Value;
param.ValueSrt3D.Rotation.X = (float)rotUDX.Value;
param.ValueSrt3D.Rotation.Y = (float)rotUDY.Value;
param.ValueSrt3D.Rotation.Z = (float)rotUDZ.Value;
param.ValueSrt3D.Translation.X = (float)transUDX.Value;
param.ValueSrt3D.Translation.Y = (float)transUDY.Value;
param.ValueSrt3D.Translation.Z = (float)transUDZ.Value;
break;
}
}
public void LoadValues(Srt2D srt2D) public void LoadValues(Srt2D srt2D)
{ {
scaleUDX.Value = (decimal)srt2D.Scaling.X; scaleUDX.Value = (decimal)srt2D.Scaling.X;

View file

@ -153,17 +153,19 @@ namespace FirstPlugin
} }
} }
public void GetValues() public void SetValues()
{ {
if (boolPanel != null) if (boolPanel != null)
{ {
boolPanel.SetValues(activeParam);
} }
if (SRTPanel != null) if (SRTPanel != null)
{ {
SRTPanel.SetValues(activeParam);
} }
if (FloatIntsPanel != null) if (FloatIntsPanel != null)
{ {
FloatIntsPanel.GetValues(activeParam); FloatIntsPanel.SetValues(activeParam);
} }
} }

View file

@ -66,14 +66,14 @@ namespace FirstPlugin
LoadImage(); LoadImage();
int MipCount = 1; int MipCount = 1;
if (textureData.mipmaps.Count <= 0) if (textureData.surfaces.Count <= 0)
return; return;
else else
MipCount = textureData.mipmaps[CurArrayDisplayLevel].Count; MipCount = textureData.surfaces[CurArrayDisplayLevel].mipmaps.Count;
mipLevelCounterLabel.Text = $"{CurMipDisplayLevel} / {textureData.mipmaps[CurArrayDisplayLevel].Count - 1}"; mipLevelCounterLabel.Text = $"{CurMipDisplayLevel} / {textureData.surfaces[CurArrayDisplayLevel].mipmaps.Count - 1}";
arrayLevelCounterLabel.Text = $"{CurArrayDisplayLevel} / {textureData.mipmaps.Count - 1}"; arrayLevelCounterLabel.Text = $"{CurArrayDisplayLevel} / {textureData.surfaces.Count - 1}";
if (CurMipDisplayLevel != MipCount - 1) if (CurMipDisplayLevel != MipCount - 1)
BtnMipsRight.Enabled = true; BtnMipsRight.Enabled = true;
@ -85,7 +85,7 @@ namespace FirstPlugin
else else
BtmMipsLeft.Enabled = false; BtmMipsLeft.Enabled = false;
if (CurArrayDisplayLevel != textureData.mipmaps.Count - 1) if (CurArrayDisplayLevel != textureData.surfaces.Count - 1)
btnRightArray.Enabled = true; btnRightArray.Enabled = true;
else else
btnRightArray.Enabled = false; btnRightArray.Enabled = false;
@ -133,7 +133,7 @@ namespace FirstPlugin
private void BtnMipsRight_Click(object sender, EventArgs e) private void BtnMipsRight_Click(object sender, EventArgs e)
{ {
if (CurMipDisplayLevel != textureData.mipmaps[CurArrayDisplayLevel].Count - 1) if (CurMipDisplayLevel != textureData.surfaces[CurArrayDisplayLevel].mipmaps.Count - 1)
CurMipDisplayLevel += 1; CurMipDisplayLevel += 1;
UpdateMipDisplay(); UpdateMipDisplay();
@ -149,7 +149,7 @@ namespace FirstPlugin
private void btnRightArray_Click(object sender, EventArgs e) private void btnRightArray_Click(object sender, EventArgs e)
{ {
if (CurArrayDisplayLevel != textureData.mipmaps.Count - 1) if (CurArrayDisplayLevel != textureData.surfaces.Count - 1)
CurArrayDisplayLevel += 1; CurArrayDisplayLevel += 1;
UpdateMipDisplay(); UpdateMipDisplay();
@ -204,7 +204,7 @@ namespace FirstPlugin
throw new Exception("Invalid Width! Must be same as original!"); throw new Exception("Invalid Width! Must be same as original!");
List<byte[]> Mipmaps = TextureImporterSettings.SwizzleSurfaceMipMaps(textureData.Texture, dds.bdata, TileMode.Default); List<byte[]> Mipmaps = TextureImporterSettings.SwizzleSurfaceMipMaps(textureData.Texture, dds.bdata, TileMode.Default);
textureData.mipmaps[CurArrayDisplayLevel] = Mipmaps; textureData.surfaces[CurArrayDisplayLevel].mipmaps = Mipmaps;
UpdateMipDisplay(); UpdateMipDisplay();
textureData.LoadOpenGLTexture(); textureData.LoadOpenGLTexture();

View file

@ -70,22 +70,9 @@ namespace FirstPlugin
TextureImporterSettings SelectedTexSettings; TextureImporterSettings SelectedTexSettings;
BNTX bntx; BNTX bntx;
List<TextureImporterSettings> settings = new List<TextureImporterSettings>(); public List<TextureImporterSettings> settings = new List<TextureImporterSettings>();
public void LoadSettings(List<TextureImporterSettings> s, BNTX b)
{
settings = s;
bntx = b;
foreach (var setting in settings)
{
listViewCustom1.Items.Add(setting.TexName).SubItems.Add(setting.Format.ToString());
}
listViewCustom1.Items[0].Selected = true;
listViewCustom1.Select();
}
public void LoadSetting(TextureImporterSettings setting, BNTX b) public void LoadSetting(TextureImporterSettings setting, BNTX b)
{ {
settings = new List<TextureImporterSettings>();
settings.Add(setting); settings.Add(setting);
bntx = b; bntx = b;
@ -123,10 +110,11 @@ namespace FirstPlugin
if (SelectedTexSettings.Format == SurfaceFormat.Invalid) if (SelectedTexSettings.Format == SurfaceFormat.Invalid)
return; return;
if (Thread != null && Thread.IsAlive) if (Thread != null && Thread.IsAlive)
Thread.Abort(); Thread.Abort();
try
{
if (formatComboBox.SelectedItem is SurfaceFormat) if (formatComboBox.SelectedItem is SurfaceFormat)
{ {
SelectedTexSettings.Format = (SurfaceFormat)formatComboBox.SelectedItem; SelectedTexSettings.Format = (SurfaceFormat)formatComboBox.SelectedItem;
@ -146,6 +134,12 @@ namespace FirstPlugin
})); }));
Thread.Start(); Thread.Start();
}
catch
{
throw new Exception("Failed to load image!");
}
// WidthLabel.Text = $"Width {pictureBox1.Image.Width}"; // WidthLabel.Text = $"Width {pictureBox1.Image.Width}";
// HeightLabel.Text = $"Height {pictureBox1.Image.Height}"; // HeightLabel.Text = $"Height {pictureBox1.Image.Height}";
@ -168,6 +162,8 @@ namespace FirstPlugin
{ {
if (listViewCustom1.SelectedItems.Count > 0) if (listViewCustom1.SelectedItems.Count > 0)
{ {
Console.WriteLine("list index " + listViewCustom1.SelectedIndices[0]);
SelectedTexSettings = settings[listViewCustom1.SelectedIndices[0]]; SelectedTexSettings = settings[listViewCustom1.SelectedIndices[0]];
formatComboBox.SelectedItem = SelectedTexSettings.Format; formatComboBox.SelectedItem = SelectedTexSettings.Format;

View file

@ -28,6 +28,7 @@ namespace FirstPlugin
public GX2CompSel[] compSel = new GX2CompSel[4]; public GX2CompSel[] compSel = new GX2CompSel[4];
public GX2SurfaceDim SurfaceDim = GX2SurfaceDim.Dim2D; public GX2SurfaceDim SurfaceDim = GX2SurfaceDim.Dim2D;
public GX2AAMode AAMode = GX2AAMode.Mode1X; public GX2AAMode AAMode = GX2AAMode.Mode1X;
public float alphaRef = 0.5f;
private GTX.GX2SurfaceFormat LoadDDSFormat(uint fourCC, DDS dds = null, bool IsSRGB = false) private GTX.GX2SurfaceFormat LoadDDSFormat(uint fourCC, DDS dds = null, bool IsSRGB = false)
{ {
@ -37,49 +38,49 @@ namespace FirstPlugin
{ {
case DDS.FOURCC_DXT1: case DDS.FOURCC_DXT1:
if (IsSRGB) if (IsSRGB)
return GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC1_SRGB; return GTX.GX2SurfaceFormat.T_BC1_SRGB;
else else
return GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC1_UNORM; return GTX.GX2SurfaceFormat.T_BC1_UNORM;
case DDS.FOURCC_DXT3: case DDS.FOURCC_DXT3:
if (IsSRGB) if (IsSRGB)
return GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC2_SRGB; return GTX.GX2SurfaceFormat.T_BC2_SRGB;
else else
return GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC2_UNORM; return GTX.GX2SurfaceFormat.T_BC2_UNORM;
case DDS.FOURCC_DXT5: case DDS.FOURCC_DXT5:
if (IsSRGB) if (IsSRGB)
return GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC3_SRGB; return GTX.GX2SurfaceFormat.T_BC3_SRGB;
else else
return GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC3_UNORM; return GTX.GX2SurfaceFormat.T_BC3_UNORM;
case DDS.FOURCC_BC4U: case DDS.FOURCC_BC4U:
return GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC4_UNORM; return GTX.GX2SurfaceFormat.T_BC4_UNORM;
case DDS.FOURCC_ATI1: case DDS.FOURCC_ATI1:
return GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC4_UNORM; return GTX.GX2SurfaceFormat.T_BC4_UNORM;
case DDS.FOURCC_ATI2: case DDS.FOURCC_ATI2:
return GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC5_UNORM; return GTX.GX2SurfaceFormat.T_BC5_UNORM;
case DDS.FOURCC_BC5U: case DDS.FOURCC_BC5U:
return GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC4_UNORM; return GTX.GX2SurfaceFormat.T_BC4_UNORM;
case DDS.FOURCC_DX10: case DDS.FOURCC_DX10:
IsDX10 = true; IsDX10 = true;
break; break;
default: default:
return GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM; return GTX.GX2SurfaceFormat.TCS_R8_G8_B8_A8_UNORM;
} }
if (IsDX10) if (IsDX10)
{ {
switch (dds.DX10header.DXGI_Format) switch (dds.DX10header.DXGI_Format)
{ {
case DDS.DXGI_FORMAT.DXGI_FORMAT_BC4_UNORM: case DDS.DXGI_FORMAT.DXGI_FORMAT_BC4_UNORM:
return GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC4_UNORM; return GTX.GX2SurfaceFormat.T_BC4_UNORM;
case DDS.DXGI_FORMAT.DXGI_FORMAT_BC4_SNORM: case DDS.DXGI_FORMAT.DXGI_FORMAT_BC4_SNORM:
return GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC4_SNORM; return GTX.GX2SurfaceFormat.T_BC4_SNORM;
case DDS.DXGI_FORMAT.DXGI_FORMAT_BC4_TYPELESS: case DDS.DXGI_FORMAT.DXGI_FORMAT_BC4_TYPELESS:
return GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC4_UNORM; return GTX.GX2SurfaceFormat.T_BC4_UNORM;
case DDS.DXGI_FORMAT.DXGI_FORMAT_BC5_UNORM: case DDS.DXGI_FORMAT.DXGI_FORMAT_BC5_UNORM:
return GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC5_UNORM; return GTX.GX2SurfaceFormat.T_BC5_UNORM;
case DDS.DXGI_FORMAT.DXGI_FORMAT_BC5_SNORM: case DDS.DXGI_FORMAT.DXGI_FORMAT_BC5_SNORM:
return GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC5_SNORM; return GTX.GX2SurfaceFormat.T_BC5_SNORM;
case DDS.DXGI_FORMAT.DXGI_FORMAT_BC5_TYPELESS: case DDS.DXGI_FORMAT.DXGI_FORMAT_BC5_TYPELESS:
return GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC5_UNORM; return GTX.GX2SurfaceFormat.T_BC5_UNORM;
default: default:
throw new Exception($"Format {dds.DX10header.DXGI_Format} not supported!"); throw new Exception($"Format {dds.DX10header.DXGI_Format} not supported!");
} }
@ -115,7 +116,7 @@ namespace FirstPlugin
DecompressedData.Clear(); DecompressedData.Clear();
TexName = Path.GetFileNameWithoutExtension(FileName); TexName = Path.GetFileNameWithoutExtension(FileName);
Format = GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC1_SRGB; Format = GTX.GX2SurfaceFormat.T_BC1_SRGB;
GenerateMipmaps = true; GenerateMipmaps = true;
Bitmap Image = new Bitmap(FileName); Bitmap Image = new Bitmap(FileName);
@ -163,14 +164,14 @@ namespace FirstPlugin
Bitmap Image = BitmapExtension.GetBitmap(DecompressedData[SurfaceLevel], (int)TexWidth, (int)TexHeight); Bitmap Image = BitmapExtension.GetBitmap(DecompressedData[SurfaceLevel], (int)TexWidth, (int)TexHeight);
List<byte[]> mipmaps = new List<byte[]>(); List<byte[]> mipmaps = new List<byte[]>();
mipmaps.Add(FTEX.CompressBlock(DecompressedData[SurfaceLevel], (int)TexWidth, (int)TexHeight, Format)); mipmaps.Add(FTEX.CompressBlock(DecompressedData[SurfaceLevel], (int)TexWidth, (int)TexHeight, Format, alphaRef));
//while (Image.Width / 2 > 0 && Image.Height / 2 > 0) //while (Image.Width / 2 > 0 && Image.Height / 2 > 0)
// for (int mipLevel = 0; mipLevel < MipCount; mipLevel++) // for (int mipLevel = 0; mipLevel < MipCount; mipLevel++)
for (int mipLevel = 0; mipLevel < MipCount; mipLevel++) for (int mipLevel = 0; mipLevel < MipCount; mipLevel++)
{ {
Image = BitmapExtension.Resize(Image, Image.Width / 2, Image.Height / 2); Image = BitmapExtension.Resize(Image, Image.Width / 2, Image.Height / 2);
mipmaps.Add(FTEX.CompressBlock(BitmapExtension.ImageToByte(Image), Image.Width, Image.Height, Format)); mipmaps.Add(FTEX.CompressBlock(BitmapExtension.ImageToByte(Image), Image.Width, Image.Height, Format, alphaRef));
} }
Image.Dispose(); Image.Dispose();
@ -181,7 +182,7 @@ namespace FirstPlugin
DataBlockOutput.Clear(); DataBlockOutput.Clear();
foreach (var surface in DecompressedData) foreach (var surface in DecompressedData)
{ {
DataBlockOutput.Add(FTEX.CompressBlock(surface, (int)TexWidth, (int)TexHeight, Format)); DataBlockOutput.Add(FTEX.CompressBlock(surface, (int)TexWidth, (int)TexHeight, Format, alphaRef));
} }
} }

View file

@ -17,47 +17,59 @@ namespace FirstPlugin
InitializeComponent(); InitializeComponent();
formatComboBox.Items.Add(GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM); formatComboBox.Items.Add(GTX.GX2SurfaceFormat.TCS_R8_G8_B8_A8_UNORM);
formatComboBox.Items.Add(GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_SRGB); formatComboBox.Items.Add(GTX.GX2SurfaceFormat.TCS_R8_G8_B8_A8_SRGB);
formatComboBox.Items.Add(GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_TCS_R10_G10_B10_A2_UNORM); formatComboBox.Items.Add(GTX.GX2SurfaceFormat.TCS_R10_G10_B10_A2_UNORM);
formatComboBox.Items.Add(GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_TCS_R5_G6_B5_UNORM); formatComboBox.Items.Add(GTX.GX2SurfaceFormat.TCS_R5_G6_B5_UNORM);
formatComboBox.Items.Add(GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_TC_R5_G5_B5_A1_UNORM); formatComboBox.Items.Add(GTX.GX2SurfaceFormat.TC_R5_G5_B5_A1_UNORM);
formatComboBox.Items.Add(GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_TC_R4_G4_B4_A4_UNORM); formatComboBox.Items.Add(GTX.GX2SurfaceFormat.TC_R4_G4_B4_A4_UNORM);
formatComboBox.Items.Add(GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_TC_R8_UNORM); formatComboBox.Items.Add(GTX.GX2SurfaceFormat.TC_R8_UNORM);
formatComboBox.Items.Add(GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_TC_R8_G8_UNORM); formatComboBox.Items.Add(GTX.GX2SurfaceFormat.TC_R8_G8_UNORM);
formatComboBox.Items.Add(GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC1_UNORM); formatComboBox.Items.Add(GTX.GX2SurfaceFormat.T_BC1_UNORM);
formatComboBox.Items.Add(GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC1_SRGB); formatComboBox.Items.Add(GTX.GX2SurfaceFormat.T_BC1_SRGB);
formatComboBox.Items.Add(GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC2_UNORM); formatComboBox.Items.Add(GTX.GX2SurfaceFormat.T_BC2_UNORM);
formatComboBox.Items.Add(GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC2_SRGB); formatComboBox.Items.Add(GTX.GX2SurfaceFormat.T_BC2_SRGB);
formatComboBox.Items.Add(GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC3_UNORM); formatComboBox.Items.Add(GTX.GX2SurfaceFormat.T_BC3_UNORM);
formatComboBox.Items.Add(GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC3_SRGB); formatComboBox.Items.Add(GTX.GX2SurfaceFormat.T_BC3_SRGB);
formatComboBox.Items.Add(GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC4_UNORM); formatComboBox.Items.Add(GTX.GX2SurfaceFormat.T_BC4_UNORM);
formatComboBox.Items.Add(GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC4_SNORM); formatComboBox.Items.Add(GTX.GX2SurfaceFormat.T_BC4_SNORM);
formatComboBox.Items.Add(GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC5_UNORM); formatComboBox.Items.Add(GTX.GX2SurfaceFormat.T_BC5_UNORM);
formatComboBox.Items.Add(GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC5_SNORM); formatComboBox.Items.Add(GTX.GX2SurfaceFormat.T_BC5_SNORM);
tileModeCB.Items.Add(GTX.GX2TileMode.GX2_TILE_MODE_DEFAULT); tileModeCB.Items.Add(GTX.GX2TileMode.MODE_DEFAULT);
tileModeCB.Items.Add(GTX.GX2TileMode.GX2_TILE_MODE_LINEAR_ALIGNED); tileModeCB.Items.Add(GTX.GX2TileMode.MODE_LINEAR_ALIGNED);
tileModeCB.Items.Add(GTX.GX2TileMode.GX2_TILE_MODE_1D_TILED_THIN1); tileModeCB.Items.Add(GTX.GX2TileMode.MODE_1D_TILED_THIN1);
tileModeCB.Items.Add(GTX.GX2TileMode.GX2_TILE_MODE_1D_TILED_THICK); tileModeCB.Items.Add(GTX.GX2TileMode.MODE_1D_TILED_THICK);
tileModeCB.Items.Add(GTX.GX2TileMode.GX2_TILE_MODE_2D_TILED_THIN1); tileModeCB.Items.Add(GTX.GX2TileMode.MODE_2D_TILED_THIN1);
tileModeCB.Items.Add(GTX.GX2TileMode.GX2_TILE_MODE_2D_TILED_THIN2); tileModeCB.Items.Add(GTX.GX2TileMode.MODE_2D_TILED_THIN2);
tileModeCB.Items.Add(GTX.GX2TileMode.GX2_TILE_MODE_2D_TILED_THIN4); tileModeCB.Items.Add(GTX.GX2TileMode.MODE_2D_TILED_THIN4);
tileModeCB.Items.Add(GTX.GX2TileMode.GX2_TILE_MODE_2D_TILED_THICK); tileModeCB.Items.Add(GTX.GX2TileMode.MODE_2D_TILED_THICK);
tileModeCB.Items.Add(GTX.GX2TileMode.GX2_TILE_MODE_2B_TILED_THIN1); tileModeCB.Items.Add(GTX.GX2TileMode.MODE_2B_TILED_THIN1);
tileModeCB.Items.Add(GTX.GX2TileMode.GX2_TILE_MODE_2B_TILED_THIN2); tileModeCB.Items.Add(GTX.GX2TileMode.MODE_2B_TILED_THIN2);
tileModeCB.Items.Add(GTX.GX2TileMode.GX2_TILE_MODE_2B_TILED_THIN4); tileModeCB.Items.Add(GTX.GX2TileMode.MODE_2B_TILED_THIN4);
tileModeCB.Items.Add(GTX.GX2TileMode.GX2_TILE_MODE_2B_TILED_THICK); tileModeCB.Items.Add(GTX.GX2TileMode.MODE_2B_TILED_THICK);
tileModeCB.Items.Add(GTX.GX2TileMode.GX2_TILE_MODE_3D_TILED_THIN1); tileModeCB.Items.Add(GTX.GX2TileMode.MODE_3D_TILED_THIN1);
tileModeCB.Items.Add(GTX.GX2TileMode.GX2_TILE_MODE_3D_TILED_THICK); tileModeCB.Items.Add(GTX.GX2TileMode.MODE_3D_TILED_THICK);
tileModeCB.Items.Add(GTX.GX2TileMode.GX2_TILE_MODE_3B_TILED_THIN1); tileModeCB.Items.Add(GTX.GX2TileMode.MODE_3B_TILED_THIN1);
tileModeCB.Items.Add(GTX.GX2TileMode.GX2_TILE_MODE_3B_TILED_THICK); tileModeCB.Items.Add(GTX.GX2TileMode.MODE_3B_TILED_THICK);
tileModeCB.Items.Add(GTX.GX2TileMode.GX2_TILE_MODE_LINEAR_SPECIAL); tileModeCB.Items.Add(GTX.GX2TileMode.MODE_LINEAR_SPECIAL);
tileModeCB.Items.Add(GTX.GX2TileMode.GX2_TILE_MODE_DEFAULT_FIX2197); tileModeCB.Items.Add(GTX.GX2TileMode.MODE_DEFAULT_FIX2197);
tileModeCB.SelectedItem = GTX.GX2TileMode.GX2_TILE_MODE_2D_TILED_THIN1; ImgDimComb.Items.Add(GTX.GX2SurfaceDimension.DIM_1D);
formatComboBox.SelectedItem = GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC1_SRGB; ImgDimComb.Items.Add(GTX.GX2SurfaceDimension.DIM_1D_ARRAY);
ImgDimComb.Items.Add(GTX.GX2SurfaceDimension.DIM_2D);
ImgDimComb.Items.Add(GTX.GX2SurfaceDimension.DIM_2D_ARRAY);
ImgDimComb.Items.Add(GTX.GX2SurfaceDimension.DIM_2D_MSAA);
ImgDimComb.Items.Add(GTX.GX2SurfaceDimension.DIM_2D_MSAA_ARRAY);
ImgDimComb.Items.Add(GTX.GX2SurfaceDimension.DIM_3D);
ImgDimComb.Items.Add(GTX.GX2SurfaceDimension.DIM_CUBE);
ImgDimComb.Items.Add(GTX.GX2SurfaceDimension.DIM_FIRST);
ImgDimComb.Items.Add(GTX.GX2SurfaceDimension.DIM_LAST);
ImgDimComb.SelectedItem = GTX.GX2SurfaceDimension.DIM_2D;
tileModeCB.SelectedItem = GTX.GX2TileMode.MODE_2D_TILED_THIN1;
formatComboBox.SelectedItem = GTX.GX2SurfaceFormat.T_BC1_SRGB;
} }
GTXImporterSettings SelectedTexSettings; GTXImporterSettings SelectedTexSettings;
@ -86,7 +98,7 @@ namespace FirstPlugin
private Thread Thread; private Thread Thread;
public void SetupSettings() public void SetupSettings()
{ {
if (SelectedTexSettings.Format == GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_INVALID) if (SelectedTexSettings.Format == GTX.GX2SurfaceFormat.INVALID)
return; return;
@ -98,6 +110,9 @@ namespace FirstPlugin
SelectedTexSettings.Format = (GTX.GX2SurfaceFormat)formatComboBox.SelectedItem; SelectedTexSettings.Format = (GTX.GX2SurfaceFormat)formatComboBox.SelectedItem;
listViewCustom1.SelectedItems[0].SubItems[1].Text = SelectedTexSettings.Format.ToString(); listViewCustom1.SelectedItems[0].SubItems[1].Text = SelectedTexSettings.Format.ToString();
} }
HeightLabel.Text = $"Height: {SelectedTexSettings.TexHeight}";
WidthLabel.Text = $"Width: {SelectedTexSettings.TexWidth}";
Bitmap bitmap = Switch_Toolbox.Library.Imaging.GetLoadingImage(); Bitmap bitmap = Switch_Toolbox.Library.Imaging.GetLoadingImage();
Thread = new Thread((ThreadStart)(() => Thread = new Thread((ThreadStart)(() =>

View file

@ -59,10 +59,10 @@ namespace FirstPlugin
prop.Name = textureData.Text; prop.Name = textureData.Text;
prop.Width = textureData.Width; prop.Width = textureData.Width;
prop.Height = textureData.Height; prop.Height = textureData.Height;
if (textureData.mipmaps.Count > 0) if (textureData.surfaces.Count > 0)
{ {
prop.MipCount = (uint)textureData.mipmaps[CurArrayDisplayLevel].Count; prop.MipCount = (uint)textureData.surfaces[CurArrayDisplayLevel].mipmaps.Count;
prop.ArrayCount = (uint)textureData.mipmaps.Count; prop.ArrayCount = (uint)textureData.surfaces.Count;
} }
prop.Height = textureData.Height; prop.Height = textureData.Height;
@ -87,14 +87,14 @@ namespace FirstPlugin
LoadImage(); LoadImage();
int MipCount = 1; int MipCount = 1;
if (textureData.mipmaps.Count <= 0) if (textureData.surfaces.Count <= 0)
return; return;
else else
MipCount = textureData.mipmaps[CurArrayDisplayLevel].Count; MipCount = textureData.surfaces[CurArrayDisplayLevel].mipmaps.Count;
mipLevelCounterLabel.Text = $"{CurMipDisplayLevel} / {textureData.mipmaps[CurArrayDisplayLevel].Count - 1}"; mipLevelCounterLabel.Text = $"{CurMipDisplayLevel} / {textureData.surfaces[CurArrayDisplayLevel].mipmaps.Count - 1}";
arrayLevelCounterLabel.Text = $"{CurArrayDisplayLevel} / {textureData.mipmaps.Count - 1}"; arrayLevelCounterLabel.Text = $"{CurArrayDisplayLevel} / {textureData.surfaces.Count - 1}";
if (CurMipDisplayLevel != MipCount - 1) if (CurMipDisplayLevel != MipCount - 1)
BtnMipsRight.Enabled = true; BtnMipsRight.Enabled = true;
@ -106,7 +106,7 @@ namespace FirstPlugin
else else
BtmMipsLeft.Enabled = false; BtmMipsLeft.Enabled = false;
if (CurArrayDisplayLevel != textureData.mipmaps.Count - 1) if (CurArrayDisplayLevel != textureData.surfaces.Count - 1)
btnRightArray.Enabled = true; btnRightArray.Enabled = true;
else else
btnRightArray.Enabled = false; btnRightArray.Enabled = false;
@ -153,7 +153,7 @@ namespace FirstPlugin
private void BtnMipsRight_Click(object sender, EventArgs e) private void BtnMipsRight_Click(object sender, EventArgs e)
{ {
if (CurMipDisplayLevel != textureData.mipmaps[CurArrayDisplayLevel].Count - 1) if (CurMipDisplayLevel != textureData.surfaces[CurArrayDisplayLevel].mipmaps.Count - 1)
CurMipDisplayLevel += 1; CurMipDisplayLevel += 1;
UpdateMipDisplay(); UpdateMipDisplay();
@ -169,7 +169,7 @@ namespace FirstPlugin
private void btnRightArray_Click(object sender, EventArgs e) private void btnRightArray_Click(object sender, EventArgs e)
{ {
if (CurArrayDisplayLevel != textureData.mipmaps.Count - 1) if (CurArrayDisplayLevel != textureData.surfaces.Count - 1)
CurArrayDisplayLevel += 1; CurArrayDisplayLevel += 1;
UpdateMipDisplay(); UpdateMipDisplay();

View file

@ -53,6 +53,7 @@ namespace FirstPlugin
public int sparseBinding = 0; //false public int sparseBinding = 0; //false
public bool IsSRGB = true; public bool IsSRGB = true;
public bool GenerateMipmaps = false; //If bitmap and count more that 1 then geenrate public bool GenerateMipmaps = false; //If bitmap and count more that 1 then geenrate
public float alphaRef = 0.5f;
private SurfaceFormat LoadDDSFormat(uint fourCC, DDS dds = null, bool IsSRGB = false) private SurfaceFormat LoadDDSFormat(uint fourCC, DDS dds = null, bool IsSRGB = false)
{ {
@ -161,6 +162,30 @@ namespace FirstPlugin
textureData = new TextureData(tex, bntxFile); textureData = new TextureData(tex, bntxFile);
} }
} }
public void LoadTGA(string FileName, BntxFile bntxFile)
{
DecompressedData.Clear();
TexName = Path.GetFileNameWithoutExtension(FileName);
bntx = bntxFile;
Format = SurfaceFormat.BC1_SRGB;
GenerateMipmaps = true;
Bitmap Image = Paloma.TargaImage.LoadTargaImage(FileName);
Image = TextureData.SwapBlueRedChannels(Image);
TexWidth = (uint)Image.Width;
TexHeight = (uint)Image.Height;
MipCount = (uint)GetTotalMipCount();
DecompressedData.Add(BitmapExtension.ImageToByte(Image));
Image.Dispose();
if (DecompressedData.Count == 0)
{
throw new Exception("Failed to load " + Format);
}
}
public void LoadBitMap(string FileName, BntxFile bntxFile) public void LoadBitMap(string FileName, BntxFile bntxFile)
{ {
DecompressedData.Clear(); DecompressedData.Clear();
@ -215,14 +240,14 @@ namespace FirstPlugin
Bitmap Image = BitmapExtension.GetBitmap(DecompressedData[SurfaceLevel], (int)TexWidth, (int)TexHeight); Bitmap Image = BitmapExtension.GetBitmap(DecompressedData[SurfaceLevel], (int)TexWidth, (int)TexHeight);
List<byte[]> mipmaps = new List<byte[]>(); List<byte[]> mipmaps = new List<byte[]>();
mipmaps.Add(TextureData.CompressBlock(DecompressedData[SurfaceLevel], (int)TexWidth, (int)TexHeight, Format)); mipmaps.Add(TextureData.CompressBlock(DecompressedData[SurfaceLevel], (int)TexWidth, (int)TexHeight, Format, alphaRef));
//while (Image.Width / 2 > 0 && Image.Height / 2 > 0) //while (Image.Width / 2 > 0 && Image.Height / 2 > 0)
// for (int mipLevel = 0; mipLevel < MipCount; mipLevel++) // for (int mipLevel = 0; mipLevel < MipCount; mipLevel++)
for (int mipLevel = 0; mipLevel < MipCount; mipLevel++) for (int mipLevel = 0; mipLevel < MipCount; mipLevel++)
{ {
Image = BitmapExtension.Resize(Image, Image.Width / 2, Image.Height / 2); Image = BitmapExtension.Resize(Image, Image.Width / 2, Image.Height / 2);
mipmaps.Add(TextureData.CompressBlock(BitmapExtension.ImageToByte(Image), Image.Width, Image.Height, Format)); mipmaps.Add(TextureData.CompressBlock(BitmapExtension.ImageToByte(Image), Image.Width, Image.Height, Format, alphaRef));
} }
Image.Dispose(); Image.Dispose();
@ -233,7 +258,7 @@ namespace FirstPlugin
DataBlockOutput.Clear(); DataBlockOutput.Clear();
foreach (var surface in DecompressedData) foreach (var surface in DecompressedData)
{ {
DataBlockOutput.Add(TextureData.CompressBlock(surface, (int)TexWidth, (int)TexHeight, Format)); DataBlockOutput.Add(TextureData.CompressBlock(surface, (int)TexWidth, (int)TexHeight, Format, alphaRef));
} }
} }
public static uint DIV_ROUND_UP(uint value1, uint value2) public static uint DIV_ROUND_UP(uint value1, uint value2)

View file

@ -103,9 +103,9 @@
<HintPath>..\Switch_Toolbox\Lib\Syroot.Maths.dll</HintPath> <HintPath>..\Switch_Toolbox\Lib\Syroot.Maths.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="Syroot.NintenTools.Bfres"> <Reference Include="Syroot.NintenTools.Bfres, Version=1.2.3.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\Switch_Toolbox\Lib\Syroot.NintenTools.Bfres.dll</HintPath> <HintPath>..\Switch_Toolbox\Lib\Syroot.NintenTools.Bfres.dll</HintPath>
<Private>False</Private>
</Reference> </Reference>
<Reference Include="Syroot.NintenTools.NSW.Bfres"> <Reference Include="Syroot.NintenTools.NSW.Bfres">
<HintPath>..\Switch_Toolbox\Lib\Syroot.NintenTools.NSW.Bfres.dll</HintPath> <HintPath>..\Switch_Toolbox\Lib\Syroot.NintenTools.NSW.Bfres.dll</HintPath>
@ -170,6 +170,7 @@
<Compile Include="FileFormats\BFRES\Bfres Structs\FMDL.cs" /> <Compile Include="FileFormats\BFRES\Bfres Structs\FMDL.cs" />
<Compile Include="FileFormats\BFRES\Bfres Structs\FSKA.cs" /> <Compile Include="FileFormats\BFRES\Bfres Structs\FSKA.cs" />
<Compile Include="FileFormats\BFSAR.cs" /> <Compile Include="FileFormats\BFSAR.cs" />
<Compile Include="FileFormats\BFSHA.cs" />
<Compile Include="FileFormats\BYAML.cs" /> <Compile Include="FileFormats\BYAML.cs" />
<Compile Include="FileFormats\CsvModels.cs" /> <Compile Include="FileFormats\CsvModels.cs" />
<Compile Include="FileFormats\GFPAK.cs" /> <Compile Include="FileFormats\GFPAK.cs" />

View file

@ -27,7 +27,6 @@ namespace FirstPlugin
ReadShaderParams(doc, n, mat); ReadShaderParams(doc, n, mat);
} }
} }
} }
} }
public static void ReadShaderParams(XmlDocument doc, XmlNode parentNode, FMAT mat) public static void ReadShaderParams(XmlDocument doc, XmlNode parentNode, FMAT mat)

View file

@ -1,19 +1,19 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<configuration> <configuration>
<runtime> <runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly> <dependentAssembly>
<assemblyIdentity name="OpenTK" publicKeyToken="bad199fe84eb3df4" culture="neutral" /> <assemblyIdentity name="OpenTK" publicKeyToken="bad199fe84eb3df4" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" /> <bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0"/>
</dependentAssembly> </dependentAssembly>
<dependentAssembly> <dependentAssembly>
<assemblyIdentity name="LZ4pn" publicKeyToken="62e1b5ec1eec9bdd" culture="neutral" /> <assemblyIdentity name="LZ4pn" publicKeyToken="62e1b5ec1eec9bdd" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-1.0.10.93" newVersion="1.0.10.93" /> <bindingRedirect oldVersion="0.0.0.0-1.0.10.93" newVersion="1.0.10.93"/>
</dependentAssembly> </dependentAssembly>
<dependentAssembly> <dependentAssembly>
<assemblyIdentity name="K4os.Hash.xxHash" publicKeyToken="32cd54395057cec3" culture="neutral" /> <assemblyIdentity name="K4os.Hash.xxHash" publicKeyToken="32cd54395057cec3" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-1.0.5.0" newVersion="1.0.5.0" /> <bindingRedirect oldVersion="0.0.0.0-1.0.5.0" newVersion="1.0.5.0"/>
</dependentAssembly> </dependentAssembly>
</assemblyBinding> </assemblyBinding>
</runtime> </runtime>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" /></startup></configuration> <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/></startup></configuration>

View file

@ -1,22 +1,22 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<configuration> <configuration>
<startup> <startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" /> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/>
</startup> </startup>
<runtime> <runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="lib" /> <probing privatePath="lib"/>
<dependentAssembly> <dependentAssembly>
<assemblyIdentity name="OpenTK" publicKeyToken="bad199fe84eb3df4" culture="neutral" /> <assemblyIdentity name="OpenTK" publicKeyToken="bad199fe84eb3df4" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" /> <bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0"/>
</dependentAssembly> </dependentAssembly>
<dependentAssembly> <dependentAssembly>
<assemblyIdentity name="LZ4pn" publicKeyToken="62e1b5ec1eec9bdd" culture="neutral" /> <assemblyIdentity name="LZ4pn" publicKeyToken="62e1b5ec1eec9bdd" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-1.0.10.93" newVersion="1.0.10.93" /> <bindingRedirect oldVersion="0.0.0.0-1.0.10.93" newVersion="1.0.10.93"/>
</dependentAssembly> </dependentAssembly>
<dependentAssembly> <dependentAssembly>
<assemblyIdentity name="K4os.Hash.xxHash" publicKeyToken="32cd54395057cec3" culture="neutral" /> <assemblyIdentity name="K4os.Hash.xxHash" publicKeyToken="32cd54395057cec3" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-1.0.5.0" newVersion="1.0.5.0" /> <bindingRedirect oldVersion="0.0.0.0-1.0.5.0" newVersion="1.0.5.0"/>
</dependentAssembly> </dependentAssembly>
</assemblyBinding> </assemblyBinding>
</runtime> </runtime>

Binary file not shown.

View file

@ -7,7 +7,7 @@ Class DirectXTex.ImageCompressor: AutoLayout, AnsiClass, Class, Public, BeforeFi
Void .ctor(): PrivateScope, Public, HideBySig, SpecialName, RTSpecialName Void .ctor(): PrivateScope, Public, HideBySig, SpecialName, RTSpecialName
Methods: Methods:
Decompress(Byte[], Int32, Int32, Int32): PrivateScope, Public, Static, HideBySig Decompress(Byte[], Int32, Int32, Int32): PrivateScope, Public, Static, HideBySig
Compress(Byte[], Int32, Int32, Int32): PrivateScope, Public, Static, HideBySig Compress(Byte[], Int32, Int32, Int32, Single): PrivateScope, Public, Static, HideBySig
Class DirectXTex.ImageConverter: AutoLayout, AnsiClass, Class, Public, BeforeFieldInit Class DirectXTex.ImageConverter: AutoLayout, AnsiClass, Class, Public, BeforeFieldInit
Void .ctor(): PrivateScope, Public, HideBySig, SpecialName, RTSpecialName Void .ctor(): PrivateScope, Public, HideBySig, SpecialName, RTSpecialName
Methods: Methods:

Binary file not shown.

Binary file not shown.

View file

@ -8,8 +8,25 @@
DirectXTexMipmaps.cpp DirectXTexMipmaps.cpp
DirectXTexUtil.cpp DirectXTexUtil.cpp
wrapper.cpp wrapper.cpp
.NETFramework,Version=v4.6.AssemblyAttributes.cpp c:\users\nathan\documents\github\switch_toolbox\switch-toolbox - copy\switch_toolbox\lib\directxtex\wrapper.cpp(27): warning C4005: '_WIN32_WINNT': macro redefinition
c:\program files (x86)\windows kits\8.1\include\shared\sdkddkver.h(200): note: see previous definition of '_WIN32_WINNT'
c:\users\nathan\documents\github\switch_toolbox\switch-toolbox - copy\switch_toolbox\lib\directxtex\wrapper.cpp(48): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data
c:\users\nathan\documents\github\switch_toolbox\switch-toolbox - copy\switch_toolbox\lib\directxtex\wrapper.cpp(83): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data
c:\users\nathan\documents\github\switch_toolbox\switch-toolbox - copy\switch_toolbox\lib\directxtex\wrapper.cpp(101): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data
c:\users\nathan\documents\github\switch_toolbox\switch-toolbox - copy\switch_toolbox\lib\directxtex\wrapper.cpp(102): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data
c:\users\nathan\documents\github\switch_toolbox\switch-toolbox - copy\switch_toolbox\lib\directxtex\wrapper.cpp(127): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data
c:\users\nathan\documents\github\switch_toolbox\switch-toolbox - copy\switch_toolbox\lib\directxtex\wrapper.cpp(145): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data
c:\users\nathan\documents\github\switch_toolbox\switch-toolbox - copy\switch_toolbox\lib\directxtex\wrapper.cpp(146): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data
c:\users\nathan\documents\github\switch_toolbox\switch-toolbox - copy\switch_toolbox\lib\directxtex\wrapper.cpp(173): warning C4267: 'return': conversion from 'size_t' to 'int', possible loss of data
c:\users\nathan\documents\github\switch_toolbox\switch-toolbox - copy\switch_toolbox\lib\directxtex\wrapper.cpp(181): warning C4267: 'return': conversion from 'size_t' to 'int', possible loss of data
c:\users\nathan\documents\github\switch_toolbox\switch-toolbox - copy\switch_toolbox\lib\directxtex\wrapper.cpp(202): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data
c:\users\nathan\documents\github\switch_toolbox\switch-toolbox - copy\switch_toolbox\lib\directxtex\wrapper.cpp(203): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data
c:\users\nathan\documents\github\switch_toolbox\switch-toolbox - copy\switch_toolbox\lib\directxtex\wrapper.cpp(204): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data
c:\users\nathan\documents\github\switch_toolbox\switch-toolbox - copy\switch_toolbox\lib\directxtex\wrapper.cpp(207): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data
c:\users\nathan\documents\github\switch_toolbox\switch-toolbox - copy\switch_toolbox\lib\directxtex\wrapper.cpp(208): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data
c:\users\nathan\documents\github\switch_toolbox\switch-toolbox - copy\switch_toolbox\lib\directxtex\wrapper.cpp(263): warning C4267: '+=': conversion from 'size_t' to 'int', possible loss of data
.NETFramework,Version=v4.6.2.AssemblyAttributes.cpp
Generating code Generating code
All 442 functions were compiled because no usable IPDB/IOBJ from previous compilation was found. All 441 functions were compiled because no usable IPDB/IOBJ from previous compilation was found.
Finished generating code Finished generating code
DirectXTex.vcxproj -> C:\Users\Nathan\Documents\GitHub\Switch_Toolbox\Switch-Toolbox - Copy\Release\DirectXTex.dll DirectXTex.vcxproj -> C:\Users\Nathan\Documents\GitHub\Switch_Toolbox\Switch-Toolbox - Copy\Switch_Toolbox\Lib\DirectXTex\Release\DirectXTex.dll

View file

@ -73,7 +73,7 @@ namespace DirectXTex
} }
} }
static array<Byte>^ Compress(array<Byte>^ data, int width, int height, int format) static array<Byte>^ Compress(array<Byte>^ data, int width, int height, int format, float alphaRef)
{ {
size_t rowPitch = width * 4; size_t rowPitch = width * 4;
size_t slicePitch = width * height * 4; size_t slicePitch = width * height * 4;
@ -93,7 +93,7 @@ namespace DirectXTex
DirectX::ScratchImage outputImage; DirectX::ScratchImage outputImage;
// compress image // compress image
DirectX::Compress(inputImage, (DXGI_FORMAT)format, 0, 1, outputImage); DirectX::Compress(inputImage, (DXGI_FORMAT)format, 0, alphaRef, outputImage);
size_t rowPitchOut; size_t rowPitchOut;
size_t slicePitchOut; size_t slicePitchOut;

View file

@ -0,0 +1,83 @@
// ==========================================================
// TargaImage
//
// Design and implementation by
// - David Polomis (paloma_sw@cox.net)
//
//
// This source code, along with any associated files, is licensed under
// The Code Project Open License (CPOL) 1.02
// A copy of this license can be found in the CPOL.html file
// which was downloaded with this source code
// or at http://www.codeproject.com/info/cpol10.aspx
//
//
// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS,
// WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
// INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS
// FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR
// NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE
// OF THE COVERED CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE
// DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY
// OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING,
// REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN
// ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS
// AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
//
// Use at your own risk!
//
// ==========================================================
.NET Targa Image Reader
Current: C# (C# 1.0, C# 2.0, C# 3.0, C#), Windows (Windows, WinXP), .NET (.NET, .NET 3.5, .NET 3.0, .NET 2.0), GDI+, WebForms, VS2008, Dev, Intermediate
Loads Targa image files into a Bitmap using pure .NET code
TargaImage is availble on CodeProject.com
http://www.codeproject.com/KB/GDI-plus/dotnettargareader.aspx
TargaImage was created with Visual Studio 2008 Standard using C# 3.0 and the .NET Framework 2.0
To use TargaImage copy the TargaImage.dll file from the Release folder in the Bin folder to your own project.
Then include a reference to TargaImage.dll in your project.
To load a targa image call the LoadTargaImage() method of the Paloma.TargaImage class.
Or if you want access to the image properties create an instance of the TargaImage class.
EXAMPLES:
// C# Sample
// Loads a targa image and assigns it to the Image of a picturebox control.
this.PictureBox1.Image = Paloma.TargaImage.LoadTargaImage(@"c:\targaimage.tga");
// Creates an instance of the TargaImage class with the specifed file
// displays a few targa properties and then assigns the targa image
// to the Image of a picturebox control
Paloma.TargaImage tgaImage = new Paloma.TargaImage(@"c:\targaimage.tga");
this.Label1.Text = tgaImage.Format.ToString();
this.Label2.Text = tgaImage.Header.ImageType.ToString();
this.Label3.Text = tgaImage.Header.PixelDepth.ToString();
this.PictureBox1.Image = Paloma.TargaImage.Image;
' VB.NET Sample
' Loads a targa image and assigns it to the Image of a picturebox control.
Me.PictureBox1.Image = Paloma.TargaImage.LoadTargaImage("c:\targaimage.tga")
' Creates an instance of the TargaImage class with the specifed file
' displays a few targa properties and then assigns the targa image
' to the Image of a picturebox control
Dim tgaImage As New Paloma.TargaImage("c:\targaimage.tga")
Me.Label1.Text = tgaImage.Format.ToString()
Me.Label2.Text = tgaImage.Header.ImageType.ToString()
Me.Label3.Text = tgaImage.Header.PixelDepth.ToString()
Me.PictureBox1.Image = Paloma.TargaImage.Image

View file

@ -32,10 +32,17 @@ namespace Switch_Toolbox
private static MainForm _instance; private static MainForm _instance;
public static MainForm Instance { get { return _instance == null ? _instance = new MainForm() : _instance; } } public static MainForm Instance { get { return _instance == null ? _instance = new MainForm() : _instance; } }
bool AttachCommit = false;
public MainForm() public MainForm()
{ {
InitializeComponent(); InitializeComponent();
string commit = "";
if (AttachCommit)
commit = $"Commit: {Runtime.CommitInfo}";
Text = $"Switch Toolbox | Compile Date: {Runtime.CompileDate} Version: {Runtime.ProgramVersion} {commit}";
ShaderTools.executableDir = executableDir; ShaderTools.executableDir = executableDir;
Config.StartupFromFile(MainForm.executableDir + "\\config.xml"); Config.StartupFromFile(MainForm.executableDir + "\\config.xml");
@ -199,8 +206,7 @@ namespace Switch_Toolbox
} }
private void LoadObjectList() private void LoadObjectList()
{ {
objectList = new ObjectList(); ObjectList.Instance.Show(dockPanel1, Runtime.objectListDockState);
objectList.Show(dockPanel1, Runtime.objectListDockState);
} }
public void SaveFile(IFileFormat format, string FileName) public void SaveFile(IFileFormat format, string FileName)
{ {
@ -286,12 +292,12 @@ namespace Switch_Toolbox
format.FileIsCompressed = Compressed; format.FileIsCompressed = Compressed;
format.Data = data; format.Data = data;
format.FileName = Path.GetFileName(FileName); format.FileName = Path.GetFileName(FileName);
format.Load();
format.FilePath = FileName; format.FilePath = FileName;
format.Load();
if (format is TreeNode) if (format is TreeNode)
{ {
objectList.treeView1.Nodes.Add((TreeNode)format); ObjectList.Instance.treeView1.Nodes.Add((TreeNode)format);
} }
if (format.CanSave) if (format.CanSave)
@ -321,7 +327,7 @@ namespace Switch_Toolbox
if (format is TreeNode) if (format is TreeNode)
{ {
objectList.treeView1.Nodes.Add((TreeNode)format); ObjectList.Instance.treeView1.Nodes.Add((TreeNode)format);
} }
if (format.CanSave) if (format.CanSave)

View file

@ -64,8 +64,15 @@ uniform int HasRoughnessMap;
uniform int HasMRA; uniform int HasMRA;
uniform int HasSubSurfaceScatteringMap; uniform int HasSubSurfaceScatteringMap;
uniform int renderTevColors;
uniform int renderMatColors;
uniform vec4 const_color0; uniform vec4 const_color0;
uniform vec4 base_color_mul_color; uniform vec4 base_color_mul_color;
uniform vec4 tev_color0;
uniform vec4 tev_color1;
uniform vec4 mat_color0;
uniform vec4 mat_color1;
struct VertexAttributes { struct VertexAttributes {
vec3 objectPosition; vec3 objectPosition;
@ -146,6 +153,17 @@ void main()
fragColor *= min(const_color0, vec4(1)); fragColor *= min(const_color0, vec4(1));
fragColor *= min(base_color_mul_color, vec4(1)); fragColor *= min(base_color_mul_color, vec4(1));
float colorScale = texture(DiffuseMap, f_texcoord0).r;
if (renderMatColors == 1)
{
// fragColor *= vec4(min(mat_color0, colorScale).rgb, 1.0);
// fragColor *= vec4(min(mat_color1, (1 - colorScale) + colorScale * 0).rgb, 1.0);
}
if (renderTevColors == 1)
{
// fragColor *= vec4(min(tev_color0, colorScale).rgb, 1.0);
// fragColor *= vec4(min(tev_color1, (1 - colorScale) + colorScale * 0).rgb, 1.0);
}
// if (isTransparent != 1) // if (isTransparent != 1)
// fragColor.a = 1; // fragColor.a = 1;

View file

@ -167,6 +167,7 @@
</Compile> </Compile>
<Compile Include="Program.cs" /> <Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="VersionCheck.cs" />
<EmbeddedResource Include="GUI\Credits.resx"> <EmbeddedResource Include="GUI\Credits.resx">
<DependentUpon>Credits.cs</DependentUpon> <DependentUpon>Credits.cs</DependentUpon>
</EmbeddedResource> </EmbeddedResource>
@ -275,6 +276,9 @@
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="Assimp32.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="libzstd.dll"> <Content Include="libzstd.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
@ -325,6 +329,12 @@
<Content Include="Lib\Licenses\SmashForge COPYRIGHT.txt"> <Content Include="Lib\Licenses\SmashForge COPYRIGHT.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
<Content Include="Lib\Licenses\TargaImage COPYRIGHT.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\Licenses\TexConv COPYRIGHT.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\LZ4.dll"> <Content Include="Lib\LZ4.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
@ -361,6 +371,9 @@
<Content Include="Lib\Syroot.Maths.dll"> <Content Include="Lib\Syroot.Maths.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
<Content Include="Lib\Syroot.NintenTools.Bfres.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\Syroot.NintenTools.NSW.Bfres.dll"> <Content Include="Lib\Syroot.NintenTools.NSW.Bfres.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>

View file

@ -0,0 +1,3 @@
Version:
Commit:
Build Date:

View file

@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Switch_Toolbox.Library;
namespace Switch_Toolbox
{
public class VersionCheck
{
public void ReadVersionInfo()
{
string path = MainForm.executableDir + "Version.txt";
using (StreamReader reader = new StreamReader(path))
{
string Version = reader.ReadLine();
}
}
public void WriteVersionInfo()
{
string path = MainForm.executableDir + "Version.txt";
using (StreamWriter writer = new StreamWriter(path))
{
writer.Write($"Version: {Runtime.ProgramVersion}");
writer.Write($"Commit: {Runtime.CommitInfo}");
writer.Write($"Build Date: {Runtime.CompileDate}");
}
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Switch_Toolbox.Library.IO;
namespace Switch_Toolbox.Library
{
public class ASTC
{
const uint Magic = 0x5CA1AB13;
public byte BlockDimX;
public byte BlockDimY;
public byte BlockDimZ;
public int X;
public int Y;
public int Z;
public void WriteASTCHeader(FileWriter writer)
{
writer.ByteOrder = Syroot.BinaryData.ByteOrder.LittleEndian;
writer.Write(Magic);
writer.Write(BlockDimX);
writer.Write(BlockDimY);
writer.Write(BlockDimZ);
writer.Write(X);
writer.Write(Y);
writer.Write(Z);
}
}
}

View file

@ -1,11 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections;
using System.Linq; using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Assimp; using Assimp;
using Assimp.Configs;
using OpenTK; using OpenTK;
using Switch_Toolbox.Library.Rendering; using Switch_Toolbox.Library.Rendering;
using System.Windows.Forms; using System.Windows.Forms;
@ -15,10 +11,10 @@ namespace Switch_Toolbox.Library
public class AssimpData public class AssimpData
{ {
public Scene scene; public Scene scene;
private Vector3 m_sceneCenter, m_sceneMin, m_sceneMax;
public List<STGenericObject> objects = new List<STGenericObject>(); public List<STGenericObject> objects = new List<STGenericObject>();
public List<STGenericMaterial> materials = new List<STGenericMaterial>(); public List<STGenericMaterial> materials = new List<STGenericMaterial>();
public List<STGenericTexture> textures = new List<STGenericTexture>();
public AssimpContext Importer = new AssimpContext(); public AssimpContext Importer = new AssimpContext();
@ -36,10 +32,14 @@ namespace Switch_Toolbox.Library
{ {
AssimpContext Importer = new AssimpContext(); AssimpContext Importer = new AssimpContext();
scene = Importer.ImportFile(FileName, PostProcessSteps.Triangulate | PostProcessSteps.JoinIdenticalVertices scene = Importer.ImportFile(FileName,
| PostProcessSteps.FlipUVs | PostProcessSteps.LimitBoneWeights | PostProcessSteps.Triangulate |
PostProcessSteps.CalculateTangentSpace | PostProcessSteps.GenerateNormals); PostProcessSteps.JoinIdenticalVertices |
LoadMeshes(); PostProcessSteps.FlipUVs |
PostProcessSteps.LimitBoneWeights |
PostProcessSteps.CalculateTangentSpace |
PostProcessSteps.GenerateNormals);
LoadScene();
} }
catch (Exception e) catch (Exception e)
{ {
@ -79,9 +79,12 @@ PostProcessSteps.CalculateTangentSpace | PostProcessSteps.GenerateNormals);
foreach (Node child in parent.Children) foreach (Node child in parent.Children)
BuildNode(child, ref world); BuildNode(child, ref world);
} }
public void LoadMeshes() public void LoadScene()
{ {
objects.Clear(); objects.Clear();
textures.Clear();
materials.Clear();
processNode(); processNode();
if (scene.HasMaterials) if (scene.HasMaterials)
{ {
@ -94,6 +97,9 @@ PostProcessSteps.CalculateTangentSpace | PostProcessSteps.GenerateNormals);
{ {
} }
foreach (var tex in scene.Textures)
{
}
} }
public Animation CreateGenericAnimation(Assimp.Animation animation) public Animation CreateGenericAnimation(Assimp.Animation animation)
{ {
@ -123,11 +129,34 @@ PostProcessSteps.CalculateTangentSpace | PostProcessSteps.GenerateNormals);
return STanim; return STanim;
} }
public STGenericTexture CreateGenericTexture(string Path)
{
STGenericTexture tex = new STGenericTexture();
switch (System.IO.Path.GetExtension(Path))
{
case ".dds":
tex.LoadDDS(Path);
break;
case ".tga":
tex.LoadTGA(Path);
break;
default:
tex.LoadBitmap(Path);
break;
}
return tex;
}
public STGenericMaterial CreateGenericMaterial(Material material) public STGenericMaterial CreateGenericMaterial(Material material)
{ {
STGenericMaterial mat = new STGenericMaterial(); STGenericMaterial mat = new STGenericMaterial();
mat.Text = material.Name; mat.Text = material.Name;
foreach (var slot in material.GetAllMaterialTextures())
{
textures.Add(CreateGenericTexture(slot.FilePath));
}
TextureSlot tex; TextureSlot tex;
if (material.GetMaterialTexture(TextureType.Diffuse, 0, out tex)) if (material.GetMaterialTexture(TextureType.Diffuse, 0, out tex))
mat.TextureMaps.Add(CreateTextureSlot(tex, TextureType.Diffuse)); mat.TextureMaps.Add(CreateTextureSlot(tex, TextureType.Diffuse));
@ -222,7 +251,7 @@ PostProcessSteps.CalculateTangentSpace | PostProcessSteps.GenerateNormals);
obj.boneList = GetBoneList(msh); obj.boneList = GetBoneList(msh);
obj.MaxSkinInfluenceCount = GetVertexSkinCount(msh); obj.MaxSkinInfluenceCount = GetVertexSkinCount(msh);
GenericObject.LOD_Mesh lod = new GenericObject.LOD_Mesh(); STGenericObject.LOD_Mesh lod = new STGenericObject.LOD_Mesh();
lod.faces = GetFaces(msh); lod.faces = GetFaces(msh);
lod.IndexFormat = STIndexFormat.UInt16; lod.IndexFormat = STIndexFormat.UInt16;
lod.PrimitiveType = STPolygonType.Triangle; lod.PrimitiveType = STPolygonType.Triangle;
@ -233,24 +262,19 @@ PostProcessSteps.CalculateTangentSpace | PostProcessSteps.GenerateNormals);
return obj; return obj;
} }
int NodeIndex; public void SaveFromModel(STGenericModel model, string FileName, List<STGenericTexture> Textures)
public void SaveFromModel(GenericModel model, string FileName)
{ {
Scene scene = new Scene(); Scene scene = new Scene();
scene.RootNode = new Node("Root"); scene.RootNode = new Node("RootNode");
Node modelNode = new Node(model.Text);
scene.RootNode.Children.Add(modelNode);
int MeshIndex = 0; int MeshIndex = 0;
foreach (var obj in model.Nodes[0].Nodes) foreach (var obj in model.Nodes[0].Nodes)
{ {
var genericObj = (STGenericObject)obj; var genericObj = (STGenericObject)obj;
Node groupNode = new Node(genericObj.Text);
Mesh mesh = new Mesh(genericObj.Text, PrimitiveType.Triangle); Mesh mesh = new Mesh(genericObj.Text, PrimitiveType.Triangle);
mesh.MaterialIndex = genericObj.MaterialIndex;
List<Vector3D> textureCoords0 = new List<Vector3D>(); List<Vector3D> textureCoords0 = new List<Vector3D>();
List<Vector3D> textureCoords1 = new List<Vector3D>(); List<Vector3D> textureCoords1 = new List<Vector3D>();
@ -269,37 +293,38 @@ PostProcessSteps.CalculateTangentSpace | PostProcessSteps.GenerateNormals);
mesh.TextureCoordinateChannels[2] = textureCoords2; mesh.TextureCoordinateChannels[2] = textureCoords2;
mesh.VertexColorChannels[0] = vertexColors; mesh.VertexColorChannels[0] = vertexColors;
} }
List<int> faces = genericObj.lodMeshes[genericObj.DisplayLODIndex].faces; List<int> faces = genericObj.lodMeshes[genericObj.DisplayLODIndex].faces;
for (int f = 0; f < faces.Count; f++) for (int f = 0; f < faces.Count; f++)
mesh.Faces.Add(new Face(new int[] { faces[f++], faces[f++], faces[f] })); mesh.Faces.Add(new Face(new int[] { faces[f++], faces[f++], faces[f] }));
Console.WriteLine(genericObj.faces.Count);
Console.WriteLine(genericObj.vertices.Count);
Console.WriteLine(genericObj.Text);
mesh.MaterialIndex = genericObj.MaterialIndex;
mesh.TextureCoordinateChannels.SetValue(textureCoords0, 0); mesh.TextureCoordinateChannels.SetValue(textureCoords0, 0);
groupNode.MeshIndices.Add(scene.Meshes.Count);
scene.Meshes.Add(mesh); scene.Meshes.Add(mesh);
MeshIndex++; MeshIndex++;
modelNode.Children.Add(groupNode);
} }
string TextureExtension = ".png";
string TexturePath = System.IO.Path.GetDirectoryName(FileName);
foreach (var mat in model.Nodes[1].Nodes) foreach (var mat in model.Nodes[1].Nodes)
{ {
var genericMat = (STGenericMaterial)mat; var genericMat = (STGenericMaterial)mat;
Material material = new Material(); Material material = new Material();
material.Name = genericMat.Name; material.Name = genericMat.Text;
foreach (var tex in genericMat.TextureMaps) foreach (var tex in genericMat.TextureMaps)
{ {
TextureSlot slot = new TextureSlot(); TextureSlot slot = new TextureSlot();
slot.FilePath = tex.Name; string path = System.IO.Path.Combine(TexturePath, tex.Name + TextureExtension);
slot.FilePath = path;
slot.UVIndex = 0;
slot.Flags = 0;
slot.TextureIndex = 0;
slot.BlendFactor = 1.0f;
slot.Mapping = TextureMapping.FromUV;
slot.Operation = TextureOperation.Add;
if (tex.Type == STGenericMatTexture.TextureType.Diffuse) if (tex.Type == STGenericMatTexture.TextureType.Diffuse)
slot.TextureType = TextureType.Diffuse; slot.TextureType = TextureType.Diffuse;
@ -311,13 +336,13 @@ PostProcessSteps.CalculateTangentSpace | PostProcessSteps.GenerateNormals);
slot.TextureType = TextureType.Emissive; slot.TextureType = TextureType.Emissive;
else if (tex.Type == STGenericMatTexture.TextureType.Light) else if (tex.Type == STGenericMatTexture.TextureType.Light)
{ {
slot.Mapping = TextureMapping.FromUV - 1;
slot.TextureType = TextureType.Lightmap; slot.TextureType = TextureType.Lightmap;
slot.UVIndex = 2;
} }
else if (tex.Type == STGenericMatTexture.TextureType.Shadow) else if (tex.Type == STGenericMatTexture.TextureType.Shadow)
{ {
slot.Mapping = TextureMapping.FromUV - 1;
slot.TextureType = TextureType.Ambient; slot.TextureType = TextureType.Ambient;
slot.UVIndex = 1;
} }
else else
slot.TextureType = TextureType.Unknown; slot.TextureType = TextureType.Unknown;
@ -329,16 +354,27 @@ PostProcessSteps.CalculateTangentSpace | PostProcessSteps.GenerateNormals);
if (tex.wrapModeS == 2) if (tex.wrapModeS == 2)
slot.WrapModeU = TextureWrapMode.Clamp; slot.WrapModeU = TextureWrapMode.Clamp;
if (tex.wrapModeT == 0) if (tex.wrapModeT == 0)
slot.WrapModeU = TextureWrapMode.Wrap; slot.WrapModeV = TextureWrapMode.Wrap;
if (tex.wrapModeT == 1) if (tex.wrapModeT == 1)
slot.WrapModeU = TextureWrapMode.Mirror; slot.WrapModeV = TextureWrapMode.Mirror;
if (tex.wrapModeT == 2) if (tex.wrapModeT == 2)
slot.WrapModeU = TextureWrapMode.Clamp; slot.WrapModeV = TextureWrapMode.Clamp;
else
{
slot.WrapModeU = TextureWrapMode.Wrap;
slot.WrapModeV = TextureWrapMode.Wrap;
}
material.AddMaterialTexture(ref slot); material.AddMaterialTexture(ref slot);
} }
scene.Materials.Add(material); scene.Materials.Add(material);
} }
foreach (var tex in Textures)
{
string path = System.IO.Path.Combine(TexturePath, tex.Name + TextureExtension);
if (!System.IO.File.Exists(path))
tex.GetBitmap().Save(path);
}
using (var v = new AssimpContext()) using (var v = new AssimpContext())
{ {
@ -348,16 +384,11 @@ PostProcessSteps.CalculateTangentSpace | PostProcessSteps.GenerateNormals);
if (ext == ".obj") if (ext == ".obj")
formatID = "obj"; formatID = "obj";
if (ext == ".fbx") if (ext == ".fbx")
formatID = "fbx"; formatID = "collada";
if (ext == ".dae") if (ext == ".dae")
formatID = "dae"; formatID = "collada";
Console.WriteLine(ext); if (v.ExportFile(scene, FileName, formatID, PostProcessSteps.ValidateDataStructure))
Console.WriteLine(formatID);
bool Exported = v.ExportFile(scene, FileName, formatID);
if (Exported)
System.Windows.Forms.MessageBox.Show($"Exported {FileName} Successfuly!"); System.Windows.Forms.MessageBox.Show($"Exported {FileName} Successfuly!");
else else
System.Windows.Forms.MessageBox.Show($"Failed to export {FileName}!"); System.Windows.Forms.MessageBox.Show($"Failed to export {FileName}!");
@ -396,7 +427,6 @@ PostProcessSteps.CalculateTangentSpace | PostProcessSteps.GenerateNormals);
mesh.TextureCoordinateChannels.SetValue(textureCoords0, 0); mesh.TextureCoordinateChannels.SetValue(textureCoords0, 0);
scene.Meshes.Add(mesh); scene.Meshes.Add(mesh);
scene.RootNode.MeshIndices.Add(0);
Material material = new Material(); Material material = new Material();
material.Name = "NewMaterial"; material.Name = "NewMaterial";

View file

@ -504,7 +504,36 @@ namespace Switch_Toolbox.Library
} }
} }
} }
public void Save(DDS dds, string FileName, List<List<byte[]>> data = null) public STGenericTexture.TEX_FORMAT GetFormat()
{
if (DX10header != null)
return (STGenericTexture.TEX_FORMAT)DX10header.DXGI_Format;
switch (header.ddspf.fourCC)
{
case FOURCC_DXT1:
return STGenericTexture.TEX_FORMAT.BC1_UNORM;
case FOURCC_DXT2:
return STGenericTexture.TEX_FORMAT.BC2_UNORM;
case FOURCC_DXT3:
return STGenericTexture.TEX_FORMAT.BC2_UNORM;
case FOURCC_DXT4:
return STGenericTexture.TEX_FORMAT.BC3_UNORM;
case FOURCC_DXT5:
return STGenericTexture.TEX_FORMAT.BC3_UNORM;
case FOURCC_ATI1:
return STGenericTexture.TEX_FORMAT.BC4_UNORM;
case FOURCC_BC4U:
return STGenericTexture.TEX_FORMAT.BC4_UNORM;
case FOURCC_ATI2:
return STGenericTexture.TEX_FORMAT.BC5_UNORM;
case FOURCC_BC5U:
return STGenericTexture.TEX_FORMAT.BC5_UNORM;
default:
return STGenericTexture.TEX_FORMAT.UNKNOWN;
}
}
public void Save(DDS dds, string FileName, List<STGenericTexture.Surface> data = null)
{ {
FileWriter writer = new FileWriter(new FileStream(FileName, FileMode.Create, FileAccess.Write, FileShare.Write)); FileWriter writer = new FileWriter(new FileStream(FileName, FileMode.Create, FileAccess.Write, FileShare.Write));
var header = dds.header; var header = dds.header;
@ -543,7 +572,7 @@ namespace Switch_Toolbox.Library
if (data != null) if (data != null)
{ {
writer.Write(data[0][0]); writer.Write(data[0].mipmaps[0]);
} }
else else
{ {

View file

@ -484,9 +484,9 @@ namespace Switch_Toolbox.Library
{ {
return DirectXTex.ImageCompressor.Decompress(data, width, height, (int)format); return DirectXTex.ImageCompressor.Decompress(data, width, height, (int)format);
} }
public static byte[] CompressBlock(Byte[] data, int width, int height, DDS.DXGI_FORMAT format) public static byte[] CompressBlock(Byte[] data, int width, int height, DDS.DXGI_FORMAT format, float alphaRef)
{ {
return DirectXTex.ImageCompressor.Compress(data, width, height, (int)format); return DirectXTex.ImageCompressor.Compress(data, width, height, (int)format, alphaRef);
} }
public static byte[] EncodePixelBlock(Byte[] data, int width, int height, DDS.DXGI_FORMAT format) public static byte[] EncodePixelBlock(Byte[] data, int width, int height, DDS.DXGI_FORMAT format)
{ {

View file

@ -50,15 +50,6 @@ namespace Switch_Toolbox.Library
return Img; return Img;
} }
private static void ConvertBgraToRgba(byte[] bytes)
{
for (int i = 0; i < bytes.Length; i += 4)
{
var temp = bytes[i];
bytes[i] = bytes[i + 2];
bytes[i + 2] = temp;
}
}
public class ColorSwapFilter public class ColorSwapFilter
{ {
private ColorSwapType swapType = ColorSwapType.FixDDS; private ColorSwapType swapType = ColorSwapType.FixDDS;

View file

@ -16,6 +16,40 @@ namespace Switch_Toolbox.Library
public virtual void OnMouseRightClick(TreeView treeview) { } public virtual void OnMouseRightClick(TreeView treeview) { }
public virtual void OnDoubleMouseClick(TreeView treeview) { } public virtual void OnDoubleMouseClick(TreeView treeview) { }
public void Sort(TreeNode node)
{
/* string[] array = new string[Nodes.Count];
for (int i = 0; i < Nodes.Count; ++i)
array[i] = Nodes[i].Text;
Array.Sort<string>(array, (IComparer<string>)StringComparer.Ordinal);
for (int index = 0; index < Nodes.Count; ++index)
Nodes[index].Text = array[index];*/
//Good enough for now. I'll update with a more cleaner method later
foreach (TreeNode n in node.Nodes)
Sort(n);
try
{
TreeNode temp = null;
List<TreeNode> childs = new List<TreeNode>();
while (node.Nodes.Count > 0)
{
foreach (TreeNode n in node.Nodes)
if (temp == null || n.Text[0] < temp.Text[0])
temp = n;
node.Nodes.Remove(temp);
childs.Add(temp);
temp = null;
}
node.Nodes.Clear();
foreach (TreeNode a in childs)
node.Nodes.Add(a);
}
catch { }
}
public TreeNodeCustom() public TreeNodeCustom()
{ {
} }

View file

@ -31,7 +31,7 @@ namespace Switch_Toolbox.Library
listView1.Items.Add(msh.Name); listView1.Items.Add(msh.Name);
} }
} }
public GenericObject GetSelectedMesh() public STGenericObject GetSelectedMesh()
{ {
assimp.processNode(); assimp.processNode();
foreach (Mesh msh in assimp.scene.Meshes) foreach (Mesh msh in assimp.scene.Meshes)

View file

@ -30,13 +30,13 @@
{ {
this.components = new System.ComponentModel.Container(); this.components = new System.ComponentModel.Container();
this.panel1 = new System.Windows.Forms.Panel(); this.panel1 = new System.Windows.Forms.Panel();
this.treeView1 = new Switch_Toolbox.Library.TreeViewCustom();
this.contextMenuStripDark1 = new Switch_Toolbox.Library.Forms.ContextMenuStripDark(); this.contextMenuStripDark1 = new Switch_Toolbox.Library.Forms.ContextMenuStripDark();
this.settingsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.settingsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.smallToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.smallToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.mediumToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.mediumToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.largeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.largeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.searchToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.searchToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.treeView1 = new Switch_Toolbox.Library.TreeViewCustom();
this.panel1.SuspendLayout(); this.panel1.SuspendLayout();
this.contextMenuStripDark1.SuspendLayout(); this.contextMenuStripDark1.SuspendLayout();
this.SuspendLayout(); this.SuspendLayout();
@ -51,6 +51,30 @@
this.panel1.Size = new System.Drawing.Size(358, 27); this.panel1.Size = new System.Drawing.Size(358, 27);
this.panel1.TabIndex = 2; this.panel1.TabIndex = 2;
// //
// treeView1
//
this.treeView1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.treeView1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(40)))), ((int)(((byte)(40)))), ((int)(((byte)(40)))));
this.treeView1.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.treeView1.CheckBoxes = true;
this.treeView1.DrawMode = System.Windows.Forms.TreeViewDrawMode.OwnerDrawText;
this.treeView1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.treeView1.ForeColor = System.Drawing.Color.White;
this.treeView1.ImageIndex = 0;
this.treeView1.Location = new System.Drawing.Point(0, 27);
this.treeView1.Name = "treeView1";
this.treeView1.SelectedImageIndex = 0;
this.treeView1.Size = new System.Drawing.Size(358, 423);
this.treeView1.TabIndex = 0;
this.treeView1.AfterCheck += new System.Windows.Forms.TreeViewEventHandler(this.treeView1_AfterCheck);
this.treeView1.DrawNode += new System.Windows.Forms.DrawTreeNodeEventHandler(this.treeView1_DrawNode);
this.treeView1.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeView1_AfterSelect);
this.treeView1.NodeMouseClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.selectItem);
this.treeView1.MouseClick += new System.Windows.Forms.MouseEventHandler(this.treeView1_MouseClick);
this.treeView1.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.treeView1_MouseDoubleClick);
//
// contextMenuStripDark1 // contextMenuStripDark1
// //
this.contextMenuStripDark1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(33)))), ((int)(((byte)(33)))), ((int)(((byte)(33))))); this.contextMenuStripDark1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(33)))), ((int)(((byte)(33)))), ((int)(((byte)(33)))));
@ -105,27 +129,6 @@
this.searchToolStripMenuItem.Text = "Search"; this.searchToolStripMenuItem.Text = "Search";
this.searchToolStripMenuItem.Click += new System.EventHandler(this.searchToolStripMenuItem_Click); this.searchToolStripMenuItem.Click += new System.EventHandler(this.searchToolStripMenuItem_Click);
// //
// treeView1
//
this.treeView1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.treeView1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(40)))), ((int)(((byte)(40)))), ((int)(((byte)(40)))));
this.treeView1.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.treeView1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.treeView1.ForeColor = System.Drawing.Color.White;
this.treeView1.ImageIndex = 0;
this.treeView1.Location = new System.Drawing.Point(0, 27);
this.treeView1.Name = "treeView1";
this.treeView1.SelectedImageIndex = 0;
this.treeView1.Size = new System.Drawing.Size(358, 423);
this.treeView1.TabIndex = 0;
this.treeView1.AfterCheck += new System.Windows.Forms.TreeViewEventHandler(this.treeView1_AfterCheck);
this.treeView1.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeView1_AfterSelect);
this.treeView1.NodeMouseClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.selectItem);
this.treeView1.MouseClick += new System.Windows.Forms.MouseEventHandler(this.treeView1_MouseClick);
this.treeView1.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.treeView1_MouseDoubleClick);
//
// ObjectList // ObjectList
// //
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);

View file

@ -17,6 +17,9 @@ namespace Switch_Toolbox.Library
{ {
public partial class ObjectList : DockContent public partial class ObjectList : DockContent
{ {
private static ObjectList _instance;
public static ObjectList Instance { get { return _instance == null ? _instance = new ObjectList() : _instance; } }
Thread Thread; Thread Thread;
public ObjectList() public ObjectList()
@ -149,16 +152,17 @@ namespace Switch_Toolbox.Library
if (treeView1.SelectedNode is TreeNodeCustom) if (treeView1.SelectedNode is TreeNodeCustom)
{ {
((TreeNodeCustom)treeView1.SelectedNode).OnClick(treeView1); ((TreeNodeCustom)treeView1.SelectedNode).OnClick(treeView1);
} }
if (treeView1.SelectedNode is STGenericObject) if (treeView1.SelectedNode is STGenericObject)
{ {
((STGenericObject)treeView1.SelectedNode).OnClick(treeView1); ((STGenericObject)treeView1.SelectedNode).OnClick(treeView1);
Viewport.Instance.Update();
} }
if (treeView1.SelectedNode is STGenericMaterial) if (treeView1.SelectedNode is STGenericMaterial)
{ {
((STGenericMaterial)treeView1.SelectedNode).OnClick(treeView1); ((STGenericMaterial)treeView1.SelectedNode).OnClick(treeView1);
} }
Viewport.Instance.UpdateViewport();
} }
private void ObjectList_DockStateChanged(object sender, EventArgs e) private void ObjectList_DockStateChanged(object sender, EventArgs e)
@ -168,6 +172,23 @@ namespace Switch_Toolbox.Library
private void treeView1_AfterCheck(object sender, TreeViewEventArgs e) private void treeView1_AfterCheck(object sender, TreeViewEventArgs e)
{ {
Viewport.Instance.UpdateViewport();
if (e.Node is STGenericModel)
{
CheckChildNodes(e.Node, e.Node.Checked);
}
}
private void CheckChildNodes(TreeNode node, bool IsChecked)
{
foreach (TreeNode n in node.Nodes)
{
n.Checked = IsChecked;
if (n.Nodes.Count > 0)
{
CheckChildNodes(n, IsChecked);
}
}
} }
private void searchToolStripMenuItem_Click(object sender, EventArgs e) private void searchToolStripMenuItem_Click(object sender, EventArgs e)
@ -209,5 +230,16 @@ namespace Switch_Toolbox.Library
((TreeNodeCustom)treeView1.SelectedNode).OnDoubleMouseClick(treeView1); ((TreeNodeCustom)treeView1.SelectedNode).OnDoubleMouseClick(treeView1);
} }
} }
private void treeView1_DrawNode(object sender, DrawTreeNodeEventArgs e)
{
e.DrawDefault = true;
if (e.Node is STGenericObject || e.Node is STGenericModel)
{
}
else
TreeViewExtensions.HideCheckBox(e.Node);
}
} }
} }

View file

@ -120,4 +120,7 @@
<metadata name="contextMenuStripDark1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> <metadata name="contextMenuStripDark1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value> <value>17, 17</value>
</metadata> </metadata>
<metadata name="contextMenuStripDark1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root> </root>

View file

@ -0,0 +1,65 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenTK.Graphics.OpenGL;
namespace Switch_Toolbox.Library
{
public class STGenericMatTexture
{
public int mapMode = 0;
public int wrapModeS = 1;
public int wrapModeT = 1;
public int wrapModeW = 1; //Used for 3D textures
public int minFilter = 3;
public int magFilter = 2;
public int mipDetail = 6;
public string Name;
public TextureType Type;
//An enum for the assumed texture type by sampler
//Many games have a consistant type of samplers and type. _a0 for diffuse, _n0 for normal, ect
public enum TextureType
{
Unknown = 0,
Diffuse = 1,
Normal = 2,
Specular = 3,
Emission = 4,
DiffuseLayer2 = 5,
TeamColor = 6,
Transparency = 7,
Shadow = 8,
AO = 9,
Light = 10,
Roughness = 11,
Metalness = 12,
MRA = 13, //Combined pbr texture HAL uses for KSA
SphereMap = 14,
SubSurfaceScattering = 15,
}
public static readonly Dictionary<int, TextureMinFilter> minfilter = new Dictionary<int, TextureMinFilter>()
{
{ 0x00, TextureMinFilter.LinearMipmapLinear},
{ 0x01, TextureMinFilter.Nearest},
{ 0x02, TextureMinFilter.Linear},
{ 0x03, TextureMinFilter.NearestMipmapLinear},
};
public static readonly Dictionary<int, TextureMagFilter> magfilter = new Dictionary<int, TextureMagFilter>()
{
{ 0x00, TextureMagFilter.Linear},
{ 0x01, TextureMagFilter.Nearest},
{ 0x02, TextureMagFilter.Linear}
};
public static Dictionary<int, TextureWrapMode> wrapmode = new Dictionary<int, TextureWrapMode>(){
{ 0x00, TextureWrapMode.Repeat},
{ 0x01, TextureWrapMode.MirroredRepeat},
{ 0x02, TextureWrapMode.ClampToEdge},
{ 0x03, TextureWrapMode.MirroredRepeat},
};
}
}

View file

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Switch_Toolbox.Library
{
public class STGenericMaterial : TreeNodeCustom
{
public List<STGenericMatTexture> TextureMaps = new List<STGenericMatTexture>();
public override void OnClick(TreeView treeView)
{
}
}
}

View file

@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Switch_Toolbox.Library
{
public class STGenericModel : TreeNodeCustom
{
public STGenericModel()
{
Checked = true;
}
public override void OnClick(TreeView treeView)
{
}
}
}

View file

@ -0,0 +1,364 @@
using System;
using System.Collections.Generic;
using System.Linq;
using OpenTK;
using System.Windows.Forms;
using Switch_Toolbox.Library.Rendering;
namespace Switch_Toolbox.Library
{
public class STGenericObject : TreeNodeCustom
{
public STGenericObject()
{
Checked = true;
}
public override void OnClick(TreeView treeView)
{
}
public bool HasPos;
public bool HasNrm;
public bool HasUv0;
public bool HasUv1;
public bool HasUv2;
public bool HasWeights;
public bool HasIndices;
public bool HasBitans;
public bool HasTans;
public bool HasVertColors;
public int MaxSkinInfluenceCount;
public string ObjectName;
public int BoneIndex;
public int MaterialIndex;
public int VertexBufferIndex;
public int DisplayLODIndex;
public int Offset;
public int GetMaxSkinInfluenceCount()
{
return vertices.Max(t => t.boneIds.Count);
}
public Vector3 GetOrigin()
{
Vector3 pos = Vector3.Zero;
foreach (Vertex vert in vertices)
{
}
return pos;
}
public List<string[]> bones = new List<string[]>();
public List<float[]> weightsT = new List<float[]>();
public List<string> boneList = new List<string>();
public List<Vertex> vertices = new List<Vertex>();
public List<LOD_Mesh> lodMeshes = new List<LOD_Mesh>();
public class LOD_Mesh
{
public STPolygonType PrimitiveType = STPolygonType.Triangle;
public STIndexFormat IndexFormat = STIndexFormat.UInt16;
public uint FirstVertex;
public List<SubMesh> subMeshes = new List<SubMesh>();
public class SubMesh
{
public uint size;
public uint offset;
}
public void GenerateSubMesh()
{
subMeshes.Clear();
SubMesh subMesh = new SubMesh();
subMesh.offset = 0;
subMesh.size = (uint)faces.Count;
subMeshes.Add(subMesh);
}
public int index = 0;
public int strip = 0x40;
public int displayFaceSize = 0;
public List<int> faces = new List<int>();
public override string ToString()
{
return "LOD Mesh " + index;
}
public List<int> getDisplayFace()
{
if ((strip >> 4) == 4)
{
displayFaceSize = faces.Count;
return faces;
}
else
{
List<int> f = new List<int>();
int startDirection = 1;
int p = 0;
int f1 = faces[p++];
int f2 = faces[p++];
int faceDirection = startDirection;
int f3;
do
{
f3 = faces[p++];
if (f3 == 0xFFFF)
{
f1 = faces[p++];
f2 = faces[p++];
faceDirection = startDirection;
}
else
{
faceDirection *= -1;
if ((f1 != f2) && (f2 != f3) && (f3 != f1))
{
if (faceDirection > 0)
{
f.Add(f3);
f.Add(f2);
f.Add(f1);
}
else
{
f.Add(f2);
f.Add(f3);
f.Add(f1);
}
}
f1 = f2;
f2 = f3;
}
} while (p < faces.Count);
displayFaceSize = f.Count;
return f;
}
}
}
public List<int> faces = new List<int>();
#region Methods
public void FlipUvsVertical()
{
foreach (Vertex v in vertices)
{
v.uv0 = new Vector2(v.uv0.X, 1 - v.uv0.Y);
}
}
public void FlipUvsHorizontal()
{
foreach (Vertex v in vertices)
{
v.uv0 = new Vector2(1 - v.uv0.X, v.uv0.Y);
}
}
public void CalculateTangentBitangent()
{
List<int> f = lodMeshes[DisplayLODIndex].getDisplayFace();
Vector3[] tanArray = new Vector3[vertices.Count];
Vector3[] bitanArray = new Vector3[vertices.Count];
CalculateTanBitanArrays(f, tanArray, bitanArray);
ApplyTanBitanArray(tanArray, bitanArray);
}
private void ApplyTanBitanArray(Vector3[] tanArray, Vector3[] bitanArray)
{
for (int i = 0; i < vertices.Count; i++)
{
Vertex v = vertices[i];
Vector3 newTan = tanArray[i];
Vector3 newBitan = bitanArray[i];
// The tangent and bitangent should be orthogonal to the normal.
// Bitangents are not calculated with a cross product to prevent flipped shading with mirrored normal maps.
v.tan = new Vector4(Vector3.Normalize(newTan - v.nrm * Vector3.Dot(v.nrm, newTan)), 1);
v.bitan = new Vector4(Vector3.Normalize(newBitan - v.nrm * Vector3.Dot(v.nrm, newBitan)), 1);
v.bitan *= -1;
}
}
private void CalculateTanBitanArrays(List<int> faces, Vector3[] tanArray, Vector3[] bitanArray)
{
for (int i = 0; i < lodMeshes[DisplayLODIndex].displayFaceSize; i += 3)
{
Vertex v1 = vertices[faces[i]];
Vertex v2 = vertices[faces[i + 1]];
Vertex v3 = vertices[faces[i + 2]];
bool UseUVLayer2 = false;
float x1 = v2.pos.X - v1.pos.X;
float x2 = v3.pos.X - v1.pos.X;
float y1 = v2.pos.Y - v1.pos.Y;
float y2 = v3.pos.Y - v1.pos.Y;
float z1 = v2.pos.Z - v1.pos.Z;
float z2 = v3.pos.Z - v1.pos.Z;
float s1, s2, t1, t2;
if (UseUVLayer2)
{
s1 = v2.uv1.X - v1.uv1.X;
s2 = v3.uv1.X - v1.uv1.X;
t1 = v2.uv1.Y - v1.uv1.Y;
t2 = v3.uv1.Y - v1.uv1.Y;
}
else
{
s1 = v2.uv0.X - v1.uv0.X;
s2 = v3.uv0.X - v1.uv0.X;
t1 = v2.uv0.Y - v1.uv0.Y;
t2 = v3.uv0.Y - v1.uv0.Y;
}
float div = (s1 * t2 - s2 * t1);
float r = 1.0f / div;
// Fix +/- infinity from division by 0.
if (r == float.PositiveInfinity || r == float.NegativeInfinity)
r = 1.0f;
float sX = t2 * x1 - t1 * x2;
float sY = t2 * y1 - t1 * y2;
float sZ = t2 * z1 - t1 * z2;
Vector3 s = new Vector3(sX, sY, sZ) * r;
float tX = s1 * x2 - s2 * x1;
float tY = s1 * y2 - s2 * y1;
float tZ = s1 * z2 - s2 * z1;
Vector3 t = new Vector3(tX, tY, tZ) * r;
// Prevents black tangents or bitangents due to having vertices with the same UV coordinates.
float delta = 0.00075f;
bool sameU, sameV;
if (UseUVLayer2)
{
sameU = (Math.Abs(v1.uv1.X - v2.uv1.X) < delta) && (Math.Abs(v2.uv1.X - v3.uv1.X) < delta);
sameV = (Math.Abs(v1.uv1.Y - v2.uv1.Y) < delta) && (Math.Abs(v2.uv1.Y - v3.uv1.Y) < delta);
}
else
{
sameU = (Math.Abs(v1.uv0.X - v2.uv0.X) < delta) && (Math.Abs(v2.uv0.X - v3.uv0.X) < delta);
sameV = (Math.Abs(v1.uv0.Y - v2.uv0.Y) < delta) && (Math.Abs(v2.uv0.Y - v3.uv0.Y) < delta);
}
if (sameU || sameV)
{
// Let's pick some arbitrary tangent vectors.
s = new Vector3(1, 0, 0);
t = new Vector3(0, 1, 0);
}
// Average tangents and bitangents.
tanArray[faces[i]] += s;
tanArray[faces[i + 1]] += s;
tanArray[faces[i + 2]] += s;
bitanArray[faces[i]] += t;
bitanArray[faces[i + 1]] += t;
bitanArray[faces[i + 2]] += t;
}
}
public void SmoothNormals()
{
Vector3[] normals = new Vector3[vertices.Count];
List<int> f = lodMeshes[DisplayLODIndex].getDisplayFace();
for (int i = 0; i < lodMeshes[DisplayLODIndex].displayFaceSize; i += 3)
{
Vertex v1 = vertices[f[i]];
Vertex v2 = vertices[f[i + 1]];
Vertex v3 = vertices[f[i + 2]];
Vector3 nrm = CalculateNormal(v1, v2, v3);
normals[f[i + 0]] += nrm;
normals[f[i + 1]] += nrm;
normals[f[i + 2]] += nrm;
}
for (int i = 0; i < normals.Length; i++)
vertices[i].nrm = normals[i].Normalized();
// Compare each vertex with all the remaining vertices. This might skip some.
for (int i = 0; i < vertices.Count; i++)
{
Vertex v = vertices[i];
for (int j = i + 1; j < vertices.Count; j++)
{
Vertex v2 = vertices[j];
if (v == v2)
continue;
float dis = (float)Math.Sqrt(Math.Pow(v.pos.X - v2.pos.X, 2) + Math.Pow(v.pos.Y - v2.pos.Y, 2) + Math.Pow(v.pos.Z - v2.pos.Z, 2));
if (dis <= 0f) // Extra smooth
{
Vector3 nn = ((v2.nrm + v.nrm) / 2).Normalized();
v.nrm = nn;
v2.nrm = nn;
}
}
}
}
public void CalculateNormals()
{
Vector3[] normals = new Vector3[vertices.Count];
for (int i = 0; i < normals.Length; i++)
normals[i] = new Vector3(0, 0, 0);
List<int> f = lodMeshes[DisplayLODIndex].getDisplayFace();
for (int i = 0; i < lodMeshes[DisplayLODIndex].displayFaceSize; i += 3)
{
Vertex v1 = vertices[f[i]];
Vertex v2 = vertices[f[i + 1]];
Vertex v3 = vertices[f[i + 2]];
Vector3 nrm = CalculateNormal(v1, v2, v3);
normals[f[i + 0]] += nrm * (nrm.Length / 2);
normals[f[i + 1]] += nrm * (nrm.Length / 2);
normals[f[i + 2]] += nrm * (nrm.Length / 2);
}
for (int i = 0; i < normals.Length; i++)
vertices[i].nrm = normals[i].Normalized();
}
private Vector3 CalculateNormal(Vertex v1, Vertex v2, Vertex v3)
{
Vector3 U = v2.pos - v1.pos;
Vector3 V = v3.pos - v1.pos;
// Don't normalize here, so surface area can be calculated.
return Vector3.Cross(U, V);
}
public void SetVertexColor(Vector4 intColor)
{
// (127, 127, 127, 255) is white.
foreach (Vertex v in vertices)
{
v.col = intColor;
}
}
#endregion
}
}

View file

@ -0,0 +1,371 @@
using System;
using System.IO;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Switch_Toolbox.Library.IO;
namespace Switch_Toolbox.Library
{
public class STGenericTexture : TreeNodeCustom
{
/// <summary>
/// Stores the <see cref="Surface"/> instances for arrays of images. Cubemaps use 6 surfaces.
/// </summary>
public List<Surface> surfaces = new List<Surface>();
/// <summary>
/// The total amount of surfaces for the texture.
/// </summary>
public int ArrayCount
{
get
{
return surfaces.Count;
}
}
/// <summary>
/// The width of the image in pixels
/// </summary>
public uint Width;
/// <summary>
/// The height of the image in pixels
/// </summary>
public uint Height;
/// <summary>
/// The <see cref="TEX_FORMAT"/> Format of the image.
/// </summary>
public TEX_FORMAT Format;
/// <summary>
/// The total amount of mip maps for the texture.
/// </summary>
public uint MipmapCount;
/// <summary>
/// A Surface contains mip levels of compressed/uncompressed texture data
/// </summary>
public class Surface
{
public List<byte[]> mipmaps = new List<byte[]>();
}
/// <summary>
/// Gets a <see cref="Bitmap"/> given an array and mip index.
/// </summary>
/// <param name="ArrayIndex">The index of the surface/array. Cubemaps will have 6</param>
/// <param name="MipLevel">The index of the mip level.</param>
/// <returns></returns>
public Bitmap GetBitmap(int ArrayIndex = 0, int MipLevel = 0)
{
if (surfaces.Count == 0)
throw new Exception($"Surfaces are empty on texture {Text}! Failed to get bitmap!");
return BitmapExtension.GetBitmap(DecodeBlock(surfaces[ArrayIndex].mipmaps[MipLevel], Height, Width, Format),
(int)Width, (int)Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
}
/// <summary>
/// Decodes a byte array of image data given the source image in bytes, width, height, and DXGI format.
/// </summary>
/// <param name="byte[]">The byte array of the image</param>
/// <param name="Width">The width of the image in pixels.</param>
/// <param name="Height">The height of the image in pixels.</param>
/// <param name=" DDS.DXGI_FORMAT">The image format.</param>
/// <returns>Returns a byte array of decoded data. </returns>
public static byte[] DecodeBlock(byte[] data, uint Width, uint Height, TEX_FORMAT Format)
{
if (data.Length <= 0)
throw new Exception($"Data is empty!");
if (Width <= 0)
throw new Exception($"Invalid width size {Width}!");
if (Height <= 0)
throw new Exception($"Invalid height size {Height}!");
if (Format == TEX_FORMAT.BC5_SNORM)
return ConvertBgraToRgba(DDSCompressor.DecompressBC5(data, (int)Width, (int)Height, true, true));
if (IsCompressed(Format))
return ConvertBgraToRgba(DDSCompressor.DecompressBlock(data, (int)Width, (int)Height, (DDS.DXGI_FORMAT)Format));
else
{
//If blue channel becomes first, do not swap them
if (Format.ToString().Contains("FORMAT_B"))
return DDSCompressor.DecodePixelBlock(data, (int)Width, (int)Height, (DDS.DXGI_FORMAT)Format);
else
return ConvertBgraToRgba(DDSCompressor.DecodePixelBlock(data, (int)Width, (int)Height, (DDS.DXGI_FORMAT)Format));
}
}
public void LoadDDS(string path)
{
SetNameFromPath(path);
DDS dds = new DDS();
LoadDDS(path);
Width = dds.header.width;
Height = dds.header.height;
Format = dds.GetFormat();
MipmapCount = dds.header.mipmapCount;
}
public void LoadTGA(string path)
{
SetNameFromPath(path);
Bitmap tga = Paloma.TargaImage.LoadTargaImage(path);
}
public void LoadBitmap(string path)
{
SetNameFromPath(path);
}
public void SaveASTC(string FileName, int SurfaceLevel = 0, int MipLevel = 0)
{
var blockDims = GetDims(Format);
ASTC atsc = new ASTC();
atsc.BlockDimX = (byte)blockDims.Item1;
atsc.BlockDimY = (byte)blockDims.Item2;
atsc.BlockDimZ = (byte)blockDims.Item3;
}
public void SaveTGA(string FileName, int SurfaceLevel = 0, int MipLevel = 0)
{
}
public void SaveBitMap(string FileName, int SurfaceLevel = 0, int MipLevel = 0)
{
Bitmap bitMap = GetBitmap(MipLevel, SurfaceLevel);
bitMap.Save(FileName);
bitMap.Dispose();
}
public void SaveDDS(string FileName, int SurfaceLevel = 0, int MipLevel = 0)
{
DDS dds = new DDS();
dds.header = new DDS.Header();
dds.header.width = Width;
dds.header.height = Height;
dds.header.mipmapCount = (uint)surfaces[SurfaceLevel].mipmaps.Count;
dds.header.pitchOrLinearSize = (uint)surfaces[SurfaceLevel].mipmaps[MipLevel].Length;
dds.SetFlags((DDS.DXGI_FORMAT)Format);
dds.Save(dds, FileName, surfaces);
}
public static Tuple<int, int, int> GetDims(TEX_FORMAT Format)
{
switch (Format)
{
case TEX_FORMAT.BC1_TYPELESS:
return Tuple.Create(4,4,4);
}
return Tuple.Create(4, 4, 4);
}
public static bool IsCompressed(TEX_FORMAT Format)
{
switch (Format)
{
case TEX_FORMAT.BC1_UNORM:
case TEX_FORMAT.BC1_UNORM_SRGB:
case TEX_FORMAT.BC1_TYPELESS:
case TEX_FORMAT.BC2_UNORM_SRGB:
case TEX_FORMAT.BC2_UNORM:
case TEX_FORMAT.BC2_TYPELESS:
case TEX_FORMAT.BC3_UNORM_SRGB:
case TEX_FORMAT.BC3_UNORM:
case TEX_FORMAT.BC3_TYPELESS:
case TEX_FORMAT.BC4_UNORM:
case TEX_FORMAT.BC4_TYPELESS:
case TEX_FORMAT.BC4_SNORM:
case TEX_FORMAT.BC5_UNORM:
case TEX_FORMAT.BC5_TYPELESS:
case TEX_FORMAT.BC5_SNORM:
return true;
default:
return false;
}
}
//DXGI formats are first, then ASTC formats after
public enum TEX_FORMAT : uint
{
UNKNOWN = 0,
R32G32B32A32_TYPELESS = 1,
R32G32B32A32_FLOAT = 2,
R32G32B32A32_UINT = 3,
R32G32B32A32_SINT = 4,
R32G32B32_TYPELESS = 5,
R32G32B32_FLOAT = 6,
R32G32B32_UINT = 7,
R32G32B32_SINT = 8,
R16G16B16A16_TYPELESS = 9,
R16G16B16A16_FLOAT = 10,
R16G16B16A16_UNORM = 11,
R16G16B16A16_UINT = 12,
R16G16B16A16_SNORM = 13,
R16G16B16A16_SINT = 14,
R32G32_TYPELESS = 15,
R32G32_FLOAT = 16,
R32G32_UINT = 17,
R32G32_SINT = 18,
R32G8X24_TYPELESS = 19,
D32_FLOAT_S8X24_UINT = 20,
R32_FLOAT_X8X24_TYPELESS = 21,
X32_TYPELESS_G8X24_UINT = 22,
R10G10B10A2_TYPELESS = 23,
R10G10B10A2_UNORM = 24,
R10G10B10A2_UINT = 25,
R11G11B10_FLOAT = 26,
R8G8B8A8_TYPELESS = 27,
R8G8B8A8_UNORM = 28,
R8G8B8A8_UNORM_SRGB = 29,
R8G8B8A8_UINT = 30,
R8G8B8A8_SNORM = 31,
R8G8B8A8_SINT = 32,
R16G16_TYPELESS = 33,
R16G16_FLOAT = 34,
R16G16_UNORM = 35,
R16G16_UINT = 36,
R16G16_SNORM = 37,
R16G16_SINT = 38,
R32_TYPELESS = 39,
D32_FLOAT = 40,
R32_FLOAT = 41,
R32_UINT = 42,
R32_SINT = 43,
R24G8_TYPELESS = 44,
D24_UNORM_S8_UINT = 45,
R24_UNORM_X8_TYPELESS = 46,
X24_TYPELESS_G8_UINT = 47,
R8G8_TYPELESS = 48,
R8G8_UNORM = 49,
R8G8_UINT = 50,
R8G8_SNORM = 51,
R8G8_SINT = 52,
R16_TYPELESS = 53,
R16_FLOAT = 54,
D16_UNORM = 55,
R16_UNORM = 56,
R16_UINT = 57,
R16_SNORM = 58,
R16_SINT = 59,
R8_TYPELESS = 60,
R8_UNORM = 61,
R8_UINT = 62,
R8_SNORM = 63,
R8_SINT = 64,
A8_UNORM = 65,
R1_UNORM = 66,
R9G9B9E5_SHAREDEXP = 67,
R8G8_B8G8_UNORM = 68,
G8R8_G8B8_UNORM = 69,
BC1_TYPELESS = 70,
BC1_UNORM = 71,
BC1_UNORM_SRGB = 72,
BC2_TYPELESS = 73,
BC2_UNORM = 74,
BC2_UNORM_SRGB = 75,
BC3_TYPELESS = 76,
BC3_UNORM = 77,
BC3_UNORM_SRGB = 78,
BC4_TYPELESS = 79,
BC4_UNORM = 80,
BC4_SNORM = 81,
BC5_TYPELESS = 82,
BC5_UNORM = 83,
BC5_SNORM = 84,
B5G6R5_UNORM = 85,
B5G5R5A1_UNORM = 86,
B8G8R8A8_UNORM = 87,
B8G8R8X8_UNORM = 88,
R10G10B10_XR_BIAS_A2_UNORM = 89,
B8G8R8A8_TYPELESS = 90,
B8G8R8A8_UNORM_SRGB = 91,
B8G8R8X8_TYPELESS = 92,
B8G8R8X8_UNORM_SRGB = 93,
BC6H_TYPELESS = 94,
BC6H_UF16 = 95,
BC6H_SF16 = 96,
BC7_TYPELESS = 97,
BC7_UNORM = 98,
BC7_UNORM_SRGB = 99,
AYUV = 100,
Y410 = 101,
Y416 = 102,
NV12 = 103,
P010 = 104,
P016 = 105,
Format_420_OPAQUE = 106,
YUY2 = 107,
Y210 = 108,
Y216 = 109,
NV11 = 110,
AI44 = 111,
IA44 = 112,
P8 = 113,
A8P8 = 114,
B4G4R4A4_UNORM = 115,
P208 = 130,
V208 = 131,
V408 = 132,
ASTC4x4 = 200,
ASTC5x4 = 201,
ASTC5x5 = 202,
ASTC6x5 = 203,
ASTC6x6 = 204,
ASTC8x5 = 205,
ASTC8x6 = 206,
ASTC8x8 = 207,
ASTC10x5 = 208,
ASTC10x6 = 209,
ASTC10x8 = 210,
ASTC10x10 = 211,
ASTC12x10 = 212,
ASTC12x12 = 213,
FORCE_UINT = 0xFFFFFFFF
}
public STGenericTexture()
{
}
public override void OnClick(TreeView treeView)
{
}
private void SetNameFromPath(string path)
{
//Replace extensions manually. This is because using the
//GetFileNameWithoutExtension function can remove .0, .1, texture names.
var name = Path.GetFileName(path);
name.Replace(".tga", string.Empty);
name.Replace(".png", string.Empty);
name.Replace(".jpg", string.Empty);
name.Replace(".dds", string.Empty);
name.Replace(".jpeg", string.Empty);
name.Replace(".tiff", string.Empty);
name.Replace(".gif", string.Empty);
name.Replace(".dds2", string.Empty);
name.Replace(".jpe", string.Empty);
name.Replace(".jfif", string.Empty);
name.Replace(".bmp", string.Empty);
name.Replace(".pdn", string.Empty);
name.Replace(".psd", string.Empty);
name.Replace(".hdr", string.Empty);
Text = name;
}
private static byte[] ConvertBgraToRgba(byte[] bytes)
{
for (int i = 0; i < bytes.Length; i += 4)
{
var temp = bytes[i];
bytes[i] = bytes[i + 2];
bytes[i + 2] = temp;
}
return bytes;
}
}
}

View file

@ -57,8 +57,8 @@ namespace Switch_Toolbox.Library.IO
} }
} }
File.WriteAllBytes(FileName, data); File.WriteAllBytes(FileName, data);
MessageBox.Show($"File has been saved to {FileName}");
Cursor.Current = Cursors.Default; Cursor.Current = Cursors.Default;
MessageBox.Show($"File has been saved to {FileName}");
} }
} }
public class STFileLoader public class STFileLoader

View file

@ -24,439 +24,6 @@ namespace Switch_Toolbox.Library.Rendering
UInt16 = 1, UInt16 = 1,
UInt32 = 2, UInt32 = 2,
} }
public class STGenericObject : GenericObject
{
public override void OnClick(TreeView treeView)
{
}
}
public abstract class STGenericModel : GenericModel
{
public override void OnClick(TreeView treeView)
{
}
}
public abstract class GenericModel : TreeNode
{
public abstract void OnClick(TreeView treeview);
}
public class STGenericMaterial : GenericMaterial
{
public override void OnClick(TreeView treeView)
{
}
}
public class STGenericMatTexture
{
public int mapMode = 0;
public int wrapModeS = 1;
public int wrapModeT = 1;
public int wrapModeW = 1; //Used for 3D textures
public int minFilter = 3;
public int magFilter = 2;
public int mipDetail = 6;
public string Name;
public TextureType Type;
//An enum for the assumed texture type by sampler
//Many games have a consistant type of samplers and type. _a0 for diffuse, _n0 for normal, ect
public enum TextureType
{
Unknown = 0,
Diffuse = 1,
Normal = 2,
Specular = 3,
Emission = 4,
DiffuseLayer2 = 5,
TeamColor = 6,
Transparency = 7,
Shadow = 8,
AO = 9,
Light = 10,
Roughness = 11,
Metalness = 12,
MRA = 13, //Combined pbr texture HAL uses for KSA
SphereMap = 14,
SubSurfaceScattering = 15,
}
public static readonly Dictionary<int, TextureMinFilter> minfilter = new Dictionary<int, TextureMinFilter>()
{
{ 0x00, TextureMinFilter.LinearMipmapLinear},
{ 0x01, TextureMinFilter.Nearest},
{ 0x02, TextureMinFilter.Linear},
{ 0x03, TextureMinFilter.NearestMipmapLinear},
};
public static readonly Dictionary<int, TextureMagFilter> magfilter = new Dictionary<int, TextureMagFilter>()
{
{ 0x00, TextureMagFilter.Linear},
{ 0x01, TextureMagFilter.Nearest},
{ 0x02, TextureMagFilter.Linear}
};
public static Dictionary<int, TextureWrapMode> wrapmode = new Dictionary<int, TextureWrapMode>(){
{ 0x00, TextureWrapMode.Repeat},
{ 0x01, TextureWrapMode.MirroredRepeat},
{ 0x02, TextureWrapMode.ClampToEdge},
{ 0x03, TextureWrapMode.MirroredRepeat},
};
}
public abstract class GenericMaterial : TreeNode
{
public abstract void OnClick(TreeView treeview);
public List<STGenericMatTexture> TextureMaps = new List<STGenericMatTexture>();
}
public abstract class GenericObject : TreeNode
{
public abstract void OnClick(TreeView treeview);
public bool HasPos;
public bool HasNrm;
public bool HasUv0;
public bool HasUv1;
public bool HasUv2;
public bool HasWeights;
public bool HasIndices;
public bool HasBitans;
public bool HasTans;
public bool HasVertColors;
public int MaxSkinInfluenceCount;
public string ObjectName;
public int BoneIndex;
public int MaterialIndex;
public int VertexBufferIndex;
public int DisplayLODIndex;
public int Offset;
public int GetMaxSkinInfluenceCount()
{
return vertices.Max(t => t.boneIds.Count);
}
public Vector3 GetOrigin()
{
Vector3 pos = Vector3.Zero;
foreach (Vertex vert in vertices)
{
}
return pos;
}
public List<string[]> bones = new List<string[]>();
public List<float[]> weightsT = new List<float[]>();
public List<string> boneList = new List<string>();
public List<Vertex> vertices = new List<Vertex>();
public List<LOD_Mesh> lodMeshes = new List<LOD_Mesh>();
public class LOD_Mesh
{
public STPolygonType PrimitiveType = STPolygonType.Triangle;
public STIndexFormat IndexFormat = STIndexFormat.UInt16;
public uint FirstVertex;
public List<SubMesh> subMeshes = new List<SubMesh>();
public class SubMesh
{
public uint size;
public uint offset;
}
public void GenerateSubMesh()
{
subMeshes.Clear();
SubMesh subMesh = new SubMesh();
subMesh.offset = 0;
subMesh.size = (uint)faces.Count;
subMeshes.Add(subMesh);
}
public int index = 0;
public int strip = 0x40;
public int displayFaceSize = 0;
public List<int> faces = new List<int>();
public override string ToString()
{
return "LOD Mesh " + index;
}
public List<int> getDisplayFace()
{
if ((strip >> 4) == 4)
{
displayFaceSize = faces.Count;
return faces;
}
else
{
List<int> f = new List<int>();
int startDirection = 1;
int p = 0;
int f1 = faces[p++];
int f2 = faces[p++];
int faceDirection = startDirection;
int f3;
do
{
f3 = faces[p++];
if (f3 == 0xFFFF)
{
f1 = faces[p++];
f2 = faces[p++];
faceDirection = startDirection;
}
else
{
faceDirection *= -1;
if ((f1 != f2) && (f2 != f3) && (f3 != f1))
{
if (faceDirection > 0)
{
f.Add(f3);
f.Add(f2);
f.Add(f1);
}
else
{
f.Add(f2);
f.Add(f3);
f.Add(f1);
}
}
f1 = f2;
f2 = f3;
}
} while (p < faces.Count);
displayFaceSize = f.Count;
return f;
}
}
}
public List<int> faces = new List<int>();
#region Methods
public void FlipUvsVertical()
{
foreach (Vertex v in vertices)
{
v.uv0 = new Vector2(v.uv0.X, 1 - v.uv0.Y);
}
}
public void FlipUvsHorizontal()
{
foreach (Vertex v in vertices)
{
v.uv0 = new Vector2(1 - v.uv0.X, v.uv0.Y);
}
}
public void CalculateTangentBitangent()
{
List<int> f = lodMeshes[DisplayLODIndex].getDisplayFace();
Vector3[] tanArray = new Vector3[vertices.Count];
Vector3[] bitanArray = new Vector3[vertices.Count];
CalculateTanBitanArrays(f, tanArray, bitanArray);
ApplyTanBitanArray(tanArray, bitanArray);
}
private void ApplyTanBitanArray(Vector3[] tanArray, Vector3[] bitanArray)
{
for (int i = 0; i < vertices.Count; i++)
{
Vertex v = vertices[i];
Vector3 newTan = tanArray[i];
Vector3 newBitan = bitanArray[i];
// The tangent and bitangent should be orthogonal to the normal.
// Bitangents are not calculated with a cross product to prevent flipped shading with mirrored normal maps.
v.tan = new Vector4(Vector3.Normalize(newTan - v.nrm * Vector3.Dot(v.nrm, newTan)), 1);
v.bitan = new Vector4(Vector3.Normalize(newBitan - v.nrm * Vector3.Dot(v.nrm, newBitan)), 1);
v.bitan *= -1;
}
}
private void CalculateTanBitanArrays(List<int> faces, Vector3[] tanArray, Vector3[] bitanArray)
{
for (int i = 0; i < lodMeshes[DisplayLODIndex].displayFaceSize; i += 3)
{
Vertex v1 = vertices[faces[i]];
Vertex v2 = vertices[faces[i + 1]];
Vertex v3 = vertices[faces[i + 2]];
bool UseUVLayer2 = false;
float x1 = v2.pos.X - v1.pos.X;
float x2 = v3.pos.X - v1.pos.X;
float y1 = v2.pos.Y - v1.pos.Y;
float y2 = v3.pos.Y - v1.pos.Y;
float z1 = v2.pos.Z - v1.pos.Z;
float z2 = v3.pos.Z - v1.pos.Z;
float s1, s2, t1, t2;
if (UseUVLayer2)
{
s1 = v2.uv1.X - v1.uv1.X;
s2 = v3.uv1.X - v1.uv1.X;
t1 = v2.uv1.Y - v1.uv1.Y;
t2 = v3.uv1.Y - v1.uv1.Y;
}
else
{
s1 = v2.uv0.X - v1.uv0.X;
s2 = v3.uv0.X - v1.uv0.X;
t1 = v2.uv0.Y - v1.uv0.Y;
t2 = v3.uv0.Y - v1.uv0.Y;
}
float div = (s1 * t2 - s2 * t1);
float r = 1.0f / div;
// Fix +/- infinity from division by 0.
if (r == float.PositiveInfinity || r == float.NegativeInfinity)
r = 1.0f;
float sX = t2 * x1 - t1 * x2;
float sY = t2 * y1 - t1 * y2;
float sZ = t2 * z1 - t1 * z2;
Vector3 s = new Vector3(sX, sY, sZ) * r;
float tX = s1 * x2 - s2 * x1;
float tY = s1 * y2 - s2 * y1;
float tZ = s1 * z2 - s2 * z1;
Vector3 t = new Vector3(tX, tY, tZ) * r;
// Prevents black tangents or bitangents due to having vertices with the same UV coordinates.
float delta = 0.00075f;
bool sameU, sameV;
if (UseUVLayer2)
{
sameU = (Math.Abs(v1.uv1.X - v2.uv1.X) < delta) && (Math.Abs(v2.uv1.X - v3.uv1.X) < delta);
sameV = (Math.Abs(v1.uv1.Y - v2.uv1.Y) < delta) && (Math.Abs(v2.uv1.Y - v3.uv1.Y) < delta);
}
else
{
sameU = (Math.Abs(v1.uv0.X - v2.uv0.X) < delta) && (Math.Abs(v2.uv0.X - v3.uv0.X) < delta);
sameV = (Math.Abs(v1.uv0.Y - v2.uv0.Y) < delta) && (Math.Abs(v2.uv0.Y - v3.uv0.Y) < delta);
}
if (sameU || sameV)
{
// Let's pick some arbitrary tangent vectors.
s = new Vector3(1, 0, 0);
t = new Vector3(0, 1, 0);
}
// Average tangents and bitangents.
tanArray[faces[i]] += s;
tanArray[faces[i + 1]] += s;
tanArray[faces[i + 2]] += s;
bitanArray[faces[i]] += t;
bitanArray[faces[i + 1]] += t;
bitanArray[faces[i + 2]] += t;
}
}
public void SmoothNormals()
{
Vector3[] normals = new Vector3[vertices.Count];
List<int> f = lodMeshes[DisplayLODIndex].getDisplayFace();
for (int i = 0; i < lodMeshes[DisplayLODIndex].displayFaceSize; i += 3)
{
Vertex v1 = vertices[f[i]];
Vertex v2 = vertices[f[i + 1]];
Vertex v3 = vertices[f[i + 2]];
Vector3 nrm = CalculateNormal(v1, v2, v3);
normals[f[i + 0]] += nrm;
normals[f[i + 1]] += nrm;
normals[f[i + 2]] += nrm;
}
for (int i = 0; i < normals.Length; i++)
vertices[i].nrm = normals[i].Normalized();
// Compare each vertex with all the remaining vertices. This might skip some.
for (int i = 0; i < vertices.Count; i++)
{
Vertex v = vertices[i];
for (int j = i + 1; j < vertices.Count; j++)
{
Vertex v2 = vertices[j];
if (v == v2)
continue;
float dis = (float)Math.Sqrt(Math.Pow(v.pos.X - v2.pos.X, 2) + Math.Pow(v.pos.Y - v2.pos.Y, 2) + Math.Pow(v.pos.Z - v2.pos.Z, 2));
if (dis <= 0f) // Extra smooth
{
Vector3 nn = ((v2.nrm + v.nrm) / 2).Normalized();
v.nrm = nn;
v2.nrm = nn;
}
}
}
}
public void CalculateNormals()
{
Vector3[] normals = new Vector3[vertices.Count];
for (int i = 0; i < normals.Length; i++)
normals[i] = new Vector3(0, 0, 0);
List<int> f = lodMeshes[DisplayLODIndex].getDisplayFace();
for (int i = 0; i < lodMeshes[DisplayLODIndex].displayFaceSize; i += 3)
{
Vertex v1 = vertices[f[i]];
Vertex v2 = vertices[f[i + 1]];
Vertex v3 = vertices[f[i + 2]];
Vector3 nrm = CalculateNormal(v1, v2, v3);
normals[f[i + 0]] += nrm * (nrm.Length / 2);
normals[f[i + 1]] += nrm * (nrm.Length / 2);
normals[f[i + 2]] += nrm * (nrm.Length / 2);
}
for (int i = 0; i < normals.Length; i++)
vertices[i].nrm = normals[i].Normalized();
}
private Vector3 CalculateNormal(Vertex v1, Vertex v2, Vertex v3)
{
Vector3 U = v2.pos - v1.pos;
Vector3 V = v3.pos - v1.pos;
// Don't normalize here, so surface area can be calculated.
return Vector3.Cross(U, V);
}
public void SetVertexColor(Vector4 intColor)
{
// (127, 127, 127, 255) is white.
foreach (Vertex v in vertices)
{
v.col = intColor;
}
}
#endregion
}
public class Vertex public class Vertex
{ {

View file

@ -62,6 +62,8 @@ namespace Switch_Toolbox.Library
public static bool renderNormalMap = true; public static bool renderNormalMap = true;
public static bool renderVertColor = true; public static bool renderVertColor = true;
public static bool renderBfresPbr = false; public static bool renderBfresPbr = false;
public static bool renderTevColors = true;
public static bool renderMatColors = true;
public static bool stereoscopy = false; public static bool stereoscopy = false;
public static bool UseLegacyGL = false; public static bool UseLegacyGL = false;
@ -77,6 +79,10 @@ namespace Switch_Toolbox.Library
public static float CameraFar = 100000.0f; public static float CameraFar = 100000.0f;
public static ActiveGame activeGame = ActiveGame.SMO; public static ActiveGame activeGame = ActiveGame.SMO;
public static string ProgramVersion = "0.0.0";
public static string CompileDate = "0/0/0000";
public static string CommitInfo = "";
public enum ActiveGame public enum ActiveGame
{ {
SMO, SMO,

View file

@ -43,8 +43,9 @@
<Reference Include="CsvHelper, Version=8.0.0.0, Culture=neutral, PublicKeyToken=8c4959082be5c823, processorArchitecture=MSIL"> <Reference Include="CsvHelper, Version=8.0.0.0, Culture=neutral, PublicKeyToken=8c4959082be5c823, processorArchitecture=MSIL">
<HintPath>..\Switch_Toolbox\Lib\CsvHelper.dll</HintPath> <HintPath>..\Switch_Toolbox\Lib\CsvHelper.dll</HintPath>
</Reference> </Reference>
<Reference Include="DirectXTex"> <Reference Include="DirectXTex, Version=0.0.0.0, Culture=neutral, processorArchitecture=AMD64">
<HintPath>..\..\Switch-Toolbox\Switch_Toolbox\Lib\DirectXTex.dll</HintPath> <SpecificVersion>False</SpecificVersion>
<HintPath>..\Switch_Toolbox\Lib\DirectXTex.dll</HintPath>
</Reference> </Reference>
<Reference Include="K4os.Compression.LZ4, Version=1.1.0.0, Culture=neutral, PublicKeyToken=27d14aecb5186925, processorArchitecture=MSIL"> <Reference Include="K4os.Compression.LZ4, Version=1.1.0.0, Culture=neutral, PublicKeyToken=27d14aecb5186925, processorArchitecture=MSIL">
<HintPath>..\Switch_Toolbox\Lib\K4os.Compression.LZ4.dll</HintPath> <HintPath>..\Switch_Toolbox\Lib\K4os.Compression.LZ4.dll</HintPath>
@ -113,8 +114,14 @@
<Compile Include="FileFormats\ANIM.cs" /> <Compile Include="FileFormats\ANIM.cs" />
<Compile Include="FileFormats\Assimp\Assimp.cs" /> <Compile Include="FileFormats\Assimp\Assimp.cs" />
<Compile Include="FileFormats\Assimp\AssimpHelper.cs" /> <Compile Include="FileFormats\Assimp\AssimpHelper.cs" />
<Compile Include="FileFormats\ASTC.cs" />
<Compile Include="FileFormats\DDS.cs" /> <Compile Include="FileFormats\DDS.cs" />
<Compile Include="FileFormats\DDSCompressor.cs" /> <Compile Include="FileFormats\DDSCompressor.cs" />
<Compile Include="Externals\TargaImage.cs" />
<Compile Include="Generics\GenericMaterial.cs" />
<Compile Include="Generics\GenericMatTexture.cs" />
<Compile Include="Generics\GenericModel.cs" />
<Compile Include="Generics\GenericObject.cs" />
<Compile Include="GUI Custom\ListViewCustom.cs"> <Compile Include="GUI Custom\ListViewCustom.cs">
<SubType>Component</SubType> <SubType>Component</SubType>
</Compile> </Compile>
@ -147,6 +154,7 @@
</Compile> </Compile>
<Compile Include="Helpers\TextureHelper.cs" /> <Compile Include="Helpers\TextureHelper.cs" />
<Compile Include="Interfaces\IMenuExtension.cs" /> <Compile Include="Interfaces\IMenuExtension.cs" />
<Compile Include="Generics\GenericTexture.cs" />
<Compile Include="Plugin\GenericPluginLoader.cs" /> <Compile Include="Plugin\GenericPluginLoader.cs" />
<Compile Include="GUI Custom\DockContentST.cs"> <Compile Include="GUI Custom\DockContentST.cs">
<SubType>Form</SubType> <SubType>Form</SubType>
@ -359,6 +367,9 @@
<ItemGroup> <ItemGroup>
<None Include="Resources\normalMapSphere.png" /> <None Include="Resources\normalMapSphere.png" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<WCFMetadata Include="Connected Services\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\Fody.3.2.9\build\Fody.targets" Condition="Exists('..\packages\Fody.3.2.9\build\Fody.targets')" /> <Import Project="..\packages\Fody.3.2.9\build\Fody.targets" Condition="Exists('..\packages\Fody.3.2.9\build\Fody.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">

View file

@ -33,6 +33,23 @@ namespace Switch_Toolbox.Library
{ {
return new Vector4(v.X, v.Y, v.Z, v.W); return new Vector4(v.X, v.Y, v.Z, v.W);
} }
public static Matrix3x4 ToMat3x4(Syroot.Maths.Matrix3x4 mat4)
{
Matrix3x4 mat = new Matrix3x4();
mat.M11 = mat4.M11;
mat.M12 = mat4.M12;
mat.M13 = mat4.M13;
mat.M14 = mat4.M14;
mat.M21 = mat4.M21;
mat.M22 = mat4.M22;
mat.M23 = mat4.M23;
mat.M24 = mat4.M24;
mat.M31 = mat4.M31;
mat.M32 = mat4.M32;
mat.M33 = mat4.M33;
mat.M34 = mat4.M34;
return mat;
}
public static byte[] CombineByteArray(params byte[][] arrays) public static byte[] CombineByteArray(params byte[][] arrays)
{ {
byte[] rv = new byte[arrays.Sum(a => a.Length)]; byte[] rv = new byte[arrays.Sum(a => a.Length)];
@ -56,7 +73,7 @@ namespace Switch_Toolbox.Library
{ {
if (strings.Contains(oldString)) if (strings.Contains(oldString))
{ {
oldString += i.ToString(); oldString = $"{oldString}_0{i++}";
if (strings.Contains(oldString)) if (strings.Contains(oldString))
RenameDuplicateString(strings, oldString); RenameDuplicateString(strings, oldString);

View file

@ -1,19 +1,19 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<configuration> <configuration>
<runtime> <runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly> <dependentAssembly>
<assemblyIdentity name="OpenTK" publicKeyToken="bad199fe84eb3df4" culture="neutral" /> <assemblyIdentity name="OpenTK" publicKeyToken="bad199fe84eb3df4" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" /> <bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0"/>
</dependentAssembly> </dependentAssembly>
<dependentAssembly> <dependentAssembly>
<assemblyIdentity name="LZ4pn" publicKeyToken="62e1b5ec1eec9bdd" culture="neutral" /> <assemblyIdentity name="LZ4pn" publicKeyToken="62e1b5ec1eec9bdd" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-1.0.10.93" newVersion="1.0.10.93" /> <bindingRedirect oldVersion="0.0.0.0-1.0.10.93" newVersion="1.0.10.93"/>
</dependentAssembly> </dependentAssembly>
<dependentAssembly> <dependentAssembly>
<assemblyIdentity name="K4os.Hash.xxHash" publicKeyToken="32cd54395057cec3" culture="neutral" /> <assemblyIdentity name="K4os.Hash.xxHash" publicKeyToken="32cd54395057cec3" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-1.0.5.0" newVersion="1.0.5.0" /> <bindingRedirect oldVersion="0.0.0.0-1.0.5.0" newVersion="1.0.5.0"/>
</dependentAssembly> </dependentAssembly>
</assemblyBinding> </assemblyBinding>
</runtime> </runtime>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" /></startup></configuration> <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/></startup></configuration>

Binary file not shown.

Binary file not shown.

5763
Syroot.NintenTools.Bfres.xml Normal file

File diff suppressed because it is too large Load diff