Updated vertex positioning

This commit is contained in:
miku-666
2023-11-01 10:17:50 +01:00
parent 884eeaef54
commit a9eec9a3ee
10 changed files with 359 additions and 406 deletions

View File

@@ -1,9 +1,9 @@
using System;
using System.Linq;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using PckStudio.Internal;
using PckStudio.Rendering;
namespace PckStudio.Forms
{

View File

@@ -42,8 +42,6 @@
this.changeColorToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.buttonDone = new System.Windows.Forms.Button();
this.labelView = new System.Windows.Forms.Label();
this.rotateRightBtn = new System.Windows.Forms.Button();
this.rotateLeftBtn = new System.Windows.Forms.Button();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.tabBody = new System.Windows.Forms.TabControl();
this.tabArmor = new System.Windows.Forms.TabPage();
@@ -85,7 +83,7 @@
this.U = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.V = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.listViewBoxes = new System.Windows.Forms.ListView();
this.renderer3D1 = new PckStudio.Rendering.Renderer3D();
this.renderer3D1 = new PckStudio.Rendering.SkinRenderer();
this.uvPictureBox = new PckStudio.ToolboxItems.InterpolationPictureBox();
label6 = new System.Windows.Forms.Label();
label5 = new System.Windows.Forms.Label();
@@ -188,22 +186,6 @@
this.labelView.ForeColor = System.Drawing.Color.White;
this.labelView.Name = "labelView";
//
// rotateRightBtn
//
resources.ApplyResources(this.rotateRightBtn, "rotateRightBtn");
this.rotateRightBtn.ForeColor = System.Drawing.Color.White;
this.rotateRightBtn.Name = "rotateRightBtn";
this.rotateRightBtn.UseVisualStyleBackColor = true;
this.rotateRightBtn.Click += new System.EventHandler(this.rotateRightBtn_Click);
//
// rotateLeftBtn
//
resources.ApplyResources(this.rotateLeftBtn, "rotateLeftBtn");
this.rotateLeftBtn.ForeColor = System.Drawing.Color.White;
this.rotateLeftBtn.Name = "rotateLeftBtn";
this.rotateLeftBtn.UseVisualStyleBackColor = true;
this.rotateLeftBtn.Click += new System.EventHandler(this.rotateLeftBtn_Click);
//
// groupBox1
//
this.groupBox1.Controls.Add(this.tabBody);
@@ -582,8 +564,6 @@
this.Controls.Add(this.buttonIMPORT);
this.Controls.Add(this.groupBox1);
this.Controls.Add(label7);
this.Controls.Add(this.rotateLeftBtn);
this.Controls.Add(this.rotateRightBtn);
this.Controls.Add(this.labelView);
this.Controls.Add(this.buttonDone);
this.Controls.Add(label3);
@@ -642,8 +622,6 @@
private System.Windows.Forms.TextBox offsetHead;
private System.Windows.Forms.Label label12;
private System.Windows.Forms.TabPage tabArmor;
private System.Windows.Forms.Button rotateLeftBtn;
private System.Windows.Forms.Button rotateRightBtn;
private System.Windows.Forms.Label labelView;
private MetroFramework.Controls.MetroButton buttonTemplate;
private MetroFramework.Controls.MetroCheckBox generateTextureCheckBox;
@@ -667,6 +645,6 @@
private System.Windows.Forms.ColumnHeader U;
private System.Windows.Forms.ColumnHeader V;
private System.Windows.Forms.ListView listViewBoxes;
private Rendering.Renderer3D renderer3D1;
private Rendering.SkinRenderer renderer3D1;
}
}

View File

