Skip to content

Commit

Permalink
#5623: XYRenderer is distinguishing the merge actions
Browse files Browse the repository at this point in the history
  • Loading branch information
codereader committed May 26, 2021
1 parent 74a75cf commit 278fb6d
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 77 deletions.
81 changes: 36 additions & 45 deletions radiant/xyview/XYRenderer.h
Expand Up @@ -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
Expand All @@ -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;
}
}

Expand All @@ -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);
}
}

Expand Down
29 changes: 14 additions & 15 deletions radiant/xyview/XYWnd.cpp
Expand Up @@ -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()
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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
8 changes: 3 additions & 5 deletions radiant/xyview/XYWnd.h
Expand Up @@ -19,6 +19,7 @@
#include "imousetool.h"
#include "tools/XYMouseToolEvent.h"
#include "wxutil/MouseToolHandler.h"
#include "XYRenderer.h"

namespace ui
{
Expand Down Expand Up @@ -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;

Expand Down
40 changes: 28 additions & 12 deletions radiantcore/rendersystem/backend/OpenGLShader.cpp
Expand Up @@ -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<float>(mergeActionColour[0]),
static_cast<float>(mergeActionColour[1]),
static_cast<float>(mergeActionColour[2]),
static_cast<float>(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);
Expand Down

0 comments on commit 278fb6d

Please sign in to comment.