diff --git a/libraries/entities-renderer/src/RenderableEntityItem.cpp b/libraries/entities-renderer/src/RenderableEntityItem.cpp index 355a004594..7cf98b861d 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableEntityItem.cpp @@ -14,6 +14,11 @@ namespace render { template <> const ItemKey payloadGetKey(const RenderableEntityItem::Pointer& payload) { + if (payload && payload->entity) { + if (payload->entity->getType() == EntityTypes::Light) { + return ItemKey::Builder::light(); + } + } return ItemKey::Builder::opaqueShape(); } diff --git a/libraries/render/src/render/DrawTask.cpp b/libraries/render/src/render/DrawTask.cpp index 2c30d0e2f8..bbee0d3cc8 100755 --- a/libraries/render/src/render/DrawTask.cpp +++ b/libraries/render/src/render/DrawTask.cpp @@ -19,6 +19,80 @@ using namespace render; +Job::~Job() { +} + +template <> void render::jobRun(const FilterItems& filterItems, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + auto& scene = sceneContext->_scene; + +} + +template <> void render::jobRun(const RenderItems& renderItems, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + auto& scene = sceneContext->_scene; + RenderArgs* args = renderContext->args; + // render + for (auto id : renderItems._items) { + auto item = scene->getItem(id); + item.render(args); + } +} + + + + +template <> void render::jobRun(const DrawOpaque& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + // render opaques + auto& scene = sceneContext->_scene; + auto& items = scene->getMasterBucket().at(ItemFilter::Builder::opaqueShape()); + + RenderArgs* args = renderContext->args; + gpu::Batch theBatch; + args->_batch = &theBatch; + for (auto id : items) { + auto item = scene->getItem(id); + item.render(args); + } + + args->_context->enqueueBatch((*args->_batch)); + args->_batch = nullptr; +} + + +template <> void render::jobRun(const DrawTransparent& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + // render transparents + auto& scene = sceneContext->_scene; + auto& items = scene->getMasterBucket().at(ItemFilter::Builder::transparentShape()); + + RenderArgs* args = renderContext->args; + gpu::Batch theBatch; + args->_batch = &theBatch; + for (auto id : items) { + auto item = scene->getItem(id); + item.render(args); + } + + args->_context->enqueueBatch((*args->_batch)); + args->_batch = nullptr; +} + +template <> void render::jobRun(const DrawLight& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + // render lights + auto& scene = sceneContext->_scene; + auto& items = scene->getMasterBucket().at(ItemFilter::Builder::light()); + + RenderArgs* args = renderContext->args; + for (auto id : items) { + auto item = scene->getItem(id); + item.render(args); + } +} + +DrawSceneTask::DrawSceneTask() : Task() { + + _jobs.push_back(Job(DrawOpaque())); + _jobs.push_back(Job(DrawLight())); + _jobs.push_back(Job(DrawTransparent())); +} DrawSceneTask::~DrawSceneTask() { } @@ -29,25 +103,9 @@ void DrawSceneTask::run(const SceneContextPointer& sceneContext, const RenderCon if (!sceneContext->_scene) { return; } - auto& scene = sceneContext->_scene; - auto& itemBucketMap = scene->getMasterBucket(); - - RenderArgs* args = renderContext->args; - gpu::Batch theBatch; - - args->_batch = &theBatch; - - // render opaques - auto filter = ItemFilter::Builder::opaqueShape(); - auto& opaqueShapeItems = itemBucketMap.at(filter); - - for (auto id : opaqueShapeItems) { - auto item = scene->getItem(id); - item.render(args); + for (auto job : _jobs) { + job.run(sceneContext, renderContext); } - - args->_context->enqueueBatch((*args->_batch)); - args->_batch = nullptr; }; diff --git a/libraries/render/src/render/DrawTask.h b/libraries/render/src/render/DrawTask.h index efa67b78ab..8556129b3f 100755 --- a/libraries/render/src/render/DrawTask.h +++ b/libraries/render/src/render/DrawTask.h @@ -16,19 +16,91 @@ namespace render { +template void jobRun(const T& jobModel, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { } -class DrawSceneTask : public Task { +class Job { public: - DrawSceneTask() : Task() {} - ~DrawSceneTask(); + template + Job(T data) : _concept(new Model(data)) {} + Job(const Job& other) : _concept(other._concept) {} + ~Job(); - virtual void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); + virtual void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + if (_concept) { + _concept->run(sceneContext, renderContext); + } + } + +protected: + class Concept { + public: + virtual ~Concept() = default; + virtual void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) = 0; + }; + + template class Model : public Concept { + public: + typedef T Data; + + Data _data; + Model(Data data): _data(data) {} + + void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { jobRun(_data, sceneContext, renderContext); } + }; + + std::shared_ptr _concept; }; +typedef std::vector Jobs; + + + +class DrawOpaque { +public: + Jobs _jobs; +}; +template <> void jobRun(const DrawOpaque& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); + + +class DrawTransparent { +public: +}; +template <> void jobRun(const DrawTransparent& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); + +class DrawLight { +public: +}; +template <> void jobRun(const DrawLight& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); + + +class FilterItems { +public: + ItemIDs _items; +}; +template <> void jobRun(const FilterItems& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); + +class RenderItems { +public: + ItemIDs _items; +}; +template <> void jobRun(const RenderItems& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); + + +class DrawSceneTask : public Task { +public: + + DrawSceneTask(); + ~DrawSceneTask(); + + Jobs _jobs; + + virtual void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); +}; + } #endif // hifi_render_Task_h diff --git a/libraries/render/src/render/Scene.cpp b/libraries/render/src/render/Scene.cpp index 8f9c5906ca..d653563dd1 100644 --- a/libraries/render/src/render/Scene.cpp +++ b/libraries/render/src/render/Scene.cpp @@ -47,6 +47,8 @@ void ItemBucketMap::reset(const ItemID& id, const ItemKey& oldKey, const ItemKey void ItemBucketMap::allocateStandardOpaqueTranparentBuckets() { (*this)[ItemFilter::Builder::opaqueShape()]; (*this)[ItemFilter::Builder::transparentShape()]; + auto lightFilter = ItemFilter::Builder().withTypeLight().build(); + (*this)[lightFilter]; } diff --git a/libraries/render/src/render/Scene.h b/libraries/render/src/render/Scene.h index c7d112e74b..c1771db52f 100644 --- a/libraries/render/src/render/Scene.h +++ b/libraries/render/src/render/Scene.h @@ -53,7 +53,7 @@ public: ItemKey(const Flags& flags) : _flags(flags) {} class Builder { - Flags _flags; + Flags _flags{ 0 }; public: Builder() {} @@ -72,6 +72,7 @@ public: // Convenient standard keys that we will keep on using all over the place static ItemKey opaqueShape() { return Builder().withTypeShape().build(); } static ItemKey transparentShape() { return Builder().withTypeShape().withTransparent().build(); } + static ItemKey light() { return Builder().withTypeLight().build(); } }; bool isOpaque() const { return !_flags[TRANSLUCENT]; } @@ -111,8 +112,8 @@ public: ItemFilter(const ItemKey::Flags& value = ItemKey::Flags(0), const ItemKey::Flags& mask = ItemKey::Flags(0)) : _value(value), _mask(mask) {} class Builder { - ItemKey::Flags _value; - ItemKey::Flags _mask; + ItemKey::Flags _value{ 0 }; + ItemKey::Flags _mask{ 0 }; public: Builder() {} @@ -142,8 +143,9 @@ public: Builder& withPickable() { _value.set(ItemKey::PICKABLE); _mask.set(ItemKey::PICKABLE); return (*this); } // Convenient standard keys that we will keep on using all over the place - static ItemFilter opaqueShape() { return Builder().withTypeShape().withOpaque().build(); } - static ItemFilter transparentShape() { return Builder().withTypeShape().withTransparent().build(); } + static ItemFilter opaqueShape() { return Builder().withTypeShape().withOpaque().withWorldSpace().build(); } + static ItemFilter transparentShape() { return Builder().withTypeShape().withTransparent().withWorldSpace().build(); } + static ItemFilter light() { return Builder().withTypeLight().build(); } }; // Item Filter operator testing if a key pass the filter @@ -152,10 +154,10 @@ public: class Less { public: bool operator() (const ItemFilter& left, const ItemFilter& right) const { - if (left._value.to_ulong() >= right._value.to_ulong()) { + if (left._value.to_ulong() == right._value.to_ulong()) { return left._mask.to_ulong() < right._mask.to_ulong(); } else { - return true; + return left._value.to_ulong() < right._value.to_ulong(); } } };