From 29983c23e36faab24d000f29f18a3fe5d32199ff Mon Sep 17 00:00:00 2001 From: 4sval Date: Wed, 7 Sep 2022 22:44:42 +0200 Subject: [PATCH] finally what I was looking for --- FModel/Resources/outline.frag | 2 +- FModel/Resources/outline.vert | 3 +- FModel/Views/Snooper/Camera.cs | 4 +- FModel/Views/Snooper/FramebufferObject.cs | 5 +-- FModel/Views/Snooper/Grid.cs | 6 +-- FModel/Views/Snooper/Model.cs | 46 ++++++++++++++--------- FModel/Views/Snooper/SnimGui.cs | 28 ++++++++------ FModel/Views/Snooper/Snooper.cs | 13 +++++-- 8 files changed, 64 insertions(+), 43 deletions(-) diff --git a/FModel/Resources/outline.frag b/FModel/Resources/outline.frag index 26817aa5..5759ca56 100644 --- a/FModel/Resources/outline.frag +++ b/FModel/Resources/outline.frag @@ -4,5 +4,5 @@ out vec4 FragColor; void main() { - FragColor = vec4(0.929, 0.588, 0.196, 0.2); + FragColor = vec4(0.929, 0.588, 0.196, 1.0); } diff --git a/FModel/Resources/outline.vert b/FModel/Resources/outline.vert index 0d2d8acc..de1087a5 100644 --- a/FModel/Resources/outline.vert +++ b/FModel/Resources/outline.vert @@ -6,10 +6,11 @@ layout (location = 6) in mat4 vInstanceMatrix; uniform mat4 uView; uniform mat4 uProjection; +uniform vec3 viewPos; void main() { - float scaleFactor = 0.005; + float scaleFactor = distance(vPos, viewPos) * 0.0025; vec3 scaleVertex = vPos + vNormal * scaleFactor; gl_Position = uProjection * uView * vInstanceMatrix * vec4(scaleVertex, 1.0); } diff --git a/FModel/Views/Snooper/Camera.cs b/FModel/Views/Snooper/Camera.cs index 201ea1a2..44a61043 100644 --- a/FModel/Views/Snooper/Camera.cs +++ b/FModel/Views/Snooper/Camera.cs @@ -11,7 +11,7 @@ public class Camera public float Yaw { get; set; } = -90f; public float Pitch { get; set; } = 0f; - public float Zoom { get; set; } = 45f; + public float Zoom { get; set; } = 60f; public float Speed { get; set; } = 1f; public float Near { get; } = 0.01f; public float Far { get; } = 100f; @@ -34,7 +34,7 @@ public Camera(Vector3 position, Vector3 direction, float near, float far, float public void ModifyZoom(float zoomAmount) { //We don't want to be able to zoom in too close or too far away so clamp to these values - Zoom = Math.Clamp(Zoom - zoomAmount, 1.0f, 45f); + Zoom = Math.Clamp(Zoom - zoomAmount, 1.0f, 60f); } public void ModifyDirection(float xOffset, float yOffset) diff --git a/FModel/Views/Snooper/FramebufferObject.cs b/FModel/Views/Snooper/FramebufferObject.cs index a385b5ad..2994779c 100644 --- a/FModel/Views/Snooper/FramebufferObject.cs +++ b/FModel/Views/Snooper/FramebufferObject.cs @@ -96,7 +96,7 @@ public void BindMsaa() public void BindStuff() { - _gl.DepthMask(false); + _gl.Disable(EnableCap.DepthTest); _shader.Use(); _vao.Bind(); @@ -104,8 +104,7 @@ public void BindStuff() _postProcessingTexture.Bind(TextureUnit.Texture0); _gl.DrawArrays(PrimitiveType.Triangles, 0, (uint) Indices.Length); - - _gl.DepthMask(true); + _gl.Enable(EnableCap.DepthTest); } public IntPtr GetPointer() => _postProcessingTexture.GetPointer(); diff --git a/FModel/Views/Snooper/Grid.cs b/FModel/Views/Snooper/Grid.cs index 77205f73..93ccd331 100644 --- a/FModel/Views/Snooper/Grid.cs +++ b/FModel/Views/Snooper/Grid.cs @@ -43,8 +43,7 @@ public void Setup(GL gl) public void Bind(Camera camera) { - _gl.DepthMask(false); - + _gl.Disable(EnableCap.DepthTest); _vao.Bind(); _shader.Use(); @@ -55,8 +54,7 @@ public void Bind(Camera camera) _shader.SetUniform("uFar", camera.Far); _gl.DrawArrays(PrimitiveType.Triangles, 0, (uint) Indices.Length); - - _gl.DepthMask(true); + _gl.Enable(EnableCap.DepthTest); } public void Dispose() diff --git a/FModel/Views/Snooper/Model.cs b/FModel/Views/Snooper/Model.cs index 0716aa8c..ea298b17 100644 --- a/FModel/Views/Snooper/Model.cs +++ b/FModel/Views/Snooper/Model.cs @@ -30,7 +30,6 @@ public class Model : IDisposable public Section[] Sections; public readonly List Skeleton; - public int InstanceIndex; public int TransformsCount; public readonly List Transforms; public readonly string[] TransformsLabels = { @@ -39,6 +38,7 @@ public class Model : IDisposable "X Scale", "Y", "Z" }; + public bool Show; public bool IsSelected; public bool DisplayVertexColors; public bool DisplayBones; @@ -47,8 +47,8 @@ protected Model(string name, string type) { Name = name; Type = type; - InstanceIndex = 0; Transforms = new List(); + Show = true; } public Model(string name, string type, CBaseMeshLod lod, CMeshVertex[] vertices, List skeleton = null, Transform transform = null) : this(name, type) @@ -165,35 +165,47 @@ public void Setup(GL gl) } } - public void Bind(Shader shader, Shader outline) + public void Bind(Shader shader) { - _vao.Bind(); + if (IsSelected) + { + _gl.Enable(EnableCap.StencilTest); + _gl.StencilFunc(StencilFunction.Always, 1, 0xFF); + } + _vao.Bind(); shader.SetUniform("display_vertex_colors", DisplayVertexColors); for (int section = 0; section < Sections.Length; section++) { Sections[section].Bind(shader, (uint) TransformsCount); } + _vao.Unbind(); if (IsSelected) { - outline.Use(); - _gl.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line); - _gl.StencilFunc(StencilFunction.Notequal, 1, 0xFF); - _gl.Disable(EnableCap.DepthTest); - _gl.StencilMask(0x00); - for (int section = 0; section < Sections.Length; section++) - { - _gl.DrawArraysInstanced(PrimitiveType.Triangles, Sections[section].FirstFaceIndex, Sections[section].FacesCount, (uint) InstanceIndex + 1); - } - _gl.StencilMask(0xFF); - _gl.Enable(EnableCap.DepthTest); _gl.StencilFunc(StencilFunction.Always, 0, 0xFF); - _gl.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); - shader.Use(); + _gl.Disable(EnableCap.StencilTest); } + } + + public void Outline(Shader shader) + { + _gl.StencilMask(0x00); + _gl.Disable(EnableCap.DepthTest); + _gl.StencilFunc(StencilFunction.Notequal, 1, 0xFF); + _vao.Bind(); + shader.Use(); + for (int section = 0; section < Sections.Length; section++) + { + if (!Sections[section].Show) continue; + _gl.DrawArraysInstanced(PrimitiveType.Triangles, Sections[section].FirstFaceIndex, Sections[section].FacesCount, (uint) TransformsCount); + } _vao.Unbind(); + + _gl.StencilFunc(StencilFunction.Always, 0, 0xFF); + _gl.Enable(EnableCap.DepthTest); + _gl.StencilMask(0xFF); } public void Dispose() diff --git a/FModel/Views/Snooper/SnimGui.cs b/FModel/Views/Snooper/SnimGui.cs index cbd593ba..85bf06fd 100644 --- a/FModel/Views/Snooper/SnimGui.cs +++ b/FModel/Views/Snooper/SnimGui.cs @@ -29,6 +29,7 @@ public class SnimGui : IDisposable private readonly Vector2 _texturePosition; private bool _viewportFocus; private FGuid _selectedModel; + private int _selectedInstance; private int _selectedSection; private const ImGuiWindowFlags _noResize = ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoMove; // delete once we have a proper docking branch @@ -55,6 +56,7 @@ public SnimGui(GL gl, IWindow window, IInputContext input) _textureSize = _viewportSize with { Y = viewport.WorkSize.Y - _viewportSize.Y - titleBarHeight }; _texturePosition = new Vector2(0, _viewportPosition.Y + _viewportSize.Y); _selectedModel = new FGuid(); + _selectedInstance = 0; _selectedSection = 0; Theme(style); @@ -137,6 +139,7 @@ private void DrawOuliner(Camera camera, IDictionary models) if (ImGui.Selectable(model.Name, model.IsSelected)) { _selectedModel = guid; + _selectedInstance = 0; _selectedSection = 0; } if (ImGui.BeginPopupContextItem()) @@ -183,11 +186,12 @@ private void DrawProperties(Camera camera, IDictionary models) ImGui.Text($"Entity: {model.Name}"); ImGui.Separator(); if (ImGui.Button("Focus")) - camera.Position = model.Transforms[model.InstanceIndex].Position; + camera.Position = model.Transforms[_selectedInstance].Position; ImGui.SameLine(); ImGui.BeginDisabled(model.TransformsCount < 2); - ImGui.SliderInt("Instance", ref model.InstanceIndex, 0, model.TransformsCount - 1, "%i", ImGuiSliderFlags.AlwaysClamp); + ImGui.SliderInt("Instance", ref _selectedInstance, 0, model.TransformsCount - 1, "%i", ImGuiSliderFlags.AlwaysClamp); ImGui.EndDisabled(); + ImGui.Checkbox("Show", ref model.Show); ImGui.BeginDisabled(!model.HasVertexColors); ImGui.Checkbox("Vertex Colors", ref model.DisplayVertexColors); ImGui.EndDisabled(); @@ -202,46 +206,46 @@ private void DrawProperties(Camera camera, IDictionary models) var index = 0; ImGui.SetNextItemWidth(width); ImGui.PushID(index); - ImGui.DragFloat(model.TransformsLabels[index], ref model.Transforms[model.InstanceIndex].Position.X, speed, 0f, 0f, "%.2f m"); + ImGui.DragFloat(model.TransformsLabels[index], ref model.Transforms[_selectedInstance].Position.X, speed, 0f, 0f, "%.2f m"); ImGui.PopID(); index++; ImGui.SetNextItemWidth(width); ImGui.PushID(index); - ImGui.DragFloat(model.TransformsLabels[index], ref model.Transforms[model.InstanceIndex].Position.Y, speed, 0f, 0f, "%.2f m"); + ImGui.DragFloat(model.TransformsLabels[index], ref model.Transforms[_selectedInstance].Position.Y, speed, 0f, 0f, "%.2f m"); ImGui.PopID(); index++; ImGui.SetNextItemWidth(width); ImGui.PushID(index); - ImGui.DragFloat(model.TransformsLabels[index], ref model.Transforms[model.InstanceIndex].Position.Z, speed, 0f, 0f, "%.2f m"); + ImGui.DragFloat(model.TransformsLabels[index], ref model.Transforms[_selectedInstance].Position.Z, speed, 0f, 0f, "%.2f m"); ImGui.PopID(); ImGui.Spacing(); index++; ImGui.SetNextItemWidth(width); ImGui.PushID(index); - ImGui.DragFloat(model.TransformsLabels[index], ref model.Transforms[model.InstanceIndex].Rotation.Pitch, .5f, 0f, 0f, "%.1f°"); + ImGui.DragFloat(model.TransformsLabels[index], ref model.Transforms[_selectedInstance].Rotation.Pitch, .5f, 0f, 0f, "%.1f°"); ImGui.PopID(); index++; ImGui.SetNextItemWidth(width); ImGui.PushID(index); - ImGui.DragFloat(model.TransformsLabels[index], ref model.Transforms[model.InstanceIndex].Rotation.Roll, .5f, 0f, 0f, "%.1f°"); + ImGui.DragFloat(model.TransformsLabels[index], ref model.Transforms[_selectedInstance].Rotation.Roll, .5f, 0f, 0f, "%.1f°"); ImGui.PopID(); index++; ImGui.SetNextItemWidth(width); ImGui.PushID(index); - ImGui.DragFloat(model.TransformsLabels[index], ref model.Transforms[model.InstanceIndex].Rotation.Yaw, .5f, 0f, 0f, "%.1f°"); + ImGui.DragFloat(model.TransformsLabels[index], ref model.Transforms[_selectedInstance].Rotation.Yaw, .5f, 0f, 0f, "%.1f°"); ImGui.PopID(); ImGui.Spacing(); index++; ImGui.SetNextItemWidth(width); ImGui.PushID(index); - ImGui.DragFloat(model.TransformsLabels[index], ref model.Transforms[model.InstanceIndex].Scale.X, speed, 0f, 0f, "%.3f"); + ImGui.DragFloat(model.TransformsLabels[index], ref model.Transforms[_selectedInstance].Scale.X, speed, 0f, 0f, "%.3f"); ImGui.PopID(); index++; ImGui.SetNextItemWidth(width); ImGui.PushID(index); - ImGui.DragFloat(model.TransformsLabels[index], ref model.Transforms[model.InstanceIndex].Scale.Y, speed, 0f, 0f, "%.3f"); + ImGui.DragFloat(model.TransformsLabels[index], ref model.Transforms[_selectedInstance].Scale.Y, speed, 0f, 0f, "%.3f"); ImGui.PopID(); index++; ImGui.SetNextItemWidth(width); ImGui.PushID(index); - ImGui.DragFloat(model.TransformsLabels[index], ref model.Transforms[model.InstanceIndex].Scale.Z, speed, 0f, 0f, "%.3f"); + ImGui.DragFloat(model.TransformsLabels[index], ref model.Transforms[_selectedInstance].Scale.Z, speed, 0f, 0f, "%.3f"); ImGui.PopID(); - model.UpdateMatrix(model.InstanceIndex); + model.UpdateMatrix(_selectedInstance); ImGui.TreePop(); } diff --git a/FModel/Views/Snooper/Snooper.cs b/FModel/Views/Snooper/Snooper.cs index 251762ee..03270c1b 100644 --- a/FModel/Views/Snooper/Snooper.cs +++ b/FModel/Views/Snooper/Snooper.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Numerics; using System.Runtime.InteropServices; using System.Windows; @@ -259,7 +260,7 @@ private void OnLoad() _gl.Enable(EnableCap.Blend); _gl.Enable(EnableCap.DepthTest); _gl.Enable(EnableCap.Multisample); - _gl.Enable(EnableCap.StencilTest); + _gl.StencilOp(StencilOp.Keep, StencilOp.Replace, StencilOp.Replace); _gl.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha); _imGui = new SnimGui(_gl, _window, input); @@ -300,6 +301,7 @@ private void OnRender(double deltaTime) _outline.Use(); _outline.SetUniform("uView", viewMatrix); _outline.SetUniform("uProjection", projMatrix); + _outline.SetUniform("viewPos", _camera.Position); _shader.Use(); _shader.SetUniform("uView", viewMatrix); @@ -315,9 +317,14 @@ private void OnRender(double deltaTime) _shader.SetUniform("light.diffuse", _diffuseLight); _shader.SetUniform("light.specular", _specularLight); - foreach (var model in _models.Values) + foreach (var model in _models.Values.Where(model => model.Show)) + { + model.Bind(_shader); + } + _gl.Enable(EnableCap.StencilTest); // I don't get why this must be here but it works now so... + foreach (var model in _models.Values.Where(model => model.IsSelected && model.Show)) { - model.Bind(_shader, _outline); + model.Outline(_outline); } _imGui.Construct(_size, _framebuffer, _camera, _mouse, _models);