1
0
mirror of synced 2024-11-30 18:24:39 +01:00

Many more bug fixes and layout rendering improvements.

Add support for BCLAN.  (It's basically the same as BRLAN)
Fix saving for BRLAN.
Fix 3DS textures being upside down for BCLYT.
Improve BCLYT rendering.
Improve texture transforms for BCLYT and BFLYT.
Fix tev stage properties not appearing for BCLYT editor.
Fix C4 and C8 decoding.
This commit is contained in:
KillzXGaming 2020-02-12 16:56:16 -05:00
parent 5ce973f3e7
commit 6129ab2b4e
34 changed files with 1158 additions and 476 deletions

View File

@ -100,7 +100,7 @@ namespace FirstPlugin
reader.ReadUInt32(); //0
reader.ReadUInt32(); //0
//Skip an unknown section that is 64 bytes in size
//Skip an unknown section that is 32 bytes in size
reader.Seek(unkSectionCount * 32);
for (int i = 0; i < FileCount; i++)

View File

@ -83,6 +83,8 @@ namespace FirstPlugin.CtrLibrary
vertex.uv2 = ConvertVector2(vertices[v].TexCoord2);
vertex.col = ConvertVector4(vertices[v].Color);
//Flip UVs
vertex.uv0 = new Vector2(vertex.uv0.X, 1 - vertex.uv0.Y);
if (boneIndices.Count > 0)
{
/* if (vertices[v].Indices.b0 != -1) vertex.boneIds.Add(boneIndices[vertices[v].Indices.b0]);

View File

@ -330,7 +330,7 @@ namespace FirstPlugin
{
vert.uv0 = new OpenTK.Vector2(
shape.TexCoord0.VertexData[v].X,
shape.TexCoord0.VertexData[v].Y);
1 - shape.TexCoord0.VertexData[v].Y);
}
if (shape.TexCoord1.VertexData != null)

View File

@ -280,7 +280,7 @@ namespace LayoutBXLYT
GL.ActiveTexture(TextureUnit.Texture0 + id);
mat.Shader.SetInt($"textures{i}", id);
bool binded = BindGLTexture(mat.TextureMaps[i], textures[TexName]);
mat.Shader.SetInt($"hasTexture{i}", 1);
mat.Shader.SetInt($"hasTexture{i}", binded ? 1 : 0);
var scale = new Syroot.Maths.Vector2F(1, 1);
float rotate = 0;

View File

@ -130,28 +130,49 @@ namespace LayoutBXLYT
shader.SetInt($"tevStage{i}A", (int)material.TevStages[i].AlphaMode);
}
if (material.TextureTransforms.Length > 0)
{
var transform = material.TextureTransforms[0];
var scale = transform.Scale;
var rotate = transform.Rotate;
var translate = transform.Translate;
for (int i = 0; i < 3; i++) {
Matrix4 matTransform = Matrix4.Identity;
shader.SetMatrix(String.Format("textureTransforms[{0}]", i), ref matTransform);
}
foreach (var animItem in material.animController.TextureSRTS)
for (int i = 0; i < material.TextureMaps.Length; i++)
{
var scale = new Syroot.Maths.Vector2F(1, 1);
float rotate = 0;
var translate = new Syroot.Maths.Vector2F(0, 0);
int index = i;
// if (material.TexCoordGens?.Length > i)
// index = (int)material.TexCoordGens[i].Source / 3 - 10;
if (material.TextureTransforms.Length > index)
{
switch (animItem.Key)
var transform = material.TextureTransforms[index];
scale = transform.Scale;
rotate = transform.Rotate;
translate = transform.Translate;
foreach (var animItem in material.animController.TextureSRTS)
{
case LTSTarget.ScaleS: scale.X = animItem.Value; break;
case LTSTarget.ScaleT: scale.Y = animItem.Value; break;
case LTSTarget.Rotate: rotate = animItem.Value; break;
case LTSTarget.TranslateS: translate.X = animItem.Value; break;
case LTSTarget.TranslateT: translate.Y = animItem.Value; break;
switch (animItem.Key)
{
case LTSTarget.ScaleS: scale.X = animItem.Value; break;
case LTSTarget.ScaleT: scale.Y = animItem.Value; break;
case LTSTarget.Rotate: rotate = animItem.Value; break;
case LTSTarget.TranslateS: translate.X = animItem.Value; break;
case LTSTarget.TranslateT: translate.Y = animItem.Value; break;
}
}
}
shader.SetVec2("uvScale0", new Vector2(scale.X, scale.Y));
shader.SetFloat("uvRotate0", rotate);
shader.SetVec2("uvTranslate0", new Vector2(translate.X, translate.Y));
var matScale = Matrix4.CreateScale(scale.X, scale.Y, 1.0f);
var matRotate = Matrix4.CreateFromAxisAngle(new Vector3(0, 0, 1), MathHelper.DegreesToRadians(rotate));
var matTranslate = Matrix4.CreateTranslation(
translate.X / scale.X - 0.5f,
translate.Y / scale.Y - 0.5f, 0);
Matrix4 matTransform = matRotate * matTranslate * matScale;
shader.SetMatrix(String.Format("textureTransforms[{0}]", i), ref matTransform);
}

View File

@ -0,0 +1,454 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using Toolbox;
using System.Windows.Forms;
using Toolbox.Library;
using Toolbox.Library.IO;
using SharpYaml.Serialization;
namespace LayoutBXLYT
{
public class BCLAN : BXLAN, IEditorForm<LayoutEditor>, IFileFormat, IConvertableTextFormat
{
public FileType FileType { get; set; } = FileType.Layout;
public bool CanSave { get; set; }
public string[] Description { get; set; } = new string[] { "Ctr Layout Animation (GUI)" };
public string[] Extension { get; set; } = new string[] { "*.bclan" };
public string FileName { get; set; }
public string FilePath { get; set; }
public IFileInfo IFileInfo { get; set; }
public bool Identify(System.IO.Stream stream)
{
using (var reader = new Toolbox.Library.IO.FileReader(stream, true))
{
return reader.CheckSignature(4, "CLAN");
}
}
public Type[] Types
{
get
{
List<Type> types = new List<Type>();
return types.ToArray();
}
}
#region Text Converter Interface
public TextFileType TextFileType => TextFileType.Xml;
public bool CanConvertBack => true;
public string ConvertToString()
{
return "";
}
public void ConvertFromString(string text)
{
BxlanHeader = FLAN.FromXml(text);
BxlanHeader.FileInfo = this;
}
#endregion
public void Load(System.IO.Stream stream)
{
CanSave = true;
BxlanHeader = new Header();
BxlanHeader.Read(new FileReader(stream),this);
}
public void Unload()
{
}
public void Save(System.IO.Stream stream) {
BxlanHeader.Write(new FileWriter(stream));
}
public LayoutEditor OpenForm()
{
LayoutEditor editor = new LayoutEditor();
editor.Dock = DockStyle.Fill;
editor.LoadBxlan(BxlanHeader);
return editor;
}
public void FillEditor(Form control)
{
((LayoutEditor)control).LoadBxlan(BxlanHeader);
}
public class Header : BxlanHeader
{
private const string Magic = "CLAN";
private ushort ByteOrderMark;
private ushort HeaderSize;
//As of now this should be empty but just for future proofing
private List<SectionCommon> UnknownSections = new List<SectionCommon>();
public override void Read(FileReader reader, BXLAN bflan)
{
AnimationTag = new PAT1();
AnimationInfo = new PAI1();
reader.SetByteOrder(true);
reader.ReadSignature(4, Magic);
ByteOrderMark = reader.ReadUInt16();
reader.CheckByteOrderMark(ByteOrderMark);
HeaderSize = reader.ReadUInt16();
Version = reader.ReadUInt32();
SetVersionInfo();
uint FileSize = reader.ReadUInt32();
ushort sectionCount = reader.ReadUInt16();
reader.ReadUInt16(); //Padding
FileInfo = (IFileFormat)bflan;
IsBigEndian = reader.ByteOrder == Syroot.BinaryData.ByteOrder.BigEndian;
reader.SeekBegin(HeaderSize);
for (int i = 0; i < sectionCount; i++)
{
long pos = reader.Position;
string Signature = reader.ReadString(4, Encoding.ASCII);
uint SectionSize = reader.ReadUInt32();
SectionCommon section = new SectionCommon(Signature);
switch (Signature)
{
case "pat1":
AnimationTag = new PAT1(reader, this);
break;
case "pai1":
AnimationInfo = new PAI1(reader, this);
break;
default:
section.Data = reader.ReadBytes((int)SectionSize - 8);
UnknownSections.Add(section);
break;
}
section.SectionSize = SectionSize;
reader.SeekBegin(pos + SectionSize);
}
}
public override void Write(FileWriter writer)
{
writer.SetByteOrder(true);
writer.WriteSignature(Magic);
if (!IsBigEndian)
writer.Write((ushort)0xFFFE);
else
writer.Write((ushort)0xFEFF);
writer.SetByteOrder(IsBigEndian);
writer.Write(HeaderSize);
writer.Write(Version);
writer.Write(uint.MaxValue); //Reserve space for file size later
writer.Write(ushort.MaxValue); //Reserve space for section count later
writer.Seek(2); //padding
int sectionCount = 0;
WriteSection(writer, "pat1", AnimationTag, () => AnimationTag.Write(writer, this));
sectionCount++;
WriteSection(writer, "pai1", AnimationInfo, () => AnimationInfo.Write(writer, this));
sectionCount++;
foreach (var section in UnknownSections)
{
WriteSection(writer, section.Signature, section, () => section.Write(writer, this));
sectionCount++;
}
//Write the total section count
using (writer.TemporarySeek(0x10, System.IO.SeekOrigin.Begin))
{
writer.Write((ushort)sectionCount);
}
//Write the total file size
using (writer.TemporarySeek(0x0C, System.IO.SeekOrigin.Begin))
{
writer.Write((uint)writer.BaseStream.Length);
}
}
}
public class PAT1 : BxlanPAT1
{
private byte[] UnknownData;
private byte flags;
public PAT1()
{
AnimationOrder = 2;
Name = "";
EndFrame = 0;
StartFrame = 0;
ChildBinding = false;
Groups = new List<string>();
}
public PAT1(FileReader reader, Header header)
{
long startPos = reader.Position - 8;
Groups = new List<string>();
AnimationOrder = reader.ReadUInt16();
ushort groupCount = reader.ReadUInt16();
uint animNameOffset = reader.ReadUInt32();
uint groupNamesOffset = reader.ReadUInt32();
StartFrame = reader.ReadInt16();
EndFrame = reader.ReadInt16();
ChildBinding = reader.ReadBoolean();
UnknownData = reader.ReadBytes((int)(startPos + animNameOffset - reader.Position));
reader.SeekBegin(startPos + animNameOffset);
Name = reader.ReadZeroTerminatedString();
reader.SeekBegin(startPos + groupNamesOffset);
for (int i = 0; i < groupCount; i++)
Groups.Add(reader.ReadString(0x14, true));
}
public override void Write(FileWriter writer, LayoutHeader header)
{
long startPos = writer.Position - 8;
writer.Write(AnimationOrder);
writer.Write((ushort)Groups.Count);
writer.Write(uint.MaxValue); //animNameOffset
writer.Write(uint.MaxValue); //groupNamesOffset
if (header.VersionMajor >= 8)
writer.Write(0); //unk
writer.Write((ushort)StartFrame);
writer.Write((ushort)EndFrame);
writer.Write(ChildBinding);
writer.Write(UnknownData);
writer.WriteUint32Offset(startPos + 12, startPos);
writer.WriteString(Name);
writer.Align(4);
writer.WriteUint32Offset(startPos + 16, startPos);
for (int i = 0; i < Groups.Count; i++)
writer.WriteString(Groups[i], 0x14);
writer.Align(4);
}
}
public class PAI1 : BxlanPAI1
{
public PAI1()
{
Textures = new List<string>();
}
public override BxlanPaiEntry AddEntry(string name, byte target) {
var entry = new PaiEntry(name, target);
Entries.Add(entry);
return entry;
}
public PAI1(FileReader reader, Header header)
{
long startPos = reader.Position - 8;
Textures = new List<string>();
FrameSize = reader.ReadUInt16();
Loop = reader.ReadBoolean();
reader.ReadByte(); //padding
var numTextures = reader.ReadUInt16();
var numEntries = reader.ReadUInt16();
var entryOffsetTbl = reader.ReadUInt32();
long texStart = reader.Position;
var texOffsets = reader.ReadUInt32s(numTextures);
for (int i = 0; i < numTextures; i++)
{
reader.SeekBegin(texStart + texOffsets[i]);
Textures.Add(reader.ReadZeroTerminatedString());
}
reader.SeekBegin(startPos + entryOffsetTbl);
var entryOffsets = reader.ReadUInt32s(numEntries);
for (int i = 0; i < numEntries; i++)
{
reader.SeekBegin(startPos + entryOffsets[i]);
Entries.Add(new PaiEntry(reader, header));
}
}
public override void Write(FileWriter writer, LayoutHeader header)
{
long startPos = writer.Position - 8;
writer.Write(FrameSize);
writer.Write(Loop);
writer.Write((byte)0);
writer.Write((ushort)Textures.Count);
writer.Write((ushort)Entries.Count);
long entryOfsTblPos = writer.Position;
writer.Write(0);
if (Textures.Count > 0)
{
long startOfsPos = writer.Position;
writer.Write(new uint[Textures.Count]);
for (int i = 0; i < Textures.Count; i++)
{
writer.WriteUint32Offset(startOfsPos + (i * 4), startPos);
writer.WriteString(Textures[i]);
}
}
if (Entries.Count > 0)
{
writer.WriteUint32Offset(entryOfsTblPos, startPos);
long startOfsPos = writer.Position;
writer.Write(new uint[Entries.Count]);
for (int i = 0; i < Entries.Count; i++)
{
writer.WriteUint32Offset(startOfsPos + (i * 4), startPos);
((PaiEntry)Entries[i]).Write(writer, header);
}
}
}
}
public class PaiEntry : BxlanPaiEntry
{
public override BxlanPaiTag AddEntry(string tag) {
var paiTag = new PaiTag(tag);
Tags.Add(paiTag);
return paiTag;
}
public PaiEntry(string name, byte target)
{
Name = name;
Target = (AnimationTarget)target;
}
public PaiEntry(FileReader reader, Header header)
{
long startPos = reader.Position;
Name = reader.ReadString(0x14, true);
var numTags = reader.ReadByte();
Target = reader.ReadEnum<AnimationTarget>(false);
reader.ReadUInt16(); //padding
var offsets = reader.ReadUInt32s(numTags);
for (int i = 0; i < numTags; i++)
{
reader.SeekBegin(startPos + offsets[i]);
Tags.Add(new PaiTag(reader, header, Target));
}
}
public void Write(FileWriter writer, LayoutHeader header)
{
long startPos = writer.Position;
writer.WriteString(Name, 0x14);
writer.Write((byte)Tags.Count);
writer.Write(Target, false);
writer.Write((ushort)0);
if (Tags.Count > 0)
{
writer.Write(new uint[Tags.Count]);
for (int i = 0; i < Tags.Count; i++)
{
writer.WriteUint32Offset(startPos + 24 + (i * 4), startPos);
((PaiTag)Tags[i]).Write(writer, header, Target);
}
}
}
}
public class PaiTag : BxlanPaiTag
{
private uint Unknown {get;set;}
public PaiTag(string tag)
{
Tag = tag;
}
public PaiTag(FileReader reader, BxlanHeader header, AnimationTarget target)
{
if ((byte)target == 2)
Unknown = reader.ReadUInt32(); //This doesn't seem to be included in the offsets to the entries (?)
long startPos = reader.Position;
Tag = reader.ReadString(4, Encoding.ASCII);
var numEntries = reader.ReadByte();
reader.Seek(3);
var offsets = reader.ReadUInt32s((int)numEntries);
for (int i = 0; i < numEntries; i++)
{
reader.SeekBegin(startPos + offsets[i]);
switch (Tag)
{
case "CLPA":
Entries.Add(new LPATagEntry(reader, header));
break;
case "CLTS":
Entries.Add(new LTSTagEntry(reader, header));
break;
case "CLVI":
Entries.Add(new LVITagEntry(reader, header));
break;
case "CLVC":
Entries.Add(new LVCTagEntry(reader, header));
break;
case "CLMC":
Entries.Add(new LMCTagEntry(reader, header));
break;
case "CLTP":
Entries.Add(new LTPTagEntry(reader, header));
break;
default:
Entries.Add(new BxlanPaiTagEntry(reader, header));
break;
}
}
}
public void Write(FileWriter writer, LayoutHeader header, AnimationTarget target)
{
if ((byte)target == 2)
writer.Write(Unknown);
long startPos = writer.Position;
writer.WriteSignature(Tag);
writer.Write((byte)Entries.Count);
writer.Seek(3);
writer.Write(new uint[Entries.Count]);
for (int i = 0; i < Entries.Count; i++)
{
writer.WriteUint32Offset(startPos + 8 + (i * 4), startPos);
((BxlanPaiTagEntry)Entries[i]).Write(writer, header);
}
}
}
}
}

View File

@ -341,6 +341,9 @@ namespace LayoutBXLYT
reader.ReadUInt16(); //Padding
IsBigEndian = reader.ByteOrder == Syroot.BinaryData.ByteOrder.BigEndian;
TextureManager.LayoutFile = this;
TextureManager.Platform = TextureManager.PlatformType.ThreeDS;
bool setRoot = false;
bool setGroupRoot = false;

View File

@ -62,25 +62,66 @@ namespace LayoutBXLYT
BindTextureUniforms(shader, material);
string textureMap0 = "";
if (material.TextureMaps.Length > 0)
textureMap0 = material.GetTexture(0);
if (textures.ContainsKey(textureMap0))
int id = 1;
for (int i = 0; i < material.TextureMaps.Length; i++)
{
GL.ActiveTexture(TextureUnit.Texture0);
shader.SetInt("textures0", 0);
bool isBinded = BxlytToGL.BindGLTexture(material.TextureMaps[0], textures[textureMap0]);
if (isBinded)
shader.SetInt("hasTexture0", 1);
string TexName = material.TextureMaps[i].Name;
if (material.animController.TexturePatterns.ContainsKey((LTPTarget)i))
TexName = material.animController.TexturePatterns[(LTPTarget)i];
shader.SetInt($"hasTexture{i}", 0);
if (textures.ContainsKey(TexName))
{
GL.ActiveTexture(TextureUnit.Texture0 + id);
shader.SetInt($"textures{i}", id);
bool binded = BxlytToGL.BindGLTexture(material.TextureMaps[i], textures[TexName]);
shader.SetInt($"hasTexture{i}", binded ? 1 : 0);
id++;
}
}
if (material.TextureTransforms.Length > 0)
{
var transform = material.TextureTransforms[0];
shader.SetVec2("uvScale0", new Vector2(transform.Scale.X, transform.Scale.Y));
shader.SetFloat("uvRotate0", transform.Rotate);
shader.SetVec2("uvTranslate0", new Vector2(transform.Translate.X, transform.Translate.Y));
for (int i = 0; i < 3; i++) {
Matrix4 matTransform = Matrix4.Identity;
shader.SetMatrix(String.Format("textureTransforms[{0}]", i), ref matTransform);
}
for (int i = 0; i < material.TextureMaps.Length; i++) {
var scale = new Syroot.Maths.Vector2F(1, 1);
float rotate = 0;
var translate = new Syroot.Maths.Vector2F(0, 0);
int index = i;
// if (material.TexCoordGens?.Length > i)
// index = (int)material.TexCoordGens[i].Source / 3 - 10;
if (material.TextureTransforms.Length > index)
{
var transform = material.TextureTransforms[index];
scale = transform.Scale;
rotate = transform.Rotate;
translate = transform.Translate;
foreach (var animItem in material.animController.TextureSRTS)
{
switch (animItem.Key)
{
case LTSTarget.ScaleS: scale.X = animItem.Value; break;
case LTSTarget.ScaleT: scale.Y = animItem.Value; break;
case LTSTarget.Rotate: rotate = animItem.Value; break;
case LTSTarget.TranslateS: translate.X = animItem.Value; break;
case LTSTarget.TranslateT: translate.Y = animItem.Value; break;
}
}
}
var matScale = Matrix4.CreateScale(scale.X, scale.Y, 1.0f);
var matRotate = Matrix4.CreateFromAxisAngle(new Vector3(0, 0, 1), MathHelper.DegreesToRadians(rotate));
var matTranslate = Matrix4.CreateTranslation(
translate.X / scale.X - 0.5f,
translate.Y / scale.Y - 0.5f, 0);
Matrix4 matTransform = matRotate * matTranslate * matScale;
shader.SetMatrix(String.Format("textureTransforms[{0}]", i), ref matTransform);
}
}

View File

@ -68,6 +68,20 @@ namespace LayoutBXLYT.CTR
PaneMagFlags = 0;
}
enum OriginXRev : byte
{
Left = 0,
Center = 1,
Right = 2
};
enum OriginYRev : byte
{
Top = 0,
Center = 1,
Bottom = 2
};
public PAN1(FileReader reader, BxlytHeader header) : base()
{
_flags1 = reader.ReadByte();
@ -81,26 +95,17 @@ namespace LayoutBXLYT.CTR
Width = reader.ReadSingle();
Height = reader.ReadSingle();
int mainorigin = origin % 16;
int parentorigin = origin / 16;
originX = (OriginX)(mainorigin % 4);
originY = (OriginY)(mainorigin / 4);
ParentOriginX = (OriginX)(parentorigin % 4);
ParentOriginY = (OriginY)(parentorigin / 4);
originX = OriginXMap[(OriginXRev)(origin % 3)];
originY = OriginYMap[(OriginYRev)(origin / 3)];
}
public override void Write(FileWriter writer, LayoutHeader header)
{
int originL = (int)originX;
int originH = (int)originY * 4;
int originPL = (int)ParentOriginX;
int originPH = (int)ParentOriginY * 4;
byte parentorigin = (byte)((originPL + originPH) * 16);
byte origin = (byte)(originL + originH + parentorigin);
byte originL = (byte)OriginXMap.FirstOrDefault(x => x.Value == originX).Key;
byte originH = (byte)OriginYMap.FirstOrDefault(x => x.Value == originY).Key;
writer.Write(_flags1);
writer.Write(origin);
writer.Write((byte)(((int)originL) + ((int)originH * 3)));
writer.Write(Alpha);
writer.Write(PaneMagFlags);
writer.WriteString(Name, 0x18);
@ -111,6 +116,20 @@ namespace LayoutBXLYT.CTR
writer.Write(Height);
}
private Dictionary<OriginYRev, OriginY> OriginYMap = new Dictionary<OriginYRev, OriginY>()
{
{ OriginYRev.Center, OriginY.Center },
{ OriginYRev.Top, OriginY.Top },
{ OriginYRev.Bottom, OriginY.Bottom },
};
private Dictionary<OriginXRev, OriginX> OriginXMap = new Dictionary<OriginXRev, OriginX>()
{
{ OriginXRev.Center, OriginX.Center },
{ OriginXRev.Left, OriginX.Left },
{ OriginXRev.Right, OriginX.Right },
};
public bool ParentVisibility
{
get

View File

@ -1441,7 +1441,7 @@ namespace LayoutBXLYT
BottomRight = reader.ReadVec2SY(),
});
Material = LayoutFile.GetMaterial(MaterialIndex);
Material = LayoutFile.Materials[MaterialIndex];
}
public void Write(FileWriter writer)
@ -1491,7 +1491,7 @@ namespace LayoutBXLYT
TextureFlip = (WindowFrameTexFlip)reader.ReadByte();
reader.ReadByte(); //padding
Material = header.GetMaterial(MaterialIndex);
Material = header.Materials[MaterialIndex];
}
public void Write(FileWriter writer)
@ -1793,6 +1793,7 @@ namespace LayoutBXLYT
public BxlanPaiTagEntry CreateTarget(object TargetType, byte interpolationType)
{
byte target = (byte)TargetType;
string tagType = Tag.Remove(0, 1);
switch (tagType)
{
@ -1850,6 +1851,20 @@ namespace LayoutBXLYT
{"RLCC","PerCharacterTransformCurve" },
};
public static Dictionary<string, string> CtrTypeDefine = new Dictionary<string, string>()
{
{"CLPA","PaneSRT" },
{"CLVI","Visibility" },
{"CLTS","TextureSRT" },
{"CLVC","VertexColor" },
{"CLMC","MaterialColor" },
{"CLTP","TexturePattern" },
{"CLIM","IndTextureSRT" },
{"CLAC","AlphaTest" },
{"CLCT","FontShadow" },
{"CLCC","PerCharacterTransformCurve" },
};
public static Dictionary<string, string> TypeDefine = new Dictionary<string, string>()
{
{"FLPA","PaneSRT" },

View File

@ -232,7 +232,7 @@ namespace LayoutBXLYT
reader.SeekBegin(startPos + groupNamesOffset);
for (int i = 0; i < groupCount; i++)
Groups.Add(reader.ReadString(28, true));
Groups.Add(reader.ReadString(0x14, true));
}
public override void Write(FileWriter writer, LayoutHeader header)
@ -254,7 +254,7 @@ namespace LayoutBXLYT
writer.WriteUint32Offset(startPos + 16, startPos);
for (int i = 0; i < Groups.Count; i++)
writer.WriteString(Groups[i], 28);
writer.WriteString(Groups[i], 0x14);
}
}
@ -365,7 +365,7 @@ namespace LayoutBXLYT
writer.Write(new uint[Tags.Count]);
for (int i = 0; i < Tags.Count; i++)
{
writer.WriteUint32Offset(startPos + 32 + (i * 4), startPos);
writer.WriteUint32Offset(startPos + 24 + (i * 4), startPos);
((PaiTag)Tags[i]).Write(writer, header, Target);
}
}

View File

@ -314,6 +314,8 @@ namespace LayoutBXLYT
ushort sectionCount = reader.ReadUInt16();
IsBigEndian = reader.ByteOrder == Syroot.BinaryData.ByteOrder.BigEndian;
TextureManager.LayoutFile = this;
TextureManager.Platform = TextureManager.PlatformType.Wii;
bool setRoot = false;
bool setGroupRoot = false;

View File

@ -130,8 +130,8 @@ namespace LayoutBXLYT.Revolution
TextureMaps = TextureMaps.AddToArray(textureRef);
TexCoordGens.Add(new TexCoordGenEntry()
{
MatrixSource = TexCoordGenEntry.TexCoordGenMatrixSource.GX_DTTMTX9 + (TexCoordGens.Count * 4),
Source = TexCoordGenEntry.TexCoordGenSource.GX_TG_TEX0
MatrixSource = TexCoordGenMatrixSource.GX_DTTMTX9 + (TexCoordGens.Count * 4),
Source = TexCoordGenSource.GX_TG_TEX0
});
TextureTransforms = TextureTransforms.AddToArray(new BxlytTextureTransform());
}

View File

@ -0,0 +1,366 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LayoutBXLYT.Revolution
{
//Thanks brawlbox. Layouts should work with these
//https://github.com/libertyernie/brawltools/blob/40d7431b1a01ef4a0411cd69e51411bd581e93e2/BrawlLib/Wii/Graphics/Enum.cs
public enum ColorArg : byte
{
OutputColor,//GX_CC_CPREV,
OutputAlpha,//GX_CC_APREV,
Color0,//GX_CC_C0,
Alpha0,//GX_CC_A0,
Color1,//GX_CC_C1,
Alpha1,//GX_CC_A1,
Color2,//GX_CC_C2,
Alpha2,//GX_CC_A2,
TextureColor,//GX_CC_TEXC,
TextureAlpha,//GX_CC_TEXA,
RasterColor,//GX_CC_RASC,
RasterAlpha,//GX_CC_RASA,
One,//GX_CC_ONE, //1
Half,//GX_CC_HALF, //0.5
ConstantColorSelection,//GX_CC_KONST,
Zero//GX_CC_ZERO //0
}
public enum Bias
{
Zero,//GX_TB_ZERO,
AddHalf,//GX_TB_ADDHALF,
SubHalf//GX_TB_SUBHALF
}
public enum TevColorRegID
{
OutputColor,
Color0,
Color1,
Color2,
}
public enum TevColorOp
{
Add = 0,
Subtract = 1,
CompR8Greater = 8,
CompR8Equal = 9,
CompGR16Greater = 10,
CompGR16Equal = 11,
CompBGR24Greater = 12,
CompBGR24Equal = 13,
CompRGB8Greater = 14,
CompRGB8Equal = 15,
//GX_TEV_COMP_A8_GT = GX_TEV_COMP_RGB8_GT, // for alpha channel
//GX_TEV_COMP_A8_EQ = GX_TEV_COMP_RGB8_EQ // for alpha channel
}
public enum TevAlphaRegID
{
OutputAlpha,
Alpha0,
Alpha1,
Alpha2,
}
public enum AlphaArg
{
OutputAlpha,//GX_CA_APREV,
Alpha0,//GX_CA_A0,
Alpha1,//GX_CA_A1,
Alpha2,//GX_CA_A2,
TextureAlpha,//GX_CA_TEXA,
RasterAlpha,//GX_CA_RASA,
ConstantAlphaSelection,//GX_CA_KONST,
Zero//GX_CA_ZERO //0
}
public enum TevAlphaOp
{
And,//ALPHAOP_AND = 0,
Or,//ALPHAOP_OR,
ExclusiveOr,//ALPHAOP_XOR,
InverseExclusiveOr//ALPHAOP_XNOR
}
public enum TevScale
{
MultiplyBy1,//GX_CS_SCALE_1,
MultiplyBy2,//GX_CS_SCALE_2,
MultiplyBy4,//GX_CS_SCALE_4,
DivideBy2//GX_CS_DIVIDE_2
}
public enum TevKAlphaSel
{
Constant1_1/*GX_TEV_KASEL_8_8*/ = 0x00, //1.0f
Constant7_8/*GX_TEV_KASEL_7_8*/ = 0x01, //0.875f
Constant3_4/*GX_TEV_KASEL_6_8*/ = 0x02, //0.75f
Constant5_8/*GX_TEV_KASEL_5_8*/ = 0x03, //0.625f
Constant1_2/*GX_TEV_KASEL_4_8*/ = 0x04, //0.5f
Constant3_8/*GX_TEV_KASEL_3_8*/ = 0x05, //0.375f
Constant1_4/*GX_TEV_KASEL_2_8*/ = 0x06, //0.25f
Constant1_8/*GX_TEV_KASEL_1_8*/ = 0x07, //0.125f
//GX_TEV_KASEL_1 = GX_TEV_KASEL_8_8,
//GX_TEV_KASEL_3_4 = GX_TEV_KASEL_6_8,
//GX_TEV_KASEL_1_2 = GX_TEV_KASEL_4_8,
//GX_TEV_KASEL_1_4 = GX_TEV_KASEL_2_8,
ConstantColor0_Red/*GX_TEV_KASEL_K0_R*/ = 0x10,
ConstantColor1_Red/*GX_TEV_KASEL_K1_R*/ = 0x11,
ConstantColor2_Red/*GX_TEV_KASEL_K2_R*/ = 0x12,
ConstantColor3_Red/*GX_TEV_KASEL_K3_R*/ = 0x13,
ConstantColor0_Green/*GX_TEV_KASEL_K0_G*/ = 0x14,
ConstantColor1_Green/*GX_TEV_KASEL_K1_G*/ = 0x15,
ConstantColor2_Green/*GX_TEV_KASEL_K2_G*/ = 0x16,
ConstantColor3_Green/*GX_TEV_KASEL_K3_G*/ = 0x17,
ConstantColor0_Blue/*GX_TEV_KASEL_K0_B*/ = 0x18,
ConstantColor1_Blue/*GX_TEV_KASEL_K1_B*/ = 0x19,
ConstantColor2_Blue/*GX_TEV_KASEL_K2_B*/ = 0x1A,
ConstantColor3_Blue/*GX_TEV_KASEL_K3_B*/ = 0x1B,
ConstantColor0_Alpha/*GX_TEV_KASEL_K0_A*/ = 0x1C,
ConstantColor1_Alpha/*GX_TEV_KASEL_K1_A*/ = 0x1D,
ConstantColor2_Alpha/*GX_TEV_KASEL_K2_A*/ = 0x1E,
ConstantColor3_Alpha/*GX_TEV_KASEL_K3_A*/ = 0x1F
}
public enum TevKColorSel
{
Constant1_1/*GX_TEV_KCSEL_8_8*/ = 0x00, //1.0f, 1.0f, 1.0f
Constant7_8/*GX_TEV_KCSEL_7_8*/ = 0x01, //0.875f, 0.875f, 0.875f
Constant3_4/*GX_TEV_KCSEL_6_8*/ = 0x02, //0.75f, 0.75f, 0.75f
Constant5_8/*GX_TEV_KCSEL_5_8*/ = 0x03, //0.625f, 0.625f, 0.625f
Constant1_2/*GX_TEV_KCSEL_4_8*/ = 0x04, //0.5f, 0.5f, 0.5f
Constant3_8/*GX_TEV_KCSEL_3_8*/ = 0x05, //0.375f, 0.375f, 0.375f
Constant1_4/*GX_TEV_KCSEL_2_8*/ = 0x06, //0.25f, 0.25f, 0.25f
Constant1_8/*GX_TEV_KCSEL_1_8*/ = 0x07, //0.125f, 0.125f, 0.125f
//GX_TEV_KCSEL_1 = GX_TEV_KCSEL_8_8,
//GX_TEV_KCSEL_3_4 = GX_TEV_KCSEL_6_8,
//GX_TEV_KCSEL_1_2 = GX_TEV_KCSEL_4_8,
//GX_TEV_KCSEL_1_4 = GX_TEV_KCSEL_2_8,
ConstantColor0_RGB/*GX_TEV_KCSEL_K0*/ = 0x0C,
ConstantColor1_RGB/*GX_TEV_KCSEL_K1*/ = 0x0D,
ConstantColor2_RGB/*GX_TEV_KCSEL_K2*/ = 0x0E,
ConstantColor3_RGB/*GX_TEV_KCSEL_K3*/ = 0x0F,
ConstantColor0_RRR/*GX_TEV_KCSEL_K0_R*/ = 0x10,
ConstantColor1_RRR/*GX_TEV_KCSEL_K1_R*/ = 0x11,
ConstantColor2_RRR/*GX_TEV_KCSEL_K2_R*/ = 0x12,
ConstantColor3_RRR/*GX_TEV_KCSEL_K3_R*/ = 0x13,
ConstantColor0_GGG/*GX_TEV_KCSEL_K0_G*/ = 0x14,
ConstantColor1_GGG/*GX_TEV_KCSEL_K1_G*/ = 0x15,
ConstantColor2_GGG/*GX_TEV_KCSEL_K2_G*/ = 0x16,
ConstantColor3_GGG/*GX_TEV_KCSEL_K3_G*/ = 0x17,
ConstantColor0_BBB/*GX_TEV_KCSEL_K0_B*/ = 0x18,
ConstantColor1_BBB/*GX_TEV_KCSEL_K1_B*/ = 0x19,
ConstantColor2_BBB/*GX_TEV_KCSEL_K2_B*/ = 0x1A,
ConstantColor3_BBB/*GX_TEV_KCSEL_K3_B*/ = 0x1B,
ConstantColor0_AAA/*GX_TEV_KCSEL_K0_A*/ = 0x1C,
ConstantColor1_AAA/*GX_TEV_KCSEL_K1_A*/ = 0x1D,
ConstantColor2_AAA/*GX_TEV_KCSEL_K2_A*/ = 0x1E,
ConstantColor3_AAA/*GX_TEV_KCSEL_K3_A*/ = 0x1F
}
public enum TevSwapSel : ushort
{
Swap0,//GX_TEV_SWAP0 = 0,
Swap1,//GX_TEV_SWAP1,
Swap2,//GX_TEV_SWAP2,
Swap3,//GX_TEV_SWAP3
}
public enum TexMapID
{
TexMap0,//GX_TEXMAP0,
TexMap1,//GX_TEXMAP1,
TexMap2,//GX_TEXMAP2,
TexMap3,//GX_TEXMAP3,
TexMap4,//GX_TEXMAP4,
TexMap5,//GX_TEXMAP5,
TexMap6,//GX_TEXMAP6,
TexMap7,//GX_TEXMAP7,
//GX_MAX_TEXMAP,
//GX_TEXMAP_NULL = 0xff,
//GX_TEX_DISABLE = 0x100 // mask : disables texture look up
}
public enum TexCoordID
{
TexCoord0,//GX_TEXCOORD0 = 0x0, // generated texture coordinate 0
TexCoord1,//GX_TEXCOORD1, // generated texture coordinate 1
TexCoord2,//GX_TEXCOORD2, // generated texture coordinate 2
TexCoord3,//GX_TEXCOORD3, // generated texture coordinate 3
TexCoord4,//GX_TEXCOORD4, // generated texture coordinate 4
TexCoord5,//GX_TEXCOORD5, // generated texture coordinate 5
TexCoord6,//GX_TEXCOORD6, // generated texture coordinate 6
TexCoord7,//GX_TEXCOORD7, // generated texture coordinate 7
//GX_MAX_TEXCOORD = 8,
//GX_TEXCOORD_NULL = 0xff
}
public enum IndTexMtxID
{
NoMatrix,//GX_ITM_OFF,
Matrix0,//GX_ITM_0,
Matrix1,//GX_ITM_1,
Matrix2,//GX_ITM_2,
MatrixS0 = 5,//GX_ITM_S0 = 5,
MatrixS1,//GX_ITM_S1,
MatrixS2,//GX_ITM_S2,
MatrixT0 = 9, //GX_ITM_T0 = 9,
MatrixT1,//GX_ITM_T1,
MatrixT2,//GX_ITM_T2
}
public enum IndTexWrap
{
NoWrap,//GX_ITW_OFF, // no wrapping
Wrap256,//GX_ITW_256, // wrap 256
Wrap128,//GX_ITW_128, // wrap 128
Wrap64,//GX_ITW_64, // wrap 64
Wrap32,//GX_ITW_32, // wrap 32
Wrap16,//GX_ITW_16, // wrap 16
Wrap0,//GX_ITW_0, // wrap 0
}
public enum IndTexScale
{
DivideBy1,//GX_ITS_1, // Scale by 1.
DivideBy2,//GX_ITS_2, // Scale by 1/2.
DivideBy4,//GX_ITS_4, // Scale by 1/4.
DivideBy8,//GX_ITS_8, // Scale by 1/8.
DivideBy16,//GX_ITS_16, // Scale by 1/16.
DivideBy32,//GX_ITS_32, // Scale by 1/32.
DivideBy64,//GX_ITS_64, // Scale by 1/64.
DivideBy128,//GX_ITS_128, // Scale by 1/128.
DivideBy256,//GX_ITS_256 // Scale by 1/256.
}
public enum IndTexFormat
{
F_8_Bit_Offsets,//GX_ITF_8, // 8 bit texture offsets.
F_5_Bit_Offsets,//GX_ITF_5, // 5 bit texture offsets.
F_4_Bit_Offsets,//GX_ITF_4, // 4 bit texture offsets.
F_3_Bit_Offsets,//GX_ITF_3 // 3 bit texture offsets.
}
public enum IndTexStageID
{
IndirectTexStg0,//GX_INDTEXSTAGE0,
IndirectTexStg1,//GX_INDTEXSTAGE1,
IndirectTexStg2,//GX_INDTEXSTAGE2,
IndirectTexStg3//GX_INDTEXSTAGE3
}
public enum IndTexAlphaSel
{
Off,//GX_ITBA_OFF,
S,//GX_ITBA_S,
T,//GX_ITBA_T,
U//GX_ITBA_U
}
public enum TexCoordGenTypes
{
GX_TG_MTX3x4 = 0,
GX_TG_MTX2x4 = 1,
GX_TG_BUMP0 = 2,
GX_TG_BUMP1 = 3,
GX_TG_BUMP2 = 4,
GX_TG_BUMP3 = 5,
GX_TG_BUMP4 = 6,
GX_TG_BUMP5 = 7,
GX_TG_BUMP6 = 8,
GX_TG_BUMP7 = 9,
GX_TG_SRTG = 0xA
}
public enum TexCoordGenSource
{
GX_TG_POS,
GX_TG_NRM,
GX_TG_BINRM,
GX_TG_TANGENT,
GX_TG_TEX0,
GX_TG_TEX1,
GX_TG_TEX2,
GX_TG_TEX3,
GX_TG_TEX4,
GX_TG_TEX5,
GX_TG_TEX6,
GX_TG_TEX7,
GX_TG_TEXCOORD0,
GX_TG_TEXCOORD1,
GX_TG_TEXCOORD2,
GX_TG_TEXCOORD3,
GX_TG_TEXCOORD4,
GX_TG_TEXCOORD5,
GX_TG_TEXCOORD6,
GX_TG_COLOR0,
GX_TG_COLOR1
}
public enum TexCoordGenMatrixSource
{
GX_PNMTX0,
GX_PNMTX1,
GX_PNMTX2,
GX_PNMTX3,
GX_PNMTX4,
GX_PNMTX5,
GX_PNMTX6,
GX_PNMTX7,
GX_PNMTX8,
GX_PNMTX9,
GX_TEXMTX0,
GX_TEXMTX1,
GX_TEXMTX2,
GX_TEXMTX3,
GX_TEXMTX4,
GX_TEXMTX5,
GX_TEXMTX6,
GX_TEXMTX7,
GX_TEXMTX8,
GX_TEXMTX9,
GX_IDENTITY,
GX_DTTMTX0,
GX_DTTMTX1,
GX_DTTMTX2,
GX_DTTMTX3,
GX_DTTMTX4,
GX_DTTMTX5,
GX_DTTMTX6,
GX_DTTMTX7,
GX_DTTMTX8,
GX_DTTMTX9,
GX_DTTMTX10,
GX_DTTMTX11,
GX_DTTMTX12,
GX_DTTMTX13,
GX_DTTMTX14,
GX_DTTMTX15,
GX_DTTMTX16,
GX_DTTMTX17,
GX_DTTMTX18,
GX_DTTMTX19,
GX_DTTIDENTITY
}
public enum SwapChannel
{
Red,
Green,
Blue,
Alpha
}
}

