diff --git a/include/vsg/app/View.h b/include/vsg/app/View.h index d1c4b97a0..a2393da8d 100644 --- a/include/vsg/app/View.h +++ b/include/vsg/app/View.h @@ -26,6 +26,9 @@ namespace vsg public: View(); + // share the specified view's children, viewID, mask and camera ViewportState + View(const View& view); + explicit View(ref_ptr in_camera, ref_ptr in_scenegraph = {}); template @@ -46,6 +49,9 @@ namespace vsg void accept(ConstVisitor& visitor) const override { t_accept(*this, visitor); } void accept(RecordTraversal& visitor) const override { t_accept(*this, visitor); } + /// share the specified view's viewID, mask, camera ViewportState, with this View + void share(const View& view); + /// camera controls the viewport state and projection and view matrices ref_ptr camera; diff --git a/include/vsg/state/GraphicsPipeline.h b/include/vsg/state/GraphicsPipeline.h index f9323e1e1..b8a7583d2 100644 --- a/include/vsg/state/GraphicsPipeline.h +++ b/include/vsg/state/GraphicsPipeline.h @@ -58,8 +58,12 @@ namespace vsg GraphicsPipeline(PipelineLayout* pipelineLayout, const ShaderStages& shaderStages, const GraphicsPipelineStates& pipelineStates, uint32_t subpass = 0); + /// return the Vukan Pipeline for specified viewID. VkPipeline vk(uint32_t viewID) const { return _implementation[viewID]->_pipeline; } + /// variant of vk(viewID) method that is slower but adds validation of the viewID parameter + VkPipeline validated_vk(uint32_t viewID) const { return (viewID < _implementation.size()) ? (_implementation[viewID] ? _implementation[viewID]->_pipeline : 0) : 0; } + /// VkGraphicsPipelineCreateInfo settings ShaderStages stages; GraphicsPipelineStates pipelineStates; diff --git a/src/vsg/app/View.cpp b/src/vsg/app/View.cpp index 6e17e1417..d54373d73 100644 --- a/src/vsg/app/View.cpp +++ b/src/vsg/app/View.cpp @@ -18,7 +18,7 @@ using namespace vsg; // thread safe container for managing the deviceID for each vsg::View static std::mutex s_ViewCountMutex; -static std::vector s_ActiveViews; +static std::vector s_ActiveViews; static uint32_t getUniqueViewID() { @@ -27,14 +27,30 @@ static uint32_t getUniqueViewID() uint32_t viewID = 0; for (viewID = 0; viewID < static_cast(s_ActiveViews.size()); ++viewID) { - if (!s_ActiveViews[viewID]) + if (s_ActiveViews[viewID]==0) { - s_ActiveViews[viewID] = true; + ++s_ActiveViews[viewID]; return viewID; } } - s_ActiveViews.push_back(true); + s_ActiveViews.push_back(1); + + return viewID; +} + +static uint32_t sharedViewID(uint32_t viewID) +{ + std::scoped_lock guard(s_ViewCountMutex); + + if (viewID < static_cast(s_ActiveViews.size())) + { + ++s_ActiveViews[viewID]; + return viewID; + } + + viewID = static_cast(s_ActiveViews.size()); + s_ActiveViews.push_back(1); return viewID; } @@ -42,7 +58,7 @@ static uint32_t getUniqueViewID() static void releaseViewID(uint32_t viewID) { std::scoped_lock guard(s_ViewCountMutex); - s_ActiveViews[viewID] = false; + --s_ActiveViews[viewID]; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -55,6 +71,18 @@ View::View() : { } +View::View(const View& view): + Inherit(view), + viewID(sharedViewID(view.viewID)), + mask(view.mask) +{ + if (view.camera && view.camera->viewportState) + { + camera = vsg::Camera::create(); + camera->viewportState = view.camera->viewportState; + } +} + View::View(ref_ptr in_camera, ref_ptr in_scenegraph) : camera(in_camera), viewID(getUniqueViewID()), @@ -67,3 +95,19 @@ View::~View() { releaseViewID(viewID); } + +void View::share(const View& view) +{ + if (viewID != view.viewID) + { + releaseViewID(viewID); + const_cast(viewID) = sharedViewID(view.viewID); + } + + mask = view.mask; + if (view.camera && view.camera->viewportState) + { + if (!camera) camera = vsg::Camera::create(); + camera->viewportState = view.camera->viewportState; + } +}