From 1afccd0b219710b685d14ecdb36b477cc4cddf9e Mon Sep 17 00:00:00 2001 From: codereader Date: Sat, 4 Dec 2021 16:43:10 +0100 Subject: [PATCH] #5584: Move some common code to a RenderableGeometry base class --- libs/render/RenderableGeometry.h | 66 +++++++++++++++++++ .../entity/target/RenderableTargetLines.h | 32 ++------- radiantcore/patch/PatchRenderables.h | 33 ++-------- tools/msvc/libs.vcxproj | 1 + tools/msvc/libs.vcxproj.filters | 3 + 5 files changed, 80 insertions(+), 55 deletions(-) create mode 100644 libs/render/RenderableGeometry.h diff --git a/libs/render/RenderableGeometry.h b/libs/render/RenderableGeometry.h new file mode 100644 index 0000000000..54a13696c7 --- /dev/null +++ b/libs/render/RenderableGeometry.h @@ -0,0 +1,66 @@ +#pragma once + +#include "igeometryrenderer.h" +#include "irender.h" + +namespace render +{ + +/** + * Geometry base type, taking care of adding/removing/updating + * indexed vertex data to an IGeometryRenderer instance. + * + * It implements the OpenGLRenderable interface which will instruct + * the shader to render just the geometry batch managed by this object. + * This is used to render highlights (such as selection overlays). + */ +class RenderableGeometry : + public OpenGLRenderable +{ +protected: + ShaderPtr _shader; + IGeometryRenderer::Slot _surfaceSlot; + +protected: + RenderableGeometry() : + _surfaceSlot(IGeometryRenderer::InvalidSlot) + {} + +public: + // Removes any geometry attached to a shader + virtual void clear() + { + if (_shader && _surfaceSlot != IGeometryRenderer::InvalidSlot) + { + _shader->removeGeometry(_surfaceSlot); + } + + _shader.reset(); + _surfaceSlot = IGeometryRenderer::InvalidSlot; + } + + virtual void render(const RenderInfo& info) const override + { + if (_surfaceSlot != IGeometryRenderer::InvalidSlot && _shader) + { + _shader->renderGeometry(_surfaceSlot); + } + } + +protected: + virtual void addOrUpdateGeometry(const ShaderPtr& shader, GeometryType type, + const std::vector& vertices, + const std::vector& indices) + { + if (_surfaceSlot == IGeometryRenderer::InvalidSlot) + { + _surfaceSlot = shader->addGeometry(type, vertices, indices); + } + else + { + shader->updateGeometry(_surfaceSlot, vertices, indices); + } + } +}; + +} diff --git a/radiantcore/entity/target/RenderableTargetLines.h b/radiantcore/entity/target/RenderableTargetLines.h index baa78a367a..fb994847f1 100644 --- a/radiantcore/entity/target/RenderableTargetLines.h +++ b/radiantcore/entity/target/RenderableTargetLines.h @@ -5,6 +5,7 @@ #include "irenderable.h" #include "ivolumetest.h" #include "math/Segment.h" +#include "render/RenderableGeometry.h" namespace entity { @@ -24,21 +25,18 @@ namespace * frontend render pass. */ class RenderableTargetLines : - public OpenGLRenderable + public render::RenderableGeometry { private: const TargetKeyCollection& _targetKeys; bool _needsUpdate; - ShaderPtr _shader; - render::IGeometryRenderer::Slot _surfaceSlot; std::size_t _numVisibleLines; public: RenderableTargetLines(const TargetKeyCollection& targetKeys) : _targetKeys(targetKeys), _needsUpdate(true), - _surfaceSlot(render::IGeometryRenderer::InvalidSlot), _numVisibleLines(0) {} @@ -52,15 +50,10 @@ class RenderableTargetLines : _needsUpdate = true; } - void clear() + void clear() override { - if (_shader && _surfaceSlot != render::IGeometryRenderer::InvalidSlot) - { - _shader->removeGeometry(_surfaceSlot); - } + RenderableGeometry::clear(); - _shader.reset(); - _surfaceSlot = render::IGeometryRenderer::InvalidSlot; _numVisibleLines = 0; } @@ -104,24 +97,9 @@ class RenderableTargetLines : _shader = shader; _numVisibleLines = numVisibleLines; - if (_surfaceSlot == render::IGeometryRenderer::InvalidSlot) - { - _surfaceSlot = shader->addGeometry(render::GeometryType::Lines, vertices, indices); - } - else - { - shader->updateGeometry(_surfaceSlot, vertices, indices); - } + addOrUpdateGeometry(shader, render::GeometryType::Lines, vertices, indices); } - void render(const RenderInfo& info) const override - { - if (_surfaceSlot != render::IGeometryRenderer::InvalidSlot && _shader) - { - _shader->renderGeometry(_surfaceSlot); - } - } - private: // Adds points to the vector, defining a line from start to end, with arrow indicators // in the XY plane (located at the midpoint between start/end). diff --git a/radiantcore/patch/PatchRenderables.h b/radiantcore/patch/PatchRenderables.h index 1a53f50323..d6444d6ddc 100644 --- a/radiantcore/patch/PatchRenderables.h +++ b/radiantcore/patch/PatchRenderables.h @@ -13,6 +13,7 @@ #include "render/VertexBuffer.h" #include "render/IndexedVertexBuffer.h" +#include "render/RenderableGeometry.h" #if 0 /// Helper class to render a PatchTesselation in solid mode @@ -158,7 +159,7 @@ class TesselationIndexer_Quads : template class RenderablePatchTesselation : - public OpenGLRenderable + public render::RenderableGeometry { private: static_assert(std::is_base_of_v, "Indexer must implement ITesselationIndexer"); @@ -166,27 +167,18 @@ class RenderablePatchTesselation : const PatchTesselation& _tess; bool _needsUpdate; - ShaderPtr _shader; std::size_t _size; - render::IGeometryRenderer::Slot _surfaceSlot; - public: RenderablePatchTesselation(const PatchTesselation& tess) : _tess(tess), _needsUpdate(true), - _surfaceSlot(render::IGeometryRenderer::InvalidSlot), _size(0) {} - void clear() + void clear() override { - if (!_shader || _surfaceSlot == render::IGeometryRenderer::InvalidSlot) return; - - _shader->removeGeometry(_surfaceSlot); - _shader.reset(); - - _surfaceSlot = render::IGeometryRenderer::InvalidSlot; + RenderableGeometry::clear(); _size = 0; } @@ -218,21 +210,6 @@ class RenderablePatchTesselation : _indexer.generateIndices(_tess, std::back_inserter(indices)); - if (_surfaceSlot == render::IGeometryRenderer::InvalidSlot) - { - _surfaceSlot = shader->addGeometry(_indexer.getType(), _tess.vertices, indices); - } - else - { - shader->updateGeometry(_surfaceSlot, _tess.vertices, indices); - } - } - - void render(const RenderInfo& info) const override - { - if (_surfaceSlot != render::IGeometryRenderer::InvalidSlot && _shader) - { - _shader->renderGeometry(_surfaceSlot); - } + addOrUpdateGeometry(shader, _indexer.getType(), _tess.vertices, indices); } }; diff --git a/tools/msvc/libs.vcxproj b/tools/msvc/libs.vcxproj index 3c8c0de594..f0f96c48f0 100644 --- a/tools/msvc/libs.vcxproj +++ b/tools/msvc/libs.vcxproj @@ -216,6 +216,7 @@ + diff --git a/tools/msvc/libs.vcxproj.filters b/tools/msvc/libs.vcxproj.filters index ac7bb6b82c..0f36a04205 100644 --- a/tools/msvc/libs.vcxproj.filters +++ b/tools/msvc/libs.vcxproj.filters @@ -344,6 +344,9 @@ render + + render +