View File

@ -196,268 +196,5 @@ namespace LayoutBXLYT.Revolution
tmp8 |= (byte)(((byte)Format & 0x3) << 0);
writer.Write(tmp8);
}
//Thanks brawlbox. Layouts should work with these
//https://github.com/libertyernie/brawltools/blob/40d7431b1a01ef4a0411cd69e51411bd581e93e2/BrawlLib/Wii/Graphics/Enum.cs
public enum ColorArg : byte
{
OutputColor,//GX_CC_CPREV,
OutputAlpha,//GX_CC_APREV,
Color0,//GX_CC_C0,
Alpha0,//GX_CC_A0,
Color1,//GX_CC_C1,
Alpha1,//GX_CC_A1,
Color2,//GX_CC_C2,
Alpha2,//GX_CC_A2,
TextureColor,//GX_CC_TEXC,
TextureAlpha,//GX_CC_TEXA,
RasterColor,//GX_CC_RASC,
RasterAlpha,//GX_CC_RASA,
One,//GX_CC_ONE, //1
Half,//GX_CC_HALF, //0.5
ConstantColorSelection,//GX_CC_KONST,
Zero//GX_CC_ZERO //0
}
public enum Bias
{
Zero,//GX_TB_ZERO,
AddHalf,//GX_TB_ADDHALF,
SubHalf//GX_TB_SUBHALF
}
public enum TevColorRegID
{
OutputColor,
Color0,
Color1,
Color2,
}
public enum TevColorOp
{
Add = 0,
Subtract = 1,
CompR8Greater = 8,
CompR8Equal = 9,
CompGR16Greater = 10,
CompGR16Equal = 11,
CompBGR24Greater = 12,
CompBGR24Equal = 13,
CompRGB8Greater = 14,
CompRGB8Equal = 15,
//GX_TEV_COMP_A8_GT = GX_TEV_COMP_RGB8_GT, // for alpha channel
//GX_TEV_COMP_A8_EQ = GX_TEV_COMP_RGB8_EQ // for alpha channel
}
public enum TevAlphaRegID
{
OutputAlpha,
Alpha0,
Alpha1,
Alpha2,
}
public enum AlphaArg
{
OutputAlpha,//GX_CA_APREV,
Alpha0,//GX_CA_A0,
Alpha1,//GX_CA_A1,
Alpha2,//GX_CA_A2,
TextureAlpha,//GX_CA_TEXA,
RasterAlpha,//GX_CA_RASA,
ConstantAlphaSelection,//GX_CA_KONST,
Zero//GX_CA_ZERO //0
}
public enum TevAlphaOp
{
And,//ALPHAOP_AND = 0,
Or,//ALPHAOP_OR,
ExclusiveOr,//ALPHAOP_XOR,
InverseExclusiveOr//ALPHAOP_XNOR
}
public enum TevScale
{
MultiplyBy1,//GX_CS_SCALE_1,
MultiplyBy2,//GX_CS_SCALE_2,
MultiplyBy4,//GX_CS_SCALE_4,
DivideBy2//GX_CS_DIVIDE_2
}
public enum TevKAlphaSel
{
Constant1_1/*GX_TEV_KASEL_8_8*/ = 0x00, //1.0f
Constant7_8/*GX_TEV_KASEL_7_8*/ = 0x01, //0.875f
Constant3_4/*GX_TEV_KASEL_6_8*/ = 0x02, //0.75f
Constant5_8/*GX_TEV_KASEL_5_8*/ = 0x03, //0.625f
Constant1_2/*GX_TEV_KASEL_4_8*/ = 0x04, //0.5f
Constant3_8/*GX_TEV_KASEL_3_8*/ = 0x05, //0.375f
Constant1_4/*GX_TEV_KASEL_2_8*/ = 0x06, //0.25f
Constant1_8/*GX_TEV_KASEL_1_8*/ = 0x07, //0.125f
//GX_TEV_KASEL_1 = GX_TEV_KASEL_8_8,
//GX_TEV_KASEL_3_4 = GX_TEV_KASEL_6_8,
//GX_TEV_KASEL_1_2 = GX_TEV_KASEL_4_8,
//GX_TEV_KASEL_1_4 = GX_TEV_KASEL_2_8,
ConstantColor0_Red/*GX_TEV_KASEL_K0_R*/ = 0x10,
ConstantColor1_Red/*GX_TEV_KASEL_K1_R*/ = 0x11,
ConstantColor2_Red/*GX_TEV_KASEL_K2_R*/ = 0x12,
ConstantColor3_Red/*GX_TEV_KASEL_K3_R*/ = 0x13,
ConstantColor0_Green/*GX_TEV_KASEL_K0_G*/ = 0x14,
ConstantColor1_Green/*GX_TEV_KASEL_K1_G*/ = 0x15,
ConstantColor2_Green/*GX_TEV_KASEL_K2_G*/ = 0x16,
ConstantColor3_Green/*GX_TEV_KASEL_K3_G*/ = 0x17,
ConstantColor0_Blue/*GX_TEV_KASEL_K0_B*/ = 0x18,
ConstantColor1_Blue/*GX_TEV_KASEL_K1_B*/ = 0x19,
ConstantColor2_Blue/*GX_TEV_KASEL_K2_B*/ = 0x1A,
ConstantColor3_Blue/*GX_TEV_KASEL_K3_B*/ = 0x1B,
ConstantColor0_Alpha/*GX_TEV_KASEL_K0_A*/ = 0x1C,
ConstantColor1_Alpha/*GX_TEV_KASEL_K1_A*/ = 0x1D,
ConstantColor2_Alpha/*GX_TEV_KASEL_K2_A*/ = 0x1E,
ConstantColor3_Alpha/*GX_TEV_KASEL_K3_A*/ = 0x1F
}
public enum TevKColorSel
{
Constant1_1/*GX_TEV_KCSEL_8_8*/ = 0x00, //1.0f, 1.0f, 1.0f
Constant7_8/*GX_TEV_KCSEL_7_8*/ = 0x01, //0.875f, 0.875f, 0.875f
Constant3_4/*GX_TEV_KCSEL_6_8*/ = 0x02, //0.75f, 0.75f, 0.75f
Constant5_8/*GX_TEV_KCSEL_5_8*/ = 0x03, //0.625f, 0.625f, 0.625f
Constant1_2/*GX_TEV_KCSEL_4_8*/ = 0x04, //0.5f, 0.5f, 0.5f
Constant3_8/*GX_TEV_KCSEL_3_8*/ = 0x05, //0.375f, 0.375f, 0.375f
Constant1_4/*GX_TEV_KCSEL_2_8*/ = 0x06, //0.25f, 0.25f, 0.25f
Constant1_8/*GX_TEV_KCSEL_1_8*/ = 0x07, //0.125f, 0.125f, 0.125f
//GX_TEV_KCSEL_1 = GX_TEV_KCSEL_8_8,
//GX_TEV_KCSEL_3_4 = GX_TEV_KCSEL_6_8,
//GX_TEV_KCSEL_1_2 = GX_TEV_KCSEL_4_8,
//GX_TEV_KCSEL_1_4 = GX_TEV_KCSEL_2_8,
ConstantColor0_RGB/*GX_TEV_KCSEL_K0*/ = 0x0C,
ConstantColor1_RGB/*GX_TEV_KCSEL_K1*/ = 0x0D,
ConstantColor2_RGB/*GX_TEV_KCSEL_K2*/ = 0x0E,
ConstantColor3_RGB/*GX_TEV_KCSEL_K3*/ = 0x0F,
ConstantColor0_RRR/*GX_TEV_KCSEL_K0_R*/ = 0x10,
ConstantColor1_RRR/*GX_TEV_KCSEL_K1_R*/ = 0x11,
ConstantColor2_RRR/*GX_TEV_KCSEL_K2_R*/ = 0x12,
ConstantColor3_RRR/*GX_TEV_KCSEL_K3_R*/ = 0x13,
ConstantColor0_GGG/*GX_TEV_KCSEL_K0_G*/ = 0x14,
ConstantColor1_GGG/*GX_TEV_KCSEL_K1_G*/ = 0x15,
ConstantColor2_GGG/*GX_TEV_KCSEL_K2_G*/ = 0x16,
ConstantColor3_GGG/*GX_TEV_KCSEL_K3_G*/ = 0x17,
ConstantColor0_BBB/*GX_TEV_KCSEL_K0_B*/ = 0x18,
ConstantColor1_BBB/*GX_TEV_KCSEL_K1_B*/ = 0x19,
ConstantColor2_BBB/*GX_TEV_KCSEL_K2_B*/ = 0x1A,
ConstantColor3_BBB/*GX_TEV_KCSEL_K3_B*/ = 0x1B,
ConstantColor0_AAA/*GX_TEV_KCSEL_K0_A*/ = 0x1C,
ConstantColor1_AAA/*GX_TEV_KCSEL_K1_A*/ = 0x1D,
ConstantColor2_AAA/*GX_TEV_KCSEL_K2_A*/ = 0x1E,
ConstantColor3_AAA/*GX_TEV_KCSEL_K3_A*/ = 0x1F
}
public enum TevSwapSel : ushort
{
Swap0,//GX_TEV_SWAP0 = 0,
Swap1,//GX_TEV_SWAP1,
Swap2,//GX_TEV_SWAP2,
Swap3,//GX_TEV_SWAP3
}
public enum TexMapID
{
TexMap0,//GX_TEXMAP0,
TexMap1,//GX_TEXMAP1,
TexMap2,//GX_TEXMAP2,
TexMap3,//GX_TEXMAP3,
TexMap4,//GX_TEXMAP4,
TexMap5,//GX_TEXMAP5,
TexMap6,//GX_TEXMAP6,
TexMap7,//GX_TEXMAP7,
//GX_MAX_TEXMAP,
//GX_TEXMAP_NULL = 0xff,
//GX_TEX_DISABLE = 0x100 // mask : disables texture look up
}
public enum TexCoordID
{
TexCoord0,//GX_TEXCOORD0 = 0x0, // generated texture coordinate 0
TexCoord1,//GX_TEXCOORD1, // generated texture coordinate 1
TexCoord2,//GX_TEXCOORD2, // generated texture coordinate 2
TexCoord3,//GX_TEXCOORD3, // generated texture coordinate 3
TexCoord4,//GX_TEXCOORD4, // generated texture coordinate 4
TexCoord5,//GX_TEXCOORD5, // generated texture coordinate 5
TexCoord6,//GX_TEXCOORD6, // generated texture coordinate 6
TexCoord7,//GX_TEXCOORD7, // generated texture coordinate 7
//GX_MAX_TEXCOORD = 8,
//GX_TEXCOORD_NULL = 0xff
}
public enum IndTexMtxID
{
NoMatrix,//GX_ITM_OFF,
Matrix0,//GX_ITM_0,
Matrix1,//GX_ITM_1,
Matrix2,//GX_ITM_2,
MatrixS0 = 5,//GX_ITM_S0 = 5,
MatrixS1,//GX_ITM_S1,
MatrixS2,//GX_ITM_S2,
MatrixT0 = 9, //GX_ITM_T0 = 9,
MatrixT1,//GX_ITM_T1,
MatrixT2,//GX_ITM_T2
}
public enum IndTexWrap
{
NoWrap,//GX_ITW_OFF, // no wrapping
Wrap256,//GX_ITW_256, // wrap 256
Wrap128,//GX_ITW_128, // wrap 128
Wrap64,//GX_ITW_64, // wrap 64
Wrap32,//GX_ITW_32, // wrap 32
Wrap16,//GX_ITW_16, // wrap 16
Wrap0,//GX_ITW_0, // wrap 0
}
public enum IndTexScale
{
DivideBy1,//GX_ITS_1, // Scale by 1.
DivideBy2,//GX_ITS_2, // Scale by 1/2.
DivideBy4,//GX_ITS_4, // Scale by 1/4.
DivideBy8,//GX_ITS_8, // Scale by 1/8.
DivideBy16,//GX_ITS_16, // Scale by 1/16.
DivideBy32,//GX_ITS_32, // Scale by 1/32.
DivideBy64,//GX_ITS_64, // Scale by 1/64.
DivideBy128,//GX_ITS_128, // Scale by 1/128.
DivideBy256,//GX_ITS_256 // Scale by 1/256.
}
public enum IndTexFormat
{
F_8_Bit_Offsets,//GX_ITF_8, // 8 bit texture offsets.
F_5_Bit_Offsets,//GX_ITF_5, // 5 bit texture offsets.
F_4_Bit_Offsets,//GX_ITF_4, // 4 bit texture offsets.
F_3_Bit_Offsets,//GX_ITF_3 // 3 bit texture offsets.
}
public enum IndTexStageID
{
IndirectTexStg0,//GX_INDTEXSTAGE0,
IndirectTexStg1,//GX_INDTEXSTAGE1,
IndirectTexStg2,//GX_INDTEXSTAGE2,
IndirectTexStg3//GX_INDTEXSTAGE3
}
public enum IndTexAlphaSel
{
Off,//GX_ITBA_OFF,
S,//GX_ITBA_S,
T,//GX_ITBA_T,
U//GX_ITBA_U
}
}
}

View File

@ -57,12 +57,4 @@ namespace LayoutBXLYT.Revolution
return value;
}
}
public enum SwapChannel
{
Red,
Green,
Blue,
Alpha
}
}

View File

@ -32,89 +32,5 @@ namespace LayoutBXLYT.Revolution
writer.Write((byte)MatrixSource);
writer.Write(Unknown);
}
public enum TexCoordGenTypes
{
GX_TG_MTX3x4 = 0,
GX_TG_MTX2x4 = 1,
GX_TG_BUMP0 = 2,
GX_TG_BUMP1 = 3,
GX_TG_BUMP2 = 4,
GX_TG_BUMP3 = 5,
GX_TG_BUMP4 = 6,
GX_TG_BUMP5 = 7,
GX_TG_BUMP6 = 8,
GX_TG_BUMP7 = 9,
GX_TG_SRTG = 0xA
}
public enum TexCoordGenSource
{
GX_TG_POS,
GX_TG_NRM,
GX_TG_BINRM,
GX_TG_TANGENT,
GX_TG_TEX0,
GX_TG_TEX1,
GX_TG_TEX2,
GX_TG_TEX3,
GX_TG_TEX4,
GX_TG_TEX5,
GX_TG_TEX6,
GX_TG_TEX7,
GX_TG_TEXCOORD0,
GX_TG_TEXCOORD1,
GX_TG_TEXCOORD2,
GX_TG_TEXCOORD3,
GX_TG_TEXCOORD4,
GX_TG_TEXCOORD5,
GX_TG_TEXCOORD6,
GX_TG_COLOR0,
GX_TG_COLOR1
}
public enum TexCoordGenMatrixSource
{
GX_PNMTX0,
GX_PNMTX1,
GX_PNMTX2,
GX_PNMTX3,
GX_PNMTX4,
GX_PNMTX5,
GX_PNMTX6,
GX_PNMTX7,
GX_PNMTX8,
GX_PNMTX9,
GX_TEXMTX0,
GX_TEXMTX1,
GX_TEXMTX2,
GX_TEXMTX3,
GX_TEXMTX4,
GX_TEXMTX5,
GX_TEXMTX6,
GX_TEXMTX7,
GX_TEXMTX8,
GX_TEXMTX9,
GX_IDENTITY,
GX_DTTMTX0,
GX_DTTMTX1,
GX_DTTMTX2,
GX_DTTMTX3,
GX_DTTMTX4,
GX_DTTMTX5,
GX_DTTMTX6,
GX_DTTMTX7,
GX_DTTMTX8,
GX_DTTMTX9,
GX_DTTMTX10,
GX_DTTMTX11,
GX_DTTMTX12,
GX_DTTMTX13,
GX_DTTMTX14,
GX_DTTMTX15,
GX_DTTMTX16,
GX_DTTMTX17,
GX_DTTMTX18,
GX_DTTMTX19,
GX_DTTIDENTITY
}
}
}

