From 9441bb477ddcdd116f96da4732ef82180558ccf1 Mon Sep 17 00:00:00 2001 From: samcake Date: Fri, 16 Feb 2018 17:21:07 -0800 Subject: [PATCH 1/7] Working on adding rendering from the workload --- interface/src/Application.cpp | 7 +++-- interface/src/Application.h | 6 ++-- interface/src/workload/GameWorkload.cpp | 32 +++++++++++++++++++ interface/src/workload/GameWorkload.h | 41 +++++++++++++++++++++++++ 4 files changed, 82 insertions(+), 4 deletions(-) create mode 100644 interface/src/workload/GameWorkload.cpp create mode 100644 interface/src/workload/GameWorkload.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 8a3bdfca0e..c5dab90556 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2209,7 +2209,8 @@ Application::~Application() { // shutdown render engine _main3DScene = nullptr; _renderEngine = nullptr; - _infinityEngine = nullptr; + + _gameWorkload.shutdown(); DependencyManager::destroy(); @@ -2332,6 +2333,8 @@ void Application::initializeGL() { DependencyManager::get()->initializeShapePipelines(); }); + _gameWorkload.startup(); + _offscreenContext = new OffscreenGLCanvas(); _offscreenContext->setObjectName("MainThreadContext"); _offscreenContext->create(_glWidget->qglContext()); @@ -4099,7 +4102,7 @@ void Application::idle() { } { - _infinityEngine->run(); + _gameWorkload._engine->run(); } { PerformanceTimer perfTimer("update"); diff --git a/interface/src/Application.h b/interface/src/Application.h index 3c2dee03e7..e04421cb6c 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -69,7 +69,8 @@ #include "ui/OverlayConductor.h" #include "ui/overlays/Overlays.h" #include "UndoStackScriptingInterface.h" -#include "workload/Engine.h" + +#include "workload/GameWorkload.h" #include #include @@ -616,7 +617,8 @@ private: render::ScenePointer _main3DScene{ new render::Scene(glm::vec3(-0.5f * (float)TREE_SCALE), (float)TREE_SCALE) }; render::EnginePointer _renderEngine{ new render::Engine() }; gpu::ContextPointer _gpuContext; // initialized during window creation - workload::EnginePointer _infinityEngine{ new workload::Engine() }; + + GameWorkload _gameWorkload; mutable QMutex _renderArgsMutex{ QMutex::Recursive }; struct AppRenderArgs { diff --git a/interface/src/workload/GameWorkload.cpp b/interface/src/workload/GameWorkload.cpp new file mode 100644 index 0000000000..4563f1e060 --- /dev/null +++ b/interface/src/workload/GameWorkload.cpp @@ -0,0 +1,32 @@ +// +// GameWorkload.cpp +// +// Created by Sam Gateau on 2/16/2018. +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +#include "GameWorkload.h" + + +GameWorkload::GameWorkload() { +} + +GameWorkload::~GameWorkload() { + shutdown(); +} + +void GameWorkload::startup() { + _engine.reset(new workload::Engine()); + + _engine.addJob(); +} + +void GameWorkload::shutdown() { + _engine.reset(); +} + + +void GameSpaceToRender::run(const workload::WorkloadContextPointer& renderContext, Outputs& outputs) { +} \ No newline at end of file diff --git a/interface/src/workload/GameWorkload.h b/interface/src/workload/GameWorkload.h new file mode 100644 index 0000000000..848e01b441 --- /dev/null +++ b/interface/src/workload/GameWorkload.h @@ -0,0 +1,41 @@ +// +// GameWorkload.h +// +// Created by Sam Gateau on 2/16/2018. +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +#ifndef hifi_GameWorkload_h +#define hifi_GameWorkload_h + +#include "workload/Space.h" +#include "workload/Engine.h" + +#include "render/Scene.h" + +class GameSpaceToRender { +public: + using Outputs = render::Transaction; + using JobModel = workload::Job::ModelO; + + GameSpaceToRender() {} + void run(const workload::WorkloadContextPointer& renderContext, Outputs& outputs); + +protected: +}; + +class GameWorkload { +public: + GameWorkload(); + ~GameWorkload(); + + void startup(); + void shutdown(); + + workload::EnginePointer _engine{}; + +}; + +#endif \ No newline at end of file From d1b1ae0ea348e5fbf1272ca96a65f3846a2a095b Mon Sep 17 00:00:00 2001 From: samcake Date: Fri, 16 Feb 2018 17:22:27 -0800 Subject: [PATCH 2/7] Working on adding rendering from the workload --- interface/src/workload/GameWorkload.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/workload/GameWorkload.cpp b/interface/src/workload/GameWorkload.cpp index 4563f1e060..7cc9cf5c25 100644 --- a/interface/src/workload/GameWorkload.cpp +++ b/interface/src/workload/GameWorkload.cpp @@ -20,7 +20,7 @@ GameWorkload::~GameWorkload() { void GameWorkload::startup() { _engine.reset(new workload::Engine()); - _engine.addJob(); + _engine->addJob("SpaceToRender"); } void GameWorkload::shutdown() { From cd14fb65f043b3774606a945032c5fd5ba4db5d7 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 19 Feb 2018 23:44:23 -0800 Subject: [PATCH 3/7] First stp to add a rendering job to debug and display the workload space --- interface/src/Application.cpp | 2 +- interface/src/workload/GameWorkload.cpp | 86 +++++++++++++++++++++- interface/src/workload/GameWorkload.h | 14 +++- libraries/workload/src/workload/Engine.cpp | 6 +- libraries/workload/src/workload/Engine.h | 9 ++- libraries/workload/src/workload/Space.h | 4 + 6 files changed, 110 insertions(+), 11 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c5dab90556..7d9233e17d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2333,7 +2333,7 @@ void Application::initializeGL() { DependencyManager::get()->initializeShapePipelines(); }); - _gameWorkload.startup(); + _gameWorkload.startup(_main3DScene); _offscreenContext = new OffscreenGLCanvas(); _offscreenContext->setObjectName("MainThreadContext"); diff --git a/interface/src/workload/GameWorkload.cpp b/interface/src/workload/GameWorkload.cpp index 7cc9cf5c25..f9a0bfa360 100644 --- a/interface/src/workload/GameWorkload.cpp +++ b/interface/src/workload/GameWorkload.cpp @@ -9,6 +9,12 @@ // #include "GameWorkload.h" +GameWorkloadContext::GameWorkloadContext(const render::ScenePointer& scene) : WorkloadContext(), _scene(scene) { +} + +GameWorkloadContext::~GameWorkloadContext() { +} + GameWorkload::GameWorkload() { } @@ -17,8 +23,8 @@ GameWorkload::~GameWorkload() { shutdown(); } -void GameWorkload::startup() { - _engine.reset(new workload::Engine()); +void GameWorkload::startup(const render::ScenePointer& scene) { + _engine.reset(new workload::Engine(std::make_shared(scene))); _engine->addJob("SpaceToRender"); } @@ -28,5 +34,79 @@ void GameWorkload::shutdown() { } -void GameSpaceToRender::run(const workload::WorkloadContextPointer& renderContext, Outputs& outputs) { + + + +class GameWorkloadRenderItem { +public: + using Payload = render::Payload; + using Pointer = Payload::DataPointer; + + GameWorkloadRenderItem() {} + ~GameWorkloadRenderItem() {} + void render(RenderArgs* args) {} + + render::Item::Bound& editBound() { _needUpdate = true; return _bound; } + const render::Item::Bound& getBound() { return _bound; } + + void setVisible(bool visible) { _isVisible = visible; } + bool isVisible() const { return _isVisible; } + +protected: + render::Item::Bound _bound; + + bool _needUpdate{ true }; + bool _isVisible{ true }; +}; + +namespace render { + template <> const ItemKey payloadGetKey(const GameWorkloadRenderItem::Pointer& payload); + template <> const Item::Bound payloadGetBound(const GameWorkloadRenderItem::Pointer& payload); + template <> void payloadRender(const GameWorkloadRenderItem::Pointer& payload, RenderArgs* args); +} + +namespace render { + template <> const ItemKey payloadGetKey(const GameWorkloadRenderItem::Pointer& payload) { + auto builder = ItemKey::Builder().withTypeShape(); + return builder.build(); + } + template <> const Item::Bound payloadGetBound(const GameWorkloadRenderItem::Pointer& payload) { + if (payload) { + return payload->getBound(); + } + return Item::Bound(); + } + template <> void payloadRender(const GameWorkloadRenderItem::Pointer& payload, RenderArgs* args) { + if (payload) { + payload->render(args); + } + } +} + + +void GameSpaceToRender::run(const workload::WorkloadContextPointer& runContext, Outputs& outputs) { + auto gameWorkloadContext = std::dynamic_pointer_cast(runContext); + if (!gameWorkloadContext) { + return; + } + + auto scene = gameWorkloadContext->_scene; + + // Valid space, let's display its content + render::Transaction transaction; + if (!render::Item::isValidID(_spaceRenderItemID)) { + _spaceRenderItemID = scene->allocateID(); + auto renderItem = std::make_shared(); + renderItem->editBound().expandedContains(glm::vec3(0.0), 32000.0); + transaction.resetItem(_spaceRenderItemID, std::make_shared(std::make_shared())); + } + + scene->enqueueTransaction(transaction); + + auto space = gameWorkloadContext->_space; + if (!space) { + return; + } + + } \ No newline at end of file diff --git a/interface/src/workload/GameWorkload.h b/interface/src/workload/GameWorkload.h index 848e01b441..1647056d60 100644 --- a/interface/src/workload/GameWorkload.h +++ b/interface/src/workload/GameWorkload.h @@ -24,6 +24,15 @@ public: void run(const workload::WorkloadContextPointer& renderContext, Outputs& outputs); protected: + render::ItemID _spaceRenderItemID{ render::Item::INVALID_ITEM_ID }; +}; + +class GameWorkloadContext : public workload::WorkloadContext { +public: + GameWorkloadContext(const render::ScenePointer& scene); + virtual ~GameWorkloadContext(); + + render::ScenePointer _scene; }; class GameWorkload { @@ -31,11 +40,10 @@ public: GameWorkload(); ~GameWorkload(); - void startup(); + void startup(const render::ScenePointer& scene); void shutdown(); - workload::EnginePointer _engine{}; - + workload::EnginePointer _engine; }; #endif \ No newline at end of file diff --git a/libraries/workload/src/workload/Engine.cpp b/libraries/workload/src/workload/Engine.cpp index 7e69731d4e..e209fbf5d5 100644 --- a/libraries/workload/src/workload/Engine.cpp +++ b/libraries/workload/src/workload/Engine.cpp @@ -33,7 +33,7 @@ namespace workload { if (_isEnabled) { std::cout << _message.toStdString() << std::endl; } - } + } }; WorkloadContext::WorkloadContext() : task::JobContext(trace_workload()) {} @@ -50,8 +50,8 @@ namespace workload { } }; - Engine::Engine() : Task("Engine", EngineModel::create()), - _context(std::make_shared()) { + Engine::Engine(const WorkloadContextPointer& context) : Task("Engine", EngineModel::create()), + _context(context) { } } // namespace workload diff --git a/libraries/workload/src/workload/Engine.h b/libraries/workload/src/workload/Engine.h index a422c5d715..1e69f555c7 100644 --- a/libraries/workload/src/workload/Engine.h +++ b/libraries/workload/src/workload/Engine.h @@ -20,6 +20,8 @@ #include +#include "Space.h" + namespace workload { // How to make an Engine under the task::Task paradigm... @@ -29,6 +31,8 @@ namespace workload { public: WorkloadContext(); virtual ~WorkloadContext() {} + + SpacePointer _space; }; using WorkloadContextPointer = std::shared_ptr; @@ -56,12 +60,15 @@ namespace workload { // (5) Engine derives from task::Task and will run all the Job's class Engine : public Task { public: - Engine(); + Engine(const WorkloadContextPointer& context = std::make_shared()); ~Engine() = default; // (6) The Engine's Context is passed to its Jobs when they are run() void run() { assert(_context); Task::run(_context); } + // Register the Space + void registerSpace(const SpacePointer& space) { _context->_space = space; } + protected: // (6) Again, the Engine's Context is passed to its Jobs when they are run() void run(const WorkloadContextPointer& context) override { assert(_context); Task::run(_context); } diff --git a/libraries/workload/src/workload/Space.h b/libraries/workload/src/workload/Space.h index 3a8dd3c488..c4e89cda60 100644 --- a/libraries/workload/src/workload/Space.h +++ b/libraries/workload/src/workload/Space.h @@ -15,9 +15,11 @@ #ifndef hifi_workload_Space_h #define hifi_workload_Space_h +#include #include #include + namespace workload { class Space { @@ -77,6 +79,8 @@ private: std::vector _freeIndices; }; +using SpacePointer = std::shared_ptr; + } // namespace workload #endif // hifi_workload_Space_h From f1dcfeb25e9a8a872e26b022bd6570819390fb6b Mon Sep 17 00:00:00 2001 From: samcake Date: Tue, 20 Feb 2018 18:20:12 -0800 Subject: [PATCH 4/7] Adding shaders and means to render the proxies contained in the workload SPace --- interface/src/Application.cpp | 2 +- interface/src/Application.h | 1 + interface/src/workload/GameWorkload.cpp | 82 +----------- interface/src/workload/GameWorkload.h | 16 +-- .../src/workload/GameWorkloadRenderer.cpp | 121 ++++++++++++++++++ interface/src/workload/GameWorkloadRenderer.h | 64 +++++++++ .../render-utils/src/drawWorkloadProxy.slf | 28 ++++ .../render-utils/src/drawWorkloadProxy.slv | 102 +++++++++++++++ libraries/workload/src/workload/Engine.cpp | 2 +- libraries/workload/src/workload/Engine.h | 7 +- libraries/workload/src/workload/Space.cpp | 9 ++ libraries/workload/src/workload/Space.h | 2 + 12 files changed, 336 insertions(+), 100 deletions(-) create mode 100644 interface/src/workload/GameWorkloadRenderer.cpp create mode 100644 interface/src/workload/GameWorkloadRenderer.h create mode 100644 libraries/render-utils/src/drawWorkloadProxy.slf create mode 100644 libraries/render-utils/src/drawWorkloadProxy.slv diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 0abb43692d..4da50ca0b0 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2400,7 +2400,7 @@ void Application::initializeGL() { DependencyManager::get()->initializeShapePipelines(); }); - _gameWorkload.startup(_main3DScene); + _gameWorkload.startup(_workloadSpace, _main3DScene); _offscreenContext = new OffscreenGLCanvas(); _offscreenContext->setObjectName("MainThreadContext"); diff --git a/interface/src/Application.h b/interface/src/Application.h index e04421cb6c..2af1d4678a 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -619,6 +619,7 @@ private: gpu::ContextPointer _gpuContext; // initialized during window creation GameWorkload _gameWorkload; + workload::SpacePointer _workloadSpace{ new workload::Space() }; mutable QMutex _renderArgsMutex{ QMutex::Recursive }; struct AppRenderArgs { diff --git a/interface/src/workload/GameWorkload.cpp b/interface/src/workload/GameWorkload.cpp index f9a0bfa360..0113e0568d 100644 --- a/interface/src/workload/GameWorkload.cpp +++ b/interface/src/workload/GameWorkload.cpp @@ -8,8 +8,9 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #include "GameWorkload.h" +#include "GameWorkloadRenderer.h" -GameWorkloadContext::GameWorkloadContext(const render::ScenePointer& scene) : WorkloadContext(), _scene(scene) { +GameWorkloadContext::GameWorkloadContext(const workload::SpacePointer& space, const render::ScenePointer& scene) : WorkloadContext(space), _scene(scene) { } GameWorkloadContext::~GameWorkloadContext() { @@ -23,8 +24,8 @@ GameWorkload::~GameWorkload() { shutdown(); } -void GameWorkload::startup(const render::ScenePointer& scene) { - _engine.reset(new workload::Engine(std::make_shared(scene))); +void GameWorkload::startup(const workload::SpacePointer& space, const render::ScenePointer& scene) { + _engine.reset(new workload::Engine(std::make_shared(space, scene))); _engine->addJob("SpaceToRender"); } @@ -35,78 +36,3 @@ void GameWorkload::shutdown() { - - -class GameWorkloadRenderItem { -public: - using Payload = render::Payload; - using Pointer = Payload::DataPointer; - - GameWorkloadRenderItem() {} - ~GameWorkloadRenderItem() {} - void render(RenderArgs* args) {} - - render::Item::Bound& editBound() { _needUpdate = true; return _bound; } - const render::Item::Bound& getBound() { return _bound; } - - void setVisible(bool visible) { _isVisible = visible; } - bool isVisible() const { return _isVisible; } - -protected: - render::Item::Bound _bound; - - bool _needUpdate{ true }; - bool _isVisible{ true }; -}; - -namespace render { - template <> const ItemKey payloadGetKey(const GameWorkloadRenderItem::Pointer& payload); - template <> const Item::Bound payloadGetBound(const GameWorkloadRenderItem::Pointer& payload); - template <> void payloadRender(const GameWorkloadRenderItem::Pointer& payload, RenderArgs* args); -} - -namespace render { - template <> const ItemKey payloadGetKey(const GameWorkloadRenderItem::Pointer& payload) { - auto builder = ItemKey::Builder().withTypeShape(); - return builder.build(); - } - template <> const Item::Bound payloadGetBound(const GameWorkloadRenderItem::Pointer& payload) { - if (payload) { - return payload->getBound(); - } - return Item::Bound(); - } - template <> void payloadRender(const GameWorkloadRenderItem::Pointer& payload, RenderArgs* args) { - if (payload) { - payload->render(args); - } - } -} - - -void GameSpaceToRender::run(const workload::WorkloadContextPointer& runContext, Outputs& outputs) { - auto gameWorkloadContext = std::dynamic_pointer_cast(runContext); - if (!gameWorkloadContext) { - return; - } - - auto scene = gameWorkloadContext->_scene; - - // Valid space, let's display its content - render::Transaction transaction; - if (!render::Item::isValidID(_spaceRenderItemID)) { - _spaceRenderItemID = scene->allocateID(); - auto renderItem = std::make_shared(); - renderItem->editBound().expandedContains(glm::vec3(0.0), 32000.0); - transaction.resetItem(_spaceRenderItemID, std::make_shared(std::make_shared())); - } - - scene->enqueueTransaction(transaction); - - auto space = gameWorkloadContext->_space; - if (!space) { - return; - } - - -} \ No newline at end of file diff --git a/interface/src/workload/GameWorkload.h b/interface/src/workload/GameWorkload.h index 1647056d60..fe48d0fe92 100644 --- a/interface/src/workload/GameWorkload.h +++ b/interface/src/workload/GameWorkload.h @@ -15,21 +15,9 @@ #include "render/Scene.h" -class GameSpaceToRender { -public: - using Outputs = render::Transaction; - using JobModel = workload::Job::ModelO; - - GameSpaceToRender() {} - void run(const workload::WorkloadContextPointer& renderContext, Outputs& outputs); - -protected: - render::ItemID _spaceRenderItemID{ render::Item::INVALID_ITEM_ID }; -}; - class GameWorkloadContext : public workload::WorkloadContext { public: - GameWorkloadContext(const render::ScenePointer& scene); + GameWorkloadContext(const workload::SpacePointer& space, const render::ScenePointer& scene); virtual ~GameWorkloadContext(); render::ScenePointer _scene; @@ -40,7 +28,7 @@ public: GameWorkload(); ~GameWorkload(); - void startup(const render::ScenePointer& scene); + void startup(const workload::SpacePointer& space, const render::ScenePointer& scene); void shutdown(); workload::EnginePointer _engine; diff --git a/interface/src/workload/GameWorkloadRenderer.cpp b/interface/src/workload/GameWorkloadRenderer.cpp new file mode 100644 index 0000000000..dcc55e54b3 --- /dev/null +++ b/interface/src/workload/GameWorkloadRenderer.cpp @@ -0,0 +1,121 @@ +// +// GameWorkloadRender.cpp +// +// Created by Sam Gateau on 2/20/2018. +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +#include "GameWorkloadRenderer.h" + +#include + + +#include "render-utils/drawWorkloadProxy_vert.h" +#include "render-utils/drawWorkloadProxy_frag.h" + +void GameSpaceToRender::run(const workload::WorkloadContextPointer& runContext, Outputs& outputs) { + auto gameWorkloadContext = std::dynamic_pointer_cast(runContext); + if (!gameWorkloadContext) { + return; + } + + auto scene = gameWorkloadContext->_scene; + + // Valid space, let's display its content + render::Transaction transaction; + if (!render::Item::isValidID(_spaceRenderItemID)) { + _spaceRenderItemID = scene->allocateID(); + auto renderItem = std::make_shared(); + renderItem->editBound().expandedContains(glm::vec3(0.0), 32000.0); + transaction.resetItem(_spaceRenderItemID, std::make_shared(std::make_shared())); + } + + scene->enqueueTransaction(transaction); + + auto space = gameWorkloadContext->_space; + if (!space) { + return; + } + + space->getNumObjects(); + +} + +namespace render { + template <> const ItemKey payloadGetKey(const GameWorkloadRenderItem::Pointer& payload) { + auto builder = ItemKey::Builder().opaqueShape().withTagBits(ItemKey::TAG_BITS_0 | ItemKey::TAG_BITS_1); + return builder.build(); + } + template <> const Item::Bound payloadGetBound(const GameWorkloadRenderItem::Pointer& payload) { + if (payload) { + return payload->getBound(); + } + return Item::Bound(); + } + template <> void payloadRender(const GameWorkloadRenderItem::Pointer& payload, RenderArgs* args) { + if (payload) { + payload->render(args); + } + } +} + + + +void GameWorkloadRenderItem::setAllProxies(const std::vector& proxies) { + static const uint32_t sizeOfProxy = sizeof(workload::Space::Proxy); + if (!_allProxiesBuffer) { + _allProxiesBuffer = std::make_shared(sizeOfProxy); + } + + _allProxiesBuffer->setData(proxies.size() * sizeOfProxy, (const gpu::Byte*) proxies.data()); + _numAllProxies = (uint32_t) proxies.size(); +} + +const gpu::PipelinePointer GameWorkloadRenderItem::getPipeline() { + if (!_drawAllProxiesPipeline) { + auto vs = drawWorkloadProxy_vert::getShader(); + auto ps = drawWorkloadProxy_frag::getShader(); + gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps); + + gpu::Shader::BindingSet slotBindings; + gpu::Shader::makeProgram(*program, slotBindings); + + auto state = std::make_shared(); + state->setDepthTest(true, false, gpu::LESS_EQUAL); + state->setBlendFunction(true, + gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, + gpu::State::DEST_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ZERO); + + _drawAllProxiesPipeline = gpu::Pipeline::create(program, state); + } + return _drawAllProxiesPipeline; +} + +void GameWorkloadRenderItem::render(RenderArgs* args) { + gpu::doInBatch(args->_context, [&](gpu::Batch& batch) { + args->_batch = &batch; + + // Setup projection + glm::mat4 projMat; + Transform viewMat; + args->getViewFrustum().evalProjectionMatrix(projMat); + args->getViewFrustum().evalViewTransform(viewMat); + batch.setProjectionTransform(projMat); + batch.setViewTransform(viewMat); + batch.setModelTransform(Transform()); + + // Bind program + batch.setPipeline(getPipeline()); + + batch.setResourceBuffer(0, _allProxiesBuffer); + + static const int NUM_VERTICES_PER_QUAD = 4; + batch.draw(gpu::LINES, NUM_VERTICES_PER_QUAD * _numAllProxies, 0); + }); + +} + + + diff --git a/interface/src/workload/GameWorkloadRenderer.h b/interface/src/workload/GameWorkloadRenderer.h new file mode 100644 index 0000000000..969c85a195 --- /dev/null +++ b/interface/src/workload/GameWorkloadRenderer.h @@ -0,0 +1,64 @@ +// +// GameWorkloadRender.h +// +// Created by Sam Gateau on 2/20/2018. +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +#ifndef hifi_GameWorkloadRenderer_h +#define hifi_GameWorkloadRenderer_h + +#include "GameWorkload.h" + +class GameSpaceToRender { +public: + using Outputs = render::Transaction; + using JobModel = workload::Job::ModelO; + + GameSpaceToRender() {} + void run(const workload::WorkloadContextPointer& renderContext, Outputs& outputs); + +protected: + render::ItemID _spaceRenderItemID{ render::Item::INVALID_ITEM_ID }; +}; + + +class GameWorkloadRenderItem { +public: + using Payload = render::Payload; + using Pointer = Payload::DataPointer; + + GameWorkloadRenderItem() {} + ~GameWorkloadRenderItem() {} + void render(RenderArgs* args); + + render::Item::Bound& editBound() { _needUpdate = true; return _bound; } + const render::Item::Bound& getBound() { return _bound; } + + void setVisible(bool visible) { _isVisible = visible; } + bool isVisible() const { return _isVisible; } + + void setAllProxies(const std::vector& proxies); + +protected: + render::Item::Bound _bound; + + gpu::BufferPointer _allProxiesBuffer; + uint32_t _numAllProxies{ 0 }; + + gpu::PipelinePointer _drawAllProxiesPipeline; + const gpu::PipelinePointer getPipeline(); + + bool _needUpdate{ true }; + bool _isVisible{ true }; +}; + +namespace render { + template <> const ItemKey payloadGetKey(const GameWorkloadRenderItem::Pointer& payload); + template <> const Item::Bound payloadGetBound(const GameWorkloadRenderItem::Pointer& payload); + template <> void payloadRender(const GameWorkloadRenderItem::Pointer& payload, RenderArgs* args); +} + +#endif \ No newline at end of file diff --git a/libraries/render-utils/src/drawWorkloadProxy.slf b/libraries/render-utils/src/drawWorkloadProxy.slf new file mode 100644 index 0000000000..84c47d0933 --- /dev/null +++ b/libraries/render-utils/src/drawWorkloadProxy.slf @@ -0,0 +1,28 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// drawItemBounds.frag +// fragment shader +// +// Created by Sam Gateau on 6/29/15. +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +in vec4 varColor; +in vec2 varTexcoord; +out vec4 outFragColor; + +void main(void) { + float var = step(fract(varTexcoord.x * varTexcoord.y * 1.0), 0.5); + + if (varColor.a == 0.0) { + outFragColor = vec4(mix(vec3(0.0), varColor.xyz, var), mix(0.0, 1.0, var)); + + } else { + outFragColor = vec4(mix(vec3(1.0), varColor.xyz, var), varColor.a); + } + +} diff --git a/libraries/render-utils/src/drawWorkloadProxy.slv b/libraries/render-utils/src/drawWorkloadProxy.slv new file mode 100644 index 0000000000..0bb2b795bd --- /dev/null +++ b/libraries/render-utils/src/drawWorkloadProxy.slv @@ -0,0 +1,102 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// drawItemBounds.slv +// vertex shader +// +// Created by Sam Gateau on 6/29/2015. +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +<@include gpu/Transform.slh@> +<$declareStandardTransform()$> + +<@include gpu/Color.slh@> +<$declareColorWheel()$> + +uniform vec4 inColor; + + +struct ItemBound { + vec4 id_boundPos; + vec4 boundDim_s; +}; + +#if defined(GPU_GL410) +uniform samplerBuffer ssbo0Buffer; +ItemBound getItemBound(int i) { + int offset = 2 * i; + ItemBound bound; + bound.id_boundPos = texelFetch(ssbo0Buffer, offset); + bound.boundDim_s = texelFetch(ssbo0Buffer, offset + 1); + return bound; +} +#else +layout(std140) buffer ssbo0Buffer { + ItemBound bounds[]; +}; +ItemBound getItemBound(int i) { + ItemBound bound = bounds[i]; + return bound; +} +#endif + + + +out vec4 varColor; +out vec2 varTexcoord; + +void main(void) { + const vec4 UNIT_BOX[8] = vec4[8]( + vec4(0.0, 0.0, 0.0, 0.0), + vec4(1.0, 0.0, 0.0, 1.0), + vec4(0.0, 1.0, 0.0, 1.0), + vec4(1.0, 1.0, 0.0, 2.0), + vec4(0.0, 0.0, 1.0, 1.0), + vec4(1.0, 0.0, 1.0, 2.0), + vec4(0.0, 1.0, 1.0, 2.0), + vec4(1.0, 1.0, 1.0, 3.0) + ); + const int UNIT_BOX_LINE_INDICES[24] = int[24]( + 0, 1, + 1, 3, + 3, 2, + 2, 0, + 4, 5, + 5, 7, + 7, 6, + 6, 4, + 2, 6, + 3, 7, + 0, 4, + 1, 5 + ); + + int boundID = gl_VertexID / 24; + int vertexID = gl_VertexID - boundID * 24; + + vec4 cubeVec = UNIT_BOX[UNIT_BOX_LINE_INDICES[vertexID]]; + + ItemBound bound = getItemBound(boundID); + vec3 boundPos = bound.id_boundPos.yzw; + vec3 boundDim = bound.boundDim_s.xyz; + + vec4 pos = vec4(boundPos + boundDim * cubeVec.xyz, 1.0); + + // standard transform + TransformCamera cam = getTransformCamera(); + TransformObject obj = getTransformObject(); + <$transformModelToClipPos(cam, obj, pos, gl_Position)$> + + if (inColor.w < 0.0) { + varColor = vec4(colorWheel(float(boundID)/(-inColor.w)), 1.0); + } else { + varColor = vec4(colorWheel(float(inColor.w)), 1.0); + } + varTexcoord = vec2(cubeVec.w, length(boundDim)); + +} \ No newline at end of file diff --git a/libraries/workload/src/workload/Engine.cpp b/libraries/workload/src/workload/Engine.cpp index e209fbf5d5..3cf31bd879 100644 --- a/libraries/workload/src/workload/Engine.cpp +++ b/libraries/workload/src/workload/Engine.cpp @@ -36,7 +36,7 @@ namespace workload { } }; - WorkloadContext::WorkloadContext() : task::JobContext(trace_workload()) {} + WorkloadContext::WorkloadContext(const SpacePointer& space) : task::JobContext(trace_workload()), _space(space) {} using EngineModel = Task::Model; diff --git a/libraries/workload/src/workload/Engine.h b/libraries/workload/src/workload/Engine.h index 1e69f555c7..365461a4a3 100644 --- a/libraries/workload/src/workload/Engine.h +++ b/libraries/workload/src/workload/Engine.h @@ -29,7 +29,7 @@ namespace workload { // (1) Derive class C from task::JobContext class WorkloadContext : public task::JobContext { public: - WorkloadContext(); + WorkloadContext(const SpacePointer& space); virtual ~WorkloadContext() {} SpacePointer _space; @@ -66,12 +66,7 @@ namespace workload { // (6) The Engine's Context is passed to its Jobs when they are run() void run() { assert(_context); Task::run(_context); } - // Register the Space - void registerSpace(const SpacePointer& space) { _context->_space = space; } - protected: - // (6) Again, the Engine's Context is passed to its Jobs when they are run() - void run(const WorkloadContextPointer& context) override { assert(_context); Task::run(_context); } private: WorkloadContextPointer _context; diff --git a/libraries/workload/src/workload/Space.cpp b/libraries/workload/src/workload/Space.cpp index 2c38ec9f8b..e37211b611 100644 --- a/libraries/workload/src/workload/Space.cpp +++ b/libraries/workload/src/workload/Space.cpp @@ -101,6 +101,15 @@ void Space::deleteProxy(int32_t proxyId) { } } +uint32_t Space::copyProxyValues(Proxy* proxies, uint32_t numDestProxies) { + + auto numCopied = std::min(numDestProxies, (uint32_t)_proxies.size()); + memcpy(proxies, _proxies.data(), numCopied * sizeof(Proxy)); + + return numCopied; +} + + // private void Space::updateProxy(int32_t proxyId, const Space::Sphere& newSphere) { if (proxyId > -1 && proxyId < (int32_t)_proxies.size()) { diff --git a/libraries/workload/src/workload/Space.h b/libraries/workload/src/workload/Space.h index c4e89cda60..fb288a060c 100644 --- a/libraries/workload/src/workload/Space.h +++ b/libraries/workload/src/workload/Space.h @@ -70,6 +70,8 @@ public: void categorizeAndGetChanges(std::vector& changes); + uint32_t copyProxyValues(Proxy* proxies, uint32_t numDestProxies); + private: void deleteProxy(int32_t proxyId); void updateProxy(int32_t proxyId, const Sphere& sphere); From 33b47f9ae29d0b7979f793e6b04b81459dcafa81 Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 21 Feb 2018 10:34:58 -0800 Subject: [PATCH 5/7] Merging with the actual worloadspace managed from the EntityTreeRenderer --- interface/src/Application.cpp | 2 +- interface/src/Application.h | 1 - interface/src/workload/GameWorkloadRenderer.cpp | 10 ++++++++-- libraries/entities-renderer/src/EntityTreeRenderer.cpp | 6 +++--- libraries/entities-renderer/src/EntityTreeRenderer.h | 5 ++++- libraries/workload/src/workload/Space.h | 2 ++ 6 files changed, 18 insertions(+), 8 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e1d5ed7e29..0c654e9196 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2400,7 +2400,7 @@ void Application::initializeGL() { DependencyManager::get()->initializeShapePipelines(); }); - _gameWorkload.startup(_workloadSpace, _main3DScene); + _gameWorkload.startup(getEntities()->getWorkloadSpace(), _main3DScene); _offscreenContext = new OffscreenGLCanvas(); _offscreenContext->setObjectName("MainThreadContext"); diff --git a/interface/src/Application.h b/interface/src/Application.h index 5617d0895d..8028dc8c68 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -616,7 +616,6 @@ private: gpu::ContextPointer _gpuContext; // initialized during window creation GameWorkload _gameWorkload; - workload::SpacePointer _workloadSpace{ new workload::Space() }; mutable QMutex _renderArgsMutex{ QMutex::Recursive }; struct AppRenderArgs { diff --git a/interface/src/workload/GameWorkloadRenderer.cpp b/interface/src/workload/GameWorkloadRenderer.cpp index dcc55e54b3..e10c28c36c 100644 --- a/interface/src/workload/GameWorkloadRenderer.cpp +++ b/interface/src/workload/GameWorkloadRenderer.cpp @@ -30,17 +30,23 @@ void GameSpaceToRender::run(const workload::WorkloadContextPointer& runContext, auto renderItem = std::make_shared(); renderItem->editBound().expandedContains(glm::vec3(0.0), 32000.0); transaction.resetItem(_spaceRenderItemID, std::make_shared(std::make_shared())); + scene->enqueueTransaction(transaction); } - scene->enqueueTransaction(transaction); auto space = gameWorkloadContext->_space; if (!space) { return; } - space->getNumObjects(); + std::vector proxies(space->getNumAllocatedProxies()); + space->copyProxyValues(proxies.data(), proxies.size()); + + transaction.updateItem(_spaceRenderItemID, [proxies](GameWorkloadRenderItem& item) { + item.setAllProxies(proxies); + }); + scene->enqueueTransaction(transaction); } namespace render { diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 879dd709e8..eecd21e5ac 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -281,7 +281,7 @@ void EntityTreeRenderer::addPendingEntities(const render::ScenePointer& scene, r if (entity->getSpaceIndex() == -1) { std::unique_lock lock(_spaceLock); workload::Space::Sphere sphere(entity->getWorldPosition(), entity->getBoundingRadius()); - int32_t spaceIndex = _space.createProxy(sphere); + int32_t spaceIndex = _space->createProxy(sphere); entity->setSpaceIndex(spaceIndex); connect(entity.get(), &EntityItem::spaceUpdate, this, &EntityTreeRenderer::handleSpaceUpdate, Qt::QueuedConnection); } @@ -428,7 +428,7 @@ void EntityTreeRenderer::update(bool simulate) { } { // update proxies in the workload::Space std::unique_lock lock(_spaceLock); - _space.updateProxies(_spaceUpdates); + _space->updateProxies(_spaceUpdates); _spaceUpdates.clear(); } { // flush final EntityTree references to removed entities @@ -442,7 +442,7 @@ void EntityTreeRenderer::update(bool simulate) { disconnect(entity.get(), &EntityItem::spaceUpdate, this, &EntityTreeRenderer::handleSpaceUpdate); deadProxies.push_back(spaceIndex); } - _space.deleteProxies(deadProxies); + _space->deleteProxies(deadProxies); } } diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index f034353347..5840dc6832 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -120,6 +120,9 @@ public: static void setRenderDebugHullsOperator(std::function renderDebugHullsOperator) { _renderDebugHullsOperator = renderDebugHullsOperator; } static bool shouldRenderDebugHulls() { return _renderDebugHullsOperator(); } + // Access the workload Space + const workload::SpacePointer getWorkloadSpace() const { return _space; } + signals: void enterEntity(const EntityItemID& entityItemID); void leaveEntity(const EntityItemID& entityItemID); @@ -266,7 +269,7 @@ private: static std::function _renderDebugHullsOperator; mutable std::mutex _spaceLock; - workload::Space _space; + workload::SpacePointer _space{ new workload::Space() }; std::vector _spaceUpdates; }; diff --git a/libraries/workload/src/workload/Space.h b/libraries/workload/src/workload/Space.h index 4b8510ebae..d7478b6066 100644 --- a/libraries/workload/src/workload/Space.h +++ b/libraries/workload/src/workload/Space.h @@ -35,6 +35,7 @@ public: class Proxy { public: + Proxy() : sphere(0.0f) {} Proxy(const Sphere& s) : sphere(s) {} Sphere sphere; uint8_t region { REGION_UNKNOWN }; @@ -68,6 +69,7 @@ public: void setViews(const std::vector& views); uint32_t getNumObjects() const { return (uint32_t)(_proxies.size() - _freeIndices.size()); } + uint32_t getNumAllocatedProxies() const { return (uint32_t)(_proxies.size()); } void categorizeAndGetChanges(std::vector& changes); From 1c3bc0aa67a903736b01d1e1246d2b66d02f74c9 Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 21 Feb 2018 11:18:41 -0800 Subject: [PATCH 6/7] addressing review and warnings --- interface/src/workload/GameWorkloadRenderer.cpp | 5 +++-- libraries/workload/src/workload/Engine.h | 6 ++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/interface/src/workload/GameWorkloadRenderer.cpp b/interface/src/workload/GameWorkloadRenderer.cpp index e10c28c36c..99a784a511 100644 --- a/interface/src/workload/GameWorkloadRenderer.cpp +++ b/interface/src/workload/GameWorkloadRenderer.cpp @@ -9,6 +9,7 @@ // #include "GameWorkloadRenderer.h" +#include #include @@ -28,7 +29,7 @@ void GameSpaceToRender::run(const workload::WorkloadContextPointer& runContext, if (!render::Item::isValidID(_spaceRenderItemID)) { _spaceRenderItemID = scene->allocateID(); auto renderItem = std::make_shared(); - renderItem->editBound().expandedContains(glm::vec3(0.0), 32000.0); + renderItem->editBound().expandedContains(glm::vec3(0.0f), 32000.0f); transaction.resetItem(_spaceRenderItemID, std::make_shared(std::make_shared())); scene->enqueueTransaction(transaction); } @@ -41,7 +42,7 @@ void GameSpaceToRender::run(const workload::WorkloadContextPointer& runContext, std::vector proxies(space->getNumAllocatedProxies()); - space->copyProxyValues(proxies.data(), proxies.size()); + space->copyProxyValues(proxies.data(), (uint32_t) proxies.size()); transaction.updateItem(_spaceRenderItemID, [proxies](GameWorkloadRenderItem& item) { item.setAllProxies(proxies); diff --git a/libraries/workload/src/workload/Engine.h b/libraries/workload/src/workload/Engine.h index 365461a4a3..08abe23e35 100644 --- a/libraries/workload/src/workload/Engine.h +++ b/libraries/workload/src/workload/Engine.h @@ -47,7 +47,7 @@ namespace workload { Q_PROPERTY(QString message READ getMessage WRITE setMessage) QString _message {"Hello World."}; public: - HelloWorldConfig() : Job::Config(true) {} + HelloWorldConfig() : Job::Config(true) {} QString getMessage() const { return _message; } void setMessage(const QString& msg) { _message = msg; } }; @@ -64,9 +64,11 @@ namespace workload { ~Engine() = default; // (6) The Engine's Context is passed to its Jobs when they are run() - void run() { assert(_context); Task::run(_context); } + void run() { assert(_context); run(_context); } protected: + // (6) Again, the Engine's Context is passed to its Jobs when they are run() + void run(const WorkloadContextPointer& context) override { assert(_context); Task::run(_context); } private: WorkloadContextPointer _context; From 85a17f1301f1f3ad31c13fdfa9d4c53a2c6d5d95 Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 21 Feb 2018 11:21:43 -0800 Subject: [PATCH 7/7] missing cstring for the memcpy in Space.cpp --- libraries/workload/src/workload/Space.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/workload/src/workload/Space.cpp b/libraries/workload/src/workload/Space.cpp index fa49d9209d..e9745e0916 100644 --- a/libraries/workload/src/workload/Space.cpp +++ b/libraries/workload/src/workload/Space.cpp @@ -13,7 +13,7 @@ // #include "Space.h" - +#include #include #include