Skip to content

Commit

Permalink
#5584: Patch control point rendering. Selection updates are not corre…
Browse files Browse the repository at this point in the history
…ctly updating the view yet.
  • Loading branch information
codereader committed Jan 7, 2022
1 parent b872517 commit 18bd4f5
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 12 deletions.
1 change: 1 addition & 0 deletions include/igeometryrenderer.h
Expand Up @@ -14,6 +14,7 @@ enum class GeometryType
Triangles,
Quads,
Lines,
Points,
};

/**
Expand Down
27 changes: 22 additions & 5 deletions radiantcore/patch/PatchNode.cpp
Expand Up @@ -17,7 +17,8 @@ PatchNode::PatchNode(patch::PatchDefType type) :
_selectedControlVerticesNeedUpdate(true),
_renderableSurfaceSolid(m_patch.getTesselation(), true),
_renderableSurfaceWireframe(m_patch.getTesselation(), false),
_renderableCtrlLattice(m_patch, m_ctrl_instances)
_renderableCtrlLattice(m_patch, m_ctrl_instances),
_renderableCtrlPoints(m_patch, m_ctrl_instances)
{
m_patch.setFixedSubdivisions(type == patch::PatchDefType::Def3, Subdivisions(m_patch.getSubdivisions()));
}
Expand All @@ -41,7 +42,8 @@ PatchNode::PatchNode(const PatchNode& other) :
_selectedControlVerticesNeedUpdate(true),
_renderableSurfaceSolid(m_patch.getTesselation(), true),
_renderableSurfaceWireframe(m_patch.getTesselation(), false),
_renderableCtrlLattice(m_patch, m_ctrl_instances)
_renderableCtrlLattice(m_patch, m_ctrl_instances),
_renderableCtrlPoints(m_patch, m_ctrl_instances)
{
}

Expand Down Expand Up @@ -346,13 +348,20 @@ void PatchNode::onPreRender(const VolumeTest& volume)

if (isSelected() && GlobalSelectionSystem().ComponentMode() == selection::ComponentSelectionMode::Vertex)
{
updateSelectedControlVertices();

// Selected patches in component mode render the lattice connecting the control points
_renderableCtrlLattice.update(_ctrlLatticeShader);
_renderableCtrlPoints.update(_ctrlPointShader);
}
else
{
_renderableCtrlPoints.clear();
_renderableCtrlLattice.clear();
_renderableCtrlLattice.queueUpdate(); // will be updated next time it's rendered

// Queue an update the next time it's rendered
_renderableCtrlPoints.queueUpdate();
_renderableCtrlLattice.queueUpdate();
}
}

Expand Down Expand Up @@ -416,15 +425,16 @@ void PatchNode::setRenderSystem(const RenderSystemPtr& renderSystem)
_renderableSurfaceSolid.clear();
_renderableSurfaceWireframe.clear();
_renderableCtrlLattice.clear();
_renderableCtrlPoints.clear();

if (renderSystem)
{
m_state_selpoint = renderSystem->capture("$SELPOINT");
_ctrlPointShader = renderSystem->capture("$POINT");
_ctrlLatticeShader = renderSystem->capture("$LATTICE");
}
else
{
m_state_selpoint.reset();
_ctrlPointShader.reset();
_ctrlLatticeShader.reset();
}
}
Expand Down Expand Up @@ -470,6 +480,7 @@ void PatchNode::updateSelectedControlVertices() const
}
}

#if 0
void PatchNode::renderComponentsSelected(IRenderableCollector& collector, const VolumeTest& volume) const
{
const_cast<Patch&>(m_patch).evaluateTransform();
Expand All @@ -484,6 +495,7 @@ void PatchNode::renderComponentsSelected(IRenderableCollector& collector, const
collector.addRenderable(*m_state_selpoint, m_render_selected, localToWorld());
}
}
#endif

std::size_t PatchNode::getHighlightFlags()
{
Expand Down Expand Up @@ -547,6 +559,7 @@ void PatchNode::_onTransformationChanged()
_renderableSurfaceSolid.queueUpdate();
_renderableSurfaceWireframe.queueUpdate();
_renderableCtrlLattice.queueUpdate();
_renderableCtrlPoints.queueUpdate();
}

void PatchNode::_applyTransformation()
Expand Down Expand Up @@ -575,13 +588,15 @@ void PatchNode::onTesselationChanged()
_renderableSurfaceSolid.queueUpdate();
_renderableSurfaceWireframe.queueUpdate();
_renderableCtrlLattice.queueUpdate();
_renderableCtrlPoints.queueUpdate();
}

void PatchNode::onControlPointsChanged()
{
_renderableSurfaceSolid.queueUpdate();
_renderableSurfaceWireframe.queueUpdate();
_renderableCtrlLattice.queueUpdate();
_renderableCtrlPoints.queueUpdate();
}

void PatchNode::onMaterialChanged()
Expand All @@ -600,12 +615,14 @@ void PatchNode::onVisibilityChanged(bool visible)
_renderableSurfaceSolid.clear();
_renderableSurfaceWireframe.clear();
_renderableCtrlLattice.clear();
_renderableCtrlPoints.clear();
}
else
{
// Update the vertex buffers next time we need to render
_renderableSurfaceSolid.queueUpdate();
_renderableSurfaceWireframe.queueUpdate();
_renderableCtrlLattice.queueUpdate();
_renderableCtrlPoints.queueUpdate();
}
}
9 changes: 5 additions & 4 deletions radiantcore/patch/PatchNode.h
Expand Up @@ -40,7 +40,7 @@ class PatchNode final :
// An internal AABB variable to calculate the bounding box of the selected components (has to be mutable)
mutable AABB m_aabb_component;

ShaderPtr m_state_selpoint;
ShaderPtr _ctrlPointShader;
ShaderPtr _ctrlLatticeShader;

// For pivoted rotations, we need a copy of this lying around
Expand All @@ -52,9 +52,8 @@ class PatchNode final :

RenderablePatchTesselation<TesselationIndexer_Triangles> _renderableSurfaceSolid;
RenderablePatchTesselation<TesselationIndexer_Quads> _renderableSurfaceWireframe;

// Draws the wireframe connecting the control points
RenderablePatchLattice _renderableCtrlLattice;
RenderablePatchLattice _renderableCtrlLattice; // Wireframe connecting the control points
RenderablePatchControlPoints _renderableCtrlPoints; // the coloured control points

public:
PatchNode(patch::PatchDefType type);
Expand Down Expand Up @@ -169,8 +168,10 @@ class PatchNode final :
// rendered as highlighted.
void updateSelectedControlVertices() const;

#if 0
// greebo: Renders the selected components. This is called by the above two render functions
void renderComponentsSelected(IRenderableCollector& collector, const VolumeTest& volume) const;
#endif
};
typedef std::shared_ptr<PatchNode> PatchNodePtr;
typedef std::weak_ptr<PatchNode> PatchNodeWeakPtr;
64 changes: 64 additions & 0 deletions radiantcore/patch/PatchRenderables.h
Expand Up @@ -290,3 +290,67 @@ class RenderablePatchLattice :
RenderableGeometry::updateGeometry(render::GeometryType::Lines, vertices, indices);
}
};

// Represents the set of coloured points used to manipulate the control point matrix
class RenderablePatchControlPoints :
public render::RenderableGeometry
{
private:
bool _needsUpdate;

const IPatch& _patch;
const std::vector<PatchControlInstance>& _controlPoints;

public:
RenderablePatchControlPoints(const IPatch& patch, const std::vector<PatchControlInstance>& controlPoints) :
_patch(patch),
_controlPoints(controlPoints),
_needsUpdate(true)
{}

void queueUpdate()
{
_needsUpdate = true;
}

protected:
void updateGeometry() override
{
if (!_needsUpdate) return;

_needsUpdate = false;

// Generate the new point vector
std::vector<ArbitraryMeshVertex> vertices;
std::vector<unsigned int> indices;

vertices.reserve(_controlPoints.size());
indices.reserve(_controlPoints.size());

static const Vector4 SelectedColour(0, 0, 0, 1);
auto width = _patch.getWidth();

for (std::size_t i = 0; i < _controlPoints.size(); ++i)
{
const auto& ctrl = _controlPoints[i];

vertices.push_back(ArbitraryMeshVertex(ctrl.control.vertex, { 0, 0, 0 }, { 0, 0 },
ctrl.isSelected() ? SelectedColour : getColour(i, width)));
indices.push_back(static_cast<unsigned int>(i));
}

RenderableGeometry::updateGeometry(render::GeometryType::Points, vertices, indices);
}

private:
inline const Vector4 getColour(std::size_t i, std::size_t width)
{
static const Vector3& cornerColourVec = GlobalPatchModule().getSettings().getVertexColour(patch::PatchEditVertexType::Corners);
static const Vector3& insideColourVec = GlobalPatchModule().getSettings().getVertexColour(patch::PatchEditVertexType::Inside);

const Vector4 colour_corner(cornerColourVec, 1);
const Vector4 colour_inside(insideColourVec, 1);

return (i % 2 || (i / width) % 2) ? colour_inside : colour_corner;
}
};
5 changes: 2 additions & 3 deletions radiantcore/rendersystem/backend/GeometryRenderer.h
Expand Up @@ -132,6 +132,7 @@ class GeometryRenderer :
_buffers.emplace_back(GL_TRIANGLES);
_buffers.emplace_back(GL_QUADS);
_buffers.emplace_back(GL_LINES);
_buffers.emplace_back(GL_POINTS);
}

bool empty() const
Expand Down Expand Up @@ -220,9 +221,7 @@ class GeometryRenderer :
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);

// Render this slot without any vertex colours
glDisableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);

glFrontFace(GL_CW);

Expand Down

0 comments on commit 18bd4f5

Please sign in to comment.