View File

@ -502,16 +502,16 @@ namespace LayoutBXLYT.Revolution
string alpha = "";
if ((byte)stage.AlphaConstantSel <= 7)
{
switch ((byte)stage.AlphaConstantSel)
switch (stage.AlphaConstantSel)
{
case 0: alpha = "vec3(1.0)"; break;
case 1: alpha = "vec3(0.875)"; break;
case 2: alpha = "vec3(0.75)"; break;
case 3: alpha = "vec3(0.625)"; break;
case 4: alpha = "vec3(0.5)"; break;
case 5: alpha = "vec3(0.375)"; break;
case 6: alpha = "vec3(0.25)"; break;
case 7: alpha = "vec3(0.125)"; break;
case TevKAlphaSel.Constant1_1: alpha = "vec3(1.0)"; break;
case TevKAlphaSel.Constant7_8: alpha = "vec3(0.875)"; break;
case TevKAlphaSel.Constant3_4: alpha = "vec3(0.75)"; break;
case TevKAlphaSel.Constant5_8: alpha = "vec3(0.625)"; break;
case TevKAlphaSel.Constant1_2: alpha = "vec3(0.5)"; break;
case TevKAlphaSel.Constant3_8: alpha = "vec3(0.375)"; break;
case TevKAlphaSel.Constant1_4: alpha = "vec3(0.25)"; break;
case TevKAlphaSel.Constant1_8: alpha = "vec3(0.125)"; break;
}
}

