diff --git a/PCK-Studio/PckStudio.csproj b/PCK-Studio/PckStudio.csproj
index df12b335..6e37cb7e 100644
--- a/PCK-Studio/PckStudio.csproj
+++ b/PCK-Studio/PckStudio.csproj
@@ -153,7 +153,7 @@
-
+
diff --git a/PCK-Studio/Rendering/CubeRenderGroup.cs b/PCK-Studio/Rendering/CubeBatchMesh.cs
similarity index 88%
rename from PCK-Studio/Rendering/CubeRenderGroup.cs
rename to PCK-Studio/Rendering/CubeBatchMesh.cs
index 67fe8700..a16b1d57 100644
--- a/PCK-Studio/Rendering/CubeRenderGroup.cs
+++ b/PCK-Studio/Rendering/CubeBatchMesh.cs
@@ -1,4 +1,4 @@
-/* Copyright (c) 2023-present miku-666
+/* Copyright (c) 2024-present miku-666
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
@@ -17,7 +17,6 @@
**/
using System;
using System.Collections.Generic;
-using System.Diagnostics;
using System.Linq;
using OpenTK;
using OpenTK.Graphics.OpenGL;
@@ -26,18 +25,18 @@ using PckStudio.Internal;
namespace PckStudio.Rendering
{
- internal class CubeRenderGroup : RenderGroup
+ internal class CubeBatchMesh : GenericMesh
{
private List cubes;
internal float Scale { get; set; } = 1f;
- internal CubeRenderGroup(string name) : base(name, PrimitiveType.Triangles)
+ internal CubeBatchMesh(string name) : base(name, PrimitiveType.Triangles)
{
cubes = new List(5);
}
- internal CubeRenderGroup(string name, float scale)
+ internal CubeBatchMesh(string name, float scale)
: this(name)
{
Scale = scale;
@@ -48,16 +47,16 @@ namespace PckStudio.Rendering
AddCube(skinBox.Pos.ToOpenTKVector(), skinBox.Size.ToOpenTKVector(), skinBox.UV.ToOpenTKVector(), skinBox.Scale + Scale, skinBox.Mirror, skinBox.Type == "HEAD");
}
- internal void Clear()
+ internal void ClearData()
{
cubes.Clear();
ResetBuffers();
}
///
- /// Submits buffered data to the underlying graphics buffer
+ /// Uploads MeshData
///
- internal void Submit()
+ internal void UploadData()
{
ResetBuffers();
foreach (var cube in cubes)
@@ -71,6 +70,7 @@ namespace PckStudio.Rendering
indices.AddRange(indexStorage.Select(n => n + indicesOffset));
indicesOffset += cubeVertices.Length;
}
+ Submit();
}
internal void AddCube(Vector3 position, Vector3 size, Vector2 uv, float scale = 1f, bool mirrorTexture = false, bool flipZMapping = false)
@@ -90,7 +90,6 @@ namespace PckStudio.Rendering
cube.Uv = uv;
cube.Scale = scale;
cube.MirrorTexture = mirrorTexture;
- Submit();
}
internal void SetEnabled(int index, bool enable)
@@ -99,7 +98,6 @@ namespace PckStudio.Rendering
throw new IndexOutOfRangeException();
cubes[index].ShouldRender = enable;
- Submit();
}
}
}
diff --git a/PCK-Studio/Rendering/SkinRenderer.cs b/PCK-Studio/Rendering/SkinRenderer.cs
index 8e3ce8e2..84e27dfc 100644
--- a/PCK-Studio/Rendering/SkinRenderer.cs
+++ b/PCK-Studio/Rendering/SkinRenderer.cs
@@ -79,6 +79,8 @@ namespace PckStudio.Rendering
{
_anim = value;
OnANIMUpdate();
+ MakeCurrent();
+ UploadMeshData();
}
}
@@ -148,22 +150,22 @@ namespace PckStudio.Rendering
private float skyboxRotation = 0f;
private float skyboxRotationStep = 0.5f;
- private Dictionary additionalModelRenderGroups;
+ private Dictionary meshStorage;
private Dictionary partOffset;
- private CubeRenderGroup head;
- private CubeRenderGroup body;
- private CubeRenderGroup rightArm;
- private CubeRenderGroup leftArm;
- private CubeRenderGroup rightLeg;
- private CubeRenderGroup leftLeg;
+ private CubeBatchMesh head;
+ private CubeBatchMesh body;
+ private CubeBatchMesh rightArm;
+ private CubeBatchMesh leftArm;
+ private CubeBatchMesh rightLeg;
+ private CubeBatchMesh leftLeg;
- private CubeRenderGroup headOverlay;
- private CubeRenderGroup bodyOverlay;
- private CubeRenderGroup rightArmOverlay;
- private CubeRenderGroup leftArmOverlay;
- private CubeRenderGroup rightLegOverlay;
- private CubeRenderGroup leftLegOverlay;
+ private CubeBatchMesh headOverlay;
+ private CubeBatchMesh bodyOverlay;
+ private CubeBatchMesh rightArmOverlay;
+ private CubeBatchMesh leftArmOverlay;
+ private CubeBatchMesh rightLegOverlay;
+ private CubeBatchMesh leftLegOverlay;
private float animationCurrentRotationAngle;
private float animationRotationStep = 0.5f;
@@ -204,16 +206,8 @@ namespace PckStudio.Rendering
public SkinRenderer() : base()
{
- InitializeCamera();
InitializeSkinData();
- InitializeShaders();
- InitializeComponent();
-
- ANIM ??= new SkinANIM(SkinAnimMask.RESOLUTION_64x64);
- OnTimerTick = AnimationTick;
- ModelData = new ObservableCollection();
- ModelData.CollectionChanged += ModelData_CollectionChanged;
- additionalModelRenderGroups = new Dictionary(6)
+ meshStorage = new Dictionary()
{
{ "HEAD", head },
{ "BODY", body },
@@ -229,12 +223,11 @@ namespace PckStudio.Rendering
{ "PANTS0" , rightLegOverlay },
{ "PANTS1" , leftLegOverlay },
- { "BODYARMOR", new CubeRenderGroup("BODYARMOR") },
- { "BELT", new CubeRenderGroup("BELT") },
- { "ARMARMOR0", new CubeRenderGroup("ARMARMOR0") },
- { "ARMARMOR1", new CubeRenderGroup("ARMARMOR1") },
+ { "BODYARMOR", new CubeBatchMesh("BODYARMOR") },
+ { "BELT", new CubeBatchMesh("BELT") },
+ { "ARMARMOR0", new CubeBatchMesh("ARMARMOR0") },
+ { "ARMARMOR1", new CubeBatchMesh("ARMARMOR1") },
};
-
partOffset = new Dictionary()
{
{ "HEAD", 0f },
@@ -262,6 +255,18 @@ namespace PckStudio.Rendering
{ "TOOL0" , 0f },
{ "TOOL1" , 0f },
};
+
+ InitializeCamera();
+ InitializeComponent();
+ MakeCurrent();
+ InitializeShaders();
+ InitializeFramebuffer();
+ UploadMeshData();
+
+ ANIM ??= new SkinANIM(SkinAnimMask.RESOLUTION_64x64);
+ OnTimerTick = AnimationTick;
+ ModelData = new ObservableCollection();
+ ModelData.CollectionChanged += ModelData_CollectionChanged;
}
// TODO: calculate CameraDistance based on model size
@@ -278,53 +283,41 @@ namespace PckStudio.Rendering
private void InitializeSkinData()
{
- head ??= new CubeRenderGroup("Head");
+ head ??= new CubeBatchMesh("Head");
head.AddCube(new(-4, -8, -4), new(8, 8, 8), new(0, 0), flipZMapping: true);
- head.Submit();
- headOverlay ??= new CubeRenderGroup("Head Overlay", OverlayScale);
+ headOverlay ??= new CubeBatchMesh("Head Overlay", OverlayScale);
headOverlay.AddCube(new(-4, -8, -4), new(8, 8, 8), new(32, 0), flipZMapping: true, scale: OverlayScale);
- headOverlay.Submit();
- body ??= new CubeRenderGroup("Body");
+ body ??= new CubeBatchMesh("Body");
body.AddCube(new(-4, 0, -2), new(8, 12, 4), new(16, 16));
- body.Submit();
- bodyOverlay ??= new CubeRenderGroup("Body Overlay", OverlayScale);
+ bodyOverlay ??= new CubeBatchMesh("Body Overlay", OverlayScale);
bodyOverlay.AddCube(new(-4, 0, -2), new(8, 12, 4), new(16, 32), scale: OverlayScale);
- bodyOverlay.Submit();
- rightArm ??= new CubeRenderGroup("Right Arm");
+ rightArm ??= new CubeBatchMesh("Right Arm");
rightArm.AddCube(new(-3, -2, -2), new(4, 12, 4), new(40, 16));
- rightArm.Submit();
- rightArmOverlay ??= new CubeRenderGroup("Right Arm Overlay", OverlayScale);
+ rightArmOverlay ??= new CubeBatchMesh("Right Arm Overlay", OverlayScale);
rightArmOverlay.AddCube(new(-3, -2, -2), new(4, 12, 4), new(40, 32), scale: OverlayScale);
- rightArmOverlay.Submit();
- leftArm ??= new CubeRenderGroup("Left Arm");
+ leftArm ??= new CubeBatchMesh("Left Arm");
leftArm.AddCube(new(-1, -2, -2), new(4, 12, 4), new(32, 48));
- leftArm.Submit();
- leftArmOverlay ??= new CubeRenderGroup("Left Arm Overlay", OverlayScale);
+ leftArmOverlay ??= new CubeBatchMesh("Left Arm Overlay", OverlayScale);
leftArmOverlay.AddCube(new(-1, -2, -2), new(4, 12, 4), new(48, 48), scale: OverlayScale);
- leftArmOverlay.Submit();
- rightLeg ??= new CubeRenderGroup("Right Leg");
+ rightLeg ??= new CubeBatchMesh("Right Leg");
rightLeg.AddCube(new(-2, 0, -2), new(4, 12, 4), new(0, 16));
- rightLeg.Submit();
- rightLegOverlay ??= new CubeRenderGroup("Right Leg Overlay", OverlayScale);
+ rightLegOverlay ??= new CubeBatchMesh("Right Leg Overlay", OverlayScale);
rightLegOverlay.AddCube(new(-2, 0, -2), new(4, 12, 4), new(0, 32), scale: OverlayScale);
- rightLegOverlay.Submit();
- leftLeg ??= new CubeRenderGroup("Left Leg");
+ leftLeg ??= new CubeBatchMesh("Left Leg");
leftLeg.AddCube(new(-2, 0, -2), new(4, 12, 4), new(16, 48));
- leftLeg.Submit();
- leftLegOverlay ??= new CubeRenderGroup("Left Leg Overlay", OverlayScale);
+ leftLegOverlay ??= new CubeBatchMesh("Left Leg Overlay", OverlayScale);
leftLegOverlay.AddCube(new(-2, 0, -2), new(4, 12, 4), new(0, 48), scale: OverlayScale);
- leftLegOverlay.Submit();
}
private void InitializeShaders()
@@ -439,14 +432,8 @@ namespace PckStudio.Rendering
}
}
- protected override void OnLoad(EventArgs e)
+ private void InitializeFramebuffer()
{
- base.OnLoad(e);
-
- MakeCurrent();
- // Initialize framebuffer
- {
-
framebuffer = new FrameBuffer();
framebuffer.Bind();
framebufferTexture = new Texture2D(0);
@@ -480,6 +467,14 @@ namespace PckStudio.Rendering
}
}
+ private void UploadMeshData()
+ {
+ foreach (var cubeMesh in meshStorage?.Values)
+ {
+ cubeMesh?.UploadData();
+ }
+ }
+
public void SetPartOffset(SkinPartOffset offset)
{
SetPartOffset(offset.Type, offset.Value);
@@ -489,7 +484,7 @@ namespace PckStudio.Rendering
{
if (!partOffset.ContainsKey(name))
{
- Debug.WriteLine($"'{name}' is not inside {nameof(partOffset)}");
+ Trace.TraceInformation($"[{nameof(SetPartOffset)}]: '{name}' is not inside {nameof(partOffset)}");
return;
}
partOffset[name] = value;
@@ -502,26 +497,32 @@ namespace PckStudio.Rendering
private void ModelData_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
- if (e.Action != NotifyCollectionChangedAction.Move &&
- e.Action != NotifyCollectionChangedAction.Reset)
+ // TODO: dont re-initialize everytime..
+ switch (e.Action)
{
- UpdateModelData();
+ case NotifyCollectionChangedAction.Add:
+ case NotifyCollectionChangedAction.Remove:
+ case NotifyCollectionChangedAction.Replace:
+ ReInitialzeSkinData();
+ goto default;
+ case NotifyCollectionChangedAction.Move:
+ break;
+ case NotifyCollectionChangedAction.Reset:
+ break;
+ default:
+ MakeCurrent();
+ UploadMeshData();
+ break;
}
}
- public void UpdateModelData()
- {
- ReInitialzeSkinData();
- }
-
private void AddCustomModelPart(SkinBOX skinBox)
{
- if (!additionalModelRenderGroups.ContainsKey(skinBox.Type))
+ if (!meshStorage.ContainsKey(skinBox.Type))
throw new KeyNotFoundException(skinBox.Type);
- CubeRenderGroup group = additionalModelRenderGroups[skinBox.Type];
- group.AddSkinBox(skinBox);
- group.Submit();
+ CubeBatchMesh cubeMesh = meshStorage[skinBox.Type];
+ cubeMesh.AddSkinBox(skinBox);
}
[Conditional("DEBUG")]
@@ -624,11 +625,11 @@ namespace PckStudio.Rendering
if (!IsHandleCreated)
return;
MakeCurrent();
+ {
framebuffer.Bind();
framebufferTexture.Bind();
- Size texSize = new Size(Size.Width, Size.Height);
- framebufferTexture.SetSize(texSize);
+ framebufferTexture.SetSize(Size);
framebufferTexture.Unbind();
int rbo = GL.GenRenderbuffer();
@@ -644,6 +645,8 @@ namespace PckStudio.Rendering
framebuffer.Unbind();
}
+ }
+
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
@@ -761,37 +764,6 @@ namespace PckStudio.Rendering
SwapBuffers();
}
- private void RenderBodyPart(Vector3 pivot, Vector3 translation, Matrix4 partMatrix, Matrix4 globalMatrix, params string[] additionalData)
- {
- foreach (var data in additionalData)
- {
- RenderPart(data, pivot, translation, partMatrix, globalMatrix);
- }
- }
-
- private void RenderPart(string name, Vector3 pivot, Vector3 translation, Matrix4 partMatrix, Matrix4 globalMatrix)
- {
- CubeRenderGroup renderGroup = additionalModelRenderGroups[name];
- float yOffset = GetOffset(name);
- translation.Y -= yOffset;
- pivot.Y += yOffset;
- renderGroup.Submit();
- RenderBuffer buffer = renderGroup.GetRenderBuffer();
- Matrix4 model = Pivot(translation, pivot, partMatrix);
- model *= globalMatrix;
- _skinShader.SetUniformMat4("u_Model", ref model);
- Renderer.Draw(_skinShader, buffer);
- }
-
- private static Matrix4 Pivot(Vector3 translation, Vector3 pivot, Matrix4 target)
- {
- var model = Matrix4.CreateTranslation(translation);
- model *= Matrix4.CreateTranslation(pivot);
- model *= target;
- model *= Matrix4.CreateTranslation(pivot).Inverted();
- return model;
- }
-
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
@@ -841,6 +813,40 @@ namespace PckStudio.Rendering
base.OnMouseUp(e);
}
+ private void RenderBodyPart(Vector3 pivot, Vector3 translation, Matrix4 partMatrix, Matrix4 globalMatrix, params string[] additionalData)
+ {
+ foreach (var data in additionalData)
+ {
+ RenderPart(data, pivot, translation, partMatrix, globalMatrix);
+ }
+ }
+
+ private void RenderPart(string name, Vector3 pivot, Vector3 translation, Matrix4 partMatrix, Matrix4 globalMatrix)
+ {
+ RenderPart(_skinShader, name, pivot, translation, partMatrix, globalMatrix);
+ }
+
+ private void RenderPart(ShaderProgram shader, string name, Vector3 pivot, Vector3 translation, Matrix4 partMatrix, Matrix4 globalMatrix)
+ {
+ CubeBatchMesh cubeMesh = meshStorage[name];
+ float yOffset = GetOffset(name);
+ translation.Y -= yOffset;
+ pivot.Y += yOffset;
+ Matrix4 model = Pivot(translation, pivot, partMatrix);
+ model *= globalMatrix;
+ _skinShader.SetUniformMat4("u_Model", ref model);
+ cubeMesh.Draw(shader);
+ }
+
+ private static Matrix4 Pivot(Vector3 translation, Vector3 pivot, Matrix4 target)
+ {
+ var model = Matrix4.CreateTranslation(translation);
+ model *= Matrix4.CreateTranslation(pivot);
+ model *= target;
+ model *= Matrix4.CreateTranslation(pivot).Inverted();
+ return model;
+ }
+
private void AnimationTick(object sender, EventArgs e)
{
skyboxRotation += skyboxRotationStep;
@@ -852,22 +858,29 @@ namespace PckStudio.Rendering
private void ReInitialzeSkinData()
{
- foreach (var renderGroup in additionalModelRenderGroups.Values)
+ foreach (var mesh in meshStorage.Values)
{
- renderGroup.Clear();
+ mesh.ClearData();
}
InitializeSkinData();
+ UpdateModelData();
+ OnANIMUpdate();
+ }
+
+ private void UpdateModelData()
+ {
foreach (var item in ModelData)
{
AddCustomModelPart(item);
}
- OnANIMUpdate();
}
private void reInitToolStripMenuItem_Click(object sender, EventArgs e)
{
ReInitialzeSkinData();
+ MakeCurrent();
+ UploadMeshData();
}
}
}
\ No newline at end of file