From 278fb6da1f118e87ac46a45f2c878b24f718b5b5 Mon Sep 17 00:00:00 2001 From: codereader Date: Wed, 26 May 2021 19:07:19 +0200 Subject: [PATCH] #5623: XYRenderer is distinguishing the merge actions --- radiant/xyview/XYRenderer.h | 81 +++++++++---------- radiant/xyview/XYWnd.cpp | 29 ++++--- radiant/xyview/XYWnd.h | 8 +- .../rendersystem/backend/OpenGLShader.cpp | 40 ++++++--- 4 files changed, 81 insertions(+), 77 deletions(-) diff --git a/radiant/xyview/XYRenderer.h b/radiant/xyview/XYRenderer.h index 9ae77a5437..94d0fbb5f6 100644 --- a/radiant/xyview/XYRenderer.h +++ b/radiant/xyview/XYRenderer.h @@ -4,43 +4,34 @@ #include "imap.h" /// RenderableCollector implementation for the ortho view -class XYRenderer: public RenderableCollector +class XYRenderer : + public RenderableCollector { - // State type structure - struct State +public: + struct HighlightShaders { - bool highlightPrimitives; - bool highlightAsGroupMember; - bool highlightAsMergeAction; - - // Constructor - State() : - highlightPrimitives(false), - highlightAsGroupMember(false), - highlightAsMergeAction(false) - {} + ShaderPtr selectedShader; + ShaderPtr selectedShaderGroup; + ShaderPtr mergeActionShaderAdd; + ShaderPtr mergeActionShaderChange; + ShaderPtr mergeActionShaderRemove; + ShaderPtr nonMergeActionNodeShader; }; - State _state; +private: + std::size_t _flags; RenderStateFlags _globalstate; - // Shader to use for highlighted objects - Shader* _selectedShader; - Shader* _selectedShaderGroup; - Shader* _mergeActionShader; - Shader* _nonMergeActionNodeShader; - IMap::EditMode _editMode; + const HighlightShaders& _shaders; + public: - XYRenderer(RenderStateFlags globalstate, Shader* selected, Shader* selectedGroup, - Shader* mergeActionShader, Shader* nonMergeActionNodeShader) : + XYRenderer(RenderStateFlags globalstate, const HighlightShaders& shaders) : + _flags(Highlight::Flags::NoHighlight), _globalstate(globalstate), - _selectedShader(selected), - _selectedShaderGroup(selectedGroup), - _mergeActionShader(mergeActionShader), - _nonMergeActionNodeShader(nonMergeActionNodeShader), - _editMode(GlobalMapModule().getEditMode()) + _editMode(GlobalMapModule().getEditMode()), + _shaders(shaders) {} bool supportsFullMaterials() const override @@ -50,19 +41,13 @@ class XYRenderer: public RenderableCollector void setHighlightFlag(Highlight::Flags flags, bool enabled) override { - if (flags & Highlight::Primitives) + if (enabled) { - _state.highlightPrimitives = enabled; + _flags |= flags; } - - if (flags & Highlight::GroupMember) - { - _state.highlightAsGroupMember = enabled; - } - - if (flags & Highlight::MergeAction) + else { - _state.highlightAsMergeAction = enabled; + _flags &= ~flags; } } @@ -77,30 +62,36 @@ class XYRenderer: public RenderableCollector { if (_editMode == IMap::EditMode::Merge) { - if (_state.highlightAsMergeAction) + if (_flags & Highlight::Flags::MergeAction) { - // Merge actions get rendered in a special colour - _mergeActionShader->addRenderable(renderable, localToWorld, nullptr, entity); + // This is a merge-relevant node that should be rendered in a special colour + const auto& mergeShader = (_flags & Highlight::Flags::MergeActionAdd) != 0 ? _shaders.mergeActionShaderAdd : + (_flags & Highlight::Flags::MergeActionRemove) != 0 ? _shaders.mergeActionShaderRemove : _shaders.mergeActionShaderChange; + + if (mergeShader) + { + mergeShader->addRenderable(renderable, localToWorld, nullptr, entity); + } } else { // Everything else is using the shader for non-merge-affected nodes - _nonMergeActionNodeShader->addRenderable(renderable, localToWorld, nullptr, entity); + _shaders.nonMergeActionNodeShader->addRenderable(renderable, localToWorld, nullptr, entity); } return; } // Regular editing mode, add all highlighted nodes to the corresponding shader - if (_state.highlightPrimitives) + if ((_flags & Highlight::Flags::Primitives) != 0) { - if (_state.highlightAsGroupMember) + if ((_flags & Highlight::Flags::GroupMember) != 0) { - _selectedShaderGroup->addRenderable(renderable, localToWorld, nullptr, entity); + _shaders.selectedShaderGroup->addRenderable(renderable, localToWorld, nullptr, entity); } else { - _selectedShader->addRenderable(renderable, localToWorld, nullptr, entity); + _shaders.selectedShader->addRenderable(renderable, localToWorld, nullptr, entity); } } diff --git a/radiant/xyview/XYWnd.cpp b/radiant/xyview/XYWnd.cpp index 89c01f30ee..ad23c4cb68 100644 --- a/radiant/xyview/XYWnd.cpp +++ b/radiant/xyview/XYWnd.cpp @@ -221,19 +221,22 @@ int XYWnd::getDeviceHeight() const void XYWnd::captureStates() { - _selectedShader = GlobalRenderSystem().capture("$XY_OVERLAY"); - _selectedShaderGroup = GlobalRenderSystem().capture("$XY_OVERLAY_GROUP"); - - _mergeActionShader = GlobalRenderSystem().capture("$XY_MERGE_ACTION"); - _nonMergeActionNodeShader = GlobalRenderSystem().capture("$XY_INACTIVE_NODE"); + _highlightShaders.selectedShader = GlobalRenderSystem().capture("$XY_OVERLAY"); + _highlightShaders.selectedShaderGroup = GlobalRenderSystem().capture("$XY_OVERLAY_GROUP"); + _highlightShaders.mergeActionShaderAdd = GlobalRenderSystem().capture("$XY_MERGE_ACTION_ADD"); + _highlightShaders.mergeActionShaderChange = GlobalRenderSystem().capture("$XY_MERGE_ACTION_CHANGE"); + _highlightShaders.mergeActionShaderRemove = GlobalRenderSystem().capture("$XY_MERGE_ACTION_REMOVE"); + _highlightShaders.nonMergeActionNodeShader = GlobalRenderSystem().capture("$XY_INACTIVE_NODE"); } void XYWnd::releaseStates() { - _selectedShader.reset(); - _selectedShaderGroup.reset(); - _mergeActionShader.reset(); - _nonMergeActionNodeShader.reset(); + _highlightShaders.selectedShader.reset(); + _highlightShaders.selectedShaderGroup.reset(); + _highlightShaders.mergeActionShaderAdd.reset(); + _highlightShaders.mergeActionShaderChange.reset(); + _highlightShaders.mergeActionShaderRemove.reset(); + _highlightShaders.nonMergeActionNodeShader.reset(); } void XYWnd::ensureFont() @@ -1368,8 +1371,7 @@ void XYWnd::draw() { // Construct the renderer and render the scene - XYRenderer renderer(flagsMask, _selectedShader.get(), _selectedShaderGroup.get(), - _mergeActionShader.get(), _nonMergeActionNodeShader.get()); + XYRenderer renderer(flagsMask, _highlightShaders); // First pass (scenegraph traversal) render::RenderableCollectionWalker::CollectRenderablesInScene(renderer, @@ -1724,9 +1726,6 @@ IInteractiveView& XYWnd::getInteractiveView() } /* STATICS */ -ShaderPtr XYWnd::_selectedShader; -ShaderPtr XYWnd::_selectedShaderGroup; -ShaderPtr XYWnd::_mergeActionShader; -ShaderPtr XYWnd::_nonMergeActionNodeShader; +XYRenderer::HighlightShaders XYWnd::_highlightShaders; } // namespace diff --git a/radiant/xyview/XYWnd.h b/radiant/xyview/XYWnd.h index dd575dd68e..e9945dc93a 100644 --- a/radiant/xyview/XYWnd.h +++ b/radiant/xyview/XYWnd.h @@ -19,6 +19,7 @@ #include "imousetool.h" #include "tools/XYMouseToolEvent.h" #include "wxutil/MouseToolHandler.h" +#include "XYRenderer.h" namespace ui { @@ -55,11 +56,8 @@ class XYWnd : render::View _view; - // Shader to use for selected items - static ShaderPtr _selectedShader; - static ShaderPtr _selectedShaderGroup; - static ShaderPtr _mergeActionShader; - static ShaderPtr _nonMergeActionNodeShader; + // Shaders used for highlighting nodes + static XYRenderer::HighlightShaders _highlightShaders; Vector3 _mousePosition; diff --git a/radiantcore/rendersystem/backend/OpenGLShader.cpp b/radiantcore/rendersystem/backend/OpenGLShader.cpp index 317c44c3e7..f3ede74e26 100644 --- a/radiantcore/rendersystem/backend/OpenGLShader.cpp +++ b/radiantcore/rendersystem/backend/OpenGLShader.cpp @@ -873,18 +873,34 @@ void OpenGLShader::construct() state.m_linewidth = 2; state.m_linestipple_factor = 3; } - else if (_name == "$XY_MERGE_ACTION") - { - Vector3 mergeActionColour(0, 0.4, 0.9); - state.setColour(static_cast(mergeActionColour[0]), - static_cast(mergeActionColour[1]), - static_cast(mergeActionColour[2]), - static_cast(0.5)); - state.setRenderFlag(RENDER_LINESTIPPLE); - state.setSortPosition(OpenGLState::SORT_OVERLAY_FIRST); - state.m_linewidth = 2; - state.m_linestipple_factor = 2; - } + else if (string::starts_with(_name, "$XY_MERGE_ACTION_")) + { + Colour4 colour; + auto sortPosition = OpenGLState::SORT_OVERLAY_FIRST; + auto lineSortPosition = OpenGLState::SORT_OVERLAY_LAST; + + if (string::ends_with(_name, "_ADD")) + { + colour = Colour4(0, 0.5f, 0, 0.5f); + sortPosition = OpenGLState::SORT_OVERLAY_THIRD; // render additions over removals + } + else if (string::ends_with(_name, "_REMOVE")) + { + colour = Colour4(0.6f, 0.1f, 0, 0.5f); + lineSortPosition = OpenGLState::SORT_OVERLAY_ONE_BEFORE_LAST; + } + else if (string::ends_with(_name, "_CHANGE")) + { + colour = Colour4(0, 0.4f, 0.9f, 0.5f); + sortPosition = OpenGLState::SORT_OVERLAY_SECOND; + } + + state.setColour(colour); + //state.setRenderFlag(RENDER_LINESTIPPLE); + state.setSortPosition(OpenGLState::SORT_OVERLAY_FIRST); + state.m_linewidth = 2; + //state.m_linestipple_factor = 1; + } else if (_name == "$XY_INACTIVE_NODE") { Colour4 colour(0, 0, 0, 0.05f);