From d7791982acafd444b09927419fc685da4e472f35 Mon Sep 17 00:00:00 2001 From: Niraj Venkat Date: Mon, 29 Jun 2015 15:19:50 -0700 Subject: [PATCH 01/21] Starting stats branch --- libraries/render/src/render/Stats.h | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 libraries/render/src/render/Stats.h diff --git a/libraries/render/src/render/Stats.h b/libraries/render/src/render/Stats.h new file mode 100644 index 0000000000..5291581d7e --- /dev/null +++ b/libraries/render/src/render/Stats.h @@ -0,0 +1,29 @@ +// +// Stats.h +// render/src/render +// +// Created by Niraj Venkat 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 +// + +#ifndef hifi_render_Stats_h +#define hifi_render_Stats_h + +#include "DrawTask.h" +#include "gpu/Batch.h" +#include + + +namespace render { + class DrawStats { + public: + void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems); + + typedef Job::ModelI JobModel; + }; +} + +#endif // hifi_render_Stats_h From 20cb519c14ff85a9e7e3a54a794c42f6e0bc2f3e Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 30 Jun 2015 08:19:00 -0700 Subject: [PATCH 02/21] first draft at using the status of the item for representing stats and current data about it in the DrawStatus phase --- libraries/gpu/src/gpu/Config.slh | 3 +- .../render-utils/src/RenderDeferredTask.cpp | 4 + libraries/render/src/render/DrawStatus.cpp | 101 ++++++++++++++++++ libraries/render/src/render/DrawStatus.h | 34 ++++++ libraries/render/src/render/DrawTask.cpp | 7 +- libraries/render/src/render/Scene.h | 21 +++- .../render/src/render/drawItemBounds.slf | 19 ++++ .../render/src/render/drawItemBounds.slv | 43 ++++++++ 8 files changed, 226 insertions(+), 6 deletions(-) create mode 100644 libraries/render/src/render/DrawStatus.cpp create mode 100644 libraries/render/src/render/DrawStatus.h create mode 100644 libraries/render/src/render/drawItemBounds.slf create mode 100644 libraries/render/src/render/drawItemBounds.slv diff --git a/libraries/gpu/src/gpu/Config.slh b/libraries/gpu/src/gpu/Config.slh index 28f447a696..a16ee372ae 100644 --- a/libraries/gpu/src/gpu/Config.slh +++ b/libraries/gpu/src/gpu/Config.slh @@ -18,7 +18,8 @@ <@elif GLPROFILE == MAC_GL @> <@def GPU_FEATURE_PROFILE GPU_LEGACY@> <@def GPU_TRANSFORM_PROFILE GPU_LEGACY@> - <@def VERSION_HEADER #version 120@> + <@def VERSION_HEADER #version 120 +#extension GL_EXT_gpu_shader4 : enable@> <@else@> <@def GPU_FEATURE_PROFILE GPU_LEGACY@> <@def GPU_TRANSFORM_PROFILE GPU_LEGACY@> diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index e0c66eb604..db2b657126 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -17,6 +17,8 @@ #include "RenderArgs.h" #include "TextureCache.h" +#include "render/DrawStatus.h" + #include #include "overlay3D_vert.h" @@ -49,6 +51,7 @@ RenderDeferredTask::RenderDeferredTask() : Task() { ))); _jobs.push_back(Job(new CullItems::JobModel("CullOpaque", _jobs.back().getOutput()))); _jobs.push_back(Job(new DepthSortItems::JobModel("DepthSortOpaque", _jobs.back().getOutput()))); + auto& renderedOpaques = _jobs.back().getOutput(); _jobs.push_back(Job(new DrawOpaqueDeferred::JobModel("DrawOpaqueDeferred", _jobs.back().getOutput()))); _jobs.push_back(Job(new DrawLight::JobModel("DrawLight"))); _jobs.push_back(Job(new ResetGLState::JobModel())); @@ -65,6 +68,7 @@ RenderDeferredTask::RenderDeferredTask() : Task() { _jobs.push_back(Job(new CullItems::JobModel("CullTransparent", _jobs.back().getOutput()))); _jobs.push_back(Job(new DepthSortItems::JobModel("DepthSortTransparent", _jobs.back().getOutput(), DepthSortItems(false)))); _jobs.push_back(Job(new DrawTransparentDeferred::JobModel("TransparentDeferred", _jobs.back().getOutput()))); + _jobs.push_back(Job(new render::DrawStatus::JobModel("DrawStatus", renderedOpaques))); _jobs.push_back(Job(new DrawOverlay3D::JobModel("DrawOverlay3D"))); _jobs.push_back(Job(new ResetGLState::JobModel())); } diff --git a/libraries/render/src/render/DrawStatus.cpp b/libraries/render/src/render/DrawStatus.cpp new file mode 100644 index 0000000000..eaf39b6893 --- /dev/null +++ b/libraries/render/src/render/DrawStatus.cpp @@ -0,0 +1,101 @@ +// +// DrawStatus.cpp +// render/src/render +// +// Created by Niraj Venkat on 5/21/15. +// Copyright 20154 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 +#include + +#include "DrawStatus.h" + +#include +#include "gpu/GPULogging.h" + + +#include "gpu/Batch.h" +#include "gpu/Context.h" + +#include "ViewFrustum.h" +#include "RenderArgs.h" + +#include "drawItemBounds_vert.h" +#include "drawItemBounds_frag.h" + +using namespace render; + + + +const gpu::PipelinePointer& DrawStatus::getDrawItemBoundsPipeline() { + if (!_drawItemBoundsPipeline) { + auto vs = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(drawItemBounds_vert))); + auto ps = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(drawItemBounds_frag))); + gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(vs, ps)); + + gpu::Shader::BindingSet slotBindings; + gpu::Shader::makeProgram(*program, slotBindings); + + gpu::StatePointer state = gpu::StatePointer(new gpu::State()); + + state->setDepthTest(true, false, gpu::LESS_EQUAL); + + // Blend on transparent + 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); + + // Good to go add the brand new pipeline + _drawItemBoundsPipeline.reset(gpu::Pipeline::create(program, state)); + } + return _drawItemBoundsPipeline; +} + +void DrawStatus::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems) { + assert(renderContext->args); + assert(renderContext->args->_viewFrustum); + RenderArgs* args = renderContext->args; + + gpu::Batch batch; + + glm::mat4 projMat; + Transform viewMat; + args->_viewFrustum->evalProjectionMatrix(projMat); + args->_viewFrustum->evalViewTransform(viewMat); + if (args->_renderMode == RenderArgs::MIRROR_RENDER_MODE) { + viewMat.postScale(glm::vec3(-1.0f, 1.0f, 1.0f)); + } + batch.setProjectionTransform(projMat); + batch.setViewTransform(viewMat); + + + // batch.setModelTransform(Transform()); + // bind the unit cube geometry + + // bind the one gpu::Pipeline we need + batch.setPipeline(getDrawItemBoundsPipeline()); + + for (auto& item : inItems) { + if (!item.bounds.isInvalid()) { + Transform model; + model.setTranslation(item.bounds.getCorner()); + if (!item.bounds.isNull()) { + model.setScale(item.bounds.getDimensions()); + } + + batch.setModelTransform(model); + batch.draw(gpu::LINE_STRIP, 13, 0); + } + } + + // Before rendering the batch make sure we re in sync with gl state + args->_context->syncCache(); + renderContext->args->_context->syncCache(); + args->_context->render((batch)); + args->_batch = nullptr; + +} \ No newline at end of file diff --git a/libraries/render/src/render/DrawStatus.h b/libraries/render/src/render/DrawStatus.h new file mode 100644 index 0000000000..a1e962ebec --- /dev/null +++ b/libraries/render/src/render/DrawStatus.h @@ -0,0 +1,34 @@ +// +// DrawStatus.h +// render/src/render +// +// Created by Niraj Venkat 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 +// + +#ifndef hifi_render_DrawStatus_h +#define hifi_render_DrawStatus_h + +#include "DrawTask.h" +#include "gpu/Batch.h" +#include + + +namespace render { + class DrawStatus { + gpu::PipelinePointer _drawItemBoundsPipeline; + + public: + + void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems); + + typedef Job::ModelI JobModel; + + const gpu::PipelinePointer& getDrawItemBoundsPipeline(); + }; +} + +#endif // hifi_render_DrawStatus_h diff --git a/libraries/render/src/render/DrawTask.cpp b/libraries/render/src/render/DrawTask.cpp index 6076ec0006..70eeb00a3d 100755 --- a/libraries/render/src/render/DrawTask.cpp +++ b/libraries/render/src/render/DrawTask.cpp @@ -128,9 +128,10 @@ struct ItemBound { float _nearDepth = 0.0f; float _farDepth = 0.0f; ItemID _id = 0; + AABox _bounds; ItemBound() {} - ItemBound(float centerDepth, float nearDepth, float farDepth, ItemID id) : _centerDepth(centerDepth), _nearDepth(nearDepth), _farDepth(farDepth), _id(id) {} + ItemBound(float centerDepth, float nearDepth, float farDepth, ItemID id, const AABox& bounds) : _centerDepth(centerDepth), _nearDepth(nearDepth), _farDepth(farDepth), _id(id), _bounds(bounds) {} }; struct FrontToBackSort { @@ -167,7 +168,7 @@ void render::depthSortItems(const SceneContextPointer& sceneContext, const Rende auto bound = itemDetails.bounds; // item.getBound(); float distance = args->_viewFrustum->distanceToCamera(bound.calcCenter()); - itemBounds.emplace_back(ItemBound(distance, distance, distance, itemDetails.id)); + itemBounds.emplace_back(ItemBound(distance, distance, distance, itemDetails.id, bound)); } // sort against Z @@ -181,7 +182,7 @@ void render::depthSortItems(const SceneContextPointer& sceneContext, const Rende // FInally once sorted result to a list of itemID for (auto& itemBound : itemBounds) { - outItems.emplace_back(itemBound._id); + outItems.emplace_back(ItemIDAndBounds(itemBound._id, itemBound._bounds)); } } diff --git a/libraries/render/src/render/Scene.h b/libraries/render/src/render/Scene.h index 5ec9f0c951..444b45800a 100644 --- a/libraries/render/src/render/Scene.h +++ b/libraries/render/src/render/Scene.h @@ -196,12 +196,19 @@ public: // Bound is the AABBox fully containing this item typedef AABox Bound; - // Stats records the life history and performances of this item while performing at rendering and updating. + // Status records the life history and performances of this item while performing at rendering and updating. // This is Used for monitoring and dynamically adjust the quality - class Stats { + class Status { public: + typedef glm::ivec2 Value; + typedef std::function Getter; + int _firstFrame; + std::vector _values; + + void addGetter(Getter& getter) { _values.push_back(getter); } }; + typedef std::shared_ptr StatusPointer; // Update Functor class UpdateFunctorInterface { @@ -222,7 +229,14 @@ public: virtual const model::MaterialKey getMaterialKey() const = 0; ~PayloadInterface() {} + + // Status interface is local to the base class + const StatusPointer& getStatus() const { return _status; } + void addStatusGetter(Status::Getter& getter) { _status->addGetter(getter); } + protected: + StatusPointer _status; + friend class Item; virtual void update(const UpdateFunctorPointer& functor) = 0; }; @@ -253,6 +267,9 @@ public: // Shape Type Interface const model::MaterialKey getMaterialKey() const { return _payload->getMaterialKey(); } + // Access the status + const StatusPointer& getStatus() const { return _payload->getStatus(); } + protected: PayloadPointer _payload; ItemKey _key; diff --git a/libraries/render/src/render/drawItemBounds.slf b/libraries/render/src/render/drawItemBounds.slf new file mode 100644 index 0000000000..b5d1a297bf --- /dev/null +++ b/libraries/render/src/render/drawItemBounds.slf @@ -0,0 +1,19 @@ +<@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 +// + +varying vec4 varColor; + + +void main(void) { + gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); +} diff --git a/libraries/render/src/render/drawItemBounds.slv b/libraries/render/src/render/drawItemBounds.slv new file mode 100644 index 0000000000..e1193a9874 --- /dev/null +++ b/libraries/render/src/render/drawItemBounds.slv @@ -0,0 +1,43 @@ +<@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()$> + +void main(void) { + const vec4 UNIT_BOX[13] = vec4[13]( + vec4(0.0, 0.0, 0.0, 1.0), + vec4(1.0, 0.0, 0.0, 1.0), + vec4(1.0, 1.0, 0.0, 1.0), + vec4(0.0, 1.0, 0.0, 1.0), + vec4(0.0, 0.0, 0.0, 1.0), + vec4(1.0, 0.0, 0.0, 1.0), + vec4(1.0, 0.0, 1.0, 1.0), + vec4(0.0, 0.0, 1.0, 1.0), + vec4(0.0, 0.0, 0.0, 1.0), + vec4(0.0, 1.0, 0.0, 1.0), + vec4(0.0, 1.0, 1.0, 1.0), + vec4(0.0, 0.0, 1.0, 1.0), + vec4(0.0, 0.0, 0.0, 1.0) + ); + vec4 pos = UNIT_BOX[gl_VertexID]; + + // standard transform + TransformCamera cam = getTransformCamera(); + TransformObject obj = getTransformObject(); + <$transformModelToClipPos(cam, obj, pos, gl_Position)$> + + // varTexcoord = (pos.xy + 1) * 0.5; +} \ No newline at end of file From 8bd5e15f739adc890ec2c8c75bdb1027a2cc7170 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 30 Jun 2015 14:43:57 -0700 Subject: [PATCH 03/21] Exposing the viewport to the shader and have a first draft of the draw status pipeline --- libraries/gpu/src/gpu/Batch.cpp | 6 ++ libraries/gpu/src/gpu/Batch.h | 2 + libraries/gpu/src/gpu/Format.h | 1 + libraries/gpu/src/gpu/GLBackend.cpp | 1 + libraries/gpu/src/gpu/GLBackend.h | 10 ++- libraries/gpu/src/gpu/GLBackendPipeline.cpp | 14 ++++ libraries/gpu/src/gpu/GLBackendShader.cpp | 10 +++ libraries/gpu/src/gpu/GLBackendTransform.cpp | 21 +++++- libraries/gpu/src/gpu/Transform.slh | 8 +++ libraries/render/src/render/DrawStatus.cpp | 41 ++++++++++++ libraries/render/src/render/DrawStatus.h | 4 +- .../render/src/render/drawItemStatus.slf | 19 ++++++ .../render/src/render/drawItemStatus.slv | 66 +++++++++++++++++++ 13 files changed, 198 insertions(+), 5 deletions(-) create mode 100644 libraries/render/src/render/drawItemStatus.slf create mode 100644 libraries/render/src/render/drawItemStatus.slv diff --git a/libraries/gpu/src/gpu/Batch.cpp b/libraries/gpu/src/gpu/Batch.cpp index bff99e7ec3..ee028e79e6 100644 --- a/libraries/gpu/src/gpu/Batch.cpp +++ b/libraries/gpu/src/gpu/Batch.cpp @@ -159,6 +159,12 @@ void Batch::setProjectionTransform(const Mat4& proj) { _params.push_back(cacheData(sizeof(Mat4), &proj)); } +void Batch::setViewportTransform(const Vec4i& viewport) { + ADD_COMMAND(setViewportTransform); + + _params.push_back(cacheData(sizeof(Vec4i), &viewport)); +} + void Batch::setPipeline(const PipelinePointer& pipeline) { ADD_COMMAND(setPipeline); diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index 9c97db65ef..599a748d9b 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -105,6 +105,7 @@ public: void setModelTransform(const Transform& model); void setViewTransform(const Transform& view); void setProjectionTransform(const Mat4& proj); + void setViewportTransform(const Vec4i& viewport); // Viewport is xy = low left corner in the framebuffer, zw = width height of the viewport // Pipeline Stage void setPipeline(const PipelinePointer& pipeline); @@ -177,6 +178,7 @@ public: COMMAND_setModelTransform, COMMAND_setViewTransform, COMMAND_setProjectionTransform, + COMMAND_setViewportTransform, COMMAND_setPipeline, COMMAND_setStateBlendFactor, diff --git a/libraries/gpu/src/gpu/Format.h b/libraries/gpu/src/gpu/Format.h index 7cf913430d..ac71cc7940 100644 --- a/libraries/gpu/src/gpu/Format.h +++ b/libraries/gpu/src/gpu/Format.h @@ -38,6 +38,7 @@ typedef uint32 Offset; typedef glm::mat4 Mat4; typedef glm::mat3 Mat3; typedef glm::vec4 Vec4; +typedef glm::ivec4 Vec4i; typedef glm::vec3 Vec3; typedef glm::vec2 Vec2; typedef glm::ivec2 Vec2i; diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index 9004c4a8fe..112e34eaea 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -29,6 +29,7 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] = (&::gpu::GLBackend::do_setModelTransform), (&::gpu::GLBackend::do_setViewTransform), (&::gpu::GLBackend::do_setProjectionTransform), + (&::gpu::GLBackend::do_setViewportTransform), (&::gpu::GLBackend::do_setPipeline), (&::gpu::GLBackend::do_setStateBlendFactor), diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index 28236c68c9..0ee0f8d349 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -96,7 +96,9 @@ public: #if (GPU_TRANSFORM_PROFILE == GPU_CORE) #else + GLuint _transformObject_model = -1; GLuint _transformCamera_viewInverse = -1; + GLuint _transformCamera_viewport = -1; #endif GLShader(); @@ -267,7 +269,8 @@ protected: void do_setModelTransform(Batch& batch, uint32 paramOffset); void do_setViewTransform(Batch& batch, uint32 paramOffset); void do_setProjectionTransform(Batch& batch, uint32 paramOffset); - + void do_setViewportTransform(Batch& batch, uint32 paramOffset); + void initTransform(); void killTransform(); // Synchronize the state cache of this Backend with the actual real state of the GL Context @@ -281,9 +284,11 @@ protected: Transform _model; Transform _view; Mat4 _projection; + Vec4i _viewport; bool _invalidModel; bool _invalidView; bool _invalidProj; + bool _invalidViewport; GLenum _lastMode; @@ -296,6 +301,7 @@ protected: _invalidModel(true), _invalidView(true), _invalidProj(false), + _invalidViewport(false), _lastMode(GL_TEXTURE) {} } _transform; @@ -329,7 +335,9 @@ protected: #if (GPU_TRANSFORM_PROFILE == GPU_CORE) #else + GLint _program_transformObject_model = -1; GLint _program_transformCamera_viewInverse = -1; + GLint _program_transformCamera_viewport = -1; #endif State::Data _stateCache; diff --git a/libraries/gpu/src/gpu/GLBackendPipeline.cpp b/libraries/gpu/src/gpu/GLBackendPipeline.cpp index f4449e9ea1..e4dd90cac0 100755 --- a/libraries/gpu/src/gpu/GLBackendPipeline.cpp +++ b/libraries/gpu/src/gpu/GLBackendPipeline.cpp @@ -73,7 +73,9 @@ void GLBackend::do_setPipeline(Batch& batch, uint32 paramOffset) { #if (GPU_TRANSFORM_PROFILE == GPU_CORE) #else + _pipeline._program_transformObject_model = -1; _pipeline._program_transformCamera_viewInverse = -1; + _pipeline._program_transformCamera_viewport = -1; #endif _pipeline._state = nullptr; @@ -91,7 +93,9 @@ void GLBackend::do_setPipeline(Batch& batch, uint32 paramOffset) { #if (GPU_TRANSFORM_PROFILE == GPU_CORE) #else + _pipeline._program_transformObject_model = pipelineObject->_program->_transformObject_model; _pipeline._program_transformCamera_viewInverse = pipelineObject->_program->_transformCamera_viewInverse; + _pipeline._program_transformCamera_viewport = pipelineObject->_program->_transformCamera_viewport; #endif } @@ -143,10 +147,20 @@ void GLBackend::updatePipeline() { #if (GPU_TRANSFORM_PROFILE == GPU_CORE) #else + // If shader program needs the model we need to provide it + if (_pipeline._program_transformObject_model >= 0) { + glUniformMatrix4fv(_pipeline._program_transformObject_model, 1, false, (const GLfloat*) &_transform._transformObject._model); + } + // If shader program needs the inverseView we need to provide it if (_pipeline._program_transformCamera_viewInverse >= 0) { glUniformMatrix4fv(_pipeline._program_transformCamera_viewInverse, 1, false, (const GLfloat*) &_transform._transformCamera._viewInverse); } + + // If shader program needs the viewport we need to provide it + if (_pipeline._program_transformCamera_viewport >= 0) { + glUniform4fv(_pipeline._program_transformCamera_viewport, 1, (const GLfloat*) &_transform._transformCamera._viewport); + } #endif } diff --git a/libraries/gpu/src/gpu/GLBackendShader.cpp b/libraries/gpu/src/gpu/GLBackendShader.cpp index 45adbcdb3c..ec02c1333b 100755 --- a/libraries/gpu/src/gpu/GLBackendShader.cpp +++ b/libraries/gpu/src/gpu/GLBackendShader.cpp @@ -111,10 +111,20 @@ void makeBindings(GLBackend::GLShader* shader) { shader->_transformCameraSlot = gpu::TRANSFORM_CAMERA_SLOT; } #else + loc = glGetUniformLocation(glprogram, "transformObject_model"); + if (loc >= 0) { + shader->_transformObject_model = loc; + } + loc = glGetUniformLocation(glprogram, "transformCamera_viewInverse"); if (loc >= 0) { shader->_transformCamera_viewInverse = loc; } + + loc = glGetUniformLocation(glprogram, "transformCamera_viewport"); + if (loc >= 0) { + shader->_transformCamera_viewport = loc; + } #endif } diff --git a/libraries/gpu/src/gpu/GLBackendTransform.cpp b/libraries/gpu/src/gpu/GLBackendTransform.cpp index 2e3c2dca70..21a2d57271 100755 --- a/libraries/gpu/src/gpu/GLBackendTransform.cpp +++ b/libraries/gpu/src/gpu/GLBackendTransform.cpp @@ -31,6 +31,12 @@ void GLBackend::do_setProjectionTransform(Batch& batch, uint32 paramOffset) { _transform._invalidProj = true; } +void GLBackend::do_setViewportTransform(Batch& batch, uint32 paramOffset) { + memcpy(&_transform._viewport, batch.editData(batch._params[paramOffset]._uint), sizeof(Vec4i)); + _transform._invalidViewport = true; +} + + void GLBackend::initTransform() { #if (GPU_TRANSFORM_PROFILE == GPU_CORE) glGenBuffers(1, &_transform._transformObjectBuffer); @@ -57,10 +63,13 @@ void GLBackend::killTransform() { } void GLBackend::syncTransformStateCache() { + _transform._invalidViewport = true; _transform._invalidProj = true; _transform._invalidView = true; _transform._invalidModel = true; + glGetIntegerv(GL_VIEWPORT, (GLint*) &_transform._viewport); + GLint currentMode; glGetIntegerv(GL_MATRIX_MODE, ¤tMode); _transform._lastMode = currentMode; @@ -78,6 +87,13 @@ void GLBackend::updateTransform() { GLint originalMatrixMode; glGetIntegerv(GL_MATRIX_MODE, &originalMatrixMode); // Check all the dirty flags and update the state accordingly + if (_transform._invalidViewport) { + _transform._transformCamera._viewport = glm::vec4(_transform._viewport); + + // Where we assign the GL viewport + glViewport(_transform._viewport.x, _transform._viewport.y, _transform._viewport.z, _transform._viewport.w); + } + if (_transform._invalidProj) { _transform._transformCamera._projection = _transform._projection; _transform._transformCamera._projectionInverse = glm::inverse(_transform._projection); @@ -100,7 +116,7 @@ void GLBackend::updateTransform() { } #if (GPU_TRANSFORM_PROFILE == GPU_CORE) - if (_transform._invalidView || _transform._invalidProj) { + if (_transform._invalidView || _transform._invalidProj || _transform._invalidViewport) { glBindBufferBase(GL_UNIFORM_BUFFER, TRANSFORM_CAMERA_SLOT, 0); glBindBuffer(GL_ARRAY_BUFFER, _transform._transformCameraBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(_transform._transformCamera), (const void*) &_transform._transformCamera, GL_DYNAMIC_DRAW); @@ -162,7 +178,8 @@ void GLBackend::updateTransform() { #endif // Flags are clean - _transform._invalidView = _transform._invalidProj = _transform._invalidModel = false; + _transform._invalidView = _transform._invalidProj = _transform._invalidModel = _transform._invalidViewport = false; + glMatrixMode(originalMatrixMode); } diff --git a/libraries/gpu/src/gpu/Transform.slh b/libraries/gpu/src/gpu/Transform.slh index d01fe128ae..274032a642 100644 --- a/libraries/gpu/src/gpu/Transform.slh +++ b/libraries/gpu/src/gpu/Transform.slh @@ -87,10 +87,18 @@ TransformCamera getTransformCamera() { } uniform mat4 transformCamera_viewInverse; +uniform vec4 transformCamera_viewport; <@endif@> <@endfunc@> +<@func transformCameraViewport(cameraTransform, viewport)@> +<@if GPU_TRANSFORM_PROFILE == GPU_CORE@> + <$viewport$> = <$cameraTransform$>._viewport; +<@else@> + <$viewport$> = transformCamera_viewport; +<@endif@> +<@endfunc@> <@func transformModelToClipPos(cameraTransform, objectTransform, modelPos, clipPos)@> <@if GPU_TRANSFORM_PROFILE == GPU_CORE@> diff --git a/libraries/render/src/render/DrawStatus.cpp b/libraries/render/src/render/DrawStatus.cpp index eaf39b6893..afe9aa3798 100644 --- a/libraries/render/src/render/DrawStatus.cpp +++ b/libraries/render/src/render/DrawStatus.cpp @@ -26,6 +26,8 @@ #include "drawItemBounds_vert.h" #include "drawItemBounds_frag.h" +#include "drawItemStatus_vert.h" +#include "drawItemStatus_frag.h" using namespace render; @@ -55,6 +57,30 @@ const gpu::PipelinePointer& DrawStatus::getDrawItemBoundsPipeline() { return _drawItemBoundsPipeline; } +const gpu::PipelinePointer& DrawStatus::getDrawItemStatusPipeline() { + if (!_drawItemStatusPipeline) { + auto vs = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(drawItemStatus_vert))); + auto ps = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(drawItemStatus_frag))); + gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(vs, ps)); + + gpu::Shader::BindingSet slotBindings; + gpu::Shader::makeProgram(*program, slotBindings); + + gpu::StatePointer state = gpu::StatePointer(new gpu::State()); + + state->setDepthTest(false, false, gpu::LESS_EQUAL); + + // Blend on transparent + 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); + + // Good to go add the brand new pipeline + _drawItemStatusPipeline.reset(gpu::Pipeline::create(program, state)); + } + return _drawItemStatusPipeline; +} + void DrawStatus::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems) { assert(renderContext->args); assert(renderContext->args->_viewFrustum); @@ -92,6 +118,21 @@ void DrawStatus::run(const SceneContextPointer& sceneContext, const RenderContex } } + batch.setPipeline(getDrawItemStatusPipeline()); + + for (auto& item : inItems) { + if (!item.bounds.isInvalid()) { + Transform model; + model.setTranslation(item.bounds.getCorner()); + if (!item.bounds.isNull()) { + model.setScale(item.bounds.getDimensions()); + } + + batch.setModelTransform(model); + batch.draw(gpu::TRIANGLE_STRIP, 4, 0); + } + } + // Before rendering the batch make sure we re in sync with gl state args->_context->syncCache(); renderContext->args->_context->syncCache(); diff --git a/libraries/render/src/render/DrawStatus.h b/libraries/render/src/render/DrawStatus.h index a1e962ebec..079f223ff5 100644 --- a/libraries/render/src/render/DrawStatus.h +++ b/libraries/render/src/render/DrawStatus.h @@ -14,12 +14,11 @@ #include "DrawTask.h" #include "gpu/Batch.h" -#include - namespace render { class DrawStatus { gpu::PipelinePointer _drawItemBoundsPipeline; + gpu::PipelinePointer _drawItemStatusPipeline; public: @@ -28,6 +27,7 @@ namespace render { typedef Job::ModelI JobModel; const gpu::PipelinePointer& getDrawItemBoundsPipeline(); + const gpu::PipelinePointer& getDrawItemStatusPipeline(); }; } diff --git a/libraries/render/src/render/drawItemStatus.slf b/libraries/render/src/render/drawItemStatus.slf new file mode 100644 index 0000000000..dcf5d3ee25 --- /dev/null +++ b/libraries/render/src/render/drawItemStatus.slf @@ -0,0 +1,19 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// drawItemStatus.frag +// fragment shader +// +// Created by Sam Gateau on 6/30/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 +// + +varying vec4 varColor; + + +void main(void) { + gl_FragColor = varColor; +} diff --git a/libraries/render/src/render/drawItemStatus.slv b/libraries/render/src/render/drawItemStatus.slv new file mode 100644 index 0000000000..da99d2692e --- /dev/null +++ b/libraries/render/src/render/drawItemStatus.slv @@ -0,0 +1,66 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// drawItemStatus.slv +// vertex shader +// +// Created by Sam Gateau on 6/30/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()$> + +varying vec4 varColor; + +attribute vec4 inStatus; + +vec3 paintRainbow(float nv) { + float v = nv * 5.f; + if ( v < 0.f ) + return vec3(1.f, 0.f, 0.f); + else if ( v < 1.f) + return vec3(1.f, v, 0.f); + else if ( v < 2.f) + return vec3(1.f - (v-1.f), 1.f, 0.f); + else if ( v < 3.f) + return vec3(0.f, 1.f, (v-2.f)); + else if ( v < 4.f) + return vec3(0.f, 1.f - (v-3.f), 1.f ); + else if ( v < 5.f) + return vec3((v-4.f), 0.f, 1.f ); + else + return vec3(1.f, 0.f, 1.f); +} + +void main(void) { + const vec2 ICON_PIXEL_SIZE = vec2(10, 10); + const vec4 UNIT_QUAD[4] = vec4[4]( + vec4(-1.0, -1.0, 0.0, 1.0), + vec4(1.0, -1.0, 0.0, 1.0), + vec4(-1.0, 1.0, 0.0, 1.0), + vec4(1.0, 1.0, 0.0, 1.0) + ); + + // Use the status for showing a color ? + varColor = vec4(paintRainbow(inStatus.x), 1.0); + + + vec4 anchorPoint = vec4(0.5, 0.5, 0.5, 1.0); + TransformCamera cam = getTransformCamera(); + TransformObject obj = getTransformObject(); + <$transformModelToClipPos(cam, obj, anchorPoint, anchorPoint)$> + + vec4 pos = UNIT_QUAD[gl_VertexID]; + + vec4 viewport; + <$transformCameraViewport(cam, viewport)$>; + vec2 clipIconSize = vec2(ICON_PIXEL_SIZE.x / viewport.z, ICON_PIXEL_SIZE.y / viewport.w); + + gl_Position = anchorPoint + anchorPoint.w * vec4(pos.xy * clipIconSize, 0.0, 0.0); +} \ No newline at end of file From aa55de46c2fb26c99e39b21cad930ed7deb75e5f Mon Sep 17 00:00:00 2001 From: Niraj Venkat Date: Tue, 30 Jun 2015 16:09:45 -0700 Subject: [PATCH 04/21] Drawing full bounding box --- libraries/render/src/render/DrawStatus.cpp | 36 +++++----- libraries/render/src/render/Stats.h | 29 --------- .../render/src/render/drawItemBounds.slv | 65 +++++++++++-------- 3 files changed, 55 insertions(+), 75 deletions(-) delete mode 100644 libraries/render/src/render/Stats.h diff --git a/libraries/render/src/render/DrawStatus.cpp b/libraries/render/src/render/DrawStatus.cpp index eaf39b6893..e95a47e872 100644 --- a/libraries/render/src/render/DrawStatus.cpp +++ b/libraries/render/src/render/DrawStatus.cpp @@ -33,23 +33,23 @@ using namespace render; const gpu::PipelinePointer& DrawStatus::getDrawItemBoundsPipeline() { if (!_drawItemBoundsPipeline) { - auto vs = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(drawItemBounds_vert))); - auto ps = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(drawItemBounds_frag))); - gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(vs, ps)); - - gpu::Shader::BindingSet slotBindings; - gpu::Shader::makeProgram(*program, slotBindings); - - gpu::StatePointer state = gpu::StatePointer(new gpu::State()); - - state->setDepthTest(true, false, gpu::LESS_EQUAL); - - // Blend on transparent - 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); - - // Good to go add the brand new pipeline + auto vs = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(drawItemBounds_vert))); + auto ps = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(drawItemBounds_frag))); + gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(vs, ps)); + + gpu::Shader::BindingSet slotBindings; + gpu::Shader::makeProgram(*program, slotBindings); + + gpu::StatePointer state = gpu::StatePointer(new gpu::State()); + + state->setDepthTest(true, false, gpu::LESS_EQUAL); + + // Blend on transparent + 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); + + // Good to go add the brand new pipeline _drawItemBoundsPipeline.reset(gpu::Pipeline::create(program, state)); } return _drawItemBoundsPipeline; @@ -88,7 +88,7 @@ void DrawStatus::run(const SceneContextPointer& sceneContext, const RenderContex } batch.setModelTransform(model); - batch.draw(gpu::LINE_STRIP, 13, 0); + batch.draw(gpu::LINES, 24, 0); } } diff --git a/libraries/render/src/render/Stats.h b/libraries/render/src/render/Stats.h deleted file mode 100644 index 5291581d7e..0000000000 --- a/libraries/render/src/render/Stats.h +++ /dev/null @@ -1,29 +0,0 @@ -// -// Stats.h -// render/src/render -// -// Created by Niraj Venkat 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 -// - -#ifndef hifi_render_Stats_h -#define hifi_render_Stats_h - -#include "DrawTask.h" -#include "gpu/Batch.h" -#include - - -namespace render { - class DrawStats { - public: - void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems); - - typedef Job::ModelI JobModel; - }; -} - -#endif // hifi_render_Stats_h diff --git a/libraries/render/src/render/drawItemBounds.slv b/libraries/render/src/render/drawItemBounds.slv index e1193a9874..74c4fe3ab5 100644 --- a/libraries/render/src/render/drawItemBounds.slv +++ b/libraries/render/src/render/drawItemBounds.slv @@ -1,38 +1,47 @@ -<@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/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()$> + void main(void) { - const vec4 UNIT_BOX[13] = vec4[13]( + const vec4 UNIT_BOX[8] = vec4[8]( vec4(0.0, 0.0, 0.0, 1.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, 1.0), - vec4(0.0, 1.0, 0.0, 1.0), - vec4(0.0, 0.0, 0.0, 1.0), - vec4(1.0, 0.0, 0.0, 1.0), + vec4(0.0, 0.0, 1.0, 1.0), vec4(1.0, 0.0, 1.0, 1.0), - vec4(0.0, 0.0, 1.0, 1.0), - vec4(0.0, 0.0, 0.0, 1.0), - vec4(0.0, 1.0, 0.0, 1.0), vec4(0.0, 1.0, 1.0, 1.0), - vec4(0.0, 0.0, 1.0, 1.0), - vec4(0.0, 0.0, 0.0, 1.0) + vec4(1.0, 1.0, 1.0, 1.0) ); - vec4 pos = UNIT_BOX[gl_VertexID]; + 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 + ); + vec4 pos = UNIT_BOX[UNIT_BOX_LINE_INDICES[gl_VertexID]]; // standard transform TransformCamera cam = getTransformCamera(); From 2f04a9d3da68147037b0738a866bf8c7f03f2835 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 1 Jul 2015 07:47:46 -0700 Subject: [PATCH 05/21] refining the shader pipeline and trying to pass a Status Getter from the model and fails --- .../src/RenderableModelEntityItem.cpp | 17 +++- libraries/gpu/src/gpu/GLBackend.cpp | 12 +++ libraries/render-utils/src/Model.cpp | 32 +++++++ libraries/render-utils/src/Model.h | 1 + libraries/render/src/render/DrawStatus.cpp | 95 ++++++++++++++----- libraries/render/src/render/DrawStatus.h | 9 ++ libraries/render/src/render/Scene.h | 13 ++- .../render/src/render/drawItemBounds.slv | 5 + .../render/src/render/drawItemStatus.slv | 6 +- 9 files changed, 159 insertions(+), 31 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 14a64d289e..c5c92837bf 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -177,7 +177,22 @@ bool RenderableModelEntityItem::addToScene(EntityItemPointer self, std::shared_p pendingChanges.resetItem(_myMetaItem, renderPayload); if (_model) { - return _model->addToScene(scene, pendingChanges); + // return _model->addToScene(scene, pendingChanges); + + render::Item::Status::Getter statusGetter = [this] () -> render::Item::Status::Value { + quint64 now = usecTimestampNow(); + /* if (now - entity->getLastEditedFromRemote() < 0.1f * USECS_PER_SECOND) { + return glm::vec4 redColor(1.0f, 0.0f, 0.0f, 1.0f); + renderBoundingBox(entity, args, 0.16f, redColor); + } + */ + if (now - this->getLastBroadcast() < 0.2f * USECS_PER_SECOND) { + return 256; + } + return 0; + }; + return _model->addToScene(scene, pendingChanges, statusGetter); + } return true; diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index 112e34eaea..b7b2744c31 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -191,6 +191,18 @@ void GLBackend::do_drawIndexed(Batch& batch, uint32 paramOffset) { } void GLBackend::do_drawInstanced(Batch& batch, uint32 paramOffset) { + updateInput(); + updateTransform(); + updatePipeline(); + + GLint numInstances = batch._params[paramOffset + 4]._uint; + Primitive primitiveType = (Primitive)batch._params[paramOffset + 3]._uint; + GLenum mode = _primitiveToGLmode[primitiveType]; + uint32 numVertices = batch._params[paramOffset + 2]._uint; + uint32 startVertex = batch._params[paramOffset + 1]._uint; + uint32 startInstance = batch._params[paramOffset + 0]._uint; + + glDrawArraysInstanced(mode, startVertex, numVertices, numInstances); (void) CHECK_GL_ERROR(); } diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 93f3f345f0..f617ecf26f 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -910,6 +910,38 @@ bool Model::addToScene(std::shared_ptr scene, render::PendingChan return somethingAdded; } +bool Model::addToScene(std::shared_ptr scene, render::PendingChanges& pendingChanges, render::Item::Status::Getter& statusGetter) { + if (!_meshGroupsKnown && isLoadedWithTextures()) { + segregateMeshGroups(); + } + + bool somethingAdded = false; + + foreach (auto renderItem, _transparentRenderItems) { + auto item = scene->allocateID(); + auto renderData = MeshPartPayload::Pointer(renderItem); + auto renderPayload = render::PayloadPointer(new MeshPartPayload::Payload(renderData)); + renderPayload->addStatusGetter(statusGetter); + pendingChanges.resetItem(item, renderPayload); + _renderItems.insert(item, renderPayload); + somethingAdded = true; + } + + foreach (auto renderItem, _opaqueRenderItems) { + auto item = scene->allocateID(); + auto renderData = MeshPartPayload::Pointer(renderItem); + auto renderPayload = render::PayloadPointer(new MeshPartPayload::Payload(renderData)); + renderPayload->addStatusGetter(statusGetter); + pendingChanges.resetItem(item, renderPayload); + _renderItems.insert(item, renderPayload); + somethingAdded = true; + } + + _readyWhenAdded = readyToAddToScene(); + + return somethingAdded; +} + void Model::removeFromScene(std::shared_ptr scene, render::PendingChanges& pendingChanges) { foreach (auto item, _renderItems.keys()) { pendingChanges.removeItem(item); diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 3748403b97..5e440d012d 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -118,6 +118,7 @@ public: bool needsFixupInScene() { return !_readyWhenAdded && readyToAddToScene(); } bool readyToAddToScene(RenderArgs* renderArgs = nullptr) { return !_needsReload && isRenderable() && isActive() && isLoadedWithTextures(); } bool addToScene(std::shared_ptr scene, render::PendingChanges& pendingChanges); + bool addToScene(std::shared_ptr scene, render::PendingChanges& pendingChanges, render::Item::Status::Getter& statusGetter); void removeFromScene(std::shared_ptr scene, render::PendingChanges& pendingChanges); /// Sets the URL of the model to render. diff --git a/libraries/render/src/render/DrawStatus.cpp b/libraries/render/src/render/DrawStatus.cpp index afe9aa3798..ef91efda71 100644 --- a/libraries/render/src/render/DrawStatus.cpp +++ b/libraries/render/src/render/DrawStatus.cpp @@ -42,6 +42,9 @@ const gpu::PipelinePointer& DrawStatus::getDrawItemBoundsPipeline() { gpu::Shader::BindingSet slotBindings; gpu::Shader::makeProgram(*program, slotBindings); + _drawItemBoundPosLoc = program->getUniforms().findLocation("inBoundPos"); + _drawItemBoundDimLoc = program->getUniforms().findLocation("inBoundDim"); + gpu::StatePointer state = gpu::StatePointer(new gpu::State()); state->setDepthTest(true, false, gpu::LESS_EQUAL); @@ -66,6 +69,10 @@ const gpu::PipelinePointer& DrawStatus::getDrawItemStatusPipeline() { gpu::Shader::BindingSet slotBindings; gpu::Shader::makeProgram(*program, slotBindings); + _drawItemStatusPosLoc = program->getUniforms().findLocation("inBoundPos"); + _drawItemStatusDimLoc = program->getUniforms().findLocation("inBoundDim"); + _drawItemStatusValueLoc = program->getUniforms().findLocation("inStatus"); + gpu::StatePointer state = gpu::StatePointer(new gpu::State()); state->setDepthTest(false, false, gpu::LESS_EQUAL); @@ -85,7 +92,49 @@ void DrawStatus::run(const SceneContextPointer& sceneContext, const RenderContex assert(renderContext->args); assert(renderContext->args->_viewFrustum); RenderArgs* args = renderContext->args; + auto& scene = sceneContext->_scene; + // FIrst thing, we collect the bound and the status for all the items we want to render + int nbItems = 0; + { + if (!_itemBounds) { + _itemBounds.reset(new gpu::Buffer()); + } + if (!_itemStatus) { + _itemStatus.reset(new gpu::Buffer()); + } + + _itemBounds->resize((inItems.size() * sizeof(AABox))); + _itemStatus->resize((inItems.size() * sizeof(glm::vec4))); + AABox* itemAABox = reinterpret_cast (_itemBounds->editData()); + glm::vec4* itemStatus = reinterpret_cast (_itemStatus->editData()); + for (auto& item : inItems) { + if (!item.bounds.isInvalid()) { + if (!item.bounds.isNull()) { + (*itemAABox) = item.bounds; + } else { + (*itemAABox).setBox(item.bounds.getCorner(), 0.1f); + } + auto& itemScene = scene->getItem(item.id); + auto& status = itemScene.getStatus(); + if (status) { + status->getValue((*itemStatus)); + } else { + (*itemStatus) = glm::vec4(-1.0f); + } + + nbItems++; + itemAABox++; + itemStatus++; + } + } + } + + if (nbItems == 0) { + return; + } + + // Allright, something to render let's do it gpu::Batch batch; glm::mat4 projMat; @@ -97,46 +146,40 @@ void DrawStatus::run(const SceneContextPointer& sceneContext, const RenderContex } batch.setProjectionTransform(projMat); batch.setViewTransform(viewMat); + batch.setModelTransform(Transform()); - - // batch.setModelTransform(Transform()); - // bind the unit cube geometry +/* if (!_drawItemFormat) { + _drawItemFormat.reset(new gpu::Stream::Format()); + _drawItemFormat->setAttribute(0, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0, gpu::Stream::PER_INSTANCE); + _drawItemFormat->setAttribute(1, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), sizeof(glm::vec3), gpu::Stream::PER_INSTANCE); + } +*/ // bind the one gpu::Pipeline we need batch.setPipeline(getDrawItemBoundsPipeline()); - for (auto& item : inItems) { - if (!item.bounds.isInvalid()) { - Transform model; - model.setTranslation(item.bounds.getCorner()); - if (!item.bounds.isNull()) { - model.setScale(item.bounds.getDimensions()); - } + AABox* itemAABox = reinterpret_cast (_itemBounds->editData()); + glm::vec4* itemStatus = reinterpret_cast (_itemStatus->editData()); - batch.setModelTransform(model); - batch.draw(gpu::LINE_STRIP, 13, 0); - } + for (int i = 0; i < nbItems; i++) { + + batch._glUniform3fv(_drawItemBoundPosLoc, 1, (const GLfloat*) (itemAABox + i)); + batch._glUniform3fv(_drawItemBoundDimLoc, 1, ((const GLfloat*) (itemAABox + i)) + 3); + + batch.draw(gpu::LINE_STRIP, 13, 0); } batch.setPipeline(getDrawItemStatusPipeline()); + for (int i = 0; i < nbItems; i++) { + batch._glUniform3fv(_drawItemStatusPosLoc, 1, (const GLfloat*) (itemAABox + i)); + batch._glUniform3fv(_drawItemStatusDimLoc, 1, ((const GLfloat*) (itemAABox + i)) + 3); + batch._glUniform4fv(_drawItemStatusValueLoc, 1, (const GLfloat*) (itemStatus + i)); - for (auto& item : inItems) { - if (!item.bounds.isInvalid()) { - Transform model; - model.setTranslation(item.bounds.getCorner()); - if (!item.bounds.isNull()) { - model.setScale(item.bounds.getDimensions()); - } - - batch.setModelTransform(model); - batch.draw(gpu::TRIANGLE_STRIP, 4, 0); - } + batch.draw(gpu::TRIANGLE_STRIP, 4, 0); } // Before rendering the batch make sure we re in sync with gl state args->_context->syncCache(); renderContext->args->_context->syncCache(); args->_context->render((batch)); - args->_batch = nullptr; - } \ No newline at end of file diff --git a/libraries/render/src/render/DrawStatus.h b/libraries/render/src/render/DrawStatus.h index 079f223ff5..ca4763d33b 100644 --- a/libraries/render/src/render/DrawStatus.h +++ b/libraries/render/src/render/DrawStatus.h @@ -17,8 +17,17 @@ namespace render { class DrawStatus { + int _drawItemBoundPosLoc = -1; + int _drawItemBoundDimLoc = -1; + int _drawItemStatusPosLoc = -1; + int _drawItemStatusDimLoc = -1; + int _drawItemStatusValueLoc = -1; + + gpu::Stream::FormatPointer _drawItemFormat; gpu::PipelinePointer _drawItemBoundsPipeline; gpu::PipelinePointer _drawItemStatusPipeline; + gpu::BufferPointer _itemBounds; + gpu::BufferPointer _itemStatus; public: diff --git a/libraries/render/src/render/Scene.h b/libraries/render/src/render/Scene.h index 444b45800a..75dc92dbdf 100644 --- a/libraries/render/src/render/Scene.h +++ b/libraries/render/src/render/Scene.h @@ -200,13 +200,22 @@ public: // This is Used for monitoring and dynamically adjust the quality class Status { public: - typedef glm::ivec2 Value; + typedef unsigned char Value; typedef std::function Getter; int _firstFrame; std::vector _values; void addGetter(Getter& getter) { _values.push_back(getter); } + void getValue(glm::vec4& value) { + for (unsigned int i = 0; i < value.length(); i++) { + if (i < _values.size()) { + value[i] = _values[i]() / 256; + } else { + value[i] = 0.0f; + } + } + } }; typedef std::shared_ptr StatusPointer; @@ -232,7 +241,7 @@ public: // Status interface is local to the base class const StatusPointer& getStatus() const { return _status; } - void addStatusGetter(Status::Getter& getter) { _status->addGetter(getter); } + void addStatusGetter(Status::Getter& getter) { if (!_status) { _status.reset(new Status());} _status->addGetter(getter); } protected: StatusPointer _status; diff --git a/libraries/render/src/render/drawItemBounds.slv b/libraries/render/src/render/drawItemBounds.slv index e1193a9874..a74d105cf1 100644 --- a/libraries/render/src/render/drawItemBounds.slv +++ b/libraries/render/src/render/drawItemBounds.slv @@ -16,6 +16,9 @@ <$declareStandardTransform()$> +uniform vec3 inBoundPos; +uniform vec3 inBoundDim; + void main(void) { const vec4 UNIT_BOX[13] = vec4[13]( vec4(0.0, 0.0, 0.0, 1.0), @@ -34,6 +37,8 @@ void main(void) { ); vec4 pos = UNIT_BOX[gl_VertexID]; + pos.xyz = inBoundPos + inBoundDim * pos.xyz; + // standard transform TransformCamera cam = getTransformCamera(); TransformObject obj = getTransformObject(); diff --git a/libraries/render/src/render/drawItemStatus.slv b/libraries/render/src/render/drawItemStatus.slv index da99d2692e..01f47862bc 100644 --- a/libraries/render/src/render/drawItemStatus.slv +++ b/libraries/render/src/render/drawItemStatus.slv @@ -18,7 +18,9 @@ varying vec4 varColor; -attribute vec4 inStatus; +uniform vec3 inBoundPos; +uniform vec3 inBoundDim; +uniform vec4 inStatus; vec3 paintRainbow(float nv) { float v = nv * 5.f; @@ -51,7 +53,7 @@ void main(void) { varColor = vec4(paintRainbow(inStatus.x), 1.0); - vec4 anchorPoint = vec4(0.5, 0.5, 0.5, 1.0); + vec4 anchorPoint = vec4(inBoundPos, 1.0) + vec4(inBoundDim, 0.0) * vec4(0.5, 0.5, 0.5, 0.0); TransformCamera cam = getTransformCamera(); TransformObject obj = getTransformObject(); <$transformModelToClipPos(cam, obj, anchorPoint, anchorPoint)$> From dfa6b03a6ba1feb3ef1f1e5da12cee284428bc20 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 1 Jul 2015 14:20:35 -0700 Subject: [PATCH 06/21] Making the first statusGetter noitify --- .../src/RenderableModelEntityItem.cpp | 20 ++++++++++++++++++- libraries/render/src/render/Scene.h | 2 +- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index c5c92837bf..4bbe2cac52 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -229,7 +229,25 @@ void RenderableModelEntityItem::render(RenderArgs* args) { render::PendingChanges pendingChanges; if (_model->needsFixupInScene()) { _model->removeFromScene(scene, pendingChanges); - _model->addToScene(scene, pendingChanges); + + + render::Item::Status::Getter statusGetter = [this] () -> render::Item::Status::Value { + quint64 now = usecTimestampNow(); + /* if (now - entity->getLastEditedFromRemote() < 0.1f * USECS_PER_SECOND) { + return glm::vec4 redColor(1.0f, 0.0f, 0.0f, 1.0f); + renderBoundingBox(entity, args, 0.16f, redColor); + } + */ + /*if (now - this->getLastBroadcast() < 0.2f * USECS_PER_SECOND) { + return 256; + } + return 0;*/ + static int i = 0; + return (i++)%256; + + }; + + _model->addToScene(scene, pendingChanges, statusGetter); } scene->enqueuePendingChanges(pendingChanges); diff --git a/libraries/render/src/render/Scene.h b/libraries/render/src/render/Scene.h index 75dc92dbdf..02bb03f285 100644 --- a/libraries/render/src/render/Scene.h +++ b/libraries/render/src/render/Scene.h @@ -210,7 +210,7 @@ public: void getValue(glm::vec4& value) { for (unsigned int i = 0; i < value.length(); i++) { if (i < _values.size()) { - value[i] = _values[i]() / 256; + value[i] = _values[i]() / 256.0f; } else { value[i] = 0.0f; } From b23f68107c6dc74b6f4bca7717cf8bbd3937d150 Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 1 Jul 2015 14:52:23 -0700 Subject: [PATCH 07/21] Adding the gpu_shader4 for linux and fixing function name for mac --- libraries/gpu/src/gpu/Config.slh | 5 +++-- libraries/gpu/src/gpu/GLBackend.cpp | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/libraries/gpu/src/gpu/Config.slh b/libraries/gpu/src/gpu/Config.slh index a16ee372ae..76be161822 100644 --- a/libraries/gpu/src/gpu/Config.slh +++ b/libraries/gpu/src/gpu/Config.slh @@ -18,12 +18,13 @@ <@elif GLPROFILE == MAC_GL @> <@def GPU_FEATURE_PROFILE GPU_LEGACY@> <@def GPU_TRANSFORM_PROFILE GPU_LEGACY@> - <@def VERSION_HEADER #version 120 + <@def VERSION_HEADER #version 120 #extension GL_EXT_gpu_shader4 : enable@> <@else@> <@def GPU_FEATURE_PROFILE GPU_LEGACY@> <@def GPU_TRANSFORM_PROFILE GPU_LEGACY@> - <@def VERSION_HEADER #version 120@> + <@def VERSION_HEADER #version 120 +#extension GL_EXT_gpu_shader4 : enable@> <@endif@> <@endif@> diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index b7b2744c31..bb855c46d4 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -202,7 +202,7 @@ void GLBackend::do_drawInstanced(Batch& batch, uint32 paramOffset) { uint32 startVertex = batch._params[paramOffset + 1]._uint; uint32 startInstance = batch._params[paramOffset + 0]._uint; - glDrawArraysInstanced(mode, startVertex, numVertices, numInstances); + glDrawArraysInstancedARB(mode, startVertex, numVertices, numInstances); (void) CHECK_GL_ERROR(); } From 219bcd19edc8d0f7d12695b1b12d5395bf49be20 Mon Sep 17 00:00:00 2001 From: Niraj Venkat Date: Wed, 1 Jul 2015 16:40:42 -0700 Subject: [PATCH 08/21] Status bar update --- libraries/render/src/render/DrawStatus.cpp | 2 +- .../render/src/render/drawItemStatus.slv | 31 ++++++++++++++----- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/libraries/render/src/render/DrawStatus.cpp b/libraries/render/src/render/DrawStatus.cpp index f61a4e56c3..25dea092b2 100644 --- a/libraries/render/src/render/DrawStatus.cpp +++ b/libraries/render/src/render/DrawStatus.cpp @@ -174,7 +174,7 @@ void DrawStatus::run(const SceneContextPointer& sceneContext, const RenderContex batch._glUniform3fv(_drawItemStatusDimLoc, 1, ((const GLfloat*) (itemAABox + i)) + 3); batch._glUniform4fv(_drawItemStatusValueLoc, 1, (const GLfloat*) (itemStatus + i)); - batch.draw(gpu::TRIANGLE_STRIP, 4, 0); + batch.draw(gpu::TRIANGLES, 24, 0); } // Before rendering the batch make sure we re in sync with gl state diff --git a/libraries/render/src/render/drawItemStatus.slv b/libraries/render/src/render/drawItemStatus.slv index 01f47862bc..048493c67e 100644 --- a/libraries/render/src/render/drawItemStatus.slv +++ b/libraries/render/src/render/drawItemStatus.slv @@ -42,27 +42,44 @@ vec3 paintRainbow(float nv) { void main(void) { const vec2 ICON_PIXEL_SIZE = vec2(10, 10); - const vec4 UNIT_QUAD[4] = vec4[4]( + const int NUM_VERTICES = 6; + const vec4 UNIT_QUAD[NUM_VERTICES] = vec4[NUM_VERTICES]( vec4(-1.0, -1.0, 0.0, 1.0), vec4(1.0, -1.0, 0.0, 1.0), vec4(-1.0, 1.0, 0.0, 1.0), + vec4(-1.0, 1.0, 0.0, 1.0), + vec4(1.0, -1.0, 0.0, 1.0), vec4(1.0, 1.0, 0.0, 1.0) ); - // Use the status for showing a color ? - varColor = vec4(paintRainbow(inStatus.x), 1.0); - - vec4 anchorPoint = vec4(inBoundPos, 1.0) + vec4(inBoundDim, 0.0) * vec4(0.5, 0.5, 0.5, 0.0); TransformCamera cam = getTransformCamera(); TransformObject obj = getTransformObject(); <$transformModelToClipPos(cam, obj, anchorPoint, anchorPoint)$> + + int notifNum = gl_VertexID / NUM_VERTICES; + int twoTriID = gl_VertexID - notifNum * NUM_VERTICES; + vec4 pos = UNIT_QUAD[twoTriID]; - vec4 pos = UNIT_QUAD[gl_VertexID]; + // Use the status for showing a color ? + if(notifNum == 0) { + varColor = vec4(paintRainbow(inStatus.x), 1.0); + } else if(notifNum == 1) { + varColor = vec4(paintRainbow(inStatus.y), 1.0); + } else if(notifNum == 2) { + varColor = vec4(paintRainbow(inStatus.z), 1.0); + } else { + varColor = vec4(paintRainbow(inStatus.w), 1.0); + } vec4 viewport; <$transformCameraViewport(cam, viewport)$>; vec2 clipIconSize = vec2(ICON_PIXEL_SIZE.x / viewport.z, ICON_PIXEL_SIZE.y / viewport.w); - gl_Position = anchorPoint + anchorPoint.w * vec4(pos.xy * clipIconSize, 0.0, 0.0); + //Offset size in pixels + float offset = 3.5f; + pos.x += offset * notifNum; + + gl_Position = anchorPoint + (anchorPoint.w * vec4(pos.xy * clipIconSize, 0.0, 0.0)); + } \ No newline at end of file From e8b11f119899732065c4e5a15a8f48d781815367 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 1 Jul 2015 17:27:41 -0700 Subject: [PATCH 09/21] Exposing the display Item Status to js to turn it on/off --- examples/utilities/tools/renderEngineDebug.js | 6 ++++ interface/src/Application.cpp | 2 ++ .../render-utils/src/RenderDeferredTask.cpp | 7 +++++ .../render-utils/src/RenderDeferredTask.h | 5 +++ libraries/render/src/render/DrawStatus.cpp | 7 +---- libraries/render/src/render/DrawTask.h | 31 ++++++++++++++++--- libraries/render/src/render/Engine.h | 2 ++ libraries/render/src/render/Scene.cpp | 9 ++++++ libraries/render/src/render/Scene.h | 15 +++------ .../src/SceneScriptingInterface.h | 6 ++++ 10 files changed, 68 insertions(+), 22 deletions(-) diff --git a/examples/utilities/tools/renderEngineDebug.js b/examples/utilities/tools/renderEngineDebug.js index 8185a24078..d337290927 100755 --- a/examples/utilities/tools/renderEngineDebug.js +++ b/examples/utilities/tools/renderEngineDebug.js @@ -66,6 +66,12 @@ panel.newSlider("Max Drawn Overlay3Ds", -1, 100, function(value) { return (value); } ); +panel.newCheckbox("Display status", + function(value) { Scene.setEngineDisplayItemStatus(value); }, + function() { return Scene.doEngineDisplayItemStatus(); }, + function(value) { return (value); } +); + var tickTackPeriod = 500; function updateCounters() { diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 2e2722aec2..95b9998778 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3526,6 +3526,8 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se renderContext._maxDrawnTransparentItems = sceneInterface->getEngineMaxDrawnTransparentItems(); renderContext._maxDrawnOverlay3DItems = sceneInterface->getEngineMaxDrawnOverlay3DItems(); + renderContext._drawItemStatus = sceneInterface->doEngineDisplayItemStatus(); + renderArgs->_shouldRender = LODManager::shouldRender; renderContext.args = renderArgs; diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index db2b657126..1012624134 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -68,7 +68,11 @@ RenderDeferredTask::RenderDeferredTask() : Task() { _jobs.push_back(Job(new CullItems::JobModel("CullTransparent", _jobs.back().getOutput()))); _jobs.push_back(Job(new DepthSortItems::JobModel("DepthSortTransparent", _jobs.back().getOutput(), DepthSortItems(false)))); _jobs.push_back(Job(new DrawTransparentDeferred::JobModel("TransparentDeferred", _jobs.back().getOutput()))); + _jobs.push_back(Job(new render::DrawStatus::JobModel("DrawStatus", renderedOpaques))); + _jobs.back().setEnabled(false); + _drawStatusJobIndex = _jobs.size() - 1; + _jobs.push_back(Job(new DrawOverlay3D::JobModel("DrawOverlay3D"))); _jobs.push_back(Job(new ResetGLState::JobModel())); } @@ -89,6 +93,9 @@ void RenderDeferredTask::run(const SceneContextPointer& sceneContext, const Rend return; } + // Make sure we turn the displayItemStatus on/off + setDrawItemStatus(renderContext->_drawItemStatus); + renderContext->args->_context->syncCache(); for (auto job : _jobs) { diff --git a/libraries/render-utils/src/RenderDeferredTask.h b/libraries/render-utils/src/RenderDeferredTask.h index 2f65c5ade6..3d11e97634 100755 --- a/libraries/render-utils/src/RenderDeferredTask.h +++ b/libraries/render-utils/src/RenderDeferredTask.h @@ -70,6 +70,11 @@ public: render::Jobs _jobs; + int _drawStatusJobIndex = -1; + + void setDrawItemStatus(bool draw) { if (_drawStatusJobIndex >= 0) { _jobs[_drawStatusJobIndex].setEnabled(draw); } } + bool doDrawItemStatus() const { if (_drawStatusJobIndex >= 0) { return _jobs[_drawStatusJobIndex].isEnabled(); } else { return false; } } + virtual void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); }; diff --git a/libraries/render/src/render/DrawStatus.cpp b/libraries/render/src/render/DrawStatus.cpp index f61a4e56c3..4961e744d9 100644 --- a/libraries/render/src/render/DrawStatus.cpp +++ b/libraries/render/src/render/DrawStatus.cpp @@ -116,12 +116,7 @@ void DrawStatus::run(const SceneContextPointer& sceneContext, const RenderContex (*itemAABox).setBox(item.bounds.getCorner(), 0.1f); } auto& itemScene = scene->getItem(item.id); - auto& status = itemScene.getStatus(); - if (status) { - status->getValue((*itemStatus)); - } else { - (*itemStatus) = glm::vec4(-1.0f); - } + (*itemStatus) = itemScene.getStatusValues(); nbItems++; itemAABox++; diff --git a/libraries/render/src/render/DrawTask.h b/libraries/render/src/render/DrawTask.h index 8a4d424005..a0139732f6 100755 --- a/libraries/render/src/render/DrawTask.h +++ b/libraries/render/src/render/DrawTask.h @@ -77,6 +77,9 @@ public: Job(const Job& other) : _concept(other._concept) {} ~Job(); + bool isEnabled() const { return _concept->isEnabled(); } + void setEnabled(bool isEnabled) { _concept->setEnabled(isEnabled); } + const std::string& getName() const { return _concept->getName(); } const Varying getInput() const { return _concept->getInput(); } const Varying getOutput() const { return _concept->getOutput(); } @@ -92,6 +95,7 @@ public: class Concept { std::string _name; + bool _isEnabled = true; public: Concept() : _name() {} Concept(const std::string& name) : _name(name) {} @@ -99,7 +103,10 @@ public: void setName(const std::string& name) { _name = name; } const std::string& getName() const { return _name; } - + + bool isEnabled() const { return _isEnabled; } + void setEnabled(bool isEnabled) { _isEnabled = isEnabled; } + virtual const Varying getInput() const { return Varying(); } virtual const Varying getOutput() const { return Varying(); } virtual void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) = 0; @@ -119,7 +126,11 @@ public: Model(Data data): _data(data) {} Model(Data data, const std::string& name): Concept(name), _data(data) {} - void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { jobRun(_data, sceneContext, renderContext); } + void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + if (isEnabled()) { + jobRun(_data, sceneContext, renderContext); + } + } }; template class ModelI : public Concept { @@ -135,7 +146,11 @@ public: ModelI(const std::string& name, const Varying& input): Concept(name), _input(input) {} ModelI(const std::string& name, Data data): Concept(name), _data(data) {} - void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { jobRunI(_data, sceneContext, renderContext, _input.get()); } + void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + if (isEnabled()) { + jobRunI(_data, sceneContext, renderContext, _input.get()); + } + } }; template class ModelO : public Concept { @@ -155,7 +170,9 @@ public: ModelO(const std::string& name, Data data): Concept(name), _data(data), _output(Output()) {} void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { - jobRunO(_data, sceneContext, renderContext, _output.edit()); + if (isEnabled()) { + jobRunO(_data, sceneContext, renderContext, _output.edit()); + } } }; @@ -177,7 +194,11 @@ public: void setInput(const Varying& input) { _input = input; } - void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { jobRunIO(_data, sceneContext, renderContext, _input.get(), _output.edit()); } + void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + if (isEnabled()) { + jobRunIO(_data, sceneContext, renderContext, _input.get(), _output.edit()); + } + } }; std::shared_ptr _concept; diff --git a/libraries/render/src/render/Engine.h b/libraries/render/src/render/Engine.h index 054f7e5ce4..1c600b13d6 100644 --- a/libraries/render/src/render/Engine.h +++ b/libraries/render/src/render/Engine.h @@ -49,6 +49,8 @@ public: int _numDrawnOverlay3DItems = 0; int _maxDrawnOverlay3DItems = -1; + bool _drawItemStatus = false; + RenderContext() {} }; typedef std::shared_ptr RenderContextPointer; diff --git a/libraries/render/src/render/Scene.cpp b/libraries/render/src/render/Scene.cpp index 1d2e54541b..7de1e6650c 100644 --- a/libraries/render/src/render/Scene.cpp +++ b/libraries/render/src/render/Scene.cpp @@ -53,6 +53,15 @@ void ItemBucketMap::allocateStandardOpaqueTranparentBuckets() { (*this)[ItemFilter::Builder::transparentShape().withLayered()]; } +void Item::Status::getValues(glm::vec4& values) { + for (int i = 0; i < values.length(); i++) { + if (i < _values.size()) { + values[i] = _values[i]() / 256.0f; + } else { + values[i] = -1.0f; + } + } +} void Item::resetPayload(const PayloadPointer& payload) { if (!payload) { diff --git a/libraries/render/src/render/Scene.h b/libraries/render/src/render/Scene.h index 02bb03f285..9b459e0f3e 100644 --- a/libraries/render/src/render/Scene.h +++ b/libraries/render/src/render/Scene.h @@ -202,20 +202,12 @@ public: public: typedef unsigned char Value; typedef std::function Getter; + typedef std::vector Getters; - int _firstFrame; - std::vector _values; + Getters _values; void addGetter(Getter& getter) { _values.push_back(getter); } - void getValue(glm::vec4& value) { - for (unsigned int i = 0; i < value.length(); i++) { - if (i < _values.size()) { - value[i] = _values[i]() / 256.0f; - } else { - value[i] = 0.0f; - } - } - } + void getValues(glm::vec4& values); }; typedef std::shared_ptr StatusPointer; @@ -278,6 +270,7 @@ public: // Access the status const StatusPointer& getStatus() const { return _payload->getStatus(); } + glm::vec4 getStatusValues() const { glm::vec4 values(-1.f); auto& status = getStatus(); if (status) { status->getValues(values); }; return values; } protected: PayloadPointer _payload; diff --git a/libraries/script-engine/src/SceneScriptingInterface.h b/libraries/script-engine/src/SceneScriptingInterface.h index 8359aa58fa..674b452528 100644 --- a/libraries/script-engine/src/SceneScriptingInterface.h +++ b/libraries/script-engine/src/SceneScriptingInterface.h @@ -106,6 +106,10 @@ public: Q_INVOKABLE int getEngineMaxDrawnTransparentItems() { return _maxDrawnTransparentItems; } Q_INVOKABLE void setEngineMaxDrawnOverlay3DItems(int count) { _maxDrawnOverlay3DItems = count; } Q_INVOKABLE int getEngineMaxDrawnOverlay3DItems() { return _maxDrawnOverlay3DItems; } + + Q_INVOKABLE void setEngineDisplayItemStatus(bool display) { _drawItemStatus = display; } + Q_INVOKABLE bool doEngineDisplayItemStatus() { return _drawItemStatus; } + signals: void shouldRenderAvatarsChanged(bool shouldRenderAvatars); void shouldRenderEntitiesChanged(bool shouldRenderEntities); @@ -136,6 +140,8 @@ protected: int _maxDrawnTransparentItems = -1; int _maxDrawnOverlay3DItems = -1; + bool _drawItemStatus = false; + }; #endif // hifi_SceneScriptingInterface_h From ee998d0c74e6309f6f2a4cc12469d9a1003f07d5 Mon Sep 17 00:00:00 2001 From: Niraj Venkat Date: Wed, 1 Jul 2015 17:30:50 -0700 Subject: [PATCH 10/21] Icon size is a pixel if the inStatus is -1 --- .../render/src/render/drawItemStatus.slv | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/libraries/render/src/render/drawItemStatus.slv b/libraries/render/src/render/drawItemStatus.slv index 048493c67e..cf9e3a5429 100644 --- a/libraries/render/src/render/drawItemStatus.slv +++ b/libraries/render/src/render/drawItemStatus.slv @@ -41,7 +41,7 @@ vec3 paintRainbow(float nv) { } void main(void) { - const vec2 ICON_PIXEL_SIZE = vec2(10, 10); + vec2 ICON_PIXEL_SIZE = vec2(10, 10); const int NUM_VERTICES = 6; const vec4 UNIT_QUAD[NUM_VERTICES] = vec4[NUM_VERTICES]( vec4(-1.0, -1.0, 0.0, 1.0), @@ -61,15 +61,33 @@ void main(void) { int twoTriID = gl_VertexID - notifNum * NUM_VERTICES; vec4 pos = UNIT_QUAD[twoTriID]; + bool isPixel = false; // Use the status for showing a color ? + // Also changes the size of the notification if(notifNum == 0) { varColor = vec4(paintRainbow(inStatus.x), 1.0); + if(inStatus.x == -1) { + isPixel = true; + } } else if(notifNum == 1) { varColor = vec4(paintRainbow(inStatus.y), 1.0); + if(inStatus.y == -1) { + isPixel = true; + } } else if(notifNum == 2) { varColor = vec4(paintRainbow(inStatus.z), 1.0); + if(inStatus.z == -1) { + isPixel = true; + } } else { varColor = vec4(paintRainbow(inStatus.w), 1.0); + if(inStatus.w == -1) { + isPixel = true; + } + } + + if(isPixel) { + ICON_PIXEL_SIZE = vec2(1, 1); } vec4 viewport; From be8fe2533843180eb64a56ee6d17807395661b48 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 2 Jul 2015 15:06:07 -0700 Subject: [PATCH 11/21] Trying to finalize the look and behavior of th estatus indicators --- .../src/RenderableModelEntityItem.cpp | 51 +++++------- libraries/gpu/src/gpu/Batch.h | 2 + libraries/gpu/src/gpu/GLBackend.cpp | 26 ++++++ libraries/gpu/src/gpu/GLBackend.h | 1 + libraries/render-utils/src/Model.cpp | 6 +- libraries/render-utils/src/Model.h | 2 +- libraries/render/src/render/DrawStatus.cpp | 8 +- libraries/render/src/render/Scene.cpp | 8 +- libraries/render/src/render/Scene.h | 32 ++++++-- .../render/src/render/drawItemStatus.slv | 80 +++++++++---------- 10 files changed, 129 insertions(+), 87 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 4bbe2cac52..3a8857eaa3 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -179,19 +179,17 @@ bool RenderableModelEntityItem::addToScene(EntityItemPointer self, std::shared_p if (_model) { // return _model->addToScene(scene, pendingChanges); - render::Item::Status::Getter statusGetter = [this] () -> render::Item::Status::Value { - quint64 now = usecTimestampNow(); - /* if (now - entity->getLastEditedFromRemote() < 0.1f * USECS_PER_SECOND) { - return glm::vec4 redColor(1.0f, 0.0f, 0.0f, 1.0f); - renderBoundingBox(entity, args, 0.16f, redColor); - } - */ - if (now - this->getLastBroadcast() < 0.2f * USECS_PER_SECOND) { - return 256; - } - return 0; - }; - return _model->addToScene(scene, pendingChanges, statusGetter); + render::Item::Status::Getters statusGetters; + statusGetters.push_back([this] () -> render::Item::Status::Value { + quint64 delta = usecTimestampNow() - this->getLastEditedFromRemote(); + return render::Item::Status::Value((delta < 0.1f * USECS_PER_SECOND), 1.0f); + }); + statusGetters.push_back([this] () -> render::Item::Status::Value { + quint64 delta = usecTimestampNow() - this->getLastBroadcast(); + return render::Item::Status::Value((delta < 0.2f * USECS_PER_SECOND), 0.5f); + }); + + return _model->addToScene(scene, pendingChanges, statusGetters); } @@ -230,24 +228,17 @@ void RenderableModelEntityItem::render(RenderArgs* args) { if (_model->needsFixupInScene()) { _model->removeFromScene(scene, pendingChanges); - - render::Item::Status::Getter statusGetter = [this] () -> render::Item::Status::Value { - quint64 now = usecTimestampNow(); - /* if (now - entity->getLastEditedFromRemote() < 0.1f * USECS_PER_SECOND) { - return glm::vec4 redColor(1.0f, 0.0f, 0.0f, 1.0f); - renderBoundingBox(entity, args, 0.16f, redColor); - } - */ - /*if (now - this->getLastBroadcast() < 0.2f * USECS_PER_SECOND) { - return 256; - } - return 0;*/ - static int i = 0; - return (i++)%256; + render::Item::Status::Getters statusGetters; + statusGetters.push_back([this] () -> render::Item::Status::Value { + quint64 delta = usecTimestampNow() - this->getLastEditedFromRemote(); + return render::Item::Status::Value((delta < 0.1f * USECS_PER_SECOND), 1.0f); + }); + statusGetters.push_back([this] () -> render::Item::Status::Value { + quint64 delta = usecTimestampNow() - this->getLastBroadcast(); + return render::Item::Status::Value((delta < 0.2f * USECS_PER_SECOND), 0.5f); + }); - }; - - _model->addToScene(scene, pendingChanges, statusGetter); + _model->addToScene(scene, pendingChanges, statusGetters); } scene->enqueuePendingChanges(pendingChanges); diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index 599a748d9b..835e872b4a 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -155,6 +155,7 @@ public: void _glUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2); void _glUniform3fv(GLint location, GLsizei count, const GLfloat* value); void _glUniform4fv(GLint location, GLsizei count, const GLfloat* value); + void _glUniform4iv(GLint location, GLsizei count, const GLint* value); void _glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); void _glEnableVertexAttribArray(GLint location); @@ -219,6 +220,7 @@ public: COMMAND_glUniform3f, COMMAND_glUniform3fv, COMMAND_glUniform4fv, + COMMAND_glUniform4iv, COMMAND_glUniformMatrix4fv, COMMAND_glEnableVertexAttribArray, diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index bb855c46d4..302dc0e8be 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -68,6 +68,7 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] = (&::gpu::GLBackend::do_glUniform3f), (&::gpu::GLBackend::do_glUniform3fv), (&::gpu::GLBackend::do_glUniform4fv), + (&::gpu::GLBackend::do_glUniform4iv), (&::gpu::GLBackend::do_glUniformMatrix4fv), (&::gpu::GLBackend::do_glEnableVertexAttribArray), @@ -605,6 +606,31 @@ void GLBackend::do_glUniform4fv(Batch& batch, uint32 paramOffset) { (void) CHECK_GL_ERROR(); } +void Batch::_glUniform4iv(GLint location, GLsizei count, const GLint* value) { + ADD_COMMAND_GL(glUniform4iv); + + const int VEC4_SIZE = 4 * sizeof(int); + _params.push_back(cacheData(count * VEC4_SIZE, value)); + _params.push_back(count); + _params.push_back(location); + + DO_IT_NOW(_glUniform4iv, 3); +} +void GLBackend::do_glUniform4iv(Batch& batch, uint32 paramOffset) { + if (_pipeline._program == 0) { + // We should call updatePipeline() to bind the program but we are not doing that + // because these uniform setters are deprecated and we don;t want to create side effect + return; + } + updatePipeline(); + glUniform4iv( + batch._params[paramOffset + 2]._int, + batch._params[paramOffset + 1]._uint, + (const GLint*)batch.editData(batch._params[paramOffset + 0]._uint)); + + (void) CHECK_GL_ERROR(); +} + void Batch::_glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { ADD_COMMAND_GL(glUniformMatrix4fv); diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index 0ee0f8d349..d798e9aaac 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -398,6 +398,7 @@ protected: void do_glUniform3f(Batch& batch, uint32 paramOffset); void do_glUniform3fv(Batch& batch, uint32 paramOffset); void do_glUniform4fv(Batch& batch, uint32 paramOffset); + void do_glUniform4iv(Batch& batch, uint32 paramOffset); void do_glUniformMatrix4fv(Batch& batch, uint32 paramOffset); void do_glEnableVertexAttribArray(Batch& batch, uint32 paramOffset); diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index f617ecf26f..1b94c70e57 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -910,7 +910,7 @@ bool Model::addToScene(std::shared_ptr scene, render::PendingChan return somethingAdded; } -bool Model::addToScene(std::shared_ptr scene, render::PendingChanges& pendingChanges, render::Item::Status::Getter& statusGetter) { +bool Model::addToScene(std::shared_ptr scene, render::PendingChanges& pendingChanges, render::Item::Status::Getters& statusGetters) { if (!_meshGroupsKnown && isLoadedWithTextures()) { segregateMeshGroups(); } @@ -921,7 +921,7 @@ bool Model::addToScene(std::shared_ptr scene, render::PendingChan auto item = scene->allocateID(); auto renderData = MeshPartPayload::Pointer(renderItem); auto renderPayload = render::PayloadPointer(new MeshPartPayload::Payload(renderData)); - renderPayload->addStatusGetter(statusGetter); + renderPayload->addStatusGetters(statusGetters); pendingChanges.resetItem(item, renderPayload); _renderItems.insert(item, renderPayload); somethingAdded = true; @@ -931,7 +931,7 @@ bool Model::addToScene(std::shared_ptr scene, render::PendingChan auto item = scene->allocateID(); auto renderData = MeshPartPayload::Pointer(renderItem); auto renderPayload = render::PayloadPointer(new MeshPartPayload::Payload(renderData)); - renderPayload->addStatusGetter(statusGetter); + renderPayload->addStatusGetters(statusGetters); pendingChanges.resetItem(item, renderPayload); _renderItems.insert(item, renderPayload); somethingAdded = true; diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 5e440d012d..a6ce566a36 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -118,7 +118,7 @@ public: bool needsFixupInScene() { return !_readyWhenAdded && readyToAddToScene(); } bool readyToAddToScene(RenderArgs* renderArgs = nullptr) { return !_needsReload && isRenderable() && isActive() && isLoadedWithTextures(); } bool addToScene(std::shared_ptr scene, render::PendingChanges& pendingChanges); - bool addToScene(std::shared_ptr scene, render::PendingChanges& pendingChanges, render::Item::Status::Getter& statusGetter); + bool addToScene(std::shared_ptr scene, render::PendingChanges& pendingChanges, render::Item::Status::Getters& statusGetters); void removeFromScene(std::shared_ptr scene, render::PendingChanges& pendingChanges); /// Sets the URL of the model to render. diff --git a/libraries/render/src/render/DrawStatus.cpp b/libraries/render/src/render/DrawStatus.cpp index 41df3c0130..b73df702be 100644 --- a/libraries/render/src/render/DrawStatus.cpp +++ b/libraries/render/src/render/DrawStatus.cpp @@ -107,7 +107,7 @@ void DrawStatus::run(const SceneContextPointer& sceneContext, const RenderContex _itemBounds->resize((inItems.size() * sizeof(AABox))); _itemStatus->resize((inItems.size() * sizeof(glm::vec4))); AABox* itemAABox = reinterpret_cast (_itemBounds->editData()); - glm::vec4* itemStatus = reinterpret_cast (_itemStatus->editData()); + glm::ivec4* itemStatus = reinterpret_cast (_itemStatus->editData()); for (auto& item : inItems) { if (!item.bounds.isInvalid()) { if (!item.bounds.isNull()) { @@ -116,7 +116,7 @@ void DrawStatus::run(const SceneContextPointer& sceneContext, const RenderContex (*itemAABox).setBox(item.bounds.getCorner(), 0.1f); } auto& itemScene = scene->getItem(item.id); - (*itemStatus) = itemScene.getStatusValues(); + (*itemStatus) = itemScene.getStatusCompressedValues(); nbItems++; itemAABox++; @@ -154,7 +154,7 @@ void DrawStatus::run(const SceneContextPointer& sceneContext, const RenderContex batch.setPipeline(getDrawItemBoundsPipeline()); AABox* itemAABox = reinterpret_cast (_itemBounds->editData()); - glm::vec4* itemStatus = reinterpret_cast (_itemStatus->editData()); + glm::ivec4* itemStatus = reinterpret_cast (_itemStatus->editData()); for (int i = 0; i < nbItems; i++) { batch._glUniform3fv(_drawItemBoundPosLoc, 1, (const GLfloat*) (itemAABox + i)); @@ -167,7 +167,7 @@ void DrawStatus::run(const SceneContextPointer& sceneContext, const RenderContex for (int i = 0; i < nbItems; i++) { batch._glUniform3fv(_drawItemStatusPosLoc, 1, (const GLfloat*) (itemAABox + i)); batch._glUniform3fv(_drawItemStatusDimLoc, 1, ((const GLfloat*) (itemAABox + i)) + 3); - batch._glUniform4fv(_drawItemStatusValueLoc, 1, (const GLfloat*) (itemStatus + i)); + batch._glUniform4iv(_drawItemStatusValueLoc, 1, (const GLint*) (itemStatus + i)); batch.draw(gpu::TRIANGLES, 24, 0); } diff --git a/libraries/render/src/render/Scene.cpp b/libraries/render/src/render/Scene.cpp index 7de1e6650c..ca56f00960 100644 --- a/libraries/render/src/render/Scene.cpp +++ b/libraries/render/src/render/Scene.cpp @@ -53,12 +53,14 @@ void ItemBucketMap::allocateStandardOpaqueTranparentBuckets() { (*this)[ItemFilter::Builder::transparentShape().withLayered()]; } -void Item::Status::getValues(glm::vec4& values) { +const Item::Status::Value Item::Status::Value::INVALID{ std::numeric_limits::min(), std::numeric_limits::min() }; + +void Item::Status::getCompressedValues(glm::ivec4& values) { for (int i = 0; i < values.length(); i++) { if (i < _values.size()) { - values[i] = _values[i]() / 256.0f; + values[i] = _values[i]().getRaw(); } else { - values[i] = -1.0f; + values[i] = Value::INVALID.getRaw(); } } } diff --git a/libraries/render/src/render/Scene.h b/libraries/render/src/render/Scene.h index 9b459e0f3e..5b66f8fcf9 100644 --- a/libraries/render/src/render/Scene.h +++ b/libraries/render/src/render/Scene.h @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -200,14 +201,27 @@ public: // This is Used for monitoring and dynamically adjust the quality class Status { public: - typedef unsigned char Value; + class Value { + short _x = 0; + short _y = 0; + Value(short x, short y) : _x(x), _y(y) {} + public: + const static Value INVALID; // Invlaid value meanss the status won't show + + Value(float x, float y = 1.0f) { setX(x); setY(y); } + void setX(float x) { _x = std::numeric_limits::max() * std::max(std::min(x, 1.0f), -1.0f); } + void setY(float y) { _y = std::numeric_limits::max() * std::max(std::min(y, 1.0f), -1.0f); } + + int getRaw() const { return *((const int*) this); } + }; + typedef std::function Getter; typedef std::vector Getters; Getters _values; - void addGetter(Getter& getter) { _values.push_back(getter); } - void getValues(glm::vec4& values); + void addGetter(const Getter& getter) { _values.push_back(getter); } + void getCompressedValues(glm::ivec4& values); }; typedef std::shared_ptr StatusPointer; @@ -233,7 +247,15 @@ public: // Status interface is local to the base class const StatusPointer& getStatus() const { return _status; } - void addStatusGetter(Status::Getter& getter) { if (!_status) { _status.reset(new Status());} _status->addGetter(getter); } + void addStatusGetter(const Status::Getter& getter) { if (!_status) { _status.reset(new Status());} _status->addGetter(getter); } + void addStatusGetters(const Status::Getters& getters) { + if (!_status) { + _status.reset(new Status()); + } + for (auto& g : getters) { + _status->addGetter(g); + } + } protected: StatusPointer _status; @@ -270,7 +292,7 @@ public: // Access the status const StatusPointer& getStatus() const { return _payload->getStatus(); } - glm::vec4 getStatusValues() const { glm::vec4 values(-1.f); auto& status = getStatus(); if (status) { status->getValues(values); }; return values; } + glm::ivec4 getStatusCompressedValues() const { glm::ivec4 values(Status::Value::INVALID.getRaw()); auto& status = getStatus(); if (status) { status->getCompressedValues(values); }; return values; } protected: PayloadPointer _payload; diff --git a/libraries/render/src/render/drawItemStatus.slv b/libraries/render/src/render/drawItemStatus.slv index cf9e3a5429..dda528bc51 100644 --- a/libraries/render/src/render/drawItemStatus.slv +++ b/libraries/render/src/render/drawItemStatus.slv @@ -20,12 +20,12 @@ varying vec4 varColor; uniform vec3 inBoundPos; uniform vec3 inBoundDim; -uniform vec4 inStatus; +uniform ivec4 inStatus; vec3 paintRainbow(float nv) { float v = nv * 5.f; if ( v < 0.f ) - return vec3(1.f, 0.f, 0.f); + return vec3(0.f, 0.f, 0.f); else if ( v < 1.f) return vec3(1.f, v, 0.f); else if ( v < 2.f) @@ -37,11 +37,18 @@ vec3 paintRainbow(float nv) { else if ( v < 5.f) return vec3((v-4.f), 0.f, 1.f ); else - return vec3(1.f, 0.f, 1.f); + return vec3(1.f, 1.f, 1.f); +} + +vec2 unpackStatus(uint v) { + // return unpackSnorm2x16(uint(packed)); + return vec2(clamp((float(v & 0xFFFF) - 32727.0) / 32727.0, -1.0, 1.0), + clamp((float((v >> 16) & 0xFFFF) - 32727.0) / 32727.0, -1.0, 1.0)); } void main(void) { - vec2 ICON_PIXEL_SIZE = vec2(10, 10); + const vec2 ICON_PIXEL_SIZE = vec2(10, 10); + const vec2 MARGIN_PIXEL_SIZE = vec2(2, 2); const int NUM_VERTICES = 6; const vec4 UNIT_QUAD[NUM_VERTICES] = vec4[NUM_VERTICES]( vec4(-1.0, -1.0, 0.0, 1.0), @@ -52,52 +59,43 @@ void main(void) { vec4(1.0, 1.0, 0.0, 1.0) ); + // anchor point in clip space vec4 anchorPoint = vec4(inBoundPos, 1.0) + vec4(inBoundDim, 0.0) * vec4(0.5, 0.5, 0.5, 0.0); TransformCamera cam = getTransformCamera(); TransformObject obj = getTransformObject(); <$transformModelToClipPos(cam, obj, anchorPoint, anchorPoint)$> - - int notifNum = gl_VertexID / NUM_VERTICES; - int twoTriID = gl_VertexID - notifNum * NUM_VERTICES; - vec4 pos = UNIT_QUAD[twoTriID]; - bool isPixel = false; - // Use the status for showing a color ? + // Which icon are we dealing with ? + int iconNum = gl_VertexID / NUM_VERTICES; + + // if invalid, just kill + if (inStatus[iconNum] == 0x80008000) { + gl_Position = anchorPoint; + varColor = vec4(1.0); + return; + } + + // unpack to get x and y satus + vec2 iconStatus = unpackStatus(uint(inStatus[iconNum])); + + // Use the status for showing a color + varColor = vec4(paintRainbow(abs(iconStatus.y)), 1.0); + // Also changes the size of the notification - if(notifNum == 0) { - varColor = vec4(paintRainbow(inStatus.x), 1.0); - if(inStatus.x == -1) { - isPixel = true; - } - } else if(notifNum == 1) { - varColor = vec4(paintRainbow(inStatus.y), 1.0); - if(inStatus.y == -1) { - isPixel = true; - } - } else if(notifNum == 2) { - varColor = vec4(paintRainbow(inStatus.z), 1.0); - if(inStatus.z == -1) { - isPixel = true; - } - } else { - varColor = vec4(paintRainbow(inStatus.w), 1.0); - if(inStatus.w == -1) { - isPixel = true; - } - } + vec2 iconScale = ICON_PIXEL_SIZE; + iconScale = max(vec2(1, 1), (iconScale * iconStatus.x)); - if(isPixel) { - ICON_PIXEL_SIZE = vec2(1, 1); - } + //Offset icon to the right based on the iconNum + vec2 offset = vec2(iconNum * (ICON_PIXEL_SIZE.x + MARGIN_PIXEL_SIZE.x), 0); + + // Final position in pixel space + int twoTriID = gl_VertexID - iconNum * NUM_VERTICES; + vec4 pos = UNIT_QUAD[twoTriID]; + vec2 quadPixelPos = offset.xy + pos.xy * 0.5 * iconScale; vec4 viewport; <$transformCameraViewport(cam, viewport)$>; - vec2 clipIconSize = vec2(ICON_PIXEL_SIZE.x / viewport.z, ICON_PIXEL_SIZE.y / viewport.w); - - //Offset size in pixels - float offset = 3.5f; - pos.x += offset * notifNum; - - gl_Position = anchorPoint + (anchorPoint.w * vec4(pos.xy * clipIconSize, 0.0, 0.0)); + vec2 pixelToClip = vec2(2.0 / viewport.z, 2.0 / viewport.w); + gl_Position = anchorPoint + (anchorPoint.w * vec4(quadPixelPos * pixelToClip, 0.0, 0.0)); } \ No newline at end of file From bf052162bba15f0ec98eddc2595e0e2d02f1f3b0 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 2 Jul 2015 15:53:02 -0700 Subject: [PATCH 12/21] improvment ? --- .../src/RenderableModelEntityItem.cpp | 36 ++++++++----------- .../render/src/render/drawItemStatus.slv | 4 +-- 2 files changed, 16 insertions(+), 24 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 3a8857eaa3..5945511584 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -167,6 +167,17 @@ namespace render { } } +void makeEntityItemStatusGetters(RenderableModelEntityItem* entity, render::Item::Status::Getters& statusGetters) { + statusGetters.push_back([entity] () -> render::Item::Status::Value { + quint64 delta = usecTimestampNow() - entity->getLastEditedFromRemote(); + return render::Item::Status::Value((delta / (0.01f * USECS_PER_SECOND)), 1.0f); + }); + statusGetters.push_back([entity] () -> render::Item::Status::Value { + quint64 delta = usecTimestampNow() - entity->getLastBroadcast(); + return render::Item::Status::Value((delta / (0.02f * USECS_PER_SECOND)), 0.5f); + }); +} + bool RenderableModelEntityItem::addToScene(EntityItemPointer self, std::shared_ptr scene, render::PendingChanges& pendingChanges) { _myMetaItem = scene->allocateID(); @@ -177,20 +188,9 @@ bool RenderableModelEntityItem::addToScene(EntityItemPointer self, std::shared_p pendingChanges.resetItem(_myMetaItem, renderPayload); if (_model) { - // return _model->addToScene(scene, pendingChanges); - render::Item::Status::Getters statusGetters; - statusGetters.push_back([this] () -> render::Item::Status::Value { - quint64 delta = usecTimestampNow() - this->getLastEditedFromRemote(); - return render::Item::Status::Value((delta < 0.1f * USECS_PER_SECOND), 1.0f); - }); - statusGetters.push_back([this] () -> render::Item::Status::Value { - quint64 delta = usecTimestampNow() - this->getLastBroadcast(); - return render::Item::Status::Value((delta < 0.2f * USECS_PER_SECOND), 0.5f); - }); - + makeEntityItemStatusGetters(this, statusGetters); return _model->addToScene(scene, pendingChanges, statusGetters); - } return true; @@ -227,17 +227,9 @@ void RenderableModelEntityItem::render(RenderArgs* args) { render::PendingChanges pendingChanges; if (_model->needsFixupInScene()) { _model->removeFromScene(scene, pendingChanges); - - render::Item::Status::Getters statusGetters; - statusGetters.push_back([this] () -> render::Item::Status::Value { - quint64 delta = usecTimestampNow() - this->getLastEditedFromRemote(); - return render::Item::Status::Value((delta < 0.1f * USECS_PER_SECOND), 1.0f); - }); - statusGetters.push_back([this] () -> render::Item::Status::Value { - quint64 delta = usecTimestampNow() - this->getLastBroadcast(); - return render::Item::Status::Value((delta < 0.2f * USECS_PER_SECOND), 0.5f); - }); + render::Item::Status::Getters statusGetters; + makeEntityItemStatusGetters(this, statusGetters); _model->addToScene(scene, pendingChanges, statusGetters); } scene->enqueuePendingChanges(pendingChanges); diff --git a/libraries/render/src/render/drawItemStatus.slv b/libraries/render/src/render/drawItemStatus.slv index dda528bc51..58637ae909 100644 --- a/libraries/render/src/render/drawItemStatus.slv +++ b/libraries/render/src/render/drawItemStatus.slv @@ -40,7 +40,7 @@ vec3 paintRainbow(float nv) { return vec3(1.f, 1.f, 1.f); } -vec2 unpackStatus(uint v) { +vec2 unpackStatus(int v) { // return unpackSnorm2x16(uint(packed)); return vec2(clamp((float(v & 0xFFFF) - 32727.0) / 32727.0, -1.0, 1.0), clamp((float((v >> 16) & 0xFFFF) - 32727.0) / 32727.0, -1.0, 1.0)); @@ -76,7 +76,7 @@ void main(void) { } // unpack to get x and y satus - vec2 iconStatus = unpackStatus(uint(inStatus[iconNum])); + vec2 iconStatus = unpackStatus(inStatus[iconNum]); // Use the status for showing a color varColor = vec4(paintRainbow(abs(iconStatus.y)), 1.0); From 79be37f78fd8487d5a02b62be7e9287ee91ead21 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 2 Jul 2015 16:00:56 -0700 Subject: [PATCH 13/21] improvment ? --- libraries/entities-renderer/src/RenderableModelEntityItem.cpp | 3 ++- libraries/render/src/render/drawItemStatus.slv | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 5945511584..3b801fd9f6 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -174,7 +174,8 @@ void makeEntityItemStatusGetters(RenderableModelEntityItem* entity, render::Item }); statusGetters.push_back([entity] () -> render::Item::Status::Value { quint64 delta = usecTimestampNow() - entity->getLastBroadcast(); - return render::Item::Status::Value((delta / (0.02f * USECS_PER_SECOND)), 0.5f); + // return render::Item::Status::Value((delta / (0.02f * USECS_PER_SECOND)), 0.5f); + return render::Item::Status::Value(1.0f, 0.5f); }); } diff --git a/libraries/render/src/render/drawItemStatus.slv b/libraries/render/src/render/drawItemStatus.slv index 58637ae909..4eff5c71d7 100644 --- a/libraries/render/src/render/drawItemStatus.slv +++ b/libraries/render/src/render/drawItemStatus.slv @@ -42,8 +42,8 @@ vec3 paintRainbow(float nv) { vec2 unpackStatus(int v) { // return unpackSnorm2x16(uint(packed)); - return vec2(clamp((float(v & 0xFFFF) - 32727.0) / 32727.0, -1.0, 1.0), - clamp((float((v >> 16) & 0xFFFF) - 32727.0) / 32727.0, -1.0, 1.0)); + return vec2(clamp((float(uint(v) & 0xFFFF) - 32727.0) / 32727.0, -1.0, 1.0), + clamp((float((uint(v) >> 16) & 0xFFFF) - 32727.0) / 32727.0, -1.0, 1.0)); } void main(void) { From dcd61fd417bb9670c54c0798c8e50152fdd969e8 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 2 Jul 2015 16:13:54 -0700 Subject: [PATCH 14/21] improvment ? --- libraries/render/src/render/drawItemStatus.slv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/render/src/render/drawItemStatus.slv b/libraries/render/src/render/drawItemStatus.slv index 4eff5c71d7..eb56095d13 100644 --- a/libraries/render/src/render/drawItemStatus.slv +++ b/libraries/render/src/render/drawItemStatus.slv @@ -42,8 +42,8 @@ vec3 paintRainbow(float nv) { vec2 unpackStatus(int v) { // return unpackSnorm2x16(uint(packed)); - return vec2(clamp((float(uint(v) & 0xFFFF) - 32727.0) / 32727.0, -1.0, 1.0), - clamp((float((uint(v) >> 16) & 0xFFFF) - 32727.0) / 32727.0, -1.0, 1.0)); + return vec2(clamp(float((v & 0xFFFF) - 32727) / 32727.0, -1.0, 1.0), + clamp(float(((v >> 16) & 0xFFFF) - 32727) / 32727.0, -1.0, 1.0)); } void main(void) { From 0c55130548f2d0dbdb28135d23f26d9e92808c41 Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 2 Jul 2015 17:31:29 -0700 Subject: [PATCH 15/21] maybe i have solved the passing of the status --- examples/utilities/tools/renderEngineDebug.js | 2 +- .../src/RenderableModelEntityItem.cpp | 7 +- libraries/render/src/render/Scene.cpp | 2 +- libraries/render/src/render/Scene.h | 10 +-- .../render/src/render/drawItemStatus.slv | 68 ++++++++++--------- 5 files changed, 46 insertions(+), 43 deletions(-) diff --git a/examples/utilities/tools/renderEngineDebug.js b/examples/utilities/tools/renderEngineDebug.js index d337290927..d50a9c545c 100755 --- a/examples/utilities/tools/renderEngineDebug.js +++ b/examples/utilities/tools/renderEngineDebug.js @@ -10,7 +10,7 @@ Script.include("cookies.js"); -var panel = new Panel(10, 800); +var panel = new Panel(10, 100); panel.newSlider("Num Feed Opaques", 0, 1000, function(value) { }, diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 3b801fd9f6..5870b22a04 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -170,12 +170,13 @@ namespace render { void makeEntityItemStatusGetters(RenderableModelEntityItem* entity, render::Item::Status::Getters& statusGetters) { statusGetters.push_back([entity] () -> render::Item::Status::Value { quint64 delta = usecTimestampNow() - entity->getLastEditedFromRemote(); - return render::Item::Status::Value((delta / (0.01f * USECS_PER_SECOND)), 1.0f); + float ndelta = (delta / (0.2f * USECS_PER_SECOND)); + return render::Item::Status::Value(1.0f - ndelta, (ndelta > 1.0f ? 0.01f : 0.5f)); }); statusGetters.push_back([entity] () -> render::Item::Status::Value { quint64 delta = usecTimestampNow() - entity->getLastBroadcast(); - // return render::Item::Status::Value((delta / (0.02f * USECS_PER_SECOND)), 0.5f); - return render::Item::Status::Value(1.0f, 0.5f); + float ndelta = (delta / (0.4f * USECS_PER_SECOND)); + return render::Item::Status::Value(1.0f - ndelta, (ndelta > 1.0f ? 0.01f : 0.5f)); }); } diff --git a/libraries/render/src/render/Scene.cpp b/libraries/render/src/render/Scene.cpp index ca56f00960..1ed66e4912 100644 --- a/libraries/render/src/render/Scene.cpp +++ b/libraries/render/src/render/Scene.cpp @@ -53,7 +53,7 @@ void ItemBucketMap::allocateStandardOpaqueTranparentBuckets() { (*this)[ItemFilter::Builder::transparentShape().withLayered()]; } -const Item::Status::Value Item::Status::Value::INVALID{ std::numeric_limits::min(), std::numeric_limits::min() }; +const Item::Status::Value Item::Status::Value::INVALID = Item::Status::Value(); void Item::Status::getCompressedValues(glm::ivec4& values) { for (int i = 0; i < values.length(); i++) { diff --git a/libraries/render/src/render/Scene.h b/libraries/render/src/render/Scene.h index 5b66f8fcf9..b846c60cfe 100644 --- a/libraries/render/src/render/Scene.h +++ b/libraries/render/src/render/Scene.h @@ -202,15 +202,15 @@ public: class Status { public: class Value { - short _x = 0; - short _y = 0; - Value(short x, short y) : _x(x), _y(y) {} + unsigned short _x = 0xFFFF; + unsigned short _y = 0xFFFF; + Value() {} public: const static Value INVALID; // Invlaid value meanss the status won't show Value(float x, float y = 1.0f) { setX(x); setY(y); } - void setX(float x) { _x = std::numeric_limits::max() * std::max(std::min(x, 1.0f), -1.0f); } - void setY(float y) { _y = std::numeric_limits::max() * std::max(std::min(y, 1.0f), -1.0f); } + void setX(float x) { _x = (std::numeric_limits::max() -1) * 0.5f * (1.0f + std::max(std::min(x, 1.0f), -1.0f)); } + void setY(float y) { _y = (std::numeric_limits::max() - 1) * 0.5f * (1.0f + std::max(std::min(y, 1.0f), -1.0f)); } int getRaw() const { return *((const int*) this); } }; diff --git a/libraries/render/src/render/drawItemStatus.slv b/libraries/render/src/render/drawItemStatus.slv index eb56095d13..f99bf006a4 100644 --- a/libraries/render/src/render/drawItemStatus.slv +++ b/libraries/render/src/render/drawItemStatus.slv @@ -1,27 +1,27 @@ -<@include gpu/Config.slh@> -<$VERSION_HEADER$> -// Generated on <$_SCRIBE_DATE$> -// -// drawItemStatus.slv -// vertex shader -// -// Created by Sam Gateau on 6/30/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()$> - -varying vec4 varColor; - -uniform vec3 inBoundPos; -uniform vec3 inBoundDim; -uniform ivec4 inStatus; - +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// drawItemStatus.slv +// vertex shader +// +// Created by Sam Gateau on 6/30/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()$> + +varying vec4 varColor; + +uniform vec3 inBoundPos; +uniform vec3 inBoundDim; +uniform ivec4 inStatus; + vec3 paintRainbow(float nv) { float v = nv * 5.f; if ( v < 0.f ) @@ -38,14 +38,16 @@ vec3 paintRainbow(float nv) { return vec3((v-4.f), 0.f, 1.f ); else return vec3(1.f, 1.f, 1.f); -} - -vec2 unpackStatus(int v) { - // return unpackSnorm2x16(uint(packed)); - return vec2(clamp(float((v & 0xFFFF) - 32727) / 32727.0, -1.0, 1.0), - clamp(float(((v >> 16) & 0xFFFF) - 32727) / 32727.0, -1.0, 1.0)); -} - +} + +vec2 unpackStatus(int v) { + // return unpackSnorm2x16(uint(packed)); + // return vec2(clamp(float((v & 0xFFFF) - 32727) / 32727.0, -1.0, 1.0), + // clamp(float(((v >> 16) & 0xFFFF) - 32727) / 32727.0, -1.0, 1.0)); + return vec2(clamp(float(int((v >> 0) & 0xFFFF) - 32727) / 32727.0, -1.0, 1.0), + clamp(float(int((v >> 16) & 0xFFFF) - 32727) / 32727.0, -1.0, 1.0)); +} + void main(void) { const vec2 ICON_PIXEL_SIZE = vec2(10, 10); const vec2 MARGIN_PIXEL_SIZE = vec2(2, 2); @@ -69,7 +71,7 @@ void main(void) { int iconNum = gl_VertexID / NUM_VERTICES; // if invalid, just kill - if (inStatus[iconNum] == 0x80008000) { + if (inStatus[iconNum] == 0xFFFFFFFF) { gl_Position = anchorPoint; varColor = vec4(1.0); return; From 76ca093e052dd58c164d37cc45f21dce7b4a4317 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 2 Jul 2015 18:12:03 -0700 Subject: [PATCH 16/21] something working ? --- libraries/entities-renderer/src/RenderableModelEntityItem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 5870b22a04..dc90a676fb 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -176,7 +176,7 @@ void makeEntityItemStatusGetters(RenderableModelEntityItem* entity, render::Item statusGetters.push_back([entity] () -> render::Item::Status::Value { quint64 delta = usecTimestampNow() - entity->getLastBroadcast(); float ndelta = (delta / (0.4f * USECS_PER_SECOND)); - return render::Item::Status::Value(1.0f - ndelta, (ndelta > 1.0f ? 0.01f : 0.5f)); + return render::Item::Status::Value(1.0f - ndelta, (ndelta > 1.0f ? 0.3f : 0.9f)); }); } From e3c06a30a11f0a841c54539aae8ddcff46ad2624 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 2 Jul 2015 19:29:09 -0700 Subject: [PATCH 17/21] removing dead code --- libraries/render/src/render/DrawStatus.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/libraries/render/src/render/DrawStatus.cpp b/libraries/render/src/render/DrawStatus.cpp index b73df702be..3c92e8f0b2 100644 --- a/libraries/render/src/render/DrawStatus.cpp +++ b/libraries/render/src/render/DrawStatus.cpp @@ -143,13 +143,6 @@ void DrawStatus::run(const SceneContextPointer& sceneContext, const RenderContex batch.setViewTransform(viewMat); batch.setModelTransform(Transform()); -/* if (!_drawItemFormat) { - _drawItemFormat.reset(new gpu::Stream::Format()); - _drawItemFormat->setAttribute(0, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0, gpu::Stream::PER_INSTANCE); - _drawItemFormat->setAttribute(1, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), sizeof(glm::vec3), gpu::Stream::PER_INSTANCE); - } -*/ - // bind the one gpu::Pipeline we need batch.setPipeline(getDrawItemBoundsPipeline()); From 2bbffff22f64d59ef536e568a56b7e536e996e98 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 6 Jul 2015 10:22:25 -0700 Subject: [PATCH 18/21] Fixing typos --- libraries/render/src/render/drawItemStatus.slv | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/libraries/render/src/render/drawItemStatus.slv b/libraries/render/src/render/drawItemStatus.slv index f99bf006a4..9e2b4919ff 100644 --- a/libraries/render/src/render/drawItemStatus.slv +++ b/libraries/render/src/render/drawItemStatus.slv @@ -24,26 +24,24 @@ uniform ivec4 inStatus; vec3 paintRainbow(float nv) { float v = nv * 5.f; - if ( v < 0.f ) + if (v < 0.f) { return vec3(0.f, 0.f, 0.f); - else if ( v < 1.f) + } else if (v < 1.f) { return vec3(1.f, v, 0.f); - else if ( v < 2.f) + } else if (v < 2.f) { return vec3(1.f - (v-1.f), 1.f, 0.f); - else if ( v < 3.f) + } else if (v < 3.f) { return vec3(0.f, 1.f, (v-2.f)); - else if ( v < 4.f) + } else if (v < 4.f) { return vec3(0.f, 1.f - (v-3.f), 1.f ); - else if ( v < 5.f) + } else if (v < 5.f) { return vec3((v-4.f), 0.f, 1.f ); - else + } else { return vec3(1.f, 1.f, 1.f); + } } vec2 unpackStatus(int v) { - // return unpackSnorm2x16(uint(packed)); - // return vec2(clamp(float((v & 0xFFFF) - 32727) / 32727.0, -1.0, 1.0), - // clamp(float(((v >> 16) & 0xFFFF) - 32727) / 32727.0, -1.0, 1.0)); return vec2(clamp(float(int((v >> 0) & 0xFFFF) - 32727) / 32727.0, -1.0, 1.0), clamp(float(int((v >> 16) & 0xFFFF) - 32727) / 32727.0, -1.0, 1.0)); } From e63be582518cf024e4cca5d5d313754db7dcfc7b Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 6 Jul 2015 12:23:57 -0700 Subject: [PATCH 19/21] CLenaing the interface of Item::Status to be more explicit --- libraries/render/src/render/DrawStatus.cpp | 2 +- libraries/render/src/render/Scene.cpp | 44 +++++++++++++++++++-- libraries/render/src/render/Scene.h | 45 +++++++++++----------- 3 files changed, 63 insertions(+), 28 deletions(-) diff --git a/libraries/render/src/render/DrawStatus.cpp b/libraries/render/src/render/DrawStatus.cpp index 3c92e8f0b2..27ad0adb72 100644 --- a/libraries/render/src/render/DrawStatus.cpp +++ b/libraries/render/src/render/DrawStatus.cpp @@ -116,7 +116,7 @@ void DrawStatus::run(const SceneContextPointer& sceneContext, const RenderContex (*itemAABox).setBox(item.bounds.getCorner(), 0.1f); } auto& itemScene = scene->getItem(item.id); - (*itemStatus) = itemScene.getStatusCompressedValues(); + (*itemStatus) = itemScene.getStatusPackedValues(); nbItems++; itemAABox++; diff --git a/libraries/render/src/render/Scene.cpp b/libraries/render/src/render/Scene.cpp index 1ed66e4912..dca32a7828 100644 --- a/libraries/render/src/render/Scene.cpp +++ b/libraries/render/src/render/Scene.cpp @@ -10,6 +10,8 @@ // #include "Scene.h" +#include + using namespace render; void ItemBucketMap::insert(const ItemID& id, const ItemKey& key) { @@ -55,16 +57,41 @@ void ItemBucketMap::allocateStandardOpaqueTranparentBuckets() { const Item::Status::Value Item::Status::Value::INVALID = Item::Status::Value(); -void Item::Status::getCompressedValues(glm::ivec4& values) { - for (int i = 0; i < values.length(); i++) { + +void Item::Status::Value::setScale(float scale) { + _scale = (std::numeric_limits::max() -1) * 0.5f * (1.0f + std::max(std::min(scale, 1.0f), -1.0f)); + } + +void Item::Status::Value::setColor(float hue) { + _color = (std::numeric_limits::max() - 1) * 0.5f * (1.0f + std::max(std::min(hue, 1.0f), -1.0f)); +} + +void Item::Status::getPackedValues(glm::ivec4& values) const { + for (unsigned int i = 0; i < values.length(); i++) { if (i < _values.size()) { - values[i] = _values[i]().getRaw(); + values[i] = _values[i]().getPackedData(); } else { - values[i] = Value::INVALID.getRaw(); + values[i] = Value::INVALID.getPackedData(); } } } +void Item::PayloadInterface::addStatusGetter(const Status::Getter& getter) { + if (!_status) { + _status.reset(new Status()); + } + _status->addGetter(getter); +} + +void Item::PayloadInterface::addStatusGetters(const Status::Getters& getters) { + if (!_status) { + _status.reset(new Status()); + } + for (auto& g : getters) { + _status->addGetter(g); + } +} + void Item::resetPayload(const PayloadPointer& payload) { if (!payload) { kill(); @@ -74,6 +101,15 @@ void Item::resetPayload(const PayloadPointer& payload) { } } +glm::ivec4 Item::getStatusPackedValues() const { + glm::ivec4 values(Status::Value::INVALID.getPackedData()); + auto& status = getStatus(); + if (status) { + status->getPackedValues(values); + }; + return values; +} + void PendingChanges::resetItem(ItemID id, const PayloadPointer& payload) { _resetItems.push_back(id); _resetPayloads.push_back(payload); diff --git a/libraries/render/src/render/Scene.h b/libraries/render/src/render/Scene.h index b846c60cfe..4a6265990d 100644 --- a/libraries/render/src/render/Scene.h +++ b/libraries/render/src/render/Scene.h @@ -20,7 +20,6 @@ #include #include #include -#include #include #include @@ -201,18 +200,24 @@ public: // This is Used for monitoring and dynamically adjust the quality class Status { public: - class Value { - unsigned short _x = 0xFFFF; - unsigned short _y = 0xFFFF; - Value() {} - public: - const static Value INVALID; // Invlaid value meanss the status won't show - Value(float x, float y = 1.0f) { setX(x); setY(y); } - void setX(float x) { _x = (std::numeric_limits::max() -1) * 0.5f * (1.0f + std::max(std::min(x, 1.0f), -1.0f)); } - void setY(float y) { _y = (std::numeric_limits::max() - 1) * 0.5f * (1.0f + std::max(std::min(y, 1.0f), -1.0f)); } - - int getRaw() const { return *((const int*) this); } + // Status::Value class is the data used to represent the transient information of a status as a square icon + // The "icon" is a square displayed in the 3D scene over the render::Item AABB center. + // It can be scaled in the range [0, 1] and the color hue can + class Value { + unsigned short _scale = 0xFFFF; + unsigned short _color = 0xFFFF; + public: + const static Value INVALID; // Invalid value meanss the status won't show + + Value() {} + Value(float scale, float hue) { setScale(scale); setColor(hue); } + + void setScale(float scale); + void setColor(float hue); + + // Retreive the Value data tightely packed as an int + int getPackedData() const { return *((const int*) this); } }; typedef std::function Getter; @@ -221,7 +226,8 @@ public: Getters _values; void addGetter(const Getter& getter) { _values.push_back(getter); } - void getCompressedValues(glm::ivec4& values); + + void getPackedValues(glm::ivec4& values) const; }; typedef std::shared_ptr StatusPointer; @@ -247,15 +253,8 @@ public: // Status interface is local to the base class const StatusPointer& getStatus() const { return _status; } - void addStatusGetter(const Status::Getter& getter) { if (!_status) { _status.reset(new Status());} _status->addGetter(getter); } - void addStatusGetters(const Status::Getters& getters) { - if (!_status) { - _status.reset(new Status()); - } - for (auto& g : getters) { - _status->addGetter(g); - } - } + void addStatusGetter(const Status::Getter& getter); + void addStatusGetters(const Status::Getters& getters); protected: StatusPointer _status; @@ -292,7 +291,7 @@ public: // Access the status const StatusPointer& getStatus() const { return _payload->getStatus(); } - glm::ivec4 getStatusCompressedValues() const { glm::ivec4 values(Status::Value::INVALID.getRaw()); auto& status = getStatus(); if (status) { status->getCompressedValues(values); }; return values; } + glm::ivec4 getStatusPackedValues() const; protected: PayloadPointer _payload; From 95f5b14d45041830b96a23a4f2e6d5da1b733ea2 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 6 Jul 2015 12:47:35 -0700 Subject: [PATCH 20/21] CLenaing the interface of Item::Status to be more explicit and removing magic numbers --- .../src/RenderableModelEntityItem.cpp | 14 ++++++++++---- libraries/render/src/render/DrawStatus.cpp | 6 ++++-- libraries/render/src/render/Scene.cpp | 5 +++-- libraries/render/src/render/Scene.h | 4 +++- 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index dc90a676fb..fb8006c60f 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -170,13 +170,19 @@ namespace render { void makeEntityItemStatusGetters(RenderableModelEntityItem* entity, render::Item::Status::Getters& statusGetters) { statusGetters.push_back([entity] () -> render::Item::Status::Value { quint64 delta = usecTimestampNow() - entity->getLastEditedFromRemote(); - float ndelta = (delta / (0.2f * USECS_PER_SECOND)); - return render::Item::Status::Value(1.0f - ndelta, (ndelta > 1.0f ? 0.01f : 0.5f)); + const float WAIT_THRESHOLD_INV = 1.0f / (0.2f * USECS_PER_SECOND); + float normalizedDelta = delta * WAIT_THRESHOLD_INV; + // Status icon will scale from 1.0f down to 0.0f after WAIT_THRESHOLD + // Color is red if last update is after WAIT_THRESHOLD, green otherwise (120 deg is green) + return render::Item::Status::Value(1.0f - normalizedDelta, (normalizedDelta > 1.0f ? 0.0f : 120.0f)); }); statusGetters.push_back([entity] () -> render::Item::Status::Value { quint64 delta = usecTimestampNow() - entity->getLastBroadcast(); - float ndelta = (delta / (0.4f * USECS_PER_SECOND)); - return render::Item::Status::Value(1.0f - ndelta, (ndelta > 1.0f ? 0.3f : 0.9f)); + const float WAIT_THRESHOLD_INV = 1.0f / (0.4f * USECS_PER_SECOND); + float normalizedDelta = delta * WAIT_THRESHOLD_INV; + // Status icon will scale from 1.0f down to 0.0f after WAIT_THRESHOLD + // Color is Magenta if last update is after WAIT_THRESHOLD, cyan otherwise (180 deg is green) + return render::Item::Status::Value(1.0f - normalizedDelta, (normalizedDelta > 1.0f ? 300.0f : 180.0f)); }); } diff --git a/libraries/render/src/render/DrawStatus.cpp b/libraries/render/src/render/DrawStatus.cpp index 27ad0adb72..90d167cc2a 100644 --- a/libraries/render/src/render/DrawStatus.cpp +++ b/libraries/render/src/render/DrawStatus.cpp @@ -149,9 +149,11 @@ void DrawStatus::run(const SceneContextPointer& sceneContext, const RenderContex AABox* itemAABox = reinterpret_cast (_itemBounds->editData()); glm::ivec4* itemStatus = reinterpret_cast (_itemStatus->editData()); + const unsigned int VEC3_ADRESS_OFFSET = 3; + for (int i = 0; i < nbItems; i++) { batch._glUniform3fv(_drawItemBoundPosLoc, 1, (const GLfloat*) (itemAABox + i)); - batch._glUniform3fv(_drawItemBoundDimLoc, 1, ((const GLfloat*) (itemAABox + i)) + 3); + batch._glUniform3fv(_drawItemBoundDimLoc, 1, ((const GLfloat*) (itemAABox + i)) + VEC3_ADRESS_OFFSET); batch.draw(gpu::LINES, 24, 0); } @@ -159,7 +161,7 @@ void DrawStatus::run(const SceneContextPointer& sceneContext, const RenderContex batch.setPipeline(getDrawItemStatusPipeline()); for (int i = 0; i < nbItems; i++) { batch._glUniform3fv(_drawItemStatusPosLoc, 1, (const GLfloat*) (itemAABox + i)); - batch._glUniform3fv(_drawItemStatusDimLoc, 1, ((const GLfloat*) (itemAABox + i)) + 3); + batch._glUniform3fv(_drawItemStatusDimLoc, 1, ((const GLfloat*) (itemAABox + i)) + VEC3_ADRESS_OFFSET); batch._glUniform4iv(_drawItemStatusValueLoc, 1, (const GLint*) (itemStatus + i)); batch.draw(gpu::TRIANGLES, 24, 0); diff --git a/libraries/render/src/render/Scene.cpp b/libraries/render/src/render/Scene.cpp index dca32a7828..d593eeb2bb 100644 --- a/libraries/render/src/render/Scene.cpp +++ b/libraries/render/src/render/Scene.cpp @@ -59,11 +59,12 @@ const Item::Status::Value Item::Status::Value::INVALID = Item::Status::Value(); void Item::Status::Value::setScale(float scale) { - _scale = (std::numeric_limits::max() -1) * 0.5f * (1.0f + std::max(std::min(scale, 1.0f), -1.0f)); + _scale = (std::numeric_limits::max() -1) * 0.5f * (1.0f + std::max(std::min(scale, 1.0f), 0.0f)); } void Item::Status::Value::setColor(float hue) { - _color = (std::numeric_limits::max() - 1) * 0.5f * (1.0f + std::max(std::min(hue, 1.0f), -1.0f)); + // Convert the HUe from range [0, 360] to signed normalized value + _color = (std::numeric_limits::max() - 1) * 0.5f * (1.0f + std::max(std::min(hue, 360.0f), 0.0f)); } void Item::Status::getPackedValues(glm::ivec4& values) const { diff --git a/libraries/render/src/render/Scene.h b/libraries/render/src/render/Scene.h index 4a6265990d..8fc27b529a 100644 --- a/libraries/render/src/render/Scene.h +++ b/libraries/render/src/render/Scene.h @@ -203,7 +203,7 @@ public: // Status::Value class is the data used to represent the transient information of a status as a square icon // The "icon" is a square displayed in the 3D scene over the render::Item AABB center. - // It can be scaled in the range [0, 1] and the color hue can + // It can be scaled in the range [0, 1] and the color hue in the range [0, 360] representing the color wheel hue class Value { unsigned short _scale = 0xFFFF; unsigned short _color = 0xFFFF; @@ -213,7 +213,9 @@ public: Value() {} Value(float scale, float hue) { setScale(scale); setColor(hue); } + // It can be scaled in the range [0, 1] void setScale(float scale); + // the color hue in the range [0, 360] representing the color wheel hue void setColor(float hue); // Retreive the Value data tightely packed as an int From 4d48b983647929a245fd07d590656c5569c8456c Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 6 Jul 2015 14:22:09 -0700 Subject: [PATCH 21/21] For a fistfull of magic numbers --- .../entities-renderer/src/RenderableModelEntityItem.cpp | 4 ++-- libraries/render/src/render/Scene.cpp | 9 ++++++++- libraries/render/src/render/Scene.h | 8 ++++++++ 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index fb8006c60f..ae1c97f07f 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -174,7 +174,7 @@ void makeEntityItemStatusGetters(RenderableModelEntityItem* entity, render::Item float normalizedDelta = delta * WAIT_THRESHOLD_INV; // Status icon will scale from 1.0f down to 0.0f after WAIT_THRESHOLD // Color is red if last update is after WAIT_THRESHOLD, green otherwise (120 deg is green) - return render::Item::Status::Value(1.0f - normalizedDelta, (normalizedDelta > 1.0f ? 0.0f : 120.0f)); + return render::Item::Status::Value(1.0f - normalizedDelta, (normalizedDelta > 1.0f ? render::Item::Status::Value::GREEN : render::Item::Status::Value::RED)); }); statusGetters.push_back([entity] () -> render::Item::Status::Value { quint64 delta = usecTimestampNow() - entity->getLastBroadcast(); @@ -182,7 +182,7 @@ void makeEntityItemStatusGetters(RenderableModelEntityItem* entity, render::Item float normalizedDelta = delta * WAIT_THRESHOLD_INV; // Status icon will scale from 1.0f down to 0.0f after WAIT_THRESHOLD // Color is Magenta if last update is after WAIT_THRESHOLD, cyan otherwise (180 deg is green) - return render::Item::Status::Value(1.0f - normalizedDelta, (normalizedDelta > 1.0f ? 300.0f : 180.0f)); + return render::Item::Status::Value(1.0f - normalizedDelta, (normalizedDelta > 1.0f ? render::Item::Status::Value::MAGENTA : render::Item::Status::Value::CYAN)); }); } diff --git a/libraries/render/src/render/Scene.cpp b/libraries/render/src/render/Scene.cpp index d593eeb2bb..a7145af4b5 100644 --- a/libraries/render/src/render/Scene.cpp +++ b/libraries/render/src/render/Scene.cpp @@ -57,6 +57,12 @@ void ItemBucketMap::allocateStandardOpaqueTranparentBuckets() { const Item::Status::Value Item::Status::Value::INVALID = Item::Status::Value(); +const float Item::Status::Value::RED = 0.0f; +const float Item::Status::Value::YELLOW = 60.0f; +const float Item::Status::Value::GREEN = 120.0f; +const float Item::Status::Value::CYAN = 180.0f; +const float Item::Status::Value::BLUE = 240.0f; +const float Item::Status::Value::MAGENTA = 300.0f; void Item::Status::Value::setScale(float scale) { _scale = (std::numeric_limits::max() -1) * 0.5f * (1.0f + std::max(std::min(scale, 1.0f), 0.0f)); @@ -64,7 +70,8 @@ void Item::Status::Value::setScale(float scale) { void Item::Status::Value::setColor(float hue) { // Convert the HUe from range [0, 360] to signed normalized value - _color = (std::numeric_limits::max() - 1) * 0.5f * (1.0f + std::max(std::min(hue, 360.0f), 0.0f)); + const float HUE_MAX = 360.0f; + _color = (std::numeric_limits::max() - 1) * 0.5f * (1.0f + std::max(std::min(hue, HUE_MAX), 0.0f) / HUE_MAX); } void Item::Status::getPackedValues(glm::ivec4& values) const { diff --git a/libraries/render/src/render/Scene.h b/libraries/render/src/render/Scene.h index 8fc27b529a..934b460e52 100644 --- a/libraries/render/src/render/Scene.h +++ b/libraries/render/src/render/Scene.h @@ -218,6 +218,14 @@ public: // the color hue in the range [0, 360] representing the color wheel hue void setColor(float hue); + // Standard color Hue + static const float RED; // 0.0f; + static const float YELLOW; // 60.0f; + static const float GREEN; // 120.0f; + static const float CYAN; // 180.0f; + static const float BLUE; // 240.0f; + static const float MAGENTA; // 300.0f; + // Retreive the Value data tightely packed as an int int getPackedData() const { return *((const int*) this); } };