1
0
mirror of synced 2024-11-15 03:27:38 +01:00
Switch-Toolbox/File_Format_Library/FileFormats/Layout/BxlytToGL.cs
KillzXGaming 644d94090f A big layout editor update.
Added support for previewing layout animations.
This includes pane SRT, tex SRT, material color (white/black blending), texture patterns, pane visibilty, and vertex colors.
Added textbox previewing.  The scaling will be off, and more features is planned (caching font data to disk for faster loading, improve rendering, etc).
Rotations now render correctly for X/Y axis.
Added game window preview. This removes any editor only drawn objects and also fits the layout to the screen (aka root pane) size.
Add support for rendering custom blending with layout materials.
Add support for loading character icons for mk8d. These are hardcoded and have been manually set. Note these will only load if within the menu.szs.
2019-09-28 17:27:48 -04:00

1338 lines
57 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Drawing;
using System.Drawing.Imaging;
using OpenTK.Graphics.OpenGL;
using Toolbox.Library;
using Toolbox.Library.IO;
using Toolbox.Library.Rendering;
using OpenTK;
using LayoutBXLYT.Cafe;
namespace LayoutBXLYT
{
public class BxlytToGL
{
public static int ConvertTextureWrap(WrapMode wrapMode)
{
switch (wrapMode)
{
case WrapMode.Clamp: return (int)TextureWrapMode.ClampToEdge;
case WrapMode.Mirror: return (int)TextureWrapMode.MirroredRepeat;
case WrapMode.Repeat: return (int)TextureWrapMode.Repeat;
default: return (int)TextureWrapMode.Clamp;
}
}
public static int ConvertMagFilterMode(FilterMode filterMode)
{
switch (filterMode)
{
case FilterMode.Linear: return (int)TextureMagFilter.Linear;
case FilterMode.Near: return (int)TextureMagFilter.Nearest;
default: return (int)TextureMagFilter.Linear;
}
}
public static int ConvertMinFilterMode(FilterMode filterMode)
{
switch (filterMode)
{
case FilterMode.Linear: return (int)TextureMinFilter.Linear;
case FilterMode.Near: return (int)TextureMinFilter.Nearest;
default: return (int)TextureMinFilter.Linear;
}
}
public static void DrawPictureBox(BasePane pane, bool gameWindow, byte effectiveAlpha, Dictionary<string, STGenericTexture> Textures)
{
if (!Runtime.LayoutEditor.DisplayPicturePane)
return;
Vector2[] TexCoords = new Vector2[] {
new Vector2(1,1),
new Vector2(0,1),
new Vector2(0,0),
new Vector2(1,0)
};
if (pane is Cafe.BFLYT.PIC1)
{
var pic1Pane = pane as Cafe.BFLYT.PIC1;
STColor8[] stColors = SetupVertexColors(pane,
pic1Pane.ColorBottomRight, pic1Pane.ColorBottomLeft,
pic1Pane.ColorTopLeft, pic1Pane.ColorTopRight);
Color[] Colors = new Color[] {
stColors[0].Color,
stColors[1].Color,
stColors[2].Color,
stColors[3].Color,
};
var mat = pic1Pane.Material;
if (mat.Shader == null)
{
mat.Shader = new BflytShader(mat);
mat.Shader.Compile();
}
mat.Shader.Enable();
((BflytShader)mat.Shader).SetMaterials(pic1Pane,Textures);
if (pic1Pane.TexCoords.Length > 0)
{
TexCoords = new Vector2[] {
pic1Pane.TexCoords[0].BottomLeft.ToTKVector2(),
pic1Pane.TexCoords[0].BottomRight.ToTKVector2(),
pic1Pane.TexCoords[0].TopRight.ToTKVector2(),
pic1Pane.TexCoords[0].TopLeft.ToTKVector2(),
};
}
DrawRectangle(pane, gameWindow, pane.Rectangle, TexCoords, Colors, false, effectiveAlpha);
mat.Shader.Disable();
}
else if (pane is BCLYT.PIC1)
{
var pic1Pane = pane as BCLYT.PIC1;
Color[] Colors = new Color[] {
pic1Pane.ColorBottomLeft.Color,
pic1Pane.ColorBottomRight.Color,
pic1Pane.ColorTopRight.Color,
pic1Pane.ColorTopLeft.Color,
};
var mat = pic1Pane.Material;
if (mat.Shader == null)
{
mat.Shader = new BclytShader(mat);
mat.Shader.Compile();
}
mat.Shader.Enable();
((BclytShader)mat.Shader).SetMaterials(pane,Textures);
if (pic1Pane.TexCoords.Length > 0)
{
TexCoords = new Vector2[] {
pic1Pane.TexCoords[0].BottomLeft.ToTKVector2(),
pic1Pane.TexCoords[0].BottomRight.ToTKVector2(),
pic1Pane.TexCoords[0].TopRight.ToTKVector2(),
pic1Pane.TexCoords[0].TopLeft.ToTKVector2(),
};
}
DrawRectangle(pane, gameWindow, pane.Rectangle, TexCoords, Colors, false, effectiveAlpha);
mat.Shader.Disable();
}
else if (pane is BRLYT.PIC1)
{
var pic1Pane = pane as BRLYT.PIC1;
Color[] Colors = new Color[] {
pic1Pane.ColorBottomLeft.Color,
pic1Pane.ColorBottomRight.Color,
pic1Pane.ColorTopRight.Color,
pic1Pane.ColorTopLeft.Color,
};
var mat = pic1Pane.Material;
if (mat.Shader == null)
{
mat.Shader = new BrlytShader(mat);
mat.Shader.Compile();
}
mat.Shader.Enable();
((BrlytShader)mat.Shader).SetMaterials(pane, Textures);
if (pic1Pane.TexCoords.Length > 0)
{
TexCoords = new Vector2[] {
pic1Pane.TexCoords[0].BottomLeft.ToTKVector2(),
pic1Pane.TexCoords[0].BottomRight.ToTKVector2(),
pic1Pane.TexCoords[0].TopRight.ToTKVector2(),
pic1Pane.TexCoords[0].TopLeft.ToTKVector2(),
};
}
DrawRectangle(pane, gameWindow, pane.Rectangle, TexCoords, Colors, false, effectiveAlpha);
mat.Shader.Disable();
}
GL.BindTexture(TextureTarget.Texture2D, 0);
GL.PopAttrib();
GL.UseProgram(0);
}
public static void DrawBoundryPane(BasePane pane, bool gameWindow, byte effectiveAlpha, List<BasePane> SelectedPanes)
{
if (!Runtime.LayoutEditor.DisplayBoundryPane || gameWindow || Runtime.LayoutEditor.IsGamePreview)
return;
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,
};
BxlytToGL.DrawRectangle(pane, gameWindow, pane.Rectangle, TexCoords, Colors, false, effectiveAlpha);
}
public static void DrawAlignmentPane(BasePane pane, bool gameWindow, byte effectiveAlpha, List<BasePane> SelectedPanes)
{
if (!Runtime.LayoutEditor.DisplayAlignmentPane || gameWindow || Runtime.LayoutEditor.IsGamePreview)
return;
Vector2[] TexCoords = new Vector2[] {
new Vector2(1,1),
new Vector2(0,1),
new Vector2(0,0),
new Vector2(1,0)
};
Color color = Color.Orange;
if (SelectedPanes.Contains(pane))
color = Color.Red;
color = Color.FromArgb(70, color);
Color[] Colors = new Color[] {
color,
color,
color,
color,
};
BxlytToGL.DrawRectangle(pane, gameWindow, pane.Rectangle, TexCoords, Colors, false, effectiveAlpha);
}
public static void DrawScissorPane(BasePane pane, bool gameWindow, byte effectiveAlpha, List<BasePane> SelectedPanes)
{
if (!Runtime.LayoutEditor.DisplayScissorPane || gameWindow || Runtime.LayoutEditor.IsGamePreview)
return;
Vector2[] TexCoords = new Vector2[] {
new Vector2(1,1),
new Vector2(0,1),
new Vector2(0,0),
new Vector2(1,0)
};
Color color = Color.Yellow;
if (SelectedPanes.Contains(pane))
color = Color.Red;
color = Color.FromArgb(70, color);
Color[] Colors = new Color[] {
color,
color,
color,
color,
};
BxlytToGL.DrawRectangle(pane, gameWindow, pane.Rectangle, TexCoords, Colors, false, effectiveAlpha);
}
public static void DrawTextbox(BasePane pane, bool gameWindow, Bitmap fontBitmap, byte effectiveAlpha,
Dictionary<string, STGenericTexture> Textures, List<BasePane> SelectedPanes, bool updateBitmap)
{
var textBox = (ITextPane)pane;
if (updateBitmap)
BindFontBitmap(pane, fontBitmap);
int width = (int)pane.Width;
int height = (int)pane.Height;
var mat = textBox.Material as BFLYT.Material;
if (mat.Shader == null)
{
mat.Shader = new BflytShader(mat);
mat.Shader.Compile();
}
mat.Shader.Enable();
((BflytShader)mat.Shader).SetMaterials(pane, Textures);
GL.ActiveTexture(TextureUnit.Texture0 + 1);
mat.Shader.SetInt($"numTextureMaps", 1);
mat.Shader.SetInt($"textures0", 1);
mat.Shader.SetInt($"hasTexture0", 1);
GL.BindTexture(TextureTarget.Texture2D, textBox.RenderableFont.TexID);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleR, ConvertChannel(STChannelType.Red));
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleG, ConvertChannel(STChannelType.Green));
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleB, ConvertChannel(STChannelType.Blue));
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleA, ConvertChannel(STChannelType.Alpha));
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS,(int)TextureWrapMode.Clamp);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Clamp);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
Vector2[] texCoords = new Vector2[] {
new Vector2(0, 1),
new Vector2(1, 1),
new Vector2(1, 0),
new Vector2(0, 0),
};
Color color = Color.White;
Color[] Colors = new Color[] {
color,
color,
color,
color,
};
DrawRectangle(pane, gameWindow, pane.Rectangle, texCoords, Colors, false, effectiveAlpha);
GL.BindTexture(TextureTarget.Texture2D, 0);
}
private static void BindFontBitmap(BasePane pane, Bitmap fontBitmap)
{
var textBox = (ITextPane)pane;
switch ($"{textBox.HorizontalAlignment}_{textBox.VerticalAlignment}")
{
case "Center_Center":
{
Bitmap b = new Bitmap((int)pane.Width, (int)pane.Height);
using (Graphics g = Graphics.FromImage(b))
g.DrawImage(fontBitmap, b.Width / 2f - fontBitmap.Width / 2f, b.Height / 2f - fontBitmap.Height / 2f);
fontBitmap = b;
}
break;
case "Left_Center":
{
Bitmap b = new Bitmap((int)pane.Width, (int)pane.Height);
using (Graphics g = Graphics.FromImage(b))
g.DrawImage(fontBitmap, 0, b.Height / 2f - fontBitmap.Height / 2f);
fontBitmap = b;
}
break;
case "Right_Center":
{
Bitmap b = new Bitmap((int)pane.Width, (int)pane.Height);
using (Graphics g = Graphics.FromImage(b))
g.DrawImage(fontBitmap, 0, b.Height / 2f - fontBitmap.Height / 2f);
fontBitmap = b;
}
break;
case "Center_Top":
{
Bitmap b = new Bitmap((int)pane.Width, (int)pane.Height);
using (Graphics g = Graphics.FromImage(b))
g.DrawImage(fontBitmap, b.Width - fontBitmap.Width, b.Height / 2f - fontBitmap.Height / 2f);
fontBitmap = b;
}
break;
case "Center_Bottom":
{
Bitmap b = new Bitmap((int)pane.Width, (int)pane.Height);
using (Graphics g = Graphics.FromImage(b))
g.DrawImage(fontBitmap, b.Width / 2f - fontBitmap.Width / 2f, b.Height - fontBitmap.Height);
fontBitmap = b;
}
break;
case "Left_Top":
{
Bitmap b = new Bitmap((int)pane.Width, (int)pane.Height);
using (Graphics g = Graphics.FromImage(b))
g.DrawImage(fontBitmap, 0, 0);
fontBitmap = b;
}
break;
case "Right_Top":
{
Bitmap b = new Bitmap((int)pane.Width, (int)pane.Height);
using (Graphics g = Graphics.FromImage(b))
g.DrawImage(fontBitmap, b.Width - fontBitmap.Width, 0);
fontBitmap = b;
}
break;
case "Left_Bottom":
{
Bitmap b = new Bitmap((int)pane.Width, (int)pane.Height);
using (Graphics g = Graphics.FromImage(b))
g.DrawImage(fontBitmap, 0, b.Height - fontBitmap.Height);
fontBitmap = b;
}
break;
case "Right_Bottom":
{
Bitmap b = new Bitmap((int)pane.Width, (int)pane.Height);
using (Graphics g = Graphics.FromImage(b))
g.DrawImage(fontBitmap, b.Width - fontBitmap.Width, b.Height - fontBitmap.Height);
fontBitmap = b;
}
break;
}
if (textBox.RenderableFont == null)
textBox.RenderableFont = RenderableTex.FromBitmap(fontBitmap);
else
textBox.RenderableFont.UpdateFromBitmap(fontBitmap);
textBox.RenderableFont.TextureWrapS = TextureWrapMode.Clamp;
textBox.RenderableFont.TextureWrapT = TextureWrapMode.Clamp;
}
//Huge thanks to layout studio for the window pane rendering code
//https://github.com/Treeki/LayoutStudio/blob/master/layoutgl/widget.cpp
//Note i still need to fix UV coordinates being flips and transformed!
public static void DrawWindowPane(BasePane pane,bool gameWindow, byte effectiveAlpha, Dictionary<string, STGenericTexture> Textures)
{
if (!Runtime.LayoutEditor.DisplayWindowPane)
return;
var window = (IWindowPane)pane;
float dX = DrawnVertexX(pane.Width, pane.originX);
float dY = DrawnVertexY(pane.Height, pane.originY);
float frameLeft = 0;
float frameRight = 0;
float frameTop = 0;
float frameBottom = 0;
switch (window.FrameCount)
{
case 1:
float oneW, oneH;
GetTextureSize(window.WindowFrames[0].Material, Textures, out oneW, out oneH);
frameLeft = frameRight = oneW;
frameTop = frameBottom = oneH;
break;
case 4:
case 8:
GetTextureSize(window.WindowFrames[0].Material, Textures, out frameLeft, out frameTop);
GetTextureSize(window.WindowFrames[3].Material, Textures, out frameRight, out frameBottom);
break;
}
if (frameLeft == 0) frameLeft = window.FrameElementLeft;
if (frameRight == 0) frameRight = window.FrameElementRight;
if (frameTop == 0) frameTop = window.FrameElementTop;
if (frameBottom == 0) frameBottom = window.FrameElementBottm;
Vector2[] texCoords = new Vector2[] {
new Vector2(0, 0),
new Vector2(1, 0),
new Vector2(1, 1),
new Vector2(0, 1),
};
if (window.Content.TexCoords.Count > 0)
{
texCoords = new Vector2[] {
window.Content.TexCoords[0].BottomLeft.ToTKVector2(),
window.Content.TexCoords[0].BottomRight.ToTKVector2(),
window.Content.TexCoords[0].TopRight.ToTKVector2(),
window.Content.TexCoords[0].TopLeft.ToTKVector2(),
};
}
//Setup vertex colors
Color[] colors = new Color[] {
window.Content.ColorBottomLeft.Color,
window.Content.ColorBottomRight.Color,
window.Content.ColorTopRight.Color,
window.Content.ColorTopLeft.Color,
};
float contentWidth = ((window.StretchLeft + (pane.Width - frameLeft)) - frameRight) + window.StretchRight;
float contentHeight = ((window.StretchTop + (pane.Height - frameTop)) - frameBottom) + window.StretchBottm;
//Apply pane alpha
for (int i = 0; i < colors.Length; i++)
{
uint setalpha = (uint)((colors[i].A * effectiveAlpha) / 255);
colors[i] = Color.FromArgb((int)setalpha, colors[i]);
}
if (!window.NotDrawnContent && window.WindowKind != WindowKind.HorizontalNoContent)
{
SetupShaders(pane, window.Content.Material, Textures);
DrawQuad(gameWindow, dX + frameLeft - window.StretchLeft,
dY - frameTop + window.StretchTop,
contentWidth,
contentHeight,
texCoords, colors);
}
//After the content is draw, check this
//If it's disabled, frames do not use vertex color
if (!window.UseVertexColorForAll)
{
colors = new Color[] {
Color.FromArgb(effectiveAlpha, 255,255,255),
Color.FromArgb(effectiveAlpha, 255,255,255),
Color.FromArgb(effectiveAlpha, 255,255,255),
Color.FromArgb(effectiveAlpha, 255,255,255),
};
}
switch (window.FrameCount)
{
case 2: //2 frame. 2 textures for corners sides (horizontal)
case 1: //1 frame. 1 texture for corners (around) or sides (horizontal)
{
var windowFrame = window.WindowFrames[0];
SetupShaders(pane, windowFrame.Material, Textures);
//2 sides, no corners
if (window.WindowKind == WindowKind.Horizontal)
{
//Left
texCoords = new Vector2[]
{
new Vector2(1, 0),
new Vector2(0, 0),
new Vector2(0, 1),
new Vector2(1, 1),
};
colors = new Color[] {
window.Content.ColorTopRight.Color,
window.Content.ColorTopRight.Color,
window.Content.ColorBottomRight.Color,
window.Content.ColorBottomRight.Color,
};
DrawQuad(gameWindow, dX + frameRight + contentWidth, dY, frameRight, pane.Height, texCoords, colors);
//Right
if (window.FrameCount == 2)
SetupShaders(pane, window.WindowFrames[1].Material, Textures);
texCoords = new Vector2[]
{
new Vector2(0, 0),
new Vector2(1, 0),
new Vector2(1, 1),
new Vector2(0, 1),
};
colors = new Color[] {
window.Content.ColorTopLeft.Color,
window.Content.ColorTopLeft.Color,
window.Content.ColorBottomLeft.Color,
window.Content.ColorBottomLeft.Color,
};
DrawQuad(gameWindow, dX, dY, frameLeft, pane.Height, texCoords, colors);
}
else if (window.WindowKind == WindowKind.HorizontalNoContent)
{
//Right
texCoords = new Vector2[]
{
new Vector2((pane.Width - frameRight) / frameRight, 0),
new Vector2(0, 0),
new Vector2(0, 1),
new Vector2((pane.Width - frameRight) / frameRight, 1),
};
colors = new Color[] {
//Top Right
window.Content.ColorTopRight.Color,
//Top Left
VertexColorHelper.Mix(window.Content.ColorTopLeft.Color,
window.Content.ColorTopRight.Color,
(frameLeft / frameLeft)),
//Bottom Left
VertexColorHelper.Mix(window.Content.ColorBottomLeft.Color,
window.Content.ColorBottomRight.Color,
(frameLeft / frameLeft)),
//Bottom Right
window.Content.ColorBottomRight.Color,
};
DrawQuad(gameWindow, dX + frameLeft, dY, pane.Width - frameLeft, pane.Height, texCoords, colors);
//Left
if (window.FrameCount == 2)
SetupShaders(pane, window.WindowFrames[1].Material, Textures);
colors = new Color[] {
//Top Left
window.Content.ColorTopLeft.Color,
//Top Right
VertexColorHelper.Mix(window.Content.ColorTopLeft.Color,
window.Content.ColorTopRight.Color,
1),
//Bottom Right
VertexColorHelper.Mix(window.Content.ColorBottomLeft.Color,
window.Content.ColorBottomRight.Color,
1),
//Bottom Left
window.Content.ColorBottomLeft.Color,
};
texCoords = new Vector2[]
{
new Vector2(0, 0),
new Vector2((pane.Width - frameLeft) / frameLeft, 0),
new Vector2((pane.Width - frameLeft) / frameLeft, 1),
new Vector2(0, 1),
};
DrawQuad(gameWindow, dX, dY, pane.Width - frameLeft, pane.Height, texCoords, colors);
}
else if (window.WindowKind == WindowKind.Around)
{
// top left
float pieceWidth = pane.Width - frameRight;
float pieceHeight = frameTop;
texCoords = new Vector2[]
{
new Vector2(0, 0),
new Vector2((pane.Width - frameLeft) / frameLeft, 0),
new Vector2((pane.Width - frameLeft) / frameLeft, 1),
new Vector2(0, 1),
};
DrawQuad(gameWindow, dX, dY, pieceWidth, pieceHeight, texCoords, colors);
// top right
pieceWidth = frameRight;
pieceHeight = pane.Height - frameBottom;
texCoords = new Vector2[]
{
new Vector2(1, 0),
new Vector2(0, 0),
new Vector2(0,(pane.Height - frameTop) / frameTop),
new Vector2(1,(pane.Height - frameTop) / frameTop),
};
DrawQuad(gameWindow, dX + pane.Width - frameRight, dY, pieceWidth, pieceHeight, texCoords, colors);
// bottom left
pieceWidth = frameLeft;
pieceHeight = pane.Height - frameTop;
texCoords = new Vector2[]
{
new Vector2(0,(pane.Height - frameBottom) / frameBottom),
new Vector2(1,(pane.Height - frameBottom) / frameBottom),
new Vector2(1, 0),
new Vector2(0, 0),
};
DrawQuad(gameWindow, dX, dY - frameTop, pieceWidth, pieceHeight, texCoords, colors);
// bottom right
pieceWidth = pane.Width - frameLeft;
pieceHeight = frameBottom;
texCoords = new Vector2[]
{
new Vector2((pane.Width - frameLeft) / frameLeft, 1),
new Vector2(0, 1),
new Vector2(0, 0),
new Vector2((pane.Width - frameLeft) / frameLeft, 0),
};
DrawQuad(gameWindow, dX + frameLeft, dY - pane.Height + frameBottom, pieceWidth, pieceHeight, texCoords, colors);
}
}
break;
//4 or more will always be around types
case 4: //4 each corner
{
var matTL = window.WindowFrames[0].Material;
var matTR = window.WindowFrames[1].Material;
var matBL = window.WindowFrames[2].Material;
var matBR = window.WindowFrames[3].Material;
//Todo check this
if (window.UseOneMaterialForAll)
{
/* matTR = matTL;
matBL = matTL;
matBR = matTL;*/
}
if (matTL.TextureMaps.Length > 0)
{
SetupShaders(pane, matTL, Textures);
matTL.Shader.SetInt("flipTexture", (int)window.WindowFrames[0].TextureFlip);
float pieceWidth = pane.Width - frameRight;
float pieceHeight = frameTop;
texCoords = new Vector2[]
{
new Vector2(0, 0),
new Vector2((pane.Width - frameLeft) / frameLeft, 0),
new Vector2((pane.Width - frameLeft) / frameLeft, 1),
new Vector2(0, 1),
};
DrawQuad(gameWindow, dX, dY, pieceWidth, pieceHeight, texCoords, colors);
}
if (matTR.TextureMaps.Length > 0)
{
SetupShaders(pane, matTR, Textures);
matTR.Shader.SetInt("flipTexture", (int)window.WindowFrames[1].TextureFlip);
float pieceWidth = frameRight;
float pieceHeight = pane.Height - frameBottom;
texCoords = new Vector2[]
{
new Vector2(0, 0),
new Vector2(1, 0),
new Vector2(1,(pane.Height - frameTop) / frameTop),
new Vector2(0,(pane.Height - frameTop) / frameTop),
};
DrawQuad(gameWindow, dX + pane.Width - frameRight, dY, pieceWidth, pieceHeight, texCoords, colors);
}
if (matBL.TextureMaps.Length > 0)
{
SetupShaders(pane, matBL, Textures);
matBL.Shader.SetInt("flipTexture", (int)window.WindowFrames[2].TextureFlip);
float pieceWidth = frameLeft;
float pieceHeight = pane.Height - frameTop;
texCoords = new Vector2[]
{
new Vector2(0,1 - ((pane.Height - frameTop) / frameTop)),
new Vector2(1,1 - ((pane.Height - frameTop) / frameTop)),
new Vector2(1, 1),
new Vector2(0, 1),
};
DrawQuad(gameWindow, dX, dY - frameTop, pieceWidth, pieceHeight, texCoords, colors);
}
if (matBR.TextureMaps.Length > 0)
{
SetupShaders(pane, matBR, Textures);
matBR.Shader.SetInt("flipTexture", (int)window.WindowFrames[3].TextureFlip);
float pieceWidth = pane.Width - frameLeft;
float pieceHeight = frameBottom;
texCoords = new Vector2[]
{
new Vector2(1 - ((pane.Width - frameLeft) / frameLeft), 0),
new Vector2(1, 0),
new Vector2(1, 1),
new Vector2(1 - ((pane.Width - frameLeft) / frameLeft), 1),
};
DrawQuad(gameWindow, dX + frameLeft, dY - pane.Height + frameBottom, pieceWidth, pieceHeight, texCoords, colors);
}
}
break;
case 8: //4 per corner, 4 per side
{
var matTL = window.WindowFrames[0].Material;
var matTR = window.WindowFrames[1].Material;
var matBL = window.WindowFrames[2].Material;
var matBR = window.WindowFrames[3].Material;
var matT = window.WindowFrames[4].Material;
var matB = window.WindowFrames[5].Material;
var matL = window.WindowFrames[6].Material;
var matR = window.WindowFrames[7].Material;
//Todo check this
if (window.UseOneMaterialForAll)
{
/* matTR = matTL;
matBL = matTL;
matBR = matTL;
matT = matTL;
matB = matTL;
matL = matTL;
matR = matTL;*/
}
if (matTL.TextureMaps.Length > 0)
{
SetupShaders(pane, matTL, Textures);
matTL.Shader.SetInt("flipTexture", (int)window.WindowFrames[0].TextureFlip);
texCoords = new Vector2[]
{
new Vector2(0, 0),
new Vector2(1, 0),
new Vector2(1, 1),
new Vector2(0, 1),
};
DrawQuad(gameWindow, dX, dY, frameLeft, frameTop, texCoords, colors);
}
if (matTR.TextureMaps.Length > 0)
{
SetupShaders(pane, matTR, Textures);
matTR.Shader.SetInt("flipTexture", (int)window.WindowFrames[1].TextureFlip);
texCoords = new Vector2[]
{
new Vector2(0, 0),
new Vector2(1, 0),
new Vector2(1, 1),
new Vector2(0, 1),
};
DrawQuad(gameWindow, dX + pane.Width - frameRight, dY, frameRight, frameTop, texCoords, colors);
}
if (matBL.TextureMaps.Length > 0)
{
SetupShaders(pane, matBL, Textures);
matBL.Shader.SetInt("flipTexture", (int)window.WindowFrames[2].TextureFlip);
texCoords = new Vector2[]
{
new Vector2(0, 0),
new Vector2(1, 0),
new Vector2(1, 1),
new Vector2(0, 1),
};
DrawQuad(gameWindow, dX, dY - pane.Height + frameTop, frameLeft, frameBottom, texCoords, colors);
}
if (matBR.TextureMaps.Length > 0)
{
SetupShaders(pane, matBR, Textures);
matBR.Shader.SetInt("flipTexture", (int)window.WindowFrames[3].TextureFlip);
texCoords = new Vector2[]
{
new Vector2(0, 0),
new Vector2(1, 0),
new Vector2(1, 1),
new Vector2(0, 1),
};
DrawQuad(gameWindow, dX + pane.Width - frameLeft, dY - pane.Height + frameBottom, frameRight, frameBottom, texCoords, colors);
}
if (matT.TextureMaps.Length > 0)
{
SetupShaders(pane, matT, Textures);
matT.Shader.SetInt("flipTexture", (int)window.WindowFrames[4].TextureFlip);
texCoords = new Vector2[]
{
new Vector2(0, 0),
new Vector2((pane.Width - frameLeft) / frameLeft, 0),
new Vector2((pane.Width - frameLeft) / frameLeft, 1),
new Vector2(0, 1),
};
DrawQuad(gameWindow, dX + frameLeft, dY, contentWidth, frameTop, texCoords, colors);
}
if (matB.TextureMaps.Length > 0)
{
SetupShaders(pane, matB, Textures);
matB.Shader.SetInt("flipTexture", (int)window.WindowFrames[5].TextureFlip);
texCoords = new Vector2[]
{
new Vector2(1-((pane.Width - frameLeft) / frameLeft), 0),
new Vector2(1, 0),
new Vector2(1, 1),
new Vector2(1-((pane.Width - frameLeft) / frameLeft), 1),
};
DrawQuad(gameWindow, dX + frameRight, dY - (pane.Height - frameBottom), contentWidth, frameTop, texCoords, colors);
}
if (matL.TextureMaps.Length > 0)
{
SetupShaders(pane, matL, Textures);
matL.Shader.SetInt("flipTexture", (int)window.WindowFrames[6].TextureFlip);
texCoords = new Vector2[]
{
new Vector2(0,1-((pane.Height - frameTop) / frameTop)),
new Vector2(1,1-((pane.Height - frameTop) / frameTop)),
new Vector2(1, 1),
new Vector2(0, 1),
};
DrawQuad(gameWindow, dX, dY - frameTop, frameLeft, contentHeight, texCoords, colors);
}
if (matR.TextureMaps.Length > 0)
{
SetupShaders(pane, matR, Textures);
matR.Shader.SetInt("flipTexture", (int)window.WindowFrames[7].TextureFlip);
texCoords = new Vector2[]
{
new Vector2(0, 0),
new Vector2(1, 0),
new Vector2(1,(pane.Height - frameBottom) / frameBottom),
new Vector2(0,(pane.Height - frameBottom) / frameBottom),
};
DrawQuad(gameWindow, dX + (pane.Width - frameRight), dY - frameTop, frameRight, contentHeight, texCoords, colors);
}
}
break;
}
}
private static void GetTextureSize(BxlytMaterial pane, Dictionary<string, STGenericTexture> Textures, out float width, out float height)
{
width = 0;
height = 0;
if (pane.TextureMaps.Length > 0)
{
if (Textures.ContainsKey(pane.TextureMaps[0].Name))
{
var tex = Textures[pane.TextureMaps[0].Name];
width = tex.Width;
height = tex.Height;
}
}
}
private static float DrawnVertexX(float width, OriginX originX)
{
switch (originX)
{
case OriginX.Center: return -width / 2.0f;
case OriginX.Right: return -width;
default: return 0.0f;
}
}
private static float DrawnVertexY(float height, OriginY originX)
{
switch (originX)
{
case OriginY.Center: return height / 2.0f;
case OriginY.Bottom: return height;
default: return 0.0f;
}
}
private static void DrawQuad(bool gameWindow, float x, float y, float w, float h, Vector2[] texCoords, Color[] colors)
{
if (!gameWindow && !Runtime.LayoutEditor.IsGamePreview)
{
GL.Disable(EnableCap.AlphaTest);
GL.Disable(EnableCap.Blend);
GL.LineWidth(0.5f);
GL.Begin(PrimitiveType.LineLoop);
GL.Color4(Color.Green);
GL.Vertex2(x, y);
GL.Vertex2(x + w, y);
GL.Vertex2(x + w, y - h);
GL.Vertex2(x, y - h);
GL.End();
GL.LineWidth(1f);
GL.Enable(EnableCap.AlphaTest);
GL.Enable(EnableCap.Blend);
}
GL.Begin(PrimitiveType.Quads);
GL.Color4(colors[0]);
GL.MultiTexCoord2(TextureUnit.Texture0, texCoords[0].X, texCoords[0].Y);
GL.Vertex2(x, y);
GL.Color4(colors[1]);
GL.MultiTexCoord2(TextureUnit.Texture0, texCoords[1].X, texCoords[1].Y);
GL.Vertex2(x + w, y);
GL.Color4(colors[2]);
GL.MultiTexCoord2(TextureUnit.Texture0, texCoords[2].X, texCoords[2].Y);
GL.Vertex2(x + w, y - h);
GL.Color4(colors[3]);
GL.MultiTexCoord2(TextureUnit.Texture0, texCoords[3].X, texCoords[3].Y);
GL.Vertex2(x, y - h);
GL.End();
}
enum FrameType
{
LeftTop,
Left,
LeftBottom,
Top,
Bottom,
RightTop,
Right,
RightBottom,
}
private static Vector2 GetFramePosition(uint paneWidth, uint paneHeight, IWindowPane window, FrameType type)
{
Vector2 pos = new Vector2();
switch (type)
{
case FrameType.LeftTop:
break;
}
return pos;
}
private static void SetupShaders(BasePane pane, BxlytMaterial mat, Dictionary<string, STGenericTexture> textures)
{
if (mat.Shader == null)
{
if (mat is Cafe.BFLYT.Material)
{
mat.Shader = new BflytShader((Cafe.BFLYT.Material)mat);
mat.Shader.Compile();
}
}
mat.Shader.Enable();
if (mat is Cafe.BFLYT.Material)
((BflytShader)mat.Shader).SetMaterials(pane, textures);
}
private static void RenderWindowContent(BasePane pane, uint sizeX, uint sizeY, BxlytWindowContent content,
byte effectiveAlpha, Dictionary<string, STGenericTexture> Textures)
{
var mat = content.Material;
var rect = pane.CreateRectangle(sizeX, sizeY);
SetupShaders(pane, mat, Textures);
Vector2[] texCoords = new Vector2[] {
new Vector2(1,1),
new Vector2(0,1),
new Vector2(0,0),
new Vector2(1,0)
};
Color[] colors = new Color[] {
content.ColorBottomLeft.Color,
content.ColorBottomRight.Color,
content.ColorTopRight.Color,
content.ColorTopLeft.Color,
};
if (content.TexCoords.Count > 0)
{
texCoords = new Vector2[] {
content.TexCoords[0].BottomLeft.ToTKVector2(),
content.TexCoords[0].BottomRight.ToTKVector2(),
content.TexCoords[0].TopRight.ToTKVector2(),
content.TexCoords[0].TopLeft.ToTKVector2(),
};
}
GL.Begin(PrimitiveType.Quads);
GL.Color4(colors[0]);
GL.MultiTexCoord2(TextureUnit.Texture0, texCoords[0].X, texCoords[0].Y);
GL.Vertex2(rect.LeftPoint, rect.BottomPoint);
GL.Color4(colors[1]);
GL.MultiTexCoord2(TextureUnit.Texture0, texCoords[1].X, texCoords[1].Y);
GL.Vertex2(rect.RightPoint, rect.BottomPoint);
GL.Color4(colors[2]);
GL.MultiTexCoord2(TextureUnit.Texture0, texCoords[2].X, texCoords[2].Y);
GL.Vertex2(rect.RightPoint, rect.TopPoint);
GL.Color4(colors[3]);
GL.MultiTexCoord2(TextureUnit.Texture0, texCoords[3].X, texCoords[3].Y);
GL.Vertex2(rect.LeftPoint, rect.TopPoint);
GL.End();
}
public static bool BindGLTexture(BxlytTextureRef 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 false;
GL.BindTexture(TextureTarget.Texture2D, texture.RenderableTex.TexID);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleR, ConvertChannel(texture.RedChannel));
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleG, ConvertChannel(texture.GreenChannel));
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleB, ConvertChannel(texture.BlueChannel));
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleA, ConvertChannel(texture.AlphaChannel));
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));
return true;
}
private static int ConvertChannel(STChannelType type)
{
switch (type)
{
case STChannelType.Red: return (int)TextureSwizzle.Red;
case STChannelType.Green: return (int)TextureSwizzle.Green;
case STChannelType.Blue: return (int)TextureSwizzle.Blue;
case STChannelType.Alpha: return (int)TextureSwizzle.Alpha;
case STChannelType.Zero: return (int)TextureSwizzle.Zero;
case STChannelType.One: return (int)TextureSwizzle.One;
default: return 0;
}
}
public static BlendingFactor ConvertBlendFactor(BlendMode.GX2BlendFactor blendFactor)
{
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;
}
}
public 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;
}
}
public static AlphaFunction ConvertAlphaFunc(GfxAlphaFunction alphaFunc)
{
switch (alphaFunc)
{
case GfxAlphaFunction.Always: return AlphaFunction.Always;
case GfxAlphaFunction.Equal: return AlphaFunction.Equal;
case GfxAlphaFunction.Greater: return AlphaFunction.Greater;
case GfxAlphaFunction.GreaterOrEqual: return AlphaFunction.Gequal;
case GfxAlphaFunction.Less: return AlphaFunction.Less;
case GfxAlphaFunction.LessOrEqual: return AlphaFunction.Lequal;
case GfxAlphaFunction.Never: return AlphaFunction.Never;
case GfxAlphaFunction.NotEqual: return AlphaFunction.Notequal;
default: return AlphaFunction.Always;
}
}
public 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;
}
}
enum TextureSwizzle
{
Zero = All.Zero,
One = All.One,
Red = All.Red,
Green = All.Green,
Blue = All.Blue,
Alpha = All.Alpha,
}
private static STColor8[] SetupVertexColors(BasePane pane,
STColor8 ColorBottomRight, STColor8 ColorBottomLeft,
STColor8 ColorTopLeft, STColor8 ColorTopRight)
{
STColor8[] outColors = new STColor8[4];
outColors[0] = ColorBottomLeft;
outColors[1] = ColorBottomRight;
outColors[2] = ColorTopRight;
outColors[3] = ColorTopLeft;
foreach (var animItem in pane.animController.PaneVertexColors)
{
switch (animItem.Key)
{
case LVCTarget.LeftBottomRed: outColors[0].R = (byte)animItem.Value; break;
case LVCTarget.LeftBottomGreen: outColors[0].G = (byte)animItem.Value; break;
case LVCTarget.LeftBottomBlue: outColors[0].B = (byte)animItem.Value; break;
case LVCTarget.LeftBottomAlpha: outColors[0].A = (byte)animItem.Value; break;
case LVCTarget.RightBottomRed: outColors[1].R = (byte)animItem.Value; break;
case LVCTarget.RightBottomGreen: outColors[1].G = (byte)animItem.Value; break;
case LVCTarget.RightBottomBlue: outColors[1].B = (byte)animItem.Value; break;
case LVCTarget.RightBottomAlpha: outColors[1].A = (byte)animItem.Value; break;
case LVCTarget.RightTopRed: outColors[2].R = (byte)animItem.Value; break;
case LVCTarget.RightTopGreen: outColors[2].G = (byte)animItem.Value; break;
case LVCTarget.RightTopBlue: outColors[2].B = (byte)animItem.Value; break;
case LVCTarget.RightTopAlpha: outColors[2].A = (byte)animItem.Value; break;
case LVCTarget.LeftTopRed: outColors[3].R = (byte)animItem.Value; break;
case LVCTarget.LeftTopGreen: outColors[3].G = (byte)animItem.Value; break;
case LVCTarget.LeftTopBlue: outColors[3].B = (byte)animItem.Value; break;
case LVCTarget.LeftTopAlpha: outColors[3].A = (byte)animItem.Value; break;
}
}
return outColors;
}
public static void DrawRectangle(BasePane pane, bool gameWindow, CustomRectangle rect, Vector2[] texCoords,
Color[] colors, bool useLines = true, byte alpha = 255)
{
for (int i = 0; i < colors.Length; i++)
{
float outAlpha = BasePane.MixColors(colors[i].A, alpha);
colors[i] = Color.FromArgb(Utils.FloatToIntClamp(outAlpha), colors[i]);
}
if (LayoutEditor.UseLegacyGL)
{
if (useLines)
{
GL.Begin(PrimitiveType.LineLoop);
GL.Color4(colors[0]);
GL.Vertex2(rect.LeftPoint, rect.BottomPoint);
GL.Vertex2(rect.RightPoint, rect.BottomPoint);
GL.Vertex2(rect.RightPoint, rect.TopPoint);
GL.Vertex2(rect.LeftPoint, rect.TopPoint);
GL.End();
}
else
{
if (!Runtime.LayoutEditor.IsGamePreview && !gameWindow)
{
GL.Disable(EnableCap.Blend);
GL.Disable(EnableCap.AlphaTest);
GL.PolygonMode(MaterialFace.Front, PolygonMode.Line);
GL.Enable(EnableCap.LineSmooth);
GL.LineWidth(1f);
GL.PolygonOffset(1f, 1f);
GL.Begin(PrimitiveType.Quads);
GL.Color4(Color.Green);
GL.Vertex2(rect.LeftPoint, rect.BottomPoint);
GL.Vertex2(rect.RightPoint, rect.BottomPoint);
GL.Vertex2(rect.RightPoint, rect.TopPoint);
GL.Vertex2(rect.LeftPoint, rect.TopPoint);
GL.End();
GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill);
GL.PolygonOffset(0f, 0f);
GL.Enable(EnableCap.Blend);
GL.Enable(EnableCap.AlphaTest);
}
GL.Begin(PrimitiveType.Quads);
GL.Color4(colors[0]);
GL.MultiTexCoord2(TextureUnit.Texture0, texCoords[0].X, texCoords[0].Y);
GL.Vertex2(rect.LeftPoint, rect.BottomPoint);
GL.Color4(colors[1]);
GL.MultiTexCoord2(TextureUnit.Texture0, texCoords[1].X, texCoords[1].Y);
GL.Vertex2(rect.RightPoint, rect.BottomPoint);
GL.Color4(colors[2]);
GL.MultiTexCoord2(TextureUnit.Texture0, texCoords[2].X, texCoords[2].Y);
GL.Vertex2(rect.RightPoint, rect.TopPoint);
GL.Color4(colors[3]);
GL.MultiTexCoord2(TextureUnit.Texture0, texCoords[3].X, texCoords[3].Y);
GL.Vertex2(rect.LeftPoint, rect.TopPoint);
GL.End();
}
}
else
{
if (pane.renderablePane == null)
pane.renderablePane = new RenderablePane();
Vector3[] vertices = new Vector3[4];
vertices[0] = new Vector3(rect.LeftPoint, rect.BottomPoint, 0);
vertices[1] = new Vector3(rect.RightPoint, rect.BottomPoint, 0);
vertices[2] = new Vector3(rect.RightPoint, rect.TopPoint, 0);
vertices[3] = new Vector3(rect.LeftPoint, rect.TopPoint, 0);
Vector4[] vertexColors = new Vector4[4];
// pane.renderablePane.Render(vertices, vertexColors, texCoords);
}
}
}
}