2019-08-27 22:38:06 +02:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.ComponentModel;
|
|
|
|
|
using System.Drawing;
|
|
|
|
|
using System.Data;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using System.Windows.Forms;
|
2019-08-28 01:03:01 +02:00
|
|
|
|
using OpenTK.Graphics.OpenGL;
|
2019-08-29 21:45:32 +02:00
|
|
|
|
using OpenTK;
|
2019-08-28 01:03:01 +02:00
|
|
|
|
using Toolbox.Library;
|
|
|
|
|
using Toolbox.Library.Rendering;
|
2019-08-29 21:45:32 +02:00
|
|
|
|
using Toolbox.Library.IO;
|
2019-09-01 19:02:48 +02:00
|
|
|
|
using LayoutBXLYT.Cafe;
|
2019-08-27 22:38:06 +02:00
|
|
|
|
|
2019-08-29 22:33:23 +02:00
|
|
|
|
namespace LayoutBXLYT
|
2019-08-27 22:38:06 +02:00
|
|
|
|
{
|
2019-09-28 23:27:48 +02:00
|
|
|
|
public partial class LayoutViewer : LayoutControlDocked
|
2019-08-27 22:38:06 +02:00
|
|
|
|
{
|
2019-08-29 22:33:23 +02:00
|
|
|
|
public List<BasePane> SelectedPanes = new List<BasePane>();
|
2019-08-29 21:45:32 +02:00
|
|
|
|
|
|
|
|
|
public Camera2D Camera = new Camera2D();
|
|
|
|
|
|
|
|
|
|
public class Camera2D
|
|
|
|
|
{
|
2019-09-28 23:27:48 +02:00
|
|
|
|
public Matrix4 ModelViewMatrix = Matrix4.Identity;
|
2019-08-29 21:45:32 +02:00
|
|
|
|
public float Zoom = 1;
|
|
|
|
|
public Vector2 Position;
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-28 23:27:48 +02:00
|
|
|
|
private LayoutEditor ParentEditor;
|
|
|
|
|
|
2019-08-28 01:03:01 +02:00
|
|
|
|
private RenderableTex backgroundTex;
|
2019-08-29 23:17:24 +02:00
|
|
|
|
public BxlytHeader LayoutFile;
|
2019-09-28 23:27:48 +02:00
|
|
|
|
public List<BxlytHeader> LayoutFiles = new List<BxlytHeader>();
|
2019-08-31 00:53:45 +02:00
|
|
|
|
private Dictionary<string, STGenericTexture> Textures;
|
2019-08-29 21:45:32 +02:00
|
|
|
|
|
2019-09-08 21:15:42 +02:00
|
|
|
|
private void glControl1_Load(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-07 01:12:39 +02:00
|
|
|
|
public void ResetCamera()
|
|
|
|
|
{
|
|
|
|
|
Camera = new Camera2D();
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-04 20:10:17 +02:00
|
|
|
|
public void ResetLayout(BxlytHeader bxlyt)
|
|
|
|
|
{
|
|
|
|
|
LayoutFile = bxlyt;
|
|
|
|
|
UpdateViewport();
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-28 23:27:48 +02:00
|
|
|
|
public GLControl GetGLControl() => glControl1;
|
|
|
|
|
|
|
|
|
|
public LayoutViewer(LayoutEditor editor, BxlytHeader bxlyt, Dictionary<string, STGenericTexture> textures)
|
2019-08-27 22:38:06 +02:00
|
|
|
|
{
|
|
|
|
|
InitializeComponent();
|
2019-09-28 23:27:48 +02:00
|
|
|
|
|
|
|
|
|
ParentEditor = editor;
|
|
|
|
|
|
2019-08-31 00:53:45 +02:00
|
|
|
|
Text = bxlyt.FileName;
|
2019-08-29 21:45:32 +02:00
|
|
|
|
|
2019-08-31 00:53:45 +02:00
|
|
|
|
Textures = textures;
|
2019-09-28 23:27:48 +02:00
|
|
|
|
LoadLayout(bxlyt);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void LoadLayout(BxlytHeader bxlyt)
|
|
|
|
|
{
|
|
|
|
|
LayoutFile = bxlyt;
|
|
|
|
|
LayoutFiles.Add(bxlyt);
|
|
|
|
|
|
2019-08-31 00:53:45 +02:00
|
|
|
|
if (bxlyt.Textures.Count > 0)
|
|
|
|
|
{
|
2019-09-28 23:27:48 +02:00
|
|
|
|
var textures = bxlyt.GetTextures;
|
|
|
|
|
foreach (var tex in textures)
|
|
|
|
|
if (!Textures.ContainsKey(tex.Key))
|
|
|
|
|
Textures.Add(tex.Key, tex.Value);
|
2019-08-31 00:53:45 +02:00
|
|
|
|
}
|
2019-08-30 01:01:47 +02:00
|
|
|
|
}
|
|
|
|
|
|
2019-09-28 23:27:48 +02:00
|
|
|
|
public override void OnControlClosing()
|
2019-08-30 01:01:47 +02:00
|
|
|
|
{
|
2019-09-28 23:27:48 +02:00
|
|
|
|
foreach (var tex in LayoutFile.Textures)
|
|
|
|
|
{
|
|
|
|
|
if (Textures.ContainsKey(tex))
|
|
|
|
|
{
|
|
|
|
|
Textures[tex].DisposeRenderable();
|
|
|
|
|
Textures.Remove(tex);
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-08-29 21:45:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void UpdateViewport()
|
|
|
|
|
{
|
|
|
|
|
glControl1.Invalidate();
|
2019-08-27 22:38:06 +02:00
|
|
|
|
}
|
2019-08-28 01:03:01 +02:00
|
|
|
|
|
|
|
|
|
private void glControl1_Paint(object sender, PaintEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (!Runtime.OpenTKInitialized)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
glControl1.Context.MakeCurrent(glControl1.WindowInfo);
|
|
|
|
|
OnRender();
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-28 23:27:48 +02:00
|
|
|
|
private BxlytShader GlobalShader;
|
|
|
|
|
public bool GameWindow = false;
|
|
|
|
|
public bool UseOrtho => Runtime.LayoutEditor.UseOrthographicView;
|
2019-08-30 02:51:41 +02:00
|
|
|
|
private Color BackgroundColor => Runtime.LayoutEditor.BackgroundColor;
|
2019-08-28 01:03:01 +02:00
|
|
|
|
private void OnRender()
|
|
|
|
|
{
|
2019-08-29 21:45:32 +02:00
|
|
|
|
if (LayoutFile == null) return;
|
|
|
|
|
|
2019-09-28 23:27:48 +02:00
|
|
|
|
if (!GameWindow)
|
|
|
|
|
{
|
|
|
|
|
if (ParentEditor != null)
|
|
|
|
|
ParentEditor.GamePreviewWindow?.UpdateViewport();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (GameWindow)
|
|
|
|
|
RenderGameWindow();
|
|
|
|
|
else
|
|
|
|
|
RenderEditor();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void RenderGameWindow()
|
|
|
|
|
{
|
|
|
|
|
int WindowWidth = (int)LayoutFile.RootPane.Width;
|
|
|
|
|
int WindowHeight = (int)LayoutFile.RootPane.Height;
|
|
|
|
|
|
|
|
|
|
GL.Viewport(0, 0, glControl1.Width, glControl1.Height);
|
|
|
|
|
GL.MatrixMode(MatrixMode.Projection);
|
|
|
|
|
GL.LoadIdentity();
|
|
|
|
|
if (UseOrtho)
|
|
|
|
|
{
|
|
|
|
|
float halfW = WindowWidth, halfH = WindowHeight;
|
|
|
|
|
var orthoMatrix = Matrix4.CreateOrthographic(halfW, halfH, -10000, 10000);
|
|
|
|
|
GL.LoadMatrix(ref orthoMatrix);
|
|
|
|
|
GL.MatrixMode(MatrixMode.Modelview);
|
|
|
|
|
Camera.ModelViewMatrix = orthoMatrix;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
var cameraPosition = new Vector3(0, 0, -600);
|
|
|
|
|
var perspectiveMatrix = Matrix4.CreateTranslation(cameraPosition) * Matrix4.CreatePerspectiveFieldOfView(1.3f, WindowWidth / WindowHeight, 0.01f, 100000);
|
|
|
|
|
GL.LoadMatrix(ref perspectiveMatrix);
|
|
|
|
|
GL.MatrixMode(MatrixMode.Modelview);
|
|
|
|
|
Camera.ModelViewMatrix = perspectiveMatrix;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RenderScene();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void RenderEditor()
|
|
|
|
|
{
|
2019-08-28 01:03:01 +02:00
|
|
|
|
GL.Viewport(0, 0, glControl1.Width, glControl1.Height);
|
|
|
|
|
GL.MatrixMode(MatrixMode.Projection);
|
|
|
|
|
GL.LoadIdentity();
|
2019-09-07 01:12:39 +02:00
|
|
|
|
if (UseOrtho)
|
|
|
|
|
{
|
2019-09-28 23:27:48 +02:00
|
|
|
|
float halfW = glControl1.Width / 2.0f, halfH = glControl1.Height / 2.0f;
|
|
|
|
|
var orthoMatrix = Matrix4.CreateOrthographic(halfW, halfH, -10000, 10000);
|
|
|
|
|
GL.LoadMatrix(ref orthoMatrix);
|
2019-09-07 01:12:39 +02:00
|
|
|
|
GL.MatrixMode(MatrixMode.Modelview);
|
2019-09-28 23:27:48 +02:00
|
|
|
|
Camera.ModelViewMatrix = orthoMatrix;
|
2019-09-07 01:12:39 +02:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
var cameraPosition = new Vector3(Camera.Position.X, Camera.Position.Y, -(Camera.Zoom * 500));
|
2019-09-28 23:27:48 +02:00
|
|
|
|
var perspectiveMatrix = Matrix4.CreateTranslation(cameraPosition) * Matrix4.CreatePerspectiveFieldOfView(1.3f, glControl1.Width / glControl1.Height, 0.01f, 100000);
|
2019-09-07 01:12:39 +02:00
|
|
|
|
GL.LoadMatrix(ref perspectiveMatrix);
|
|
|
|
|
GL.MatrixMode(MatrixMode.Modelview);
|
2019-09-28 23:27:48 +02:00
|
|
|
|
Camera.ModelViewMatrix = perspectiveMatrix;
|
2019-09-07 01:12:39 +02:00
|
|
|
|
}
|
2019-08-28 01:03:01 +02:00
|
|
|
|
|
2019-09-28 23:27:48 +02:00
|
|
|
|
RenderScene();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void RenderScene()
|
|
|
|
|
{
|
2019-08-29 21:45:32 +02:00
|
|
|
|
GL.ClearColor(BackgroundColor);
|
2019-08-28 01:03:01 +02:00
|
|
|
|
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
|
|
|
|
|
|
2019-09-17 01:56:41 +02:00
|
|
|
|
// GL.Disable(EnableCap.CullFace);
|
2019-08-29 21:45:32 +02:00
|
|
|
|
GL.Enable(EnableCap.Blend);
|
2019-09-08 21:15:42 +02:00
|
|
|
|
GL.Enable(EnableCap.AlphaTest);
|
|
|
|
|
GL.AlphaFunc(AlphaFunction.Always, 0f);
|
2019-08-29 21:45:32 +02:00
|
|
|
|
GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
|
2019-09-03 01:48:47 +02:00
|
|
|
|
GL.Enable(EnableCap.ColorMaterial);
|
2019-08-31 03:53:00 +02:00
|
|
|
|
GL.Enable(EnableCap.Texture2D);
|
|
|
|
|
GL.BindTexture(TextureTarget.Texture2D, 0);
|
2019-09-28 23:27:48 +02:00
|
|
|
|
GL.BlendEquation(BlendEquationMode.FuncAdd);
|
2019-08-31 03:53:00 +02:00
|
|
|
|
|
2019-09-28 23:27:48 +02:00
|
|
|
|
if (UseOrtho && !GameWindow)
|
2019-09-07 01:12:39 +02:00
|
|
|
|
{
|
|
|
|
|
GL.PushMatrix();
|
2019-09-28 23:27:48 +02:00
|
|
|
|
GL.Scale(Camera.Zoom, Camera.Zoom, 1);
|
2019-09-07 01:12:39 +02:00
|
|
|
|
GL.Translate(Camera.Position.X, Camera.Position.Y, 0);
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-28 23:27:48 +02:00
|
|
|
|
if (!GameWindow)
|
|
|
|
|
{
|
|
|
|
|
DrawRootPane(LayoutFile.RootPane);
|
|
|
|
|
DrawGrid();
|
|
|
|
|
DrawXyLines();
|
|
|
|
|
}
|
2019-09-08 21:15:42 +02:00
|
|
|
|
|
|
|
|
|
GL.BindTexture(TextureTarget.Texture2D, 0);
|
|
|
|
|
|
2019-09-28 23:27:48 +02:00
|
|
|
|
if (GlobalShader == null)
|
|
|
|
|
{
|
|
|
|
|
GlobalShader = new BxlytShader();
|
|
|
|
|
GlobalShader.Compile();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach (var layout in LayoutFiles)
|
|
|
|
|
RenderPanes(GlobalShader, layout.RootPane, true, 255, false, null, 0);
|
2019-08-29 21:45:32 +02:00
|
|
|
|
|
2019-09-07 01:12:39 +02:00
|
|
|
|
if (UseOrtho)
|
|
|
|
|
GL.PopMatrix();
|
2019-08-28 01:03:01 +02:00
|
|
|
|
|
2019-09-08 21:15:42 +02:00
|
|
|
|
GL.UseProgram(0);
|
|
|
|
|
|
2019-08-28 01:03:01 +02:00
|
|
|
|
glControl1.SwapBuffers();
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-28 23:27:48 +02:00
|
|
|
|
private bool test = true;
|
|
|
|
|
private void RenderPanes(BxlytShader shader, BasePane pane, bool isRoot, byte parentAlpha, bool parentAlphaInfluence, BasePane partPane = null, int stage = 0)
|
2019-08-28 01:03:01 +02:00
|
|
|
|
{
|
2019-09-28 23:27:48 +02:00
|
|
|
|
if (!pane.DisplayInEditor || !pane.animController.Visibile)
|
2019-08-29 21:45:32 +02:00
|
|
|
|
return;
|
2019-08-28 01:03:01 +02:00
|
|
|
|
|
2019-08-29 21:45:32 +02:00
|
|
|
|
GL.PushMatrix();
|
2019-08-28 01:03:01 +02:00
|
|
|
|
|
2019-09-07 01:12:39 +02:00
|
|
|
|
//Check XY rotation and draw the pane before it was rotated
|
|
|
|
|
bool isRotatedXY = pane.Rotate.X != 0 || pane.Rotate.Y != 0;
|
|
|
|
|
if (isRotatedXY && SelectedPanes.Contains(pane))
|
|
|
|
|
{
|
|
|
|
|
GL.PushMatrix();
|
|
|
|
|
GL.Translate(pane.Translate.X, pane.Translate.Y, 0);
|
|
|
|
|
GL.Rotate(pane.Rotate.Z, 0, 0, 1);
|
|
|
|
|
GL.Scale(pane.Scale.X, pane.Scale.Y, 1);
|
|
|
|
|
|
2019-09-28 23:27:48 +02:00
|
|
|
|
DrawDefaultPane(shader, pane, true);
|
2019-09-07 01:12:39 +02:00
|
|
|
|
|
|
|
|
|
GL.PopMatrix();
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-28 23:27:48 +02:00
|
|
|
|
|
|
|
|
|
var translate = pane.Translate;
|
|
|
|
|
var rotate = pane.Rotate;
|
|
|
|
|
var scale = pane.Scale;
|
|
|
|
|
|
|
|
|
|
foreach (var animItem in pane.animController.PaneSRT)
|
|
|
|
|
{
|
|
|
|
|
switch (animItem.Key)
|
|
|
|
|
{
|
|
|
|
|
case LPATarget.RotateX: rotate.X = animItem.Value; break;
|
|
|
|
|
case LPATarget.RotateY: rotate.Y = animItem.Value; break;
|
|
|
|
|
case LPATarget.RotateZ: rotate.Z = animItem.Value; break;
|
|
|
|
|
case LPATarget.ScaleX: scale.X = animItem.Value; break;
|
|
|
|
|
case LPATarget.ScaleY: scale.Y = animItem.Value; break;
|
|
|
|
|
case LPATarget.TranslateX: translate.X = animItem.Value; break;
|
|
|
|
|
case LPATarget.TranslateY: translate.Y = animItem.Value; break;
|
|
|
|
|
case LPATarget.TranslateZ: translate.Z = animItem.Value; break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-05 22:24:03 +02:00
|
|
|
|
if (partPane != null)
|
|
|
|
|
{
|
2019-09-28 23:27:48 +02:00
|
|
|
|
translate = translate + pane.Translate;
|
|
|
|
|
scale = scale * pane.Scale;
|
|
|
|
|
rotate = rotate + pane.Rotate;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GL.Translate(translate.X, translate.Y, 0);
|
2019-09-05 22:24:03 +02:00
|
|
|
|
|
2019-09-28 23:27:48 +02:00
|
|
|
|
//Rotate normally unless the object uses shaders/materials
|
|
|
|
|
//Rotation matrix + shaders works accurately with X/Y rotation axis
|
|
|
|
|
//Todo, do everything by shaders
|
|
|
|
|
bool HasMaterials = pane is IWindowPane || pane is IPicturePane || pane is BFLYT.PRT1;
|
|
|
|
|
if (!HasMaterials)
|
|
|
|
|
{
|
2019-09-09 02:47:19 +02:00
|
|
|
|
GL.Rotate(rotate.X, 1, 0, 0);
|
2019-09-07 01:12:39 +02:00
|
|
|
|
GL.Rotate(rotate.Y, 0, 1, 0);
|
|
|
|
|
GL.Rotate(rotate.Z, 0, 0, 1);
|
2019-09-05 22:24:03 +02:00
|
|
|
|
}
|
2019-09-17 01:56:41 +02:00
|
|
|
|
|
2019-09-28 23:27:48 +02:00
|
|
|
|
GL.Scale(scale.X, scale.Y, 1);
|
|
|
|
|
|
|
|
|
|
byte alpha = pane.Alpha;
|
|
|
|
|
if (pane.animController.PaneVertexColors.ContainsKey(LVCTarget.PaneAlpha))
|
|
|
|
|
alpha = (byte)pane.animController.PaneVertexColors[LVCTarget.PaneAlpha];
|
2019-09-05 22:24:03 +02:00
|
|
|
|
|
2019-09-28 23:27:48 +02:00
|
|
|
|
byte effectiveAlpha = (byte)(parentAlpha == 255 ? alpha : (alpha * parentAlpha) / 255);
|
2019-09-08 21:15:42 +02:00
|
|
|
|
if (!parentAlphaInfluence)
|
2019-09-28 23:27:48 +02:00
|
|
|
|
effectiveAlpha = alpha;
|
2019-09-08 21:15:42 +02:00
|
|
|
|
|
2019-09-07 01:12:39 +02:00
|
|
|
|
parentAlphaInfluence = parentAlphaInfluence || pane.InfluenceAlpha;
|
2019-09-02 23:10:24 +02:00
|
|
|
|
|
2019-08-29 21:45:32 +02:00
|
|
|
|
if (!isRoot)
|
|
|
|
|
{
|
2019-09-28 23:27:48 +02:00
|
|
|
|
if (pane is IPicturePane)
|
|
|
|
|
BxlytToGL.DrawPictureBox(pane, GameWindow, effectiveAlpha, Textures);
|
2019-09-11 00:42:48 +02:00
|
|
|
|
else if (pane is IWindowPane)
|
2019-09-28 23:27:48 +02:00
|
|
|
|
BxlytToGL.DrawWindowPane(pane, GameWindow, effectiveAlpha, Textures);
|
|
|
|
|
else if (pane is IBoundryPane)
|
|
|
|
|
BxlytToGL.DrawBoundryPane(pane, GameWindow, effectiveAlpha, SelectedPanes);
|
|
|
|
|
else if (pane is ITextPane && Runtime.LayoutEditor.DisplayTextPane)
|
|
|
|
|
{
|
|
|
|
|
var textPane = (ITextPane)pane;
|
2019-09-29 02:24:20 +02:00
|
|
|
|
Bitmap bitmap = null;
|
2019-09-28 23:27:48 +02:00
|
|
|
|
if (textPane.RenderableFont == null)
|
|
|
|
|
{
|
|
|
|
|
if (pane is BFLYT.TXT1)
|
|
|
|
|
{
|
|
|
|
|
foreach (var fontFile in FirstPlugin.PluginRuntime.BxfntFiles)
|
|
|
|
|
{
|
|
|
|
|
if (Utils.CompareNoExtension(fontFile.Name, textPane.FontName))
|
|
|
|
|
{
|
|
|
|
|
bitmap = fontFile.GetBitmap(textPane.Text, false, pane);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (bitmap != null)
|
|
|
|
|
BxlytToGL.DrawTextbox(pane, GameWindow, bitmap, effectiveAlpha, Textures, SelectedPanes, textPane.RenderableFont == null);
|
2019-09-29 02:24:20 +02:00
|
|
|
|
else
|
|
|
|
|
DrawDefaultPane(shader, pane);
|
2019-09-28 23:27:48 +02:00
|
|
|
|
}
|
2019-09-13 00:52:47 +02:00
|
|
|
|
else if (pane is BFLYT.SCR1)
|
2019-09-28 23:27:48 +02:00
|
|
|
|
BxlytToGL.DrawScissorPane(pane, GameWindow, effectiveAlpha, SelectedPanes);
|
2019-09-13 00:52:47 +02:00
|
|
|
|
else if (pane is BFLYT.ALI1)
|
2019-09-28 23:27:48 +02:00
|
|
|
|
BxlytToGL.DrawAlignmentPane(pane, GameWindow, effectiveAlpha, SelectedPanes);
|
2019-09-05 22:24:03 +02:00
|
|
|
|
else if (pane is BFLYT.PRT1)
|
2019-09-28 23:27:48 +02:00
|
|
|
|
DrawPartsPane(shader, (BFLYT.PRT1)pane, effectiveAlpha, parentAlphaInfluence);
|
2019-09-09 02:47:19 +02:00
|
|
|
|
else
|
2019-09-28 23:27:48 +02:00
|
|
|
|
DrawDefaultPane(shader, pane);
|
2019-08-29 21:45:32 +02:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
isRoot = false;
|
2019-08-28 01:03:01 +02:00
|
|
|
|
|
2019-09-07 01:12:39 +02:00
|
|
|
|
byte childAlpha = pane.InfluenceAlpha || parentAlphaInfluence ? effectiveAlpha : byte.MaxValue;
|
2019-08-29 21:45:32 +02:00
|
|
|
|
foreach (var childPane in pane.Childern)
|
2019-09-28 23:27:48 +02:00
|
|
|
|
RenderPanes(shader, childPane, isRoot, childAlpha, parentAlphaInfluence, partPane);
|
2019-08-29 21:45:32 +02:00
|
|
|
|
|
|
|
|
|
GL.PopMatrix();
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-29 22:33:23 +02:00
|
|
|
|
private void DrawRootPane(BasePane pane)
|
2019-08-29 21:45:32 +02:00
|
|
|
|
{
|
|
|
|
|
Color color = Color.Black;
|
|
|
|
|
if (SelectedPanes.Contains(pane))
|
|
|
|
|
color = Color.Red;
|
2019-08-28 01:03:01 +02:00
|
|
|
|
|
2019-08-29 22:33:23 +02:00
|
|
|
|
CustomRectangle rect = pane.CreateRectangle();
|
2019-08-29 21:45:32 +02:00
|
|
|
|
|
|
|
|
|
//Draw a quad which is the backcolor but lighter
|
2019-08-28 01:03:01 +02:00
|
|
|
|
GL.Begin(PrimitiveType.Quads);
|
2019-08-29 21:45:32 +02:00
|
|
|
|
GL.Color3(BackgroundColor.Lighten(10));
|
|
|
|
|
GL.Vertex2(rect.LeftPoint, rect.TopPoint);
|
|
|
|
|
GL.Vertex2(rect.RightPoint, rect.TopPoint);
|
|
|
|
|
GL.Vertex2(rect.RightPoint, rect.BottomPoint);
|
|
|
|
|
GL.Vertex2(rect.LeftPoint, rect.BottomPoint);
|
|
|
|
|
GL.End();
|
|
|
|
|
|
|
|
|
|
//Draw outline of root pane
|
|
|
|
|
GL.Begin(PrimitiveType.LineLoop);
|
|
|
|
|
GL.PolygonOffset(0.5f, 2);
|
|
|
|
|
GL.LineWidth(33);
|
|
|
|
|
GL.Color3(color);
|
|
|
|
|
GL.Vertex2(rect.LeftPoint, rect.TopPoint);
|
|
|
|
|
GL.Vertex2(rect.RightPoint, rect.TopPoint);
|
|
|
|
|
GL.Vertex2(rect.RightPoint, rect.BottomPoint);
|
|
|
|
|
GL.Vertex2(rect.LeftPoint, rect.BottomPoint);
|
2019-08-28 01:03:01 +02:00
|
|
|
|
GL.End();
|
2019-08-29 21:45:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
2019-09-28 23:27:48 +02:00
|
|
|
|
private void DrawDefaultPane(BxlytShader shader, BasePane pane, bool isSelectionBox = false)
|
2019-08-29 21:45:32 +02:00
|
|
|
|
{
|
2019-09-28 23:27:48 +02:00
|
|
|
|
if (!Runtime.LayoutEditor.DisplayNullPane && !isSelectionBox || GameWindow || Runtime.LayoutEditor.IsGamePreview)
|
2019-09-13 00:52:47 +02:00
|
|
|
|
return;
|
|
|
|
|
|
2019-08-29 21:45:32 +02:00
|
|
|
|
Vector2[] TexCoords = new Vector2[] {
|
|
|
|
|
new Vector2(1,1),
|
|
|
|
|
new Vector2(0,1),
|
|
|
|
|
new Vector2(0,0),
|
|
|
|
|
new Vector2(1,0)
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Color color = Color.White;
|
|
|
|
|
if (SelectedPanes.Contains(pane))
|
|
|
|
|
color = Color.Red;
|
|
|
|
|
|
|
|
|
|
Color[] Colors = new Color[] {
|
|
|
|
|
color,
|
|
|
|
|
color,
|
|
|
|
|
color,
|
|
|
|
|
color,
|
|
|
|
|
};
|
|
|
|
|
|
2019-09-28 23:27:48 +02:00
|
|
|
|
BxlytToGL.DrawRectangle(pane, GameWindow, pane.Rectangle, TexCoords, Colors);
|
2019-08-29 21:45:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
2019-09-28 23:27:48 +02:00
|
|
|
|
private void DrawPartsPane(BxlytShader shader, BFLYT.PRT1 pane, byte effectiveAlpha, bool parentInfluenceAlpha)
|
2019-09-05 22:24:03 +02:00
|
|
|
|
{
|
|
|
|
|
pane.UpdateTextureData(this.Textures);
|
|
|
|
|
var partPane = pane.GetExternalPane();
|
|
|
|
|
if (partPane != null)
|
2019-09-28 23:27:48 +02:00
|
|
|
|
RenderPanes(shader,partPane, true, effectiveAlpha, parentInfluenceAlpha);
|
2019-09-05 22:24:03 +02:00
|
|
|
|
else
|
2019-09-28 23:27:48 +02:00
|
|
|
|
DrawDefaultPane(shader, pane);
|
2019-09-05 22:24:03 +02:00
|
|
|
|
|
|
|
|
|
if (pane.Properties != null)
|
|
|
|
|
{
|
|
|
|
|
foreach (var prop in pane.Properties)
|
|
|
|
|
{
|
|
|
|
|
if (prop.Property != null)
|
2019-09-08 21:15:42 +02:00
|
|
|
|
{
|
2019-09-28 23:27:48 +02:00
|
|
|
|
RenderPanes(shader,prop.Property, false, effectiveAlpha, parentInfluenceAlpha || pane.InfluenceAlpha);
|
2019-09-08 21:15:42 +02:00
|
|
|
|
}
|
2019-09-05 22:24:03 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-07 01:12:39 +02:00
|
|
|
|
|
2019-08-29 21:45:32 +02:00
|
|
|
|
private void DrawBackground()
|
|
|
|
|
{
|
|
|
|
|
if (backgroundTex == null)
|
|
|
|
|
{
|
2019-09-17 01:56:41 +02:00
|
|
|
|
/* backgroundTex = RenderableTex.FromBitmap(Properties.Resources.GridBackground);
|
|
|
|
|
backgroundTex.TextureWrapR = TextureWrapMode.Repeat;
|
|
|
|
|
backgroundTex.TextureWrapT = TextureWrapMode.Repeat;
|
2019-08-29 21:45:32 +02:00
|
|
|
|
|
|
|
|
|
|
2019-09-17 01:56:41 +02:00
|
|
|
|
GL.Enable(EnableCap.Texture2D);
|
|
|
|
|
GL.BindTexture(TextureTarget.Texture2D, backgroundTex.TexID);
|
|
|
|
|
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (float)backgroundTex.TextureWrapR);
|
|
|
|
|
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (float)backgroundTex.TextureWrapT);
|
|
|
|
|
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (float)backgroundTex.TextureMagFilter);
|
|
|
|
|
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (float)backgroundTex.TextureMinFilter);
|
2019-08-29 21:45:32 +02:00
|
|
|
|
|
2019-09-17 01:56:41 +02:00
|
|
|
|
float UVscale = 15;
|
2019-08-29 21:45:32 +02:00
|
|
|
|
|
2019-09-17 01:56:41 +02:00
|
|
|
|
int PanelWidth = 9000;
|
|
|
|
|
int PanelWHeight = 9000;
|
2019-08-29 21:45:32 +02:00
|
|
|
|
|
2019-09-17 01:56:41 +02:00
|
|
|
|
Vector2 scaleCenter = new Vector2(0.5f, 0.5f);
|
2019-08-29 21:45:32 +02:00
|
|
|
|
|
2019-09-17 01:56:41 +02:00
|
|
|
|
Vector2[] TexCoords = new Vector2[] {
|
|
|
|
|
new Vector2(1,1),
|
|
|
|
|
new Vector2(0,1),
|
|
|
|
|
new Vector2(0,0),
|
|
|
|
|
new Vector2(1,0),
|
|
|
|
|
};
|
2019-08-29 21:45:32 +02:00
|
|
|
|
|
2019-09-17 01:56:41 +02:00
|
|
|
|
for (int i = 0; i < TexCoords.Length; i++)
|
|
|
|
|
TexCoords[i] = (TexCoords[i] - scaleCenter) * 20 + scaleCenter;
|
|
|
|
|
|
|
|
|
|
GL.MatrixMode(MatrixMode.Modelview);
|
|
|
|
|
GL.LoadIdentity();
|
|
|
|
|
GL.PushMatrix();
|
|
|
|
|
GL.Scale(1, 1, 1);
|
|
|
|
|
GL.Translate(0, 0, 0);
|
|
|
|
|
|
|
|
|
|
GL.Color4(Color.White);
|
|
|
|
|
|
|
|
|
|
GL.Begin(PrimitiveType.Quads);
|
|
|
|
|
GL.TexCoord2(TexCoords[0]);
|
|
|
|
|
GL.Vertex3(PanelWidth, PanelWHeight, 0);
|
|
|
|
|
GL.TexCoord2(TexCoords[1]);
|
|
|
|
|
GL.Vertex3(-PanelWidth, PanelWHeight, 0);
|
|
|
|
|
GL.TexCoord2(TexCoords[2]);
|
|
|
|
|
GL.Vertex3(-PanelWidth, -PanelWHeight, 0);
|
|
|
|
|
GL.TexCoord2(TexCoords[3]);
|
|
|
|
|
GL.Vertex3(PanelWidth, -PanelWHeight, 0);
|
|
|
|
|
GL.End();
|
|
|
|
|
|
|
|
|
|
GL.BindTexture(TextureTarget.Texture2D, 0);
|
|
|
|
|
GL.PopMatrix();*/
|
2019-08-29 21:45:32 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void UpdateBackgroundColor(Color color)
|
|
|
|
|
{
|
2019-08-30 02:51:41 +02:00
|
|
|
|
Runtime.LayoutEditor.BackgroundColor = color;
|
2019-08-29 21:45:32 +02:00
|
|
|
|
glControl1.Invalidate();
|
2019-08-30 02:51:41 +02:00
|
|
|
|
Config.Save();
|
2019-08-29 21:45:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void DrawXyLines()
|
|
|
|
|
{
|
2019-09-28 23:27:48 +02:00
|
|
|
|
if (GameWindow || Runtime.LayoutEditor.IsGamePreview)
|
2019-09-17 03:02:00 +02:00
|
|
|
|
return;
|
|
|
|
|
|
2019-08-29 21:45:32 +02:00
|
|
|
|
int lineLength = 20;
|
|
|
|
|
|
|
|
|
|
GL.Color3(Color.Green);
|
|
|
|
|
GL.Begin(PrimitiveType.Lines);
|
|
|
|
|
GL.Vertex2(0, 0);
|
|
|
|
|
GL.Vertex2(0, lineLength);
|
|
|
|
|
GL.End();
|
|
|
|
|
|
|
|
|
|
GL.Color3(Color.Red);
|
|
|
|
|
GL.Begin(PrimitiveType.Lines);
|
|
|
|
|
GL.Vertex2(0, 0);
|
|
|
|
|
GL.Vertex2(lineLength, 0);
|
|
|
|
|
GL.End();
|
2019-08-28 01:03:01 +02:00
|
|
|
|
}
|
|
|
|
|
|
2019-08-29 21:45:32 +02:00
|
|
|
|
private void DrawGrid()
|
2019-08-28 01:03:01 +02:00
|
|
|
|
{
|
2019-09-17 03:02:00 +02:00
|
|
|
|
if (!Runtime.LayoutEditor.DisplayGrid)
|
|
|
|
|
return;
|
|
|
|
|
|
2019-08-29 21:45:32 +02:00
|
|
|
|
var size = 40;
|
|
|
|
|
var amount = 300;
|
|
|
|
|
|
|
|
|
|
GL.LineWidth(0.001f);
|
|
|
|
|
GL.Color3(BackgroundColor.Darken(20));
|
|
|
|
|
GL.Begin(PrimitiveType.Lines);
|
|
|
|
|
|
|
|
|
|
int squareGridCounter = 0;
|
|
|
|
|
for (var i = -amount; i <= amount; i++)
|
|
|
|
|
{
|
|
|
|
|
if (squareGridCounter > 5)
|
|
|
|
|
{
|
|
|
|
|
squareGridCounter = 0;
|
|
|
|
|
GL.LineWidth(33f);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
GL.LineWidth(0.001f);
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-07 01:12:39 +02:00
|
|
|
|
GL.Vertex2(new Vector2(-amount * size, i * size));
|
|
|
|
|
GL.Vertex2(new Vector2(amount * size, i * size));
|
|
|
|
|
GL.Vertex2(new Vector2(i * size, -amount * size));
|
|
|
|
|
GL.Vertex2(new Vector2(i * size, amount * size));
|
2019-08-28 01:03:01 +02:00
|
|
|
|
|
2019-08-29 21:45:32 +02:00
|
|
|
|
squareGridCounter++;
|
|
|
|
|
}
|
|
|
|
|
GL.End();
|
|
|
|
|
GL.Color3(Color.Transparent);
|
|
|
|
|
GL.PopAttrib();
|
2019-08-28 01:03:01 +02:00
|
|
|
|
}
|
|
|
|
|
|
2019-08-29 21:45:32 +02:00
|
|
|
|
private bool mouseHeldDown = false;
|
2019-09-03 01:48:47 +02:00
|
|
|
|
private bool isPicked = false;
|
2019-08-29 21:45:32 +02:00
|
|
|
|
private Point originMouse;
|
|
|
|
|
private void glControl1_MouseDown(object sender, MouseEventArgs e)
|
2019-08-28 01:03:01 +02:00
|
|
|
|
{
|
2019-09-04 00:58:58 +02:00
|
|
|
|
SelectedPanes.Clear();
|
|
|
|
|
|
2019-09-03 01:48:47 +02:00
|
|
|
|
//Pick an object for moving
|
|
|
|
|
if (Control.ModifierKeys == Keys.Alt && e.Button == MouseButtons.Left)
|
|
|
|
|
{
|
2019-09-04 00:58:58 +02:00
|
|
|
|
BasePane hitPane = null;
|
|
|
|
|
SearchHit(LayoutFile.RootPane, e.X, e.Y, ref hitPane);
|
2019-09-03 01:48:47 +02:00
|
|
|
|
if (hitPane != null)
|
|
|
|
|
{
|
|
|
|
|
SelectedPanes.Add(hitPane);
|
|
|
|
|
UpdateViewport();
|
|
|
|
|
|
|
|
|
|
isPicked = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (e.Button == MouseButtons.Left)
|
2019-08-29 21:45:32 +02:00
|
|
|
|
{
|
|
|
|
|
mouseHeldDown = true;
|
|
|
|
|
originMouse = e.Location;
|
2019-09-03 01:48:47 +02:00
|
|
|
|
|
2019-09-04 00:58:58 +02:00
|
|
|
|
BasePane hitPane = null;
|
|
|
|
|
foreach (var child in LayoutFile.RootPane.Childern)
|
|
|
|
|
SearchHit(child, e.X, e.Y, ref hitPane);
|
2019-09-03 01:48:47 +02:00
|
|
|
|
Console.WriteLine($"Has Hit " + hitPane != null);
|
|
|
|
|
if (hitPane != null)
|
|
|
|
|
{
|
|
|
|
|
SelectedPanes.Add(hitPane);
|
|
|
|
|
UpdateViewport();
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-29 21:45:32 +02:00
|
|
|
|
glControl1.Invalidate();
|
|
|
|
|
}
|
2019-09-04 00:58:58 +02:00
|
|
|
|
|
|
|
|
|
Console.WriteLine("SelectedPanes " + SelectedPanes.Count);
|
2019-08-29 21:45:32 +02:00
|
|
|
|
}
|
2019-08-28 01:03:01 +02:00
|
|
|
|
|
2019-09-04 00:58:58 +02:00
|
|
|
|
private void SearchHit(BasePane pane, int X, int Y, ref BasePane SelectedPane)
|
2019-09-03 01:48:47 +02:00
|
|
|
|
{
|
2019-09-17 01:56:41 +02:00
|
|
|
|
if (pane.IsHit(X, Y))
|
|
|
|
|
{
|
2019-09-04 00:58:58 +02:00
|
|
|
|
SelectedPane = pane;
|
|
|
|
|
return;
|
|
|
|
|
}
|
2019-09-03 01:48:47 +02:00
|
|
|
|
|
|
|
|
|
foreach (var childPane in pane.Childern)
|
2019-09-17 01:56:41 +02:00
|
|
|
|
SearchHit(childPane, X, Y, ref SelectedPane);
|
2019-09-03 01:48:47 +02:00
|
|
|
|
}
|
|
|
|
|
|
2019-08-29 21:45:32 +02:00
|
|
|
|
private void glControl1_MouseUp(object sender, MouseEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (e.Button == MouseButtons.Left)
|
|
|
|
|
{
|
|
|
|
|
mouseHeldDown = false;
|
2019-09-03 01:48:47 +02:00
|
|
|
|
isPicked = false;
|
2019-08-29 21:45:32 +02:00
|
|
|
|
glControl1.Invalidate();
|
|
|
|
|
}
|
2019-08-28 01:03:01 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void glControl1_MouseMove(object sender, MouseEventArgs e)
|
|
|
|
|
{
|
2019-08-29 21:45:32 +02:00
|
|
|
|
if (mouseHeldDown)
|
|
|
|
|
{
|
|
|
|
|
var pos = new Vector2(e.Location.X - originMouse.X, e.Location.Y - originMouse.Y);
|
|
|
|
|
Camera.Position.X += pos.X;
|
|
|
|
|
Camera.Position.Y -= pos.Y;
|
|
|
|
|
|
|
|
|
|
originMouse = e.Location;
|
|
|
|
|
|
|
|
|
|
glControl1.Invalidate();
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-08-28 01:03:01 +02:00
|
|
|
|
|
2019-08-29 21:45:32 +02:00
|
|
|
|
protected override void OnMouseWheel(MouseEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
base.OnMouseWheel(e);
|
2019-09-07 01:12:39 +02:00
|
|
|
|
if (UseOrtho)
|
|
|
|
|
{
|
|
|
|
|
if (e.Delta > 0 && Camera.Zoom > 0)
|
|
|
|
|
Camera.Zoom += 0.1f;
|
|
|
|
|
if (e.Delta < 0 && Camera.Zoom < 100 && Camera.Zoom > 0.1)
|
|
|
|
|
Camera.Zoom -= 0.1f;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (e.Delta > 0 && Camera.Zoom > 0.1)
|
|
|
|
|
Camera.Zoom -= 0.1f;
|
|
|
|
|
if (e.Delta < 0 && Camera.Zoom < 100 && Camera.Zoom > 0)
|
|
|
|
|
Camera.Zoom += 0.1f;
|
|
|
|
|
}
|
2019-08-29 21:45:32 +02:00
|
|
|
|
|
|
|
|
|
glControl1.Invalidate();
|
2019-08-28 01:03:01 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void glControl1_Resize(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
glControl1.Invalidate();
|
|
|
|
|
}
|
2019-08-27 22:38:06 +02:00
|
|
|
|
}
|
|
|
|
|
}
|