From 35b8d45beedc80dbd10bb30aa8d3b4225cf453c4 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Sun, 24 May 2015 17:03:43 -0700 Subject: [PATCH] Insert a first scene and the engine in the Application and render a first Item --- interface/src/Application.cpp | 39 ++++++++++++++++++++++- interface/src/Application.h | 4 +++ libraries/render/src/render/DrawTask.cpp | 9 +++--- libraries/render/src/render/Engine.cpp | 7 +++++ libraries/render/src/render/Engine.h | 4 ++- libraries/render/src/render/Scene.cpp | 23 ++++++++++++-- libraries/render/src/render/Scene.h | 40 +++++++++++------------- 7 files changed, 97 insertions(+), 29 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f6c9195c16..f71510cb27 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -369,7 +369,11 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : _bookmarks = new Bookmarks(); // Before setting up the menu _runningScriptsWidget = new RunningScriptsWidget(_window); - + + + _renderEngine->buildStandardTaskPipeline(); + _renderEngine->registerScene(_main3DScene); + // start the nodeThread so its event loop is running QThread* nodeThread = new QThread(this); nodeThread->setObjectName("Datagram Processor Thread"); @@ -3145,6 +3149,22 @@ const ViewFrustum* Application::getDisplayViewFrustum() const { return &_displayViewFrustum; } +class MyFirstStuff { +public: + typedef render::Payload Payload; + typedef std::shared_ptr Pointer; + +}; + +template <> const render::ItemKey render::payloadGetKey(const MyFirstStuff::Pointer& stuff) { return ItemKey::Builder::opaqueShape(); } +template <> const render::Item::Bound render::payloadGetBound(const MyFirstStuff::Pointer& stuff) { return Item::Bound(); } +template <> void render::payloadRender(const MyFirstStuff::Pointer& stuff, RenderArgs* args) { + if (args) { + args->_elementsTouched ++; + } +} + + void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs::RenderSide renderSide) { activeRenderingThread = QThread::currentThread(); PROFILE_RANGE(__FUNCTION__); @@ -3362,6 +3382,23 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs false, selfAvatarOnly); } + static render::ItemID myFirstRenderItem = 0; + + if (myFirstRenderItem == 0) { + std::shared_ptr myFirstPayload(new MyFirstStuff::Payload(std::shared_ptr(new MyFirstStuff()))); + myFirstRenderItem = _main3DScene->allocateID(); + + render::Scene::PendingChanges pendingChanges; + pendingChanges.resetItem(myFirstRenderItem, myFirstPayload); + + _main3DScene->enqueuePendingChanges(pendingChanges); + } + + _main3DScene->processPendingChangesQueue(); + + // Before the deferred pass, let's try to use the render engine + _renderEngine->run(); + { DependencyManager::get()->setAmbientLightMode(getRenderAmbientLight()); auto skyStage = DependencyManager::get()->getSkyStage(); diff --git a/interface/src/Application.h b/interface/src/Application.h index 2226c97b99..0e24de4e0a 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -77,6 +77,7 @@ #include "octree/OctreePacketProcessor.h" #include "UndoStackScriptingInterface.h" +#include "render/Engine.h" class QGLWidget; class QKeyEvent; @@ -670,6 +671,9 @@ private: int _maxOctreePPS = DEFAULT_MAX_OCTREE_PPS; quint64 _lastFaceTrackerUpdate; + + render::ScenePointer _main3DScene{ new render::Scene() }; + render::EnginePointer _renderEngine{ new render::Engine() }; }; #endif // hifi_Application_h diff --git a/libraries/render/src/render/DrawTask.cpp b/libraries/render/src/render/DrawTask.cpp index f44291ea15..36eafb5672 100755 --- a/libraries/render/src/render/DrawTask.cpp +++ b/libraries/render/src/render/DrawTask.cpp @@ -23,17 +23,18 @@ void DrawSceneTask::run(const SceneContextPointer& sceneContext) { if (!sceneContext->_scene) { return; } - auto scene = sceneContext->_scene; + auto& scene = sceneContext->_scene; - auto itemBucketMap = scene->getMasterBucket(); + auto& itemBucketMap = scene->getMasterBucket(); RenderArgs args; // render opaques - auto& opaqueShapeItems = itemBucketMap[ItemFilter::Builder::opaqueShape()]; + auto filter = ItemFilter::Builder::opaqueShape(); + auto& opaqueShapeItems = itemBucketMap.at(filter); for (auto id : opaqueShapeItems) { auto item = scene->getItem(id); - item.render(&args); + item.render(&args); } }; diff --git a/libraries/render/src/render/Engine.cpp b/libraries/render/src/render/Engine.cpp index 8648f2c583..d1e2a87b78 100644 --- a/libraries/render/src/render/Engine.cpp +++ b/libraries/render/src/render/Engine.cpp @@ -10,6 +10,7 @@ // #include "Engine.h" +#include "DrawTask.h" using namespace render; @@ -34,5 +35,11 @@ void Engine::run() { } } +void Engine::buildStandardTaskPipeline() { + if (!_tasks.empty()) { + _tasks.clear(); + } + addTask(TaskPointer(new DrawSceneTask())); +} diff --git a/libraries/render/src/render/Engine.h b/libraries/render/src/render/Engine.h index 755d302ecf..0c7adadd79 100644 --- a/libraries/render/src/render/Engine.h +++ b/libraries/render/src/render/Engine.h @@ -57,6 +57,9 @@ public: void run(); + // standard pipeline of tasks + void buildStandardTaskPipeline(); + protected: Tasks _tasks; @@ -65,7 +68,6 @@ protected: }; typedef std::shared_ptr EnginePointer; - } #endif // hifi_render_Engine_h diff --git a/libraries/render/src/render/Scene.cpp b/libraries/render/src/render/Scene.cpp index 21d6dc1bc3..a59f9b9d20 100644 --- a/libraries/render/src/render/Scene.cpp +++ b/libraries/render/src/render/Scene.cpp @@ -49,7 +49,26 @@ void ItemBucketMap::allocateStandardOpaqueTranparentBuckets() { (*this)[ItemFilter::Builder::transparentShape()]; } -void Scene::PendingChanges::resetItem(ItemID id, PayloadPointer& payload) { + +void Item::resetPayload(const PayloadPointer& payload) { + if (!payload) { + kill(); + } else { + _payload = payload; + _key = _payload->getKey(); + } +} + +void Item::kill() { + _payload.reset(); + _key._flags.reset(); +} + +void Item::move() { + +} + +void Scene::PendingChanges::resetItem(ItemID id, const PayloadPointer& payload) { _resetItems.push_back(id); _resetPayloads.push_back(payload); } @@ -123,7 +142,7 @@ void Scene::resetItems(const ItemIDs& ids, Payloads& payloads) { auto resetID = ids.begin(); auto resetPayload = payloads.begin(); for (;resetID != ids.end(); resetID++, resetPayload++) { - auto item = _items[(*resetID)]; + auto& item = _items[(*resetID)]; auto oldKey = item.getKey(); item.resetPayload(*resetPayload); diff --git a/libraries/render/src/render/Scene.h b/libraries/render/src/render/Scene.h index 5d33d74fca..685e8c1a72 100644 --- a/libraries/render/src/render/Scene.h +++ b/libraries/render/src/render/Scene.h @@ -33,7 +33,7 @@ public: enum FlagBit { TYPE_SHAPE = 0, // Item is a Shape TYPE_LIGHT, // Item is a Light - TRANSPARENT, // Transparent and not opaque + TRANSLUCENT, // Transparent and not opaque, for some odd reason TRANSPARENCY doesn't work... VIEW_SPACE, // Transformed in view space, and not in world space DYNAMIC, // Dynamic and bound will change unlike static item DEFORMED, // Deformed within bound, not solid @@ -42,7 +42,6 @@ public: PICKABLE, // Item can be picked/selected NUM_FLAGS, // Not a valid flag - ALL_FLAGS_MASK = 0xFFFF, }; typedef std::bitset Flags; @@ -57,11 +56,11 @@ public: public: Builder() {} - const ItemKey build() const { return ItemKey(_flags); } + ItemKey build() const { return ItemKey(_flags); } Builder& withTypeShape() { _flags.set(TYPE_SHAPE); return (*this); } Builder& withTypeLight() { _flags.set(TYPE_LIGHT); return (*this); } - Builder& withTransparent() { _flags.set(TRANSPARENT); return (*this); } + Builder& withTransparent() { _flags.set(TRANSLUCENT); return (*this); } Builder& withViewSpace() { _flags.set(VIEW_SPACE); return (*this); } Builder& withDynamic() { _flags.set(DYNAMIC); return (*this); } Builder& withDeformed() { _flags.set(DEFORMED); return (*this); } @@ -70,12 +69,12 @@ public: Builder& withPickable() { _flags.set(PICKABLE); return (*this); } // Convenient standard keys that we will keep on using all over the place - static const ItemKey opaqueShape() { return Builder().withTypeShape().build(); } - static const ItemKey transparentShape() { return Builder().withTypeShape().withTransparent().build(); } + static ItemKey opaqueShape() { return Builder().withTypeShape().build(); } + static ItemKey transparentShape() { return Builder().withTypeShape().withTransparent().build(); } }; - bool isOpaque() const { return !_flags[TRANSPARENT]; } - bool isTransparent() const { return _flags[TRANSPARENT]; } + bool isOpaque() const { return !_flags[TRANSLUCENT]; } + bool isTransparent() const { return _flags[TRANSLUCENT]; } bool isWorldSpace() const { return !_flags[VIEW_SPACE]; } bool isViewSpace() const { return _flags[VIEW_SPACE]; } @@ -109,13 +108,13 @@ public: public: Builder() {} - const ItemFilter build() const { return ItemFilter(_value, _mask); } + ItemFilter build() const { return ItemFilter(_value, _mask); } Builder& withTypeShape() { _value.set(ItemKey::TYPE_SHAPE); _mask.set(ItemKey::TYPE_SHAPE); return (*this); } Builder& withTypeLight() { _value.set(ItemKey::TYPE_LIGHT); _mask.set(ItemKey::TYPE_LIGHT); return (*this); } - Builder& withOpaque() { _value.reset(ItemKey::TRANSPARENT); _mask.set(ItemKey::TRANSPARENT); return (*this); } - Builder& withTransparent() { _value.set(ItemKey::TRANSPARENT); _mask.set(ItemKey::TRANSPARENT); return (*this); } + Builder& withOpaque() { _value.reset(ItemKey::TRANSLUCENT); _mask.set(ItemKey::TRANSLUCENT); return (*this); } + Builder& withTransparent() { _value.set(ItemKey::TRANSLUCENT); _mask.set(ItemKey::TRANSLUCENT); return (*this); } Builder& withWorldSpace() { _value.reset(ItemKey::VIEW_SPACE); _mask.set(ItemKey::VIEW_SPACE); return (*this); } Builder& withViewSpace() { _value.set(ItemKey::VIEW_SPACE); _mask.set(ItemKey::VIEW_SPACE); return (*this); } @@ -135,8 +134,8 @@ 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 const ItemFilter opaqueShape() { return Builder().withTypeShape().withOpaque().build(); } - static const ItemFilter transparentShape() { return Builder().withTypeShape().withTransparent().build(); } + static ItemFilter opaqueShape() { return Builder().withTypeShape().withOpaque().build(); } + static ItemFilter transparentShape() { return Builder().withTypeShape().withTransparent().build(); } }; // Item Filter operator testing if a key pass the filter @@ -145,7 +144,7 @@ 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; @@ -183,12 +182,9 @@ public: typedef std::shared_ptr PayloadPointer; Item() {} - Item(PayloadPointer& payload): - _payload(payload) {} - ~Item() {} - void resetPayload(PayloadPointer& payload); + void resetPayload(const PayloadPointer& payload); void kill(); void move(); @@ -327,9 +323,9 @@ public: class PendingChanges { public: PendingChanges() {} - ~PendingChanges(); + ~PendingChanges() {} - void resetItem(ItemID id, PayloadPointer& payload); + void resetItem(ItemID id, const PayloadPointer& payload); void removeItem(ItemID id); void moveItem(ItemID id); @@ -367,6 +363,9 @@ public: unsigned int getNumItems() const { return _items.size(); } + + void processPendingChangesQueue(); + protected: // Thread safe elements that can be accessed from anywhere std::atomic _IDAllocator; @@ -379,7 +378,6 @@ protected: Item::Vector _items; ItemBucketMap _masterBucketMap; - void processPendingChangesQueue(); void resetItems(const ItemIDs& ids, Payloads& payloads); void removeItems(const ItemIDs& ids); void moveItems(const ItemIDs& ids);