diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index 8ce1a2ef9a..7e78837345 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -24,6 +24,8 @@ #include "RenderableEntityItem.h" #include +#include "DeferredLightingEffect.h" + // Sphere entities should fit inside a cube entity of the same size, so a sphere that has dimensions 1x1x1 @@ -73,6 +75,7 @@ void RenderableZoneEntityItem::somethingChangedNotification() { // If graphics elements are changed, we need to update the render items if (_keyLightPropertiesChanged || _backgroundPropertiesChanged || _stagePropertiesChanged || _skyboxPropertiesChanged) { + notifyChangedRenderItem(); } @@ -120,6 +123,52 @@ void RenderableZoneEntityItem::updateGeometry() { } } +void RenderableZoneEntityItem::updateTextures() { + auto textureCache = DependencyManager::get(); + bool isAmbientSet = false; + if (_pendingAmbientTexture && !_ambientTexture) { + _ambientTexture = textureCache->getTexture(_ambientTextureURL, image::TextureUsage::CUBE_TEXTURE); + } + if (_ambientTexture && _ambientTexture->isLoaded()) { + _pendingAmbientTexture = false; + + auto texture = _ambientTexture->getGPUTexture(); + if (texture) { + isAmbientSet = true; + } else { + qCDebug(entitiesrenderer) << "Failed to load ambient texture:" << _ambientTexture->getURL(); + } + } + + if (_pendingSkyboxTexture && + (!_skyboxTexture || (_skyboxTexture->getURL() != _skyboxTextureURL))) { + _skyboxTexture = textureCache->getTexture(_skyboxTextureURL, image::TextureUsage::CUBE_TEXTURE); + } + if (_skyboxTexture && _skyboxTexture->isLoaded()) { + _pendingSkyboxTexture = false; + + auto texture = _skyboxTexture->getGPUTexture(); + if (texture) { + // skybox->setCubemap(texture); + if (!isAmbientSet) { + // sceneKeyLight->setAmbientSphere(texture->getIrradiance()); + // sceneKeyLight->setAmbientMap(texture); + isAmbientSet = true; + } + } else { + qCDebug(entitiesrenderer) << "Failed to load skybox texture:" << _skyboxTexture->getURL(); + } + } else { + // skybox->setCubemap(nullptr); + } + + if (!isAmbientSet) { + // sceneKeyLight->resetAmbientSphere(); + // sceneKeyLight->setAmbientMap(nullptr); + } + +} + void RenderableZoneEntityItem::render(RenderArgs* args) { Q_ASSERT(getType() == EntityTypes::Zone); @@ -235,6 +284,23 @@ public: typedef Payload::DataPointer Pointer; EntityItemPointer entity; + + 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; } + + + model::LightPointer _light; + render::Item::Bound _bound; + LightStagePointer _stage; + LightStage::Index _index { LightStage::INVALID_INDEX }; + bool _needUpdate { true }; + bool _isVisible { true }; + }; namespace render { @@ -254,11 +320,7 @@ namespace render { return render::Item::Bound(); } template <> void payloadRender(const RenderableZoneEntityItemMeta::Pointer& payload, RenderArgs* args) { - if (args) { - if (payload && payload->entity) { - payload->entity->render(args); - } - } + payload->render(args); } } @@ -318,19 +380,20 @@ void RenderableZoneEntityItem::notifyBoundChanged() { } } -void RenderableZoneEntityItem::updateKeyLightItemFromEntity(KeyLightPayload& keylightPayload) { + +void RenderableZoneEntityItem::updateKeyZoneItemFromEntity(RenderableZoneEntityItemMeta& keyZonePayload) { auto entity = this; - keylightPayload.setVisible(entity->getVisible()); + keyZonePayload.setVisible(entity->getVisible()); - auto light = keylightPayload.editLight(); + auto light = keyZonePayload.editLight(); light->setPosition(entity->getPosition()); light->setOrientation(entity->getRotation()); bool success; - keylightPayload.editBound() = entity->getAABox(success); + keyZonePayload.editBound() = entity->getAABox(success); if (!success) { - keylightPayload.editBound() = render::Item::Bound(); + keyZonePayload.editBound() = render::Item::Bound(); } // Set the keylight @@ -340,8 +403,14 @@ void RenderableZoneEntityItem::updateKeyLightItemFromEntity(KeyLightPayload& key light->setDirection(this->getKeyLightProperties().getDirection()); light->setType(model::Light::SUN); + + } +void RenderableZoneEntityItem::updateKeyLightItemFromEntity(KeyLightPayload& keylightPayload) { +} + + void RenderableZoneEntityItem::sceneUpdateRenderItemFromEntity(render::Transaction& transaction) { if (!render::Item::isValidID(_myKeyLightItem)) { return; @@ -361,4 +430,35 @@ void RenderableZoneEntityItem::notifyChangedRenderItem() { render::ScenePointer scene = AbstractViewStateInterface::instance()->getMain3DScene(); sceneUpdateRenderItemFromEntity(transaction); scene->enqueueTransaction(transaction); -} \ No newline at end of file +} + +void RenderableZoneEntityItemMeta::render(RenderArgs* args) { + entity->render(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/entities-renderer/src/RenderableZoneEntityItem.h b/libraries/entities-renderer/src/RenderableZoneEntityItem.h index 1f3132746c..79641682cf 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.h +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.h @@ -18,6 +18,8 @@ class NetworkGeometry; class KeyLightPayload; +class RenderableZoneEntityItemMeta; + class RenderableZoneEntityItem : public ZoneEntityItem { public: static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties); @@ -52,21 +54,34 @@ private: Model* getModel(); void initialSimulation(); void updateGeometry(); + + void updateTextures(); template void changeProperties(Lambda functor); void notifyChangedRenderItem(); void sceneUpdateRenderItemFromEntity(render::Transaction& transaction); - void updateKeyLightItemFromEntity(KeyLightPayload& keylightPayload); + void updateKeyZoneItemFromEntity(RenderableZoneEntityItemMeta& keyZonePayload); + void updateKeyLightItemFromEntity(KeyLightPayload& keyLightPayload); - Model* _model; bool _needsInitialSimulation; - + render::ItemID _myMetaItem{ render::Item::INVALID_ITEM_ID }; render::ItemID _myKeyLightItem { render::Item::INVALID_ITEM_ID }; + + + // More attributes used for rendering: + NetworkTexturePointer _ambientTexture; + NetworkTexturePointer _skyboxTexture; + QString _ambientTextureURL; + QString _skyboxTextureURL; + bool _pendingAmbientTexture { false }; + bool _pendingSkyboxTexture { false }; + bool _validAmbientTextureURL { false }; + bool _validSkyboxTextureURL { false }; }; #endif // hifi_RenderableZoneEntityItem_h diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 93a176f4f3..3dd5ed0352 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -143,53 +143,12 @@ void DeferredLightingEffect::init() { } -void DeferredLightingEffect::addLight(const model::LightPointer& light) { - assert(light); - auto lightID = _lightStage->addLight(light); - if (light->getType() == model::Light::POINT) { - _pointLights.push_back(lightID); - } else { - _spotLights.push_back(lightID); - } -} - - -void DeferredLightingEffect::addPointLight(const glm::vec3& position, float radius, const glm::vec3& color, - float intensity, float falloffRadius) { - addSpotLight(position, radius, color, intensity, falloffRadius); -} - -void DeferredLightingEffect::addSpotLight(const glm::vec3& position, float radius, const glm::vec3& color, - float intensity, float falloffRadius, const glm::quat& orientation, float exponent, float cutoff) { - - unsigned int lightID = (unsigned int)(_pointLights.size() + _spotLights.size() + _globalLights.size()); - if (lightID >= _allocatedLights.size()) { - _allocatedLights.push_back(std::make_shared()); - } - model::LightPointer lp = _allocatedLights[lightID]; - - lp->setPosition(position); - lp->setMaximumRadius(radius); - lp->setColor(color); - lp->setIntensity(intensity); - lp->setFalloffRadius(falloffRadius); - - if (exponent == 0.0f && cutoff == PI) { - lp->setType(model::Light::POINT); - _pointLights.push_back(lightID); - - } else { - lp->setOrientation(orientation); - lp->setSpotAngle(cutoff); - lp->setSpotExponent(exponent); - lp->setType(model::Light::SPOT); - _spotLights.push_back(lightID); - } -} - void DeferredLightingEffect::setupKeyLightBatch(gpu::Batch& batch, int lightBufferUnit, int ambientBufferUnit, int skyboxCubemapUnit) { PerformanceTimer perfTimer("DLE->setupBatch()"); auto keyLight = _allocatedLights[_globalLights.front()]; + if (_lightStage && _lightStage->_currentFrame._sunLights.size()) { + keyLight = _lightStage->getLight(_lightStage->_currentFrame._sunLights.front()); + } if (lightBufferUnit >= 0) { batch.setUniformBuffer(lightBufferUnit, keyLight->getLightSchemaBuffer()); @@ -772,16 +731,6 @@ void RenderDeferredCleanup::run(const render::RenderContextPointer& renderContex batch.setUniformBuffer(LIGHT_CLUSTER_GRID_CLUSTER_CONTENT_SLOT, nullptr); } - - auto deferredLightingEffect = DependencyManager::get(); - - // End of the Lighting pass - if (!deferredLightingEffect->_pointLights.empty()) { - deferredLightingEffect->_pointLights.clear(); - } - if (!deferredLightingEffect->_spotLights.empty()) { - deferredLightingEffect->_spotLights.clear(); - } } RenderDeferred::RenderDeferred() { diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index dcf0c84622..ad3dcc9061 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -43,18 +43,7 @@ class DeferredLightingEffect : public Dependency { public: void init(); - - void addLight(const model::LightPointer& light); - - /// Adds a point light to render for the current frame. - void addPointLight(const glm::vec3& position, float radius, const glm::vec3& color = glm::vec3(0.0f, 0.0f, 0.0f), - float intensity = 0.5f, float falloffRadius = 0.01f); - - /// Adds a spot light to render for the current frame. - void addSpotLight(const glm::vec3& position, float radius, const glm::vec3& color = glm::vec3(1.0f, 1.0f, 1.0f), - float intensity = 0.5f, float falloffRadius = 0.01f, - const glm::quat& orientation = glm::quat(), float exponent = 0.0f, float cutoff = PI); - + void setupKeyLightBatch(gpu::Batch& batch, int lightBufferUnit, int ambientBufferUnit, int skyboxCubemapUnit); void unsetKeyLightBatch(gpu::Batch& batch, int lightBufferUnit, int ambientBufferUnit, int skyboxCubemapUnit); @@ -113,8 +102,6 @@ private: Lights _allocatedLights; std::vector _globalLights; - std::vector _pointLights; - std::vector _spotLights; friend class LightClusteringPass; friend class RenderDeferredSetup; diff --git a/libraries/render-utils/src/LightPayload.h b/libraries/render-utils/src/LightPayload.h index 6a1435e12b..0cf8f8e2de 100644 --- a/libraries/render-utils/src/LightPayload.h +++ b/libraries/render-utils/src/LightPayload.h @@ -15,6 +15,7 @@ #include #include #include "LightStage.h" +#include "TextureCache.h" class LightPayload { public: @@ -61,6 +62,13 @@ public: void setVisible(bool visible) { _isVisible = visible; } bool isVisible() const { return _isVisible; } + + // More attributes used for rendering: + NetworkTexturePointer _ambientTexture; + QString _ambientTextureURL; + bool _pendingAmbientTexture { false }; + bool _validAmbientTextureURL { false }; + protected: model::LightPointer _light; render::Item::Bound _bound; diff --git a/libraries/render-utils/src/LightStage.h b/libraries/render-utils/src/LightStage.h index c38ca404ce..8da05ec052 100644 --- a/libraries/render-utils/src/LightStage.h +++ b/libraries/render-utils/src/LightStage.h @@ -118,7 +118,7 @@ public: public: Frame() {} - void clear() { _pointLights.clear(); _spotLights.clear(); } + void clear() { _pointLights.clear(); _spotLights.clear(); _sunLights.clear(); } void pushLight(LightStage::Index index, model::Light::Type type) { switch (type) { case model::Light::POINT: { pushPointLight(index); break; }