From 0eb89efb343cf5fdb61988ebf8c1ce95e26f33b7 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 2 Jul 2015 12:31:18 -0700 Subject: [PATCH 01/10] Fix text entity billboarding --- .../src/RenderableTextEntityItem.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableTextEntityItem.cpp b/libraries/entities-renderer/src/RenderableTextEntityItem.cpp index 7603187e94..5ff7b781a4 100644 --- a/libraries/entities-renderer/src/RenderableTextEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableTextEntityItem.cpp @@ -36,10 +36,6 @@ void RenderableTextEntityItem::render(RenderArgs* args) { glm::vec4 backgroundColor = glm::vec4(toGlm(getBackgroundColorX()), 1.0f); glm::vec3 dimensions = getDimensions(); - Transform transformToTopLeft = getTransformToCenter(); - transformToTopLeft.postTranslate(glm::vec3(-0.5f, 0.5f, 0.0f)); // Go to the top left - transformToTopLeft.setScale(1.0f); // Use a scale of one so that the text is not deformed - // Render background glm::vec3 minCorner = glm::vec3(0.0f, -dimensions.y, SLIGHTLY_BEHIND); glm::vec3 maxCorner = glm::vec3(dimensions.x, 0.0f, SLIGHTLY_BEHIND); @@ -48,13 +44,20 @@ void RenderableTextEntityItem::render(RenderArgs* args) { // Batch render calls Q_ASSERT(args->_batch); gpu::Batch& batch = *args->_batch; - batch.setModelTransform(transformToTopLeft); - //rotate about vertical to face the camera + Transform transformToTopLeft = getTransformToCenter(); if (getFaceCamera()) { - transformToTopLeft.postRotate(args->_viewFrustum->getOrientation()); - batch.setModelTransform(transformToTopLeft); + //rotate about vertical to face the camera + glm::vec3 dPosition = args->_viewFrustum->getPosition() - getPosition(); + // If x and z are 0, atan(x, z) is undefined, so default to 0 degrees + float yawRotation = dPosition.x == 0.0f && dPosition.z == 0.0f ? 0.0f : glm::atan(dPosition.x, dPosition.z); + glm::quat orientation = glm::quat(glm::vec3(0.0f, yawRotation, 0.0f)); + transformToTopLeft.setRotation(orientation); } + transformToTopLeft.postTranslate(glm::vec3(-0.5f, 0.5f, 0.0f)); // Go to the top left + transformToTopLeft.setScale(1.0f); // Use a scale of one so that the text is not deformed + + batch.setModelTransform(transformToTopLeft); DependencyManager::get()->bindSimpleProgram(batch, false, false); DependencyManager::get()->renderQuad(batch, minCorner, maxCorner, backgroundColor); From 32cf4dac78c21c8097d0f8e02d0f7481eca98813 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 2 Jul 2015 13:22:59 -0700 Subject: [PATCH 02/10] Fix displayname z-fighting --- interface/src/avatar/Avatar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 748ef7c5a5..a14eeace6d 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -767,7 +767,7 @@ void Avatar::renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum) co auto textTransform = calculateDisplayNameTransform(frustum, renderer->getFontSize()); // Render background slightly behind to avoid z-fighting - auto backgroundTransform = textTransform; + auto backgroundTransform(textTransform); backgroundTransform.postTranslate(glm::vec3(0.0f, 0.0f, SLIGHTLY_BEHIND)); batch.setModelTransform(backgroundTransform); DependencyManager::get()->bindSimpleProgram(batch); From d243190cafbaa0caf2682ce8e709c742141ab7e0 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 2 Jul 2015 13:23:19 -0700 Subject: [PATCH 03/10] Coding standard --- libraries/gpu/src/gpu/GLBackendState.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/gpu/src/gpu/GLBackendState.cpp b/libraries/gpu/src/gpu/GLBackendState.cpp index ef272bb708..274e33a049 100644 --- a/libraries/gpu/src/gpu/GLBackendState.cpp +++ b/libraries/gpu/src/gpu/GLBackendState.cpp @@ -589,7 +589,7 @@ void GLBackend::do_setStateAntialiasedLineEnable(bool enable) { void GLBackend::do_setStateDepthBias(Vec2 bias) { if ( (bias.x != _pipeline._stateCache.depthBias) || (bias.y != _pipeline._stateCache.depthBiasSlopeScale)) { - if ((bias.x != 0.f) || (bias.y != 0.f)) { + if ((bias.x != 0.0f) || (bias.y != 0.0f)) { glEnable(GL_POLYGON_OFFSET_FILL); glEnable(GL_POLYGON_OFFSET_LINE); glEnable(GL_POLYGON_OFFSET_POINT); From 0093403bba095edaa1636b7e2449d83740f4054a Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Sat, 4 Jul 2015 18:33:03 -0700 Subject: [PATCH 04/10] Add depth bias option to simple programs Simple programs are now lazily generated and stored in a hash --- .../src/DeferredLightingEffect.cpp | 76 +++++++++---------- .../render-utils/src/DeferredLightingEffect.h | 61 +++++++++++++-- 2 files changed, 93 insertions(+), 44 deletions(-) diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index a44f1f053c..cc3ced93db 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -50,37 +50,44 @@ static const std::string glowIntensityShaderHandle = "glowIntensity"; +gpu::PipelinePointer DeferredLightingEffect::getPipeline(SimpleProgramKey config) { + auto it = _simplePrograms.find(config); + if (it != _simplePrograms.end()) { + return it.value(); + } + + gpu::StatePointer state = gpu::StatePointer(new gpu::State()); + if (config.isCulled()) { + state->setCullMode(gpu::State::CULL_BACK); + } else { + state->setCullMode(gpu::State::CULL_NONE); + } + state->setDepthTest(true, true, gpu::LESS_EQUAL); + if (config.hasDepthBias()) { + state->setDepthBias(1.0f); + state->setDepthBiasSlopeScale(1.0f); + } + state->setBlendFunction(false, + gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, + gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); + + gpu::ShaderPointer program = (config.isEmissive()) ? _emissiveShader : _simpleShader; + gpu::PipelinePointer pipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, state)); + _simplePrograms.insert(config, pipeline); + return pipeline; +} + void DeferredLightingEffect::init(AbstractViewStateInterface* viewState) { auto VS = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(simple_vert))); auto PS = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(simple_textured_frag))); auto PSEmissive = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(simple_textured_emisive_frag))); - gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(VS, PS)); - gpu::ShaderPointer programEmissive = gpu::ShaderPointer(gpu::Shader::createProgram(VS, PSEmissive)); + _simpleShader = gpu::ShaderPointer(gpu::Shader::createProgram(VS, PS)); + _emissiveShader = gpu::ShaderPointer(gpu::Shader::createProgram(VS, PSEmissive)); gpu::Shader::BindingSet slotBindings; - gpu::Shader::makeProgram(*program, slotBindings); - gpu::Shader::makeProgram(*programEmissive, slotBindings); - - gpu::StatePointer state = gpu::StatePointer(new gpu::State()); - state->setCullMode(gpu::State::CULL_BACK); - state->setDepthTest(true, true, gpu::LESS_EQUAL); - state->setBlendFunction(false, - gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, - gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); - - - gpu::StatePointer stateCullNone = gpu::StatePointer(new gpu::State()); - stateCullNone->setCullMode(gpu::State::CULL_NONE); - stateCullNone->setDepthTest(true, true, gpu::LESS_EQUAL); - stateCullNone->setBlendFunction(false, - gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, - gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); - - _simpleProgram = gpu::PipelinePointer(gpu::Pipeline::create(program, state)); - _simpleProgramCullNone = gpu::PipelinePointer(gpu::Pipeline::create(program, stateCullNone)); - _simpleProgramEmissive = gpu::PipelinePointer(gpu::Pipeline::create(programEmissive, state)); - _simpleProgramEmissiveCullNone = gpu::PipelinePointer(gpu::Pipeline::create(programEmissive, stateCullNone)); + gpu::Shader::makeProgram(*_simpleShader, slotBindings); + gpu::Shader::makeProgram(*_emissiveShader, slotBindings); _viewState = viewState; loadLightProgram(directional_light_frag, false, _directionalLight, _directionalLightLocations); @@ -117,21 +124,12 @@ void DeferredLightingEffect::init(AbstractViewStateInterface* viewState) { lp->setAmbientSpherePreset(gpu::SphericalHarmonics::Preset(_ambientLightMode % gpu::SphericalHarmonics::NUM_PRESET)); } -void DeferredLightingEffect::bindSimpleProgram(gpu::Batch& batch, bool textured, bool culled, bool emmisive) { - if (emmisive) { - if (culled) { - batch.setPipeline(_simpleProgramEmissive); - } else { - batch.setPipeline(_simpleProgramEmissiveCullNone); - } - } else { - if (culled) { - batch.setPipeline(_simpleProgram); - } else { - batch.setPipeline(_simpleProgramCullNone); - } - } - if (!textured) { +void DeferredLightingEffect::bindSimpleProgram(gpu::Batch& batch, bool textured, bool culled, + bool emmisive, bool depthBias) { + SimpleProgramKey config{textured, culled, emmisive, depthBias}; + batch.setPipeline(getPipeline(config)); + + if (!config.isTextured()) { // If it is not textured, bind white texture and keep using textured pipeline batch.setUniformTexture(0, DependencyManager::get()->getWhiteTexture()); } diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index d948f2c305..53aac7ee93 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -24,6 +24,7 @@ class AbstractViewStateInterface; class RenderArgs; +class SimpleProgramKey; /// Handles deferred lighting for the bits that require it (voxels...) class DeferredLightingEffect : public Dependency { @@ -34,7 +35,8 @@ public: void init(AbstractViewStateInterface* viewState); /// Sets up the state necessary to render static untextured geometry with the simple program. - void bindSimpleProgram(gpu::Batch& batch, bool textured = false, bool culled = true, bool emmisive = false); + void bindSimpleProgram(gpu::Batch& batch, bool textured = false, bool culled = true, + bool emmisive = false, bool depthBias = false); //// Renders a solid sphere with the simple program. void renderSolidSphere(gpu::Batch& batch, float radius, int slices, int stacks, const glm::vec4& color); @@ -95,11 +97,11 @@ private: }; static void loadLightProgram(const char* fragSource, bool limited, ProgramObject& program, LightLocations& locations); + gpu::PipelinePointer getPipeline(SimpleProgramKey config); - gpu::PipelinePointer _simpleProgram; - gpu::PipelinePointer _simpleProgramCullNone; - gpu::PipelinePointer _simpleProgramEmissive; - gpu::PipelinePointer _simpleProgramEmissiveCullNone; + gpu::ShaderPointer _simpleShader; + gpu::ShaderPointer _emissiveShader; + QHash _simplePrograms; ProgramObject _directionalSkyboxLight; LightLocations _directionalSkyboxLightLocations; @@ -160,4 +162,53 @@ private: model::SkyboxPointer _skybox; }; +class SimpleProgramKey { +public: + enum FlagBit { + IS_TEXTURED_FLAG = 0, + IS_CULLED_FLAG, + IS_EMISSIVE_FLAG, + HAS_DEPTH_BIAS_FLAG, + + NUM_FLAGS, + }; + + enum Flag { + IS_TEXTURED = (1 << IS_TEXTURED_FLAG), + IS_CULLED = (1 << IS_CULLED_FLAG), + IS_EMISSIVE = (1 << IS_EMISSIVE_FLAG), + HAS_DEPTH_BIAS = (1 << HAS_DEPTH_BIAS_FLAG), + }; + typedef unsigned short Flags; + + bool isFlag(short flagNum) const { return bool((_flags & flagNum) != 0); } + + bool isTextured() const { return isFlag(IS_TEXTURED); } + bool isCulled() const { return isFlag(IS_CULLED); } + bool isEmissive() const { return isFlag(IS_EMISSIVE); } + bool hasDepthBias() const { return isFlag(HAS_DEPTH_BIAS); } + + Flags _flags = 0; + short _spare = 0; + + int getRaw() const { return *reinterpret_cast(this); } + + + SimpleProgramKey(bool textured = false, bool culled = true, + bool emissive = false, bool depthBias = false) { + _flags = (textured ? IS_TEXTURED : 0) | (culled ? IS_CULLED : 0) | + (emissive ? IS_EMISSIVE : 0) | (depthBias ? HAS_DEPTH_BIAS : 0); + } + + SimpleProgramKey(int bitmask) : _flags(bitmask) {} +}; + +inline uint qHash(const SimpleProgramKey& key, uint seed) { + return qHash(key.getRaw(), seed); +} + +inline bool operator==(const SimpleProgramKey& a, const SimpleProgramKey& b) { + return a.getRaw() == b.getRaw(); +} + #endif // hifi_DeferredLightingEffect_h From 9bf6c439aaecc8eac228aebbe48ec743510c3adc Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Sat, 4 Jul 2015 18:34:19 -0700 Subject: [PATCH 05/10] Use depth bias to avoid z-fighting on display name --- interface/src/avatar/Avatar.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index a14eeace6d..a5fa7d3c82 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -750,7 +750,6 @@ void Avatar::renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum) co const int text_y = -nameDynamicRect.height() / 2; // Compute background position/size - static const float SLIGHTLY_BEHIND = -0.05f; const int border = 0.1f * nameDynamicRect.height(); const int left = text_x - border; const int bottom = text_y - border; @@ -765,17 +764,13 @@ void Avatar::renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum) co // Compute display name transform auto textTransform = calculateDisplayNameTransform(frustum, renderer->getFontSize()); + batch.setModelTransform(textTransform); - // Render background slightly behind to avoid z-fighting - auto backgroundTransform(textTransform); - backgroundTransform.postTranslate(glm::vec3(0.0f, 0.0f, SLIGHTLY_BEHIND)); - batch.setModelTransform(backgroundTransform); - DependencyManager::get()->bindSimpleProgram(batch); + DependencyManager::get()->bindSimpleProgram(batch, false, true, true, true); DependencyManager::get()->renderBevelCornersRect(batch, left, bottom, width, height, bevelDistance, backgroundColor); // Render actual name QByteArray nameUTF8 = renderedDisplayName.toLocal8Bit(); - batch.setModelTransform(textTransform); renderer->draw(batch, text_x, -text_y, nameUTF8.data(), textColor); } From c61bf342007fe3c57aa43aaf28effc48103df421 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Sat, 4 Jul 2015 18:35:00 -0700 Subject: [PATCH 06/10] Use depth bias to avoid z-fighting on text entities --- .../entities-renderer/src/RenderableTextEntityItem.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableTextEntityItem.cpp b/libraries/entities-renderer/src/RenderableTextEntityItem.cpp index 5ff7b781a4..c768bc521c 100644 --- a/libraries/entities-renderer/src/RenderableTextEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableTextEntityItem.cpp @@ -31,14 +31,13 @@ void RenderableTextEntityItem::render(RenderArgs* args) { PerformanceTimer perfTimer("RenderableTextEntityItem::render"); Q_ASSERT(getType() == EntityTypes::Text); - static const float SLIGHTLY_BEHIND = -0.005f; glm::vec4 textColor = glm::vec4(toGlm(getTextColorX()), 1.0f); glm::vec4 backgroundColor = glm::vec4(toGlm(getBackgroundColorX()), 1.0f); glm::vec3 dimensions = getDimensions(); // Render background - glm::vec3 minCorner = glm::vec3(0.0f, -dimensions.y, SLIGHTLY_BEHIND); - glm::vec3 maxCorner = glm::vec3(dimensions.x, 0.0f, SLIGHTLY_BEHIND); + glm::vec3 minCorner = glm::vec3(0.0f, -dimensions.y, 0.0f); + glm::vec3 maxCorner = glm::vec3(dimensions.x, 0.0f, 0.0f); // Batch render calls @@ -59,7 +58,7 @@ void RenderableTextEntityItem::render(RenderArgs* args) { batch.setModelTransform(transformToTopLeft); - DependencyManager::get()->bindSimpleProgram(batch, false, false); + DependencyManager::get()->bindSimpleProgram(batch, false, false, false, true); DependencyManager::get()->renderQuad(batch, minCorner, maxCorner, backgroundColor); float scale = _lineHeight / _textRenderer->getFontSize(); From 85df510b4b75f05f4d5115c7d959c8a3894fc337 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Sat, 4 Jul 2015 18:40:37 -0700 Subject: [PATCH 07/10] Use depth bias to avoid z-fighting on text3d overlays --- interface/src/ui/overlays/Text3DOverlay.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/interface/src/ui/overlays/Text3DOverlay.cpp b/interface/src/ui/overlays/Text3DOverlay.cpp index 37774094de..9ee0a90a89 100644 --- a/interface/src/ui/overlays/Text3DOverlay.cpp +++ b/interface/src/ui/overlays/Text3DOverlay.cpp @@ -13,6 +13,7 @@ #include "Text3DOverlay.h" +#include #include #include @@ -110,10 +111,9 @@ void Text3DOverlay::render(RenderArgs* args) { glm::vec2 dimensions = getDimensions(); glm::vec2 halfDimensions = dimensions * 0.5f; - const float SLIGHTLY_BEHIND = -0.005f; - - glm::vec3 topLeft(-halfDimensions.x, -halfDimensions.y, SLIGHTLY_BEHIND); - glm::vec3 bottomRight(halfDimensions.x, halfDimensions.y, SLIGHTLY_BEHIND); + glm::vec3 topLeft(-halfDimensions.x, -halfDimensions.y, 0.0f); + glm::vec3 bottomRight(halfDimensions.x, halfDimensions.y, 0.0f); + DependencyManager::get()->bindSimpleProgram(batch, false, true, false, true); DependencyManager::get()->renderQuad(batch, topLeft, bottomRight, quadColor); // Same font properties as textSize() From 05f28064bf26366ab6581bdda7334b997a7bdf08 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 6 Jul 2015 16:03:42 -0700 Subject: [PATCH 08/10] add stats for PPS for inbound from network into OctreePacketProcessor and processing out of OctreePacketProcessor --- interface/src/ui/OctreeStatsDialog.cpp | 31 +++++++++++++------ .../src/ReceivedPacketProcessor.cpp | 27 ++++++++++++++++ .../networking/src/ReceivedPacketProcessor.h | 11 ++++++- 3 files changed, 59 insertions(+), 10 deletions(-) diff --git a/interface/src/ui/OctreeStatsDialog.cpp b/interface/src/ui/OctreeStatsDialog.cpp index 94f91a5ab7..fbfc3ea662 100644 --- a/interface/src/ui/OctreeStatsDialog.cpp +++ b/interface/src/ui/OctreeStatsDialog.cpp @@ -21,6 +21,7 @@ #include "Application.h" +#include "../octree/OctreePacketProcessor.h" #include "ui/OctreeStatsDialog.h" OctreeStatsDialog::OctreeStatsDialog(QWidget* parent, NodeToOctreeSceneStats* model) : @@ -53,7 +54,7 @@ OctreeStatsDialog::OctreeStatsDialog(QWidget* parent, NodeToOctreeSceneStats* mo _localElementsMemory = AddStatItem("Elements Memory"); _sendingMode = AddStatItem("Sending Mode"); - _processedPackets = AddStatItem("Processed Packets"); + _processedPackets = AddStatItem("Entity Packets"); _processedPacketsElements = AddStatItem("Processed Packets Elements"); _processedPacketsEntities = AddStatItem("Processed Packets Entities"); _processedPacketsTiming = AddStatItem("Processed Packets Timing"); @@ -155,6 +156,8 @@ void OctreeStatsDialog::paintEvent(QPaintEvent* event) { if (sinceLastRefresh < REFRESH_AFTER) { return QDialog::paintEvent(event); } + const int FLOATING_POINT_PRECISION = 3; + _lastRefresh = now; // Update labels @@ -245,7 +248,6 @@ void OctreeStatsDialog::paintEvent(QPaintEvent* event) { auto averageElementsPerPacket = entities->getAverageElementsPerPacket(); auto averageEntitiesPerPacket = entities->getAverageEntitiesPerPacket(); - auto averagePacketsPerSecond = entities->getAveragePacketsPerSecond(); auto averageElementsPerSecond = entities->getAverageElementsPerSecond(); auto averageEntitiesPerSecond = entities->getAverageEntitiesPerSecond(); @@ -253,21 +255,32 @@ void OctreeStatsDialog::paintEvent(QPaintEvent* event) { auto averageUncompressPerPacket = entities->getAverageUncompressPerPacket(); auto averageReadBitstreamPerPacket = entities->getAverageReadBitstreamPerPacket(); - QString averageElementsPerPacketString = locale.toString(averageElementsPerPacket); - QString averageEntitiesPerPacketString = locale.toString(averageEntitiesPerPacket); + QString averageElementsPerPacketString = locale.toString(averageElementsPerPacket, 'f', FLOATING_POINT_PRECISION); + QString averageEntitiesPerPacketString = locale.toString(averageEntitiesPerPacket, 'f', FLOATING_POINT_PRECISION); - QString averagePacketsPerSecondString = locale.toString(averagePacketsPerSecond); - QString averageElementsPerSecondString = locale.toString(averageElementsPerSecond); - QString averageEntitiesPerSecondString = locale.toString(averageEntitiesPerSecond); + QString averageElementsPerSecondString = locale.toString(averageElementsPerSecond, 'f', FLOATING_POINT_PRECISION); + QString averageEntitiesPerSecondString = locale.toString(averageEntitiesPerSecond, 'f', FLOATING_POINT_PRECISION); QString averageWaitLockPerPacketString = locale.toString(averageWaitLockPerPacket); QString averageUncompressPerPacketString = locale.toString(averageUncompressPerPacket); QString averageReadBitstreamPerPacketString = locale.toString(averageReadBitstreamPerPacket); label = _labels[_processedPackets]; + const OctreePacketProcessor& entitiesPacketProcessor = Application::getInstance()->getOctreePacketProcessor(); + + auto incomingPPS = entitiesPacketProcessor.getIncomingPPS(); + auto processedPPS = entitiesPacketProcessor.getProcessedPPS(); + auto treeProcessedPPS = entities->getAveragePacketsPerSecond(); + + QString incomingPPSString = locale.toString(incomingPPS, 'f', FLOATING_POINT_PRECISION); + QString processedPPSString = locale.toString(processedPPS, 'f', FLOATING_POINT_PRECISION); + QString treeProcessedPPSString = locale.toString(treeProcessedPPS, 'f', FLOATING_POINT_PRECISION); + statsValue.str(""); statsValue << - "" << qPrintable(averagePacketsPerSecondString) << " per second"; + "Network IN: " << qPrintable(incomingPPSString) << " PPS / " << + "Queue OUT: " << qPrintable(processedPPSString) << " PPS / " << + "Tree IN: " << qPrintable(treeProcessedPPSString) << " PPS"; label->setText(statsValue.str().c_str()); @@ -321,7 +334,7 @@ void OctreeStatsDialog::paintEvent(QPaintEvent* event) { } QString totalTrackedEditsString = locale.toString((uint)totalTrackedEdits); - QString updatesPerSecondString = locale.toString(updatesPerSecond); + QString updatesPerSecondString = locale.toString(updatesPerSecond, 'f', FLOATING_POINT_PRECISION); QString bytesPerEditString = locale.toString(bytesPerEdit); statsValue.str(""); diff --git a/libraries/networking/src/ReceivedPacketProcessor.cpp b/libraries/networking/src/ReceivedPacketProcessor.cpp index 3c4b32b4ec..94dd04d44b 100644 --- a/libraries/networking/src/ReceivedPacketProcessor.cpp +++ b/libraries/networking/src/ReceivedPacketProcessor.cpp @@ -9,10 +9,17 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include + #include "NodeList.h" #include "ReceivedPacketProcessor.h" #include "SharedUtil.h" +ReceivedPacketProcessor::ReceivedPacketProcessor() { + _lastWindowAt = usecTimestampNow(); +} + + void ReceivedPacketProcessor::terminating() { _hasPackets.wakeAll(); } @@ -25,6 +32,7 @@ void ReceivedPacketProcessor::queueReceivedPacket(const SharedNodePointer& sendi lock(); _packets.push_back(networkPacket); _nodePacketCounts[sendingNode->getUUID()]++; + _lastWindowIncomingPackets++; unlock(); // Make sure to wake our actual processing thread because we now have packets for it to process. @@ -32,6 +40,24 @@ void ReceivedPacketProcessor::queueReceivedPacket(const SharedNodePointer& sendi } bool ReceivedPacketProcessor::process() { + quint64 now = usecTimestampNow(); + quint64 sinceLastWindow = now - _lastWindowAt; + + + if (sinceLastWindow > USECS_PER_SECOND) { + lock(); + float secondsSinceLastWindow = sinceLastWindow / USECS_PER_SECOND; + float incomingPacketsPerSecondInWindow = (float)_lastWindowIncomingPackets / secondsSinceLastWindow; + _incomingPPS.updateAverage(incomingPacketsPerSecondInWindow); + + float processedPacketsPerSecondInWindow = (float)_lastWindowIncomingPackets / secondsSinceLastWindow; + _processedPPS.updateAverage(processedPacketsPerSecondInWindow); + + _lastWindowAt = now; + _lastWindowIncomingPackets = 0; + _lastWindowProcessedPackets = 0; + unlock(); + } if (_packets.size() == 0) { _waitingOnPacketsMutex.lock(); @@ -51,6 +77,7 @@ bool ReceivedPacketProcessor::process() { foreach(auto& packet, currentPackets) { processPacket(packet.getNode(), packet.getByteArray()); + _lastWindowProcessedPackets++; midProcess(); } diff --git a/libraries/networking/src/ReceivedPacketProcessor.h b/libraries/networking/src/ReceivedPacketProcessor.h index bcc9f9a1f5..84a954760c 100644 --- a/libraries/networking/src/ReceivedPacketProcessor.h +++ b/libraries/networking/src/ReceivedPacketProcessor.h @@ -21,7 +21,7 @@ class ReceivedPacketProcessor : public GenericThread { Q_OBJECT public: - ReceivedPacketProcessor() { } + ReceivedPacketProcessor(); /// Add packet from network receive thread to the processing queue. void queueReceivedPacket(const SharedNodePointer& sendingNode, const QByteArray& packet); @@ -47,6 +47,9 @@ public: /// How many received packets waiting are to be processed int packetsToProcessCount() const { return _packets.size(); } + float getIncomingPPS() const { return _incomingPPS.getAverage(); } + float getProcessedPPS() const { return _processedPPS.getAverage(); } + virtual void terminating(); public slots: @@ -80,6 +83,12 @@ protected: QWaitCondition _hasPackets; QMutex _waitingOnPacketsMutex; + + quint64 _lastWindowAt = 0; + int _lastWindowIncomingPackets = 0; + int _lastWindowProcessedPackets = 0; + SimpleMovingAverage _incomingPPS; + SimpleMovingAverage _processedPPS; }; #endif // hifi_ReceivedPacketProcessor_h From 687f9dda4a20c2d3041f1e8a6fbe6b08cc3c78c4 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 6 Jul 2015 18:21:17 -0700 Subject: [PATCH 09/10] Restore old offset behaviors --- interface/src/avatar/Avatar.cpp | 7 ++++++- interface/src/ui/overlays/Text3DOverlay.cpp | 6 ++++-- .../entities-renderer/src/RenderableTextEntityItem.cpp | 5 +++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index a5fa7d3c82..3525109766 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -750,6 +750,7 @@ void Avatar::renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum) co const int text_y = -nameDynamicRect.height() / 2; // Compute background position/size + static const float SLIGHTLY_IN_FRONT = 0.05f; const int border = 0.1f * nameDynamicRect.height(); const int left = text_x - border; const int bottom = text_y - border; @@ -765,12 +766,16 @@ void Avatar::renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum) co // Compute display name transform auto textTransform = calculateDisplayNameTransform(frustum, renderer->getFontSize()); batch.setModelTransform(textTransform); - + DependencyManager::get()->bindSimpleProgram(batch, false, true, true, true); DependencyManager::get()->renderBevelCornersRect(batch, left, bottom, width, height, bevelDistance, backgroundColor); // Render actual name QByteArray nameUTF8 = renderedDisplayName.toLocal8Bit(); + + // Render text slightly in front to avoid z-fighting + textTransform.postTranslate(glm::vec3(0.0f, 0.0f, SLIGHTLY_IN_FRONT * renderer->getFontSize())); + batch.setModelTransform(textTransform); renderer->draw(batch, text_x, -text_y, nameUTF8.data(), textColor); } diff --git a/interface/src/ui/overlays/Text3DOverlay.cpp b/interface/src/ui/overlays/Text3DOverlay.cpp index 9ee0a90a89..17dc8d03a8 100644 --- a/interface/src/ui/overlays/Text3DOverlay.cpp +++ b/interface/src/ui/overlays/Text3DOverlay.cpp @@ -111,8 +111,10 @@ void Text3DOverlay::render(RenderArgs* args) { glm::vec2 dimensions = getDimensions(); glm::vec2 halfDimensions = dimensions * 0.5f; - glm::vec3 topLeft(-halfDimensions.x, -halfDimensions.y, 0.0f); - glm::vec3 bottomRight(halfDimensions.x, halfDimensions.y, 0.0f); + const float SLIGHTLY_BEHIND = -0.005f; + + glm::vec3 topLeft(-halfDimensions.x, -halfDimensions.y, SLIGHTLY_BEHIND); + glm::vec3 bottomRight(halfDimensions.x, halfDimensions.y, SLIGHTLY_BEHIND); DependencyManager::get()->bindSimpleProgram(batch, false, true, false, true); DependencyManager::get()->renderQuad(batch, topLeft, bottomRight, quadColor); diff --git a/libraries/entities-renderer/src/RenderableTextEntityItem.cpp b/libraries/entities-renderer/src/RenderableTextEntityItem.cpp index c768bc521c..0c9b36dd87 100644 --- a/libraries/entities-renderer/src/RenderableTextEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableTextEntityItem.cpp @@ -31,13 +31,14 @@ void RenderableTextEntityItem::render(RenderArgs* args) { PerformanceTimer perfTimer("RenderableTextEntityItem::render"); Q_ASSERT(getType() == EntityTypes::Text); + static const float SLIGHTLY_BEHIND = -0.005f; glm::vec4 textColor = glm::vec4(toGlm(getTextColorX()), 1.0f); glm::vec4 backgroundColor = glm::vec4(toGlm(getBackgroundColorX()), 1.0f); glm::vec3 dimensions = getDimensions(); // Render background - glm::vec3 minCorner = glm::vec3(0.0f, -dimensions.y, 0.0f); - glm::vec3 maxCorner = glm::vec3(dimensions.x, 0.0f, 0.0f); + glm::vec3 minCorner = glm::vec3(0.0f, -dimensions.y, SLIGHTLY_BEHIND); + glm::vec3 maxCorner = glm::vec3(dimensions.x, 0.0f, SLIGHTLY_BEHIND); // Batch render calls From 2ba6bd3afcb873d81488c5103d9fc48336f05580 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 6 Jul 2015 18:39:43 -0700 Subject: [PATCH 10/10] Double display name offset --- interface/src/avatar/Avatar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 3525109766..3d4c158a0b 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -750,7 +750,7 @@ void Avatar::renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum) co const int text_y = -nameDynamicRect.height() / 2; // Compute background position/size - static const float SLIGHTLY_IN_FRONT = 0.05f; + static const float SLIGHTLY_IN_FRONT = 0.1f; const int border = 0.1f * nameDynamicRect.height(); const int left = text_x - border; const int bottom = text_y - border;