diff --git a/FinModelUtility/Fin/Fin.Ui/src/rendering/gl/AotWaveformRenderer.cs b/FinModelUtility/Fin/Fin.Ui/src/rendering/gl/AotWaveformRenderer.cs index 8b6fa994b..c8777f910 100644 --- a/FinModelUtility/Fin/Fin.Ui/src/rendering/gl/AotWaveformRenderer.cs +++ b/FinModelUtility/Fin/Fin.Ui/src/rendering/gl/AotWaveformRenderer.cs @@ -4,17 +4,18 @@ using fin.math; using fin.model; using fin.model.impl; +using fin.ui.rendering.gl.model; using OpenTK.Graphics.OpenGL; +using LogicOp = fin.model.LogicOp; using PrimitiveType = fin.model.PrimitiveType; namespace fin.ui.rendering.gl; public class AotWaveformRenderer { private IReadOnlyList vertices_; - private IDynamicGlBufferManager bufferManager_; - private IGlBufferRenderer bufferRenderer_; + private IDynamicModelRenderer renderer_; public IAotAudioPlayback? ActivePlayback { get; set; } @@ -29,14 +30,15 @@ public void Render() { if (this.vertices_ == null) { var model = ModelImpl.CreateForViewer(1000); + + var material = model.MaterialManager.AddColorMaterial(Color.Red); + var skin = model.Skin; this.vertices_ = skin.TypedVertices; + skin.AddMesh().AddLineStrip(this.vertices_).SetMaterial(material); - this.bufferManager_ = GlBufferManager.CreateDynamic(model); - this.bufferRenderer_ - = this.bufferManager_.CreateRenderer(PrimitiveType.LINE_STRIP, - this.vertices_); + this.renderer_ = ModelRendererV2.CreateDynamic(model); } var source = this.ActivePlayback.TypedSource; @@ -87,9 +89,11 @@ var baseSampleOffset floatMin + normalizedShortSample * (floatMax - floatMin); var x = i * xPerPoint; - var y = this.MiddleY + this.Amplitude * fraction * - MathF.Sign(floatSample) * - MathF.Pow(MathF.Abs(floatSample), .8f); + var y = this.MiddleY + + this.Amplitude * + fraction * + MathF.Sign(floatSample) * + MathF.Pow(MathF.Abs(floatSample), .8f); this.vertices_[i].SetLocalPosition(x, y, 0); } @@ -101,13 +105,8 @@ var baseSampleOffset } } - GlTransform.PassMatricesIntoGl(); - GL.LineWidth(1); - GlUtil.SetBlendColor(Color.Red); - GlUtil.SetBlending(BlendEquation.ADD, BlendFactor.CONST_COLOR, BlendFactor.SRC_ALPHA); - - this.bufferManager_.UpdateBuffer(); - this.bufferRenderer_.Render(); + this.renderer_.UpdateBuffer(); + this.renderer_.Render(); } } \ No newline at end of file diff --git a/FinModelUtility/Fin/Fin.Ui/src/rendering/gl/material/CommonShaderPrograms.cs b/FinModelUtility/Fin/Fin.Ui/src/rendering/gl/material/CommonShaderPrograms.cs deleted file mode 100644 index aebe2f2db..000000000 --- a/FinModelUtility/Fin/Fin.Ui/src/rendering/gl/material/CommonShaderPrograms.cs +++ /dev/null @@ -1,40 +0,0 @@ -using fin.shaders.glsl; - -namespace fin.ui.rendering.gl.material; - -public static class CommonShaderPrograms { - private static GlShaderProgram? texturelessShaderProgram_; - - public static GlShaderProgram TEXTURELESS_SHADER_PROGRAM { - get { - if (texturelessShaderProgram_ == null) { - texturelessShaderProgram_ = - GlShaderProgram.FromShaders( - """ - #version 120 - - varying vec4 vertexColor; - - void main() { - gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex; - vertexColor = gl_Color; - } - """, - $$""" - #version 130 - {{GlslConstants.FLOAT_PRECISION}} - - out vec4 fragColor; - - in vec4 vertexColor; - - void main() { - fragColor = vertexColor; - } - """); - } - - return texturelessShaderProgram_; - } - } -} \ No newline at end of file diff --git a/FinModelUtility/Fin/Fin.Ui/src/rendering/gl/model/IModelRenderer.cs b/FinModelUtility/Fin/Fin.Ui/src/rendering/gl/model/IModelRenderer.cs index 4141b59b8..8f0697276 100644 --- a/FinModelUtility/Fin/Fin.Ui/src/rendering/gl/model/IModelRenderer.cs +++ b/FinModelUtility/Fin/Fin.Ui/src/rendering/gl/model/IModelRenderer.cs @@ -5,4 +5,8 @@ namespace fin.ui.rendering.gl.model; public interface IModelRenderer : IRenderable, IDisposable { IReadOnlyModel Model { get; } IReadOnlySet? HiddenMeshes { get; set; } +} + +public interface IDynamicModelRenderer : IModelRenderer { + void UpdateBuffer(); } \ No newline at end of file diff --git a/FinModelUtility/Fin/Fin.Ui/src/rendering/gl/model/MergedMaterialAcrossMeshesRenderer.cs b/FinModelUtility/Fin/Fin.Ui/src/rendering/gl/model/MergedMaterialAcrossMeshesRenderer.cs deleted file mode 100644 index 6ef15ec2d..000000000 --- a/FinModelUtility/Fin/Fin.Ui/src/rendering/gl/model/MergedMaterialAcrossMeshesRenderer.cs +++ /dev/null @@ -1,130 +0,0 @@ -using fin.math; -using fin.model; -using fin.model.util; -using fin.util.image; - - -namespace fin.ui.rendering.gl.model; - -public class MergedMaterialAcrossMeshesRenderer : IModelRenderer { - private IGlBufferManager? bufferManager_; - private readonly IReadOnlyTextureTransformManager? textureTransformManager_; - private IReadOnlyMesh selectedMesh_; - - private (IReadOnlyMesh, MergedMaterialPrimitivesAcrossMeshesRenderer)[] - materialMeshRenderers_ = []; - - public MergedMaterialAcrossMeshesRenderer( - IReadOnlyModel model, - IReadOnlyTextureTransformManager? textureTransformManager = null) { - this.Model = model; - this.textureTransformManager_ = textureTransformManager; - - SelectedMeshService.OnMeshSelected += selectedMesh - => this.selectedMesh_ = selectedMesh; - } - - // Generates buffer manager and model within the current GL context. - private void GenerateModelIfNull_() { - if (this.bufferManager_ != null) { - return; - } - - this.bufferManager_ = GlBufferManager.CreateStatic(this.Model); - - var primitiveQueue = new PrimitiveRenderPriorityList(); - foreach (var mesh in this.Model.Skin.Meshes) { - foreach (var primitive in mesh.Primitives) { - primitiveQueue.Add(mesh, - primitive, - primitive.InversePriority, - primitive.Material?.TransparencyType ?? - TransparencyType.OPAQUE); - } - } - - var primitiveMerger = new PrimitiveMerger(); - var allMaterialMeshRenderers - = new List<(IReadOnlyMesh, MergedMaterialPrimitivesAcrossMeshesRenderer - )>(); - Action> - addMergedPrimitiveMesh = (mesh, material, primitives) => { - if (primitives.Count == 0) { - return; - } - - if (!primitiveMerger.TryToMergePrimitives( - primitives, - out var mergedPrimitives)) { - return; - } - - allMaterialMeshRenderers.Add( - (mesh, - new MergedMaterialPrimitivesAcrossMeshesRenderer( - this.textureTransformManager_, - this.bufferManager_, - this.Model, - material, - mergedPrimitives))); - }; - - IReadOnlyMesh? currentMesh = null; - IReadOnlyMaterial? currentMaterial = null; - var currentPrimitives = new List(); - foreach (var (mesh, primitive) in primitiveQueue) { - if (currentMesh != mesh || currentMaterial != primitive.Material) { - addMergedPrimitiveMesh(currentMesh!, - currentMaterial!, - currentPrimitives); - - currentMesh = mesh; - currentMaterial = primitive.Material; - currentPrimitives.Clear(); - } - - currentPrimitives.Add(primitive); - } - - addMergedPrimitiveMesh(currentMesh!, currentMaterial!, currentPrimitives); - - this.materialMeshRenderers_ = allMaterialMeshRenderers.ToArray(); - } - - ~MergedMaterialAcrossMeshesRenderer() => this.ReleaseUnmanagedResources_(); - - public void Dispose() { - this.ReleaseUnmanagedResources_(); - GC.SuppressFinalize(this); - } - - private void ReleaseUnmanagedResources_() { - foreach (var (_, materialMeshRenderer) in this.materialMeshRenderers_) { - materialMeshRenderer.Dispose(); - } - - this.bufferManager_?.Dispose(); - } - - public IReadOnlyModel Model { get; } - - public IReadOnlySet? HiddenMeshes { get; set; } - - public void Render() { - this.GenerateModelIfNull_(); - - foreach (var (mesh, materialMeshRenderer) in this.materialMeshRenderers_) { - if (this.HiddenMeshes?.Contains(mesh) ?? false) { - continue; - } - - var isSelected = this.selectedMesh_ == mesh; - - materialMeshRenderer.Render(); - - if (isSelected) { - GlUtil.RenderHighlight(materialMeshRenderer.Render); - } - } - } -} \ No newline at end of file diff --git a/FinModelUtility/Fin/Fin.Ui/src/rendering/gl/model/MergedMaterialByMeshRenderer.cs b/FinModelUtility/Fin/Fin.Ui/src/rendering/gl/model/MergedMaterialByMeshRenderer.cs index 8b45aeb69..9ade75e06 100644 --- a/FinModelUtility/Fin/Fin.Ui/src/rendering/gl/model/MergedMaterialByMeshRenderer.cs +++ b/FinModelUtility/Fin/Fin.Ui/src/rendering/gl/model/MergedMaterialByMeshRenderer.cs @@ -7,131 +7,145 @@ namespace fin.ui.rendering.gl.model; -public class MergedMaterialByMeshRenderer : IModelRenderer { - private IGlBufferManager? bufferManager_; - private readonly IReadOnlyTextureTransformManager? textureTransformManager_; - private IReadOnlyMesh selectedMesh_; - - private (IReadOnlyMesh, MergedMaterialPrimitivesByMeshRenderer[])[] - materialMeshRenderers_ = []; - - public MergedMaterialByMeshRenderer( - IReadOnlyModel model, - IReadOnlyTextureTransformManager? textureTransformManager = null) { - this.Model = model; - this.textureTransformManager_ = textureTransformManager; - - SelectedMeshService.OnMeshSelected += selectedMesh - => this.selectedMesh_ = selectedMesh; - } - - // Generates buffer manager and model within the current GL context. - private void GenerateModelIfNull_() { - if (this.bufferManager_ != null) { - return; +public partial class ModelRendererV2 { + private class MergedMaterialByMeshRenderer : IDynamicModelRenderer { + private readonly bool dynamic_; + private readonly IReadOnlyTextureTransformManager? textureTransformManager_; + + private IGlBufferManager? bufferManager_; + private IDynamicGlBufferManager? dynamicBufferManager_; + private IReadOnlyMesh selectedMesh_; + + private (IReadOnlyMesh, MergedMaterialPrimitivesByMeshRenderer[])[] + materialMeshRenderers_ = []; + + public MergedMaterialByMeshRenderer( + IReadOnlyModel model, + IReadOnlyTextureTransformManager? textureTransformManager = null, + bool dynamic = false) { + this.Model = model; + this.textureTransformManager_ = textureTransformManager; + this.dynamic_ = dynamic; + + SelectedMeshService.OnMeshSelected += selectedMesh + => this.selectedMesh_ = selectedMesh; } - this.bufferManager_ = GlBufferManager.CreateStatic(this.Model); - - var allMaterialMeshRenderers = - new List<(IReadOnlyMesh, MergedMaterialPrimitivesByMeshRenderer[])>(); + // Generates buffer manager and model within the current GL context. + private void GenerateModelIfNull_() { + if (this.bufferManager_ != null) { + return; + } - // TODO: Optimize this with something like a "MinMap"? - var meshQueue = new RenderPriorityOrderedSet(); - foreach (var mesh in this.Model.Skin.Meshes) { - foreach (var primitive in mesh.Primitives) { - meshQueue.Add(mesh, - primitive.InversePriority, - (primitive.Material?.TransparencyType ?? - TransparencyType.OPAQUE) == - TransparencyType.TRANSPARENT); + if (!this.dynamic_) { + this.bufferManager_ = GlBufferManager.CreateStatic(this.Model); + } else { + this.bufferManager_ = this.dynamicBufferManager_ + = GlBufferManager.CreateDynamic(this.Model); } - } - var primitiveMerger = new PrimitiveMerger(); - foreach (var mesh in meshQueue) { - var materialQueue = new RenderPriorityOrderedSet(); - var primitivesByMaterial - = new ListDictionary( - new NullFriendlyDictionary>()); - foreach (var primitive in mesh.Primitives) { - primitivesByMaterial.Add(primitive.Material, primitive); - materialQueue.Add( - primitive.Material, - primitive.InversePriority, - (primitive.Material?.TransparencyType ?? - TransparencyType.OPAQUE) == - TransparencyType.TRANSPARENT); + var allMaterialMeshRenderers = + new List<(IReadOnlyMesh, MergedMaterialPrimitivesByMeshRenderer[])>(); + + // TODO: Optimize this with something like a "MinMap"? + var meshQueue = new RenderPriorityOrderedSet(); + foreach (var mesh in this.Model.Skin.Meshes) { + foreach (var primitive in mesh.Primitives) { + meshQueue.Add(mesh, + primitive.InversePriority, + (primitive.Material?.TransparencyType ?? + TransparencyType.OPAQUE) == + TransparencyType.TRANSPARENT); + } } - var materialMeshRenderers = - new ListDictionary(); - foreach (var material in materialQueue) { - var primitives = primitivesByMaterial[material]; - if (!primitiveMerger.TryToMergePrimitives( - primitives, - out var mergedPrimitives)) { - continue; + var primitiveMerger = new PrimitiveMerger(); + foreach (var mesh in meshQueue) { + var materialQueue = new RenderPriorityOrderedSet(); + var primitivesByMaterial + = new ListDictionary( + new NullFriendlyDictionary>()); + foreach (var primitive in mesh.Primitives) { + primitivesByMaterial.Add(primitive.Material, primitive); + materialQueue.Add( + primitive.Material, + primitive.InversePriority, + (primitive.Material?.TransparencyType ?? + TransparencyType.OPAQUE) == + TransparencyType.TRANSPARENT); } - materialMeshRenderers.Add( - mesh, - new MergedMaterialPrimitivesByMeshRenderer( - this.textureTransformManager_, - this.bufferManager_, - this.Model, - material, - mergedPrimitives)); + var materialMeshRenderers = + new ListDictionary(); + foreach (var material in materialQueue) { + var primitives = primitivesByMaterial[material]; + if (!primitiveMerger.TryToMergePrimitives( + primitives, + out var mergedPrimitives)) { + continue; + } + + materialMeshRenderers.Add( + mesh, + new MergedMaterialPrimitivesByMeshRenderer( + this.textureTransformManager_, + this.bufferManager_, + this.Model, + material, + mergedPrimitives)); + } + + allMaterialMeshRenderers.AddRange( + materialMeshRenderers + .GetPairs() + .Select(tuple => (tuple.key, tuple.value.ToArray()))); } - allMaterialMeshRenderers.AddRange( - materialMeshRenderers - .GetPairs() - .Select(tuple => (tuple.key, tuple.value.ToArray()))); + this.materialMeshRenderers_ = allMaterialMeshRenderers.ToArray(); } - this.materialMeshRenderers_ = allMaterialMeshRenderers.ToArray(); - } + ~MergedMaterialByMeshRenderer() => this.ReleaseUnmanagedResources_(); - ~MergedMaterialByMeshRenderer() => this.ReleaseUnmanagedResources_(); - - public void Dispose() { - this.ReleaseUnmanagedResources_(); - GC.SuppressFinalize(this); - } + public void Dispose() { + this.ReleaseUnmanagedResources_(); + GC.SuppressFinalize(this); + } - private void ReleaseUnmanagedResources_() { - foreach (var (_, materialMeshRenderers) in this.materialMeshRenderers_) { - foreach (var materialMeshRenderer in materialMeshRenderers) { - materialMeshRenderer.Dispose(); + private void ReleaseUnmanagedResources_() { + foreach (var (_, materialMeshRenderers) in this.materialMeshRenderers_) { + foreach (var materialMeshRenderer in materialMeshRenderers) { + materialMeshRenderer.Dispose(); + } } + + this.bufferManager_?.Dispose(); } - this.bufferManager_?.Dispose(); - } + public IReadOnlyModel Model { get; } - public IReadOnlyModel Model { get; } + public IReadOnlySet? HiddenMeshes { get; set; } - public IReadOnlySet? HiddenMeshes { get; set; } + public void UpdateBuffer() => this.dynamicBufferManager_?.UpdateBuffer(); - public void Render() { - this.GenerateModelIfNull_(); + public void Render() { + this.GenerateModelIfNull_(); - foreach (var (mesh, materialMeshRenderers) in - this.materialMeshRenderers_) { - if (this.HiddenMeshes?.Contains(mesh) ?? false) { - continue; - } + foreach (var (mesh, materialMeshRenderers) in + this.materialMeshRenderers_) { + if (this.HiddenMeshes?.Contains(mesh) ?? false) { + continue; + } - foreach (var materialMeshRenderer in materialMeshRenderers) { - var isSelected = this.selectedMesh_ == mesh; + foreach (var materialMeshRenderer in materialMeshRenderers) { + var isSelected = this.selectedMesh_ == mesh; - materialMeshRenderer.Render(); + materialMeshRenderer.Render(); - if (isSelected) { - GlUtil.RenderHighlight(materialMeshRenderer.Render); + if (isSelected) { + GlUtil.RenderHighlight(materialMeshRenderer.Render); + } } } } diff --git a/FinModelUtility/Fin/Fin.Ui/src/rendering/gl/model/MergedMaterialPrimitivesAcrossMeshesRenderer.cs b/FinModelUtility/Fin/Fin.Ui/src/rendering/gl/model/MergedMaterialPrimitivesAcrossMeshesRenderer.cs index da5ddeed2..912ead886 100644 --- a/FinModelUtility/Fin/Fin.Ui/src/rendering/gl/model/MergedMaterialPrimitivesAcrossMeshesRenderer.cs +++ b/FinModelUtility/Fin/Fin.Ui/src/rendering/gl/model/MergedMaterialPrimitivesAcrossMeshesRenderer.cs @@ -4,79 +4,81 @@ namespace fin.ui.rendering.gl.model; -public class MergedMaterialPrimitivesAcrossMeshesRenderer : IDisposable { - private readonly IGlBufferRenderer bufferRenderer_; - private readonly IReadOnlyMaterial? material_; - private readonly IGlMaterialShader? materialShader_; - private bool isSelected_; +public partial class ModelRendererV2 { + private class MergedMaterialPrimitivesAcrossMeshesRenderer : IDisposable { + private readonly IGlBufferRenderer bufferRenderer_; + private readonly IReadOnlyMaterial? material_; + private readonly IGlMaterialShader? materialShader_; + private bool isSelected_; - public MergedMaterialPrimitivesAcrossMeshesRenderer( - IReadOnlyTextureTransformManager? textureTransformManager, - IGlBufferManager bufferManager, - IReadOnlyModel model, - IReadOnlyMaterial? material, - MergedPrimitive mergedPrimitive) { - this.material_ = material; + public MergedMaterialPrimitivesAcrossMeshesRenderer( + IReadOnlyTextureTransformManager? textureTransformManager, + IGlBufferManager bufferManager, + IReadOnlyModel model, + IReadOnlyMaterial? material, + MergedPrimitive mergedPrimitive) { + this.material_ = material; - this.materialShader_ = GlMaterialShader.FromMaterial(model, - material, - textureTransformManager); + this.materialShader_ = GlMaterialShader.FromMaterial(model, + material, + textureTransformManager); - this.bufferRenderer_ = bufferManager.CreateRenderer(mergedPrimitive); + this.bufferRenderer_ = bufferManager.CreateRenderer(mergedPrimitive); - SelectedMaterialsService.OnMaterialsSelected - += selectedMaterials => - this.isSelected_ = this.material_ != null && - (selectedMaterials?.Contains(this.material_) ?? - false); - } + SelectedMaterialsService.OnMaterialsSelected + += selectedMaterials => + this.isSelected_ = this.material_ != null && + (selectedMaterials?.Contains(this.material_) ?? + false); + } - ~MergedMaterialPrimitivesAcrossMeshesRenderer() - => this.ReleaseUnmanagedResources_(); + ~MergedMaterialPrimitivesAcrossMeshesRenderer() + => this.ReleaseUnmanagedResources_(); - public void Dispose() { - this.ReleaseUnmanagedResources_(); - GC.SuppressFinalize(this); - } + public void Dispose() { + this.ReleaseUnmanagedResources_(); + GC.SuppressFinalize(this); + } - private void ReleaseUnmanagedResources_() { - this.materialShader_?.Dispose(); - this.bufferRenderer_.Dispose(); - } + private void ReleaseUnmanagedResources_() { + this.materialShader_?.Dispose(); + this.bufferRenderer_.Dispose(); + } - public void Render() { - this.RenderImpl_(); + public void Render() { + this.RenderImpl_(); - if (this.isSelected_) { - GlUtil.RenderHighlight(this.RenderImpl_); + if (this.isSelected_) { + GlUtil.RenderHighlight(this.RenderImpl_); + } } - } - private void RenderImpl_() { - this.materialShader_?.Use(); + private void RenderImpl_() { + this.materialShader_?.Use(); - if (this.material_ is IReadOnlyFixedFunctionMaterial - fixedFunctionMaterial) { - GlUtil.SetBlendingSeparate( - fixedFunctionMaterial.ColorBlendEquation, - fixedFunctionMaterial.ColorSrcFactor, - fixedFunctionMaterial.ColorDstFactor, - fixedFunctionMaterial.AlphaBlendEquation, - fixedFunctionMaterial.AlphaSrcFactor, - fixedFunctionMaterial.AlphaDstFactor, - fixedFunctionMaterial.LogicOp); - } else { - GlUtil.ResetBlending(); - } + if (this.material_ is IReadOnlyFixedFunctionMaterial + fixedFunctionMaterial) { + GlUtil.SetBlendingSeparate( + fixedFunctionMaterial.ColorBlendEquation, + fixedFunctionMaterial.ColorSrcFactor, + fixedFunctionMaterial.ColorDstFactor, + fixedFunctionMaterial.AlphaBlendEquation, + fixedFunctionMaterial.AlphaSrcFactor, + fixedFunctionMaterial.AlphaDstFactor, + fixedFunctionMaterial.LogicOp); + } else { + GlUtil.ResetBlending(); + } - GlUtil.SetCulling(this.material_?.CullingMode ?? CullingMode.SHOW_BOTH); - GlUtil.SetDepth( - this.material_?.DepthMode ?? DepthMode.READ_AND_WRITE, - this.material_?.DepthCompareType ?? - DepthCompareType.LEqual); - GlUtil.SetChannelUpdateMask(this.material_?.UpdateColorChannel ?? true, - this.material_?.UpdateAlphaChannel ?? true); + GlUtil.SetCulling(this.material_?.CullingMode ?? CullingMode.SHOW_BOTH); + GlUtil.SetDepth( + this.material_?.DepthMode ?? DepthMode.READ_AND_WRITE, + this.material_?.DepthCompareType ?? + DepthCompareType.LEqual); + GlUtil.SetChannelUpdateMask(this.material_?.UpdateColorChannel ?? true, + this.material_?.UpdateAlphaChannel ?? true); - this.bufferRenderer_.Render(); + this.bufferRenderer_.Render(); + } } } \ No newline at end of file diff --git a/FinModelUtility/Fin/Fin.Ui/src/rendering/gl/model/MergedMaterialPrimitivesByMeshRenderer.cs b/FinModelUtility/Fin/Fin.Ui/src/rendering/gl/model/MergedMaterialPrimitivesByMeshRenderer.cs index 4bb9ba9d8..f6fd2dcd4 100644 --- a/FinModelUtility/Fin/Fin.Ui/src/rendering/gl/model/MergedMaterialPrimitivesByMeshRenderer.cs +++ b/FinModelUtility/Fin/Fin.Ui/src/rendering/gl/model/MergedMaterialPrimitivesByMeshRenderer.cs @@ -4,85 +4,88 @@ namespace fin.ui.rendering.gl.model; -public class MergedMaterialPrimitivesByMeshRenderer : IDisposable { - private readonly IGlBufferRenderer bufferRenderer_; - private readonly IReadOnlyMaterial? material_; - private readonly IGlMaterialShader? materialShader_; - private bool isSelected_; - - public MergedMaterialPrimitivesByMeshRenderer( - IReadOnlyTextureTransformManager? textureTransformManager, - IGlBufferManager bufferManager, - IReadOnlyModel model, - IReadOnlyMaterial? material, - MergedPrimitive mergedPrimitive) { - this.material_ = material; - - this.materialShader_ = GlMaterialShader.FromMaterial(model, - material, - textureTransformManager); - - this.bufferRenderer_ = bufferManager.CreateRenderer(mergedPrimitive); - - SelectedMaterialsService.OnMaterialsSelected - += selectedMaterials => - this.isSelected_ = this.material_ != null && - (selectedMaterials?.Contains(this.material_) ?? - false); - } +public partial class ModelRendererV2 { + private class MergedMaterialPrimitivesByMeshRenderer : IDisposable { + private readonly IGlBufferRenderer bufferRenderer_; + private readonly IReadOnlyMaterial? material_; + private readonly IGlMaterialShader? materialShader_; + private bool isSelected_; + + public MergedMaterialPrimitivesByMeshRenderer( + IReadOnlyTextureTransformManager? textureTransformManager, + IGlBufferManager bufferManager, + IReadOnlyModel model, + IReadOnlyMaterial? material, + MergedPrimitive mergedPrimitive) { + this.material_ = material; + + this.materialShader_ = GlMaterialShader.FromMaterial(model, + material, + textureTransformManager); + + this.bufferRenderer_ = bufferManager.CreateRenderer(mergedPrimitive); + + SelectedMaterialsService.OnMaterialsSelected + += selectedMaterials => + this.isSelected_ = this.material_ != null && + (selectedMaterials?.Contains(this.material_) ?? + false); + } - ~MergedMaterialPrimitivesByMeshRenderer() => this.ReleaseUnmanagedResources_(); + ~MergedMaterialPrimitivesByMeshRenderer() + => this.ReleaseUnmanagedResources_(); - public void Dispose() { - this.ReleaseUnmanagedResources_(); - GC.SuppressFinalize(this); - } + public void Dispose() { + this.ReleaseUnmanagedResources_(); + GC.SuppressFinalize(this); + } - private void ReleaseUnmanagedResources_() { - this.materialShader_?.Dispose(); - this.bufferRenderer_.Dispose(); - } + private void ReleaseUnmanagedResources_() { + this.materialShader_?.Dispose(); + this.bufferRenderer_.Dispose(); + } - public bool UseLighting { - get => this.materialShader_?.UseLighting ?? false; - set { - if (this.materialShader_ != null) { - this.materialShader_.UseLighting = value; + public bool UseLighting { + get => this.materialShader_?.UseLighting ?? false; + set { + if (this.materialShader_ != null) { + this.materialShader_.UseLighting = value; + } } } - } - public void Render() { - this.RenderImpl_(); + public void Render() { + this.RenderImpl_(); - if (this.isSelected_) { - GlUtil.RenderHighlight(this.RenderImpl_); + if (this.isSelected_) { + GlUtil.RenderHighlight(this.RenderImpl_); + } } - } - private void RenderImpl_() { - this.materialShader_?.Use(); - - if (this.material_ != null) { - GlUtil.SetBlendingSeparate(this.material_.ColorBlendEquation, - this.material_.ColorSrcFactor, - this.material_.ColorDstFactor, - this.material_.AlphaBlendEquation, - this.material_.AlphaSrcFactor, - this.material_.AlphaDstFactor, - this.material_.LogicOp); - } else { - GlUtil.ResetBlending(); - } + private void RenderImpl_() { + this.materialShader_?.Use(); + + if (this.material_ != null) { + GlUtil.SetBlendingSeparate(this.material_.ColorBlendEquation, + this.material_.ColorSrcFactor, + this.material_.ColorDstFactor, + this.material_.AlphaBlendEquation, + this.material_.AlphaSrcFactor, + this.material_.AlphaDstFactor, + this.material_.LogicOp); + } else { + GlUtil.ResetBlending(); + } - GlUtil.SetCulling(this.material_?.CullingMode ?? CullingMode.SHOW_BOTH); - GlUtil.SetDepth( - this.material_?.DepthMode ?? DepthMode.READ_AND_WRITE, - this.material_?.DepthCompareType ?? - DepthCompareType.LEqual); - GlUtil.SetChannelUpdateMask(this.material_?.UpdateColorChannel ?? true, - this.material_?.UpdateAlphaChannel ?? true); + GlUtil.SetCulling(this.material_?.CullingMode ?? CullingMode.SHOW_BOTH); + GlUtil.SetDepth( + this.material_?.DepthMode ?? DepthMode.READ_AND_WRITE, + this.material_?.DepthCompareType ?? + DepthCompareType.LEqual); + GlUtil.SetChannelUpdateMask(this.material_?.UpdateColorChannel ?? true, + this.material_?.UpdateAlphaChannel ?? true); - this.bufferRenderer_.Render(); + this.bufferRenderer_.Render(); + } } } \ No newline at end of file diff --git a/FinModelUtility/Fin/Fin.Ui/src/rendering/gl/model/ModelRendererV2.cs b/FinModelUtility/Fin/Fin.Ui/src/rendering/gl/model/ModelRendererV2.cs index a3c6e6205..ec1e4d945 100644 --- a/FinModelUtility/Fin/Fin.Ui/src/rendering/gl/model/ModelRendererV2.cs +++ b/FinModelUtility/Fin/Fin.Ui/src/rendering/gl/model/ModelRendererV2.cs @@ -12,18 +12,54 @@ namespace fin.ui.rendering.gl.model; /// /// NOTE: This will only be valid in the GL context this was first rendered in! /// -public class ModelRendererV2( - IReadOnlyModel model, - IReadOnlyLighting? lighting = null, - IReadOnlyBoneTransformManager? boneTransformManager = null, - IReadOnlyTextureTransformManager? textureTransformManager = null) - : IModelRenderer { - // TODO: Require passing in a GL context in the constructor. - - private readonly IModelRenderer impl_ - = (model.Skin.AllowMaterialRendererMerging) - ? new MergedMaterialByMeshRenderer(model, textureTransformManager) - : new UnmergedMaterialMeshesRenderer(model, textureTransformManager); +public partial class ModelRendererV2 : IDynamicModelRenderer { + private readonly IReadOnlyModel model_; + private readonly IDynamicModelRenderer impl_; + private readonly IReadOnlyLighting lighting_; + private readonly IReadOnlyBoneTransformManager boneTransformManager_; + + public static IModelRenderer CreateStatic( + IReadOnlyModel model, + IReadOnlyLighting? lighting = null, + IReadOnlyBoneTransformManager? boneTransformManager = null, + IReadOnlyTextureTransformManager? textureTransformManager = null) + => new ModelRendererV2(model, + lighting, + boneTransformManager, + textureTransformManager); + + public static IDynamicModelRenderer CreateDynamic( + IReadOnlyModel model, + IReadOnlyLighting? lighting = null, + IReadOnlyBoneTransformManager? boneTransformManager = null, + IReadOnlyTextureTransformManager? textureTransformManager = null) + => new ModelRendererV2(model, + lighting, + boneTransformManager, + textureTransformManager, + true); + + public ModelRendererV2( + IReadOnlyModel model, + IReadOnlyLighting? lighting = null, + IReadOnlyBoneTransformManager? boneTransformManager = null, + IReadOnlyTextureTransformManager? textureTransformManager = null, + bool dynamic = false) { + this.model_ = model; + this.lighting_ = lighting; + this.boneTransformManager_ = boneTransformManager; + + this.impl_ + = (model.Skin.AllowMaterialRendererMerging) + ? new MergedMaterialByMeshRenderer(model, + textureTransformManager, + dynamic) + : new UnmergedMaterialMeshesRenderer( + model, + textureTransformManager, + dynamic); + } + private MatricesUbo? matricesUbo_; private LightsUbo? lightsUbo_; @@ -50,23 +86,25 @@ public IReadOnlySet? HiddenMeshes { public bool UseLighting { get; set; } + public void UpdateBuffer() => this.impl_.UpdateBuffer(); + public void Render() { - var bonesUsedByVertices = model.Skin.BonesUsedByVertices; + var bonesUsedByVertices = this.model_.Skin.BonesUsedByVertices; Span boneMatrices = stackalloc Matrix4x4[1 + bonesUsedByVertices.Count]; boneMatrices[0] = Matrix4x4.Identity; var boneIndex = 1; foreach (var bone in bonesUsedByVertices) { var localToWorldMatrix = - boneTransformManager?.GetLocalToWorldMatrix(bone).Impl ?? + this.boneTransformManager_?.GetLocalToWorldMatrix(bone).Impl ?? Matrix4x4.Identity; var inverseMatrix = - boneTransformManager?.GetInverseBindMatrix(bone).Impl ?? + this.boneTransformManager_?.GetInverseBindMatrix(bone).Impl ?? Matrix4x4.Identity; boneMatrices[boneIndex++] = inverseMatrix * localToWorldMatrix; } - this.matricesUbo_ ??= new(model.Skin.BonesUsedByVertices.Count); + this.matricesUbo_ ??= new(this.model_.Skin.BonesUsedByVertices.Count); this.lightsUbo_ ??= new LightsUbo(); this.matricesUbo_.UpdateData(GlTransform.ModelMatrix, @@ -75,7 +113,7 @@ Span boneMatrices boneMatrices); this.matricesUbo_.Bind(); - this.lightsUbo_.UpdateData(this.UseLighting, lighting); + this.lightsUbo_.UpdateData(this.UseLighting, this.lighting_); this.lightsUbo_.Bind(); this.impl_.Render(); diff --git a/FinModelUtility/Fin/Fin.Ui/src/rendering/gl/model/UnmergedMaterialMeshesRenderer.cs b/FinModelUtility/Fin/Fin.Ui/src/rendering/gl/model/UnmergedMaterialMeshesRenderer.cs index 0b0f4f6d4..a943eac49 100644 --- a/FinModelUtility/Fin/Fin.Ui/src/rendering/gl/model/UnmergedMaterialMeshesRenderer.cs +++ b/FinModelUtility/Fin/Fin.Ui/src/rendering/gl/model/UnmergedMaterialMeshesRenderer.cs @@ -3,104 +3,116 @@ namespace fin.ui.rendering.gl.model; -public class UnmergedMaterialMeshesRenderer( - IReadOnlyModel model, - IReadOnlyTextureTransformManager? textureTransformManager = null) - : IModelRenderer { - private IGlBufferManager? bufferManager_; - - private readonly - List<(IReadOnlyMesh, List)> - materialMeshRenderers_ = new(); - - // Generates buffer manager and model within the current GL context. - private void GenerateModelIfNull_() { - if (this.bufferManager_ != null) { - return; - } +public partial class ModelRendererV2 { + private class UnmergedMaterialMeshesRenderer( + IReadOnlyModel model, + IReadOnlyTextureTransformManager? textureTransformManager = null, + bool dynamic = false) + : IDynamicModelRenderer { + private IGlBufferManager? bufferManager_; + private IDynamicGlBufferManager? dynamicBufferManager_; + + private readonly + List<(IReadOnlyMesh, List)> + materialMeshRenderers_ = new(); + + // Generates buffer manager and model within the current GL context. + private void GenerateModelIfNull_() { + if (this.bufferManager_ != null) { + return; + } + + if (!dynamic) { + this.bufferManager_ = GlBufferManager.CreateStatic(this.Model); + } else { + this.bufferManager_ = this.dynamicBufferManager_ + = GlBufferManager.CreateDynamic(this.Model); + } - this.bufferManager_ = GlBufferManager.CreateStatic(this.Model); - - List currentList = null; - var primitiveMerger = new PrimitiveMerger(); - Action> - addPrimitivesRenderer = - (mesh, material, primitives) => { - if (primitiveMerger.TryToMergePrimitives( - primitives - .OrderBy(primitive => primitive.InversePriority) - .ToList(), - out var mergedPrimitive)) { - - currentList.Add(new MergedMaterialPrimitivesByMeshRenderer( - textureTransformManager, - this.bufferManager_, - this.Model, - material, - mergedPrimitive)); - } - }; - - foreach (var mesh in this.Model.Skin.Meshes) { - currentList = new List(); - this.materialMeshRenderers_.Add((mesh, currentList)); - - IReadOnlyMaterial? currentMaterial = null; - var currentPrimitives = new LinkedList(); - - foreach (var primitive in mesh.Primitives) { - var material = primitive.Material; - - if (currentMaterial != material) { - if (currentPrimitives.Count > 0) { - addPrimitivesRenderer(mesh, currentMaterial, currentPrimitives); - currentPrimitives.Clear(); + List currentList = null; + var primitiveMerger = new PrimitiveMerger(); + Action> + addPrimitivesRenderer = + (mesh, material, primitives) => { + if (primitiveMerger.TryToMergePrimitives( + primitives + .OrderBy(primitive => primitive.InversePriority) + .ToList(), + out var mergedPrimitive)) { + + currentList.Add(new MergedMaterialPrimitivesByMeshRenderer( + textureTransformManager, + this.bufferManager_, + this.Model, + material, + mergedPrimitive)); + } + }; + + foreach (var mesh in this.Model.Skin.Meshes) { + currentList = new List(); + this.materialMeshRenderers_.Add((mesh, currentList)); + + IReadOnlyMaterial? currentMaterial = null; + var currentPrimitives = new LinkedList(); + + foreach (var primitive in mesh.Primitives) { + var material = primitive.Material; + + if (currentMaterial != material) { + if (currentPrimitives.Count > 0) { + addPrimitivesRenderer(mesh, currentMaterial, currentPrimitives); + currentPrimitives.Clear(); + } + + currentMaterial = material; } - currentMaterial = material; + currentPrimitives.AddLast(primitive); } - currentPrimitives.AddLast(primitive); - } - - if (currentPrimitives.Count > 0) { - addPrimitivesRenderer(mesh, currentMaterial, currentPrimitives); + if (currentPrimitives.Count > 0) { + addPrimitivesRenderer(mesh, currentMaterial, currentPrimitives); + } } } - } - ~UnmergedMaterialMeshesRenderer() => this.ReleaseUnmanagedResources_(); + ~UnmergedMaterialMeshesRenderer() => this.ReleaseUnmanagedResources_(); - public void Dispose() { - this.ReleaseUnmanagedResources_(); - GC.SuppressFinalize(this); - } + public void Dispose() { + this.ReleaseUnmanagedResources_(); + GC.SuppressFinalize(this); + } - private void ReleaseUnmanagedResources_() { - foreach (var (_, materialMeshRenderers) in this.materialMeshRenderers_) { - foreach (var materialMeshRenderer in materialMeshRenderers) { - materialMeshRenderer.Dispose(); + private void ReleaseUnmanagedResources_() { + foreach (var (_, materialMeshRenderers) in this.materialMeshRenderers_) { + foreach (var materialMeshRenderer in materialMeshRenderers) { + materialMeshRenderer.Dispose(); + } } + + this.materialMeshRenderers_.Clear(); + this.bufferManager_?.Dispose(); } - this.materialMeshRenderers_.Clear(); - this.bufferManager_?.Dispose(); - } + public IReadOnlyModel Model { get; } = model; - public IReadOnlyModel Model { get; } = model; + public IReadOnlySet? HiddenMeshes { get; set; } - public IReadOnlySet? HiddenMeshes { get; set; } + public void UpdateBuffer() => this.dynamicBufferManager_?.UpdateBuffer(); - public void Render() { - this.GenerateModelIfNull_(); + public void Render() { + this.GenerateModelIfNull_(); - foreach (var (mesh, materialMeshRenderers) in this.materialMeshRenderers_) { - if (this.HiddenMeshes?.Contains(mesh) ?? false) { - continue; - } + foreach (var (mesh, materialMeshRenderers) in + this.materialMeshRenderers_) { + if (this.HiddenMeshes?.Contains(mesh) ?? false) { + continue; + } - foreach (var materialMeshRenderer in materialMeshRenderers) { - materialMeshRenderer.Render(); + foreach (var materialMeshRenderer in materialMeshRenderers) { + materialMeshRenderer.Render(); + } } } } diff --git a/FinModelUtility/UniversalAssetTool/UniversalAssetTool.Ui.Avalonia/resources/audio/AudioWaveformGlPanel.cs b/FinModelUtility/UniversalAssetTool/UniversalAssetTool.Ui.Avalonia/resources/audio/AudioWaveformGlPanel.cs index 0cd217c4d..c6bbecee9 100644 --- a/FinModelUtility/UniversalAssetTool/UniversalAssetTool.Ui.Avalonia/resources/audio/AudioWaveformGlPanel.cs +++ b/FinModelUtility/UniversalAssetTool/UniversalAssetTool.Ui.Avalonia/resources/audio/AudioWaveformGlPanel.cs @@ -49,8 +49,6 @@ protected override void RenderGl() { GlTransform.LoadIdentity(); } - CommonShaderPrograms.TEXTURELESS_SHADER_PROGRAM.Use(); - var amplitude = height * .45f; this.waveformRenderer_.Width = width; this.waveformRenderer_.Amplitude = amplitude; diff --git a/FinModelUtility/UniversalAssetTool/UniversalAssetTool.Ui/src/winforms/common/audio/AudioPlayerGlPanel.cs b/FinModelUtility/UniversalAssetTool/UniversalAssetTool.Ui/src/winforms/common/audio/AudioPlayerGlPanel.cs index 2ba0ee974..09a942298 100644 --- a/FinModelUtility/UniversalAssetTool/UniversalAssetTool.Ui/src/winforms/common/audio/AudioPlayerGlPanel.cs +++ b/FinModelUtility/UniversalAssetTool/UniversalAssetTool.Ui/src/winforms/common/audio/AudioPlayerGlPanel.cs @@ -97,7 +97,6 @@ protected override void RenderGl() { GlUtil.ClearColorAndDepth(); - CommonShaderPrograms.TEXTURELESS_SHADER_PROGRAM.Use(); this.RenderOrtho_(); }