View File

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LayoutBXLYT.Revolution
{
public class ShaderGenerator
{
private string GenerateTexSource(TexCoordGenSource src)
{
switch (src)
{
case TexCoordGenSource.GX_TG_POS: return "vec4(a_Position, 1.0)";
default:
throw new Exception("Unsupported tex source " + src);
}
}
}
}

View File

@ -301,6 +301,7 @@ namespace FirstPlugin.LuigisMansion.DarkMoon
}
genericObj.RemoveDuplicateVertices();
genericObj.FlipUvsVertical();
}
}
}

View File

@ -95,39 +95,27 @@ namespace FirstPlugin
}
}
ImageEditorBase form;
private ImageEditorBase form;
public ImageEditorBase OpenForm()
{
bool IsDialog = IFileInfo != null && IFileInfo.InArchive;
Properties prop = new Properties();
prop.Width = Width;
prop.Height = Height;
prop.Depth = Depth;
prop.MipCount = MipCount;
prop.ArrayCount = ArrayCount;
prop.ImageSize = (uint)ImageData.Length;
prop.Format = Format;
form = new ImageEditorBase();
form.Text = Text;
form.Dock = DockStyle.Fill;
form.AddFileContextEvent("Save", Save);
form.AddFileContextEvent("Replace", Replace);
form.LoadProperties(prop);
form.LoadImage(this);
return form;
}
public void UpdateForm()
{
UpdateForm(form);
}
public void FillEditor(UserControl control)
{
UpdateForm();
form = (ImageEditorBase)control;
UpdateForm((ImageEditorBase)control);
}
private void UpdateForm()
private void UpdateForm(ImageEditorBase form)
{
if (form != null && image != null)
if (image != null)
{
Properties prop = new Properties();
prop.Width = Width;
@ -138,8 +126,15 @@ namespace FirstPlugin
prop.ImageSize = (uint)ImageData.Length;
prop.Format = Format;
form.Text = Text;
form.Dock = DockStyle.Fill;
form.ResetMenus();
form.AddFileContextEvent("Save", Save);
form.AddFileContextEvent("Replace", Replace);
form.LoadProperties(prop);
form.LoadImage(this);
Console.WriteLine("UpdateForm LoadImage");
}
}

