From c3dd25e4994837de299a3928f855f4f1a6e97ecc Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 7 Jul 2017 18:26:10 +0200 Subject: [PATCH] Drafting the mechanism to add shape pipeline --- .../RenderableParticleEffectEntityItem.cpp | 9 ++++++++ libraries/render/src/render/DrawTask.cpp | 23 +++++++++++++++++-- libraries/render/src/render/Item.h | 4 ++++ libraries/render/src/render/ShapePipeline.h | 20 ++++++++++++++++ 4 files changed, 54 insertions(+), 2 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp index 10bd70be13..5ea8af4d7a 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp @@ -142,6 +142,15 @@ namespace render { payload->render(args); } } + template <> + const ShapeKey shapeGetShapeKey(const ParticlePayloadData::Pointer& payload) { + return ShapeKey::Builder().withCustom(75).build(); + } + + template <> + bool shapeDefineCustomShapePipeline(const ParticlePayloadData::Pointer& payload, ShapePlumber& plumber, const ShapeKey& key) { + return false; + } } diff --git a/libraries/render/src/render/DrawTask.cpp b/libraries/render/src/render/DrawTask.cpp index 13d454e393..ce6e26faf2 100755 --- a/libraries/render/src/render/DrawTask.cpp +++ b/libraries/render/src/render/DrawTask.cpp @@ -44,10 +44,17 @@ void renderShape(RenderArgs* args, const ShapePlumberPointer& shapeContext, cons auto key = item.getShapeKey() | globalKey; if (key.isValid() && !key.hasOwnPipeline()) { args->_pipeline = shapeContext->pickPipeline(args, key); + if (!args->_pipeline) { + if (key.isCustom()) { + if (item.defineCustomShapePipeline(*shapeContext, key)) { + args->_pipeline = shapeContext->pickPipeline(args, key); + } + } + } if (args->_pipeline) { args->_pipeline->prepareShapeItem(args, key, item); item.render(args); - } + } args->_pipeline = nullptr; } else if (key.hasOwnPipeline()) { item.render(args); @@ -111,7 +118,19 @@ void render::renderStateSortShapes(const RenderContextPointer& renderContext, for (auto& pipelineKey : sortedPipelines) { auto& bucket = sortedShapes[pipelineKey]; args->_pipeline = shapeContext->pickPipeline(args, pipelineKey); - if (!args->_pipeline) { + if (!args->_pipeline) { + if (pipelineKey.isCustom()) { + if (bucket.front().defineCustomShapePipeline(*shapeContext, pipelineKey)) { + args->_pipeline = shapeContext->pickPipeline(args, pipelineKey); + if (!args->_pipeline) { + + } else { + continue; + } + } else { + continue; + } + } continue; } for (auto& item : bucket) { diff --git a/libraries/render/src/render/Item.h b/libraries/render/src/render/Item.h index 007b34395d..8ec80a7d7e 100644 --- a/libraries/render/src/render/Item.h +++ b/libraries/render/src/render/Item.h @@ -320,6 +320,7 @@ public: virtual void render(RenderArgs* args) = 0; virtual const ShapeKey getShapeKey() const = 0; + virtual bool defineCustomShapePipeline(ShapePlumber& plumber, const ShapeKey& key) const = 0; virtual uint32_t fetchMetaSubItems(ItemIDs& subItems) const = 0; @@ -369,6 +370,7 @@ public: // Shape Type Interface const ShapeKey getShapeKey() const { return _payload->getShapeKey(); } + bool defineCustomShapePipeline(ShapePlumber& plumber, const ShapeKey& key) const { return _payload->defineCustomShapePipeline(plumber, key); } // Meta Type Interface uint32_t fetchMetaSubItems(ItemIDs& subItems) const { return _payload->fetchMetaSubItems(subItems); } @@ -415,6 +417,7 @@ template void payloadRender(const std::shared_ptr& payloadData, Ren // When creating a new shape payload you need to create a specialized version, or the ShapeKey will be ownPipeline, // implying that the shape will setup its own pipeline without the use of the ShapeKey. template const ShapeKey shapeGetShapeKey(const std::shared_ptr& payloadData) { return ShapeKey::Builder::ownPipeline(); } +template bool shapeDefineCustomShapePipeline(const std::shared_ptr& payloadData, ShapePlumber& plumber, const ShapeKey& key) { return false; } // Meta Type Interface // Meta items act as the grouping object for several sub items (typically shapes). @@ -441,6 +444,7 @@ public: // Shape Type interface virtual const ShapeKey getShapeKey() const override { return shapeGetShapeKey(_data); } + virtual bool defineCustomShapePipeline(ShapePlumber& plumber, const ShapeKey& key) const override { return shapeDefineCustomShapePipeline(_data, plumber, key); } // Meta Type Interface virtual uint32_t fetchMetaSubItems(ItemIDs& subItems) const override { return metaFetchMetaSubItems(_data, subItems); } diff --git a/libraries/render/src/render/ShapePipeline.h b/libraries/render/src/render/ShapePipeline.h index 7b2eff994f..afc0eac011 100644 --- a/libraries/render/src/render/ShapePipeline.h +++ b/libraries/render/src/render/ShapePipeline.h @@ -39,7 +39,19 @@ public: OWN_PIPELINE, INVALID, + CUSTOM_0, + CUSTOM_1, + CUSTOM_2, + CUSTOM_3, + CUSTOM_4, + CUSTOM_5, + CUSTOM_6, + CUSTOM_7, + NUM_FLAGS, // Not a valid flag + + CUSTOM_MASK = (0xFF << CUSTOM_0), + }; using Flags = std::bitset; @@ -74,6 +86,8 @@ public: Builder& withOwnPipeline() { _flags.set(OWN_PIPELINE); return (*this); } Builder& invalidate() { _flags.set(INVALID); return (*this); } + Builder& withCustom(uint8_t custom) { _flags &= (~CUSTOM_MASK); _flags |= (custom << CUSTOM_0); return (*this); } + static const ShapeKey ownPipeline() { return Builder().withOwnPipeline(); } static const ShapeKey invalid() { return Builder().invalidate(); } @@ -128,6 +142,9 @@ public: Builder& withCullFace() { _flags.reset(NO_CULL_FACE); _mask.set(NO_CULL_FACE); return (*this); } Builder& withoutCullFace() { _flags.set(NO_CULL_FACE); _mask.set(NO_CULL_FACE); return (*this); } + Builder& withCustom(uint8_t custom) { _flags &= (~CUSTOM_MASK); _flags |= (custom << CUSTOM_0); _mask |= (CUSTOM_MASK); return (*this); } + Builder& withoutCustom() { _flags &= (~CUSTOM_MASK); _mask |= (CUSTOM_MASK); return (*this); } + protected: friend class Filter; Flags _flags{0}; @@ -156,6 +173,9 @@ public: bool hasOwnPipeline() const { return _flags[OWN_PIPELINE]; } bool isValid() const { return !_flags[INVALID]; } + uint8_t getCustom() const { return (_flags.to_ulong() & CUSTOM_MASK) >> CUSTOM_0; } + bool isCustom() const { return (_flags.to_ulong() & CUSTOM_MASK); } + // Comparator for use in stl containers class Hash { public: