Skip to content

Commit

Permalink
#5584: Selected Patches submit separate geometry to render the quad m…
Browse files Browse the repository at this point in the history
…esh overlay
  • Loading branch information
codereader committed Nov 12, 2021
1 parent 9fd332a commit d6e8630
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 7 deletions.
25 changes: 19 additions & 6 deletions radiantcore/patch/PatchNode.cpp
Expand Up @@ -319,16 +319,29 @@ bool PatchNode::intersectsLight(const RendererLight& light) const {
return light.lightAABB().intersects(worldAABB());
}

void PatchNode::renderSolid(RenderableCollector& collector, const VolumeTest& volume) const
void PatchNode::onPreRender(const VolumeTest& volume)
{
// Don't render invisible shaders
if (!isForcedVisible() && !m_patch.hasVisibleMaterial()) return;
// Don't do anything when invisible
if (!isForcedVisible() && !m_patch.hasVisibleMaterial()) return;

// Defer the tesselation calculation to the last minute
const_cast<Patch&>(m_patch).evaluateTransform();
const_cast<Patch&>(m_patch).updateTesselation();
m_patch.evaluateTransform();
m_patch.updateTesselation();

const_cast<PatchNode&>(*this)._renderableSurface.update(m_patch._shader.getGLShader());
_renderableSurface.update(m_patch._shader.getGLShader());
}

void PatchNode::renderSolid(RenderableCollector& collector, const VolumeTest& volume) const
{
// Don't render invisible patches
if (!isForcedVisible() && !m_patch.hasVisibleMaterial()) return;

if (isSelected())
{
// Send the patch geometry for rendering highlights
collector.addGeometry(const_cast<Patch&>(m_patch)._solidRenderable,
RenderableCollector::Highlight::Primitives | RenderableCollector::Highlight::Flags::Faces);
}

assert(_renderEntity); // patches rendered without parent - no way!

Expand Down
1 change: 1 addition & 0 deletions radiantcore/patch/PatchNode.h
Expand Up @@ -135,6 +135,7 @@ class PatchNode final :

// Render functions, these make sure that all things get rendered properly. The calls are also passed on
// to the contained patch <m_patch>
void onPreRender(const VolumeTest& volume) override;
void renderSolid(RenderableCollector& collector, const VolumeTest& volume) const override;
void renderWireframe(RenderableCollector& collector, const VolumeTest& volume) const override;
void setRenderSystem(const RenderSystemPtr& renderSystem) override;
Expand Down
58 changes: 58 additions & 0 deletions radiantcore/patch/PatchRenderables.cpp
Expand Up @@ -96,6 +96,64 @@ void RenderablePatchSolid::queueUpdate()
_needsUpdate = true;
}

RenderableGeometry::Type RenderablePatchSolid::getType() const
{
return RenderableGeometry::Type::Quads;
}

const Vector3& RenderablePatchSolid::getFirstVertex()
{
return _tess.vertices.front().vertex;
}

std::size_t RenderablePatchSolid::getVertexStride()
{
return sizeof(ArbitraryMeshVertex);
}

const unsigned int& RenderablePatchSolid::getFirstIndex()
{
updateIndices();
return _indices.front();
}

std::size_t RenderablePatchSolid::getNumIndices()
{
updateIndices();
return _indices.size();
}

void RenderablePatchSolid::updateIndices()
{
// To render the patch mesh as quads, we need 4 indices per quad
auto numRequiredIndices = (_tess.height - 1) * (_tess.width - 1) * 4;

if (_indices.size() == numRequiredIndices)
{
return;
}

if (_tess.height == 0 || _tess.width == 0)
{
_indices.clear();
return;
}

_indices.resize(numRequiredIndices);

auto index = 0;
for (auto h = 0; h < _tess.height - 1; ++h)
{
for (auto w = 0; w < _tess.width - 1; ++w)
{
_indices[index++] = static_cast<unsigned int>(h * _tess.width + w + 0);
_indices[index++] = static_cast<unsigned int>((h + 1) * _tess.width + w + 0);
_indices[index++] = static_cast<unsigned int>((h + 1) * _tess.width + w + 1);
_indices[index++] = static_cast<unsigned int>(h * _tess.width + w + 1);
}
}
}

const ShaderPtr& RenderablePatchVectorsNTB::getShader() const
{
return _shader;
Expand Down
15 changes: 14 additions & 1 deletion radiantcore/patch/PatchRenderables.h
Expand Up @@ -52,7 +52,8 @@ class RenderablePatchFixedWireframe :

/// Helper class to render a PatchTesselation in solid mode
class RenderablePatchSolid :
public OpenGLRenderable
public OpenGLRenderable,
public RenderableGeometry
{
// Geometry source
PatchTesselation& _tess;
Expand All @@ -63,12 +64,24 @@ class RenderablePatchSolid :

mutable bool _needsUpdate;

// The render indices to render the mesh vertices as QUADS
std::vector<unsigned int> _indices;

public:
RenderablePatchSolid(PatchTesselation& tess);

void render(const RenderInfo& info) const;

void queueUpdate();

Type getType() const override;
const Vector3& getFirstVertex() override;
std::size_t getVertexStride() override;
const unsigned int& getFirstIndex() override;
std::size_t getNumIndices() override;

private:
void updateIndices();
};

// Renders a vertex' normal/tangent/bitangent vector (for debugging purposes)
Expand Down

0 comments on commit d6e8630

Please sign in to comment.