@@ -20,27 +20,13 @@ using System.Text;
namespace PckStudio.Forms
{
[Obsolete]
//[Obsolete]
public partial class generateModel : MetroForm
{
[Obsolete("We don't need a full control to get an image")]
private PictureBox skinPreview = new PictureBox();
private Image _previewImage;
public Image PreviewImage => _previewImage;
private ViewDirection direction = ViewDirection.front;
private enum ViewDirection
{
front,
right,
back,
left,
}
private PckFileData _file;
private SkinANIM _ANIM;
private static Color _backgroundColor = Color.FromArgb(0xff, 0x50, 0x50, 0x50);
private static GraphicsConfig _graphicsConfig = new GraphicsConfig()
@@ -128,18 +114,19 @@ namespace PckStudio.Forms
public generateModel(PckFileData file)
{
MessageBox.Show(this, "This feature is now considered deprecated and will no longer recieve updates. A better alternative is currently under development. Use at your own risk.", "Deprecated Feature", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
//MessageBox.Show(this, "This feature is now considered deprecated and will no longer recieve updates. A better alternative is currently under development. Use at your own risk.", "Deprecated Feature", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
InitializeComponent();
_file = file;
if (file.Size > 0)
if (_file.Size > 0)
{
uvPictureBox.Image = file.GetTexture();
uvPictureBox.Image = renderer3D1.Texture = _file.GetTexture() as Bitmap;
}
comboParent.Items.Clear();
comboParent.Items.AddRange(ValidModelBoxTypes);
LoadData(file.Properties);
}
private static readonly Regex sWhitespace = new Regex(@"\s+");
public static string ReplaceWhitespace(string input, string replacement)
{
@@ -148,15 +135,8 @@ namespace PckStudio.Forms
private void LoadData(PckFileProperties properties)
{
comboParent.Enabled = properties.GetProperties("BOX").All(kv => {
var box = SkinBOX.FromString(kv.Value);
if (ValidModelBoxTypes.Contains(box.Type))
{
modelBoxes.Add(box);
return true;
}
return false;
});
renderer3D1.ANIM = properties.GetPropertyValue("ANIM", SkinANIM.FromString);
renderer3D1.ModelData.AddRange(properties.GetProperties("BOX").Select(kv => SkinBOX.FromString(kv.Value)));
properties.GetProperties("OFFSET").All(kv => {
string[] offset = ReplaceWhitespace(kv.Value, ",").TrimEnd('\n', '\r', ' ').Split(',');
if (offset.Length < 3)
@@ -173,9 +153,7 @@ namespace PckStudio.Forms
return false;
});
_ANIM = properties.GetPropertyValue("ANIM", SkinANIM.FromString);
UpdateListView();
Rerender();
}
//Rename model part/item
@@ -184,14 +162,6 @@ namespace PckStudio.Forms
listViewBoxes.SelectedItems[0].BeginEdit();
}
private void Rerender([CallerMemberName] string caller = default!)
{
Debug.WriteLine($"Call from {caller}", category: nameof(Rerender));
Render(this, EventArgs.Empty);
if (generateTextureCheckBox.Checked)
GenerateUVTextureMap();
}
private void Render(object sender, EventArgs e)
{
//buttonTemplate.Enabled = listViewBoxes.Items.Count == 0;
@@ -875,14 +845,12 @@ namespace PckStudio.Forms
if (Screen.PrimaryScreen.Bounds.Height >= 780 && Screen.PrimaryScreen.Bounds.Width >= 1080) {
return;
}
Rerender();
}
private void createToolStripMenuItem_Click(object sender, EventArgs e)
{
modelBoxes.Add(SkinBOX.Empty);
UpdateListView();
Rerender();
}
private void listView1_SelectedIndexChanged(object sender, EventArgs e)
@@ -903,11 +871,9 @@ namespace PckStudio.Forms
SizeZUpDown.Value = (decimal)part.Size.Z;
TextureXUpDown.Value = (decimal)part.UV.X;
TextureYUpDown.Value = (decimal)part.UV.Y;
Rerender();
}
}
//Changes Item Model Class
private void comboParent_SelectedIndexChanged(object sender, EventArgs e)
{
@@ -926,7 +892,6 @@ namespace PckStudio.Forms
TextureXUpDown.Enabled = true;
TextureYUpDown.Enabled = true;
}
Rerender();
}
private void SizeXUpDown_ValueChanged(object sender, EventArgs e)
@@ -937,7 +902,6 @@ namespace PckStudio.Forms
part.Size.X = (float)SizeXUpDown.Value;
}
UpdateListView();
Rerender();
}
private void SizeYUpDown_ValueChanged(object sender, EventArgs e)
@@ -948,7 +912,6 @@ namespace PckStudio.Forms
part.Size.Y = (float)SizeYUpDown.Value;
}
UpdateListView();
Rerender();
}
private void SizeZUpDown_ValueChanged(object sender, EventArgs e)
@@ -959,7 +922,6 @@ namespace PckStudio.Forms
part.Size.Z = (float)SizeZUpDown.Value;
}
UpdateListView();
Rerender();
}
private void PosXUpDown_ValueChanged(object sender, EventArgs e)
@@ -970,10 +932,8 @@ namespace PckStudio.Forms
part.Pos.X = (float)PosXUpDown.Value;
}
UpdateListView();
Rerender();
}
private void PosYUpDown_ValueChanged(object sender, EventArgs e)
{
if (listViewBoxes.SelectedItems.Count != 0 &&
@@ -982,10 +942,8 @@ namespace PckStudio.Forms
part.Pos.Y = (float)PosYUpDown.Value;
}
UpdateListView();
Rerender();
}
private void PosZUpDown_ValueChanged(object sender, EventArgs e)
{
if (listViewBoxes.SelectedItems.Count != 0 &&
@@ -994,30 +952,8 @@ namespace PckStudio.Forms
part.Pos.Z = (float)PosZUpDown.Value;
}
UpdateListView();
Rerender();
}
private void rotateRightBtn_Click(object sender, EventArgs e)
{
if (direction == ViewDirection.front)
direction = ViewDirection.left;
else
--direction;
labelView.Text = $"View: {direction}";
Rerender();
}
private void rotateLeftBtn_Click(object sender, EventArgs e)
{
if (direction == ViewDirection.left)
direction = ViewDirection.front;
else
++direction;
labelView.Text = $"View: {direction}";
Rerender();
}
//Sets Texture X-Offset
private void TextureXUpDown_ValueChanged(object sender, EventArgs e)
{
@@ -1027,10 +963,8 @@ namespace PckStudio.Forms
part.UV.X = (int)TextureXUpDown.Value;
}
UpdateListView();
Rerender();
}
//Sets texture Y-Offset
private void TextureYUpDown_ValueChanged(object sender, EventArgs e)
{
@@ -1040,10 +974,8 @@ namespace PckStudio.Forms
part.UV.Y = (int)TextureYUpDown.Value;
}
UpdateListView();
Rerender();
}
//Export Current Skin Texture
private void buttonEXPORT_Click(object sender, EventArgs e)
{
@@ -1056,7 +988,6 @@ namespace PckStudio.Forms
}
}
//Imports Skin Texture
private void buttonIMPORT_Click(object sender, EventArgs e)
{
@@ -1077,7 +1008,6 @@ namespace PckStudio.Forms
graphics.DrawImage(img, 0, 0, img.Width, img.Height);
}
uvPictureBox.Invalidate();
Rerender();
}
else
{
@@ -1094,45 +1024,28 @@ namespace PckStudio.Forms
{
_file.Properties.Add("BOX", part);
}
//Bitmap bitmap2 = new Bitmap(64, 64);
//using (Graphics graphics = Graphics.FromImage(bitmap2))
//{
// graphics.ApplyConfig(_graphicsConfig);
// graphics.DrawImage(uvPictureBox.Image, 0, 0, 64, 64);
//}
Close();
}
// Renders model after texture change
private void texturePreview_BackgroundImageChanged(object sender, EventArgs e)
{
Rerender();
}
// Trigger Dialog to select model part/item color
private void listView1_DoubleClick(object sender, EventArgs e)
{
ColorDialog colorDialog = new ColorDialog();
if (colorDialog.ShowDialog() == DialogResult.OK)
listViewBoxes.SelectedItems[0].ForeColor = colorDialog.Color;
Rerender();
}
//Re-renders head with updated x-offset
private void offsetHead_TextChanged(object sender, EventArgs e)
{
Rerender();
}
//Re-renders body with updated x-offset
private void offsetBody_TextAlignChanged(object sender, EventArgs e)
{
Rerender();
}
}
//Loads in model template(Steve)
private void buttonTemplate_Click(object sender, EventArgs e)
@@ -1145,7 +1058,6 @@ namespace PckStudio.Forms
modelBoxes.Add(SkinBOX.FromString("LEG1 -2 0 -2 4 12 4 0 16 0 1 0"));
comboParent.Enabled = true;
UpdateListView();
Rerender();
}
private void UpdateListView()
@@ -1189,7 +1101,6 @@ namespace PckStudio.Forms
File.WriteAllText(saveFileDialog.FileName, contents);
}
// Imports model from csm file
private void buttonImportModel_Click(object sender, EventArgs e)
{
@@ -1220,7 +1131,6 @@ namespace PckStudio.Forms
}
comboParent.Enabled = true;
UpdateListView();
Rerender();
}
private void cloneToolStripMenuItem_Click(object sender, EventArgs e)
@@ -1252,7 +1162,6 @@ namespace PckStudio.Forms
if (listViewBoxes.SelectedItems[0] == null)
return;
listViewBoxes.SelectedItems[0].Remove();
Rerender();
}
private void changeColorToolStripMenuItem_Click(object sender, EventArgs e)
@@ -1260,37 +1169,36 @@ namespace PckStudio.Forms
ColorDialog colorDialog = new ColorDialog();
if (colorDialog.ShowDialog() == DialogResult.OK)
listViewBoxes.SelectedItems[0].ForeColor = colorDialog.Color;
Rerender();
}
//Re-renders tool with updated x-offset
private void offsetTool_TextChanged(object sender, EventArgs e)
{
Rerender();
}
//Re-renders helmet with updated x-offset
private void offsetHelmet_TextChanged(object sender, EventArgs e)
{
Rerender();
}
//Re-renders pants with updated x-offset
private void offsetPants_TextChanged(object sender, EventArgs e)
{
Rerender();
}
//Re-renders leggings with updated x-offset
private void offsetLeggings_TextChanged(object sender, EventArgs e)
{
Rerender();
}
//Re-renders boots with updated x-offset
private void offsetBoots_TextChanged(object sender, EventArgs e)
{
Rerender();
}
//Item Selection
@@ -1328,13 +1236,13 @@ namespace PckStudio.Forms
TextureXUpDown.Enabled = false;
TextureYUpDown.Enabled = false;
comboParent.Enabled = false;
Rerender();
}
//currently scrapped
private void generateModel_FormClosing(object sender, FormClosingEventArgs e)
{/*
if (MessageBox.Show("You done here?", "", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.No)
{
/*if (MessageBox.Show("You done here?", "", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.No)
{
e.Cancel = true;
return;
@@ -1350,13 +1258,13 @@ namespace PckStudio.Forms
{
if (modelBoxes.Remove(part))
listViewBoxes.SelectedItems[0].Remove();
Rerender();
}
}
private void generateModel_SizeChanged(object sender, EventArgs e)
{
Rerender();
}
// TODO
@@ -1416,7 +1324,7 @@ namespace PckStudio.Forms
}
}
}
Rerender();
}
[Obsolete("Just whyyyyy")]

View File

@@ -149,6 +149,7 @@
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Rendering\Camera.cs" />
<Compile Include="Rendering\CubeRenderGroup.cs" />
<Compile Include="Rendering\IndexBuffer.cs" />
<Compile Include="Rendering\PerspectiveCamera.cs" />
<Compile Include="Rendering\RenderBuffer.cs" />

View File

@@ -0,0 +1,86 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenTK;
using OpenTK.Graphics.OpenGL;
using PckStudio.Extensions;
using PckStudio.Internal;
namespace PckStudio.Rendering
{
internal class CubeRenderGroup : RenderGroup<TextureVertex>
{
private const int vertexCountPerCube = 16;
internal CubeRenderGroup(string name)
: base(name, new VertexBufferLayout().Add<float>(3).Add<float>(2), PrimitiveType.Quads)
{
}
internal void AddSkinBox(SkinBOX skinBox)
{
AddCube(skinBox.Pos.ToOpenTKVector(), skinBox.Size.ToOpenTKVector(), skinBox.UV.ToOpenTKVector(), skinBox.Scale, skinBox.Mirror);
}
internal void AddCube(Vector3 position, Vector3 size, Vector2 uv, float scale = 0f, bool mirror = false)
{
var vertexData = GetCubeVertexData(position, size, uv, scale, mirror);
vertices.AddRange(vertexData);
var indexStorage = new uint[] {
// Face 1 (Front)
0, 1, 2, 3,
// Face 2 (Back)
4, 5, 6, 7,
// Face 3 (Right)
4, 8, 9, 7,
// Face 4 (Left)
1, 5, 6, 2,
// Face 5 (Top)
10, 11, 4, 5,
// Face 6 (Bottom)
12, 13, 14, 15
};
indices.AddRange(indexStorage.Select(n => n + indicesOffset));
indicesOffset += vertexCountPerCube;
}
internal void ReplaceCube(int index, Vector3 position, Vector3 size, Vector2 uv, float scale = 0f, bool mirror = false)
{
if (index * vertexCountPerCube > vertices.Count || index < 0)
throw new IndexOutOfRangeException();
vertices.InsertRange(index * vertexCountPerCube, GetCubeVertexData(position, size, uv, scale, mirror));
}
// TODO: add mirroring support
private TextureVertex[] GetCubeVertexData(Vector3 position, Vector3 size, Vector2 uv, float scale, bool mirror)
{
return new TextureVertex[]
{
new TextureVertex(new Vector3(position.X , size.Y + position.Y, -(size.Z + position.Z)) * (scale + 1f), new Vector2(uv.X + size.Z * 2 + size.X * 2, uv.Y + size.Z)),
new TextureVertex(new Vector3(size.X + position.X, size.Y + position.Y, -(size.Z + position.Z)) * (scale + 1f), new Vector2(uv.X + size.Z * 2 + size.X, uv.Y + size.Z)),
new TextureVertex(new Vector3(size.X + position.X, position.Y , -(size.Z + position.Z)) * (scale + 1f), new Vector2(uv.X + size.Z * 2 + size.X, uv.Y + size.Z + size.Y)),
new TextureVertex(new Vector3(position.X , position.Y , -(size.Z + position.Z)) * (scale + 1f), new Vector2(uv.X + size.Z * 2 + size.X * 2, uv.Y + size.Z + size.Y)),
new TextureVertex(new Vector3(position.X , size.Y + position.Y, -position.Z ) * (scale + 1f), new Vector2(uv.X + size.Z, uv.Y + size.Z)),
new TextureVertex(new Vector3(size.X + position.X, size.Y + position.Y, -position.Z ) * (scale + 1f), new Vector2(uv.X + size.Z + size.X, uv.Y + size.Z)),
new TextureVertex(new Vector3(size.X + position.X, position.Y , -position.Z ) * (scale + 1f), new Vector2(uv.X + size.Z + size.X, uv.Y + size.Z + size.Y)),
new TextureVertex(new Vector3(position.X , position.Y , -position.Z ) * (scale + 1f), new Vector2(uv.X + size.Z, uv.Y + size.Z + size.Y)),
new TextureVertex(new Vector3(position.X , size.Y + position.Y, -(size.Z + position.Z)) * (scale + 1f), new Vector2(uv.X, uv.Y + size.Z)),
new TextureVertex(new Vector3(position.X , position.Y , -(size.Z + position.Z)) * (scale + 1f), new Vector2(uv.X, uv.Y + size.Z + size.Y)),
new TextureVertex(new Vector3(size.X + position.X, size.Y + position.Y, -(size.Z + position.Z)) * (scale + 1f), new Vector2(uv.X + size.Z + size.X, uv.Y)),
new TextureVertex(new Vector3(position.X , size.Y + position.Y, -(size.Z + position.Z)) * (scale + 1f), new Vector2(uv.X + size.Z, uv.Y)),
new TextureVertex(new Vector3(size.X + position.X, position.Y , -position.Z ) * (scale + 1f), new Vector2(uv.X + size.Z + size.X * 2, uv.Y)),
new TextureVertex(new Vector3(position.X , position.Y , -position.Z ) * (scale + 1f), new Vector2(uv.X + size.Z + size.X, uv.Y)),
new TextureVertex(new Vector3(position.X , position.Y , -(size.Z + position.Z)) * (scale + 1f), new Vector2(uv.X + size.Z + size.X, uv.Y + size.Z)),
new TextureVertex(new Vector3(size.X + position.X, position.Y , -(size.Z + position.Z)) * (scale + 1f), new Vector2(uv.X + size.Z + size.X * 2, uv.Y + size.Z)),
};
}
}
}

View File

@@ -11,17 +11,33 @@ namespace PckStudio.Rendering
internal class IndexBuffer : IDisposable
{
private int _id;
private int _count;
private List<uint> _indecies;
public IndexBuffer(params uint[] indecies)
{
_id = GL.GenBuffer();
_count = indecies.Length;
Bind();
GL.BufferData(BufferTarget.ElementArrayBuffer, indecies.Length * sizeof(uint), indecies, BufferUsageHint.StaticDraw);
_indecies = new List<uint>(indecies);
}
public int GetCount() => _count;
/// <summary>
/// Creates and attaches created index buffer
/// </summary>
/// <param name="indecies"></param>
/// <returns></returns>
public static IndexBuffer Create(params uint[] indecies)
{
var ib = new IndexBuffer(indecies);
ib.Attach();
return ib;
}
public void Attach()
{
_id = GL.GenBuffer();
Bind();
GL.BufferData(BufferTarget.ElementArrayBuffer, _indecies.Count * sizeof(uint), _indecies.ToArray(), BufferUsageHint.StaticDraw);
}
public int GetCount() => _indecies.Count;
public void Bind()
{

View File

@@ -1,125 +1,51 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenTK;
using System.Runtime.InteropServices;
using OpenTK.Graphics.OpenGL;
using PckStudio.Extensions;
using PckStudio.Internal;
namespace PckStudio.Rendering
{
internal class RenderGroup
internal class RenderGroup<T> where T : struct
{
internal string Name { get; }
private List<TextureVertex> vertices;
private List<uint> indices;
private uint indicesOffset;
internal static int SizeInBytes = Marshal.SizeOf<T>();
protected List<T> vertices;
protected List<uint> indices;
protected uint indicesOffset;
private VertexArray vertexArray;
private VertexBuffer<TextureVertex> vertexBuffer;
private VertexBuffer<T> vertexBuffer;
private IndexBuffer indexBuffer;
private readonly VertexBufferLayout layout;
private readonly VertexBufferLayout _layout;
private readonly PrimitiveType drawType;
private const int vertexCountPerBox = 16;
internal RenderGroup(string name, PrimitiveType type = PrimitiveType.Quads)
internal RenderGroup(string name, VertexBufferLayout layout, PrimitiveType type)
{
Name = name;
drawType = type;
vertices = new List<TextureVertex>(10);
indices = new List<uint>(10);
indicesOffset = 0;
layout = new VertexBufferLayout();
layout.Add<float>(3);
layout.Add<float>(2);
vertices = new List<T>(10);
indices = new List<uint>(10);
_layout = layout;
}
internal RenderBuffer GetRenderBuffer()
{
//vertexArray?.Dispose();
indexBuffer?.Dispose();
vertexBuffer.Dispose();
var vertexData = vertices.ToArray();
vertexBuffer = new VertexBuffer<TextureVertex>(vertexData, vertexData.Length * TextureVertex.SizeInBytes);
vertexArray ??= new VertexArray();
vertexArray.AddBuffer(vertexBuffer, layout);
var vertexData = vertices.ToArray();
vertexBuffer = new VertexBuffer<T>(vertexData, vertexData.Length * SizeInBytes);
indexBuffer = new IndexBuffer(indices.ToArray());
vertexArray.AddBuffer(vertexBuffer, _layout);
indexBuffer = IndexBuffer.Create(indices.ToArray());
return new RenderBuffer(vertexArray, indexBuffer, drawType);
}
// TODO: add mirroring support
internal void AddBox(SkinBOX skinBox)
{
AddBox(skinBox.Pos.ToOpenTKVector(), skinBox.Size.ToOpenTKVector(), skinBox.UV.ToOpenTKVector(), skinBox.Scale);
}
internal void AddBox(Vector3 position, Vector3 size, Vector2 uv, float scale = 0f)
{
var vertexData = GetCubeVertexData(position, size, uv, scale);
vertices.AddRange(vertexData);
var indexStorage = new uint[] {
0 + indicesOffset, 1 + indicesOffset, 2 + indicesOffset, 3 + indicesOffset, // Face 1 (Front)
4 + indicesOffset, 5 + indicesOffset, 6 + indicesOffset, 7 + indicesOffset, // Face 2 (Back)
0 + indicesOffset, 8 + indicesOffset, 9 + indicesOffset, 3 + indicesOffset, // Face 3 (Left)
1 + indicesOffset, 5 + indicesOffset, 6 + indicesOffset, 2 + indicesOffset, // Face 4 (Right)
0 + indicesOffset, 1 + indicesOffset, 10 + indicesOffset, 11 + indicesOffset, // Face 5 (Top)
13 + indicesOffset, 12 + indicesOffset, 14 + indicesOffset, 15 + indicesOffset // Face 6 (Bottom)
};
indicesOffset += vertexCountPerBox;
indices.AddRange(indexStorage);
}
internal void ReplaceBox(int index, Vector3 position, Vector3 size, Vector2 uv, float scale = 0f)
{
if (index * vertexCountPerBox > vertices.Count || index < 0)
throw new IndexOutOfRangeException();
vertices.InsertRange(index * vertexCountPerBox, GetCubeVertexData(position, size, uv, scale));
}
private TextureVertex[] GetCubeVertexData(Vector3 position, Vector3 size, Vector2 uv, float scale)
{
return new TextureVertex[]
{
new TextureVertex(new Vector3(position.X , size.Y + position.Y, size.Z + position.Z) * (scale + 1f), new Vector2(uv.X + size.Z, uv.Y + size.Z)),
new TextureVertex(new Vector3(size.X + position.X, size.Y + position.Y, size.Z + position.Z) * (scale + 1f), new Vector2(uv.X + size.Z + size.X, uv.Y + size.Z)),
new TextureVertex(new Vector3(size.X + position.X, position.Y , size.Z + position.Z) * (scale + 1f), new Vector2(uv.X + size.Z + size.X, uv.Y + size.Z + size.Y)),
new TextureVertex(new Vector3(position.X , position.Y , size.Z + position.Z) * (scale + 1f), new Vector2(uv.X + size.Z, uv.Y + size.Z + size.Y)),
new TextureVertex(new Vector3(position.X , size.Y + position.Y, position.Z ) * (scale + 1f), new Vector2(uv.X + size.Z * 2 + size.X * 2, uv.Y + size.Z)),
new TextureVertex(new Vector3(size.X + position.X, size.Y + position.Y, position.Z ) * (scale + 1f), new Vector2(uv.X + size.Z * 2 + size.X, uv.Y + size.Z)),
new TextureVertex(new Vector3(size.X + position.X, position.Y , position.Z ) * (scale + 1f), new Vector2(uv.X + size.Z * 2 + size.X, uv.Y + size.Z + size.Y)),
new TextureVertex(new Vector3(position.X , position.Y , position.Z ) * (scale + 1f), new Vector2(uv.X + size.Z * 2 + size.X * 2, uv.Y + size.Z + size.Y)),
new TextureVertex(new Vector3(position.X , size.Y + position.Y, position.Z ) * (scale + 1f), new Vector2(uv.X, uv.Y + size.Z)),
new TextureVertex(new Vector3(position.X , position.Y , position.Z ) * (scale + 1f), new Vector2(uv.X, uv.Y + size.Z + size.Y)),
new TextureVertex(new Vector3(size.X + position.X, size.Y + position.Y, position.Z ) * (scale + 1f), new Vector2(uv.X + size.Z + size.X, uv.Y)),
new TextureVertex(new Vector3(position.X , size.Y + position.Y, position.Z ) * (scale + 1f), new Vector2(uv.X + size.Z, uv.Y)),
new TextureVertex(
new Vector3(position.X , position.Y , size.Z + position.Z) * (scale + 1f),
new Vector2(uv.X + size.Z + size.X, uv.Y)),
new TextureVertex(
new Vector3(size.X + position.X, position.Y , size.Z + position.Z) * (scale + 1f),
new Vector2(uv.X + size.Z + size.X * 2, uv.Y)),
new TextureVertex(
new Vector3(position.X , position.Y , position.Z ) * (scale + 1f),
new Vector2(uv.X + size.Z + size.X, uv.Y + size.Z)),
new TextureVertex(
new Vector3(size.X + position.X, position.Y , position.Z ) * (scale + 1f),
new Vector2(uv.X + size.Z + size.X * 2, uv.Y + size.Z)),
};
}
}
}

View File

@@ -38,7 +38,7 @@ namespace PckStudio.Rendering
public Renderer3D()
{
VSync = true;
camera = new PerspectiveCamera(Vector2.Zero, 1f, Vector2.Zero, 30f);
camera = new PerspectiveCamera(Vector3.UnitZ, Vector2.Zero, 30f);
}
}
}

View File

@@ -14,6 +14,8 @@ using System.Drawing;
using System.Runtime.InteropServices;
using PckStudio.Properties;
using PckStudio.Forms.Editor;
using System.Windows.Media.Imaging;
using System.Xml.Linq;
namespace PckStudio.Rendering
{
@@ -25,24 +27,7 @@ namespace PckStudio.Rendering
/// <returns>The visible Texture</returns>
[Description("The current Texture")]
[Category("Appearance")]
public Bitmap Texture
{
get => _texture;
set
{
if (value is null)
return;
if (HasValidContext && skinShader is not null)
{
var texture = new Texture2D(value);
texture.Bind(0);
skinShader.SetUniform1("u_Texture", 0);
Refresh();
}
_texture = value;
}
}
public Bitmap Texture { get; set; }
[Description("Anim flags for special effects applied to the skin")]
[Category("Appearance")]
@@ -62,13 +47,12 @@ namespace PckStudio.Rendering
[Description("The offset from the orignal point (for zoom)")]
[Category("Appearance")]
public Vector2 LookAngle
public Vector2 CameraTarget
{
get => camera.Position;
set => camera.LookAt(value);
}
private void GLDebugMessage(DebugSource source, DebugType type, int id, DebugSeverity severity, int length, IntPtr message, IntPtr userParam)
{
string msg = Marshal.PtrToStringAnsi(message, length);
@@ -90,12 +74,25 @@ namespace PckStudio.Rendering
}
}
private Bitmap _texture;
private Vector2 TextureScaleValue = new Vector2(1f / 64);
private Vector2 UvTranslation = new Vector2(1f / 64);
private const float OverlayScale = 0.1f;
private bool IsLeftMouseDown;
private bool IsRightMouseDown;
private Bitmap RenderTexture
{
set
{
if (HasValidContext && skinShader is not null)
{
var texture = new Texture2D(value);
texture.Bind(0);
skinShader.SetUniform1("u_Texture", 0);
Refresh();
}
}
}
private bool IsMouseHidden
{
get => !Cursor.IsVisible();
@@ -115,61 +112,46 @@ namespace PckStudio.Rendering
private Shader skinShader;
private SkinANIM _anim;
private Dictionary<string, RenderGroup> defaultRenderGroups;
private Dictionary<string, RenderGroup> additionalModelRenderGroups;
private Dictionary<string, CubeRenderGroup> additionalModelRenderGroups;
private CubeRenderGroup head;
private CubeRenderGroup headOverlay;
private CubeRenderGroup body;
private CubeRenderGroup bodyOverlay;
private CubeRenderGroup rightArm;
private CubeRenderGroup rightArmOverlay;
private CubeRenderGroup leftArm;
private CubeRenderGroup leftArmOverlay;
private CubeRenderGroup rightLeg;
private CubeRenderGroup rightLegOverlay;
private CubeRenderGroup leftLeg;
private CubeRenderGroup leftLegOverlay;
private float animationRot;
private float animationRotStep = 1f;
public SkinRenderer()
public SkinRenderer() : base()
{
InitializeComponent();
InitializeCamera();
InitializeSkinData();
_anim = new SkinANIM(); // use backing field to not raise OnANIMUpdate
defaultRenderGroups = new Dictionary<string, RenderGroup>(6)
additionalModelRenderGroups = new Dictionary<string, CubeRenderGroup>(6)
{
{ "HEAD", new RenderGroup("HEAD") },
{ "BODY", new RenderGroup("BODY") },
{ "ARM0", new RenderGroup("ARM0") },
{ "ARM1", new RenderGroup("ARM1") },
{ "LEG0", new RenderGroup("LEG0") },
{ "LEG1", new RenderGroup("LEG1") },
{ "HEADWEAR", new RenderGroup("HEADWEAR") },
{ "JACKET", new RenderGroup("JACKET")},
{ "SLEEVE0", new RenderGroup("SLEEVE0")},
{ "SLEEVE1", new RenderGroup("SLEEVE1")},
{ "LEGGING0", new RenderGroup("LEGGING0")},
{ "LEGGING1", new RenderGroup("LEGGING1")},
//{ "PANTS0", new RenderGroup("PANTS0")},
//{ "PANTS1", new RenderGroup("PANTS1")},
//{ "WAIST", new RenderGroup("WAIST")},
//{ "SOCK0", new RenderGroup("SOCK0")},
//{ "SOCK1", new RenderGroup("SOCK1")},
//{ "BOOT0", new RenderGroup("BOOT0")},
//{ "BOOT1", new RenderGroup("BOOT1")},
//{ "ARMARMOR1", new RenderGroup("ARMARMOR1")},
//{ "ARMARMOR0", new RenderGroup("ARMARMOR0")},
//{ "BODYARMOR", new RenderGroup("BODYARMOR")},
//{ "BELT", new RenderGroup("BELT")},
};
additionalModelRenderGroups = new Dictionary<string, RenderGroup>(6)
{
{ "HEAD", new RenderGroup("HEAD") },
{ "BODY", new RenderGroup("BODY") },
{ "ARM0", new RenderGroup("ARM0") },
{ "ARM1", new RenderGroup("ARM1") },
{ "LEG0", new RenderGroup("LEG0") },
{ "LEG1", new RenderGroup("LEG1") },
{ "HEAD", new CubeRenderGroup("HEAD") },
{ "BODY", new CubeRenderGroup("BODY") },
{ "ARM0", new CubeRenderGroup("ARM0") },
{ "ARM1", new CubeRenderGroup("ARM1") },
{ "LEG0", new CubeRenderGroup("LEG0") },
{ "LEG1", new CubeRenderGroup("LEG1") },
{ "HEADWEAR", new RenderGroup("HEADWEAR") },
{ "JACKET", new RenderGroup("JACKET")},
{ "SLEEVE0", new RenderGroup("SLEEVE0")},
{ "SLEEVE1", new RenderGroup("SLEEVE1")},
{ "LEGGING0", new RenderGroup("LEGGING0")},
{ "LEGGING1", new RenderGroup("LEGGING1")},
{ "HEADWEAR", new CubeRenderGroup("HEADWEAR") },
{ "JACKET" , new CubeRenderGroup("JACKET")},
{ "SLEEVE0" , new CubeRenderGroup("SLEEVE0")},
{ "SLEEVE1" , new CubeRenderGroup("SLEEVE1")},
{ "PANTS0" , new CubeRenderGroup("PANTS0")},
{ "PANTS1" , new CubeRenderGroup("PANTS1")},
};
}
@@ -183,6 +165,45 @@ namespace PckStudio.Rendering
};
}
private void InitializeSkinData()
{
head = new CubeRenderGroup("Head");
head.AddCube(new(-4, -8, -4), new(8, 8, 8), new(0, 0));
headOverlay = new CubeRenderGroup("Head overlay");
headOverlay.AddCube(new(-4, -8, -4), new(8, 8, 8), new(32, 0), scale: OverlayScale);
body = new CubeRenderGroup("Body");
body.AddCube(new(-4, 0, -2), new(8, 12, 4), new(16, 16));
bodyOverlay = new CubeRenderGroup("Body overlay");
bodyOverlay.AddCube(new(-4, 0, -2), new(8, 12, 4), new(16, 32), scale: OverlayScale);
rightArm = new CubeRenderGroup("Right arm");
rightArm.AddCube(new(-3, -2, -2), new(4, 12, 4), new(40, 16));
rightArmOverlay = new CubeRenderGroup("Right arm overlay");
rightArmOverlay.AddCube(new(-3, -2, -2), new(4, 12, 4), new(40, 32), scale: OverlayScale);
leftArm = new CubeRenderGroup("Left arm");
leftArm.AddCube(new(-1, -2, -2), new(4, 12, 4), new(32, 48));
leftArmOverlay = new CubeRenderGroup("Left arm overlay");
leftArmOverlay.AddCube(new(-1, -2, -2), new(4, 12, 4), new(48, 48), scale: OverlayScale);
rightLeg = new CubeRenderGroup("Right leg");
rightLeg.AddCube(new(-2, 0, -2), new(4, 12, 4), new(0, 16));
rightLegOverlay = new CubeRenderGroup("Right leg overlay");
rightLegOverlay.AddCube(new(-2, 0, -2), new(4, 12, 4), new(0, 32), scale: OverlayScale);
leftLeg = new CubeRenderGroup("Left leg");
leftLeg.AddCube(new(-2, 0, -2), new(4, 12, 4), new(16, 48));
leftLegOverlay = new CubeRenderGroup("Left leg overlay");
leftLegOverlay.AddCube(new(-2, 0, -2), new(4, 12, 4), new(0, 48), scale: OverlayScale);
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
@@ -197,40 +218,9 @@ namespace PckStudio.Rendering
skinShader = Shader.Create(Resources.skinVertexShader, Resources.skinFragment);
skinShader.Bind();
if (_texture is null)
{
Texture = Resources.classic_template;
if (Texture.Size == new Size(64, 64))
{
ANIM.SetFlag(SkinAnimFlag.RESOLUTION_64x64, true);
}
}
Texture ??= Resources.classic_template;
var headbox = new SkinBOX("HEAD", new(-4, -8, -4), new(8, 8, 8), new( 0, 0));
var headoverlaybox = new SkinBOX("HEADWEAR", new(-4, -8, -4), new(8, 8, 8), new(32, 0), scale: OverlayScale);
var bodybox = new SkinBOX("BODY", new(-4, 0, -2), new(8, 12, 4), new(16, 16));
var bodyoverlaybox = new SkinBOX("JACKET", new(-4, 0, -2), new(8, 12, 4), new(16, 32), scale: OverlayScale);
var arm0box = new SkinBOX("ARM0", new(-3, -2, -2), new(4, 12, 4), new(40, 16));
var arm1box = new SkinBOX("ARM1", new(-1, -2, -2), new(4, 12, 4), new(32, 48));
var arm0overlaybox = new SkinBOX("SLEEVE0", new(-3, -2, -2), new(4, 12, 4), new(40, 32), scale: OverlayScale);
var arm1overlaybox = new SkinBOX("SLEEVE1", new(-1, -2, -2), new(4, 12, 4), new(48, 48), scale: OverlayScale);
var leg0box = new SkinBOX("LEG0", new(-2, 0, -2), new(4, 12, 4), new( 0, 16));
var leg0overlaybox = new SkinBOX("LEGGING0", new(-2, 0, -2), new(4, 12, 4), new( 0, 32), scale: OverlayScale);
var leg1box = new SkinBOX("LEG1", new(-2, 0, -2), new(4, 12, 4), new(16, 48));
var leg1overlaybox = new SkinBOX("LEGGING1", new(-2, 0, -2), new(4, 12, 4), new( 0, 48), scale: OverlayScale);
AddToGroup(headbox);
AddToGroup(headoverlaybox);
AddToGroup(bodybox);
AddToGroup(bodyoverlaybox);
AddToGroup(arm0box);
AddToGroup(arm0overlaybox);
AddToGroup(arm1box);
AddToGroup(arm1overlaybox);
AddToGroup(leg0box);
AddToGroup(leg0overlaybox);
AddToGroup(leg1box);
AddToGroup(leg1overlaybox);
RenderTexture = Texture;
foreach (var item in ModelData)
{
@@ -240,20 +230,22 @@ namespace PckStudio.Rendering
GLErrorCheck();
}
public void Reload()
{
additionalModelRenderGroups.Clear();
foreach (var item in ModelData)
{
AddCustomModelPart(item);
}
Refresh();
}
private void AddCustomModelPart(SkinBOX skinBox)
{
if (!additionalModelRenderGroups.ContainsKey(skinBox.Type))
throw new KeyNotFoundException(skinBox.Type);
additionalModelRenderGroups[skinBox.Type].AddBox(skinBox);
}
private void AddToGroup(SkinBOX skinBox)
{
if (!defaultRenderGroups.ContainsKey(skinBox.Type))
throw new KeyNotFoundException(skinBox.Type);
defaultRenderGroups[skinBox.Type].AddBox(skinBox);
additionalModelRenderGroups[skinBox.Type].AddSkinBox(skinBox);
}
[Conditional("DEBUG")]
@@ -276,7 +268,7 @@ namespace PckStudio.Rendering
break;
case Keys.R:
GlobalModelRotation = Vector2.Zero;
LookAngle = Vector2.Zero;
CameraTarget = Vector2.Zero;
Refresh();
return true;
case Keys.F1:
@@ -286,11 +278,14 @@ namespace PckStudio.Rendering
};
if (fileDialog.ShowDialog() == DialogResult.OK)
{
Texture = Image.FromFile(fileDialog.FileName) as Bitmap;
RenderTexture = Texture = Image.FromFile(fileDialog.FileName) as Bitmap;
}
return true;
case Keys.F3:
foreach (var item in ModelData)
{
Debug.WriteLine(item);
}
return true;
case Keys.A:
{
@@ -312,23 +307,23 @@ namespace PckStudio.Rendering
if (slim || ANIM.GetFlag(SkinAnimFlag.RESOLUTION_64x64))
{
int slimValue = slim ? 3 : 4;
TextureScaleValue = new Vector2(1f / 64);
defaultRenderGroups["ARM0"].ReplaceBox(0, new(-3, -2, -2), new(slimValue, 12, 4), new(40, 16));
defaultRenderGroups["ARM1"].ReplaceBox(0, new(-1, -2, -2), new(slimValue, 12, 4), new(32, 48));
defaultRenderGroups["SLEEVE0"].ReplaceBox(0, new(-3, -2, -2), new(slimValue, 12, 4), new(40, 32), scale: OverlayScale);
defaultRenderGroups["SLEEVE1"].ReplaceBox(0, new(-1, -2, -2), new(slimValue, 12, 4), new(48, 48), scale: OverlayScale);
UvTranslation = new Vector2(1f / 64);
rightArm.ReplaceCube(0, new(-3, -2, -2), new(slimValue, 12, 4), new(40, 16));
rightArmOverlay.ReplaceCube(0, new(-3, -2, -2), new(slimValue, 12, 4), new(40, 32), scale: OverlayScale);
leftArm.ReplaceCube(0, new(-1, -2, -2), new(slimValue, 12, 4), new(32, 48));
leftArmOverlay.ReplaceCube(0, new(-1, -2, -2), new(slimValue, 12, 4), new(48, 48), scale: OverlayScale);
defaultRenderGroups["LEG0"].ReplaceBox(0, new(-2, 0, -2), new(4, 12, 4), new(0, 16));
defaultRenderGroups["LEG1"].ReplaceBox(0, new(-2, 0, -2), new(4, 12, 4), new(16, 48));
rightLeg.ReplaceCube(0, new(-2, 0, -2), new(4, 12, 4), new(0, 16));
leftLeg.ReplaceCube(0, new(-2, 0, -2), new(4, 12, 4), new(16, 48));
return;
}
TextureScaleValue = new Vector2(1f / 64, 1f / 32);
defaultRenderGroups["ARM0"].ReplaceBox(0, new(-3, -2, -2), new(4, 12, 4), new(40, 16));
defaultRenderGroups["ARM1"].ReplaceBox(0, new(-1, -2, -2), new(4, 12, 4), new(40, 16));
defaultRenderGroups["LEG0"].ReplaceBox(0, new(-2, 0, -2), new(4, 12, 4), new(0, 16));
defaultRenderGroups["LEG1"].ReplaceBox(0, new(-2, 0, -2), new(4, 12, 4), new(0, 16));
defaultRenderGroups["SLEEVE0"].ReplaceBox(0, new(-3, -2, -2), new(4, 12, 4), new(40, 32), scale: OverlayScale);
defaultRenderGroups["SLEEVE1"].ReplaceBox(0, new(-1, -2, -2), new(4, 12, 4), new(40, 32), scale: OverlayScale);
UvTranslation = new Vector2(1f / 64, 1f / 32);
rightArm.ReplaceCube(0, new(-3, -2, -2), new(4, 12, 4), new(40, 16));
leftArm.ReplaceCube(0, new(-1, -2, -2), new(4, 12, 4), new(40, 16));
rightLeg.ReplaceCube(0, new(-2, 0, -2), new(4, 12, 4), new(0, 16));
leftLeg.ReplaceCube(0, new(-2, 0, -2), new(4, 12, 4), new(0, 16));
rightArmOverlay.ReplaceCube(0, new(-3, -2, -2), new(4, 12, 4), new(40, 32), scale: OverlayScale);
leftArmOverlay.ReplaceCube(0, new(-1, -2, -2), new(4, 12, 4), new(40, 32), scale: OverlayScale);
}
protected override void OnPaint(PaintEventArgs e)
@@ -345,7 +340,7 @@ namespace PckStudio.Rendering
var viewProjection = camera.GetViewProjection();
skinShader.SetUniformMat4("u_ViewProjection", ref viewProjection);
skinShader.SetUniform2("u_TexScale", TextureScaleValue);
skinShader.SetUniform2("u_TexScale", UvTranslation);
GL.Viewport(Size);
@@ -356,7 +351,6 @@ namespace PckStudio.Rendering
GL.Enable(EnableCap.Texture2D); // Enable textures
GL.Enable(EnableCap.DepthTest); // Enable correct Z Drawings
GL.DepthFunc(DepthFunction.Lequal); // Enable correct Z Drawings
GL.Disable(EnableCap.AlphaTest); // Disable transparent
GL.Enable(EnableCap.Blend);
GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
@@ -364,20 +358,45 @@ namespace PckStudio.Rendering
GL.Enable(EnableCap.AlphaTest); // Enable transparent
GL.AlphaFunc(AlphaFunction.Greater, 0.4f);
Matrix4 modelRotationMatrix = Matrix4.CreateFromAxisAngle(new Vector3(-1f, 0f, 0f), MathHelper.DegreesToRadians(GlobalModelRotation.X))
* Matrix4.CreateFromAxisAngle(new Vector3(0f, 1f, 0f), MathHelper.DegreesToRadians(GlobalModelRotation.Y));
RenderSkinPartIf("HEAD" , !ANIM.GetFlag(SkinAnimFlag.HEAD_DISABLED), new Vector3(0f, 16f, 0f), modelRotationMatrix);
RenderSkinPartIf("HEADWEAR", !ANIM.GetFlag(SkinAnimFlag.HEAD_OVERLAY_DISABLED), new Vector3(0f, 16f + OverlayScale, 0f), modelRotationMatrix);
Matrix4 modelMatrix =
Matrix4.CreateFromAxisAngle(-Vector3.UnitX, MathHelper.DegreesToRadians(GlobalModelRotation.X))
* Matrix4.CreateFromAxisAngle(Vector3.UnitY, MathHelper.DegreesToRadians(GlobalModelRotation.Y));
RenderSkinPartIf("BODY" , !ANIM.GetFlag(SkinAnimFlag.BODY_DISABLED), new Vector3(0f, -4f, 0f), modelRotationMatrix);
RenderSkinPartIf("JACKET", !ANIM.GetFlag(SkinAnimFlag.BODY_OVERLAY_DISABLED), new Vector3(0f, -4f + OverlayScale, 0f), modelRotationMatrix);
RenderSkin(modelMatrix);
#if true
RenderAdditionalModelData("HEAD", new Vector3(0f, 0f, 0f), /*Matrix4.CreateFromAxisAngle(Vector3.UnitX, MathHelper.DegreesToRadians(180f)) **/ modelMatrix);
RenderAdditionalModelData("BODY", new Vector3(0f, -4f, 0f), /*Matrix4.CreateFromAxisAngle(Vector3.UnitX, MathHelper.DegreesToRadians(180f)) **/ modelMatrix);
//RenderAdditionalModelData("ARM0", new Vector3(0f, 28f, 0f), /*Matrix4.CreateFromAxisAngle(Vector3.UnitX, MathHelper.DegreesToRadians(180f)) **/ modelRotationMatrix);
//RenderAdditionalModelData("ARM1", new Vector3(0f, 28f, 0f), /*Matrix4.CreateFromAxisAngle(Vector3.UnitX, MathHelper.DegreesToRadians(180f)) **/ modelRotationMatrix);
//RenderAdditionalModelData("LEG0", new Vector3(0f, 28f, 0f), /*Matrix4.CreateFromAxisAngle(Vector3.UnitX, MathHelper.DegreesToRadians(180f)) **/ modelRotationMatrix);
//RenderAdditionalModelData("LEG1", new Vector3(0f, 28f, 0f), /*Matrix4.CreateFromAxisAngle(Vector3.UnitX, MathHelper.DegreesToRadians(180f)) **/ modelRotationMatrix);
#endif
SwapBuffers();
}
private void RenderSkin(Matrix4 modelMatrix)
{
if (!ANIM.GetFlag(SkinAnimFlag.HEAD_DISABLED))
{
RenderSkinPart(head.GetRenderBuffer(), new Vector3(0f, 16f, 0f), modelMatrix);
}
if (!ANIM.GetFlag(SkinAnimFlag.HEAD_OVERLAY_DISABLED))
{
RenderSkinPart(headOverlay.GetRenderBuffer(), new Vector3(0f, 16f + OverlayScale, 0f), modelMatrix);
}
if (!ANIM.GetFlag(SkinAnimFlag.BODY_DISABLED))
{
RenderSkinPart(body.GetRenderBuffer(), new Vector3(0f, -4f, 0f), modelMatrix);
}
bool slimModel = ANIM.GetFlag(SkinAnimFlag.SLIM_MODEL);
var extraRightRotation = Matrix4.CreateFromAxisAngle(Vector3.UnitY, MathHelper.DegreesToRadians(animationRot));
var extraLeftRotation = Matrix4.CreateFromAxisAngle(Vector3.UnitY, MathHelper.DegreesToRadians(-animationRot));
var translationRight = new Vector3(ANIM.GetFlag(SkinAnimFlag.SLIM_MODEL) ? -4f : -5f, -2f, 0f);
var translationLeft = new Vector3(5f, -2f, 0f);
var extraLeftRotation = Matrix4.CreateFromAxisAngle(Vector3.UnitY, MathHelper.DegreesToRadians(-animationRot));
var translationRight = new Vector3(slimModel ? -4f : -5f, -2f, 0f);
var translationLeft = new Vector3(5f, -2f, 0f);
if (ANIM.GetFlag(SkinAnimFlag.ZOMBIE_ARMS))
{
extraRightRotation *= Matrix4.CreateFromAxisAngle(Vector3.UnitX, MathHelper.DegreesToRadians(-90f));
@@ -385,43 +404,61 @@ namespace PckStudio.Rendering
translationRight.Yz = translationLeft.Yz = new Vector2(-8f, 6f);
}
RenderSkinPartIf("ARM0" , !ANIM.GetFlag(SkinAnimFlag.RIGHT_ARM_DISABLED) , translationRight, extraRightRotation * modelRotationMatrix);
RenderSkinPartIf("SLEEVE0", !ANIM.GetFlag(SkinAnimFlag.RIGHT_ARM_OVERLAY_DISABLED), translationRight, extraRightRotation * modelRotationMatrix);
RenderSkinPartIf("ARM1" , !ANIM.GetFlag(SkinAnimFlag.LEFT_ARM_DISABLED) , translationLeft , extraLeftRotation * modelRotationMatrix);
RenderSkinPartIf("SLEEVE1", !ANIM.GetFlag(SkinAnimFlag.LEFT_ARM_OVERLAY_DISABLED) , translationLeft , extraLeftRotation * modelRotationMatrix);
RenderSkinPartIf("LEG0" , !ANIM.GetFlag(SkinAnimFlag.RIGHT_LEG_DISABLED) , new Vector3(-2f, -16f, 0f), modelRotationMatrix);
RenderSkinPartIf("LEGGING0", !ANIM.GetFlag(SkinAnimFlag.RIGHT_LEG_OVERLAY_DISABLED), new Vector3(-2f, -16f, 0f), modelRotationMatrix);
RenderSkinPartIf("LEG1" , !ANIM.GetFlag(SkinAnimFlag.LEFT_LEG_DISABLED) , new Vector3( 2f, -16f, 0f), modelRotationMatrix);
RenderSkinPartIf("LEGGING1", !ANIM.GetFlag(SkinAnimFlag.LEFT_LEG_OVERLAY_DISABLED) , new Vector3( 2f, -16f, 0f), modelRotationMatrix);
#if flase
RenderAdditionalModelData("HEAD", new Vector3(0f, 28f, 0f), /*Matrix4.CreateFromAxisAngle(Vector3.UnitX, MathHelper.DegreesToRadians(180f)) **/ modelRotationMatrix);
RenderAdditionalModelData("BODY", new Vector3(0f, 28f, 0f), /*Matrix4.CreateFromAxisAngle(Vector3.UnitX, MathHelper.DegreesToRadians(180f)) **/ modelRotationMatrix);
RenderAdditionalModelData("ARM0", new Vector3(0f, 28f, 0f), /*Matrix4.CreateFromAxisAngle(Vector3.UnitX, MathHelper.DegreesToRadians(180f)) **/ modelRotationMatrix);
RenderAdditionalModelData("ARM1", new Vector3(0f, 28f, 0f), /*Matrix4.CreateFromAxisAngle(Vector3.UnitX, MathHelper.DegreesToRadians(180f)) **/ modelRotationMatrix);
RenderAdditionalModelData("LEG0", new Vector3(0f, 28f, 0f), /*Matrix4.CreateFromAxisAngle(Vector3.UnitX, MathHelper.DegreesToRadians(180f)) **/ modelRotationMatrix);
RenderAdditionalModelData("LEG1", new Vector3(0f, 28f, 0f), /*Matrix4.CreateFromAxisAngle(Vector3.UnitX, MathHelper.DegreesToRadians(180f)) **/ modelRotationMatrix);
#endif
SwapBuffers();
}
private void RenderSkinPartIf(string name, bool condition, Vector3 translation, Matrix4 rotation)
{
if (condition)
if (!ANIM.GetFlag(SkinAnimFlag.RIGHT_ARM_DISABLED))
{
RenderSkinPart(name, translation, rotation);
RenderSkinPart(rightArm.GetRenderBuffer(), translationRight, extraRightRotation * modelMatrix);
}
if (!ANIM.GetFlag(SkinAnimFlag.LEFT_ARM_DISABLED))
{
RenderSkinPart(leftArm.GetRenderBuffer(), translationLeft, extraLeftRotation * modelMatrix);
}
if (!ANIM.GetFlag(SkinAnimFlag.RIGHT_LEG_DISABLED))
{
RenderSkinPart(rightLeg.GetRenderBuffer(), new Vector3(-2f, -16f, 0f), modelMatrix);
}
if (!ANIM.GetFlag(SkinAnimFlag.LEFT_LEG_DISABLED))
{
RenderSkinPart(leftLeg.GetRenderBuffer(), new Vector3(2f, -16f, 0f), modelMatrix);
}
if (ANIM.GetFlag(SkinAnimFlag.RESOLUTION_64x64) || slimModel)
{
if (!ANIM.GetFlag(SkinAnimFlag.BODY_OVERLAY_DISABLED))
{
RenderSkinPart(bodyOverlay.GetRenderBuffer(), new Vector3(0f, -4f + OverlayScale, 0f), modelMatrix);
}
if (!ANIM.GetFlag(SkinAnimFlag.RIGHT_ARM_OVERLAY_DISABLED))
{
RenderSkinPart(rightArmOverlay.GetRenderBuffer(), translationRight, extraRightRotation * modelMatrix);
}
if (!ANIM.GetFlag(SkinAnimFlag.LEFT_ARM_OVERLAY_DISABLED))
{
RenderSkinPart(leftArmOverlay.GetRenderBuffer(), translationLeft, extraLeftRotation * modelMatrix);
}
if (!ANIM.GetFlag(SkinAnimFlag.RIGHT_LEG_OVERLAY_DISABLED))
{
RenderSkinPart(rightLegOverlay.GetRenderBuffer(), new Vector3(-2f, -16f, 0f), modelMatrix);
}
if (!ANIM.GetFlag(SkinAnimFlag.LEFT_LEG_OVERLAY_DISABLED))
{
RenderSkinPart(leftLegOverlay.GetRenderBuffer(), new Vector3(2f, -16f, 0f), modelMatrix);
}
}
}
private void RenderSkinPart(string name, Vector3 translation, Matrix4 rotation)
private void RenderSkinPart(RenderBuffer buffer, Vector3 translation, Matrix4 rotation)
{
var transform = Matrix4.CreateTranslation(translation);
var model = transform * rotation;
skinShader.SetUniformMat4("u_Model", ref model);
Renderer.Draw(skinShader, defaultRenderGroups[name].GetRenderBuffer());
Renderer.Draw(skinShader, buffer);
}
private void RenderAdditionalModelData(string name, Vector3 translation, Matrix4 rotation)
@@ -508,7 +545,7 @@ namespace PckStudio.Rendering
{
float deltaX = -(Cursor.Position.X - MouseLoc.X) * 0.05f / (float)MathHelper.DegreesToRadians(camera.Fov);
float deltaY = (Cursor.Position.Y - MouseLoc.Y) * 0.05f / (float)MathHelper.DegreesToRadians(camera.Fov);
LookAngle += new Vector2(deltaX, deltaY);
CameraTarget += new Vector2(deltaX, deltaY);
Refresh();
Cursor.Position = new Point((int)Math.Round(Screen.PrimaryScreen.Bounds.Width / 2d), (int)Math.Round(Screen.PrimaryScreen.Bounds.Height / 2d));
MouseLoc = Cursor.Position;

View File

@@ -50,7 +50,7 @@ namespace PckStudio.Rendering
return elements.AsReadOnly();
}
public void Add<T>(int count)
public VertexBufferLayout Add<T>(int count)
{
if (typeof(T).Equals(typeof(float)))
{
@@ -67,6 +67,7 @@ namespace PckStudio.Rendering
elements.Add(new VertexBufferElement(VertexAttribPointerType.UnsignedInt, count, false));
stride += count * VertexBufferElement.GetStrideSize(VertexAttribPointerType.UnsignedInt);
}
return this;
}
internal int GetStride()