View File

@ -188,6 +188,8 @@ namespace FirstPlugin
public TplTextureWrapper(TPL tpl, ImageHeader header) {
TPLParent = tpl;
ImageHeader = header;
CanReplace = true;
}
public override TEX_FORMAT[] SupportedFormats
@ -237,6 +239,64 @@ namespace FirstPlugin
editor.LoadProperties(ImageHeader);
editor.LoadImage(this);
}
public void UpdateEditor()
{
ImageEditorBase editor = (ImageEditorBase)LibraryGUI.GetActiveContent(typeof(ImageEditorBase));
if (editor == null)
{
editor = new ImageEditorBase();
editor.Dock = DockStyle.Fill;
LibraryGUI.LoadEditor(editor);
}
editor.LoadProperties(GenericProperties);
editor.LoadImage(this);
}
public override void Replace(string FileName)
{
GamecubeTextureImporterList importer = new GamecubeTextureImporterList(SupportedFormats);
GameCubeTextureImporterSettings settings = new GameCubeTextureImporterSettings();
importer.ForceMipCount = true;
importer.SelectedMipCount = 1;
if (Utils.GetExtension(FileName) == ".dds" ||
Utils.GetExtension(FileName) == ".dds2")
{
settings.LoadDDS(FileName);
importer.LoadSettings(new List<GameCubeTextureImporterSettings>() { settings, });
ApplySettings(settings);
UpdateEditor();
}
else
{
settings.LoadBitMap(FileName);
importer.LoadSettings(new List<GameCubeTextureImporterSettings>() { settings, });
if (importer.ShowDialog() == DialogResult.OK)
{
if (settings.GenerateMipmaps && !settings.IsFinishedCompressing)
settings.Compress();
ApplySettings(settings);
UpdateEditor();
}
}
}
private void ApplySettings(GameCubeTextureImporterSettings settings)
{
this.ImageData = settings.DataBlockOutput[0];
this.Width = settings.TexWidth;
this.Height = settings.TexHeight;
this.Format = settings.GenericFormat;
this.MipCount = 1; //Always 1
this.Depth = 1;
this.ArrayCount = (uint)settings.DataBlockOutput.Count;
}
}
public class PaletteHeader

