From bd7c22e715d5db93cac04f928ec29d97bb08a7a9 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 1 Jun 2015 17:31:00 -0700 Subject: [PATCH] Trying to transfer the rnedering from displaySide to RenderDeferredTask --- interface/src/Application.cpp | 213 +++++++++++------- interface/src/Application.h | 4 +- interface/src/Environment.cpp | 4 +- interface/src/Environment.h | 6 +- libraries/render-utils/src/Model.cpp | 7 +- .../render-utils/src/RenderDeferredTask.cpp | 18 ++ .../render-utils/src/RenderDeferredTask.h | 12 + libraries/render/src/render/DrawTask.cpp | 60 ++++- libraries/render/src/render/DrawTask.h | 5 + libraries/render/src/render/Scene.cpp | 4 +- libraries/render/src/render/Scene.h | 5 + libraries/shared/src/RenderArgs.h | 2 + 12 files changed, 241 insertions(+), 99 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9f5a7ae43b..2b3029bfed 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3192,6 +3192,113 @@ namespace render { } } +// Background Render Data & rendering functions +class BackgroundRenderData { +public: + typedef render::Payload Payload; + typedef Payload::DataPointer Pointer; + + Stars _stars; + Environment* _environment; + + BackgroundRenderData(Environment* environment) : _environment(environment) { + } + + static render::ItemID _item; // unique WorldBoxRenderData +}; + +render::ItemID BackgroundRenderData::_item = 0; + +namespace render { + template <> const ItemKey payloadGetKey(const BackgroundRenderData::Pointer& stuff) { return ItemKey::Builder::background(); } + template <> const Item::Bound payloadGetBound(const BackgroundRenderData::Pointer& stuff) { return Item::Bound(); } + template <> void payloadRender(const BackgroundRenderData::Pointer& background, RenderArgs* args) { + + // Background rendering decision + auto skyStage = DependencyManager::get()->getSkyStage(); + auto skybox = model::SkyboxPointer(); + if (skyStage->getBackgroundMode() == model::SunSkyStage::NO_BACKGROUND) { + } else if (skyStage->getBackgroundMode() == model::SunSkyStage::SKY_DOME) { + if (/*!selfAvatarOnly &&*/ Menu::getInstance()->isOptionChecked(MenuOption::Stars)) { + PerformanceTimer perfTimer("stars"); + PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), + "Application::payloadRender() ... stars..."); + if (!background->_stars.isStarsLoaded()) { + background->_stars.generate(STARFIELD_NUM_STARS, STARFIELD_SEED); + } + // should be the first rendering pass - w/o depth buffer / lighting + + // compute starfield alpha based on distance from atmosphere + float alpha = 1.0f; + bool hasStars = true; + + if (Menu::getInstance()->isOptionChecked(MenuOption::Atmosphere)) { + // TODO: handle this correctly for zones + const EnvironmentData& closestData = background->_environment->getClosestData(args->_viewFrustum->getPosition()); // was theCamera instead of _viewFrustum + + if (closestData.getHasStars()) { + const float APPROXIMATE_DISTANCE_FROM_HORIZON = 0.1f; + const float DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON = 0.2f; + + glm::vec3 sunDirection = (args->_viewFrustum->getPosition()/*getAvatarPosition()*/ - closestData.getSunLocation()) + / closestData.getAtmosphereOuterRadius(); + float height = glm::distance(args->_viewFrustum->getPosition()/*theCamera.getPosition()*/, closestData.getAtmosphereCenter()); + if (height < closestData.getAtmosphereInnerRadius()) { + // If we're inside the atmosphere, then determine if our keyLight is below the horizon + alpha = 0.0f; + + if (sunDirection.y > -APPROXIMATE_DISTANCE_FROM_HORIZON) { + float directionY = glm::clamp(sunDirection.y, + -APPROXIMATE_DISTANCE_FROM_HORIZON, APPROXIMATE_DISTANCE_FROM_HORIZON) + + APPROXIMATE_DISTANCE_FROM_HORIZON; + alpha = (directionY / DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON); + } + + + } else if (height < closestData.getAtmosphereOuterRadius()) { + alpha = (height - closestData.getAtmosphereInnerRadius()) / + (closestData.getAtmosphereOuterRadius() - closestData.getAtmosphereInnerRadius()); + + if (sunDirection.y > -APPROXIMATE_DISTANCE_FROM_HORIZON) { + float directionY = glm::clamp(sunDirection.y, + -APPROXIMATE_DISTANCE_FROM_HORIZON, APPROXIMATE_DISTANCE_FROM_HORIZON) + + APPROXIMATE_DISTANCE_FROM_HORIZON; + alpha = (directionY / DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON); + } + } + } else { + hasStars = false; + } + } + + // finally render the starfield + if (hasStars) { + background->_stars.render(args->_viewFrustum->getFieldOfView(), args->_viewFrustum->getAspectRatio(), args->_viewFrustum->getNearClip(), alpha); + } + + // draw the sky dome + if (/*!selfAvatarOnly &&*/ Menu::getInstance()->isOptionChecked(MenuOption::Atmosphere)) { + PerformanceTimer perfTimer("atmosphere"); + PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), + "Application::displaySide() ... atmosphere..."); + background->_environment->renderAtmospheres(*(args->_viewFrustum)); + } + + } + } else if (skyStage->getBackgroundMode() == model::SunSkyStage::SKY_BOX) { + PerformanceTimer perfTimer("skybox"); + + skybox = skyStage->getSkybox(); + if (skybox) { + gpu::Batch batch; + model::Skybox::render(batch, *(args->_viewFrustum), *skybox); + + gpu::GLBackend::renderBatch(batch, true); + glUseProgram(0); + } + } + } +} void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool selfAvatarOnly) { @@ -3264,86 +3371,19 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se glTexGenfv(GL_R, GL_EYE_PLANE, (const GLfloat*)&_shadowMatrices[i][2]); } + // THe pending changes collecting the changes here + render::PendingChanges pendingChanges; + // Background rendering decision - auto skyStage = DependencyManager::get()->getSkyStage(); - auto skybox = model::SkyboxPointer(); - if (skyStage->getBackgroundMode() == model::SunSkyStage::NO_BACKGROUND) { - } else if (skyStage->getBackgroundMode() == model::SunSkyStage::SKY_DOME) { - if (!selfAvatarOnly && Menu::getInstance()->isOptionChecked(MenuOption::Stars)) { - PerformanceTimer perfTimer("stars"); - PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), - "Application::displaySide() ... stars..."); - if (!_stars.isStarsLoaded()) { - _stars.generate(STARFIELD_NUM_STARS, STARFIELD_SEED); - } - // should be the first rendering pass - w/o depth buffer / lighting + if (BackgroundRenderData::_item == 0) { + auto backgroundRenderData = BackgroundRenderData::Pointer(new BackgroundRenderData(&_environment)); + auto backgroundRenderPayload = render::PayloadPointer(new BackgroundRenderData::Payload(backgroundRenderData)); - // compute starfield alpha based on distance from atmosphere - float alpha = 1.0f; - bool hasStars = true; + BackgroundRenderData::_item = _main3DScene->allocateID(); - if (Menu::getInstance()->isOptionChecked(MenuOption::Atmosphere)) { - // TODO: handle this correctly for zones - const EnvironmentData& closestData = _environment.getClosestData(theCamera.getPosition()); + pendingChanges.resetItem(WorldBoxRenderData::_item, backgroundRenderPayload); + } else { - if (closestData.getHasStars()) { - const float APPROXIMATE_DISTANCE_FROM_HORIZON = 0.1f; - const float DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON = 0.2f; - - glm::vec3 sunDirection = (getAvatarPosition() - closestData.getSunLocation()) - / closestData.getAtmosphereOuterRadius(); - float height = glm::distance(theCamera.getPosition(), closestData.getAtmosphereCenter()); - if (height < closestData.getAtmosphereInnerRadius()) { - // If we're inside the atmosphere, then determine if our keyLight is below the horizon - alpha = 0.0f; - - if (sunDirection.y > -APPROXIMATE_DISTANCE_FROM_HORIZON) { - float directionY = glm::clamp(sunDirection.y, - -APPROXIMATE_DISTANCE_FROM_HORIZON, APPROXIMATE_DISTANCE_FROM_HORIZON) - + APPROXIMATE_DISTANCE_FROM_HORIZON; - alpha = (directionY / DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON); - } - - - } else if (height < closestData.getAtmosphereOuterRadius()) { - alpha = (height - closestData.getAtmosphereInnerRadius()) / - (closestData.getAtmosphereOuterRadius() - closestData.getAtmosphereInnerRadius()); - - if (sunDirection.y > -APPROXIMATE_DISTANCE_FROM_HORIZON) { - float directionY = glm::clamp(sunDirection.y, - -APPROXIMATE_DISTANCE_FROM_HORIZON, APPROXIMATE_DISTANCE_FROM_HORIZON) - + APPROXIMATE_DISTANCE_FROM_HORIZON; - alpha = (directionY / DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON); - } - } - } else { - hasStars = false; - } - } - - // finally render the starfield - if (hasStars) { - _stars.render(_displayViewFrustum.getFieldOfView(), _displayViewFrustum.getAspectRatio(), _displayViewFrustum.getNearClip(), alpha); - } - - // draw the sky dome - if (!selfAvatarOnly && Menu::getInstance()->isOptionChecked(MenuOption::Atmosphere)) { - PerformanceTimer perfTimer("atmosphere"); - PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), - "Application::displaySide() ... atmosphere..."); - _environment.renderAtmospheres(theCamera); - } - - } - } else if (skyStage->getBackgroundMode() == model::SunSkyStage::SKY_BOX) { - skybox = skyStage->getSkybox(); - if (skybox) { - gpu::Batch batch; - model::Skybox::render(batch, _viewFrustum, *skybox); - - gpu::GLBackend::renderBatch(batch, true); - glUseProgram(0); - } } if (Menu::getInstance()->isOptionChecked(MenuOption::Wireframe)) { @@ -3353,7 +3393,8 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se glEnable(GL_LIGHTING); glEnable(GL_DEPTH_TEST); - DependencyManager::get()->prepare(); + // Assuming nothing get's rendered through that + // DependencyManager::get()->prepare(); if (!selfAvatarOnly) { @@ -3380,10 +3421,11 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se renderArgs->_debugFlags = renderDebugFlags; _entities.render(renderArgs); - if (!Menu::getInstance()->isOptionChecked(MenuOption::Wireframe)) { + // This shouldn't matter anymore + /* if (!Menu::getInstance()->isOptionChecked(MenuOption::Wireframe)) { // Restaure polygon mode glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - } + }*/ } // render the ambient occlusion effect if enabled @@ -3395,7 +3437,6 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se } } - render::PendingChanges pendingChanges; // Make sure the WorldBox is in the scene if (WorldBoxRenderData::_item == 0) { @@ -3445,11 +3486,19 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se auto skyStage = DependencyManager::get()->getSkyStage(); DependencyManager::get()->setGlobalLight(skyStage->getSunLight()->getDirection(), skyStage->getSunLight()->getColor(), skyStage->getSunLight()->getIntensity(), skyStage->getSunLight()->getAmbientIntensity()); DependencyManager::get()->setGlobalAtmosphere(skyStage->getAtmosphere()); + + auto skybox = model::SkyboxPointer(); + if (skyStage->getBackgroundMode() == model::SunSkyStage::SKY_BOX) { + skybox = skyStage->getSkybox(); + } DependencyManager::get()->setGlobalSkybox(skybox); + // Not needed anymore here, taken care off by the Engine + /* PROFILE_RANGE("DeferredLighting"); PerformanceTimer perfTimer("lighting"); - DependencyManager::get()->render(); + DependencyManager::get()->render();*/ + } //Render the sixense lasers @@ -3700,7 +3749,7 @@ void Application::updateWindowTitle(){ void Application::clearDomainOctreeDetails() { qCDebug(interfaceapp) << "Clearing domain octree details..."; // reset the environment so that we don't erroneously end up with multiple - _environment.resetToDefault(); + // _environment.resetToDefault(); // reset our node to stats and node to jurisdiction maps... since these must be changing... _entityServerJurisdictions.lockForWrite(); diff --git a/interface/src/Application.h b/interface/src/Application.h index 56cfb87674..aaf831a511 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -210,7 +210,7 @@ public: ViewFrustum* getShadowViewFrustum() { return &_shadowViewFrustum; } const OctreePacketProcessor& getOctreePacketProcessor() const { return _octreeProcessor; } EntityTreeRenderer* getEntities() { return &_entities; } - Environment* getEnvironment() { return &_environment; } + // Environment* getEnvironment() { return &_environment; } QUndoStack* getUndoStack() { return &_undoStack; } MainWindow* getWindow() { return _window; } OctreeQuery& getOctreeQuery() { return _octreeQuery; } @@ -535,7 +535,7 @@ private: QElapsedTimer _timerStart; QElapsedTimer _lastTimeUpdated; bool _justStarted; - Stars _stars; + // Stars _stars; ShapeManager _shapeManager; PhysicalEntitySimulation _entitySimulation; diff --git a/interface/src/Environment.cpp b/interface/src/Environment.cpp index a2b78c2ff5..9f197920d9 100644 --- a/interface/src/Environment.cpp +++ b/interface/src/Environment.cpp @@ -68,7 +68,7 @@ void Environment::resetToDefault() { _data[HifiSockAddr()][0]; } -void Environment::renderAtmospheres(Camera& camera) { +void Environment::renderAtmospheres(ViewFrustum& camera) { // get the lock for the duration of the call QMutexLocker locker(&_mutex); @@ -228,7 +228,7 @@ ProgramObject* Environment::createSkyProgram(const char* from, int* locations) { return program; } -void Environment::renderAtmosphere(Camera& camera, const EnvironmentData& data) { +void Environment::renderAtmosphere(ViewFrustum& camera, const EnvironmentData& data) { glm::vec3 center = data.getAtmosphereCenter(); glPushMatrix(); diff --git a/interface/src/Environment.h b/interface/src/Environment.h index 1a46a10175..c1b4171947 100644 --- a/interface/src/Environment.h +++ b/interface/src/Environment.h @@ -19,7 +19,7 @@ #include "EnvironmentData.h" -class Camera; +class ViewFrustum; class ProgramObject; class Environment { @@ -29,7 +29,7 @@ public: void init(); void resetToDefault(); - void renderAtmospheres(Camera& camera); + void renderAtmospheres(ViewFrustum& camera); void override(const EnvironmentData& overrideData) { _overrideData = overrideData; _environmentIsOverridden = true; } void endOverride() { _environmentIsOverridden = false; } @@ -46,7 +46,7 @@ private: ProgramObject* createSkyProgram(const char* from, int* locations); - void renderAtmosphere(Camera& camera, const EnvironmentData& data); + void renderAtmosphere(ViewFrustum& camera, const EnvironmentData& data); bool _initialized; ProgramObject* _skyFromAtmosphereProgram; diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 9a82d4acfe..72857476cb 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -2239,9 +2239,10 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran batch.setViewTransform(_transforms[0]); - const float OPAQUE_ALPHA_THRESHOLD = 0.5f; - const float TRANSPARENT_ALPHA_THRESHOLD = 0.0f; - auto alphaThreshold = translucent ? TRANSPARENT_ALPHA_THRESHOLD : OPAQUE_ALPHA_THRESHOLD; // FIX ME + // const float OPAQUE_ALPHA_THRESHOLD = 0.5f; + // const float TRANSPARENT_ALPHA_THRESHOLD = 0.0f; + // auto alphaThreshold = translucent ? TRANSPARENT_ALPHA_THRESHOLD : OPAQUE_ALPHA_THRESHOLD; // FIX ME + auto alphaThreshold = args->_alphaThreshold; //translucent ? TRANSPARENT_ALPHA_THRESHOLD : OPAQUE_ALPHA_THRESHOLD; // FIX ME const FBXGeometry& geometry = _geometry->getFBXGeometry(); const QVector& networkMeshes = _geometry->getMeshes(); diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 821a93f567..4483fedfb2 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -12,12 +12,30 @@ #include "gpu/Context.h" +#include + using namespace render; + +template <> void render::jobRun(const PrepareDeferred& job, const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext) { + PerformanceTimer perfTimer("PrepareDeferred"); + DependencyManager::get()->prepare(); +} + +template <> void render::jobRun(const ResolveDeferred& job, const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext) { + PerformanceTimer perfTimer("ResolveDeferred"); + DependencyManager::get()->render(); +} + + RenderDeferredTask::RenderDeferredTask() : Task() { + _jobs.push_back(Job(PrepareDeferred())); + _jobs.push_back(Job(DrawBackground())); _jobs.push_back(Job(DrawOpaque())); _jobs.push_back(Job(DrawLight())); _jobs.push_back(Job(DrawTransparent())); + _jobs.push_back(Job(ResolveDeferred())); + } RenderDeferredTask::~RenderDeferredTask() { diff --git a/libraries/render-utils/src/RenderDeferredTask.h b/libraries/render-utils/src/RenderDeferredTask.h index 574dc651b1..010fa80d3d 100755 --- a/libraries/render-utils/src/RenderDeferredTask.h +++ b/libraries/render-utils/src/RenderDeferredTask.h @@ -14,6 +14,18 @@ #include "render/DrawTask.h" +#include "DeferredLightingEffect.h" + +class PrepareDeferred { +public: +}; +template <> void render::jobRun(const PrepareDeferred& job, const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); + +class ResolveDeferred { +public: +}; +template <> void render::jobRun(const ResolveDeferred& job, const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); + class RenderDeferredTask : public render::Task { public: diff --git a/libraries/render/src/render/DrawTask.cpp b/libraries/render/src/render/DrawTask.cpp index 9e66ec0938..37180ff0aa 100755 --- a/libraries/render/src/render/DrawTask.cpp +++ b/libraries/render/src/render/DrawTask.cpp @@ -239,6 +239,7 @@ void addClearStateCommands(gpu::Batch& batch) { template <> void render::jobRun(const DrawOpaque& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + PerformanceTimer perfTimer("DrawOpaque"); assert(renderContext->args); assert(renderContext->args->_viewFrustum); @@ -251,12 +252,16 @@ template <> void render::jobRun(const DrawOpaque& job, const SceneContextPointer for (auto id : items) { inItems.push_back(id); } + ItemIDs& renderedItems = inItems; ItemIDs culledItems; cullItems(sceneContext, renderContext, inItems, culledItems); - + renderedItems = culledItems; + ItemIDs sortedItems; depthSortItems(sceneContext, renderContext, true, culledItems, sortedItems); // Sort Front to back opaque items! + renderedItems = sortedItems; + RenderArgs* args = renderContext->args; gpu::Batch theBatch; @@ -276,15 +281,15 @@ template <> void render::jobRun(const DrawOpaque& job, const SceneContextPointer theBatch._glDrawBuffers(bufferCount, buffers); } - renderItems(sceneContext, renderContext, sortedItems); + renderItems(sceneContext, renderContext, renderedItems); - addClearStateCommands((*args->_batch)); args->_context->render((*args->_batch)); args->_batch = nullptr; } template <> void render::jobRun(const DrawTransparent& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + PerformanceTimer perfTimer("DrawTransparent"); assert(renderContext->args); assert(renderContext->args->_viewFrustum); @@ -297,26 +302,47 @@ template <> void render::jobRun(const DrawTransparent& job, const SceneContextPo for (auto id : items) { inItems.push_back(id); } + ItemIDs& renderedItems = inItems; ItemIDs culledItems; cullItems(sceneContext, renderContext, inItems, culledItems); + renderedItems = culledItems; ItemIDs sortedItems; depthSortItems(sceneContext, renderContext, false, culledItems, sortedItems); // Sort Back to front transparent items! + renderedItems = sortedItems; RenderArgs* args = renderContext->args; gpu::Batch theBatch; args->_batch = &theBatch; - renderContext->args->_renderMode = RenderArgs::NORMAL_RENDER_MODE; + args->_renderMode = RenderArgs::NORMAL_RENDER_MODE; + + const float MOSTLY_OPAQUE_THRESHOLD = 0.75f; + const float TRANSPARENT_ALPHA_THRESHOLD = 0.0f; + + // render translucent meshes afterwards + { + GLenum buffers[2]; + int bufferCount = 0; + buffers[bufferCount++] = GL_COLOR_ATTACHMENT1; + buffers[bufferCount++] = GL_COLOR_ATTACHMENT2; + theBatch._glDrawBuffers(bufferCount, buffers); + args->_alphaThreshold = MOSTLY_OPAQUE_THRESHOLD; + } + + renderItems(sceneContext, renderContext, renderedItems); + { GLenum buffers[3]; int bufferCount = 0; buffers[bufferCount++] = GL_COLOR_ATTACHMENT0; theBatch._glDrawBuffers(bufferCount, buffers); + args->_alphaThreshold = TRANSPARENT_ALPHA_THRESHOLD; } - renderItems(sceneContext, renderContext, sortedItems); + + renderItems(sceneContext, renderContext, renderedItems); addClearStateCommands((*args->_batch)); args->_context->render((*args->_batch)); @@ -324,6 +350,7 @@ template <> void render::jobRun(const DrawTransparent& job, const SceneContextPo } template <> void render::jobRun(const DrawLight& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + PerformanceTimer perfTimer("DrawLight"); assert(renderContext->args); assert(renderContext->args->_viewFrustum); @@ -348,3 +375,26 @@ template <> void render::jobRun(const DrawLight& job, const SceneContextPointer& args->_context->render((*args->_batch)); args->_batch = nullptr; } + +template <> void render::jobRun(const DrawBackground& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + PerformanceTimer perfTimer("DrawBackground"); + assert(renderContext->args); + assert(renderContext->args->_viewFrustum); + + // render backgrounds + auto& scene = sceneContext->_scene; + auto& items = scene->getMasterBucket().at(ItemFilter::Builder::background()); + + + ItemIDs inItems; + inItems.reserve(items.size()); + for (auto id : items) { + inItems.push_back(id); + } + RenderArgs* args = renderContext->args; + gpu::Batch theBatch; + args->_batch = &theBatch; + renderItems(sceneContext, renderContext, inItems); + args->_context->render((*args->_batch)); + args->_batch = nullptr; +} diff --git a/libraries/render/src/render/DrawTask.h b/libraries/render/src/render/DrawTask.h index 78d4d1bd8b..d9213aca4a 100755 --- a/libraries/render/src/render/DrawTask.h +++ b/libraries/render/src/render/DrawTask.h @@ -78,6 +78,11 @@ public: }; template <> void jobRun(const DrawLight& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); +class DrawBackground { +public: +}; +template <> void jobRun(const DrawBackground& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); + class DrawSceneTask : public Task { public: diff --git a/libraries/render/src/render/Scene.cpp b/libraries/render/src/render/Scene.cpp index 93b8b4d7ef..8615f7cf7a 100644 --- a/libraries/render/src/render/Scene.cpp +++ b/libraries/render/src/render/Scene.cpp @@ -47,8 +47,8 @@ void ItemBucketMap::reset(const ItemID& id, const ItemKey& oldKey, const ItemKey void ItemBucketMap::allocateStandardOpaqueTranparentBuckets() { (*this)[ItemFilter::Builder::opaqueShape()]; (*this)[ItemFilter::Builder::transparentShape()]; - auto lightFilter = ItemFilter::Builder().withTypeLight().build(); - (*this)[lightFilter]; + (*this)[ItemFilter::Builder::light()]; + (*this)[ItemFilter::Builder::background()]; } diff --git a/libraries/render/src/render/Scene.h b/libraries/render/src/render/Scene.h index afacb25067..88ba2b478c 100644 --- a/libraries/render/src/render/Scene.h +++ b/libraries/render/src/render/Scene.h @@ -34,6 +34,7 @@ public: enum FlagBit { TYPE_SHAPE = 0, // Item is a Shape TYPE_LIGHT, // Item is a Light + TYPE_BACKGROUND, // Item is a Background TRANSLUCENT, // Transparent and not opaque, for some odd reason TRANSPARENCY doesn't work... VIEW_SPACE, // Transformed in view space, and not in world space DYNAMIC, // Dynamic and bound will change unlike static item @@ -62,6 +63,7 @@ public: Builder& withTypeShape() { _flags.set(TYPE_SHAPE); return (*this); } Builder& withTypeLight() { _flags.set(TYPE_LIGHT); return (*this); } + Builder& withTypeBackground() { _flags.set(TYPE_BACKGROUND); return (*this); } Builder& withTransparent() { _flags.set(TRANSLUCENT); return (*this); } Builder& withViewSpace() { _flags.set(VIEW_SPACE); return (*this); } Builder& withDynamic() { _flags.set(DYNAMIC); return (*this); } @@ -75,6 +77,7 @@ public: static ItemKey opaqueShape() { return Builder().withTypeShape().build(); } static ItemKey transparentShape() { return Builder().withTypeShape().withTransparent().build(); } static ItemKey light() { return Builder().withTypeLight().build(); } + static ItemKey background() { return Builder().withTypeBackground().build(); } }; bool isOpaque() const { return !_flags[TRANSLUCENT]; } @@ -126,6 +129,7 @@ public: Builder& withTypeShape() { _value.set(ItemKey::TYPE_SHAPE); _mask.set(ItemKey::TYPE_SHAPE); return (*this); } Builder& withTypeLight() { _value.set(ItemKey::TYPE_LIGHT); _mask.set(ItemKey::TYPE_LIGHT); return (*this); } + Builder& withTypeBackground() { _value.set(ItemKey::TYPE_BACKGROUND); _mask.set(ItemKey::TYPE_BACKGROUND); return (*this); } Builder& withOpaque() { _value.reset(ItemKey::TRANSLUCENT); _mask.set(ItemKey::TRANSLUCENT); return (*this); } Builder& withTransparent() { _value.set(ItemKey::TRANSLUCENT); _mask.set(ItemKey::TRANSLUCENT); return (*this); } @@ -154,6 +158,7 @@ public: static ItemFilter opaqueShape() { return Builder().withTypeShape().withOpaque().withWorldSpace().build(); } static ItemFilter transparentShape() { return Builder().withTypeShape().withTransparent().withWorldSpace().build(); } static ItemFilter light() { return Builder().withTypeLight().build(); } + static ItemFilter background() { return Builder().withTypeBackground().build(); } }; // Item Filter operator testing if a key pass the filter diff --git a/libraries/shared/src/RenderArgs.h b/libraries/shared/src/RenderArgs.h index e86389d705..08602dbacd 100644 --- a/libraries/shared/src/RenderArgs.h +++ b/libraries/shared/src/RenderArgs.h @@ -111,6 +111,8 @@ public: int _translucentMeshPartsRendered; int _opaqueMeshPartsRendered; + + float _alphaThreshold = 0.5f; }; #endif // hifi_RenderArgs_h