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

Tons more bflyt improvements

Opengl textures that are not power of 2 decode from ST decoder. This prevents those from not loading. (Common in SMM1, SMM2, and also BFLYT).
Bflyt displays bounding panes, and window panes display textures. Window panes still need more work for rendering.
Bflyt now uses custom shaders for more advancements with rendering. Legacy PCs should still work fine with this.
Fixed uv transforms for bflyt if they are negative, which flips them.
Fixed an issue loading bclyt layouts.
Fixed pane trnasformation issues. They are nearly perfect, but rotations for X and Y are off.
Parts now search for opened sarc archives.
Fixed an issue with some spaces not quite saving for txt1 panes. This may fix some saving issues, as most i've tried output back identically.
Fixed an issue displaying LA8 textures.
This commit is contained in:
KillzXGaming 2019-09-08 15:15:42 -04:00
parent 4e63b2f5a4
commit ed78d46545
15 changed files with 775 additions and 301 deletions

View File

@ -0,0 +1,179 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Threading.Tasks;
using OpenTK.Graphics.OpenGL;
using OpenTK;
namespace LayoutBXLYT
{
public class BxlytShader : IDisposable
{
public int program;
private int vertexShader;
private int fragmentShader;
private Dictionary<string, int> attributes = new Dictionary<string, int>();
private Dictionary<string, int> uniforms = new Dictionary<string, int>();
private int activeAttributeCount;
public void LoadShaders()
{
program = CompileShaders();
}
public void Enable()
{
GL.UseProgram(program);
}
public void Disable()
{
GL.UseProgram(0);
}
public void Dispose()
{
GL.DeleteProgram(program);
}
public virtual string VertexShader
{
get
{
StringBuilder vert = new StringBuilder();
vert.AppendLine("uniform mat4 globalTransform;");
vert.AppendLine("void main()");
vert.AppendLine("{");
{
vert.AppendLine("gl_FrontColor = gl_Color;");
vert.AppendLine("gl_Position = gl_ModelViewProjectionMatrix * globalTransform * gl_Vertex;");
}
vert.AppendLine("}");
return vert.ToString();
}
}
public virtual string FragmentShader
{
get
{
StringBuilder vert = new StringBuilder();
vert.AppendLine("void main()");
vert.AppendLine("{");
{
vert.AppendLine("gl_FragColor = gl_Color;");
}
vert.AppendLine("}");
return vert.ToString();
}
}
public void SetVec4(string name, Vector4 value)
{
if (uniforms.ContainsKey(name))
GL.Uniform4(uniforms[name], value);
}
public void SetVec2(string name, Vector2 value)
{
if (uniforms.ContainsKey(name))
GL.Uniform2(uniforms[name], value);
}
public void SetFloat(string name, float value)
{
if (uniforms.ContainsKey(name))
GL.Uniform1(uniforms[name], value);
}
public void SetInt(string name, int value)
{
if (uniforms.ContainsKey(name))
GL.Uniform1(uniforms[name], value);
}
public void SetColor(string name, Color color)
{
if (uniforms.ContainsKey(name))
GL.Uniform4(uniforms[name], color);
}
public void SetMatrix(string name, ref Matrix4 value)
{
if (uniforms.ContainsKey(name))
GL.UniformMatrix4(uniforms[name], false, ref value);
}
public int this[string name]
{
get => uniforms[name];
}
private void LoadAttributes(int program)
{
attributes.Clear();
GL.GetProgram(program, GetProgramParameterName.ActiveAttributes, out activeAttributeCount);
for (int i = 0; i < activeAttributeCount; i++)
{
string name = GL.GetActiveAttrib(program, i, out int size, out ActiveAttribType type);
int location = GL.GetAttribLocation(program, name);
// Overwrite existing vertex attributes.
attributes[name] = location;
}
}
private void LoadUniorms(int program)
{
uniforms.Clear();
GL.GetProgram(program, GetProgramParameterName.ActiveUniforms, out activeAttributeCount);
for (int i = 0; i < activeAttributeCount; i++)
{
string name = GL.GetActiveUniform(program, i, out int size, out ActiveUniformType type);
int location = GL.GetUniformLocation(program, name);
// Overwrite existing vertex attributes.
uniforms[name] = location;
}
}
public void Compile()
{
program = CompileShaders();
LoadUniorms(program);
OnCompiled();
}
public virtual void OnCompiled() { }
private int CompileShaders()
{
vertexShader = GL.CreateShader(ShaderType.VertexShader);
GL.ShaderSource(vertexShader, VertexShader);
GL.CompileShader(vertexShader);
fragmentShader = GL.CreateShader(ShaderType.FragmentShader);
GL.ShaderSource(fragmentShader, FragmentShader);
GL.CompileShader(fragmentShader);
var program = GL.CreateProgram();
GL.AttachShader(program, vertexShader);
GL.AttachShader(program, fragmentShader);
GL.LinkProgram(program);
var info = GL.GetProgramInfoLog(program);
if (!string.IsNullOrWhiteSpace(info))
Console.WriteLine($"GL.LinkProgram had info log: {info}");
GL.DetachShader(program, vertexShader);
GL.DetachShader(program, fragmentShader);
GL.DeleteShader(vertexShader);
GL.DeleteShader(fragmentShader);
return program;
}
}
}

View File

@ -193,11 +193,11 @@ namespace LayoutBXLYT.Cafe
public Dictionary<string, STGenericTexture> GetTextures()
{
BFLIM test = new BFLIM();
Dictionary<string, STGenericTexture> textures = new Dictionary<string, STGenericTexture>();
if (IFileInfo.ArchiveParent != null)
foreach (var archive in PluginRuntime.SarcArchives)
{
foreach (var file in IFileInfo.ArchiveParent.Files)
foreach (var file in archive.Files)
{
if (Utils.GetExtension(file.FileName) == ".bntx")
{
@ -222,7 +222,14 @@ namespace LayoutBXLYT.Cafe
public void Unload()
{
if (header != null)
{
foreach (var mat in header.GetMaterials())
{
if (mat.Shader != null)
mat.Shader.Dispose();
}
}
}
public void Save(System.IO.Stream stream) {
@ -830,6 +837,11 @@ namespace LayoutBXLYT.Cafe
writer.Write(ShadowForeColor.ToBytes());
writer.Write(ShadowBackColor.ToBytes());
writer.Write(ShadowItalic);
if (header.VersionMajor == 9)
{
writer.Write(0);
writer.Write(0);
}
if (Text != null)
{
@ -886,6 +898,7 @@ namespace LayoutBXLYT.Cafe
private byte _flag;
[TypeConverter(typeof(ExpandableObjectConverter))]
public WindowContent Content { get; set; }
public List<WindowFrame> WindowFrames = new List<WindowFrame>();
@ -909,7 +922,7 @@ namespace LayoutBXLYT.Cafe
uint frameOffsetTbl = reader.ReadUInt32();
reader.SeekBegin(pos + contentOffset);
Content = new WindowContent(reader);
Content = new WindowContent(reader, header);
reader.SeekBegin(pos + frameOffsetTbl);
@ -961,21 +974,31 @@ namespace LayoutBXLYT.Cafe
public class WindowContent
{
public STColor8 TopLeftColor { get; set; }
public STColor8 TopRightColor { get; set; }
public STColor8 BottomLeftColor { get; set; }
public STColor8 BottomRightColor { get; set; }
private Header LayoutFile;
public STColor8 ColorTopLeft { get; set; }
public STColor8 ColorTopRight { get; set; }
public STColor8 ColorBottomLeft { get; set; }
public STColor8 ColorBottomRight { get; set; }
public ushort MaterialIndex { get; set; }
public List<TexCoord> TexCoords = new List<TexCoord>();
public WindowContent(FileReader reader)
[TypeConverter(typeof(ExpandableObjectConverter))]
public Material Material
{
TopLeftColor = reader.ReadColor8RGBA();
TopRightColor = reader.ReadColor8RGBA();
BottomLeftColor = reader.ReadColor8RGBA();
BottomRightColor = reader.ReadColor8RGBA();
get { return LayoutFile.MaterialList.Materials[MaterialIndex]; }
}
public WindowContent(FileReader reader, Header header)
{
LayoutFile = header;
ColorTopLeft = reader.ReadColor8RGBA();
ColorTopRight = reader.ReadColor8RGBA();
ColorBottomLeft = reader.ReadColor8RGBA();
ColorBottomRight = reader.ReadColor8RGBA();
MaterialIndex = reader.ReadUInt16();
byte UVCount = reader.ReadByte();
reader.ReadByte(); //padding
@ -992,10 +1015,10 @@ namespace LayoutBXLYT.Cafe
public void Write(FileWriter writer)
{
writer.Write(TopLeftColor);
writer.Write(TopRightColor);
writer.Write(BottomLeftColor);
writer.Write(BottomRightColor);
writer.Write(ColorTopLeft);
writer.Write(ColorTopRight);
writer.Write(ColorBottomLeft);
writer.Write(ColorBottomRight);
writer.Write(MaterialIndex);
writer.Write((byte)TexCoords.Count);
writer.Write((byte)0);
@ -1094,18 +1117,18 @@ namespace LayoutBXLYT.Cafe
ushort numNodes = 0;
if (header.VersionMajor >= 5)
{
Name = reader.ReadString(34).Replace("\0", string.Empty);
Name = reader.ReadString(34, true);
numNodes = reader.ReadUInt16();
}
else
{
Name = reader.ReadString(24).Replace("\0", string.Empty);
Name = reader.ReadString(24, true);;
numNodes = reader.ReadUInt16();
reader.Seek(2); //padding
}
for (int i = 0; i < numNodes; i++)
Panes.Add(reader.ReadString(24).Replace("\0", string.Empty));
Panes.Add(reader.ReadString(24, true));
}
public override void Write(FileWriter writer, BxlytHeader header)
@ -1183,10 +1206,12 @@ namespace LayoutBXLYT.Cafe
{
var fileFormat = layoutFile.FileInfo;
Console.WriteLine("Searching parts");
//File is outside an archive so check the contents it is in
if (File.Exists(fileFormat.FileName))
if (File.Exists(fileFormat.FilePath))
{
string folder = Path.GetDirectoryName(fileFormat.FileName);
string folder = Path.GetDirectoryName(fileFormat.FilePath);
foreach (var file in Directory.GetFiles(folder))
{
if (file.Contains(LayoutFile))
@ -1201,11 +1226,15 @@ namespace LayoutBXLYT.Cafe
}
}
}
else if (fileFormat.IFileInfo.ArchiveParent != null)
foreach (var archive in PluginRuntime.SarcArchives)
{
Console.WriteLine("Searching archive! " + archive.FileName);
BFLYT bflyt = null;
SearchArchive(fileFormat.IFileInfo.ArchiveParent, ref bflyt);
return bflyt;
SearchArchive(archive, ref bflyt);
if (bflyt != null)
return bflyt;
}
return null;
@ -1216,8 +1245,11 @@ namespace LayoutBXLYT.Cafe
layoutFile = null;
foreach (var file in archiveFile.Files)
{
if (file.FileName.Contains(LayoutFile))
{
Console.WriteLine("Part found! " + file.FileName);
var openedFile = file.OpenFile();
if (openedFile is IArchiveFile)
SearchArchive((IArchiveFile)openedFile, ref layoutFile);
@ -1229,6 +1261,7 @@ namespace LayoutBXLYT.Cafe
return;
}
}
}
}
private Header layoutFile;
@ -1279,7 +1312,7 @@ namespace LayoutBXLYT.Cafe
public PartProperty(FileReader reader, Header header, long StartPosition)
{
Name = reader.ReadString(0x18).Replace("\0", string.Empty);
Name = reader.ReadString(0x18, true);
UsageFlag = reader.ReadByte();
BasicUsageFlag = reader.ReadByte();
MaterialUsageFlag = reader.ReadByte();
@ -1679,8 +1712,8 @@ namespace LayoutBXLYT.Cafe
origin = reader.ReadByte();
Alpha = reader.ReadByte();
PaneMagFlags = reader.ReadByte();
Name = reader.ReadString(0x18).Replace("\0", string.Empty);
UserDataInfo = reader.ReadString(0x8).Replace("\0", string.Empty);
Name = reader.ReadString(0x18, true);
UserDataInfo = reader.ReadString(0x8, true);
Translate = reader.ReadVec3SY();
Rotate = reader.ReadVec3SY();
Scale = reader.ReadVec2SY();
@ -1832,7 +1865,7 @@ namespace LayoutBXLYT.Cafe
{
ParentLayout = header;
Name = reader.ReadString(0x1C).Replace("\0", string.Empty);
Name = reader.ReadString(0x1C, true);
Name = Name.Replace("\x01", string.Empty);
Name = Name.Replace("\x04", string.Empty);

View File

@ -0,0 +1,174 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Threading.Tasks;
using OpenTK.Graphics.OpenGL;
using OpenTK;
using LayoutBXLYT.Cafe;
using Toolbox.Library;
namespace LayoutBXLYT
{
public class BflytShader : BxlytShader
{
public BFLYT.Material material;
public BflytShader(BFLYT.Material mat) : base()
{
material = mat;
LoadShaders();
}
public override void OnCompiled()
{
SetColor("whiteColor", Color.FromArgb(255,255,255,255));
SetColor("blackColor", Color.FromArgb(0, 0, 0, 0));
SetInt("debugShading", 0);
SetInt("hasTexture0", 0);
SetInt("numTextureMaps", 0);
SetVec2("uvScale0", new Vector2(1,1));
SetFloat("uvRotate0", 0);
SetVec2("uvTranslate0", new Vector2(0, 0));
}
public void SetMaterials(Dictionary<string, STGenericTexture> textures)
{
SetColor("whiteColor", material.WhiteColor.Color);
SetColor("blackColor", material.BlackColor.Color);
SetInt("debugShading", (int)Runtime.LayoutEditor.Shading);
SetInt("numTextureMaps", material.TextureMaps.Length);
BindTextureUniforms();
string textureMap0 = "";
if (material.TextureMaps.Length > 0)
textureMap0 = material.GetTexture(0);
if (textures.ContainsKey(textureMap0))
{
GL.ActiveTexture(TextureUnit.Texture0);
SetInt("textures0", 0);
bool isBinded = LayoutViewer.BindGLTexture(material.TextureMaps[0], textures[textureMap0]);
if (isBinded)
SetInt("hasTexture0", 1);
}
if (material.TextureTransforms.Length > 0)
{
var transform = material.TextureTransforms[0];
float shiftX = 0;
float shiftY = 0;
if (transform.Scale.X < 0)
shiftX = 1;
if (transform.Scale.Y < 0)
shiftY = 1;
SetVec2("uvScale0",new Vector2(transform.Scale.X, transform.Scale.Y));
SetFloat("uvRotate0", transform.Rotate);
SetVec2("uvTranslate0",new Vector2(shiftX + transform.Translate.X, shiftY + transform.Translate.Y));
}
}
private void BindTextureUniforms()
{
//Do uv test pattern
GL.ActiveTexture(TextureUnit.Texture10);
GL.Uniform1(GL.GetUniformLocation(program, "uvTestPattern"), 10);
GL.BindTexture(TextureTarget.Texture2D, RenderTools.uvTestPattern.RenderableTex.TexID);
if (material.TextureMaps.Length > 0)
{
var tex = material.TextureMaps[0];
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, ConvertTextureWrap(tex.WrapModeU));
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, ConvertTextureWrap(tex.WrapModeV));
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, ConvertMagFilterMode(tex.MaxFilterMode));
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, ConvertMinFilterMode(tex.MinFilterMode));
}
}
public override string VertexShader
{
get
{
string path = System.IO.Path.Combine(Runtime.ExecutableDir, "Shader", "Layout", "Bflyt.vert");
return System.IO.File.ReadAllText(path);
}
}
public override string FragmentShader
{
get
{
StringBuilder frag = new StringBuilder();
frag.AppendLine("uniform vec4 blackColor;");
frag.AppendLine("uniform vec4 whiteColor;");
frag.AppendLine("uniform int hasTexture0;");
frag.AppendLine("uniform int debugShading;");
frag.AppendLine("uniform int numTextureMaps;");
frag.AppendFormat("uniform sampler2D textures{0};\n", 0);
frag.AppendLine("uniform sampler2D uvTestPattern;");
frag.AppendLine("void main()");
frag.AppendLine("{");
frag.AppendLine("vec4 textureMap0 = vec4(1);");
frag.AppendLine("if (numTextureMaps > 0)");
frag.AppendLine("{");
frag.AppendLine("if (hasTexture0 == 1)");
frag.AppendLine(" textureMap0 = texture2D(textures0, gl_TexCoord[0].st);");
frag.AppendLine("}");
frag.AppendLine("if (debugShading == 0)");
frag.AppendLine("{");
frag.AppendLine("vec4 colorFrag = gl_Color * textureMap0;");
frag.AppendLine("vec4 colorBlend = colorFrag * whiteColor;");
frag.AppendLine("gl_FragColor = colorBlend;");
frag.AppendLine("}");
frag.AppendLine("else if (debugShading == 1)");
frag.AppendLine(" gl_FragColor = vec4(textureMap0.rgb, 1);");
frag.AppendLine("else if (debugShading == 2)");
frag.AppendLine(" gl_FragColor = whiteColor;");
frag.AppendLine("else if (debugShading == 3)");
frag.AppendLine(" gl_FragColor = blackColor;");
frag.AppendLine("else if (debugShading == 4)");
frag.AppendLine(" gl_FragColor = texture2D(uvTestPattern, gl_TexCoord[0].st);");
frag.AppendLine("}");
return frag.ToString();
}
}
private static int ConvertTextureWrap(TextureRef.WrapMode wrapMode)
{
switch (wrapMode)
{
case TextureRef.WrapMode.Clamp: return (int)TextureWrapMode.Clamp;
case TextureRef.WrapMode.Mirror: return (int)TextureWrapMode.MirroredRepeat;
case TextureRef.WrapMode.Repeat: return (int)TextureWrapMode.Repeat;
default: return (int)TextureWrapMode.Clamp;
}
}
private static int ConvertMagFilterMode(TextureRef.FilterMode filterMode)
{
switch (filterMode)
{
case TextureRef.FilterMode.Linear: return (int)TextureMagFilter.Linear;
case TextureRef.FilterMode.Near: return (int)TextureMagFilter.Nearest;
default: return (int)TextureRef.FilterMode.Linear;
}
}
private static int ConvertMinFilterMode(TextureRef.FilterMode filterMode)
{
switch (filterMode)
{
case TextureRef.FilterMode.Linear: return (int)TextureMinFilter.Linear;
case TextureRef.FilterMode.Near: return (int)TextureMinFilter.Nearest;
default: return (int)TextureRef.FilterMode.Linear;
}
}
}
}

View File

@ -139,11 +139,6 @@ namespace LayoutBXLYT
//https://github.com/FuryBaguette/SwitchLayoutEditor/tree/master/SwitchThemesCommon
public class Header : BxlytHeader, IDisposable
{
public string FileName
{
get { return FileInfo.FileName; }
}
private const string Magic = "CLYT";
private ushort ByteOrderMark;
@ -168,6 +163,11 @@ namespace LayoutBXLYT
get { return TextureList.Textures; }
}
public override List<string> Fonts
{
get { return FontList.Fonts; }
}
public override Dictionary<string, STGenericTexture> GetTextures
{
get { return ((BCLYT)FileInfo).GetTextures(); }
@ -187,6 +187,17 @@ namespace LayoutBXLYT
return panes;
}
public override List<BxlytMaterial> GetMaterials()
{
List<BxlytMaterial> materials = new List<BxlytMaterial>();
if (MaterialList != null && MaterialList.Materials != null)
{
for (int i = 0; i < MaterialList.Materials.Count; i++)
materials.Add(MaterialList.Materials[i]);
}
return materials;
}
private void GetPaneChildren(List<PAN1> panes, PAN1 root)
{
panes.Add(root);
@ -584,12 +595,12 @@ namespace LayoutBXLYT
public GRP1(FileReader reader, Header header)
{
Name = reader.ReadString(0x10).Replace("\0", string.Empty);
Name = reader.ReadString(0x10, true);
ushort numNodes = reader.ReadUInt16();
reader.ReadUInt16();//padding
for (int i = 0; i < numNodes; i++)
Panes.Add(reader.ReadString(0x10));
Panes.Add(reader.ReadString(0x10, true));
}
public override void Write(FileWriter writer, BxlytHeader header)
@ -800,7 +811,7 @@ namespace LayoutBXLYT
Origin = reader.ReadByte();
Alpha = reader.ReadByte();
PaneMagFlags = reader.ReadByte();
Name = reader.ReadString(0x18).Replace("\0", string.Empty);
Name = reader.ReadString(0x18, true);
Translate = reader.ReadVec3SY();
Rotate = reader.ReadVec3SY();
Scale = reader.ReadVec2SY();
@ -870,10 +881,8 @@ namespace LayoutBXLYT
}
}
public class Material
public class Material : BxlytMaterial
{
public string Name { get; set; }
public STColor8 TevColor { get; set; }
public STColor8[] TevConstantColors { get; set; }
@ -881,7 +890,6 @@ namespace LayoutBXLYT
public List<TextureTransform> TextureTransforms { get; set; }
private uint flags;
private int unknown;
private BCLYT.Header ParentLayout;
public string GetTexture(int index)
@ -905,7 +913,7 @@ namespace LayoutBXLYT
TextureMaps = new List<TextureRef>();
TextureTransforms = new List<TextureTransform>();
Name = reader.ReadString(0x1C).Replace("\0", string.Empty);
Name = reader.ReadString(0x1C, true);
TevColor = reader.ReadColor8RGBA();
TevConstantColors = reader.ReadColor8sRGBA(8);
flags = reader.ReadUInt32();

View File

@ -44,7 +44,7 @@ namespace LayoutBXLYT
[DisplayName("Width"), CategoryAttribute("Pane")]
public float Width { get; set; }
[DisplayName("Width"), CategoryAttribute("Pane")]
[DisplayName("Height"), CategoryAttribute("Pane")]
public float Height { get; set; }
[DisplayName("Origin X"), CategoryAttribute("Origin")]
@ -80,6 +80,8 @@ namespace LayoutBXLYT
}
private CustomRectangle rectangle;
[Browsable(false)]
public CustomRectangle Rectangle
{
get
@ -167,9 +169,9 @@ namespace LayoutBXLYT
}
if (originY == OriginY.Top)
bottom = Height;
bottom = -Height;
else if (originY == OriginY.Bottom)
top = -Height;
top = Height;
else //To center
{
top = -Height / 2;
@ -352,14 +354,18 @@ namespace LayoutBXLYT
{
[DisplayName("Name"), CategoryAttribute("General")]
public virtual string Name { get; set; }
[Browsable(false)]
public virtual BxlytShader Shader { get; set; }
}
public class SectionCommon
{
[Browsable(false)]
public virtual string Signature { get; }
public uint SectionSize { get; set; }
public long StartPosition { get; set; }
internal uint SectionSize { get; set; }
internal long StartPosition { get; set; }
internal byte[] Data { get; set; }
public SectionCommon()

View File

@ -143,11 +143,6 @@ namespace LayoutBXLYT
//https://github.com/FuryBaguette/SwitchLayoutEditor/tree/master/SwitchThemesCommon
public class Header : BxlytHeader, IDisposable
{
public string FileName
{
get { return FileInfo.FileName; }
}
private const string Magic = "RLYT";
private ushort ByteOrderMark;
@ -173,6 +168,11 @@ namespace LayoutBXLYT
get { return TextureList.Textures; }
}
public override List<string> Fonts
{
get { return FontList.Fonts; }
}
public override Dictionary<string, STGenericTexture> GetTextures
{
get { return ((BRLYT)FileInfo).GetTextures(); }
@ -185,6 +185,17 @@ namespace LayoutBXLYT
return panes;
}
public override List<BxlytMaterial> GetMaterials()
{
List<BxlytMaterial> materials = new List<BxlytMaterial>();
if (MaterialList != null && MaterialList.Materials != null)
{
for (int i = 0; i < MaterialList.Materials.Count; i++)
materials.Add(MaterialList.Materials[i]);
}
return materials;
}
public List<GRP1> GetGroupPanes()
{
List<GRP1> panes = new List<GRP1>();
@ -586,12 +597,12 @@ namespace LayoutBXLYT
public GRP1(FileReader reader, Header header)
{
Name = reader.ReadString(0x10).Replace("\0", string.Empty);
Name = reader.ReadString(0x10, true);
ushort numNodes = reader.ReadUInt16();
reader.ReadUInt16();//padding
for (int i = 0; i < numNodes; i++)
Panes.Add(reader.ReadString(0x10));
Panes.Add(reader.ReadString(0x10, true));
}
public override void Write(FileWriter writer, BxlytHeader header)
@ -784,8 +795,8 @@ namespace LayoutBXLYT
Origin = reader.ReadByte();
Alpha = reader.ReadByte();
PaneMagFlags = reader.ReadByte();
Name = reader.ReadString(0x10).Replace("\0", string.Empty);
UserDataInfo = reader.ReadString(0x8).Replace("\0", string.Empty);
Name = reader.ReadString(0x10, true);
UserDataInfo = reader.ReadString(0x8, true);
Translate = reader.ReadVec3SY();
Rotate = reader.ReadVec3SY();
Scale = reader.ReadVec2SY();
@ -856,7 +867,7 @@ namespace LayoutBXLYT
}
}
public class Material
public class Material : BxlytMaterial
{
public string Name { get; set; }
@ -897,7 +908,7 @@ namespace LayoutBXLYT
TextureMaps = new List<TextureRef>();
TextureTransforms = new List<TextureTransform>();
Name = reader.ReadString(0x14).Replace("\0", string.Empty);
Name = reader.ReadString(0x14, true);
ForeColor = reader.ReadColor16RGBA();
BackColor = reader.ReadColor16RGBA();

View File

@ -294,6 +294,7 @@
<Compile Include="FileFormats\Font\BFTTF.cs" />
<Compile Include="FileFormats\HyruleWarriors\G1M\G1M.cs" />
<Compile Include="FileFormats\HyruleWarriors\LINKDATA.cs" />
<Compile Include="FileFormats\Layout\BxlytShader.cs" />
<Compile Include="FileFormats\Layout\CAFE\Materials\AlphaCompare.cs" />
<Compile Include="FileFormats\Layout\CAFE\Materials\BlendMode.cs" />
<Compile Include="FileFormats\Layout\CAFE\Materials\FontShadowParameter.cs" />
@ -330,7 +331,7 @@
<Compile Include="GL\GXToOpenGL.cs" />
<Compile Include="GL\KCL_Render.cs" />
<Compile Include="GL\LM2_Render.cs" />
<Compile Include="GUI\BFLYT\BflytShader.cs" />
<Compile Include="FileFormats\Layout\CAFE\BflytShader.cs" />
<Compile Include="GUI\BFLYT\FileSelector.cs">
<SubType>Form</SubType>
</Compile>

View File

@ -1,69 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenTK.Graphics.OpenGL;
using OpenTK;
namespace LayoutBXLYT
{
public class BflytShader : IDisposable
{
private int program;
private int vertexShader;
private int fragmentShader;
public BflytShader()
{
program = CompileShaders();
}
public void Dispose()
{
GL.DeleteProgram(program);
}
public string VertexShader
{
get
{
StringBuilder vert = new StringBuilder();
return vert.ToString();
}
}
public string FragmentShader
{
get
{
StringBuilder frag = new StringBuilder();
return frag.ToString();
}
}
private int CompileShaders()
{
vertexShader = GL.CreateShader(ShaderType.VertexShader);
GL.ShaderSource(vertexShader, VertexShader);
GL.CompileShader(vertexShader);
fragmentShader = GL.CreateShader(ShaderType.FragmentShader);
GL.ShaderSource(fragmentShader, FragmentShader);
GL.CompileShader(fragmentShader);
var program = GL.CreateProgram();
GL.AttachShader(program, vertexShader);
GL.AttachShader(program, fragmentShader);
GL.LinkProgram(program);
GL.DetachShader(program, vertexShader);
GL.DetachShader(program, fragmentShader);
GL.DeleteShader(vertexShader);
GL.DeleteShader(fragmentShader);
return program;
}
}
}

View File

@ -30,8 +30,13 @@
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(LayoutEditor));
this.dockPanel1 = new WeifenLuo.WinFormsUI.Docking.DockPanel();
this.backColorDisplay = new System.Windows.Forms.PictureBox();
this.stLabel1 = new Toolbox.Library.Forms.STLabel();
this.debugShading = new Toolbox.Library.Forms.STComboBox();
this.viewportBackColorCB = new Toolbox.Library.Forms.STComboBox();
this.stToolStrip1 = new Toolbox.Library.Forms.STToolStrip();
this.toolStripButton1 = new System.Windows.Forms.ToolStripButton();
this.toolstripOrthoBtn = new System.Windows.Forms.ToolStripButton();
this.stMenuStrip1 = new Toolbox.Library.Forms.STMenuStrip();
this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.openToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
@ -43,14 +48,9 @@
this.textureListToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.textConverterToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.orthographicViewToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.debugShading = new Toolbox.Library.Forms.STComboBox();
this.stLabel1 = new Toolbox.Library.Forms.STLabel();
this.backColorDisplay = new System.Windows.Forms.PictureBox();
this.toolStripButton1 = new System.Windows.Forms.ToolStripButton();
this.toolstripOrthoBtn = new System.Windows.Forms.ToolStripButton();
((System.ComponentModel.ISupportInitialize)(this.backColorDisplay)).BeginInit();
this.stToolStrip1.SuspendLayout();
this.stMenuStrip1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.backColorDisplay)).BeginInit();
this.SuspendLayout();
//
// dockPanel1
@ -62,6 +62,37 @@
this.dockPanel1.TabIndex = 6;
this.dockPanel1.ActiveDocumentChanged += new System.EventHandler(this.dockPanel1_ActiveDocumentChanged);
//
// backColorDisplay
//
this.backColorDisplay.Location = new System.Drawing.Point(253, 25);
this.backColorDisplay.Name = "backColorDisplay";
this.backColorDisplay.Size = new System.Drawing.Size(21, 21);
this.backColorDisplay.TabIndex = 10;
this.backColorDisplay.TabStop = false;
this.backColorDisplay.Click += new System.EventHandler(this.backColorDisplay_Click);
//
// stLabel1
//
this.stLabel1.AutoSize = true;
this.stLabel1.Location = new System.Drawing.Point(301, 28);
this.stLabel1.Name = "stLabel1";
this.stLabel1.Size = new System.Drawing.Size(84, 13);
this.stLabel1.TabIndex = 14;
this.stLabel1.Text = "Debug Shading:";
//
// debugShading
//
this.debugShading.BorderColor = System.Drawing.Color.Empty;
this.debugShading.BorderStyle = System.Windows.Forms.ButtonBorderStyle.Solid;
this.debugShading.ButtonColor = System.Drawing.Color.Empty;
this.debugShading.FormattingEnabled = true;
this.debugShading.IsReadOnly = false;
this.debugShading.Location = new System.Drawing.Point(391, 25);
this.debugShading.Name = "debugShading";
this.debugShading.Size = new System.Drawing.Size(146, 21);
this.debugShading.TabIndex = 13;
this.debugShading.SelectedIndexChanged += new System.EventHandler(this.debugShading_SelectedIndexChanged);
//
// viewportBackColorCB
//
this.viewportBackColorCB.BorderColor = System.Drawing.Color.Empty;
@ -87,6 +118,26 @@
this.stToolStrip1.TabIndex = 3;
this.stToolStrip1.Text = "stToolStrip1";
//
// toolStripButton1
//
this.toolStripButton1.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.toolStripButton1.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton1.Image")));
this.toolStripButton1.ImageTransparentColor = System.Drawing.Color.Magenta;
this.toolStripButton1.Name = "toolStripButton1";
this.toolStripButton1.Size = new System.Drawing.Size(23, 22);
this.toolStripButton1.Text = "toolStripButton1";
this.toolStripButton1.Click += new System.EventHandler(this.toolStripButton1_Click);
//
// toolstripOrthoBtn
//
this.toolstripOrthoBtn.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.toolstripOrthoBtn.Image = global::FirstPlugin.Properties.Resources.OrthoView;
this.toolstripOrthoBtn.ImageTransparentColor = System.Drawing.Color.Magenta;
this.toolstripOrthoBtn.Name = "toolstripOrthoBtn";
this.toolstripOrthoBtn.Size = new System.Drawing.Size(23, 22);
this.toolstripOrthoBtn.Text = "Toggle Orthographic";
this.toolstripOrthoBtn.Click += new System.EventHandler(this.toolstripOrthoBtn_Click);
//
// stMenuStrip1
//
this.stMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
@ -113,28 +164,28 @@
// openToolStripMenuItem
//
this.openToolStripMenuItem.Name = "openToolStripMenuItem";
this.openToolStripMenuItem.Size = new System.Drawing.Size(127, 22);
this.openToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.openToolStripMenuItem.Text = "Open";
this.openToolStripMenuItem.Click += new System.EventHandler(this.openToolStripMenuItem_Click);
//
// clearWorkspaceToolStripMenuItem
//
this.clearWorkspaceToolStripMenuItem.Name = "clearWorkspaceToolStripMenuItem";
this.clearWorkspaceToolStripMenuItem.Size = new System.Drawing.Size(127, 22);
this.clearWorkspaceToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.clearWorkspaceToolStripMenuItem.Text = "Clear Files";
this.clearWorkspaceToolStripMenuItem.Click += new System.EventHandler(this.clearWorkspaceToolStripMenuItem_Click);
//
// saveToolStripMenuItem1
//
this.saveToolStripMenuItem1.Name = "saveToolStripMenuItem1";
this.saveToolStripMenuItem1.Size = new System.Drawing.Size(127, 22);
this.saveToolStripMenuItem1.Size = new System.Drawing.Size(180, 22);
this.saveToolStripMenuItem1.Text = "Save";
this.saveToolStripMenuItem1.Click += new System.EventHandler(this.saveToolStripMenuItem1_Click);
//
// saveToolStripMenuItem
//
this.saveToolStripMenuItem.Name = "saveToolStripMenuItem";
this.saveToolStripMenuItem.Size = new System.Drawing.Size(127, 22);
this.saveToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.saveToolStripMenuItem.Text = "Save As";
this.saveToolStripMenuItem.Click += new System.EventHandler(this.saveToolStripMenuItem_Click);
//
@ -176,57 +227,6 @@
this.orthographicViewToolStripMenuItem.Text = "Orthographic View";
this.orthographicViewToolStripMenuItem.Click += new System.EventHandler(this.orthographicViewToolStripMenuItem_Click);
//
// debugShading
//
this.debugShading.BorderColor = System.Drawing.Color.Empty;
this.debugShading.BorderStyle = System.Windows.Forms.ButtonBorderStyle.Solid;
this.debugShading.ButtonColor = System.Drawing.Color.Empty;
this.debugShading.FormattingEnabled = true;
this.debugShading.IsReadOnly = false;
this.debugShading.Location = new System.Drawing.Point(391, 25);
this.debugShading.Name = "debugShading";
this.debugShading.Size = new System.Drawing.Size(146, 21);
this.debugShading.TabIndex = 13;
this.debugShading.SelectedIndexChanged += new System.EventHandler(this.debugShading_SelectedIndexChanged);
//
// stLabel1
//
this.stLabel1.AutoSize = true;
this.stLabel1.Location = new System.Drawing.Point(301, 28);
this.stLabel1.Name = "stLabel1";
this.stLabel1.Size = new System.Drawing.Size(84, 13);
this.stLabel1.TabIndex = 14;
this.stLabel1.Text = "Debug Shading:";
//
// backColorDisplay
//
this.backColorDisplay.Location = new System.Drawing.Point(253, 25);
this.backColorDisplay.Name = "backColorDisplay";
this.backColorDisplay.Size = new System.Drawing.Size(21, 21);
this.backColorDisplay.TabIndex = 10;
this.backColorDisplay.TabStop = false;
this.backColorDisplay.Click += new System.EventHandler(this.backColorDisplay_Click);
//
// toolStripButton1
//
this.toolStripButton1.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.toolStripButton1.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton1.Image")));
this.toolStripButton1.ImageTransparentColor = System.Drawing.Color.Magenta;
this.toolStripButton1.Name = "toolStripButton1";
this.toolStripButton1.Size = new System.Drawing.Size(23, 22);
this.toolStripButton1.Text = "toolStripButton1";
this.toolStripButton1.Click += new System.EventHandler(this.toolStripButton1_Click);
//
// toolstripOrthoBtn
//
this.toolstripOrthoBtn.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.toolstripOrthoBtn.Image = global::FirstPlugin.Properties.Resources.OrthoView;
this.toolstripOrthoBtn.ImageTransparentColor = System.Drawing.Color.Magenta;
this.toolstripOrthoBtn.Name = "toolstripOrthoBtn";
this.toolstripOrthoBtn.Size = new System.Drawing.Size(23, 22);
this.toolstripOrthoBtn.Text = "Toggle Orthographic";
this.toolstripOrthoBtn.Click += new System.EventHandler(this.toolstripOrthoBtn_Click);
//
// LayoutEditor
//
this.AllowDrop = true;
@ -246,11 +246,11 @@
this.DragEnter += new System.Windows.Forms.DragEventHandler(this.LayoutEditor_DragEnter);
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.LayoutEditor_KeyDown);
this.ParentChanged += new System.EventHandler(this.LayoutEditor_ParentChanged);
((System.ComponentModel.ISupportInitialize)(this.backColorDisplay)).EndInit();
this.stToolStrip1.ResumeLayout(false);
this.stToolStrip1.PerformLayout();
this.stMenuStrip1.ResumeLayout(false);
this.stMenuStrip1.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.backColorDisplay)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();

