diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 7134860df0..a43d7806f0 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3635,10 +3635,15 @@ public: 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) { + 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) { Q_ASSERT(args->_batch); gpu::Batch& batch = *args->_batch; @@ -3646,20 +3651,18 @@ namespace render { auto skyStage = DependencyManager::get()->getSkyStage(); auto backgroundMode = skyStage->getBackgroundMode(); - if (backgroundMode == model::SunSkyStage::NO_BACKGROUND) { - // this line intentionally left blank - } else { - if (backgroundMode == model::SunSkyStage::SKY_BOX) { + switch (backgroundMode) { + case model::SunSkyStage::SKY_BOX: { auto skybox = skyStage->getSkybox(); if (skybox && skybox->getCubemap() && skybox->getCubemap()->isDefined()) { PerformanceTimer perfTimer("skybox"); skybox->render(batch, *(args->_viewFrustum)); - } else { - // If no skybox texture is available, render the SKY_DOME while it loads - backgroundMode = model::SunSkyStage::SKY_DOME; + break; } + // If no skybox texture is available, render the SKY_DOME while it loads } - if (backgroundMode == model::SunSkyStage::SKY_DOME) { + // fall through to next case + case model::SunSkyStage::SKY_DOME: { if (Menu::getInstance()->isOptionChecked(MenuOption::Stars)) { PerformanceTimer perfTimer("stars"); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), @@ -3725,6 +3728,11 @@ namespace render { } } + break; + case model::SunSkyStage::NO_BACKGROUND: + default: + // this line intentionally left blank + break; } } } diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 6beba4eefa..c3e012d412 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -23,7 +23,6 @@ #include #include #include -#include #include "EntityTreeRenderer.h" @@ -141,7 +140,7 @@ void EntityTreeRenderer::update() { // even if we haven't changed positions, if we previously attempted to set the skybox, but // have a pending download of the skybox texture, then we should attempt to reapply to // get the correct texture. - if (_pendingSkyboxTextureDownload) { + if (_pendingSkyboxTexture && _skyboxTexture && _skyboxTexture->isLoaded()) { applyZonePropertiesToScene(_bestZone); } @@ -254,94 +253,17 @@ void EntityTreeRenderer::forceRecheckEntities() { void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptr zone) { - QSharedPointer scene = DependencyManager::get(); + auto scene = DependencyManager::get(); auto sceneStage = scene->getStage(); + auto skyStage = scene->getSkyStage(); auto sceneKeyLight = sceneStage->getKeyLight(); auto sceneLocation = sceneStage->getLocation(); auto sceneTime = sceneStage->getTime(); + + if (!zone) { + _pendingSkyboxTexture = false; + _skyboxTexture.clear(); - if (zone) { - if (!_hasPreviousZone) { - _previousKeyLightColor = sceneKeyLight->getColor(); - _previousKeyLightIntensity = sceneKeyLight->getIntensity(); - _previousKeyLightAmbientIntensity = sceneKeyLight->getAmbientIntensity(); - _previousKeyLightDirection = sceneKeyLight->getDirection(); - _previousStageSunModelEnabled = sceneStage->isSunModelEnabled(); - _previousStageLongitude = sceneLocation->getLongitude(); - _previousStageLatitude = sceneLocation->getLatitude(); - _previousStageAltitude = sceneLocation->getAltitude(); - _previousStageHour = sceneTime->getHour(); - _previousStageDay = sceneTime->getDay(); - _hasPreviousZone = true; - } - sceneKeyLight->setColor(ColorUtils::toVec3(zone->getKeyLightProperties().getColor())); - sceneKeyLight->setIntensity(zone->getKeyLightProperties().getIntensity()); - sceneKeyLight->setAmbientIntensity(zone->getKeyLightProperties().getAmbientIntensity()); - sceneKeyLight->setDirection(zone->getKeyLightProperties().getDirection()); - sceneStage->setSunModelEnable(zone->getStageProperties().getSunModelEnabled()); - sceneStage->setLocation(zone->getStageProperties().getLongitude(), zone->getStageProperties().getLatitude(), - zone->getStageProperties().getAltitude()); - sceneTime->setHour(zone->getStageProperties().calculateHour()); - sceneTime->setDay(zone->getStageProperties().calculateDay()); - - if (zone->getBackgroundMode() == BACKGROUND_MODE_ATMOSPHERE) { - EnvironmentData data = zone->getEnvironmentData(); - glm::vec3 keyLightDirection = sceneKeyLight->getDirection(); - glm::vec3 inverseKeyLightDirection = keyLightDirection * -1.0f; - - // NOTE: is this right? It seems like the "sun" should be based on the center of the - // atmosphere, not where the camera is. - glm::vec3 keyLightLocation = _viewState->getAvatarPosition() - + (inverseKeyLightDirection * data.getAtmosphereOuterRadius()); - - data.setSunLocation(keyLightLocation); - - const float KEY_LIGHT_INTENSITY_TO_SUN_BRIGHTNESS_RATIO = 20.0f; - float sunBrightness = sceneKeyLight->getIntensity() * KEY_LIGHT_INTENSITY_TO_SUN_BRIGHTNESS_RATIO; - data.setSunBrightness(sunBrightness); - - _viewState->overrideEnvironmentData(data); - scene->getSkyStage()->setBackgroundMode(model::SunSkyStage::SKY_DOME); - _pendingSkyboxTextureDownload = false; - - } else { - _viewState->endOverrideEnvironmentData(); - auto stage = scene->getSkyStage(); - if (zone->getBackgroundMode() == BACKGROUND_MODE_SKYBOX) { - auto skybox = std::dynamic_pointer_cast(stage->getSkybox()); - skybox->setColor(zone->getSkyboxProperties().getColorVec3()); - static QString userData; - if (userData != zone->getUserData()) { - userData = zone->getUserData(); - ProceduralPointer procedural(new Procedural(userData)); - if (procedural->_enabled) { - skybox->setProcedural(procedural); - } else { - skybox->setProcedural(ProceduralPointer()); - } - } - if (zone->getSkyboxProperties().getURL().isEmpty()) { - skybox->setCubemap(gpu::TexturePointer()); - _pendingSkyboxTextureDownload = false; - } else { - // Update the Texture of the Skybox with the one pointed by this zone - auto cubeMap = DependencyManager::get()->getTexture(zone->getSkyboxProperties().getURL(), CUBE_TEXTURE); - - if (cubeMap->getGPUTexture()) { - skybox->setCubemap(cubeMap->getGPUTexture()); - _pendingSkyboxTextureDownload = false; - } else { - _pendingSkyboxTextureDownload = true; - } - } - stage->setBackgroundMode(model::SunSkyStage::SKY_BOX); - } else { - stage->setBackgroundMode(model::SunSkyStage::SKY_DOME); // let the application atmosphere through - _pendingSkyboxTextureDownload = false; - } - } - } else { - _pendingSkyboxTextureDownload = false; if (_hasPreviousZone) { sceneKeyLight->setColor(_previousKeyLightColor); sceneKeyLight->setIntensity(_previousKeyLightIntensity); @@ -354,14 +276,106 @@ void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptrsetDay(_previousStageDay); _hasPreviousZone = false; } + _viewState->endOverrideEnvironmentData(); - scene->getSkyStage()->setBackgroundMode(model::SunSkyStage::SKY_DOME); // let the application atmosphere through + skyStage->setBackgroundMode(model::SunSkyStage::SKY_DOME); // let the application atmosphere through + + return; // Early exit + } + + if (!_hasPreviousZone) { + _previousKeyLightColor = sceneKeyLight->getColor(); + _previousKeyLightIntensity = sceneKeyLight->getIntensity(); + _previousKeyLightAmbientIntensity = sceneKeyLight->getAmbientIntensity(); + _previousKeyLightDirection = sceneKeyLight->getDirection(); + _previousStageSunModelEnabled = sceneStage->isSunModelEnabled(); + _previousStageLongitude = sceneLocation->getLongitude(); + _previousStageLatitude = sceneLocation->getLatitude(); + _previousStageAltitude = sceneLocation->getAltitude(); + _previousStageHour = sceneTime->getHour(); + _previousStageDay = sceneTime->getDay(); + _hasPreviousZone = true; + } + + sceneKeyLight->setColor(ColorUtils::toVec3(zone->getKeyLightProperties().getColor())); + sceneKeyLight->setIntensity(zone->getKeyLightProperties().getIntensity()); + sceneKeyLight->setAmbientIntensity(zone->getKeyLightProperties().getAmbientIntensity()); + sceneKeyLight->setDirection(zone->getKeyLightProperties().getDirection()); + sceneStage->setSunModelEnable(zone->getStageProperties().getSunModelEnabled()); + sceneStage->setLocation(zone->getStageProperties().getLongitude(), zone->getStageProperties().getLatitude(), + zone->getStageProperties().getAltitude()); + sceneTime->setHour(zone->getStageProperties().calculateHour()); + sceneTime->setDay(zone->getStageProperties().calculateDay()); + + switch (zone->getBackgroundMode()) { + case BACKGROUND_MODE_ATMOSPHERE: { + EnvironmentData data = zone->getEnvironmentData(); + glm::vec3 keyLightDirection = sceneKeyLight->getDirection(); + glm::vec3 inverseKeyLightDirection = keyLightDirection * -1.0f; + + // NOTE: is this right? It seems like the "sun" should be based on the center of the + // atmosphere, not where the camera is. + glm::vec3 keyLightLocation = _viewState->getAvatarPosition() + + (inverseKeyLightDirection * data.getAtmosphereOuterRadius()); + + data.setSunLocation(keyLightLocation); + + const float KEY_LIGHT_INTENSITY_TO_SUN_BRIGHTNESS_RATIO = 20.0f; + float sunBrightness = sceneKeyLight->getIntensity() * KEY_LIGHT_INTENSITY_TO_SUN_BRIGHTNESS_RATIO; + data.setSunBrightness(sunBrightness); + + _viewState->overrideEnvironmentData(data); + skyStage->setBackgroundMode(model::SunSkyStage::SKY_DOME); + _pendingSkyboxTexture = false; + _skyboxTexture.clear(); + break; + } + case BACKGROUND_MODE_SKYBOX: { + auto skybox = std::dynamic_pointer_cast(skyStage->getSkybox()); + skybox->setColor(zone->getSkyboxProperties().getColorVec3()); + static QString userData; + if (userData != zone->getUserData()) { + userData = zone->getUserData(); + auto procedural = std::make_shared(userData); + if (procedural->_enabled) { + skybox->setProcedural(procedural); + } else { + skybox->setProcedural(ProceduralPointer()); + } + } + if (zone->getSkyboxProperties().getURL().isEmpty()) { + skybox->setCubemap(gpu::TexturePointer()); + _pendingSkyboxTexture = false; + _skyboxTexture.clear(); + } else { + // Update the Texture of the Skybox with the one pointed by this zone + auto textureCache = DependencyManager::get(); + _skyboxTexture = textureCache->getTexture(zone->getSkyboxProperties().getURL(), CUBE_TEXTURE); + + if (_skyboxTexture->getGPUTexture()) { + skybox->setCubemap(_skyboxTexture->getGPUTexture()); + _pendingSkyboxTexture = false; + } else { + _pendingSkyboxTexture = true; + } + } + + _viewState->endOverrideEnvironmentData(); + skyStage->setBackgroundMode(model::SunSkyStage::SKY_BOX); + break; + } + case BACKGROUND_MODE_INHERIT: + _viewState->endOverrideEnvironmentData(); + skyStage->setBackgroundMode(model::SunSkyStage::SKY_DOME); // let the application atmosphere through + _pendingSkyboxTexture = false; + _skyboxTexture.clear(); + break; } } const FBXGeometry* EntityTreeRenderer::getGeometryForEntity(EntityItemPointer entityItem) { const FBXGeometry* result = NULL; - + if (entityItem->getType() == EntityTypes::Model) { std::shared_ptr modelEntityItem = std::dynamic_pointer_cast(entityItem); diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index e2cd4fc2dd..09fe7a527c 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -15,12 +15,13 @@ #include #include -#include +#include #include // for RayToEntityIntersectionResult +#include #include #include #include -#include +#include class AbstractScriptingServicesInterface; class AbstractViewStateInterface; @@ -142,9 +143,11 @@ private: void forceRecheckEntities(); glm::vec3 _lastAvatarPosition; - bool _pendingSkyboxTextureDownload = false; QVector _currentEntitiesInside; - + + bool _pendingSkyboxTexture { false }; + NetworkTexturePointer _skyboxTexture; + bool _wantScripts; ScriptEngine* _entitiesScriptEngine; @@ -161,11 +164,11 @@ private: bool _displayModelBounds; bool _dontDoPrecisionPicking; - bool _shuttingDown = false; + bool _shuttingDown { false }; QMultiMap _waitingOnPreload; - bool _hasPreviousZone = false; + bool _hasPreviousZone { false }; std::shared_ptr _bestZone; float _bestZoneVolume; diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index 1d436851d7..0bec7636b9 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -147,7 +147,6 @@ void NetworkGeometry::setTextureWithNameToURL(const QString& name, const QUrl& u if (_meshes.size() > 0) { auto textureCache = DependencyManager::get(); for (auto&& material : _materials) { - QSharedPointer matchingTexture = QSharedPointer(); if (material->diffuseTextureName == name) { material->diffuseTexture = textureCache->getTexture(url, DEFAULT_TEXTURE); } else if (material->normalTextureName == name) { diff --git a/libraries/model-networking/src/model-networking/TextureCache.cpp b/libraries/model-networking/src/model-networking/TextureCache.cpp index ae705faf86..60f6d50d59 100644 --- a/libraries/model-networking/src/model-networking/TextureCache.cpp +++ b/libraries/model-networking/src/model-networking/TextureCache.cpp @@ -72,11 +72,12 @@ const gpu::TexturePointer& TextureCache::getPermutationNormalTexture() { data[3*i+0] = permutation[i]; data[3*i+1] = permutation[i]; data[3*i+2] = permutation[i]; + } #else for (int i = 0; i < 256 * 3; i++) { data[i] = rand() % 256; -#endif } +#endif for (int i = 256 * 3; i < 256 * 3 * 2; i += 3) { glm::vec3 randvec = glm::sphericalRand(1.0f); @@ -173,19 +174,11 @@ QSharedPointer TextureCache::createResource(const QUrl& url, &Resource::allReferencesCleared); } -Texture::Texture() { -} - -Texture::~Texture() { -} - NetworkTexture::NetworkTexture(const QUrl& url, TextureType type, const QByteArray& content) : Resource(url, !content.isEmpty()), - _type(type), - _width(0), - _height(0) { - - _textureSource.reset(new gpu::TextureSource()); + _type(type) +{ + _textureSource = std::make_shared(); if (!url.isValid()) { _loaded = true; @@ -200,24 +193,9 @@ NetworkTexture::NetworkTexture(const QUrl& url, TextureType type, const QByteArr } NetworkTexture::NetworkTexture(const QUrl& url, const TextureLoaderFunc& textureLoader, const QByteArray& content) : - Resource(url, !content.isEmpty()), - _type(CUSTOM_TEXTURE), - _textureLoader(textureLoader), - _width(0), - _height(0) { - - _textureSource.reset(new gpu::TextureSource()); - - if (!url.isValid()) { - _loaded = true; - } - - std::string theName = url.toString().toStdString(); - // if we have content, load it after we have our self pointer - if (!content.isEmpty()) { - _startedLoading = true; - QMetaObject::invokeMethod(this, "loadContent", Qt::QueuedConnection, Q_ARG(const QByteArray&, content)); - } + NetworkTexture(url, CUSTOM_TEXTURE, content) +{ + _textureLoader = textureLoader; } NetworkTexture::TextureLoaderFunc NetworkTexture::getTextureLoader() const { @@ -247,57 +225,52 @@ NetworkTexture::TextureLoaderFunc NetworkTexture::getTextureLoader() const { } } } - + class ImageReader : public QRunnable { public: - ImageReader(const QWeakPointer& texture, const NetworkTexture::TextureLoaderFunc& textureLoader, const QByteArray& data, const QUrl& url = QUrl()); - + ImageReader(const QWeakPointer& texture, const QByteArray& data, const QUrl& url = QUrl()); + virtual void run(); private: - + static void listSupportedImageFormats(); + QWeakPointer _texture; - NetworkTexture::TextureLoaderFunc _textureLoader; QUrl _url; QByteArray _content; }; void NetworkTexture::downloadFinished(const QByteArray& data) { // send the reader off to the thread pool - QThreadPool::globalInstance()->start(new ImageReader(_self, getTextureLoader(), data, _url)); + QThreadPool::globalInstance()->start(new ImageReader(_self, data, _url)); } void NetworkTexture::loadContent(const QByteArray& content) { - QThreadPool::globalInstance()->start(new ImageReader(_self, getTextureLoader(), content, _url)); + QThreadPool::globalInstance()->start(new ImageReader(_self, content, _url)); } -ImageReader::ImageReader(const QWeakPointer& texture, const NetworkTexture::TextureLoaderFunc& textureLoader, const QByteArray& data, +ImageReader::ImageReader(const QWeakPointer& texture, const QByteArray& data, const QUrl& url) : _texture(texture), - _textureLoader(textureLoader), _url(url), _content(data) { - } -std::once_flag onceListSupportedFormatsflag; -void listSupportedImageFormats() { - std::call_once(onceListSupportedFormatsflag, [](){ +void ImageReader::listSupportedImageFormats() { + static std::once_flag once; + std::call_once(once, []{ auto supportedFormats = QImageReader::supportedImageFormats(); - QString formats; - foreach(const QByteArray& f, supportedFormats) { - formats += QString(f) + ","; - } - qCDebug(modelnetworking) << "List of supported Image formats:" << formats; + qCDebug(modelnetworking) << "List of supported Image formats:" << supportedFormats.join(", "); }); } void ImageReader::run() { - QSharedPointer texture = _texture.toStrongRef(); - if (texture.isNull()) { + auto texture = _texture.toStrongRef(); + if (!texture) { + qCWarning(modelnetworking) << "Could not get strong ref"; return; } @@ -324,7 +297,7 @@ void ImageReader::run() { } gpu::Texture* theTexture = nullptr; - auto ntex = dynamic_cast(&*texture); + auto ntex = texture.dynamicCast(); if (ntex) { theTexture = ntex->getTextureLoader()(image, _url.toString().toStdString()); } @@ -333,8 +306,6 @@ void ImageReader::run() { Q_ARG(const QImage&, image), Q_ARG(void*, theTexture), Q_ARG(int, originalWidth), Q_ARG(int, originalHeight)); - - } void NetworkTexture::setImage(const QImage& image, void* voidTexture, int originalWidth, diff --git a/libraries/model-networking/src/model-networking/TextureCache.h b/libraries/model-networking/src/model-networking/TextureCache.h index 4171b6c1cb..033b4bede6 100644 --- a/libraries/model-networking/src/model-networking/TextureCache.h +++ b/libraries/model-networking/src/model-networking/TextureCache.h @@ -67,9 +67,6 @@ public: typedef gpu::Texture* TextureLoader(const QImage& image, const std::string& srcImageName); typedef std::function TextureLoaderFunc; - - NetworkTexturePointer getTexture(const QUrl& url, const TextureLoaderFunc& textureLoader, - const QByteArray& content = QByteArray()); protected: virtual QSharedPointer createResource(const QUrl& url, @@ -94,15 +91,9 @@ private: class Texture { public: friend class TextureCache; - Texture(); - ~Texture(); - const gpu::TexturePointer getGPUTexture() const { return _textureSource->getGPUTexture(); } + gpu::TexturePointer getGPUTexture() const { return _textureSource->getGPUTexture(); } gpu::TextureSourcePointer _textureSource; - -protected: - -private: }; /// A texture loaded from the network. @@ -134,14 +125,14 @@ protected: virtual void imageLoaded(const QImage& image); - TextureType _type; private: + TextureType _type; TextureLoaderFunc _textureLoader; - int _originalWidth; - int _originalHeight; - int _width; - int _height; + int _originalWidth { 0 }; + int _originalHeight { 0 }; + int _width { 0 }; + int _height { 0 }; }; #endif // hifi_TextureCache_h