diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index fa730c5d40..6facf0c19a 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -672,7 +672,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : initializeGL(); // Start rendering - _renderEngine->addTask(make_shared()); + _renderEngine->addTask(make_shared(LODManager::shouldRender)); _renderEngine->registerScene(_main3DScene); _offscreenContext->makeCurrent(); @@ -3826,7 +3826,6 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se auto renderInterface = DependencyManager::get(); auto renderContext = renderInterface->getRenderContext(); - renderArgs->_shouldRender = LODManager::shouldRender; renderArgs->_viewFrustum = getDisplayViewFrustum(); renderContext.setArgs(renderArgs); diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index dc3e5c652b..455c9acc31 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -72,7 +72,9 @@ void ToneMappingDeferred::run(const SceneContextPointer& sceneContext, const Ren _toneMappingEffect.render(renderContext->getArgs()); } -RenderDeferredTask::RenderDeferredTask() : Task() { +RenderDeferredTask::RenderDeferredTask(CullFunctor cullFunctor) : Task() { + cullFunctor = cullFunctor ? cullFunctor : [](const RenderArgs*, const AABox&){ return true; }; + // Prepare the ShapePipelines ShapePlumberPointer shapePlumber = std::make_shared(); initDeferredPipelines(*shapePlumber); @@ -81,7 +83,7 @@ RenderDeferredTask::RenderDeferredTask() : Task() { auto fetchedOpaques = addJob("FetchOpaque", FetchItems([](const RenderContextPointer& context, int count) { context->getItemsConfig().opaque.numFeed = count; })); - auto culledOpaques = addJob>("CullOpaque", fetchedOpaques); + auto culledOpaques = addJob>("CullOpaque", fetchedOpaques, cullFunctor); auto opaques = addJob("DepthSortOpaque", culledOpaques); // CPU only, create the list of renderedTransparents items @@ -91,7 +93,7 @@ RenderDeferredTask::RenderDeferredTask() : Task() { context->getItemsConfig().transparent.numFeed = count; } )); - auto culledTransparents = addJob>("CullTransparent", fetchedTransparents); + auto culledTransparents = addJob>("CullTransparent", fetchedTransparents, cullFunctor); auto transparents = addJob("DepthSortTransparent", culledTransparents, DepthSortItems(false)); // GPU Jobs: Start preparing the deferred and lighting buffer @@ -107,7 +109,7 @@ RenderDeferredTask::RenderDeferredTask() : Task() { addJob("DrawBackgroundDeferred"); // Draw Lights just add the lights to the current list of lights to deal with. NOt really gpu job for now. - addJob("DrawLight"); + addJob("DrawLight", cullFunctor); // DeferredBuffer is complete, now let's shade it into the LightingBuffer addJob("RenderDeferred"); @@ -174,6 +176,7 @@ void RenderDeferredTask::run(const SceneContextPointer& sceneContext, const Rend setAntialiasingStatus(renderContext->getFxaaStatus()); setToneMappingExposure(renderContext->getTone().exposure); setToneMappingToneCurve(renderContext->getTone().toneCurve); + // TODO: Allow runtime manipulation of culling ShouldRenderFunctor for (auto job : _jobs) { job.run(sceneContext, renderContext); diff --git a/libraries/render-utils/src/RenderDeferredTask.h b/libraries/render-utils/src/RenderDeferredTask.h index 4fe0c75198..3c195f3492 100755 --- a/libraries/render-utils/src/RenderDeferredTask.h +++ b/libraries/render-utils/src/RenderDeferredTask.h @@ -12,10 +12,10 @@ #ifndef hifi_RenderDeferredTask_h #define hifi_RenderDeferredTask_h -#include "render/Engine.h" - #include "gpu/Pipeline.h" +#include "render/DrawTask.h" + #include "ToneMappingEffect.h" class SetupDeferred { @@ -113,15 +113,8 @@ public: class RenderDeferredTask : public render::Task { public: - RenderDeferredTask(); + RenderDeferredTask(render::CullFunctor cullFunctor); - int _drawDebugDeferredBufferIndex; - int _drawStatusJobIndex; - int _drawHitEffectJobIndex; - int _occlusionJobIndex; - int _antialiasingJobIndex; - int _toneMappingJobIndex; - void setDrawDebugDeferredBuffer(int draw) { enableJob(_drawDebugDeferredBufferIndex, draw >= 0); } bool doDrawDebugDeferredBuffer() const { return getEnableJob(_drawDebugDeferredBufferIndex); } @@ -147,6 +140,14 @@ public: int getToneMappingToneCurve() const; virtual void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); + +protected: + int _drawDebugDeferredBufferIndex; + int _drawStatusJobIndex; + int _drawHitEffectJobIndex; + int _occlusionJobIndex; + int _antialiasingJobIndex; + int _toneMappingJobIndex; }; #endif // hifi_RenderDeferredTask_h diff --git a/libraries/render-utils/src/RenderShadowTask.cpp b/libraries/render-utils/src/RenderShadowTask.cpp index b6b9f15f60..f608f64379 100644 --- a/libraries/render-utils/src/RenderShadowTask.cpp +++ b/libraries/render-utils/src/RenderShadowTask.cpp @@ -77,7 +77,9 @@ void RenderShadowMap::run(const render::SceneContextPointer& sceneContext, const }); } -RenderShadowTask::RenderShadowTask() : Task() { +RenderShadowTask::RenderShadowTask(CullFunctor cullFunctor) : Task() { + cullFunctor = cullFunctor ? cullFunctor : [](const RenderArgs*, const AABox&){ return true; }; + // Prepare the ShapePipeline ShapePlumberPointer shapePlumber = std::make_shared(); { @@ -104,7 +106,7 @@ RenderShadowTask::RenderShadowTask() : Task() { auto fetchedItems = addJob("FetchShadowMap"); // CPU: Cull against KeyLight frustum (nearby viewing camera) - auto culledItems = addJob>("CullShadowMap", fetchedItems); + auto culledItems = addJob>("CullShadowMap", fetchedItems, cullFunctor); // CPU: Sort by pipeline auto sortedShapes = addJob("PipelineSortShadowSort", culledItems); @@ -142,6 +144,7 @@ void RenderShadowTask::run(const SceneContextPointer& sceneContext, const Render // Set the keylight frustum args->_viewFrustum = globalLight->shadow.getFrustum().get(); + // TODO: Allow runtime manipulation of culling ShouldRenderFunctor for (auto job : _jobs) { job.run(sceneContext, renderContext); diff --git a/libraries/render-utils/src/RenderShadowTask.h b/libraries/render-utils/src/RenderShadowTask.h index 4853022359..add021994a 100644 --- a/libraries/render-utils/src/RenderShadowTask.h +++ b/libraries/render-utils/src/RenderShadowTask.h @@ -15,7 +15,6 @@ #include #include -#include #include class ViewFrustum; @@ -33,7 +32,7 @@ protected: class RenderShadowTask : public render::Task { public: - RenderShadowTask(); + RenderShadowTask(render::CullFunctor shouldRender); void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); }; diff --git a/libraries/render/src/render/DrawTask.cpp b/libraries/render/src/render/DrawTask.cpp index 68e1841345..191cb693fd 100755 --- a/libraries/render/src/render/DrawTask.cpp +++ b/libraries/render/src/render/DrawTask.cpp @@ -20,14 +20,15 @@ using namespace render; -void render::cullItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outItems) { +void render::cullItems(const RenderContextPointer& renderContext, const CullFunctor& cullFunctor, RenderDetails::Item& details, + const ItemIDsBounds& inItems, ItemIDsBounds& outItems) { assert(renderContext->getArgs()); assert(renderContext->getArgs()->_viewFrustum); RenderArgs* args = renderContext->getArgs(); - auto renderDetails = renderContext->getArgs()->_details._item; + ViewFrustum* frustum = args->_viewFrustum; - renderDetails->_considered += inItems.size(); + details._considered += inItems.size(); // Culling / LOD for (auto item : inItems) { @@ -41,24 +42,24 @@ void render::cullItems(const SceneContextPointer& sceneContext, const RenderCont bool outOfView; { PerformanceTimer perfTimer("boxInFrustum"); - outOfView = args->_viewFrustum->boxInFrustum(item.bounds) == ViewFrustum::OUTSIDE; + outOfView = frustum->boxInFrustum(item.bounds) == ViewFrustum::OUTSIDE; } if (!outOfView) { bool bigEnoughToRender; { PerformanceTimer perfTimer("shouldRender"); - bigEnoughToRender = (args->_shouldRender) ? args->_shouldRender(args, item.bounds) : true; + bigEnoughToRender = cullFunctor(args, item.bounds); } if (bigEnoughToRender) { outItems.emplace_back(item); // One more Item to render } else { - renderDetails->_tooSmall++; + details._tooSmall++; } } else { - renderDetails->_outOfView++; + details._outOfView++; } } - renderDetails->_rendered += outItems.size(); + details._rendered += outItems.size(); } struct ItemBound { @@ -202,10 +203,10 @@ void DrawLight::run(const SceneContextPointer& sceneContext, const RenderContext RenderArgs* args = renderContext->getArgs(); + auto& details = args->_details.edit(RenderDetails::OTHER_ITEM); ItemIDsBounds culledItems; culledItems.reserve(inItems.size()); - args->_details.pointTo(RenderDetails::OTHER_ITEM); - cullItems(sceneContext, renderContext, inItems, culledItems); + cullItems(renderContext, _cullFunctor, details, inItems, culledItems); gpu::doInBatch(args->_context, [&](gpu::Batch& batch) { args->_batch = &batch; diff --git a/libraries/render/src/render/DrawTask.h b/libraries/render/src/render/DrawTask.h index 5ad1bbf8d4..684d8bf4ea 100755 --- a/libraries/render/src/render/DrawTask.h +++ b/libraries/render/src/render/DrawTask.h @@ -19,7 +19,10 @@ namespace render { -void cullItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outItems); +using CullFunctor = std::function; + +void cullItems(const RenderContextPointer& renderContext, const CullFunctor& cullFunctor, RenderDetails::Item& details, + const ItemIDsBounds& inItems, ItemIDsBounds& outItems); void depthSortItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, bool frontToBack, const ItemIDsBounds& inItems, ItemIDsBounds& outItems); void renderItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems); void renderShapes(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ShapePlumberPointer& shapeContext, const ItemIDsBounds& inItems, int maxDrawnItems = -1); @@ -41,14 +44,20 @@ public: template class CullItems { public: + CullItems(CullFunctor cullFunctor) : _cullFunctor{ cullFunctor } {} + void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outItems) { + const auto& args = renderContext->getArgs(); + auto& details = args->_details.edit(T); outItems.clear(); outItems.reserve(inItems.size()); - renderContext->getArgs()->_details.pointTo(T); - render::cullItems(sceneContext, renderContext, inItems, outItems); + render::cullItems(renderContext, _cullFunctor, details, inItems, outItems); } using JobModel = Task::Job::ModelIO, ItemIDsBounds, ItemIDsBounds>; + +protected: + CullFunctor _cullFunctor; }; class DepthSortItems { @@ -62,8 +71,12 @@ public: class DrawLight { public: + DrawLight(CullFunctor cullFunctor) : _cullFunctor{ cullFunctor } {} void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); using JobModel = Task::Job::Model; + +protected: + CullFunctor _cullFunctor; }; class PipelineSortShapes { diff --git a/libraries/shared/src/RenderArgs.h b/libraries/shared/src/RenderArgs.h index e5dfd5f8ea..7012c78c8f 100644 --- a/libraries/shared/src/RenderArgs.h +++ b/libraries/shared/src/RenderArgs.h @@ -56,34 +56,25 @@ public: Item _translucent; Item _other; - Item* _item = &_other; - - void pointTo(Type type) { + Item& edit(Type type) { switch (type) { case OPAQUE_ITEM: - _item = &_opaque; - break; + return _opaque; case SHADOW_ITEM: - _item = &_shadow; - break; + return _shadow; case TRANSLUCENT_ITEM: - _item = &_translucent; - break; + return _translucent; case OTHER_ITEM: - _item = &_other; - break; + default: + return _other; } } }; class RenderArgs { public: - typedef std::function ShoudRenderFunctor; - enum RenderMode { DEFAULT_RENDER_MODE, SHADOW_RENDER_MODE, DIFFUSE_RENDER_MODE, NORMAL_RENDER_MODE, MIRROR_RENDER_MODE }; - enum RenderSide { MONO, STEREO_LEFT, STEREO_RIGHT }; - enum DebugFlags { RENDER_DEBUG_NONE = 0, RENDER_DEBUG_HULLS = 1 @@ -97,8 +88,7 @@ public: RenderMode renderMode = DEFAULT_RENDER_MODE, RenderSide renderSide = MONO, DebugFlags debugFlags = RENDER_DEBUG_NONE, - gpu::Batch* batch = nullptr, - ShoudRenderFunctor shouldRender = nullptr) : + gpu::Batch* batch = nullptr) : _context(context), _renderer(renderer), _viewFrustum(viewFrustum), @@ -107,8 +97,7 @@ public: _renderMode(renderMode), _renderSide(renderSide), _debugFlags(debugFlags), - _batch(batch), - _shouldRender(shouldRender) { + _batch(batch) { } std::shared_ptr _context = nullptr; @@ -123,7 +112,6 @@ public: RenderSide _renderSide = MONO; DebugFlags _debugFlags = RENDER_DEBUG_NONE; gpu::Batch* _batch = nullptr; - ShoudRenderFunctor _shouldRender; std::shared_ptr _whiteTexture;