From 5b8e18f15d78ceaa6fa943cd4375dd30ba4e9ec5 Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 1 Mar 2018 17:57:44 -0800 Subject: [PATCH] Adding the pipeline to render the view spheres --- .../src/workload/GameWorkloadRenderer.cpp | 97 ++++++++++++++++--- interface/src/workload/GameWorkloadRenderer.h | 25 +++-- .../render-utils/src/drawWorkloadView.slv | 94 ++++++++++++++++++ libraries/workload/src/workload/Space.cpp | 6 +- libraries/workload/src/workload/Space.h | 11 ++- .../developer/utilities/workload/workload.qml | 20 +++- 6 files changed, 225 insertions(+), 28 deletions(-) create mode 100644 libraries/render-utils/src/drawWorkloadView.slv diff --git a/interface/src/workload/GameWorkloadRenderer.cpp b/interface/src/workload/GameWorkloadRenderer.cpp index bb6aa35257..4a6cca118e 100644 --- a/interface/src/workload/GameWorkloadRenderer.cpp +++ b/interface/src/workload/GameWorkloadRenderer.cpp @@ -16,11 +16,13 @@ #include #include "render-utils/drawWorkloadProxy_vert.h" +#include "render-utils/drawWorkloadView_vert.h" #include "render-utils/drawWorkloadProxy_frag.h" void GameSpaceToRender::configure(const Config& config) { - _showAllProxies = config.showAllProxies; + _showAllProxies = config.showProxies; + _showAllViews = config.showViews; } void GameSpaceToRender::run(const workload::WorkloadContextPointer& runContext, Outputs& outputs) { @@ -33,7 +35,10 @@ void GameSpaceToRender::run(const workload::WorkloadContextPointer& runContext, return; } - auto visible = _showAllProxies; + auto visible = _showAllProxies || _showAllViews; + auto showProxies = _showAllProxies; + auto showViews = _showAllViews; + render::Transaction transaction; auto scene = gameWorkloadContext->_scene; @@ -51,22 +56,26 @@ void GameSpaceToRender::run(const workload::WorkloadContextPointer& runContext, std::vector proxies(space->getNumAllocatedProxies()); space->copyProxyValues(proxies.data(), (uint32_t)proxies.size()); - + std::vector views(space->getNumViews()); + space->copyViews(views); // Valid space, let's display its content if (!render::Item::isValidID(_spaceRenderItemID)) { _spaceRenderItemID = scene->allocateID(); auto renderItem = std::make_shared(); renderItem->editBound().setBox(glm::vec3(-100.0f), 200.0f); - renderItem->setVisible(visible); renderItem->setAllProxies(proxies); transaction.resetItem(_spaceRenderItemID, std::make_shared(renderItem)); - } else { - transaction.updateItem(_spaceRenderItemID, [visible, proxies](GameWorkloadRenderItem& item) { - item.setVisible(visible); - item.setAllProxies(proxies); - }); } + + transaction.updateItem(_spaceRenderItemID, [visible, showProxies, proxies, showViews, views](GameWorkloadRenderItem& item) { + item.setVisible(visible); + item.showProxies(showProxies); + item.setAllProxies(proxies); + item.showViews(showViews); + item.setAllViews(views); + }); + scene->enqueueTransaction(transaction); } @@ -109,6 +118,15 @@ void GameWorkloadRenderItem::setVisible(bool isVisible) { } } +void GameWorkloadRenderItem::showProxies(bool show) { + _showProxies = show; +} + +void GameWorkloadRenderItem::showViews(bool show) { + _showViews = show; +} + + void GameWorkloadRenderItem::setAllProxies(const std::vector& proxies) { _myOwnProxies = proxies; static const uint32_t sizeOfProxy = sizeof(workload::Space::Proxy); @@ -120,7 +138,18 @@ void GameWorkloadRenderItem::setAllProxies(const std::vector& views) { + _myOwnViews = views; + static const uint32_t sizeOfView = sizeof(workload::Space::View); + if (!_allViewsBuffer) { + _allViewsBuffer = std::make_shared(sizeOfView); + } + + _allViewsBuffer->setData(views.size() * sizeOfView, (const gpu::Byte*) views.data()); + _numAllViews = (uint32_t)views.size(); +} + +const gpu::PipelinePointer GameWorkloadRenderItem::getProxiesPipeline() { if (!_drawAllProxiesPipeline) { auto vs = drawWorkloadProxy_vert::getShader(); auto ps = drawWorkloadProxy_frag::getShader(); @@ -143,6 +172,29 @@ const gpu::PipelinePointer GameWorkloadRenderItem::getPipeline() { return _drawAllProxiesPipeline; } + +const gpu::PipelinePointer GameWorkloadRenderItem::getViewsPipeline() { + if (!_drawAllViewsPipeline) { + auto vs = drawWorkloadView_vert::getShader(); + auto ps = drawWorkloadProxy_frag::getShader(); + gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps); + + gpu::Shader::BindingSet slotBindings; + slotBindings.insert(gpu::Shader::Binding("workloadViewsBuffer", 1)); + gpu::Shader::makeProgram(*program, slotBindings); + + auto state = std::make_shared(); + state->setDepthTest(true, true, 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);*/ + + PrepareStencil::testMaskDrawShape(*state); + state->setCullMode(gpu::State::CULL_NONE); + _drawAllViewsPipeline = gpu::Pipeline::create(program, state); + } + return _drawAllViewsPipeline; +} void GameWorkloadRenderItem::render(RenderArgs* args) { gpu::Batch& batch = *(args->_batch); @@ -155,15 +207,28 @@ void GameWorkloadRenderItem::render(RenderArgs* args) { batch.setViewTransform(viewMat); batch.setModelTransform(Transform()); - // Bind program - batch.setPipeline(getPipeline()); - batch.setResourceBuffer(0, _allProxiesBuffer); + batch.setResourceBuffer(1, _allViewsBuffer); - static const int NUM_VERTICES_PER_QUAD = 3; - batch.draw(gpu::TRIANGLES, NUM_VERTICES_PER_QUAD * _numAllProxies, 0); + // Show Proxies + if (_showProxies) { + batch.setPipeline(getProxiesPipeline()); + + static const int NUM_VERTICES_PER_QUAD = 3; + batch.draw(gpu::TRIANGLES, NUM_VERTICES_PER_QUAD * _numAllProxies, 0); + } + + // Show Views + if (_showViews) { + batch.setPipeline(getViewsPipeline()); + + static const int NUM_VERTICES_PER_QUAD = 3; + batch.draw(gpu::TRIANGLES, NUM_VERTICES_PER_QUAD * 3 * _numAllViews, 0); + } + + batch.setResourceBuffer(0, nullptr); + batch.setResourceBuffer(1, nullptr); - batch.setResourceBuffer(11, nullptr); } diff --git a/interface/src/workload/GameWorkloadRenderer.h b/interface/src/workload/GameWorkloadRenderer.h index dc0fb9f3a1..0c2b521a01 100644 --- a/interface/src/workload/GameWorkloadRenderer.h +++ b/interface/src/workload/GameWorkloadRenderer.h @@ -14,10 +14,12 @@ class GameSpaceToRenderConfig : public workload::Job::Config { Q_OBJECT - Q_PROPERTY(bool showAllProxies MEMBER showAllProxies NOTIFY dirty) + Q_PROPERTY(bool showProxies MEMBER showProxies NOTIFY dirty) + Q_PROPERTY(bool showViews MEMBER showViews NOTIFY dirty) public: - bool showAllProxies{ false }; + bool showProxies{ false }; + bool showViews{ false }; signals: void dirty(); @@ -38,6 +40,7 @@ public: protected: render::ItemID _spaceRenderItemID{ render::Item::INVALID_ITEM_ID }; bool _showAllProxies{ false }; + bool _showAllViews{ false }; }; @@ -50,12 +53,15 @@ public: ~GameWorkloadRenderItem() {} void render(RenderArgs* args); - render::Item::Bound& editBound() { _needUpdate = true; return _bound; } + render::Item::Bound& editBound() { return _bound; } const render::Item::Bound& getBound() { return _bound; } void setVisible(bool visible); + void showProxies(bool show); + void showViews(bool show); void setAllProxies(const std::vector& proxies); + void setAllViews(const std::vector& views); render::ItemKey getKey() const; @@ -66,12 +72,19 @@ protected: gpu::BufferPointer _allProxiesBuffer; uint32_t _numAllProxies{ 0 }; + std::vector _myOwnViews; + gpu::BufferPointer _allViewsBuffer; + uint32_t _numAllViews{ 0 }; + gpu::PipelinePointer _drawAllProxiesPipeline; - const gpu::PipelinePointer getPipeline(); + const gpu::PipelinePointer getProxiesPipeline(); + + gpu::PipelinePointer _drawAllViewsPipeline; + const gpu::PipelinePointer getViewsPipeline(); render::ItemKey _key; - bool _needUpdate{ true }; - bool _isVisible{ true }; + bool _showProxies{ true }; + bool _showViews{ true }; }; namespace render { diff --git a/libraries/render-utils/src/drawWorkloadView.slv b/libraries/render-utils/src/drawWorkloadView.slv new file mode 100644 index 0000000000..c1a272a66c --- /dev/null +++ b/libraries/render-utils/src/drawWorkloadView.slv @@ -0,0 +1,94 @@ +<@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 WorkloadView { + vec4 origin; + vec4 radiuses; +}; + +#if defined(GPU_GL410) +uniform samplerBuffer workloadViewsBuffer; +WorkloadView getWorkloadView(int i) { + int offset = 2 * i; + WorkloadView view; + view.origin = texelFetch(workloadViewsBuffer, offset); + view.radiuses = texelFetch(workloadViewsBuffer, offset + 1); + return view; +} +#else +layout(std140) buffer workloadViewsBuffer { + WorkloadView _views[]; +}; +WorkloadView getWorkloadView(int i) { + WorkloadView view = _views[i]; + return view; +} +#endif + + + +out vec4 varColor; +out vec2 varTexcoord; + +void main(void) { + const vec4 UNIT_SPRITE[3] = vec4[3]( + vec4(-1.0, -1.0, 0.0, 1.0), + vec4(3.0, -1.0, 0.0, 1.0), + vec4(-1.0, 3.0, 0.0, 1.0) + ); + const int UNIT_SPRITE_INDICES[3] = int[3]( + 0, 1, 2 + ); + + int viewID = gl_VertexID / 9; + int reminder = gl_VertexID - viewID * 9; + int regionID = reminder / 3; + reminder = reminder - regionID * 3; + int vertexID = reminder; + + vec4 spriteVert = UNIT_SPRITE[UNIT_SPRITE_INDICES[vertexID]]; + + WorkloadView view = getWorkloadView(viewID); + vec4 proxyPosWorld = vec4(view.origin.xyz, 1.0); + + // standard transform, bring proxy in view space + TransformCamera cam = getTransformCamera(); + TransformObject obj = getTransformObject(); + vec4 proxyPosEye; + <$transformModelToEyePos(cam, obj, proxyPosWorld, proxyPosEye)$> + + // Define the billboarded space + vec3 dirZ = -normalize(proxyPosEye.xyz); + vec3 dirX = normalize(cross(vec3(0.0, 1.0, 0.0), dirZ)); + vec3 dirY = vec3(0.0, 1.0, 0.0); + // vec3 dirY = normalize(cross(dirZ, vec3(1.0, 0.0, 0.0))); + + float regionRadius = view.radiuses[regionID]; + + vec4 pos = vec4(proxyPosEye.xyz + regionRadius * ( dirX * spriteVert.x + dirY * spriteVert.y /* + dirZ * spriteVert.z*/), 1.0); + varTexcoord = spriteVert.xy; + <$transformEyeToClipPos(cam, pos, gl_Position)$> + + // Convert region to color + varColor = vec4(colorWheel(float(regionID) / 4.0), regionRadius); +} diff --git a/libraries/workload/src/workload/Space.cpp b/libraries/workload/src/workload/Space.cpp index 016b246725..c5881ab756 100644 --- a/libraries/workload/src/workload/Space.cpp +++ b/libraries/workload/src/workload/Space.cpp @@ -58,6 +58,10 @@ void Space::setViews(const std::vector& views) { _views = views; } +void Space::copyViews(std::vector& copy) const { + copy = _views; +} + // TODO?: move this to an algorithm/job? void Space::categorizeAndGetChanges(std::vector& changes) { uint32_t numProxies = (uint32_t)_proxies.size(); @@ -106,7 +110,7 @@ void Space::deleteProxy(int32_t proxyId) { } } -uint32_t Space::copyProxyValues(Proxy* proxies, uint32_t numDestProxies) { +uint32_t Space::copyProxyValues(Proxy* proxies, uint32_t numDestProxies) const { auto numCopied = std::min(numDestProxies, (uint32_t)_proxies.size()); memcpy(proxies, _proxies.data(), numCopied * sizeof(Proxy)); diff --git a/libraries/workload/src/workload/Space.h b/libraries/workload/src/workload/Space.h index 46ea8651bf..34c74af2eb 100644 --- a/libraries/workload/src/workload/Space.h +++ b/libraries/workload/src/workload/Space.h @@ -51,13 +51,16 @@ public: class View { public: + View() = default; View(const glm::vec3& pos, float nearRadius, float midRadius, float farRadius) : center(pos) { radiuses[REGION_NEAR] = nearRadius; radiuses[REGION_MIDDLE] = midRadius; radiuses[REGION_FAR] = farRadius; } - glm::vec3 center; + glm::vec3 center; + float _padding0; float radiuses[NUM_CLASSIFICATIONS - 1]; + float _padding1; }; class Change { @@ -76,11 +79,15 @@ public: void updateProxies(const std::vector& changedProxies); void setViews(const std::vector& views); + uint32_t getNumViews() const { return (uint32_t)(_views.size()); } + void copyViews(std::vector& copy) const; + + 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); - uint32_t copyProxyValues(Proxy* proxies, uint32_t numDestProxies); + uint32_t copyProxyValues(Proxy* proxies, uint32_t numDestProxies) const; private: void deleteProxy(int32_t proxyId); diff --git a/scripts/developer/utilities/workload/workload.qml b/scripts/developer/utilities/workload/workload.qml index e514e9b28a..530707b076 100644 --- a/scripts/developer/utilities/workload/workload.qml +++ b/scripts/developer/utilities/workload/workload.qml @@ -30,11 +30,25 @@ Rectangle { anchors.margins: hifi.dimensions.contentMargin.x //padding: hifi.dimensions.contentMargin.x + HifiControls.Label { + text: "Workload" + } + Separator {} + HifiControls.Label { + text: "Display" + } HifiControls.CheckBox { boxSize: 20 - text: "Show All Proxies" - checked: workload.spaceToRender["showAllProxies"] - onCheckedChanged: { workload.spaceToRender["showAllProxies"] = checked } + text: "Show Proxies" + checked: workload.spaceToRender["showProxies"] + onCheckedChanged: { workload.spaceToRender["showProxies"] = checked } } + HifiControls.CheckBox { + boxSize: 20 + text: "Show Views" + checked: workload.spaceToRender["showViews"] + onCheckedChanged: { workload.spaceToRender["showViews"] = checked } + } + Separator {} } }