View File

@ -37,9 +37,10 @@
this.glControl1.Dock = System.Windows.Forms.DockStyle.Fill;
this.glControl1.Location = new System.Drawing.Point(0, 0);
this.glControl1.Name = "glControl1";
this.glControl1.Size = new System.Drawing.Size(625, 414);
this.glControl1.Size = new System.Drawing.Size(609, 375);
this.glControl1.TabIndex = 0;
this.glControl1.VSync = false;
this.glControl1.Load += new System.EventHandler(this.glControl1_Load);
this.glControl1.Paint += new System.Windows.Forms.PaintEventHandler(this.glControl1_Paint);
this.glControl1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.glControl1_MouseDown);
this.glControl1.MouseMove += new System.Windows.Forms.MouseEventHandler(this.glControl1_MouseMove);
@ -50,9 +51,9 @@
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(609, 375);
this.Controls.Add(this.glControl1);
this.Name = "LayoutViewer";
this.Size = new System.Drawing.Size(625, 414);
this.ResumeLayout(false);
}

View File

@ -29,11 +29,13 @@ namespace LayoutBXLYT
}
private RenderableTex backgroundTex;
public BxlytHeader LayoutFile;
private Dictionary<string, STGenericTexture> Textures;
private void glControl1_Load(object sender, EventArgs e)
{
}
public void ResetCamera()
{
Camera = new Camera2D();
@ -118,11 +120,11 @@ namespace LayoutBXLYT
GL.ClearColor(BackgroundColor);
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.Enable(EnableCap.AlphaTest);
GL.AlphaFunc(AlphaFunction.Gequal, 0.1f);
// GL.Disable(EnableCap.CullFace);
GL.Enable(EnableCap.Blend);
GL.Enable(EnableCap.AlphaTest);
GL.AlphaFunc(AlphaFunction.Always, 0f);
GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
GL.Enable(EnableCap.ColorMaterial);
GL.Enable(EnableCap.Texture2D);
GL.BindTexture(TextureTarget.Texture2D, 0);
@ -137,15 +139,20 @@ namespace LayoutBXLYT
DrawRootPane(LayoutFile.RootPane);
DrawGrid();
DrawXyLines();
RenderPanes(LayoutFile.RootPane, true, 255, false);
GL.BindTexture(TextureTarget.Texture2D, 0);
RenderPanes(LayoutFile.RootPane, true, 255, false, null, 0);
if (UseOrtho)
GL.PopMatrix();
GL.UseProgram(0);
glControl1.SwapBuffers();
}
private void RenderPanes(BasePane pane, bool isRoot, byte parentAlpha, bool parentAlphaInfluence, BasePane partPane = null)
private void RenderPanes(BasePane pane, bool isRoot, byte parentAlpha, bool parentAlphaInfluence, BasePane partPane = null, int stage = 0)
{
if (!pane.DisplayInEditor)
return;
@ -193,16 +200,23 @@ namespace LayoutBXLYT
}
byte effectiveAlpha = (byte)(parentAlpha == 255 ? pane.Alpha : (pane.Alpha * parentAlpha) / 255);
if (!parentAlphaInfluence)
effectiveAlpha = pane.Alpha;
parentAlphaInfluence = parentAlphaInfluence || pane.InfluenceAlpha;
if (!isRoot)
{
if (pane is BFLYT.PIC1)
DrawPicturePane((BFLYT.PIC1)pane, effectiveAlpha);
DrawPicturePane((BFLYT.PIC1)pane, effectiveAlpha, stage);
else if (pane is BCLYT.PIC1)
DrawPicturePane((BCLYT.PIC1)pane, effectiveAlpha);
else if (pane is BRLYT.PIC1)
DrawPicturePane((BRLYT.PIC1)pane, effectiveAlpha);
else if (pane is BFLYT.WND1)
DrawWindowPane((BFLYT.WND1)pane, effectiveAlpha);
else if (pane is BFLYT.BND1)
DrawBoundryPane((BFLYT.BND1)pane, effectiveAlpha);
else if (pane is BFLYT.PRT1)
DrawPartsPane((BFLYT.PRT1)pane, effectiveAlpha, parentAlphaInfluence);
else if (pane is BFLYT.PAN1)
@ -211,9 +225,6 @@ namespace LayoutBXLYT
DrawDefaultPane((BCLYT.PAN1)pane);
else if (pane is BRLYT.PAN1)
DrawDefaultPane((BRLYT.PAN1)pane);
// else if (pane is BFLYT.WND1)
// DrawWindowPane((BFLYT.WND1)pane, effectiveAlpha);
}
else
isRoot = false;
@ -254,6 +265,31 @@ namespace LayoutBXLYT
GL.End();
}
private void DrawBoundryPane(BFLYT.BND1 pane, byte effectiveAlpha)
{
Vector2[] TexCoords = new Vector2[] {
new Vector2(1,1),
new Vector2(0,1),
new Vector2(0,0),
new Vector2(1,0)
};
Color color = Color.DarkGreen;
if (SelectedPanes.Contains(pane))
color = Color.Red;
color = Color.FromArgb(70, color);
Color[] Colors = new Color[] {
color,
color,
color,
color,
};
DrawRectangle(pane.Rectangle, TexCoords, Colors, false, effectiveAlpha);
}
private void DrawDefaultPane(BasePane pane)
{
Vector2[] TexCoords = new Vector2[] {
@ -282,9 +318,7 @@ namespace LayoutBXLYT
pane.UpdateTextureData(this.Textures);
var partPane = pane.GetExternalPane();
if (partPane != null)
{
RenderPanes(partPane, false, effectiveAlpha, parentInfluenceAlpha);
}
RenderPanes(partPane, true, effectiveAlpha, parentInfluenceAlpha);
else
DrawDefaultPane(pane);
@ -293,13 +327,30 @@ namespace LayoutBXLYT
foreach (var prop in pane.Properties)
{
if (prop.Property != null)
{
RenderPanes(prop.Property, false, effectiveAlpha, parentInfluenceAlpha || pane.InfluenceAlpha);
}
}
}
}
private void DrawWindowPane(BFLYT.WND1 pane, byte effectiveAlpha)
{
Vector2[] TexCoords = new Vector2[] {
new Vector2(1,1),
new Vector2(0,1),
new Vector2(0,0),
new Vector2(1,0)
};
Color[] Colors = new Color[] {
pane.Content.ColorTopLeft.Color,
pane.Content.ColorTopRight.Color,
pane.Content.ColorBottomRight.Color,
pane.Content.ColorBottomLeft.Color,
};
float frameLeft = 0;
float frameTop = 0;
float frameRight = 0;
@ -316,11 +367,37 @@ namespace LayoutBXLYT
{
}
var mat = pane.Content.Material;
if (mat.Shader == null)
{
mat.Shader = new BflytShader(mat);
mat.Shader.Compile();
}
mat.Shader.Enable();
((BflytShader)mat.Shader).SetMaterials(Textures);
if (pane.Content.TexCoords.Count > 0)
{
TexCoords = new Vector2[] {
pane.Content.TexCoords[0].TopLeft.ToTKVector2(),
pane.Content.TexCoords[0].TopRight.ToTKVector2(),
pane.Content.TexCoords[0].BottomRight.ToTKVector2(),
pane.Content.TexCoords[0].BottomLeft.ToTKVector2(),
};
}
DrawRectangle(pane.Rectangle, TexCoords, Colors, false, effectiveAlpha);
mat.Shader.Disable();
GL.BindTexture(TextureTarget.Texture2D, 0);
GL.PopAttrib();
}
private void DrawPicturePane(BCLYT.PIC1 pane, byte effectiveAlpha)
{
Vector2[] TexCoords = new Vector2[] {
Vector2[] TexCoords = new Vector2[] {
new Vector2(1,1),
new Vector2(0,1),
new Vector2(0,0),
@ -353,7 +430,6 @@ namespace LayoutBXLYT
}
DrawRectangle(pane.Rectangle, TexCoords, Colors, false, effectiveAlpha);
GL.BindTexture(TextureTarget.Texture2D, 0);
}
@ -398,7 +474,7 @@ namespace LayoutBXLYT
GL.BindTexture(TextureTarget.Texture2D, 0);
}
private void DrawPicturePane(BFLYT.PIC1 pane, byte effectiveAlpha)
private void DrawPicturePane(BFLYT.PIC1 pane, byte effectiveAlpha, int stage = 0)
{
Vector2[] TexCoords = new Vector2[] {
new Vector2(1,1),
@ -415,35 +491,17 @@ namespace LayoutBXLYT
};
var mat = pane.Material;
bool defaultShading = Runtime.LayoutEditor.Shading == Runtime.LayoutEditor.DebugShading.Default;
SetBlending(mat.BlackColor.Color, mat.WhiteColor.Color);
if (pane.TexCoords.Length > 0 && defaultShading)
if (mat.Shader == null)
{
string textureMap0 = "";
if (mat.TextureMaps.Length > 0)
textureMap0 = mat.GetTexture(0);
mat.Shader = new BflytShader(mat);
mat.Shader.Compile();
}
if (Textures.ContainsKey(textureMap0))
BindGLTexture(mat.TextureMaps[0], Textures[textureMap0]);
else if (mat.TextureMaps.Length > 0)
{
}
if (mat.TextureTransforms.Length > 0)
{
GL.MatrixMode(MatrixMode.Texture);
GL.LoadIdentity();
var transform = mat.TextureTransforms[0];
GL.Scale(transform.Scale.X, transform.Scale.Y, 1);
GL.Rotate(transform.Rotate, 1, 0,0);
GL.Translate(transform.Translate.X, transform.Translate.Y, 1);
GL.MatrixMode(MatrixMode.Modelview);
}
mat.Shader.Enable();
((BflytShader)mat.Shader).SetMaterials(Textures);
if (pane.TexCoords.Length > 0)
{
TexCoords = new Vector2[] {
pane.TexCoords[0].TopLeft.ToTKVector2(),
pane.TexCoords[0].TopRight.ToTKVector2(),
@ -452,53 +510,71 @@ namespace LayoutBXLYT
};
}
if (pane.TexCoords.Length > 0 && Runtime.LayoutEditor.Shading == Runtime.LayoutEditor.DebugShading.UVTestPattern)
{
GL.BindTexture(TextureTarget.Texture2D, RenderTools.uvTestPattern.RenderableTex.TexID);
if (mat.TextureMaps.Length > 0)
{
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, ConvertTextureWrap(mat.TextureMaps[0].WrapModeU));
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, ConvertTextureWrap(mat.TextureMaps[0].WrapModeV));
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, ConvertMagFilterMode(mat.TextureMaps[0].MaxFilterMode));
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, ConvertMinFilterMode(mat.TextureMaps[0].MinFilterMode));
}
}
if (Runtime.LayoutEditor.Shading == Runtime.LayoutEditor.DebugShading.BlackColor)
{
for (int i = 0; i < Colors.Length; i++)
Colors[i] = pane.Material.BlackColor.Color;
}
if (Runtime.LayoutEditor.Shading == Runtime.LayoutEditor.DebugShading.WhiteColor)
{
for (int i = 0; i < Colors.Length; i++)
Colors[i] = pane.Material.WhiteColor.Color;
}
DrawRectangle(pane.Rectangle, TexCoords, Colors, false, effectiveAlpha);
GL.BindTexture(TextureTarget.Texture2D, 0);
mat.Shader.Disable();
// GL.PopAttrib();
// GL.PopAttrib();
GL.BindTexture(TextureTarget.Texture2D, 0);
GL.PopAttrib();
}
private void SetBlending(Color blackColor, Color whiteColor)
private static BlendingFactor ConvertBlendFactor(BlendMode.GX2BlendFactor blendFactor)
{
/* GL.PushAttrib(AttribMask.AllAttribBits);
GL.Enable(EnableCap.Blend);
GL.BlendFunc(BlendingFactor.ConstantColor, BlendingFactor.Zero);
GL.BlendEquation(BlendEquationMode.FuncAdd);
GL.BlendColor(Color.FromArgb(255, blackColor));
GL.Enable(EnableCap.Blend);*/
switch (blendFactor)
{
case BlendMode.GX2BlendFactor.DestAlpha: return BlendingFactor.DstAlpha;
case BlendMode.GX2BlendFactor.DestColor: return BlendingFactor.DstColor;
case BlendMode.GX2BlendFactor.DestInvAlpha: return BlendingFactor.OneMinusDstAlpha;
case BlendMode.GX2BlendFactor.DestInvColor: return BlendingFactor.OneMinusDstColor;
case BlendMode.GX2BlendFactor.Factor0: return BlendingFactor.Zero;
case BlendMode.GX2BlendFactor.Factor1: return BlendingFactor.One;
case BlendMode.GX2BlendFactor.SourceAlpha: return BlendingFactor.SrcAlpha;
case BlendMode.GX2BlendFactor.SourceColor: return BlendingFactor.SrcColor;
case BlendMode.GX2BlendFactor.SourceInvAlpha: return BlendingFactor.OneMinusSrcAlpha;
case BlendMode.GX2BlendFactor.SourceInvColor: return BlendingFactor.OneMinusSrcColor;
default: return BlendingFactor.Zero;
}
}
/* GL.PushAttrib(AttribMask.AllAttribBits);
GL.Enable(EnableCap.Blend);
GL.BlendFunc(BlendingFactor.ConstantColor, BlendingFactor.OneMinusSrcColor);
GL.BlendEquation(BlendEquationMode.FuncAdd);
GL.BlendColor(whiteColor);
GL.Enable(EnableCap.Blend);*/
private static LogicOp ConvertLogicOperation(BlendMode.GX2LogicOp blendOp)
{
switch (blendOp)
{
case BlendMode.GX2LogicOp.And: return LogicOp.And;
case BlendMode.GX2LogicOp.Clear: return LogicOp.Clear;
case BlendMode.GX2LogicOp.Copy: return LogicOp.Copy;
case BlendMode.GX2LogicOp.Equiv: return LogicOp.Equiv;
case BlendMode.GX2LogicOp.Inv: return LogicOp.Invert;
case BlendMode.GX2LogicOp.Nand: return LogicOp.Nand;
case BlendMode.GX2LogicOp.NoOp: return LogicOp.Noop;
case BlendMode.GX2LogicOp.Nor: return LogicOp.Nor;
case BlendMode.GX2LogicOp.Or: return LogicOp.Or;
case BlendMode.GX2LogicOp.RevAnd: return LogicOp.AndReverse;
case BlendMode.GX2LogicOp.RevOr: return LogicOp.OrReverse;
case BlendMode.GX2LogicOp.Set: return LogicOp.Set;
case BlendMode.GX2LogicOp.Xor: return LogicOp.Xor;
case BlendMode.GX2LogicOp.Disable:
GL.Disable(EnableCap.ColorLogicOp);
return LogicOp.Noop;
default: return LogicOp.Noop;
}
}
private static BlendEquationMode ConvertBlendOperation(BlendMode.GX2BlendOp blendOp)
{
switch (blendOp)
{
case BlendMode.GX2BlendOp.Add: return BlendEquationMode.FuncAdd;
case BlendMode.GX2BlendOp.ReverseSubtract: return BlendEquationMode.FuncReverseSubtract;
case BlendMode.GX2BlendOp.SelectMax: return BlendEquationMode.Max;
case BlendMode.GX2BlendOp.SelectMin: return BlendEquationMode.Min;
case BlendMode.GX2BlendOp.Subtract: return BlendEquationMode.FuncSubtract;
case BlendMode.GX2BlendOp.Disable:
GL.Disable(EnableCap.Blend);
return BlendEquationMode.FuncAdd;
default: return BlendEquationMode.FuncAdd;
}
}
public void DrawRectangle(CustomRectangle rect, Vector2[] texCoords,
@ -524,16 +600,16 @@ namespace LayoutBXLYT
{
GL.Begin(PrimitiveType.Quads);
GL.Color4(colors[0]);
GL.TexCoord2(texCoords[0]);
GL.MultiTexCoord2(TextureUnit.Texture0, texCoords[0].X, texCoords[0].Y);
GL.Vertex2(rect.LeftPoint, rect.BottomPoint);
GL.Color4(colors[1]);
GL.TexCoord2(texCoords[1]);
GL.MultiTexCoord2(TextureUnit.Texture0, texCoords[1].X, texCoords[1].Y);
GL.Vertex2(rect.RightPoint, rect.BottomPoint);
GL.Color4(colors[2]);
GL.TexCoord2(texCoords[2]);
GL.MultiTexCoord2(TextureUnit.Texture0, texCoords[2].X, texCoords[2].Y);
GL.Vertex2(rect.RightPoint, rect.TopPoint);
GL.Color4(colors[3]);
GL.TexCoord2(texCoords[3]);
GL.MultiTexCoord2(TextureUnit.Texture0, texCoords[3].X, texCoords[3].Y);
GL.Vertex2(rect.LeftPoint, rect.TopPoint);
GL.End();
@ -559,14 +635,14 @@ namespace LayoutBXLYT
Alpha = All.Alpha,
}
private static void BindGLTexture(TextureRef tex, STGenericTexture texture)
public static bool BindGLTexture(TextureRef tex, STGenericTexture texture)
{
if (texture.RenderableTex == null || !texture.RenderableTex.GLInitialized)
texture.LoadOpenGLTexture();
//If the texture is still not initialized then return
if (!texture.RenderableTex.GLInitialized)
return;
return false;
GL.BindTexture(TextureTarget.Texture2D, texture.RenderableTex.TexID);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleR, ConvertChannel(texture.RedChannel));
@ -577,6 +653,8 @@ namespace LayoutBXLYT
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, ConvertTextureWrap(tex.WrapModeV));
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, ConvertMagFilterMode(tex.MaxFilterMode));
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, ConvertMinFilterMode(tex.MinFilterMode));
return true;
}
private static int ConvertChannel(STChannelType type)

View File

@ -57,7 +57,7 @@ namespace Toolbox.Library
byte[] compSel = new byte[4] {0,1,2,3 };
if (format == TEX_FORMAT.L8 || format == TEX_FORMAT.LA8)
compSel = new byte[4] { 0, 0, 0, 1 };
compSel = new byte[4] { 2, 2, 2, 3 };
for (int Y = 0; Y < height; Y++)
@ -74,9 +74,9 @@ namespace Toolbox.Library
byte[] comp = GetComponentsFromPixel(format, pixel);
output[outPos + 3] = comp[compSel[3]];
output[outPos + 2] = comp[compSel[0]];
output[outPos + 2] = comp[compSel[2]];
output[outPos + 1] = comp[compSel[1]];
output[outPos + 0] = comp[compSel[2]];
output[outPos + 0] = comp[compSel[0]];
}
}

View File

@ -107,6 +107,7 @@ namespace Toolbox.Library.Rendering
}
private bool UseMipmaps = false;
private bool UseOpenGLDecoder = true;
public void LoadOpenGLTexture(STGenericTexture GenericTexture, int ArrayStartIndex = 0, bool LoadArrayLevels = false)
{
if (!Runtime.OpenTKInitialized || GLInitialized || Runtime.UseLegacyGL)
@ -161,7 +162,46 @@ namespace Toolbox.Library.Rendering
TextureMagFilter = TextureMagFilter.Linear;
}
switch (GenericTexture.Format)
//Force RGBA and use ST for decoding for weird width/heights
//Open GL decoder has issues with certain width/heights
Console.WriteLine($"width pow {width} {IsPow2(width)}");
Console.WriteLine($"height pow {height} {IsPow2(height)}");
if (!IsPow2(width) || !IsPow2(height))
UseOpenGLDecoder = false;
pixelInternalFormat = PixelInternalFormat.Rgba;
pixelFormat = OpenTK.Graphics.OpenGL.PixelFormat.Rgba;
if (UseOpenGLDecoder)
SetPixelFormats(GenericTexture.Format);
GLInitialized = true;
for (int i = 0; i < Surfaces.Count; i++)
{
for (int MipLevel = 0; MipLevel < Surfaces[i].mipmaps.Count; MipLevel++)
{
uint width = Math.Max(1, GenericTexture.Width >> MipLevel);
uint height = Math.Max(1, GenericTexture.Height >> MipLevel);
Surfaces[i].mipmaps[MipLevel] = DecodeWithoutOpenGLDecoder(Surfaces[i].mipmaps[MipLevel], width, height, GenericTexture);
}
}
TexID = GenerateOpenGLTexture(this, Surfaces);
Surfaces.Clear();
}
static bool IsPow2(int Value)
{
return Value != 0 && (Value & (Value - 1)) == 0;
}
private void SetPixelFormats(TEX_FORMAT Format)
{
switch (Format)
{
case TEX_FORMAT.BC1_UNORM:
pixelInternalFormat = PixelInternalFormat.CompressedRgbaS3tcDxt1Ext;
@ -231,25 +271,23 @@ namespace Toolbox.Library.Rendering
}
break;
}
GLInitialized = true;
for (int i = 0; i < Surfaces.Count; i++)
{
for (int MipLevel = 0; MipLevel < Surfaces[i].mipmaps.Count; MipLevel++)
{
uint width = Math.Max(1, GenericTexture.Width >> MipLevel);
uint height = Math.Max(1, GenericTexture.Height >> MipLevel);
Surfaces[i].mipmaps[MipLevel] = DecodeWithoutOpenGLDecoder(Surfaces[i].mipmaps[MipLevel], width, height, GenericTexture);
}
}
TexID = GenerateOpenGLTexture(this, Surfaces);
Surfaces.Clear();
}
private byte[] DecodeWithoutOpenGLDecoder(byte[] ImageData, uint width, uint height, STGenericTexture GenericTexture)
{
if (!UseOpenGLDecoder)
{
return STGenericTexture.ConvertBgraToRgba(
STGenericTexture.DecodeBlock(ImageData,
width,
height,
GenericTexture.Format,
new byte[0],
GenericTexture.Parameters,
PALETTE_FORMAT.None,
GenericTexture.PlatformSwizzle));
}
switch (GenericTexture.Format)
{
case TEX_FORMAT.BC1_UNORM:

View File

@ -0,0 +1,11 @@
uniform vec2 uvScale0;
uniform vec2 uvRotate0;
uniform vec2 uvTranslate0;
void main()
{
gl_FrontColor = gl_Color;
vec2 texCoord0 = uvScale0 * gl_MultiTexCoord0.xy + uvTranslate0;
gl_TexCoord[0].st = texCoord0;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}

View File

@ -245,6 +245,9 @@
<None Include="Shader\KCL.vert">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="Shader\Layout\Bflyt.vert">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="Shader\Legacy\BFRES.frag" />
<None Include="Shader\Legacy\BFRES.vert" />
<None Include="Shader\Legacy\KCL.frag">