diff --git a/cmake/compiler.cmake b/cmake/compiler.cmake index 6ff6fce1d8..e68b2ec9b0 100644 --- a/cmake/compiler.cmake +++ b/cmake/compiler.cmake @@ -88,7 +88,7 @@ if (APPLE) set(OSX_SDK "${OSX_VERSION}" CACHE String "OS X SDK version to look for inside Xcode bundle or at OSX_SDK_PATH") # set our OS X deployment target - set(CMAKE_OSX_DEPLOYMENT_TARGET 10.8) + set(CMAKE_OSX_DEPLOYMENT_TARGET 10.9) # find the SDK path for the desired SDK find_path( diff --git a/cmake/externals/quazip/CMakeLists.txt b/cmake/externals/quazip/CMakeLists.txt index 6960f7682a..7a13720f35 100644 --- a/cmake/externals/quazip/CMakeLists.txt +++ b/cmake/externals/quazip/CMakeLists.txt @@ -1,14 +1,12 @@ set(EXTERNAL_NAME quazip) string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) -cmake_policy(SET CMP0046 OLD) include(ExternalProject) set(QUAZIP_CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH= -DCMAKE_PREFIX_PATH=${QT_CMAKE_PREFIX_PATH} -DCMAKE_INSTALL_NAME_DIR:PATH=/lib -DZLIB_ROOT=${ZLIB_ROOT} -DCMAKE_POSITION_INDEPENDENT_CODE=ON) -if (APPLE) -else () - set(QUAZIP_CMAKE_ARGS ${QUAZIP_CMAKE_ARGS} -DCMAKE_CXX_STANDARD=11) +if (NOT APPLE) + set(QUAZIP_CMAKE_ARGS ${QUAZIP_CMAKE_ARGS} -DCMAKE_CXX_STANDARD=11) endif () ExternalProject_Add( @@ -22,10 +20,12 @@ ExternalProject_Add( LOG_BUILD 1 ) -add_dependencies(quazip zlib) +if (WIN32) + add_dependencies(quazip zlib) +endif () # Hide this external target (for ide users) -set_target_properties(${EXTERNAL_NAME} PROPERTIES +set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals" INSTALL_NAME_DIR ${INSTALL_DIR}/lib BUILD_WITH_INSTALL_RPATH True) @@ -54,4 +54,4 @@ select_library_configurations(${EXTERNAL_NAME_UPPER}) # Force selected libraries into the cache set(${EXTERNAL_NAME_UPPER}_LIBRARY ${${EXTERNAL_NAME_UPPER}_LIBRARY} CACHE FILEPATH "Location of QuaZip libraries") -set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${${EXTERNAL_NAME_UPPER}_LIBRARIES} CACHE FILEPATH "Location of QuaZip libraries") +set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${${EXTERNAL_NAME_UPPER}_LIBRARIES} CACHE FILEPATH "Location of QuaZip libraries") diff --git a/cmake/init.cmake b/cmake/init.cmake index 9d7b0fd94c..9adcb167df 100644 --- a/cmake/init.cmake +++ b/cmake/init.cmake @@ -3,11 +3,11 @@ if (WIN32) endif (WIN32) if (POLICY CMP0043) - cmake_policy(SET CMP0043 OLD) + cmake_policy(SET CMP0043 NEW) endif () if (POLICY CMP0042) - cmake_policy(SET CMP0042 OLD) + cmake_policy(SET CMP0042 NEW) endif () set_property(GLOBAL PROPERTY USE_FOLDERS ON) @@ -34,7 +34,7 @@ file(GLOB HIFI_CUSTOM_MACROS "cmake/macros/*.cmake") foreach(CUSTOM_MACRO ${HIFI_CUSTOM_MACROS}) include(${CUSTOM_MACRO}) endforeach() -unset(HIFI_CUSTOM_MACROS) +unset(HIFI_CUSTOM_MACROS) if (ANDROID) set(BUILD_SHARED_LIBS ON) diff --git a/cmake/macros/TargetZlib.cmake b/cmake/macros/TargetZlib.cmake index 3eb0322ea0..ef746031e8 100644 --- a/cmake/macros/TargetZlib.cmake +++ b/cmake/macros/TargetZlib.cmake @@ -1,10 +1,10 @@ -# +# # Copyright 2015 High Fidelity, Inc. # Created by Bradley Austin Davis on 2015/10/10 # # Distributed under the Apache License, Version 2.0. # See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -# +# macro(TARGET_ZLIB) if (WIN32) diff --git a/interface/resources/images/+gles/Default-Sky-9-cubemap.ktx b/interface/resources/images/+gles/Default-Sky-9-cubemap.ktx deleted file mode 100644 index 6d46791fa2..0000000000 Binary files a/interface/resources/images/+gles/Default-Sky-9-cubemap.ktx and /dev/null differ diff --git a/interface/resources/images/Default-Sky-9-cubemap.ktx b/interface/resources/images/Default-Sky-9-cubemap.ktx deleted file mode 100644 index 70f495c3ab..0000000000 Binary files a/interface/resources/images/Default-Sky-9-cubemap.ktx and /dev/null differ diff --git a/interface/resources/images/Default-Sky-9-cubemap/Default-Sky-9-cubemap.jpg b/interface/resources/images/Default-Sky-9-cubemap/Default-Sky-9-cubemap.jpg new file mode 100644 index 0000000000..7977396159 Binary files /dev/null and b/interface/resources/images/Default-Sky-9-cubemap/Default-Sky-9-cubemap.jpg differ diff --git a/interface/resources/images/Default-Sky-9-cubemap/Default-Sky-9-cubemap.ktx b/interface/resources/images/Default-Sky-9-cubemap/Default-Sky-9-cubemap.ktx new file mode 100644 index 0000000000..4231bf7650 Binary files /dev/null and b/interface/resources/images/Default-Sky-9-cubemap/Default-Sky-9-cubemap.ktx differ diff --git a/interface/resources/images/Default-Sky-9-cubemap/Default-Sky-9-cubemap.texmeta.json b/interface/resources/images/Default-Sky-9-cubemap/Default-Sky-9-cubemap.texmeta.json new file mode 100644 index 0000000000..28512662d9 --- /dev/null +++ b/interface/resources/images/Default-Sky-9-cubemap/Default-Sky-9-cubemap.texmeta.json @@ -0,0 +1,8 @@ +{ + "compressed": { + "COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT": "Default-Sky-9-cubemap_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT.ktx", + "COMPRESSED_SRGB8_ETC2": "Default-Sky-9-cubemap_COMPRESSED_SRGB8_ETC2.ktx" + }, + "original": "Default-Sky-9-cubemap.jpg", + "uncompressed": "Default-Sky-9-cubemap.ktx" +} diff --git a/interface/resources/images/Default-Sky-9-cubemap/Default-Sky-9-cubemap_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT.ktx b/interface/resources/images/Default-Sky-9-cubemap/Default-Sky-9-cubemap_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT.ktx new file mode 100644 index 0000000000..c789fa4ac5 Binary files /dev/null and b/interface/resources/images/Default-Sky-9-cubemap/Default-Sky-9-cubemap_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT.ktx differ diff --git a/interface/resources/images/Default-Sky-9-cubemap/Default-Sky-9-cubemap_COMPRESSED_SRGB8_ETC2.ktx b/interface/resources/images/Default-Sky-9-cubemap/Default-Sky-9-cubemap_COMPRESSED_SRGB8_ETC2.ktx new file mode 100644 index 0000000000..deede32614 Binary files /dev/null and b/interface/resources/images/Default-Sky-9-cubemap/Default-Sky-9-cubemap_COMPRESSED_SRGB8_ETC2.ktx differ diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index aa2b382c58..2dc3645be0 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -152,6 +152,8 @@ #include #include #include +#include +#include "recording/ClipCache.h" #include "AudioClient.h" #include "audio/AudioScope.h" @@ -328,9 +330,9 @@ static bool DISABLE_DEFERRED = QProcessEnvironment::systemEnvironment().contains #endif #if !defined(Q_OS_ANDROID) -static const int MAX_CONCURRENT_RESOURCE_DOWNLOADS = 16; +static const uint32_t MAX_CONCURRENT_RESOURCE_DOWNLOADS = 16; #else -static const int MAX_CONCURRENT_RESOURCE_DOWNLOADS = 4; +static const uint32_t MAX_CONCURRENT_RESOURCE_DOWNLOADS = 4; #endif // For processing on QThreadPool, we target a number of threads after reserving some @@ -1327,7 +1329,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo QString concurrentDownloadsStr = getCmdOption(argc, constArgv, "--concurrent-downloads"); bool success; - int concurrentDownloads = concurrentDownloadsStr.toInt(&success); + uint32_t concurrentDownloads = concurrentDownloadsStr.toUInt(&success); if (!success) { concurrentDownloads = MAX_CONCURRENT_RESOURCE_DOWNLOADS; } @@ -2054,7 +2056,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo } properties["active_downloads"] = loadingRequests.size(); - properties["pending_downloads"] = ResourceCache::getPendingRequestCount(); + properties["pending_downloads"] = (int)ResourceCache::getPendingRequestCount(); properties["active_downloads_details"] = loadingRequestsStats; auto statTracker = DependencyManager::get(); @@ -4653,8 +4655,8 @@ void Application::idle() { PROFILE_COUNTER_IF_CHANGED(app, "present", float, displayPlugin->presentRate()); } PROFILE_COUNTER_IF_CHANGED(app, "renderLoopRate", float, _renderLoopCounter.rate()); - PROFILE_COUNTER_IF_CHANGED(app, "currentDownloads", int, ResourceCache::getLoadingRequests().length()); - PROFILE_COUNTER_IF_CHANGED(app, "pendingDownloads", int, ResourceCache::getPendingRequestCount()); + PROFILE_COUNTER_IF_CHANGED(app, "currentDownloads", uint32_t, ResourceCache::getLoadingRequestCount()); + PROFILE_COUNTER_IF_CHANGED(app, "pendingDownloads", uint32_t, ResourceCache::getPendingRequestCount()); PROFILE_COUNTER_IF_CHANGED(app, "currentProcessing", int, DependencyManager::get()->getStat("Processing").toInt()); PROFILE_COUNTER_IF_CHANGED(app, "pendingProcessing", int, DependencyManager::get()->getStat("PendingProcessing").toInt()); auto renderConfig = _renderEngine->getConfiguration(); @@ -5399,13 +5401,21 @@ void Application::reloadResourceCaches() { queryOctree(NodeType::EntityServer, PacketType::EntityQuery); + // Clear the entities and their renderables + getEntities()->clear(); + DependencyManager::get()->clearCache(); DependencyManager::get()->clearCache(); + // Clear all the resource caches + DependencyManager::get()->clear(); DependencyManager::get()->refreshAll(); - DependencyManager::get()->refreshAll(); DependencyManager::get()->refreshAll(); + MaterialCache::instance().refreshAll(); + DependencyManager::get()->refreshAll(); + ShaderCache::instance().refreshAll(); DependencyManager::get()->refreshAll(); + DependencyManager::get()->refreshAll(); DependencyManager::get()->reset(); // Force redownload of .fst models @@ -6470,9 +6480,12 @@ void Application::clearDomainOctreeDetails() { skyStage->setBackgroundMode(graphics::SunSkyStage::SKY_DEFAULT); DependencyManager::get()->clearUnusedResources(); - DependencyManager::get()->clearUnusedResources(); DependencyManager::get()->clearUnusedResources(); + MaterialCache::instance().clearUnusedResources(); + DependencyManager::get()->clearUnusedResources(); + ShaderCache::instance().clearUnusedResources(); DependencyManager::get()->clearUnusedResources(); + DependencyManager::get()->clearUnusedResources(); getMyAvatar()->setAvatarEntityDataChanged(true); } diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index b347963cf1..c61b424bce 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1942,7 +1942,7 @@ void MyAvatar::updateMotors() { horizontalMotorTimescale = FLYING_MOTOR_TIMESCALE; verticalMotorTimescale = FLYING_MOTOR_TIMESCALE; } else { - horizontalMotorTimescale = WALKING_MOTOR_TIMESCALE; + horizontalMotorTimescale = WALKING_MOTOR_TIMESCALE * getSensorToWorldScale(); verticalMotorTimescale = INVALID_MOTOR_TIMESCALE; } diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp index 8faa51bc58..495e29f986 100644 --- a/interface/src/ui/Stats.cpp +++ b/interface/src/ui/Stats.cpp @@ -267,8 +267,8 @@ void Stats::updateStats(bool force) { auto loadingRequests = ResourceCache::getLoadingRequests(); STAT_UPDATE(downloads, loadingRequests.size()); - STAT_UPDATE(downloadLimit, ResourceCache::getRequestLimit()) - STAT_UPDATE(downloadsPending, ResourceCache::getPendingRequestCount()); + STAT_UPDATE(downloadLimit, (int)ResourceCache::getRequestLimit()) + STAT_UPDATE(downloadsPending, (int)ResourceCache::getPendingRequestCount()); STAT_UPDATE(processing, DependencyManager::get()->getStat("Processing").toInt()); STAT_UPDATE(processingPending, DependencyManager::get()->getStat("PendingProcessing").toInt()); diff --git a/libraries/animation/src/AnimationCache.cpp b/libraries/animation/src/AnimationCache.cpp index f30d5605d7..04b7952ddb 100644 --- a/libraries/animation/src/AnimationCache.cpp +++ b/libraries/animation/src/AnimationCache.cpp @@ -32,12 +32,6 @@ AnimationCache::AnimationCache(QObject* parent) : } AnimationPointer AnimationCache::getAnimation(const QUrl& url) { - if (QThread::currentThread() != thread()) { - AnimationPointer result; - BLOCKING_INVOKE_METHOD(this, "getAnimation", - Q_RETURN_ARG(AnimationPointer, result), Q_ARG(const QUrl&, url)); - return result; - } return getResource(url).staticCast(); } diff --git a/libraries/audio/src/SoundCache.cpp b/libraries/audio/src/SoundCache.cpp index 162e833da2..2877de3d6f 100644 --- a/libraries/audio/src/SoundCache.cpp +++ b/libraries/audio/src/SoundCache.cpp @@ -30,12 +30,6 @@ SoundCache::SoundCache(QObject* parent) : } SharedSoundPointer SoundCache::getSound(const QUrl& url) { - if (QThread::currentThread() != thread()) { - SharedSoundPointer result; - BLOCKING_INVOKE_METHOD(this, "getSound", - Q_RETURN_ARG(SharedSoundPointer, result), Q_ARG(const QUrl&, url)); - return result; - } return getResource(url).staticCast(); } diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 095283b1e5..0452587439 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -308,7 +308,7 @@ bool RenderableModelEntityItem::findDetailedParabolaIntersection(const glm::vec3 } void RenderableModelEntityItem::getCollisionGeometryResource() { - QUrl hullURL(getCompoundShapeURL()); + QUrl hullURL(getCollisionShapeURL()); QUrlQuery queryArgs(hullURL); queryArgs.addQueryItem("collision-hull", ""); hullURL.setQuery(queryArgs); @@ -325,8 +325,9 @@ bool RenderableModelEntityItem::computeShapeFailedToLoad() { void RenderableModelEntityItem::setShapeType(ShapeType type) { ModelEntityItem::setShapeType(type); - if (getShapeType() == SHAPE_TYPE_COMPOUND) { - if (!_compoundShapeResource && !getCompoundShapeURL().isEmpty()) { + auto shapeType = getShapeType(); + if (shapeType == SHAPE_TYPE_COMPOUND || shapeType == SHAPE_TYPE_SIMPLE_COMPOUND) { + if (!_compoundShapeResource && !getCollisionShapeURL().isEmpty()) { getCollisionGeometryResource(); } } else if (_compoundShapeResource && !getCompoundShapeURL().isEmpty()) { @@ -352,18 +353,21 @@ void RenderableModelEntityItem::setCompoundShapeURL(const QString& url) { bool RenderableModelEntityItem::isReadyToComputeShape() const { ShapeType type = getShapeType(); auto model = getModel(); - if (type == SHAPE_TYPE_COMPOUND) { - if (!model || getCompoundShapeURL().isEmpty()) { + auto shapeType = getShapeType(); + if (shapeType == SHAPE_TYPE_COMPOUND || shapeType == SHAPE_TYPE_SIMPLE_COMPOUND) { + auto shapeURL = getCollisionShapeURL(); + + if (!model || shapeURL.isEmpty()) { return false; } - if (model->getURL().isEmpty()) { + if (model->getURL().isEmpty() || !_dimensionsInitialized) { // we need a render geometry with a scale to proceed, so give up. return false; } if (model->isLoaded()) { - if (!getCompoundShapeURL().isEmpty() && !_compoundShapeResource) { + if (!shapeURL.isEmpty() && !_compoundShapeResource) { const_cast(this)->getCollisionGeometryResource(); } @@ -518,7 +522,16 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { return; } - auto& meshes = model->getGeometry()->getMeshes(); + std::vector> meshes; + if (type == SHAPE_TYPE_SIMPLE_COMPOUND) { + auto& fbxMeshes = _compoundShapeResource->getFBXGeometry().meshes; + meshes.reserve(fbxMeshes.size()); + for (auto& fbxMesh : fbxMeshes) { + meshes.push_back(fbxMesh._mesh); + } + } else { + meshes = model->getGeometry()->getMeshes(); + } int32_t numMeshes = (int32_t)(meshes.size()); const int MAX_ALLOWED_MESH_COUNT = 1000; @@ -752,7 +765,7 @@ bool RenderableModelEntityItem::shouldBePhysical() const { auto model = getModel(); // If we have a model, make sure it hasn't failed to download. // If it has, we'll report back that we shouldn't be physical so that physics aren't held waiting for us to be ready. - if (model && getShapeType() == SHAPE_TYPE_COMPOUND && model->didCollisionGeometryRequestFail()) { + if (model && (getShapeType() == SHAPE_TYPE_COMPOUND || getShapeType() == SHAPE_TYPE_SIMPLE_COMPOUND) && model->didCollisionGeometryRequestFail()) { return false; } else if (model && getShapeType() != SHAPE_TYPE_NONE && model->didVisualGeometryRequestFail()) { return false; diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp index f51a3f7740..38027a80ed 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp @@ -320,7 +320,7 @@ void ParticleEffectEntityRenderer::stepSimulation() { } void ParticleEffectEntityRenderer::doRender(RenderArgs* args) { - if (!_visible) { + if (!_visible || !(_networkTexture && _networkTexture->isLoaded())) { return; } @@ -328,11 +328,7 @@ void ParticleEffectEntityRenderer::doRender(RenderArgs* args) { stepSimulation(); gpu::Batch& batch = *args->_batch; - if (_networkTexture && _networkTexture->isLoaded()) { - batch.setResourceTexture(0, _networkTexture->getGPUTexture()); - } else { - batch.setResourceTexture(0, DependencyManager::get()->getWhiteTexture()); - } + batch.setResourceTexture(0, _networkTexture->getGPUTexture()); Transform transform; // The particles are in world space, so the transform is unused, except for the rotation, which we use diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index 9006df7ac2..72192c8702 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -551,6 +551,10 @@ QString ModelEntityItem::getCompoundShapeURL() const { return _compoundShapeURL.get(); } +QString ModelEntityItem::getCollisionShapeURL() const { + return getShapeType() == SHAPE_TYPE_COMPOUND ? getCompoundShapeURL() : getModelURL(); +} + void ModelEntityItem::setColor(const glm::u8vec3& value) { withWriteLock([&] { _color = value; diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h index a37c40e317..91d2d81b88 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -69,6 +69,9 @@ public: static const QString DEFAULT_COMPOUND_SHAPE_URL; QString getCompoundShapeURL() const; + // Returns the URL used for the collision shape + QString getCollisionShapeURL() const; + // model related properties virtual void setModelURL(const QString& url); virtual void setCompoundShapeURL(const QString& url); diff --git a/libraries/model-networking/src/model-networking/TextureCache.h b/libraries/model-networking/src/model-networking/TextureCache.h index c914ad91af..3933e3ae56 100644 --- a/libraries/model-networking/src/model-networking/TextureCache.h +++ b/libraries/model-networking/src/model-networking/TextureCache.h @@ -75,8 +75,6 @@ protected: void makeLocalRequest(); Q_INVOKABLE void handleLocalRequestCompleted(); - virtual bool isCacheable() const override { return _loaded; } - Q_INVOKABLE virtual void downloadFinished(const QByteArray& data) override; bool handleFailedRequest(ResourceRequest::Result result) override; diff --git a/libraries/networking/src/ResourceCache.cpp b/libraries/networking/src/ResourceCache.cpp index aed9f3b0e5..076db44ea6 100644 --- a/libraries/networking/src/ResourceCache.cpp +++ b/libraries/networking/src/ResourceCache.cpp @@ -27,28 +27,35 @@ #include "NetworkLogging.h" #include "NodeList.h" - -#define clamp(x, min, max) (((x) < (min)) ? (min) :\ - (((x) > (max)) ? (max) :\ - (x))) - -void ResourceCacheSharedItems::appendActiveRequest(QWeakPointer resource) { +bool ResourceCacheSharedItems::appendRequest(QWeakPointer resource) { Lock lock(_mutex); - _loadingRequests.append(resource); + if ((uint32_t)_loadingRequests.size() < _requestLimit) { + _loadingRequests.append(resource); + return true; + } else { + _pendingRequests.append(resource); + return false; + } } -void ResourceCacheSharedItems::appendPendingRequest(QWeakPointer resource) { +void ResourceCacheSharedItems::setRequestLimit(uint32_t limit) { Lock lock(_mutex); - _pendingRequests.append(resource); + _requestLimit = limit; } -QList> ResourceCacheSharedItems::getPendingRequests() { +uint32_t ResourceCacheSharedItems::getRequestLimit() const { + Lock lock(_mutex); + return _requestLimit; +} + +QList> ResourceCacheSharedItems::getPendingRequests() const { QList> result; Lock lock(_mutex); - foreach(QSharedPointer resource, _pendingRequests) { - if (resource) { - result.append(resource); + foreach (QWeakPointer resource, _pendingRequests) { + auto locked = resource.lock(); + if (locked) { + result.append(locked); } } @@ -60,16 +67,12 @@ uint32_t ResourceCacheSharedItems::getPendingRequestsCount() const { return _pendingRequests.size(); } -QList> ResourceCacheSharedItems::getLoadingRequests() { +QList> ResourceCacheSharedItems::getLoadingRequests() const { QList> result; - Lock lock(_mutex); - - foreach(QSharedPointer resource, _loadingRequests) { - if (resource) { - result.append(resource); - } + { + Lock lock(_mutex); + result = _loadingRequests; } - return result; } @@ -131,6 +134,11 @@ QSharedPointer ResourceCacheSharedItems::getHighestPendingRequest() { return highestResource; } +void ResourceCacheSharedItems::clear() { + Lock lock(_mutex); + _pendingRequests.clear(); + _loadingRequests.clear(); +} ScriptableResourceCache::ScriptableResourceCache(QSharedPointer resourceCache) { _resourceCache = resourceCache; @@ -244,9 +252,7 @@ ResourceCache::ResourceCache(QObject* parent) : QObject(parent) { } } -ResourceCache::~ResourceCache() { - clearUnusedResources(); -} +ResourceCache::~ResourceCache() {} void ResourceCache::clearATPAssets() { { @@ -260,6 +266,7 @@ void ResourceCache::clearATPAssets() { if (auto strongRef = resource.lock()) { // Make sure the resource won't reinsert itself strongRef->setCache(nullptr); + _totalResourcesSize -= strongRef->getBytes(); } } } @@ -269,28 +276,18 @@ void ResourceCache::clearATPAssets() { for (auto& resource : _unusedResources.values()) { if (resource->getURL().scheme() == URL_SCHEME_ATP) { _unusedResources.remove(resource->getLRUKey()); - } - } - } - { - QWriteLocker locker(&_resourcesToBeGottenLock); - auto it = _resourcesToBeGotten.begin(); - while (it != _resourcesToBeGotten.end()) { - if (it->scheme() == URL_SCHEME_ATP) { - it = _resourcesToBeGotten.erase(it); - } else { - ++it; + _unusedResourcesSize -= resource->getBytes(); } } } - + resetResourceCounters(); } void ResourceCache::refreshAll() { // Clear all unused resources so we don't have to reload them clearUnusedResources(); - resetResourceCounters(); + resetUnusedResourceCounter(); QHash> resources; { @@ -306,21 +303,6 @@ void ResourceCache::refreshAll() { } } -void ResourceCache::refresh(const QUrl& url) { - QSharedPointer resource; - { - QReadLocker locker(&_resourcesLock); - resource = _resources.value(url).lock(); - } - - if (resource) { - resource->refresh(); - } else { - removeResource(url); - resetResourceCounters(); - } -} - QVariantList ResourceCache::getResourceList() { QVariantList list; if (QThread::currentThread() != thread()) { @@ -338,12 +320,13 @@ QVariantList ResourceCache::getResourceList() { return list; } -void ResourceCache::setRequestLimit(int limit) { - _requestLimit = limit; +void ResourceCache::setRequestLimit(uint32_t limit) { + auto sharedItems = DependencyManager::get(); + sharedItems->setRequestLimit(limit); // Now go fill any new request spots - while (attemptHighestPriorityRequest()) { - // just keep looping until we reach the new limit or no more pending requests + while (sharedItems->getLoadingRequestsCount() < limit && sharedItems->getPendingRequestsCount() > 0) { + attemptHighestPriorityRequest(); } } @@ -381,9 +364,9 @@ QSharedPointer ResourceCache::getResource(const QUrl& url, const QUrl& } void ResourceCache::setUnusedResourceCacheSize(qint64 unusedResourcesMaxSize) { - _unusedResourcesMaxSize = clamp(unusedResourcesMaxSize, MIN_UNUSED_MAX_SIZE, MAX_UNUSED_MAX_SIZE); + _unusedResourcesMaxSize = glm::clamp(unusedResourcesMaxSize, MIN_UNUSED_MAX_SIZE, MAX_UNUSED_MAX_SIZE); reserveUnusedResource(0); - resetResourceCounters(); + resetUnusedResourceCounter(); } void ResourceCache::addUnusedResource(const QSharedPointer& resource) { @@ -391,18 +374,20 @@ void ResourceCache::addUnusedResource(const QSharedPointer& resource) if (resource->getBytes() == 0 || resource->getBytes() > _unusedResourcesMaxSize) { resource->setCache(nullptr); removeResource(resource->getURL(), resource->getBytes()); - resetResourceCounters(); + resetTotalResourceCounter(); return; } reserveUnusedResource(resource->getBytes()); resource->setLRUKey(++_lastLRUKey); - _unusedResourcesSize += resource->getBytes(); - resetResourceCounters(); + { + QWriteLocker locker(&_unusedResourcesLock); + _unusedResources.insert(resource->getLRUKey(), resource); + _unusedResourcesSize += resource->getBytes(); + } - QWriteLocker locker(&_unusedResourcesLock); - _unusedResources.insert(resource->getLRUKey(), resource); + resetUnusedResourceCounter(); } void ResourceCache::removeUnusedResource(const QSharedPointer& resource) { @@ -412,7 +397,7 @@ void ResourceCache::removeUnusedResource(const QSharedPointer& resourc _unusedResourcesSize -= resource->getBytes(); locker.unlock(); - resetResourceCounters(); + resetUnusedResourceCounter(); } } @@ -445,14 +430,19 @@ void ResourceCache::clearUnusedResources() { } _unusedResources.clear(); } + _unusedResourcesSize = 0; } -void ResourceCache::resetResourceCounters() { +void ResourceCache::resetTotalResourceCounter() { { QReadLocker locker(&_resourcesLock); _numTotalResources = _resources.size(); } + emit dirty(); +} + +void ResourceCache::resetUnusedResourceCounter() { { QReadLocker locker(&_unusedResourcesLock); _numUnusedResources = _unusedResources.size(); @@ -461,6 +451,13 @@ void ResourceCache::resetResourceCounters() { emit dirty(); } +void ResourceCache::resetResourceCounters() { + resetTotalResourceCounter(); + resetUnusedResourceCounter(); + + emit dirty(); +} + void ResourceCache::removeResource(const QUrl& url, qint64 size) { QWriteLocker locker(&_resourcesLock); _resources.remove(url); @@ -481,38 +478,34 @@ QList> ResourceCache::getLoadingRequests() { return DependencyManager::get()->getLoadingRequests(); } -int ResourceCache::getPendingRequestCount() { +uint32_t ResourceCache::getPendingRequestCount() { return DependencyManager::get()->getPendingRequestsCount(); } -int ResourceCache::getLoadingRequestCount() { +uint32_t ResourceCache::getLoadingRequestCount() { return DependencyManager::get()->getLoadingRequestsCount(); } bool ResourceCache::attemptRequest(QSharedPointer resource) { Q_ASSERT(!resource.isNull()); - auto sharedItems = DependencyManager::get(); - if (_requestsActive >= _requestLimit) { - // wait until a slot becomes available - sharedItems->appendPendingRequest(resource); - return false; + if (sharedItems->appendRequest(resource)) { + resource->makeRequest(); + return true; } - - ++_requestsActive; - sharedItems->appendActiveRequest(resource); - resource->makeRequest(); - return true; + return false; } void ResourceCache::requestCompleted(QWeakPointer resource) { auto sharedItems = DependencyManager::get(); sharedItems->removeRequest(resource); - --_requestsActive; - attemptHighestPriorityRequest(); + // Now go fill any new request spots + while (sharedItems->getLoadingRequestsCount() < sharedItems->getRequestLimit() && sharedItems->getPendingRequestsCount() > 0) { + attemptHighestPriorityRequest(); + } } bool ResourceCache::attemptHighestPriorityRequest() { @@ -521,10 +514,6 @@ bool ResourceCache::attemptHighestPriorityRequest() { return (resource && attemptRequest(resource)); } -const int DEFAULT_REQUEST_LIMIT = 10; -int ResourceCache::_requestLimit = DEFAULT_REQUEST_LIMIT; -int ResourceCache::_requestsActive = 0; - static int requestID = 0; Resource::Resource(const QUrl& url) : @@ -550,7 +539,7 @@ void Resource::ensureLoading() { } void Resource::setLoadPriority(const QPointer& owner, float priority) { - if (!(_failedToLoad)) { + if (!_failedToLoad) { _loadPriorities.insert(owner, priority); } } @@ -566,7 +555,7 @@ void Resource::setLoadPriorities(const QHash, float>& prioriti } void Resource::clearLoadPriority(const QPointer& owner) { - if (!(_failedToLoad)) { + if (!_failedToLoad) { _loadPriorities.remove(owner); } } @@ -592,6 +581,7 @@ void Resource::refresh() { if (_request && !(_loaded || _failedToLoad)) { return; } + if (_request) { _request->disconnect(this); _request->deleteLater(); @@ -613,7 +603,7 @@ void Resource::allReferencesCleared() { if (_cache && isCacheable()) { // create and reinsert new shared pointer - QSharedPointer self(this, &Resource::allReferencesCleared); + QSharedPointer self(this, &Resource::deleter); setSelf(self); reinsert(); @@ -623,7 +613,7 @@ void Resource::allReferencesCleared() { if (_cache) { // remove from the cache _cache->removeResource(getURL(), getBytes()); - _cache->resetResourceCounters(); + _cache->resetTotalResourceCounter(); } deleteLater(); @@ -732,6 +722,7 @@ void Resource::handleReplyFinished() { { "from_cache", false }, { "size_mb", _bytesTotal / 1000000.0 } }); + ResourceCache::requestCompleted(_self); return; } diff --git a/libraries/networking/src/ResourceCache.h b/libraries/networking/src/ResourceCache.h index 2c0baad3f7..33490301d7 100644 --- a/libraries/networking/src/ResourceCache.h +++ b/libraries/networking/src/ResourceCache.h @@ -66,21 +66,25 @@ class ResourceCacheSharedItems : public Dependency { using Lock = std::unique_lock; public: - void appendPendingRequest(QWeakPointer newRequest); - void appendActiveRequest(QWeakPointer newRequest); + bool appendRequest(QWeakPointer newRequest); void removeRequest(QWeakPointer doneRequest); - QList> getPendingRequests(); - uint32_t getPendingRequestsCount() const; - QList> getLoadingRequests(); + void setRequestLimit(uint32_t limit); + uint32_t getRequestLimit() const; + QList> getPendingRequests() const; QSharedPointer getHighestPendingRequest(); + uint32_t getPendingRequestsCount() const; + QList> getLoadingRequests() const; uint32_t getLoadingRequestsCount() const; + void clear(); private: ResourceCacheSharedItems() = default; mutable Mutex _mutex; QList> _pendingRequests; - QList> _loadingRequests; + QList> _loadingRequests; + const uint32_t DEFAULT_REQUEST_LIMIT = 10; + uint32_t _requestLimit { DEFAULT_REQUEST_LIMIT }; }; /// Wrapper to expose resources to JS/QML @@ -200,25 +204,20 @@ public: Q_INVOKABLE QVariantList getResourceList(); - static void setRequestLimit(int limit); - static int getRequestLimit() { return _requestLimit; } - - static int getRequestsActive() { return _requestsActive; } + static void setRequestLimit(uint32_t limit); + static uint32_t getRequestLimit() { return DependencyManager::get()->getRequestLimit(); } void setUnusedResourceCacheSize(qint64 unusedResourcesMaxSize); qint64 getUnusedResourceCacheSize() const { return _unusedResourcesMaxSize; } static QList> getLoadingRequests(); - - static int getPendingRequestCount(); - - static int getLoadingRequestCount(); + static uint32_t getPendingRequestCount(); + static uint32_t getLoadingRequestCount(); ResourceCache(QObject* parent = nullptr); virtual ~ResourceCache(); void refreshAll(); - void refresh(const QUrl& url); void clearUnusedResources(); signals: @@ -272,11 +271,11 @@ private: friend class ScriptableResourceCache; void reserveUnusedResource(qint64 resourceSize); - void resetResourceCounters(); void removeResource(const QUrl& url, qint64 size = 0); - static int _requestLimit; - static int _requestsActive; + void resetTotalResourceCounter(); + void resetUnusedResourceCounter(); + void resetResourceCounters(); // Resources QHash> _resources; @@ -293,10 +292,6 @@ private: std::atomic _numUnusedResources { 0 }; std::atomic _unusedResourcesSize { 0 }; - - // Pending resources - QQueue _resourcesToBeGotten; - QReadWriteLock _resourcesToBeGottenLock { QReadWriteLock::Recursive }; }; /// Wrapper to expose resource caches to JS/QML @@ -455,7 +450,7 @@ protected: virtual void makeRequest(); /// Checks whether the resource is cacheable. - virtual bool isCacheable() const { return true; } + virtual bool isCacheable() const { return _loaded; } /// Called when the download has finished. /// This should be overridden by subclasses that need to process the data once it is downloaded. diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp index b716d5c0d1..626184d1dc 100755 --- a/libraries/physics/src/CharacterController.cpp +++ b/libraries/physics/src/CharacterController.cpp @@ -701,7 +701,7 @@ void CharacterController::updateState() { const btScalar GROUND_TO_FLY_THRESHOLD = 0.8f * _radius + _halfHeight; const quint64 TAKE_OFF_TO_IN_AIR_PERIOD = 250 * MSECS_PER_SECOND; const btScalar MIN_HOVER_HEIGHT = _scaleFactor * DEFAULT_AVATAR_MIN_HOVER_HEIGHT; - const quint64 JUMP_TO_HOVER_PERIOD = 1100 * MSECS_PER_SECOND; + const quint64 JUMP_TO_HOVER_PERIOD = _scaleFactor < 1.0f ? _scaleFactor * 1100 * MSECS_PER_SECOND : 1100 * MSECS_PER_SECOND; // scan for distant floor // rayStart is at center of bottom sphere diff --git a/libraries/render-utils/src/BackgroundStage.cpp b/libraries/render-utils/src/BackgroundStage.cpp index d9115c7943..ca643b9f14 100644 --- a/libraries/render-utils/src/BackgroundStage.cpp +++ b/libraries/render-utils/src/BackgroundStage.cpp @@ -55,85 +55,46 @@ BackgroundStage::BackgroundPointer BackgroundStage::removeBackground(Index index void DrawBackgroundStage::run(const render::RenderContextPointer& renderContext, const Inputs& inputs) { - const auto& lightingModel = inputs; + const auto& lightingModel = inputs.get0(); if (!lightingModel->isBackgroundEnabled()) { return; } // Background rendering decision - auto backgroundStage = renderContext->_scene->getStage(); - assert(backgroundStage); - - graphics::SunSkyStagePointer background; + const auto& backgroundStage = renderContext->_scene->getStage(); + const auto& backgroundFrame = inputs.get1(); graphics::SkyboxPointer skybox; - if (backgroundStage->_currentFrame._backgrounds.size()) { - auto backgroundId = backgroundStage->_currentFrame._backgrounds.front(); - auto background = backgroundStage->getBackground(backgroundId); + if (backgroundStage && backgroundFrame->_backgrounds.size()) { + const auto& background = backgroundStage->getBackground(backgroundFrame->_backgrounds.front()); if (background) { skybox = background->getSkybox(); } } - /* auto backgroundMode = skyStage->getBackgroundMode(); - switch (backgroundMode) { - case graphics::SunSkyStage::SKY_DEFAULT: { - auto scene = DependencyManager::get()->getStage(); - auto sceneKeyLight = scene->getKeyLight(); - - scene->setSunModelEnable(false); - sceneKeyLight->setColor(ColorUtils::toVec3(KeyLightPropertyGroup::DEFAULT_KEYLIGHT_COLOR)); - sceneKeyLight->setIntensity(KeyLightPropertyGroup::DEFAULT_KEYLIGHT_INTENSITY); - sceneKeyLight->setAmbientIntensity(KeyLightPropertyGroup::DEFAULT_KEYLIGHT_AMBIENT_INTENSITY); - sceneKeyLight->setDirection(KeyLightPropertyGroup::DEFAULT_KEYLIGHT_DIRECTION); - // fall through: render a skybox (if available), or the defaults (if requested) - } - - case graphics::SunSkyStage::SKY_BOX: {*/ if (skybox && !skybox->empty()) { - PerformanceTimer perfTimer("skybox"); - auto args = renderContext->args; + PerformanceTimer perfTimer("skybox"); + auto args = renderContext->args; - gpu::doInBatch("DrawBackgroundStage::run", args->_context, [&](gpu::Batch& batch) { - args->_batch = &batch; + gpu::doInBatch("DrawBackgroundStage::run", args->_context, [&](gpu::Batch& batch) { + args->_batch = &batch; - batch.enableSkybox(true); + batch.enableSkybox(true); - batch.setViewportTransform(args->_viewport); - batch.setStateScissorRect(args->_viewport); + batch.setViewportTransform(args->_viewport); + batch.setStateScissorRect(args->_viewport); - glm::mat4 projMat; - Transform viewMat; - args->getViewFrustum().evalProjectionMatrix(projMat); - args->getViewFrustum().evalViewTransform(viewMat); + glm::mat4 projMat; + Transform viewMat; + args->getViewFrustum().evalProjectionMatrix(projMat); + args->getViewFrustum().evalViewTransform(viewMat); - batch.setProjectionTransform(projMat); - batch.setViewTransform(viewMat); + batch.setProjectionTransform(projMat); + batch.setViewTransform(viewMat); - skybox->render(batch, args->getViewFrustum()); - }); - args->_batch = nullptr; - - // break; - } - // fall through: render defaults (if requested) -// } -/* - case graphics::SunSkyStage::SKY_DEFAULT_AMBIENT_TEXTURE: { - if (Menu::getInstance()->isOptionChecked(MenuOption::DefaultSkybox)) { - auto scene = DependencyManager::get()->getStage(); - auto sceneKeyLight = scene->getKeyLight(); - auto defaultSkyboxAmbientTexture = qApp->getDefaultSkyboxAmbientTexture(); - if (defaultSkyboxAmbientTexture) { - sceneKeyLight->setAmbientSphere(defaultSkyboxAmbientTexture->getIrradiance()); - sceneKeyLight->setAmbientMap(defaultSkyboxAmbientTexture); - } - // fall through: render defaults skybox - } else { - break; - } + skybox->render(batch, args->getViewFrustum()); + }); + args->_batch = nullptr; } - */ - } BackgroundStageSetup::BackgroundStageSetup() { diff --git a/libraries/render-utils/src/BackgroundStage.h b/libraries/render-utils/src/BackgroundStage.h index db876b1993..61ca576ca8 100644 --- a/libraries/render-utils/src/BackgroundStage.h +++ b/libraries/render-utils/src/BackgroundStage.h @@ -65,6 +65,7 @@ public: BackgroundStage::BackgroundIndices _backgrounds; }; + using FramePointer = std::shared_ptr; Frame _currentFrame; }; @@ -76,18 +77,16 @@ public: BackgroundStageSetup(); void run(const render::RenderContextPointer& renderContext); - -protected: }; class DrawBackgroundStage { public: - using Inputs = LightingModelPointer; + using Inputs = render::VaryingSet2; using JobModel = render::Job::ModelI; - void run(const render::RenderContextPointer& renderContext, const Inputs& inputs); + DrawBackgroundStage() {} -protected: + void run(const render::RenderContextPointer& renderContext, const Inputs& inputs); }; #endif diff --git a/libraries/render-utils/src/BloomEffect.cpp b/libraries/render-utils/src/BloomEffect.cpp index e6217eb825..db86480eea 100644 --- a/libraries/render-utils/src/BloomEffect.cpp +++ b/libraries/render-utils/src/BloomEffect.cpp @@ -35,7 +35,16 @@ void BloomThreshold::run(const render::RenderContextPointer& renderContext, cons const auto frameTransform = inputs.get0(); const auto inputFrameBuffer = inputs.get1(); - const auto bloom = inputs.get2(); + const auto bloomFrame = inputs.get2(); + const auto& bloomStage = renderContext->_scene->getStage(); + graphics::BloomPointer bloom; + if (bloomStage && bloomFrame->_blooms.size()) { + bloom = bloomStage->getBloom(bloomFrame->_blooms.front()); + } + if (!bloom) { + renderContext->taskFlow.abortTask(); + return; + } assert(inputFrameBuffer->hasColor()); @@ -65,11 +74,6 @@ void BloomThreshold::run(const render::RenderContextPointer& renderContext, cons glm::ivec4 viewport{ 0, 0, bufferSize.x, bufferSize.y }; - if (!bloom) { - renderContext->taskFlow.abortTask(); - return; - } - _parameters.edit()._threshold = bloom->getBloomThreshold(); gpu::doInBatch("BloomThreshold::run", args->_context, [&](gpu::Batch& batch) { @@ -89,6 +93,7 @@ void BloomThreshold::run(const render::RenderContextPointer& renderContext, cons outputs.edit0() = _outputBuffer; outputs.edit1() = 0.5f + bloom->getBloomSize() * 3.5f; + outputs.edit2() = bloom; } BloomApply::BloomApply() { @@ -296,9 +301,9 @@ void BloomEffect::build(JobModel& task, const render::Varying& inputs, render::V const auto blurFB2 = task.addJob("BloomBlur2", blurInput2); const auto& frameBuffer = inputs.getN(1); - const auto& bloom = inputs.getN(2); // Mix all blur levels at quarter resolution + const auto bloom = bloomOutputs.getN(2); const auto applyInput = BloomApply::Inputs(blurInputBuffer, blurFB0, blurFB1, blurFB2, bloom).asVarying(); task.addJob("BloomApply", applyInput); // And then blend result in additive manner on top of final color buffer diff --git a/libraries/render-utils/src/BloomEffect.h b/libraries/render-utils/src/BloomEffect.h index 12c94bb929..07ae2887c9 100644 --- a/libraries/render-utils/src/BloomEffect.h +++ b/libraries/render-utils/src/BloomEffect.h @@ -14,7 +14,7 @@ #include -#include "graphics/Bloom.h" +#include "BloomStage.h" #include "DeferredFrameTransform.h" @@ -28,8 +28,8 @@ class BloomThresholdConfig : public render::Job::Config { class BloomThreshold { public: - using Inputs = render::VaryingSet3; - using Outputs = render::VaryingSet2; + using Inputs = render::VaryingSet3; + using Outputs = render::VaryingSet3; using Config = BloomThresholdConfig; using JobModel = render::Job::ModelIO; @@ -127,7 +127,7 @@ private: class BloomEffect { public: - using Inputs = render::VaryingSet3; + using Inputs = render::VaryingSet3; using Config = BloomConfig; using JobModel = render::Task::ModelI; diff --git a/libraries/render-utils/src/BloomStage.cpp b/libraries/render-utils/src/BloomStage.cpp index 904e27f5da..b3ba5f9565 100644 --- a/libraries/render-utils/src/BloomStage.cpp +++ b/libraries/render-utils/src/BloomStage.cpp @@ -16,16 +16,6 @@ std::string BloomStage::_stageName { "BLOOM_STAGE"}; const BloomStage::Index BloomStage::INVALID_INDEX { render::indexed_container::INVALID_INDEX }; -FetchBloomStage::FetchBloomStage() { - _bloom = std::make_shared(); -} - -void FetchBloomStage::configure(const Config& config) { - _bloom->setBloomIntensity(config.bloomIntensity); - _bloom->setBloomThreshold(config.bloomThreshold); - _bloom->setBloomSize(config.bloomSize); -} - BloomStage::Index BloomStage::findBloom(const BloomPointer& bloom) const { auto found = _bloomMap.find(bloom); if (found != _bloomMap.end()) { @@ -66,14 +56,3 @@ void BloomStageSetup::run(const render::RenderContextPointer& renderContext) { renderContext->_scene->resetStage(BloomStage::getName(), std::make_shared()); } } - -void FetchBloomStage::run(const render::RenderContextPointer& renderContext, graphics::BloomPointer& bloom) { - auto bloomStage = renderContext->_scene->getStage(); - assert(bloomStage); - - bloom = nullptr; - if (bloomStage->_currentFrame._blooms.size() != 0) { - auto bloomId = bloomStage->_currentFrame._blooms.front(); - bloom = bloomStage->getBloom(bloomId); - } -} diff --git a/libraries/render-utils/src/BloomStage.h b/libraries/render-utils/src/BloomStage.h index 27bd97dcab..7ba7e56035 100644 --- a/libraries/render-utils/src/BloomStage.h +++ b/libraries/render-utils/src/BloomStage.h @@ -65,6 +65,7 @@ public: BloomStage::BloomIndices _blooms; }; + using FramePointer = std::shared_ptr; Frame _currentFrame; }; @@ -102,17 +103,4 @@ signals: void dirty(); }; -class FetchBloomStage { -public: - using Config = FetchBloomConfig; - using JobModel = render::Job::ModelO; - - FetchBloomStage(); - - void configure(const Config& config); - void run(const render::RenderContextPointer& renderContext, graphics::BloomPointer& bloom); - -private: - graphics::BloomPointer _bloom; -}; #endif diff --git a/libraries/render-utils/src/DebugDeferredBuffer.cpp b/libraries/render-utils/src/DebugDeferredBuffer.cpp index 0e61b36280..be9e75a9a5 100644 --- a/libraries/render-utils/src/DebugDeferredBuffer.cpp +++ b/libraries/render-utils/src/DebugDeferredBuffer.cpp @@ -405,6 +405,7 @@ void DebugDeferredBuffer::run(const RenderContextPointer& renderContext, const I auto& ambientOcclusionFramebuffer = inputs.get3(); auto& velocityFramebuffer = inputs.get4(); auto& frameTransform = inputs.get5(); + auto& lightFrame = inputs.get6(); gpu::doInBatch("DebugDeferredBuffer::run", args->_context, [&](gpu::Batch& batch) { batch.enableStereo(false); @@ -443,7 +444,7 @@ void DebugDeferredBuffer::run(const RenderContextPointer& renderContext, const I auto lightStage = renderContext->_scene->getStage(); assert(lightStage); assert(lightStage->getNumLights() > 0); - auto lightAndShadow = lightStage->getCurrentKeyLightAndShadow(); + auto lightAndShadow = lightStage->getCurrentKeyLightAndShadow(*lightFrame); const auto& globalShadow = lightAndShadow.second; if (globalShadow) { batch.setResourceTexture(Textures::Shadow, globalShadow->map); diff --git a/libraries/render-utils/src/DebugDeferredBuffer.h b/libraries/render-utils/src/DebugDeferredBuffer.h index 9daa8fd530..dba3ff8532 100644 --- a/libraries/render-utils/src/DebugDeferredBuffer.h +++ b/libraries/render-utils/src/DebugDeferredBuffer.h @@ -21,6 +21,8 @@ #include "AmbientOcclusionEffect.h" #include "VelocityBufferPass.h" +#include "LightStage.h" + class DebugDeferredBufferConfig : public render::Job::Config { Q_OBJECT Q_PROPERTY(bool enabled MEMBER enabled) @@ -39,12 +41,13 @@ signals: class DebugDeferredBuffer { public: - using Inputs = render::VaryingSet6; + DeferredFrameTransformPointer, + LightStage::FramePointer>; using Config = DebugDeferredBufferConfig; using JobModel = render::Job::ModelI; diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 3b23711a64..a10949e0e6 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -70,17 +70,22 @@ void DeferredLightingEffect::init() { loadLightProgram(shader::render_utils::program::local_lights_drawOutline, true, _localLightOutline, _localLightOutlineLocations); } +// FIXME: figure out how to move lightFrame into a varying in GeometryCache and RenderPipelines void DeferredLightingEffect::setupKeyLightBatch(const RenderArgs* args, gpu::Batch& batch) { + setupKeyLightBatch(args, batch, args->_scene->getStage()->_currentFrame); +} + +void DeferredLightingEffect::setupKeyLightBatch(const RenderArgs* args, gpu::Batch& batch, const LightStage::Frame& lightFrame) { PerformanceTimer perfTimer("DLE->setupBatch()"); graphics::LightPointer keySunLight; auto lightStage = args->_scene->getStage(); if (lightStage) { - keySunLight = lightStage->getCurrentKeyLight(); + keySunLight = lightStage->getCurrentKeyLight(lightFrame); } graphics::LightPointer keyAmbiLight; if (lightStage) { - keyAmbiLight = lightStage->getCurrentAmbientLight(); + keyAmbiLight = lightStage->getCurrentAmbientLight(lightFrame); } if (keySunLight) { @@ -361,12 +366,6 @@ void PrepareDeferred::run(const RenderContextPointer& renderContext, const Input // For the rest of the rendering, bind the lighting model batch.setUniformBuffer(ru::Buffer::LightModel, lightingModel->getParametersBuffer()); }); - - - // Prepare a fresh Light Frame - auto lightStage = renderContext->_scene->getStage(); - assert(lightStage); - lightStage->_currentFrame.clear(); } @@ -374,7 +373,8 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext, const DeferredFrameTransformPointer& frameTransform, const DeferredFramebufferPointer& deferredFramebuffer, const LightingModelPointer& lightingModel, - const graphics::HazePointer& haze, + const LightStage::FramePointer& lightFrame, + const HazeStage::FramePointer& hazeFrame, const SurfaceGeometryFramebufferPointer& surfaceGeometryFramebuffer, const AmbientOcclusionFramebufferPointer& ambientOcclusionFramebuffer, const SubsurfaceScatteringResourcePointer& subsurfaceScatteringResource, @@ -434,7 +434,7 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext, auto lightStage = renderContext->_scene->getStage(); assert(lightStage); assert(lightStage->getNumLights() > 0); - auto lightAndShadow = lightStage->getCurrentKeyLightAndShadow(); + auto lightAndShadow = lightStage->getCurrentKeyLightAndShadow(*lightFrame); const auto& globalShadow = lightAndShadow.second; // Bind the shadow buffers @@ -448,8 +448,8 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext, auto keyLight = lightAndShadow.first; graphics::LightPointer ambientLight; - if (lightStage && lightStage->_currentFrame._ambientLights.size()) { - ambientLight = lightStage->getLight(lightStage->_currentFrame._ambientLights.front()); + if (lightStage && lightFrame->_ambientLights.size()) { + ambientLight = lightStage->getLight(lightFrame->_ambientLights.front()); } bool hasAmbientMap = (ambientLight != nullptr); @@ -458,8 +458,8 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext, // Check if keylight casts shadows bool keyLightCastShadows { false }; - if (renderShadows && lightStage && lightStage->_currentFrame._sunLights.size()) { - graphics::LightPointer keyLight = lightStage->getLight(lightStage->_currentFrame._sunLights.front()); + if (renderShadows && lightStage && lightFrame->_sunLights.size()) { + graphics::LightPointer keyLight = lightStage->getLight(lightFrame->_sunLights.front()); if (keyLight) { keyLightCastShadows = keyLight->getCastShadows(); } @@ -496,13 +496,17 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext, } // Setup the global lighting - deferredLightingEffect->setupKeyLightBatch(args, batch); + deferredLightingEffect->setupKeyLightBatch(args, batch, *lightFrame); // Haze - if (haze) { - batch.setUniformBuffer(ru::Buffer::HazeParams, haze->getHazeParametersBuffer()); + const auto& hazeStage = args->_scene->getStage(); + if (hazeStage && hazeFrame->_hazes.size() > 0) { + const auto& hazePointer = hazeStage->getHaze(hazeFrame->_hazes.front()); + if (hazePointer) { + batch.setUniformBuffer(ru::Buffer::HazeParams, hazePointer->getHazeParametersBuffer()); + } } - + batch.draw(gpu::TRIANGLE_STRIP, 4); deferredLightingEffect->unsetKeyLightBatch(batch); @@ -617,7 +621,8 @@ void RenderDeferred::run(const RenderContextPointer& renderContext, const Inputs auto lightClusters = inputs.get6(); auto args = renderContext->args; - const auto haze = inputs.get7(); + const auto& lightFrame = inputs.get7(); + const auto& hazeFrame = inputs.get8(); if (!_gpuTimer) { _gpuTimer = std::make_shared < gpu::RangeTimer>(__FUNCTION__); @@ -626,10 +631,10 @@ void RenderDeferred::run(const RenderContextPointer& renderContext, const Inputs auto previousBatch = args->_batch; gpu::doInBatch(nullptr, args->_context, [&](gpu::Batch& batch) { args->_batch = &batch; - _gpuTimer->begin(batch); + _gpuTimer->begin(batch); + + setupJob.run(renderContext, deferredTransform, deferredFramebuffer, lightingModel, lightFrame, hazeFrame, surfaceGeometryFramebuffer, ssaoFramebuffer, subsurfaceScatteringResource, _renderShadows); - setupJob.run(renderContext, deferredTransform, deferredFramebuffer, lightingModel, haze, surfaceGeometryFramebuffer, ssaoFramebuffer, subsurfaceScatteringResource, _renderShadows); - lightsJob.run(renderContext, deferredTransform, deferredFramebuffer, lightingModel, surfaceGeometryFramebuffer, lightClusters); cleanupJob.run(renderContext); @@ -647,19 +652,18 @@ void RenderDeferred::run(const RenderContextPointer& renderContext, const Inputs void DefaultLightingSetup::run(const RenderContextPointer& renderContext) { if (!_defaultLight || !_defaultBackground) { - if (!_defaultSkyboxTexture) { - auto textureCache = DependencyManager::get(); - { - PROFILE_RANGE(render, "Process Default Skybox"); - QFileSelector fileSelector; - fileSelector.setExtraSelectors(FileUtils::getFileSelectors()); - auto skyboxUrl = fileSelector.select(PathUtils::resourcesPath() + "images/Default-Sky-9-cubemap.ktx"); + if (!_defaultSkyboxNetworkTexture) { + PROFILE_RANGE(render, "Process Default Skybox"); + _defaultSkyboxNetworkTexture = DependencyManager::get()->getTexture( + PathUtils::resourcesUrl() + "images/Default-Sky-9-cubemap/Default-Sky-9-cubemap.texmeta.json", image::TextureUsage::CUBE_TEXTURE); + } - _defaultSkyboxTexture = gpu::Texture::unserialize(skyboxUrl.toStdString()); - _defaultSkyboxAmbientTexture = _defaultSkyboxTexture; - - _defaultSkybox->setCubemap(_defaultSkyboxTexture); - } + if (_defaultSkyboxNetworkTexture && _defaultSkyboxNetworkTexture->isLoaded() && _defaultSkyboxNetworkTexture->getGPUTexture()) { + _defaultSkyboxAmbientTexture = _defaultSkyboxNetworkTexture->getGPUTexture(); + _defaultSkybox->setCubemap(_defaultSkyboxAmbientTexture); + } else { + // Don't do anything until the skybox has loaded + return; } auto lightStage = renderContext->_scene->getStage(); diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index 70bfb65f38..a838d0c4d6 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -49,6 +49,7 @@ public: void init(); static void setupKeyLightBatch(const RenderArgs* args, gpu::Batch& batch); + static void setupKeyLightBatch(const RenderArgs* args, gpu::Batch& batch, const LightStage::Frame& lightFrame); static void unsetKeyLightBatch(gpu::Batch& batch); static void setupLocalLightsBatch(gpu::Batch& batch, const LightClustersPointer& lightClusters); @@ -139,13 +140,13 @@ public: class RenderDeferredSetup { public: - // using JobModel = render::Job::ModelI; - + void run(const render::RenderContextPointer& renderContext, const DeferredFrameTransformPointer& frameTransform, const DeferredFramebufferPointer& deferredFramebuffer, const LightingModelPointer& lightingModel, - const graphics::HazePointer& haze, + const LightStage::FramePointer& lightFrame, + const HazeStage::FramePointer& hazeFrame, const SurfaceGeometryFramebufferPointer& surfaceGeometryFramebuffer, const AmbientOcclusionFramebufferPointer& ambientOcclusionFramebuffer, const SubsurfaceScatteringResourcePointer& subsurfaceScatteringResource, @@ -181,9 +182,9 @@ using RenderDeferredConfig = render::GPUJobConfig; class RenderDeferred { public: - using Inputs = render::VaryingSet8 < + using Inputs = render::VaryingSet9< DeferredFrameTransformPointer, DeferredFramebufferPointer, LightingModelPointer, SurfaceGeometryFramebufferPointer, - AmbientOcclusionFramebufferPointer, SubsurfaceScatteringResourcePointer, LightClustersPointer, graphics::HazePointer>; + AmbientOcclusionFramebufferPointer, SubsurfaceScatteringResourcePointer, LightClustersPointer, LightStage::FramePointer, HazeStage::FramePointer>; using Config = RenderDeferredConfig; using JobModel = render::Job::ModelI; @@ -220,7 +221,7 @@ protected: graphics::HazePointer _defaultHaze{ nullptr }; HazeStage::Index _defaultHazeID{ HazeStage::INVALID_INDEX }; graphics::SkyboxPointer _defaultSkybox { new ProceduralSkybox() }; - gpu::TexturePointer _defaultSkyboxTexture; + NetworkTexturePointer _defaultSkyboxNetworkTexture; gpu::TexturePointer _defaultSkyboxAmbientTexture; }; diff --git a/libraries/render-utils/src/DrawHaze.cpp b/libraries/render-utils/src/DrawHaze.cpp index 538a916a06..db80cbecae 100644 --- a/libraries/render-utils/src/DrawHaze.cpp +++ b/libraries/render-utils/src/DrawHaze.cpp @@ -19,7 +19,6 @@ #include "StencilMaskPass.h" #include "FramebufferCache.h" -#include "HazeStage.h" #include "LightStage.h" namespace ru { @@ -32,98 +31,15 @@ namespace gr { using graphics::slot::buffer::Buffer; } -void HazeConfig::setHazeColor(const glm::vec3 value) { - hazeColor = value; -} - -void HazeConfig::setHazeGlareAngle(const float value) { - hazeGlareAngle = value; -} - -void HazeConfig::setHazeGlareColor(const glm::vec3 value) { - hazeGlareColor = value; -} - -void HazeConfig::setHazeBaseReference(const float value) { - hazeBaseReference = value; -} - -void HazeConfig::setHazeActive(const bool active) { - isHazeActive = active; -} - -void HazeConfig::setAltitudeBased(const bool active) { - isAltitudeBased = active; -} - -void HazeConfig::setHazeAttenuateKeyLight(const bool active) { - isHazeAttenuateKeyLight = active; -} - -void HazeConfig::setModulateColorActive(const bool active) { - isModulateColorActive = active; -} - -void HazeConfig::setHazeEnableGlare(const bool active) { - isHazeEnableGlare = active; -} - -void HazeConfig::setHazeRange(const float value) { - hazeRange = value; -} - -void HazeConfig::setHazeAltitude(const float value) { - hazeHeight = value; -} - -void HazeConfig::setHazeKeyLightRange(const float value) { - hazeKeyLightRange = value; -} - -void HazeConfig::setHazeKeyLightAltitude(const float value) { - hazeKeyLightAltitude = value; -} - -void HazeConfig::setHazeBackgroundBlend(const float value) { - hazeBackgroundBlend = value; -} - -MakeHaze::MakeHaze() { - _haze = std::make_shared(); -} - -void MakeHaze::configure(const Config& config) { - _haze->setHazeColor(config.hazeColor); - _haze->setHazeGlareBlend(graphics::Haze::convertGlareAngleToPower(config.hazeGlareAngle)); - - _haze->setHazeGlareColor(config.hazeGlareColor); - _haze->setHazeBaseReference(config.hazeBaseReference); - - _haze->setHazeActive(config.isHazeActive); - _haze->setAltitudeBased(config.isAltitudeBased); - _haze->setHazeAttenuateKeyLight(config.isHazeAttenuateKeyLight); - _haze->setModulateColorActive(config.isModulateColorActive); - _haze->setHazeEnableGlare(config.isHazeEnableGlare); - - _haze->setHazeRangeFactor(graphics::Haze::convertHazeRangeToHazeRangeFactor(config.hazeRange)); - _haze->setHazeAltitudeFactor(graphics::Haze::convertHazeAltitudeToHazeAltitudeFactor(config.hazeHeight)); - - _haze->setHazeKeyLightRangeFactor(graphics::Haze::convertHazeRangeToHazeRangeFactor(config.hazeKeyLightRange)); - _haze->setHazeKeyLightAltitudeFactor(graphics::Haze::convertHazeAltitudeToHazeAltitudeFactor(config.hazeKeyLightAltitude)); - - _haze->setHazeBackgroundBlend(config.hazeBackgroundBlend); -} - -void MakeHaze::run(const render::RenderContextPointer& renderContext, graphics::HazePointer& haze) { - haze = _haze; -} - -void DrawHaze::configure(const Config& config) { -} - void DrawHaze::run(const render::RenderContextPointer& renderContext, const Inputs& inputs) { - const auto haze = inputs.get0(); - if (haze == nullptr) { + const auto hazeFrame = inputs.get0(); + const auto& hazeStage = renderContext->args->_scene->getStage(); + graphics::HazePointer haze; + if (hazeStage && hazeFrame->_hazes.size() > 0) { + haze = hazeStage->getHaze(hazeFrame->_hazes.front()); + } + + if (!haze) { return; } @@ -131,6 +47,7 @@ void DrawHaze::run(const render::RenderContextPointer& renderContext, const Inpu const auto framebuffer = inputs.get2(); const auto transformBuffer = inputs.get3(); const auto lightingModel = inputs.get4(); + const auto lightFrame = inputs.get5(); auto depthBuffer = framebuffer->getLinearDepthTexture(); @@ -161,17 +78,7 @@ void DrawHaze::run(const render::RenderContextPointer& renderContext, const Inpu batch.setModelTransform(gpu::Framebuffer::evalSubregionTexcoordTransform(outputFramebufferSize, args->_viewport)); batch.setPipeline(_hazePipeline); - - auto hazeStage = args->_scene->getStage(); - if (hazeStage && hazeStage->_currentFrame._hazes.size() > 0) { - graphics::HazePointer hazePointer = hazeStage->getHaze(hazeStage->_currentFrame._hazes.front()); - if (hazePointer) { - batch.setUniformBuffer(ru::Buffer::HazeParams, hazePointer->getHazeParametersBuffer()); - } else { - // Something is wrong, so just quit Haze - return; - } - } + batch.setUniformBuffer(ru::Buffer::HazeParams, haze->getHazeParametersBuffer()); batch.setUniformBuffer(ru::Buffer::DeferredFrameTransform, transformBuffer->getFrameTransformBuffer()); batch.setUniformBuffer(ru::Buffer::LightModel, lightingModel->getParametersBuffer()); @@ -179,13 +86,12 @@ void DrawHaze::run(const render::RenderContextPointer& renderContext, const Inpu auto lightStage = args->_scene->getStage(); if (lightStage) { graphics::LightPointer keyLight; - keyLight = lightStage->getCurrentKeyLight(); + keyLight = lightStage->getCurrentKeyLight(*lightFrame); if (keyLight) { batch.setUniformBuffer(gr::Buffer::KeyLight, keyLight->getLightSchemaBuffer()); } } - batch.draw(gpu::TRIANGLE_STRIP, 4); }); } diff --git a/libraries/render-utils/src/DrawHaze.h b/libraries/render-utils/src/DrawHaze.h index e30ce26dd4..9236543068 100644 --- a/libraries/render-utils/src/DrawHaze.h +++ b/libraries/render-utils/src/DrawHaze.h @@ -19,152 +19,20 @@ #include #include #include -#include #include "SurfaceGeometryPass.h" #include "LightingModel.h" +#include "HazeStage.h" +#include "LightStage.h" + using LinearDepthFramebufferPointer = std::shared_ptr; -class MakeHazeConfig : public render::Job::Config { - Q_OBJECT - - Q_PROPERTY(glm::vec3 hazeColor MEMBER hazeColor WRITE setHazeColor NOTIFY dirty); - Q_PROPERTY(float hazeGlareAngle MEMBER hazeGlareAngle WRITE setHazeGlareAngle NOTIFY dirty); - - Q_PROPERTY(glm::vec3 hazeGlareColor MEMBER hazeGlareColor WRITE setHazeGlareColor NOTIFY dirty); - Q_PROPERTY(float hazeBaseReference MEMBER hazeBaseReference WRITE setHazeBaseReference NOTIFY dirty); - - Q_PROPERTY(bool isHazeActive MEMBER isHazeActive WRITE setHazeActive NOTIFY dirty); - Q_PROPERTY(bool isAltitudeBased MEMBER isAltitudeBased WRITE setAltitudeBased NOTIFY dirty); - Q_PROPERTY(bool isHazeAttenuateKeyLight MEMBER isHazeAttenuateKeyLight WRITE setHazeAttenuateKeyLight NOTIFY dirty); - Q_PROPERTY(bool isModulateColorActive MEMBER isModulateColorActive WRITE setModulateColorActive NOTIFY dirty); - Q_PROPERTY(bool isHazeEnableGlare MEMBER isHazeEnableGlare WRITE setHazeEnableGlare NOTIFY dirty); - - Q_PROPERTY(float hazeRange MEMBER hazeRange WRITE setHazeRange NOTIFY dirty); - Q_PROPERTY(float hazeHeight MEMBER hazeHeight WRITE setHazeAltitude NOTIFY dirty); - - Q_PROPERTY(float hazeKeyLightRange MEMBER hazeKeyLightRange WRITE setHazeKeyLightRange NOTIFY dirty); - Q_PROPERTY(float hazeKeyLightAltitude MEMBER hazeKeyLightAltitude WRITE setHazeKeyLightAltitude NOTIFY dirty); - - Q_PROPERTY(float hazeBackgroundBlend MEMBER hazeBackgroundBlend WRITE setHazeBackgroundBlend NOTIFY dirty); - -public: - MakeHazeConfig() : render::Job::Config() {} - - glm::vec3 hazeColor{ graphics::Haze::INITIAL_HAZE_COLOR }; - float hazeGlareAngle{ graphics::Haze::INITIAL_HAZE_GLARE_ANGLE }; - - glm::vec3 hazeGlareColor{ graphics::Haze::INITIAL_HAZE_GLARE_COLOR }; - float hazeBaseReference{ graphics::Haze::INITIAL_HAZE_BASE_REFERENCE }; - - bool isHazeActive{ false }; - bool isAltitudeBased{ false }; - bool isHazeAttenuateKeyLight{ false }; - bool isModulateColorActive{ false }; - bool isHazeEnableGlare{ false }; - - float hazeRange{ graphics::Haze::INITIAL_HAZE_RANGE }; - float hazeHeight{ graphics::Haze::INITIAL_HAZE_HEIGHT }; - - float hazeKeyLightRange{ graphics::Haze::INITIAL_KEY_LIGHT_RANGE }; - float hazeKeyLightAltitude{ graphics::Haze::INITIAL_KEY_LIGHT_ALTITUDE }; - - float hazeBackgroundBlend{ graphics::Haze::INITIAL_HAZE_BACKGROUND_BLEND }; - -public slots: - void setHazeColor(const glm::vec3 value) { hazeColor = value; emit dirty(); } - void setHazeGlareAngle(const float value) { hazeGlareAngle = value; emit dirty(); } - - void setHazeGlareColor(const glm::vec3 value) { hazeGlareColor = value; emit dirty(); } - void setHazeBaseReference(const float value) { hazeBaseReference = value; ; emit dirty(); } - - void setHazeActive(const bool active) { isHazeActive = active; emit dirty(); } - void setAltitudeBased(const bool active) { isAltitudeBased = active; emit dirty(); } - void setHazeAttenuateKeyLight(const bool active) { isHazeAttenuateKeyLight = active; emit dirty(); } - void setModulateColorActive(const bool active) { isModulateColorActive = active; emit dirty(); } - void setHazeEnableGlare(const bool active) { isHazeEnableGlare = active; emit dirty(); } - - void setHazeRange(const float value) { hazeRange = value; emit dirty(); } - void setHazeAltitude(const float value) { hazeHeight = value; emit dirty(); } - - void setHazeKeyLightRange(const float value) { hazeKeyLightRange = value; emit dirty(); } - void setHazeKeyLightAltitude(const float value) { hazeKeyLightAltitude = value; emit dirty(); } - - void setHazeBackgroundBlend(const float value) { hazeBackgroundBlend = value; ; emit dirty(); } - -signals: - void dirty(); -}; - -class MakeHaze { -public: - using Config = MakeHazeConfig; - using JobModel = render::Job::ModelO; - - MakeHaze(); - - void configure(const Config& config); - void run(const render::RenderContextPointer& renderContext, graphics::HazePointer& haze); - -private: - graphics::HazePointer _haze; -}; - -class HazeConfig : public render::Job::Config { -public: - HazeConfig() : render::Job::Config(true) {} - - // attributes - glm::vec3 hazeColor{ graphics::Haze::INITIAL_HAZE_COLOR }; - float hazeGlareAngle{ graphics::Haze::INITIAL_HAZE_GLARE_ANGLE }; - - glm::vec3 hazeGlareColor{ graphics::Haze::INITIAL_HAZE_GLARE_COLOR }; - float hazeBaseReference{ graphics::Haze::INITIAL_HAZE_BASE_REFERENCE }; - - bool isHazeActive{ false }; // Setting this to true will set haze to on - bool isAltitudeBased{ false }; - bool isHazeAttenuateKeyLight{ false }; - bool isModulateColorActive{ false }; - bool isHazeEnableGlare{ false }; - - float hazeRange{ graphics::Haze::INITIAL_HAZE_RANGE }; - float hazeHeight{ graphics::Haze::INITIAL_HAZE_HEIGHT }; - - float hazeKeyLightRange{ graphics::Haze::INITIAL_KEY_LIGHT_RANGE }; - float hazeKeyLightAltitude{ graphics::Haze::INITIAL_KEY_LIGHT_ALTITUDE }; - - float hazeBackgroundBlend{ graphics::Haze::INITIAL_HAZE_BACKGROUND_BLEND }; - - // methods - void setHazeColor(const glm::vec3 value); - void setHazeGlareAngle(const float value); - - void setHazeGlareColor(const glm::vec3 value); - void setHazeBaseReference(const float value); - - void setHazeActive(const bool active); - void setAltitudeBased(const bool active); - void setHazeAttenuateKeyLight(const bool active); - void setModulateColorActive(const bool active); - void setHazeEnableGlare(const bool active); - - void setHazeRange(const float value); - void setHazeAltitude(const float value); - - void setHazeKeyLightRange(const float value); - void setHazeKeyLightAltitude(const float value); - - void setHazeBackgroundBlend(const float value); -}; - class DrawHaze { public: - using Inputs = render::VaryingSet5; - using Config = HazeConfig; - using JobModel = render::Job::ModelI; + using Inputs = render::VaryingSet6; + using JobModel = render::Job::ModelI; - void configure(const Config& config); void run(const render::RenderContextPointer& renderContext, const Inputs& inputs); private: diff --git a/libraries/render-utils/src/HazeStage.cpp b/libraries/render-utils/src/HazeStage.cpp index e56b715b8c..c850828be5 100644 --- a/libraries/render-utils/src/HazeStage.cpp +++ b/libraries/render-utils/src/HazeStage.cpp @@ -16,32 +16,6 @@ std::string HazeStage::_stageName { "HAZE_STAGE"}; const HazeStage::Index HazeStage::INVALID_INDEX { render::indexed_container::INVALID_INDEX }; -FetchHazeStage::FetchHazeStage() { - _haze = std::make_shared(); -} - -void FetchHazeStage::configure(const Config& config) { - _haze->setHazeColor(config.hazeColor); - _haze->setHazeGlareBlend(graphics::Haze::convertGlareAngleToPower(config.hazeGlareAngle)); - - _haze->setHazeGlareColor(config.hazeGlareColor); - _haze->setHazeBaseReference(config.hazeBaseReference); - - _haze->setHazeActive(config.isHazeActive); - _haze->setAltitudeBased(config.isAltitudeBased); - _haze->setHazeAttenuateKeyLight(config.isHazeAttenuateKeyLight); - _haze->setModulateColorActive(config.isModulateColorActive); - _haze->setHazeEnableGlare(config.isHazeEnableGlare); - - _haze->setHazeRangeFactor(graphics::Haze::convertHazeRangeToHazeRangeFactor(config.hazeRange)); - _haze->setHazeAltitudeFactor(graphics::Haze::convertHazeAltitudeToHazeAltitudeFactor(config.hazeHeight)); - - _haze->setHazeKeyLightRangeFactor(graphics::Haze::convertHazeRangeToHazeRangeFactor(config.hazeKeyLightRange)); - _haze->setHazeKeyLightAltitudeFactor(graphics::Haze::convertHazeAltitudeToHazeAltitudeFactor(config.hazeKeyLightAltitude)); - - _haze->setHazeBackgroundBlend(config.hazeBackgroundBlend); -} - HazeStage::Index HazeStage::findHaze(const HazePointer& haze) const { auto found = _hazeMap.find(haze); if (found != _hazeMap.end()) { @@ -84,15 +58,4 @@ void HazeStageSetup::run(const render::RenderContextPointer& renderContext) { if (!stage) { renderContext->_scene->resetStage(HazeStage::getName(), std::make_shared()); } -} - -void FetchHazeStage::run(const render::RenderContextPointer& renderContext, graphics::HazePointer& haze) { - auto hazeStage = renderContext->_scene->getStage(); - assert(hazeStage); - - haze = nullptr; - if (hazeStage->_currentFrame._hazes.size() != 0) { - auto hazeId = hazeStage->_currentFrame._hazes.front(); - haze = hazeStage->getHaze(hazeId); - } -} +} \ No newline at end of file diff --git a/libraries/render-utils/src/HazeStage.h b/libraries/render-utils/src/HazeStage.h index b48168e376..b1c7d0384c 100644 --- a/libraries/render-utils/src/HazeStage.h +++ b/libraries/render-utils/src/HazeStage.h @@ -65,6 +65,7 @@ public: HazeStage::HazeIndices _hazes; }; + using FramePointer = std::shared_ptr; Frame _currentFrame; }; @@ -150,18 +151,4 @@ public slots: signals: void dirty(); }; - -class FetchHazeStage { -public: - using Config = FetchHazeConfig; - using JobModel = render::Job::ModelO; - - FetchHazeStage(); - - void configure(const Config& config); - void run(const render::RenderContextPointer& renderContext, graphics::HazePointer& haze); - -private: - graphics::HazePointer _haze; -}; #endif diff --git a/libraries/render-utils/src/LightClusters.cpp b/libraries/render-utils/src/LightClusters.cpp index ae484f868f..252416ea9d 100644 --- a/libraries/render-utils/src/LightClusters.cpp +++ b/libraries/render-utils/src/LightClusters.cpp @@ -175,15 +175,15 @@ void LightClusters::updateLightStage(const LightStagePointer& lightStage) { } -void LightClusters::updateLightFrame(const LightStage::Frame& lightFrame, bool points, bool spots) { +void LightClusters::updateLightFrame(const LightStage::FramePointer& lightFrame, bool points, bool spots) { // start fresh _visibleLightIndices.clear(); // Now gather the lights // gather lights - auto& srcPointLights = lightFrame._pointLights; - auto& srcSpotLights = lightFrame._spotLights; + auto& srcPointLights = lightFrame->_pointLights; + auto& srcSpotLights = lightFrame->_spotLights; int numPointLights = (int)srcPointLights.size(); int numSpotLights = (int)srcSpotLights.size(); @@ -548,7 +548,8 @@ void LightClusteringPass::run(const render::RenderContextPointer& renderContext, auto deferredTransform = inputs.get0(); auto lightingModel = inputs.get1(); - auto surfaceGeometryFramebuffer = inputs.get2(); + auto lightFrame = inputs.get2(); + auto surfaceGeometryFramebuffer = inputs.get3(); // first update the Grid with the new frustum if (!_freeze) { @@ -559,7 +560,7 @@ void LightClusteringPass::run(const render::RenderContextPointer& renderContext, auto lightStage = renderContext->_scene->getStage(); assert(lightStage); _lightClusters->updateLightStage(lightStage); - _lightClusters->updateLightFrame(lightStage->_currentFrame, lightingModel->isPointLightEnabled(), lightingModel->isSpotLightEnabled()); + _lightClusters->updateLightFrame(lightFrame, lightingModel->isPointLightEnabled(), lightingModel->isSpotLightEnabled()); auto clusteringStats = _lightClusters->updateClusters(); diff --git a/libraries/render-utils/src/LightClusters.h b/libraries/render-utils/src/LightClusters.h index fa054c304a..e109e43aaa 100644 --- a/libraries/render-utils/src/LightClusters.h +++ b/libraries/render-utils/src/LightClusters.h @@ -79,7 +79,7 @@ public: void updateLightStage(const LightStagePointer& lightStage); - void updateLightFrame(const LightStage::Frame& lightFrame, bool points = true, bool spots = true); + void updateLightFrame(const LightStage::FramePointer& lightFrame, bool points = true, bool spots = true); glm::ivec3 updateClusters(); @@ -167,7 +167,7 @@ protected: class LightClusteringPass { public: - using Inputs = render::VaryingSet3; + using Inputs = render::VaryingSet4; using Outputs = LightClustersPointer; using Config = LightClusteringPassConfig; using JobModel = render::Job::ModelIO; diff --git a/libraries/render-utils/src/LightStage.cpp b/libraries/render-utils/src/LightStage.cpp index 369c62c197..ccedb0cd7b 100644 --- a/libraries/render-utils/src/LightStage.cpp +++ b/libraries/render-utils/src/LightStage.cpp @@ -372,36 +372,36 @@ LightStage::LightPointer LightStage::removeLight(Index index) { return removedLight; } -LightStage::LightPointer LightStage::getCurrentKeyLight() const { - Index keyLightId{ _defaultLightId }; - if (!_currentFrame._sunLights.empty()) { - keyLightId = _currentFrame._sunLights.front(); +LightStage::LightPointer LightStage::getCurrentKeyLight(const LightStage::Frame& frame) const { + Index keyLightId { _defaultLightId }; + if (!frame._sunLights.empty()) { + keyLightId = frame._sunLights.front(); } return _lights.get(keyLightId); } -LightStage::LightPointer LightStage::getCurrentAmbientLight() const { +LightStage::LightPointer LightStage::getCurrentAmbientLight(const LightStage::Frame& frame) const { Index keyLightId { _defaultLightId }; - if (!_currentFrame._ambientLights.empty()) { - keyLightId = _currentFrame._ambientLights.front(); + if (!frame._ambientLights.empty()) { + keyLightId = frame._ambientLights.front(); } return _lights.get(keyLightId); } -LightStage::ShadowPointer LightStage::getCurrentKeyShadow() const { +LightStage::ShadowPointer LightStage::getCurrentKeyShadow(const LightStage::Frame& frame) const { Index keyLightId { _defaultLightId }; - if (!_currentFrame._sunLights.empty()) { - keyLightId = _currentFrame._sunLights.front(); + if (!frame._sunLights.empty()) { + keyLightId = frame._sunLights.front(); } auto shadow = getShadow(keyLightId); assert(shadow == nullptr || shadow->getLight() == getLight(keyLightId)); return shadow; } -LightStage::LightAndShadow LightStage::getCurrentKeyLightAndShadow() const { +LightStage::LightAndShadow LightStage::getCurrentKeyLightAndShadow(const LightStage::Frame& frame) const { Index keyLightId { _defaultLightId }; - if (!_currentFrame._sunLights.empty()) { - keyLightId = _currentFrame._sunLights.front(); + if (!frame._sunLights.empty()) { + keyLightId = frame._sunLights.front(); } auto shadow = getShadow(keyLightId); auto light = getLight(keyLightId); diff --git a/libraries/render-utils/src/LightStage.h b/libraries/render-utils/src/LightStage.h index b8a49d81bb..5e5b6cf4fa 100644 --- a/libraries/render-utils/src/LightStage.h +++ b/libraries/render-utils/src/LightStage.h @@ -151,11 +151,6 @@ public: return LightAndShadow(light, shadow); } - LightPointer getCurrentKeyLight() const; - LightPointer getCurrentAmbientLight() const; - ShadowPointer getCurrentKeyShadow() const; - LightAndShadow getCurrentKeyLightAndShadow() const; - LightStage(); gpu::BufferPointer getLightArrayBuffer() const { return _lightArrayBuffer; } @@ -185,6 +180,7 @@ public: LightStage::LightIndices _sunLights; LightStage::LightIndices _ambientLights; }; + using FramePointer = std::shared_ptr; Frame _currentFrame; @@ -193,6 +189,11 @@ public: Index getSpotOffLight() { return _spotOffLightId; } Index getSunOffLight() { return _sunOffLightId; } + LightPointer getCurrentKeyLight(const LightStage::Frame& frame) const; + LightPointer getCurrentAmbientLight(const LightStage::Frame& frame) const; + ShadowPointer getCurrentKeyShadow(const LightStage::Frame& frame) const; + LightAndShadow getCurrentKeyLightAndShadow(const LightStage::Frame& frame) const; + protected: struct Desc { diff --git a/libraries/render-utils/src/RenderCommonTask.cpp b/libraries/render-utils/src/RenderCommonTask.cpp index 9aee0e57a4..4422d15d5c 100644 --- a/libraries/render-utils/src/RenderCommonTask.cpp +++ b/libraries/render-utils/src/RenderCommonTask.cpp @@ -197,12 +197,14 @@ void Blit::run(const RenderContextPointer& renderContext, const gpu::Framebuffer }); } -void ExtractFrustums::run(const render::RenderContextPointer& renderContext, Output& output) { +void ExtractFrustums::run(const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& output) { assert(renderContext->args); assert(renderContext->args->_context); RenderArgs* args = renderContext->args; + const auto& lightFrame = inputs; + // Return view frustum auto& viewFrustum = output[VIEW_FRUSTUM].edit(); if (!viewFrustum) { @@ -216,7 +218,7 @@ void ExtractFrustums::run(const render::RenderContextPointer& renderContext, Out for (auto i = 0; i < SHADOW_CASCADE_FRUSTUM_COUNT; i++) { auto& shadowFrustum = output[SHADOW_CASCADE0_FRUSTUM+i].edit(); if (lightStage) { - auto globalShadow = lightStage->getCurrentKeyShadow(); + auto globalShadow = lightStage->getCurrentKeyShadow(*lightFrame); if (globalShadow && i<(int)globalShadow->getCascadeCount()) { auto& cascade = globalShadow->getCascade(i); @@ -229,3 +231,21 @@ void ExtractFrustums::run(const render::RenderContextPointer& renderContext, Out } } } + +void FetchCurrentFrames::run(const render::RenderContextPointer& renderContext, Outputs& outputs) { + auto lightStage = renderContext->_scene->getStage(); + assert(lightStage); + outputs.edit0() = std::make_shared(lightStage->_currentFrame); + + auto backgroundStage = renderContext->_scene->getStage(); + assert(backgroundStage); + outputs.edit1() = std::make_shared(backgroundStage->_currentFrame); + + auto hazeStage = renderContext->_scene->getStage(); + assert(hazeStage); + outputs.edit2() = std::make_shared(hazeStage->_currentFrame); + + auto bloomStage = renderContext->_scene->getStage(); + assert(bloomStage); + outputs.edit3() = std::make_shared(bloomStage->_currentFrame); +} diff --git a/libraries/render-utils/src/RenderCommonTask.h b/libraries/render-utils/src/RenderCommonTask.h index 65f8cdfbfc..9b611bc38d 100644 --- a/libraries/render-utils/src/RenderCommonTask.h +++ b/libraries/render-utils/src/RenderCommonTask.h @@ -13,6 +13,11 @@ #include #include "LightingModel.h" +#include "LightStage.h" +#include "BackgroundStage.h" +#include "HazeStage.h" +#include "BloomStage.h" + class BeginGPURangeTimer { public: using JobModel = render::Job::ModelO; @@ -106,10 +111,22 @@ public: FRUSTUM_COUNT }; - using Output = render::VaryingArray; - using JobModel = render::Job::ModelO; + using Inputs = LightStage::FramePointer; + using Outputs = render::VaryingArray; + using JobModel = render::Job::ModelIO; - void run(const render::RenderContextPointer& renderContext, Output& output); + void run(const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& output); +}; + + +class FetchCurrentFrames { +public: + using Outputs = render::VaryingSet4; + using JobModel = render::Job::ModelO; + + FetchCurrentFrames() {} + + void run(const render::RenderContextPointer& renderContext, Outputs& outputs); }; #endif // hifi_RenderDeferredTask_h diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 57f5c3ec34..4052b6bd5a 100644 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -180,29 +180,32 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren // Draw Lights just add the lights to the current list of lights to deal with. NOt really gpu job for now. task.addJob("DrawLight", lights); + // Fetch the current frame stacks from all the stages + const auto currentFrames = task.addJob("FetchCurrentFrames"); + const auto lightFrame = currentFrames.getN(0); + const auto backgroundFrame = currentFrames.getN(1); + const auto hazeFrame = currentFrames.getN(2); + const auto bloomFrame = currentFrames.getN(3); + // Light Clustering // Create the cluster grid of lights, cpu job for now - const auto lightClusteringPassInputs = LightClusteringPass::Inputs(deferredFrameTransform, lightingModel, linearDepthTarget).asVarying(); + const auto lightClusteringPassInputs = LightClusteringPass::Inputs(deferredFrameTransform, lightingModel, lightFrame, linearDepthTarget).asVarying(); const auto lightClusters = task.addJob("LightClustering", lightClusteringPassInputs); - - // Add haze model - const auto hazeModel = task.addJob("HazeModel"); // DeferredBuffer is complete, now let's shade it into the LightingBuffer const auto deferredLightingInputs = RenderDeferred::Inputs(deferredFrameTransform, deferredFramebuffer, lightingModel, - surfaceGeometryFramebuffer, ambientOcclusionFramebuffer, scatteringResource, lightClusters, hazeModel).asVarying(); - + surfaceGeometryFramebuffer, ambientOcclusionFramebuffer, scatteringResource, lightClusters, lightFrame, hazeFrame).asVarying(); task.addJob("RenderDeferred", deferredLightingInputs, renderShadows); - // Similar to light stage, background stage has been filled by several potential render items and resolved for the frame in this job - task.addJob("DrawBackgroundDeferred", lightingModel); + const auto backgroundInputs = DrawBackgroundStage::Inputs(lightingModel, backgroundFrame).asVarying(); + task.addJob("DrawBackgroundDeferred", backgroundInputs); - const auto drawHazeInputs = render::Varying(DrawHaze::Inputs(hazeModel, lightingFramebuffer, linearDepthTarget, deferredFrameTransform, lightingModel)); + const auto drawHazeInputs = render::Varying(DrawHaze::Inputs(hazeFrame, lightingFramebuffer, linearDepthTarget, deferredFrameTransform, lightingModel, lightFrame)); task.addJob("DrawHazeDeferred", drawHazeInputs); // Render transparent objects forward in LightingBuffer - const auto transparentsInputs = DrawDeferred::Inputs(transparents, lightingModel, lightClusters, jitter).asVarying(); + const auto transparentsInputs = DrawDeferred::Inputs(transparents, hazeFrame, lightFrame, lightingModel, lightClusters, jitter).asVarying(); task.addJob("DrawTransparentDeferred", transparentsInputs, shapePlumber); // Light Cluster Grid Debuging job @@ -246,8 +249,7 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren task.addJob("Antialiasing", antialiasingInputs); // Add bloom - const auto bloomModel = task.addJob("BloomModel"); - const auto bloomInputs = BloomEffect::Inputs(deferredFrameTransform, lightingFramebuffer, bloomModel).asVarying(); + const auto bloomInputs = BloomEffect::Inputs(deferredFrameTransform, lightingFramebuffer, bloomFrame).asVarying(); task.addJob("Bloom", bloomInputs); // Lighting Buffer ready for tone mapping @@ -261,11 +263,11 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren task.addJob("DrawLightBounds", lights); task.addJob("DrawZones", zones); - const auto frustums = task.addJob("ExtractFrustums"); - const auto viewFrustum = frustums.getN(ExtractFrustums::VIEW_FRUSTUM); + const auto frustums = task.addJob("ExtractFrustums", lightFrame); + const auto viewFrustum = frustums.getN(ExtractFrustums::VIEW_FRUSTUM); task.addJob("DrawViewFrustum", viewFrustum, glm::vec3(0.0f, 1.0f, 0.0f)); for (auto i = 0; i < ExtractFrustums::SHADOW_CASCADE_FRUSTUM_COUNT; i++) { - const auto shadowFrustum = frustums.getN(ExtractFrustums::SHADOW_CASCADE0_FRUSTUM + i); + const auto shadowFrustum = frustums.getN(ExtractFrustums::SHADOW_CASCADE0_FRUSTUM + i); float tint = 1.0f - i / float(ExtractFrustums::SHADOW_CASCADE_FRUSTUM_COUNT - 1); char jobName[64]; sprintf(jobName, "DrawShadowFrustum%d", i); @@ -290,7 +292,7 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren // Debugging stages { // Debugging Deferred buffer job - const auto debugFramebuffers = render::Varying(DebugDeferredBuffer::Inputs(deferredFramebuffer, linearDepthTarget, surfaceGeometryFramebuffer, ambientOcclusionFramebuffer, velocityBuffer, deferredFrameTransform)); + const auto debugFramebuffers = render::Varying(DebugDeferredBuffer::Inputs(deferredFramebuffer, linearDepthTarget, surfaceGeometryFramebuffer, ambientOcclusionFramebuffer, velocityBuffer, deferredFrameTransform, lightFrame)); task.addJob("DebugDeferredBuffer", debugFramebuffers); const auto debugSubsurfaceScatteringInputs = DebugSubsurfaceScattering::Inputs(deferredFrameTransform, deferredFramebuffer, lightingModel, @@ -315,7 +317,8 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren task.addJob("DrawStatus", drawStatusInputs, DrawStatus(statusIconMap)); } - task.addJob("DrawZoneStack", deferredFrameTransform); + const auto debugZoneInputs = DebugZoneLighting::Inputs(deferredFrameTransform, lightFrame, backgroundFrame).asVarying(); + task.addJob("DrawZoneStack", debugZoneInputs); } // Upscale to finale resolution @@ -351,9 +354,11 @@ void DrawDeferred::run(const RenderContextPointer& renderContext, const Inputs& auto config = std::static_pointer_cast(renderContext->jobConfig); const auto& inItems = inputs.get0(); - const auto& lightingModel = inputs.get1(); - const auto& lightClusters = inputs.get2(); - const auto jitter = inputs.get3(); + const auto& hazeFrame = inputs.get1(); + const auto& lightFrame = inputs.get2(); + const auto& lightingModel = inputs.get3(); + const auto& lightClusters = inputs.get4(); + const auto jitter = inputs.get5(); auto deferredLightingEffect = DependencyManager::get(); RenderArgs* args = renderContext->args; @@ -378,13 +383,13 @@ void DrawDeferred::run(const RenderContextPointer& renderContext, const Inputs& batch.setUniformBuffer(ru::Buffer::LightModel, lightingModel->getParametersBuffer()); // Set the light - deferredLightingEffect->setupKeyLightBatch(args, batch); + deferredLightingEffect->setupKeyLightBatch(args, batch, *lightFrame); deferredLightingEffect->setupLocalLightsBatch(batch, lightClusters); // Setup haze if current zone has haze - auto hazeStage = args->_scene->getStage(); - if (hazeStage && hazeStage->_currentFrame._hazes.size() > 0) { - graphics::HazePointer hazePointer = hazeStage->getHaze(hazeStage->_currentFrame._hazes.front()); + const auto& hazeStage = args->_scene->getStage(); + if (hazeStage && hazeFrame->_hazes.size() > 0) { + const auto& hazePointer = hazeStage->getHaze(hazeFrame->_hazes.front()); if (hazePointer) { batch.setUniformBuffer(ru::Buffer::HazeParams, hazePointer->getHazeParametersBuffer()); } diff --git a/libraries/render-utils/src/RenderDeferredTask.h b/libraries/render-utils/src/RenderDeferredTask.h index 161a14c943..c18daa6d3d 100644 --- a/libraries/render-utils/src/RenderDeferredTask.h +++ b/libraries/render-utils/src/RenderDeferredTask.h @@ -17,6 +17,7 @@ #include "LightingModel.h" #include "LightClusters.h" #include "RenderShadowTask.h" +#include "HazeStage.h" class DrawDeferredConfig : public render::Job::Config { Q_OBJECT @@ -42,7 +43,7 @@ protected: class DrawDeferred { public: - using Inputs = render::VaryingSet4; + using Inputs = render::VaryingSet6; using Config = DrawDeferredConfig; using JobModel = render::Job::ModelI; diff --git a/libraries/render-utils/src/RenderForwardTask.cpp b/libraries/render-utils/src/RenderForwardTask.cpp index 9ab60786b5..53f89aaec3 100755 --- a/libraries/render-utils/src/RenderForwardTask.cpp +++ b/libraries/render-utils/src/RenderForwardTask.cpp @@ -32,7 +32,6 @@ #include "FramebufferCache.h" #include "TextureCache.h" #include "RenderCommonTask.h" -#include "LightStage.h" namespace ru { using render_utils::slot::texture::Texture; @@ -59,13 +58,13 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend // Extract opaques / transparents / lights / metas / overlays / background const auto& opaques = items.get0()[RenderFetchCullSortTask::OPAQUE_SHAPE]; const auto& transparents = items.get0()[RenderFetchCullSortTask::TRANSPARENT_SHAPE]; - // const auto& lights = items.get0()[RenderFetchCullSortTask::LIGHT]; + //const auto& lights = items.get0()[RenderFetchCullSortTask::LIGHT]; const auto& metas = items.get0()[RenderFetchCullSortTask::META]; const auto& overlayOpaques = items.get0()[RenderFetchCullSortTask::OVERLAY_OPAQUE_SHAPE]; const auto& overlayTransparents = items.get0()[RenderFetchCullSortTask::OVERLAY_TRANSPARENT_SHAPE]; //const auto& background = items.get0()[RenderFetchCullSortTask::BACKGROUND]; - // const auto& spatialSelection = items[1]; + //const auto& spatialSelection = items[1]; fadeEffect->build(task, opaques); @@ -76,10 +75,17 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend // Filter zones from the general metas bucket const auto zones = task.addJob("ZoneRenderer", metas); + // Fetch the current frame stacks from all the stages + const auto currentFrames = task.addJob("FetchCurrentFrames"); + const auto lightFrame = currentFrames.getN(0); + const auto backgroundFrame = currentFrames.getN(1); + //const auto hazeFrame = currentFrames.getN(2); + //const auto bloomFrame = currentFrames.getN(3); + // GPU jobs: Start preparing the main framebuffer const auto framebuffer = task.addJob("PrepareFramebuffer"); - task.addJob("PrepareForward", lightingModel); + task.addJob("PrepareForward", lightFrame); // draw a stencil mask in hidden regions of the framebuffer. task.addJob("PrepareStencil", framebuffer); @@ -101,7 +107,8 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend task.addJob("DrawOpaques", opaqueInputs, shapePlumber); // Similar to light stage, background stage has been filled by several potential render items and resolved for the frame in this job - task.addJob("DrawBackgroundDeferred", lightingModel); + const auto backgroundInputs = DrawBackgroundStage::Inputs(lightingModel, backgroundFrame).asVarying(); + task.addJob("DrawBackgroundForward", backgroundInputs); // Draw transparent objects forward const auto transparentInputs = DrawForward::Inputs(transparents, lightingModel).asVarying(); @@ -114,8 +121,8 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend task.addJob("DrawTransparentBounds", transparents); task.addJob("DrawZones", zones); - task.addJob("DrawZoneStack", deferredFrameTransform); - + const auto debugZoneInputs = DebugZoneLighting::Inputs(deferredFrameTransform, lightFrame, backgroundFrame).asVarying(); + task.addJob("DrawZoneStack", debugZoneInputs); } // Lighting Buffer ready for tone mapping @@ -180,12 +187,12 @@ void PrepareForward::run(const RenderContextPointer& renderContext, const Inputs graphics::LightPointer keySunLight; auto lightStage = args->_scene->getStage(); if (lightStage) { - keySunLight = lightStage->getCurrentKeyLight(); + keySunLight = lightStage->getCurrentKeyLight(*inputs); } graphics::LightPointer keyAmbiLight; if (lightStage) { - keyAmbiLight = lightStage->getCurrentAmbientLight(); + keyAmbiLight = lightStage->getCurrentAmbientLight(*inputs); } if (keySunLight) { diff --git a/libraries/render-utils/src/RenderForwardTask.h b/libraries/render-utils/src/RenderForwardTask.h index 22e75d4bdc..54341d1ded 100755 --- a/libraries/render-utils/src/RenderForwardTask.h +++ b/libraries/render-utils/src/RenderForwardTask.h @@ -15,6 +15,7 @@ #include #include #include "LightingModel.h" +#include "LightStage.h" class RenderForwardTask { public: @@ -40,7 +41,7 @@ private: class PrepareForward { public: - using Inputs = LightingModelPointer; + using Inputs = LightStage::FramePointer; using JobModel = render::Job::ModelI; void run(const render::RenderContextPointer& renderContext, diff --git a/libraries/render-utils/src/RenderShadowTask.cpp b/libraries/render-utils/src/RenderShadowTask.cpp index 7c24c08c27..c4fa297965 100644 --- a/libraries/render-utils/src/RenderShadowTask.cpp +++ b/libraries/render-utils/src/RenderShadowTask.cpp @@ -24,6 +24,8 @@ #include "RenderUtilsLogging.h" +#include "RenderCommonTask.h" + // These values are used for culling the objects rendered in the shadow map // but are readjusted afterwards #define SHADOW_FRUSTUM_NEAR 1.0f @@ -40,10 +42,6 @@ void RenderShadowTask::configure(const Config& configuration) { } void RenderShadowTask::build(JobModel& task, const render::Varying& input, render::Varying& output, render::CullFunctor cameraCullFunctor, uint8_t tagBits, uint8_t tagMask) { - ::CullFunctor shadowCullFunctor = [this](const RenderArgs* args, const AABox& bounds) { - return _cullFunctor(args, bounds); - }; - // Prepare the ShapePipeline ShapePlumberPointer shapePlumber = std::make_shared(); { @@ -54,7 +52,12 @@ void RenderShadowTask::build(JobModel& task, const render::Varying& input, rende initZPassPipelines(*shapePlumber, state); } - const auto setupOutput = task.addJob("ShadowSetup"); + // FIXME: calling this here before the zones/lights are drawn during the deferred/forward passes means we're actually using the frames from the previous draw + // Fetch the current frame stacks from all the stages + const auto currentFrames = task.addJob("FetchCurrentFrames"); + const auto lightFrame = currentFrames.getN(0); + + const auto setupOutput = task.addJob("ShadowSetup", lightFrame); const auto queryResolution = setupOutput.getN(1); // Fetch and cull the items from the scene @@ -89,7 +92,7 @@ void RenderShadowTask::build(JobModel& task, const render::Varying& input, rende for (auto i = 0; i < SHADOW_CASCADE_MAX_COUNT; i++) { char jobName[64]; sprintf(jobName, "ShadowCascadeSetup%d", i); - const auto cascadeSetupOutput = task.addJob(jobName, i, _cullFunctor, tagBits, tagMask); + const auto cascadeSetupOutput = task.addJob(jobName, lightFrame, i, tagBits, tagMask); const auto shadowFilter = cascadeSetupOutput.getN(0); auto antiFrustum = render::Varying(ViewFrustumPointer()); cascadeFrustums[i] = cascadeSetupOutput.getN(1); @@ -97,14 +100,15 @@ void RenderShadowTask::build(JobModel& task, const render::Varying& input, rende antiFrustum = cascadeFrustums[i - 2]; } - // CPU jobs: finer grained culling - const auto cullInputs = CullShadowBounds::Inputs(sortedShapes, shadowFilter, antiFrustum).asVarying(); + const auto cullInputs = CullShadowBounds::Inputs(sortedShapes, shadowFilter, antiFrustum, lightFrame, cascadeSetupOutput.getN(2)).asVarying(); sprintf(jobName, "CullShadowCascade%d", i); - const auto culledShadowItemsAndBounds = task.addJob(jobName, cullInputs, shadowCullFunctor); + const auto culledShadowItemsAndBounds = task.addJob(jobName, cullInputs); // GPU jobs: Render to shadow map sprintf(jobName, "RenderShadowMap%d", i); - task.addJob(jobName, culledShadowItemsAndBounds, shapePlumber, i); + const auto shadowInputs = RenderShadowMap::Inputs(culledShadowItemsAndBounds.getN(0), + culledShadowItemsAndBounds.getN(1), lightFrame).asVarying(); + task.addJob(jobName, shadowInputs, shapePlumber, i); sprintf(jobName, "ShadowCascadeTeardown%d", i); task.addJob(jobName, shadowFilter); @@ -204,11 +208,12 @@ void RenderShadowMap::run(const render::RenderContextPointer& renderContext, con const auto& inShapes = inputs.get0(); const auto& inShapeBounds = inputs.get1(); + const auto& lightFrame = inputs.get2(); auto lightStage = renderContext->_scene->getStage(); assert(lightStage); - auto shadow = lightStage->getCurrentKeyShadow(); + auto shadow = lightStage->getCurrentKeyShadow(*lightFrame); if (!shadow || _cascadeIndex >= shadow->getCascadeCount()) { return; } @@ -328,11 +333,12 @@ void RenderShadowSetup::setSlopeBias(int cascadeIndex, float value) { _bias[cascadeIndex]._slope = value * value * value * 0.01f; } -void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, Outputs& output) { +void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, const Inputs& input, Outputs& output) { // Abort all jobs if not casting shadows auto lightStage = renderContext->_scene->getStage(); + auto lightFrame = *input; assert(lightStage); - if (!lightStage->getCurrentKeyLight() || !lightStage->getCurrentKeyLight()->getCastShadows()) { + if (!lightStage->getCurrentKeyLight(lightFrame) || !lightStage->getCurrentKeyLight(lightFrame)->getCastShadows()) { renderContext->taskFlow.abortTask(); return; } @@ -346,7 +352,7 @@ void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, O *_cameraFrustum = args->getViewFrustum(); output.edit2() = _cameraFrustum; - const auto globalShadow = lightStage->getCurrentKeyShadow(); + const auto globalShadow = lightStage->getCurrentKeyShadow(lightFrame); if (globalShadow) { globalShadow->setKeylightFrustum(args->getViewFrustum(), SHADOW_FRUSTUM_NEAR, SHADOW_FRUSTUM_FAR); @@ -413,15 +419,18 @@ void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, O } } -void RenderShadowCascadeSetup::run(const render::RenderContextPointer& renderContext, Outputs& output) { +void RenderShadowCascadeSetup::run(const render::RenderContextPointer& renderContext, const Inputs& input, Outputs& output) { auto lightStage = renderContext->_scene->getStage(); + const auto& lightFrame = *input; assert(lightStage); // Cache old render args RenderArgs* args = renderContext->args; - const auto globalShadow = lightStage->getCurrentKeyShadow(); - if (globalShadow && _cascadeIndexgetCascadeCount()) { + RenderShadowTask::CullFunctor cullFunctor; + + const auto globalShadow = lightStage->getCurrentKeyShadow(lightFrame); + if (globalShadow && _cascadeIndex < globalShadow->getCascadeCount()) { // Second item filter is to filter items to keep in shadow frustum computation (here we need to keep shadow receivers) output.edit0() = ItemFilter::Builder::visibleWorldItems().withTypeShape().withOpaque().withoutLayered().withTagBits(_tagBits, _tagMask); @@ -434,13 +443,14 @@ void RenderShadowCascadeSetup::run(const render::RenderContextPointer& renderCon const auto minTexelCount = 24.0f; // TODO : maybe adapt that with LOD management system? texelSize *= minTexelCount; - _cullFunctor._minSquareSize = texelSize * texelSize; + cullFunctor._minSquareSize = texelSize * texelSize; output.edit1() = cascadeFrustum; } else { output.edit0() = ItemFilter::Builder::nothing(); output.edit1() = ViewFrustumPointer(); } + output.edit2() = cullFunctor; } void RenderShadowCascadeTeardown::run(const render::RenderContextPointer& renderContext, const Input& input) { @@ -498,13 +508,20 @@ void CullShadowBounds::run(const render::RenderContextPointer& renderContext, co outShapes.clear(); outBounds = AABox(); + const auto& lightFrame = *inputs.get3(); + auto cullFunctor = inputs.get4(); + + render::CullFunctor shadowCullFunctor = [cullFunctor](const RenderArgs* args, const AABox& bounds) { + return cullFunctor(args, bounds); + }; + if (!filter.selectsNothing()) { auto& details = args->_details.edit(RenderDetails::SHADOW); - render::CullTest test(_cullFunctor, args, details, antiFrustum); + render::CullTest test(shadowCullFunctor, args, details, antiFrustum); auto scene = args->_scene; auto lightStage = renderContext->_scene->getStage(); assert(lightStage); - const auto globalLightDir = lightStage->getCurrentKeyLight()->getDirection(); + const auto globalLightDir = lightStage->getCurrentKeyLight(lightFrame)->getDirection(); auto castersFilter = render::ItemFilter::Builder(filter).withShadowCaster().build(); const auto& receiversFilter = filter; diff --git a/libraries/render-utils/src/RenderShadowTask.h b/libraries/render-utils/src/RenderShadowTask.h index 77892305fb..8aaf554514 100644 --- a/libraries/render-utils/src/RenderShadowTask.h +++ b/libraries/render-utils/src/RenderShadowTask.h @@ -19,11 +19,13 @@ #include "Shadows_shared.slh" +#include "LightStage.h" + class ViewFrustum; class RenderShadowMap { public: - using Inputs = render::VaryingSet2; + using Inputs = render::VaryingSet3; using JobModel = render::Job::ModelI; RenderShadowMap(render::ShapePlumberPointer shapePlumber, unsigned int cascadeIndex) : _shapePlumber{ shapePlumber }, _cascadeIndex{ cascadeIndex } {} @@ -98,13 +100,14 @@ signals: class RenderShadowSetup { public: + using Inputs = LightStage::FramePointer; using Outputs = render::VaryingSet3; using Config = RenderShadowSetupConfig; - using JobModel = render::Job::ModelO; + using JobModel = render::Job::ModelIO; RenderShadowSetup(); void configure(const Config& configuration); - void run(const render::RenderContextPointer& renderContext, Outputs& output); + void run(const render::RenderContextPointer& renderContext, const Inputs& input, Outputs& output); private: @@ -121,19 +124,19 @@ private: class RenderShadowCascadeSetup { public: - using Outputs = render::VaryingSet2; - using JobModel = render::Job::ModelO; + using Inputs = LightStage::FramePointer; + using Outputs = render::VaryingSet3; + using JobModel = render::Job::ModelIO; - RenderShadowCascadeSetup(unsigned int cascadeIndex, RenderShadowTask::CullFunctor& cullFunctor, uint8_t tagBits = 0x00, uint8_t tagMask = 0x00) : - _cascadeIndex{ cascadeIndex }, _cullFunctor{ cullFunctor }, _tagBits(tagBits), _tagMask(tagMask) {} - void run(const render::RenderContextPointer& renderContext, Outputs& output); + RenderShadowCascadeSetup(unsigned int cascadeIndex, uint8_t tagBits = 0x00, uint8_t tagMask = 0x00) : + _cascadeIndex(cascadeIndex), _tagBits(tagBits), _tagMask(tagMask) {} + + void run(const render::RenderContextPointer& renderContext, const Inputs& input, Outputs& output); private: - unsigned int _cascadeIndex; - RenderShadowTask::CullFunctor& _cullFunctor; - uint8_t _tagBits{ 0x00 }; - uint8_t _tagMask{ 0x00 }; + uint8_t _tagBits { 0x00 }; + uint8_t _tagMask { 0x00 }; }; class RenderShadowCascadeTeardown { @@ -152,20 +155,11 @@ public: class CullShadowBounds { public: - using Inputs = render::VaryingSet3; + using Inputs = render::VaryingSet5; using Outputs = render::VaryingSet2; using JobModel = render::Job::ModelIO; - CullShadowBounds(render::CullFunctor cullFunctor) : - _cullFunctor{ cullFunctor } { - } - void run(const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs); - -private: - - render::CullFunctor _cullFunctor; - }; #endif // hifi_RenderShadowTask_h diff --git a/libraries/render-utils/src/ZoneRenderer.cpp b/libraries/render-utils/src/ZoneRenderer.cpp index 1a1b3706f9..4ffc8730a7 100644 --- a/libraries/render-utils/src/ZoneRenderer.cpp +++ b/libraries/render-utils/src/ZoneRenderer.cpp @@ -39,28 +39,16 @@ namespace gr { using namespace render; -class SetupZones { -public: - using Inputs = render::ItemBounds; - using JobModel = render::Job::ModelI; - - SetupZones() {} - - void run(const RenderContextPointer& context, const Inputs& inputs); - -protected: -}; - const Selection::Name ZoneRendererTask::ZONES_SELECTION { "RankedZones" }; -void ZoneRendererTask::build(JobModel& task, const Varying& input, Varying& ouput) { +void ZoneRendererTask::build(JobModel& task, const Varying& input, Varying& output) { // Filter out the sorted list of zones const auto zoneItems = task.addJob("FilterZones", input, ZONES_SELECTION.c_str()); // just setup the current zone env task.addJob("SetupZones", zoneItems); - ouput = zoneItems; + output = zoneItems; } void SetupZones::run(const RenderContextPointer& context, const Inputs& inputs) { @@ -130,27 +118,29 @@ const gpu::PipelinePointer& DebugZoneLighting::getBackgroundPipeline() { void DebugZoneLighting::run(const render::RenderContextPointer& context, const Inputs& inputs) { RenderArgs* args = context->args; - auto deferredTransform = inputs; + auto deferredTransform = inputs.get0(); + auto lightFrame = inputs.get1(); + auto backgroundFrame = inputs.get2(); auto lightStage = context->_scene->getStage(LightStage::getName()); std::vector keyLightStack; - if (lightStage && lightStage->_currentFrame._sunLights.size()) { - for (auto index : lightStage->_currentFrame._sunLights) { + if (lightStage && lightFrame->_sunLights.size()) { + for (auto index : lightFrame->_sunLights) { keyLightStack.push_back(lightStage->getLight(index)); } } std::vector ambientLightStack; - if (lightStage && lightStage->_currentFrame._ambientLights.size()) { - for (auto index : lightStage->_currentFrame._ambientLights) { + if (lightStage && lightFrame->_ambientLights.size()) { + for (auto index : lightFrame->_ambientLights) { ambientLightStack.push_back(lightStage->getLight(index)); } } auto backgroundStage = context->_scene->getStage(BackgroundStage::getName()); std::vector skyboxStack; - if (backgroundStage && backgroundStage->_currentFrame._backgrounds.size()) { - for (auto index : backgroundStage->_currentFrame._backgrounds) { + if (backgroundStage && backgroundFrame->_backgrounds.size()) { + for (auto index : backgroundFrame->_backgrounds) { auto background = backgroundStage->getBackground(index); if (background) { skyboxStack.push_back(background->getSkybox()); @@ -158,7 +148,6 @@ void DebugZoneLighting::run(const render::RenderContextPointer& context, const I } } - gpu::doInBatch("DebugZoneLighting::run", args->_context, [=](gpu::Batch& batch) { batch.setViewportTransform(args->_viewport); diff --git a/libraries/render-utils/src/ZoneRenderer.h b/libraries/render-utils/src/ZoneRenderer.h index 6e85243d1a..1646c5977d 100644 --- a/libraries/render-utils/src/ZoneRenderer.h +++ b/libraries/render-utils/src/ZoneRenderer.h @@ -16,6 +16,19 @@ #include "DeferredFrameTransform.h" +#include "LightStage.h" +#include "BackgroundStage.h" + +class SetupZones { +public: + using Inputs = render::ItemBounds; + using JobModel = render::Job::ModelI; + + SetupZones() {} + + void run(const render::RenderContextPointer& context, const Inputs& inputs); +}; + class ZoneRendererConfig : public render::Task::Config { Q_OBJECT Q_PROPERTY(int maxDrawn MEMBER maxDrawn NOTIFY dirty) @@ -44,7 +57,7 @@ public: ZoneRendererTask() {} - void build(JobModel& task, const render::Varying& inputs, render::Varying& outputs); + void build(JobModel& task, const render::Varying& inputs, render::Varying& output); void configure(const Config& config) { _maxDrawn = config.maxDrawn; } @@ -59,7 +72,7 @@ public: Config(bool enabled = false) : JobConfig(enabled) {} }; - using Inputs = DeferredFrameTransformPointer; + using Inputs = render::VaryingSet3; using JobModel = render::Job::ModelI; DebugZoneLighting() {} diff --git a/libraries/shared/src/PathUtils.cpp b/libraries/shared/src/PathUtils.cpp index e66121f159..60b426e46d 100644 --- a/libraries/shared/src/PathUtils.cpp +++ b/libraries/shared/src/PathUtils.cpp @@ -132,8 +132,6 @@ QUrl PathUtils::expandToLocalDataAbsolutePath(const QUrl& fileUrl) { return expandedURL; } - QUrl::fromLocalFile(resourcesPath()).toString(); - return fileUrl; } diff --git a/libraries/task/src/task/Task.h b/libraries/task/src/task/Task.h index 3878c5719b..ee5483d5cb 100644 --- a/libraries/task/src/task/Task.h +++ b/libraries/task/src/task/Task.h @@ -418,6 +418,7 @@ protected: template < typename T0, typename T1, typename T2, typename T3, typename T4, typename T5 > using VaryingSet6 = task::VaryingSet6; \ template < typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6 > using VaryingSet7 = task::VaryingSet7; \ template < typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7 > using VaryingSet8 = task::VaryingSet8; \ + template < typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8 > using VaryingSet9 = task::VaryingSet9; \ template < class T, int NUM > using VaryingArray = task::VaryingArray; diff --git a/libraries/task/src/task/Varying.h b/libraries/task/src/task/Varying.h index 7b7b9907fb..9536db2799 100644 --- a/libraries/task/src/task/Varying.h +++ b/libraries/task/src/task/Varying.h @@ -328,6 +328,45 @@ public: Varying asVarying() const { return Varying((*this)); } }; +template +class VaryingSet9 : public std::tuple { +public: + using Parent = std::tuple; + + VaryingSet9() : Parent(Varying(T0()), Varying(T1()), Varying(T2()), Varying(T3()), Varying(T4()), Varying(T5()), Varying(T6()), Varying(T7()), Varying(T8())) {} + VaryingSet9(const VaryingSet9& src) : Parent(std::get<0>(src), std::get<1>(src), std::get<2>(src), std::get<3>(src), std::get<4>(src), std::get<5>(src), std::get<6>(src), std::get<7>(src), std::get<8>(src)) {} + VaryingSet9(const Varying& first, const Varying& second, const Varying& third, const Varying& fourth, const Varying& fifth, const Varying& sixth, const Varying& seventh, const Varying& eighth, const Varying& nine) : Parent(first, second, third, fourth, fifth, sixth, seventh, eighth, nine) {} + + const T0& get0() const { return std::get<0>((*this)).template get(); } + T0& edit0() { return std::get<0>((*this)).template edit(); } + + const T1& get1() const { return std::get<1>((*this)).template get(); } + T1& edit1() { return std::get<1>((*this)).template edit(); } + + const T2& get2() const { return std::get<2>((*this)).template get(); } + T2& edit2() { return std::get<2>((*this)).template edit(); } + + const T3& get3() const { return std::get<3>((*this)).template get(); } + T3& edit3() { return std::get<3>((*this)).template edit(); } + + const T4& get4() const { return std::get<4>((*this)).template get(); } + T4& edit4() { return std::get<4>((*this)).template edit(); } + + const T5& get5() const { return std::get<5>((*this)).template get(); } + T5& edit5() { return std::get<5>((*this)).template edit(); } + + const T6& get6() const { return std::get<6>((*this)).template get(); } + T6& edit6() { return std::get<6>((*this)).template edit(); } + + const T7& get7() const { return std::get<7>((*this)).template get(); } + T7& edit7() { return std::get<7>((*this)).template edit(); } + + const T8& get8() const { return std::get<8>((*this)).template get(); } + T8& edit8() { return std::get<8>((*this)).template edit(); } + + Varying asVarying() const { return Varying((*this)); } +}; + template < class T, int NUM > class VaryingArray : public std::array { public: diff --git a/scripts/system/html/css/edit-style.css b/scripts/system/html/css/edit-style.css index 6c1931932a..8e7b3f1ad5 100644 --- a/scripts/system/html/css/edit-style.css +++ b/scripts/system/html/css/edit-style.css @@ -244,7 +244,7 @@ input.search:focus { height: 26px; margin-top: 1px; margin-bottom: 1px; - box-shadow: 0 0 0px 1px #00b4ef; + box-shadow: 0 0 0 1px #00b4ef; } input:disabled, textarea:disabled { @@ -455,11 +455,11 @@ input[type=checkbox]:checked + label:hover { #properties-list fieldset { position: relative; /* 0.1px on the top is to prevent margin collapsing between this and it's first child */ - margin: 21px -21px 0px -21px; - padding: 0.1px 21px 0px 21px; + margin: 21px -21px 0 -21px; + padding: 0.1px 21px 0 21px; border: none; border-top: 1px rgb(90,90,90) solid; - box-shadow: 0px -1px 0px rgb(37,37,37); + box-shadow: 0 -1px 0 rgb(37,37,37); } #properties-list fieldset.fstuple, #properties-list fieldset.fsrow { @@ -469,7 +469,7 @@ input[type=checkbox]:checked + label:hover { } #properties-list > fieldset[data-collapsed="true"] + fieldset { - margin-top: 0px; + margin-top: 0; } #properties-list > fieldset[data-collapsed="true"] > *:not(legend) { @@ -477,14 +477,14 @@ input[type=checkbox]:checked + label:hover { } #properties-list legend + fieldset { - margin-top: 0px; + margin-top: 0; border: none; box-shadow: none; } #properties-list > fieldset#properties-header { - margin-top: 0px; - padding-bottom: 0px; + margin-top: 0; + padding-bottom: 0; } @@ -940,8 +940,8 @@ tuple, .blue:focus, .tuple .z:focus, .tuple .roll:focus { #properties-list .two-column fieldset legend { display: table; width: 100%; - margin: 21px -21px 0px -21px; - padding: 0px 0px 0px 21px; + margin: 21px -21px 0 -21px; + padding: 0 0 0 21px; font-family: Raleway-Regular; font-size: 12px; color: #afafaf; @@ -973,6 +973,10 @@ fieldset .checkbox-sub-props .property:first-child { ::-webkit-scrollbar-track { background-color: #2e2e2e; } +#entity-table-scroll::-webkit-scrollbar-track { + border-bottom-right-radius: 7px; +} + ::-webkit-scrollbar-thumb { background-color: #696969; border: 2px solid #2e2e2e; @@ -1031,6 +1035,16 @@ textarea:enabled[scrolling="true"]::-webkit-resizer { position: relative; /* New positioning context. */ } +#footer-text { + float: right; + padding-top: 12px; + padding-right: 22px; +} + +#entity-list-footer { + padding-top: 9px; +} + #search-area { padding-right: 168px; padding-bottom: 24px; @@ -1068,6 +1082,9 @@ textarea:enabled[scrolling="true"]::-webkit-resizer { margin-top: 28px; border-left: 2px solid #575757; border-right: 2px solid #575757; + border-bottom: 2px solid #575757; + border-bottom-left-radius: 7px; + border-bottom-right-radius: 7px; background-color: #1c1c1c; } @@ -1084,8 +1101,7 @@ textarea:enabled[scrolling="true"]::-webkit-resizer { background-color: #1c1c1c; } -#entity-table thead tr, #entity-table thead tr th, -#entity-table tfoot tr, #entity-table tfoot tr td { +#entity-table thead tr, #entity-table thead tr th { background: none; } @@ -1196,19 +1212,6 @@ th#entity-hasTransparent .sort-order { top: -1px; } -#entity-table tfoot { - box-sizing: border-box; - border: 2px solid #575757; - border-bottom-left-radius: 7px; - border-bottom-right-radius: 7px; - border-top: 1px solid #575757; - position: absolute; - bottom: -21px; - left: 0; - width: 100%; -} - - #col-type { width: 16%; } @@ -1788,4 +1791,13 @@ input#reset-to-natural-dimensions { .skybox-section { display: none; -} \ No newline at end of file +} + +input[type=button]#export { + height: 38px; + width: 180px; +} + +body#entity-list-body { + padding-bottom: 0; +} diff --git a/scripts/system/html/entityList.html b/scripts/system/html/entityList.html index 7eed78ecf3..c62c785c99 100644 --- a/scripts/system/html/entityList.html +++ b/scripts/system/html/entityList.html @@ -1,4 +1,4 @@ -