From ae8a9e68c8229c48645dd96f5a9424b217526dd1 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Wed, 25 Oct 2017 11:58:16 +0200 Subject: [PATCH] Added debug tool to view shadow & view frustums --- .gitignore | 3 + libraries/gpu/src/gpu/DrawColor.slf | 19 ++++ libraries/gpu/src/gpu/StandardShaderLib.cpp | 9 ++ libraries/gpu/src/gpu/StandardShaderLib.h | 2 + .../render-utils/src/RenderDeferredTask.cpp | 86 +++++++++++++++++++ .../render-utils/src/RenderDeferredTask.h | 34 ++++++++ .../developer/utilities/render/debugShadow.js | 20 +++++ scripts/developer/utilities/render/shadow.qml | 46 ++++++++++ 8 files changed, 219 insertions(+) create mode 100644 libraries/gpu/src/gpu/DrawColor.slf create mode 100644 scripts/developer/utilities/render/debugShadow.js create mode 100644 scripts/developer/utilities/render/shadow.qml diff --git a/.gitignore b/.gitignore index 072e6001da..f085b676e4 100644 --- a/.gitignore +++ b/.gitignore @@ -65,6 +65,9 @@ gvr-interface/libs/* TAGS *.sw[po] +# ignore QML compilation output +*.qmlc + # ignore node files for the console node_modules npm-debug.log diff --git a/libraries/gpu/src/gpu/DrawColor.slf b/libraries/gpu/src/gpu/DrawColor.slf new file mode 100644 index 0000000000..c24d69d29f --- /dev/null +++ b/libraries/gpu/src/gpu/DrawColor.slf @@ -0,0 +1,19 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// Draw with color uniform +// +// Created by Olivier Prat on 25/10/2017 +// Copyright 2017 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 +// +uniform vec4 color; + +out vec4 outFragColor; + +void main(void) { + outFragColor = color; +} diff --git a/libraries/gpu/src/gpu/StandardShaderLib.cpp b/libraries/gpu/src/gpu/StandardShaderLib.cpp index 7143242618..0d8d131e0b 100755 --- a/libraries/gpu/src/gpu/StandardShaderLib.cpp +++ b/libraries/gpu/src/gpu/StandardShaderLib.cpp @@ -22,6 +22,7 @@ const char DrawNada_frag[] = "void main(void) {}"; // DrawNada is really simple... #include "DrawWhite_frag.h" +#include "DrawColor_frag.h" #include "DrawTexture_frag.h" #include "DrawTextureMirroredX_frag.h" #include "DrawTextureOpaque_frag.h" @@ -37,6 +38,7 @@ ShaderPointer StandardShaderLib::_drawVertexPositionVS; ShaderPointer StandardShaderLib::_drawTransformVertexPositionVS; ShaderPointer StandardShaderLib::_drawNadaPS; ShaderPointer StandardShaderLib::_drawWhitePS; +ShaderPointer StandardShaderLib::_drawColorPS; ShaderPointer StandardShaderLib::_drawTexturePS; ShaderPointer StandardShaderLib::_drawTextureMirroredXPS; ShaderPointer StandardShaderLib::_drawTextureOpaquePS; @@ -125,6 +127,13 @@ ShaderPointer StandardShaderLib::getDrawWhitePS() { return _drawWhitePS; } +ShaderPointer StandardShaderLib::getDrawColorPS() { + if (!_drawColorPS) { + _drawColorPS = gpu::Shader::createPixel(std::string(DrawColor_frag)); + } + return _drawColorPS; +} + ShaderPointer StandardShaderLib::getDrawTexturePS() { if (!_drawTexturePS) { _drawTexturePS = gpu::Shader::createPixel(std::string(DrawTexture_frag)); diff --git a/libraries/gpu/src/gpu/StandardShaderLib.h b/libraries/gpu/src/gpu/StandardShaderLib.h index 94885b8ca0..9c11f6cc3a 100755 --- a/libraries/gpu/src/gpu/StandardShaderLib.h +++ b/libraries/gpu/src/gpu/StandardShaderLib.h @@ -46,6 +46,7 @@ public: static ShaderPointer getDrawNadaPS(); static ShaderPointer getDrawWhitePS(); + static ShaderPointer getDrawColorPS(); static ShaderPointer getDrawTexturePS(); static ShaderPointer getDrawTextureMirroredXPS(); static ShaderPointer getDrawTextureOpaquePS(); @@ -67,6 +68,7 @@ protected: static ShaderPointer _drawNadaPS; static ShaderPointer _drawWhitePS; + static ShaderPointer _drawColorPS; static ShaderPointer _drawTexturePS; static ShaderPointer _drawTextureMirroredXPS; static ShaderPointer _drawTextureOpaquePS; diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 6a3b560167..75af8506a2 100644 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -190,6 +190,7 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren task.addJob("DrawLightBounds", lights); task.addJob("DrawZones", zones); + task.addJob("DrawFrustums"); } // Layered Overlays @@ -516,3 +517,88 @@ void Blit::run(const RenderContextPointer& renderContext, const gpu::Framebuffer }); } +void DrawFrustums::configure(const Config& configuration) { + _updateFrustums = !configuration.isFrozen; +} + +void DrawFrustums::run(const render::RenderContextPointer& renderContext) { + assert(renderContext->args); + assert(renderContext->args->_context); + + RenderArgs* args = renderContext->args; + static uint8_t indexData[] = { 0, 1, 2, 3, 0, 4, 5, 6, 7, 4, 5, 1, 2, 6, 7, 3 }; + + if (!_frustumMeshIndices._buffer) { + auto indices = std::make_shared(sizeof(indexData), indexData); + _frustumMeshIndices = gpu::BufferView(indices, gpu::Element(gpu::SCALAR, gpu::UINT8, gpu::INDEX)); + _viewFrustumMeshVertices = gpu::BufferView(std::make_shared(sizeof(glm::vec3) * 8, nullptr), gpu::Element::VEC3F_XYZ); + _viewFrustumMeshStream.addBuffer(_viewFrustumMeshVertices._buffer, _viewFrustumMeshVertices._offset, _viewFrustumMeshVertices._stride); + _shadowFrustumMeshVertices = gpu::BufferView(std::make_shared(sizeof(glm::vec3) * 8, nullptr), gpu::Element::VEC3F_XYZ); + _shadowFrustumMeshStream.addBuffer(_shadowFrustumMeshVertices._buffer, _shadowFrustumMeshVertices._offset, _shadowFrustumMeshVertices._stride); + } + + if (_updateFrustums) { + updateFrustum(args->getViewFrustum(), _viewFrustumMeshVertices); + + auto lightStage = renderContext->_scene->getStage(); + assert(lightStage); + + const auto globalShadow = lightStage->getCurrentKeyShadow(); + if (globalShadow) { + updateFrustum(*globalShadow->getFrustum(), _shadowFrustumMeshVertices); + } + } + + if (!_pipeline) { + auto vs = gpu::StandardShaderLib::getDrawTransformVertexPositionVS(); + auto ps = gpu::StandardShaderLib::getDrawColorPS(); + gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps); + + gpu::Shader::BindingSet slotBindings; + slotBindings.insert(gpu::Shader::Binding("color", 0)); + gpu::Shader::makeProgram(*program, slotBindings); + + gpu::StatePointer state = gpu::StatePointer(new gpu::State()); + state->setDepthTest(gpu::State::DepthTest(true, false)); + _pipeline = gpu::Pipeline::create(program, state); + } + + // Render the frustums in wireframe + gpu::doInBatch(args->_context, [&](gpu::Batch& batch) { + args->_batch = &batch; + batch.setViewportTransform(args->_viewport); + batch.setStateScissorRect(args->_viewport); + + glm::mat4 projMat; + Transform viewMat; + args->getViewFrustum().evalProjectionMatrix(projMat); + args->getViewFrustum().evalViewTransform(viewMat); + + batch.setProjectionTransform(projMat); + batch.setViewTransform(viewMat); + batch.setPipeline(_pipeline); + batch.setIndexBuffer(_frustumMeshIndices); + + batch._glUniform4f(0, 1.0f, 1.0f, 0.0f, 1.0f); + batch.setInputStream(0, _viewFrustumMeshStream); + batch.drawIndexed(gpu::LINE_STRIP, sizeof(indexData) / sizeof(indexData[0]), 0U); + + batch._glUniform4f(0, 1.0f, 0.0f, 0.0f, 1.0f); + batch.setInputStream(0, _shadowFrustumMeshStream); + batch.drawIndexed(gpu::LINE_STRIP, sizeof(indexData) / sizeof(indexData[0]), 0U); + + args->_batch = nullptr; + }); +} + +void DrawFrustums::updateFrustum(const ViewFrustum& frustum, gpu::BufferView& vertexBuffer) { + auto& vertices = vertexBuffer.edit >(); + vertices[0] = frustum.getNearTopLeft(); + vertices[1] = frustum.getNearTopRight(); + vertices[2] = frustum.getNearBottomRight(); + vertices[3] = frustum.getNearBottomLeft(); + vertices[4] = frustum.getFarTopLeft(); + vertices[5] = frustum.getFarTopRight(); + vertices[6] = frustum.getFarBottomRight(); + vertices[7] = frustum.getFarBottomLeft(); +} diff --git a/libraries/render-utils/src/RenderDeferredTask.h b/libraries/render-utils/src/RenderDeferredTask.h index 452420589b..e8dd22359d 100644 --- a/libraries/render-utils/src/RenderDeferredTask.h +++ b/libraries/render-utils/src/RenderDeferredTask.h @@ -170,6 +170,40 @@ public: void run(const render::RenderContextPointer& renderContext, const gpu::FramebufferPointer& srcFramebuffer); }; +class DrawFrustumsConfig : public render::Job::Config { + Q_OBJECT + Q_PROPERTY(bool isFrozen MEMBER isFrozen NOTIFY dirty) +public: + + DrawFrustumsConfig(bool enabled = false) : JobConfig(enabled) {} + + bool isFrozen{ false }; +signals: + void dirty(); + +}; + +class DrawFrustums { +public: + using Config = DrawFrustumsConfig; + using JobModel = render::Job::Model; + + void configure(const Config& configuration); + void run(const render::RenderContextPointer& renderContext); + +private: + + bool _updateFrustums{ true }; + gpu::PipelinePointer _pipeline; + gpu::BufferView _frustumMeshIndices; + gpu::BufferView _viewFrustumMeshVertices; + gpu::BufferView _shadowFrustumMeshVertices; + gpu::BufferStream _viewFrustumMeshStream; + gpu::BufferStream _shadowFrustumMeshStream; + + static void updateFrustum(const ViewFrustum& frustum, gpu::BufferView& vertexBuffer); +}; + class RenderDeferredTaskConfig : public render::Task::Config { Q_OBJECT Q_PROPERTY(float fadeScale MEMBER fadeScale NOTIFY dirty) diff --git a/scripts/developer/utilities/render/debugShadow.js b/scripts/developer/utilities/render/debugShadow.js new file mode 100644 index 0000000000..a0d2142258 --- /dev/null +++ b/scripts/developer/utilities/render/debugShadow.js @@ -0,0 +1,20 @@ +// +// debugShadow.js +// developer/utilities/render +// +// Olivier Prat, created on 10/25/2017. +// Copyright 2017 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 +// + +// Set up the qml ui +var qml = Script.resolvePath('shadow.qml'); +var window = new OverlayWindow({ + title: 'Shadow Debug', + source: qml, + width: 200, + height: 90 +}); +window.closed.connect(function() { Script.stop(); }); \ No newline at end of file diff --git a/scripts/developer/utilities/render/shadow.qml b/scripts/developer/utilities/render/shadow.qml new file mode 100644 index 0000000000..1b4e647c77 --- /dev/null +++ b/scripts/developer/utilities/render/shadow.qml @@ -0,0 +1,46 @@ +// +// shadow.qml +// developer/utilities/render +// +// Olivier Prat, created on 10/25/2017. +// Copyright 2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html +// +import QtQuick 2.5 +import QtQuick.Controls 1.4 + +Column { + id: root + spacing: 8 + property var config: Render.getConfig("RenderMainView.DrawFrustums"); + + Component.onCompleted: { + config.enabled = true; + } + Component.onDestruction: { + config.enabled = false; + } + + CheckBox { + text: "Freeze Frustums" + checked: false + onCheckedChanged: { + config.isFrozen = checked; + } + } + Row { + spacing: 8 + Label { + text: "View" + color: "yellow" + font.italic: true + } + Label { + text: "Shadow" + color: "red" + font.italic: true + } + } +}