View File

@ -49,6 +49,8 @@ namespace LayoutBXLYT
tagValue = BxlanPaiTag.CafeTypeDefine.FirstOrDefault(x => x.Value == (string)stComboBox1.SelectedItem).Key;
if (ActiveGroup is BRLAN.PaiEntry)
tagValue = BxlanPaiTag.RevTypeDefine.FirstOrDefault(x => x.Value == (string)stComboBox1.SelectedItem).Key;
if (ActiveGroup is BCLAN.PaiEntry)
tagValue = BxlanPaiTag.CtrTypeDefine.FirstOrDefault(x => x.Value == (string)stComboBox1.SelectedItem).Key;
return ActiveGroup.AddEntry(tagValue);
}

View File

@ -50,6 +50,7 @@ namespace LayoutBXLYT
vertexColorBox1.BottomRightColor = pane.ColorBottomRight.Color;
vertexColorBox1.Refresh();
texCoordIndexCB.Items.Clear();
for (int i = 0; i < pane.TexCoords?.Length; i++)
texCoordIndexCB.Items.Add($"TexCoord [{i}]");

View File

@ -58,8 +58,7 @@ namespace LayoutBXLYT.CTR
};
colorDlg.ColorChanged += delegate
{
whiteColorPB.Color = colorDlg.NewColor;
ActiveMaterial.WhiteColor.Color = colorDlg.NewColor;
((ColorAlphaBox)sender).Color = colorDlg.NewColor;
//Apply to all selected panes
foreach (BasePane pane in ParentEditor.SelectedPanes)

View File

@ -142,7 +142,7 @@ namespace LayoutBXLYT
public override void OnControlClosing()
{
foreach (var img in Images)
img.Dispose();
img?.Dispose();
Images.Clear();
}

View File

@ -61,8 +61,7 @@ namespace LayoutBXLYT
};
colorDlg.ColorChanged += delegate
{
whiteColorPB.Color = colorDlg.NewColor;
ActiveMaterial.WhiteColor.Color = colorDlg.NewColor;
((ColorAlphaBox)sender).Color = colorDlg.NewColor;
//Apply to all selected panes
foreach (BasePane pane in ParentEditor.SelectedPanes)

View File

@ -46,10 +46,10 @@ namespace LayoutBXLYT.Revolution
int index = tevStageCB.SelectedIndex;
stageCounterLbl.Text = $"Stage {index + 1} of {ActiveMaterial.TevStages.Length}";
LoadTevStage((TevStage)ActiveMaterial.TevStages[index]);
LoadTevStage((CTR.TevStage)ActiveMaterial.TevStages[index]);
}
private void LoadTevStage(TevStage stage) {
private void LoadTevStage(CTR.TevStage stage) {
stPropertyGrid1.LoadProperty(stage, OnPropertyChanged);
}

View File

@ -76,7 +76,7 @@ namespace LayoutBXLYT
sizeRestrictUD.Value = 0;
//BRLYT has no shader parameters. Text cannot do those so hide them
if (pane is Revolution.TXT1)
if (pane is Revolution.TXT1 || pane is CTR.TXT1)
{
stDropDownPanel4.Visible = false;
}

View File

@ -418,6 +418,7 @@ namespace FirstPlugin
Formats.Add(typeof(LayoutBXLYT.BRLYT));
Formats.Add(typeof(LayoutBXLYT.BFLAN));
Formats.Add(typeof(LayoutBXLYT.BRLAN));
Formats.Add(typeof(LayoutBXLYT.BCLAN));
Formats.Add(typeof(ZSI));
Formats.Add(typeof(IGZ_TEX));
Formats.Add(typeof(MOD));

View File

@ -561,7 +561,6 @@ namespace Toolbox.Library
{
var Image = BitmapExtension.GetBitmap(ConvertBgraToRgba(CTR_3DS.DecodeBlock(data, (int)width, (int)height, Format)),
(int)width, (int)height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
Image.RotateFlip(RotateFlipType.RotateNoneFlipY); //It's upside down for some reason so flip it
return Image;
}

View File

@ -102,7 +102,7 @@ namespace Toolbox.Library
public static byte[] DecodeBlock(byte[] Input, int Width, int Height, PICASurfaceFormat picaFormat)
{
if (picaFormat == PICASurfaceFormat.ETC1 || picaFormat == PICASurfaceFormat.ETC1A4)
return ETC1.ETC1Decompress(Input, Width, Height, picaFormat == PICASurfaceFormat.ETC1A4);
return FlipVertical(Width, Height, ETC1.ETC1Decompress(Input, Width, Height, picaFormat == PICASurfaceFormat.ETC1A4));
byte[] Output = new byte[Width * Height * 4];
@ -195,7 +195,31 @@ namespace Toolbox.Library
}
}
return Output;
return FlipVertical(Width, Height, Output);
}
private static byte[] FlipVertical(int Width, int Height, byte[] Input)
{
byte[] FlippedOutput = new byte[Width * Height * 4];
int Stride = Width * 4;
for (int Y = 0; Y < Height; Y++)
{
int IOffs = Stride * Y;
int OOffs = Stride * (Height - 1 - Y);
for (int X = 0; X < Width; X++)
{
FlippedOutput[OOffs + 0] = Input[IOffs + 0];
FlippedOutput[OOffs + 1] = Input[IOffs + 1];
FlippedOutput[OOffs + 2] = Input[IOffs + 2];
FlippedOutput[OOffs + 3] = Input[IOffs + 3];
IOffs += 4;
OOffs += 4;
}
}
return FlippedOutput;
}
public static byte[] EncodeBlock(byte[] Input, int Width, int Height, TEX_FORMAT Format) {

View File

@ -384,8 +384,8 @@ namespace Toolbox.Library
stream.SetByteOrder(true);
//4 bpp, 8 block width/height, block size 32 bytes, possible palettes (IA8, RGB565, RGB5A3)
uint numBlocksW = width / 8;
uint numBlocksH = height / 8;
uint numBlocksW = (width + 7) / 8;
uint numBlocksH = (height + 7) / 8;
byte[] decodedData = new byte[width * height * 8];
@ -399,9 +399,11 @@ namespace Toolbox.Library
{
for (int pX = 0; pX < 8; pX += 2)
{
//Ensure we're not reading past the end of the image.
if ((xBlock * 8 + pX >= width) || (yBlock * 8 + pY >= height))
{
stream.Seek(1);
continue;
}
byte data = stream.ReadByte();
byte t = (byte)(data & 0xF0);
@ -436,8 +438,8 @@ namespace Toolbox.Library
stream.SetByteOrder(true);
//4 bpp, 8 block width/4 block height, block size 32 bytes, possible palettes (IA8, RGB565, RGB5A3)
uint numBlocksW = width / 8;
uint numBlocksH = height / 4;
uint numBlocksW = (width + 7) / 8;
uint numBlocksH = (height + 3) / 4;
byte[] decodedData = new byte[width * height * 8];
@ -451,10 +453,11 @@ namespace Toolbox.Library
{
for (int pX = 0; pX < 8; pX++)
{
//Ensure we're not reading past the end of the image.
if ((xBlock * 8 + pX >= width) || (yBlock * 4 + pY >= height))
{
stream.Seek(1);
continue;
}
byte data = stream.ReadByte();
decodedData[width * ((yBlock * 4) + pY) + (xBlock * 8) + pX] = data;
@ -857,6 +860,9 @@ namespace Toolbox.Library
/// <param name="destOffset">Offset into destination array to write RGBA pixel.</param>
private static void RGB565ToRGBA8(ushort sourcePixel, ref byte[] dest, int destOffset)
{
//This repo fixes some decoding bugs SuperBMD had
//https://github.com/RenolY2/SuperBMD/tree/master/SuperBMDLib/source
byte r, g, b;
r = (byte)((sourcePixel & 0xF100) >> 11);
g = (byte)((sourcePixel & 0x7E0) >> 5);
@ -887,17 +893,26 @@ namespace Toolbox.Library
if ((sourcePixel & 0x8000) == 0x8000)
{
a = 0xFF;
r = Expand5to8((sourcePixel >> 10) & 0x1F);
g = Expand5to8((sourcePixel >> 5) & 0x1F);
b = Expand5to8(sourcePixel & 0x1F);
r = (byte)((sourcePixel & 0x7C00) >> 10);
g = (byte)((sourcePixel & 0x3E0) >> 5);
b = (byte)(sourcePixel & 0x1F);
r = (byte)((r << (8 - 5)) | (r >> (10 - 8)));
g = (byte)((g << (8 - 5)) | (g >> (10 - 8)));
b = (byte)((b << (8 - 5)) | (b >> (10 - 8)));
}
//Alpha bits
else
{
a = Expand3to8(sourcePixel >> 12);
r = Expand4to8((sourcePixel >> 8) & 0x0F);
g = Expand4to8((sourcePixel >> 4) & 0x0F);
b = Expand4to8(sourcePixel & 0x0F);
a = (byte)((sourcePixel & 0x7000) >> 12);
r = (byte)((sourcePixel & 0xF00) >> 8);
g = (byte)((sourcePixel & 0xF0) >> 4);
b = (byte)(sourcePixel & 0xF);
a = (byte)((a << (8 - 3)) | (a << (8 - 6)) | (a >> (9 - 8)));
r = (byte)((r << (8 - 4)) | r);
g = (byte)((g << (8 - 4)) | g);
b = (byte)((b << (8 - 4)) | b);
}
dest[destOffset + 0] = b;

View File

@ -1,12 +1,10 @@
#version 110
uniform vec2 uvScale0;
uniform float uvRotate0;
uniform vec2 uvTranslate0;
uniform int flipTexture;
uniform mat4 rotationMatrix;
uniform int texCoords0GenType;
uniform int texCoords0Source;
uniform mat4 textureTransforms[3];
vec2 rotateUV(vec2 uv, float rotation)
{
@ -58,12 +56,8 @@ vec2 SetTexCoordType(int type, vec2 tex)
void main()
{
gl_FrontColor = gl_Color;
vec2 texCoord0 = vec2(0.5, 0.5) + uvScale0 * (gl_MultiTexCoord0.xy + (uvTranslate0 / uvScale0 - 0.5));
texCoord0 = SetTexCoordType(texCoords0GenType, texCoord0);
texCoord0 = rotateUV(texCoord0, radians(-uvRotate0));
gl_TexCoord[0].st = SetFlip(texCoord0);
gl_TexCoord[0] = textureTransforms[0] * gl_MultiTexCoord0;
gl_TexCoord[0].st = SetFlip(vec2(0.5, 0.5) + gl_TexCoord[0].st);
gl_Position = gl_ModelViewProjectionMatrix * rotationMatrix * gl_Vertex;
}