From 690e2e38f20caadad4411daa16f78b138502aa19 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 19 Jun 2015 09:45:13 -0700 Subject: [PATCH] Move circle3d and text overlays to batches --- interface/src/ui/overlays/Circle3DOverlay.cpp | 328 +++++----- interface/src/ui/overlays/Text3DOverlay.cpp | 66 +- interface/src/ui/overlays/Text3DOverlay.h | 4 +- .../render-utils/src/RenderDeferredTask.cpp | 579 +++++++++--------- .../render-utils/src/RenderDeferredTask.h | 4 +- 5 files changed, 496 insertions(+), 485 deletions(-) diff --git a/interface/src/ui/overlays/Circle3DOverlay.cpp b/interface/src/ui/overlays/Circle3DOverlay.cpp index 77debf304f..e5461d3478 100644 --- a/interface/src/ui/overlays/Circle3DOverlay.cpp +++ b/interface/src/ui/overlays/Circle3DOverlay.cpp @@ -101,205 +101,207 @@ void Circle3DOverlay::render(RenderArgs* args) { bool colorChanged = colorX.red != _lastColor.red || colorX.green != _lastColor.green || colorX.blue != _lastColor.blue; _lastColor = colorX; - glDisable(GL_LIGHTING); - glm::vec3 position = getPosition(); glm::vec3 center = getCenter(); glm::vec2 dimensions = getDimensions(); glm::quat rotation = getRotation(); - float glowLevel = getGlowLevel(); - Glower* glower = NULL; - if (glowLevel > 0.0f) { - glower = new Glower(glowLevel); - } + auto batch = args->_batch; - glPushMatrix(); - glTranslatef(position.x, position.y, position.z); - glm::vec3 axis = glm::axis(rotation); - glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z); - glPushMatrix(); - glm::vec3 positionToCenter = center - position; - glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z); - glScalef(dimensions.x / 2.0f, dimensions.y / 2.0f, 1.0f); + if (batch) { + Transform transform; + transform.setTranslation(position); + transform.setRotation(rotation); + transform.setScale(glm::vec3(dimensions.x, dimensions.y, 1.0f) / 2.0f); - glLineWidth(_lineWidth); + batch->setModelTransform(transform); - auto geometryCache = DependencyManager::get(); + batch->_glLineWidth(_lineWidth); - // for our overlay, is solid means we draw a ring between the inner and outer radius of the circle, otherwise - // we just draw a line... - if (getIsSolid()) { - if (_quadVerticesID == GeometryCache::UNKNOWN_ID) { - _quadVerticesID = geometryCache->allocateID(); - } + auto geometryCache = DependencyManager::get(); - if (geometryChanged || colorChanged) { + // for our overlay, is solid means we draw a ring between the inner and outer radius of the circle, otherwise + // we just draw a line... + if (getIsSolid()) { + if (_quadVerticesID == GeometryCache::UNKNOWN_ID) { + _quadVerticesID = geometryCache->allocateID(); + } - QVector points; + if (geometryChanged || colorChanged) { - float angle = startAt; - float angleInRadians = glm::radians(angle); - glm::vec2 firstInnerPoint(cosf(angleInRadians) * innerRadius, sinf(angleInRadians) * innerRadius); - glm::vec2 firstOuterPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius); + QVector points; - points << firstInnerPoint << firstOuterPoint; + float angle = startAt; + float angleInRadians = glm::radians(angle); + glm::vec2 firstInnerPoint(cos(angleInRadians) * innerRadius, sin(angleInRadians) * innerRadius); + glm::vec2 firstOuterPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius); - while (angle < endAt) { - angleInRadians = glm::radians(angle); - glm::vec2 thisInnerPoint(cosf(angleInRadians) * innerRadius, sinf(angleInRadians) * innerRadius); - glm::vec2 thisOuterPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius); + points << firstInnerPoint << firstOuterPoint; - points << thisOuterPoint << thisInnerPoint; - - angle += SLICE_ANGLE; - } - - // get the last slice portion.... - angle = endAt; + while (angle < endAt) { angleInRadians = glm::radians(angle); - glm::vec2 lastInnerPoint(cosf(angleInRadians) * innerRadius, sinf(angleInRadians) * innerRadius); - glm::vec2 lastOuterPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius); + glm::vec2 thisInnerPoint(cos(angleInRadians) * innerRadius, sin(angleInRadians) * innerRadius); + glm::vec2 thisOuterPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius); - points << lastOuterPoint << lastInnerPoint; + points << thisOuterPoint << thisInnerPoint; - geometryCache->updateVertices(_quadVerticesID, points, color); + angle += SLICE_ANGLE; } - geometryCache->renderVertices(gpu::QUAD_STRIP, _quadVerticesID); + // get the last slice portion.... + angle = endAt; + angleInRadians = glm::radians(angle); + glm::vec2 lastInnerPoint(cos(angleInRadians) * innerRadius, sin(angleInRadians) * innerRadius); + glm::vec2 lastOuterPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius); + // Add quads for the back side + while (angle > startAt) { + angleInRadians = glm::radians(angle); + glm::vec2 thisInnerPoint(cos(angleInRadians) * innerRadius, sin(angleInRadians) * innerRadius); + glm::vec2 thisOuterPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius); + + points << thisOuterPoint << thisInnerPoint; + + angle -= SLICE_ANGLE; + } + + // get the last slice portion.... + angle = startAt; + angleInRadians = glm::radians(angle); + lastInnerPoint = glm::vec2(cos(angleInRadians) * innerRadius, sin(angleInRadians) * innerRadius); + lastOuterPoint = glm::vec2(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius); + + points << lastOuterPoint << lastInnerPoint; + + geometryCache->updateVertices(_quadVerticesID, points, color); + } + geometryCache->renderVertices(*batch, gpu::QUAD_STRIP, _quadVerticesID); + + } else { + if (_lineVerticesID == GeometryCache::UNKNOWN_ID) { + _lineVerticesID = geometryCache->allocateID(); + } + + if (geometryChanged || colorChanged) { + QVector points; + + float angle = startAt; + float angleInRadians = glm::radians(angle); + glm::vec2 firstPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius); + points << firstPoint; + + while (angle < endAt) { + angle += SLICE_ANGLE; + angleInRadians = glm::radians(angle); + glm::vec2 thisPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius); + points << thisPoint; + + if (getIsDashedLine()) { + angle += SLICE_ANGLE / 2.0f; // short gap + angleInRadians = glm::radians(angle); + glm::vec2 dashStartPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius); + points << dashStartPoint; + } + } + + // get the last slice portion.... + angle = endAt; + angleInRadians = glm::radians(angle); + glm::vec2 lastPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius); + points << lastPoint; + + geometryCache->updateVertices(_lineVerticesID, points, color); + } + + if (getIsDashedLine()) { + geometryCache->renderVertices(*batch, gpu::LINES, _lineVerticesID); } else { - if (_lineVerticesID == GeometryCache::UNKNOWN_ID) { - _lineVerticesID = geometryCache->allocateID(); - } + geometryCache->renderVertices(*batch, gpu::LINE_STRIP, _lineVerticesID); + } + } - if (geometryChanged || colorChanged) { - QVector points; + // draw our tick marks + // for our overlay, is solid means we draw a ring between the inner and outer radius of the circle, otherwise + // we just draw a line... + if (getHasTickMarks()) { - float angle = startAt; + if (_majorTicksVerticesID == GeometryCache::UNKNOWN_ID) { + _majorTicksVerticesID = geometryCache->allocateID(); + } + if (_minorTicksVerticesID == GeometryCache::UNKNOWN_ID) { + _minorTicksVerticesID = geometryCache->allocateID(); + } + + if (geometryChanged) { + QVector majorPoints; + QVector minorPoints; + + // draw our major tick marks + if (getMajorTickMarksAngle() > 0.0f && getMajorTickMarksLength() != 0.0f) { + + float tickMarkAngle = getMajorTickMarksAngle(); + float angle = startAt - fmod(startAt, tickMarkAngle) + tickMarkAngle; float angleInRadians = glm::radians(angle); - glm::vec2 firstPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius); - points << firstPoint; + float tickMarkLength = getMajorTickMarksLength(); + float startRadius = (tickMarkLength > 0.0f) ? innerRadius : outerRadius; + float endRadius = startRadius + tickMarkLength; - while (angle < endAt) { - angle += SLICE_ANGLE; + while (angle <= endAt) { angleInRadians = glm::radians(angle); - glm::vec2 thisPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius); - points << thisPoint; - if (getIsDashedLine()) { - angle += SLICE_ANGLE / 2.0f; // short gap - angleInRadians = glm::radians(angle); - glm::vec2 dashStartPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius); - points << dashStartPoint; - } + glm::vec2 thisPointA(cos(angleInRadians) * startRadius, sin(angleInRadians) * startRadius); + glm::vec2 thisPointB(cos(angleInRadians) * endRadius, sin(angleInRadians) * endRadius); + + majorPoints << thisPointA << thisPointB; + + angle += tickMarkAngle; } - - // get the last slice portion.... - angle = endAt; - angleInRadians = glm::radians(angle); - glm::vec2 lastPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius); - points << lastPoint; - - geometryCache->updateVertices(_lineVerticesID, points, color); } - if (getIsDashedLine()) { - geometryCache->renderVertices(gpu::LINES, _lineVerticesID); - } else { - geometryCache->renderVertices(gpu::LINE_STRIP, _lineVerticesID); + // draw our minor tick marks + if (getMinorTickMarksAngle() > 0.0f && getMinorTickMarksLength() != 0.0f) { + + float tickMarkAngle = getMinorTickMarksAngle(); + float angle = startAt - fmod(startAt, tickMarkAngle) + tickMarkAngle; + float angleInRadians = glm::radians(angle); + float tickMarkLength = getMinorTickMarksLength(); + float startRadius = (tickMarkLength > 0.0f) ? innerRadius : outerRadius; + float endRadius = startRadius + tickMarkLength; + + while (angle <= endAt) { + angleInRadians = glm::radians(angle); + + glm::vec2 thisPointA(cos(angleInRadians) * startRadius, sin(angleInRadians) * startRadius); + glm::vec2 thisPointB(cos(angleInRadians) * endRadius, sin(angleInRadians) * endRadius); + + minorPoints << thisPointA << thisPointB; + + angle += tickMarkAngle; + } } + + xColor majorColorX = getMajorTickMarksColor(); + glm::vec4 majorColor(majorColorX.red / MAX_COLOR, majorColorX.green / MAX_COLOR, majorColorX.blue / MAX_COLOR, alpha); + + geometryCache->updateVertices(_majorTicksVerticesID, majorPoints, majorColor); + + xColor minorColorX = getMinorTickMarksColor(); + glm::vec4 minorColor(minorColorX.red / MAX_COLOR, minorColorX.green / MAX_COLOR, minorColorX.blue / MAX_COLOR, alpha); + + geometryCache->updateVertices(_minorTicksVerticesID, minorPoints, minorColor); } - // draw our tick marks - // for our overlay, is solid means we draw a ring between the inner and outer radius of the circle, otherwise - // we just draw a line... - if (getHasTickMarks()) { + geometryCache->renderVertices(*batch, gpu::LINES, _majorTicksVerticesID); - if (_majorTicksVerticesID == GeometryCache::UNKNOWN_ID) { - _majorTicksVerticesID = geometryCache->allocateID(); - } - if (_minorTicksVerticesID == GeometryCache::UNKNOWN_ID) { - _minorTicksVerticesID = geometryCache->allocateID(); - } + geometryCache->renderVertices(*batch, gpu::LINES, _minorTicksVerticesID); + } - if (geometryChanged) { - QVector majorPoints; - QVector minorPoints; - - // draw our major tick marks - if (getMajorTickMarksAngle() > 0.0f && getMajorTickMarksLength() != 0.0f) { - - float tickMarkAngle = getMajorTickMarksAngle(); - float angle = startAt - fmodf(startAt, tickMarkAngle) + tickMarkAngle; - float angleInRadians = glm::radians(angle); - float tickMarkLength = getMajorTickMarksLength(); - float startRadius = (tickMarkLength > 0.0f) ? innerRadius : outerRadius; - float endRadius = startRadius + tickMarkLength; - - while (angle <= endAt) { - angleInRadians = glm::radians(angle); - - glm::vec2 thisPointA(cosf(angleInRadians) * startRadius, sinf(angleInRadians) * startRadius); - glm::vec2 thisPointB(cosf(angleInRadians) * endRadius, sinf(angleInRadians) * endRadius); - - majorPoints << thisPointA << thisPointB; - - angle += tickMarkAngle; - } - } - - // draw our minor tick marks - if (getMinorTickMarksAngle() > 0.0f && getMinorTickMarksLength() != 0.0f) { - - float tickMarkAngle = getMinorTickMarksAngle(); - float angle = startAt - fmodf(startAt, tickMarkAngle) + tickMarkAngle; - float angleInRadians = glm::radians(angle); - float tickMarkLength = getMinorTickMarksLength(); - float startRadius = (tickMarkLength > 0.0f) ? innerRadius : outerRadius; - float endRadius = startRadius + tickMarkLength; - - while (angle <= endAt) { - angleInRadians = glm::radians(angle); - - glm::vec2 thisPointA(cosf(angleInRadians) * startRadius, sinf(angleInRadians) * startRadius); - glm::vec2 thisPointB(cosf(angleInRadians) * endRadius, sinf(angleInRadians) * endRadius); - - minorPoints << thisPointA << thisPointB; - - angle += tickMarkAngle; - } - } - - xColor majorColorX = getMajorTickMarksColor(); - glm::vec4 majorColor(majorColorX.red / MAX_COLOR, majorColorX.green / MAX_COLOR, majorColorX.blue / MAX_COLOR, alpha); - - geometryCache->updateVertices(_majorTicksVerticesID, majorPoints, majorColor); - - xColor minorColorX = getMinorTickMarksColor(); - glm::vec4 minorColor(minorColorX.red / MAX_COLOR, minorColorX.green / MAX_COLOR, minorColorX.blue / MAX_COLOR, alpha); - - geometryCache->updateVertices(_minorTicksVerticesID, minorPoints, minorColor); - } - - geometryCache->renderVertices(gpu::LINES, _majorTicksVerticesID); - - geometryCache->renderVertices(gpu::LINES, _minorTicksVerticesID); - } - - - glPopMatrix(); - glPopMatrix(); - - if (geometryChanged) { - _lastStartAt = startAt; - _lastEndAt = endAt; - _lastInnerRadius = innerRadius; - _lastOuterRadius = outerRadius; - } - - if (glower) { - delete glower; + if (geometryChanged) { + _lastStartAt = startAt; + _lastEndAt = endAt; + _lastInnerRadius = innerRadius; + _lastOuterRadius = outerRadius; + } } } diff --git a/interface/src/ui/overlays/Text3DOverlay.cpp b/interface/src/ui/overlays/Text3DOverlay.cpp index fd8410b7e6..327c70d778 100644 --- a/interface/src/ui/overlays/Text3DOverlay.cpp +++ b/interface/src/ui/overlays/Text3DOverlay.cpp @@ -14,6 +14,8 @@ #include "Application.h" #include "Text3DOverlay.h" +#include + const xColor DEFAULT_BACKGROUND_COLOR = { 0, 0, 0 }; const float DEFAULT_BACKGROUND_ALPHA = 0.7f; const float DEFAULT_MARGIN = 0.1f; @@ -52,7 +54,7 @@ Text3DOverlay::~Text3DOverlay() { xColor Text3DOverlay::getBackgroundColor() { if (_colorPulse == 0.0f) { - return _backgroundColor; + return _backgroundColor; } float pulseLevel = updatePulse(); @@ -75,19 +77,23 @@ void Text3DOverlay::render(RenderArgs* args) { return; // do nothing if we're not visible } - glPushMatrix(); { - glTranslatef(_position.x, _position.y, _position.z); + auto batch = args->_batch; + + if (batch) { glm::quat rotation; - + if (_isFacingAvatar) { // rotate about vertical to face the camera rotation = Application::getInstance()->getCamera()->getRotation(); } else { rotation = getRotation(); } - - glm::vec3 axis = glm::axis(rotation); - glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z); + + Transform transform; + transform.setTranslation(_position); + transform.setRotation(rotation); + + batch->setModelTransform(transform); const float MAX_COLOR = 255.0f; xColor backgroundColor = getBackgroundColor(); @@ -96,40 +102,42 @@ 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); - DependencyManager::get()->renderQuad(topLeft, bottomRight, quadColor); - + DependencyManager::get()->renderQuad(*batch, topLeft, bottomRight, quadColor); + // Same font properties as textSize() float maxHeight = (float)_textRenderer->computeExtent("Xy").y * LINE_SCALE_RATIO; - - float scaleFactor = (maxHeight / FIXED_FONT_SCALING_RATIO) * _lineHeight; - glTranslatef(-(halfDimensions.x - _leftMargin), halfDimensions.y - _topMargin, 0.0f); + float scaleFactor = (maxHeight / FIXED_FONT_SCALING_RATIO) * _lineHeight; glm::vec2 clipMinimum(0.0f, 0.0f); - glm::vec2 clipDimensions((dimensions.x - (_leftMargin + _rightMargin)) / scaleFactor, + glm::vec2 clipDimensions((dimensions.x - (_leftMargin + _rightMargin)) / scaleFactor, (dimensions.y - (_topMargin + _bottomMargin)) / scaleFactor); - glScalef(scaleFactor, -scaleFactor, scaleFactor); - enableClipPlane(GL_CLIP_PLANE0, -1.0f, 0.0f, 0.0f, clipMinimum.x + clipDimensions.x); - enableClipPlane(GL_CLIP_PLANE1, 1.0f, 0.0f, 0.0f, -clipMinimum.x); - enableClipPlane(GL_CLIP_PLANE2, 0.0f, -1.0f, 0.0f, clipMinimum.y + clipDimensions.y); - enableClipPlane(GL_CLIP_PLANE3, 0.0f, 1.0f, 0.0f, -clipMinimum.y); - - glm::vec4 textColor = { _color.red / MAX_COLOR, _color.green / MAX_COLOR, _color.blue / MAX_COLOR, getAlpha() }; - _textRenderer->draw(0, 0, _text, textColor); + transform.setScale(glm::vec3(scaleFactor, -scaleFactor, scaleFactor)); + transform.preTranslate(glm::vec3(-(halfDimensions.x - _leftMargin), halfDimensions.y - _topMargin, 0.0f)); + batch->setModelTransform(transform); + + // enableClipPlane(GL_CLIP_PLANE0, -1.0f, 0.0f, 0.0f, clipMinimum.x + clipDimensions.x); + // enableClipPlane(GL_CLIP_PLANE1, 1.0f, 0.0f, 0.0f, -clipMinimum.x); + // enableClipPlane(GL_CLIP_PLANE2, 0.0f, -1.0f, 0.0f, clipMinimum.y + clipDimensions.y); + // enableClipPlane(GL_CLIP_PLANE3, 0.0f, 1.0f, 0.0f, -clipMinimum.y); + + glm::vec4 textColor = { _color.red / MAX_COLOR, _color.green / MAX_COLOR, _color.blue / MAX_COLOR, getAlpha() }; + _textRenderer->draw(*batch, 0, 0, _text, textColor); + + // glDisable(GL_CLIP_PLANE0); + // glDisable(GL_CLIP_PLANE1); + // glDisable(GL_CLIP_PLANE2); + // glDisable(GL_CLIP_PLANE3); + + batch->setPipeline(DrawOverlay3D::getOpaquePipeline()); + } - glDisable(GL_CLIP_PLANE0); - glDisable(GL_CLIP_PLANE1); - glDisable(GL_CLIP_PLANE2); - glDisable(GL_CLIP_PLANE3); - - } glPopMatrix(); - } void Text3DOverlay::enableClipPlane(GLenum plane, float x, float y, float z, float w) { diff --git a/interface/src/ui/overlays/Text3DOverlay.h b/interface/src/ui/overlays/Text3DOverlay.h index 77a5c23cb9..f2c71f8676 100644 --- a/interface/src/ui/overlays/Text3DOverlay.h +++ b/interface/src/ui/overlays/Text3DOverlay.h @@ -17,7 +17,7 @@ #include #include -#include +#include #include "Planar3DOverlay.h" @@ -62,7 +62,7 @@ public: private: void enableClipPlane(GLenum plane, float x, float y, float z, float w); - TextRenderer* _textRenderer = TextRenderer::getInstance(SANS_FONT_FAMILY, FIXED_FONT_POINT_SIZE); + TextRenderer3D* _textRenderer = TextRenderer3D::getInstance(SANS_FONT_FAMILY, FIXED_FONT_POINT_SIZE); QString _text; xColor _backgroundColor; diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index ce3c6769ca..b8ec2e0467 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -1,244 +1,245 @@ -// -// RenderDeferredTask.cpp -// render-utils/src/ -// -// Created by Sam Gateau on 5/29/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 "RenderDeferredTask.h" - -#include "gpu/Batch.h" -#include "gpu/Context.h" -#include "DeferredLightingEffect.h" -#include "ViewFrustum.h" -#include "RenderArgs.h" -#include "TextureCache.h" - -#include - +// +// RenderDeferredTask.cpp +// render-utils/src/ +// +// Created by Sam Gateau on 5/29/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 "RenderDeferredTask.h" + +#include "gpu/Batch.h" +#include "gpu/Context.h" +#include "DeferredLightingEffect.h" +#include "ViewFrustum.h" +#include "RenderArgs.h" +#include "TextureCache.h" + +#include + #include "overlay3D_vert.h" -#include "overlay3D_frag.h" - -using namespace render; - -template <> void render::jobRun(const PrepareDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { - PerformanceTimer perfTimer("PrepareDeferred"); - DependencyManager::get()->prepare(); -} - -template <> void render::jobRun(const RenderDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { - PerformanceTimer perfTimer("RenderDeferred"); - DependencyManager::get()->render(); -// renderContext->args->_context->syncCache(); -} - -template <> void render::jobRun(const ResolveDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { - PerformanceTimer perfTimer("ResolveDeferred"); - DependencyManager::get()->copyBack(renderContext->args); - renderContext->args->_context->syncCache(); - -} - - - -RenderDeferredTask::RenderDeferredTask() : Task() { - _jobs.push_back(Job(PrepareDeferred())); - _jobs.push_back(Job(DrawBackground())); - _jobs.push_back(Job(DrawOpaqueDeferred())); - _jobs.push_back(Job(DrawLight())); - _jobs.push_back(Job(ResetGLState())); - _jobs.push_back(Job(RenderDeferred())); - _jobs.push_back(Job(ResolveDeferred())); - _jobs.push_back(Job(DrawTransparentDeferred())); - _jobs.push_back(Job(DrawOverlay3D())); - _jobs.push_back(Job(ResetGLState())); -} - -RenderDeferredTask::~RenderDeferredTask() { -} - -void RenderDeferredTask::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { - // sanity checks - assert(sceneContext); - if (!sceneContext->_scene) { - return; - } - - - // Is it possible that we render without a viewFrustum ? - if (!(renderContext->args && renderContext->args->_viewFrustum)) { - return; - } - - renderContext->args->_context->syncCache(); - - for (auto job : _jobs) { - job.run(sceneContext, renderContext); - } -}; - - - -template <> void render::jobRun(const DrawOpaqueDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { - PerformanceTimer perfTimer("DrawOpaqueDeferred"); - assert(renderContext->args); - assert(renderContext->args->_viewFrustum); - - // render opaques - auto& scene = sceneContext->_scene; - auto& items = scene->getMasterBucket().at(ItemFilter::Builder::opaqueShape().withoutLayered()); - auto& renderDetails = renderContext->args->_details; - - ItemIDsBounds inItems; - inItems.reserve(items.size()); - for (auto id : items) { - inItems.emplace_back(ItemIDAndBounds(id)); - } - ItemIDsBounds& renderedItems = inItems; - - renderContext->_numFeedOpaqueItems = renderedItems.size(); - - ItemIDsBounds culledItems; - culledItems.reserve(inItems.size()); - if (renderContext->_cullOpaque) { - renderDetails.pointTo(RenderDetails::OPAQUE_ITEM); - cullItems(sceneContext, renderContext, renderedItems, culledItems); - renderDetails.pointTo(RenderDetails::OTHER_ITEM); - renderedItems = culledItems; - } - - renderContext->_numDrawnOpaqueItems = renderedItems.size(); - - - ItemIDsBounds sortedItems; - sortedItems.reserve(culledItems.size()); - if (renderContext->_sortOpaque) { - depthSortItems(sceneContext, renderContext, true, renderedItems, sortedItems); // Sort Front to back opaque items! - renderedItems = sortedItems; - } - - // ItemIDsBounds sortedItems; - /* ItemMaterialBucketMap stateSortedItems; - stateSortedItems.allocateStandardMaterialBuckets(); - if (true) { - for (auto& itemIDAndBound : renderedItems) { - stateSortedItems.insert(itemIDAndBound.id, scene->getItem(itemIDAndBound.id).getMaterialKey()); - } - } -*/ - - if (renderContext->_renderOpaque) { - RenderArgs* args = renderContext->args; - gpu::Batch batch; - args->_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); - - { - GLenum buffers[3]; - int bufferCount = 0; - buffers[bufferCount++] = GL_COLOR_ATTACHMENT0; - buffers[bufferCount++] = GL_COLOR_ATTACHMENT1; - buffers[bufferCount++] = GL_COLOR_ATTACHMENT2; - batch._glDrawBuffers(bufferCount, buffers); - } - - renderItems(sceneContext, renderContext, renderedItems, renderContext->_maxDrawnOpaqueItems); - - args->_context->render((*args->_batch)); - args->_batch = nullptr; - } -} - - -template <> void render::jobRun(const DrawTransparentDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { - PerformanceTimer perfTimer("DrawTransparentDeferred"); - assert(renderContext->args); - assert(renderContext->args->_viewFrustum); - - // render transparents - auto& scene = sceneContext->_scene; - auto& items = scene->getMasterBucket().at(ItemFilter::Builder::transparentShape().withoutLayered()); - auto& renderDetails = renderContext->args->_details; - - ItemIDsBounds inItems; - inItems.reserve(items.size()); - for (auto id : items) { - inItems.push_back(id); - } - ItemIDsBounds& renderedItems = inItems; - - renderContext->_numFeedTransparentItems = renderedItems.size(); - - ItemIDsBounds culledItems; - if (renderContext->_cullTransparent) { - renderDetails.pointTo(RenderDetails::TRANSLUCENT_ITEM); - cullItems(sceneContext, renderContext, inItems, culledItems); - renderDetails.pointTo(RenderDetails::OTHER_ITEM); - renderedItems = culledItems; - } - - renderContext->_numDrawnTransparentItems = renderedItems.size(); - - ItemIDsBounds sortedItems; - if (renderContext->_sortTransparent) { - depthSortItems(sceneContext, renderContext, false, renderedItems, sortedItems); // Sort Back to front transparent items! - renderedItems = sortedItems; - } - - if (renderContext->_renderTransparent) { - RenderArgs* args = renderContext->args; - gpu::Batch batch; - args->_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); - - const float TRANSPARENT_ALPHA_THRESHOLD = 0.0f; - - { - GLenum buffers[3]; - int bufferCount = 0; - buffers[bufferCount++] = GL_COLOR_ATTACHMENT0; - batch._glDrawBuffers(bufferCount, buffers); - args->_alphaThreshold = TRANSPARENT_ALPHA_THRESHOLD; - } - - - renderItems(sceneContext, renderContext, renderedItems, renderContext->_maxDrawnTransparentItems); - - // Before rendering the batch make sure we re in sync with gl state - args->_context->syncCache(); - args->_context->render((*args->_batch)); - args->_batch = nullptr; - - // reset blend function to standard... - // glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE); - } -} - -const gpu::PipelinePointer& DrawOverlay3D::getOpaquePipeline() const { +#include "overlay3D_frag.h" + +using namespace render; + +template <> void render::jobRun(const PrepareDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + PerformanceTimer perfTimer("PrepareDeferred"); + DependencyManager::get()->prepare(); +} + +template <> void render::jobRun(const RenderDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + PerformanceTimer perfTimer("RenderDeferred"); + DependencyManager::get()->render(); +// renderContext->args->_context->syncCache(); +} + +template <> void render::jobRun(const ResolveDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + PerformanceTimer perfTimer("ResolveDeferred"); + DependencyManager::get()->copyBack(renderContext->args); + renderContext->args->_context->syncCache(); + +} + + + +RenderDeferredTask::RenderDeferredTask() : Task() { + _jobs.push_back(Job(PrepareDeferred())); + _jobs.push_back(Job(DrawBackground())); + _jobs.push_back(Job(DrawOpaqueDeferred())); + _jobs.push_back(Job(DrawLight())); + _jobs.push_back(Job(ResetGLState())); + _jobs.push_back(Job(RenderDeferred())); + _jobs.push_back(Job(ResolveDeferred())); + _jobs.push_back(Job(DrawTransparentDeferred())); + _jobs.push_back(Job(DrawOverlay3D())); + _jobs.push_back(Job(ResetGLState())); +} + +RenderDeferredTask::~RenderDeferredTask() { +} + +void RenderDeferredTask::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + // sanity checks + assert(sceneContext); + if (!sceneContext->_scene) { + return; + } + + + // Is it possible that we render without a viewFrustum ? + if (!(renderContext->args && renderContext->args->_viewFrustum)) { + return; + } + + renderContext->args->_context->syncCache(); + + for (auto job : _jobs) { + job.run(sceneContext, renderContext); + } +}; + + + +template <> void render::jobRun(const DrawOpaqueDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + PerformanceTimer perfTimer("DrawOpaqueDeferred"); + assert(renderContext->args); + assert(renderContext->args->_viewFrustum); + + // render opaques + auto& scene = sceneContext->_scene; + auto& items = scene->getMasterBucket().at(ItemFilter::Builder::opaqueShape().withoutLayered()); + auto& renderDetails = renderContext->args->_details; + + ItemIDsBounds inItems; + inItems.reserve(items.size()); + for (auto id : items) { + inItems.emplace_back(ItemIDAndBounds(id)); + } + ItemIDsBounds& renderedItems = inItems; + + renderContext->_numFeedOpaqueItems = renderedItems.size(); + + ItemIDsBounds culledItems; + culledItems.reserve(inItems.size()); + if (renderContext->_cullOpaque) { + renderDetails.pointTo(RenderDetails::OPAQUE_ITEM); + cullItems(sceneContext, renderContext, renderedItems, culledItems); + renderDetails.pointTo(RenderDetails::OTHER_ITEM); + renderedItems = culledItems; + } + + renderContext->_numDrawnOpaqueItems = renderedItems.size(); + + + ItemIDsBounds sortedItems; + sortedItems.reserve(culledItems.size()); + if (renderContext->_sortOpaque) { + depthSortItems(sceneContext, renderContext, true, renderedItems, sortedItems); // Sort Front to back opaque items! + renderedItems = sortedItems; + } + + // ItemIDsBounds sortedItems; + /* ItemMaterialBucketMap stateSortedItems; + stateSortedItems.allocateStandardMaterialBuckets(); + if (true) { + for (auto& itemIDAndBound : renderedItems) { + stateSortedItems.insert(itemIDAndBound.id, scene->getItem(itemIDAndBound.id).getMaterialKey()); + } + } +*/ + + if (renderContext->_renderOpaque) { + RenderArgs* args = renderContext->args; + gpu::Batch batch; + args->_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); + + { + GLenum buffers[3]; + int bufferCount = 0; + buffers[bufferCount++] = GL_COLOR_ATTACHMENT0; + buffers[bufferCount++] = GL_COLOR_ATTACHMENT1; + buffers[bufferCount++] = GL_COLOR_ATTACHMENT2; + batch._glDrawBuffers(bufferCount, buffers); + } + + renderItems(sceneContext, renderContext, renderedItems, renderContext->_maxDrawnOpaqueItems); + + args->_context->render((*args->_batch)); + args->_batch = nullptr; + } +} + + +template <> void render::jobRun(const DrawTransparentDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + PerformanceTimer perfTimer("DrawTransparentDeferred"); + assert(renderContext->args); + assert(renderContext->args->_viewFrustum); + + // render transparents + auto& scene = sceneContext->_scene; + auto& items = scene->getMasterBucket().at(ItemFilter::Builder::transparentShape().withoutLayered()); + auto& renderDetails = renderContext->args->_details; + + ItemIDsBounds inItems; + inItems.reserve(items.size()); + for (auto id : items) { + inItems.push_back(id); + } + ItemIDsBounds& renderedItems = inItems; + + renderContext->_numFeedTransparentItems = renderedItems.size(); + + ItemIDsBounds culledItems; + if (renderContext->_cullTransparent) { + renderDetails.pointTo(RenderDetails::TRANSLUCENT_ITEM); + cullItems(sceneContext, renderContext, inItems, culledItems); + renderDetails.pointTo(RenderDetails::OTHER_ITEM); + renderedItems = culledItems; + } + + renderContext->_numDrawnTransparentItems = renderedItems.size(); + + ItemIDsBounds sortedItems; + if (renderContext->_sortTransparent) { + depthSortItems(sceneContext, renderContext, false, renderedItems, sortedItems); // Sort Back to front transparent items! + renderedItems = sortedItems; + } + + if (renderContext->_renderTransparent) { + RenderArgs* args = renderContext->args; + gpu::Batch batch; + args->_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); + + const float TRANSPARENT_ALPHA_THRESHOLD = 0.0f; + + { + GLenum buffers[3]; + int bufferCount = 0; + buffers[bufferCount++] = GL_COLOR_ATTACHMENT0; + batch._glDrawBuffers(bufferCount, buffers); + args->_alphaThreshold = TRANSPARENT_ALPHA_THRESHOLD; + } + + + renderItems(sceneContext, renderContext, renderedItems, renderContext->_maxDrawnTransparentItems); + + // Before rendering the batch make sure we re in sync with gl state + args->_context->syncCache(); + args->_context->render((*args->_batch)); + args->_batch = nullptr; + + // reset blend function to standard... + // glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE); + } +} + +gpu::PipelinePointer DrawOverlay3D::_opaquePipeline; +const gpu::PipelinePointer& DrawOverlay3D::getOpaquePipeline() { if (!_opaquePipeline) { auto vs = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(overlay3D_vert))); auto ps = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(overlay3D_frag))); @@ -251,53 +252,53 @@ const gpu::PipelinePointer& DrawOverlay3D::getOpaquePipeline() const { _opaquePipeline.reset(gpu::Pipeline::create(program, state)); } return _opaquePipeline; -} - -template <> void render::jobRun(const DrawOverlay3D& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { - PerformanceTimer perfTimer("DrawOverlay3D"); - assert(renderContext->args); - assert(renderContext->args->_viewFrustum); - - // render backgrounds - auto& scene = sceneContext->_scene; - auto& items = scene->getMasterBucket().at(ItemFilter::Builder::opaqueShape().withLayered()); - - - ItemIDsBounds inItems; - inItems.reserve(items.size()); - for (auto id : items) { - auto& item = scene->getItem(id); - if (item.getKey().isVisible() && (item.getLayer() == 1)) { - inItems.emplace_back(id); - } - } - - RenderArgs* args = renderContext->args; - gpu::Batch batch; - args->_batch = &batch; - args->_whiteTexture = DependencyManager::get()->getWhiteTexture(); - - - 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.setPipeline(job.getOpaquePipeline()); - batch.setUniformTexture(0, args->_whiteTexture); - - if (!inItems.empty()) { +} + +template <> void render::jobRun(const DrawOverlay3D& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + PerformanceTimer perfTimer("DrawOverlay3D"); + assert(renderContext->args); + assert(renderContext->args->_viewFrustum); + + // render backgrounds + auto& scene = sceneContext->_scene; + auto& items = scene->getMasterBucket().at(ItemFilter::Builder::opaqueShape().withLayered()); + + + ItemIDsBounds inItems; + inItems.reserve(items.size()); + for (auto id : items) { + auto& item = scene->getItem(id); + if (item.getKey().isVisible() && (item.getLayer() == 1)) { + inItems.emplace_back(id); + } + } + + RenderArgs* args = renderContext->args; + gpu::Batch batch; + args->_batch = &batch; + args->_whiteTexture = DependencyManager::get()->getWhiteTexture(); + + + 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.setPipeline(job.getOpaquePipeline()); + batch.setUniformTexture(0, args->_whiteTexture); + + if (!inItems.empty()) { batch.clearFramebuffer(gpu::Framebuffer::BUFFER_DEPTH, glm::vec4(), 1.f, 0); - renderItems(sceneContext, renderContext, inItems); - } - - // Before rendering the batch make sure we re in sync with gl state - args->_context->syncCache(); - args->_context->render((*args->_batch)); - args->_batch = nullptr; - args->_whiteTexture.reset(); -} + renderItems(sceneContext, renderContext, inItems); + } + + // Before rendering the batch make sure we re in sync with gl state + args->_context->syncCache(); + args->_context->render((*args->_batch)); + args->_batch = nullptr; + args->_whiteTexture.reset(); +} diff --git a/libraries/render-utils/src/RenderDeferredTask.h b/libraries/render-utils/src/RenderDeferredTask.h index 3b0ffdfc9b..d05a0b6f24 100755 --- a/libraries/render-utils/src/RenderDeferredTask.h +++ b/libraries/render-utils/src/RenderDeferredTask.h @@ -53,9 +53,9 @@ template <> void jobRun(const DrawTransparentDeferred& job, const SceneContextPo } class DrawOverlay3D { - mutable gpu::PipelinePointer _opaquePipeline; //lazy evaluation hence mutable + static gpu::PipelinePointer _opaquePipeline; //lazy evaluation hence mutable public: - const gpu::PipelinePointer& getOpaquePipeline() const; + static const gpu::PipelinePointer& getOpaquePipeline(); }; namespace render { template <> void jobRun(const DrawOverlay3D& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext);