From 64317f5fd097996d67781b3b0e162b583b03b01f Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 4 May 2017 16:47:03 -0700 Subject: [PATCH] Adding a light item per zone --- .../src/RenderableZoneEntityItem.cpp | 84 ++++++++++++++++++- .../src/RenderableZoneEntityItem.h | 9 +- libraries/render-utils/src/LightPayload.cpp | 68 +++++++++++++++ libraries/render-utils/src/LightPayload.h | 30 +++++++ libraries/render-utils/src/LightStage.h | 5 +- .../render-utils/src/RenderDeferredTask.cpp | 1 + .../utilities/render/deferredLighting.qml | 5 ++ 7 files changed, 198 insertions(+), 4 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index 66495a7054..de7b943a92 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -21,6 +21,9 @@ #include "EntityTreeRenderer.h" #include "RenderableEntityItem.h" +#include + + // Sphere entities should fit inside a cube entity of the same size, so a sphere that has dimensions 1x1x1 // is a half unit sphere. However, the geometry cache renders a UNIT sphere, so we need to scale down. static const float SPHERE_ENTITY_SCALE = 0.5f; @@ -168,6 +171,37 @@ void RenderableZoneEntityItem::render(RenderArgs* args) { _model->removeFromScene(scene, transaction); scene->enqueueTransaction(transaction); } + + /* + { + // Set the keylight + sceneKeyLight->setColor(ColorUtils::toVec3(this->getKeyLightProperties().getColor())); + sceneKeyLight->setIntensity(this->getKeyLightProperties().getIntensity()); + sceneKeyLight->setAmbientIntensity(this->getKeyLightProperties().getAmbientIntensity()); + sceneKeyLight->setDirection(this->getKeyLightProperties().getDirection()); + + // Set the stage + bool isSunModelEnabled = this->getStageProperties().getSunModelEnabled(); + sceneStage->setSunModelEnable(isSunModelEnabled); + if (isSunModelEnabled) { + sceneStage->setLocation(this->getStageProperties().getLongitude(), + this->getStageProperties().getLatitude(), + this->getStageProperties().getAltitude()); + + auto sceneTime = sceneStage->getTime(); + sceneTime->setHour(this->getStageProperties().calculateHour()); + sceneTime->setDay(this->getStageProperties().calculateDay()); + } + + // Set the ambient texture + _ambientTextureURL = this->getKeyLightProperties().getAmbientURL(); + if (_ambientTextureURL.isEmpty()) { + _pendingAmbientTexture = false; + _ambientTexture.clear(); + } else { + _pendingAmbientTexture = true; + } + }*/ } bool RenderableZoneEntityItem::contains(const glm::vec3& point) const { @@ -229,11 +263,25 @@ bool RenderableZoneEntityItem::addToScene(EntityItemPointer self, const render:: renderPayload->addStatusGetters(statusGetters); transaction.resetItem(_myMetaItem, renderPayload); + + + _myKeyLightItem = scene->allocateID(); + + auto keyLightPayload = std::make_shared(); + updateKeyLightItemFromEntity((*keyLightPayload)); + + auto keyLightItem = std::make_shared(keyLightPayload); + + transaction.resetItem(_myKeyLightItem, keyLightItem); + + return true; } void RenderableZoneEntityItem::removeFromScene(EntityItemPointer self, const render::ScenePointer& scene, render::Transaction& transaction) { + transaction.removeItem(_myKeyLightItem); + render::Item::clearID(_myKeyLightItem); transaction.removeItem(_myMetaItem); render::Item::clearID(_myMetaItem); if (_model) { @@ -249,11 +297,43 @@ void RenderableZoneEntityItem::notifyBoundChanged() { render::Transaction transaction; render::ScenePointer scene = AbstractViewStateInterface::instance()->getMain3DScene(); if (scene) { - transaction.updateItem(_myMetaItem, [](RenderableZoneEntityItemMeta& data) { - }); + transaction.updateItem(_myMetaItem, [](RenderableZoneEntityItemMeta& data) {}); + transaction.updateItem(_myKeyLightItem, [](KeyLightPayload& data) {}); scene->enqueueTransaction(transaction); } else { qCWarning(entitiesrenderer) << "RenderableZoneEntityItem::notifyBoundChanged(), Unexpected null scene, possibly during application shutdown"; } } + +void RenderableZoneEntityItem::updateKeyLightItemFromEntity(KeyLightPayload& keylightPayload) { + auto entity = this; + + keylightPayload.setVisible(entity->getVisible()); + + auto light = keylightPayload.editLight(); + light->setPosition(entity->getPosition()); + light->setOrientation(entity->getRotation()); + + bool success; + keylightPayload.editBound() = entity->getAABox(success); + if (!success) { + keylightPayload.editBound() = render::Item::Bound(); + } + + // Set the keylight + light->setColor(ColorUtils::toVec3(this->getKeyLightProperties().getColor())); + light->setIntensity(this->getKeyLightProperties().getIntensity()); + light->setAmbientIntensity(this->getKeyLightProperties().getAmbientIntensity()); + light->setDirection(this->getKeyLightProperties().getDirection()); + + + // light->setColor(toGlm(entity->getXColor())); + + // float intensity = entity->getIntensity();//* entity->getFadingRatio(); + // light->setIntensity(intensity); + + + light->setType(model::Light::SUN); + +} diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.h b/libraries/entities-renderer/src/RenderableZoneEntityItem.h index c81afdab08..d90993145e 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.h +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.h @@ -16,6 +16,7 @@ #include class NetworkGeometry; +class KeyLightPayload; class RenderableZoneEntityItem : public ZoneEntityItem { public: @@ -42,7 +43,7 @@ public: virtual void removeFromScene(EntityItemPointer self, const render::ScenePointer& scene, render::Transaction& transaction) override; render::ItemID getRenderItemID() const { return _myMetaItem; } - + private: virtual void locationChanged(bool tellPhysics = true) override { EntityItem::locationChanged(tellPhysics); notifyBoundChanged(); } virtual void dimensionsChanged() override { EntityItem::dimensionsChanged(); notifyBoundChanged(); } @@ -54,11 +55,17 @@ private: template void changeProperties(Lambda functor); + + + void updateKeyLightItemFromEntity(KeyLightPayload& keylightPayload); + Model* _model; bool _needsInitialSimulation; render::ItemID _myMetaItem{ render::Item::INVALID_ITEM_ID }; + + render::ItemID _myKeyLightItem { render::Item::INVALID_ITEM_ID }; }; #endif // hifi_RenderableZoneEntityItem_h diff --git a/libraries/render-utils/src/LightPayload.cpp b/libraries/render-utils/src/LightPayload.cpp index a670c9f620..dbdf7129ef 100644 --- a/libraries/render-utils/src/LightPayload.cpp +++ b/libraries/render-utils/src/LightPayload.cpp @@ -81,3 +81,71 @@ void LightPayload::render(RenderArgs* args) { } } + +namespace render { + template <> const ItemKey payloadGetKey(const KeyLightPayload::Pointer& payload) { + ItemKey::Builder builder; + builder.withTypeLight(); + if (!payload || !payload->isVisible()) { + builder.withInvisible(); + } + return builder.build(); + } + + template <> const Item::Bound payloadGetBound(const KeyLightPayload::Pointer& payload) { + if (payload) { + return payload->editBound(); + } + return render::Item::Bound(); + } + template <> void payloadRender(const KeyLightPayload::Pointer& payload, RenderArgs* args) { + if (args) { + if (payload) { + payload->render(args); + } + } + } +} + +KeyLightPayload::KeyLightPayload() : +_light(std::make_shared()) +{ +} + + +KeyLightPayload::~KeyLightPayload() { + if (!LightStage::isIndexInvalid(_index)) { + if (_stage) { + _stage->removeLight(_index); + } + } +} + +void KeyLightPayload::render(RenderArgs* args) { + if (!_stage) { + _stage = DependencyManager::get()->getLightStage(); + } + // Do we need to allocate the light in the stage ? + if (LightStage::isIndexInvalid(_index)) { + _index = _stage->addLight(_light); + _needUpdate = false; + } + // Need an update ? + if (_needUpdate) { + _stage->updateLightArrayBuffer(_index); + _needUpdate = false; + } + + if (isVisible()) { + // FInally, push the light visible in the frame + _stage->_currentFrame.pushLight(_index, _light->getType()); + +#ifdef WANT_DEBUG + Q_ASSERT(args->_batch); + gpu::Batch& batch = *args->_batch; + batch.setModelTransform(getTransformToCenter()); + DependencyManager::get()->renderWireSphere(batch, 0.5f, 15, 15, glm::vec4(color, 1.0f)); +#endif + } +} + diff --git a/libraries/render-utils/src/LightPayload.h b/libraries/render-utils/src/LightPayload.h index 6b5fe83f07..6a1435e12b 100644 --- a/libraries/render-utils/src/LightPayload.h +++ b/libraries/render-utils/src/LightPayload.h @@ -46,4 +46,34 @@ namespace render { template <> void payloadRender(const LightPayload::Pointer& payload, RenderArgs* args); } +class KeyLightPayload { +public: + using Payload = render::Payload; + using Pointer = Payload::DataPointer; + + KeyLightPayload(); + ~KeyLightPayload(); + void render(RenderArgs* args); + + model::LightPointer editLight() { _needUpdate = true; return _light; } + render::Item::Bound& editBound() { _needUpdate = true; return _bound; } + + void setVisible(bool visible) { _isVisible = visible; } + bool isVisible() const { return _isVisible; } + +protected: + model::LightPointer _light; + render::Item::Bound _bound; + LightStagePointer _stage; + LightStage::Index _index { LightStage::INVALID_INDEX }; + bool _needUpdate { true }; + bool _isVisible { true }; +}; + +namespace render { + template <> const ItemKey payloadGetKey(const KeyLightPayload::Pointer& payload); + template <> const Item::Bound payloadGetBound(const KeyLightPayload::Pointer& payload); + template <> void payloadRender(const KeyLightPayload::Pointer& payload, RenderArgs* args); +} + #endif \ No newline at end of file diff --git a/libraries/render-utils/src/LightStage.h b/libraries/render-utils/src/LightStage.h index c2293ac099..c38ca404ce 100644 --- a/libraries/render-utils/src/LightStage.h +++ b/libraries/render-utils/src/LightStage.h @@ -123,14 +123,17 @@ public: switch (type) { case model::Light::POINT: { pushPointLight(index); break; } case model::Light::SPOT: { pushSpotLight(index); break; } + case model::Light::SUN: { pushSunLight(index); break; } default: { break; } } } void pushPointLight(LightStage::Index index) { _pointLights.emplace_back(index); } void pushSpotLight(LightStage::Index index) { _spotLights.emplace_back(index); } - + void pushSunLight(LightStage::Index index) { _sunLights.emplace_back(index); } + LightStage::LightIndices _pointLights; LightStage::LightIndices _spotLights; + LightStage::LightIndices _sunLights; }; Frame _currentFrame; diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 313b176f19..6367093cb4 100644 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -162,6 +162,7 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren task.addJob("DrawOpaqueBounds", opaques); task.addJob("DrawTransparentBounds", transparents); + task.addJob("DrawLightBounds", lights); task.addJob("ZoneRenderer", opaques); } diff --git a/scripts/developer/utilities/render/deferredLighting.qml b/scripts/developer/utilities/render/deferredLighting.qml index 229a2d1c3b..c1d8da3db1 100644 --- a/scripts/developer/utilities/render/deferredLighting.qml +++ b/scripts/developer/utilities/render/deferredLighting.qml @@ -189,6 +189,11 @@ Column { checked: Render.getConfig("DrawOverlayTransparentBounds")["enabled"] onCheckedChanged: { Render.getConfig("DrawOverlayTransparentBounds")["enabled"] = checked } } + CheckBox { + text: "Lights" + checked: Render.getConfig("DrawLightBounds")["enabled"] + onCheckedChanged: { Render.getConfig("DrawLightBounds")["enabled"] = checked; } + } CheckBox { text: "Zones" checked: Render.getConfig("DrawZones")["enabled"]