mirror of
https://github.com/KillzXGaming/Switch-Toolbox
synced 2024-11-22 20:43:09 +00:00
Tons of stuff!
- Compress BC1 with alpha. - Add GFPAK rebuilding. - Fix some lag issues with bntx textures loading - Fix saving multiple files. - Support DDS cubemap importing - Support rigged DAE/FBX files. - Support animation playing thanks to smash forge. - Some minor stuff to prepare custom animations. - Many bug fixes.
This commit is contained in:
parent
029f350526
commit
50ea4183ef
84 changed files with 26073 additions and 496 deletions
22
.gitignore
vendored
22
.gitignore
vendored
|
@ -1,27 +1,5 @@
|
||||||
|
|
||||||
.vs/Switch_Toolbox/v15/Server/sqlite3/db.lock
|
.vs/Switch_Toolbox/v15/Server/sqlite3/db.lock
|
||||||
*.suo
|
|
||||||
*.user
|
|
||||||
*.userosscache
|
|
||||||
*.sln.docstates
|
|
||||||
*.resources
|
*.resources
|
||||||
Debug/
|
Debug/
|
||||||
Release/
|
Release/
|
||||||
.vs/Switch_Toolbox/v15/.suo
|
|
||||||
.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide
|
|
||||||
.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide-shm
|
|
||||||
.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide-wal
|
|
||||||
.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide-wal
|
|
||||||
.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide-shm
|
|
||||||
.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide
|
|
||||||
.vs/Switch_Toolbox/v15/.suo
|
|
||||||
.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide-wal
|
|
||||||
.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide-shm
|
|
||||||
.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide
|
|
||||||
.vs/Switch_Toolbox/v15/.suo
|
|
||||||
*.ide
|
|
||||||
.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide-wal
|
|
||||||
.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide-shm
|
|
||||||
.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide
|
|
||||||
.vs/Switch_Toolbox/v15/.suo
|
|
||||||
.vs/Switch_Toolbox/v15/.suo
|
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -46,7 +46,7 @@ namespace FirstPlugin
|
||||||
this.eitorRoot = value;
|
this.eitorRoot = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private void SaveFile()
|
public void SaveFile()
|
||||||
{
|
{
|
||||||
List<IFileFormat> formats = new List<IFileFormat>();
|
List<IFileFormat> formats = new List<IFileFormat>();
|
||||||
formats.Add(this);
|
formats.Add(this);
|
||||||
|
@ -112,7 +112,6 @@ namespace FirstPlugin
|
||||||
bfres = new BFRESRender();
|
bfres = new BFRESRender();
|
||||||
bfres.ResFileNode = new ResourceFile(this);
|
bfres.ResFileNode = new ResourceFile(this);
|
||||||
bfres.ResFileNode.BFRESRender = bfres;
|
bfres.ResFileNode.BFRESRender = bfres;
|
||||||
bfres.SaveFile = SaveFile;
|
|
||||||
|
|
||||||
EditorRoot = bfres.ResFileNode;
|
EditorRoot = bfres.ResFileNode;
|
||||||
|
|
||||||
|
|
|
@ -193,8 +193,12 @@ namespace Bfres.Structs
|
||||||
string Magic = f.ReadMagic(0, 4);
|
string Magic = f.ReadMagic(0, 4);
|
||||||
if (Magic == "BNTX")
|
if (Magic == "BNTX")
|
||||||
{
|
{
|
||||||
BinaryTextureContainer bntxTreeNode = new BinaryTextureContainer(extfile.Data, Name, resFile.Name);
|
BNTX bntx = new BNTX();
|
||||||
Nodes["EXT"].Nodes.Add(bntxTreeNode);
|
bntx.Data = extfile.Data;
|
||||||
|
bntx.FileName = Name;
|
||||||
|
bntx.Load();
|
||||||
|
bntx.IFileInfo.InArchive = true;
|
||||||
|
Nodes["EXT"].Nodes.Add(bntx.EditorRoot);
|
||||||
}
|
}
|
||||||
else if (Magic == "FSHA")
|
else if (Magic == "FSHA")
|
||||||
{
|
{
|
||||||
|
@ -232,7 +236,7 @@ namespace Bfres.Structs
|
||||||
}
|
}
|
||||||
private void Save(object sender, EventArgs args)
|
private void Save(object sender, EventArgs args)
|
||||||
{
|
{
|
||||||
BFRESRender.SaveFile();
|
((BFRES)FileHandler).SaveFile();
|
||||||
}
|
}
|
||||||
private void Rename(object sender, EventArgs args)
|
private void Rename(object sender, EventArgs args)
|
||||||
{
|
{
|
||||||
|
@ -292,7 +296,7 @@ namespace Bfres.Structs
|
||||||
Nodes.Add(FSKA);
|
Nodes.Add(FSKA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public class FskaFolder : TreeNodeCustom
|
public class FskaFolder : AnimationGroupNode
|
||||||
{
|
{
|
||||||
public FskaFolder()
|
public FskaFolder()
|
||||||
{
|
{
|
||||||
|
@ -319,10 +323,10 @@ namespace Bfres.Structs
|
||||||
Nodes.Add(skeletonAnim);
|
Nodes.Add(skeletonAnim);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public override void OnClick(TreeView treeView)
|
/* public override void OnClick(TreeView treeView)
|
||||||
{
|
{
|
||||||
FormLoader.LoadEditor(this, Text);
|
FormLoader.LoadEditor(this, Text);
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
public class FmdlFolder : TreeNodeCustom
|
public class FmdlFolder : TreeNodeCustom
|
||||||
{
|
{
|
||||||
|
@ -631,36 +635,34 @@ namespace Bfres.Structs
|
||||||
|
|
||||||
bone.Text = bonean.Text;
|
bone.Text = bonean.Text;
|
||||||
|
|
||||||
|
|
||||||
for (int Frame = 0; Frame < ska.FrameCount; Frame++)
|
for (int Frame = 0; Frame < ska.FrameCount; Frame++)
|
||||||
{
|
{
|
||||||
|
|
||||||
//Set base/start values for bones.
|
|
||||||
//Note. BOTW doesn't use base values as it uses havok engine. Need to add option to disable these
|
|
||||||
if (Frame == 0)
|
if (Frame == 0)
|
||||||
{
|
{
|
||||||
if (bn.FlagsBase.HasFlag(BoneAnimFlagsBase.Scale))
|
if (bn.FlagsBase.HasFlag(BoneAnimFlagsBase.Scale))
|
||||||
{
|
{
|
||||||
bone.XSCA.Keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.sca.X });
|
bone.XSCA.Keys.Add(new KeyFrame() { Frame = 0, Value = bonean.sca.X });
|
||||||
bone.YSCA.Keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.sca.Y });
|
bone.YSCA.Keys.Add(new KeyFrame() { Frame = 0, Value = bonean.sca.Y });
|
||||||
bone.ZSCA.Keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.sca.Z });
|
bone.ZSCA.Keys.Add(new KeyFrame() { Frame = 0, Value = bonean.sca.Z });
|
||||||
}
|
}
|
||||||
if (bn.FlagsBase.HasFlag(BoneAnimFlagsBase.Rotate))
|
if (bn.FlagsBase.HasFlag(BoneAnimFlagsBase.Rotate))
|
||||||
{
|
{
|
||||||
bone.XROT.Keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.rot.X });
|
bone.XROT.Keys.Add(new KeyFrame() { Frame = 0, Value = bonean.rot.X });
|
||||||
bone.YROT.Keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.rot.Y });
|
bone.YROT.Keys.Add(new KeyFrame() { Frame = 0, Value = bonean.rot.Y });
|
||||||
bone.ZROT.Keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.rot.Z });
|
bone.ZROT.Keys.Add(new KeyFrame() { Frame = 0, Value = bonean.rot.Z });
|
||||||
bone.WROT.Keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.rot.W });
|
bone.WROT.Keys.Add(new KeyFrame() { Frame = 0, Value = bonean.rot.W });
|
||||||
}
|
}
|
||||||
if (bn.FlagsBase.HasFlag(BoneAnimFlagsBase.Translate))
|
if (bn.FlagsBase.HasFlag(BoneAnimFlagsBase.Translate))
|
||||||
{
|
{
|
||||||
bone.XPOS.Keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.pos.X });
|
bone.XPOS.Keys.Add(new KeyFrame() { Frame = 0, Value = bonean.pos.X });
|
||||||
bone.YPOS.Keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.pos.Y });
|
bone.YPOS.Keys.Add(new KeyFrame() { Frame = 0, Value = bonean.pos.Y });
|
||||||
bone.ZPOS.Keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.pos.Z });
|
bone.ZPOS.Keys.Add(new KeyFrame() { Frame = 0, Value = bonean.pos.Z });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach (FSKATrack track in bonean.tracks)
|
foreach (FSKATrack track in bonean.tracks)
|
||||||
{
|
{
|
||||||
Animation.KeyFrame frame = new Animation.KeyFrame();
|
KeyFrame frame = new KeyFrame();
|
||||||
frame.InterType = Animation.InterpolationType.HERMITE;
|
frame.InterType = Animation.InterpolationType.HERMITE;
|
||||||
frame.Frame = Frame;
|
frame.Frame = Frame;
|
||||||
|
|
||||||
|
@ -668,8 +670,6 @@ namespace Bfres.Structs
|
||||||
FSKAKey right = track.GetRight(Frame);
|
FSKAKey right = track.GetRight(Frame);
|
||||||
float value;
|
float value;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
value = Animation.Hermite(Frame, left.frame, right.frame, 0, 0, left.unk1, right.unk1);
|
value = Animation.Hermite(Frame, left.frame, right.frame, 0, 0, left.unk1, right.unk1);
|
||||||
|
|
||||||
// interpolate the value and apply
|
// interpolate the value and apply
|
||||||
|
@ -711,11 +711,8 @@ namespace Bfres.Structs
|
||||||
{
|
{
|
||||||
Text = b.Name;
|
Text = b.Name;
|
||||||
|
|
||||||
if (b.BaseData.Scale != Syroot.Maths.Vector3F.Zero)
|
|
||||||
sca = new Vector3(b.BaseData.Scale.X, b.BaseData.Scale.Y, b.BaseData.Scale.Z);
|
sca = new Vector3(b.BaseData.Scale.X, b.BaseData.Scale.Y, b.BaseData.Scale.Z);
|
||||||
if (b.BaseData.Rotate != Syroot.Maths.Vector4F.Zero)
|
|
||||||
rot = new Vector4(b.BaseData.Rotate.X, b.BaseData.Rotate.Y, b.BaseData.Rotate.Z, b.BaseData.Rotate.W);
|
rot = new Vector4(b.BaseData.Rotate.X, b.BaseData.Rotate.Y, b.BaseData.Rotate.Z, b.BaseData.Rotate.W);
|
||||||
if (b.BaseData.Translate != Syroot.Maths.Vector3F.Zero)
|
|
||||||
pos = new Vector3(b.BaseData.Translate.X, b.BaseData.Translate.Y, b.BaseData.Translate.Z);
|
pos = new Vector3(b.BaseData.Translate.X, b.BaseData.Translate.Y, b.BaseData.Translate.Z);
|
||||||
|
|
||||||
foreach (AnimCurve tr in b.Curves)
|
foreach (AnimCurve tr in b.Curves)
|
||||||
|
|
|
@ -303,6 +303,157 @@ namespace FirstPlugin
|
||||||
VertexBufferHelperAttrib attd = helper[attName];
|
VertexBufferHelperAttrib attd = helper[attName];
|
||||||
return attd.Data;
|
return attd.Data;
|
||||||
}
|
}
|
||||||
|
public static SkeletalAnim SetSkeletalAniamtion(BfresSkeletonAnim anim)
|
||||||
|
{
|
||||||
|
SkeletalAnim animation = new SkeletalAnim();
|
||||||
|
|
||||||
|
animation.Name = anim.Text;
|
||||||
|
animation.FrameCount = anim.FrameCount;
|
||||||
|
animation.FlagsAnimSettings = SkeletalAnimFlags.Looping;
|
||||||
|
animation.FlagsRotate = SkeletalAnimFlagsRotate.EulerXYZ;
|
||||||
|
animation.FlagsScale = SkeletalAnimFlagsScale.Maya;
|
||||||
|
animation.BindIndices = new ushort[anim.Bones.Count];
|
||||||
|
animation.BindSkeleton = new Skeleton();
|
||||||
|
animation.BakedSize = 0;
|
||||||
|
animation.BoneAnims = new List<BoneAnim>();
|
||||||
|
animation.UserDataDict = new ResDict();
|
||||||
|
animation.UserDatas = new List<UserData>();
|
||||||
|
|
||||||
|
foreach (var bone in anim.Bones)
|
||||||
|
animation.BoneAnims.Add(createBoneAnim(bone, anim));
|
||||||
|
|
||||||
|
return animation;
|
||||||
|
}
|
||||||
|
private static BoneAnim createBoneAnim(Animation.KeyNode bone, BfresSkeletonAnim anim)
|
||||||
|
{
|
||||||
|
BoneAnim boneAnim = new BoneAnim();
|
||||||
|
boneAnim.Name = bone.Name;
|
||||||
|
var posx = bone.XPOS.GetValue(0);
|
||||||
|
var posy = bone.YPOS.GetValue(0);
|
||||||
|
var posz = bone.ZPOS.GetValue(0);
|
||||||
|
var scax = bone.XSCA.GetValue(0);
|
||||||
|
var scay = bone.YSCA.GetValue(0);
|
||||||
|
var scaz = bone.ZSCA.GetValue(0);
|
||||||
|
var rotx = bone.XROT.GetValue(0);
|
||||||
|
var roty = bone.YROT.GetValue(0);
|
||||||
|
var rotz = bone.ZROT.GetValue(0);
|
||||||
|
var rotw = bone.WROT.GetValue(0);
|
||||||
|
|
||||||
|
BoneAnimData boneBaseData = new BoneAnimData();
|
||||||
|
boneBaseData.Translate = new Syroot.Maths.Vector3F(posx, posy, posz);
|
||||||
|
boneBaseData.Scale = new Syroot.Maths.Vector3F(scax, scay, scaz);
|
||||||
|
boneBaseData.Rotate = new Syroot.Maths.Vector4F(rotx, roty, rotz, rotw);
|
||||||
|
boneAnim.BaseData = boneBaseData;
|
||||||
|
boneAnim.BeginBaseTranslate = 0;
|
||||||
|
boneAnim.BeginRotate = 0;
|
||||||
|
boneAnim.BeginTranslate = 0;
|
||||||
|
boneAnim.Curves = new List<AnimCurve>();
|
||||||
|
boneAnim.FlagsBase = BoneAnimFlagsBase.Translate | BoneAnimFlagsBase.Scale | BoneAnimFlagsBase.Rotate;
|
||||||
|
boneAnim.FlagsTransform = BoneAnimFlagsTransform.Identity;
|
||||||
|
|
||||||
|
if (bone.XPOS.HasAnimation())
|
||||||
|
{
|
||||||
|
boneAnim.FlagsCurve |= BoneAnimFlagsCurve.TranslateX;
|
||||||
|
boneAnim.Curves.Add(SetAnimationCurve(bone.XPOS));
|
||||||
|
}
|
||||||
|
if (bone.YPOS.HasAnimation())
|
||||||
|
{
|
||||||
|
boneAnim.FlagsCurve |= BoneAnimFlagsCurve.TranslateY;
|
||||||
|
boneAnim.Curves.Add(SetAnimationCurve(bone.YPOS));
|
||||||
|
}
|
||||||
|
if (bone.ZPOS.HasAnimation())
|
||||||
|
{
|
||||||
|
boneAnim.FlagsCurve |= BoneAnimFlagsCurve.TranslateZ;
|
||||||
|
boneAnim.Curves.Add(SetAnimationCurve(bone.ZPOS));
|
||||||
|
}
|
||||||
|
if (bone.XSCA.HasAnimation())
|
||||||
|
{
|
||||||
|
boneAnim.FlagsCurve |= BoneAnimFlagsCurve.ScaleX;
|
||||||
|
boneAnim.Curves.Add(SetAnimationCurve(bone.XSCA));
|
||||||
|
}
|
||||||
|
if (bone.YSCA.HasAnimation())
|
||||||
|
{
|
||||||
|
boneAnim.FlagsCurve |= BoneAnimFlagsCurve.ScaleY;
|
||||||
|
boneAnim.Curves.Add(SetAnimationCurve(bone.YSCA));
|
||||||
|
}
|
||||||
|
if (bone.ZSCA.HasAnimation())
|
||||||
|
{
|
||||||
|
boneAnim.FlagsCurve |= BoneAnimFlagsCurve.ScaleZ;
|
||||||
|
boneAnim.Curves.Add(SetAnimationCurve(bone.ZSCA));
|
||||||
|
}
|
||||||
|
if (bone.XROT.HasAnimation())
|
||||||
|
{
|
||||||
|
boneAnim.FlagsCurve |= BoneAnimFlagsCurve.RotateX;
|
||||||
|
boneAnim.Curves.Add(SetAnimationCurve(bone.XROT));
|
||||||
|
}
|
||||||
|
if (bone.YROT.HasAnimation())
|
||||||
|
{
|
||||||
|
boneAnim.FlagsCurve |= BoneAnimFlagsCurve.RotateY;
|
||||||
|
boneAnim.Curves.Add(SetAnimationCurve(bone.YROT));
|
||||||
|
}
|
||||||
|
if (bone.ZROT.HasAnimation())
|
||||||
|
{
|
||||||
|
boneAnim.FlagsCurve |= BoneAnimFlagsCurve.RotateZ;
|
||||||
|
boneAnim.Curves.Add(SetAnimationCurve(bone.ZROT));
|
||||||
|
}
|
||||||
|
if (bone.WROT.HasAnimation())
|
||||||
|
{
|
||||||
|
boneAnim.FlagsCurve |= BoneAnimFlagsCurve.RotateW;
|
||||||
|
boneAnim.Curves.Add(SetAnimationCurve(bone.WROT));
|
||||||
|
}
|
||||||
|
|
||||||
|
return boneAnim;
|
||||||
|
}
|
||||||
|
private static AnimCurve SetAnimationCurve(Animation.KeyGroup keyGroup)
|
||||||
|
{
|
||||||
|
AnimCurve curve = new AnimCurve();
|
||||||
|
curve.Frames = new float[(int)keyGroup.Keys.Count];
|
||||||
|
curve.FrameType = AnimCurveFrameType.Single;
|
||||||
|
curve.KeyType = AnimCurveKeyType.Single;
|
||||||
|
curve.EndFrame = keyGroup.FrameCount;
|
||||||
|
curve.AnimDataOffset = 0;
|
||||||
|
curve.Delta = 0;
|
||||||
|
curve.Scale = 1;
|
||||||
|
curve.StartFrame = 0;
|
||||||
|
curve.Offset = 0;
|
||||||
|
|
||||||
|
var frame = keyGroup.GetKeyFrame(0);
|
||||||
|
int valuesLength = 1;
|
||||||
|
if (frame.InterType == Animation.InterpolationType.HERMITE)
|
||||||
|
{
|
||||||
|
curve.CurveType = AnimCurveType.Cubic;
|
||||||
|
curve.Keys = new float[keyGroup.Keys.Count, 4];
|
||||||
|
for (int k = 0; k < keyGroup.Keys.Count; k++)
|
||||||
|
{
|
||||||
|
float value = keyGroup.GetValue(keyGroup.Keys[k].Frame);
|
||||||
|
curve.Keys[k, 0] = value;
|
||||||
|
curve.Keys[k, 1] = 0;
|
||||||
|
curve.Keys[k, 2] = 0;
|
||||||
|
curve.Keys[k, 3] = 0;
|
||||||
|
|
||||||
|
curve.Frames[k] = keyGroup.Keys[k].Frame;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (frame.InterType == Animation.InterpolationType.LINEAR)
|
||||||
|
{
|
||||||
|
curve.CurveType = AnimCurveType.Linear;
|
||||||
|
curve.Keys = new float[keyGroup.Keys.Count, 2];
|
||||||
|
}
|
||||||
|
if (frame.InterType == Animation.InterpolationType.STEP)
|
||||||
|
{
|
||||||
|
curve.CurveType = AnimCurveType.StepInt;
|
||||||
|
curve.Keys = new float[keyGroup.Keys.Count, 1];
|
||||||
|
}
|
||||||
|
if (frame.InterType == Animation.InterpolationType.STEPBOOL)
|
||||||
|
{
|
||||||
|
curve.CurveType = AnimCurveType.StepBool;
|
||||||
|
curve.Keys = new float[keyGroup.Keys.Count, 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return curve;
|
||||||
|
}
|
||||||
|
|
||||||
public static void SetSkeleton(this TreeNodeCustom skl, Skeleton skeleton, FSKL RenderableSkeleton)
|
public static void SetSkeleton(this TreeNodeCustom skl, Skeleton skeleton, FSKL RenderableSkeleton)
|
||||||
{
|
{
|
||||||
|
@ -327,9 +478,9 @@ namespace FirstPlugin
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,10 +40,10 @@ namespace FirstPlugin
|
||||||
public void Load()
|
public void Load()
|
||||||
{
|
{
|
||||||
IsActive = true;
|
IsActive = true;
|
||||||
EditorRoot = new TreeNodeFile(FileName, this);
|
EditorRoot = new GFLXPACK(FileName, this);
|
||||||
|
IFileInfo = new IFileInfo();
|
||||||
|
|
||||||
GFLXPACK gflx = new GFLXPACK();
|
((GFLXPACK)EditorRoot).Read(new FileReader(new MemoryStream(Data)), EditorRoot);
|
||||||
gflx.Read(new FileReader(new MemoryStream(Data)), EditorRoot);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
public void Unload()
|
public void Unload()
|
||||||
|
@ -52,19 +52,107 @@ namespace FirstPlugin
|
||||||
}
|
}
|
||||||
public byte[] Save()
|
public byte[] Save()
|
||||||
{
|
{
|
||||||
return null;
|
MemoryStream mem = new MemoryStream();
|
||||||
|
((GFLXPACK)EditorRoot).Write(new FileWriter(mem));
|
||||||
|
return mem.ToArray();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class GFLXPACK : TreeNodeFile
|
||||||
}
|
|
||||||
|
|
||||||
public class GFLXPACK
|
|
||||||
{
|
{
|
||||||
|
public GFLXPACK(string text, IFileFormat format)
|
||||||
|
{
|
||||||
|
Text = text;
|
||||||
|
FileHandler = format;
|
||||||
|
|
||||||
|
ContextMenu = new ContextMenu();
|
||||||
|
MenuItem save = new MenuItem("Save");
|
||||||
|
ContextMenu.MenuItems.Add(save);
|
||||||
|
save.Click += Save;
|
||||||
|
MenuItem previewFiles = new MenuItem("Preview Window");
|
||||||
|
ContextMenu.MenuItems.Add(previewFiles);
|
||||||
|
previewFiles.Click += PreviewWindow;
|
||||||
|
}
|
||||||
|
private void Save(object sender, EventArgs args)
|
||||||
|
{
|
||||||
|
List<IFileFormat> formats = new List<IFileFormat>();
|
||||||
|
formats.Add(FileHandler);
|
||||||
|
|
||||||
|
SaveFileDialog sfd = new SaveFileDialog();
|
||||||
|
sfd.Filter = Utils.GetAllFilters(formats);
|
||||||
|
sfd.FileName = FileHandler.FileName;
|
||||||
|
|
||||||
|
if (sfd.ShowDialog() == DialogResult.OK)
|
||||||
|
{
|
||||||
|
Cursor.Current = Cursors.WaitCursor;
|
||||||
|
SaveCompressFile(FileHandler.Save(), sfd.FileName, FileHandler.IFileInfo.Alignment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void SaveCompressFile(byte[] data, string FileName, int Alignment = 0, bool EnableDialog = true)
|
||||||
|
{
|
||||||
|
if (EnableDialog)
|
||||||
|
{
|
||||||
|
DialogResult save = MessageBox.Show("Compress file?", "File Save", MessageBoxButtons.YesNo);
|
||||||
|
|
||||||
|
if (save == DialogResult.Yes)
|
||||||
|
data = EveryFileExplorer.YAZ0.Compress(data, 3, (uint)Alignment);
|
||||||
|
}
|
||||||
|
File.WriteAllBytes(FileName, data);
|
||||||
|
MessageBox.Show($"File has been saved to {FileName}");
|
||||||
|
Cursor.Current = Cursors.Default;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PreviewWindow(object sender, EventArgs args)
|
||||||
|
{
|
||||||
|
PreviewFormatList previewFormatList = new PreviewFormatList();
|
||||||
|
|
||||||
|
if (previewFormatList.ShowDialog() == DialogResult.OK)
|
||||||
|
{
|
||||||
|
CallRecursive(TreeView);
|
||||||
|
PreviewEditor previewWindow = new PreviewEditor();
|
||||||
|
previewWindow.Show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void CallRecursive(TreeView treeView)
|
||||||
|
{
|
||||||
|
// Print each node recursively.
|
||||||
|
TreeNodeCollection nodes = treeView.Nodes;
|
||||||
|
foreach (TreeNode n in nodes)
|
||||||
|
{
|
||||||
|
PrintRecursive(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void PrintRecursive(TreeNode treeNode)
|
||||||
|
{
|
||||||
|
if (treeNode is FileEntry)
|
||||||
|
{
|
||||||
|
FileEntry file = (FileEntry)treeNode;
|
||||||
|
|
||||||
|
if (file.ImageKey == "bntx")
|
||||||
|
OpenFile(file.Name, file.data, file);
|
||||||
|
|
||||||
|
if (file.ImageKey == "bntx")
|
||||||
|
Console.WriteLine(file.Name);
|
||||||
|
// if (file.ImageKey == "bfres")
|
||||||
|
// OpenFile(file.Name, GetASSTData(file.FullName), TreeView);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print each node recursively.
|
||||||
|
foreach (TreeNode tn in treeNode.Nodes)
|
||||||
|
{
|
||||||
|
PrintRecursive(tn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public ushort BOM;
|
public ushort BOM;
|
||||||
public uint Version;
|
public uint Version;
|
||||||
public List<FileEntry> files = new List<FileEntry>();
|
public List<FileEntry> files = new List<FileEntry>();
|
||||||
public List<UInt64> hashes = new List<UInt64>();
|
public List<UInt64> hashes = new List<UInt64>();
|
||||||
|
public List<HashIndex> hashIndices = new List<HashIndex>();
|
||||||
|
|
||||||
|
public int version;
|
||||||
|
public int FolderCount;
|
||||||
|
|
||||||
public void Read(FileReader reader, TreeNode root)
|
public void Read(FileReader reader, TreeNode root)
|
||||||
{
|
{
|
||||||
|
@ -72,15 +160,13 @@ namespace FirstPlugin
|
||||||
if (Signature != "GFLXPACK")
|
if (Signature != "GFLXPACK")
|
||||||
throw new Exception($"Invalid signature {Signature}! Expected GFLXPACK.");
|
throw new Exception($"Invalid signature {Signature}! Expected GFLXPACK.");
|
||||||
|
|
||||||
uint unk = reader.ReadUInt32();
|
version = reader.ReadInt32();
|
||||||
uint padding = reader.ReadUInt32();
|
uint padding = reader.ReadUInt32();
|
||||||
uint FileCount = reader.ReadUInt32();
|
uint FileCount = reader.ReadUInt32();
|
||||||
uint unk2 = reader.ReadUInt32();
|
FolderCount = reader.ReadInt32();
|
||||||
ulong FileInfoOffset = reader.ReadUInt64();
|
ulong FileInfoOffset = reader.ReadUInt64();
|
||||||
ulong hashArrayOffset = reader.ReadUInt64();
|
ulong hashArrayOffset = reader.ReadUInt64();
|
||||||
ulong UnkOffset = reader.ReadUInt64();
|
ulong hashArrayIndexOffset = reader.ReadUInt64();
|
||||||
ulong Unk2Offset = reader.ReadUInt64();
|
|
||||||
ulong Unk3Offset = reader.ReadUInt64();
|
|
||||||
|
|
||||||
reader.Seek((long)hashArrayOffset, SeekOrigin.Begin);
|
reader.Seek((long)hashArrayOffset, SeekOrigin.Begin);
|
||||||
for (int i = 0; i < FileCount; i++)
|
for (int i = 0; i < FileCount; i++)
|
||||||
|
@ -88,6 +174,13 @@ namespace FirstPlugin
|
||||||
ulong hash = reader.ReadUInt64();
|
ulong hash = reader.ReadUInt64();
|
||||||
hashes.Add(hash);
|
hashes.Add(hash);
|
||||||
}
|
}
|
||||||
|
reader.Seek((long)hashArrayIndexOffset, SeekOrigin.Begin);
|
||||||
|
for (int i = 0; i < FileCount; i++)
|
||||||
|
{
|
||||||
|
HashIndex hashindex = new HashIndex();
|
||||||
|
hashindex.Read(reader);
|
||||||
|
hashIndices.Add(hashindex);
|
||||||
|
}
|
||||||
|
|
||||||
reader.Seek((long)FileInfoOffset, SeekOrigin.Begin);
|
reader.Seek((long)FileInfoOffset, SeekOrigin.Begin);
|
||||||
for (int i = 0; i < FileCount; i++)
|
for (int i = 0; i < FileCount; i++)
|
||||||
|
@ -95,12 +188,60 @@ namespace FirstPlugin
|
||||||
FileEntry fileEntry = new FileEntry();
|
FileEntry fileEntry = new FileEntry();
|
||||||
fileEntry.Read(reader);
|
fileEntry.Read(reader);
|
||||||
fileEntry.Text = hashes[i].ToString();
|
fileEntry.Text = hashes[i].ToString();
|
||||||
files.Add(fileEntry);
|
|
||||||
|
|
||||||
root.Nodes.Add(fileEntry);
|
root.Nodes.Add(fileEntry);
|
||||||
|
files.Add(fileEntry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public void Write(FileWriter writer)
|
||||||
|
{
|
||||||
|
writer.WriteSignature("GFLXPACK");
|
||||||
|
writer.Write(version);
|
||||||
|
writer.Write(0);
|
||||||
|
writer.Write(files.Count);
|
||||||
|
writer.Write(FolderCount);
|
||||||
|
long FileInfoOffset = writer.Position;
|
||||||
|
writer.Write(0L);
|
||||||
|
long HashArrayOffset = writer.Position;
|
||||||
|
writer.Write(0L);
|
||||||
|
long HashIndexArrOffset = writer.Position;
|
||||||
|
writer.Write(0L);
|
||||||
|
//Now write all sections
|
||||||
|
writer.WriteUint64Offset(HashArrayOffset);
|
||||||
|
writer.Write(hashes);
|
||||||
|
|
||||||
|
writer.WriteUint64Offset(HashIndexArrOffset);
|
||||||
|
foreach (var hashIndx in hashIndices)
|
||||||
|
hashIndx.Write(writer);
|
||||||
|
|
||||||
|
writer.WriteUint64Offset(FileInfoOffset);
|
||||||
|
foreach (var fileTbl in files)
|
||||||
|
fileTbl.Write(writer);
|
||||||
|
|
||||||
|
//Save data blocks
|
||||||
|
foreach (var fileTbl in files)
|
||||||
|
{
|
||||||
|
fileTbl.WriteBlock(writer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class HashIndex
|
||||||
|
{
|
||||||
|
public ulong hash;
|
||||||
|
public int Index;
|
||||||
|
public uint unkown;
|
||||||
|
|
||||||
|
public void Read(FileReader reader)
|
||||||
|
{
|
||||||
|
hash = reader.ReadUInt64();
|
||||||
|
Index = reader.ReadInt32();
|
||||||
|
unkown = reader.ReadUInt32(); //Always 0xCC?
|
||||||
|
}
|
||||||
|
public void Write(FileWriter writer)
|
||||||
|
{
|
||||||
|
writer.Write(hash);
|
||||||
|
writer.Write(Index);
|
||||||
|
writer.Write(unkown);
|
||||||
|
}
|
||||||
|
}
|
||||||
public class FileEntry : TreeNodeCustom
|
public class FileEntry : TreeNodeCustom
|
||||||
{
|
{
|
||||||
public FileEntry()
|
public FileEntry()
|
||||||
|
@ -114,21 +255,26 @@ namespace FirstPlugin
|
||||||
export.Click += Export;
|
export.Click += Export;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
public uint unkown;
|
||||||
|
public uint CompressionType;
|
||||||
public byte[] data;
|
public byte[] data;
|
||||||
|
private long DataOffset;
|
||||||
|
private byte[] CompressedData;
|
||||||
|
public IFileFormat FileHandler;
|
||||||
|
|
||||||
public void Read(FileReader reader)
|
public void Read(FileReader reader)
|
||||||
{
|
{
|
||||||
uint unk = reader.ReadUInt16();
|
unkown = reader.ReadUInt16(); //Usually 9?
|
||||||
uint unk2 = reader.ReadUInt16();
|
CompressionType = reader.ReadUInt16();
|
||||||
uint unk3 = reader.ReadUInt32();
|
uint DecompressedFileSize = reader.ReadUInt32();
|
||||||
uint FileSize = reader.ReadUInt32();
|
uint CompressedFileSize = reader.ReadUInt32();
|
||||||
uint unk4 = reader.ReadUInt32();
|
uint padding = reader.ReadUInt32();
|
||||||
ulong FileOffset = reader.ReadUInt64();
|
ulong FileOffset = reader.ReadUInt64();
|
||||||
|
|
||||||
using (reader.TemporarySeek((long)FileOffset, SeekOrigin.Begin))
|
using (reader.TemporarySeek((long)FileOffset, SeekOrigin.Begin))
|
||||||
{
|
{
|
||||||
byte type = reader.ReadByte();
|
data = reader.ReadBytes((int)CompressedFileSize);
|
||||||
data = reader.ReadBytes((int)FileSize - 1);
|
data = STLibraryCompression.Type_LZ4.Decompress(data, 0, (int)CompressedFileSize, (int)DecompressedFileSize);
|
||||||
|
|
||||||
string ext = SARCExt.SARC.GuessFileExtension(data);
|
string ext = SARCExt.SARC.GuessFileExtension(data);
|
||||||
|
|
||||||
|
@ -153,11 +299,45 @@ namespace FirstPlugin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public void Write(FileWriter writer)
|
||||||
|
{
|
||||||
|
if (FileHandler != null && FileHandler.CanSave)
|
||||||
|
{
|
||||||
|
data = FileHandler.Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
CompressedData = Compress(data, CompressionType);
|
||||||
|
|
||||||
|
writer.Write((ushort)unkown);
|
||||||
|
writer.Write((ushort)CompressionType);
|
||||||
|
writer.Write(data.Length);
|
||||||
|
writer.Write(CompressedData.Length);
|
||||||
|
writer.Write(0);
|
||||||
|
DataOffset = writer.Position;
|
||||||
|
writer.Write(0L);
|
||||||
|
}
|
||||||
|
public void WriteBlock(FileWriter writer)
|
||||||
|
{
|
||||||
|
writer.WriteUint64Offset(DataOffset);
|
||||||
|
writer.Write(CompressedData);
|
||||||
|
}
|
||||||
|
public static byte[] Compress(byte[] data, uint Type)
|
||||||
|
{
|
||||||
|
if (Type == 2)
|
||||||
|
{
|
||||||
|
return STLibraryCompression.Type_LZ4.Compress(data);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new Exception("Unkown compression type?");
|
||||||
|
}
|
||||||
public override void OnClick(TreeView treeview)
|
public override void OnClick(TreeView treeview)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
public override void OnMouseLeftClick(TreeView treeView)
|
||||||
|
{
|
||||||
|
ReplaceNode(this.Parent, this, OpenFile(Name, data, this));
|
||||||
|
}
|
||||||
private void Export(object sender, EventArgs args)
|
private void Export(object sender, EventArgs args)
|
||||||
{
|
{
|
||||||
SaveFileDialog sfd = new SaveFileDialog();
|
SaveFileDialog sfd = new SaveFileDialog();
|
||||||
|
@ -166,11 +346,87 @@ namespace FirstPlugin
|
||||||
|
|
||||||
if (sfd.ShowDialog() == DialogResult.OK)
|
if (sfd.ShowDialog() == DialogResult.OK)
|
||||||
{
|
{
|
||||||
File.WriteAllBytes(sfd.FileName, STLibraryCompression.Type_LZ4.Decompress(data));
|
File.WriteAllBytes(sfd.FileName, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static TreeNode OpenFile(string FileName, byte[] data, FileEntry fileEntry, bool Compressed = false, CompressionType CompType = 0)
|
||||||
|
{
|
||||||
|
Cursor.Current = Cursors.WaitCursor;
|
||||||
|
FileReader fileReader = new FileReader(data);
|
||||||
|
string Magic4 = fileReader.ReadMagic(0, 4);
|
||||||
|
string Magic2 = fileReader.ReadMagic(0, 2);
|
||||||
|
if (Magic4 == "Yaz0")
|
||||||
|
{
|
||||||
|
data = EveryFileExplorer.YAZ0.Decompress(data);
|
||||||
|
return OpenFile(FileName, data, fileEntry, true, (CompressionType)1);
|
||||||
|
}
|
||||||
|
if (Magic4 == "ZLIB")
|
||||||
|
{
|
||||||
|
data = FileReader.InflateZLIB(fileReader.getSection(64, data.Length - 64));
|
||||||
|
return OpenFile(FileName, data, fileEntry, true, (CompressionType)2);
|
||||||
|
}
|
||||||
|
fileReader.Dispose();
|
||||||
|
fileReader.Close();
|
||||||
|
foreach (IFileFormat fileFormat in FileManager.GetFileFormats())
|
||||||
|
{
|
||||||
|
if (fileFormat.Magic == Magic4 || fileFormat.Magic == Magic2)
|
||||||
|
{
|
||||||
|
fileFormat.CompressionType = CompType;
|
||||||
|
fileFormat.FileIsCompressed = Compressed;
|
||||||
|
fileFormat.Data = data;
|
||||||
|
fileFormat.Load();
|
||||||
|
fileFormat.FileName = Path.GetFileName(FileName);
|
||||||
|
fileFormat.FilePath = FileName;
|
||||||
|
fileFormat.IFileInfo = new IFileInfo();
|
||||||
|
fileFormat.IFileInfo.InArchive = true;
|
||||||
|
if (fileFormat.EditorRoot == null)
|
||||||
|
return null;
|
||||||
|
fileFormat.EditorRoot.ImageKey = fileEntry.ImageKey;
|
||||||
|
fileFormat.EditorRoot.SelectedImageKey = fileEntry.SelectedImageKey;
|
||||||
|
fileFormat.EditorRoot.Text = fileEntry.Text;
|
||||||
|
fileEntry.FileHandler = fileFormat;
|
||||||
|
|
||||||
|
return fileFormat.EditorRoot;
|
||||||
|
}
|
||||||
|
if (fileFormat.Magic == string.Empty)
|
||||||
|
{
|
||||||
|
foreach (string str3 in fileFormat.Extension)
|
||||||
|
{
|
||||||
|
if (str3.Remove(0, 1) == Path.GetExtension(FileName))
|
||||||
|
{
|
||||||
|
fileFormat.Data = data;
|
||||||
|
fileFormat.Load();
|
||||||
|
fileFormat.FileName = Path.GetFileName(FileName);
|
||||||
|
fileFormat.FilePath = FileName;
|
||||||
|
fileFormat.IFileInfo = new IFileInfo();
|
||||||
|
fileFormat.IFileInfo.InArchive = true;
|
||||||
|
if (fileFormat.EditorRoot == null)
|
||||||
|
return null;
|
||||||
|
fileFormat.EditorRoot.ImageKey = fileEntry.ImageKey;
|
||||||
|
fileFormat.EditorRoot.SelectedImageKey = fileEntry.SelectedImageKey;
|
||||||
|
fileFormat.EditorRoot.Text = fileEntry.Text;
|
||||||
|
fileEntry.FileHandler = fileFormat;
|
||||||
|
|
||||||
|
return fileFormat.EditorRoot;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return (TreeNode)null;
|
||||||
|
}
|
||||||
|
public static void ReplaceNode(TreeNode node, TreeNode replaceNode, TreeNode NewNode)
|
||||||
|
{
|
||||||
|
if (NewNode == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int index = node.Nodes.IndexOf(replaceNode);
|
||||||
|
node.Nodes.RemoveAt(index);
|
||||||
|
node.Nodes.Insert(index, NewNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public class FileUnk
|
public class FileUnk
|
||||||
{
|
{
|
||||||
public uint Size;
|
public uint Size;
|
||||||
|
|
|
@ -46,11 +46,10 @@ namespace FirstPlugin
|
||||||
UseEditMenu = true;
|
UseEditMenu = true;
|
||||||
|
|
||||||
var SzsFiles = SARCExt.SARC.UnpackRamN(Data);
|
var SzsFiles = SARCExt.SARC.UnpackRamN(Data);
|
||||||
|
|
||||||
sarcData = new SarcData();
|
sarcData = new SarcData();
|
||||||
sarcData.HashOnly = false;
|
sarcData.HashOnly = false;
|
||||||
sarcData.Files = SzsFiles.Files;
|
sarcData.Files = SzsFiles.Files;
|
||||||
sarcData.endianness = Syroot.BinaryData.ByteOrder.LittleEndian;
|
sarcData.endianness = GetByteOrder(Data);
|
||||||
SarcHash = Utils.GenerateUniqueHashID();
|
SarcHash = Utils.GenerateUniqueHashID();
|
||||||
|
|
||||||
IFileInfo = new IFileInfo();
|
IFileInfo = new IFileInfo();
|
||||||
|
@ -59,6 +58,22 @@ namespace FirstPlugin
|
||||||
|
|
||||||
sarcData.Files.Clear();
|
sarcData.Files.Clear();
|
||||||
}
|
}
|
||||||
|
public Syroot.BinaryData.ByteOrder GetByteOrder(byte[] data)
|
||||||
|
{
|
||||||
|
using (FileReader reader = new FileReader(data))
|
||||||
|
{
|
||||||
|
reader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian;
|
||||||
|
reader.Seek(6);
|
||||||
|
ushort bom = reader.ReadUInt16();
|
||||||
|
reader.Close();
|
||||||
|
reader.Dispose();
|
||||||
|
|
||||||
|
if (bom == 0xFFFE)
|
||||||
|
return Syroot.BinaryData.ByteOrder.LittleEndian;
|
||||||
|
else
|
||||||
|
return Syroot.BinaryData.ByteOrder.BigEndian;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void Unload()
|
public void Unload()
|
||||||
{
|
{
|
||||||
|
@ -248,7 +263,7 @@ namespace FirstPlugin
|
||||||
public override void OnClick(TreeView treeView)
|
public override void OnClick(TreeView treeView)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
public override void OnMouseClick(TreeView treeView)
|
public override void OnMouseLeftClick(TreeView treeView)
|
||||||
{
|
{
|
||||||
ReplaceNode(this.Parent, this, OpenFile(Name, Data, this));
|
ReplaceNode(this.Parent, this, OpenFile(Name, Data, this));
|
||||||
}
|
}
|
||||||
|
|
|
@ -161,10 +161,11 @@ namespace FirstPlugin
|
||||||
|
|
||||||
public void Load()
|
public void Load()
|
||||||
{
|
{
|
||||||
|
IFileInfo = new IFileInfo();
|
||||||
|
|
||||||
IsActive = true;
|
IsActive = true;
|
||||||
UseEditMenu = true;
|
UseEditMenu = true;
|
||||||
CanSave = true;
|
CanSave = true;
|
||||||
|
|
||||||
bntx = new BinaryTextureContainer(Data, FileName, "", this);
|
bntx = new BinaryTextureContainer(Data, FileName, "", this);
|
||||||
EditorRoot = bntx;
|
EditorRoot = bntx;
|
||||||
}
|
}
|
||||||
|
@ -194,12 +195,41 @@ namespace FirstPlugin
|
||||||
public BntxFile BinaryTexFile;
|
public BntxFile BinaryTexFile;
|
||||||
public string FileNameText;
|
public string FileNameText;
|
||||||
|
|
||||||
|
MenuItem save = new MenuItem("Save");
|
||||||
|
MenuItem replace = new MenuItem("Replace");
|
||||||
|
MenuItem rename = new MenuItem("Rename");
|
||||||
|
MenuItem importTex = new MenuItem("Import Texture");
|
||||||
|
MenuItem exportAll = new MenuItem("Export All Textures");
|
||||||
|
MenuItem clear = new MenuItem("Clear");
|
||||||
|
|
||||||
|
private bool hasParent;
|
||||||
|
public bool HasParent
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
hasParent = Parent != null;
|
||||||
|
replace.Enabled = hasParent;
|
||||||
|
rename.Enabled = hasParent;
|
||||||
|
return hasParent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public bool CanReplace;
|
||||||
|
public bool AllGLInitialized
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (Textures.Any(item => item.Value.GLInitialized == false))
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public BinaryTextureContainer()
|
public BinaryTextureContainer()
|
||||||
{
|
{
|
||||||
ImageKey = "bntx";
|
ImageKey = "bntx";
|
||||||
SelectedImageKey = "bntx";
|
SelectedImageKey = "bntx";
|
||||||
}
|
}
|
||||||
|
|
||||||
public BinaryTextureContainer(byte[] data, string Name = "", string FileName = "", IFileFormat handler = null)
|
public BinaryTextureContainer(byte[] data, string Name = "", string FileName = "", IFileFormat handler = null)
|
||||||
{
|
{
|
||||||
if (data.Length == 0)
|
if (data.Length == 0)
|
||||||
|
@ -212,6 +242,25 @@ namespace FirstPlugin
|
||||||
LoadFile(data, Name);
|
LoadFile(data, Name);
|
||||||
|
|
||||||
PluginRuntime.bntxContainers.Add(this);
|
PluginRuntime.bntxContainers.Add(this);
|
||||||
|
FileHandler = handler;
|
||||||
|
|
||||||
|
//Check if bntx is parented to determine if an archive is used
|
||||||
|
bool checkParent = HasParent;
|
||||||
|
|
||||||
|
ContextMenu = new ContextMenu();
|
||||||
|
ContextMenu.MenuItems.Add(save);
|
||||||
|
ContextMenu.MenuItems.Add(replace);
|
||||||
|
ContextMenu.MenuItems.Add(rename);
|
||||||
|
ContextMenu.MenuItems.Add(importTex);
|
||||||
|
ContextMenu.MenuItems.Add(exportAll);
|
||||||
|
ContextMenu.MenuItems.Add(clear);
|
||||||
|
|
||||||
|
save.Click += Save;
|
||||||
|
replace.Click += Import;
|
||||||
|
rename.Click += Rename;
|
||||||
|
importTex.Click += ImportTexture;
|
||||||
|
exportAll.Click += ExportAll;
|
||||||
|
clear.Click += Clear;
|
||||||
}
|
}
|
||||||
private byte[] CreateNewBNTX(string Name)
|
private byte[] CreateNewBNTX(string Name)
|
||||||
{
|
{
|
||||||
|
@ -241,15 +290,13 @@ namespace FirstPlugin
|
||||||
Viewport.Instance.UpdateViewport();
|
Viewport.Instance.UpdateViewport();
|
||||||
}
|
}
|
||||||
public override void OnClick(TreeView treeView)
|
public override void OnClick(TreeView treeView)
|
||||||
{
|
|
||||||
Console.WriteLine(FirstPlugin.MainF);
|
|
||||||
foreach (Control control in FirstPlugin.MainF.Controls)
|
|
||||||
{
|
|
||||||
if (control is DockPanel)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
//Check right click to enable/disable certain context menus
|
||||||
|
public override void OnMouseRightClick(TreeView treeview)
|
||||||
|
{
|
||||||
|
bool checkParent = HasParent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadFile(byte[] data, string Name = "")
|
public void LoadFile(byte[] data, string Name = "")
|
||||||
|
@ -276,23 +323,8 @@ namespace FirstPlugin
|
||||||
Nodes.Add(texData);
|
Nodes.Add(texData);
|
||||||
Textures.Add(tex.Name, texData);
|
Textures.Add(tex.Name, texData);
|
||||||
}
|
}
|
||||||
|
BinaryTexFile.Textures.Clear(); //We don't need these in memeory anymore
|
||||||
ContextMenu = new ContextMenu();
|
BinaryTexFile.TextureDict.Clear();
|
||||||
MenuItem export = new MenuItem("Export BNTX");
|
|
||||||
ContextMenu.MenuItems.Add(export);
|
|
||||||
export.Click += Export;
|
|
||||||
MenuItem replace = new MenuItem("Replace BNTX");
|
|
||||||
ContextMenu.MenuItems.Add(replace);
|
|
||||||
replace.Click += Import;
|
|
||||||
MenuItem importTex = new MenuItem("Import Texture");
|
|
||||||
ContextMenu.MenuItems.Add(importTex);
|
|
||||||
importTex.Click += ImportTexture;
|
|
||||||
MenuItem exportAll = new MenuItem("Export All Textures");
|
|
||||||
ContextMenu.MenuItems.Add(exportAll);
|
|
||||||
exportAll.Click += ExportAll;
|
|
||||||
MenuItem clear = new MenuItem("Clear");
|
|
||||||
ContextMenu.MenuItems.Add(clear);
|
|
||||||
clear.Click += Clear;
|
|
||||||
}
|
}
|
||||||
private void ImportTexture(object sender, EventArgs args)
|
private void ImportTexture(object sender, EventArgs args)
|
||||||
{
|
{
|
||||||
|
@ -341,8 +373,15 @@ namespace FirstPlugin
|
||||||
importer.LoadSettings(settings, this);
|
importer.LoadSettings(settings, this);
|
||||||
if (importer.ShowDialog() == DialogResult.OK)
|
if (importer.ShowDialog() == DialogResult.OK)
|
||||||
{
|
{
|
||||||
|
Cursor.Current = Cursors.WaitCursor;
|
||||||
foreach (var setting in settings)
|
foreach (var setting in settings)
|
||||||
{
|
{
|
||||||
|
if (setting.GenerateMipmaps)
|
||||||
|
{
|
||||||
|
setting.DataBlockOutput.Clear();
|
||||||
|
setting.DataBlockOutput.Add(setting.GenerateMips());
|
||||||
|
}
|
||||||
|
|
||||||
if (setting.DataBlockOutput != null)
|
if (setting.DataBlockOutput != null)
|
||||||
{
|
{
|
||||||
Texture tex = setting.FromBitMap(setting.DataBlockOutput[0], setting);
|
Texture tex = setting.FromBitMap(setting.DataBlockOutput[0], setting);
|
||||||
|
@ -355,6 +394,12 @@ namespace FirstPlugin
|
||||||
setting.textureData = new TextureData(tex, setting.bntx);
|
setting.textureData = new TextureData(tex, setting.bntx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
if (Textures.ContainsKey(setting.textureData.Text))
|
||||||
|
{
|
||||||
|
setting.textureData.Text = setting.textureData.Text + i++;
|
||||||
|
}
|
||||||
|
|
||||||
Nodes.Add(setting.textureData);
|
Nodes.Add(setting.textureData);
|
||||||
Textures.Add(setting.textureData.Text, setting.textureData);
|
Textures.Add(setting.textureData.Text, setting.textureData);
|
||||||
setting.textureData.LoadOpenGLTexture();
|
setting.textureData.LoadOpenGLTexture();
|
||||||
|
@ -367,6 +412,7 @@ namespace FirstPlugin
|
||||||
}
|
}
|
||||||
settings.Clear();
|
settings.Clear();
|
||||||
GC.Collect();
|
GC.Collect();
|
||||||
|
Cursor.Current = Cursors.Default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//This function is an optional feature that will import a dummy texture if one is missing in the materials
|
//This function is an optional feature that will import a dummy texture if one is missing in the materials
|
||||||
|
@ -500,6 +546,7 @@ namespace FirstPlugin
|
||||||
{
|
{
|
||||||
Nodes.Clear();
|
Nodes.Clear();
|
||||||
Textures.Clear();
|
Textures.Clear();
|
||||||
|
GC.Collect();
|
||||||
}
|
}
|
||||||
private void ExportAll(object sender, EventArgs args)
|
private void ExportAll(object sender, EventArgs args)
|
||||||
{
|
{
|
||||||
|
@ -611,16 +658,26 @@ namespace FirstPlugin
|
||||||
LoadFile(Data);
|
LoadFile(Data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private void Rename(object sender, EventArgs args)
|
||||||
|
{
|
||||||
|
RenameDialog dialog = new RenameDialog();
|
||||||
|
dialog.SetString(Text);
|
||||||
|
|
||||||
private void Export(object sender, EventArgs args)
|
if (dialog.ShowDialog() == DialogResult.OK)
|
||||||
|
{
|
||||||
|
Text = dialog.textBox1.Text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void Save(object sender, EventArgs args)
|
||||||
{
|
{
|
||||||
SaveFileDialog sfd = new SaveFileDialog();
|
SaveFileDialog sfd = new SaveFileDialog();
|
||||||
sfd.DefaultExt = "bntx";
|
sfd.DefaultExt = "bntx";
|
||||||
sfd.Filter = "Supported Formats|*.bntx;";
|
sfd.Filter = "Supported Formats|*.bntx;";
|
||||||
|
sfd.FileName = FileHandler.FileName;
|
||||||
|
|
||||||
if (sfd.ShowDialog() == DialogResult.OK)
|
if (sfd.ShowDialog() == DialogResult.OK)
|
||||||
{
|
{
|
||||||
File.WriteAllBytes(sfd.FileName, Data);
|
File.WriteAllBytes(sfd.FileName, FileHandler.Save());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -631,8 +688,7 @@ namespace FirstPlugin
|
||||||
public BntxFile bntxFile;
|
public BntxFile bntxFile;
|
||||||
public List<List<byte[]>> mipmaps = new List<List<byte[]>>();
|
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;
|
||||||
BNTXEditor BNTXEditor;
|
|
||||||
|
|
||||||
public TextureData()
|
public TextureData()
|
||||||
{
|
{
|
||||||
|
@ -672,12 +728,12 @@ namespace FirstPlugin
|
||||||
|
|
||||||
}
|
}
|
||||||
public override void OnClick(TreeView treeView)
|
public override void OnClick(TreeView treeView)
|
||||||
|
{
|
||||||
|
if (FirstPlugin.DockedEditorS == null)
|
||||||
{
|
{
|
||||||
foreach (Control control in FirstPlugin.MainF.Controls)
|
foreach (Control control in FirstPlugin.MainF.Controls)
|
||||||
{
|
{
|
||||||
if (control is DockPanel)
|
if (control is DockPanel)
|
||||||
{
|
|
||||||
if (FirstPlugin.DockedEditorS == null)
|
|
||||||
{
|
{
|
||||||
FirstPlugin.DockedEditorS = new DockContent();
|
FirstPlugin.DockedEditorS = new DockContent();
|
||||||
FirstPlugin.DockedEditorS.Show((DockPanel)control, PluginRuntime.FSHPDockState);
|
FirstPlugin.DockedEditorS.Show((DockPanel)control, PluginRuntime.FSHPDockState);
|
||||||
|
@ -689,14 +745,24 @@ namespace FirstPlugin
|
||||||
{
|
{
|
||||||
FirstPlugin.DockedEditorS.Controls.Clear();
|
FirstPlugin.DockedEditorS.Controls.Clear();
|
||||||
|
|
||||||
BNTXEditor = new BNTXEditor();
|
BNTXEditor BNTXEditor = new BNTXEditor();
|
||||||
BNTXEditor.Text = Text;
|
BNTXEditor.Text = Text;
|
||||||
BNTXEditor.Dock = DockStyle.Fill;
|
BNTXEditor.Dock = DockStyle.Fill;
|
||||||
BNTXEditor.LoadPicture(DisplayTexture());
|
|
||||||
BNTXEditor.LoadProperty(this);
|
BNTXEditor.LoadProperty(this);
|
||||||
FirstPlugin.DockedEditorS.Controls.Add(BNTXEditor);
|
FirstPlugin.DockedEditorS.Controls.Add(BNTXEditor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public void UpdateEditor()
|
||||||
|
{
|
||||||
|
foreach (Control ctrl in FirstPlugin.DockedEditorS.Controls)
|
||||||
|
{
|
||||||
|
if (ctrl is BNTXEditor)
|
||||||
|
{
|
||||||
|
FirstPlugin.DockedEditorS.Text = Text;
|
||||||
|
((BNTXEditor)ctrl).LoadProperty(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
public bool EditorIsActive(DockContent dock)
|
public bool EditorIsActive(DockContent dock)
|
||||||
{
|
{
|
||||||
foreach (Control ctrl in dock.Controls)
|
foreach (Control ctrl in dock.Controls)
|
||||||
|
@ -704,7 +770,6 @@ namespace FirstPlugin
|
||||||
if (ctrl is BNTXEditor)
|
if (ctrl is BNTXEditor)
|
||||||
{
|
{
|
||||||
dock.Text = Text;
|
dock.Text = Text;
|
||||||
((BNTXEditor)ctrl).LoadPicture(DisplayTexture());
|
|
||||||
((BNTXEditor)ctrl).LoadProperty(this);
|
((BNTXEditor)ctrl).LoadProperty(this);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -781,6 +846,7 @@ namespace FirstPlugin
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
renderedGLTex.display = loadImage(renderedGLTex);
|
renderedGLTex.display = loadImage(renderedGLTex);
|
||||||
|
GLInitialized = true;
|
||||||
|
|
||||||
return renderedGLTex;
|
return renderedGLTex;
|
||||||
}
|
}
|
||||||
|
@ -793,62 +859,128 @@ namespace FirstPlugin
|
||||||
if (Format == SurfaceFormat.BC5_SNORM)
|
if (Format == SurfaceFormat.BC5_SNORM)
|
||||||
return DDSCompressor.DecompressBC5(data, (int)Width, (int)Height, true);
|
return DDSCompressor.DecompressBC5(data, (int)Width, (int)Height, true);
|
||||||
|
|
||||||
byte[] d = DecodePixelBlocks(data, (int)Width, (int)Height, Format);
|
byte[] d = null;
|
||||||
d = DecompressBlocks(data, (int)Width, (int)Height, Format);
|
if (IsCompressedFormat(Format))
|
||||||
|
d = DDSCompressor.DecompressBlock(data, (int)Width, (int)Height, GetCompressedDXGI_FORMAT(Format));
|
||||||
|
else if (IsAtscFormat(Format))
|
||||||
|
d = null;
|
||||||
|
else
|
||||||
|
d = DDSCompressor.DecodePixelBlock(data, (int)Width, (int)Height, 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);
|
||||||
return SwapBlueRedChannels(decomp);
|
return SwapBlueRedChannels(decomp);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
private static byte[] DecompressBlocks(byte[] data, int width, int height, SurfaceFormat Format)
|
private static DDS.DXGI_FORMAT GetUncompressedDXGI_FORMAT(SurfaceFormat Format)
|
||||||
{
|
{
|
||||||
switch (Format)
|
switch (Format)
|
||||||
{
|
{
|
||||||
case SurfaceFormat.BC1_UNORM: return DDSCompressor.DecompressBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM);
|
case SurfaceFormat.A1_B5_G5_R5_UNORM: return DDS.DXGI_FORMAT.DXGI_FORMAT_B5G5R5A1_UNORM;
|
||||||
case SurfaceFormat.BC1_SRGB: return DDSCompressor.DecompressBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM_SRGB);
|
case SurfaceFormat.A4_B4_G4_R4_UNORM: return DDS.DXGI_FORMAT.DXGI_FORMAT_B4G4R4A4_UNORM;
|
||||||
case SurfaceFormat.BC2_UNORM: return DDSCompressor.DecompressBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM);
|
case SurfaceFormat.B5_G5_R5_A1_UNORM: return DDS.DXGI_FORMAT.DXGI_FORMAT_B5G5R5A1_UNORM;
|
||||||
case SurfaceFormat.BC2_SRGB: return DDSCompressor.DecompressBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM_SRGB);
|
case SurfaceFormat.B5_G6_R5_UNORM: return DDS.DXGI_FORMAT.DXGI_FORMAT_B5G6R5_UNORM;
|
||||||
case SurfaceFormat.BC3_UNORM: return DDSCompressor.DecompressBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM);
|
case SurfaceFormat.B8_G8_R8_A8_SRGB: return DDS.DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
|
||||||
case SurfaceFormat.BC3_SRGB: return DDSCompressor.DecompressBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM_SRGB);
|
case SurfaceFormat.B8_G8_R8_A8_UNORM: return DDS.DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||||
case SurfaceFormat.BC4_UNORM: return DDSCompressor.DecompressBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_BC4_UNORM);
|
case SurfaceFormat.R10_G10_B10_A2_UNORM: return DDS.DXGI_FORMAT.DXGI_FORMAT_R10G10B10A2_UNORM;
|
||||||
case SurfaceFormat.BC4_SNORM: return DDSCompressor.DecompressBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_BC4_SNORM);
|
case SurfaceFormat.R11_G11_B10_FLOAT: return DDS.DXGI_FORMAT.DXGI_FORMAT_R11G11B10_FLOAT;
|
||||||
case SurfaceFormat.BC5_UNORM: return DDSCompressor.DecompressBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_BC5_UNORM);
|
case SurfaceFormat.R16_UNORM: return DDS.DXGI_FORMAT.DXGI_FORMAT_R16_UNORM;
|
||||||
case SurfaceFormat.BC6_UFLOAT: return DDSCompressor.DecompressBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_BC6H_UF16);
|
case SurfaceFormat.R32_FLOAT: return DDS.DXGI_FORMAT.DXGI_FORMAT_R32_FLOAT;
|
||||||
case SurfaceFormat.BC6_FLOAT: return DDSCompressor.DecompressBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_BC4_SNORM);
|
case SurfaceFormat.R4_G4_B4_A4_UNORM: return DDS.DXGI_FORMAT.DXGI_FORMAT_B4G4R4A4_UNORM;
|
||||||
case SurfaceFormat.BC7_UNORM: return DDSCompressor.DecompressBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM);
|
case SurfaceFormat.R4_G4_UNORM: return DDS.DXGI_FORMAT.DXGI_FORMAT_B4G4R4A4_UNORM;
|
||||||
case SurfaceFormat.BC7_SRGB: return DDSCompressor.DecompressBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM_SRGB);
|
case SurfaceFormat.R5_G5_B5_A1_UNORM: return DDS.DXGI_FORMAT.DXGI_FORMAT_B5G5R5A1_UNORM;
|
||||||
|
case SurfaceFormat.R5_G6_B5_UNORM: return DDS.DXGI_FORMAT.DXGI_FORMAT_B5G6R5_UNORM;
|
||||||
|
case SurfaceFormat.R8_G8_B8_A8_SRGB: return DDS.DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
|
||||||
|
case SurfaceFormat.R8_G8_B8_A8_UNORM: return DDS.DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
case SurfaceFormat.R8_G8_UNORM: return DDS.DXGI_FORMAT.DXGI_FORMAT_R8G8_UNORM;
|
||||||
|
case SurfaceFormat.R8_UNORM: return DDS.DXGI_FORMAT.DXGI_FORMAT_R8_UNORM;
|
||||||
|
case SurfaceFormat.Invalid: throw new Exception("Invalid Format");
|
||||||
default:
|
default:
|
||||||
return null;
|
throw new Exception($"Cannot convert format {Format}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private static byte[] DecodePixelBlocks(byte[] data, int width, int height, SurfaceFormat Format)
|
private static DDS.DXGI_FORMAT GetCompressedDXGI_FORMAT(SurfaceFormat Format)
|
||||||
{
|
{
|
||||||
switch (Format)
|
switch (Format)
|
||||||
{
|
{
|
||||||
case SurfaceFormat.A1_B5_G5_R5_UNORM: return DDSCompressor.DecodePixelBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_B5G5R5A1_UNORM);
|
case SurfaceFormat.BC1_UNORM: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM;
|
||||||
case SurfaceFormat.A4_B4_G4_R4_UNORM: return DDSCompressor.DecodePixelBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_B4G4R4A4_UNORM);
|
case SurfaceFormat.BC1_SRGB: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM_SRGB;
|
||||||
case SurfaceFormat.B5_G5_R5_A1_UNORM: return DDSCompressor.DecodePixelBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_B5G5R5A1_UNORM);
|
case SurfaceFormat.BC2_UNORM: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM;
|
||||||
case SurfaceFormat.B5_G6_R5_UNORM: return DDSCompressor.DecodePixelBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_B5G6R5_UNORM);
|
case SurfaceFormat.BC2_SRGB: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM_SRGB;
|
||||||
case SurfaceFormat.B8_G8_R8_A8_SRGB: return DDSCompressor.DecodePixelBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM_SRGB);
|
case SurfaceFormat.BC3_UNORM: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM;
|
||||||
case SurfaceFormat.B8_G8_R8_A8_UNORM: return DDSCompressor.DecodePixelBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM);
|
case SurfaceFormat.BC3_SRGB: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM_SRGB;
|
||||||
case SurfaceFormat.R10_G10_B10_A2_UNORM: return DDSCompressor.DecodePixelBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_R10G10B10A2_UNORM);
|
case SurfaceFormat.BC4_UNORM: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC4_UNORM;
|
||||||
case SurfaceFormat.R11_G11_B10_FLOAT: return DDSCompressor.DecodePixelBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_R11G11B10_FLOAT);
|
case SurfaceFormat.BC4_SNORM: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC4_SNORM;
|
||||||
case SurfaceFormat.R16_UNORM: return DDSCompressor.DecodePixelBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_R16_UNORM);
|
case SurfaceFormat.BC5_UNORM: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC5_UNORM;
|
||||||
case SurfaceFormat.R32_FLOAT: return DDSCompressor.DecodePixelBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_R32_FLOAT);
|
case SurfaceFormat.BC5_SNORM: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC5_SNORM;
|
||||||
case SurfaceFormat.R4_G4_B4_A4_UNORM: return DDSCompressor.DecodePixelBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_B4G4R4A4_UNORM);
|
case SurfaceFormat.BC6_UFLOAT: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC6H_UF16;
|
||||||
case SurfaceFormat.R4_G4_UNORM: return DDSCompressor.DecodePixelBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_B4G4R4A4_UNORM);
|
case SurfaceFormat.BC6_FLOAT: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC6H_SF16;
|
||||||
case SurfaceFormat.R5_G5_B5_A1_UNORM: return DDSCompressor.DecodePixelBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_B5G5R5A1_UNORM);
|
case SurfaceFormat.BC7_UNORM: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM;
|
||||||
case SurfaceFormat.R5_G6_B5_UNORM: return DDSCompressor.DecodePixelBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_B5G6R5_UNORM);
|
case SurfaceFormat.BC7_SRGB: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM_SRGB;
|
||||||
case SurfaceFormat.R8_G8_B8_A8_SRGB: return DDSCompressor.DecodePixelBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM_SRGB);
|
case SurfaceFormat.Invalid: throw new Exception("Invalid Format");
|
||||||
case SurfaceFormat.R8_G8_B8_A8_UNORM: return data;
|
|
||||||
case SurfaceFormat.R8_G8_UNORM: return DDSCompressor.DecodePixelBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_R8G8_UNORM);
|
|
||||||
case SurfaceFormat.R8_UNORM: return DDSCompressor.DecodePixelBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_R8_UNORM);
|
|
||||||
default:
|
default:
|
||||||
return null;
|
throw new Exception($"Cannot convert format {Format}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static bool IsCompressedFormat(SurfaceFormat Format)
|
||||||
|
{
|
||||||
|
switch (Format)
|
||||||
|
{
|
||||||
|
case SurfaceFormat.BC1_UNORM:
|
||||||
|
case SurfaceFormat.BC1_SRGB:
|
||||||
|
case SurfaceFormat.BC2_UNORM:
|
||||||
|
case SurfaceFormat.BC2_SRGB:
|
||||||
|
case SurfaceFormat.BC3_UNORM:
|
||||||
|
case SurfaceFormat.BC3_SRGB:
|
||||||
|
case SurfaceFormat.BC4_UNORM:
|
||||||
|
case SurfaceFormat.BC4_SNORM:
|
||||||
|
case SurfaceFormat.BC5_UNORM:
|
||||||
|
case SurfaceFormat.BC5_SNORM:
|
||||||
|
case SurfaceFormat.BC6_UFLOAT:
|
||||||
|
case SurfaceFormat.BC6_FLOAT:
|
||||||
|
case SurfaceFormat.BC7_UNORM:
|
||||||
|
case SurfaceFormat.BC7_SRGB:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static bool IsAtscFormat(SurfaceFormat Format)
|
||||||
|
{
|
||||||
|
switch (Format)
|
||||||
|
{
|
||||||
|
case SurfaceFormat.ASTC_10x10_SRGB:
|
||||||
|
case SurfaceFormat.ASTC_10x10_UNORM:
|
||||||
|
case SurfaceFormat.ASTC_10x5_SRGB:
|
||||||
|
case SurfaceFormat.ASTC_10x5_UNORM:
|
||||||
|
case SurfaceFormat.ASTC_10x6_SRGB:
|
||||||
|
case SurfaceFormat.ASTC_10x6_UNORM:
|
||||||
|
case SurfaceFormat.ASTC_10x8_SRGB:
|
||||||
|
case SurfaceFormat.ASTC_10x8_UNORM:
|
||||||
|
case SurfaceFormat.ASTC_12x10_SRGB:
|
||||||
|
case SurfaceFormat.ASTC_12x10_UNORM:
|
||||||
|
case SurfaceFormat.ASTC_12x12_SRGB:
|
||||||
|
case SurfaceFormat.ASTC_12x12_UNORM:
|
||||||
|
case SurfaceFormat.ASTC_4x4_SRGB:
|
||||||
|
case SurfaceFormat.ASTC_5x4_SRGB:
|
||||||
|
case SurfaceFormat.ASTC_5x4_UNORM:
|
||||||
|
case SurfaceFormat.ASTC_5x5_SRGB:
|
||||||
|
case SurfaceFormat.ASTC_5x5_UNORM:
|
||||||
|
case SurfaceFormat.ASTC_6x5_SRGB:
|
||||||
|
case SurfaceFormat.ASTC_6x5_UNORM:
|
||||||
|
case SurfaceFormat.ASTC_6x6_SRGB:
|
||||||
|
case SurfaceFormat.ASTC_6x6_UNORM:
|
||||||
|
case SurfaceFormat.ASTC_8x5_SRGB:
|
||||||
|
case SurfaceFormat.ASTC_8x5_UNORM:
|
||||||
|
case SurfaceFormat.ASTC_8x6_SRGB:
|
||||||
|
case SurfaceFormat.ASTC_8x6_UNORM:
|
||||||
|
case SurfaceFormat.ASTC_8x8_SRGB:
|
||||||
|
case SurfaceFormat.ASTC_8x8_UNORM:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public static Bitmap SwapBlueRedChannels(Bitmap bitmap)
|
public static Bitmap SwapBlueRedChannels(Bitmap bitmap)
|
||||||
|
@ -857,45 +989,12 @@ namespace FirstPlugin
|
||||||
}
|
}
|
||||||
public static byte[] CompressBlock(byte[] data, int width, int height, SurfaceFormat format)
|
public static byte[] CompressBlock(byte[] data, int width, int height, SurfaceFormat format)
|
||||||
{
|
{
|
||||||
switch (format)
|
if (IsCompressedFormat(format))
|
||||||
{
|
return DDSCompressor.CompressBlock(data, width, height, GetCompressedDXGI_FORMAT(format));
|
||||||
case SurfaceFormat.A1_B5_G5_R5_UNORM: return DDSCompressor.EncodePixelBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_B5G5R5A1_UNORM);
|
else if (IsAtscFormat(format))
|
||||||
case SurfaceFormat.A4_B4_G4_R4_UNORM: return DDSCompressor.EncodePixelBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_B4G4R4A4_UNORM);
|
return null;
|
||||||
case SurfaceFormat.B5_G5_R5_A1_UNORM: return DDSCompressor.EncodePixelBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_B5G5R5A1_UNORM);
|
else
|
||||||
case SurfaceFormat.B5_G6_R5_UNORM: return DDSCompressor.EncodePixelBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_B5G6R5_UNORM);
|
return DDSCompressor.EncodePixelBlock(data, width, height, GetUncompressedDXGI_FORMAT(format));
|
||||||
case SurfaceFormat.B8_G8_R8_A8_SRGB: return DDSCompressor.EncodePixelBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM_SRGB);
|
|
||||||
case SurfaceFormat.B8_G8_R8_A8_UNORM: return DDSCompressor.EncodePixelBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM);
|
|
||||||
case SurfaceFormat.R10_G10_B10_A2_UNORM: return DDSCompressor.EncodePixelBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_R10G10B10A2_UNORM);
|
|
||||||
case SurfaceFormat.R11_G11_B10_FLOAT: return DDSCompressor.EncodePixelBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_R11G11B10_FLOAT);
|
|
||||||
case SurfaceFormat.R16_UNORM: return DDSCompressor.EncodePixelBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_R16_UNORM);
|
|
||||||
case SurfaceFormat.R32_FLOAT: return DDSCompressor.EncodePixelBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_R32_FLOAT);
|
|
||||||
case SurfaceFormat.R4_G4_B4_A4_UNORM: return DDSCompressor.EncodePixelBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_B4G4R4A4_UNORM);
|
|
||||||
case SurfaceFormat.R4_G4_UNORM: return DDSCompressor.EncodePixelBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_B4G4R4A4_UNORM);
|
|
||||||
case SurfaceFormat.R5_G5_B5_A1_UNORM: return DDSCompressor.EncodePixelBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_B5G5R5A1_UNORM);
|
|
||||||
case SurfaceFormat.R5_G6_B5_UNORM: return DDSCompressor.EncodePixelBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_B5G6R5_UNORM);
|
|
||||||
case SurfaceFormat.R8_G8_B8_A8_SRGB: return DDSCompressor.EncodePixelBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM_SRGB);
|
|
||||||
case SurfaceFormat.R8_G8_B8_A8_UNORM: return data;
|
|
||||||
case SurfaceFormat.R8_G8_UNORM: return DDSCompressor.EncodePixelBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_R8G8_UNORM);
|
|
||||||
case SurfaceFormat.R8_UNORM: return DDSCompressor.EncodePixelBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_R8_UNORM);
|
|
||||||
|
|
||||||
|
|
||||||
case SurfaceFormat.BC1_UNORM: return DDSCompressor.CompressBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM);
|
|
||||||
case SurfaceFormat.BC1_SRGB: return DDSCompressor.CompressBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM_SRGB);
|
|
||||||
case SurfaceFormat.BC2_UNORM: return DDSCompressor.CompressBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM);
|
|
||||||
case SurfaceFormat.BC2_SRGB: return DDSCompressor.CompressBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM_SRGB);
|
|
||||||
case SurfaceFormat.BC3_UNORM: return DDSCompressor.CompressBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM);
|
|
||||||
case SurfaceFormat.BC3_SRGB: return DDSCompressor.CompressBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM_SRGB);
|
|
||||||
case SurfaceFormat.BC4_UNORM: return DDSCompressor.CompressBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_BC4_UNORM);
|
|
||||||
case SurfaceFormat.BC4_SNORM: return DDSCompressor.CompressBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_BC4_SNORM);
|
|
||||||
case SurfaceFormat.BC5_UNORM: return DDSCompressor.CompressBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_BC5_UNORM);
|
|
||||||
case SurfaceFormat.BC5_SNORM: return DDSCompressor.CompressBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_BC5_SNORM);
|
|
||||||
case SurfaceFormat.BC6_UFLOAT: return DDSCompressor.CompressBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_BC6H_UF16);
|
|
||||||
case SurfaceFormat.BC6_FLOAT: return DDSCompressor.CompressBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_BC6H_SF16);
|
|
||||||
case SurfaceFormat.BC7_UNORM: return DDSCompressor.CompressBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM);
|
|
||||||
case SurfaceFormat.BC7_SRGB: return DDSCompressor.CompressBlock(data, width, height, DDS.DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM_SRGB);
|
|
||||||
default:
|
|
||||||
throw new Exception($"Format {format} unsupported and cannot be compressed!");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
public unsafe Bitmap GLTextureToBitmap(BRTI_Texture t, int id)
|
public unsafe Bitmap GLTextureToBitmap(BRTI_Texture t, int id)
|
||||||
{
|
{
|
||||||
|
@ -990,18 +1089,13 @@ 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|*.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|" +
|
||||||
"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|*.bftex;*.dds|" +
|
|
||||||
"Binary Texture |*.bftex|" +
|
|
||||||
"Microsoft DDS |*.dds|" +
|
|
||||||
"All files(*.*)|*.*";
|
"All files(*.*)|*.*";
|
||||||
|
|
||||||
ofd.Multiselect = false;
|
ofd.Multiselect = false;
|
||||||
|
@ -1015,26 +1109,47 @@ namespace FirstPlugin
|
||||||
string ext = Path.GetExtension(FileName);
|
string ext = Path.GetExtension(FileName);
|
||||||
ext = ext.ToLower();
|
ext = ext.ToLower();
|
||||||
|
|
||||||
|
TextureImporterSettings setting = new TextureImporterSettings();
|
||||||
|
BinaryTextureImporterList importer = new BinaryTextureImporterList();
|
||||||
|
|
||||||
switch (ext)
|
switch (ext)
|
||||||
{
|
{
|
||||||
case ".bftex":
|
case ".bftex":
|
||||||
Texture.Import(FileName);
|
Texture.Import(FileName);
|
||||||
break;
|
break;
|
||||||
case ".dds":
|
case ".dds":
|
||||||
TextureImporterSettings importDDS = new TextureImporterSettings();
|
setting.LoadDDS(FileName, bntxFile, null, this);
|
||||||
importDDS.LoadDDS(FileName, bntxFile, null, this);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
TextureImporterSettings import = new TextureImporterSettings();
|
setting.LoadBitMap(FileName, bntxFile);
|
||||||
import.LoadBitMap(FileName, bntxFile, this);
|
importer.LoadSetting(setting, (BinaryTextureContainer)Parent);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (importer.ShowDialog() == DialogResult.OK)
|
||||||
|
{
|
||||||
|
Cursor.Current = Cursors.WaitCursor;
|
||||||
|
|
||||||
|
if (setting.GenerateMipmaps)
|
||||||
|
{
|
||||||
|
setting.DataBlockOutput.Clear();
|
||||||
|
setting.DataBlockOutput.Add(setting.GenerateMips());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setting.DataBlockOutput != null)
|
||||||
|
{
|
||||||
|
Texture = setting.FromBitMap(setting.DataBlockOutput[0], setting);
|
||||||
|
LoadTexture(Texture, 1);
|
||||||
|
LoadOpenGLTexture();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MessageBox.Show("Something went wrong???");
|
||||||
|
}
|
||||||
Texture.Name = Text;
|
Texture.Name = Text;
|
||||||
UpdateBfresTextureMapping();
|
UpdateBfresTextureMapping();
|
||||||
if (BNTXEditor != null)
|
|
||||||
{
|
UpdateEditor();
|
||||||
BNTXEditor.LoadPicture(DisplayTexture());
|
|
||||||
BNTXEditor.LoadProperty(this);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private void UpdateBfresTextureMapping()
|
private void UpdateBfresTextureMapping()
|
||||||
|
|
|
@ -444,48 +444,91 @@ namespace FirstPlugin
|
||||||
|
|
||||||
byte[] data = renderedTex.mipmaps[ArrayIndex][DisplayMipIndex];
|
byte[] data = renderedTex.mipmaps[ArrayIndex][DisplayMipIndex];
|
||||||
|
|
||||||
return DecodeBlock(data, width, height, format);
|
return DecodeBlock(data, width, height, (GX2SurfaceFormat)format);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Bitmap DecodeBlock(byte[] data, uint Width, uint Height, int Format)
|
public static Bitmap DecodeBlock(byte[] data, uint Width, uint Height, GX2SurfaceFormat Format)
|
||||||
{
|
{
|
||||||
Bitmap decomp;
|
Bitmap decomp;
|
||||||
|
|
||||||
|
if (Format == GX2SurfaceFormat.T_BC5_SNorm)
|
||||||
|
return DDSCompressor.DecompressBC5(data, (int)Width, (int)Height, true);
|
||||||
|
|
||||||
|
byte[] d = null;
|
||||||
|
if (IsCompressedFormat(Format))
|
||||||
|
d = DDSCompressor.DecompressBlock(data, (int)Width, (int)Height, GetCompressedDXGI_FORMAT(Format));
|
||||||
|
else
|
||||||
|
d = DDSCompressor.DecodePixelBlock(data, (int)Width, (int)Height, GetUncompressedDXGI_FORMAT(Format));
|
||||||
|
|
||||||
|
if (d != null)
|
||||||
|
{
|
||||||
|
decomp = BitmapExtension.GetBitmap(d, (int)Width, (int)Height);
|
||||||
|
return SwapBlueRedChannels(decomp);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
private static DDS.DXGI_FORMAT GetUncompressedDXGI_FORMAT(GX2SurfaceFormat Format)
|
||||||
|
{
|
||||||
switch (Format)
|
switch (Format)
|
||||||
{
|
{
|
||||||
case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC1_UNORM):
|
case GX2SurfaceFormat.TC_A1_B5_G5_R5_UNorm: return DDS.DXGI_FORMAT.DXGI_FORMAT_B5G5R5A1_UNORM;
|
||||||
decomp = DDSCompressor.DecompressBC1(data, (int)Width, (int)Height, false); break;
|
case GX2SurfaceFormat.TC_R4_G4_B4_A4_UNorm: return DDS.DXGI_FORMAT.DXGI_FORMAT_B4G4R4A4_UNORM;
|
||||||
case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC1_SRGB):
|
case GX2SurfaceFormat.TCS_R5_G6_B5_UNorm: return DDS.DXGI_FORMAT.DXGI_FORMAT_B5G6R5_UNORM;
|
||||||
decomp = DDSCompressor.DecompressBC1(data, (int)Width, (int)Height, true); break;
|
case GX2SurfaceFormat.TCS_R8_G8_B8_A8_SRGB: return DDS.DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
|
||||||
case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC3_UNORM):
|
case GX2SurfaceFormat.TCS_R8_G8_B8_A8_UNorm: return DDS.DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||||
decomp = DDSCompressor.DecompressBC3(data, (int)Width, (int)Height, false); break;
|
case GX2SurfaceFormat.TCS_R10_G10_B10_A2_UNorm: return DDS.DXGI_FORMAT.DXGI_FORMAT_R10G10B10A2_UNORM;
|
||||||
case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC3_SRGB):
|
case GX2SurfaceFormat.TC_R11_G11_B10_Float: return DDS.DXGI_FORMAT.DXGI_FORMAT_R11G11B10_FLOAT;
|
||||||
decomp = DDSCompressor.DecompressBC3(data, (int)Width, (int)Height, true); break;
|
case GX2SurfaceFormat.TCD_R16_UNorm: return DDS.DXGI_FORMAT.DXGI_FORMAT_R16_UNORM;
|
||||||
case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC4_UNORM):
|
case GX2SurfaceFormat.TCD_R32_Float: return DDS.DXGI_FORMAT.DXGI_FORMAT_R32_FLOAT;
|
||||||
decomp = DDSCompressor.DecompressBC4(data, (int)Width, (int)Height, false); break;
|
case GX2SurfaceFormat.T_R4_G4_UNorm: return DDS.DXGI_FORMAT.DXGI_FORMAT_B4G4R4A4_UNORM;
|
||||||
case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC4_SNORM):
|
case GX2SurfaceFormat.TC_R8_G8_UNorm: return DDS.DXGI_FORMAT.DXGI_FORMAT_R8G8_UNORM;
|
||||||
decomp = DDSCompressor.DecompressBC4(data, (int)Width, (int)Height, true); break;
|
case GX2SurfaceFormat.TC_R8_UNorm: return DDS.DXGI_FORMAT.DXGI_FORMAT_R8_UNORM;
|
||||||
case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC5_UNORM):
|
case GX2SurfaceFormat.Invalid: throw new Exception("Invalid Format");
|
||||||
decomp = DDSCompressor.DecompressBC5(data, (int)Width, (int)Height, false); break;
|
|
||||||
case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC5_SNORM):
|
|
||||||
decomp = DDSCompressor.DecompressBC5(data, (int)Width, (int)Height, true); break;
|
|
||||||
case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_TC_R8_G8_B8_A8_SNORM):
|
|
||||||
byte[] dec = DDSCompressor.DecodePixelBlock(data, (int)Width, (int)Height, DDS.DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM_SRGB);
|
|
||||||
decomp = BitmapExtension.GetBitmap(dec, (int)Width, (int)Height);
|
|
||||||
decomp = TextureData.SwapBlueRedChannels(decomp);
|
|
||||||
break;
|
|
||||||
case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_TC_R8_G8_B8_A8_UINT):
|
|
||||||
decomp = BitmapExtension.GetBitmap(data, (int)Width, (int)Height);
|
|
||||||
decomp = TextureData.SwapBlueRedChannels(decomp);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
decomp = Properties.Resources.TextureError;
|
throw new Exception($"Cannot convert format {Format}");
|
||||||
Console.WriteLine($"Format {Format} not supported!");
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return decomp;
|
|
||||||
}
|
}
|
||||||
|
private static bool IsCompressedFormat(GX2SurfaceFormat Format)
|
||||||
|
{
|
||||||
|
switch (Format)
|
||||||
|
{
|
||||||
|
case GX2SurfaceFormat.T_BC1_UNorm:
|
||||||
|
case GX2SurfaceFormat.T_BC1_SRGB:
|
||||||
|
case GX2SurfaceFormat.T_BC2_SRGB:
|
||||||
|
case GX2SurfaceFormat.T_BC2_UNorm:
|
||||||
|
case GX2SurfaceFormat.T_BC3_UNorm:
|
||||||
|
case GX2SurfaceFormat.T_BC3_SRGB:
|
||||||
|
case GX2SurfaceFormat.T_BC4_UNorm:
|
||||||
|
case GX2SurfaceFormat.T_BC4_SNorm:
|
||||||
|
case GX2SurfaceFormat.T_BC5_UNorm:
|
||||||
|
case GX2SurfaceFormat.T_BC5_SNorm:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static DDS.DXGI_FORMAT GetCompressedDXGI_FORMAT(GX2SurfaceFormat Format)
|
||||||
|
{
|
||||||
|
switch (Format)
|
||||||
|
{
|
||||||
|
case GX2SurfaceFormat.T_BC1_UNorm: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM;
|
||||||
|
case GX2SurfaceFormat.T_BC1_SRGB: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM_SRGB;
|
||||||
|
case GX2SurfaceFormat.T_BC2_SRGB: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM;
|
||||||
|
case GX2SurfaceFormat.T_BC2_UNorm: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM_SRGB;
|
||||||
|
case GX2SurfaceFormat.T_BC3_UNorm: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM;
|
||||||
|
case GX2SurfaceFormat.T_BC3_SRGB: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM_SRGB;
|
||||||
|
case GX2SurfaceFormat.T_BC4_UNorm: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC4_UNORM;
|
||||||
|
case GX2SurfaceFormat.T_BC4_SNorm: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC4_SNORM;
|
||||||
|
case GX2SurfaceFormat.T_BC5_UNorm: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC5_UNORM;
|
||||||
|
case GX2SurfaceFormat.T_BC5_SNorm: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC5_SNORM;
|
||||||
|
default:
|
||||||
|
throw new Exception($"Cannot convert format {Format}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static Bitmap SwapBlueRedChannels(Bitmap bitmap)
|
||||||
|
{
|
||||||
|
return ColorComponentSelector(bitmap, GX2CompSel.ChannelB, GX2CompSel.ChannelG, GX2CompSel.ChannelR, GX2CompSel.ChannelA);
|
||||||
|
}
|
||||||
public Bitmap UpdateBitmap(Bitmap image)
|
public Bitmap UpdateBitmap(Bitmap image)
|
||||||
{
|
{
|
||||||
return ColorComponentSelector(image, ChannelRed, ChannelGreen, ChannelBlue, ChannelAlpha);
|
return ColorComponentSelector(image, ChannelRed, ChannelGreen, ChannelBlue, ChannelAlpha);
|
||||||
|
@ -502,9 +545,9 @@ namespace FirstPlugin
|
||||||
if (R == GX2CompSel.ChannelA)
|
if (R == GX2CompSel.ChannelA)
|
||||||
color.CompRed = BitmapExtension.ColorSwapFilter.Red.Alpha;
|
color.CompRed = BitmapExtension.ColorSwapFilter.Red.Alpha;
|
||||||
if (R == GX2CompSel.Always0)
|
if (R == GX2CompSel.Always0)
|
||||||
color.CompRed = BitmapExtension.ColorSwapFilter.Red.One;
|
|
||||||
if (R == GX2CompSel.Always1)
|
|
||||||
color.CompRed = BitmapExtension.ColorSwapFilter.Red.Zero;
|
color.CompRed = BitmapExtension.ColorSwapFilter.Red.Zero;
|
||||||
|
if (R == GX2CompSel.Always1)
|
||||||
|
color.CompRed = BitmapExtension.ColorSwapFilter.Red.One;
|
||||||
|
|
||||||
if (G == GX2CompSel.ChannelR)
|
if (G == GX2CompSel.ChannelR)
|
||||||
color.CompGreen = BitmapExtension.ColorSwapFilter.Green.Red;
|
color.CompGreen = BitmapExtension.ColorSwapFilter.Green.Red;
|
||||||
|
@ -515,9 +558,9 @@ namespace FirstPlugin
|
||||||
if (G == GX2CompSel.ChannelA)
|
if (G == GX2CompSel.ChannelA)
|
||||||
color.CompGreen = BitmapExtension.ColorSwapFilter.Green.Alpha;
|
color.CompGreen = BitmapExtension.ColorSwapFilter.Green.Alpha;
|
||||||
if (G == GX2CompSel.Always0)
|
if (G == GX2CompSel.Always0)
|
||||||
color.CompGreen = BitmapExtension.ColorSwapFilter.Green.One;
|
|
||||||
if (G == GX2CompSel.Always1)
|
|
||||||
color.CompGreen = BitmapExtension.ColorSwapFilter.Green.Zero;
|
color.CompGreen = BitmapExtension.ColorSwapFilter.Green.Zero;
|
||||||
|
if (G == GX2CompSel.Always1)
|
||||||
|
color.CompGreen = BitmapExtension.ColorSwapFilter.Green.One;
|
||||||
|
|
||||||
if (B == GX2CompSel.ChannelR)
|
if (B == GX2CompSel.ChannelR)
|
||||||
color.CompBlue = BitmapExtension.ColorSwapFilter.Blue.Red;
|
color.CompBlue = BitmapExtension.ColorSwapFilter.Blue.Red;
|
||||||
|
@ -528,9 +571,9 @@ namespace FirstPlugin
|
||||||
if (B == GX2CompSel.ChannelA)
|
if (B == GX2CompSel.ChannelA)
|
||||||
color.CompBlue = BitmapExtension.ColorSwapFilter.Blue.Alpha;
|
color.CompBlue = BitmapExtension.ColorSwapFilter.Blue.Alpha;
|
||||||
if (B == GX2CompSel.Always0)
|
if (B == GX2CompSel.Always0)
|
||||||
color.CompBlue = BitmapExtension.ColorSwapFilter.Blue.One;
|
|
||||||
if (B == GX2CompSel.Always1)
|
|
||||||
color.CompBlue = BitmapExtension.ColorSwapFilter.Blue.Zero;
|
color.CompBlue = BitmapExtension.ColorSwapFilter.Blue.Zero;
|
||||||
|
if (B == GX2CompSel.Always1)
|
||||||
|
color.CompBlue = BitmapExtension.ColorSwapFilter.Blue.One;
|
||||||
|
|
||||||
if (A == GX2CompSel.ChannelR)
|
if (A == GX2CompSel.ChannelR)
|
||||||
color.CompAlpha = BitmapExtension.ColorSwapFilter.Alpha.Red;
|
color.CompAlpha = BitmapExtension.ColorSwapFilter.Alpha.Red;
|
||||||
|
@ -541,9 +584,9 @@ namespace FirstPlugin
|
||||||
if (A == GX2CompSel.ChannelA)
|
if (A == GX2CompSel.ChannelA)
|
||||||
color.CompAlpha = BitmapExtension.ColorSwapFilter.Alpha.Alpha;
|
color.CompAlpha = BitmapExtension.ColorSwapFilter.Alpha.Alpha;
|
||||||
if (A == GX2CompSel.Always0)
|
if (A == GX2CompSel.Always0)
|
||||||
color.CompAlpha = BitmapExtension.ColorSwapFilter.Alpha.One;
|
|
||||||
if (A == GX2CompSel.Always1)
|
|
||||||
color.CompAlpha = BitmapExtension.ColorSwapFilter.Alpha.Zero;
|
color.CompAlpha = BitmapExtension.ColorSwapFilter.Alpha.Zero;
|
||||||
|
if (A == GX2CompSel.Always1)
|
||||||
|
color.CompAlpha = BitmapExtension.ColorSwapFilter.Alpha.One;
|
||||||
|
|
||||||
return BitmapExtension.SwapRGB(image, color);
|
return BitmapExtension.SwapRGB(image, color);
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,10 +33,8 @@ namespace FirstPlugin
|
||||||
|
|
||||||
public Shader shader = null;
|
public Shader shader = null;
|
||||||
public List<FMDL> models = new List<FMDL>();
|
public List<FMDL> models = new List<FMDL>();
|
||||||
public AnimationGroupNode SkeletonAnimGroup;
|
|
||||||
|
|
||||||
public ResourceFile ResFileNode;
|
public ResourceFile ResFileNode;
|
||||||
public Action SaveFile;
|
|
||||||
|
|
||||||
public BFRESRender()
|
public BFRESRender()
|
||||||
{
|
{
|
||||||
|
@ -492,6 +490,7 @@ namespace FirstPlugin
|
||||||
{
|
{
|
||||||
if (bntx.Textures.ContainsKey(t.Name))
|
if (bntx.Textures.ContainsKey(t.Name))
|
||||||
{
|
{
|
||||||
|
if (!bntx.Textures[t.Name].GLInitialized)
|
||||||
bntx.Textures[t.Name].LoadOpenGLTexture();
|
bntx.Textures[t.Name].LoadOpenGLTexture();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -505,12 +504,16 @@ namespace FirstPlugin
|
||||||
return;
|
return;
|
||||||
|
|
||||||
foreach (BinaryTextureContainer bntx in PluginRuntime.bntxContainers)
|
foreach (BinaryTextureContainer bntx in PluginRuntime.bntxContainers)
|
||||||
|
{
|
||||||
|
if (!bntx.AllGLInitialized)
|
||||||
{
|
{
|
||||||
foreach (var tex in bntx.Textures)
|
foreach (var tex in bntx.Textures)
|
||||||
{
|
{
|
||||||
|
if (!tex.Value.GLInitialized)
|
||||||
tex.Value.LoadOpenGLTexture();
|
tex.Value.LoadOpenGLTexture();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
foreach (FTEXContainer ftexCont in PluginRuntime.ftexContainers)
|
foreach (FTEXContainer ftexCont in PluginRuntime.ftexContainers)
|
||||||
{
|
{
|
||||||
foreach (var tex in ftexCont.Textures)
|
foreach (var tex in ftexCont.Textures)
|
||||||
|
|
|
@ -19,7 +19,6 @@ namespace FirstPlugin
|
||||||
public void LoadTexture(TextureData tex)
|
public void LoadTexture(TextureData tex)
|
||||||
{
|
{
|
||||||
TextureData.BRTI_Texture renderedTex = tex.renderedGLTex;
|
TextureData.BRTI_Texture renderedTex = tex.renderedGLTex;
|
||||||
bntxEditor1.LoadPicture(tex.GLTextureToBitmap(renderedTex, renderedTex.display));
|
|
||||||
bntxEditor1.LoadProperty(tex);
|
bntxEditor1.LoadProperty(tex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,16 +28,15 @@ namespace FirstPlugin
|
||||||
imageBGComboBox.SelectedItem = Runtime.pictureBoxStyle;
|
imageBGComboBox.SelectedItem = Runtime.pictureBoxStyle;
|
||||||
UpdateBackgroundImage();
|
UpdateBackgroundImage();
|
||||||
}
|
}
|
||||||
public void LoadPicture(Bitmap image)
|
|
||||||
{
|
|
||||||
// pictureBoxCustom1.Image = image;
|
|
||||||
}
|
|
||||||
|
|
||||||
TextureData textureData;
|
TextureData textureData;
|
||||||
int CurMipDisplayLevel = 0;
|
int CurMipDisplayLevel = 0;
|
||||||
int CurArrayDisplayLevel = 0;
|
int CurArrayDisplayLevel = 0;
|
||||||
public void LoadProperty(TextureData tex)
|
public void LoadProperty(TextureData tex)
|
||||||
{
|
{
|
||||||
|
pictureBoxCustom1.Image = Imaging.GetLoadingImage();
|
||||||
|
LoadImage();
|
||||||
|
|
||||||
CurMipDisplayLevel = 0;
|
CurMipDisplayLevel = 0;
|
||||||
CurArrayDisplayLevel = 0;
|
CurArrayDisplayLevel = 0;
|
||||||
|
|
||||||
|
@ -48,11 +47,8 @@ namespace FirstPlugin
|
||||||
propertyGrid1.SelectedObject = texture;
|
propertyGrid1.SelectedObject = texture;
|
||||||
UpdateMipDisplay();
|
UpdateMipDisplay();
|
||||||
}
|
}
|
||||||
private void UpdateMipDisplay()
|
private void LoadImage()
|
||||||
{
|
{
|
||||||
mipLevelCounterLabel.Text = $"{CurMipDisplayLevel} / {textureData.mipmaps[CurArrayDisplayLevel].Count - 1}";
|
|
||||||
arrayLevelCounterLabel.Text = $"{CurArrayDisplayLevel} / {textureData.mipmaps.Count - 1}";
|
|
||||||
|
|
||||||
if (Thread != null && Thread.IsAlive)
|
if (Thread != null && Thread.IsAlive)
|
||||||
Thread.Abort();
|
Thread.Abort();
|
||||||
|
|
||||||
|
@ -60,13 +56,26 @@ namespace FirstPlugin
|
||||||
{
|
{
|
||||||
pictureBoxCustom1.Image = Imaging.GetLoadingImage();
|
pictureBoxCustom1.Image = Imaging.GetLoadingImage();
|
||||||
pictureBoxCustom1.Image = textureData.DisplayTexture(CurMipDisplayLevel, CurArrayDisplayLevel);
|
pictureBoxCustom1.Image = textureData.DisplayTexture(CurMipDisplayLevel, CurArrayDisplayLevel);
|
||||||
|
|
||||||
// texSizeMipsLabel.Text = $"Width = {pictureBoxCustom1.Image.Width} Height = {pictureBoxCustom1.Image.Height}";
|
|
||||||
}));
|
}));
|
||||||
Thread.Start();
|
Thread.Start();
|
||||||
|
|
||||||
|
GC.Collect();
|
||||||
|
}
|
||||||
|
private void UpdateMipDisplay()
|
||||||
|
{
|
||||||
|
LoadImage();
|
||||||
|
|
||||||
if (CurMipDisplayLevel != textureData.mipmaps[CurArrayDisplayLevel].Count - 1)
|
int MipCount = 1;
|
||||||
|
if (textureData.mipmaps.Count <= 0)
|
||||||
|
return;
|
||||||
|
else
|
||||||
|
MipCount = textureData.mipmaps[CurArrayDisplayLevel].Count;
|
||||||
|
|
||||||
|
|
||||||
|
mipLevelCounterLabel.Text = $"{CurMipDisplayLevel} / {textureData.mipmaps[CurArrayDisplayLevel].Count - 1}";
|
||||||
|
arrayLevelCounterLabel.Text = $"{CurArrayDisplayLevel} / {textureData.mipmaps.Count - 1}";
|
||||||
|
|
||||||
|
if (CurMipDisplayLevel != MipCount - 1)
|
||||||
BtnMipsRight.Enabled = true;
|
BtnMipsRight.Enabled = true;
|
||||||
else
|
else
|
||||||
BtnMipsRight.Enabled = false;
|
BtnMipsRight.Enabled = false;
|
||||||
|
|
|
@ -79,10 +79,20 @@ namespace FirstPlugin
|
||||||
foreach (var setting in settings)
|
foreach (var setting in settings)
|
||||||
{
|
{
|
||||||
listViewCustom1.Items.Add(setting.TexName).SubItems.Add(setting.Format.ToString());
|
listViewCustom1.Items.Add(setting.TexName).SubItems.Add(setting.Format.ToString());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
listViewCustom1.Items[0].Selected = true;
|
||||||
|
listViewCustom1.Select();
|
||||||
}
|
}
|
||||||
|
public void LoadSetting(TextureImporterSettings setting, BinaryTextureContainer b)
|
||||||
|
{
|
||||||
|
settings = new List<TextureImporterSettings>();
|
||||||
|
settings.Add(setting);
|
||||||
|
bntx = b;
|
||||||
|
|
||||||
|
listViewCustom1.Items.Add(setting.TexName).SubItems.Add(setting.Format.ToString());
|
||||||
|
listViewCustom1.Items[0].Selected = true;
|
||||||
|
listViewCustom1.Select();
|
||||||
|
}
|
||||||
public bool IsCompressed(SurfaceFormat format)
|
public bool IsCompressed(SurfaceFormat format)
|
||||||
{
|
{
|
||||||
switch (format)
|
switch (format)
|
||||||
|
@ -163,18 +173,8 @@ namespace FirstPlugin
|
||||||
|
|
||||||
SetupSettings();
|
SetupSettings();
|
||||||
|
|
||||||
MipmapNum.Value = 0;
|
MipmapNum.Maximum = SelectedTexSettings.GetTotalMipCount();
|
||||||
|
MipmapNum.Value = SelectedTexSettings.MipCount;
|
||||||
uint num = Math.Max(SelectedTexSettings.TexHeight, SelectedTexSettings.TexWidth);
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
num >>= 1;
|
|
||||||
if (num > 0)
|
|
||||||
++MipmapNum.Value;
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
MipmapNum.Maximum = MipmapNum.Value;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,7 @@ namespace FirstPlugin
|
||||||
public int sparseResidency = 0; //false
|
public int sparseResidency = 0; //false
|
||||||
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
|
||||||
|
|
||||||
private SurfaceFormat LoadDDSFormat(string fourCC, DDS dds = null, bool IsSRGB = false)
|
private SurfaceFormat LoadDDSFormat(string fourCC, DDS dds = null, bool IsSRGB = false)
|
||||||
{
|
{
|
||||||
|
@ -135,6 +136,11 @@ namespace FirstPlugin
|
||||||
MipCount = dds.header.mipmapCount;
|
MipCount = dds.header.mipmapCount;
|
||||||
TexWidth = dds.header.width;
|
TexWidth = dds.header.width;
|
||||||
TexHeight = dds.header.height;
|
TexHeight = dds.header.height;
|
||||||
|
arrayLength = 1;
|
||||||
|
if (dds.header.caps2 == (uint)DDS.DDSCAPS2.CUBEMAP_ALLFACES)
|
||||||
|
{
|
||||||
|
arrayLength = 6;
|
||||||
|
}
|
||||||
|
|
||||||
DataBlockOutput.Add(dds.bdata);
|
DataBlockOutput.Add(dds.bdata);
|
||||||
|
|
||||||
|
@ -152,27 +158,22 @@ namespace FirstPlugin
|
||||||
textureData = new TextureData(tex, bntxFile);
|
textureData = new TextureData(tex, bntxFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void LoadBitMap(string FileName, BntxFile bntxFile, TextureData tree = null)
|
public void LoadBitMap(string FileName, BntxFile bntxFile)
|
||||||
{
|
{
|
||||||
DecompressedData.Clear();
|
DecompressedData.Clear();
|
||||||
|
|
||||||
TexName = Path.GetFileNameWithoutExtension(FileName);
|
TexName = Path.GetFileNameWithoutExtension(FileName);
|
||||||
bntx = bntxFile;
|
bntx = bntxFile;
|
||||||
textureData = tree;
|
|
||||||
Format = SurfaceFormat.BC1_SRGB;
|
Format = SurfaceFormat.BC1_SRGB;
|
||||||
|
GenerateMipmaps = true;
|
||||||
|
|
||||||
Bitmap Image = new Bitmap(FileName);
|
Bitmap Image = new Bitmap(FileName);
|
||||||
Image = TextureData.SwapBlueRedChannels(Image);
|
Image = TextureData.SwapBlueRedChannels(Image);
|
||||||
|
|
||||||
TexWidth = (uint)Image.Width;
|
TexWidth = (uint)Image.Width;
|
||||||
TexHeight = (uint)Image.Height;
|
TexHeight = (uint)Image.Height;
|
||||||
MipCount = 1;
|
MipCount = (uint)GetTotalMipCount();
|
||||||
|
|
||||||
List<byte[]> mipMaps = new List<byte[]>();
|
|
||||||
/* while(Image.Width / 2 > 0)
|
|
||||||
{
|
|
||||||
Image.SetResolution(Image.Width / 2, Image.Height / 2);
|
|
||||||
}*/
|
|
||||||
DecompressedData.Add(BitmapExtension.ImageToByte(Image));
|
DecompressedData.Add(BitmapExtension.ImageToByte(Image));
|
||||||
|
|
||||||
Image.Dispose();
|
Image.Dispose();
|
||||||
|
@ -181,6 +182,49 @@ namespace FirstPlugin
|
||||||
throw new Exception("Failed to load " + Format);
|
throw new Exception("Failed to load " + Format);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public int GetTotalMipCount()
|
||||||
|
{
|
||||||
|
int MipmapNum = 0;
|
||||||
|
uint num = Math.Max(TexHeight, TexWidth);
|
||||||
|
|
||||||
|
int width = (int)TexWidth;
|
||||||
|
int height = (int)TexHeight;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
num >>= 1;
|
||||||
|
|
||||||
|
width = width / 2;
|
||||||
|
height = height / 2;
|
||||||
|
if (width <= 0 || height <= 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (num > 0)
|
||||||
|
++MipmapNum;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MipmapNum;
|
||||||
|
}
|
||||||
|
public byte[] GenerateMips(int SurfaceLevel = 0)
|
||||||
|
{
|
||||||
|
Bitmap Image = BitmapExtension.GetBitmap(DecompressedData[SurfaceLevel], (int)TexWidth, (int)TexHeight);
|
||||||
|
|
||||||
|
List<byte[]> mipmaps = new List<byte[]>();
|
||||||
|
mipmaps.Add(TextureData.CompressBlock(DecompressedData[SurfaceLevel], (int)TexWidth, (int)TexHeight, Format));
|
||||||
|
|
||||||
|
//while (Image.Width / 2 > 0 && Image.Height / 2 > 0)
|
||||||
|
// for (int mipLevel = 0; mipLevel < MipCount; mipLevel++)
|
||||||
|
for (int mipLevel = 0; mipLevel < MipCount; mipLevel++)
|
||||||
|
{
|
||||||
|
Image = BitmapExtension.Resize(Image, Image.Width / 2, Image.Height / 2);
|
||||||
|
mipmaps.Add(TextureData.CompressBlock(BitmapExtension.ImageToByte(Image), Image.Width, Image.Height, Format));
|
||||||
|
}
|
||||||
|
Image.Dispose();
|
||||||
|
|
||||||
|
return Utils.CombineByteArray(mipmaps.ToArray());
|
||||||
|
}
|
||||||
public void Compress()
|
public void Compress()
|
||||||
{
|
{
|
||||||
DataBlockOutput.Clear();
|
DataBlockOutput.Clear();
|
||||||
|
@ -254,11 +298,19 @@ namespace FirstPlugin
|
||||||
|
|
||||||
tex.MipOffsets = new long[tex.MipCount];
|
tex.MipOffsets = new long[tex.MipCount];
|
||||||
|
|
||||||
List<byte[]> mipmaps = SwizzleSurfaceMipMaps(tex, data, tex.TileMode);
|
List<byte[]> arrayFaces = new List<byte[]>();
|
||||||
|
if (tex.ArrayLength > 1)
|
||||||
|
arrayFaces = DDS.GetArrayFaces(data, tex.ArrayLength);
|
||||||
|
else
|
||||||
|
arrayFaces.Add(data);
|
||||||
|
|
||||||
|
for (int i = 0; i < tex.ArrayLength; i++)
|
||||||
|
{
|
||||||
|
List<byte[]> mipmaps = SwizzleSurfaceMipMaps(tex, arrayFaces[i], tex.TileMode);
|
||||||
tex.TextureData.Add(mipmaps);
|
tex.TextureData.Add(mipmaps);
|
||||||
byte[] test = Combine(mipmaps);
|
byte[] test = Combine(mipmaps);
|
||||||
tex.TextureData[0][0] = test;
|
tex.TextureData[i][0] = test;
|
||||||
|
}
|
||||||
return tex;
|
return tex;
|
||||||
}
|
}
|
||||||
public static List<byte[]> SwizzleSurfaceMipMaps(FTEX tex, byte[] data)
|
public static List<byte[]> SwizzleSurfaceMipMaps(FTEX tex, byte[] data)
|
||||||
|
|
|
@ -16,32 +16,73 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GL_Core", "GL_EditorFramewo
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Updater", "Updater\Updater.csproj", "{D82A2C08-2A65-43AF-BDA6-A36CC27AA003}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Updater", "Updater\Updater.csproj", "{D82A2C08-2A65-43AF-BDA6-A36CC27AA003}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DirectXTex", "Switch_Toolbox\Lib\DirectXTex\DirectXTex.vcxproj", "{755AB64B-16B4-4C90-AA3B-BFF448E5A21E}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DirectXTexNet", "DirectXTexNet-master\DirectXTexNet\DirectXTexNet.csproj", "{98495BF2-DED3-4E08-B965-C12D471BC86F}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
Release|Any CPU = Release|Any CPU
|
Release|Any CPU = Release|Any CPU
|
||||||
|
Release|x64 = Release|x64
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{E861C28B-B039-48F7-9A4F-C83F67C0ADDE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{E861C28B-B039-48F7-9A4F-C83F67C0ADDE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{E861C28B-B039-48F7-9A4F-C83F67C0ADDE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{E861C28B-B039-48F7-9A4F-C83F67C0ADDE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{E861C28B-B039-48F7-9A4F-C83F67C0ADDE}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{E861C28B-B039-48F7-9A4F-C83F67C0ADDE}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
{E861C28B-B039-48F7-9A4F-C83F67C0ADDE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{E861C28B-B039-48F7-9A4F-C83F67C0ADDE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{E861C28B-B039-48F7-9A4F-C83F67C0ADDE}.Release|Any CPU.Build.0 = Release|Any CPU
|
{E861C28B-B039-48F7-9A4F-C83F67C0ADDE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{E861C28B-B039-48F7-9A4F-C83F67C0ADDE}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{E861C28B-B039-48F7-9A4F-C83F67C0ADDE}.Release|x64.Build.0 = Release|Any CPU
|
||||||
{A11705CF-A6A3-41C3-875A-E1CFD8080F09}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{A11705CF-A6A3-41C3-875A-E1CFD8080F09}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{A11705CF-A6A3-41C3-875A-E1CFD8080F09}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{A11705CF-A6A3-41C3-875A-E1CFD8080F09}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{A11705CF-A6A3-41C3-875A-E1CFD8080F09}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{A11705CF-A6A3-41C3-875A-E1CFD8080F09}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
{A11705CF-A6A3-41C3-875A-E1CFD8080F09}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{A11705CF-A6A3-41C3-875A-E1CFD8080F09}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{A11705CF-A6A3-41C3-875A-E1CFD8080F09}.Release|Any CPU.Build.0 = Release|Any CPU
|
{A11705CF-A6A3-41C3-875A-E1CFD8080F09}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{A11705CF-A6A3-41C3-875A-E1CFD8080F09}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{A11705CF-A6A3-41C3-875A-E1CFD8080F09}.Release|x64.Build.0 = Release|Any CPU
|
||||||
{96820047-2A39-4E5A-BFA4-E84FFF5C66CF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{96820047-2A39-4E5A-BFA4-E84FFF5C66CF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{96820047-2A39-4E5A-BFA4-E84FFF5C66CF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{96820047-2A39-4E5A-BFA4-E84FFF5C66CF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{96820047-2A39-4E5A-BFA4-E84FFF5C66CF}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{96820047-2A39-4E5A-BFA4-E84FFF5C66CF}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
{96820047-2A39-4E5A-BFA4-E84FFF5C66CF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{96820047-2A39-4E5A-BFA4-E84FFF5C66CF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{96820047-2A39-4E5A-BFA4-E84FFF5C66CF}.Release|Any CPU.Build.0 = Release|Any CPU
|
{96820047-2A39-4E5A-BFA4-E84FFF5C66CF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{96820047-2A39-4E5A-BFA4-E84FFF5C66CF}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{96820047-2A39-4E5A-BFA4-E84FFF5C66CF}.Release|x64.Build.0 = Release|Any CPU
|
||||||
{29647BA5-2859-46F0-A99E-C3A387A9447A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{29647BA5-2859-46F0-A99E-C3A387A9447A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{29647BA5-2859-46F0-A99E-C3A387A9447A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{29647BA5-2859-46F0-A99E-C3A387A9447A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{29647BA5-2859-46F0-A99E-C3A387A9447A}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{29647BA5-2859-46F0-A99E-C3A387A9447A}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
{29647BA5-2859-46F0-A99E-C3A387A9447A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{29647BA5-2859-46F0-A99E-C3A387A9447A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{29647BA5-2859-46F0-A99E-C3A387A9447A}.Release|Any CPU.Build.0 = Release|Any CPU
|
{29647BA5-2859-46F0-A99E-C3A387A9447A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{29647BA5-2859-46F0-A99E-C3A387A9447A}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{29647BA5-2859-46F0-A99E-C3A387A9447A}.Release|x64.Build.0 = Release|Any CPU
|
||||||
{D82A2C08-2A65-43AF-BDA6-A36CC27AA003}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{D82A2C08-2A65-43AF-BDA6-A36CC27AA003}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{D82A2C08-2A65-43AF-BDA6-A36CC27AA003}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{D82A2C08-2A65-43AF-BDA6-A36CC27AA003}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{D82A2C08-2A65-43AF-BDA6-A36CC27AA003}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{D82A2C08-2A65-43AF-BDA6-A36CC27AA003}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
{D82A2C08-2A65-43AF-BDA6-A36CC27AA003}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{D82A2C08-2A65-43AF-BDA6-A36CC27AA003}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{D82A2C08-2A65-43AF-BDA6-A36CC27AA003}.Release|Any CPU.Build.0 = Release|Any CPU
|
{D82A2C08-2A65-43AF-BDA6-A36CC27AA003}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{D82A2C08-2A65-43AF-BDA6-A36CC27AA003}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{D82A2C08-2A65-43AF-BDA6-A36CC27AA003}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{755AB64B-16B4-4C90-AA3B-BFF448E5A21E}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||||
|
{755AB64B-16B4-4C90-AA3B-BFF448E5A21E}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{755AB64B-16B4-4C90-AA3B-BFF448E5A21E}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{755AB64B-16B4-4C90-AA3B-BFF448E5A21E}.Release|Any CPU.ActiveCfg = Release|Win32
|
||||||
|
{755AB64B-16B4-4C90-AA3B-BFF448E5A21E}.Release|Any CPU.Build.0 = Release|Win32
|
||||||
|
{755AB64B-16B4-4C90-AA3B-BFF448E5A21E}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{755AB64B-16B4-4C90-AA3B-BFF448E5A21E}.Release|x64.Build.0 = Release|x64
|
||||||
|
{98495BF2-DED3-4E08-B965-C12D471BC86F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{98495BF2-DED3-4E08-B965-C12D471BC86F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{98495BF2-DED3-4E08-B965-C12D471BC86F}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{98495BF2-DED3-4E08-B965-C12D471BC86F}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{98495BF2-DED3-4E08-B965-C12D471BC86F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{98495BF2-DED3-4E08-B965-C12D471BC86F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{98495BF2-DED3-4E08-B965-C12D471BC86F}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{98495BF2-DED3-4E08-B965-C12D471BC86F}.Release|x64.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
|
@ -56,6 +56,9 @@ namespace Switch_Toolbox
|
||||||
case "RenderModelWireframe":
|
case "RenderModelWireframe":
|
||||||
bool.TryParse(node.InnerText, out Runtime.RenderModelWireframe);
|
bool.TryParse(node.InnerText, out Runtime.RenderModelWireframe);
|
||||||
break;
|
break;
|
||||||
|
case "EnablePBR":
|
||||||
|
bool.TryParse(node.InnerText, out Runtime.EnablePBR);
|
||||||
|
break;
|
||||||
case "viewportShading":
|
case "viewportShading":
|
||||||
if (node.ParentNode != null && node.ParentNode.Name.Equals("RENDERSETTINGS"))
|
if (node.ParentNode != null && node.ParentNode.Name.Equals("RENDERSETTINGS"))
|
||||||
Enum.TryParse(node.InnerText, out Runtime.viewportShading);
|
Enum.TryParse(node.InnerText, out Runtime.viewportShading);
|
||||||
|
@ -78,6 +81,7 @@ namespace Switch_Toolbox
|
||||||
case "Yaz0CompressionLevel":
|
case "Yaz0CompressionLevel":
|
||||||
int.TryParse(node.InnerText, out Runtime.Yaz0CompressionLevel);
|
int.TryParse(node.InnerText, out Runtime.Yaz0CompressionLevel);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,6 +131,7 @@ namespace Switch_Toolbox
|
||||||
renderSettingsNode.AppendChild(createNode(doc, "CameraFar", Runtime.CameraFar.ToString()));
|
renderSettingsNode.AppendChild(createNode(doc, "CameraFar", Runtime.CameraFar.ToString()));
|
||||||
renderSettingsNode.AppendChild(createNode(doc, "CameraNear", Runtime.CameraNear.ToString()));
|
renderSettingsNode.AppendChild(createNode(doc, "CameraNear", Runtime.CameraNear.ToString()));
|
||||||
renderSettingsNode.AppendChild(createNode(doc, "PreviewScale", Runtime.previewScale.ToString()));
|
renderSettingsNode.AppendChild(createNode(doc, "PreviewScale", Runtime.previewScale.ToString()));
|
||||||
|
renderSettingsNode.AppendChild(createNode(doc, "EnablePBR", Runtime.EnablePBR.ToString()));
|
||||||
}
|
}
|
||||||
public static XmlNode createNode(XmlDocument doc, string el, string v)
|
public static XmlNode createNode(XmlDocument doc, string el, string v)
|
||||||
{
|
{
|
||||||
|
|
37
Switch_Toolbox/GUI/Settings.Designer.cs
generated
37
Switch_Toolbox/GUI/Settings.Designer.cs
generated
|
@ -48,13 +48,14 @@
|
||||||
this.chkBoxStereoscopy = new System.Windows.Forms.CheckBox();
|
this.chkBoxStereoscopy = new System.Windows.Forms.CheckBox();
|
||||||
this.label2 = new System.Windows.Forms.Label();
|
this.label2 = new System.Windows.Forms.Label();
|
||||||
this.panel1 = new System.Windows.Forms.Panel();
|
this.panel1 = new System.Windows.Forms.Panel();
|
||||||
|
this.disableViewportCHKBX = new System.Windows.Forms.CheckBox();
|
||||||
this.GLSLVerLabel = new System.Windows.Forms.Label();
|
this.GLSLVerLabel = new System.Windows.Forms.Label();
|
||||||
this.openGLVerLabel = new System.Windows.Forms.Label();
|
this.openGLVerLabel = new System.Windows.Forms.Label();
|
||||||
this.btnSave = new System.Windows.Forms.Button();
|
this.btnSave = new System.Windows.Forms.Button();
|
||||||
this.label7 = new System.Windows.Forms.Label();
|
this.label7 = new System.Windows.Forms.Label();
|
||||||
this.yazoCompressionLevelUD = new System.Windows.Forms.NumericUpDown();
|
this.yazoCompressionLevelUD = new System.Windows.Forms.NumericUpDown();
|
||||||
this.panel3 = new System.Windows.Forms.Panel();
|
this.panel3 = new System.Windows.Forms.Panel();
|
||||||
this.disableViewportCHKBX = new System.Windows.Forms.CheckBox();
|
this.chkBoxEnablePBR = new System.Windows.Forms.CheckBox();
|
||||||
this.panel2.SuspendLayout();
|
this.panel2.SuspendLayout();
|
||||||
((System.ComponentModel.ISupportInitialize)(this.previewScaleUD)).BeginInit();
|
((System.ComponentModel.ISupportInitialize)(this.previewScaleUD)).BeginInit();
|
||||||
((System.ComponentModel.ISupportInitialize)(this.camFarNumUD)).BeginInit();
|
((System.ComponentModel.ISupportInitialize)(this.camFarNumUD)).BeginInit();
|
||||||
|
@ -111,6 +112,7 @@
|
||||||
//
|
//
|
||||||
// panel2
|
// panel2
|
||||||
//
|
//
|
||||||
|
this.panel2.Controls.Add(this.chkBoxEnablePBR);
|
||||||
this.panel2.Controls.Add(this.label6);
|
this.panel2.Controls.Add(this.label6);
|
||||||
this.panel2.Controls.Add(this.previewScaleUD);
|
this.panel2.Controls.Add(this.previewScaleUD);
|
||||||
this.panel2.Controls.Add(this.chkBoxDisplayPolyCount);
|
this.panel2.Controls.Add(this.chkBoxDisplayPolyCount);
|
||||||
|
@ -332,6 +334,18 @@
|
||||||
this.panel1.Size = new System.Drawing.Size(215, 137);
|
this.panel1.Size = new System.Drawing.Size(215, 137);
|
||||||
this.panel1.TabIndex = 5;
|
this.panel1.TabIndex = 5;
|
||||||
//
|
//
|
||||||
|
// disableViewportCHKBX
|
||||||
|
//
|
||||||
|
this.disableViewportCHKBX.AutoSize = true;
|
||||||
|
this.disableViewportCHKBX.ForeColor = System.Drawing.Color.White;
|
||||||
|
this.disableViewportCHKBX.Location = new System.Drawing.Point(0, 67);
|
||||||
|
this.disableViewportCHKBX.Name = "disableViewportCHKBX";
|
||||||
|
this.disableViewportCHKBX.Size = new System.Drawing.Size(105, 17);
|
||||||
|
this.disableViewportCHKBX.TabIndex = 16;
|
||||||
|
this.disableViewportCHKBX.Text = "Disable Viewport";
|
||||||
|
this.disableViewportCHKBX.UseVisualStyleBackColor = true;
|
||||||
|
this.disableViewportCHKBX.CheckedChanged += new System.EventHandler(this.checkBox1_CheckedChanged_2);
|
||||||
|
//
|
||||||
// GLSLVerLabel
|
// GLSLVerLabel
|
||||||
//
|
//
|
||||||
this.GLSLVerLabel.AutoSize = true;
|
this.GLSLVerLabel.AutoSize = true;
|
||||||
|
@ -404,17 +418,17 @@
|
||||||
this.panel3.Size = new System.Drawing.Size(313, 138);
|
this.panel3.Size = new System.Drawing.Size(313, 138);
|
||||||
this.panel3.TabIndex = 18;
|
this.panel3.TabIndex = 18;
|
||||||
//
|
//
|
||||||
// disableViewportCHKBX
|
// chkBoxEnablePBR
|
||||||
//
|
//
|
||||||
this.disableViewportCHKBX.AutoSize = true;
|
this.chkBoxEnablePBR.AutoSize = true;
|
||||||
this.disableViewportCHKBX.ForeColor = System.Drawing.Color.White;
|
this.chkBoxEnablePBR.ForeColor = System.Drawing.Color.White;
|
||||||
this.disableViewportCHKBX.Location = new System.Drawing.Point(0, 67);
|
this.chkBoxEnablePBR.Location = new System.Drawing.Point(258, 139);
|
||||||
this.disableViewportCHKBX.Name = "disableViewportCHKBX";
|
this.chkBoxEnablePBR.Name = "chkBoxEnablePBR";
|
||||||
this.disableViewportCHKBX.Size = new System.Drawing.Size(105, 17);
|
this.chkBoxEnablePBR.Size = new System.Drawing.Size(84, 17);
|
||||||
this.disableViewportCHKBX.TabIndex = 16;
|
this.chkBoxEnablePBR.TabIndex = 17;
|
||||||
this.disableViewportCHKBX.Text = "Disable Viewport";
|
this.chkBoxEnablePBR.Text = "Enable PBR";
|
||||||
this.disableViewportCHKBX.UseVisualStyleBackColor = true;
|
this.chkBoxEnablePBR.UseVisualStyleBackColor = true;
|
||||||
this.disableViewportCHKBX.CheckedChanged += new System.EventHandler(this.checkBox1_CheckedChanged_2);
|
this.chkBoxEnablePBR.CheckedChanged += new System.EventHandler(this.chkBoxEnablePBR_CheckedChanged);
|
||||||
//
|
//
|
||||||
// Settings
|
// Settings
|
||||||
//
|
//
|
||||||
|
@ -473,5 +487,6 @@
|
||||||
private System.Windows.Forms.NumericUpDown yazoCompressionLevelUD;
|
private System.Windows.Forms.NumericUpDown yazoCompressionLevelUD;
|
||||||
private System.Windows.Forms.Panel panel3;
|
private System.Windows.Forms.Panel panel3;
|
||||||
private System.Windows.Forms.CheckBox disableViewportCHKBX;
|
private System.Windows.Forms.CheckBox disableViewportCHKBX;
|
||||||
|
private System.Windows.Forms.CheckBox chkBoxEnablePBR;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -45,6 +45,7 @@ namespace Switch_Toolbox
|
||||||
previewScaleUD.Value = (decimal)Runtime.previewScale;
|
previewScaleUD.Value = (decimal)Runtime.previewScale;
|
||||||
yazoCompressionLevelUD.Value = Runtime.Yaz0CompressionLevel;
|
yazoCompressionLevelUD.Value = Runtime.Yaz0CompressionLevel;
|
||||||
disableViewportCHKBX.Checked = Runtime.DisableViewport;
|
disableViewportCHKBX.Checked = Runtime.DisableViewport;
|
||||||
|
chkBoxEnablePBR.Checked = Runtime.EnablePBR;
|
||||||
|
|
||||||
GLSLVerLabel.Text = $"Open GL Version: {Runtime.GLSLVersion}";
|
GLSLVerLabel.Text = $"Open GL Version: {Runtime.GLSLVersion}";
|
||||||
openGLVerLabel.Text = $"GLSL Version: {Runtime.openGLVersion}";
|
openGLVerLabel.Text = $"GLSL Version: {Runtime.openGLVersion}";
|
||||||
|
@ -139,5 +140,10 @@ namespace Switch_Toolbox
|
||||||
{
|
{
|
||||||
Runtime.DisableViewport = disableViewportCHKBX.Checked;
|
Runtime.DisableViewport = disableViewportCHKBX.Checked;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void chkBoxEnablePBR_CheckedChanged(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
Runtime.EnablePBR = chkBoxEnablePBR.Checked;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
25
Switch_Toolbox/Lib/DirectXTex.Build.CppClean.log
Normal file
25
Switch_Toolbox/Lib/DirectXTex.Build.CppClean.log
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
c:\users\nathan\documents\github\switch_toolbox\switch-toolbox - copy\switch_toolbox\lib\directxtex\release\vc141.pdb
|
||||||
|
c:\users\nathan\documents\github\switch_toolbox\switch-toolbox - copy\switch_toolbox\lib\directxtex\release\directxtexutil.obj
|
||||||
|
c:\users\nathan\documents\github\switch_toolbox\switch-toolbox - copy\switch_toolbox\lib\directxtex\release\directxtexmipmaps.obj
|
||||||
|
c:\users\nathan\documents\github\switch_toolbox\switch-toolbox - copy\switch_toolbox\lib\directxtex\release\directxteximage.obj
|
||||||
|
c:\users\nathan\documents\github\switch_toolbox\switch-toolbox - copy\switch_toolbox\lib\directxtex\release\directxtexdds.obj
|
||||||
|
c:\users\nathan\documents\github\switch_toolbox\switch-toolbox - copy\switch_toolbox\lib\directxtex\release\directxtexconvert.obj
|
||||||
|
c:\users\nathan\documents\github\switch_toolbox\switch-toolbox - copy\switch_toolbox\lib\directxtex\release\directxtexcompress.obj
|
||||||
|
c:\users\nathan\documents\github\switch_toolbox\switch-toolbox - copy\switch_toolbox\lib\directxtex\release\bc6hbc7.obj
|
||||||
|
c:\users\nathan\documents\github\switch_toolbox\switch-toolbox - copy\switch_toolbox\lib\directxtex\release\bc4bc5.obj
|
||||||
|
c:\users\nathan\documents\github\switch_toolbox\switch-toolbox - copy\switch_toolbox\lib\directxtex\release\bc.obj
|
||||||
|
c:\users\nathan\documents\github\switch_toolbox\switch-toolbox - copy\switch_toolbox\lib\directxtex\release\wrapper.obj
|
||||||
|
c:\users\nathan\documents\github\switch_toolbox\switch-toolbox - copy\switch_toolbox\lib\directxtex\release\.netframework,version=v4.6.assemblyattributes.obj
|
||||||
|
c:\users\nathan\documents\github\switch_toolbox\switch-toolbox - copy\switch_toolbox\lib\directxtex\release\.netframework,version=v4.6.assemblyattributes.asm
|
||||||
|
c:\users\nathan\documents\github\switch_toolbox\switch-toolbox - copy\release\directxtex.ipdb
|
||||||
|
c:\users\nathan\documents\github\switch_toolbox\switch-toolbox - copy\release\directxtex.iobj
|
||||||
|
c:\users\nathan\documents\github\switch_toolbox\switch-toolbox - copy\release\directxtex.dll
|
||||||
|
c:\users\nathan\documents\github\switch_toolbox\switch-toolbox - copy\switch_toolbox\lib\directxtex\release\directxtex.tlog\cl.command.1.tlog
|
||||||
|
c:\users\nathan\documents\github\switch_toolbox\switch-toolbox - copy\switch_toolbox\lib\directxtex\release\directxtex.tlog\cl.read.1.tlog
|
||||||
|
c:\users\nathan\documents\github\switch_toolbox\switch-toolbox - copy\switch_toolbox\lib\directxtex\release\directxtex.tlog\cl.write.1.tlog
|
||||||
|
c:\users\nathan\documents\github\switch_toolbox\switch-toolbox - copy\switch_toolbox\lib\directxtex\release\directxtex.tlog\directxtex.write.1u.tlog
|
||||||
|
c:\users\nathan\documents\github\switch_toolbox\switch-toolbox - copy\switch_toolbox\lib\directxtex\release\directxtex.tlog\link.command.1.tlog
|
||||||
|
c:\users\nathan\documents\github\switch_toolbox\switch-toolbox - copy\switch_toolbox\lib\directxtex\release\directxtex.tlog\link.read.1.tlog
|
||||||
|
c:\users\nathan\documents\github\switch_toolbox\switch-toolbox - copy\switch_toolbox\lib\directxtex\release\directxtex.tlog\link.write.1.tlog
|
||||||
|
c:\users\nathan\documents\github\switch_toolbox\switch-toolbox - copy\switch_toolbox\lib\directxtex\release\directxtex.tlog\metagen.read.1.tlog
|
||||||
|
c:\users\nathan\documents\github\switch_toolbox\switch-toolbox - copy\switch_toolbox\lib\directxtex\release\directxtex.tlog\metagen.write.1.tlog
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
15
Switch_Toolbox/Lib/DirectXTex.log
Normal file
15
Switch_Toolbox/Lib/DirectXTex.log
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
BC.cpp
|
||||||
|
BC4BC5.cpp
|
||||||
|
BC6HBC7.cpp
|
||||||
|
DirectXTexCompress.cpp
|
||||||
|
DirectXTexConvert.cpp
|
||||||
|
DirectXTexDDS.cpp
|
||||||
|
DirectXTexImage.cpp
|
||||||
|
DirectXTexMipmaps.cpp
|
||||||
|
DirectXTexUtil.cpp
|
||||||
|
wrapper.cpp
|
||||||
|
.NETFramework,Version=v4.6.AssemblyAttributes.cpp
|
||||||
|
Generating code
|
||||||
|
All 442 functions were compiled because no usable IPDB/IOBJ from previous compilation was found.
|
||||||
|
Finished generating code
|
||||||
|
DirectXTex.vcxproj -> C:\Users\Nathan\Documents\GitHub\Switch_Toolbox\Switch-Toolbox - Copy\Release\DirectXTex.dll
|
BIN
Switch_Toolbox/Lib/DirectXTex.vcxprojAssemblyReference.cache
Normal file
BIN
Switch_Toolbox/Lib/DirectXTex.vcxprojAssemblyReference.cache
Normal file
Binary file not shown.
BIN
Switch_Toolbox/Lib/DirectXTex.zip
Normal file
BIN
Switch_Toolbox/Lib/DirectXTex.zip
Normal file
Binary file not shown.
1141
Switch_Toolbox/Lib/DirectXTex/BC.cpp
Normal file
1141
Switch_Toolbox/Lib/DirectXTex/BC.cpp
Normal file
File diff suppressed because it is too large
Load diff
891
Switch_Toolbox/Lib/DirectXTex/BC.h
Normal file
891
Switch_Toolbox/Lib/DirectXTex/BC.h
Normal file
|
@ -0,0 +1,891 @@
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
// BC.h
|
||||||
|
//
|
||||||
|
// Block-compression (BC) functionality
|
||||||
|
//
|
||||||
|
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||||
|
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
||||||
|
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||||
|
// PARTICULAR PURPOSE.
|
||||||
|
//
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
//
|
||||||
|
// http://go.microsoft.com/fwlink/?LinkId=248926
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <directxmath.h>
|
||||||
|
#include <directxpackedvector.h>
|
||||||
|
|
||||||
|
namespace DirectX
|
||||||
|
{
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
// Constants
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
const uint16_t F16S_MASK = 0x8000; // f16 sign mask
|
||||||
|
const uint16_t F16EM_MASK = 0x7fff; // f16 exp & mantissa mask
|
||||||
|
const uint16_t F16MAX = 0x7bff; // MAXFLT bit pattern for XMHALF
|
||||||
|
|
||||||
|
#define SIGN_EXTEND(x,nb) ((((x)&(1<<((nb)-1)))?((~0)<<(nb)):0)|(x))
|
||||||
|
|
||||||
|
// Because these are used in SAL annotations, they need to remain macros rather than const values
|
||||||
|
#define NUM_PIXELS_PER_BLOCK 16
|
||||||
|
#define BC6H_MAX_REGIONS 2
|
||||||
|
#define BC6H_MAX_INDICES 16
|
||||||
|
#define BC7_MAX_REGIONS 3
|
||||||
|
#define BC7_MAX_INDICES 16
|
||||||
|
|
||||||
|
const size_t BC6H_NUM_CHANNELS = 3;
|
||||||
|
const size_t BC6H_MAX_SHAPES = 32;
|
||||||
|
|
||||||
|
const size_t BC7_NUM_CHANNELS = 4;
|
||||||
|
const size_t BC7_MAX_SHAPES = 64;
|
||||||
|
|
||||||
|
const int32_t BC67_WEIGHT_MAX = 64;
|
||||||
|
const uint32_t BC67_WEIGHT_SHIFT = 6;
|
||||||
|
const int32_t BC67_WEIGHT_ROUND = 32;
|
||||||
|
|
||||||
|
extern const int g_aWeights2[4];
|
||||||
|
extern const int g_aWeights3[8];
|
||||||
|
extern const int g_aWeights4[16];
|
||||||
|
|
||||||
|
enum BC_FLAGS
|
||||||
|
{
|
||||||
|
BC_FLAGS_NONE = 0x0,
|
||||||
|
BC_FLAGS_DITHER_RGB = 0x10000, // Enables dithering for RGB colors for BC1-3
|
||||||
|
BC_FLAGS_DITHER_A = 0x20000, // Enables dithering for Alpha channel for BC1-3
|
||||||
|
BC_FLAGS_UNIFORM = 0x40000, // By default, uses perceptual weighting for BC1-3; this flag makes it a uniform weighting
|
||||||
|
BC_FLAGS_USE_3SUBSETS = 0x80000,// By default, BC7 skips mode 0 & 2; this flag adds those modes back
|
||||||
|
};
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
// Structures
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
class HDRColorA;
|
||||||
|
|
||||||
|
class LDRColorA
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
uint8_t r, g, b, a;
|
||||||
|
|
||||||
|
LDRColorA() DIRECTX_CTOR_DEFAULT
|
||||||
|
LDRColorA(uint8_t _r, uint8_t _g, uint8_t _b, uint8_t _a) : r(_r), g(_g), b(_b), a(_a) {}
|
||||||
|
|
||||||
|
const uint8_t& operator [] (_In_range_(0,3) size_t uElement) const
|
||||||
|
{
|
||||||
|
switch(uElement)
|
||||||
|
{
|
||||||
|
case 0: return r;
|
||||||
|
case 1: return g;
|
||||||
|
case 2: return b;
|
||||||
|
case 3: return a;
|
||||||
|
default: assert(false); return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t& operator [] (_In_range_(0,3) size_t uElement)
|
||||||
|
{
|
||||||
|
switch(uElement)
|
||||||
|
{
|
||||||
|
case 0: return r;
|
||||||
|
case 1: return g;
|
||||||
|
case 2: return b;
|
||||||
|
case 3: return a;
|
||||||
|
default: assert(false); return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LDRColorA operator = (_In_ const HDRColorA& c);
|
||||||
|
|
||||||
|
static void InterpolateRGB(_In_ const LDRColorA& c0, _In_ const LDRColorA& c1, _In_ size_t wc, _In_ _In_range_(2, 4) size_t wcprec, _Out_ LDRColorA& out)
|
||||||
|
{
|
||||||
|
const int* aWeights = nullptr;
|
||||||
|
switch(wcprec)
|
||||||
|
{
|
||||||
|
case 2: aWeights = g_aWeights2; assert( wc < 4 ); _Analysis_assume_( wc < 4 ); break;
|
||||||
|
case 3: aWeights = g_aWeights3; assert( wc < 8 ); _Analysis_assume_( wc < 8 ); break;
|
||||||
|
case 4: aWeights = g_aWeights4; assert( wc < 16 ); _Analysis_assume_( wc < 16 ); break;
|
||||||
|
default: assert(false); out.r = out.g = out.b = 0; return;
|
||||||
|
}
|
||||||
|
out.r = uint8_t((uint32_t(c0.r) * uint32_t(BC67_WEIGHT_MAX - aWeights[wc]) + uint32_t(c1.r) * uint32_t(aWeights[wc]) + BC67_WEIGHT_ROUND) >> BC67_WEIGHT_SHIFT);
|
||||||
|
out.g = uint8_t((uint32_t(c0.g) * uint32_t(BC67_WEIGHT_MAX - aWeights[wc]) + uint32_t(c1.g) * uint32_t(aWeights[wc]) + BC67_WEIGHT_ROUND) >> BC67_WEIGHT_SHIFT);
|
||||||
|
out.b = uint8_t((uint32_t(c0.b) * uint32_t(BC67_WEIGHT_MAX - aWeights[wc]) + uint32_t(c1.b) * uint32_t(aWeights[wc]) + BC67_WEIGHT_ROUND) >> BC67_WEIGHT_SHIFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void InterpolateA(_In_ const LDRColorA& c0, _In_ const LDRColorA& c1, _In_ size_t wa, _In_range_(2, 4) _In_ size_t waprec, _Out_ LDRColorA& out)
|
||||||
|
{
|
||||||
|
const int* aWeights = nullptr;
|
||||||
|
switch(waprec)
|
||||||
|
{
|
||||||
|
case 2: aWeights = g_aWeights2; assert( wa < 4 ); _Analysis_assume_( wa < 4 ); break;
|
||||||
|
case 3: aWeights = g_aWeights3; assert( wa < 8 ); _Analysis_assume_( wa < 8 ); break;
|
||||||
|
case 4: aWeights = g_aWeights4; assert( wa < 16 ); _Analysis_assume_( wa < 16 ); break;
|
||||||
|
default: assert(false); out.a = 0; return;
|
||||||
|
}
|
||||||
|
out.a = uint8_t((uint32_t(c0.a) * uint32_t(BC67_WEIGHT_MAX - aWeights[wa]) + uint32_t(c1.a) * uint32_t(aWeights[wa]) + BC67_WEIGHT_ROUND) >> BC67_WEIGHT_SHIFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Interpolate(_In_ const LDRColorA& c0, _In_ const LDRColorA& c1, _In_ size_t wc, _In_ size_t wa, _In_ _In_range_(2, 4) size_t wcprec, _In_ _In_range_(2, 4) size_t waprec, _Out_ LDRColorA& out)
|
||||||
|
{
|
||||||
|
InterpolateRGB(c0, c1, wc, wcprec, out);
|
||||||
|
InterpolateA(c0, c1, wa, waprec, out);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert( sizeof(LDRColorA) == 4, "Unexpected packing");
|
||||||
|
|
||||||
|
class HDRColorA
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
float r, g, b, a;
|
||||||
|
|
||||||
|
public:
|
||||||
|
HDRColorA() DIRECTX_CTOR_DEFAULT
|
||||||
|
HDRColorA(float _r, float _g, float _b, float _a) : r(_r), g(_g), b(_b), a(_a) {}
|
||||||
|
HDRColorA(const HDRColorA& c) : r(c.r), g(c.g), b(c.b), a(c.a) {}
|
||||||
|
HDRColorA(const LDRColorA& c)
|
||||||
|
{
|
||||||
|
r = float(c.r) * (1.0f/255.0f);
|
||||||
|
g = float(c.g) * (1.0f/255.0f);
|
||||||
|
b = float(c.b) * (1.0f/255.0f);
|
||||||
|
a = float(c.a) * (1.0f/255.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
// binary operators
|
||||||
|
HDRColorA operator + ( _In_ const HDRColorA& c ) const
|
||||||
|
{
|
||||||
|
return HDRColorA(r + c.r, g + c.g, b + c.b, a + c.a);
|
||||||
|
}
|
||||||
|
|
||||||
|
HDRColorA operator - ( _In_ const HDRColorA& c ) const
|
||||||
|
{
|
||||||
|
return HDRColorA(r - c.r, g - c.g, b - c.b, a - c.a);
|
||||||
|
}
|
||||||
|
|
||||||
|
HDRColorA operator * ( _In_ float f ) const
|
||||||
|
{
|
||||||
|
return HDRColorA(r * f, g * f, b * f, a * f);
|
||||||
|
}
|
||||||
|
|
||||||
|
HDRColorA operator / ( _In_ float f ) const
|
||||||
|
{
|
||||||
|
float fInv = 1.0f / f;
|
||||||
|
return HDRColorA(r * fInv, g * fInv, b * fInv, a * fInv);
|
||||||
|
}
|
||||||
|
|
||||||
|
float operator * ( _In_ const HDRColorA& c ) const
|
||||||
|
{
|
||||||
|
return r * c.r + g * c.g + b * c.b + a * c.a;
|
||||||
|
}
|
||||||
|
|
||||||
|
// assignment operators
|
||||||
|
HDRColorA& operator += ( _In_ const HDRColorA& c )
|
||||||
|
{
|
||||||
|
r += c.r;
|
||||||
|
g += c.g;
|
||||||
|
b += c.b;
|
||||||
|
a += c.a;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
HDRColorA& operator -= ( _In_ const HDRColorA& c )
|
||||||
|
{
|
||||||
|
r -= c.r;
|
||||||
|
g -= c.g;
|
||||||
|
b -= c.b;
|
||||||
|
a -= c.a;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
HDRColorA& operator *= ( _In_ float f )
|
||||||
|
{
|
||||||
|
r *= f;
|
||||||
|
g *= f;
|
||||||
|
b *= f;
|
||||||
|
a *= f;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
HDRColorA& operator /= ( _In_ float f )
|
||||||
|
{
|
||||||
|
float fInv = 1.0f / f;
|
||||||
|
r *= fInv;
|
||||||
|
g *= fInv;
|
||||||
|
b *= fInv;
|
||||||
|
a *= fInv;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
HDRColorA& operator = (_In_ const LDRColorA& c)
|
||||||
|
{
|
||||||
|
r = (float) c.r;
|
||||||
|
g = (float) c.g;
|
||||||
|
b = (float) c.b;
|
||||||
|
a = (float) c.a;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
HDRColorA& Clamp(_In_ float fMin, _In_ float fMax)
|
||||||
|
{
|
||||||
|
r = std::min<float>(fMax, std::max<float>(fMin, r));
|
||||||
|
g = std::min<float>(fMax, std::max<float>(fMin, g));
|
||||||
|
b = std::min<float>(fMax, std::max<float>(fMin, b));
|
||||||
|
a = std::min<float>(fMax, std::max<float>(fMin, a));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
LDRColorA ToLDRColorA() const
|
||||||
|
{
|
||||||
|
return LDRColorA((uint8_t) (r + 0.01f), (uint8_t) (g + 0.01f), (uint8_t) (b + 0.01f), (uint8_t) (a + 0.01f));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline LDRColorA LDRColorA::operator = (_In_ const HDRColorA& c)
|
||||||
|
{
|
||||||
|
LDRColorA ret;
|
||||||
|
HDRColorA tmp(c);
|
||||||
|
tmp = tmp.Clamp(0.0f, 1.0f) * 255.0f;
|
||||||
|
ret.r = uint8_t(tmp.r + 0.001f);
|
||||||
|
ret.g = uint8_t(tmp.g + 0.001f);
|
||||||
|
ret.b = uint8_t(tmp.b + 0.001f);
|
||||||
|
ret.a = uint8_t(tmp.a + 0.001f);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct LDREndPntPair
|
||||||
|
{
|
||||||
|
LDRColorA A;
|
||||||
|
LDRColorA B;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct HDREndPntPair
|
||||||
|
{
|
||||||
|
HDRColorA A;
|
||||||
|
HDRColorA B;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline HDRColorA* HDRColorALerp(_Out_ HDRColorA *pOut, _In_ const HDRColorA *pC1, _In_ const HDRColorA *pC2, _In_ float s)
|
||||||
|
{
|
||||||
|
pOut->r = pC1->r + s * (pC2->r - pC1->r);
|
||||||
|
pOut->g = pC1->g + s * (pC2->g - pC1->g);
|
||||||
|
pOut->b = pC1->b + s * (pC2->b - pC1->b);
|
||||||
|
pOut->a = pC1->a + s * (pC2->a - pC1->a);
|
||||||
|
return pOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma pack(push,1)
|
||||||
|
// BC1/DXT1 compression (4 bits per texel)
|
||||||
|
struct D3DX_BC1
|
||||||
|
{
|
||||||
|
uint16_t rgb[2]; // 565 colors
|
||||||
|
uint32_t bitmap; // 2bpp rgb bitmap
|
||||||
|
};
|
||||||
|
|
||||||
|
// BC2/DXT2/3 compression (8 bits per texel)
|
||||||
|
struct D3DX_BC2
|
||||||
|
{
|
||||||
|
uint32_t bitmap[2]; // 4bpp alpha bitmap
|
||||||
|
D3DX_BC1 bc1; // BC1 rgb data
|
||||||
|
};
|
||||||
|
|
||||||
|
// BC3/DXT4/5 compression (8 bits per texel)
|
||||||
|
struct D3DX_BC3
|
||||||
|
{
|
||||||
|
uint8_t alpha[2]; // alpha values
|
||||||
|
uint8_t bitmap[6]; // 3bpp alpha bitmap
|
||||||
|
D3DX_BC1 bc1; // BC1 rgb data
|
||||||
|
};
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
class INTColor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int r, g, b;
|
||||||
|
int pad;
|
||||||
|
|
||||||
|
public:
|
||||||
|
INTColor() DIRECTX_CTOR_DEFAULT
|
||||||
|
INTColor(int nr, int ng, int nb) {r = nr; g = ng; b = nb;}
|
||||||
|
INTColor(const INTColor& c) {r = c.r; g = c.g; b = c.b;}
|
||||||
|
|
||||||
|
INTColor operator - ( _In_ const INTColor& c ) const
|
||||||
|
{
|
||||||
|
return INTColor(r - c.r, g - c.g, b - c.b);
|
||||||
|
}
|
||||||
|
|
||||||
|
INTColor& operator += ( _In_ const INTColor& c )
|
||||||
|
{
|
||||||
|
r += c.r;
|
||||||
|
g += c.g;
|
||||||
|
b += c.b;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
INTColor& operator -= ( _In_ const INTColor& c )
|
||||||
|
{
|
||||||
|
r -= c.r;
|
||||||
|
g -= c.g;
|
||||||
|
b -= c.b;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
INTColor& operator &= ( _In_ const INTColor& c )
|
||||||
|
{
|
||||||
|
r &= c.r;
|
||||||
|
g &= c.g;
|
||||||
|
b &= c.b;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
int& operator [] ( _In_ uint8_t i )
|
||||||
|
{
|
||||||
|
assert(i < sizeof(INTColor) / sizeof(int));
|
||||||
|
_Analysis_assume_(i < sizeof(INTColor) / sizeof(int));
|
||||||
|
return ((int*) this)[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Set(_In_ const HDRColorA& c, _In_ bool bSigned)
|
||||||
|
{
|
||||||
|
PackedVector::XMHALF4 aF16;
|
||||||
|
|
||||||
|
XMVECTOR v = XMLoadFloat4( (const XMFLOAT4*)& c );
|
||||||
|
XMStoreHalf4( &aF16, v );
|
||||||
|
|
||||||
|
r = F16ToINT(aF16.x, bSigned);
|
||||||
|
g = F16ToINT(aF16.y, bSigned);
|
||||||
|
b = F16ToINT(aF16.z, bSigned);
|
||||||
|
}
|
||||||
|
|
||||||
|
INTColor& Clamp(_In_ int iMin, _In_ int iMax)
|
||||||
|
{
|
||||||
|
r = std::min<int>(iMax, std::max<int>(iMin, r));
|
||||||
|
g = std::min<int>(iMax, std::max<int>(iMin, g));
|
||||||
|
b = std::min<int>(iMax, std::max<int>(iMin, b));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
INTColor& SignExtend(_In_ const LDRColorA& Prec)
|
||||||
|
{
|
||||||
|
r = SIGN_EXTEND(r, Prec.r);
|
||||||
|
g = SIGN_EXTEND(g, Prec.g);
|
||||||
|
b = SIGN_EXTEND(b, Prec.b);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ToF16(_Out_writes_(3) PackedVector::HALF aF16[3], _In_ bool bSigned) const
|
||||||
|
{
|
||||||
|
aF16[0] = INT2F16(r, bSigned);
|
||||||
|
aF16[1] = INT2F16(g, bSigned);
|
||||||
|
aF16[2] = INT2F16(b, bSigned);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static int F16ToINT(_In_ const PackedVector::HALF& f, _In_ bool bSigned)
|
||||||
|
{
|
||||||
|
uint16_t input = *((const uint16_t*) &f);
|
||||||
|
int out, s;
|
||||||
|
if(bSigned)
|
||||||
|
{
|
||||||
|
s = input & F16S_MASK;
|
||||||
|
input &= F16EM_MASK;
|
||||||
|
if(input > F16MAX) out = F16MAX;
|
||||||
|
else out = input;
|
||||||
|
out = s ? -out : out;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(input & F16S_MASK) out = 0;
|
||||||
|
else out = input;
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PackedVector::HALF INT2F16(_In_ int input, _In_ bool bSigned)
|
||||||
|
{
|
||||||
|
PackedVector::HALF h;
|
||||||
|
uint16_t out;
|
||||||
|
if(bSigned)
|
||||||
|
{
|
||||||
|
int s = 0;
|
||||||
|
if(input < 0)
|
||||||
|
{
|
||||||
|
s = F16S_MASK;
|
||||||
|
input = -input;
|
||||||
|
}
|
||||||
|
out = uint16_t(s | input);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(input >= 0 && input <= F16MAX);
|
||||||
|
out = (uint16_t) input;
|
||||||
|
}
|
||||||
|
|
||||||
|
*((uint16_t*) &h) = out;
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert( sizeof(INTColor) == 16, "Unexpected packing");
|
||||||
|
|
||||||
|
struct INTEndPntPair
|
||||||
|
{
|
||||||
|
INTColor A;
|
||||||
|
INTColor B;
|
||||||
|
};
|
||||||
|
|
||||||
|
template< size_t SizeInBytes >
|
||||||
|
class CBits
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
uint8_t GetBit(_Inout_ size_t& uStartBit) const
|
||||||
|
{
|
||||||
|
assert(uStartBit < 128);
|
||||||
|
_Analysis_assume_(uStartBit < 128);
|
||||||
|
size_t uIndex = uStartBit >> 3;
|
||||||
|
uint8_t ret = (m_uBits[uIndex] >> (uStartBit - (uIndex << 3))) & 0x01;
|
||||||
|
uStartBit++;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t GetBits(_Inout_ size_t& uStartBit, _In_ size_t uNumBits) const
|
||||||
|
{
|
||||||
|
if(uNumBits == 0) return 0;
|
||||||
|
assert(uStartBit + uNumBits <= 128 && uNumBits <= 8);
|
||||||
|
_Analysis_assume_(uStartBit + uNumBits <= 128 && uNumBits <= 8);
|
||||||
|
uint8_t ret;
|
||||||
|
size_t uIndex = uStartBit >> 3;
|
||||||
|
size_t uBase = uStartBit - (uIndex << 3);
|
||||||
|
if(uBase + uNumBits > 8)
|
||||||
|
{
|
||||||
|
size_t uFirstIndexBits = 8 - uBase;
|
||||||
|
size_t uNextIndexBits = uNumBits - uFirstIndexBits;
|
||||||
|
ret = (m_uBits[uIndex] >> uBase) | ((m_uBits[uIndex+1] & ((1 << uNextIndexBits) - 1)) << uFirstIndexBits);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = (m_uBits[uIndex] >> uBase) & ((1 << uNumBits) - 1);
|
||||||
|
}
|
||||||
|
assert(ret < (1 << uNumBits));
|
||||||
|
uStartBit += uNumBits;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetBit(_Inout_ size_t& uStartBit, _In_ uint8_t uValue)
|
||||||
|
{
|
||||||
|
assert(uStartBit < 128 && uValue < 2);
|
||||||
|
_Analysis_assume_(uStartBit < 128 && uValue < 2);
|
||||||
|
size_t uIndex = uStartBit >> 3;
|
||||||
|
size_t uBase = uStartBit - (uIndex << 3);
|
||||||
|
m_uBits[uIndex] &= ~(1 << uBase);
|
||||||
|
m_uBits[uIndex] |= uValue << uBase;
|
||||||
|
uStartBit++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetBits(_Inout_ size_t& uStartBit, _In_ size_t uNumBits, _In_ uint8_t uValue)
|
||||||
|
{
|
||||||
|
if(uNumBits == 0)
|
||||||
|
return;
|
||||||
|
assert(uStartBit + uNumBits <= 128 && uNumBits <= 8);
|
||||||
|
_Analysis_assume_(uStartBit + uNumBits <= 128 && uNumBits <= 8);
|
||||||
|
assert(uValue < (1 << uNumBits));
|
||||||
|
size_t uIndex = uStartBit >> 3;
|
||||||
|
size_t uBase = uStartBit - (uIndex << 3);
|
||||||
|
if(uBase + uNumBits > 8)
|
||||||
|
{
|
||||||
|
size_t uFirstIndexBits = 8 - uBase;
|
||||||
|
size_t uNextIndexBits = uNumBits - uFirstIndexBits;
|
||||||
|
m_uBits[uIndex] &= ~(((1 << uFirstIndexBits) - 1) << uBase);
|
||||||
|
m_uBits[uIndex] |= uValue << uBase;
|
||||||
|
m_uBits[uIndex+1] &= ~((1 << uNextIndexBits) - 1);
|
||||||
|
m_uBits[uIndex+1] |= uValue >> uFirstIndexBits;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_uBits[uIndex] &= ~(((1 << uNumBits) - 1) << uBase);
|
||||||
|
m_uBits[uIndex] |= uValue << uBase;
|
||||||
|
}
|
||||||
|
uStartBit += uNumBits;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint8_t m_uBits[ SizeInBytes ];
|
||||||
|
};
|
||||||
|
|
||||||
|
// BC6H compression (16 bits per texel)
|
||||||
|
class D3DX_BC6H : private CBits< 16 >
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void Decode(_In_ bool bSigned, _Out_writes_(NUM_PIXELS_PER_BLOCK) HDRColorA* pOut) const;
|
||||||
|
void Encode(_In_ bool bSigned, _In_reads_(NUM_PIXELS_PER_BLOCK) const HDRColorA* const pIn);
|
||||||
|
|
||||||
|
private:
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable : 4480)
|
||||||
|
enum EField : uint8_t
|
||||||
|
{
|
||||||
|
NA, // N/A
|
||||||
|
M, // Mode
|
||||||
|
D, // Shape
|
||||||
|
RW,
|
||||||
|
RX,
|
||||||
|
RY,
|
||||||
|
RZ,
|
||||||
|
GW,
|
||||||
|
GX,
|
||||||
|
GY,
|
||||||
|
GZ,
|
||||||
|
BW,
|
||||||
|
BX,
|
||||||
|
BY,
|
||||||
|
BZ,
|
||||||
|
};
|
||||||
|
#pragma warning(pop)
|
||||||
|
|
||||||
|
struct ModeDescriptor
|
||||||
|
{
|
||||||
|
EField m_eField;
|
||||||
|
uint8_t m_uBit;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ModeInfo
|
||||||
|
{
|
||||||
|
uint8_t uMode;
|
||||||
|
uint8_t uPartitions;
|
||||||
|
bool bTransformed;
|
||||||
|
uint8_t uIndexPrec;
|
||||||
|
LDRColorA RGBAPrec[BC6H_MAX_REGIONS][2];
|
||||||
|
};
|
||||||
|
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable : 4512)
|
||||||
|
struct EncodeParams
|
||||||
|
{
|
||||||
|
float fBestErr;
|
||||||
|
const bool bSigned;
|
||||||
|
uint8_t uMode;
|
||||||
|
uint8_t uShape;
|
||||||
|
const HDRColorA* const aHDRPixels;
|
||||||
|
INTEndPntPair aUnqEndPts[BC6H_MAX_SHAPES][BC6H_MAX_REGIONS];
|
||||||
|
INTColor aIPixels[NUM_PIXELS_PER_BLOCK];
|
||||||
|
|
||||||
|
EncodeParams(const HDRColorA* const aOriginal, bool bSignedFormat) :
|
||||||
|
aHDRPixels(aOriginal), fBestErr(FLT_MAX), bSigned(bSignedFormat)
|
||||||
|
{
|
||||||
|
for(size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i)
|
||||||
|
{
|
||||||
|
aIPixels[i].Set(aOriginal[i], bSigned);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#pragma warning(pop)
|
||||||
|
|
||||||
|
static int Quantize(_In_ int iValue, _In_ int prec, _In_ bool bSigned);
|
||||||
|
static int Unquantize(_In_ int comp, _In_ uint8_t uBitsPerComp, _In_ bool bSigned);
|
||||||
|
static int FinishUnquantize(_In_ int comp, _In_ bool bSigned);
|
||||||
|
|
||||||
|
static bool EndPointsFit(_In_ const EncodeParams* pEP, _In_reads_(BC6H_MAX_REGIONS) const INTEndPntPair aEndPts[]);
|
||||||
|
|
||||||
|
void GeneratePaletteQuantized(_In_ const EncodeParams* pEP, _In_ const INTEndPntPair& endPts,
|
||||||
|
_Out_writes_(BC6H_MAX_INDICES) INTColor aPalette[]) const;
|
||||||
|
float MapColorsQuantized(_In_ const EncodeParams* pEP, _In_reads_(np) const INTColor aColors[], _In_ size_t np, _In_ const INTEndPntPair &endPts) const;
|
||||||
|
float PerturbOne(_In_ const EncodeParams* pEP, _In_reads_(np) const INTColor aColors[], _In_ size_t np, _In_ uint8_t ch,
|
||||||
|
_In_ const INTEndPntPair& oldEndPts, _Out_ INTEndPntPair& newEndPts, _In_ float fOldErr, _In_ int do_b) const;
|
||||||
|
void OptimizeOne(_In_ const EncodeParams* pEP, _In_reads_(np) const INTColor aColors[], _In_ size_t np, _In_ float aOrgErr,
|
||||||
|
_In_ const INTEndPntPair &aOrgEndPts, _Out_ INTEndPntPair &aOptEndPts) const;
|
||||||
|
void OptimizeEndPoints(_In_ const EncodeParams* pEP, _In_reads_(BC6H_MAX_REGIONS) const float aOrgErr[],
|
||||||
|
_In_reads_(BC6H_MAX_REGIONS) const INTEndPntPair aOrgEndPts[],
|
||||||
|
_Out_writes_all_(BC6H_MAX_REGIONS) INTEndPntPair aOptEndPts[]) const;
|
||||||
|
static void SwapIndices(_In_ const EncodeParams* pEP, _Inout_updates_all_(BC6H_MAX_REGIONS) INTEndPntPair aEndPts[],
|
||||||
|
_In_reads_(NUM_PIXELS_PER_BLOCK) size_t aIndices[]);
|
||||||
|
void AssignIndices(_In_ const EncodeParams* pEP, _In_reads_(BC6H_MAX_REGIONS) const INTEndPntPair aEndPts[],
|
||||||
|
_Out_writes_(NUM_PIXELS_PER_BLOCK) size_t aIndices[],
|
||||||
|
_Out_writes_(BC6H_MAX_REGIONS) float aTotErr[]) const;
|
||||||
|
void QuantizeEndPts(_In_ const EncodeParams* pEP, _Out_writes_(BC6H_MAX_REGIONS) INTEndPntPair* qQntEndPts) const;
|
||||||
|
void EmitBlock(_In_ const EncodeParams* pEP, _In_reads_(BC6H_MAX_REGIONS) const INTEndPntPair aEndPts[],
|
||||||
|
_In_reads_(NUM_PIXELS_PER_BLOCK) const size_t aIndices[]);
|
||||||
|
void Refine(_Inout_ EncodeParams* pEP);
|
||||||
|
|
||||||
|
static void GeneratePaletteUnquantized(_In_ const EncodeParams* pEP, _In_ size_t uRegion, _Out_writes_(BC6H_MAX_INDICES) INTColor aPalette[]);
|
||||||
|
float MapColors(_In_ const EncodeParams* pEP, _In_ size_t uRegion, _In_ size_t np, _In_reads_(np) const size_t* auIndex) const;
|
||||||
|
float RoughMSE(_Inout_ EncodeParams* pEP) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const static ModeDescriptor ms_aDesc[][82];
|
||||||
|
const static ModeInfo ms_aInfo[];
|
||||||
|
const static int ms_aModeToInfo[];
|
||||||
|
};
|
||||||
|
|
||||||
|
// BC67 compression (16b bits per texel)
|
||||||
|
class D3DX_BC7 : private CBits< 16 >
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void Decode(_Out_writes_(NUM_PIXELS_PER_BLOCK) HDRColorA* pOut) const;
|
||||||
|
void Encode(bool skip3subsets, _In_reads_(NUM_PIXELS_PER_BLOCK) const HDRColorA* const pIn);
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct ModeInfo
|
||||||
|
{
|
||||||
|
uint8_t uPartitions;
|
||||||
|
uint8_t uPartitionBits;
|
||||||
|
uint8_t uPBits;
|
||||||
|
uint8_t uRotationBits;
|
||||||
|
uint8_t uIndexModeBits;
|
||||||
|
uint8_t uIndexPrec;
|
||||||
|
uint8_t uIndexPrec2;
|
||||||
|
LDRColorA RGBAPrec;
|
||||||
|
LDRColorA RGBAPrecWithP;
|
||||||
|
};
|
||||||
|
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable : 4512)
|
||||||
|
struct EncodeParams
|
||||||
|
{
|
||||||
|
uint8_t uMode;
|
||||||
|
LDREndPntPair aEndPts[BC7_MAX_SHAPES][BC7_MAX_REGIONS];
|
||||||
|
LDRColorA aLDRPixels[NUM_PIXELS_PER_BLOCK];
|
||||||
|
const HDRColorA* const aHDRPixels;
|
||||||
|
|
||||||
|
EncodeParams(const HDRColorA* const aOriginal) : aHDRPixels(aOriginal) {}
|
||||||
|
};
|
||||||
|
#pragma warning(pop)
|
||||||
|
|
||||||
|
static uint8_t Quantize(_In_ uint8_t comp, _In_ uint8_t uPrec)
|
||||||
|
{
|
||||||
|
assert(0 < uPrec && uPrec <= 8);
|
||||||
|
uint8_t rnd = (uint8_t) std::min<uint16_t>(255, uint16_t(comp) + (1 << (7 - uPrec)));
|
||||||
|
return rnd >> (8 - uPrec);
|
||||||
|
}
|
||||||
|
|
||||||
|
static LDRColorA Quantize(_In_ const LDRColorA& c, _In_ const LDRColorA& RGBAPrec)
|
||||||
|
{
|
||||||
|
LDRColorA q;
|
||||||
|
q.r = Quantize(c.r, RGBAPrec.r);
|
||||||
|
q.g = Quantize(c.g, RGBAPrec.g);
|
||||||
|
q.b = Quantize(c.b, RGBAPrec.b);
|
||||||
|
if(RGBAPrec.a)
|
||||||
|
q.a = Quantize(c.a, RGBAPrec.a);
|
||||||
|
else
|
||||||
|
q.a = 255;
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t Unquantize(_In_ uint8_t comp, _In_ size_t uPrec)
|
||||||
|
{
|
||||||
|
assert(0 < uPrec && uPrec <= 8);
|
||||||
|
comp = comp << (8 - uPrec);
|
||||||
|
return comp | (comp >> uPrec);
|
||||||
|
}
|
||||||
|
|
||||||
|
static LDRColorA Unquantize(_In_ const LDRColorA& c, _In_ const LDRColorA& RGBAPrec)
|
||||||
|
{
|
||||||
|
LDRColorA q;
|
||||||
|
q.r = Unquantize(c.r, RGBAPrec.r);
|
||||||
|
q.g = Unquantize(c.g, RGBAPrec.g);
|
||||||
|
q.b = Unquantize(c.b, RGBAPrec.b);
|
||||||
|
q.a = RGBAPrec.a > 0 ? Unquantize(c.a, RGBAPrec.a) : 255;
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GeneratePaletteQuantized(_In_ const EncodeParams* pEP, _In_ size_t uIndexMode, _In_ const LDREndPntPair& endpts,
|
||||||
|
_Out_writes_(BC7_MAX_INDICES) LDRColorA aPalette[]) const;
|
||||||
|
float PerturbOne(_In_ const EncodeParams* pEP, _In_reads_(np) const LDRColorA colors[], _In_ size_t np, _In_ size_t uIndexMode,
|
||||||
|
_In_ size_t ch, _In_ const LDREndPntPair &old_endpts,
|
||||||
|
_Out_ LDREndPntPair &new_endpts, _In_ float old_err, _In_ uint8_t do_b) const;
|
||||||
|
void Exhaustive(_In_ const EncodeParams* pEP, _In_reads_(np) const LDRColorA aColors[], _In_ size_t np, _In_ size_t uIndexMode,
|
||||||
|
_In_ size_t ch, _Inout_ float& fOrgErr, _Inout_ LDREndPntPair& optEndPt) const;
|
||||||
|
void OptimizeOne(_In_ const EncodeParams* pEP, _In_reads_(np) const LDRColorA colors[], _In_ size_t np, _In_ size_t uIndexMode,
|
||||||
|
_In_ float orig_err, _In_ const LDREndPntPair &orig_endpts, _Out_ LDREndPntPair &opt_endpts) const;
|
||||||
|
void OptimizeEndPoints(_In_ const EncodeParams* pEP, _In_ size_t uShape, _In_ size_t uIndexMode,
|
||||||
|
_In_reads_(BC7_MAX_REGIONS) const float orig_err[],
|
||||||
|
_In_reads_(BC7_MAX_REGIONS) const LDREndPntPair orig_endpts[],
|
||||||
|
_Out_writes_(BC7_MAX_REGIONS) LDREndPntPair opt_endpts[]) const;
|
||||||
|
void AssignIndices(_In_ const EncodeParams* pEP, _In_ size_t uShape, _In_ size_t uIndexMode,
|
||||||
|
_In_reads_(BC7_MAX_REGIONS) LDREndPntPair endpts[],
|
||||||
|
_Out_writes_(NUM_PIXELS_PER_BLOCK) size_t aIndices[], _Out_writes_(NUM_PIXELS_PER_BLOCK) size_t aIndices2[],
|
||||||
|
_Out_writes_(BC7_MAX_REGIONS) float afTotErr[]) const;
|
||||||
|
void EmitBlock(_In_ const EncodeParams* pEP, _In_ size_t uShape, _In_ size_t uRotation, _In_ size_t uIndexMode,
|
||||||
|
_In_reads_(BC7_MAX_REGIONS) const LDREndPntPair aEndPts[],
|
||||||
|
_In_reads_(NUM_PIXELS_PER_BLOCK) const size_t aIndex[],
|
||||||
|
_In_reads_(NUM_PIXELS_PER_BLOCK) const size_t aIndex2[]);
|
||||||
|
float Refine(_In_ const EncodeParams* pEP, _In_ size_t uShape, _In_ size_t uRotation, _In_ size_t uIndexMode);
|
||||||
|
|
||||||
|
float MapColors(_In_ const EncodeParams* pEP, _In_reads_(np) const LDRColorA aColors[], _In_ size_t np, _In_ size_t uIndexMode,
|
||||||
|
_In_ const LDREndPntPair& endPts, _In_ float fMinErr) const;
|
||||||
|
static float RoughMSE(_Inout_ EncodeParams* pEP, _In_ size_t uShape, _In_ size_t uIndexMode);
|
||||||
|
|
||||||
|
private:
|
||||||
|
const static ModeInfo ms_aInfo[];
|
||||||
|
};
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable : 4127)
|
||||||
|
template <bool bRange> void OptimizeAlpha(float *pX, float *pY, const float *pPoints, size_t cSteps)
|
||||||
|
{
|
||||||
|
static const float pC6[] = { 5.0f/5.0f, 4.0f/5.0f, 3.0f/5.0f, 2.0f/5.0f, 1.0f/5.0f, 0.0f/5.0f };
|
||||||
|
static const float pD6[] = { 0.0f/5.0f, 1.0f/5.0f, 2.0f/5.0f, 3.0f/5.0f, 4.0f/5.0f, 5.0f/5.0f };
|
||||||
|
static const float pC8[] = { 7.0f/7.0f, 6.0f/7.0f, 5.0f/7.0f, 4.0f/7.0f, 3.0f/7.0f, 2.0f/7.0f, 1.0f/7.0f, 0.0f/7.0f };
|
||||||
|
static const float pD8[] = { 0.0f/7.0f, 1.0f/7.0f, 2.0f/7.0f, 3.0f/7.0f, 4.0f/7.0f, 5.0f/7.0f, 6.0f/7.0f, 7.0f/7.0f };
|
||||||
|
|
||||||
|
const float *pC = (6 == cSteps) ? pC6 : pC8;
|
||||||
|
const float *pD = (6 == cSteps) ? pD6 : pD8;
|
||||||
|
|
||||||
|
float MAX_VALUE = 1.0f;
|
||||||
|
float MIN_VALUE;
|
||||||
|
if (bRange)
|
||||||
|
{
|
||||||
|
MIN_VALUE = -1.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MIN_VALUE = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find Min and Max points, as starting point
|
||||||
|
float fX = MAX_VALUE;
|
||||||
|
float fY = MIN_VALUE;
|
||||||
|
|
||||||
|
if(8 == cSteps)
|
||||||
|
{
|
||||||
|
for(size_t iPoint = 0; iPoint < NUM_PIXELS_PER_BLOCK; iPoint++)
|
||||||
|
{
|
||||||
|
if(pPoints[iPoint] < fX)
|
||||||
|
fX = pPoints[iPoint];
|
||||||
|
|
||||||
|
if(pPoints[iPoint] > fY)
|
||||||
|
fY = pPoints[iPoint];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(size_t iPoint = 0; iPoint < NUM_PIXELS_PER_BLOCK; iPoint++)
|
||||||
|
{
|
||||||
|
if(pPoints[iPoint] < fX && pPoints[iPoint] > MIN_VALUE)
|
||||||
|
fX = pPoints[iPoint];
|
||||||
|
|
||||||
|
if(pPoints[iPoint] > fY && pPoints[iPoint] < MAX_VALUE)
|
||||||
|
fY = pPoints[iPoint];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fX == fY)
|
||||||
|
{
|
||||||
|
fY = MAX_VALUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use Newton's Method to find local minima of sum-of-squares error.
|
||||||
|
float fSteps = (float) (cSteps - 1);
|
||||||
|
|
||||||
|
for(size_t iIteration = 0; iIteration < 8; iIteration++)
|
||||||
|
{
|
||||||
|
float fScale;
|
||||||
|
|
||||||
|
if((fY - fX) < (1.0f / 256.0f))
|
||||||
|
break;
|
||||||
|
|
||||||
|
fScale = fSteps / (fY - fX);
|
||||||
|
|
||||||
|
// Calculate new steps
|
||||||
|
float pSteps[8];
|
||||||
|
|
||||||
|
for(size_t iStep = 0; iStep < cSteps; iStep++)
|
||||||
|
pSteps[iStep] = pC[iStep] * fX + pD[iStep] * fY;
|
||||||
|
|
||||||
|
if(6 == cSteps)
|
||||||
|
{
|
||||||
|
pSteps[6] = MIN_VALUE;
|
||||||
|
pSteps[7] = MAX_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate function, and derivatives
|
||||||
|
float dX = 0.0f;
|
||||||
|
float dY = 0.0f;
|
||||||
|
float d2X = 0.0f;
|
||||||
|
float d2Y = 0.0f;
|
||||||
|
|
||||||
|
for(size_t iPoint = 0; iPoint < NUM_PIXELS_PER_BLOCK; iPoint++)
|
||||||
|
{
|
||||||
|
float fDot = (pPoints[iPoint] - fX) * fScale;
|
||||||
|
|
||||||
|
size_t iStep;
|
||||||
|
|
||||||
|
if(fDot <= 0.0f)
|
||||||
|
iStep = ((6 == cSteps) && (pPoints[iPoint] <= fX * 0.5f)) ? 6 : 0;
|
||||||
|
else if(fDot >= fSteps)
|
||||||
|
iStep = ((6 == cSteps) && (pPoints[iPoint] >= (fY + 1.0f) * 0.5f)) ? 7 : (cSteps - 1);
|
||||||
|
else
|
||||||
|
iStep = static_cast<int32_t>(fDot + 0.5f);
|
||||||
|
|
||||||
|
|
||||||
|
if(iStep < cSteps)
|
||||||
|
{
|
||||||
|
// D3DX had this computation backwards (pPoints[iPoint] - pSteps[iStep])
|
||||||
|
// this fix improves RMS of the alpha component
|
||||||
|
float fDiff = pSteps[iStep] - pPoints[iPoint];
|
||||||
|
|
||||||
|
dX += pC[iStep] * fDiff;
|
||||||
|
d2X += pC[iStep] * pC[iStep];
|
||||||
|
|
||||||
|
dY += pD[iStep] * fDiff;
|
||||||
|
d2Y += pD[iStep] * pD[iStep];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move endpoints
|
||||||
|
if(d2X > 0.0f)
|
||||||
|
fX -= dX / d2X;
|
||||||
|
|
||||||
|
if(d2Y > 0.0f)
|
||||||
|
fY -= dY / d2Y;
|
||||||
|
|
||||||
|
if(fX > fY)
|
||||||
|
{
|
||||||
|
float f = fX; fX = fY; fY = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((dX * dX < (1.0f / 64.0f)) && (dY * dY < (1.0f / 64.0f)))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
*pX = (fX < MIN_VALUE) ? MIN_VALUE : (fX > MAX_VALUE) ? MAX_VALUE : fX;
|
||||||
|
*pY = (fY < MIN_VALUE) ? MIN_VALUE : (fY > MAX_VALUE) ? MAX_VALUE : fY;
|
||||||
|
}
|
||||||
|
#pragma warning(pop)
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
// Functions
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
typedef void (*BC_DECODE)(XMVECTOR *pColor, const uint8_t *pBC);
|
||||||
|
typedef void (*BC_ENCODE)(uint8_t *pDXT, const XMVECTOR *pColor, DWORD flags);
|
||||||
|
|
||||||
|
void D3DXDecodeBC1(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(8) const uint8_t *pBC);
|
||||||
|
void D3DXDecodeBC2(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(16) const uint8_t *pBC);
|
||||||
|
void D3DXDecodeBC3(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(16) const uint8_t *pBC);
|
||||||
|
void D3DXDecodeBC4U(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(8) const uint8_t *pBC);
|
||||||
|
void D3DXDecodeBC4S(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(8) const uint8_t *pBC);
|
||||||
|
void D3DXDecodeBC5U(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(16) const uint8_t *pBC);
|
||||||
|
void D3DXDecodeBC5S(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(16) const uint8_t *pBC);
|
||||||
|
void D3DXDecodeBC6HU(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(16) const uint8_t *pBC);
|
||||||
|
void D3DXDecodeBC6HS(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(16) const uint8_t *pBC);
|
||||||
|
void D3DXDecodeBC7(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(16) const uint8_t *pBC);
|
||||||
|
|
||||||
|
void D3DXEncodeBC1(_Out_writes_(8) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ float alphaRef, _In_ DWORD flags);
|
||||||
|
// BC1 requires one additional parameter, so it doesn't match signature of BC_ENCODE above
|
||||||
|
|
||||||
|
void D3DXEncodeBC2(_Out_writes_(16) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags);
|
||||||
|
void D3DXEncodeBC3(_Out_writes_(16) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags);
|
||||||
|
void D3DXEncodeBC4U(_Out_writes_(8) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags);
|
||||||
|
void D3DXEncodeBC4S(_Out_writes_(8) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags);
|
||||||
|
void D3DXEncodeBC5U(_Out_writes_(16) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags);
|
||||||
|
void D3DXEncodeBC5S(_Out_writes_(16) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags);
|
||||||
|
void D3DXEncodeBC6HU(_Out_writes_(16) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags);
|
||||||
|
void D3DXEncodeBC6HS(_Out_writes_(16) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags);
|
||||||
|
void D3DXEncodeBC7(_Out_writes_(16) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags);
|
||||||
|
|
||||||
|
}; // namespace
|
548
Switch_Toolbox/Lib/DirectXTex/BC4BC5.cpp
Normal file
548
Switch_Toolbox/Lib/DirectXTex/BC4BC5.cpp
Normal file
|
@ -0,0 +1,548 @@
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
// BC4BC5.cpp
|
||||||
|
//
|
||||||
|
// Block-compression (BC) functionality for BC4 and BC5 (DirectX 10 texture compression)
|
||||||
|
//
|
||||||
|
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||||
|
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
||||||
|
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||||
|
// PARTICULAR PURPOSE.
|
||||||
|
//
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
//
|
||||||
|
// http://go.microsoft.com/fwlink/?LinkId=248926
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "directxtexp.h"
|
||||||
|
|
||||||
|
#include "BC.h"
|
||||||
|
|
||||||
|
namespace DirectX
|
||||||
|
{
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Constants
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Because these are used in SAL annotations, they need to remain macros rather than const values
|
||||||
|
#define BLOCK_LEN 4
|
||||||
|
// length of each block in texel
|
||||||
|
|
||||||
|
#define BLOCK_SIZE (BLOCK_LEN * BLOCK_LEN)
|
||||||
|
// total texels in a 4x4 block.
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Structures
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable : 4201)
|
||||||
|
|
||||||
|
// BC4U/BC5U
|
||||||
|
struct BC4_UNORM
|
||||||
|
{
|
||||||
|
float R(size_t uOffset) const
|
||||||
|
{
|
||||||
|
size_t uIndex = GetIndex(uOffset);
|
||||||
|
return DecodeFromIndex(uIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
float DecodeFromIndex(size_t uIndex) const
|
||||||
|
{
|
||||||
|
if (uIndex == 0)
|
||||||
|
return red_0 / 255.0f;
|
||||||
|
if (uIndex == 1)
|
||||||
|
return red_1 / 255.0f;
|
||||||
|
float fred_0 = red_0 / 255.0f;
|
||||||
|
float fred_1 = red_1 / 255.0f;
|
||||||
|
if (red_0 > red_1)
|
||||||
|
{
|
||||||
|
uIndex -= 1;
|
||||||
|
return (fred_0 * (7-uIndex) + fred_1 * uIndex) / 7.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (uIndex == 6)
|
||||||
|
return 0.0f;
|
||||||
|
if (uIndex == 7)
|
||||||
|
return 1.0f;
|
||||||
|
uIndex -= 1;
|
||||||
|
return (fred_0 * (5-uIndex) + fred_1 * uIndex) / 5.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t GetIndex(size_t uOffset) const
|
||||||
|
{
|
||||||
|
return (size_t) ((data >> (3*uOffset + 16)) & 0x07);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetIndex(size_t uOffset, size_t uIndex)
|
||||||
|
{
|
||||||
|
data &= ~((uint64_t) 0x07 << (3*uOffset + 16));
|
||||||
|
data |= ((uint64_t) uIndex << (3*uOffset + 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint8_t red_0;
|
||||||
|
uint8_t red_1;
|
||||||
|
uint8_t indices[6];
|
||||||
|
};
|
||||||
|
uint64_t data;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// BC4S/BC5S
|
||||||
|
struct BC4_SNORM
|
||||||
|
{
|
||||||
|
float R(size_t uOffset) const
|
||||||
|
{
|
||||||
|
size_t uIndex = GetIndex(uOffset);
|
||||||
|
return DecodeFromIndex(uIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
float DecodeFromIndex(size_t uIndex) const
|
||||||
|
{
|
||||||
|
int8_t sred_0 = (red_0 == -128)? -127 : red_0;
|
||||||
|
int8_t sred_1 = (red_1 == -128)? -127 : red_1;
|
||||||
|
|
||||||
|
if (uIndex == 0)
|
||||||
|
return sred_0 / 127.0f;
|
||||||
|
if (uIndex == 1)
|
||||||
|
return sred_1 / 127.0f;
|
||||||
|
float fred_0 = sred_0 / 127.0f;
|
||||||
|
float fred_1 = sred_1 / 127.0f;
|
||||||
|
if (red_0 > red_1)
|
||||||
|
{
|
||||||
|
uIndex -= 1;
|
||||||
|
return (fred_0 * (7-uIndex) + fred_1 * uIndex) / 7.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (uIndex == 6)
|
||||||
|
return -1.0f;
|
||||||
|
if (uIndex == 7)
|
||||||
|
return 1.0f;
|
||||||
|
uIndex -= 1;
|
||||||
|
return (fred_0 * (5-uIndex) + fred_1 * uIndex) / 5.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t GetIndex(size_t uOffset) const
|
||||||
|
{
|
||||||
|
return (size_t) ((data >> (3*uOffset + 16)) & 0x07);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetIndex(size_t uOffset, size_t uIndex)
|
||||||
|
{
|
||||||
|
data &= ~((uint64_t) 0x07 << (3*uOffset + 16));
|
||||||
|
data |= ((uint64_t) uIndex << (3*uOffset + 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
int8_t red_0;
|
||||||
|
int8_t red_1;
|
||||||
|
uint8_t indices[6];
|
||||||
|
};
|
||||||
|
uint64_t data;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#pragma warning(pop)
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
// Convert a floating point value to an 8-bit SNORM
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
static void inline FloatToSNorm( _In_ float fVal, _Out_ int8_t *piSNorm )
|
||||||
|
{
|
||||||
|
const uint32_t dwMostNeg = ( 1 << ( 8 * sizeof( int8_t ) - 1 ) );
|
||||||
|
|
||||||
|
if( _isnan( fVal ) )
|
||||||
|
fVal = 0;
|
||||||
|
else
|
||||||
|
if( fVal > 1 )
|
||||||
|
fVal = 1; // Clamp to 1
|
||||||
|
else
|
||||||
|
if( fVal < -1 )
|
||||||
|
fVal = -1; // Clamp to -1
|
||||||
|
|
||||||
|
fVal = fVal * (int8_t) ( dwMostNeg - 1 );
|
||||||
|
|
||||||
|
if( fVal >= 0 )
|
||||||
|
fVal += .5f;
|
||||||
|
else
|
||||||
|
fVal -= .5f;
|
||||||
|
|
||||||
|
*piSNorm = (int8_t) (fVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
static void FindEndPointsBC4U( _In_reads_(BLOCK_SIZE) const float theTexelsU[], _Out_ uint8_t &endpointU_0, _Out_ uint8_t &endpointU_1)
|
||||||
|
{
|
||||||
|
// The boundary of codec for signed/unsigned format
|
||||||
|
float MIN_NORM;
|
||||||
|
float MAX_NORM = 1.0f;
|
||||||
|
int8_t iStart, iEnd;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
MIN_NORM = 0.0f;
|
||||||
|
|
||||||
|
// Find max/min of input texels
|
||||||
|
float fBlockMax = theTexelsU[0];
|
||||||
|
float fBlockMin = theTexelsU[0];
|
||||||
|
for (i = 0; i < BLOCK_SIZE; ++i)
|
||||||
|
{
|
||||||
|
if (theTexelsU[i]<fBlockMin)
|
||||||
|
{
|
||||||
|
fBlockMin = theTexelsU[i];
|
||||||
|
}
|
||||||
|
else if (theTexelsU[i]>fBlockMax)
|
||||||
|
{
|
||||||
|
fBlockMax = theTexelsU[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there are boundary values in input texels, Should use 4 block-codec to guarantee
|
||||||
|
// the exact code of the boundary values.
|
||||||
|
bool bUsing4BlockCodec = ( MIN_NORM == fBlockMin || MAX_NORM == fBlockMax );
|
||||||
|
|
||||||
|
// Using Optimize
|
||||||
|
float fStart, fEnd;
|
||||||
|
|
||||||
|
if (!bUsing4BlockCodec)
|
||||||
|
{
|
||||||
|
OptimizeAlpha<false>(&fStart, &fEnd, theTexelsU, 8);
|
||||||
|
|
||||||
|
iStart = (uint8_t) (fStart * 255.0f);
|
||||||
|
iEnd = (uint8_t) (fEnd * 255.0f);
|
||||||
|
|
||||||
|
endpointU_0 = iEnd;
|
||||||
|
endpointU_1 = iStart;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OptimizeAlpha<false>(&fStart, &fEnd, theTexelsU, 6);
|
||||||
|
|
||||||
|
iStart = (uint8_t) (fStart * 255.0f);
|
||||||
|
iEnd = (uint8_t) (fEnd * 255.0f);
|
||||||
|
|
||||||
|
endpointU_1 = iEnd;
|
||||||
|
endpointU_0 = iStart;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FindEndPointsBC4S(_In_reads_(BLOCK_SIZE) const float theTexelsU[], _Out_ int8_t &endpointU_0, _Out_ int8_t &endpointU_1)
|
||||||
|
{
|
||||||
|
// The boundary of codec for signed/unsigned format
|
||||||
|
float MIN_NORM;
|
||||||
|
float MAX_NORM = 1.0f;
|
||||||
|
int8_t iStart, iEnd;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
MIN_NORM = -1.0f;
|
||||||
|
|
||||||
|
// Find max/min of input texels
|
||||||
|
float fBlockMax = theTexelsU[0];
|
||||||
|
float fBlockMin = theTexelsU[0];
|
||||||
|
for (i = 0; i < BLOCK_SIZE; ++i)
|
||||||
|
{
|
||||||
|
if (theTexelsU[i]<fBlockMin)
|
||||||
|
{
|
||||||
|
fBlockMin = theTexelsU[i];
|
||||||
|
}
|
||||||
|
else if (theTexelsU[i]>fBlockMax)
|
||||||
|
{
|
||||||
|
fBlockMax = theTexelsU[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there are boundary values in input texels, Should use 4 block-codec to guarantee
|
||||||
|
// the exact code of the boundary values.
|
||||||
|
bool bUsing4BlockCodec = ( MIN_NORM == fBlockMin || MAX_NORM == fBlockMax );
|
||||||
|
|
||||||
|
// Using Optimize
|
||||||
|
float fStart, fEnd;
|
||||||
|
|
||||||
|
if (!bUsing4BlockCodec)
|
||||||
|
{
|
||||||
|
OptimizeAlpha<true>(&fStart, &fEnd, theTexelsU, 8);
|
||||||
|
|
||||||
|
FloatToSNorm(fStart, &iStart);
|
||||||
|
FloatToSNorm(fEnd, &iEnd);
|
||||||
|
|
||||||
|
endpointU_0 = iEnd;
|
||||||
|
endpointU_1 = iStart;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OptimizeAlpha<true>(&fStart, &fEnd, theTexelsU, 6);
|
||||||
|
|
||||||
|
FloatToSNorm(fStart, &iStart);
|
||||||
|
FloatToSNorm(fEnd, &iEnd);
|
||||||
|
|
||||||
|
endpointU_1 = iEnd;
|
||||||
|
endpointU_0 = iStart;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
static inline void FindEndPointsBC5U( _In_reads_(BLOCK_SIZE) const float theTexelsU[], _In_reads_(BLOCK_SIZE) const float theTexelsV[],
|
||||||
|
_Out_ uint8_t &endpointU_0, _Out_ uint8_t &endpointU_1, _Out_ uint8_t &endpointV_0, _Out_ uint8_t &endpointV_1)
|
||||||
|
{
|
||||||
|
//Encoding the U and V channel by BC4 codec separately.
|
||||||
|
FindEndPointsBC4U( theTexelsU, endpointU_0, endpointU_1);
|
||||||
|
FindEndPointsBC4U( theTexelsV, endpointV_0, endpointV_1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void FindEndPointsBC5S( _In_reads_(BLOCK_SIZE) const float theTexelsU[], _In_reads_(BLOCK_SIZE) const float theTexelsV[],
|
||||||
|
_Out_ int8_t &endpointU_0, _Out_ int8_t &endpointU_1, _Out_ int8_t &endpointV_0, _Out_ int8_t &endpointV_1)
|
||||||
|
{
|
||||||
|
//Encoding the U and V channel by BC4 codec separately.
|
||||||
|
FindEndPointsBC4S( theTexelsU, endpointU_0, endpointU_1);
|
||||||
|
FindEndPointsBC4S( theTexelsV, endpointV_0, endpointV_1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
static void FindClosestUNORM(_Inout_ BC4_UNORM* pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const float theTexelsU[])
|
||||||
|
{
|
||||||
|
float rGradient[8];
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 8; ++i)
|
||||||
|
{
|
||||||
|
rGradient[i] = pBC->DecodeFromIndex(i);
|
||||||
|
}
|
||||||
|
for (i = 0; i < NUM_PIXELS_PER_BLOCK; ++i)
|
||||||
|
{
|
||||||
|
size_t uBestIndex = 0;
|
||||||
|
float fBestDelta = 100000;
|
||||||
|
for (size_t uIndex = 0; uIndex < 8; uIndex++)
|
||||||
|
{
|
||||||
|
float fCurrentDelta = fabsf(rGradient[uIndex]-theTexelsU[i]);
|
||||||
|
if (fCurrentDelta < fBestDelta)
|
||||||
|
{
|
||||||
|
uBestIndex = uIndex;
|
||||||
|
fBestDelta = fCurrentDelta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pBC->SetIndex(i, uBestIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FindClosestSNORM(_Inout_ BC4_SNORM* pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const float theTexelsU[])
|
||||||
|
{
|
||||||
|
float rGradient[8];
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 8; ++i)
|
||||||
|
{
|
||||||
|
rGradient[i] = pBC->DecodeFromIndex(i);
|
||||||
|
}
|
||||||
|
for (i = 0; i < NUM_PIXELS_PER_BLOCK; ++i)
|
||||||
|
{
|
||||||
|
size_t uBestIndex = 0;
|
||||||
|
float fBestDelta = 100000;
|
||||||
|
for (size_t uIndex = 0; uIndex < 8; uIndex++)
|
||||||
|
{
|
||||||
|
float fCurrentDelta = fabsf(rGradient[uIndex]-theTexelsU[i]);
|
||||||
|
if (fCurrentDelta < fBestDelta)
|
||||||
|
{
|
||||||
|
uBestIndex = uIndex;
|
||||||
|
fBestDelta = fCurrentDelta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pBC->SetIndex(i, uBestIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//=====================================================================================
|
||||||
|
// Entry points
|
||||||
|
//=====================================================================================
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
// BC4 Compression
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
_Use_decl_annotations_
|
||||||
|
void D3DXDecodeBC4U( XMVECTOR *pColor, const uint8_t *pBC )
|
||||||
|
{
|
||||||
|
assert( pColor && pBC );
|
||||||
|
static_assert( sizeof(BC4_UNORM) == 8, "BC4_UNORM should be 8 bytes" );
|
||||||
|
|
||||||
|
auto pBC4 = reinterpret_cast<const BC4_UNORM*>(pBC);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i)
|
||||||
|
{
|
||||||
|
#pragma prefast(suppress:22103, "writing blocks in two halves confuses tool")
|
||||||
|
pColor[i] = XMVectorSet( pBC4->R(i), 0, 0, 1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_Use_decl_annotations_
|
||||||
|
void D3DXDecodeBC4S(XMVECTOR *pColor, const uint8_t *pBC)
|
||||||
|
{
|
||||||
|
assert( pColor && pBC );
|
||||||
|
static_assert( sizeof(BC4_SNORM) == 8, "BC4_SNORM should be 8 bytes" );
|
||||||
|
|
||||||
|
auto pBC4 = reinterpret_cast<const BC4_SNORM*>(pBC);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i)
|
||||||
|
{
|
||||||
|
#pragma prefast(suppress:22103, "writing blocks in two halves confuses tool")
|
||||||
|
pColor[i] = XMVectorSet( pBC4->R(i), 0, 0, 1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_Use_decl_annotations_
|
||||||
|
void D3DXEncodeBC4U( uint8_t *pBC, const XMVECTOR *pColor, DWORD flags )
|
||||||
|
{
|
||||||
|
UNREFERENCED_PARAMETER( flags );
|
||||||
|
|
||||||
|
assert( pBC && pColor );
|
||||||
|
static_assert( sizeof(BC4_UNORM) == 8, "BC4_UNORM should be 8 bytes" );
|
||||||
|
|
||||||
|
memset(pBC, 0, sizeof(BC4_UNORM));
|
||||||
|
auto pBC4 = reinterpret_cast<BC4_UNORM*>(pBC);
|
||||||
|
float theTexelsU[NUM_PIXELS_PER_BLOCK];
|
||||||
|
|
||||||
|
for (size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i)
|
||||||
|
{
|
||||||
|
theTexelsU[i] = XMVectorGetX( pColor[i] );
|
||||||
|
}
|
||||||
|
|
||||||
|
FindEndPointsBC4U(theTexelsU, pBC4->red_0, pBC4->red_1);
|
||||||
|
FindClosestUNORM(pBC4, theTexelsU);
|
||||||
|
}
|
||||||
|
|
||||||
|
_Use_decl_annotations_
|
||||||
|
void D3DXEncodeBC4S( uint8_t *pBC, const XMVECTOR *pColor, DWORD flags )
|
||||||
|
{
|
||||||
|
UNREFERENCED_PARAMETER( flags );
|
||||||
|
|
||||||
|
assert( pBC && pColor );
|
||||||
|
static_assert( sizeof(BC4_SNORM) == 8, "BC4_SNORM should be 8 bytes" );
|
||||||
|
|
||||||
|
memset(pBC, 0, sizeof(BC4_UNORM));
|
||||||
|
auto pBC4 = reinterpret_cast<BC4_SNORM*>(pBC);
|
||||||
|
float theTexelsU[NUM_PIXELS_PER_BLOCK];
|
||||||
|
|
||||||
|
for (size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i)
|
||||||
|
{
|
||||||
|
theTexelsU[i] = XMVectorGetX( pColor[i] );
|
||||||
|
}
|
||||||
|
|
||||||
|
FindEndPointsBC4S(theTexelsU, pBC4->red_0, pBC4->red_1);
|
||||||
|
FindClosestSNORM(pBC4, theTexelsU);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
// BC5 Compression
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
_Use_decl_annotations_
|
||||||
|
void D3DXDecodeBC5U(XMVECTOR *pColor, const uint8_t *pBC)
|
||||||
|
{
|
||||||
|
assert( pColor && pBC );
|
||||||
|
static_assert( sizeof(BC4_UNORM) == 8, "BC4_UNORM should be 8 bytes" );
|
||||||
|
|
||||||
|
auto pBCR = reinterpret_cast<const BC4_UNORM*>(pBC);
|
||||||
|
auto pBCG = reinterpret_cast<const BC4_UNORM*>(pBC+sizeof(BC4_UNORM));
|
||||||
|
|
||||||
|
for (size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i)
|
||||||
|
{
|
||||||
|
#pragma prefast(suppress:22103, "writing blocks in two halves confuses tool")
|
||||||
|
pColor[i] = XMVectorSet(pBCR->R(i), pBCG->R(i), 0, 1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_Use_decl_annotations_
|
||||||
|
void D3DXDecodeBC5S(XMVECTOR *pColor, const uint8_t *pBC)
|
||||||
|
{
|
||||||
|
assert( pColor && pBC );
|
||||||
|
static_assert( sizeof(BC4_SNORM) == 8, "BC4_SNORM should be 8 bytes" );
|
||||||
|
|
||||||
|
auto pBCR = reinterpret_cast<const BC4_SNORM*>(pBC);
|
||||||
|
auto pBCG = reinterpret_cast<const BC4_SNORM*>(pBC+sizeof(BC4_SNORM));
|
||||||
|
|
||||||
|
for (size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i)
|
||||||
|
{
|
||||||
|
#pragma prefast(suppress:22103, "writing blocks in two halves confuses tool")
|
||||||
|
pColor[i] = XMVectorSet(pBCR->R(i), pBCG->R(i), 0, 1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_Use_decl_annotations_
|
||||||
|
void D3DXEncodeBC5U( uint8_t *pBC, const XMVECTOR *pColor, DWORD flags )
|
||||||
|
{
|
||||||
|
UNREFERENCED_PARAMETER( flags );
|
||||||
|
|
||||||
|
assert( pBC && pColor );
|
||||||
|
static_assert( sizeof(BC4_UNORM) == 8, "BC4_UNORM should be 8 bytes" );
|
||||||
|
|
||||||
|
memset(pBC, 0, sizeof(BC4_UNORM)*2);
|
||||||
|
auto pBCR = reinterpret_cast<BC4_UNORM*>(pBC);
|
||||||
|
auto pBCG = reinterpret_cast<BC4_UNORM*>(pBC+sizeof(BC4_UNORM));
|
||||||
|
float theTexelsU[NUM_PIXELS_PER_BLOCK];
|
||||||
|
float theTexelsV[NUM_PIXELS_PER_BLOCK];
|
||||||
|
|
||||||
|
for (size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i)
|
||||||
|
{
|
||||||
|
XMFLOAT4A clr;
|
||||||
|
XMStoreFloat4A( &clr, pColor[i] );
|
||||||
|
theTexelsU[i] = clr.x;
|
||||||
|
theTexelsV[i] = clr.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
FindEndPointsBC5U(
|
||||||
|
theTexelsU,
|
||||||
|
theTexelsV,
|
||||||
|
pBCR->red_0,
|
||||||
|
pBCR->red_1,
|
||||||
|
pBCG->red_0,
|
||||||
|
pBCG->red_1);
|
||||||
|
|
||||||
|
FindClosestUNORM(pBCR, theTexelsU);
|
||||||
|
FindClosestUNORM(pBCG, theTexelsV);
|
||||||
|
}
|
||||||
|
|
||||||
|
_Use_decl_annotations_
|
||||||
|
void D3DXEncodeBC5S( uint8_t *pBC, const XMVECTOR *pColor, DWORD flags )
|
||||||
|
{
|
||||||
|
UNREFERENCED_PARAMETER( flags );
|
||||||
|
|
||||||
|
assert( pBC && pColor );
|
||||||
|
static_assert( sizeof(BC4_SNORM) == 8, "BC4_SNORM should be 8 bytes" );
|
||||||
|
|
||||||
|
memset(pBC, 0, sizeof(BC4_UNORM)*2);
|
||||||
|
auto pBCR = reinterpret_cast<BC4_SNORM*>(pBC);
|
||||||
|
auto pBCG = reinterpret_cast<BC4_SNORM*>(pBC+sizeof(BC4_SNORM));
|
||||||
|
float theTexelsU[NUM_PIXELS_PER_BLOCK];
|
||||||
|
float theTexelsV[NUM_PIXELS_PER_BLOCK];
|
||||||
|
|
||||||
|
for (size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i)
|
||||||
|
{
|
||||||
|
XMFLOAT4A clr;
|
||||||
|
XMStoreFloat4A( &clr, pColor[i] );
|
||||||
|
theTexelsU[i] = clr.x;
|
||||||
|
theTexelsV[i] = clr.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
FindEndPointsBC5S(
|
||||||
|
theTexelsU,
|
||||||
|
theTexelsV,
|
||||||
|
pBCR->red_0,
|
||||||
|
pBCR->red_1,
|
||||||
|
pBCG->red_0,
|
||||||
|
pBCG->red_1);
|
||||||
|
|
||||||
|
FindClosestSNORM(pBCR, theTexelsU);
|
||||||
|
FindClosestSNORM(pBCG, theTexelsV);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
2874
Switch_Toolbox/Lib/DirectXTex/BC6HBC7.cpp
Normal file
2874
Switch_Toolbox/Lib/DirectXTex/BC6HBC7.cpp
Normal file
File diff suppressed because it is too large
Load diff
237
Switch_Toolbox/Lib/DirectXTex/DDS.h
Normal file
237
Switch_Toolbox/Lib/DirectXTex/DDS.h
Normal file
|
@ -0,0 +1,237 @@
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
// dds.h
|
||||||
|
//
|
||||||
|
// This header defines constants and structures that are useful when parsing
|
||||||
|
// DDS files. DDS files were originally designed to use several structures
|
||||||
|
// and constants that are native to DirectDraw and are defined in ddraw.h,
|
||||||
|
// such as DDSURFACEDESC2 and DDSCAPS2. This file defines similar
|
||||||
|
// (compatible) constants and structures so that one can use DDS files
|
||||||
|
// without needing to include ddraw.h.
|
||||||
|
//
|
||||||
|
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||||
|
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
||||||
|
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||||
|
// PARTICULAR PURPOSE.
|
||||||
|
//
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
//
|
||||||
|
// http://go.microsoft.com/fwlink/?LinkId=248926
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if defined(_XBOX_ONE) && defined(_TITLE)
|
||||||
|
#include <d3d11_x.h>
|
||||||
|
#else
|
||||||
|
#include <dxgiformat.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// VS 2010's stdint.h conflicts with intsafe.h
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable : 4005)
|
||||||
|
#include <stdint.h>
|
||||||
|
#pragma warning(pop)
|
||||||
|
|
||||||
|
namespace DirectX
|
||||||
|
{
|
||||||
|
|
||||||
|
#pragma pack(push,1)
|
||||||
|
|
||||||
|
const uint32_t DDS_MAGIC = 0x20534444; // "DDS "
|
||||||
|
|
||||||
|
struct DDS_PIXELFORMAT
|
||||||
|
{
|
||||||
|
uint32_t dwSize;
|
||||||
|
uint32_t dwFlags;
|
||||||
|
uint32_t dwFourCC;
|
||||||
|
uint32_t dwRGBBitCount;
|
||||||
|
uint32_t dwRBitMask;
|
||||||
|
uint32_t dwGBitMask;
|
||||||
|
uint32_t dwBBitMask;
|
||||||
|
uint32_t dwABitMask;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define DDS_FOURCC 0x00000004 // DDPF_FOURCC
|
||||||
|
#define DDS_RGB 0x00000040 // DDPF_RGB
|
||||||
|
#define DDS_RGBA 0x00000041 // DDPF_RGB | DDPF_ALPHAPIXELS
|
||||||
|
#define DDS_LUMINANCE 0x00020000 // DDPF_LUMINANCE
|
||||||
|
#define DDS_LUMINANCEA 0x00020001 // DDPF_LUMINANCE | DDPF_ALPHAPIXELS
|
||||||
|
#define DDS_ALPHA 0x00000002 // DDPF_ALPHA
|
||||||
|
#define DDS_PAL8 0x00000020 // DDPF_PALETTEINDEXED8
|
||||||
|
|
||||||
|
#ifndef MAKEFOURCC
|
||||||
|
#define MAKEFOURCC(ch0, ch1, ch2, ch3) \
|
||||||
|
((uint32_t)(uint8_t)(ch0) | ((uint32_t)(uint8_t)(ch1) << 8) | \
|
||||||
|
((uint32_t)(uint8_t)(ch2) << 16) | ((uint32_t)(uint8_t)(ch3) << 24 ))
|
||||||
|
#endif /* defined(MAKEFOURCC) */
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_DXT1 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','1'), 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_DXT2 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','2'), 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_DXT3 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','3'), 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_DXT4 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','4'), 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_DXT5 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','5'), 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_BC4_UNORM =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('B','C','4','U'), 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_BC4_SNORM =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('B','C','4','S'), 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_BC5_UNORM =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('B','C','5','U'), 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_BC5_SNORM =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('B','C','5','S'), 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_R8G8_B8G8 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('R','G','B','G'), 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_G8R8_G8B8 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('G','R','G','B'), 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_YUY2 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('Y','U','Y','2'), 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_A8R8G8B8 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_X8R8G8B8 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_A8B8G8R8 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_X8B8G8R8 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_G16R16 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 32, 0x0000ffff, 0xffff0000, 0x00000000, 0x00000000 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_R5G6B5 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 16, 0x0000f800, 0x000007e0, 0x0000001f, 0x00000000 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_A1R5G5B5 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 16, 0x00007c00, 0x000003e0, 0x0000001f, 0x00008000 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_A4R4G4B4 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 16, 0x00000f00, 0x000000f0, 0x0000000f, 0x0000f000 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_R8G8B8 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_L8 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_LUMINANCE, 0, 8, 0xff, 0x00, 0x00, 0x00 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_L16 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_LUMINANCE, 0, 16, 0xffff, 0x0000, 0x0000, 0x0000 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_A8L8 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_LUMINANCEA, 0, 16, 0x00ff, 0x0000, 0x0000, 0xff00 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_A8 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_ALPHA, 0, 8, 0x00, 0x00, 0x00, 0xff };
|
||||||
|
|
||||||
|
// D3DFMT_A2R10G10B10/D3DFMT_A2B10G10R10 should be written using DX10 extension to avoid D3DX 10:10:10:2 reversal issue
|
||||||
|
|
||||||
|
// This indicates the DDS_HEADER_DXT10 extension is present (the format is in dxgiFormat)
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_DX10 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','1','0'), 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
#define DDS_HEADER_FLAGS_TEXTURE 0x00001007 // DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT
|
||||||
|
#define DDS_HEADER_FLAGS_MIPMAP 0x00020000 // DDSD_MIPMAPCOUNT
|
||||||
|
#define DDS_HEADER_FLAGS_VOLUME 0x00800000 // DDSD_DEPTH
|
||||||
|
#define DDS_HEADER_FLAGS_PITCH 0x00000008 // DDSD_PITCH
|
||||||
|
#define DDS_HEADER_FLAGS_LINEARSIZE 0x00080000 // DDSD_LINEARSIZE
|
||||||
|
|
||||||
|
#define DDS_HEIGHT 0x00000002 // DDSD_HEIGHT
|
||||||
|
#define DDS_WIDTH 0x00000004 // DDSD_WIDTH
|
||||||
|
|
||||||
|
#define DDS_SURFACE_FLAGS_TEXTURE 0x00001000 // DDSCAPS_TEXTURE
|
||||||
|
#define DDS_SURFACE_FLAGS_MIPMAP 0x00400008 // DDSCAPS_COMPLEX | DDSCAPS_MIPMAP
|
||||||
|
#define DDS_SURFACE_FLAGS_CUBEMAP 0x00000008 // DDSCAPS_COMPLEX
|
||||||
|
|
||||||
|
#define DDS_CUBEMAP_POSITIVEX 0x00000600 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX
|
||||||
|
#define DDS_CUBEMAP_NEGATIVEX 0x00000a00 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX
|
||||||
|
#define DDS_CUBEMAP_POSITIVEY 0x00001200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY
|
||||||
|
#define DDS_CUBEMAP_NEGATIVEY 0x00002200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY
|
||||||
|
#define DDS_CUBEMAP_POSITIVEZ 0x00004200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ
|
||||||
|
#define DDS_CUBEMAP_NEGATIVEZ 0x00008200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ
|
||||||
|
|
||||||
|
#define DDS_CUBEMAP_ALLFACES ( DDS_CUBEMAP_POSITIVEX | DDS_CUBEMAP_NEGATIVEX |\
|
||||||
|
DDS_CUBEMAP_POSITIVEY | DDS_CUBEMAP_NEGATIVEY |\
|
||||||
|
DDS_CUBEMAP_POSITIVEZ | DDS_CUBEMAP_NEGATIVEZ )
|
||||||
|
|
||||||
|
#define DDS_CUBEMAP 0x00000200 // DDSCAPS2_CUBEMAP
|
||||||
|
|
||||||
|
#define DDS_FLAGS_VOLUME 0x00200000 // DDSCAPS2_VOLUME
|
||||||
|
|
||||||
|
// Subset here matches D3D10_RESOURCE_DIMENSION and D3D11_RESOURCE_DIMENSION
|
||||||
|
enum DDS_RESOURCE_DIMENSION
|
||||||
|
{
|
||||||
|
DDS_DIMENSION_TEXTURE1D = 2,
|
||||||
|
DDS_DIMENSION_TEXTURE2D = 3,
|
||||||
|
DDS_DIMENSION_TEXTURE3D = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Subset here matches D3D10_RESOURCE_MISC_FLAG and D3D11_RESOURCE_MISC_FLAG
|
||||||
|
enum DDS_RESOURCE_MISC_FLAG
|
||||||
|
{
|
||||||
|
DDS_RESOURCE_MISC_TEXTURECUBE = 0x4L,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum DDS_MISC_FLAGS2
|
||||||
|
{
|
||||||
|
DDS_MISC_FLAGS2_ALPHA_MODE_MASK = 0x7L,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum DDS_ALPHA_MODE
|
||||||
|
{
|
||||||
|
DDS_ALPHA_MODE_UNKNOWN = 0,
|
||||||
|
DDS_ALPHA_MODE_STRAIGHT = 1,
|
||||||
|
DDS_ALPHA_MODE_PREMULTIPLIED = 2,
|
||||||
|
DDS_ALPHA_MODE_OPAQUE = 3,
|
||||||
|
DDS_ALPHA_MODE_CUSTOM = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DDS_HEADER
|
||||||
|
{
|
||||||
|
uint32_t dwSize;
|
||||||
|
uint32_t dwFlags;
|
||||||
|
uint32_t dwHeight;
|
||||||
|
uint32_t dwWidth;
|
||||||
|
uint32_t dwPitchOrLinearSize;
|
||||||
|
uint32_t dwDepth; // only if DDS_HEADER_FLAGS_VOLUME is set in dwFlags
|
||||||
|
uint32_t dwMipMapCount;
|
||||||
|
uint32_t dwReserved1[11];
|
||||||
|
DDS_PIXELFORMAT ddspf;
|
||||||
|
uint32_t dwCaps;
|
||||||
|
uint32_t dwCaps2;
|
||||||
|
uint32_t dwCaps3;
|
||||||
|
uint32_t dwCaps4;
|
||||||
|
uint32_t dwReserved2;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DDS_HEADER_DXT10
|
||||||
|
{
|
||||||
|
DXGI_FORMAT dxgiFormat;
|
||||||
|
uint32_t resourceDimension;
|
||||||
|
uint32_t miscFlag; // see DDS_RESOURCE_MISC_FLAG
|
||||||
|
uint32_t arraySize;
|
||||||
|
uint32_t miscFlags2; // see DDS_MISC_FLAGS2
|
||||||
|
};
|
||||||
|
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
static_assert( sizeof(DDS_HEADER) == 124, "DDS Header size mismatch" );
|
||||||
|
static_assert( sizeof(DDS_HEADER_DXT10) == 20, "DDS DX10 Extended Header size mismatch");
|
||||||
|
|
||||||
|
}; // namespace
|
654
Switch_Toolbox/Lib/DirectXTex/DirectXTex.h
Normal file
654
Switch_Toolbox/Lib/DirectXTex/DirectXTex.h
Normal file
|
@ -0,0 +1,654 @@
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
// DirectXTex.h
|
||||||
|
//
|
||||||
|
// DirectX Texture Library
|
||||||
|
//
|
||||||
|
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||||
|
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
||||||
|
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||||
|
// PARTICULAR PURPOSE.
|
||||||
|
//
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
//
|
||||||
|
// http://go.microsoft.com/fwlink/?LinkId=248926
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) && (_WIN32_WINNT <= _WIN32_WINNT_WIN8)
|
||||||
|
#error WIC is not supported on Windows Phone 8.0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// VS 2010's stdint.h conflicts with intsafe.h
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable : 4005)
|
||||||
|
#include <stdint.h>
|
||||||
|
#pragma warning(pop)
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
#if defined(_XBOX_ONE) && defined(_TITLE)
|
||||||
|
#include <d3d11_x.h>
|
||||||
|
#define DCOMMON_H_INCLUDED
|
||||||
|
#else
|
||||||
|
#include <d3d11_1.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <ocidl.h>
|
||||||
|
|
||||||
|
// VS 2010 doesn't support explicit calling convention for std::function
|
||||||
|
#ifndef DIRECTX_STD_CALLCONV
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER < 1700)
|
||||||
|
#define DIRECTX_STD_CALLCONV
|
||||||
|
#else
|
||||||
|
#define DIRECTX_STD_CALLCONV __cdecl
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// VS 2010/2012 do not support =default =delete
|
||||||
|
#ifndef DIRECTX_CTOR_DEFAULT
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER < 1800)
|
||||||
|
#define DIRECTX_CTOR_DEFAULT {}
|
||||||
|
#define DIRECTX_CTOR_DELETE ;
|
||||||
|
#else
|
||||||
|
#define DIRECTX_CTOR_DEFAULT =default;
|
||||||
|
#define DIRECTX_CTOR_DELETE =delete;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define DIRECTX_TEX_VERSION 133
|
||||||
|
|
||||||
|
struct IWICImagingFactory;
|
||||||
|
|
||||||
|
|
||||||
|
namespace DirectX
|
||||||
|
{
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
|
// DXGI Format Utilities
|
||||||
|
bool __cdecl IsValid( _In_ DXGI_FORMAT fmt );
|
||||||
|
bool __cdecl IsCompressed( _In_ DXGI_FORMAT fmt );
|
||||||
|
bool __cdecl IsPacked( _In_ DXGI_FORMAT fmt );
|
||||||
|
bool __cdecl IsVideo( _In_ DXGI_FORMAT fmt );
|
||||||
|
bool __cdecl IsPlanar( _In_ DXGI_FORMAT fmt );
|
||||||
|
bool __cdecl IsPalettized( _In_ DXGI_FORMAT fmt );
|
||||||
|
bool __cdecl IsDepthStencil(_In_ DXGI_FORMAT fmt );
|
||||||
|
bool __cdecl IsSRGB( _In_ DXGI_FORMAT fmt );
|
||||||
|
bool __cdecl IsTypeless( _In_ DXGI_FORMAT fmt, _In_ bool partialTypeless = true );
|
||||||
|
|
||||||
|
bool __cdecl HasAlpha( _In_ DXGI_FORMAT fmt );
|
||||||
|
|
||||||
|
size_t __cdecl BitsPerPixel( _In_ DXGI_FORMAT fmt );
|
||||||
|
|
||||||
|
size_t __cdecl BitsPerColor( _In_ DXGI_FORMAT fmt );
|
||||||
|
|
||||||
|
enum CP_FLAGS
|
||||||
|
{
|
||||||
|
CP_FLAGS_NONE = 0x0, // Normal operation
|
||||||
|
CP_FLAGS_LEGACY_DWORD = 0x1, // Assume pitch is DWORD aligned instead of BYTE aligned
|
||||||
|
CP_FLAGS_PARAGRAPH = 0x2, // Assume pitch is 16-byte aligned instead of BYTE aligned
|
||||||
|
CP_FLAGS_YMM = 0x4, // Assume pitch is 32-byte aligned instead of BYTE aligned
|
||||||
|
CP_FLAGS_ZMM = 0x8, // Assume pitch is 64-byte aligned instead of BYTE aligned
|
||||||
|
CP_FLAGS_PAGE4K = 0x200, // Assume pitch is 4096-byte aligned instead of BYTE aligned
|
||||||
|
CP_FLAGS_24BPP = 0x10000, // Override with a legacy 24 bits-per-pixel format size
|
||||||
|
CP_FLAGS_16BPP = 0x20000, // Override with a legacy 16 bits-per-pixel format size
|
||||||
|
CP_FLAGS_8BPP = 0x40000, // Override with a legacy 8 bits-per-pixel format size
|
||||||
|
};
|
||||||
|
|
||||||
|
void __cdecl ComputePitch( _In_ DXGI_FORMAT fmt, _In_ size_t width, _In_ size_t height,
|
||||||
|
_Out_ size_t& rowPitch, _Out_ size_t& slicePitch, _In_ DWORD flags = CP_FLAGS_NONE );
|
||||||
|
|
||||||
|
size_t __cdecl ComputeScanlines( _In_ DXGI_FORMAT fmt, _In_ size_t height );
|
||||||
|
|
||||||
|
DXGI_FORMAT __cdecl MakeSRGB( _In_ DXGI_FORMAT fmt );
|
||||||
|
DXGI_FORMAT __cdecl MakeTypeless( _In_ DXGI_FORMAT fmt );
|
||||||
|
DXGI_FORMAT __cdecl MakeTypelessUNORM( _In_ DXGI_FORMAT fmt );
|
||||||
|
DXGI_FORMAT __cdecl MakeTypelessFLOAT( _In_ DXGI_FORMAT fmt );
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
|
// Texture metadata
|
||||||
|
enum TEX_DIMENSION
|
||||||
|
// Subset here matches D3D10_RESOURCE_DIMENSION and D3D11_RESOURCE_DIMENSION
|
||||||
|
{
|
||||||
|
TEX_DIMENSION_TEXTURE1D = 2,
|
||||||
|
TEX_DIMENSION_TEXTURE2D = 3,
|
||||||
|
TEX_DIMENSION_TEXTURE3D = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum TEX_MISC_FLAG
|
||||||
|
// Subset here matches D3D10_RESOURCE_MISC_FLAG and D3D11_RESOURCE_MISC_FLAG
|
||||||
|
{
|
||||||
|
TEX_MISC_TEXTURECUBE = 0x4L,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum TEX_MISC_FLAG2
|
||||||
|
{
|
||||||
|
TEX_MISC2_ALPHA_MODE_MASK = 0x7L,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum TEX_ALPHA_MODE
|
||||||
|
// Matches DDS_ALPHA_MODE, encoded in MISC_FLAGS2
|
||||||
|
{
|
||||||
|
TEX_ALPHA_MODE_UNKNOWN = 0,
|
||||||
|
TEX_ALPHA_MODE_STRAIGHT = 1,
|
||||||
|
TEX_ALPHA_MODE_PREMULTIPLIED = 2,
|
||||||
|
TEX_ALPHA_MODE_OPAQUE = 3,
|
||||||
|
TEX_ALPHA_MODE_CUSTOM = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TexMetadata
|
||||||
|
{
|
||||||
|
size_t width;
|
||||||
|
size_t height; // Should be 1 for 1D textures
|
||||||
|
size_t depth; // Should be 1 for 1D or 2D textures
|
||||||
|
size_t arraySize; // For cubemap, this is a multiple of 6
|
||||||
|
size_t mipLevels;
|
||||||
|
uint32_t miscFlags;
|
||||||
|
uint32_t miscFlags2;
|
||||||
|
DXGI_FORMAT format;
|
||||||
|
TEX_DIMENSION dimension;
|
||||||
|
|
||||||
|
size_t __cdecl ComputeIndex( _In_ size_t mip, _In_ size_t item, _In_ size_t slice ) const;
|
||||||
|
// Returns size_t(-1) to indicate an out-of-range error
|
||||||
|
|
||||||
|
bool __cdecl IsCubemap() const { return (miscFlags & TEX_MISC_TEXTURECUBE) != 0; }
|
||||||
|
// Helper for miscFlags
|
||||||
|
|
||||||
|
bool __cdecl IsPMAlpha() const { return ((miscFlags2 & TEX_MISC2_ALPHA_MODE_MASK) == TEX_ALPHA_MODE_PREMULTIPLIED) != 0; }
|
||||||
|
void __cdecl SetAlphaMode( TEX_ALPHA_MODE mode ) { miscFlags2 = (miscFlags2 & ~TEX_MISC2_ALPHA_MODE_MASK) | static_cast<uint32_t>(mode); }
|
||||||
|
// Helpers for miscFlags2
|
||||||
|
|
||||||
|
bool __cdecl IsVolumemap() const { return (dimension == TEX_DIMENSION_TEXTURE3D); }
|
||||||
|
// Helper for dimension
|
||||||
|
};
|
||||||
|
|
||||||
|
enum DDS_FLAGS
|
||||||
|
{
|
||||||
|
DDS_FLAGS_NONE = 0x0,
|
||||||
|
|
||||||
|
DDS_FLAGS_LEGACY_DWORD = 0x1,
|
||||||
|
// Assume pitch is DWORD aligned instead of BYTE aligned (used by some legacy DDS files)
|
||||||
|
|
||||||
|
DDS_FLAGS_NO_LEGACY_EXPANSION = 0x2,
|
||||||
|
// Do not implicitly convert legacy formats that result in larger pixel sizes (24 bpp, 3:3:2, A8L8, A4L4, P8, A8P8)
|
||||||
|
|
||||||
|
DDS_FLAGS_NO_R10B10G10A2_FIXUP = 0x4,
|
||||||
|
// Do not use work-around for long-standing D3DX DDS file format issue which reversed the 10:10:10:2 color order masks
|
||||||
|
|
||||||
|
DDS_FLAGS_FORCE_RGB = 0x8,
|
||||||
|
// Convert DXGI 1.1 BGR formats to DXGI_FORMAT_R8G8B8A8_UNORM to avoid use of optional WDDM 1.1 formats
|
||||||
|
|
||||||
|
DDS_FLAGS_NO_16BPP = 0x10,
|
||||||
|
// Conversions avoid use of 565, 5551, and 4444 formats and instead expand to 8888 to avoid use of optional WDDM 1.2 formats
|
||||||
|
|
||||||
|
DDS_FLAGS_EXPAND_LUMINANCE = 0x20,
|
||||||
|
// When loading legacy luminance formats expand replicating the color channels rather than leaving them packed (L8, L16, A8L8)
|
||||||
|
|
||||||
|
DDS_FLAGS_FORCE_DX10_EXT = 0x10000,
|
||||||
|
// Always use the 'DX10' header extension for DDS writer (i.e. don't try to write DX9 compatible DDS files)
|
||||||
|
|
||||||
|
DDS_FLAGS_FORCE_DX10_EXT_MISC2 = 0x20000,
|
||||||
|
// DDS_FLAGS_FORCE_DX10_EXT including miscFlags2 information (result may not be compatible with D3DX10 or D3DX11)
|
||||||
|
};
|
||||||
|
|
||||||
|
enum WIC_FLAGS
|
||||||
|
{
|
||||||
|
WIC_FLAGS_NONE = 0x0,
|
||||||
|
|
||||||
|
WIC_FLAGS_FORCE_RGB = 0x1,
|
||||||
|
// Loads DXGI 1.1 BGR formats as DXGI_FORMAT_R8G8B8A8_UNORM to avoid use of optional WDDM 1.1 formats
|
||||||
|
|
||||||
|
WIC_FLAGS_NO_X2_BIAS = 0x2,
|
||||||
|
// Loads DXGI 1.1 X2 10:10:10:2 format as DXGI_FORMAT_R10G10B10A2_UNORM
|
||||||
|
|
||||||
|
WIC_FLAGS_NO_16BPP = 0x4,
|
||||||
|
// Loads 565, 5551, and 4444 formats as 8888 to avoid use of optional WDDM 1.2 formats
|
||||||
|
|
||||||
|
WIC_FLAGS_ALLOW_MONO = 0x8,
|
||||||
|
// Loads 1-bit monochrome (black & white) as R1_UNORM rather than 8-bit grayscale
|
||||||
|
|
||||||
|
WIC_FLAGS_ALL_FRAMES = 0x10,
|
||||||
|
// Loads all images in a multi-frame file, converting/resizing to match the first frame as needed, defaults to 0th frame otherwise
|
||||||
|
|
||||||
|
WIC_FLAGS_IGNORE_SRGB = 0x20,
|
||||||
|
// Ignores sRGB metadata if present in the file
|
||||||
|
|
||||||
|
WIC_FLAGS_DITHER = 0x10000,
|
||||||
|
// Use ordered 4x4 dithering for any required conversions
|
||||||
|
|
||||||
|
WIC_FLAGS_DITHER_DIFFUSION = 0x20000,
|
||||||
|
// Use error-diffusion dithering for any required conversions
|
||||||
|
|
||||||
|
WIC_FLAGS_FILTER_POINT = 0x100000,
|
||||||
|
WIC_FLAGS_FILTER_LINEAR = 0x200000,
|
||||||
|
WIC_FLAGS_FILTER_CUBIC = 0x300000,
|
||||||
|
WIC_FLAGS_FILTER_FANT = 0x400000, // Combination of Linear and Box filter
|
||||||
|
// Filtering mode to use for any required image resizing (only needed when loading arrays of differently sized images; defaults to Fant)
|
||||||
|
};
|
||||||
|
|
||||||
|
HRESULT __cdecl GetMetadataFromDDSMemory( _In_reads_bytes_(size) LPCVOID pSource, _In_ size_t size, _In_ DWORD flags,
|
||||||
|
_Out_ TexMetadata& metadata );
|
||||||
|
HRESULT __cdecl GetMetadataFromDDSFile( _In_z_ LPCWSTR szFile, _In_ DWORD flags,
|
||||||
|
_Out_ TexMetadata& metadata );
|
||||||
|
|
||||||
|
HRESULT __cdecl GetMetadataFromTGAMemory( _In_reads_bytes_(size) LPCVOID pSource, _In_ size_t size,
|
||||||
|
_Out_ TexMetadata& metadata );
|
||||||
|
HRESULT __cdecl GetMetadataFromTGAFile( _In_z_ LPCWSTR szFile,
|
||||||
|
_Out_ TexMetadata& metadata );
|
||||||
|
|
||||||
|
HRESULT __cdecl GetMetadataFromWICMemory( _In_reads_bytes_(size) LPCVOID pSource, _In_ size_t size, _In_ DWORD flags,
|
||||||
|
_Out_ TexMetadata& metadata );
|
||||||
|
HRESULT __cdecl GetMetadataFromWICFile( _In_z_ LPCWSTR szFile, _In_ DWORD flags,
|
||||||
|
_Out_ TexMetadata& metadata );
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
|
// Bitmap image container
|
||||||
|
struct Image
|
||||||
|
{
|
||||||
|
size_t width;
|
||||||
|
size_t height;
|
||||||
|
DXGI_FORMAT format;
|
||||||
|
size_t rowPitch;
|
||||||
|
size_t slicePitch;
|
||||||
|
uint8_t* pixels;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ScratchImage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ScratchImage()
|
||||||
|
: _nimages(0), _size(0), _image(nullptr), _memory(nullptr) {}
|
||||||
|
ScratchImage(ScratchImage&& moveFrom)
|
||||||
|
: _nimages(0), _size(0), _image(nullptr), _memory(nullptr) { *this = std::move(moveFrom); }
|
||||||
|
~ScratchImage() { Release(); }
|
||||||
|
|
||||||
|
ScratchImage& __cdecl operator= (ScratchImage&& moveFrom);
|
||||||
|
|
||||||
|
HRESULT __cdecl Initialize( _In_ const TexMetadata& mdata, _In_ DWORD flags = CP_FLAGS_NONE );
|
||||||
|
|
||||||
|
HRESULT __cdecl Initialize1D( _In_ DXGI_FORMAT fmt, _In_ size_t length, _In_ size_t arraySize, _In_ size_t mipLevels, _In_ DWORD flags = CP_FLAGS_NONE );
|
||||||
|
HRESULT __cdecl Initialize2D( _In_ DXGI_FORMAT fmt, _In_ size_t width, _In_ size_t height, _In_ size_t arraySize, _In_ size_t mipLevels, _In_ DWORD flags = CP_FLAGS_NONE );
|
||||||
|
HRESULT __cdecl Initialize3D( _In_ DXGI_FORMAT fmt, _In_ size_t width, _In_ size_t height, _In_ size_t depth, _In_ size_t mipLevels, _In_ DWORD flags = CP_FLAGS_NONE );
|
||||||
|
HRESULT __cdecl InitializeCube( _In_ DXGI_FORMAT fmt, _In_ size_t width, _In_ size_t height, _In_ size_t nCubes, _In_ size_t mipLevels, _In_ DWORD flags = CP_FLAGS_NONE );
|
||||||
|
|
||||||
|
HRESULT __cdecl InitializeFromImage( _In_ const Image& srcImage, _In_ bool allow1D = false, _In_ DWORD flags = CP_FLAGS_NONE );
|
||||||
|
HRESULT __cdecl InitializeArrayFromImages( _In_reads_(nImages) const Image* images, _In_ size_t nImages, _In_ bool allow1D = false, _In_ DWORD flags = CP_FLAGS_NONE );
|
||||||
|
HRESULT __cdecl InitializeCubeFromImages( _In_reads_(nImages) const Image* images, _In_ size_t nImages, _In_ DWORD flags = CP_FLAGS_NONE );
|
||||||
|
HRESULT __cdecl Initialize3DFromImages( _In_reads_(depth) const Image* images, _In_ size_t depth, _In_ DWORD flags = CP_FLAGS_NONE );
|
||||||
|
|
||||||
|
void __cdecl Release();
|
||||||
|
|
||||||
|
bool __cdecl OverrideFormat( _In_ DXGI_FORMAT f );
|
||||||
|
|
||||||
|
const TexMetadata& __cdecl GetMetadata() const { return _metadata; }
|
||||||
|
const Image* __cdecl GetImage(_In_ size_t mip, _In_ size_t item, _In_ size_t slice) const;
|
||||||
|
|
||||||
|
const Image* __cdecl GetImages() const { return _image; }
|
||||||
|
size_t __cdecl GetImageCount() const { return _nimages; }
|
||||||
|
|
||||||
|
uint8_t* __cdecl GetPixels() const { return _memory; }
|
||||||
|
size_t __cdecl GetPixelsSize() const { return _size; }
|
||||||
|
|
||||||
|
bool __cdecl IsAlphaAllOpaque() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
size_t _nimages;
|
||||||
|
size_t _size;
|
||||||
|
TexMetadata _metadata;
|
||||||
|
Image* _image;
|
||||||
|
uint8_t* _memory;
|
||||||
|
|
||||||
|
// Hide copy constructor and assignment operator
|
||||||
|
ScratchImage( const ScratchImage& );
|
||||||
|
ScratchImage& operator=( const ScratchImage& );
|
||||||
|
};
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
|
// Memory blob (allocated buffer pointer is always 16-byte aligned)
|
||||||
|
class Blob
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Blob() : _buffer(nullptr), _size(0) {}
|
||||||
|
Blob(Blob&& moveFrom) : _buffer(nullptr), _size(0) { *this = std::move(moveFrom); }
|
||||||
|
~Blob() { Release(); }
|
||||||
|
|
||||||
|
Blob& __cdecl operator= (Blob&& moveFrom);
|
||||||
|
|
||||||
|
HRESULT __cdecl Initialize( _In_ size_t size );
|
||||||
|
|
||||||
|
void __cdecl Release();
|
||||||
|
|
||||||
|
void *__cdecl GetBufferPointer() const { return _buffer; }
|
||||||
|
size_t __cdecl GetBufferSize() const { return _size; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void* _buffer;
|
||||||
|
size_t _size;
|
||||||
|
|
||||||
|
// Hide copy constructor and assignment operator
|
||||||
|
Blob( const Blob& );
|
||||||
|
Blob& operator=( const Blob& );
|
||||||
|
};
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
|
// Image I/O
|
||||||
|
|
||||||
|
// DDS operations
|
||||||
|
HRESULT __cdecl LoadFromDDSMemory( _In_reads_bytes_(size) LPCVOID pSource, _In_ size_t size, _In_ DWORD flags,
|
||||||
|
_Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image );
|
||||||
|
HRESULT __cdecl LoadFromDDSFile( _In_z_ LPCWSTR szFile, _In_ DWORD flags,
|
||||||
|
_Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image );
|
||||||
|
|
||||||
|
HRESULT __cdecl SaveToDDSMemory( _In_ const Image& image, _In_ DWORD flags,
|
||||||
|
_Out_ Blob& blob );
|
||||||
|
HRESULT __cdecl SaveToDDSMemory( _In_reads_(nimages) const Image* images, _In_ size_t nimages, _In_ const TexMetadata& metadata, _In_ DWORD flags,
|
||||||
|
_Out_ Blob& blob );
|
||||||
|
|
||||||
|
HRESULT __cdecl SaveToDDSFile( _In_ const Image& image, _In_ DWORD flags, _In_z_ LPCWSTR szFile );
|
||||||
|
HRESULT __cdecl SaveToDDSFile( _In_reads_(nimages) const Image* images, _In_ size_t nimages, _In_ const TexMetadata& metadata, _In_ DWORD flags, _In_z_ LPCWSTR szFile );
|
||||||
|
|
||||||
|
// TGA operations
|
||||||
|
HRESULT __cdecl LoadFromTGAMemory( _In_reads_bytes_(size) LPCVOID pSource, _In_ size_t size,
|
||||||
|
_Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image );
|
||||||
|
HRESULT __cdecl LoadFromTGAFile( _In_z_ LPCWSTR szFile,
|
||||||
|
_Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image );
|
||||||
|
|
||||||
|
HRESULT __cdecl SaveToTGAMemory( _In_ const Image& image, _Out_ Blob& blob );
|
||||||
|
HRESULT __cdecl SaveToTGAFile( _In_ const Image& image, _In_z_ LPCWSTR szFile );
|
||||||
|
|
||||||
|
// WIC operations
|
||||||
|
HRESULT __cdecl LoadFromWICMemory( _In_reads_bytes_(size) LPCVOID pSource, _In_ size_t size, _In_ DWORD flags,
|
||||||
|
_Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image );
|
||||||
|
HRESULT __cdecl LoadFromWICFile( _In_z_ LPCWSTR szFile, _In_ DWORD flags,
|
||||||
|
_Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image );
|
||||||
|
|
||||||
|
HRESULT __cdecl SaveToWICMemory( _In_ const Image& image, _In_ DWORD flags, _In_ REFGUID guidContainerFormat,
|
||||||
|
_Out_ Blob& blob, _In_opt_ const GUID* targetFormat = nullptr,
|
||||||
|
_In_opt_ std::function<void DIRECTX_STD_CALLCONV(IPropertyBag2*)> setCustomProps = nullptr );
|
||||||
|
HRESULT __cdecl SaveToWICMemory( _In_count_(nimages) const Image* images, _In_ size_t nimages, _In_ DWORD flags, _In_ REFGUID guidContainerFormat,
|
||||||
|
_Out_ Blob& blob, _In_opt_ const GUID* targetFormat = nullptr,
|
||||||
|
_In_opt_ std::function<void DIRECTX_STD_CALLCONV(IPropertyBag2*)> setCustomProps = nullptr );
|
||||||
|
|
||||||
|
HRESULT __cdecl SaveToWICFile( _In_ const Image& image, _In_ DWORD flags, _In_ REFGUID guidContainerFormat,
|
||||||
|
_In_z_ LPCWSTR szFile, _In_opt_ const GUID* targetFormat = nullptr,
|
||||||
|
_In_opt_ std::function<void DIRECTX_STD_CALLCONV(IPropertyBag2*)> setCustomProps = nullptr );
|
||||||
|
HRESULT __cdecl SaveToWICFile( _In_count_(nimages) const Image* images, _In_ size_t nimages, _In_ DWORD flags, _In_ REFGUID guidContainerFormat,
|
||||||
|
_In_z_ LPCWSTR szFile, _In_opt_ const GUID* targetFormat = nullptr,
|
||||||
|
_In_opt_ std::function<void DIRECTX_STD_CALLCONV(IPropertyBag2*)> setCustomProps = nullptr );
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
|
// Texture conversion, resizing, mipmap generation, and block compression
|
||||||
|
|
||||||
|
enum TEX_FR_FLAGS
|
||||||
|
{
|
||||||
|
TEX_FR_ROTATE0 = 0x0,
|
||||||
|
TEX_FR_ROTATE90 = 0x1,
|
||||||
|
TEX_FR_ROTATE180 = 0x2,
|
||||||
|
TEX_FR_ROTATE270 = 0x3,
|
||||||
|
TEX_FR_FLIP_HORIZONTAL = 0x08,
|
||||||
|
TEX_FR_FLIP_VERTICAL = 0x10,
|
||||||
|
};
|
||||||
|
|
||||||
|
HRESULT __cdecl FlipRotate( _In_ const Image& srcImage, _In_ DWORD flags, _Out_ ScratchImage& image );
|
||||||
|
HRESULT __cdecl FlipRotate( _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata,
|
||||||
|
_In_ DWORD flags, _Out_ ScratchImage& result );
|
||||||
|
// Flip and/or rotate image
|
||||||
|
|
||||||
|
enum TEX_FILTER_FLAGS
|
||||||
|
{
|
||||||
|
TEX_FILTER_DEFAULT = 0,
|
||||||
|
|
||||||
|
TEX_FILTER_WRAP_U = 0x1,
|
||||||
|
TEX_FILTER_WRAP_V = 0x2,
|
||||||
|
TEX_FILTER_WRAP_W = 0x4,
|
||||||
|
TEX_FILTER_WRAP = ( TEX_FILTER_WRAP_U | TEX_FILTER_WRAP_V | TEX_FILTER_WRAP_W ),
|
||||||
|
TEX_FILTER_MIRROR_U = 0x10,
|
||||||
|
TEX_FILTER_MIRROR_V = 0x20,
|
||||||
|
TEX_FILTER_MIRROR_W = 0x40,
|
||||||
|
TEX_FILTER_MIRROR = ( TEX_FILTER_MIRROR_U | TEX_FILTER_MIRROR_V | TEX_FILTER_MIRROR_W ),
|
||||||
|
// Wrap vs. Mirror vs. Clamp filtering options
|
||||||
|
|
||||||
|
TEX_FILTER_SEPARATE_ALPHA = 0x100,
|
||||||
|
// Resize color and alpha channel independently
|
||||||
|
|
||||||
|
TEX_FILTER_RGB_COPY_RED = 0x1000,
|
||||||
|
TEX_FILTER_RGB_COPY_GREEN = 0x2000,
|
||||||
|
TEX_FILTER_RGB_COPY_BLUE = 0x4000,
|
||||||
|
// When converting RGB to R, defaults to using grayscale. These flags indicate copying a specific channel instead
|
||||||
|
// When converting RGB to RG, defaults to copying RED | GREEN. These flags control which channels are selected instead.
|
||||||
|
|
||||||
|
TEX_FILTER_DITHER = 0x10000,
|
||||||
|
// Use ordered 4x4 dithering for any required conversions
|
||||||
|
TEX_FILTER_DITHER_DIFFUSION = 0x20000,
|
||||||
|
// Use error-diffusion dithering for any required conversions
|
||||||
|
|
||||||
|
TEX_FILTER_POINT = 0x100000,
|
||||||
|
TEX_FILTER_LINEAR = 0x200000,
|
||||||
|
TEX_FILTER_CUBIC = 0x300000,
|
||||||
|
TEX_FILTER_BOX = 0x400000,
|
||||||
|
TEX_FILTER_FANT = 0x400000, // Equiv to Box filtering for mipmap generation
|
||||||
|
TEX_FILTER_TRIANGLE = 0x500000,
|
||||||
|
// Filtering mode to use for any required image resizing
|
||||||
|
|
||||||
|
TEX_FILTER_SRGB_IN = 0x1000000,
|
||||||
|
TEX_FILTER_SRGB_OUT = 0x2000000,
|
||||||
|
TEX_FILTER_SRGB = ( TEX_FILTER_SRGB_IN | TEX_FILTER_SRGB_OUT ),
|
||||||
|
// sRGB <-> RGB for use in conversion operations
|
||||||
|
// if the input format type is IsSRGB(), then SRGB_IN is on by default
|
||||||
|
// if the output format type is IsSRGB(), then SRGB_OUT is on by default
|
||||||
|
|
||||||
|
TEX_FILTER_FORCE_NON_WIC = 0x10000000,
|
||||||
|
// Forces use of the non-WIC path when both are an option
|
||||||
|
|
||||||
|
TEX_FILTER_FORCE_WIC = 0x20000000,
|
||||||
|
// Forces use of the WIC path even when logic would have picked a non-WIC path when both are an option
|
||||||
|
};
|
||||||
|
|
||||||
|
HRESULT __cdecl Resize( _In_ const Image& srcImage, _In_ size_t width, _In_ size_t height, _In_ DWORD filter,
|
||||||
|
_Out_ ScratchImage& image );
|
||||||
|
HRESULT __cdecl Resize( _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata,
|
||||||
|
_In_ size_t width, _In_ size_t height, _In_ DWORD filter, _Out_ ScratchImage& result );
|
||||||
|
// Resize the image to width x height. Defaults to Fant filtering.
|
||||||
|
// Note for a complex resize, the result will always have mipLevels == 1
|
||||||
|
|
||||||
|
HRESULT __cdecl Convert( _In_ const Image& srcImage, _In_ DXGI_FORMAT format, _In_ DWORD filter, _In_ float threshold,
|
||||||
|
_Out_ ScratchImage& image );
|
||||||
|
HRESULT __cdecl Convert( _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata,
|
||||||
|
_In_ DXGI_FORMAT format, _In_ DWORD filter, _In_ float threshold, _Out_ ScratchImage& result );
|
||||||
|
// Convert the image to a new format
|
||||||
|
|
||||||
|
HRESULT __cdecl ConvertToSinglePlane( _In_ const Image& srcImage, _Out_ ScratchImage& image );
|
||||||
|
HRESULT __cdecl ConvertToSinglePlane( _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata,
|
||||||
|
_Out_ ScratchImage& image );
|
||||||
|
// Converts the image from a planar format to an equivalent non-planar format
|
||||||
|
|
||||||
|
HRESULT __cdecl GenerateMipMaps( _In_ const Image& baseImage, _In_ DWORD filter, _In_ size_t levels,
|
||||||
|
_Inout_ ScratchImage& mipChain, _In_ bool allow1D = false );
|
||||||
|
HRESULT __cdecl GenerateMipMaps( _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata,
|
||||||
|
_In_ DWORD filter, _In_ size_t levels, _Inout_ ScratchImage& mipChain );
|
||||||
|
// levels of '0' indicates a full mipchain, otherwise is generates that number of total levels (including the source base image)
|
||||||
|
// Defaults to Fant filtering which is equivalent to a box filter
|
||||||
|
|
||||||
|
HRESULT __cdecl GenerateMipMaps3D( _In_reads_(depth) const Image* baseImages, _In_ size_t depth, _In_ DWORD filter, _In_ size_t levels,
|
||||||
|
_Out_ ScratchImage& mipChain );
|
||||||
|
HRESULT __cdecl GenerateMipMaps3D( _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata,
|
||||||
|
_In_ DWORD filter, _In_ size_t levels, _Out_ ScratchImage& mipChain );
|
||||||
|
// levels of '0' indicates a full mipchain, otherwise is generates that number of total levels (including the source base image)
|
||||||
|
// Defaults to Fant filtering which is equivalent to a box filter
|
||||||
|
|
||||||
|
enum TEX_PMALPHA_FLAGS
|
||||||
|
{
|
||||||
|
TEX_PMALPHA_DEFAULT = 0,
|
||||||
|
|
||||||
|
TEX_PMALPHA_IGNORE_SRGB = 0x1,
|
||||||
|
// ignores sRGB colorspace conversions
|
||||||
|
|
||||||
|
TEX_PMALPHA_SRGB_IN = 0x1000000,
|
||||||
|
TEX_PMALPHA_SRGB_OUT = 0x2000000,
|
||||||
|
TEX_PMALPHA_SRGB = ( TEX_PMALPHA_SRGB_IN | TEX_PMALPHA_SRGB_OUT ),
|
||||||
|
// if the input format type is IsSRGB(), then SRGB_IN is on by default
|
||||||
|
// if the output format type is IsSRGB(), then SRGB_OUT is on by default
|
||||||
|
};
|
||||||
|
|
||||||
|
HRESULT __cdecl PremultiplyAlpha( _In_ const Image& srcImage, _In_ DWORD flags, _Out_ ScratchImage& image );
|
||||||
|
HRESULT __cdecl PremultiplyAlpha( _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata, _In_ DWORD flags, _Out_ ScratchImage& result );
|
||||||
|
// Converts to a premultiplied alpha version of the texture
|
||||||
|
|
||||||
|
enum TEX_COMPRESS_FLAGS
|
||||||
|
{
|
||||||
|
TEX_COMPRESS_DEFAULT = 0,
|
||||||
|
|
||||||
|
TEX_COMPRESS_RGB_DITHER = 0x10000,
|
||||||
|
// Enables dithering RGB colors for BC1-3 compression
|
||||||
|
|
||||||
|
TEX_COMPRESS_A_DITHER = 0x20000,
|
||||||
|
// Enables dithering alpha for BC1-3 compression
|
||||||
|
|
||||||
|
TEX_COMPRESS_DITHER = 0x30000,
|
||||||
|
// Enables both RGB and alpha dithering for BC1-3 compression
|
||||||
|
|
||||||
|
TEX_COMPRESS_UNIFORM = 0x40000,
|
||||||
|
// Uniform color weighting for BC1-3 compression; by default uses perceptual weighting
|
||||||
|
|
||||||
|
TEX_COMPRESS_BC7_USE_3SUBSETS = 0x80000,
|
||||||
|
// Enables exhaustive search for BC7 compress for mode 0 and 2; by default skips trying these modes
|
||||||
|
|
||||||
|
TEX_COMPRESS_SRGB_IN = 0x1000000,
|
||||||
|
TEX_COMPRESS_SRGB_OUT = 0x2000000,
|
||||||
|
TEX_COMPRESS_SRGB = ( TEX_COMPRESS_SRGB_IN | TEX_COMPRESS_SRGB_OUT ),
|
||||||
|
// if the input format type is IsSRGB(), then SRGB_IN is on by default
|
||||||
|
// if the output format type is IsSRGB(), then SRGB_OUT is on by default
|
||||||
|
|
||||||
|
TEX_COMPRESS_PARALLEL = 0x10000000,
|
||||||
|
// Compress is free to use multithreading to improve performance (by default it does not use multithreading)
|
||||||
|
};
|
||||||
|
|
||||||
|
HRESULT __cdecl Compress( _In_ const Image& srcImage, _In_ DXGI_FORMAT format, _In_ DWORD compress, _In_ float alphaRef,
|
||||||
|
_Out_ ScratchImage& cImage );
|
||||||
|
HRESULT __cdecl Compress( _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata,
|
||||||
|
_In_ DXGI_FORMAT format, _In_ DWORD compress, _In_ float alphaRef, _Out_ ScratchImage& cImages );
|
||||||
|
// Note that alphaRef is only used by BC1. 0.5f is a typical value to use
|
||||||
|
|
||||||
|
HRESULT __cdecl Compress( _In_ ID3D11Device* pDevice, _In_ const Image& srcImage, _In_ DXGI_FORMAT format, _In_ DWORD compress,
|
||||||
|
_In_ float alphaWeight, _Out_ ScratchImage& image );
|
||||||
|
HRESULT __cdecl Compress( _In_ ID3D11Device* pDevice, _In_ const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata,
|
||||||
|
_In_ DXGI_FORMAT format, _In_ DWORD compress, _In_ float alphaWeight, _Out_ ScratchImage& cImages );
|
||||||
|
// DirectCompute-based compression (alphaWeight is only used by BC7. 1.0 is the typical value to use)
|
||||||
|
|
||||||
|
HRESULT __cdecl Decompress( _In_ const Image& cImage, _In_ DXGI_FORMAT format, _Out_ ScratchImage& image );
|
||||||
|
HRESULT __cdecl Decompress( _In_reads_(nimages) const Image* cImages, _In_ size_t nimages, _In_ const TexMetadata& metadata,
|
||||||
|
_In_ DXGI_FORMAT format, _Out_ ScratchImage& images );
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
|
// Normal map operations
|
||||||
|
|
||||||
|
enum CNMAP_FLAGS
|
||||||
|
{
|
||||||
|
CNMAP_DEFAULT = 0,
|
||||||
|
|
||||||
|
CNMAP_CHANNEL_RED = 0x1,
|
||||||
|
CNMAP_CHANNEL_GREEN = 0x2,
|
||||||
|
CNMAP_CHANNEL_BLUE = 0x3,
|
||||||
|
CNMAP_CHANNEL_ALPHA = 0x4,
|
||||||
|
CNMAP_CHANNEL_LUMINANCE = 0x5,
|
||||||
|
// Channel selection when evaluting color value for height
|
||||||
|
// Luminance is a combination of red, green, and blue
|
||||||
|
|
||||||
|
CNMAP_MIRROR_U = 0x1000,
|
||||||
|
CNMAP_MIRROR_V = 0x2000,
|
||||||
|
CNMAP_MIRROR = 0x3000,
|
||||||
|
// Use mirror semantics for scanline references (defaults to wrap)
|
||||||
|
|
||||||
|
CNMAP_INVERT_SIGN = 0x4000,
|
||||||
|
// Inverts normal sign
|
||||||
|
|
||||||
|
CNMAP_COMPUTE_OCCLUSION = 0x8000,
|
||||||
|
// Computes a crude occlusion term stored in the alpha channel
|
||||||
|
};
|
||||||
|
|
||||||
|
HRESULT __cdecl ComputeNormalMap( _In_ const Image& srcImage, _In_ DWORD flags, _In_ float amplitude,
|
||||||
|
_In_ DXGI_FORMAT format, _Out_ ScratchImage& normalMap );
|
||||||
|
HRESULT __cdecl ComputeNormalMap( _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata,
|
||||||
|
_In_ DWORD flags, _In_ float amplitude, _In_ DXGI_FORMAT format, _Out_ ScratchImage& normalMaps );
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
|
// Misc image operations
|
||||||
|
|
||||||
|
struct Rect
|
||||||
|
{
|
||||||
|
size_t x;
|
||||||
|
size_t y;
|
||||||
|
size_t w;
|
||||||
|
size_t h;
|
||||||
|
|
||||||
|
Rect() DIRECTX_CTOR_DEFAULT
|
||||||
|
Rect( size_t _x, size_t _y, size_t _w, size_t _h ) : x(_x), y(_y), w(_w), h(_h) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
HRESULT __cdecl CopyRectangle( _In_ const Image& srcImage, _In_ const Rect& srcRect, _In_ const Image& dstImage,
|
||||||
|
_In_ DWORD filter, _In_ size_t xOffset, _In_ size_t yOffset );
|
||||||
|
|
||||||
|
enum CMSE_FLAGS
|
||||||
|
{
|
||||||
|
CMSE_DEFAULT = 0,
|
||||||
|
|
||||||
|
CMSE_IMAGE1_SRGB = 0x1,
|
||||||
|
CMSE_IMAGE2_SRGB = 0x2,
|
||||||
|
// Indicates that image needs gamma correction before comparision
|
||||||
|
|
||||||
|
CMSE_IGNORE_RED = 0x10,
|
||||||
|
CMSE_IGNORE_GREEN = 0x20,
|
||||||
|
CMSE_IGNORE_BLUE = 0x40,
|
||||||
|
CMSE_IGNORE_ALPHA = 0x80,
|
||||||
|
// Ignore the channel when computing MSE
|
||||||
|
|
||||||
|
CMSE_IMAGE1_X2_BIAS = 0x100,
|
||||||
|
CMSE_IMAGE2_X2_BIAS = 0x200,
|
||||||
|
// Indicates that image should be scaled and biased before comparison (i.e. UNORM -> SNORM)
|
||||||
|
};
|
||||||
|
|
||||||
|
HRESULT __cdecl ComputeMSE( _In_ const Image& image1, _In_ const Image& image2, _Out_ float& mse, _Out_writes_opt_(4) float* mseV, _In_ DWORD flags = 0 );
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
|
// WIC utility code
|
||||||
|
|
||||||
|
enum WICCodecs
|
||||||
|
{
|
||||||
|
WIC_CODEC_BMP = 1, // Windows Bitmap (.bmp)
|
||||||
|
WIC_CODEC_JPEG, // Joint Photographic Experts Group (.jpg, .jpeg)
|
||||||
|
WIC_CODEC_PNG, // Portable Network Graphics (.png)
|
||||||
|
WIC_CODEC_TIFF, // Tagged Image File Format (.tif, .tiff)
|
||||||
|
WIC_CODEC_GIF, // Graphics Interchange Format (.gif)
|
||||||
|
WIC_CODEC_WMP, // Windows Media Photo / HD Photo / JPEG XR (.hdp, .jxr, .wdp)
|
||||||
|
WIC_CODEC_ICO, // Windows Icon (.ico)
|
||||||
|
};
|
||||||
|
|
||||||
|
REFGUID __cdecl GetWICCodec(_In_ WICCodecs codec);
|
||||||
|
|
||||||
|
IWICImagingFactory* __cdecl GetWICFactory( bool& iswic2 );
|
||||||
|
void __cdecl SetWICFactory( _In_opt_ IWICImagingFactory* pWIC);
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
|
// Direct3D 11 functions
|
||||||
|
bool __cdecl IsSupportedTexture( _In_ ID3D11Device* pDevice, _In_ const TexMetadata& metadata );
|
||||||
|
|
||||||
|
HRESULT __cdecl CreateTexture( _In_ ID3D11Device* pDevice, _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata,
|
||||||
|
_Outptr_ ID3D11Resource** ppResource );
|
||||||
|
|
||||||
|
HRESULT __cdecl CreateShaderResourceView( _In_ ID3D11Device* pDevice, _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata,
|
||||||
|
_Outptr_ ID3D11ShaderResourceView** ppSRV );
|
||||||
|
|
||||||
|
HRESULT __cdecl CreateTextureEx( _In_ ID3D11Device* pDevice, _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata,
|
||||||
|
_In_ D3D11_USAGE usage, _In_ unsigned int bindFlags, _In_ unsigned int cpuAccessFlags, _In_ unsigned int miscFlags, _In_ bool forceSRGB,
|
||||||
|
_Outptr_ ID3D11Resource** ppResource );
|
||||||
|
|
||||||
|
HRESULT __cdecl CreateShaderResourceViewEx( _In_ ID3D11Device* pDevice, _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata,
|
||||||
|
_In_ D3D11_USAGE usage, _In_ unsigned int bindFlags, _In_ unsigned int cpuAccessFlags, _In_ unsigned int miscFlags, _In_ bool forceSRGB,
|
||||||
|
_Outptr_ ID3D11ShaderResourceView** ppSRV );
|
||||||
|
|
||||||
|
HRESULT __cdecl CaptureTexture( _In_ ID3D11Device* pDevice, _In_ ID3D11DeviceContext* pContext, _In_ ID3D11Resource* pSource, _Out_ ScratchImage& result );
|
||||||
|
|
||||||
|
#include "DirectXTex.inl"
|
||||||
|
|
||||||
|
}; // namespace
|
130
Switch_Toolbox/Lib/DirectXTex/DirectXTex.inl
Normal file
130
Switch_Toolbox/Lib/DirectXTex/DirectXTex.inl
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
// DirectXTex.inl
|
||||||
|
//
|
||||||
|
// DirectX Texture Library
|
||||||
|
//
|
||||||
|
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||||
|
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
||||||
|
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||||
|
// PARTICULAR PURPOSE.
|
||||||
|
//
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
//
|
||||||
|
// http://go.microsoft.com/fwlink/?LinkId=248926
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
//=====================================================================================
|
||||||
|
// DXGI Format Utilities
|
||||||
|
//=====================================================================================
|
||||||
|
|
||||||
|
_Use_decl_annotations_
|
||||||
|
inline bool __cdecl IsValid( DXGI_FORMAT fmt )
|
||||||
|
{
|
||||||
|
return ( static_cast<size_t>(fmt) >= 1 && static_cast<size_t>(fmt) <= 190 );
|
||||||
|
}
|
||||||
|
|
||||||
|
_Use_decl_annotations_
|
||||||
|
inline bool __cdecl IsCompressed(DXGI_FORMAT fmt)
|
||||||
|
{
|
||||||
|
switch ( fmt )
|
||||||
|
{
|
||||||
|
case DXGI_FORMAT_BC1_TYPELESS:
|
||||||
|
case DXGI_FORMAT_BC1_UNORM:
|
||||||
|
case DXGI_FORMAT_BC1_UNORM_SRGB:
|
||||||
|
case DXGI_FORMAT_BC2_TYPELESS:
|
||||||
|
case DXGI_FORMAT_BC2_UNORM:
|
||||||
|
case DXGI_FORMAT_BC2_UNORM_SRGB:
|
||||||
|
case DXGI_FORMAT_BC3_TYPELESS:
|
||||||
|
case DXGI_FORMAT_BC3_UNORM:
|
||||||
|
case DXGI_FORMAT_BC3_UNORM_SRGB:
|
||||||
|
case DXGI_FORMAT_BC4_TYPELESS:
|
||||||
|
case DXGI_FORMAT_BC4_UNORM:
|
||||||
|
case DXGI_FORMAT_BC4_SNORM:
|
||||||
|
case DXGI_FORMAT_BC5_TYPELESS:
|
||||||
|
case DXGI_FORMAT_BC5_UNORM:
|
||||||
|
case DXGI_FORMAT_BC5_SNORM:
|
||||||
|
case DXGI_FORMAT_BC6H_TYPELESS:
|
||||||
|
case DXGI_FORMAT_BC6H_UF16:
|
||||||
|
case DXGI_FORMAT_BC6H_SF16:
|
||||||
|
case DXGI_FORMAT_BC7_TYPELESS:
|
||||||
|
case DXGI_FORMAT_BC7_UNORM:
|
||||||
|
case DXGI_FORMAT_BC7_UNORM_SRGB:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_Use_decl_annotations_
|
||||||
|
inline bool __cdecl IsPalettized(DXGI_FORMAT fmt)
|
||||||
|
{
|
||||||
|
switch( fmt )
|
||||||
|
{
|
||||||
|
case DXGI_FORMAT_AI44:
|
||||||
|
case DXGI_FORMAT_IA44:
|
||||||
|
case DXGI_FORMAT_P8:
|
||||||
|
case DXGI_FORMAT_A8P8:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_Use_decl_annotations_
|
||||||
|
inline bool __cdecl IsSRGB(DXGI_FORMAT fmt)
|
||||||
|
{
|
||||||
|
switch( fmt )
|
||||||
|
{
|
||||||
|
case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
|
||||||
|
case DXGI_FORMAT_BC1_UNORM_SRGB:
|
||||||
|
case DXGI_FORMAT_BC2_UNORM_SRGB:
|
||||||
|
case DXGI_FORMAT_BC3_UNORM_SRGB:
|
||||||
|
case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
|
||||||
|
case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
|
||||||
|
case DXGI_FORMAT_BC7_UNORM_SRGB:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//=====================================================================================
|
||||||
|
// Image I/O
|
||||||
|
//=====================================================================================
|
||||||
|
_Use_decl_annotations_
|
||||||
|
inline HRESULT __cdecl SaveToDDSMemory(const Image& image, DWORD flags, Blob& blob)
|
||||||
|
{
|
||||||
|
TexMetadata mdata;
|
||||||
|
memset( &mdata, 0, sizeof(mdata) );
|
||||||
|
mdata.width = image.width;
|
||||||
|
mdata.height = image.height;
|
||||||
|
mdata.depth = 1;
|
||||||
|
mdata.arraySize = 1;
|
||||||
|
mdata.mipLevels = 1;
|
||||||
|
mdata.format = image.format;
|
||||||
|
mdata.dimension = TEX_DIMENSION_TEXTURE2D;
|
||||||
|
|
||||||
|
return SaveToDDSMemory( &image, 1, mdata, flags, blob );
|
||||||
|
}
|
||||||
|
|
||||||
|
_Use_decl_annotations_
|
||||||
|
inline HRESULT __cdecl SaveToDDSFile(const Image& image, DWORD flags, LPCWSTR szFile)
|
||||||
|
{
|
||||||
|
TexMetadata mdata;
|
||||||
|
memset( &mdata, 0, sizeof(mdata) );
|
||||||
|
mdata.width = image.width;
|
||||||
|
mdata.height = image.height;
|
||||||
|
mdata.depth = 1;
|
||||||
|
mdata.arraySize = 1;
|
||||||
|
mdata.mipLevels = 1;
|
||||||
|
mdata.format = image.format;
|
||||||
|
mdata.dimension = TEX_DIMENSION_TEXTURE2D;
|
||||||
|
|
||||||
|
return SaveToDDSFile( &image, 1, mdata, flags, szFile );
|
||||||
|
}
|
240
Switch_Toolbox/Lib/DirectXTex/DirectXTex.vcxproj
Normal file
240
Switch_Toolbox/Lib/DirectXTex/DirectXTex.vcxproj
Normal file
|
@ -0,0 +1,240 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|ARM">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>ARM</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|ARM">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>ARM</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>{755AB64B-16B4-4C90-AA3B-BFF448E5A21E}</ProjectGuid>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<RootNamespace>DirectXTex</RootNamespace>
|
||||||
|
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||||
|
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<CLRSupport>true</CLRSupport>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<CLRSupport>true</CLRSupport>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<CLRSupport>true</CLRSupport>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<CLRSupport>true</CLRSupport>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
|
||||||
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
|
||||||
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="Shared">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
<OutDir>$(ProjectDir)$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(ProjectDir)$(Configuration)\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
<OutDir>$(ProjectDir)$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(ProjectDir)$(Configuration)\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;DIRECTXTEX_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;DIRECTXTEX_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;DIRECTXTEX_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<OpenMPSupport>true</OpenMPSupport>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>No</GenerateDebugInformation>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;DIRECTXTEX_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<OpenMPSupport>true</OpenMPSupport>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>No</GenerateDebugInformation>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="BC.cpp">
|
||||||
|
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsManaged>
|
||||||
|
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged>
|
||||||
|
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsManaged>
|
||||||
|
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="BC4BC5.cpp">
|
||||||
|
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsManaged>
|
||||||
|
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged>
|
||||||
|
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsManaged>
|
||||||
|
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="BC6HBC7.cpp">
|
||||||
|
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsManaged>
|
||||||
|
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged>
|
||||||
|
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsManaged>
|
||||||
|
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="DirectXTexCompress.cpp">
|
||||||
|
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsManaged>
|
||||||
|
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged>
|
||||||
|
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsManaged>
|
||||||
|
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="DirectXTexConvert.cpp">
|
||||||
|
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsManaged>
|
||||||
|
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged>
|
||||||
|
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsManaged>
|
||||||
|
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="DirectXTexDDS.cpp">
|
||||||
|
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsManaged>
|
||||||
|
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged>
|
||||||
|
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsManaged>
|
||||||
|
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="DirectXTexImage.cpp">
|
||||||
|
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsManaged>
|
||||||
|
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged>
|
||||||
|
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsManaged>
|
||||||
|
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="DirectXTexMipmaps.cpp">
|
||||||
|
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsManaged>
|
||||||
|
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged>
|
||||||
|
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsManaged>
|
||||||
|
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="DirectXTexUtil.cpp">
|
||||||
|
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsManaged>
|
||||||
|
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged>
|
||||||
|
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsManaged>
|
||||||
|
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="wrapper.cpp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="BC.h" />
|
||||||
|
<ClInclude Include="DDS.h" />
|
||||||
|
<ClInclude Include="DirectXTex.h" />
|
||||||
|
<ClInclude Include="DirectXTexP.h" />
|
||||||
|
<ClInclude Include="Filters.h" />
|
||||||
|
<ClInclude Include="scoped.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="DirectXTex.inl" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
74
Switch_Toolbox/Lib/DirectXTex/DirectXTex.vcxproj.filters
Normal file
74
Switch_Toolbox/Lib/DirectXTex/DirectXTex.vcxproj.filters
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="Quelldateien">
|
||||||
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Headerdateien">
|
||||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
|
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Ressourcendateien">
|
||||||
|
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||||
|
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="wrapper.cpp">
|
||||||
|
<Filter>Quelldateien</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="BC.cpp">
|
||||||
|
<Filter>Quelldateien</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="BC4BC5.cpp">
|
||||||
|
<Filter>Quelldateien</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="BC6HBC7.cpp">
|
||||||
|
<Filter>Quelldateien</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="DirectXTexCompress.cpp">
|
||||||
|
<Filter>Quelldateien</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="DirectXTexConvert.cpp">
|
||||||
|
<Filter>Quelldateien</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="DirectXTexDDS.cpp">
|
||||||
|
<Filter>Quelldateien</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="DirectXTexImage.cpp">
|
||||||
|
<Filter>Quelldateien</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="DirectXTexUtil.cpp">
|
||||||
|
<Filter>Quelldateien</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="DirectXTexMipmaps.cpp">
|
||||||
|
<Filter>Quelldateien</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="BC.h">
|
||||||
|
<Filter>Headerdateien</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="DDS.h">
|
||||||
|
<Filter>Headerdateien</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="DirectXTex.h">
|
||||||
|
<Filter>Headerdateien</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="DirectXTexP.h">
|
||||||
|
<Filter>Headerdateien</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Filters.h">
|
||||||
|
<Filter>Headerdateien</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="scoped.h">
|
||||||
|
<Filter>Headerdateien</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="DirectXTex.inl">
|
||||||
|
<Filter>Headerdateien</Filter>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
4
Switch_Toolbox/Lib/DirectXTex/DirectXTex.vcxproj.user
Normal file
4
Switch_Toolbox/Lib/DirectXTex/DirectXTex.vcxproj.user
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup />
|
||||||
|
</Project>
|
810
Switch_Toolbox/Lib/DirectXTex/DirectXTexCompress.cpp
Normal file
810
Switch_Toolbox/Lib/DirectXTex/DirectXTexCompress.cpp
Normal file
|
@ -0,0 +1,810 @@
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
// DirectXTexCompress.cpp
|
||||||
|
//
|
||||||
|
// DirectX Texture Library - Texture compression
|
||||||
|
//
|
||||||
|
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||||
|
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
||||||
|
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||||
|
// PARTICULAR PURPOSE.
|
||||||
|
//
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
//
|
||||||
|
// http://go.microsoft.com/fwlink/?LinkId=248926
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "directxtexp.h"
|
||||||
|
|
||||||
|
#ifdef _OPENMP
|
||||||
|
#include <omp.h>
|
||||||
|
#pragma warning(disable : 4616 6993)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "bc.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace DirectX
|
||||||
|
{
|
||||||
|
|
||||||
|
inline static DWORD _GetBCFlags( _In_ DWORD compress )
|
||||||
|
{
|
||||||
|
static_assert( TEX_COMPRESS_RGB_DITHER == BC_FLAGS_DITHER_RGB, "TEX_COMPRESS_* flags should match BC_FLAGS_*" );
|
||||||
|
static_assert( TEX_COMPRESS_A_DITHER == BC_FLAGS_DITHER_A, "TEX_COMPRESS_* flags should match BC_FLAGS_*" );
|
||||||
|
static_assert( TEX_COMPRESS_DITHER == (BC_FLAGS_DITHER_RGB | BC_FLAGS_DITHER_A), "TEX_COMPRESS_* flags should match BC_FLAGS_*" );
|
||||||
|
static_assert( TEX_COMPRESS_UNIFORM == BC_FLAGS_UNIFORM, "TEX_COMPRESS_* flags should match BC_FLAGS_*" );
|
||||||
|
static_assert( TEX_COMPRESS_BC7_USE_3SUBSETS == BC_FLAGS_USE_3SUBSETS, "TEX_COMPRESS_* flags should match BC_FLAGS_*" );
|
||||||
|
return ( compress & (BC_FLAGS_DITHER_RGB|BC_FLAGS_DITHER_A|BC_FLAGS_UNIFORM|BC_FLAGS_USE_3SUBSETS) );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static DWORD _GetSRGBFlags( _In_ DWORD compress )
|
||||||
|
{
|
||||||
|
static_assert( TEX_COMPRESS_SRGB_IN == TEX_FILTER_SRGB_IN, "TEX_COMPRESS_SRGB* should match TEX_FILTER_SRGB*" );
|
||||||
|
static_assert( TEX_COMPRESS_SRGB_OUT == TEX_FILTER_SRGB_OUT, "TEX_COMPRESS_SRGB* should match TEX_FILTER_SRGB*" );
|
||||||
|
static_assert( TEX_COMPRESS_SRGB == TEX_FILTER_SRGB, "TEX_COMPRESS_SRGB* should match TEX_FILTER_SRGB*" );
|
||||||
|
return ( compress & TEX_COMPRESS_SRGB );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static bool _DetermineEncoderSettings( _In_ DXGI_FORMAT format, _Out_ BC_ENCODE& pfEncode, _Out_ size_t& blocksize, _Out_ DWORD& cflags )
|
||||||
|
{
|
||||||
|
switch(format)
|
||||||
|
{
|
||||||
|
case DXGI_FORMAT_BC1_UNORM:
|
||||||
|
case DXGI_FORMAT_BC1_UNORM_SRGB: pfEncode = nullptr; blocksize = 8; cflags = 0; break;
|
||||||
|
case DXGI_FORMAT_BC2_UNORM:
|
||||||
|
case DXGI_FORMAT_BC2_UNORM_SRGB: pfEncode = D3DXEncodeBC2; blocksize = 16; cflags = 0; break;
|
||||||
|
case DXGI_FORMAT_BC3_UNORM:
|
||||||
|
case DXGI_FORMAT_BC3_UNORM_SRGB: pfEncode = D3DXEncodeBC3; blocksize = 16; cflags = 0; break;
|
||||||
|
case DXGI_FORMAT_BC4_UNORM: pfEncode = D3DXEncodeBC4U; blocksize = 8; cflags = TEX_FILTER_RGB_COPY_RED; break;
|
||||||
|
case DXGI_FORMAT_BC4_SNORM: pfEncode = D3DXEncodeBC4S; blocksize = 8; cflags = TEX_FILTER_RGB_COPY_RED; break;
|
||||||
|
case DXGI_FORMAT_BC5_UNORM: pfEncode = D3DXEncodeBC5U; blocksize = 16; cflags = TEX_FILTER_RGB_COPY_RED | TEX_FILTER_RGB_COPY_GREEN; break;
|
||||||
|
case DXGI_FORMAT_BC5_SNORM: pfEncode = D3DXEncodeBC5S; blocksize = 16; cflags = TEX_FILTER_RGB_COPY_RED | TEX_FILTER_RGB_COPY_GREEN; break;
|
||||||
|
case DXGI_FORMAT_BC6H_UF16: pfEncode = D3DXEncodeBC6HU; blocksize = 16; cflags = 0; break;
|
||||||
|
case DXGI_FORMAT_BC6H_SF16: pfEncode = D3DXEncodeBC6HS; blocksize = 16; cflags = 0; break;
|
||||||
|
case DXGI_FORMAT_BC7_UNORM:
|
||||||
|
case DXGI_FORMAT_BC7_UNORM_SRGB: pfEncode = D3DXEncodeBC7; blocksize = 16; cflags = 0; break;
|
||||||
|
default: pfEncode = nullptr; blocksize = 0; cflags = 0; return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
static HRESULT _CompressBC( _In_ const Image& image, _In_ const Image& result, _In_ DWORD bcflags,
|
||||||
|
_In_ DWORD srgb, _In_ float alphaRef )
|
||||||
|
{
|
||||||
|
if ( !image.pixels || !result.pixels )
|
||||||
|
return E_POINTER;
|
||||||
|
|
||||||
|
assert( image.width == result.width );
|
||||||
|
assert( image.height == result.height );
|
||||||
|
|
||||||
|
const DXGI_FORMAT format = image.format;
|
||||||
|
size_t sbpp = BitsPerPixel( format );
|
||||||
|
if ( !sbpp )
|
||||||
|
return E_FAIL;
|
||||||
|
|
||||||
|
if ( sbpp < 8 )
|
||||||
|
{
|
||||||
|
// We don't support compressing from monochrome (DXGI_FORMAT_R1_UNORM)
|
||||||
|
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Round to bytes
|
||||||
|
sbpp = ( sbpp + 7 ) / 8;
|
||||||
|
|
||||||
|
uint8_t *pDest = result.pixels;
|
||||||
|
|
||||||
|
// Determine BC format encoder
|
||||||
|
BC_ENCODE pfEncode;
|
||||||
|
size_t blocksize;
|
||||||
|
DWORD cflags;
|
||||||
|
if ( !_DetermineEncoderSettings( result.format, pfEncode, blocksize, cflags ) )
|
||||||
|
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
|
||||||
|
|
||||||
|
XMVECTOR temp[16];
|
||||||
|
const uint8_t *pSrc = image.pixels;
|
||||||
|
const size_t rowPitch = image.rowPitch;
|
||||||
|
for( size_t h=0; h < image.height; h += 4 )
|
||||||
|
{
|
||||||
|
const uint8_t *sptr = pSrc;
|
||||||
|
uint8_t* dptr = pDest;
|
||||||
|
size_t ph = std::min<size_t>( 4, image.height - h );
|
||||||
|
size_t w = 0;
|
||||||
|
for( size_t count = 0; (count < result.rowPitch) && (w < image.width); count += blocksize, w += 4 )
|
||||||
|
{
|
||||||
|
size_t pw = std::min<size_t>( 4, image.width - w );
|
||||||
|
assert( pw > 0 && ph > 0 );
|
||||||
|
|
||||||
|
if ( !_LoadScanline( &temp[0], pw, sptr, rowPitch, format ) )
|
||||||
|
return E_FAIL;
|
||||||
|
|
||||||
|
if ( ph > 1 )
|
||||||
|
{
|
||||||
|
if ( !_LoadScanline( &temp[4], pw, sptr + rowPitch, rowPitch, format ) )
|
||||||
|
return E_FAIL;
|
||||||
|
|
||||||
|
if ( ph > 2 )
|
||||||
|
{
|
||||||
|
if ( !_LoadScanline( &temp[8], pw, sptr + rowPitch*2, rowPitch, format ) )
|
||||||
|
return E_FAIL;
|
||||||
|
|
||||||
|
if ( ph > 3 )
|
||||||
|
{
|
||||||
|
if ( !_LoadScanline( &temp[12], pw, sptr + rowPitch*3, rowPitch, format ) )
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( pw != 4 || ph != 4 )
|
||||||
|
{
|
||||||
|
// Replicate pixels for partial block
|
||||||
|
static const size_t uSrc[] = { 0, 0, 0, 1 };
|
||||||
|
|
||||||
|
if ( pw < 4 )
|
||||||
|
{
|
||||||
|
for( size_t t = 0; t < ph && t < 4; ++t )
|
||||||
|
{
|
||||||
|
for( size_t s = pw; s < 4; ++s )
|
||||||
|
{
|
||||||
|
#pragma prefast(suppress: 26000, "PREFAST false positive")
|
||||||
|
temp[ (t << 2) | s ] = temp[ (t << 2) | uSrc[s] ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ph < 4 )
|
||||||
|
{
|
||||||
|
for( size_t t = ph; t < 4; ++t )
|
||||||
|
{
|
||||||
|
for( size_t s = 0; s < 4; ++s )
|
||||||
|
{
|
||||||
|
#pragma prefast(suppress: 26000, "PREFAST false positive")
|
||||||
|
temp[ (t << 2) | s ] = temp[ (uSrc[t] << 2) | s ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_ConvertScanline( temp, 16, result.format, format, cflags | srgb );
|
||||||
|
|
||||||
|
if ( pfEncode )
|
||||||
|
pfEncode( dptr, temp, bcflags );
|
||||||
|
else
|
||||||
|
D3DXEncodeBC1( dptr, temp, alphaRef, bcflags );
|
||||||
|
|
||||||
|
sptr += sbpp*4;
|
||||||
|
dptr += blocksize;
|
||||||
|
}
|
||||||
|
|
||||||
|
pSrc += rowPitch*4;
|
||||||
|
pDest += result.rowPitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
#ifdef _OPENMP
|
||||||
|
static HRESULT _CompressBC_Parallel( _In_ const Image& image, _In_ const Image& result, _In_ DWORD bcflags,
|
||||||
|
_In_ DWORD srgb, _In_ float alphaRef )
|
||||||
|
{
|
||||||
|
if ( !image.pixels || !result.pixels )
|
||||||
|
return E_POINTER;
|
||||||
|
|
||||||
|
assert( image.width == result.width );
|
||||||
|
assert( image.height == result.height );
|
||||||
|
|
||||||
|
const DXGI_FORMAT format = image.format;
|
||||||
|
size_t sbpp = BitsPerPixel( format );
|
||||||
|
if ( !sbpp )
|
||||||
|
return E_FAIL;
|
||||||
|
|
||||||
|
if ( sbpp < 8 )
|
||||||
|
{
|
||||||
|
// We don't support compressing from monochrome (DXGI_FORMAT_R1_UNORM)
|
||||||
|
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Round to bytes
|
||||||
|
sbpp = ( sbpp + 7 ) / 8;
|
||||||
|
|
||||||
|
// Determine BC format encoder
|
||||||
|
BC_ENCODE pfEncode;
|
||||||
|
size_t blocksize;
|
||||||
|
DWORD cflags;
|
||||||
|
if ( !_DetermineEncoderSettings( result.format, pfEncode, blocksize, cflags ) )
|
||||||
|
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
|
||||||
|
|
||||||
|
// Refactored version of loop to support parallel independance
|
||||||
|
const size_t nBlocks = std::max<size_t>(1, (image.width + 3) / 4 ) * std::max<size_t>(1, (image.height + 3) / 4 );
|
||||||
|
|
||||||
|
bool fail = false;
|
||||||
|
|
||||||
|
#pragma omp parallel for
|
||||||
|
for( int nb=0; nb < static_cast<int>( nBlocks ); ++nb )
|
||||||
|
{
|
||||||
|
const size_t nbWidth = std::max<size_t>(1, (image.width + 3) / 4 );
|
||||||
|
|
||||||
|
const size_t y = nb / nbWidth;
|
||||||
|
const size_t x = nb - (y*nbWidth);
|
||||||
|
|
||||||
|
assert( x < image.width && y < image.height );
|
||||||
|
|
||||||
|
size_t rowPitch = image.rowPitch;
|
||||||
|
const uint8_t *pSrc = image.pixels + (y*4*rowPitch) + (x*4*sbpp);
|
||||||
|
|
||||||
|
uint8_t *pDest = result.pixels + (nb*blocksize);
|
||||||
|
|
||||||
|
size_t ph = std::min<size_t>( 4, image.height - y );
|
||||||
|
size_t pw = std::min<size_t>( 4, image.width - x );
|
||||||
|
assert( pw > 0 && ph > 0 );
|
||||||
|
|
||||||
|
XMVECTOR temp[16];
|
||||||
|
if ( !_LoadScanline( &temp[0], pw, pSrc, rowPitch, format ) )
|
||||||
|
fail = true;
|
||||||
|
|
||||||
|
if ( ph > 1 )
|
||||||
|
{
|
||||||
|
if ( !_LoadScanline( &temp[4], pw, pSrc + rowPitch, rowPitch, format ) )
|
||||||
|
fail = true;
|
||||||
|
|
||||||
|
if ( ph > 2 )
|
||||||
|
{
|
||||||
|
if ( !_LoadScanline( &temp[8], pw, pSrc + rowPitch*2, rowPitch, format ) )
|
||||||
|
fail = true;
|
||||||
|
|
||||||
|
if ( ph > 3 )
|
||||||
|
{
|
||||||
|
if ( !_LoadScanline( &temp[12], pw, pSrc + rowPitch*3, rowPitch, format ) )
|
||||||
|
fail = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( pw != 4 || ph != 4 )
|
||||||
|
{
|
||||||
|
// Replicate pixels for partial block
|
||||||
|
static const size_t uSrc[] = { 0, 0, 0, 1 };
|
||||||
|
|
||||||
|
if ( pw < 4 )
|
||||||
|
{
|
||||||
|
for( size_t t = 0; t < ph && t < 4; ++t )
|
||||||
|
{
|
||||||
|
for( size_t s = pw; s < 4; ++s )
|
||||||
|
{
|
||||||
|
temp[ (t << 2) | s ] = temp[ (t << 2) | uSrc[s] ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ph < 4 )
|
||||||
|
{
|
||||||
|
for( size_t t = ph; t < 4; ++t )
|
||||||
|
{
|
||||||
|
for( size_t s = 0; s < 4; ++s )
|
||||||
|
{
|
||||||
|
temp[ (t << 2) | s ] = temp[ (uSrc[t] << 2) | s ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_ConvertScanline( temp, 16, result.format, format, cflags | srgb );
|
||||||
|
|
||||||
|
if ( pfEncode )
|
||||||
|
pfEncode( pDest, temp, bcflags );
|
||||||
|
else
|
||||||
|
D3DXEncodeBC1( pDest, temp, alphaRef, bcflags );
|
||||||
|
}
|
||||||
|
|
||||||
|
return (fail) ? E_FAIL : S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // _OPENMP
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
static DXGI_FORMAT _DefaultDecompress( _In_ DXGI_FORMAT format )
|
||||||
|
{
|
||||||
|
switch( format )
|
||||||
|
{
|
||||||
|
case DXGI_FORMAT_BC1_TYPELESS:
|
||||||
|
case DXGI_FORMAT_BC1_UNORM:
|
||||||
|
case DXGI_FORMAT_BC2_TYPELESS:
|
||||||
|
case DXGI_FORMAT_BC2_UNORM:
|
||||||
|
case DXGI_FORMAT_BC3_TYPELESS:
|
||||||
|
case DXGI_FORMAT_BC3_UNORM:
|
||||||
|
case DXGI_FORMAT_BC7_TYPELESS:
|
||||||
|
case DXGI_FORMAT_BC7_UNORM:
|
||||||
|
return DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
|
||||||
|
case DXGI_FORMAT_BC1_UNORM_SRGB:
|
||||||
|
case DXGI_FORMAT_BC2_UNORM_SRGB:
|
||||||
|
case DXGI_FORMAT_BC3_UNORM_SRGB:
|
||||||
|
case DXGI_FORMAT_BC7_UNORM_SRGB:
|
||||||
|
return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
|
||||||
|
|
||||||
|
case DXGI_FORMAT_BC4_TYPELESS:
|
||||||
|
case DXGI_FORMAT_BC4_UNORM:
|
||||||
|
return DXGI_FORMAT_R8_UNORM;
|
||||||
|
|
||||||
|
case DXGI_FORMAT_BC4_SNORM:
|
||||||
|
return DXGI_FORMAT_R8_SNORM;
|
||||||
|
|
||||||
|
case DXGI_FORMAT_BC5_TYPELESS:
|
||||||
|
case DXGI_FORMAT_BC5_UNORM:
|
||||||
|
return DXGI_FORMAT_R8G8_UNORM;
|
||||||
|
|
||||||
|
case DXGI_FORMAT_BC5_SNORM:
|
||||||
|
return DXGI_FORMAT_R8G8_SNORM;
|
||||||
|
|
||||||
|
case DXGI_FORMAT_BC6H_TYPELESS:
|
||||||
|
case DXGI_FORMAT_BC6H_UF16:
|
||||||
|
case DXGI_FORMAT_BC6H_SF16:
|
||||||
|
// We could use DXGI_FORMAT_R32G32B32_FLOAT here since BC6H is always Alpha 1.0,
|
||||||
|
// but this format is more supported by viewers
|
||||||
|
return DXGI_FORMAT_R32G32B32A32_FLOAT;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return DXGI_FORMAT_UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
static HRESULT _DecompressBC( _In_ const Image& cImage, _In_ const Image& result )
|
||||||
|
{
|
||||||
|
if ( !cImage.pixels || !result.pixels )
|
||||||
|
return E_POINTER;
|
||||||
|
|
||||||
|
assert( cImage.width == result.width );
|
||||||
|
assert( cImage.height == result.height );
|
||||||
|
|
||||||
|
const DXGI_FORMAT format = result.format;
|
||||||
|
size_t dbpp = BitsPerPixel( format );
|
||||||
|
if ( !dbpp )
|
||||||
|
return E_FAIL;
|
||||||
|
|
||||||
|
if ( dbpp < 8 )
|
||||||
|
{
|
||||||
|
// We don't support decompressing to monochrome (DXGI_FORMAT_R1_UNORM)
|
||||||
|
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Round to bytes
|
||||||
|
dbpp = ( dbpp + 7 ) / 8;
|
||||||
|
|
||||||
|
uint8_t *pDest = result.pixels;
|
||||||
|
if ( !pDest )
|
||||||
|
return E_POINTER;
|
||||||
|
|
||||||
|
// Promote "typeless" BC formats
|
||||||
|
DXGI_FORMAT cformat;
|
||||||
|
switch( cImage.format )
|
||||||
|
{
|
||||||
|
case DXGI_FORMAT_BC1_TYPELESS: cformat = DXGI_FORMAT_BC1_UNORM; break;
|
||||||
|
case DXGI_FORMAT_BC2_TYPELESS: cformat = DXGI_FORMAT_BC2_UNORM; break;
|
||||||
|
case DXGI_FORMAT_BC3_TYPELESS: cformat = DXGI_FORMAT_BC3_UNORM; break;
|
||||||
|
case DXGI_FORMAT_BC4_TYPELESS: cformat = DXGI_FORMAT_BC4_UNORM; break;
|
||||||
|
case DXGI_FORMAT_BC5_TYPELESS: cformat = DXGI_FORMAT_BC5_UNORM; break;
|
||||||
|
case DXGI_FORMAT_BC6H_TYPELESS: cformat = DXGI_FORMAT_BC6H_UF16; break;
|
||||||
|
case DXGI_FORMAT_BC7_TYPELESS: cformat = DXGI_FORMAT_BC7_UNORM; break;
|
||||||
|
default: cformat = cImage.format; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine BC format decoder
|
||||||
|
BC_DECODE pfDecode;
|
||||||
|
size_t sbpp;
|
||||||
|
switch(cformat)
|
||||||
|
{
|
||||||
|
case DXGI_FORMAT_BC1_UNORM:
|
||||||
|
case DXGI_FORMAT_BC1_UNORM_SRGB: pfDecode = D3DXDecodeBC1; sbpp = 8; break;
|
||||||
|
case DXGI_FORMAT_BC2_UNORM:
|
||||||
|
case DXGI_FORMAT_BC2_UNORM_SRGB: pfDecode = D3DXDecodeBC2; sbpp = 16; break;
|
||||||
|
case DXGI_FORMAT_BC3_UNORM:
|
||||||
|
case DXGI_FORMAT_BC3_UNORM_SRGB: pfDecode = D3DXDecodeBC3; sbpp = 16; break;
|
||||||
|
case DXGI_FORMAT_BC4_UNORM: pfDecode = D3DXDecodeBC4U; sbpp = 8; break;
|
||||||
|
case DXGI_FORMAT_BC4_SNORM: pfDecode = D3DXDecodeBC4S; sbpp = 8; break;
|
||||||
|
case DXGI_FORMAT_BC5_UNORM: pfDecode = D3DXDecodeBC5U; sbpp = 16; break;
|
||||||
|
case DXGI_FORMAT_BC5_SNORM: pfDecode = D3DXDecodeBC5S; sbpp = 16; break;
|
||||||
|
case DXGI_FORMAT_BC6H_UF16: pfDecode = D3DXDecodeBC6HU; sbpp = 16; break;
|
||||||
|
case DXGI_FORMAT_BC6H_SF16: pfDecode = D3DXDecodeBC6HS; sbpp = 16; break;
|
||||||
|
case DXGI_FORMAT_BC7_UNORM:
|
||||||
|
case DXGI_FORMAT_BC7_UNORM_SRGB: pfDecode = D3DXDecodeBC7; sbpp = 16; break;
|
||||||
|
default:
|
||||||
|
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
|
||||||
|
}
|
||||||
|
|
||||||
|
XMVECTOR temp[16];
|
||||||
|
const uint8_t *pSrc = cImage.pixels;
|
||||||
|
const size_t rowPitch = result.rowPitch;
|
||||||
|
for( size_t h=0; h < cImage.height; h += 4 )
|
||||||
|
{
|
||||||
|
const uint8_t *sptr = pSrc;
|
||||||
|
uint8_t* dptr = pDest;
|
||||||
|
size_t ph = std::min<size_t>( 4, cImage.height - h );
|
||||||
|
size_t w = 0;
|
||||||
|
for( size_t count = 0; (count < cImage.rowPitch) && (w < cImage.width); count += sbpp, w += 4 )
|
||||||
|
{
|
||||||
|
pfDecode( temp, sptr );
|
||||||
|
_ConvertScanline( temp, 16, format, cformat, 0 );
|
||||||
|
|
||||||
|
size_t pw = std::min<size_t>( 4, cImage.width - w );
|
||||||
|
assert( pw > 0 && ph > 0 );
|
||||||
|
|
||||||
|
if ( !_StoreScanline( dptr, rowPitch, format, &temp[0], pw ) )
|
||||||
|
return E_FAIL;
|
||||||
|
|
||||||
|
if ( ph > 1 )
|
||||||
|
{
|
||||||
|
if ( !_StoreScanline( dptr + rowPitch, rowPitch, format, &temp[4], pw ) )
|
||||||
|
return E_FAIL;
|
||||||
|
|
||||||
|
if ( ph > 2 )
|
||||||
|
{
|
||||||
|
if ( !_StoreScanline( dptr + rowPitch*2, rowPitch, format, &temp[8], pw ) )
|
||||||
|
return E_FAIL;
|
||||||
|
|
||||||
|
if ( ph > 3 )
|
||||||
|
{
|
||||||
|
if ( !_StoreScanline( dptr + rowPitch*3, rowPitch, format, &temp[12], pw ) )
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sptr += sbpp;
|
||||||
|
dptr += dbpp*4;
|
||||||
|
}
|
||||||
|
|
||||||
|
pSrc += cImage.rowPitch;
|
||||||
|
pDest += rowPitch*4;
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
bool _IsAlphaAllOpaqueBC( _In_ const Image& cImage )
|
||||||
|
{
|
||||||
|
if ( !cImage.pixels )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Promote "typeless" BC formats
|
||||||
|
DXGI_FORMAT cformat;
|
||||||
|
switch( cImage.format )
|
||||||
|
{
|
||||||
|
case DXGI_FORMAT_BC1_TYPELESS: cformat = DXGI_FORMAT_BC1_UNORM; break;
|
||||||
|
case DXGI_FORMAT_BC2_TYPELESS: cformat = DXGI_FORMAT_BC2_UNORM; break;
|
||||||
|
case DXGI_FORMAT_BC3_TYPELESS: cformat = DXGI_FORMAT_BC3_UNORM; break;
|
||||||
|
case DXGI_FORMAT_BC7_TYPELESS: cformat = DXGI_FORMAT_BC7_UNORM; break;
|
||||||
|
default: cformat = cImage.format; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine BC format decoder
|
||||||
|
BC_DECODE pfDecode;
|
||||||
|
size_t sbpp;
|
||||||
|
switch(cformat)
|
||||||
|
{
|
||||||
|
case DXGI_FORMAT_BC1_UNORM:
|
||||||
|
case DXGI_FORMAT_BC1_UNORM_SRGB: pfDecode = D3DXDecodeBC1; sbpp = 8; break;
|
||||||
|
case DXGI_FORMAT_BC2_UNORM:
|
||||||
|
case DXGI_FORMAT_BC2_UNORM_SRGB: pfDecode = D3DXDecodeBC2; sbpp = 16; break;
|
||||||
|
case DXGI_FORMAT_BC3_UNORM:
|
||||||
|
case DXGI_FORMAT_BC3_UNORM_SRGB: pfDecode = D3DXDecodeBC3; sbpp = 16; break;
|
||||||
|
case DXGI_FORMAT_BC7_UNORM:
|
||||||
|
case DXGI_FORMAT_BC7_UNORM_SRGB: pfDecode = D3DXDecodeBC7; sbpp = 16; break;
|
||||||
|
default:
|
||||||
|
// BC4, BC5, and BC6 don't have alpha channels
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scan blocks for non-opaque alpha
|
||||||
|
static const XMVECTORF32 threshold = { 0.99f, 0.99f, 0.99f, 0.99f };
|
||||||
|
|
||||||
|
XMVECTOR temp[16];
|
||||||
|
const uint8_t *pPixels = cImage.pixels;
|
||||||
|
for( size_t h = 0; h < cImage.height; h += 4 )
|
||||||
|
{
|
||||||
|
const uint8_t *ptr = pPixels;
|
||||||
|
size_t ph = std::min<size_t>( 4, cImage.height - h );
|
||||||
|
size_t w = 0;
|
||||||
|
for( size_t count = 0; (count < cImage.rowPitch) && (w < cImage.width); count += sbpp, w += 4 )
|
||||||
|
{
|
||||||
|
pfDecode( temp, ptr );
|
||||||
|
|
||||||
|
size_t pw = std::min<size_t>( 4, cImage.width - w );
|
||||||
|
assert( pw > 0 && ph > 0 );
|
||||||
|
|
||||||
|
if ( pw == 4 && ph == 4 )
|
||||||
|
{
|
||||||
|
// Full blocks
|
||||||
|
for( size_t j = 0; j < 16; ++j )
|
||||||
|
{
|
||||||
|
XMVECTOR alpha = XMVectorSplatW( temp[j] );
|
||||||
|
if ( XMVector4Less( alpha, threshold ) )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Handle partial blocks
|
||||||
|
for( size_t y = 0; y < ph; ++y )
|
||||||
|
{
|
||||||
|
for( size_t x = 0; x < pw; ++x )
|
||||||
|
{
|
||||||
|
XMVECTOR alpha = XMVectorSplatW( temp[ y * 4 + x ] );
|
||||||
|
if ( XMVector4Less( alpha, threshold ) )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr += sbpp;
|
||||||
|
}
|
||||||
|
|
||||||
|
pPixels += cImage.rowPitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//=====================================================================================
|
||||||
|
// Entry-points
|
||||||
|
//=====================================================================================
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
// Compression
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
_Use_decl_annotations_
|
||||||
|
HRESULT Compress( const Image& srcImage, DXGI_FORMAT format, DWORD compress, float alphaRef, ScratchImage& image )
|
||||||
|
{
|
||||||
|
if ( IsCompressed(srcImage.format) || !IsCompressed(format) )
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
if ( IsTypeless(format)
|
||||||
|
|| IsTypeless(srcImage.format) || IsPlanar(srcImage.format) || IsPalettized(srcImage.format) )
|
||||||
|
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
|
||||||
|
|
||||||
|
// Create compressed image
|
||||||
|
HRESULT hr = image.Initialize2D( format, srcImage.width, srcImage.height, 1, 1 );
|
||||||
|
if ( FAILED(hr) )
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
const Image *img = image.GetImage( 0, 0, 0 );
|
||||||
|
if ( !img )
|
||||||
|
{
|
||||||
|
image.Release();
|
||||||
|
return E_POINTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compress single image
|
||||||
|
if (compress & TEX_COMPRESS_PARALLEL)
|
||||||
|
{
|
||||||
|
#ifndef _OPENMP
|
||||||
|
return E_NOTIMPL;
|
||||||
|
#else
|
||||||
|
hr = _CompressBC_Parallel( srcImage, *img, _GetBCFlags( compress ), _GetSRGBFlags( compress ), alphaRef );
|
||||||
|
#endif // _OPENMP
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hr = _CompressBC( srcImage, *img, _GetBCFlags( compress ), _GetSRGBFlags( compress ), alphaRef );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( FAILED(hr) )
|
||||||
|
image.Release();
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
_Use_decl_annotations_
|
||||||
|
HRESULT Compress( const Image* srcImages, size_t nimages, const TexMetadata& metadata,
|
||||||
|
DXGI_FORMAT format, DWORD compress, float alphaRef, ScratchImage& cImages )
|
||||||
|
{
|
||||||
|
if ( !srcImages || !nimages )
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
if ( IsCompressed(metadata.format) || !IsCompressed(format) )
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
if ( IsTypeless(format)
|
||||||
|
|| IsTypeless(metadata.format) || IsPlanar(metadata.format) || IsPalettized(metadata.format) )
|
||||||
|
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
|
||||||
|
|
||||||
|
cImages.Release();
|
||||||
|
|
||||||
|
TexMetadata mdata2 = metadata;
|
||||||
|
mdata2.format = format;
|
||||||
|
HRESULT hr = cImages.Initialize( mdata2 );
|
||||||
|
if ( FAILED(hr) )
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
if ( nimages != cImages.GetImageCount() )
|
||||||
|
{
|
||||||
|
cImages.Release();
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Image* dest = cImages.GetImages();
|
||||||
|
if ( !dest )
|
||||||
|
{
|
||||||
|
cImages.Release();
|
||||||
|
return E_POINTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
for( size_t index=0; index < nimages; ++index )
|
||||||
|
{
|
||||||
|
assert( dest[ index ].format == format );
|
||||||
|
|
||||||
|
const Image& src = srcImages[ index ];
|
||||||
|
|
||||||
|
if ( src.width != dest[ index ].width || src.height != dest[ index ].height )
|
||||||
|
{
|
||||||
|
cImages.Release();
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (compress & TEX_COMPRESS_PARALLEL) )
|
||||||
|
{
|
||||||
|
#ifndef _OPENMP
|
||||||
|
return E_NOTIMPL;
|
||||||
|
#else
|
||||||
|
if ( compress & TEX_COMPRESS_PARALLEL )
|
||||||
|
{
|
||||||
|
hr = _CompressBC_Parallel( src, dest[ index ], _GetBCFlags( compress ), _GetSRGBFlags( compress ), alphaRef );
|
||||||
|
if ( FAILED(hr) )
|
||||||
|
{
|
||||||
|
cImages.Release();
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // _OPENMP
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hr = _CompressBC( src, dest[ index ], _GetBCFlags( compress ), _GetSRGBFlags( compress ), alphaRef );
|
||||||
|
if ( FAILED(hr) )
|
||||||
|
{
|
||||||
|
cImages.Release();
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
// Decompression
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
_Use_decl_annotations_
|
||||||
|
HRESULT Decompress( const Image& cImage, DXGI_FORMAT format, ScratchImage& image )
|
||||||
|
{
|
||||||
|
if ( !IsCompressed(cImage.format) || IsCompressed(format) )
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
if ( format == DXGI_FORMAT_UNKNOWN )
|
||||||
|
{
|
||||||
|
// Pick a default decompressed format based on BC input format
|
||||||
|
format = _DefaultDecompress( cImage.format );
|
||||||
|
if ( format == DXGI_FORMAT_UNKNOWN )
|
||||||
|
{
|
||||||
|
// Input is not a compressed format
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( !IsValid(format) )
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
if ( IsTypeless(format) || IsPlanar(format) || IsPalettized(format) )
|
||||||
|
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create decompressed image
|
||||||
|
HRESULT hr = image.Initialize2D( format, cImage.width, cImage.height, 1, 1 );
|
||||||
|
if ( FAILED(hr) )
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
const Image *img = image.GetImage( 0, 0, 0 );
|
||||||
|
if ( !img )
|
||||||
|
{
|
||||||
|
image.Release();
|
||||||
|
return E_POINTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decompress single image
|
||||||
|
hr = _DecompressBC( cImage, *img );
|
||||||
|
if ( FAILED(hr) )
|
||||||
|
image.Release();
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
_Use_decl_annotations_
|
||||||
|
HRESULT Decompress( const Image* cImages, size_t nimages, const TexMetadata& metadata,
|
||||||
|
DXGI_FORMAT format, ScratchImage& images )
|
||||||
|
{
|
||||||
|
if ( !cImages || !nimages )
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
if ( !IsCompressed(metadata.format) || IsCompressed(format) )
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
if ( format == DXGI_FORMAT_UNKNOWN )
|
||||||
|
{
|
||||||
|
// Pick a default decompressed format based on BC input format
|
||||||
|
format = _DefaultDecompress( cImages[0].format );
|
||||||
|
if ( format == DXGI_FORMAT_UNKNOWN )
|
||||||
|
{
|
||||||
|
// Input is not a compressed format
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( !IsValid(format) )
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
if ( IsTypeless(format) || IsPlanar(format) || IsPalettized(format) )
|
||||||
|
HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
|
||||||
|
}
|
||||||
|
|
||||||
|
images.Release();
|
||||||
|
|
||||||
|
TexMetadata mdata2 = metadata;
|
||||||
|
mdata2.format = format;
|
||||||
|
HRESULT hr = images.Initialize( mdata2 );
|
||||||
|
if ( FAILED(hr) )
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
if ( nimages != images.GetImageCount() )
|
||||||
|
{
|
||||||
|
images.Release();
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Image* dest = images.GetImages();
|
||||||
|
if ( !dest )
|
||||||
|
{
|
||||||
|
images.Release();
|
||||||
|
return E_POINTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
for( size_t index=0; index < nimages; ++index )
|
||||||
|
{
|
||||||
|
assert( dest[ index ].format == format );
|
||||||
|
|
||||||
|
const Image& src = cImages[ index ];
|
||||||
|
if ( !IsCompressed( src.format ) )
|
||||||
|
{
|
||||||
|
images.Release();
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( src.width != dest[ index ].width || src.height != dest[ index ].height )
|
||||||
|
{
|
||||||
|
images.Release();
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = _DecompressBC( src, dest[ index ] );
|
||||||
|
if ( FAILED(hr) )
|
||||||
|
{
|
||||||
|
images.Release();
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
}; // namespace
|
4982
Switch_Toolbox/Lib/DirectXTex/DirectXTexConvert.cpp
Normal file
4982
Switch_Toolbox/Lib/DirectXTex/DirectXTexConvert.cpp
Normal file
File diff suppressed because it is too large
Load diff
2002
Switch_Toolbox/Lib/DirectXTex/DirectXTexDDS.cpp
Normal file
2002
Switch_Toolbox/Lib/DirectXTex/DirectXTexDDS.cpp
Normal file
File diff suppressed because it is too large
Load diff
794
Switch_Toolbox/Lib/DirectXTex/DirectXTexImage.cpp
Normal file
794
Switch_Toolbox/Lib/DirectXTex/DirectXTexImage.cpp
Normal file
|
@ -0,0 +1,794 @@
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
// DirectXTexImage.cpp
|
||||||
|
//
|
||||||
|
// DirectX Texture Library - Image container
|
||||||
|
//
|
||||||
|
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||||
|
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
||||||
|
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||||
|
// PARTICULAR PURPOSE.
|
||||||
|
//
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
//
|
||||||
|
// http://go.microsoft.com/fwlink/?LinkId=248926
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "directxtexp.h"
|
||||||
|
|
||||||
|
namespace DirectX
|
||||||
|
{
|
||||||
|
|
||||||
|
extern bool _CalculateMipLevels( _In_ size_t width, _In_ size_t height, _Inout_ size_t& mipLevels );
|
||||||
|
extern bool _CalculateMipLevels3D( _In_ size_t width, _In_ size_t height, _In_ size_t depth, _Inout_ size_t& mipLevels );
|
||||||
|
extern bool _IsAlphaAllOpaqueBC( _In_ const Image& cImage );
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
// Determines number of image array entries and pixel size
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
_Use_decl_annotations_
|
||||||
|
void _DetermineImageArray( const TexMetadata& metadata, DWORD cpFlags,
|
||||||
|
size_t& nImages, size_t& pixelSize )
|
||||||
|
{
|
||||||
|
assert( metadata.width > 0 && metadata.height > 0 && metadata.depth > 0 );
|
||||||
|
assert( metadata.arraySize > 0 );
|
||||||
|
assert( metadata.mipLevels > 0 );
|
||||||
|
|
||||||
|
size_t _pixelSize = 0;
|
||||||
|
size_t _nimages = 0;
|
||||||
|
|
||||||
|
switch( metadata.dimension )
|
||||||
|
{
|
||||||
|
case TEX_DIMENSION_TEXTURE1D:
|
||||||
|
case TEX_DIMENSION_TEXTURE2D:
|
||||||
|
for( size_t item = 0; item < metadata.arraySize; ++item )
|
||||||
|
{
|
||||||
|
size_t w = metadata.width;
|
||||||
|
size_t h = metadata.height;
|
||||||
|
|
||||||
|
for( size_t level=0; level < metadata.mipLevels; ++level )
|
||||||
|
{
|
||||||
|
size_t rowPitch, slicePitch;
|
||||||
|
ComputePitch( metadata.format, w, h, rowPitch, slicePitch, cpFlags );
|
||||||
|
|
||||||
|
_pixelSize += slicePitch;
|
||||||
|
++_nimages;
|
||||||
|
|
||||||
|
if ( h > 1 )
|
||||||
|
h >>= 1;
|
||||||
|
|
||||||
|
if ( w > 1 )
|
||||||
|
w >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TEX_DIMENSION_TEXTURE3D:
|
||||||
|
{
|
||||||
|
size_t w = metadata.width;
|
||||||
|
size_t h = metadata.height;
|
||||||
|
size_t d = metadata.depth;
|
||||||
|
|
||||||
|
for( size_t level=0; level < metadata.mipLevels; ++level )
|
||||||
|
{
|
||||||
|
size_t rowPitch, slicePitch;
|
||||||
|
ComputePitch( metadata.format, w, h, rowPitch, slicePitch, cpFlags );
|
||||||
|
|
||||||
|
for( size_t slice=0; slice < d; ++slice )
|
||||||
|
{
|
||||||
|
_pixelSize += slicePitch;
|
||||||
|
++_nimages;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( h > 1 )
|
||||||
|
h >>= 1;
|
||||||
|
|
||||||
|
if ( w > 1 )
|
||||||
|
w >>= 1;
|
||||||
|
|
||||||
|
if ( d > 1 )
|
||||||
|
d >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert( false );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
nImages = _nimages;
|
||||||
|
pixelSize = _pixelSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
// Fills in the image array entries
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
_Use_decl_annotations_
|
||||||
|
bool _SetupImageArray( uint8_t *pMemory, size_t pixelSize,
|
||||||
|
const TexMetadata& metadata, DWORD cpFlags,
|
||||||
|
Image* images, size_t nImages )
|
||||||
|
{
|
||||||
|
assert( pMemory );
|
||||||
|
assert( pixelSize > 0 );
|
||||||
|
assert( nImages > 0 );
|
||||||
|
|
||||||
|
if ( !images )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
size_t index = 0;
|
||||||
|
uint8_t* pixels = pMemory;
|
||||||
|
const uint8_t* pEndBits = pMemory + pixelSize;
|
||||||
|
|
||||||
|
switch( metadata.dimension )
|
||||||
|
{
|
||||||
|
case TEX_DIMENSION_TEXTURE1D:
|
||||||
|
case TEX_DIMENSION_TEXTURE2D:
|
||||||
|
if (metadata.arraySize == 0 || metadata.mipLevels == 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for( size_t item = 0; item < metadata.arraySize; ++item )
|
||||||
|
{
|
||||||
|
size_t w = metadata.width;
|
||||||
|
size_t h = metadata.height;
|
||||||
|
|
||||||
|
for( size_t level=0; level < metadata.mipLevels; ++level )
|
||||||
|
{
|
||||||
|
if ( index >= nImages )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t rowPitch, slicePitch;
|
||||||
|
ComputePitch( metadata.format, w, h, rowPitch, slicePitch, cpFlags );
|
||||||
|
|
||||||
|
images[index].width = w;
|
||||||
|
images[index].height = h;
|
||||||
|
images[index].format = metadata.format;
|
||||||
|
images[index].rowPitch = rowPitch;
|
||||||
|
images[index].slicePitch = slicePitch;
|
||||||
|
images[index].pixels = pixels;
|
||||||
|
++index;
|
||||||
|
|
||||||
|
pixels += slicePitch;
|
||||||
|
if ( pixels > pEndBits )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( h > 1 )
|
||||||
|
h >>= 1;
|
||||||
|
|
||||||
|
if ( w > 1 )
|
||||||
|
w >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case TEX_DIMENSION_TEXTURE3D:
|
||||||
|
{
|
||||||
|
if (metadata.mipLevels == 0 || metadata.depth == 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t w = metadata.width;
|
||||||
|
size_t h = metadata.height;
|
||||||
|
size_t d = metadata.depth;
|
||||||
|
|
||||||
|
for( size_t level=0; level < metadata.mipLevels; ++level )
|
||||||
|
{
|
||||||
|
size_t rowPitch, slicePitch;
|
||||||
|
ComputePitch( metadata.format, w, h, rowPitch, slicePitch, cpFlags );
|
||||||
|
|
||||||
|
for( size_t slice=0; slice < d; ++slice )
|
||||||
|
{
|
||||||
|
if ( index >= nImages )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We use the same memory organization that Direct3D 11 needs for D3D11_SUBRESOURCE_DATA
|
||||||
|
// with all slices of a given miplevel being continuous in memory
|
||||||
|
images[index].width = w;
|
||||||
|
images[index].height = h;
|
||||||
|
images[index].format = metadata.format;
|
||||||
|
images[index].rowPitch = rowPitch;
|
||||||
|
images[index].slicePitch = slicePitch;
|
||||||
|
images[index].pixels = pixels;
|
||||||
|
++index;
|
||||||
|
|
||||||
|
pixels += slicePitch;
|
||||||
|
if ( pixels > pEndBits )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( h > 1 )
|
||||||
|
h >>= 1;
|
||||||
|
|
||||||
|
if ( w > 1 )
|
||||||
|
w >>= 1;
|
||||||
|
|
||||||
|
if ( d > 1 )
|
||||||
|
d >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//=====================================================================================
|
||||||
|
// ScratchImage - Bitmap image container
|
||||||
|
//=====================================================================================
|
||||||
|
|
||||||
|
ScratchImage& ScratchImage::operator= (ScratchImage&& moveFrom)
|
||||||
|
{
|
||||||
|
if ( this != &moveFrom )
|
||||||
|
{
|
||||||
|
Release();
|
||||||
|
|
||||||
|
_nimages = moveFrom._nimages;
|
||||||
|
_size = moveFrom._size;
|
||||||
|
_metadata = moveFrom._metadata;
|
||||||
|
_image = moveFrom._image;
|
||||||
|
_memory = moveFrom._memory;
|
||||||
|
|
||||||
|
moveFrom._nimages = 0;
|
||||||
|
moveFrom._size = 0;
|
||||||
|
moveFrom._image = nullptr;
|
||||||
|
moveFrom._memory = nullptr;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
// Methods
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
_Use_decl_annotations_
|
||||||
|
HRESULT ScratchImage::Initialize( const TexMetadata& mdata, DWORD flags )
|
||||||
|
{
|
||||||
|
if ( !IsValid(mdata.format) )
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
if ( IsPalettized(mdata.format) )
|
||||||
|
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
|
||||||
|
|
||||||
|
size_t mipLevels = mdata.mipLevels;
|
||||||
|
|
||||||
|
switch( mdata.dimension )
|
||||||
|
{
|
||||||
|
case TEX_DIMENSION_TEXTURE1D:
|
||||||
|
if ( !mdata.width || mdata.height != 1 || mdata.depth != 1 || !mdata.arraySize )
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
if ( !_CalculateMipLevels(mdata.width,1,mipLevels) )
|
||||||
|
return E_INVALIDARG;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TEX_DIMENSION_TEXTURE2D:
|
||||||
|
if ( !mdata.width || !mdata.height || mdata.depth != 1 || !mdata.arraySize )
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
if ( mdata.IsCubemap() )
|
||||||
|
{
|
||||||
|
if ( (mdata.arraySize % 6) != 0 )
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !_CalculateMipLevels(mdata.width,mdata.height,mipLevels) )
|
||||||
|
return E_INVALIDARG;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TEX_DIMENSION_TEXTURE3D:
|
||||||
|
if ( !mdata.width || !mdata.height || !mdata.depth || mdata.arraySize != 1 )
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
if ( !_CalculateMipLevels3D(mdata.width,mdata.height,mdata.depth,mipLevels) )
|
||||||
|
return E_INVALIDARG;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
|
||||||
|
}
|
||||||
|
|
||||||
|
Release();
|
||||||
|
|
||||||
|
_metadata.width = mdata.width;
|
||||||
|
_metadata.height = mdata.height;
|
||||||
|
_metadata.depth = mdata.depth;
|
||||||
|
_metadata.arraySize = mdata.arraySize;
|
||||||
|
_metadata.mipLevels = mipLevels;
|
||||||
|
_metadata.miscFlags = mdata.miscFlags;
|
||||||
|
_metadata.miscFlags2 = mdata.miscFlags2;
|
||||||
|
_metadata.format = mdata.format;
|
||||||
|
_metadata.dimension = mdata.dimension;
|
||||||
|
|
||||||
|
size_t pixelSize, nimages;
|
||||||
|
_DetermineImageArray( _metadata, flags, nimages, pixelSize );
|
||||||
|
|
||||||
|
_image = new (std::nothrow) Image[ nimages ];
|
||||||
|
if ( !_image )
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
_nimages = nimages;
|
||||||
|
memset( _image, 0, sizeof(Image) * nimages );
|
||||||
|
|
||||||
|
_memory = reinterpret_cast<uint8_t*>( _aligned_malloc( pixelSize, 16 ) );
|
||||||
|
if ( !_memory )
|
||||||
|
{
|
||||||
|
Release();
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
_size = pixelSize;
|
||||||
|
if ( !_SetupImageArray( _memory, pixelSize, _metadata, flags, _image, nimages ) )
|
||||||
|
{
|
||||||
|
Release();
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
_Use_decl_annotations_
|
||||||
|
HRESULT ScratchImage::Initialize1D( DXGI_FORMAT fmt, size_t length, size_t arraySize, size_t mipLevels, DWORD flags )
|
||||||
|
{
|
||||||
|
if ( !length || !arraySize )
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
// 1D is a special case of the 2D case
|
||||||
|
HRESULT hr = Initialize2D( fmt, length, 1, arraySize, mipLevels, flags );
|
||||||
|
if ( FAILED(hr) )
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
_metadata.dimension = TEX_DIMENSION_TEXTURE1D;
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
_Use_decl_annotations_
|
||||||
|
HRESULT ScratchImage::Initialize2D( DXGI_FORMAT fmt, size_t width, size_t height, size_t arraySize, size_t mipLevels, DWORD flags )
|
||||||
|
{
|
||||||
|
if ( !IsValid(fmt) || !width || !height || !arraySize )
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
if ( IsPalettized(fmt) )
|
||||||
|
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
|
||||||
|
|
||||||
|
if ( !_CalculateMipLevels(width,height,mipLevels) )
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
Release();
|
||||||
|
|
||||||
|
_metadata.width = width;
|
||||||
|
_metadata.height = height;
|
||||||
|
_metadata.depth = 1;
|
||||||
|
_metadata.arraySize = arraySize;
|
||||||
|
_metadata.mipLevels = mipLevels;
|
||||||
|
_metadata.miscFlags = 0;
|
||||||
|
_metadata.miscFlags2 = 0;
|
||||||
|
_metadata.format = fmt;
|
||||||
|
_metadata.dimension = TEX_DIMENSION_TEXTURE2D;
|
||||||
|
|
||||||
|
size_t pixelSize, nimages;
|
||||||
|
_DetermineImageArray( _metadata, flags, nimages, pixelSize );
|
||||||
|
|
||||||
|
_image = new (std::nothrow) Image[ nimages ];
|
||||||
|
if ( !_image )
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
_nimages = nimages;
|
||||||
|
memset( _image, 0, sizeof(Image) * nimages );
|
||||||
|
|
||||||
|
_memory = reinterpret_cast<uint8_t*>( _aligned_malloc( pixelSize, 16 ) );
|
||||||
|
if ( !_memory )
|
||||||
|
{
|
||||||
|
Release();
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
_size = pixelSize;
|
||||||
|
if ( !_SetupImageArray( _memory, pixelSize, _metadata, flags, _image, nimages ) )
|
||||||
|
{
|
||||||
|
Release();
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
_Use_decl_annotations_
|
||||||
|
HRESULT ScratchImage::Initialize3D( DXGI_FORMAT fmt, size_t width, size_t height, size_t depth, size_t mipLevels, DWORD flags )
|
||||||
|
{
|
||||||
|
if ( !IsValid(fmt) || !width || !height || !depth )
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
if ( IsPalettized(fmt) )
|
||||||
|
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
|
||||||
|
|
||||||
|
if ( !_CalculateMipLevels3D(width,height,depth,mipLevels) )
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
Release();
|
||||||
|
|
||||||
|
_metadata.width = width;
|
||||||
|
_metadata.height = height;
|
||||||
|
_metadata.depth = depth;
|
||||||
|
_metadata.arraySize = 1; // Direct3D 10.x/11 does not support arrays of 3D textures
|
||||||
|
_metadata.mipLevels = mipLevels;
|
||||||
|
_metadata.miscFlags = 0;
|
||||||
|
_metadata.miscFlags2 = 0;
|
||||||
|
_metadata.format = fmt;
|
||||||
|
_metadata.dimension = TEX_DIMENSION_TEXTURE3D;
|
||||||
|
|
||||||
|
size_t pixelSize, nimages;
|
||||||
|
_DetermineImageArray( _metadata, flags, nimages, pixelSize );
|
||||||
|
|
||||||
|
_image = new (std::nothrow) Image[ nimages ];
|
||||||
|
if ( !_image )
|
||||||
|
{
|
||||||
|
Release();
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
_nimages = nimages;
|
||||||
|
memset( _image, 0, sizeof(Image) * nimages );
|
||||||
|
|
||||||
|
_memory = reinterpret_cast<uint8_t*>( _aligned_malloc( pixelSize, 16 ) );
|
||||||
|
if ( !_memory )
|
||||||
|
{
|
||||||
|
Release();
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
_size = pixelSize;
|
||||||
|
|
||||||
|
if ( !_SetupImageArray( _memory, pixelSize, _metadata, flags, _image, nimages ) )
|
||||||
|
{
|
||||||
|
Release();
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
_Use_decl_annotations_
|
||||||
|
HRESULT ScratchImage::InitializeCube( DXGI_FORMAT fmt, size_t width, size_t height, size_t nCubes, size_t mipLevels, DWORD flags )
|
||||||
|
{
|
||||||
|
if ( !width || !height || !nCubes )
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
// A DirectX11 cubemap is just a 2D texture array that is a multiple of 6 for each cube
|
||||||
|
HRESULT hr = Initialize2D( fmt, width, height, nCubes * 6, mipLevels, flags );
|
||||||
|
if ( FAILED(hr) )
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
_metadata.miscFlags |= TEX_MISC_TEXTURECUBE;
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
_Use_decl_annotations_
|
||||||
|
HRESULT ScratchImage::InitializeFromImage( const Image& srcImage, bool allow1D, DWORD flags )
|
||||||
|
{
|
||||||
|
HRESULT hr = ( srcImage.height > 1 || !allow1D )
|
||||||
|
? Initialize2D( srcImage.format, srcImage.width, srcImage.height, 1, 1, flags )
|
||||||
|
: Initialize1D( srcImage.format, srcImage.width, 1, 1, flags );
|
||||||
|
|
||||||
|
if ( FAILED(hr) )
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
size_t rowCount = ComputeScanlines( srcImage.format, srcImage.height );
|
||||||
|
if ( !rowCount )
|
||||||
|
return E_UNEXPECTED;
|
||||||
|
|
||||||
|
const uint8_t* sptr = reinterpret_cast<const uint8_t*>( srcImage.pixels );
|
||||||
|
if ( !sptr )
|
||||||
|
return E_POINTER;
|
||||||
|
|
||||||
|
auto dptr = reinterpret_cast<uint8_t*>( _image[0].pixels );
|
||||||
|
if ( !dptr )
|
||||||
|
return E_POINTER;
|
||||||
|
|
||||||
|
size_t spitch = srcImage.rowPitch;
|
||||||
|
size_t dpitch = _image[0].rowPitch;
|
||||||
|
|
||||||
|
size_t size = std::min<size_t>( dpitch, spitch );
|
||||||
|
|
||||||
|
for( size_t y = 0; y < rowCount; ++y )
|
||||||
|
{
|
||||||
|
memcpy_s( dptr, dpitch, sptr, size );
|
||||||
|
sptr += spitch;
|
||||||
|
dptr += dpitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
_Use_decl_annotations_
|
||||||
|
HRESULT ScratchImage::InitializeArrayFromImages( const Image* images, size_t nImages, bool allow1D, DWORD flags )
|
||||||
|
{
|
||||||
|
if ( !images || !nImages )
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
DXGI_FORMAT format = images[0].format;
|
||||||
|
size_t width = images[0].width;
|
||||||
|
size_t height = images[0].height;
|
||||||
|
|
||||||
|
for( size_t index=0; index < nImages; ++index )
|
||||||
|
{
|
||||||
|
if ( !images[index].pixels )
|
||||||
|
return E_POINTER;
|
||||||
|
|
||||||
|
if ( images[index].format != format || images[index].width != width || images[index].height != height )
|
||||||
|
{
|
||||||
|
// All images must be the same format, width, and height
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT hr = ( height > 1 || !allow1D )
|
||||||
|
? Initialize2D( format, width, height, nImages, 1, flags )
|
||||||
|
: Initialize1D( format, width, nImages, 1, flags );
|
||||||
|
|
||||||
|
if ( FAILED(hr) )
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
size_t rowCount = ComputeScanlines( format, height );
|
||||||
|
if ( !rowCount )
|
||||||
|
return E_UNEXPECTED;
|
||||||
|
|
||||||
|
for( size_t index=0; index < nImages; ++index )
|
||||||
|
{
|
||||||
|
auto sptr = reinterpret_cast<const uint8_t*>( images[index].pixels );
|
||||||
|
if ( !sptr )
|
||||||
|
return E_POINTER;
|
||||||
|
|
||||||
|
assert( index < _nimages );
|
||||||
|
auto dptr = reinterpret_cast<uint8_t*>( _image[index].pixels );
|
||||||
|
if ( !dptr )
|
||||||
|
return E_POINTER;
|
||||||
|
|
||||||
|
size_t spitch = images[index].rowPitch;
|
||||||
|
size_t dpitch = _image[index].rowPitch;
|
||||||
|
|
||||||
|
size_t size = std::min<size_t>( dpitch, spitch );
|
||||||
|
|
||||||
|
for( size_t y = 0; y < rowCount; ++y )
|
||||||
|
{
|
||||||
|
memcpy_s( dptr, dpitch, sptr, size );
|
||||||
|
sptr += spitch;
|
||||||
|
dptr += dpitch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
_Use_decl_annotations_
|
||||||
|
HRESULT ScratchImage::InitializeCubeFromImages( const Image* images, size_t nImages, DWORD flags )
|
||||||
|
{
|
||||||
|
if ( !images || !nImages )
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
// A DirectX11 cubemap is just a 2D texture array that is a multiple of 6 for each cube
|
||||||
|
if ( ( nImages % 6 ) != 0 )
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
HRESULT hr = InitializeArrayFromImages( images, nImages, false, flags );
|
||||||
|
if ( FAILED(hr) )
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
_metadata.miscFlags |= TEX_MISC_TEXTURECUBE;
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
_Use_decl_annotations_
|
||||||
|
HRESULT ScratchImage::Initialize3DFromImages( const Image* images, size_t depth, DWORD flags )
|
||||||
|
{
|
||||||
|
if ( !images || !depth )
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
DXGI_FORMAT format = images[0].format;
|
||||||
|
size_t width = images[0].width;
|
||||||
|
size_t height = images[0].height;
|
||||||
|
|
||||||
|
for( size_t slice=0; slice < depth; ++slice )
|
||||||
|
{
|
||||||
|
if ( !images[slice].pixels )
|
||||||
|
return E_POINTER;
|
||||||
|
|
||||||
|
if ( images[slice].format != format || images[slice].width != width || images[slice].height != height )
|
||||||
|
{
|
||||||
|
// All images must be the same format, width, and height
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT hr = Initialize3D( format, width, height, depth, 1, flags );
|
||||||
|
if ( FAILED(hr) )
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
size_t rowCount = ComputeScanlines( format, height );
|
||||||
|
if ( !rowCount )
|
||||||
|
return E_UNEXPECTED;
|
||||||
|
|
||||||
|
for( size_t slice=0; slice < depth; ++slice )
|
||||||
|
{
|
||||||
|
auto sptr = reinterpret_cast<const uint8_t*>( images[slice].pixels );
|
||||||
|
if ( !sptr )
|
||||||
|
return E_POINTER;
|
||||||
|
|
||||||
|
assert( slice < _nimages );
|
||||||
|
auto dptr = reinterpret_cast<uint8_t*>( _image[slice].pixels );
|
||||||
|
if ( !dptr )
|
||||||
|
return E_POINTER;
|
||||||
|
|
||||||
|
size_t spitch = images[slice].rowPitch;
|
||||||
|
size_t dpitch = _image[slice].rowPitch;
|
||||||
|
|
||||||
|
size_t size = std::min<size_t>( dpitch, spitch );
|
||||||
|
|
||||||
|
for( size_t y = 0; y < rowCount; ++y )
|
||||||
|
{
|
||||||
|
memcpy_s( dptr, dpitch, sptr, size );
|
||||||
|
sptr += spitch;
|
||||||
|
dptr += dpitch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScratchImage::Release()
|
||||||
|
{
|
||||||
|
_nimages = 0;
|
||||||
|
_size = 0;
|
||||||
|
|
||||||
|
if ( _image )
|
||||||
|
{
|
||||||
|
delete [] _image;
|
||||||
|
_image = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( _memory )
|
||||||
|
{
|
||||||
|
_aligned_free( _memory );
|
||||||
|
_memory = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&_metadata, 0, sizeof(_metadata));
|
||||||
|
}
|
||||||
|
|
||||||
|
_Use_decl_annotations_
|
||||||
|
bool ScratchImage::OverrideFormat( DXGI_FORMAT f )
|
||||||
|
{
|
||||||
|
if ( !_image )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ( !IsValid( f ) || IsPlanar( f ) || IsPalettized( f ) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for( size_t index = 0; index < _nimages; ++index )
|
||||||
|
{
|
||||||
|
_image[ index ].format = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
_metadata.format = f;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
_Use_decl_annotations_
|
||||||
|
const Image* ScratchImage::GetImage(size_t mip, size_t item, size_t slice) const
|
||||||
|
{
|
||||||
|
if ( mip >= _metadata.mipLevels )
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
size_t index = 0;
|
||||||
|
|
||||||
|
switch( _metadata.dimension )
|
||||||
|
{
|
||||||
|
case TEX_DIMENSION_TEXTURE1D:
|
||||||
|
case TEX_DIMENSION_TEXTURE2D:
|
||||||
|
if ( slice > 0 )
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
if ( item >= _metadata.arraySize )
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
index = item*( _metadata.mipLevels ) + mip;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TEX_DIMENSION_TEXTURE3D:
|
||||||
|
if ( item > 0 )
|
||||||
|
{
|
||||||
|
// No support for arrays of volumes
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size_t d = _metadata.depth;
|
||||||
|
|
||||||
|
for( size_t level = 0; level < mip; ++level )
|
||||||
|
{
|
||||||
|
index += d;
|
||||||
|
if ( d > 1 )
|
||||||
|
d >>= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( slice >= d )
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
index += slice;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &_image[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ScratchImage::IsAlphaAllOpaque() const
|
||||||
|
{
|
||||||
|
if ( !_image )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ( !HasAlpha( _metadata.format ) )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if ( IsCompressed( _metadata.format ) )
|
||||||
|
{
|
||||||
|
for( size_t index = 0; index < _nimages; ++index )
|
||||||
|
{
|
||||||
|
if ( !_IsAlphaAllOpaqueBC( _image[ index ] ) )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ScopedAlignedArrayXMVECTOR scanline( reinterpret_cast<XMVECTOR*>( _aligned_malloc( (sizeof(XMVECTOR)*_metadata.width), 16 ) ) );
|
||||||
|
if ( !scanline )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
static const XMVECTORF32 threshold = { 0.99f, 0.99f, 0.99f, 0.99f };
|
||||||
|
|
||||||
|
for( size_t index = 0; index < _nimages; ++index )
|
||||||
|
{
|
||||||
|
#pragma warning( suppress : 6011 )
|
||||||
|
const Image& img = _image[ index ];
|
||||||
|
|
||||||
|
const uint8_t *pPixels = img.pixels;
|
||||||
|
assert( pPixels );
|
||||||
|
|
||||||
|
for( size_t h = 0; h < img.height; ++h )
|
||||||
|
{
|
||||||
|
if ( !_LoadScanline( scanline.get(), img.width, pPixels, img.rowPitch, img.format ) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
XMVECTOR* ptr = scanline.get();
|
||||||
|
for( size_t w = 0; w < img.width; ++w )
|
||||||
|
{
|
||||||
|
XMVECTOR alpha = XMVectorSplatW( *ptr );
|
||||||
|
if ( XMVector4Less( alpha, threshold ) )
|
||||||
|
return false;
|
||||||
|
++ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
pPixels += img.rowPitch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}; // namespace
|
3099
Switch_Toolbox/Lib/DirectXTex/DirectXTexMipmaps.cpp
Normal file
3099
Switch_Toolbox/Lib/DirectXTex/DirectXTexMipmaps.cpp
Normal file
File diff suppressed because it is too large
Load diff
231
Switch_Toolbox/Lib/DirectXTex/DirectXTexP.h
Normal file
231
Switch_Toolbox/Lib/DirectXTex/DirectXTexP.h
Normal file
|
@ -0,0 +1,231 @@
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
// DirectXTexp.h
|
||||||
|
//
|
||||||
|
// DirectX Texture Library - Private header
|
||||||
|
//
|
||||||
|
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||||
|
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
||||||
|
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||||
|
// PARTICULAR PURPOSE.
|
||||||
|
//
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
//
|
||||||
|
// http://go.microsoft.com/fwlink/?LinkId=248926
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if !defined(WIN32_LEAN_AND_MEAN)
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(NOMINMAX)
|
||||||
|
#define NOMINMAX
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _WIN32_WINNT_WIN10
|
||||||
|
#define _WIN32_WINNT_WIN10 0x0A00
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <directxmath.h>
|
||||||
|
#include <directxpackedvector.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <search.h>
|
||||||
|
|
||||||
|
#include <ole2.h>
|
||||||
|
|
||||||
|
#include "directxtex.h"
|
||||||
|
|
||||||
|
// VS 2010's stdint.h conflicts with intsafe.h
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable : 4005)
|
||||||
|
#include <wincodec.h>
|
||||||
|
#include <intsafe.h>
|
||||||
|
#pragma warning(pop)
|
||||||
|
|
||||||
|
#include <wrl\client.h>
|
||||||
|
|
||||||
|
#include "scoped.h"
|
||||||
|
|
||||||
|
#define TEX_FILTER_MASK 0xF00000
|
||||||
|
|
||||||
|
#define XBOX_DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT DXGI_FORMAT(116)
|
||||||
|
#define XBOX_DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT DXGI_FORMAT(117)
|
||||||
|
#define XBOX_DXGI_FORMAT_D16_UNORM_S8_UINT DXGI_FORMAT(118)
|
||||||
|
#define XBOX_DXGI_FORMAT_R16_UNORM_X8_TYPELESS DXGI_FORMAT(119)
|
||||||
|
#define XBOX_DXGI_FORMAT_X16_TYPELESS_G8_UINT DXGI_FORMAT(120)
|
||||||
|
|
||||||
|
#define WIN10_DXGI_FORMAT_P208 DXGI_FORMAT(130)
|
||||||
|
#define WIN10_DXGI_FORMAT_V208 DXGI_FORMAT(131)
|
||||||
|
#define WIN10_DXGI_FORMAT_V408 DXGI_FORMAT(132)
|
||||||
|
|
||||||
|
#ifndef XBOX_DXGI_FORMAT_R10G10B10_SNORM_A2_UNORM
|
||||||
|
#define XBOX_DXGI_FORMAT_R10G10B10_SNORM_A2_UNORM DXGI_FORMAT(189)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define XBOX_DXGI_FORMAT_R4G4_UNORM DXGI_FORMAT(190)
|
||||||
|
|
||||||
|
|
||||||
|
namespace DirectX
|
||||||
|
{
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
|
// WIC helper functions
|
||||||
|
DXGI_FORMAT __cdecl _WICToDXGI( _In_ const GUID& guid );
|
||||||
|
bool __cdecl _DXGIToWIC( _In_ DXGI_FORMAT format, _Out_ GUID& guid, _In_ bool ignoreRGBvsBGR = false );
|
||||||
|
|
||||||
|
DWORD __cdecl _CheckWICColorSpace( _In_ const GUID& sourceGUID, _In_ const GUID& targetGUID );
|
||||||
|
|
||||||
|
inline WICBitmapDitherType __cdecl _GetWICDither( _In_ DWORD flags )
|
||||||
|
{
|
||||||
|
static_assert( TEX_FILTER_DITHER == 0x10000, "TEX_FILTER_DITHER* flag values don't match mask" );
|
||||||
|
|
||||||
|
static_assert( TEX_FILTER_DITHER == WIC_FLAGS_DITHER, "TEX_FILTER_DITHER* should match WIC_FLAGS_DITHER*" );
|
||||||
|
static_assert( TEX_FILTER_DITHER_DIFFUSION == WIC_FLAGS_DITHER_DIFFUSION, "TEX_FILTER_DITHER* should match WIC_FLAGS_DITHER*" );
|
||||||
|
|
||||||
|
switch( flags & 0xF0000 )
|
||||||
|
{
|
||||||
|
case TEX_FILTER_DITHER:
|
||||||
|
return WICBitmapDitherTypeOrdered4x4;
|
||||||
|
|
||||||
|
case TEX_FILTER_DITHER_DIFFUSION:
|
||||||
|
return WICBitmapDitherTypeErrorDiffusion;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return WICBitmapDitherTypeNone;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline WICBitmapInterpolationMode __cdecl _GetWICInterp( _In_ DWORD flags )
|
||||||
|
{
|
||||||
|
static_assert( TEX_FILTER_POINT == 0x100000, "TEX_FILTER_ flag values don't match TEX_FILTER_MASK" );
|
||||||
|
|
||||||
|
static_assert( TEX_FILTER_POINT == WIC_FLAGS_FILTER_POINT, "TEX_FILTER_* flags should match WIC_FLAGS_FILTER_*" );
|
||||||
|
static_assert( TEX_FILTER_LINEAR == WIC_FLAGS_FILTER_LINEAR, "TEX_FILTER_* flags should match WIC_FLAGS_FILTER_*" );
|
||||||
|
static_assert( TEX_FILTER_CUBIC == WIC_FLAGS_FILTER_CUBIC, "TEX_FILTER_* flags should match WIC_FLAGS_FILTER_*" );
|
||||||
|
static_assert( TEX_FILTER_FANT == WIC_FLAGS_FILTER_FANT, "TEX_FILTER_* flags should match WIC_FLAGS_FILTER_*" );
|
||||||
|
|
||||||
|
switch( flags & TEX_FILTER_MASK )
|
||||||
|
{
|
||||||
|
case TEX_FILTER_POINT:
|
||||||
|
return WICBitmapInterpolationModeNearestNeighbor;
|
||||||
|
|
||||||
|
case TEX_FILTER_LINEAR:
|
||||||
|
return WICBitmapInterpolationModeLinear;
|
||||||
|
|
||||||
|
case TEX_FILTER_CUBIC:
|
||||||
|
return WICBitmapInterpolationModeCubic;
|
||||||
|
|
||||||
|
case TEX_FILTER_FANT:
|
||||||
|
default:
|
||||||
|
return WICBitmapInterpolationModeFant;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
|
// Image helper functions
|
||||||
|
void __cdecl _DetermineImageArray( _In_ const TexMetadata& metadata, _In_ DWORD cpFlags,
|
||||||
|
_Out_ size_t& nImages, _Out_ size_t& pixelSize );
|
||||||
|
|
||||||
|
_Success_(return != false)
|
||||||
|
bool __cdecl _SetupImageArray( _In_reads_bytes_(pixelSize) uint8_t *pMemory, _In_ size_t pixelSize,
|
||||||
|
_In_ const TexMetadata& metadata, _In_ DWORD cpFlags,
|
||||||
|
_Out_writes_(nImages) Image* images, _In_ size_t nImages );
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
|
// Conversion helper functions
|
||||||
|
|
||||||
|
enum TEXP_SCANLINE_FLAGS
|
||||||
|
{
|
||||||
|
TEXP_SCANLINE_NONE = 0,
|
||||||
|
TEXP_SCANLINE_SETALPHA = 0x1, // Set alpha channel to known opaque value
|
||||||
|
TEXP_SCANLINE_LEGACY = 0x2, // Enables specific legacy format conversion cases
|
||||||
|
};
|
||||||
|
|
||||||
|
enum CONVERT_FLAGS
|
||||||
|
{
|
||||||
|
CONVF_FLOAT = 0x1,
|
||||||
|
CONVF_UNORM = 0x2,
|
||||||
|
CONVF_UINT = 0x4,
|
||||||
|
CONVF_SNORM = 0x8,
|
||||||
|
CONVF_SINT = 0x10,
|
||||||
|
CONVF_DEPTH = 0x20,
|
||||||
|
CONVF_STENCIL = 0x40,
|
||||||
|
CONVF_SHAREDEXP = 0x80,
|
||||||
|
CONVF_BGR = 0x100,
|
||||||
|
CONVF_XR = 0x200,
|
||||||
|
CONVF_PACKED = 0x400,
|
||||||
|
CONVF_BC = 0x800,
|
||||||
|
CONVF_YUV = 0x1000,
|
||||||
|
CONVF_R = 0x10000,
|
||||||
|
CONVF_G = 0x20000,
|
||||||
|
CONVF_B = 0x40000,
|
||||||
|
CONVF_A = 0x80000,
|
||||||
|
CONVF_RGB_MASK = 0x70000,
|
||||||
|
CONVF_RGBA_MASK = 0xF0000,
|
||||||
|
};
|
||||||
|
|
||||||
|
DWORD __cdecl _GetConvertFlags( _In_ DXGI_FORMAT format );
|
||||||
|
|
||||||
|
void __cdecl _CopyScanline( _When_(pDestination == pSource, _Inout_updates_bytes_(outSize))
|
||||||
|
_When_(pDestination != pSource, _Out_writes_bytes_(outSize))
|
||||||
|
LPVOID pDestination, _In_ size_t outSize,
|
||||||
|
_In_reads_bytes_(inSize) LPCVOID pSource, _In_ size_t inSize,
|
||||||
|
_In_ DXGI_FORMAT format, _In_ DWORD flags );
|
||||||
|
|
||||||
|
void __cdecl _SwizzleScanline( _When_(pDestination == pSource, _In_)
|
||||||
|
_When_(pDestination != pSource, _Out_writes_bytes_(outSize))
|
||||||
|
LPVOID pDestination, _In_ size_t outSize,
|
||||||
|
_In_reads_bytes_(inSize) LPCVOID pSource, _In_ size_t inSize,
|
||||||
|
_In_ DXGI_FORMAT format, _In_ DWORD flags );
|
||||||
|
|
||||||
|
_Success_(return != false)
|
||||||
|
bool __cdecl _ExpandScanline( _Out_writes_bytes_(outSize) LPVOID pDestination, _In_ size_t outSize,
|
||||||
|
_In_ DXGI_FORMAT outFormat,
|
||||||
|
_In_reads_bytes_(inSize) LPCVOID pSource, _In_ size_t inSize,
|
||||||
|
_In_ DXGI_FORMAT inFormat, _In_ DWORD flags );
|
||||||
|
|
||||||
|
_Success_(return != false)
|
||||||
|
bool __cdecl _LoadScanline( _Out_writes_(count) XMVECTOR* pDestination, _In_ size_t count,
|
||||||
|
_In_reads_bytes_(size) LPCVOID pSource, _In_ size_t size, _In_ DXGI_FORMAT format );
|
||||||
|
|
||||||
|
_Success_(return != false)
|
||||||
|
bool __cdecl _LoadScanlineLinear( _Out_writes_(count) XMVECTOR* pDestination, _In_ size_t count,
|
||||||
|
_In_reads_bytes_(size) LPCVOID pSource, _In_ size_t size, _In_ DXGI_FORMAT format, _In_ DWORD flags );
|
||||||
|
|
||||||
|
_Success_(return != false)
|
||||||
|
bool __cdecl _StoreScanline( LPVOID pDestination, _In_ size_t size, _In_ DXGI_FORMAT format,
|
||||||
|
_In_reads_(count) const XMVECTOR* pSource, _In_ size_t count, _In_ float threshold = 0 );
|
||||||
|
|
||||||
|
_Success_(return != false)
|
||||||
|
bool __cdecl _StoreScanlineLinear( LPVOID pDestination, _In_ size_t size, _In_ DXGI_FORMAT format,
|
||||||
|
_Inout_updates_all_(count) XMVECTOR* pSource, _In_ size_t count, _In_ DWORD flags, _In_ float threshold = 0 );
|
||||||
|
|
||||||
|
_Success_(return != false)
|
||||||
|
bool __cdecl _StoreScanlineDither( LPVOID pDestination, _In_ size_t size, _In_ DXGI_FORMAT format,
|
||||||
|
_Inout_updates_all_(count) XMVECTOR* pSource, _In_ size_t count, _In_ float threshold, size_t y, size_t z,
|
||||||
|
_Inout_updates_all_opt_(count+2) XMVECTOR* pDiffusionErrors );
|
||||||
|
|
||||||
|
HRESULT __cdecl _ConvertToR32G32B32A32( _In_ const Image& srcImage, _Inout_ ScratchImage& image );
|
||||||
|
|
||||||
|
HRESULT __cdecl _ConvertFromR32G32B32A32( _In_ const Image& srcImage, _In_ const Image& destImage );
|
||||||
|
HRESULT __cdecl _ConvertFromR32G32B32A32( _In_ const Image& srcImage, _In_ DXGI_FORMAT format, _Inout_ ScratchImage& image );
|
||||||
|
HRESULT __cdecl _ConvertFromR32G32B32A32( _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata,
|
||||||
|
_In_ DXGI_FORMAT format, _Out_ ScratchImage& result );
|
||||||
|
|
||||||
|
void __cdecl _ConvertScanline( _Inout_updates_all_(count) XMVECTOR* pBuffer, _In_ size_t count,
|
||||||
|
_In_ DXGI_FORMAT outFormat, _In_ DXGI_FORMAT inFormat, _In_ DWORD flags );
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
|
// DDS helper functions
|
||||||
|
HRESULT __cdecl _EncodeDDSHeader( _In_ const TexMetadata& metadata, DWORD flags,
|
||||||
|
_Out_writes_bytes_to_opt_(maxsize, required) LPVOID pDestination, _In_ size_t maxsize, _Out_ size_t& required );
|
||||||
|
|
||||||
|
}; // namespace
|
1452
Switch_Toolbox/Lib/DirectXTex/DirectXTexUtil.cpp
Normal file
1452
Switch_Toolbox/Lib/DirectXTex/DirectXTexUtil.cpp
Normal file
File diff suppressed because it is too large
Load diff
422
Switch_Toolbox/Lib/DirectXTex/Filters.h
Normal file
422
Switch_Toolbox/Lib/DirectXTex/Filters.h
Normal file
|
@ -0,0 +1,422 @@
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
// filters.h
|
||||||
|
//
|
||||||
|
// Utility header with helpers for implementing image filters
|
||||||
|
//
|
||||||
|
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||||
|
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
||||||
|
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||||
|
// PARTICULAR PURPOSE.
|
||||||
|
//
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <directxmath.h>
|
||||||
|
#include <directxpackedvector.h>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "scoped.h"
|
||||||
|
|
||||||
|
namespace DirectX
|
||||||
|
{
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
// Box filtering helpers
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
XMGLOBALCONST XMVECTORF32 g_boxScale = { 0.25f, 0.25f, 0.25f, 0.25f };
|
||||||
|
XMGLOBALCONST XMVECTORF32 g_boxScale3D = { 0.125f, 0.125f, 0.125f, 0.125f };
|
||||||
|
|
||||||
|
#define AVERAGE4( res, p0, p1, p2, p3 ) \
|
||||||
|
{ \
|
||||||
|
XMVECTOR v = XMVectorAdd( (p0), (p1) ); \
|
||||||
|
v = XMVectorAdd( v, (p2) ); \
|
||||||
|
v = XMVectorAdd( v, (p3) ); \
|
||||||
|
res = XMVectorMultiply( v, g_boxScale ); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define AVERAGE8( res, p0, p1, p2, p3, p4, p5, p6, p7) \
|
||||||
|
{ \
|
||||||
|
XMVECTOR v = XMVectorAdd( (p0), (p1) ); \
|
||||||
|
v = XMVectorAdd( v, (p2) ); \
|
||||||
|
v = XMVectorAdd( v, (p3) ); \
|
||||||
|
v = XMVectorAdd( v, (p4) ); \
|
||||||
|
v = XMVectorAdd( v, (p5) ); \
|
||||||
|
v = XMVectorAdd( v, (p6) ); \
|
||||||
|
v = XMVectorAdd( v, (p7) ); \
|
||||||
|
res = XMVectorMultiply( v, g_boxScale3D ); \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
// Linear filtering helpers
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
struct LinearFilter
|
||||||
|
{
|
||||||
|
size_t u0;
|
||||||
|
float weight0;
|
||||||
|
size_t u1;
|
||||||
|
float weight1;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline void _CreateLinearFilter( _In_ size_t source, _In_ size_t dest, _In_ bool wrap, _Out_writes_(dest) LinearFilter* lf )
|
||||||
|
{
|
||||||
|
assert( source > 0 );
|
||||||
|
assert( dest > 0 );
|
||||||
|
assert( lf != 0 );
|
||||||
|
|
||||||
|
float scale = float(source) / float(dest);
|
||||||
|
|
||||||
|
// Mirror is the same case as clamp for linear
|
||||||
|
|
||||||
|
for( size_t u = 0; u < dest; ++u )
|
||||||
|
{
|
||||||
|
float srcB = ( float(u) + 0.5f ) * scale + 0.5f;
|
||||||
|
|
||||||
|
ptrdiff_t isrcB = ptrdiff_t(srcB);
|
||||||
|
ptrdiff_t isrcA = isrcB - 1;
|
||||||
|
|
||||||
|
if ( isrcA < 0 )
|
||||||
|
{
|
||||||
|
isrcA = ( wrap ) ? ( source - 1) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( size_t(isrcB) >= source )
|
||||||
|
{
|
||||||
|
isrcB = ( wrap ) ? 0 : ( source - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
float weight = 1.0f + float(isrcB) - srcB;
|
||||||
|
|
||||||
|
auto& entry = lf[ u ];
|
||||||
|
entry.u0 = size_t(isrcA);
|
||||||
|
entry.weight0 = weight;
|
||||||
|
|
||||||
|
entry.u1 = size_t(isrcB);
|
||||||
|
entry.weight1 = 1.0f - weight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BILINEAR_INTERPOLATE( res, x, y, r0, r1 ) \
|
||||||
|
res = ( y.weight0 * ( (r0)[ x.u0 ] * x.weight0 + (r0)[ x.u1 ] * x.weight1 ) ) \
|
||||||
|
+ ( y.weight1 * ( (r1)[ x.u0 ] * x.weight0 + (r1)[ x.u1 ] * x.weight1 ) )
|
||||||
|
|
||||||
|
#define TRILINEAR_INTERPOLATE( res, x, y, z, r0, r1, r2, r3 ) \
|
||||||
|
res = ( z.weight0 * ( ( y.weight0 * ( (r0)[ x.u0 ] * x.weight0 + (r0)[ x.u1 ] * x.weight1 ) ) \
|
||||||
|
+ ( y.weight1 * ( (r1)[ x.u0 ] * x.weight0 + (r1)[ x.u1 ] * x.weight1 ) ) ) ) \
|
||||||
|
+ ( z.weight1 * ( ( y.weight0 * ( (r2)[ x.u0 ] * x.weight0 + (r2)[ x.u1 ] * x.weight1 ) ) \
|
||||||
|
+ ( y.weight1 * ( (r3)[ x.u0 ] * x.weight0 + (r3)[ x.u1 ] * x.weight1 ) ) ) )
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
// Cubic filtering helpers
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
XMGLOBALCONST XMVECTORF32 g_cubicThird = { 1.f/3.f, 1.f/3.f, 1.f/3.f, 1.f/3.f };
|
||||||
|
XMGLOBALCONST XMVECTORF32 g_cubicSixth = { 1.f/6.f, 1.f/6.f, 1.f/6.f, 1.f/6.f };
|
||||||
|
XMGLOBALCONST XMVECTORF32 g_cubicHalf = { 1.f/2.f, 1.f/2.f, 1.f/2.f, 1.f/2.f };
|
||||||
|
|
||||||
|
inline ptrdiff_t bounduvw( ptrdiff_t u, ptrdiff_t maxu, bool wrap, bool mirror )
|
||||||
|
{
|
||||||
|
if ( wrap )
|
||||||
|
{
|
||||||
|
if ( u < 0 )
|
||||||
|
{
|
||||||
|
u = maxu + u + 1;
|
||||||
|
}
|
||||||
|
else if ( u > maxu )
|
||||||
|
{
|
||||||
|
u = u - maxu - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( mirror )
|
||||||
|
{
|
||||||
|
if ( u < 0 )
|
||||||
|
{
|
||||||
|
u = ( -u ) - 1;
|
||||||
|
}
|
||||||
|
else if ( u > maxu )
|
||||||
|
{
|
||||||
|
u = maxu - (u - maxu - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handles clamp, but also a safety factor for degenerate images for wrap/mirror
|
||||||
|
u = std::min<ptrdiff_t>( u, maxu );
|
||||||
|
u = std::max<ptrdiff_t>( u, 0 );
|
||||||
|
|
||||||
|
return u;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CubicFilter
|
||||||
|
{
|
||||||
|
size_t u0;
|
||||||
|
size_t u1;
|
||||||
|
size_t u2;
|
||||||
|
size_t u3;
|
||||||
|
float x;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline void _CreateCubicFilter( _In_ size_t source, _In_ size_t dest, _In_ bool wrap, _In_ bool mirror, _Out_writes_(dest) CubicFilter* cf )
|
||||||
|
{
|
||||||
|
assert( source > 0 );
|
||||||
|
assert( dest > 0 );
|
||||||
|
assert( cf != 0 );
|
||||||
|
|
||||||
|
float scale = float(source) / float(dest);
|
||||||
|
|
||||||
|
for( size_t u = 0; u < dest; ++u )
|
||||||
|
{
|
||||||
|
float srcB = ( float(u) + 0.5f ) * scale - 0.5f;
|
||||||
|
|
||||||
|
ptrdiff_t isrcB = bounduvw( ptrdiff_t(srcB), source - 1, wrap, mirror );
|
||||||
|
ptrdiff_t isrcA = bounduvw( isrcB - 1, source - 1, wrap, mirror );
|
||||||
|
ptrdiff_t isrcC = bounduvw( isrcB + 1, source - 1, wrap, mirror );
|
||||||
|
ptrdiff_t isrcD = bounduvw( isrcB + 2, source - 1, wrap, mirror );
|
||||||
|
|
||||||
|
auto& entry = cf[ u ];
|
||||||
|
entry.u0 = size_t(isrcA);
|
||||||
|
entry.u1 = size_t(isrcB);
|
||||||
|
entry.u2 = size_t(isrcC);
|
||||||
|
entry.u3 = size_t(isrcD);
|
||||||
|
|
||||||
|
float x = srcB - float(isrcB);
|
||||||
|
entry.x = x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CUBIC_INTERPOLATE( res, dx, p0, p1, p2, p3 ) \
|
||||||
|
{ \
|
||||||
|
XMVECTOR a0 = (p1); \
|
||||||
|
XMVECTOR d0 = (p0) - a0; \
|
||||||
|
XMVECTOR d2 = (p2) - a0; \
|
||||||
|
XMVECTOR d3 = (p3) - a0; \
|
||||||
|
XMVECTOR a1 = d2 - g_cubicThird*d0 - g_cubicSixth*d3; \
|
||||||
|
XMVECTOR a2 = g_cubicHalf*d0 + g_cubicHalf*d2; \
|
||||||
|
XMVECTOR a3 = g_cubicSixth*d3 - g_cubicSixth*d0 - g_cubicHalf*d2; \
|
||||||
|
XMVECTOR vdx = XMVectorReplicate( dx ); \
|
||||||
|
XMVECTOR vdx2 = vdx * vdx; \
|
||||||
|
XMVECTOR vdx3 = vdx2 * vdx; \
|
||||||
|
res = a0 + a1*vdx + a2*vdx2 + a3*vdx3; \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
// Triangle filtering helpers
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace TriangleFilter
|
||||||
|
{
|
||||||
|
struct FilterTo
|
||||||
|
{
|
||||||
|
size_t u;
|
||||||
|
float weight;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FilterFrom
|
||||||
|
{
|
||||||
|
size_t count;
|
||||||
|
size_t sizeInBytes;
|
||||||
|
FilterTo to[1]; // variable-sized array
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Filter
|
||||||
|
{
|
||||||
|
size_t sizeInBytes;
|
||||||
|
size_t totalSize;
|
||||||
|
FilterFrom from[1]; // variable-sized array
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TriangleRow
|
||||||
|
{
|
||||||
|
size_t remaining;
|
||||||
|
TriangleRow* next;
|
||||||
|
ScopedAlignedArrayXMVECTOR scanline;
|
||||||
|
|
||||||
|
TriangleRow() : remaining(0), next(nullptr) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const size_t TF_FILTER_SIZE = sizeof(Filter) - sizeof(FilterFrom);
|
||||||
|
static const size_t TF_FROM_SIZE = sizeof(FilterFrom) - sizeof(FilterTo);
|
||||||
|
static const size_t TF_TO_SIZE = sizeof(FilterTo);
|
||||||
|
|
||||||
|
static const float TF_EPSILON = 0.00001f;
|
||||||
|
|
||||||
|
inline HRESULT _Create( _In_ size_t source, _In_ size_t dest, _In_ bool wrap, _Inout_ std::unique_ptr<Filter>& tf )
|
||||||
|
{
|
||||||
|
assert( source > 0 );
|
||||||
|
assert( dest > 0 );
|
||||||
|
|
||||||
|
float scale = float(dest) / float(source);
|
||||||
|
float scaleInv = 0.5f / scale;
|
||||||
|
|
||||||
|
// Determine storage required for filter and allocate memory if needed
|
||||||
|
size_t totalSize = TF_FILTER_SIZE + TF_FROM_SIZE + TF_TO_SIZE;
|
||||||
|
float repeat = (wrap) ? 1.f : 0.f;
|
||||||
|
|
||||||
|
for( size_t u = 0; u < source; ++u )
|
||||||
|
{
|
||||||
|
float src = float(u) - 0.5f;
|
||||||
|
float destMin = src * scale;
|
||||||
|
float destMax = destMin + scale;
|
||||||
|
|
||||||
|
totalSize += TF_FROM_SIZE + TF_TO_SIZE + size_t( destMax - destMin + repeat + 1.f ) * TF_TO_SIZE * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t* pFilter = nullptr;
|
||||||
|
|
||||||
|
if ( tf )
|
||||||
|
{
|
||||||
|
// See if existing filter memory block is large enough to reuse
|
||||||
|
if ( tf->totalSize >= totalSize )
|
||||||
|
{
|
||||||
|
pFilter = reinterpret_cast<uint8_t*>( tf.get() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Need to reallocate filter memory block
|
||||||
|
tf.reset( nullptr );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !tf )
|
||||||
|
{
|
||||||
|
// Allocate filter memory block
|
||||||
|
pFilter = new (std::nothrow) uint8_t[ totalSize ];
|
||||||
|
if ( !pFilter )
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
tf.reset( reinterpret_cast<Filter*>( pFilter ) );
|
||||||
|
tf->totalSize = totalSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert( pFilter != 0 );
|
||||||
|
|
||||||
|
// Filter setup
|
||||||
|
size_t sizeInBytes = TF_FILTER_SIZE;
|
||||||
|
size_t accumU = 0;
|
||||||
|
float accumWeight = 0.f;
|
||||||
|
|
||||||
|
for( size_t u = 0; u < source; ++u )
|
||||||
|
{
|
||||||
|
// Setup from entry
|
||||||
|
size_t sizeFrom = sizeInBytes;
|
||||||
|
auto pFrom = reinterpret_cast<FilterFrom*>( pFilter + sizeInBytes );
|
||||||
|
sizeInBytes += TF_FROM_SIZE;
|
||||||
|
|
||||||
|
if ( sizeInBytes > totalSize )
|
||||||
|
return E_FAIL;
|
||||||
|
|
||||||
|
size_t toCount = 0;
|
||||||
|
|
||||||
|
// Perform two passes to capture the influences from both sides
|
||||||
|
for( size_t j = 0; j < 2; ++j )
|
||||||
|
{
|
||||||
|
float src = float( u + j ) - 0.5f;
|
||||||
|
|
||||||
|
float destMin = src * scale;
|
||||||
|
float destMax = destMin + scale;
|
||||||
|
|
||||||
|
if ( !wrap )
|
||||||
|
{
|
||||||
|
// Clamp
|
||||||
|
if ( destMin < 0.f )
|
||||||
|
destMin = 0.f;
|
||||||
|
if ( destMax > float(dest) )
|
||||||
|
destMax = float(dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
for( auto k = static_cast<ptrdiff_t>( floorf( destMin ) ); float(k) < destMax; ++k )
|
||||||
|
{
|
||||||
|
float d0 = float(k);
|
||||||
|
float d1 = d0 + 1.f;
|
||||||
|
|
||||||
|
size_t u0;
|
||||||
|
if ( k < 0 )
|
||||||
|
{
|
||||||
|
// Handle wrap
|
||||||
|
u0 = size_t( k + ptrdiff_t(dest) );
|
||||||
|
}
|
||||||
|
else if ( k >= ptrdiff_t(dest) )
|
||||||
|
{
|
||||||
|
// Handle wrap
|
||||||
|
u0 = size_t( k - ptrdiff_t(dest) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
u0 = size_t( k );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save previous accumulated weight (if any)
|
||||||
|
if ( u0 != accumU )
|
||||||
|
{
|
||||||
|
if ( accumWeight > TF_EPSILON )
|
||||||
|
{
|
||||||
|
auto pTo = reinterpret_cast<FilterTo*>( pFilter + sizeInBytes );
|
||||||
|
sizeInBytes += TF_TO_SIZE;
|
||||||
|
++toCount;
|
||||||
|
|
||||||
|
if ( sizeInBytes > totalSize )
|
||||||
|
return E_FAIL;
|
||||||
|
|
||||||
|
pTo->u = accumU;
|
||||||
|
pTo->weight = accumWeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
accumWeight = 0.f;
|
||||||
|
accumU = u0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clip destination
|
||||||
|
if ( d0 < destMin )
|
||||||
|
d0 = destMin;
|
||||||
|
if ( d1 > destMax )
|
||||||
|
d1 = destMax;
|
||||||
|
|
||||||
|
// Calculate average weight over destination pixel
|
||||||
|
|
||||||
|
float weight;
|
||||||
|
if ( !wrap && src < 0.f )
|
||||||
|
weight = 1.f;
|
||||||
|
else if ( !wrap && ( ( src + 1.f ) >= float(source) ) )
|
||||||
|
weight = 0.f;
|
||||||
|
else
|
||||||
|
weight = (d0 + d1) * scaleInv - src;
|
||||||
|
|
||||||
|
accumWeight += (d1 - d0) * ( j ? (1.f - weight) : weight );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store accumulated weight
|
||||||
|
if ( accumWeight > TF_EPSILON )
|
||||||
|
{
|
||||||
|
auto pTo = reinterpret_cast<FilterTo*>( pFilter + sizeInBytes );
|
||||||
|
sizeInBytes += TF_TO_SIZE;
|
||||||
|
++toCount;
|
||||||
|
|
||||||
|
if ( sizeInBytes > totalSize )
|
||||||
|
return E_FAIL;
|
||||||
|
|
||||||
|
pTo->u = accumU;
|
||||||
|
pTo->weight = accumWeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
accumWeight = 0.f;
|
||||||
|
|
||||||
|
// Finalize from entry
|
||||||
|
pFrom->count = toCount;
|
||||||
|
pFrom->sizeInBytes = sizeInBytes - sizeFrom;
|
||||||
|
}
|
||||||
|
|
||||||
|
tf->sizeInBytes = sizeInBytes;
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
}; // namespace
|
||||||
|
|
||||||
|
}; // namespace
|
32
Switch_Toolbox/Lib/DirectXTex/scoped.h
Normal file
32
Switch_Toolbox/Lib/DirectXTex/scoped.h
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
// scoped.h
|
||||||
|
//
|
||||||
|
// Utility header with helper classes for exception-safe handling of resources
|
||||||
|
//
|
||||||
|
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||||
|
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
||||||
|
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||||
|
// PARTICULAR PURPOSE.
|
||||||
|
//
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <memory>
|
||||||
|
#include <malloc.h>
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
|
struct aligned_deleter { void operator()(void* p) { _aligned_free(p); } };
|
||||||
|
|
||||||
|
typedef std::unique_ptr<float[], aligned_deleter> ScopedAlignedArrayFloat;
|
||||||
|
|
||||||
|
typedef std::unique_ptr<DirectX::XMVECTOR[], aligned_deleter> ScopedAlignedArrayXMVECTOR;
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
|
struct handle_closer { void operator()(HANDLE h) { assert(h != INVALID_HANDLE_VALUE); if (h) CloseHandle(h); } };
|
||||||
|
|
||||||
|
typedef public std::unique_ptr<void, handle_closer> ScopedHandle;
|
||||||
|
|
||||||
|
inline HANDLE safe_handle( HANDLE h ) { return (h == INVALID_HANDLE_VALUE) ? 0 : h; }
|
274
Switch_Toolbox/Lib/DirectXTex/wrapper.cpp
Normal file
274
Switch_Toolbox/Lib/DirectXTex/wrapper.cpp
Normal file
|
@ -0,0 +1,274 @@
|
||||||
|
/*
|
||||||
|
Copyright(c) 2015 Neodymium
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma managed
|
||||||
|
|
||||||
|
#include <vcclr.h>
|
||||||
|
#include "DirectXTex.h"
|
||||||
|
|
||||||
|
using namespace System;
|
||||||
|
using namespace System::IO;
|
||||||
|
using namespace System::Runtime::InteropServices;
|
||||||
|
|
||||||
|
namespace DirectXTex
|
||||||
|
{
|
||||||
|
public ref class ImageCompressor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
static array<Byte>^ Decompress(array<Byte>^ data, int width, int height, int format)
|
||||||
|
{
|
||||||
|
size_t rowPitch;
|
||||||
|
size_t slicePitch;
|
||||||
|
DirectX::ComputePitch((DXGI_FORMAT)format, width, height, rowPitch, slicePitch);
|
||||||
|
|
||||||
|
if (data->Length == slicePitch)
|
||||||
|
{
|
||||||
|
uint8_t *buf = new uint8_t[slicePitch];
|
||||||
|
Marshal::Copy(data, 0, (IntPtr)buf, slicePitch);
|
||||||
|
|
||||||
|
DirectX::Image inputImage;
|
||||||
|
inputImage.width = width;
|
||||||
|
inputImage.height = height;
|
||||||
|
inputImage.format = (DXGI_FORMAT)format;
|
||||||
|
inputImage.pixels = buf;
|
||||||
|
inputImage.rowPitch = rowPitch;
|
||||||
|
inputImage.slicePitch = slicePitch;
|
||||||
|
|
||||||
|
DirectX::ScratchImage outputImage;
|
||||||
|
|
||||||
|
// decompress image
|
||||||
|
DirectX::Decompress(inputImage, DXGI_FORMAT_R8G8B8A8_UNORM, outputImage);
|
||||||
|
|
||||||
|
array<Byte>^ result = gcnew array<Byte>(4 * width * height);
|
||||||
|
Marshal::Copy((IntPtr)outputImage.GetPixels(), result, 0, 4 * width * height);
|
||||||
|
|
||||||
|
delete[] buf;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw gcnew Exception("Compressed image should be " + slicePitch.ToString() + " bytes");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static array<Byte>^ Compress(array<Byte>^ data, int width, int height, int format)
|
||||||
|
{
|
||||||
|
size_t rowPitch = width * 4;
|
||||||
|
size_t slicePitch = width * height * 4;
|
||||||
|
if (data->Length == slicePitch)
|
||||||
|
{
|
||||||
|
uint8_t *buf = new uint8_t[slicePitch];
|
||||||
|
Marshal::Copy(data, 0, (IntPtr)buf, slicePitch);
|
||||||
|
|
||||||
|
DirectX::Image inputImage;
|
||||||
|
inputImage.width = width;
|
||||||
|
inputImage.height = height;
|
||||||
|
inputImage.format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
inputImage.pixels = buf;
|
||||||
|
inputImage.rowPitch = rowPitch;
|
||||||
|
inputImage.slicePitch = slicePitch;
|
||||||
|
|
||||||
|
DirectX::ScratchImage outputImage;
|
||||||
|
|
||||||
|
// compress image
|
||||||
|
DirectX::Compress(inputImage, (DXGI_FORMAT)format, 0, 1, outputImage);
|
||||||
|
|
||||||
|
size_t rowPitchOut;
|
||||||
|
size_t slicePitchOut;
|
||||||
|
DirectX::ComputePitch((DXGI_FORMAT)format, width, height, rowPitchOut, slicePitchOut);
|
||||||
|
array<Byte>^ result = gcnew array<Byte>(slicePitchOut);
|
||||||
|
Marshal::Copy((IntPtr)outputImage.GetPixels(), result, 0, slicePitchOut);
|
||||||
|
|
||||||
|
delete[] buf;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw gcnew Exception("Uncompressed image should be " + slicePitch.ToString() + " bytes");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public ref class ImageConverter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
static array<Byte>^ Convert(array<Byte>^ data, int width, int height, int inputFormat, int outputFormat)
|
||||||
|
{
|
||||||
|
size_t inputRowPitch;
|
||||||
|
size_t inrputSlicePitch;
|
||||||
|
DirectX::ComputePitch((DXGI_FORMAT)inputFormat, width, height, inputRowPitch, inrputSlicePitch);
|
||||||
|
|
||||||
|
if (data->Length == inrputSlicePitch)
|
||||||
|
{
|
||||||
|
uint8_t *buf = new uint8_t[inrputSlicePitch];
|
||||||
|
Marshal::Copy(data, 0, (IntPtr)buf, inrputSlicePitch);
|
||||||
|
|
||||||
|
DirectX::Image inputImage;
|
||||||
|
inputImage.width = width;
|
||||||
|
inputImage.height = height;
|
||||||
|
inputImage.format = (DXGI_FORMAT)inputFormat;
|
||||||
|
inputImage.pixels = buf;
|
||||||
|
inputImage.rowPitch = inputRowPitch;
|
||||||
|
inputImage.slicePitch = inrputSlicePitch;
|
||||||
|
|
||||||
|
DirectX::ScratchImage outputImage;
|
||||||
|
|
||||||
|
// convert image
|
||||||
|
DirectX::Convert(inputImage, (DXGI_FORMAT)outputFormat, 0, 0, outputImage);
|
||||||
|
|
||||||
|
size_t outputRowPitch;
|
||||||
|
size_t outputSlicePitch;
|
||||||
|
DirectX::ComputePitch((DXGI_FORMAT)outputFormat, width, height, outputRowPitch, outputSlicePitch);
|
||||||
|
array<Byte>^ result = gcnew array<Byte>(outputSlicePitch);
|
||||||
|
Marshal::Copy((IntPtr)outputImage.GetPixels(), result, 0, outputSlicePitch);
|
||||||
|
|
||||||
|
delete[] buf;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw gcnew Exception("Input image should be " + inrputSlicePitch.ToString() + " bytes");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public ref class ImageStruct
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
property int Width;
|
||||||
|
property int Height;
|
||||||
|
//property int Stride;
|
||||||
|
property int Format;
|
||||||
|
property int MipMapLevels;
|
||||||
|
property array<Byte>^ Data;
|
||||||
|
|
||||||
|
int GetRowPitch()
|
||||||
|
{
|
||||||
|
size_t rowPitch;
|
||||||
|
size_t slicePitch;
|
||||||
|
DirectX::ComputePitch((DXGI_FORMAT)Format, Width, Height, rowPitch, slicePitch);
|
||||||
|
return rowPitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetSlicePitch()
|
||||||
|
{
|
||||||
|
size_t rowPitch;
|
||||||
|
size_t slicePitch;
|
||||||
|
DirectX::ComputePitch((DXGI_FORMAT)Format, Width, Height, rowPitch, slicePitch);
|
||||||
|
return slicePitch;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public ref class DDSIO
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
public:
|
||||||
|
|
||||||
|
static ImageStruct^ ReadDDS(String^ fileName)
|
||||||
|
{
|
||||||
|
DirectX::TexMetadata meta;
|
||||||
|
DirectX::ScratchImage im;
|
||||||
|
|
||||||
|
pin_ptr<const wchar_t> wname = PtrToStringChars(fileName);
|
||||||
|
|
||||||
|
// load dds
|
||||||
|
HRESULT x = DirectX::LoadFromDDSFile(wname, 0, &meta, im);
|
||||||
|
|
||||||
|
ImageStruct^ result = gcnew ImageStruct();
|
||||||
|
|
||||||
|
result->MipMapLevels = im.GetImageCount();
|
||||||
|
result->Width = im.GetImage(0, 0, 0)->width;
|
||||||
|
result->Height = im.GetImage(0, 0, 0)->height;
|
||||||
|
// result->Stride = im.GetImage(0, 0, 0)->rowPitch;
|
||||||
|
result->Format = im.GetImage(0, 0, 0)->format;
|
||||||
|
result->Data = gcnew array<Byte>(im.GetPixelsSize());
|
||||||
|
Marshal::Copy((IntPtr)im.GetPixels(), result->Data, 0, im.GetPixelsSize());
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//static ImageStruct^ ReadDDS(Stream^ stream)
|
||||||
|
//{
|
||||||
|
// DirectX::TexMetadata meta;
|
||||||
|
// DirectX::ScratchImage im;
|
||||||
|
|
||||||
|
// //pin_ptr<const wchar_t> wname = PtrToStringChars(fileName);
|
||||||
|
// HRESULT x = DirectX:::LoadFromDDSMemory(
|
||||||
|
|
||||||
|
// ImageStruct^ result = gcnew ImageStruct();
|
||||||
|
|
||||||
|
// result->mipMapLevels = im.GetImageCount();
|
||||||
|
// result->width = im.GetImage(0, 0, 0)->width;
|
||||||
|
// result->height = im.GetImage(0, 0, 0)->height;
|
||||||
|
// result->stride = im.GetImage(0, 0, 0)->rowPitch;
|
||||||
|
// result->format = im.GetImage(0, 0, 0)->format;
|
||||||
|
// result->data = gcnew array<Byte>(im.GetPixelsSize());
|
||||||
|
// Marshal::Copy((IntPtr)im.GetPixels(), result->data, 0, im.GetPixelsSize());
|
||||||
|
|
||||||
|
// return result;
|
||||||
|
//}
|
||||||
|
|
||||||
|
static void WriteDDS(String^ fileName, ImageStruct^ image)
|
||||||
|
{
|
||||||
|
uint8_t *buf = new uint8_t[image->Data->Length];
|
||||||
|
Marshal::Copy(image->Data, 0, (IntPtr)buf, image->Data->Length);
|
||||||
|
|
||||||
|
DirectX::TexMetadata meta;
|
||||||
|
meta.width = image->Width;
|
||||||
|
meta.height = image->Height;
|
||||||
|
meta.depth = 1;
|
||||||
|
meta.arraySize = 1; // ???
|
||||||
|
meta.mipLevels = image->MipMapLevels;
|
||||||
|
meta.miscFlags = 0; // ???
|
||||||
|
meta.miscFlags2 = 0; // ???
|
||||||
|
meta.format = (DXGI_FORMAT)image->Format;
|
||||||
|
meta.dimension = DirectX::TEX_DIMENSION_TEXTURE2D;
|
||||||
|
|
||||||
|
DirectX::Image *images = new DirectX::Image[image->MipMapLevels];
|
||||||
|
|
||||||
|
int div = 1;
|
||||||
|
int add = 0;
|
||||||
|
for (int i = 0; i < image->MipMapLevels; i++)
|
||||||
|
{
|
||||||
|
images[i].width = image->Width / div;
|
||||||
|
images[i].height = image->Height / div;
|
||||||
|
images[i].format = (DXGI_FORMAT)image->Format;
|
||||||
|
images[i].pixels = buf + add;
|
||||||
|
|
||||||
|
DirectX::ComputePitch(images[i].format, images[i].width, images[i].height, images[i].rowPitch, images[i].slicePitch, 0);
|
||||||
|
|
||||||
|
add += images[i].slicePitch;
|
||||||
|
div *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
pin_ptr<const wchar_t> wname = PtrToStringChars(fileName);
|
||||||
|
|
||||||
|
// save dds
|
||||||
|
DirectX::SaveToDDSFile(images, image->MipMapLevels, meta, 0, wname);
|
||||||
|
|
||||||
|
delete[] images;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
Binary file not shown.
BIN
Switch_Toolbox/Lib/Syroot.NintenTools.NSW.Bntx.pdb
Normal file
BIN
Switch_Toolbox/Lib/Syroot.NintenTools.NSW.Bntx.pdb
Normal file
Binary file not shown.
2141
Switch_Toolbox/Lib/Syroot.NintenTools.NSW.Bntx.xml
Normal file
2141
Switch_Toolbox/Lib/Syroot.NintenTools.NSW.Bntx.xml
Normal file
File diff suppressed because it is too large
Load diff
|
@ -240,6 +240,7 @@ namespace Switch_Toolbox
|
||||||
public void OpenFile(string FileName, byte[] data = null, bool Compressed = false,
|
public void OpenFile(string FileName, byte[] data = null, bool Compressed = false,
|
||||||
CompressionType CompType = CompressionType.None)
|
CompressionType CompType = CompressionType.None)
|
||||||
{
|
{
|
||||||
|
Reload();
|
||||||
if (data == null)
|
if (data == null)
|
||||||
data = File.ReadAllBytes(FileName);
|
data = File.ReadAllBytes(FileName);
|
||||||
|
|
||||||
|
@ -278,8 +279,6 @@ namespace Switch_Toolbox
|
||||||
|
|
||||||
foreach (IFileFormat format in SupportedFormats)
|
foreach (IFileFormat format in SupportedFormats)
|
||||||
{
|
{
|
||||||
Console.WriteLine(format.Magic.Reverse());
|
|
||||||
Console.WriteLine(Magic2);
|
|
||||||
|
|
||||||
if (format.Magic == Magic || format.Magic == Magic2 || format.Magic.Reverse() == Magic2)
|
if (format.Magic == Magic || format.Magic == Magic2 || format.Magic.Reverse() == Magic2)
|
||||||
{
|
{
|
||||||
|
|
|
@ -388,9 +388,6 @@
|
||||||
<Content Include="Lib\Licenses\ZSTD NET COPYRIGHT.txt">
|
<Content Include="Lib\Licenses\ZSTD NET COPYRIGHT.txt">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Include="LZ4.dll">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Projects\Recent\DUMMY.txt" />
|
<Content Include="Projects\Recent\DUMMY.txt" />
|
||||||
<None Include="Resources\Logo.png" />
|
<None Include="Resources\Logo.png" />
|
||||||
<Content Include="Tool.ico" />
|
<Content Include="Tool.ico" />
|
||||||
|
|
|
@ -43,6 +43,7 @@ namespace Switch_Toolbox.Library
|
||||||
CONSTANT,
|
CONSTANT,
|
||||||
HERMITE,
|
HERMITE,
|
||||||
STEP,
|
STEP,
|
||||||
|
STEPBOOL,
|
||||||
};
|
};
|
||||||
|
|
||||||
public class KeyNode : TreeNode
|
public class KeyNode : TreeNode
|
||||||
|
@ -298,6 +299,7 @@ namespace Switch_Toolbox.Library
|
||||||
if (Frame == 0 && !isChild)
|
if (Frame == 0 && !isChild)
|
||||||
skeleton.reset();
|
skeleton.reset();
|
||||||
|
|
||||||
|
|
||||||
foreach (object child in Children)
|
foreach (object child in Children)
|
||||||
{
|
{
|
||||||
if (child is Animation)
|
if (child is Animation)
|
||||||
|
|
|
@ -8,7 +8,7 @@ using OpenTK;
|
||||||
|
|
||||||
namespace Switch_Toolbox.Library
|
namespace Switch_Toolbox.Library
|
||||||
{
|
{
|
||||||
public class AnimationGroupNode : TreeNode
|
public class AnimationGroupNode : TreeNodeCustom
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ 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.Triangulate | PostProcessSteps.JoinIdenticalVertices
|
||||||
| PostProcessSteps.FlipUVs | PostProcessSteps.ValidateDataStructure |
|
| PostProcessSteps.FlipUVs | PostProcessSteps.LimitBoneWeights |
|
||||||
PostProcessSteps.CalculateTangentSpace | PostProcessSteps.GenerateNormals);
|
PostProcessSteps.CalculateTangentSpace | PostProcessSteps.GenerateNormals);
|
||||||
LoadMeshes();
|
LoadMeshes();
|
||||||
}
|
}
|
||||||
|
@ -55,23 +55,17 @@ namespace Switch_Toolbox.Library
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private void BuildNode(Node node, ref Matrix4x4 rootTransform)
|
private void BuildNode(Node parent, ref Matrix4x4 rootTransform)
|
||||||
{
|
{
|
||||||
Matrix4x4 trafo = node.Transform;
|
Matrix4x4 trafo = parent.Transform;
|
||||||
Matrix4x4 world = trafo * rootTransform;
|
Matrix4x4 world = trafo * rootTransform;
|
||||||
Matrix4 worldTK = TKMatrix(world);
|
Matrix4 worldTK = AssimpHelper.TKMatrix(world);
|
||||||
|
|
||||||
if (node.HasMeshes)
|
foreach (int index in parent.MeshIndices)
|
||||||
{
|
|
||||||
foreach (int index in node.MeshIndices)
|
|
||||||
{
|
|
||||||
objects.Add(CreateGenericObject(scene.Meshes[index], index, worldTK));
|
objects.Add(CreateGenericObject(scene.Meshes[index], index, worldTK));
|
||||||
}
|
|
||||||
}
|
foreach (Node child in parent.Children)
|
||||||
for (int i = 0; i < node.ChildCount; i++)
|
BuildNode(child, ref rootTransform);
|
||||||
{
|
|
||||||
BuildNode(node.Children[i], ref world);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
public void LoadMeshes()
|
public void LoadMeshes()
|
||||||
{
|
{
|
||||||
|
@ -81,15 +75,42 @@ namespace Switch_Toolbox.Library
|
||||||
{
|
{
|
||||||
foreach (Material mat in scene.Materials)
|
foreach (Material mat in scene.Materials)
|
||||||
{
|
{
|
||||||
Console.WriteLine(mat.Name + " TEST");
|
|
||||||
materials.Add(CreateGenericMaterial(mat));
|
materials.Add(CreateGenericMaterial(mat));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
foreach (Assimp.Animation animation in scene.Animations)
|
||||||
void CopyNodesWithMeshes()
|
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
public Animation CreateGenericAnimation(Assimp.Animation animation)
|
||||||
|
{
|
||||||
|
Animation STanim = new Animation();
|
||||||
|
STanim.Text = animation.Name;
|
||||||
|
STanim.FrameCount = (int)animation.DurationInTicks;
|
||||||
|
|
||||||
|
//Load node animations
|
||||||
|
if (animation.HasNodeAnimations)
|
||||||
|
{
|
||||||
|
var _channels = new NodeAnimationChannel[animation.NodeAnimationChannelCount];
|
||||||
|
for (int i = 0; i < _channels.Length; i++)
|
||||||
|
{
|
||||||
|
_channels[i] = new NodeAnimationChannel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Load mesh animations
|
||||||
|
if (animation.HasMeshAnimations)
|
||||||
|
{
|
||||||
|
var _meshChannels = new MeshAnimationChannel[animation.MeshAnimationChannelCount];
|
||||||
|
for (int i = 0; i < _meshChannels.Length; i++)
|
||||||
|
{
|
||||||
|
_meshChannels[i] = new MeshAnimationChannel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return STanim;
|
||||||
|
}
|
||||||
public STGenericMaterial CreateGenericMaterial(Material material)
|
public STGenericMaterial CreateGenericMaterial(Material material)
|
||||||
{
|
{
|
||||||
STGenericMaterial mat = new STGenericMaterial();
|
STGenericMaterial mat = new STGenericMaterial();
|
||||||
|
@ -459,13 +480,6 @@ namespace Switch_Toolbox.Library
|
||||||
vert.col = new Vector4(msh.VertexColorChannels[0][v].R, msh.VertexColorChannels[0][v].G, msh.VertexColorChannels[0][v].B, msh.VertexColorChannels[0][v].A);
|
vert.col = new Vector4(msh.VertexColorChannels[0][v].R, msh.VertexColorChannels[0][v].G, msh.VertexColorChannels[0][v].B, msh.VertexColorChannels[0][v].A);
|
||||||
if (msh.HasTangentBasis)
|
if (msh.HasTangentBasis)
|
||||||
vert.bitan = new Vector4(msh.BiTangents[v].X, msh.BiTangents[v].Y, msh.BiTangents[v].Z, 1);
|
vert.bitan = new Vector4(msh.BiTangents[v].X, msh.BiTangents[v].Y, msh.BiTangents[v].Z, 1);
|
||||||
if (msh.HasBones)
|
|
||||||
{
|
|
||||||
foreach (Bone bn in msh.Bones)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
vertices.Add(vert);
|
vertices.Add(vert);
|
||||||
}
|
}
|
||||||
if (msh.HasBones)
|
if (msh.HasBones)
|
||||||
|
@ -473,19 +487,12 @@ namespace Switch_Toolbox.Library
|
||||||
for (int i = 0; i < msh.BoneCount; i++)
|
for (int i = 0; i < msh.BoneCount; i++)
|
||||||
{
|
{
|
||||||
Bone bn = msh.Bones[i];
|
Bone bn = msh.Bones[i];
|
||||||
|
|
||||||
Console.WriteLine($"Bone Info {bn.VertexWeightCount} {bn.Name}");
|
|
||||||
|
|
||||||
Vertex.Bone bone = new Vertex.Bone();
|
|
||||||
bone.Name = bn.Name;
|
|
||||||
bone.HasWeights = bn.HasVertexWeights;
|
|
||||||
|
|
||||||
if (bn.HasVertexWeights)
|
if (bn.HasVertexWeights)
|
||||||
{
|
{
|
||||||
foreach (VertexWeight w in bn.VertexWeights)
|
foreach (VertexWeight w in bn.VertexWeights)
|
||||||
{
|
{
|
||||||
vertices[w.VertexID].pos = Vector3.TransformPosition(vertices[w.VertexID].pos, FromMatrix( bn.OffsetMatrix));
|
// vertices[w.VertexID].pos = Vector3.TransformPosition(vertices[w.VertexID].pos, AssimpHelper.TKMatrix(bn.OffsetMatrix));
|
||||||
vertices[w.VertexID].weights.Add(w.Weight);
|
vertices[w.VertexID].boneWeights.Add(w.Weight);
|
||||||
vertices[w.VertexID].boneNames.Add(bn.Name);
|
vertices[w.VertexID].boneNames.Add(bn.Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -503,13 +510,6 @@ namespace Switch_Toolbox.Library
|
||||||
v.Z = vec.Z;
|
v.Z = vec.Z;
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
public static OpenTK.Matrix4 TKMatrix(Assimp.Matrix4x4 input)
|
|
||||||
{
|
|
||||||
return new OpenTK.Matrix4(input.A1, input.B1, input.C1, input.D1,
|
|
||||||
input.A2, input.B2, input.C2, input.D2,
|
|
||||||
input.A3, input.B3, input.C3, input.D3,
|
|
||||||
input.A4, input.B4, input.C4, input.D4);
|
|
||||||
}
|
|
||||||
public static OpenTK.Matrix4 TKMatrix2(Assimp.Matrix4x4 matOut)
|
public static OpenTK.Matrix4 TKMatrix2(Assimp.Matrix4x4 matOut)
|
||||||
{
|
{
|
||||||
var matIn = new OpenTK.Matrix4();
|
var matIn = new OpenTK.Matrix4();
|
||||||
|
@ -550,78 +550,11 @@ namespace Switch_Toolbox.Library
|
||||||
Console.WriteLine($"rotQ " + rot);
|
Console.WriteLine($"rotQ " + rot);
|
||||||
|
|
||||||
Matrix4 positionMat = Matrix4.CreateTranslation(FromVector(tranlation));
|
Matrix4 positionMat = Matrix4.CreateTranslation(FromVector(tranlation));
|
||||||
Matrix4 rotQ = Matrix4.CreateFromQuaternion(TKQuaternion(rot));
|
Matrix4 rotQ = Matrix4.CreateFromQuaternion(AssimpHelper.TKQuaternion(rot));
|
||||||
Matrix4 scaleMat = Matrix4.CreateScale(FromVector(scaling));
|
Matrix4 scaleMat = Matrix4.CreateScale(FromVector(scaling));
|
||||||
Matrix4 matrixFinal = scaleMat * rotQ * positionMat;
|
Matrix4 matrixFinal = scaleMat * rotQ * positionMat;
|
||||||
|
|
||||||
return matrixFinal;
|
return matrixFinal;
|
||||||
}
|
}
|
||||||
private OpenTK.Quaternion TKQuaternion(Assimp.Quaternion rot)
|
|
||||||
{
|
|
||||||
OpenTK.Quaternion quat = new OpenTK.Quaternion();
|
|
||||||
quat.X = rot.X;
|
|
||||||
quat.Y = rot.Y;
|
|
||||||
quat.Z = rot.Z;
|
|
||||||
quat.W = rot.W;
|
|
||||||
return quat;
|
|
||||||
}
|
|
||||||
private Matrix4 FromMatrix(Matrix4x4 mat)
|
|
||||||
{
|
|
||||||
Matrix4 m = new Matrix4();
|
|
||||||
m.M11 = mat.A1;
|
|
||||||
m.M12 = mat.A2;
|
|
||||||
m.M13 = mat.A3;
|
|
||||||
m.M14 = mat.A4;
|
|
||||||
m.M21 = mat.B1;
|
|
||||||
m.M22 = mat.B2;
|
|
||||||
m.M23 = mat.B3;
|
|
||||||
m.M24 = mat.B4;
|
|
||||||
m.M31 = mat.C1;
|
|
||||||
m.M32 = mat.C2;
|
|
||||||
m.M33 = mat.C3;
|
|
||||||
m.M34 = mat.C4;
|
|
||||||
m.M41 = mat.D1;
|
|
||||||
m.M42 = mat.D2;
|
|
||||||
m.M43 = mat.D3;
|
|
||||||
m.M44 = mat.D4;
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Vector3 ToEulerAngles(Assimp.Quaternion q)
|
|
||||||
{
|
|
||||||
float PI = (float)Math.PI;
|
|
||||||
// Store the Euler angles in radians
|
|
||||||
Vector3 pitchYawRoll = new Vector3();
|
|
||||||
|
|
||||||
double sqw = q.W * q.W;
|
|
||||||
double sqx = q.X * q.X;
|
|
||||||
double sqy = q.Y * q.Y;
|
|
||||||
double sqz = q.Z * q.Z;
|
|
||||||
|
|
||||||
// If quaternion is normalised the unit is one, otherwise it is the correction factor
|
|
||||||
double unit = sqx + sqy + sqz + sqw;
|
|
||||||
double test = q.X * q.Y + q.Z * q.W;
|
|
||||||
|
|
||||||
if (test > 0.499f * unit)
|
|
||||||
{
|
|
||||||
// Singularity at north pole
|
|
||||||
pitchYawRoll.Y = 2f * (float)Math.Atan2(q.X, q.W); // Yaw
|
|
||||||
pitchYawRoll.X = PI * 0.5f; // Pitch
|
|
||||||
pitchYawRoll.Z = 0f; // Roll
|
|
||||||
return pitchYawRoll;
|
|
||||||
}
|
|
||||||
else if (test < -0.499f * unit)
|
|
||||||
{
|
|
||||||
// Singularity at south pole
|
|
||||||
pitchYawRoll.Y = -2f * (float)Math.Atan2(q.X, q.W); // Yaw
|
|
||||||
pitchYawRoll.X = -PI * 0.5f; // Pitch
|
|
||||||
pitchYawRoll.Z = 0f; // Roll
|
|
||||||
return pitchYawRoll;
|
|
||||||
}
|
|
||||||
pitchYawRoll.Y = (float)Math.Atan2(2 * q.Y * q.W - 2 * q.X * q.Z, sqx - sqy - sqz + sqw); // Yaw
|
|
||||||
pitchYawRoll.X = (float)Math.Asin(2 * test / unit); // Pitch
|
|
||||||
pitchYawRoll.Z = (float)Math.Atan2(2 * q.X * q.W - 2 * q.Y * q.Z, -sqx + sqy - sqz + sqw); // Roll
|
|
||||||
return pitchYawRoll;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,64 @@ using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Assimp;
|
using Assimp;
|
||||||
|
using OpenTK;
|
||||||
|
|
||||||
namespace Switch_Toolbox.Library
|
namespace Switch_Toolbox.Library
|
||||||
{
|
{
|
||||||
public class AssimpHelper
|
public class AssimpHelper
|
||||||
{
|
{
|
||||||
|
public static OpenTK.Matrix4 TKMatrix(Assimp.Matrix4x4 input)
|
||||||
|
{
|
||||||
|
return new OpenTK.Matrix4(input.A1, input.B1, input.C1, input.D1,
|
||||||
|
input.A2, input.B2, input.C2, input.D2,
|
||||||
|
input.A3, input.B3, input.C3, input.D3,
|
||||||
|
input.A4, input.B4, input.C4, input.D4);
|
||||||
|
}
|
||||||
|
public static OpenTK.Quaternion TKQuaternion(Assimp.Quaternion rot)
|
||||||
|
{
|
||||||
|
OpenTK.Quaternion quat = new OpenTK.Quaternion();
|
||||||
|
quat.X = rot.X;
|
||||||
|
quat.Y = rot.Y;
|
||||||
|
quat.Z = rot.Z;
|
||||||
|
quat.W = rot.W;
|
||||||
|
return quat;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector3 ToEulerAngles(Assimp.Quaternion q)
|
||||||
|
{
|
||||||
|
float PI = (float)Math.PI;
|
||||||
|
// Store the Euler angles in radians
|
||||||
|
Vector3 pitchYawRoll = new Vector3();
|
||||||
|
|
||||||
|
double sqw = q.W * q.W;
|
||||||
|
double sqx = q.X * q.X;
|
||||||
|
double sqy = q.Y * q.Y;
|
||||||
|
double sqz = q.Z * q.Z;
|
||||||
|
|
||||||
|
// If quaternion is normalised the unit is one, otherwise it is the correction factor
|
||||||
|
double unit = sqx + sqy + sqz + sqw;
|
||||||
|
double test = q.X * q.Y + q.Z * q.W;
|
||||||
|
|
||||||
|
if (test > 0.499f * unit)
|
||||||
|
{
|
||||||
|
// Singularity at north pole
|
||||||
|
pitchYawRoll.Y = 2f * (float)Math.Atan2(q.X, q.W); // Yaw
|
||||||
|
pitchYawRoll.X = PI * 0.5f; // Pitch
|
||||||
|
pitchYawRoll.Z = 0f; // Roll
|
||||||
|
return pitchYawRoll;
|
||||||
|
}
|
||||||
|
else if (test < -0.499f * unit)
|
||||||
|
{
|
||||||
|
// Singularity at south pole
|
||||||
|
pitchYawRoll.Y = -2f * (float)Math.Atan2(q.X, q.W); // Yaw
|
||||||
|
pitchYawRoll.X = -PI * 0.5f; // Pitch
|
||||||
|
pitchYawRoll.Z = 0f; // Roll
|
||||||
|
return pitchYawRoll;
|
||||||
|
}
|
||||||
|
pitchYawRoll.Y = (float)Math.Atan2(2 * q.Y * q.W - 2 * q.X * q.Z, sqx - sqy - sqz + sqw); // Yaw
|
||||||
|
pitchYawRoll.X = (float)Math.Asin(2 * test / unit); // Pitch
|
||||||
|
pitchYawRoll.Z = (float)Math.Atan2(2 * q.X * q.W - 2 * q.Y * q.Z, -sqx + sqy - sqz + sqw); // Roll
|
||||||
|
return pitchYawRoll;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,11 +10,92 @@ using System.IO;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using Switch_Toolbox.Library;
|
using Switch_Toolbox.Library;
|
||||||
using Switch_Toolbox.Library.IO;
|
using Switch_Toolbox.Library.IO;
|
||||||
|
using SFGraphics.GLObjects.Textures;
|
||||||
|
using OpenTK.Graphics.OpenGL;
|
||||||
|
|
||||||
namespace Switch_Toolbox.Library
|
namespace Switch_Toolbox.Library
|
||||||
{
|
{
|
||||||
|
//Data from https://github.com/jam1garner/Smash-Forge/blob/master/Smash%20Forge/Filetypes/Textures/DDS.cs
|
||||||
public class DDS
|
public class DDS
|
||||||
{
|
{
|
||||||
|
public enum CubemapFace
|
||||||
|
{
|
||||||
|
PosX,
|
||||||
|
NegX,
|
||||||
|
PosY,
|
||||||
|
NegY,
|
||||||
|
PosZ,
|
||||||
|
NegZ
|
||||||
|
}
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
public enum DDSD : uint
|
||||||
|
{
|
||||||
|
CAPS = 0x00000001,
|
||||||
|
HEIGHT = 0x00000002,
|
||||||
|
WIDTH = 0x00000004,
|
||||||
|
PITCH = 0x00000008,
|
||||||
|
PIXELFORMAT = 0x00001000,
|
||||||
|
MIPMAPCOUNT = 0x00020000,
|
||||||
|
LINEARSIZE = 0x00080000,
|
||||||
|
DEPTH = 0x00800000
|
||||||
|
}
|
||||||
|
[Flags]
|
||||||
|
public enum DDPF : uint
|
||||||
|
{
|
||||||
|
ALPHAPIXELS = 0x00000001,
|
||||||
|
ALPHA = 0x00000002,
|
||||||
|
FOURCC = 0x00000004,
|
||||||
|
RGB = 0x00000040,
|
||||||
|
YUV = 0x00000200,
|
||||||
|
LUMINANCE = 0x00020000,
|
||||||
|
}
|
||||||
|
[Flags]
|
||||||
|
public enum DDSCAPS : uint
|
||||||
|
{
|
||||||
|
COMPLEX = 0x00000008,
|
||||||
|
TEXTURE = 0x00001000,
|
||||||
|
MIPMAP = 0x00400000,
|
||||||
|
}
|
||||||
|
[Flags]
|
||||||
|
public enum DDSCAPS2 : uint
|
||||||
|
{
|
||||||
|
CUBEMAP = 0x00000200,
|
||||||
|
CUBEMAP_POSITIVEX = 0x00000400 | CUBEMAP,
|
||||||
|
CUBEMAP_NEGATIVEX = 0x00000800 | CUBEMAP,
|
||||||
|
CUBEMAP_POSITIVEY = 0x00001000 | CUBEMAP,
|
||||||
|
CUBEMAP_NEGATIVEY = 0x00002000 | CUBEMAP,
|
||||||
|
CUBEMAP_POSITIVEZ = 0x00004000 | CUBEMAP,
|
||||||
|
CUBEMAP_NEGATIVEZ = 0x00008000 | CUBEMAP,
|
||||||
|
CUBEMAP_ALLFACES = (CUBEMAP_POSITIVEX | CUBEMAP_NEGATIVEX |
|
||||||
|
CUBEMAP_POSITIVEY | CUBEMAP_NEGATIVEY |
|
||||||
|
CUBEMAP_POSITIVEZ | CUBEMAP_NEGATIVEZ),
|
||||||
|
VOLUME = 0x00200000
|
||||||
|
}
|
||||||
|
|
||||||
|
public static uint getFormatSize(uint fourCC)
|
||||||
|
{
|
||||||
|
switch (fourCC)
|
||||||
|
{
|
||||||
|
case 0x00000000: //RGBA
|
||||||
|
return 0x4;
|
||||||
|
case 0x31545844: //DXT1
|
||||||
|
return 0x8;
|
||||||
|
case 0x33545844: //DXT3
|
||||||
|
return 0x10;
|
||||||
|
case 0x35545844: //DXT5
|
||||||
|
return 0x10;
|
||||||
|
case 0x31495441: //ATI1
|
||||||
|
case 0x55344342: //BC4U
|
||||||
|
return 0x8;
|
||||||
|
case 0x32495441: //ATI2
|
||||||
|
case 0x55354342: //BC5U
|
||||||
|
return 0x10;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Header header;
|
public Header header;
|
||||||
public DX10Header DX10header;
|
public DX10Header DX10header;
|
||||||
public class Header
|
public class Header
|
||||||
|
@ -259,6 +340,26 @@ namespace Switch_Toolbox.Library
|
||||||
DX10header.arrayFlag = reader.ReadUInt32();
|
DX10header.arrayFlag = reader.ReadUInt32();
|
||||||
DX10header.miscFlags2 = reader.ReadUInt32();
|
DX10header.miscFlags2 = reader.ReadUInt32();
|
||||||
}
|
}
|
||||||
|
public static TextureCubeMap CreateGLCubeMap(DDS dds)
|
||||||
|
{
|
||||||
|
TextureCubeMap texture = new TextureCubeMap();
|
||||||
|
List<byte[]> cubemap = GetArrayFaces(dds.bdata, 6);
|
||||||
|
texture.LoadImageData((int)dds.header.width,new SFGraphics.GLObjects.Textures.TextureFormats.TextureFormatUncompressed(PixelInternalFormat.Rgba,
|
||||||
|
OpenTK.Graphics.OpenGL.PixelFormat.Rgba, OpenTK.Graphics.OpenGL.PixelType.Float), cubemap[0],
|
||||||
|
cubemap[1], cubemap[2], cubemap[3], cubemap[4], cubemap[5]);
|
||||||
|
return texture;
|
||||||
|
}
|
||||||
|
public static List<byte[]> GetArrayFaces(byte[] data, uint Length)
|
||||||
|
{
|
||||||
|
using (FileReader reader = new FileReader(data))
|
||||||
|
{
|
||||||
|
List<byte[]> array = new List<byte[]>();
|
||||||
|
for (int i = 0; i < Length; i++)
|
||||||
|
array.Add(reader.ReadBytes(data.Length / (int)Length));
|
||||||
|
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
}
|
||||||
public void Save(DDS dds, string FileName, bool IsDX10 = false, List<List<byte[]>> data = null)
|
public void Save(DDS dds, string FileName, bool IsDX10 = false, List<List<byte[]>> 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));
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using Switch_Toolbox.Library;
|
using Switch_Toolbox.Library;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Switch_Toolbox.Library
|
namespace Switch_Toolbox.Library
|
||||||
{
|
{
|
||||||
|
@ -180,7 +181,6 @@ namespace Switch_Toolbox.Library
|
||||||
|
|
||||||
return BitmapExtension.GetBitmap(Output, W * 4, H * 4);
|
return BitmapExtension.GetBitmap(Output, W * 4, H * 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Bitmap DecompressBC4(Byte[] data, int width, int height, bool IsSNORM)
|
public static Bitmap DecompressBC4(Byte[] data, int width, int height, bool IsSNORM)
|
||||||
{
|
{
|
||||||
int W = (width + 3) / 4;
|
int W = (width + 3) / 4;
|
||||||
|
@ -436,7 +436,50 @@ namespace Switch_Toolbox.Library
|
||||||
return BitmapExtension.GetBitmap(Output, W * 4, H * 4);
|
return BitmapExtension.GetBitmap(Output, W * 4, H * 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* public static unsafe byte[] CreateImage(Byte[] data, int width, int height, DDS.DXGI_FORMAT format)
|
||||||
|
{
|
||||||
|
long inputRowPitch;
|
||||||
|
long inputSlicePitch;
|
||||||
|
TexHelper.Instance.ComputePitch((DXGI_FORMAT)format, width, height, out inputRowPitch, out inputSlicePitch, CP_FLAGS.NONE);
|
||||||
|
|
||||||
|
if (data.Length == inputSlicePitch)
|
||||||
|
{
|
||||||
|
byte* buf;
|
||||||
|
buf = (byte*)Marshal.AllocHGlobal((int)inputSlicePitch);
|
||||||
|
Marshal.Copy(data, 0, (IntPtr)buf, (int)inputSlicePitch);
|
||||||
|
|
||||||
|
DirectXTexNet.Image inputImage = new DirectXTexNet.Image(width, height, (DXGI_FORMAT)format, inputRowPitch, inputSlicePitch, (IntPtr)buf, null);
|
||||||
|
ScratchImage scratchImage = TexHelper.Instance.Initialize2D((DXGI_FORMAT)format, width, height, 1, 1, CP_FLAGS.NONE);
|
||||||
|
|
||||||
|
using (var comp = scratchImage.Compress(DXGI_FORMAT.BC1_UNORM, TEX_COMPRESS_FLAGS.PARALLEL, 0.5f))
|
||||||
|
{
|
||||||
|
long outRowPitch;
|
||||||
|
long outSlicePitch;
|
||||||
|
TexHelper.Instance.ComputePitch((DXGI_FORMAT)format, width, height, out outRowPitch, out outSlicePitch, CP_FLAGS.NONE);
|
||||||
|
|
||||||
|
byte[] result = new byte[outSlicePitch];
|
||||||
|
Marshal.Copy(result, 0, scratchImage.GetPixels(), (int)outSlicePitch);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}*/
|
||||||
|
public unsafe byte* PointerData(byte* data, int length)
|
||||||
|
{
|
||||||
|
byte[] safe = new byte[length];
|
||||||
|
for (int i = 0; i < length; i++)
|
||||||
|
safe[i] = data[i];
|
||||||
|
|
||||||
|
fixed (byte* converted = safe)
|
||||||
|
{
|
||||||
|
// This will update the safe and converted arrays.
|
||||||
|
for (int i = 0; i < length; i++)
|
||||||
|
converted[i]++;
|
||||||
|
|
||||||
|
return converted;
|
||||||
|
}
|
||||||
|
}
|
||||||
public static byte[] DecompressBlock(Byte[] data, int width, int height, DDS.DXGI_FORMAT format)
|
public static byte[] DecompressBlock(Byte[] data, int width, int height, DDS.DXGI_FORMAT format)
|
||||||
{
|
{
|
||||||
return DirectXTex.ImageCompressor.Decompress(data, width, height, (int)format);
|
return DirectXTex.ImageCompressor.Decompress(data, width, height, (int)format);
|
||||||
|
@ -447,10 +490,16 @@ namespace Switch_Toolbox.Library
|
||||||
}
|
}
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
if (format == DDS.DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM)
|
||||||
|
return data;
|
||||||
|
|
||||||
return DirectXTex.ImageConverter.Convert(data, width, height,(int)DDS.DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM, (int)format);
|
return DirectXTex.ImageConverter.Convert(data, width, height,(int)DDS.DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM, (int)format);
|
||||||
}
|
}
|
||||||
public static byte[] DecodePixelBlock(Byte[] data, int width, int height, DDS.DXGI_FORMAT format)
|
public static byte[] DecodePixelBlock(Byte[] data, int width, int height, DDS.DXGI_FORMAT format)
|
||||||
{
|
{
|
||||||
|
if (format == DDS.DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM)
|
||||||
|
return data;
|
||||||
|
|
||||||
return DirectXTex.ImageConverter.Convert(data, width, height, (int)format, (int)DDS.DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM);
|
return DirectXTex.ImageConverter.Convert(data, width, height, (int)format, (int)DDS.DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,22 @@ namespace Switch_Toolbox.Library
|
||||||
public BitmapExtension()
|
public BitmapExtension()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
public static List<byte[]> GenerateMipMaps(Bitmap bitmap)
|
||||||
|
{
|
||||||
|
List<byte[]> datas = new List<byte[]>();
|
||||||
|
|
||||||
|
datas.Add(ImageToByte(bitmap));
|
||||||
|
while (bitmap.Width / 2 > 0 && bitmap.Height / 2 > 0)
|
||||||
|
{
|
||||||
|
bitmap = Resize(bitmap, bitmap.Width / 2, bitmap.Height / 2);
|
||||||
|
datas.Add(ImageToByte(bitmap));
|
||||||
|
}
|
||||||
|
return datas;
|
||||||
|
}
|
||||||
|
public static Bitmap Resize(Image original, int width, int height)
|
||||||
|
{
|
||||||
|
return new Bitmap(original, new Size(width, height));
|
||||||
}
|
}
|
||||||
public static Bitmap GetBitmap(byte[] Buffer, int Width, int Height, PixelFormat pixelFormat = PixelFormat.Format32bppArgb)
|
public static Bitmap GetBitmap(byte[] Buffer, int Width, int Height, PixelFormat pixelFormat = PixelFormat.Format32bppArgb)
|
||||||
{
|
{
|
||||||
|
@ -143,9 +159,9 @@ namespace Switch_Toolbox.Library
|
||||||
|
|
||||||
for (int k = 0; k < resultBuffer.Length; k += 4)
|
for (int k = 0; k < resultBuffer.Length; k += 4)
|
||||||
{
|
{
|
||||||
sourceBlue = resultBuffer[k];
|
sourceRed = resultBuffer[k];
|
||||||
sourceGreen = resultBuffer[k + 1];
|
sourceGreen = resultBuffer[k + 1];
|
||||||
sourceRed = resultBuffer[k + 2];
|
sourceBlue = resultBuffer[k + 2];
|
||||||
sourceAlpha = resultBuffer[k + 3];
|
sourceAlpha = resultBuffer[k + 3];
|
||||||
|
|
||||||
|
|
||||||
|
@ -245,9 +261,9 @@ namespace Switch_Toolbox.Library
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
resultBuffer[k] = resultBlue;
|
resultBuffer[k] = resultRed;
|
||||||
resultBuffer[k + 1] = resultGreen;
|
resultBuffer[k + 1] = resultGreen;
|
||||||
resultBuffer[k + 2] = resultRed;
|
resultBuffer[k + 2] = resultBlue;
|
||||||
resultBuffer[k + 3] = resultAlpha;
|
resultBuffer[k + 3] = resultAlpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,8 @@ namespace Switch_Toolbox.Library
|
||||||
public abstract class TreeNodeCustom : TreeNode
|
public abstract class TreeNodeCustom : TreeNode
|
||||||
{
|
{
|
||||||
public virtual void OnClick(TreeView treeview) { }
|
public virtual void OnClick(TreeView treeview) { }
|
||||||
public virtual void OnMouseClick(TreeView treeview) { }
|
public virtual void OnMouseLeftClick(TreeView treeview) { }
|
||||||
|
public virtual void OnMouseRightClick(TreeView treeview) { }
|
||||||
public virtual void OnDoubleMouseClick(TreeView treeview) { }
|
public virtual void OnDoubleMouseClick(TreeView treeview) { }
|
||||||
|
|
||||||
public TreeNodeCustom()
|
public TreeNodeCustom()
|
||||||
|
|
|
@ -101,13 +101,13 @@
|
||||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(33)))), ((int)(((byte)(33)))), ((int)(((byte)(33)))));
|
this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(33)))), ((int)(((byte)(33)))), ((int)(((byte)(33)))));
|
||||||
this.ClientSize = new System.Drawing.Size(602, 69);
|
|
||||||
this.Controls.Add(this.animationTrackBar);
|
this.Controls.Add(this.animationTrackBar);
|
||||||
this.Controls.Add(this.totalFrame);
|
this.Controls.Add(this.totalFrame);
|
||||||
this.Controls.Add(this.currentFrameUpDown);
|
this.Controls.Add(this.currentFrameUpDown);
|
||||||
this.Controls.Add(this.animationPlayBtn);
|
this.Controls.Add(this.animationPlayBtn);
|
||||||
this.Name = "AnimationPanel";
|
this.Name = "AnimationPanel";
|
||||||
this.Text = "AnimationPanel";
|
this.Size = new System.Drawing.Size(602, 69);
|
||||||
|
this.Load += new System.EventHandler(this.AnimationPanel_Load);
|
||||||
this.Click += new System.EventHandler(this.AnimationPanel_Click);
|
this.Click += new System.EventHandler(this.AnimationPanel_Click);
|
||||||
this.Enter += new System.EventHandler(this.AnimationPanel_Enter);
|
this.Enter += new System.EventHandler(this.AnimationPanel_Enter);
|
||||||
this.Leave += new System.EventHandler(this.AnimationPanel_Leave);
|
this.Leave += new System.EventHandler(this.AnimationPanel_Leave);
|
||||||
|
|
|
@ -25,10 +25,9 @@ namespace Switch_Toolbox.Library
|
||||||
public int AnimationSpeed = 60;
|
public int AnimationSpeed = 60;
|
||||||
public float Frame = 0;
|
public float Frame = 0;
|
||||||
public bool isPlaying;
|
public bool isPlaying;
|
||||||
private bool isOpen = true;
|
public bool isOpen = true;
|
||||||
private Thread renderThread;
|
private Thread renderThread;
|
||||||
private GL_Core.GL_ControlModern gL_ControlModern1;
|
public bool renderThreadIsUpdating = false;
|
||||||
private bool renderThreadIsUpdating = false;
|
|
||||||
|
|
||||||
private Animation currentAnimation;
|
private Animation currentAnimation;
|
||||||
public Animation CurrentAnimation
|
public Animation CurrentAnimation
|
||||||
|
@ -39,13 +38,16 @@ namespace Switch_Toolbox.Library
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
|
if (value == null)
|
||||||
|
return;
|
||||||
|
|
||||||
ResetModels();
|
ResetModels();
|
||||||
/* currentAnimation = value;
|
currentAnimation = value;
|
||||||
totalFrame.Value = value.FrameCount;
|
totalFrame.Value = value.FrameCount;
|
||||||
animationTrackBar.TickFrequency = 1;
|
animationTrackBar.TickFrequency = 1;
|
||||||
animationTrackBar.SetRange(0, (int)value.FrameCount);
|
animationTrackBar.SetRange(0, (int)value.FrameCount);
|
||||||
currentFrameUpDown.Value = 1;
|
currentFrameUpDown.Value = 1;
|
||||||
currentFrameUpDown.Value = 0;*/
|
currentFrameUpDown.Value = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,6 +120,9 @@ namespace Switch_Toolbox.Library
|
||||||
|
|
||||||
private void UpdateViewport()
|
private void UpdateViewport()
|
||||||
{
|
{
|
||||||
|
if (IsDisposed)
|
||||||
|
return;
|
||||||
|
|
||||||
if (Viewport.Instance.gL_ControlModern1.InvokeRequired)
|
if (Viewport.Instance.gL_ControlModern1.InvokeRequired)
|
||||||
{
|
{
|
||||||
Viewport.Instance.gL_ControlModern1.Invoke((MethodInvoker)delegate {
|
Viewport.Instance.gL_ControlModern1.Invoke((MethodInvoker)delegate {
|
||||||
|
@ -226,6 +231,7 @@ namespace Switch_Toolbox.Library
|
||||||
|
|
||||||
SetAnimationsToFrame(currentFrame);
|
SetAnimationsToFrame(currentFrame);
|
||||||
|
|
||||||
|
if (!renderThreadIsUpdating || !isPlaying)
|
||||||
UpdateViewport();
|
UpdateViewport();
|
||||||
}
|
}
|
||||||
private void SetAnimationsToFrame(int frameNum)
|
private void SetAnimationsToFrame(int frameNum)
|
||||||
|
@ -252,19 +258,19 @@ namespace Switch_Toolbox.Library
|
||||||
animationTrackBar.Value = (int)currentFrameUpDown.Value;
|
animationTrackBar.Value = (int)currentFrameUpDown.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AnimationPanel_FormClosed(object sender, FormClosedEventArgs e)
|
public void AnimationPanel_FormClosed()
|
||||||
{
|
{
|
||||||
isOpen = false;
|
isOpen = false;
|
||||||
Dispose();
|
Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AnimationPanel_Shown(object sender, EventArgs e)
|
private void AnimationPanel_Load(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
// if (Viewport.Instance.gL_ControlModern1 != null)
|
if (Viewport.Instance.gL_ControlModern1 != null)
|
||||||
// Viewport.Instance.gL_ControlModern1.VSync = Runtime.enableVSync;
|
Viewport.Instance.gL_ControlModern1.VSync = Runtime.enableVSync;
|
||||||
|
|
||||||
// renderThread = new Thread(new ThreadStart(RenderAndAnimationLoop));
|
renderThread = new Thread(new ThreadStart(RenderAndAnimationLoop));
|
||||||
// renderThread.Start();
|
renderThread.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AnimationPanel_Enter(object sender, EventArgs e)
|
private void AnimationPanel_Enter(object sender, EventArgs e)
|
||||||
|
@ -281,5 +287,12 @@ namespace Switch_Toolbox.Library
|
||||||
{
|
{
|
||||||
renderThreadIsUpdating = false;
|
renderThreadIsUpdating = false;
|
||||||
}
|
}
|
||||||
|
public void ClosePanel()
|
||||||
|
{
|
||||||
|
renderThreadIsUpdating = false;
|
||||||
|
isOpen = false;
|
||||||
|
Dispose();
|
||||||
|
renderThread.Abort();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
236
Switch_Toolbox_Library/GUI/CubeMapFaceCreator.Designer.cs
generated
Normal file
236
Switch_Toolbox_Library/GUI/CubeMapFaceCreator.Designer.cs
generated
Normal file
|
@ -0,0 +1,236 @@
|
||||||
|
namespace Switch_Toolbox.Library.GUI
|
||||||
|
{
|
||||||
|
partial class CubeMapFaceCreator
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Windows Form Designer generated code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CubeMapFaceCreator));
|
||||||
|
this.pictureBoxCustom6 = new Switch_Toolbox.Library.Forms.PictureBoxCustom();
|
||||||
|
this.pictureBoxCustom1 = new Switch_Toolbox.Library.Forms.PictureBoxCustom();
|
||||||
|
this.pictureBoxCustom2 = new Switch_Toolbox.Library.Forms.PictureBoxCustom();
|
||||||
|
this.pictureBoxCustom3 = new Switch_Toolbox.Library.Forms.PictureBoxCustom();
|
||||||
|
this.pictureBoxCustom4 = new Switch_Toolbox.Library.Forms.PictureBoxCustom();
|
||||||
|
this.pictureBoxCustom5 = new Switch_Toolbox.Library.Forms.PictureBoxCustom();
|
||||||
|
this.label1 = new System.Windows.Forms.Label();
|
||||||
|
this.label2 = new System.Windows.Forms.Label();
|
||||||
|
this.label3 = new System.Windows.Forms.Label();
|
||||||
|
this.label4 = new System.Windows.Forms.Label();
|
||||||
|
this.label5 = new System.Windows.Forms.Label();
|
||||||
|
this.label6 = new System.Windows.Forms.Label();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.pictureBoxCustom6)).BeginInit();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.pictureBoxCustom1)).BeginInit();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.pictureBoxCustom2)).BeginInit();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.pictureBoxCustom3)).BeginInit();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.pictureBoxCustom4)).BeginInit();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.pictureBoxCustom5)).BeginInit();
|
||||||
|
this.SuspendLayout();
|
||||||
|
//
|
||||||
|
// pictureBoxCustom6
|
||||||
|
//
|
||||||
|
this.pictureBoxCustom6.BackColor = System.Drawing.Color.Transparent;
|
||||||
|
this.pictureBoxCustom6.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("pictureBoxCustom6.BackgroundImage")));
|
||||||
|
this.pictureBoxCustom6.Location = new System.Drawing.Point(217, 12);
|
||||||
|
this.pictureBoxCustom6.Name = "pictureBoxCustom6";
|
||||||
|
this.pictureBoxCustom6.Size = new System.Drawing.Size(200, 200);
|
||||||
|
this.pictureBoxCustom6.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
|
||||||
|
this.pictureBoxCustom6.TabIndex = 5;
|
||||||
|
this.pictureBoxCustom6.TabStop = false;
|
||||||
|
//
|
||||||
|
// pictureBoxCustom1
|
||||||
|
//
|
||||||
|
this.pictureBoxCustom1.BackColor = System.Drawing.Color.Transparent;
|
||||||
|
this.pictureBoxCustom1.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("pictureBoxCustom1.BackgroundImage")));
|
||||||
|
this.pictureBoxCustom1.Location = new System.Drawing.Point(217, 218);
|
||||||
|
this.pictureBoxCustom1.Name = "pictureBoxCustom1";
|
||||||
|
this.pictureBoxCustom1.Size = new System.Drawing.Size(200, 200);
|
||||||
|
this.pictureBoxCustom1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
|
||||||
|
this.pictureBoxCustom1.TabIndex = 6;
|
||||||
|
this.pictureBoxCustom1.TabStop = false;
|
||||||
|
//
|
||||||
|
// pictureBoxCustom2
|
||||||
|
//
|
||||||
|
this.pictureBoxCustom2.BackColor = System.Drawing.Color.Transparent;
|
||||||
|
this.pictureBoxCustom2.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("pictureBoxCustom2.BackgroundImage")));
|
||||||
|
this.pictureBoxCustom2.Location = new System.Drawing.Point(11, 218);
|
||||||
|
this.pictureBoxCustom2.Name = "pictureBoxCustom2";
|
||||||
|
this.pictureBoxCustom2.Size = new System.Drawing.Size(200, 200);
|
||||||
|
this.pictureBoxCustom2.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
|
||||||
|
this.pictureBoxCustom2.TabIndex = 7;
|
||||||
|
this.pictureBoxCustom2.TabStop = false;
|
||||||
|
//
|
||||||
|
// pictureBoxCustom3
|
||||||
|
//
|
||||||
|
this.pictureBoxCustom3.BackColor = System.Drawing.Color.Transparent;
|
||||||
|
this.pictureBoxCustom3.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("pictureBoxCustom3.BackgroundImage")));
|
||||||
|
this.pictureBoxCustom3.Location = new System.Drawing.Point(217, 424);
|
||||||
|
this.pictureBoxCustom3.Name = "pictureBoxCustom3";
|
||||||
|
this.pictureBoxCustom3.Size = new System.Drawing.Size(200, 200);
|
||||||
|
this.pictureBoxCustom3.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
|
||||||
|
this.pictureBoxCustom3.TabIndex = 8;
|
||||||
|
this.pictureBoxCustom3.TabStop = false;
|
||||||
|
//
|
||||||
|
// pictureBoxCustom4
|
||||||
|
//
|
||||||
|
this.pictureBoxCustom4.BackColor = System.Drawing.Color.Transparent;
|
||||||
|
this.pictureBoxCustom4.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("pictureBoxCustom4.BackgroundImage")));
|
||||||
|
this.pictureBoxCustom4.Location = new System.Drawing.Point(423, 218);
|
||||||
|
this.pictureBoxCustom4.Name = "pictureBoxCustom4";
|
||||||
|
this.pictureBoxCustom4.Size = new System.Drawing.Size(200, 200);
|
||||||
|
this.pictureBoxCustom4.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
|
||||||
|
this.pictureBoxCustom4.TabIndex = 9;
|
||||||
|
this.pictureBoxCustom4.TabStop = false;
|
||||||
|
//
|
||||||
|
// pictureBoxCustom5
|
||||||
|
//
|
||||||
|
this.pictureBoxCustom5.BackColor = System.Drawing.Color.Transparent;
|
||||||
|
this.pictureBoxCustom5.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("pictureBoxCustom5.BackgroundImage")));
|
||||||
|
this.pictureBoxCustom5.Location = new System.Drawing.Point(629, 218);
|
||||||
|
this.pictureBoxCustom5.Name = "pictureBoxCustom5";
|
||||||
|
this.pictureBoxCustom5.Size = new System.Drawing.Size(200, 200);
|
||||||
|
this.pictureBoxCustom5.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
|
||||||
|
this.pictureBoxCustom5.TabIndex = 10;
|
||||||
|
this.pictureBoxCustom5.TabStop = false;
|
||||||
|
//
|
||||||
|
// label1
|
||||||
|
//
|
||||||
|
this.label1.AutoSize = true;
|
||||||
|
this.label1.BackColor = System.Drawing.Color.White;
|
||||||
|
this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||||
|
this.label1.ForeColor = System.Drawing.Color.Black;
|
||||||
|
this.label1.Location = new System.Drawing.Point(274, 300);
|
||||||
|
this.label1.Name = "label1";
|
||||||
|
this.label1.Size = new System.Drawing.Size(76, 24);
|
||||||
|
this.label1.TabIndex = 11;
|
||||||
|
this.label1.Text = "FRONT";
|
||||||
|
//
|
||||||
|
// label2
|
||||||
|
//
|
||||||
|
this.label2.AutoSize = true;
|
||||||
|
this.label2.BackColor = System.Drawing.Color.White;
|
||||||
|
this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||||
|
this.label2.ForeColor = System.Drawing.Color.Black;
|
||||||
|
this.label2.Location = new System.Drawing.Point(488, 300);
|
||||||
|
this.label2.Name = "label2";
|
||||||
|
this.label2.Size = new System.Drawing.Size(67, 24);
|
||||||
|
this.label2.TabIndex = 12;
|
||||||
|
this.label2.Text = "RIGHT";
|
||||||
|
//
|
||||||
|
// label3
|
||||||
|
//
|
||||||
|
this.label3.AutoSize = true;
|
||||||
|
this.label3.BackColor = System.Drawing.Color.White;
|
||||||
|
this.label3.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||||
|
this.label3.ForeColor = System.Drawing.Color.Black;
|
||||||
|
this.label3.Location = new System.Drawing.Point(78, 300);
|
||||||
|
this.label3.Name = "label3";
|
||||||
|
this.label3.Size = new System.Drawing.Size(57, 24);
|
||||||
|
this.label3.TabIndex = 13;
|
||||||
|
this.label3.Text = "LEFT";
|
||||||
|
//
|
||||||
|
// label4
|
||||||
|
//
|
||||||
|
this.label4.AutoSize = true;
|
||||||
|
this.label4.BackColor = System.Drawing.Color.White;
|
||||||
|
this.label4.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||||
|
this.label4.ForeColor = System.Drawing.Color.Black;
|
||||||
|
this.label4.Location = new System.Drawing.Point(716, 300);
|
||||||
|
this.label4.Name = "label4";
|
||||||
|
this.label4.Size = new System.Drawing.Size(60, 24);
|
||||||
|
this.label4.TabIndex = 14;
|
||||||
|
this.label4.Text = "BACK";
|
||||||
|
//
|
||||||
|
// label5
|
||||||
|
//
|
||||||
|
this.label5.AutoSize = true;
|
||||||
|
this.label5.BackColor = System.Drawing.Color.White;
|
||||||
|
this.label5.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||||
|
this.label5.ForeColor = System.Drawing.Color.Black;
|
||||||
|
this.label5.Location = new System.Drawing.Point(283, 90);
|
||||||
|
this.label5.Name = "label5";
|
||||||
|
this.label5.Size = new System.Drawing.Size(49, 24);
|
||||||
|
this.label5.TabIndex = 15;
|
||||||
|
this.label5.Text = "TOP";
|
||||||
|
//
|
||||||
|
// label6
|
||||||
|
//
|
||||||
|
this.label6.AutoSize = true;
|
||||||
|
this.label6.BackColor = System.Drawing.Color.White;
|
||||||
|
this.label6.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||||
|
this.label6.ForeColor = System.Drawing.Color.Black;
|
||||||
|
this.label6.Location = new System.Drawing.Point(268, 528);
|
||||||
|
this.label6.Name = "label6";
|
||||||
|
this.label6.Size = new System.Drawing.Size(92, 24);
|
||||||
|
this.label6.TabIndex = 16;
|
||||||
|
this.label6.Text = "BOTTOM";
|
||||||
|
//
|
||||||
|
// CubeMapFaceCreator
|
||||||
|
//
|
||||||
|
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||||
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
|
this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(40)))), ((int)(((byte)(40)))), ((int)(((byte)(40)))));
|
||||||
|
this.ClientSize = new System.Drawing.Size(840, 630);
|
||||||
|
this.Controls.Add(this.label6);
|
||||||
|
this.Controls.Add(this.label5);
|
||||||
|
this.Controls.Add(this.label4);
|
||||||
|
this.Controls.Add(this.label3);
|
||||||
|
this.Controls.Add(this.label2);
|
||||||
|
this.Controls.Add(this.label1);
|
||||||
|
this.Controls.Add(this.pictureBoxCustom5);
|
||||||
|
this.Controls.Add(this.pictureBoxCustom4);
|
||||||
|
this.Controls.Add(this.pictureBoxCustom3);
|
||||||
|
this.Controls.Add(this.pictureBoxCustom2);
|
||||||
|
this.Controls.Add(this.pictureBoxCustom1);
|
||||||
|
this.Controls.Add(this.pictureBoxCustom6);
|
||||||
|
this.Name = "CubeMapFaceCreator";
|
||||||
|
this.Text = "CubeMap Face Creator";
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.pictureBoxCustom6)).EndInit();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.pictureBoxCustom1)).EndInit();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.pictureBoxCustom2)).EndInit();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.pictureBoxCustom3)).EndInit();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.pictureBoxCustom4)).EndInit();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.pictureBoxCustom5)).EndInit();
|
||||||
|
this.ResumeLayout(false);
|
||||||
|
this.PerformLayout();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private Forms.PictureBoxCustom pictureBoxCustom6;
|
||||||
|
private Forms.PictureBoxCustom pictureBoxCustom1;
|
||||||
|
private Forms.PictureBoxCustom pictureBoxCustom2;
|
||||||
|
private Forms.PictureBoxCustom pictureBoxCustom3;
|
||||||
|
private Forms.PictureBoxCustom pictureBoxCustom4;
|
||||||
|
private Forms.PictureBoxCustom pictureBoxCustom5;
|
||||||
|
private System.Windows.Forms.Label label1;
|
||||||
|
private System.Windows.Forms.Label label2;
|
||||||
|
private System.Windows.Forms.Label label3;
|
||||||
|
private System.Windows.Forms.Label label4;
|
||||||
|
private System.Windows.Forms.Label label5;
|
||||||
|
private System.Windows.Forms.Label label6;
|
||||||
|
}
|
||||||
|
}
|
20
Switch_Toolbox_Library/GUI/CubeMapFaceCreator.cs
Normal file
20
Switch_Toolbox_Library/GUI/CubeMapFaceCreator.cs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Data;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace Switch_Toolbox.Library.GUI
|
||||||
|
{
|
||||||
|
public partial class CubeMapFaceCreator : Form
|
||||||
|
{
|
||||||
|
public CubeMapFaceCreator()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
1363
Switch_Toolbox_Library/GUI/CubeMapFaceCreator.resx
Normal file
1363
Switch_Toolbox_Library/GUI/CubeMapFaceCreator.resx
Normal file
File diff suppressed because it is too large
Load diff
|
@ -131,8 +131,8 @@
|
||||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(40)))), ((int)(((byte)(40)))), ((int)(((byte)(40)))));
|
this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(40)))), ((int)(((byte)(40)))), ((int)(((byte)(40)))));
|
||||||
this.ClientSize = new System.Drawing.Size(358, 450);
|
this.ClientSize = new System.Drawing.Size(358, 450);
|
||||||
this.Controls.Add(this.panel1);
|
|
||||||
this.Controls.Add(this.treeView1);
|
this.Controls.Add(this.treeView1);
|
||||||
|
this.Controls.Add(this.panel1);
|
||||||
this.Name = "ObjectList";
|
this.Name = "ObjectList";
|
||||||
this.Text = "ObjectList";
|
this.Text = "ObjectList";
|
||||||
this.DockStateChanged += new System.EventHandler(this.ObjectList_DockStateChanged);
|
this.DockStateChanged += new System.EventHandler(this.ObjectList_DockStateChanged);
|
||||||
|
|
|
@ -74,32 +74,13 @@ namespace Switch_Toolbox.Library
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AnimationPanel AnimationPanel = LoadAnimationPanel();
|
if (Viewport.Instance.animationPanel1 != null)
|
||||||
|
|
||||||
if (AnimationPanel != null)
|
|
||||||
{
|
{
|
||||||
AnimationPanel.CurrentAnimation = running;
|
Console.WriteLine("running" + running.Text);
|
||||||
|
Viewport.Instance.animationPanel1.CurrentAnimation = running;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public AnimationPanel LoadAnimationPanel()
|
|
||||||
{
|
|
||||||
Form form1 = Application.OpenForms[0];
|
|
||||||
foreach (Control control in form1.Controls)
|
|
||||||
{
|
|
||||||
if (control is DockPanel)
|
|
||||||
{
|
|
||||||
foreach (DockContent ctrl in ((DockPanel)control).Contents)
|
|
||||||
{
|
|
||||||
if (ctrl is AnimationPanel)
|
|
||||||
{
|
|
||||||
// return (AnimationPanel)ctrl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ApplyThumbnailSetting(Runtime.ThumbnailSize size)
|
private void ApplyThumbnailSetting(Runtime.ThumbnailSize size)
|
||||||
{
|
{
|
||||||
|
@ -210,16 +191,17 @@ namespace Switch_Toolbox.Library
|
||||||
}
|
}
|
||||||
|
|
||||||
private void treeView1_MouseClick(object sender, MouseEventArgs e)
|
private void treeView1_MouseClick(object sender, MouseEventArgs e)
|
||||||
{
|
|
||||||
if (e.Button == MouseButtons.Left)
|
|
||||||
{
|
{
|
||||||
TreeViewHitTestInfo info = treeView1.HitTest(treeView1.PointToClient(Cursor.Position));
|
TreeViewHitTestInfo info = treeView1.HitTest(treeView1.PointToClient(Cursor.Position));
|
||||||
if (info != null && info.Node is TreeNodeCustom)
|
if (info != null && info.Node is TreeNodeCustom)
|
||||||
{
|
{
|
||||||
((TreeNodeCustom)info.Node).OnMouseClick(treeView1);
|
if (e.Button == MouseButtons.Left)
|
||||||
|
((TreeNodeCustom)info.Node).OnMouseLeftClick(treeView1);
|
||||||
|
else if (e.Button == MouseButtons.Right)
|
||||||
|
((TreeNodeCustom)info.Node).OnMouseRightClick(treeView1);
|
||||||
|
|
||||||
treeView1.SelectedNode = info.Node;
|
treeView1.SelectedNode = info.Node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
26
Switch_Toolbox_Library/GUI/Viewport.Designer.cs
generated
26
Switch_Toolbox_Library/GUI/Viewport.Designer.cs
generated
|
@ -32,10 +32,10 @@
|
||||||
this.animationPanel1 = new Switch_Toolbox.Library.AnimationPanel();
|
this.animationPanel1 = new Switch_Toolbox.Library.AnimationPanel();
|
||||||
this.contextMenuStripDark1 = new Switch_Toolbox.Library.Forms.ContextMenuStripDark();
|
this.contextMenuStripDark1 = new Switch_Toolbox.Library.Forms.ContextMenuStripDark();
|
||||||
this.shadingToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
this.shadingToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.normalsShadingToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
|
||||||
this.translateToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
this.translateToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.rotateToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
this.rotateToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.scaleToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
this.scaleToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
|
this.normalsShadingToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.contextMenuStripDark1.SuspendLayout();
|
this.contextMenuStripDark1.SuspendLayout();
|
||||||
this.SuspendLayout();
|
this.SuspendLayout();
|
||||||
//
|
//
|
||||||
|
@ -85,7 +85,6 @@
|
||||||
//
|
//
|
||||||
// shadingToolStripMenuItem
|
// shadingToolStripMenuItem
|
||||||
//
|
//
|
||||||
this.shadingToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {});
|
|
||||||
this.shadingToolStripMenuItem.Image = global::Switch_Toolbox.Library.Properties.Resources.diffuseSphere;
|
this.shadingToolStripMenuItem.Image = global::Switch_Toolbox.Library.Properties.Resources.diffuseSphere;
|
||||||
this.shadingToolStripMenuItem.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None;
|
this.shadingToolStripMenuItem.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None;
|
||||||
this.shadingToolStripMenuItem.Name = "shadingToolStripMenuItem";
|
this.shadingToolStripMenuItem.Name = "shadingToolStripMenuItem";
|
||||||
|
@ -95,16 +94,6 @@
|
||||||
this.shadingToolStripMenuItem.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText;
|
this.shadingToolStripMenuItem.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText;
|
||||||
this.shadingToolStripMenuItem.DropDownItemClicked += new System.Windows.Forms.ToolStripItemClickedEventHandler(this.shadingToolStripMenuItem_DropDownItemClicked);
|
this.shadingToolStripMenuItem.DropDownItemClicked += new System.Windows.Forms.ToolStripItemClickedEventHandler(this.shadingToolStripMenuItem_DropDownItemClicked);
|
||||||
//
|
//
|
||||||
// normalsShadingToolStripMenuItem
|
|
||||||
//
|
|
||||||
this.normalsShadingToolStripMenuItem.ForeColor = System.Drawing.Color.White;
|
|
||||||
this.normalsShadingToolStripMenuItem.Image = global::Switch_Toolbox.Library.Properties.Resources.normalsSphere;
|
|
||||||
this.normalsShadingToolStripMenuItem.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None;
|
|
||||||
this.normalsShadingToolStripMenuItem.Name = "normalsShadingToolStripMenuItem";
|
|
||||||
this.normalsShadingToolStripMenuItem.Size = new System.Drawing.Size(204, 46);
|
|
||||||
this.normalsShadingToolStripMenuItem.Text = "Normals Shading";
|
|
||||||
this.normalsShadingToolStripMenuItem.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText;
|
|
||||||
//
|
|
||||||
// translateToolStripMenuItem
|
// translateToolStripMenuItem
|
||||||
//
|
//
|
||||||
this.translateToolStripMenuItem.Image = global::Switch_Toolbox.Library.Properties.Resources.translateGizmo;
|
this.translateToolStripMenuItem.Image = global::Switch_Toolbox.Library.Properties.Resources.translateGizmo;
|
||||||
|
@ -132,6 +121,16 @@
|
||||||
this.scaleToolStripMenuItem.Text = "Scale";
|
this.scaleToolStripMenuItem.Text = "Scale";
|
||||||
this.scaleToolStripMenuItem.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText;
|
this.scaleToolStripMenuItem.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText;
|
||||||
//
|
//
|
||||||
|
// normalsShadingToolStripMenuItem
|
||||||
|
//
|
||||||
|
this.normalsShadingToolStripMenuItem.ForeColor = System.Drawing.Color.White;
|
||||||
|
this.normalsShadingToolStripMenuItem.Image = global::Switch_Toolbox.Library.Properties.Resources.normalsSphere;
|
||||||
|
this.normalsShadingToolStripMenuItem.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None;
|
||||||
|
this.normalsShadingToolStripMenuItem.Name = "normalsShadingToolStripMenuItem";
|
||||||
|
this.normalsShadingToolStripMenuItem.Size = new System.Drawing.Size(204, 46);
|
||||||
|
this.normalsShadingToolStripMenuItem.Text = "Normals Shading";
|
||||||
|
this.normalsShadingToolStripMenuItem.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText;
|
||||||
|
//
|
||||||
// Viewport
|
// Viewport
|
||||||
//
|
//
|
||||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||||
|
@ -150,6 +149,7 @@
|
||||||
this.Name = "Viewport";
|
this.Name = "Viewport";
|
||||||
this.ShowHint = WeifenLuo.WinFormsUI.Docking.DockState.Unknown;
|
this.ShowHint = WeifenLuo.WinFormsUI.Docking.DockState.Unknown;
|
||||||
this.Text = "Viewport";
|
this.Text = "Viewport";
|
||||||
|
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Viewport_FormClosing);
|
||||||
this.contextMenuStripDark1.ResumeLayout(false);
|
this.contextMenuStripDark1.ResumeLayout(false);
|
||||||
this.contextMenuStripDark1.PerformLayout();
|
this.contextMenuStripDark1.PerformLayout();
|
||||||
this.ResumeLayout(false);
|
this.ResumeLayout(false);
|
||||||
|
@ -160,7 +160,7 @@
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public GL_Core.GL_ControlModern gL_ControlModern1;
|
public GL_Core.GL_ControlModern gL_ControlModern1;
|
||||||
private AnimationPanel animationPanel1;
|
public AnimationPanel animationPanel1;
|
||||||
private Forms.ContextMenuStripDark contextMenuStripDark1;
|
private Forms.ContextMenuStripDark contextMenuStripDark1;
|
||||||
private System.Windows.Forms.ToolStripMenuItem shadingToolStripMenuItem;
|
private System.Windows.Forms.ToolStripMenuItem shadingToolStripMenuItem;
|
||||||
private System.Windows.Forms.ToolStripMenuItem translateToolStripMenuItem;
|
private System.Windows.Forms.ToolStripMenuItem translateToolStripMenuItem;
|
||||||
|
|
|
@ -121,5 +121,10 @@ namespace Switch_Toolbox.Library
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void Viewport_FormClosing(object sender, FormClosingEventArgs e)
|
||||||
|
{
|
||||||
|
animationPanel1.ClosePanel();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,6 +158,22 @@ namespace Switch_Toolbox.Library.IO
|
||||||
{
|
{
|
||||||
Write(Encoding.ASCII.GetBytes(value));
|
Write(Encoding.ASCII.GetBytes(value));
|
||||||
}
|
}
|
||||||
|
public void WriteUint64Offset(long target)
|
||||||
|
{
|
||||||
|
long pos = Position;
|
||||||
|
using (TemporarySeek(target, SeekOrigin.Begin))
|
||||||
|
{
|
||||||
|
Write(pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void WriteUint32Offset(long target)
|
||||||
|
{
|
||||||
|
long pos = Position;
|
||||||
|
using (TemporarySeek(target, SeekOrigin.Begin))
|
||||||
|
{
|
||||||
|
Write((uint)pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
public class FileExt
|
public class FileExt
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,6 +8,7 @@ using SFGraphics.GLObjects.Textures.TextureFormats;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using OpenTK.Graphics.OpenGL;
|
using OpenTK.Graphics.OpenGL;
|
||||||
using Smash_Forge.Rendering;
|
using Smash_Forge.Rendering;
|
||||||
|
using Switch_Toolbox.Library.IO;
|
||||||
|
|
||||||
namespace Switch_Toolbox.Library
|
namespace Switch_Toolbox.Library
|
||||||
{
|
{
|
||||||
|
@ -25,8 +26,13 @@ namespace Switch_Toolbox.Library
|
||||||
uvTestPattern = new Texture2D();
|
uvTestPattern = new Texture2D();
|
||||||
uvTestPattern.LoadImageData(Properties.Resources.UVPattern);
|
uvTestPattern.LoadImageData(Properties.Resources.UVPattern);
|
||||||
|
|
||||||
// DDS specularSdr = new DDS(Properties.Resources.specularSDR);
|
if (Runtime.EnablePBR)
|
||||||
// specularPbr = NUT.CreateTextureCubeMap(specularSdr.ToNutTexture());
|
{
|
||||||
|
byte[] decompSpecular = STLibraryCompression.GZIP.Decompress(Properties.Resources.specularSDR);
|
||||||
|
DDS specularSdr = new DDS(decompSpecular);
|
||||||
|
// specularPbr = DDS.CreateGLCubeMap(specularSdr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// DDS diffuseSdr = new DDS(Properties.Resources.diffuseSDR);
|
// DDS diffuseSdr = new DDS(Properties.Resources.diffuseSDR);
|
||||||
// diffusePbr = CreateTextureCubeMap(bntx.textureData.texture);
|
// diffusePbr = CreateTextureCubeMap(bntx.textureData.texture);
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 5.3 MiB |
Binary file not shown.
Before Width: | Height: | Size: 108 KiB |
Binary file not shown.
Before Width: | Height: | Size: 81 KiB |
BIN
Switch_Toolbox_Library/Resources/skeletonAnimation.dds
Normal file
BIN
Switch_Toolbox_Library/Resources/skeletonAnimation.dds
Normal file
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 945 KiB |
|
@ -25,6 +25,7 @@ namespace Switch_Toolbox.Library
|
||||||
public static ViewportShading viewportShading;
|
public static ViewportShading viewportShading;
|
||||||
public static bool IsDebugMode = false; //Enables experimental features and other things to debug.
|
public static bool IsDebugMode = false; //Enables experimental features and other things to debug.
|
||||||
public static bool DisableViewport = false;
|
public static bool DisableViewport = false;
|
||||||
|
public static bool EnablePBR = false;
|
||||||
|
|
||||||
public static bool enableVSync = false;
|
public static bool enableVSync = false;
|
||||||
public static float floorSize = 30f;
|
public static float floorSize = 30f;
|
||||||
|
|
|
@ -54,8 +54,8 @@
|
||||||
<Reference Include="K4os.Hash.xxHash, Version=1.0.5.0, Culture=neutral, PublicKeyToken=32cd54395057cec3, processorArchitecture=MSIL">
|
<Reference Include="K4os.Hash.xxHash, Version=1.0.5.0, Culture=neutral, PublicKeyToken=32cd54395057cec3, processorArchitecture=MSIL">
|
||||||
<HintPath>..\Switch_Toolbox\Lib\K4os.Hash.xxHash.dll</HintPath>
|
<HintPath>..\Switch_Toolbox\Lib\K4os.Hash.xxHash.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="LZ4">
|
<Reference Include="LZ4, Version=1.0.15.93, Culture=neutral, PublicKeyToken=62e1b5ec1eec9bdd, processorArchitecture=MSIL">
|
||||||
<HintPath>..\Switch_Toolbox\Lib\LZ4.dll</HintPath>
|
<HintPath>..\packages\lz4net.1.0.15.93\lib\net4-client\LZ4.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Microsoft.VisualBasic" />
|
<Reference Include="Microsoft.VisualBasic" />
|
||||||
<Reference Include="OpenTK">
|
<Reference Include="OpenTK">
|
||||||
|
@ -129,6 +129,12 @@
|
||||||
<Compile Include="GUI\Assimp Settings.Designer.cs">
|
<Compile Include="GUI\Assimp Settings.Designer.cs">
|
||||||
<DependentUpon>Assimp Settings.cs</DependentUpon>
|
<DependentUpon>Assimp Settings.cs</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="GUI\CubeMapFaceCreator.cs">
|
||||||
|
<SubType>Form</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="GUI\CubeMapFaceCreator.Designer.cs">
|
||||||
|
<DependentUpon>CubeMapFaceCreator.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<Compile Include="GUI\Viewport.cs">
|
<Compile Include="GUI\Viewport.cs">
|
||||||
<SubType>Form</SubType>
|
<SubType>Form</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
@ -223,6 +229,9 @@
|
||||||
<EmbeddedResource Include="GUI\AssimpMeshSelector.resx">
|
<EmbeddedResource Include="GUI\AssimpMeshSelector.resx">
|
||||||
<DependentUpon>AssimpMeshSelector.cs</DependentUpon>
|
<DependentUpon>AssimpMeshSelector.cs</DependentUpon>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="GUI\CubeMapFaceCreator.resx">
|
||||||
|
<DependentUpon>CubeMapFaceCreator.cs</DependentUpon>
|
||||||
|
</EmbeddedResource>
|
||||||
<EmbeddedResource Include="GUI\ObjectList.resx">
|
<EmbeddedResource Include="GUI\ObjectList.resx">
|
||||||
<DependentUpon>ObjectList.cs</DependentUpon>
|
<DependentUpon>ObjectList.cs</DependentUpon>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
|
|
|
@ -33,6 +33,17 @@ 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 byte[] CombineByteArray(params byte[][] arrays)
|
||||||
|
{
|
||||||
|
byte[] rv = new byte[arrays.Sum(a => a.Length)];
|
||||||
|
int offset = 0;
|
||||||
|
foreach (byte[] array in arrays)
|
||||||
|
{
|
||||||
|
System.Buffer.BlockCopy(array, 0, rv, offset, array.Length);
|
||||||
|
offset += array.Length;
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
static int i = 0;
|
static int i = 0;
|
||||||
public static string RenameDuplicateString(List<string> strings, string oldString)
|
public static string RenameDuplicateString(List<string> strings, string oldString)
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,3 +11,10 @@ C:\Users\Nathan\Documents\GitHub\Switch_Toolbox\Switch-Toolbox\Updater\bin\Relea
|
||||||
C:\Users\Nathan\Documents\GitHub\Switch_Toolbox\Switch-Toolbox\Updater\obj\Release\Updater.csproj.CoreCompileInputs.cache
|
C:\Users\Nathan\Documents\GitHub\Switch_Toolbox\Switch-Toolbox\Updater\obj\Release\Updater.csproj.CoreCompileInputs.cache
|
||||||
C:\Users\Nathan\Documents\GitHub\Switch_Toolbox\Switch-Toolbox\Updater\obj\Release\Updater.exe
|
C:\Users\Nathan\Documents\GitHub\Switch_Toolbox\Switch-Toolbox\Updater\obj\Release\Updater.exe
|
||||||
C:\Users\Nathan\Documents\GitHub\Switch_Toolbox\Switch-Toolbox\Updater\obj\Release\Updater.pdb
|
C:\Users\Nathan\Documents\GitHub\Switch_Toolbox\Switch-Toolbox\Updater\obj\Release\Updater.pdb
|
||||||
|
C:\Users\Nathan\Documents\GitHub\Switch_Toolbox\Switch-Toolbox - Copy\Updater\bin\Release\Updater.exe.config
|
||||||
|
C:\Users\Nathan\Documents\GitHub\Switch_Toolbox\Switch-Toolbox - Copy\Updater\bin\Release\Updater.exe
|
||||||
|
C:\Users\Nathan\Documents\GitHub\Switch_Toolbox\Switch-Toolbox - Copy\Updater\bin\Release\Updater.pdb
|
||||||
|
C:\Users\Nathan\Documents\GitHub\Switch_Toolbox\Switch-Toolbox - Copy\Updater\obj\Release\Updater.csprojAssemblyReference.cache
|
||||||
|
C:\Users\Nathan\Documents\GitHub\Switch_Toolbox\Switch-Toolbox - Copy\Updater\obj\Release\Updater.csproj.CoreCompileInputs.cache
|
||||||
|
C:\Users\Nathan\Documents\GitHub\Switch_Toolbox\Switch-Toolbox - Copy\Updater\obj\Release\Updater.exe
|
||||||
|
C:\Users\Nathan\Documents\GitHub\Switch_Toolbox\Switch-Toolbox - Copy\Updater\obj\Release\Updater.pdb
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in a new issue