From 69b0691eb6ff10aa0f067e3af0d01d6b43014196 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 18 May 2017 16:35:56 -0700 Subject: [PATCH 01/73] Update content set URL for RC40 --- server-console/src/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-console/src/main.js b/server-console/src/main.js index 4ce1ccfb02..98bda9a10f 100644 --- a/server-console/src/main.js +++ b/server-console/src/main.js @@ -42,7 +42,7 @@ const appIcon = path.join(__dirname, '../resources/console.png'); const DELETE_LOG_FILES_OLDER_THAN_X_SECONDS = 60 * 60 * 24 * 7; // 7 Days const LOG_FILE_REGEX = /(domain-server|ac-monitor|ac)-.*-std(out|err).txt/; -const HOME_CONTENT_URL = "http://cdn.highfidelity.com/content-sets/home-tutorial-RC39.tar.gz"; +const HOME_CONTENT_URL = "http://cdn.highfidelity.com/content-sets/home-tutorial-RC40.tar.gz"; function getBuildInfo() { var buildInfoPath = null; From d7d4ff1f822ce3390e276ee48525b12ef5542c5c Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 19 May 2017 11:11:00 -0700 Subject: [PATCH 02/73] Add notes to KtxStorage::maybeOpenFile --- libraries/gpu/src/gpu/Texture_ktx.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libraries/gpu/src/gpu/Texture_ktx.cpp b/libraries/gpu/src/gpu/Texture_ktx.cpp index 92ead5f616..9799aecdf5 100644 --- a/libraries/gpu/src/gpu/Texture_ktx.cpp +++ b/libraries/gpu/src/gpu/Texture_ktx.cpp @@ -184,6 +184,11 @@ KtxStorage::KtxStorage(const std::string& filename) : _filename(filename) { } std::shared_ptr KtxStorage::maybeOpenFile() const { + // 1. Try to get the shared ptr + // 2. If it doesn't exist, grab the mutex around its creation + // 3. If it was created before we got the mutex, return it + // 4. Otherwise, create it + std::shared_ptr file = _cacheFile.lock(); if (file) { return file; From 50f5ae6e7799c1a4f38fc4167674f49911d441dd Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 19 May 2017 11:16:20 -0700 Subject: [PATCH 03/73] Fix FileStorage to not close files after they are opened This is particularly an issue with KTX file reading/writing where we do both concurrently. --- libraries/gpu/src/gpu/Texture_ktx.cpp | 12 +++++--- libraries/shared/src/shared/Storage.cpp | 41 ++++++------------------- libraries/shared/src/shared/Storage.h | 3 +- 3 files changed, 18 insertions(+), 38 deletions(-) diff --git a/libraries/gpu/src/gpu/Texture_ktx.cpp b/libraries/gpu/src/gpu/Texture_ktx.cpp index 9799aecdf5..bf5b4d7965 100644 --- a/libraries/gpu/src/gpu/Texture_ktx.cpp +++ b/libraries/gpu/src/gpu/Texture_ktx.cpp @@ -210,7 +210,6 @@ std::shared_ptr KtxStorage::maybeOpenFile() const { } PixelsPointer KtxStorage::getMipFace(uint16 level, uint8 face) const { - storage::StoragePointer result; auto faceOffset = _ktxDescriptor->getMipFaceTexelsOffset(level, face); auto faceSize = _ktxDescriptor->getMipFaceTexelsSize(level, face); if (faceSize != 0 && faceOffset != 0) { @@ -226,7 +225,7 @@ PixelsPointer KtxStorage::getMipFace(uint16 level, uint8 face) const { qWarning() << "Failed to get a valid file out of maybeOpenFile " << QString::fromStdString(_filename); } } - return result; + return nullptr; } Size KtxStorage::getMipFaceSize(uint16 level, uint8 face) const { @@ -260,8 +259,13 @@ void KtxStorage::assignMipData(uint16 level, const storage::StoragePointer& stor } auto file = maybeOpenFile(); + if (!file) { + qWarning() << "Failed to open file to assign mip data " << QString::fromStdString(_filename); + return; + } - auto imageData = file->mutableData(); + auto fileData = file->mutableData(); + auto imageData = fileData; imageData += ktx::KTX_HEADER_SIZE + _ktxDescriptor->header.bytesOfKeyValueData + _ktxDescriptor->images[level]._imageOffset; imageData += ktx::IMAGE_SIZE_WIDTH; @@ -276,7 +280,7 @@ void KtxStorage::assignMipData(uint16 level, const storage::StoragePointer& stor memcpy(imageData, storage->data(), storage->size()); _minMipLevelAvailable = level; if (_offsetToMinMipKV > 0) { - auto minMipKeyData = file->mutableData() + ktx::KTX_HEADER_SIZE + _offsetToMinMipKV; + auto minMipKeyData = fileData + ktx::KTX_HEADER_SIZE + _offsetToMinMipKV; memcpy(minMipKeyData, (void*)&_minMipLevelAvailable, 1); } } diff --git a/libraries/shared/src/shared/Storage.cpp b/libraries/shared/src/shared/Storage.cpp index e479559e6a..b07f896df0 100644 --- a/libraries/shared/src/shared/Storage.cpp +++ b/libraries/shared/src/shared/Storage.cpp @@ -70,7 +70,15 @@ StoragePointer FileStorage::create(const QString& filename, size_t size, const u } FileStorage::FileStorage(const QString& filename) : _file(filename) { - if (_file.open(QFile::ReadOnly)) { + bool opened = _file.open(QFile::ReadWrite); + if (opened) { + _hasWriteAccess = true; + } else { + _hasWriteAccess = false; + opened = _file.open(QFile::ReadOnly); + } + + if (opened) { _mapped = _file.map(0, _file.size()); if (_mapped) { _valid = true; @@ -91,35 +99,4 @@ FileStorage::~FileStorage() { if (_file.isOpen()) { _file.close(); } -} - -void FileStorage::ensureWriteAccess() { - if (_hasWriteAccess) { - return; - } - - if (_mapped) { - if (!_file.unmap(_mapped)) { - throw std::runtime_error("Unable to unmap file"); - } - } - if (_file.isOpen()) { - _file.close(); - } - _valid = false; - _mapped = nullptr; - - if (_file.open(QFile::ReadWrite)) { - _mapped = _file.map(0, _file.size()); - if (_mapped) { - _valid = true; - _hasWriteAccess = true; - } else { - qCWarning(storagelogging) << "Failed to map file " << _file.fileName(); - throw std::runtime_error("Failed to map file"); - } - } else { - qCWarning(storagelogging) << "Failed to open file " << _file.fileName(); - throw std::runtime_error("Failed to open file"); - } } \ No newline at end of file diff --git a/libraries/shared/src/shared/Storage.h b/libraries/shared/src/shared/Storage.h index 4cad9fa083..d7946738cf 100644 --- a/libraries/shared/src/shared/Storage.h +++ b/libraries/shared/src/shared/Storage.h @@ -60,11 +60,10 @@ namespace storage { FileStorage& operator=(const FileStorage& other) = delete; const uint8_t* data() const override { return _mapped; } - uint8_t* mutableData() override { ensureWriteAccess(); return _mapped; } + uint8_t* mutableData() override { return _hasWriteAccess ? _mapped : nullptr; } size_t size() const override { return _file.size(); } operator bool() const override { return _valid; } private: - void ensureWriteAccess(); bool _valid { false }; bool _hasWriteAccess { false }; From 53a963726d2c1d76341ab3707ce73d565363d6d1 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 19 May 2017 15:00:53 -0700 Subject: [PATCH 04/73] Add check for valid mutableData in assignMipData --- libraries/gpu/src/gpu/Texture_ktx.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libraries/gpu/src/gpu/Texture_ktx.cpp b/libraries/gpu/src/gpu/Texture_ktx.cpp index bf5b4d7965..14282ec525 100644 --- a/libraries/gpu/src/gpu/Texture_ktx.cpp +++ b/libraries/gpu/src/gpu/Texture_ktx.cpp @@ -265,6 +265,11 @@ void KtxStorage::assignMipData(uint16 level, const storage::StoragePointer& stor } auto fileData = file->mutableData(); + if (!fileData) { + qWarning() << "Failed to get mutable data for " << QString::fromStdString(_filename); + return; + } + auto imageData = fileData; imageData += ktx::KTX_HEADER_SIZE + _ktxDescriptor->header.bytesOfKeyValueData + _ktxDescriptor->images[level]._imageOffset; imageData += ktx::IMAGE_SIZE_WIDTH; From 5cb25b1ef1692c5daffc647efd86e0bf9a2a668e Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Fri, 19 May 2017 16:53:25 -0700 Subject: [PATCH 05/73] Increment _identitySequenceId before sending ID packet for agents --- assignment-client/src/Agent.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 5864cadc15..96b2336af8 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -584,6 +584,7 @@ void Agent::setIsAvatar(bool isAvatar) { void Agent::sendAvatarIdentityPacket() { if (_isAvatar) { auto scriptedAvatar = DependencyManager::get(); + scriptedAvatar->markIdentityDataChanged(); scriptedAvatar->sendIdentityPacket(); } } From 2928507e4898cc863d701398598895d360f9f6ba Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 19 May 2017 10:48:38 -0700 Subject: [PATCH 06/73] Fix "Reset Settings" window poping up every time --- interface/src/Application.cpp | 8 ++++---- interface/src/Application.h | 2 +- interface/src/CrashHandler.cpp | 5 +---- interface/src/CrashHandler.h | 2 +- interface/src/main.cpp | 3 ++- libraries/shared/src/RunningMarker.cpp | 7 ++++++- libraries/shared/src/RunningMarker.h | 4 +++- 7 files changed, 18 insertions(+), 13 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c39f7294c0..bd66a96879 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -431,7 +431,7 @@ static const QString STATE_ADVANCED_MOVEMENT_CONTROLS = "AdvancedMovement"; static const QString STATE_GROUNDED = "Grounded"; static const QString STATE_NAV_FOCUSED = "NavigationFocused"; -bool setupEssentials(int& argc, char** argv) { +bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { const char** constArgv = const_cast(argv); const char* portStr = getCmdOption(argc, constArgv, "--listenPort"); const int listenPort = portStr ? atoi(portStr) : INVALID_PORT; @@ -458,7 +458,7 @@ bool setupEssentials(int& argc, char** argv) { static const auto SUPPRESS_SETTINGS_RESET = "--suppress-settings-reset"; bool suppressPrompt = cmdOptionExists(argc, const_cast(argv), SUPPRESS_SETTINGS_RESET); - bool previousSessionCrashed = CrashHandler::checkForResetSettings(suppressPrompt); + bool previousSessionCrashed = CrashHandler::checkForResetSettings(runningMarkerExisted, suppressPrompt); DependencyManager::registerInheritance(); DependencyManager::registerInheritance(); @@ -563,11 +563,11 @@ const bool DEFAULT_DESKTOP_TABLET_BECOMES_TOOLBAR = true; const bool DEFAULT_HMD_TABLET_BECOMES_TOOLBAR = false; const bool DEFAULT_PREFER_AVATAR_FINGER_OVER_STYLUS = false; -Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : +Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bool runningMarkerExisted) : QApplication(argc, argv), _window(new MainWindow(desktop())), _sessionRunTimer(startupTimer), - _previousSessionCrashed(setupEssentials(argc, argv)), + _previousSessionCrashed(setupEssentials(argc, argv, runningMarkerExisted)), _undoStackScriptingInterface(&_undoStack), _entitySimulation(new PhysicalEntitySimulation()), _physicsEngine(new PhysicsEngine(Vectors::ZERO)), diff --git a/interface/src/Application.h b/interface/src/Application.h index 5cf3580c09..d9dc3f389f 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -136,7 +136,7 @@ public: static void initPlugins(const QStringList& arguments); static void shutdownPlugins(); - Application(int& argc, char** argv, QElapsedTimer& startup_time); + Application(int& argc, char** argv, QElapsedTimer& startup_time, bool runningMarkerExisted); ~Application(); void postLambdaEvent(std::function f) override; diff --git a/interface/src/CrashHandler.cpp b/interface/src/CrashHandler.cpp index b254cd58de..8081dd3ffc 100644 --- a/interface/src/CrashHandler.cpp +++ b/interface/src/CrashHandler.cpp @@ -28,7 +28,7 @@ #include -bool CrashHandler::checkForResetSettings(bool suppressPrompt) { +bool CrashHandler::checkForResetSettings(bool wasLikelyCrash, bool suppressPrompt) { Settings settings; settings.beginGroup("Developer"); QVariant displayCrashOptions = settings.value(MenuOption::DisplayCrashOptions); @@ -39,9 +39,6 @@ bool CrashHandler::checkForResetSettings(bool suppressPrompt) { // If option does not exist in Interface.ini so assume default behavior. bool displaySettingsResetOnCrash = !displayCrashOptions.isValid() || displayCrashOptions.toBool(); - QFile runningMarkerFile(RunningMarker::getMarkerFilePath(RUNNING_MARKER_FILENAME)); - bool wasLikelyCrash = runningMarkerFile.exists(); - if (suppressPrompt) { return wasLikelyCrash; } diff --git a/interface/src/CrashHandler.h b/interface/src/CrashHandler.h index 308cac3411..da2e1575db 100644 --- a/interface/src/CrashHandler.h +++ b/interface/src/CrashHandler.h @@ -17,7 +17,7 @@ class CrashHandler { public: - static bool checkForResetSettings(bool suppressPrompt = false); + static bool checkForResetSettings(bool wasLikelyCrash, bool suppressPrompt = false); private: enum Action { diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 3430ffbd15..49517eb38e 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -192,6 +192,7 @@ int main(int argc, const char* argv[]) { int exitCode; { RunningMarker runningMarker(nullptr, RUNNING_MARKER_FILENAME); + bool runningMarkerExisted = runningMarker.fileExists(); runningMarker.writeRunningMarkerFile(); bool noUpdater = parser.isSet(noUpdaterOption); @@ -202,7 +203,7 @@ int main(int argc, const char* argv[]) { SandboxUtils::runLocalSandbox(serverContentPath, true, RUNNING_MARKER_FILENAME, noUpdater); } - Application app(argc, const_cast(argv), startupTime); + Application app(argc, const_cast(argv), startupTime, runningMarkerExisted); // Now that the main event loop is setup, launch running marker thread runningMarker.startRunningMarker(); diff --git a/libraries/shared/src/RunningMarker.cpp b/libraries/shared/src/RunningMarker.cpp index f8aaee42df..0c1fd06df8 100644 --- a/libraries/shared/src/RunningMarker.cpp +++ b/libraries/shared/src/RunningMarker.cpp @@ -53,6 +53,11 @@ RunningMarker::~RunningMarker() { _runningMarkerThread->deleteLater(); } +bool RunningMarker::fileExists() const { + QFile runningMarkerFile(getFilePath()); + return runningMarkerFile.exists(); +} + void RunningMarker::writeRunningMarkerFile() { QFile runningMarkerFile(getFilePath()); @@ -69,7 +74,7 @@ void RunningMarker::deleteRunningMarkerFile() { } } -QString RunningMarker::getFilePath() { +QString RunningMarker::getFilePath() const { return QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/" + _name; } diff --git a/libraries/shared/src/RunningMarker.h b/libraries/shared/src/RunningMarker.h index 1137dbf5fa..f9c8e72d37 100644 --- a/libraries/shared/src/RunningMarker.h +++ b/libraries/shared/src/RunningMarker.h @@ -25,9 +25,11 @@ public: void startRunningMarker(); - QString getFilePath(); + QString getFilePath() const; static QString getMarkerFilePath(QString name); + bool fileExists() const; + void writeRunningMarkerFile(); void deleteRunningMarkerFile(); From 0c4cd96bfddd85c2587f56821043635a46b169b0 Mon Sep 17 00:00:00 2001 From: volansystech Date: Wed, 24 May 2017 12:25:21 +0530 Subject: [PATCH 07/73] Initial Commit : Switch from HMD [Oculus Rift] mode to Desktop mode automatically when user removing Oculus Rift. --- interface/src/Application.cpp | 40 +++++++++++++++++++++++++++++++++++ interface/src/Application.h | 8 +++++-- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ae490c05e7..ced5e51565 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1338,6 +1338,13 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo properties["active_display_plugin"] = getActiveDisplayPlugin()->getName(); properties["using_hmd"] = isHMDMode(); + if (isOculusRiftPluginAvailable()){ + qCDebug(interfaceapp) << "Oculus Rift Plugin is available"; + QTimer *switchModeTimer = new QTimer(this); + connect(switchModeTimer, SIGNAL(timeout()), this, SLOT(switchmode())); + switchModeTimer->start(500); + } + auto glInfo = getGLContextData(); properties["gl_info"] = glInfo; properties["gpu_used_memory"] = (int)BYTES_TO_MB(gpu::Context::getUsedGPUMemory()); @@ -6833,6 +6840,39 @@ void Application::updateDisplayMode() { Q_ASSERT_X(_displayPlugin, "Application::updateDisplayMode", "could not find an activated display plugin"); } +bool Application::isOculusRiftPluginAvailable(){ + bool isOculusRiftPluginAvailable = false; + auto displayPlugins = PluginManager::getInstance()->getDisplayPlugins(); + // Default to the first item on the list, in case none of the menu items match + DisplayPluginPointer defaultplugin = displayPlugins.at(0); + if (defaultplugin->isHmd() && defaultplugin->getName() == "Oculus Rift"){ + oculusRiftPlugin = defaultplugin; + return true; // No need to iterate again,so return + } + // Iterate to check If Oculus Rift Plugin is available + foreach(DisplayPluginPointer displayPlugin, PluginManager::getInstance()->getDisplayPlugins()) { + QString pluginname = displayPlugin->getName(); + if (displayPlugin->isHmd() && pluginname == "Oculus Rift") { + oculusRiftPlugin = displayPlugin; + _isDisplayVisible = displayPlugin->isDisplayVisible(); + isOculusRiftPluginAvailable = true; + break; + } + } + return isOculusRiftPluginAvailable; +} + +void Application::switchmode(){ + bool isDisplayVisible = oculusRiftPlugin->isDisplayVisible(); + if (isDisplayVisible != _isDisplayVisible){ + if (isDisplayVisible == false && _isDisplayVisible == true){ + qCDebug(interfaceapp) << "switching from HMD to desktop mode"; + setActiveDisplayPlugin("Desktop"); + } + } + _isDisplayVisible = isDisplayVisible; // assign current status +} + mat4 Application::getEyeProjection(int eye) const { QMutexLocker viewLocker(&_viewMutex); if (isHMDMode()) { diff --git a/interface/src/Application.h b/interface/src/Application.h index d9dc3f389f..c181e74c74 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -152,7 +152,7 @@ public: void paintGL(); void resizeGL(); - bool event(QEvent* event) override; + bool event(QEvent* event) override; bool eventFilter(QObject* object, QEvent* event) override; glm::uvec2 getCanvasSize() const; @@ -443,7 +443,7 @@ private slots: void addAssetToWorldErrorTimeout(); void handleSandboxStatus(QNetworkReply* reply); - + void switchmode(); private: static void initDisplay(); void init(); @@ -683,6 +683,10 @@ private: FileScriptingInterface* _fileDownload; AudioInjector* _snapshotSoundInjector { nullptr }; SharedSoundPointer _snapshotSound; + + bool isOculusRiftPluginAvailable(); + DisplayPluginPointer oculusRiftPlugin; + bool _isDisplayVisible; }; From ac55908e42984a27c91cd386609808f61073376b Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 24 May 2017 16:50:06 -0700 Subject: [PATCH 08/73] add additional information to stats/launch activities --- interface/src/Application.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index bd66a96879..253277b37f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -946,6 +946,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo properties["processor_l3_cache_count"] = procInfo.numProcessorCachesL3; } + // add firstRun flag from settings to launch event + Setting::Handle firstRun { Settings::firstRun, true }; + properties["first_run"] = firstRun.get(); + UserActivityLogger::getInstance().logAction("launch", properties); // Tell our entity edit sender about our known jurisdictions @@ -1305,6 +1309,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo properties["kbps_in"] = bandwidthRecorder->getCachedTotalAverageInputKilobitsPerSecond(); properties["kbps_out"] = bandwidthRecorder->getCachedTotalAverageOutputKilobitsPerSecond(); + properties["asset_in_kbps"] = bandwidthRecorder->getAverageInputKilobitsPerSecond(NodeType::AssetServer); + auto nodeList = DependencyManager::get(); SharedNodePointer entityServerNode = nodeList->soloNodeOfType(NodeType::EntityServer); SharedNodePointer audioMixerNode = nodeList->soloNodeOfType(NodeType::AudioMixer); @@ -1317,10 +1323,14 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo properties["asset_ping"] = assetServerNode ? assetServerNode->getPingMs() : -1; properties["messages_ping"] = messagesMixerNode ? messagesMixerNode->getPingMs() : -1; + auto loadingRequests = ResourceCache::getLoadingRequests(); properties["active_downloads"] = loadingRequests.size(); properties["pending_downloads"] = ResourceCache::getPendingRequestCount(); + properties["processing_resources"] = DependencyManager::get()->getStat("Processing").toInt(); + properties["pending_processing_resources"] = DependencyManager::get()->getStat("PendingProcessing").toInt(); + properties["throttled"] = _displayPlugin ? _displayPlugin->isThrottled() : false; auto myAvatar = getMyAvatar(); @@ -1335,6 +1345,15 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo properties["deleted_entity_cnt"] = entityActivityTracking.deletedEntityCount; properties["edited_entity_cnt"] = entityActivityTracking.editedEntityCount; + NodeToOctreeSceneStats* octreeServerSceneStats = getOcteeSceneStats(); + unsigned long totalServerOctreeElements = 0; + for (NodeToOctreeSceneStatsIterator i = octreeServerSceneStats->begin(); i != octreeServerSceneStats->end(); i++) { + totalServerOctreeElements += i->second.getTotalElements(); + } + + properties["local_octree_elements"] = (qint64) OctreeElement::getInternalNodeCount(); + properties["server_octree_elements"] = (qint64) totalServerOctreeElements; + properties["active_display_plugin"] = getActiveDisplayPlugin()->getName(); properties["using_hmd"] = isHMDMode(); From 3743cd23b4fe6d74092d34ba3c62b1bb32b7f8fa Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 24 May 2017 17:20:24 -0700 Subject: [PATCH 09/73] add detailed download stats for file/http/atp --- interface/src/Application.cpp | 33 +++++++++++++++++-- .../networking/src/AssetResourceRequest.cpp | 22 +++++++++++-- .../networking/src/FileResourceRequest.cpp | 11 +++++++ .../networking/src/HTTPResourceRequest.cpp | 16 +++++++++ libraries/networking/src/ResourceRequest.h | 12 +++++++ 5 files changed, 90 insertions(+), 4 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 253277b37f..08981ee6c1 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -111,6 +111,7 @@ #include #include #include +#include #include #include #include @@ -1328,8 +1329,36 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo properties["active_downloads"] = loadingRequests.size(); properties["pending_downloads"] = ResourceCache::getPendingRequestCount(); - properties["processing_resources"] = DependencyManager::get()->getStat("Processing").toInt(); - properties["pending_processing_resources"] = DependencyManager::get()->getStat("PendingProcessing").toInt(); + auto statTracker = DependencyManager::get(); + + properties["processing_resources"] = statTracker->getStat("Processing").toInt(); + properties["pending_processing_resources"] = statTracker->getStat("PendingProcessing").toInt(); + + properties["started_atp_requests"] = statTracker->getStat(STAT_ATP_REQUEST_STARTED).toInt(); + properties["started_http_requests"] = statTracker->getStat(STAT_HTTP_REQUEST_STARTED).toInt(); + properties["started_file_requests"] = statTracker->getStat(STAT_FILE_REQUEST_STARTED).toInt(); + auto totalRequestsStarted = properties["started_atp_requests"].toInt() + + properties["started_http_requests"].toInt() + properties["started_file_requests"].toInt(); + properties["started_requests"] = totalRequestsStarted; + + properties["successful_atp_requests"] = statTracker->getStat(STAT_ATP_REQUEST_SUCCESS).toInt(); + properties["successful_http_requests"] = statTracker->getStat(STAT_HTTP_REQUEST_SUCCESS).toInt(); + properties["successful_file_requests"] = statTracker->getStat(STAT_FILE_REQUEST_SUCCESS).toInt(); + auto totalRequestsSuccessful = properties["successful_atp_requests"].toInt() + + properties["successful_http_requests"].toInt() + properties["successful_file_requests"].toInt(); + properties["successful_requests"] = totalRequestsSuccessful; + + properties["failed_atp_requests"] = statTracker->getStat(STAT_ATP_REQUEST_FAILED).toInt(); + properties["failed_http_requests"] = statTracker->getStat(STAT_HTTP_REQUEST_FAILED).toInt(); + properties["failed_file_requests"] = statTracker->getStat(STAT_FILE_REQUEST_FAILED).toInt(); + auto totalRequestsFailed = properties["failed_atp_requests"].toInt() + + properties["failed_http_requests"].toInt() + properties["failed_file_requests"].toInt(); + properties["failed_requests"] = totalRequestsFailed; + + properties["cache_atp_requests"] = statTracker->getStat(STAT_ATP_REQUEST_CACHE).toInt(); + properties["cache_http_requests"] = statTracker->getStat(STAT_HTTP_REQUEST_FAILED).toInt(); + auto totalRequestsCache = properties["cache_atp_requests"].toInt() + properties["cache_http_requests"].toInt(); + properties["cache_requests"] = totalRequestsCache; properties["throttled"] = _displayPlugin ? _displayPlugin->isThrottled() : false; diff --git a/libraries/networking/src/AssetResourceRequest.cpp b/libraries/networking/src/AssetResourceRequest.cpp index a4d5d66923..d23d85d79e 100644 --- a/libraries/networking/src/AssetResourceRequest.cpp +++ b/libraries/networking/src/AssetResourceRequest.cpp @@ -13,12 +13,14 @@ #include +#include +#include +#include + #include "AssetClient.h" #include "AssetUtils.h" #include "MappingRequest.h" #include "NetworkLogging.h" -#include -#include static const int DOWNLOAD_PROGRESS_LOG_INTERVAL_SECONDS = 5; @@ -48,6 +50,8 @@ bool AssetResourceRequest::urlIsAssetHash(const QUrl& url) { } void AssetResourceRequest::doSend() { + DependencyManager::get()->incrementStat(STAT_ATP_REQUEST_STARTED); + // We'll either have a hash or an ATP path to a file (that maps to a hash) if (urlIsAssetHash(_url)) { // We've detected that this is a hash - simply use AssetClient to request that asset @@ -100,6 +104,8 @@ void AssetResourceRequest::requestMappingForPath(const AssetPath& path) { _state = Finished; emit finished(); + DependencyManager::get()->incrementStat(STAT_ATP_REQUEST_FAILED); + break; } } @@ -140,10 +146,22 @@ void AssetResourceRequest::requestHash(const AssetHash& hash) { _result = Error; break; } + + auto statTracker = DependencyManager::get(); _state = Finished; emit finished(); + if (_result == Success) { + statTracker->incrementStat(STAT_ATP_REQUEST_SUCCESS); + + if (loadedFromCache()) { + statTracker->incrementStat(STAT_ATP_REQUEST_CACHE); + } + } else { + statTracker->incrementStat(STAT_ATP_REQUEST_FAILED); + } + _assetRequest->deleteLater(); _assetRequest = nullptr; }); diff --git a/libraries/networking/src/FileResourceRequest.cpp b/libraries/networking/src/FileResourceRequest.cpp index 1e549e5fa3..d0e2721679 100644 --- a/libraries/networking/src/FileResourceRequest.cpp +++ b/libraries/networking/src/FileResourceRequest.cpp @@ -15,7 +15,12 @@ #include +#include + void FileResourceRequest::doSend() { + auto statTracker = DependencyManager::get(); + statTracker->incrementStat(STAT_FILE_REQUEST_STARTED); + QString filename = _url.toLocalFile(); // sometimes on windows, we see the toLocalFile() return null, @@ -60,4 +65,10 @@ void FileResourceRequest::doSend() { _state = Finished; emit finished(); + + if (_result == ResourceRequest::Success) { + statTracker->incrementStat(STAT_FILE_REQUEST_SUCCESS); + } else { + statTracker->incrementStat(STAT_FILE_REQUEST_FAILED); + } } diff --git a/libraries/networking/src/HTTPResourceRequest.cpp b/libraries/networking/src/HTTPResourceRequest.cpp index c6a4b93e51..266ea429a0 100644 --- a/libraries/networking/src/HTTPResourceRequest.cpp +++ b/libraries/networking/src/HTTPResourceRequest.cpp @@ -17,6 +17,7 @@ #include #include +#include #include "NetworkAccessManager.h" #include "NetworkLogging.h" @@ -49,6 +50,8 @@ void HTTPResourceRequest::cleanupTimer() { } void HTTPResourceRequest::doSend() { + DependencyManager::get()->incrementStat(STAT_HTTP_REQUEST_STARTED); + QNetworkRequest networkRequest(_url); networkRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); networkRequest.setHeader(QNetworkRequest::UserAgentHeader, HIGH_FIDELITY_USER_AGENT); @@ -178,6 +181,17 @@ void HTTPResourceRequest::onRequestFinished() { _state = Finished; emit finished(); + + auto statTracker = DependencyManager::get(); + if (_result == Success) { + statTracker->incrementStat(STAT_HTTP_REQUEST_SUCCESS); + + if (loadedFromCache()) { + statTracker->incrementStat(STAT_HTTP_REQUEST_CACHE); + } + } else { + statTracker->incrementStat(STAT_HTTP_REQUEST_FAILED); + } } void HTTPResourceRequest::onDownloadProgress(qint64 bytesReceived, qint64 bytesTotal) { @@ -202,4 +216,6 @@ void HTTPResourceRequest::onTimeout() { _result = Timeout; _state = Finished; emit finished(); + + DependencyManager::get()->incrementStat(STAT_HTTP_REQUEST_FAILED); } diff --git a/libraries/networking/src/ResourceRequest.h b/libraries/networking/src/ResourceRequest.h index ef40cb3455..452380f2f3 100644 --- a/libraries/networking/src/ResourceRequest.h +++ b/libraries/networking/src/ResourceRequest.h @@ -19,6 +19,18 @@ #include "ByteRange.h" +const QString STAT_ATP_REQUEST_STARTED = "StartedATPRequest"; +const QString STAT_HTTP_REQUEST_STARTED = "StartedHTTPRequest"; +const QString STAT_FILE_REQUEST_STARTED = "StartedFileRequest"; +const QString STAT_ATP_REQUEST_SUCCESS = "SuccessfulATPRequest"; +const QString STAT_HTTP_REQUEST_SUCCESS = "SuccessfulHTTPRequest"; +const QString STAT_FILE_REQUEST_SUCCESS = "SuccessfulFileRequest"; +const QString STAT_ATP_REQUEST_FAILED = "FailedATPRequest"; +const QString STAT_HTTP_REQUEST_FAILED = "FailedHTTPRequest"; +const QString STAT_FILE_REQUEST_FAILED = "FailedFileRequest"; +const QString STAT_ATP_REQUEST_CACHE = "CacheATPRequest"; +const QString STAT_HTTP_REQUEST_CACHE = "CacheHTTPRequest"; + class ResourceRequest : public QObject { Q_OBJECT public: From 48c4db1ca4a6bfcd687a76caaa66c6194d055142 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 24 May 2017 17:36:21 -0700 Subject: [PATCH 10/73] nest the download stats so they are cleaner --- interface/src/Application.cpp | 55 +++++++++++-------- .../networking/src/AssetResourceRequest.cpp | 10 +++- libraries/networking/src/ResourceRequest.h | 3 + 3 files changed, 43 insertions(+), 25 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 08981ee6c1..4d18c26296 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1324,7 +1324,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo properties["asset_ping"] = assetServerNode ? assetServerNode->getPingMs() : -1; properties["messages_ping"] = messagesMixerNode ? messagesMixerNode->getPingMs() : -1; - auto loadingRequests = ResourceCache::getLoadingRequests(); properties["active_downloads"] = loadingRequests.size(); properties["pending_downloads"] = ResourceCache::getPendingRequestCount(); @@ -1334,31 +1333,41 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo properties["processing_resources"] = statTracker->getStat("Processing").toInt(); properties["pending_processing_resources"] = statTracker->getStat("PendingProcessing").toInt(); - properties["started_atp_requests"] = statTracker->getStat(STAT_ATP_REQUEST_STARTED).toInt(); - properties["started_http_requests"] = statTracker->getStat(STAT_HTTP_REQUEST_STARTED).toInt(); - properties["started_file_requests"] = statTracker->getStat(STAT_FILE_REQUEST_STARTED).toInt(); - auto totalRequestsStarted = properties["started_atp_requests"].toInt() - + properties["started_http_requests"].toInt() + properties["started_file_requests"].toInt(); - properties["started_requests"] = totalRequestsStarted; + QJsonObject startedRequests; + startedRequests["atp"] = statTracker->getStat(STAT_ATP_REQUEST_STARTED).toInt(); + startedRequests["http"] = statTracker->getStat(STAT_HTTP_REQUEST_STARTED).toInt(); + startedRequests["file"] = statTracker->getStat(STAT_FILE_REQUEST_STARTED).toInt(); + startedRequests["total"] = startedRequests["atp"].toInt() + startedRequests["http"].toInt() + + startedRequests["file"].toInt(); + properties["started_requests"] = startedRequests; - properties["successful_atp_requests"] = statTracker->getStat(STAT_ATP_REQUEST_SUCCESS).toInt(); - properties["successful_http_requests"] = statTracker->getStat(STAT_HTTP_REQUEST_SUCCESS).toInt(); - properties["successful_file_requests"] = statTracker->getStat(STAT_FILE_REQUEST_SUCCESS).toInt(); - auto totalRequestsSuccessful = properties["successful_atp_requests"].toInt() - + properties["successful_http_requests"].toInt() + properties["successful_file_requests"].toInt(); - properties["successful_requests"] = totalRequestsSuccessful; + QJsonObject successfulRequests; + successfulRequests["atp"] = statTracker->getStat(STAT_ATP_REQUEST_SUCCESS).toInt(); + successfulRequests["http"] = statTracker->getStat(STAT_HTTP_REQUEST_SUCCESS).toInt(); + successfulRequests["file"] = statTracker->getStat(STAT_FILE_REQUEST_SUCCESS).toInt(); + successfulRequests["total"] = successfulRequests["atp"].toInt() + successfulRequests["http"].toInt() + + successfulRequests["file"].toInt(); + properties["successful_requests"] = successfulRequests; - properties["failed_atp_requests"] = statTracker->getStat(STAT_ATP_REQUEST_FAILED).toInt(); - properties["failed_http_requests"] = statTracker->getStat(STAT_HTTP_REQUEST_FAILED).toInt(); - properties["failed_file_requests"] = statTracker->getStat(STAT_FILE_REQUEST_FAILED).toInt(); - auto totalRequestsFailed = properties["failed_atp_requests"].toInt() - + properties["failed_http_requests"].toInt() + properties["failed_file_requests"].toInt(); - properties["failed_requests"] = totalRequestsFailed; + QJsonObject failedRequests; + failedRequests["atp"] = statTracker->getStat(STAT_ATP_REQUEST_FAILED).toInt(); + failedRequests["http"] = statTracker->getStat(STAT_HTTP_REQUEST_FAILED).toInt(); + failedRequests["file"] = statTracker->getStat(STAT_FILE_REQUEST_FAILED).toInt(); + failedRequests["total"] = failedRequests["atp"].toInt() + failedRequests["http"].toInt() + + failedRequests["file"].toInt(); + properties["failed_requests"] = failedRequests; - properties["cache_atp_requests"] = statTracker->getStat(STAT_ATP_REQUEST_CACHE).toInt(); - properties["cache_http_requests"] = statTracker->getStat(STAT_HTTP_REQUEST_FAILED).toInt(); - auto totalRequestsCache = properties["cache_atp_requests"].toInt() + properties["cache_http_requests"].toInt(); - properties["cache_requests"] = totalRequestsCache; + QJsonObject cacheRequests; + cacheRequests["atp"] = statTracker->getStat(STAT_ATP_REQUEST_CACHE).toInt(); + cacheRequests["http"] = statTracker->getStat(STAT_HTTP_REQUEST_FAILED).toInt(); + cacheRequests["total"] = cacheRequests["atp"].toInt() + cacheRequests["http"].toInt(); + properties["cache_requests"] = cacheRequests; + + QJsonObject atpMappingRequests; + atpMappingRequests["started"] = statTracker->getStat(STAT_ATP_MAPPING_REQUEST_STARTED).toInt(); + atpMappingRequests["failed"] = statTracker->getStat(STAT_ATP_MAPPING_REQUEST_FAILED).toInt(); + atpMappingRequests["successful"] = statTracker->getStat(STAT_ATP_MAPPING_REQUEST_SUCCESS).toInt(); + properties["atp_mapping_requests"] = atpMappingRequests; properties["throttled"] = _displayPlugin ? _displayPlugin->isThrottled() : false; diff --git a/libraries/networking/src/AssetResourceRequest.cpp b/libraries/networking/src/AssetResourceRequest.cpp index d23d85d79e..fc83fb6cae 100644 --- a/libraries/networking/src/AssetResourceRequest.cpp +++ b/libraries/networking/src/AssetResourceRequest.cpp @@ -69,11 +69,14 @@ void AssetResourceRequest::doSend() { } void AssetResourceRequest::requestMappingForPath(const AssetPath& path) { + auto statTracker = DependencyManager::get(); + statTracker->incrementStat(STAT_ATP_MAPPING_REQUEST_STARTED); + auto assetClient = DependencyManager::get(); _assetMappingRequest = assetClient->createGetMappingRequest(path); // make sure we'll hear about the result of the get mapping request - connect(_assetMappingRequest, &GetMappingRequest::finished, this, [this, path](GetMappingRequest* request){ + connect(_assetMappingRequest, &GetMappingRequest::finished, this, [this, path, statTracker](GetMappingRequest* request){ Q_ASSERT(_state == InProgress); Q_ASSERT(request == _assetMappingRequest); @@ -84,6 +87,8 @@ void AssetResourceRequest::requestMappingForPath(const AssetPath& path) { requestHash(request->getHash()); + statTracker->incrementStat(STAT_ATP_MAPPING_REQUEST_SUCCESS); + break; default: { switch (request->getError()) { @@ -104,7 +109,8 @@ void AssetResourceRequest::requestMappingForPath(const AssetPath& path) { _state = Finished; emit finished(); - DependencyManager::get()->incrementStat(STAT_ATP_REQUEST_FAILED); + statTracker->incrementStat(STAT_ATP_MAPPING_REQUEST_FAILED); + statTracker->incrementStat(STAT_ATP_REQUEST_FAILED); break; } diff --git a/libraries/networking/src/ResourceRequest.h b/libraries/networking/src/ResourceRequest.h index 452380f2f3..39bcb3fe93 100644 --- a/libraries/networking/src/ResourceRequest.h +++ b/libraries/networking/src/ResourceRequest.h @@ -30,6 +30,9 @@ const QString STAT_HTTP_REQUEST_FAILED = "FailedHTTPRequest"; const QString STAT_FILE_REQUEST_FAILED = "FailedFileRequest"; const QString STAT_ATP_REQUEST_CACHE = "CacheATPRequest"; const QString STAT_HTTP_REQUEST_CACHE = "CacheHTTPRequest"; +const QString STAT_ATP_MAPPING_REQUEST_STARTED = "StartedATPMappingRequest"; +const QString STAT_ATP_MAPPING_REQUEST_FAILED = "FailedATPMappingRequest"; +const QString STAT_ATP_MAPPING_REQUEST_SUCCESS = "SuccessfulATPMappingRequest"; class ResourceRequest : public QObject { Q_OBJECT From 5e61f20df8d5c59cf02108579040245c51654805 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 24 May 2017 17:37:42 -0700 Subject: [PATCH 11/73] add more details about pending downloads --- interface/src/Application.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 4d18c26296..28d183a18b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1325,8 +1325,20 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo properties["messages_ping"] = messagesMixerNode ? messagesMixerNode->getPingMs() : -1; auto loadingRequests = ResourceCache::getLoadingRequests(); + + QJsonArray loadingRequestsStats; + for (const auto& request : loadingRequests) { + QJsonObject requestStats; + requestStats["filename"] = request->getURL().fileName(); + requestStats["received"] = request->getBytesReceived(); + requestStats["total"] = request->getBytesTotal(); + requestStats["attempts"] = (int)request->getDownloadAttempts(); + loadingRequestsStats.append(requestStats); + } + properties["active_downloads"] = loadingRequests.size(); properties["pending_downloads"] = ResourceCache::getPendingRequestCount(); + properties["active_downloads_details"] = loadingRequestsStats; auto statTracker = DependencyManager::get(); From c37fd335e1d6560692fdc1a3bfd0db642751cf38 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 24 May 2017 17:41:52 -0700 Subject: [PATCH 12/73] track the number of local socket changes --- interface/src/Application.cpp | 2 ++ libraries/networking/src/LimitedNodeList.cpp | 4 ++-- libraries/networking/src/LimitedNodeList.h | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 28d183a18b..1f5eebee84 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1429,6 +1429,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo lastLeftHandPose = leftHandPose; lastRightHandPose = rightHandPose; + properties["local_socket_changes"] = DependencyManager::get()->getStat(LOCAL_SOCKET_CHANGE_STAT).toInt(); + UserActivityLogger::getInstance().logAction("stats", properties); }); sendStatsTimer->start(); diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 8feb695c79..cba1e664ab 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include "AccountManager.h" @@ -37,7 +38,6 @@ #include "HifiSockAddr.h" #include "NetworkLogging.h" #include "udt/Packet.h" -#include static Setting::Handle LIMITED_NODELIST_LOCAL_PORT("LimitedNodeList.LocalPort", 0); @@ -1044,10 +1044,10 @@ void LimitedNodeList::setLocalSocket(const HifiSockAddr& sockAddr) { qCInfo(networking) << "Local socket is" << sockAddr; } else { qCInfo(networking) << "Local socket has changed from" << _localSockAddr << "to" << sockAddr; + DependencyManager::get()->incrementStat(LOCAL_SOCKET_CHANGE_STAT); } _localSockAddr = sockAddr; - emit localSockAddrChanged(_localSockAddr); } } diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index 3eb898463a..056a4d16cf 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -66,6 +66,8 @@ const QHostAddress DEFAULT_ASSIGNMENT_CLIENT_MONITOR_HOSTNAME = QHostAddress::Lo const QString USERNAME_UUID_REPLACEMENT_STATS_KEY = "$username"; +const QString LOCAL_SOCKET_CHANGE_STAT = "LocalSocketChanges"; + using namespace tbb; typedef std::pair UUIDNodePair; typedef concurrent_unordered_map NodeHash; From fefb34512d399fa2f164ab37ebe82ed205fc94c4 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 24 May 2017 17:44:09 -0700 Subject: [PATCH 13/73] change asset inbound key to atp --- interface/src/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1f5eebee84..e73d46185e 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1310,7 +1310,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo properties["kbps_in"] = bandwidthRecorder->getCachedTotalAverageInputKilobitsPerSecond(); properties["kbps_out"] = bandwidthRecorder->getCachedTotalAverageOutputKilobitsPerSecond(); - properties["asset_in_kbps"] = bandwidthRecorder->getAverageInputKilobitsPerSecond(NodeType::AssetServer); + properties["atp_in_kbps"] = bandwidthRecorder->getAverageInputKilobitsPerSecond(NodeType::AssetServer); auto nodeList = DependencyManager::get(); SharedNodePointer entityServerNode = nodeList->soloNodeOfType(NodeType::EntityServer); From c671817fa3985967f9bc3dfb310e85ccc74158d0 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 24 May 2017 17:47:40 -0700 Subject: [PATCH 14/73] fix cache http request count in stats --- interface/src/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e73d46185e..0b05efbadb 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1371,7 +1371,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo QJsonObject cacheRequests; cacheRequests["atp"] = statTracker->getStat(STAT_ATP_REQUEST_CACHE).toInt(); - cacheRequests["http"] = statTracker->getStat(STAT_HTTP_REQUEST_FAILED).toInt(); + cacheRequests["http"] = statTracker->getStat(STAT_HTTP_REQUEST_CACHE).toInt(); cacheRequests["total"] = cacheRequests["atp"].toInt() + cacheRequests["http"].toInt(); properties["cache_requests"] = cacheRequests; From a04fc41e17587853a3d6ebcf2e7a22238911f474 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 24 May 2017 17:54:07 -0700 Subject: [PATCH 15/73] don't capture strong pointer to stat tracker --- libraries/networking/src/AssetResourceRequest.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libraries/networking/src/AssetResourceRequest.cpp b/libraries/networking/src/AssetResourceRequest.cpp index fc83fb6cae..c0150fd3ed 100644 --- a/libraries/networking/src/AssetResourceRequest.cpp +++ b/libraries/networking/src/AssetResourceRequest.cpp @@ -76,7 +76,9 @@ void AssetResourceRequest::requestMappingForPath(const AssetPath& path) { _assetMappingRequest = assetClient->createGetMappingRequest(path); // make sure we'll hear about the result of the get mapping request - connect(_assetMappingRequest, &GetMappingRequest::finished, this, [this, path, statTracker](GetMappingRequest* request){ + connect(_assetMappingRequest, &GetMappingRequest::finished, this, [this, path](GetMappingRequest* request){ + auto statTracker = DependencyManager::get(); + Q_ASSERT(_state == InProgress); Q_ASSERT(request == _assetMappingRequest); From 50285005beead11349656f0ca380ad98b144319d Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 24 May 2017 18:35:57 -0700 Subject: [PATCH 16/73] add machine fingerprint to the launch event --- interface/src/Application.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 0b05efbadb..2fe0af8556 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -69,6 +69,7 @@ #include #include #include +#include #include #include #include @@ -951,6 +952,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo Setting::Handle firstRun { Settings::firstRun, true }; properties["first_run"] = firstRun.get(); + // add the user's machine ID to the launch event + properties["machine_fingerprint"] = FingerprintUtils::getMachineFingerprint().toString(); + UserActivityLogger::getInstance().logAction("launch", properties); // Tell our entity edit sender about our known jurisdictions From f897f3f0902c4cef7f04357a26db448b26677f7f Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 24 May 2017 19:08:25 -0700 Subject: [PATCH 17/73] send machine fingerprint as uuid without curly braces --- interface/src/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 2fe0af8556..abccc5197d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -953,7 +953,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo properties["first_run"] = firstRun.get(); // add the user's machine ID to the launch event - properties["machine_fingerprint"] = FingerprintUtils::getMachineFingerprint().toString(); + properties["machine_fingerprint"] = uuidStringWithoutCurlyBraces(FingerprintUtils::getMachineFingerprint()); UserActivityLogger::getInstance().logAction("launch", properties); From d7b3ee9bcb06fbf3df764918e1629e9bbb10327b Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 24 May 2017 19:15:10 -0700 Subject: [PATCH 18/73] check for cached ATP assets in right place --- libraries/networking/src/AssetRequest.cpp | 9 +++++++-- libraries/networking/src/AssetRequest.h | 3 +++ libraries/networking/src/AssetResourceRequest.cpp | 6 +++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/libraries/networking/src/AssetRequest.cpp b/libraries/networking/src/AssetRequest.cpp index 920c7ae036..00fa3d9f2f 100644 --- a/libraries/networking/src/AssetRequest.cpp +++ b/libraries/networking/src/AssetRequest.cpp @@ -15,11 +15,13 @@ #include +#include +#include + #include "AssetClient.h" #include "NetworkLogging.h" #include "NodeList.h" #include "ResourceCache.h" -#include static int requestID = 0; @@ -62,9 +64,12 @@ void AssetRequest::start() { _data = loadFromCache(getUrl()); if (!_data.isNull()) { _error = NoError; - + + _loadedFromCache = true; + _state = Finished; emit finished(this); + return; } diff --git a/libraries/networking/src/AssetRequest.h b/libraries/networking/src/AssetRequest.h index b808ae0ca6..df5cf80ecd 100644 --- a/libraries/networking/src/AssetRequest.h +++ b/libraries/networking/src/AssetRequest.h @@ -52,6 +52,8 @@ public: QUrl getUrl() const { return ::getATPUrl(_hash); } QString getHash() const { return _hash; } + bool loadedFromCache() const { return _loadedFromCache; } + signals: void finished(AssetRequest* thisRequest); void progress(qint64 totalReceived, qint64 total); @@ -66,6 +68,7 @@ private: int _numPendingRequests { 0 }; MessageID _assetRequestID { INVALID_MESSAGE_ID }; const ByteRange _byteRange; + bool _loadedFromCache { false }; }; #endif diff --git a/libraries/networking/src/AssetResourceRequest.cpp b/libraries/networking/src/AssetResourceRequest.cpp index c0150fd3ed..f4a3b20fd5 100644 --- a/libraries/networking/src/AssetResourceRequest.cpp +++ b/libraries/networking/src/AssetResourceRequest.cpp @@ -156,7 +156,11 @@ void AssetResourceRequest::requestHash(const AssetHash& hash) { } auto statTracker = DependencyManager::get(); - + + if (_assetRequest->loadedFromCache()) { + _loadedFromCache = true; + } + _state = Finished; emit finished(); From 1f24e38585cca9d1d7919e803b4806569af34570 Mon Sep 17 00:00:00 2001 From: volansystech Date: Wed, 24 May 2017 21:00:40 +0530 Subject: [PATCH 19/73] Initial Commit: Switching from Desktop mode to HMD [Oculus Rift] mode automatically when the user wear Oculus Rift. --- interface/src/Application.cpp | 54 ++++++++++++++----- interface/src/Application.h | 10 ++-- .../display-plugins/OpenGLDisplayPlugin.cpp | 15 +++++- .../src/display-plugins/OpenGLDisplayPlugin.h | 6 +++ libraries/plugins/src/plugins/Plugin.h | 13 +++++ .../oculus/src/OculusBaseDisplayPlugin.cpp | 11 ++++ plugins/oculus/src/OculusBaseDisplayPlugin.h | 2 + 7 files changed, 92 insertions(+), 19 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ced5e51565..99c2b2febf 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1338,11 +1338,18 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo properties["active_display_plugin"] = getActiveDisplayPlugin()->getName(); properties["using_hmd"] = isHMDMode(); - if (isOculusRiftPluginAvailable()){ - qCDebug(interfaceapp) << "Oculus Rift Plugin is available"; - QTimer *switchModeTimer = new QTimer(this); - connect(switchModeTimer, SIGNAL(timeout()), this, SLOT(switchmode())); - switchModeTimer->start(500); + if (isOculusRiftPluginAvailable()) { + // If Oculus Rift Plugin is Available,And Current Display Plugin is not Oculus Rift + // then startOculusRiftStandBySession to listen Oculus HMD Mounted status. + if (getActiveDisplayPlugin()->getName() != "Oculus Rift" && + !oculusRiftPlugin->isFakeSessionActive()) { + startOculusRiftStandBySession(); + } + // Poll periodically to check whether the user has worn Oculus HMD or not. And switch mode + // accordingly. If the user wear HMD, switch to VR mode, if remove switch to Desktop mode. + QTimer *switchDisplayModeTimer = new QTimer(this); + connect(switchDisplayModeTimer, SIGNAL(timeout()), this, SLOT(switchDisplayModeForOculus())); + switchDisplayModeTimer->start(500); } auto glInfo = getGLContextData(); @@ -1574,7 +1581,9 @@ void Application::aboutToQuit() { } getActiveDisplayPlugin()->deactivate(); - + if (oculusRiftPlugin && oculusRiftPlugin->isFakeSessionActive()){ + oculusRiftPlugin->endStandBySession(); + } // Hide Running Scripts dialog so that it gets destroyed in an orderly manner; prevents warnings at shutdown. DependencyManager::get()->hide("RunningScripts"); @@ -6845,7 +6854,7 @@ bool Application::isOculusRiftPluginAvailable(){ auto displayPlugins = PluginManager::getInstance()->getDisplayPlugins(); // Default to the first item on the list, in case none of the menu items match DisplayPluginPointer defaultplugin = displayPlugins.at(0); - if (defaultplugin->isHmd() && defaultplugin->getName() == "Oculus Rift"){ + if (defaultplugin->isHmd() && defaultplugin->getName() == "Oculus Rift") { oculusRiftPlugin = defaultplugin; return true; // No need to iterate again,so return } @@ -6854,7 +6863,7 @@ bool Application::isOculusRiftPluginAvailable(){ QString pluginname = displayPlugin->getName(); if (displayPlugin->isHmd() && pluginname == "Oculus Rift") { oculusRiftPlugin = displayPlugin; - _isDisplayVisible = displayPlugin->isDisplayVisible(); + _oculusHMDMountedStatus = displayPlugin->isDisplayVisible(); isOculusRiftPluginAvailable = true; break; } @@ -6862,15 +6871,32 @@ bool Application::isOculusRiftPluginAvailable(){ return isOculusRiftPluginAvailable; } -void Application::switchmode(){ - bool isDisplayVisible = oculusRiftPlugin->isDisplayVisible(); - if (isDisplayVisible != _isDisplayVisible){ - if (isDisplayVisible == false && _isDisplayVisible == true){ - qCDebug(interfaceapp) << "switching from HMD to desktop mode"; +void Application::switchDisplayModeForOculus(){ + bool currenthmdMountedStatus = oculusRiftPlugin->isDisplayVisible(); + if (currenthmdMountedStatus != _oculusHMDMountedStatus){ + // Switch to respective mode as soon as currenthmdMountedStatus changes + if (currenthmdMountedStatus == false && _oculusHMDMountedStatus == true) { + qCDebug(interfaceapp) << "Switching from HMD to desktop mode"; setActiveDisplayPlugin("Desktop"); + startOculusRiftStandBySession(); + } + if (currenthmdMountedStatus == true && _oculusHMDMountedStatus == false) { + qCDebug(interfaceapp) << "Switching from Desktop to HMD mode"; + endOculusRiftStandBySession(); + setActiveDisplayPlugin("Oculus Rift"); } } - _isDisplayVisible = isDisplayVisible; // assign current status + _oculusHMDMountedStatus = currenthmdMountedStatus; +} + +bool Application::startOculusRiftStandBySession(){ + bool isStandBySessionStarted = oculusRiftPlugin->startStandBySession(); + qCDebug(interfaceapp) << "startOculusRiftStandBySession: " << isStandBySessionStarted; + return isStandBySessionStarted; +} + +void Application::endOculusRiftStandBySession(){ + oculusRiftPlugin->endStandBySession(); } mat4 Application::getEyeProjection(int eye) const { diff --git a/interface/src/Application.h b/interface/src/Application.h index c181e74c74..a6ac244dc8 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -443,7 +443,7 @@ private slots: void addAssetToWorldErrorTimeout(); void handleSandboxStatus(QNetworkReply* reply); - void switchmode(); + void switchDisplayModeForOculus(); private: static void initDisplay(); void init(); @@ -684,9 +684,13 @@ private: AudioInjector* _snapshotSoundInjector { nullptr }; SharedSoundPointer _snapshotSound; - bool isOculusRiftPluginAvailable(); + DisplayPluginPointer oculusRiftPlugin; - bool _isDisplayVisible; + + bool isOculusRiftPluginAvailable(); + bool _oculusHMDMountedStatus; // Keep track of HMD Mounted Flag + bool startOculusRiftStandBySession(); + void endOculusRiftStandBySession(); }; diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index 306db98b35..639acc7739 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -315,8 +315,7 @@ bool OpenGLDisplayPlugin::activate() { if (isHmd() && (getHmdScreen() >= 0)) { _container->showDisplayPluginsTools(); } - - return Parent::activate(); + return Parent::activate(); } void OpenGLDisplayPlugin::deactivate() { @@ -339,6 +338,18 @@ void OpenGLDisplayPlugin::deactivate() { Parent::deactivate(); } +bool OpenGLDisplayPlugin::startStandBySession() { + if (!activateStandBySession()) { + return false; + } + return Parent::startStandBySession(); +} + +void OpenGLDisplayPlugin::endStandBySession() { + deactivateStandBySession(); + return Parent::endStandBySession(); +} + void OpenGLDisplayPlugin::customizeContext() { auto presentThread = DependencyManager::get(); Q_ASSERT(thread() == presentThread->thread()); diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h index e1eea5de6c..ecde3b3c93 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h @@ -42,6 +42,8 @@ public: // between the main thread and the presentation thread bool activate() override final; void deactivate() override final; + bool startStandBySession() override final; + void endStandBySession() override final; bool eventFilter(QObject* receiver, QEvent* event) override; bool isDisplayVisible() const override { return true; } @@ -99,6 +101,10 @@ protected: // Returns true on successful activation virtual bool internalActivate() { return true; } virtual void internalDeactivate() {} + + // Returns true on successful activation of standby session + virtual bool activateStandBySession() { return true; } + virtual void deactivateStandBySession() {} // Plugin specific functionality to send the composed scene to the output window or device virtual void internalPresent(); diff --git a/libraries/plugins/src/plugins/Plugin.h b/libraries/plugins/src/plugins/Plugin.h index 15588fafa4..74f04fff18 100644 --- a/libraries/plugins/src/plugins/Plugin.h +++ b/libraries/plugins/src/plugins/Plugin.h @@ -53,6 +53,18 @@ public: virtual bool isActive() { return _active; } + virtual bool startStandBySession(){ + _standbysessionactive = true; + return _standbysessionactive; + } + + virtual void endStandBySession(){ + _standbysessionactive = false; + } + + virtual bool isFakeSessionActive() { + return _standbysessionactive; + } /** * Called by the application during it's idle phase. If the plugin needs to do @@ -73,6 +85,7 @@ signals: protected: bool _active { false }; + bool _standbysessionactive { false }; PluginContainer* _container { nullptr }; static const char* UNKNOWN_PLUGIN_ID; diff --git a/plugins/oculus/src/OculusBaseDisplayPlugin.cpp b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp index 26906ef2fb..28e30e0d21 100644 --- a/plugins/oculus/src/OculusBaseDisplayPlugin.cpp +++ b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp @@ -127,6 +127,17 @@ void OculusBaseDisplayPlugin::internalDeactivate() { _session = nullptr; } +bool OculusBaseDisplayPlugin::activateStandBySession() { + _session = acquireOculusSession(); + if (!_session) { + return false; + } + return true; +} +void OculusBaseDisplayPlugin::deactivateStandBySession() { + releaseOculusSession(); + _session = nullptr; +} void OculusBaseDisplayPlugin::updatePresentPose() { //mat4 sensorResetMat; //_currentPresentFrameInfo.sensorSampleTime = ovr_GetTimeInSeconds(); diff --git a/plugins/oculus/src/OculusBaseDisplayPlugin.h b/plugins/oculus/src/OculusBaseDisplayPlugin.h index e5dc75095d..79085f817b 100644 --- a/plugins/oculus/src/OculusBaseDisplayPlugin.h +++ b/plugins/oculus/src/OculusBaseDisplayPlugin.h @@ -33,6 +33,8 @@ protected: void uncustomizeContext() override; bool internalActivate() override; void internalDeactivate() override; + bool activateStandBySession() override; + void deactivateStandBySession() override; void updatePresentPose() override; protected: From a2851b5bcbe9db8147348e5d54543a666e2b690b Mon Sep 17 00:00:00 2001 From: volansystech Date: Thu, 25 May 2017 18:32:46 +0530 Subject: [PATCH 20/73] Put proper comments and indentation. --- interface/src/Application.cpp | 22 +++++++++---------- interface/src/Application.h | 5 ++--- .../display-plugins/OpenGLDisplayPlugin.cpp | 2 +- libraries/plugins/src/plugins/Plugin.h | 16 +++++++------- 4 files changed, 22 insertions(+), 23 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index fda9b7b8f9..a40f31a8bb 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1339,14 +1339,14 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo properties["using_hmd"] = isHMDMode(); if (isOculusRiftPluginAvailable()) { - // If Oculus Rift Plugin is Available,And Current Display Plugin is not Oculus Rift + // If Oculus Rift Plugin is available and current display plugin is not Oculus Rift // then startOculusRiftStandBySession to listen Oculus HMD Mounted status. if (getActiveDisplayPlugin()->getName() != "Oculus Rift" && - !oculusRiftPlugin->isFakeSessionActive()) { + !oculusRiftPlugin->isStandBySessionActive()) { startOculusRiftStandBySession(); } - // Poll periodically to check whether the user has worn Oculus HMD or not. And switch mode - // accordingly. If the user wear HMD, switch to VR mode, if remove switch to Desktop mode. + // Poll periodically to check whether the user has worn Oculus HMD or not. And switch Display mode accordingly. + // If the user wear Oculus HMD then switch to VR mode. If the user removes Oculus HMD then switch to Desktop mode. QTimer *switchDisplayModeTimer = new QTimer(this); connect(switchDisplayModeTimer, SIGNAL(timeout()), this, SLOT(switchDisplayModeForOculus())); switchDisplayModeTimer->start(500); @@ -1581,7 +1581,7 @@ void Application::aboutToQuit() { } getActiveDisplayPlugin()->deactivate(); - if (oculusRiftPlugin && oculusRiftPlugin->isFakeSessionActive()){ + if (oculusRiftPlugin && oculusRiftPlugin->isStandBySessionActive()) { oculusRiftPlugin->endStandBySession(); } // Hide Running Scripts dialog so that it gets destroyed in an orderly manner; prevents warnings at shutdown. @@ -6846,14 +6846,14 @@ void Application::updateDisplayMode() { Q_ASSERT_X(_displayPlugin, "Application::updateDisplayMode", "could not find an activated display plugin"); } -bool Application::isOculusRiftPluginAvailable(){ +bool Application::isOculusRiftPluginAvailable() { bool isOculusRiftPluginAvailable = false; auto displayPlugins = PluginManager::getInstance()->getDisplayPlugins(); // Default to the first item on the list, in case none of the menu items match DisplayPluginPointer defaultplugin = displayPlugins.at(0); if (defaultplugin->isHmd() && defaultplugin->getName() == "Oculus Rift") { oculusRiftPlugin = defaultplugin; - return true; // No need to iterate again,so return + return true; } // Iterate to check If Oculus Rift Plugin is available foreach(DisplayPluginPointer displayPlugin, PluginManager::getInstance()->getDisplayPlugins()) { @@ -6868,9 +6868,9 @@ bool Application::isOculusRiftPluginAvailable(){ return isOculusRiftPluginAvailable; } -void Application::switchDisplayModeForOculus(){ +void Application::switchDisplayModeForOculus() { bool currenthmdMountedStatus = oculusRiftPlugin->isDisplayVisible(); - if (currenthmdMountedStatus != _oculusHMDMountedStatus){ + if (currenthmdMountedStatus != _oculusHMDMountedStatus) { // Switch to respective mode as soon as currenthmdMountedStatus changes if (currenthmdMountedStatus == false && _oculusHMDMountedStatus == true) { qCDebug(interfaceapp) << "Switching from HMD to desktop mode"; @@ -6886,13 +6886,13 @@ void Application::switchDisplayModeForOculus(){ _oculusHMDMountedStatus = currenthmdMountedStatus; } -bool Application::startOculusRiftStandBySession(){ +bool Application::startOculusRiftStandBySession() { bool isStandBySessionStarted = oculusRiftPlugin->startStandBySession(); qCDebug(interfaceapp) << "startOculusRiftStandBySession: " << isStandBySessionStarted; return isStandBySessionStarted; } -void Application::endOculusRiftStandBySession(){ +void Application::endOculusRiftStandBySession() { oculusRiftPlugin->endStandBySession(); } diff --git a/interface/src/Application.h b/interface/src/Application.h index 6b172cdb9e..112b650160 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -152,7 +152,7 @@ public: void paintGL(); void resizeGL(); - bool event(QEvent* event) override; + bool event(QEvent* event) override; bool eventFilter(QObject* object, QEvent* event) override; glm::uvec2 getCanvasSize() const; @@ -685,9 +685,8 @@ private: DisplayPluginPointer oculusRiftPlugin; - bool isOculusRiftPluginAvailable(); - bool _oculusHMDMountedStatus; // Keep track of HMD Mounted Flag + bool _oculusHMDMountedStatus; // Keep track of Oculus Rift HMDMounted Flag bool startOculusRiftStandBySession(); void endOculusRiftStandBySession(); }; diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index 96d3d8114c..cebe844b84 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -315,7 +315,7 @@ bool OpenGLDisplayPlugin::activate() { if (isHmd() && (getHmdScreen() >= 0)) { _container->showDisplayPluginsTools(); } - return Parent::activate(); + return Parent::activate(); } void OpenGLDisplayPlugin::deactivate() { diff --git a/libraries/plugins/src/plugins/Plugin.h b/libraries/plugins/src/plugins/Plugin.h index 74f04fff18..045a9eee15 100644 --- a/libraries/plugins/src/plugins/Plugin.h +++ b/libraries/plugins/src/plugins/Plugin.h @@ -53,17 +53,17 @@ public: virtual bool isActive() { return _active; } - virtual bool startStandBySession(){ - _standbysessionactive = true; - return _standbysessionactive; + virtual bool startStandBySession() { + _standbysessionstatus = true; + return _standbysessionstatus; } - virtual void endStandBySession(){ - _standbysessionactive = false; + virtual void endStandBySession() { + _standbysessionstatus = false; } - virtual bool isFakeSessionActive() { - return _standbysessionactive; + virtual bool isStandBySessionActive() { + return _standbysessionstatus; } /** @@ -85,7 +85,7 @@ signals: protected: bool _active { false }; - bool _standbysessionactive { false }; + bool _standbysessionstatus { false }; PluginContainer* _container { nullptr }; static const char* UNKNOWN_PLUGIN_ID; From 64191ee20ac4eac47943232c961ff50fb8eabe64 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 23 May 2017 10:11:16 -0700 Subject: [PATCH 21/73] Make the changes - big thanks to Andrew! --- libraries/entities-renderer/src/EntityTreeRenderer.cpp | 9 ++++++--- libraries/entities/src/EntityItemProperties.cpp | 7 ++++++- libraries/entities/src/EntityItemProperties.h | 1 + libraries/entities/src/EntityScriptingInterface.cpp | 10 ++++++---- 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 09308baabb..d62181c651 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -1091,15 +1091,18 @@ void EntityTreeRenderer::entityCollisionWithEntity(const EntityItemID& idA, cons // trigger scripted collision sounds and events for locally owned objects EntityItemPointer entityA = entityTree->findEntityByEntityItemID(idA); - if ((bool)entityA && myNodeID == entityA->getSimulatorID()) { + EntityItemPointer entityB = entityTree->findEntityByEntityItemID(idB); + QUuid entityASimulatorID = entityA->getSimulatorID(); + QUuid entityBSimulatorID = entityB->getSimulatorID(); + if ((bool)entityA && (myNodeID == entityASimulatorID || ((bool)entityB && myNodeID == entityBSimulatorID && entityASimulatorID.isNull()))) { playEntityCollisionSound(entityA, collision); emit collisionWithEntity(idA, idB, collision); if (_entitiesScriptEngine) { _entitiesScriptEngine->callEntityScriptMethod(idA, "collisionWithEntity", idB, collision); } } - EntityItemPointer entityB = entityTree->findEntityByEntityItemID(idB); - if ((bool)entityB && myNodeID == entityB->getSimulatorID()) { + + if ((bool)entityB && (myNodeID == entityBSimulatorID || ((bool)entityA && myNodeID == entityASimulatorID && entityBSimulatorID.isNull()))) { playEntityCollisionSound(entityB, collision); // since we're swapping A and B we need to send the inverted collision Collision invertedCollision(collision); diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 1ed020e592..4595ebf70d 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -1824,10 +1824,15 @@ bool EntityItemProperties::hasTerseUpdateChanges() const { return _positionChanged || _velocityChanged || _rotationChanged || _angularVelocityChanged || _accelerationChanged; } +bool EntityItemProperties::hasDynamicPhysicsChanges() const { + return _dynamicChanged || _velocityChanged || _angularVelocityChanged || _accelerationChanged; +} + bool EntityItemProperties::hasMiscPhysicsChanges() const { return _gravityChanged || _dimensionsChanged || _densityChanged || _frictionChanged || _restitutionChanged || _dampingChanged || _angularDampingChanged || _registrationPointChanged || - _compoundShapeURLChanged || _dynamicChanged || _collisionlessChanged || _collisionMaskChanged; + _compoundShapeURLChanged || _collisionlessChanged || _collisionMaskChanged || + _rotationChanged || _positionChanged; } void EntityItemProperties::clearSimulationOwner() { diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 590298e102..697c634c67 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -274,6 +274,7 @@ public: void setCreated(QDateTime& v); bool hasTerseUpdateChanges() const; + bool hasDynamicPhysicsChanges() const; bool hasMiscPhysicsChanges() const; void clearSimulationOwner(); diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index b184d648da..367343cb60 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -414,15 +414,17 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties& entityFound = true; // make sure the properties has a type, so that the encode can know which properties to include properties.setType(entity->getType()); - bool hasTerseUpdateChanges = properties.hasTerseUpdateChanges(); - bool hasPhysicsChanges = properties.hasMiscPhysicsChanges() || hasTerseUpdateChanges; - if (_bidOnSimulationOwnership && hasPhysicsChanges) { + bool hasMiscPhysicsChanges = properties.hasMiscPhysicsChanges(); + bool hasDynamicsChanges = properties.hasDynamicPhysicsChanges(); + // _bidOnSimulationOwnership is set per-instance of the scripting interface. + // It essentially corresponds to "Am I an AC or an Interface client?" - ACs will never bid. + if ((_bidOnSimulationOwnership && ((hasMiscPhysicsChanges && entity->isMoving()) || hasDynamicsChanges))) { auto nodeList = DependencyManager::get(); const QUuid myNodeID = nodeList->getSessionUUID(); if (entity->getSimulatorID() == myNodeID) { // we think we already own the simulation, so make sure to send ALL TerseUpdate properties - if (hasTerseUpdateChanges) { + if (properties.hasTerseUpdateChanges()) { entity->getAllTerseUpdateProperties(properties); } // TODO: if we knew that ONLY TerseUpdate properties have changed in properties AND the object From 827daade1b140c7dbfc142c6116a2fc2d931359e Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 23 May 2017 12:50:43 -0700 Subject: [PATCH 22/73] Make this PR a protocol change --- libraries/networking/src/udt/PacketHeaders.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index f88015a4e4..0dbbcd771f 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -114,7 +114,8 @@ public: EntityServerScriptLog, AdjustAvatarSorting, OctreeFileReplacement, - LAST_PACKET_TYPE = OctreeFileReplacement + SimulationBiddingChanges, + LAST_PACKET_TYPE = SimulationBiddingChanges }; }; From 8dec066c2bba98b8d02b88afa057c0c22a97ccfa Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 23 May 2017 14:41:02 -0700 Subject: [PATCH 23/73] Revert 'dynamicChanged' to be a 'misc' physics property --- libraries/entities/src/EntityItemProperties.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 4595ebf70d..fa4df72387 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -1825,13 +1825,13 @@ bool EntityItemProperties::hasTerseUpdateChanges() const { } bool EntityItemProperties::hasDynamicPhysicsChanges() const { - return _dynamicChanged || _velocityChanged || _angularVelocityChanged || _accelerationChanged; + return _velocityChanged || _angularVelocityChanged || _accelerationChanged; } bool EntityItemProperties::hasMiscPhysicsChanges() const { return _gravityChanged || _dimensionsChanged || _densityChanged || _frictionChanged || _restitutionChanged || _dampingChanged || _angularDampingChanged || _registrationPointChanged || - _compoundShapeURLChanged || _collisionlessChanged || _collisionMaskChanged || + _compoundShapeURLChanged || _dynamicChanged || _collisionlessChanged || _collisionMaskChanged || _rotationChanged || _positionChanged; } From ebe6ce9c8d3640e7e357755fa11bde766a6b95cb Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 24 May 2017 10:16:51 -0700 Subject: [PATCH 24/73] Committing checkpoint changes, then testing --- .../src/EntityTreeRenderer.cpp | 39 +++++++++++-------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index d62181c651..7b2333ade9 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -1092,24 +1092,29 @@ void EntityTreeRenderer::entityCollisionWithEntity(const EntityItemID& idA, cons // trigger scripted collision sounds and events for locally owned objects EntityItemPointer entityA = entityTree->findEntityByEntityItemID(idA); EntityItemPointer entityB = entityTree->findEntityByEntityItemID(idB); - QUuid entityASimulatorID = entityA->getSimulatorID(); - QUuid entityBSimulatorID = entityB->getSimulatorID(); - if ((bool)entityA && (myNodeID == entityASimulatorID || ((bool)entityB && myNodeID == entityBSimulatorID && entityASimulatorID.isNull()))) { - playEntityCollisionSound(entityA, collision); - emit collisionWithEntity(idA, idB, collision); - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(idA, "collisionWithEntity", idB, collision); - } - } + if ((bool)entityA && (bool)entityB) { + QUuid entityASimulatorID = entityA->getSimulatorID(); + QUuid entityBSimulatorID = entityB->getSimulatorID(); + bool entityAIsStatic = !entityA->getDynamic() && !entityA->isMoving(); + bool entityBIsStatic = !entityB->getDynamic() && !entityB->isMoving(); - if ((bool)entityB && (myNodeID == entityBSimulatorID || ((bool)entityA && myNodeID == entityASimulatorID && entityBSimulatorID.isNull()))) { - playEntityCollisionSound(entityB, collision); - // since we're swapping A and B we need to send the inverted collision - Collision invertedCollision(collision); - invertedCollision.invert(); - emit collisionWithEntity(idB, idA, invertedCollision); - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(idB, "collisionWithEntity", idA, invertedCollision); + if (myNodeID == entityASimulatorID || (myNodeID == entityBSimulatorID && entityAIsStatic)) { + playEntityCollisionSound(entityA, collision); + emit collisionWithEntity(idA, idB, collision); + if (_entitiesScriptEngine) { + _entitiesScriptEngine->callEntityScriptMethod(idA, "collisionWithEntity", idB, collision); + } + } + + if (myNodeID == entityBSimulatorID || (myNodeID == entityASimulatorID && entityBIsStatic)) { + playEntityCollisionSound(entityB, collision); + // since we're swapping A and B we need to send the inverted collision + Collision invertedCollision(collision); + invertedCollision.invert(); + emit collisionWithEntity(idB, idA, invertedCollision); + if (_entitiesScriptEngine) { + _entitiesScriptEngine->callEntityScriptMethod(idB, "collisionWithEntity", idA, invertedCollision); + } } } } From 3ec73cc5e1ffe2b7a5cd8c2cbcb81d5159322cf3 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 24 May 2017 11:17:03 -0700 Subject: [PATCH 25/73] Changes after discussion with Brad --- .../src/EntityTreeRenderer.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 7b2333ade9..fccc6f512f 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -1095,10 +1095,20 @@ void EntityTreeRenderer::entityCollisionWithEntity(const EntityItemID& idA, cons if ((bool)entityA && (bool)entityB) { QUuid entityASimulatorID = entityA->getSimulatorID(); QUuid entityBSimulatorID = entityB->getSimulatorID(); - bool entityAIsStatic = !entityA->getDynamic() && !entityA->isMoving(); - bool entityBIsStatic = !entityB->getDynamic() && !entityB->isMoving(); + bool entityAIsDynamic = entityA->getDynamic(); + bool entityBIsDynamic = entityB->getDynamic(); - if (myNodeID == entityASimulatorID || (myNodeID == entityBSimulatorID && entityAIsStatic)) { +#ifdef WANT_DEBUG + bool bothEntitiesStatic = !entityAIsDynamic && !entityBIsDynamic; + if (bothEntitiesStatic) { + qCDebug(entities) << "A collision has occurred between two static entities!"; + qCDebug(entities) << "Entity A ID:" << entityA->getID(); + qCDebug(entities) << "Entity B ID:" << entityB->getID(); + } + assert(!bothEntitiesStatic); +#endif + + if ((myNodeID == entityASimulatorID && entityAIsDynamic) || (myNodeID == entityBSimulatorID && !entityAIsDynamic)) { playEntityCollisionSound(entityA, collision); emit collisionWithEntity(idA, idB, collision); if (_entitiesScriptEngine) { @@ -1106,7 +1116,7 @@ void EntityTreeRenderer::entityCollisionWithEntity(const EntityItemID& idA, cons } } - if (myNodeID == entityBSimulatorID || (myNodeID == entityASimulatorID && entityBIsStatic)) { + if ((myNodeID == entityBSimulatorID && entityBIsDynamic) || (myNodeID == entityASimulatorID && !entityBIsDynamic)) { playEntityCollisionSound(entityB, collision); // since we're swapping A and B we need to send the inverted collision Collision invertedCollision(collision); From 21d396bbb507b152c6a89152328b1f68da188f29 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 24 May 2017 14:15:59 -0700 Subject: [PATCH 26/73] Pull out ownership bidding changes --- libraries/entities/src/EntityItemProperties.cpp | 7 +------ libraries/entities/src/EntityItemProperties.h | 1 - libraries/entities/src/EntityScriptingInterface.cpp | 10 ++++------ libraries/networking/src/udt/PacketHeaders.h | 4 ++-- 4 files changed, 7 insertions(+), 15 deletions(-) diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index fa4df72387..1ed020e592 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -1824,15 +1824,10 @@ bool EntityItemProperties::hasTerseUpdateChanges() const { return _positionChanged || _velocityChanged || _rotationChanged || _angularVelocityChanged || _accelerationChanged; } -bool EntityItemProperties::hasDynamicPhysicsChanges() const { - return _velocityChanged || _angularVelocityChanged || _accelerationChanged; -} - bool EntityItemProperties::hasMiscPhysicsChanges() const { return _gravityChanged || _dimensionsChanged || _densityChanged || _frictionChanged || _restitutionChanged || _dampingChanged || _angularDampingChanged || _registrationPointChanged || - _compoundShapeURLChanged || _dynamicChanged || _collisionlessChanged || _collisionMaskChanged || - _rotationChanged || _positionChanged; + _compoundShapeURLChanged || _dynamicChanged || _collisionlessChanged || _collisionMaskChanged; } void EntityItemProperties::clearSimulationOwner() { diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 697c634c67..590298e102 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -274,7 +274,6 @@ public: void setCreated(QDateTime& v); bool hasTerseUpdateChanges() const; - bool hasDynamicPhysicsChanges() const; bool hasMiscPhysicsChanges() const; void clearSimulationOwner(); diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 367343cb60..b184d648da 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -414,17 +414,15 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties& entityFound = true; // make sure the properties has a type, so that the encode can know which properties to include properties.setType(entity->getType()); - bool hasMiscPhysicsChanges = properties.hasMiscPhysicsChanges(); - bool hasDynamicsChanges = properties.hasDynamicPhysicsChanges(); - // _bidOnSimulationOwnership is set per-instance of the scripting interface. - // It essentially corresponds to "Am I an AC or an Interface client?" - ACs will never bid. - if ((_bidOnSimulationOwnership && ((hasMiscPhysicsChanges && entity->isMoving()) || hasDynamicsChanges))) { + bool hasTerseUpdateChanges = properties.hasTerseUpdateChanges(); + bool hasPhysicsChanges = properties.hasMiscPhysicsChanges() || hasTerseUpdateChanges; + if (_bidOnSimulationOwnership && hasPhysicsChanges) { auto nodeList = DependencyManager::get(); const QUuid myNodeID = nodeList->getSessionUUID(); if (entity->getSimulatorID() == myNodeID) { // we think we already own the simulation, so make sure to send ALL TerseUpdate properties - if (properties.hasTerseUpdateChanges()) { + if (hasTerseUpdateChanges) { entity->getAllTerseUpdateProperties(properties); } // TODO: if we knew that ONLY TerseUpdate properties have changed in properties AND the object diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index 0dbbcd771f..2cc3a2c42e 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -114,8 +114,8 @@ public: EntityServerScriptLog, AdjustAvatarSorting, OctreeFileReplacement, - SimulationBiddingChanges, - LAST_PACKET_TYPE = SimulationBiddingChanges + CollisionEventChanges, + LAST_PACKET_TYPE = CollisionEventChanges }; }; From 252298938b89a98235efe0d58306435d67c5b50d Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 25 May 2017 09:28:11 -0700 Subject: [PATCH 27/73] Update conditional to handle 'other unowned' case --- libraries/entities-renderer/src/EntityTreeRenderer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index fccc6f512f..e029ca6ada 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -1108,7 +1108,7 @@ void EntityTreeRenderer::entityCollisionWithEntity(const EntityItemID& idA, cons assert(!bothEntitiesStatic); #endif - if ((myNodeID == entityASimulatorID && entityAIsDynamic) || (myNodeID == entityBSimulatorID && !entityAIsDynamic)) { + if ((myNodeID == entityASimulatorID && entityAIsDynamic) || (myNodeID == entityBSimulatorID && (!entityAIsDynamic || entityASimulatorID.isNull()))) { playEntityCollisionSound(entityA, collision); emit collisionWithEntity(idA, idB, collision); if (_entitiesScriptEngine) { @@ -1116,7 +1116,7 @@ void EntityTreeRenderer::entityCollisionWithEntity(const EntityItemID& idA, cons } } - if ((myNodeID == entityBSimulatorID && entityBIsDynamic) || (myNodeID == entityASimulatorID && !entityBIsDynamic)) { + if ((myNodeID == entityBSimulatorID && entityBIsDynamic) || (myNodeID == entityASimulatorID && (!entityBIsDynamic || entityBSimulatorID.isNull()))) { playEntityCollisionSound(entityB, collision); // since we're swapping A and B we need to send the inverted collision Collision invertedCollision(collision); From 0a7a42bdc3855b1b08e92930f182815276130f86 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 26 May 2017 12:04:35 -0700 Subject: [PATCH 28/73] fix force of BC3 instead of BC1a compression --- libraries/image/src/image/Image.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/libraries/image/src/image/Image.cpp b/libraries/image/src/image/Image.cpp index dcc65e8995..f274dc54f8 100644 --- a/libraries/image/src/image/Image.cpp +++ b/libraries/image/src/image/Image.cpp @@ -493,10 +493,6 @@ gpu::TexturePointer TextureUsage::process2DTextureColorFromImage(const QImage& s if (validAlpha) { processTextureAlpha(image, validAlpha, alphaAsMask); - - // NOTE: This disables BC1a compression because it was producing odd artifacts on text textures - // for the tutorial. Instead we use BC3 (which is larger) but doesn't produce the same artifacts). - alphaAsMask = false; } gpu::TexturePointer theTexture = nullptr; @@ -506,7 +502,9 @@ gpu::TexturePointer TextureUsage::process2DTextureColorFromImage(const QImage& s gpu::Element formatGPU; if (isColorTexturesCompressionEnabled()) { if (validAlpha) { - formatGPU = alphaAsMask ? gpu::Element::COLOR_COMPRESSED_SRGBA_MASK : gpu::Element::COLOR_COMPRESSED_SRGBA; + // NOTE: This disables BC1a compression because it was producing odd artifacts on text textures + // for the tutorial. Instead we use BC3 (which is larger) but doesn't produce the same artifacts). + formatGPU = gpu::Element::COLOR_COMPRESSED_SRGBA; } else { formatGPU = gpu::Element::COLOR_COMPRESSED_SRGB; } From bf057219acdeb201a1f78be085aa017eae187bd9 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 26 May 2017 14:37:24 -0700 Subject: [PATCH 29/73] fix reference to pending transfer count for progress/stats --- scripts/developer/utilities/render/stats.qml | 13 ++++++------- scripts/system/progress.js | 4 ++-- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/scripts/developer/utilities/render/stats.qml b/scripts/developer/utilities/render/stats.qml index 7acf678570..54e0dc4ce8 100644 --- a/scripts/developer/utilities/render/stats.qml +++ b/scripts/developer/utilities/render/stats.qml @@ -20,9 +20,9 @@ Item { id: stats spacing: 8 anchors.fill:parent - + property var config: Render.getConfig("Stats") - + function evalEvenHeight() { // Why do we have to do that manually ? cannot seem to find a qml / anchor / layout mode that does that ? return (height - spacing * (children.length - 1)) / children.length @@ -81,7 +81,7 @@ Item { color: "#1AC567" }, { - prop: "textureGPUTransferCount", + prop: "texturePendingGPUTransferCount", label: "Transfer", color: "#9495FF" } @@ -158,7 +158,7 @@ Item { } ] } - + PlotPerf { title: "State Changes" height: parent.evalEvenHeight() @@ -180,7 +180,7 @@ Item { color: "#1AC567" } ] - } + } property var drawOpaqueConfig: Render.getConfig("DrawOpaqueDeferred") property var drawTransparentConfig: Render.getConfig("DrawTransparentDeferred") @@ -211,7 +211,7 @@ Item { color: "#FED959" } ] - } + } PlotPerf { title: "Timing" @@ -250,4 +250,3 @@ Item { } } - diff --git a/scripts/system/progress.js b/scripts/system/progress.js index 81da38c8c2..f4741c5b6a 100644 --- a/scripts/system/progress.js +++ b/scripts/system/progress.js @@ -261,7 +261,7 @@ } } - gpuTextures = Render.getConfig("Stats").textureGPUTransferCount; + gpuTextures = Render.getConfig("Stats").texturePendingGPUTransferCount; // Update state if (!visible) { // Not visible because no recent downloads @@ -290,7 +290,7 @@ }, FADE_OUT_WAIT); } } else { - if (displayProgress < 100 || gpuTextures > 0) { // Was finished and waiting to fade out but have resumed so + if (displayProgress < 100 || gpuTextures > 0) { // Was finished and waiting to fade out but have resumed so // don't fade out Script.clearInterval(fadeWaitTimer); fadeWaitTimer = null; From 0920dbc1a8910c986b2c83b2422aa7fa63e192d9 Mon Sep 17 00:00:00 2001 From: volansystech Date: Mon, 29 May 2017 15:53:33 +0530 Subject: [PATCH 30/73] Resolve the comments of @ZappoMan. --- interface/src/Application.cpp | 111 +++++++++--------- interface/src/Application.h | 13 +- .../display-plugins/OpenGLDisplayPlugin.cpp | 12 +- .../src/display-plugins/OpenGLDisplayPlugin.h | 10 +- libraries/plugins/src/plugins/Plugin.h | 22 ++-- .../oculus/src/OculusBaseDisplayPlugin.cpp | 14 +-- plugins/oculus/src/OculusBaseDisplayPlugin.h | 4 +- 7 files changed, 92 insertions(+), 94 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a40f31a8bb..57a627fe53 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -244,6 +244,8 @@ static const QString DESKTOP_LOCATION = QStandardPaths::writableLocation(QStanda Setting::Handle maxOctreePacketsPerSecond("maxOctreePPS", DEFAULT_MAX_OCTREE_PPS); static const QString MARKETPLACE_CDN_HOSTNAME = "mpassets.highfidelity.com"; +static const int INTERVAL_TO_CHECK_HMD_MOUNTED_STATUS = 500; // milliseconds +static const QString OCULUS_RIFT_DISPLAY_PLUGIN_NAME = "Oculus Rift"; const QHash Application::_acceptedExtensions { { SVO_EXTENSION, &Application::importSVOFromURL }, @@ -1338,19 +1340,20 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo properties["active_display_plugin"] = getActiveDisplayPlugin()->getName(); properties["using_hmd"] = isHMDMode(); - if (isOculusRiftPluginAvailable()) { - // If Oculus Rift Plugin is available and current display plugin is not Oculus Rift - // then startOculusRiftStandBySession to listen Oculus HMD Mounted status. - if (getActiveDisplayPlugin()->getName() != "Oculus Rift" && - !oculusRiftPlugin->isStandBySessionActive()) { - startOculusRiftStandBySession(); - } - // Poll periodically to check whether the user has worn Oculus HMD or not. And switch Display mode accordingly. - // If the user wear Oculus HMD then switch to VR mode. If the user removes Oculus HMD then switch to Desktop mode. - QTimer *switchDisplayModeTimer = new QTimer(this); - connect(switchDisplayModeTimer, SIGNAL(timeout()), this, SLOT(switchDisplayModeForOculus())); - switchDisplayModeTimer->start(500); - } + if (isHMDPluginAvailable()) { + // Currently, autoswitch display mode support is only for Oculus Rift. + // If HMD Plugin is available and current display plugin is not HMD plugin + // then startHMDStandBySession to listen HMD Mounted status. + if (getActiveDisplayPlugin()->getName() != _hmdPluginName && + !_hmdPlugin->isStandBySessionActive()) { + startHMDStandBySession(); + } + // Poll periodically to check whether the user has worn HMD or not. And switch Display mode accordingly. + // If the user wear HMD then switch to VR mode. If the user removes HMD then switch to Desktop mode. + QTimer *switchDisplayModeTimer = new QTimer(this); + connect(switchDisplayModeTimer, SIGNAL(timeout()), this, SLOT(switchDisplayMode())); + switchDisplayModeTimer->start(INTERVAL_TO_CHECK_HMD_MOUNTED_STATUS); + } auto glInfo = getGLContextData(); properties["gl_info"] = glInfo; @@ -1581,8 +1584,8 @@ void Application::aboutToQuit() { } getActiveDisplayPlugin()->deactivate(); - if (oculusRiftPlugin && oculusRiftPlugin->isStandBySessionActive()) { - oculusRiftPlugin->endStandBySession(); + if (_hmdPlugin && _hmdPlugin->isStandBySessionActive()) { + _hmdPlugin->endStandBySession(); } // Hide Running Scripts dialog so that it gets destroyed in an orderly manner; prevents warnings at shutdown. DependencyManager::get()->hide("RunningScripts"); @@ -6846,54 +6849,48 @@ void Application::updateDisplayMode() { Q_ASSERT_X(_displayPlugin, "Application::updateDisplayMode", "could not find an activated display plugin"); } -bool Application::isOculusRiftPluginAvailable() { - bool isOculusRiftPluginAvailable = false; - auto displayPlugins = PluginManager::getInstance()->getDisplayPlugins(); - // Default to the first item on the list, in case none of the menu items match - DisplayPluginPointer defaultplugin = displayPlugins.at(0); - if (defaultplugin->isHmd() && defaultplugin->getName() == "Oculus Rift") { - oculusRiftPlugin = defaultplugin; - return true; - } - // Iterate to check If Oculus Rift Plugin is available - foreach(DisplayPluginPointer displayPlugin, PluginManager::getInstance()->getDisplayPlugins()) { - QString pluginname = displayPlugin->getName(); - if (displayPlugin->isHmd() && pluginname == "Oculus Rift") { - oculusRiftPlugin = displayPlugin; - _oculusHMDMountedStatus = displayPlugin->isDisplayVisible(); - isOculusRiftPluginAvailable = true; - break; - } - } - return isOculusRiftPluginAvailable; +bool Application::isHMDPluginAvailable() { + bool isHMDEnabledPluginAvailable = false; + auto displayPlugins = PluginManager::getInstance()->getDisplayPlugins(); + // Currently, autoswitch display mode support is only for Oculus Rift. + foreach(DisplayPluginPointer displayPlugin, PluginManager::getInstance()->getDisplayPlugins()) { + if (displayPlugin->isHmd() && displayPlugin->getName() == OCULUS_RIFT_DISPLAY_PLUGIN_NAME) { + _hmdPlugin = displayPlugin; + _hmdPluginName = displayPlugin->getName(); + _hmdMountedStatus = displayPlugin->isDisplayVisible(); + isHMDEnabledPluginAvailable = true; + break; + } + } + return isHMDEnabledPluginAvailable; } -void Application::switchDisplayModeForOculus() { - bool currenthmdMountedStatus = oculusRiftPlugin->isDisplayVisible(); - if (currenthmdMountedStatus != _oculusHMDMountedStatus) { - // Switch to respective mode as soon as currenthmdMountedStatus changes - if (currenthmdMountedStatus == false && _oculusHMDMountedStatus == true) { - qCDebug(interfaceapp) << "Switching from HMD to desktop mode"; - setActiveDisplayPlugin("Desktop"); - startOculusRiftStandBySession(); - } - if (currenthmdMountedStatus == true && _oculusHMDMountedStatus == false) { - qCDebug(interfaceapp) << "Switching from Desktop to HMD mode"; - endOculusRiftStandBySession(); - setActiveDisplayPlugin("Oculus Rift"); - } - } - _oculusHMDMountedStatus = currenthmdMountedStatus; +void Application::switchDisplayMode() { + bool currentHMDMountedStatus = _hmdPlugin->isDisplayVisible(); + if (currentHMDMountedStatus != _hmdMountedStatus) { + // Switch to respective mode as soon as currenthmdMountedStatus changes + if (currentHMDMountedStatus == false && _hmdMountedStatus == true) { + qCDebug(interfaceapp) << "Switching from HMD to desktop mode"; + setActiveDisplayPlugin("Desktop"); + startHMDStandBySession(); + } + if (currentHMDMountedStatus == true && _hmdMountedStatus == false) { + qCDebug(interfaceapp) << "Switching from Desktop to HMD mode"; + endHMDStandBySession(); + setActiveDisplayPlugin(_hmdPluginName); + } + } + _hmdMountedStatus = currentHMDMountedStatus; } -bool Application::startOculusRiftStandBySession() { - bool isStandBySessionStarted = oculusRiftPlugin->startStandBySession(); - qCDebug(interfaceapp) << "startOculusRiftStandBySession: " << isStandBySessionStarted; - return isStandBySessionStarted; +bool Application::startHMDStandBySession() { + bool isStandBySessionStarted = _hmdPlugin->startStandBySession(); + qCDebug(interfaceapp) << "startHMDStandBySession: " << isStandBySessionStarted; + return isStandBySessionStarted; } -void Application::endOculusRiftStandBySession() { - oculusRiftPlugin->endStandBySession(); +void Application::endHMDStandBySession() { + _hmdPlugin->endStandBySession(); } mat4 Application::getEyeProjection(int eye) const { diff --git a/interface/src/Application.h b/interface/src/Application.h index 112b650160..699cb9f879 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -442,7 +442,7 @@ private slots: void addAssetToWorldErrorTimeout(); void handleSandboxStatus(QNetworkReply* reply); - void switchDisplayModeForOculus(); + void switchDisplayMode(); private: static void initDisplay(); void init(); @@ -684,11 +684,12 @@ private: SharedSoundPointer _snapshotSound; - DisplayPluginPointer oculusRiftPlugin; - bool isOculusRiftPluginAvailable(); - bool _oculusHMDMountedStatus; // Keep track of Oculus Rift HMDMounted Flag - bool startOculusRiftStandBySession(); - void endOculusRiftStandBySession(); + DisplayPluginPointer _hmdPlugin; // HMD Enabled Plugin + QString _hmdPluginName; + bool isHMDPluginAvailable(); + bool _hmdMountedStatus; // Check HMD Mounted status + bool startHMDStandBySession(); + void endHMDStandBySession(); }; diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index cebe844b84..3bdf9a672c 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -339,15 +339,15 @@ void OpenGLDisplayPlugin::deactivate() { } bool OpenGLDisplayPlugin::startStandBySession() { - if (!activateStandBySession()) { - return false; - } - return Parent::startStandBySession(); + if (!activateStandBySession()) { + return false; + } + return Parent::startStandBySession(); } void OpenGLDisplayPlugin::endStandBySession() { - deactivateStandBySession(); - return Parent::endStandBySession(); + deactivateStandBySession(); + return Parent::endStandBySession(); } void OpenGLDisplayPlugin::customizeContext() { diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h index ecde3b3c93..9681158c55 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h @@ -42,8 +42,8 @@ public: // between the main thread and the presentation thread bool activate() override final; void deactivate() override final; - bool startStandBySession() override final; - void endStandBySession() override final; + bool startStandBySession() override final; + void endStandBySession() override final; bool eventFilter(QObject* receiver, QEvent* event) override; bool isDisplayVisible() const override { return true; } @@ -102,9 +102,9 @@ protected: virtual bool internalActivate() { return true; } virtual void internalDeactivate() {} - // Returns true on successful activation of standby session - virtual bool activateStandBySession() { return true; } - virtual void deactivateStandBySession() {} + // Returns true on successful activation of standby session + virtual bool activateStandBySession() { return true; } + virtual void deactivateStandBySession() {} // Plugin specific functionality to send the composed scene to the output window or device virtual void internalPresent(); diff --git a/libraries/plugins/src/plugins/Plugin.h b/libraries/plugins/src/plugins/Plugin.h index 045a9eee15..11ea79186a 100644 --- a/libraries/plugins/src/plugins/Plugin.h +++ b/libraries/plugins/src/plugins/Plugin.h @@ -53,18 +53,18 @@ public: virtual bool isActive() { return _active; } - virtual bool startStandBySession() { - _standbysessionstatus = true; - return _standbysessionstatus; - } + virtual bool startStandBySession() { + _standbysessionstatus = true; + return _standbysessionstatus; + } - virtual void endStandBySession() { - _standbysessionstatus = false; - } + virtual void endStandBySession() { + _standbysessionstatus = false; + } - virtual bool isStandBySessionActive() { - return _standbysessionstatus; - } + virtual bool isStandBySessionActive() { + return _standbysessionstatus; + } /** * Called by the application during it's idle phase. If the plugin needs to do @@ -85,7 +85,7 @@ signals: protected: bool _active { false }; - bool _standbysessionstatus { false }; + bool _standbysessionstatus { false }; PluginContainer* _container { nullptr }; static const char* UNKNOWN_PLUGIN_ID; diff --git a/plugins/oculus/src/OculusBaseDisplayPlugin.cpp b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp index 28e30e0d21..df98abf408 100644 --- a/plugins/oculus/src/OculusBaseDisplayPlugin.cpp +++ b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp @@ -128,15 +128,15 @@ void OculusBaseDisplayPlugin::internalDeactivate() { } bool OculusBaseDisplayPlugin::activateStandBySession() { - _session = acquireOculusSession(); - if (!_session) { - return false; - } - return true; + _session = acquireOculusSession(); + if (!_session) { + return false; + } + return true; } void OculusBaseDisplayPlugin::deactivateStandBySession() { - releaseOculusSession(); - _session = nullptr; + releaseOculusSession(); + _session = nullptr; } void OculusBaseDisplayPlugin::updatePresentPose() { //mat4 sensorResetMat; diff --git a/plugins/oculus/src/OculusBaseDisplayPlugin.h b/plugins/oculus/src/OculusBaseDisplayPlugin.h index 79085f817b..1f54742c2d 100644 --- a/plugins/oculus/src/OculusBaseDisplayPlugin.h +++ b/plugins/oculus/src/OculusBaseDisplayPlugin.h @@ -33,8 +33,8 @@ protected: void uncustomizeContext() override; bool internalActivate() override; void internalDeactivate() override; - bool activateStandBySession() override; - void deactivateStandBySession() override; + bool activateStandBySession() override; + void deactivateStandBySession() override; void updatePresentPose() override; protected: From e90b1b5a67c8fd33d539c7d86b677ba24d17f61c Mon Sep 17 00:00:00 2001 From: volansystech Date: Mon, 29 May 2017 18:21:59 +0530 Subject: [PATCH 31/73] Resolve the comments of @ZappoMan. --- interface/src/Application.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index d219d7bcb6..b5733fa6f5 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -246,6 +246,7 @@ Setting::Handle maxOctreePacketsPerSecond("maxOctreePPS", DEFAULT_MAX_OCTRE static const QString MARKETPLACE_CDN_HOSTNAME = "mpassets.highfidelity.com"; static const int INTERVAL_TO_CHECK_HMD_MOUNTED_STATUS = 500; // milliseconds static const QString OCULUS_RIFT_DISPLAY_PLUGIN_NAME = "Oculus Rift"; +static const QString DESKTOP_DISPLAY_PLUGIN_NAME = "Desktop"; const QHash Application::_acceptedExtensions { { SVO_EXTENSION, &Application::importSVOFromURL }, @@ -1348,8 +1349,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo !_hmdPlugin->isStandBySessionActive()) { startHMDStandBySession(); } - // Poll periodically to check whether the user has worn HMD or not. And switch Display mode accordingly. - // If the user wear HMD then switch to VR mode. If the user removes HMD then switch to Desktop mode. + // Poll periodically to check whether the user has worn HMD or not. Switch Display mode accordingly. + // If the user wears HMD then switch to VR mode. If the user removes HMD then switch to Desktop mode. QTimer *switchDisplayModeTimer = new QTimer(this); connect(switchDisplayModeTimer, SIGNAL(timeout()), this, SLOT(switchDisplayMode())); switchDisplayModeTimer->start(INTERVAL_TO_CHECK_HMD_MOUNTED_STATUS); @@ -6773,7 +6774,7 @@ void Application::switchDisplayMode() { // Switch to respective mode as soon as currenthmdMountedStatus changes if (currentHMDMountedStatus == false && _hmdMountedStatus == true) { qCDebug(interfaceapp) << "Switching from HMD to desktop mode"; - setActiveDisplayPlugin("Desktop"); + setActiveDisplayPlugin(DESKTOP_DISPLAY_PLUGIN_NAME); startHMDStandBySession(); } if (currentHMDMountedStatus == true && _hmdMountedStatus == false) { From 0f80a8b7af6991a5873fafd220fde1600f2b9d27 Mon Sep 17 00:00:00 2001 From: Vladyslav Stelmakhovskyi Date: Tue, 30 May 2017 16:51:04 +0200 Subject: [PATCH 32/73] On create button, switch Tablet to landscape mode --- scripts/system/edit.js | 6 +++++- scripts/system/tablet-ui/tabletUI.js | 8 ++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/scripts/system/edit.js b/scripts/system/edit.js index f39165f3df..79064a02df 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -564,6 +564,8 @@ var toolBar = (function () { enabled: active })); isActive = active; + var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); + if (!isActive) { entityListTool.setVisible(false); gridTool.setVisible(false); @@ -572,8 +574,8 @@ var toolBar = (function () { selectionManager.clearSelections(); cameraManager.disable(); selectionDisplay.triggerMapping.disable(); + tablet.landscape = false; } else { - var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); tablet.loadQMLSource("Edit.qml"); UserActivityLogger.enabledEdit(); entityListTool.setVisible(true); @@ -581,6 +583,8 @@ var toolBar = (function () { grid.setEnabled(true); propertiesTool.setVisible(true); selectionDisplay.triggerMapping.enable(); + print("starting tablet in landscape mode") + tablet.landscape = true; // Not sure what the following was meant to accomplish, but it currently causes // everybody else to think that Interface has lost focus overall. fogbugzid:558 // Window.setFocus(); diff --git a/scripts/system/tablet-ui/tabletUI.js b/scripts/system/tablet-ui/tabletUI.js index f83e8d9550..e45fc8d87b 100644 --- a/scripts/system/tablet-ui/tabletUI.js +++ b/scripts/system/tablet-ui/tabletUI.js @@ -191,16 +191,12 @@ gTablet.updateAudioBar(currentMicLevel); } - if (validCheckTime - now > MSECS_PER_SEC/4) { - //each 250ms should be just fine + if (now - validCheckTime > MSECS_PER_SEC) { + validCheckTime = now; updateTabletWidthFromSettings(); if (UIWebTablet) { UIWebTablet.setLandscape(landscape); } - } - - if (validCheckTime - now > MSECS_PER_SEC) { - validCheckTime = now; if (tabletRezzed && UIWebTablet && !tabletIsValid()) { // when we switch domains, the tablet entity gets destroyed and recreated. this causes // the overlay to be deleted, but not recreated. If the overlay is deleted for this or any From 8559ed6260f04c61d22eac76d9057e20b8d3b900 Mon Sep 17 00:00:00 2001 From: samcake Date: Tue, 30 May 2017 16:37:10 -0700 Subject: [PATCH 33/73] Starting to add the stencil mask for hmd --- .../src/gpu/DrawTransformVertexPosition.slv | 28 ++++++++ libraries/gpu/src/gpu/DrawWhite.slf | 18 +++++ libraries/gpu/src/gpu/StandardShaderLib.cpp | 17 +++++ libraries/gpu/src/gpu/StandardShaderLib.h | 8 +++ libraries/model/src/model/Geometry.cpp | 38 ++++++++++ libraries/model/src/model/Geometry.h | 6 ++ .../src/DeferredLightingEffect.cpp | 10 +-- .../render-utils/src/RenderDeferredTask.cpp | 69 +++++++++++++++++++ .../render-utils/src/RenderDeferredTask.h | 16 +++++ 9 files changed, 205 insertions(+), 5 deletions(-) create mode 100644 libraries/gpu/src/gpu/DrawTransformVertexPosition.slv create mode 100644 libraries/gpu/src/gpu/DrawWhite.slf diff --git a/libraries/gpu/src/gpu/DrawTransformVertexPosition.slv b/libraries/gpu/src/gpu/DrawTransformVertexPosition.slv new file mode 100644 index 0000000000..cf66a615f5 --- /dev/null +++ b/libraries/gpu/src/gpu/DrawTransformVertexPosition.slv @@ -0,0 +1,28 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// Draw and transform the fed vertex position with the standard MVP stack +// Output the clip position +// +// Created by Sam Gateau on 5/30/2017 +// Copyright 2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +<@include gpu/Transform.slh@> + +<$declareStandardTransform()$> + +layout(location = 0) in vec4 inPosition; + +out vec3 varWorldPos; + +void main(void) { + // standard transform + TransformCamera cam = getTransformCamera(); + TransformObject obj = getTransformObject(); + <$transformModelToClipPos(cam, obj, inPosition, gl_Position)$> +} diff --git a/libraries/gpu/src/gpu/DrawWhite.slf b/libraries/gpu/src/gpu/DrawWhite.slf new file mode 100644 index 0000000000..bdecc0c5c5 --- /dev/null +++ b/libraries/gpu/src/gpu/DrawWhite.slf @@ -0,0 +1,18 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// Draw white +// +// Created by Sam Gateau on 5/30/2017 +// Copyright 2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +out vec4 outFragColor; + +void main(void) { + outFragColor = vec4(1.0); +} diff --git a/libraries/gpu/src/gpu/StandardShaderLib.cpp b/libraries/gpu/src/gpu/StandardShaderLib.cpp index 81500347fd..cc92719a06 100755 --- a/libraries/gpu/src/gpu/StandardShaderLib.cpp +++ b/libraries/gpu/src/gpu/StandardShaderLib.cpp @@ -16,6 +16,8 @@ #include "DrawTransformUnitQuad_vert.h" #include "DrawTexcoordRectTransformUnitQuad_vert.h" #include "DrawViewportQuadTransformTexcoord_vert.h" +#include "DrawTransformVertexPosition_vert.h" +#include "DrawWhite_frag.h" #include "DrawTexture_frag.h" #include "DrawTextureOpaque_frag.h" #include "DrawColoredTexture_frag.h" @@ -26,6 +28,8 @@ ShaderPointer StandardShaderLib::_drawUnitQuadTexcoordVS; ShaderPointer StandardShaderLib::_drawTransformUnitQuadVS; ShaderPointer StandardShaderLib::_drawTexcoordRectTransformUnitQuadVS; ShaderPointer StandardShaderLib::_drawViewportQuadTransformTexcoordVS; +ShaderPointer StandardShaderLib::_drawTransformVertexPositionVS; +ShaderPointer StandardShaderLib::_drawWhitePS; ShaderPointer StandardShaderLib::_drawTexturePS; ShaderPointer StandardShaderLib::_drawTextureOpaquePS; ShaderPointer StandardShaderLib::_drawColoredTexturePS; @@ -84,6 +88,19 @@ ShaderPointer StandardShaderLib::getDrawViewportQuadTransformTexcoordVS() { } return _drawViewportQuadTransformTexcoordVS; } +ShaderPointer StandardShaderLib::getDrawTransformVertexPositionVS() { + if (!_drawTransformVertexPositionVS) { + _drawTransformVertexPositionVS = gpu::Shader::createVertex(std::string(DrawTransformVertexPosition_vert)); + } + return _drawTransformVertexPositionVS; +} + +ShaderPointer StandardShaderLib::getDrawWhitePS() { + if (!_drawWhitePS) { + _drawWhitePS = gpu::Shader::createPixel(std::string(DrawWhite_frag)); + } + return _drawWhitePS; +} ShaderPointer StandardShaderLib::getDrawTexturePS() { if (!_drawTexturePS) { diff --git a/libraries/gpu/src/gpu/StandardShaderLib.h b/libraries/gpu/src/gpu/StandardShaderLib.h index 12ea9045c2..677ad8c7a1 100755 --- a/libraries/gpu/src/gpu/StandardShaderLib.h +++ b/libraries/gpu/src/gpu/StandardShaderLib.h @@ -37,6 +37,11 @@ public: // Shader draws the unit quad in the full viewport clipPos = ([(-1,-1),(1,1)]) and transform the texcoord = [(0,0),(1,1)] by the model transform. static ShaderPointer getDrawViewportQuadTransformTexcoordVS(); + // Shader draw the fed vertex position and transform it by the full model transform stack (Model, View, Proj). + // simply output the world pos and the clip pos to the next stage + static ShaderPointer getDrawTransformVertexPositionVS(); + + static ShaderPointer getDrawWhitePS(); static ShaderPointer getDrawTexturePS(); static ShaderPointer getDrawTextureOpaquePS(); static ShaderPointer getDrawColoredTexturePS(); @@ -51,6 +56,9 @@ protected: static ShaderPointer _drawTransformUnitQuadVS; static ShaderPointer _drawTexcoordRectTransformUnitQuadVS; static ShaderPointer _drawViewportQuadTransformTexcoordVS; + static ShaderPointer _drawTransformVertexPositionVS; + + static ShaderPointer _drawWhitePS; static ShaderPointer _drawTexturePS; static ShaderPointer _drawTextureOpaquePS; static ShaderPointer _drawColoredTexturePS; diff --git a/libraries/model/src/model/Geometry.cpp b/libraries/model/src/model/Geometry.cpp index 16608ab63e..2525491460 100755 --- a/libraries/model/src/model/Geometry.cpp +++ b/libraries/model/src/model/Geometry.cpp @@ -241,6 +241,42 @@ void Mesh::forEach(std::function vertexFunc, } } +MeshPointer Mesh::createIndexedTriangles_P3F(uint32_t numVertices, uint32_t numIndices, const glm::vec3* vertices, const uint32_t* indices) { + MeshPointer mesh; + if (numVertices == 0) { return mesh; } + if (numIndices < 3) { return mesh; } + + mesh = std::make_shared(); + + // Vertex buffer + mesh->setVertexBuffer(gpu::BufferView(new gpu::Buffer(numVertices * sizeof(glm::vec3), (gpu::Byte*) vertices), gpu::Element::VEC3F_XYZ)); + + // trim down the indices to shorts if possible + if (numIndices < std::numeric_limits::max()) { + Indices16 shortIndicesVector; + int16_t* shortIndices = nullptr; + if (indices) { + shortIndicesVector.resize(numIndices); + for (int i = 0; i < numIndices; i++) { + shortIndicesVector[i] = indices[i]; + } + shortIndices = shortIndicesVector.data(); + } + + mesh->setIndexBuffer(gpu::BufferView(new gpu::Buffer(numIndices * sizeof(uint16_t), (gpu::Byte*) shortIndices), gpu::Element::INDEX_UINT16)); + } else { + + mesh->setIndexBuffer(gpu::BufferView(new gpu::Buffer(numIndices * sizeof(uint32_t), (gpu::Byte*) indices), gpu::Element::INDEX_INT32)); + } + + + std::vector parts; + parts.push_back(model::Mesh::Part(0, numIndices, 0, model::Mesh::TRIANGLES)); + mesh->setPartBuffer(gpu::BufferView(new gpu::Buffer(parts.size() * sizeof(model::Mesh::Part), (gpu::Byte*) parts.data()), gpu::Element::PART_DRAWCALL)); + + return mesh; +} + Geometry::Geometry() { } @@ -256,3 +292,5 @@ Geometry::~Geometry() { void Geometry::setMesh(const MeshPointer& mesh) { _mesh = mesh; } + + diff --git a/libraries/model/src/model/Geometry.h b/libraries/model/src/model/Geometry.h index 7ba3e83407..2375944f04 100755 --- a/libraries/model/src/model/Geometry.h +++ b/libraries/model/src/model/Geometry.h @@ -65,6 +65,9 @@ public: const gpu::BufferStream& getVertexStream() const { return _vertexStream; } // Index Buffer + using Indices16 = std::vector; + using Indices32 = std::vector; + void setIndexBuffer(const BufferView& buffer); const BufferView& getIndexBuffer() const { return _indexBuffer; } size_t getNumIndices() const { return _indexBuffer.getNumElements(); } @@ -127,6 +130,9 @@ public: std::function normalFunc, std::function indexFunc); + + static MeshPointer createIndexedTriangles_P3F(uint32_t numVertices, uint32_t numTriangles, const glm::vec3* vertices = nullptr, const uint32_t* indices = nullptr); + protected: gpu::Stream::FormatPointer _vertexFormat; diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index e1042912aa..9d839d6ee1 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -160,11 +160,11 @@ void DeferredLightingEffect::init() { lp->setAmbientIntensity(0.5f); - lp->setAmbientMap(_defaultSkyboxAmbientTexture); - auto irradianceSH = _defaultSkyboxAmbientTexture->getIrradiance(); - if (irradianceSH) { - lp->setAmbientSphere((*irradianceSH)); - } + lp->setAmbientMap(_defaultSkyboxAmbientTexture); + auto irradianceSH = _defaultSkyboxAmbientTexture->getIrradiance(); + if (irradianceSH) { + lp->setAmbientSphere((*irradianceSH)); + } } void DeferredLightingEffect::setupKeyLightBatch(gpu::Batch& batch, int lightBufferUnit, int ambientBufferUnit, int skyboxCubemapUnit) { diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index b844da8bbe..60fd6e2f64 100644 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -85,12 +85,15 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren const auto deferredFramebuffer = prepareDeferredOutputs.getN(0); const auto lightingFramebuffer = prepareDeferredOutputs.getN(1); + // draw a stencil mask in hidden regions of the frmaebuffer. + // Render opaque objects in DeferredBuffer const auto opaqueInputs = DrawStateSortDeferred::Inputs(opaques, lightingModel).hasVarying(); task.addJob("DrawOpaqueDeferred", opaqueInputs, shapePlumber); // Once opaque is all rendered create stencil background task.addJob("DrawOpaqueStencil", deferredFramebuffer); + task.addJob("PrepareStencil", primaryFramebuffer); task.addJob("OpaqueRangeTimer", opaqueRangeTimer); @@ -469,6 +472,71 @@ void DrawBackgroundDeferred::run(const RenderContextPointer& renderContext, cons // std::static_pointer_cast(renderContext->jobConfig)->gpuTime = _gpuTimer.getAverage(); } +gpu::PipelinePointer PrepareStencil::getDrawStencilPipeline() { + if (!_drawStencilPipeline) { + const gpu::int8 STENCIL_OPAQUE = 1; + auto vs = gpu::StandardShaderLib::getDrawTransformVertexPositionVS(); + auto ps = gpu::StandardShaderLib::getDrawWhitePS(); + auto program = gpu::Shader::createProgram(vs, ps); + gpu::Shader::makeProgram((*program)); + + auto state = std::make_shared(); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_KEEP)); + state->setColorWriteMask(0); + + _drawStencilPipeline = gpu::Pipeline::create(program, state); + } + return _drawStencilPipeline; +} + +model::MeshPointer PrepareStencil::getMesh() { + if (!_mesh) { + + std::vector vertices { + { -1.0f, -1.0f, 0.0f }, { -1.0f, 0.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, + { 1.0f, 1.0f, 0.0f }, { 1.0f, 0.0f, 0.0f }, + { 1.0f, -1.0f, 0.0f }, { 0.0f, -1.0f, 0.0f } }; + + std::vector indices { 0, 7, 1, 1, 3, 2, 3, 5, 4, 5, 7, 6 }; + + _mesh = model::Mesh::createIndexedTriangles_P3F((uint32_t) vertices.size(), (uint32_t) indices.size(), vertices.data(), indices.data()); + + } + return _mesh; +} + + +void PrepareStencil::run(const RenderContextPointer& renderContext, const gpu::FramebufferPointer& srcFramebuffer) { + assert(renderContext->args); + assert(renderContext->args->_context); + + RenderArgs* args = renderContext->args; + doInBatch(args->_context, [&](gpu::Batch& batch) { + args->_batch = &batch; + + batch.setViewportTransform(args->_viewport); + batch.setStateScissorRect(args->_viewport); + + batch.resetViewTransform(); + batch.setModelTransform(Transform()); + glm::mat4 proj; + batch.setProjectionTransform(proj); + + batch.setPipeline(getDrawStencilPipeline()); + + auto mesh = getMesh(); + batch.setIndexBuffer(gpu::UINT32, (mesh->getIndexBuffer()._buffer), 0); + batch.setInputFormat((mesh->getVertexFormat())); + batch.setInputStream(0, mesh->getVertexStream()); + + // Draw + auto part = mesh->getPartBuffer().get(0); + batch.drawIndexed(gpu::TRIANGLES, part._numIndices, part._startIndex); + }); + args->_batch = nullptr; +} + void Blit::run(const RenderContextPointer& renderContext, const gpu::FramebufferPointer& srcFramebuffer) { assert(renderContext->args); assert(renderContext->args->_context); @@ -538,3 +606,4 @@ void Blit::run(const RenderContextPointer& renderContext, const gpu::Framebuffer } }); } + diff --git a/libraries/render-utils/src/RenderDeferredTask.h b/libraries/render-utils/src/RenderDeferredTask.h index 12ecd5ecaf..bba1b26404 100644 --- a/libraries/render-utils/src/RenderDeferredTask.h +++ b/libraries/render-utils/src/RenderDeferredTask.h @@ -13,6 +13,7 @@ #define hifi_RenderDeferredTask_h #include +#include #include #include "LightingModel.h" @@ -185,6 +186,21 @@ protected: bool _opaquePass{ true }; }; +class PrepareStencil { +public: + using JobModel = render::Job::ModelI; + + void run(const render::RenderContextPointer& renderContext, const gpu::FramebufferPointer& dstFramebuffer); +private: + gpu::PipelinePointer _drawStencilPipeline; + gpu::PipelinePointer getDrawStencilPipeline(); + + model::MeshPointer _mesh; + model::MeshPointer getMesh(); + +}; + + class Blit { public: using JobModel = render::Job::ModelI; From 32c5dac66af66ebfd805890d3206531c60854d5a Mon Sep 17 00:00:00 2001 From: Sam Cake Date: Wed, 31 May 2017 00:55:28 -0700 Subject: [PATCH 34/73] Big cleanup of unecessary shaders and legacy from deferred lighting, and messing around with the stencil --- libraries/gpu/src/gpu/DrawVertexPosition.slv | 19 +++ libraries/gpu/src/gpu/StandardShaderLib.cpp | 10 ++ libraries/gpu/src/gpu/StandardShaderLib.h | 3 + .../src/DeferredLightingEffect.cpp | 66 +--------- .../render-utils/src/DeferredLightingEffect.h | 11 -- .../render-utils/src/RenderDeferredTask.cpp | 25 ++-- .../render-utils/src/RenderDeferredTask.h | 3 + .../render-utils/src/RenderPipelines.cpp | 1 + .../render-utils/src/directional_light.slf | 47 ------- .../src/directional_light_shadow.slf | 49 -------- libraries/render-utils/src/point_light.slf | 85 ------------- libraries/render-utils/src/spot_light.slf | 115 ------------------ 12 files changed, 49 insertions(+), 385 deletions(-) create mode 100644 libraries/gpu/src/gpu/DrawVertexPosition.slv delete mode 100644 libraries/render-utils/src/directional_light.slf delete mode 100644 libraries/render-utils/src/directional_light_shadow.slf delete mode 100644 libraries/render-utils/src/point_light.slf delete mode 100644 libraries/render-utils/src/spot_light.slf diff --git a/libraries/gpu/src/gpu/DrawVertexPosition.slv b/libraries/gpu/src/gpu/DrawVertexPosition.slv new file mode 100644 index 0000000000..b12280d577 --- /dev/null +++ b/libraries/gpu/src/gpu/DrawVertexPosition.slv @@ -0,0 +1,19 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// Draw the fed vertex position, pass straight as clip pos +// Output the clip position +// +// Created by Sam Gateau on 5/30/2017 +// Copyright 2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +layout(location = 0) in vec4 inPosition; + +void main(void) { + gl_Position = inPosition; +} diff --git a/libraries/gpu/src/gpu/StandardShaderLib.cpp b/libraries/gpu/src/gpu/StandardShaderLib.cpp index cc92719a06..36ad548cfa 100755 --- a/libraries/gpu/src/gpu/StandardShaderLib.cpp +++ b/libraries/gpu/src/gpu/StandardShaderLib.cpp @@ -16,6 +16,7 @@ #include "DrawTransformUnitQuad_vert.h" #include "DrawTexcoordRectTransformUnitQuad_vert.h" #include "DrawViewportQuadTransformTexcoord_vert.h" +#include "DrawVertexPosition_vert.h" #include "DrawTransformVertexPosition_vert.h" #include "DrawWhite_frag.h" #include "DrawTexture_frag.h" @@ -28,6 +29,7 @@ ShaderPointer StandardShaderLib::_drawUnitQuadTexcoordVS; ShaderPointer StandardShaderLib::_drawTransformUnitQuadVS; ShaderPointer StandardShaderLib::_drawTexcoordRectTransformUnitQuadVS; ShaderPointer StandardShaderLib::_drawViewportQuadTransformTexcoordVS; +ShaderPointer StandardShaderLib::_drawVertexPositionVS; ShaderPointer StandardShaderLib::_drawTransformVertexPositionVS; ShaderPointer StandardShaderLib::_drawWhitePS; ShaderPointer StandardShaderLib::_drawTexturePS; @@ -88,6 +90,14 @@ ShaderPointer StandardShaderLib::getDrawViewportQuadTransformTexcoordVS() { } return _drawViewportQuadTransformTexcoordVS; } + +ShaderPointer StandardShaderLib::getDrawVertexPositionVS() { + if (!_drawVertexPositionVS) { + _drawVertexPositionVS = gpu::Shader::createVertex(std::string(DrawVertexPosition_vert)); + } + return _drawVertexPositionVS; +} + ShaderPointer StandardShaderLib::getDrawTransformVertexPositionVS() { if (!_drawTransformVertexPositionVS) { _drawTransformVertexPositionVS = gpu::Shader::createVertex(std::string(DrawTransformVertexPosition_vert)); diff --git a/libraries/gpu/src/gpu/StandardShaderLib.h b/libraries/gpu/src/gpu/StandardShaderLib.h index 677ad8c7a1..485e5bbbf9 100755 --- a/libraries/gpu/src/gpu/StandardShaderLib.h +++ b/libraries/gpu/src/gpu/StandardShaderLib.h @@ -39,6 +39,7 @@ public: // Shader draw the fed vertex position and transform it by the full model transform stack (Model, View, Proj). // simply output the world pos and the clip pos to the next stage + static ShaderPointer getDrawVertexPositionVS(); static ShaderPointer getDrawTransformVertexPositionVS(); static ShaderPointer getDrawWhitePS(); @@ -56,6 +57,8 @@ protected: static ShaderPointer _drawTransformUnitQuadVS; static ShaderPointer _drawTexcoordRectTransformUnitQuadVS; static ShaderPointer _drawViewportQuadTransformTexcoordVS; + + static ShaderPointer _drawVertexPositionVS; static ShaderPointer _drawTransformVertexPositionVS; static ShaderPointer _drawWhitePS; diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 9d839d6ee1..025274e66d 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -27,18 +27,15 @@ #include "deferred_light_point_vert.h" #include "deferred_light_spot_vert.h" -#include "directional_light_frag.h" #include "directional_ambient_light_frag.h" #include "directional_skybox_light_frag.h" -#include "directional_light_shadow_frag.h" #include "directional_ambient_light_shadow_frag.h" #include "directional_skybox_light_shadow_frag.h" #include "local_lights_shading_frag.h" #include "local_lights_drawOutline_frag.h" -#include "point_light_frag.h" -#include "spot_light_frag.h" + using namespace render; @@ -82,48 +79,26 @@ enum DeferredShader_BufferSlot { }; static void loadLightProgram(const char* vertSource, const char* fragSource, bool lightVolume, gpu::PipelinePointer& program, LightLocationsPtr& locations); -static void loadLightVolumeProgram(const char* vertSource, const char* fragSource, bool front, gpu::PipelinePointer& program, LightLocationsPtr& locations); - -const char no_light_frag[] = -R"SCRIBE( -out vec4 _fragColor; - -void main(void) { - _fragColor = vec4(1.0, 1.0, 1.0, 1.0); -} -)SCRIBE" -; void DeferredLightingEffect::init() { - _directionalLightLocations = std::make_shared(); _directionalAmbientSphereLightLocations = std::make_shared(); _directionalSkyboxLightLocations = std::make_shared(); - _directionalLightShadowLocations = std::make_shared(); _directionalAmbientSphereLightShadowLocations = std::make_shared(); _directionalSkyboxLightShadowLocations = std::make_shared(); _localLightLocations = std::make_shared(); _localLightOutlineLocations = std::make_shared(); - _pointLightLocations = std::make_shared(); - _spotLightLocations = std::make_shared(); - loadLightProgram(deferred_light_vert, directional_light_frag, false, _directionalLight, _directionalLightLocations); loadLightProgram(deferred_light_vert, directional_ambient_light_frag, false, _directionalAmbientSphereLight, _directionalAmbientSphereLightLocations); loadLightProgram(deferred_light_vert, directional_skybox_light_frag, false, _directionalSkyboxLight, _directionalSkyboxLightLocations); - loadLightProgram(deferred_light_vert, directional_light_shadow_frag, false, _directionalLightShadow, _directionalLightShadowLocations); loadLightProgram(deferred_light_vert, directional_ambient_light_shadow_frag, false, _directionalAmbientSphereLightShadow, _directionalAmbientSphereLightShadowLocations); loadLightProgram(deferred_light_vert, directional_skybox_light_shadow_frag, false, _directionalSkyboxLightShadow, _directionalSkyboxLightShadowLocations); loadLightProgram(deferred_light_vert, local_lights_shading_frag, true, _localLight, _localLightLocations); loadLightProgram(deferred_light_vert, local_lights_drawOutline_frag, true, _localLightOutline, _localLightOutlineLocations); - loadLightVolumeProgram(deferred_light_point_vert, no_light_frag, false, _pointLightBack, _pointLightLocations); - loadLightVolumeProgram(deferred_light_point_vert, no_light_frag, true, _pointLightFront, _pointLightLocations); - loadLightVolumeProgram(deferred_light_spot_vert, no_light_frag, false, _spotLightBack, _spotLightLocations); - loadLightVolumeProgram(deferred_light_spot_vert, no_light_frag, true, _spotLightFront, _spotLightLocations); - // Light Stage and clusters _lightStage = std::make_shared(); @@ -290,39 +265,6 @@ static void loadLightProgram(const char* vertSource, const char* fragSource, boo } - -static void loadLightVolumeProgram(const char* vertSource, const char* fragSource, bool front, gpu::PipelinePointer& pipeline, LightLocationsPtr& locations) { - gpu::ShaderPointer program = makeLightProgram(vertSource, fragSource, locations); - - auto state = std::make_shared(); - - // Stencil test all the light passes for objects pixels only, not the background - - if (front) { - state->setCullMode(gpu::State::CULL_BACK); - state->setDepthTest(true, false, gpu::LESS_EQUAL); - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_DECR, gpu::State::STENCIL_OP_KEEP)); - - // state->setDepthClampEnable(true); - // TODO: We should use DepthClamp and avoid changing geometry for inside /outside cases - // additive blending - // state->setBlendFunction(true, gpu::State::ONE, gpu::State::BLEND_OP_ADD, gpu::State::ONE); - - //state->setColorWriteMask(true, true, true, false); - state->setColorWriteMask(false, false, false, false); - } else { - state->setCullMode(gpu::State::CULL_FRONT); - state->setDepthTest(true, false, gpu::LESS_EQUAL); - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_INCR, gpu::State::STENCIL_OP_KEEP)); - // additive blending - // state->setBlendFunction(true, gpu::State::ONE, gpu::State::BLEND_OP_ADD, gpu::State::ONE); - // state->setColorWriteMask(true, true, true, false); - state->setColorWriteMask(false, false, false, false); - } - pipeline = gpu::Pipeline::create(program, state); - -} - void DeferredLightingEffect::setGlobalLight(const model::LightPointer& light) { /* auto globalLight = _allocatedLights.front(); globalLight->setDirection(light->getDirection()); @@ -535,7 +477,7 @@ void PrepareDeferred::run(const RenderContextPointer& renderContext, const Input gpu::Framebuffer::BUFFER_COLOR0 | gpu::Framebuffer::BUFFER_COLOR1 | gpu::Framebuffer::BUFFER_COLOR2 | gpu::Framebuffer::BUFFER_COLOR3 | gpu::Framebuffer::BUFFER_DEPTH | gpu::Framebuffer::BUFFER_STENCIL, - vec4(vec3(0), 0), 1.0, 0.0, true); + vec4(vec3(0), 0), 1.0, 0, true); // For the rest of the rendering, bind the lighting model batch.setUniformBuffer(LIGHTING_MODEL_BUFFER_SLOT, lightingModel->getParametersBuffer()); @@ -619,8 +561,8 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext, batch.setResourceTexture(SHADOW_MAP_UNIT, globalShadow->map); } - auto& program = deferredLightingEffect->_shadowMapEnabled ? deferredLightingEffect->_directionalLightShadow : deferredLightingEffect->_directionalLight; - LightLocationsPtr locations = deferredLightingEffect->_shadowMapEnabled ? deferredLightingEffect->_directionalLightShadowLocations : deferredLightingEffect->_directionalLightLocations; + auto& program = deferredLightingEffect->_directionalSkyboxLight; + LightLocationsPtr locations = deferredLightingEffect->_directionalSkyboxLightLocations; const auto& keyLight = deferredLightingEffect->_allocatedLights[deferredLightingEffect->_globalLights.front()]; // Setup the global directional pass pipeline diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index 2f4f9901c3..c171973216 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -82,32 +82,21 @@ private: gpu::PipelinePointer _directionalSkyboxLight; gpu::PipelinePointer _directionalAmbientSphereLight; - gpu::PipelinePointer _directionalLight; gpu::PipelinePointer _directionalSkyboxLightShadow; gpu::PipelinePointer _directionalAmbientSphereLightShadow; - gpu::PipelinePointer _directionalLightShadow; gpu::PipelinePointer _localLight; gpu::PipelinePointer _localLightOutline; - gpu::PipelinePointer _pointLightBack; - gpu::PipelinePointer _pointLightFront; - gpu::PipelinePointer _spotLightBack; - gpu::PipelinePointer _spotLightFront; - LightLocationsPtr _directionalSkyboxLightLocations; LightLocationsPtr _directionalAmbientSphereLightLocations; - LightLocationsPtr _directionalLightLocations; LightLocationsPtr _directionalSkyboxLightShadowLocations; LightLocationsPtr _directionalAmbientSphereLightShadowLocations; - LightLocationsPtr _directionalLightShadowLocations; LightLocationsPtr _localLightLocations; LightLocationsPtr _localLightOutlineLocations; - LightLocationsPtr _pointLightLocations; - LightLocationsPtr _spotLightLocations; using Lights = std::vector; diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 60fd6e2f64..0fbe35025d 100644 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -85,7 +85,8 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren const auto deferredFramebuffer = prepareDeferredOutputs.getN(0); const auto lightingFramebuffer = prepareDeferredOutputs.getN(1); - // draw a stencil mask in hidden regions of the frmaebuffer. + // draw a stencil mask in hidden regions of the framebuffer. + task.addJob("PrepareStencil", primaryFramebuffer); // Render opaque objects in DeferredBuffer const auto opaqueInputs = DrawStateSortDeferred::Inputs(opaques, lightingModel).hasVarying(); @@ -93,7 +94,6 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren // Once opaque is all rendered create stencil background task.addJob("DrawOpaqueStencil", deferredFramebuffer); - task.addJob("PrepareStencil", primaryFramebuffer); task.addJob("OpaqueRangeTimer", opaqueRangeTimer); @@ -401,7 +401,7 @@ gpu::PipelinePointer DrawStencilDeferred::getOpaquePipeline() { auto state = std::make_shared(); state->setDepthTest(true, false, gpu::LESS_EQUAL); - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(STENCIL_OPAQUE, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_KEEP)); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(STENCIL_OPAQUE, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); state->setColorWriteMask(0); _opaquePipeline = gpu::Pipeline::create(program, state); @@ -410,6 +410,7 @@ gpu::PipelinePointer DrawStencilDeferred::getOpaquePipeline() { } void DrawStencilDeferred::run(const RenderContextPointer& renderContext, const DeferredFramebufferPointer& deferredFramebuffer) { + // return; assert(renderContext->args); assert(renderContext->args->hasViewFrustum()); @@ -474,15 +475,14 @@ void DrawBackgroundDeferred::run(const RenderContextPointer& renderContext, cons gpu::PipelinePointer PrepareStencil::getDrawStencilPipeline() { if (!_drawStencilPipeline) { - const gpu::int8 STENCIL_OPAQUE = 1; - auto vs = gpu::StandardShaderLib::getDrawTransformVertexPositionVS(); + auto vs = gpu::StandardShaderLib::getDrawVertexPositionVS(); auto ps = gpu::StandardShaderLib::getDrawWhitePS(); auto program = gpu::Shader::createProgram(vs, ps); gpu::Shader::makeProgram((*program)); auto state = std::make_shared(); - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_KEEP)); - state->setColorWriteMask(0); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(STENCIL_MASK, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE)); + // state->setColorWriteMask(0); _drawStencilPipeline = gpu::Pipeline::create(program, state); } @@ -499,9 +499,7 @@ model::MeshPointer PrepareStencil::getMesh() { { 1.0f, -1.0f, 0.0f }, { 0.0f, -1.0f, 0.0f } }; std::vector indices { 0, 7, 1, 1, 3, 2, 3, 5, 4, 5, 7, 6 }; - _mesh = model::Mesh::createIndexedTriangles_P3F((uint32_t) vertices.size(), (uint32_t) indices.size(), vertices.data(), indices.data()); - } return _mesh; } @@ -514,19 +512,14 @@ void PrepareStencil::run(const RenderContextPointer& renderContext, const gpu::F RenderArgs* args = renderContext->args; doInBatch(args->_context, [&](gpu::Batch& batch) { args->_batch = &batch; + batch.enableStereo(false); batch.setViewportTransform(args->_viewport); - batch.setStateScissorRect(args->_viewport); - - batch.resetViewTransform(); - batch.setModelTransform(Transform()); - glm::mat4 proj; - batch.setProjectionTransform(proj); batch.setPipeline(getDrawStencilPipeline()); auto mesh = getMesh(); - batch.setIndexBuffer(gpu::UINT32, (mesh->getIndexBuffer()._buffer), 0); + batch.setIndexBuffer(mesh->getIndexBuffer()); batch.setInputFormat((mesh->getVertexFormat())); batch.setInputStream(0, mesh->getVertexStream()); diff --git a/libraries/render-utils/src/RenderDeferredTask.h b/libraries/render-utils/src/RenderDeferredTask.h index bba1b26404..c978a5f9a3 100644 --- a/libraries/render-utils/src/RenderDeferredTask.h +++ b/libraries/render-utils/src/RenderDeferredTask.h @@ -191,6 +191,9 @@ public: using JobModel = render::Job::ModelI; void run(const render::RenderContextPointer& renderContext, const gpu::FramebufferPointer& dstFramebuffer); + + static const gpu::int8 STENCIL_MASK = 64; + private: gpu::PipelinePointer _drawStencilPipeline; gpu::PipelinePointer getDrawStencilPipeline(); diff --git a/libraries/render-utils/src/RenderPipelines.cpp b/libraries/render-utils/src/RenderPipelines.cpp index da264cbf7d..c83e5c5f34 100644 --- a/libraries/render-utils/src/RenderPipelines.cpp +++ b/libraries/render-utils/src/RenderPipelines.cpp @@ -330,6 +330,7 @@ void addPlumberPipeline(ShapePlumber& plumber, bool isWireframed = (i & 4); auto state = std::make_shared(); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::GREATER, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_INCR_SAT)); // Depth test depends on transparency state->setDepthTest(true, !key.isTranslucent(), gpu::LESS_EQUAL); diff --git a/libraries/render-utils/src/directional_light.slf b/libraries/render-utils/src/directional_light.slf deleted file mode 100644 index cda03b0779..0000000000 --- a/libraries/render-utils/src/directional_light.slf +++ /dev/null @@ -1,47 +0,0 @@ -<@include gpu/Config.slh@> -<$VERSION_HEADER$> -// Generated on <$_SCRIBE_DATE$> -// -// directional_light.frag -// fragment shader -// -// Created by Andrzej Kapolka on 9/3/14. -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -<@include DeferredBufferRead.slh@> -<@include DeferredGlobalLight.slh@> - -<$declareEvalLightmappedColor()$> -<$declareEvalAmbientGlobalColor()$> - -in vec2 _texCoord0; -out vec4 _fragColor; - -void main(void) { - DeferredFrameTransform deferredTransform = getDeferredFrameTransform(); - DeferredFragment frag = unpackDeferredFragment(deferredTransform, _texCoord0); - - float shadowAttenuation = 1.0; - - if (frag.mode == FRAG_MODE_UNLIT) { - discard; - } else if (frag.mode == FRAG_MODE_LIGHTMAPPED) { - discard; - } else { - vec3 color = evalAmbientGlobalColor( - getViewInverse(), - shadowAttenuation, - frag.obscurance, - frag.position.xyz, - frag.normal, - frag.albedo, - frag.fresnel, - frag.metallic, - frag.roughness); - _fragColor = vec4(color, 1.0); - } -} diff --git a/libraries/render-utils/src/directional_light_shadow.slf b/libraries/render-utils/src/directional_light_shadow.slf deleted file mode 100644 index 7f98330f84..0000000000 --- a/libraries/render-utils/src/directional_light_shadow.slf +++ /dev/null @@ -1,49 +0,0 @@ -<@include gpu/Config.slh@> -<$VERSION_HEADER$> -// Generated on <$_SCRIBE_DATE$> -// -// directional_light_shadow.frag -// fragment shader -// -// Created by Zach Pomerantz on 1/18/2016. -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -<@include Shadow.slh@> -<@include DeferredBufferRead.slh@> -<@include DeferredGlobalLight.slh@> - -<$declareEvalLightmappedColor()$> -<$declareEvalAmbientGlobalColor()$> - -in vec2 _texCoord0; -out vec4 _fragColor; - -void main(void) { - DeferredFrameTransform deferredTransform = getDeferredFrameTransform(); - DeferredFragment frag = unpackDeferredFragment(deferredTransform, _texCoord0); - - vec4 worldPos = getViewInverse() * vec4(frag.position.xyz, 1.0); - float shadowAttenuation = evalShadowAttenuation(worldPos); - - if (frag.mode == FRAG_MODE_UNLIT) { - discard; - } else if (frag.mode == FRAG_MODE_LIGHTMAPPED) { - discard; - } else { - vec3 color = evalAmbientGlobalColor( - getViewInverse(), - shadowAttenuation, - frag.obscurance, - frag.position.xyz, - frag.normal, - frag.albedo, - frag.fresnel, - frag.metallic, - frag.roughness); - _fragColor = vec4(color, 1.0); - } -} diff --git a/libraries/render-utils/src/point_light.slf b/libraries/render-utils/src/point_light.slf deleted file mode 100644 index e646db5069..0000000000 --- a/libraries/render-utils/src/point_light.slf +++ /dev/null @@ -1,85 +0,0 @@ -<@include gpu/Config.slh@> -<$VERSION_HEADER$> -// Generated on <$_SCRIBE_DATE$> -// -// point_light.frag -// fragment shader -// -// Created by Sam Gateau on 9/18/15. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - - -<$declareDeferredCurvature()$> - -// Everything about light -<@include model/Light.slh@> -<$declareLightBuffer()$> - -<@include LightingModel.slh@> - -<@include LightPoint.slh@> -<$declareLightingPoint(supportScattering)$> - - -uniform vec4 texcoordFrameTransform; - -in vec4 _texCoord0;!> -out vec4 _fragColor; - -void main(void) { - _fragColor = vec4(1.0, 1.0, 1.0, 1.0); - - -} diff --git a/libraries/render-utils/src/spot_light.slf b/libraries/render-utils/src/spot_light.slf deleted file mode 100644 index 4cacff86c4..0000000000 --- a/libraries/render-utils/src/spot_light.slf +++ /dev/null @@ -1,115 +0,0 @@ -<@include gpu/Config.slh@> -<$VERSION_HEADER$> -// Generated on <$_SCRIBE_DATE$> -// -// spot_light.frag -// fragment shader -// -// Created by Sam Gateau on 9/18/15. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -// Everything about deferred buffer - - -<$declareDeferredCurvature()$> - -// Everything about light -<@include model/Light.slh@> -<$declareLightBuffer(256)$> -uniform lightIndexBuffer { - int lightIndex[256]; -}; -<@include LightingModel.slh@> - -<@include LightPoint.slh@> -<$declareLightingPoint(supportScattering)$> -<@include LightSpot.slh@> -<$declareLightingSpot(supportScattering)$> - -//uniform vec4 texcoordFrameTransform; -!> - - -//in vec4 _texCoord0; -//flat in int instanceID; -out vec4 _fragColor; - -void main(void) { - _fragColor = vec4(1.0, 1.0, 1.0, 1.0); - -// DeferredFrameTransform deferredTransform = getDeferredFrameTransform(); - - // Grab the fragment data from the uv - //vec2 texCoord = _texCoord0.st;/* / _texCoord0.q; - /*texCoord *= texcoordFrameTransform.zw; - texCoord += texcoordFrameTransform.xy;*/ - /* - vec4 fragPosition = unpackDeferredPositionFromZeye(texCoord); - DeferredFragment frag = unpackDeferredFragmentNoPosition(texCoord); - - if (frag.mode == FRAG_MODE_UNLIT) { - discard; - } - - - // frag.depthVal = depthValue; - frag.position = fragPosition; - - vec4 midNormalCurvature; - vec4 lowNormalCurvature; - if (frag.mode == FRAG_MODE_SCATTERING) { - unpackMidLowNormalCurvature(texCoord, midNormalCurvature, lowNormalCurvature); - } - - // Frag pos in world - mat4 invViewMat = getViewInverse(); - vec4 fragPos = invViewMat * fragPosition; - - // Frag to eye vec - vec4 fragEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0); - vec3 fragEyeDir = normalize(fragEyeVector.xyz); - - int numLights = lightIndex[0]; - for (int i = 0; i < numLights; i++) { - // Need the light now - Light light = getLight(lightIndex[i + 1]); - bool isSpot = light_isSpot(light); - // Clip againgst the light volume and Make the Light vector going from fragment to light center in world space - vec4 fragLightVecLen2; - vec4 fragLightDirLen; - float cosSpotAngle; - if (isSpot) { - if (!clipFragToLightVolumeSpot(light, fragPos.xyz, fragLightVecLen2, fragLightDirLen, cosSpotAngle)) { - continue; - } - } else { - if (!clipFragToLightVolumePoint(light, fragPos.xyz, fragLightVecLen2)) { - continue; - } - } - - vec3 diffuse; - vec3 specular; - - if (isSpot) { - evalLightingSpot(diffuse, specular, light, - fragLightDirLen.xyzw, cosSpotAngle, fragEyeDir, frag.normal, frag.roughness, - frag.metallic, frag.fresnel, frag.albedo, 1.0, - frag.scattering, midNormalCurvature, lowNormalCurvature); - } else { - evalLightingPoint(diffuse, specular, light, - fragLightVecLen2.xyz, fragEyeDir, frag.normal, frag.roughness, - frag.metallic, frag.fresnel, frag.albedo, 1.0, - frag.scattering, midNormalCurvature, lowNormalCurvature); - } - - _fragColor.rgb += diffuse; - _fragColor.rgb += specular; - } - */ -} - From 58142817a12d132077515669953fd3c4087487df Mon Sep 17 00:00:00 2001 From: NeetBhagat Date: Wed, 31 May 2017 19:13:55 +0530 Subject: [PATCH 35/73] Resolve the review comments of @ZappoMan. --- interface/src/Application.cpp | 86 ++++++++++++++++++----------------- interface/src/Application.h | 14 ++---- 2 files changed, 49 insertions(+), 51 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index b5733fa6f5..ac39f51d7e 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -244,8 +244,8 @@ static const QString DESKTOP_LOCATION = QStandardPaths::writableLocation(QStanda Setting::Handle maxOctreePacketsPerSecond("maxOctreePPS", DEFAULT_MAX_OCTREE_PPS); static const QString MARKETPLACE_CDN_HOSTNAME = "mpassets.highfidelity.com"; -static const int INTERVAL_TO_CHECK_HMD_MOUNTED_STATUS = 500; // milliseconds -static const QString OCULUS_RIFT_DISPLAY_PLUGIN_NAME = "Oculus Rift"; +static const int INTERVAL_TO_CHECK_HMD_WORN_STATUS = 500; // milliseconds +static const QString DISPLAY_PLUGIN_NAME_OCULUS_RIFT = "Oculus Rift"; static const QString DESKTOP_DISPLAY_PLUGIN_NAME = "Desktop"; const QHash Application::_acceptedExtensions { @@ -1341,19 +1341,38 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo properties["active_display_plugin"] = getActiveDisplayPlugin()->getName(); properties["using_hmd"] = isHMDMode(); - if (isHMDPluginAvailable()) { - // Currently, autoswitch display mode support is only for Oculus Rift. - // If HMD Plugin is available and current display plugin is not HMD plugin - // then startHMDStandBySession to listen HMD Mounted status. - if (getActiveDisplayPlugin()->getName() != _hmdPluginName && - !_hmdPlugin->isStandBySessionActive()) { + _autoSwitchDisplayModeSupportedHMDPlugin = nullptr; + foreach(DisplayPluginPointer displayPlugin, PluginManager::getInstance()->getDisplayPlugins()) { + if (displayPlugin->isHmd() && + displayPlugin->getName() == DISPLAY_PLUGIN_NAME_OCULUS_RIFT) { + + // Currently auto switch display mode support is only for Oculus Rift + // To support other plugins, add a condition + // (|| displayPlugin->getName() == "Other HMD Display Plugin Name") + + _autoSwitchDisplayModeSupportedHMDPlugin = displayPlugin; + _autoSwitchDisplayModeSupportedHMDPluginName = + _autoSwitchDisplayModeSupportedHMDPlugin->getName(); + _previousHMDWornStatus = + _autoSwitchDisplayModeSupportedHMDPlugin->isDisplayVisible(); + qCDebug(interfaceapp) << "_autoSwitchModeSupportedPluginName::" + << _autoSwitchDisplayModeSupportedHMDPluginName; + break; + } + } + + if (_autoSwitchDisplayModeSupportedHMDPlugin != nullptr) { + // If HMD Plugin is available and current display plugin is not HMD plugin + // then startHMDStandBySession to poll HMD Worn status. + if (getActiveDisplayPlugin()->getName() != _autoSwitchDisplayModeSupportedHMDPluginName && + !_autoSwitchDisplayModeSupportedHMDPlugin->isStandBySessionActive()) { startHMDStandBySession(); } // Poll periodically to check whether the user has worn HMD or not. Switch Display mode accordingly. // If the user wears HMD then switch to VR mode. If the user removes HMD then switch to Desktop mode. - QTimer *switchDisplayModeTimer = new QTimer(this); - connect(switchDisplayModeTimer, SIGNAL(timeout()), this, SLOT(switchDisplayMode())); - switchDisplayModeTimer->start(INTERVAL_TO_CHECK_HMD_MOUNTED_STATUS); + QTimer* autoSwitchDisplayModeTimer = new QTimer(this); + connect(autoSwitchDisplayModeTimer, SIGNAL(timeout()), this, SLOT(switchDisplayMode())); + autoSwitchDisplayModeTimer->start(INTERVAL_TO_CHECK_HMD_WORN_STATUS); } auto glInfo = getGLContextData(); @@ -1585,9 +1604,10 @@ void Application::aboutToQuit() { } getActiveDisplayPlugin()->deactivate(); - if (_hmdPlugin && _hmdPlugin->isStandBySessionActive()) { - _hmdPlugin->endStandBySession(); - } + if (_autoSwitchDisplayModeSupportedHMDPlugin != nullptr + && _autoSwitchDisplayModeSupportedHMDPlugin->isStandBySessionActive()) { + _autoSwitchDisplayModeSupportedHMDPlugin->endStandBySession(); + } // Hide Running Scripts dialog so that it gets destroyed in an orderly manner; prevents warnings at shutdown. DependencyManager::get()->hide("RunningScripts"); @@ -6752,48 +6772,30 @@ void Application::updateDisplayMode() { Q_ASSERT_X(_displayPlugin, "Application::updateDisplayMode", "could not find an activated display plugin"); } -bool Application::isHMDPluginAvailable() { - bool isHMDEnabledPluginAvailable = false; - auto displayPlugins = PluginManager::getInstance()->getDisplayPlugins(); - // Currently, autoswitch display mode support is only for Oculus Rift. - foreach(DisplayPluginPointer displayPlugin, PluginManager::getInstance()->getDisplayPlugins()) { - if (displayPlugin->isHmd() && displayPlugin->getName() == OCULUS_RIFT_DISPLAY_PLUGIN_NAME) { - _hmdPlugin = displayPlugin; - _hmdPluginName = displayPlugin->getName(); - _hmdMountedStatus = displayPlugin->isDisplayVisible(); - isHMDEnabledPluginAvailable = true; - break; - } - } - return isHMDEnabledPluginAvailable; -} - void Application::switchDisplayMode() { - bool currentHMDMountedStatus = _hmdPlugin->isDisplayVisible(); - if (currentHMDMountedStatus != _hmdMountedStatus) { - // Switch to respective mode as soon as currenthmdMountedStatus changes - if (currentHMDMountedStatus == false && _hmdMountedStatus == true) { + bool currentHMDWornStatus = _autoSwitchDisplayModeSupportedHMDPlugin->isDisplayVisible(); + if (currentHMDWornStatus != _previousHMDWornStatus) { + // Switch to respective mode as soon as currentHMDWornStatus changes + if (currentHMDWornStatus == false && _previousHMDWornStatus == true) { qCDebug(interfaceapp) << "Switching from HMD to desktop mode"; setActiveDisplayPlugin(DESKTOP_DISPLAY_PLUGIN_NAME); startHMDStandBySession(); } - if (currentHMDMountedStatus == true && _hmdMountedStatus == false) { + if (currentHMDWornStatus == true && _previousHMDWornStatus == false) { qCDebug(interfaceapp) << "Switching from Desktop to HMD mode"; endHMDStandBySession(); - setActiveDisplayPlugin(_hmdPluginName); + setActiveDisplayPlugin(_autoSwitchDisplayModeSupportedHMDPluginName); } } - _hmdMountedStatus = currentHMDMountedStatus; + _previousHMDWornStatus = currentHMDWornStatus; } -bool Application::startHMDStandBySession() { - bool isStandBySessionStarted = _hmdPlugin->startStandBySession(); - qCDebug(interfaceapp) << "startHMDStandBySession: " << isStandBySessionStarted; - return isStandBySessionStarted; +void Application::startHMDStandBySession() { + _autoSwitchDisplayModeSupportedHMDPlugin->startStandBySession(); } void Application::endHMDStandBySession() { - _hmdPlugin->endStandBySession(); + _autoSwitchDisplayModeSupportedHMDPlugin->endStandBySession(); } mat4 Application::getEyeProjection(int eye) const { diff --git a/interface/src/Application.h b/interface/src/Application.h index f19c2c9adf..e1fb37ef3a 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -681,14 +681,10 @@ private: AudioInjector* _snapshotSoundInjector { nullptr }; SharedSoundPointer _snapshotSound; - - DisplayPluginPointer _hmdPlugin; // HMD Enabled Plugin - QString _hmdPluginName; - bool isHMDPluginAvailable(); - bool _hmdMountedStatus; // Check HMD Mounted status - bool startHMDStandBySession(); - void endHMDStandBySession(); + DisplayPluginPointer _autoSwitchDisplayModeSupportedHMDPlugin = nullptr; + QString _autoSwitchDisplayModeSupportedHMDPluginName; + bool _previousHMDWornStatus; + void startHMDStandBySession(); + void endHMDStandBySession(); }; - - #endif // hifi_Application_h From 82d348a2efd87c39d321592ce7d66c184c5c4af1 Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 31 May 2017 16:46:20 -0700 Subject: [PATCH 36/73] Stencil rejection is working, and more cleaning --- libraries/gpu/src/gpu/StandardShaderLib.cpp | 13 +- libraries/gpu/src/gpu/StandardShaderLib.h | 4 + libraries/model/src/model/Skybox.cpp | 2 +- .../src/procedural/ProceduralSkybox.cpp | 2 +- .../src/DeferredLightingEffect.cpp | 6 +- .../render-utils/src/RenderDeferredTask.cpp | 145 +----------------- .../render-utils/src/RenderDeferredTask.h | 48 ------ .../render-utils/src/RenderPipelines.cpp | 2 +- .../render-utils/src/StencilMaskPass.cpp | 123 +++++++++++++++ libraries/render-utils/src/StencilMaskPass.h | 50 ++++++ .../render-utils/src/SurfaceGeometryPass.cpp | 4 +- .../render-utils/src/drawOpaqueStencil.slf | 16 -- 12 files changed, 198 insertions(+), 217 deletions(-) create mode 100644 libraries/render-utils/src/StencilMaskPass.cpp create mode 100644 libraries/render-utils/src/StencilMaskPass.h delete mode 100644 libraries/render-utils/src/drawOpaqueStencil.slf diff --git a/libraries/gpu/src/gpu/StandardShaderLib.cpp b/libraries/gpu/src/gpu/StandardShaderLib.cpp index 36ad548cfa..756070ff68 100755 --- a/libraries/gpu/src/gpu/StandardShaderLib.cpp +++ b/libraries/gpu/src/gpu/StandardShaderLib.cpp @@ -18,6 +18,9 @@ #include "DrawViewportQuadTransformTexcoord_vert.h" #include "DrawVertexPosition_vert.h" #include "DrawTransformVertexPosition_vert.h" + +const char DrawNada_frag[] = "void main(void) {}"; // DrawNada is really simple... + #include "DrawWhite_frag.h" #include "DrawTexture_frag.h" #include "DrawTextureOpaque_frag.h" @@ -31,6 +34,7 @@ ShaderPointer StandardShaderLib::_drawTexcoordRectTransformUnitQuadVS; ShaderPointer StandardShaderLib::_drawViewportQuadTransformTexcoordVS; ShaderPointer StandardShaderLib::_drawVertexPositionVS; ShaderPointer StandardShaderLib::_drawTransformVertexPositionVS; +ShaderPointer StandardShaderLib::_drawNadaPS; ShaderPointer StandardShaderLib::_drawWhitePS; ShaderPointer StandardShaderLib::_drawTexturePS; ShaderPointer StandardShaderLib::_drawTextureOpaquePS; @@ -105,6 +109,13 @@ ShaderPointer StandardShaderLib::getDrawTransformVertexPositionVS() { return _drawTransformVertexPositionVS; } +ShaderPointer StandardShaderLib::getDrawNadaPS() { + if (!_drawNadaPS) { + _drawNadaPS = gpu::Shader::createPixel(std::string(DrawNada_frag)); + } + return _drawNadaPS; +} + ShaderPointer StandardShaderLib::getDrawWhitePS() { if (!_drawWhitePS) { _drawWhitePS = gpu::Shader::createPixel(std::string(DrawWhite_frag)); @@ -126,8 +137,6 @@ ShaderPointer StandardShaderLib::getDrawTextureOpaquePS() { return _drawTextureOpaquePS; } - - ShaderPointer StandardShaderLib::getDrawColoredTexturePS() { if (!_drawColoredTexturePS) { _drawColoredTexturePS = gpu::Shader::createPixel(std::string(DrawColoredTexture_frag)); diff --git a/libraries/gpu/src/gpu/StandardShaderLib.h b/libraries/gpu/src/gpu/StandardShaderLib.h index 485e5bbbf9..a21d4dea9a 100755 --- a/libraries/gpu/src/gpu/StandardShaderLib.h +++ b/libraries/gpu/src/gpu/StandardShaderLib.h @@ -42,6 +42,9 @@ public: static ShaderPointer getDrawVertexPositionVS(); static ShaderPointer getDrawTransformVertexPositionVS(); + // PShader does nothing, no really nothing, but still needed for defining a program triggering rasterization + static ShaderPointer getDrawNadaPS(); + static ShaderPointer getDrawWhitePS(); static ShaderPointer getDrawTexturePS(); static ShaderPointer getDrawTextureOpaquePS(); @@ -61,6 +64,7 @@ protected: static ShaderPointer _drawVertexPositionVS; static ShaderPointer _drawTransformVertexPositionVS; + static ShaderPointer _drawNadaPS; static ShaderPointer _drawWhitePS; static ShaderPointer _drawTexturePS; static ShaderPointer _drawTextureOpaquePS; diff --git a/libraries/model/src/model/Skybox.cpp b/libraries/model/src/model/Skybox.cpp index 4901a3c61b..d327593573 100755 --- a/libraries/model/src/model/Skybox.cpp +++ b/libraries/model/src/model/Skybox.cpp @@ -97,7 +97,7 @@ void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Sky } auto skyState = std::make_shared(); - skyState->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + skyState->setStencilTest(true, 0xFF, gpu::State::StencilTest(1, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); thePipeline = gpu::Pipeline::create(skyShader, skyState); } diff --git a/libraries/procedural/src/procedural/ProceduralSkybox.cpp b/libraries/procedural/src/procedural/ProceduralSkybox.cpp index 0275a875ec..f5feb434fa 100644 --- a/libraries/procedural/src/procedural/ProceduralSkybox.cpp +++ b/libraries/procedural/src/procedural/ProceduralSkybox.cpp @@ -23,7 +23,7 @@ ProceduralSkybox::ProceduralSkybox() : model::Skybox() { _procedural._fragmentSource = skybox_frag; // Adjust the pipeline state for background using the stencil test _procedural.setDoesFade(false); - _procedural._opaqueState->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + _procedural._opaqueState->setStencilTest(true, 0xFF, gpu::State::StencilTest(1, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); } bool ProceduralSkybox::empty() { diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 025274e66d..04255fbb87 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -242,7 +242,7 @@ static void loadLightProgram(const char* vertSource, const char* fragSource, boo state->setColorWriteMask(true, true, true, false); if (lightVolume) { - state->setStencilTest(true, 0x00, gpu::State::StencilTest(1, 0xFF, gpu::LESS_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + state->setStencilTest(true, 0x00, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); state->setCullMode(gpu::State::CULL_BACK); // state->setCullMode(gpu::State::CULL_FRONT); @@ -255,7 +255,7 @@ static void loadLightProgram(const char* vertSource, const char* fragSource, boo } else { // Stencil test all the light passes for objects pixels only, not the background - state->setStencilTest(true, 0x00, gpu::State::StencilTest(0, 0x01, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + state->setStencilTest(true, 0x00, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); state->setCullMode(gpu::State::CULL_BACK); // additive blending @@ -477,7 +477,7 @@ void PrepareDeferred::run(const RenderContextPointer& renderContext, const Input gpu::Framebuffer::BUFFER_COLOR0 | gpu::Framebuffer::BUFFER_COLOR1 | gpu::Framebuffer::BUFFER_COLOR2 | gpu::Framebuffer::BUFFER_COLOR3 | gpu::Framebuffer::BUFFER_DEPTH | gpu::Framebuffer::BUFFER_STENCIL, - vec4(vec3(0), 0), 1.0, 0, true); + vec4(vec3(0), 0), 1.0, 1, true); // For the rest of the rendering, bind the lighting model batch.setUniformBuffer(LIGHTING_MODEL_BUFFER_SLOT, lightingModel->getParametersBuffer()); diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 0fbe35025d..89b4b72944 100644 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -27,6 +27,7 @@ #include #include "LightingModel.h" +#include "StencilMaskPass.h" #include "DebugDeferredBuffer.h" #include "DeferredFramebuffer.h" #include "DeferredLightingEffect.h" @@ -43,8 +44,6 @@ #include -#include "drawOpaqueStencil_frag.h" - using namespace render; extern void initOverlay3DPipelines(render::ShapePlumber& plumber); @@ -93,7 +92,7 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren task.addJob("DrawOpaqueDeferred", opaqueInputs, shapePlumber); // Once opaque is all rendered create stencil background - task.addJob("DrawOpaqueStencil", deferredFramebuffer); + task.addJob("DrawOpaqueStencil", primaryFramebuffer); task.addJob("OpaqueRangeTimer", opaqueRangeTimer); @@ -390,146 +389,6 @@ void DrawOverlay3D::run(const RenderContextPointer& renderContext, const Inputs& } } - -gpu::PipelinePointer DrawStencilDeferred::getOpaquePipeline() { - if (!_opaquePipeline) { - const gpu::int8 STENCIL_OPAQUE = 1; - auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS(); - auto ps = gpu::Shader::createPixel(std::string(drawOpaqueStencil_frag)); - auto program = gpu::Shader::createProgram(vs, ps); - gpu::Shader::makeProgram((*program)); - - auto state = std::make_shared(); - state->setDepthTest(true, false, gpu::LESS_EQUAL); - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(STENCIL_OPAQUE, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); - state->setColorWriteMask(0); - - _opaquePipeline = gpu::Pipeline::create(program, state); - } - return _opaquePipeline; -} - -void DrawStencilDeferred::run(const RenderContextPointer& renderContext, const DeferredFramebufferPointer& deferredFramebuffer) { - // return; - assert(renderContext->args); - assert(renderContext->args->hasViewFrustum()); - - // from the touched pixel generate the stencil buffer - RenderArgs* args = renderContext->args; - doInBatch(args->_context, [&](gpu::Batch& batch) { - args->_batch = &batch; - - auto deferredFboColorDepthStencil = deferredFramebuffer->getDeferredFramebufferDepthColor(); - - - batch.enableStereo(false); - - batch.setFramebuffer(deferredFboColorDepthStencil); - batch.setViewportTransform(args->_viewport); - batch.setStateScissorRect(args->_viewport); - - batch.setPipeline(getOpaquePipeline()); - - batch.draw(gpu::TRIANGLE_STRIP, 4); - batch.setResourceTexture(0, nullptr); - - }); - args->_batch = nullptr; -} - -void DrawBackgroundDeferred::run(const RenderContextPointer& renderContext, const Inputs& inputs) { - assert(renderContext->args); - assert(renderContext->args->hasViewFrustum()); - - const auto& inItems = inputs.get0(); - const auto& lightingModel = inputs.get1(); - if (!lightingModel->isBackgroundEnabled()) { - return; - } - - RenderArgs* args = renderContext->args; - doInBatch(args->_context, [&](gpu::Batch& batch) { - args->_batch = &batch; - // _gpuTimer.begin(batch); - - batch.enableSkybox(true); - - batch.setViewportTransform(args->_viewport); - batch.setStateScissorRect(args->_viewport); - - glm::mat4 projMat; - Transform viewMat; - args->getViewFrustum().evalProjectionMatrix(projMat); - args->getViewFrustum().evalViewTransform(viewMat); - - batch.setProjectionTransform(projMat); - batch.setViewTransform(viewMat); - - renderItems(renderContext, inItems); - // _gpuTimer.end(batch); - }); - args->_batch = nullptr; - - // std::static_pointer_cast(renderContext->jobConfig)->gpuTime = _gpuTimer.getAverage(); -} - -gpu::PipelinePointer PrepareStencil::getDrawStencilPipeline() { - if (!_drawStencilPipeline) { - auto vs = gpu::StandardShaderLib::getDrawVertexPositionVS(); - auto ps = gpu::StandardShaderLib::getDrawWhitePS(); - auto program = gpu::Shader::createProgram(vs, ps); - gpu::Shader::makeProgram((*program)); - - auto state = std::make_shared(); - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(STENCIL_MASK, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE)); - // state->setColorWriteMask(0); - - _drawStencilPipeline = gpu::Pipeline::create(program, state); - } - return _drawStencilPipeline; -} - -model::MeshPointer PrepareStencil::getMesh() { - if (!_mesh) { - - std::vector vertices { - { -1.0f, -1.0f, 0.0f }, { -1.0f, 0.0f, 0.0f }, - { -1.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, - { 1.0f, 1.0f, 0.0f }, { 1.0f, 0.0f, 0.0f }, - { 1.0f, -1.0f, 0.0f }, { 0.0f, -1.0f, 0.0f } }; - - std::vector indices { 0, 7, 1, 1, 3, 2, 3, 5, 4, 5, 7, 6 }; - _mesh = model::Mesh::createIndexedTriangles_P3F((uint32_t) vertices.size(), (uint32_t) indices.size(), vertices.data(), indices.data()); - } - return _mesh; -} - - -void PrepareStencil::run(const RenderContextPointer& renderContext, const gpu::FramebufferPointer& srcFramebuffer) { - assert(renderContext->args); - assert(renderContext->args->_context); - - RenderArgs* args = renderContext->args; - doInBatch(args->_context, [&](gpu::Batch& batch) { - args->_batch = &batch; - batch.enableStereo(false); - - batch.setViewportTransform(args->_viewport); - - batch.setPipeline(getDrawStencilPipeline()); - - auto mesh = getMesh(); - batch.setIndexBuffer(mesh->getIndexBuffer()); - batch.setInputFormat((mesh->getVertexFormat())); - batch.setInputStream(0, mesh->getVertexStream()); - - // Draw - auto part = mesh->getPartBuffer().get(0); - batch.drawIndexed(gpu::TRIANGLES, part._numIndices, part._startIndex); - }); - args->_batch = nullptr; -} - void Blit::run(const RenderContextPointer& renderContext, const gpu::FramebufferPointer& srcFramebuffer) { assert(renderContext->args); assert(renderContext->args->_context); diff --git a/libraries/render-utils/src/RenderDeferredTask.h b/libraries/render-utils/src/RenderDeferredTask.h index c978a5f9a3..fd7c5eb23b 100644 --- a/libraries/render-utils/src/RenderDeferredTask.h +++ b/libraries/render-utils/src/RenderDeferredTask.h @@ -13,7 +13,6 @@ #define hifi_RenderDeferredTask_h #include -#include #include #include "LightingModel.h" @@ -121,35 +120,6 @@ protected: bool _stateSort; }; -class DeferredFramebuffer; -class DrawStencilDeferred { -public: - using JobModel = render::Job::ModelI>; - - void run(const render::RenderContextPointer& renderContext, const std::shared_ptr& deferredFramebuffer); - -protected: - gpu::PipelinePointer _opaquePipeline; - - gpu::PipelinePointer getOpaquePipeline(); -}; - -using DrawBackgroundDeferredConfig = render::GPUJobConfig; - -class DrawBackgroundDeferred { -public: - using Inputs = render::VaryingSet2 ; - - using Config = DrawBackgroundDeferredConfig; - using JobModel = render::Job::ModelI; - - void configure(const Config& config) {} - void run(const render::RenderContextPointer& renderContext, const Inputs& inputs); - -protected: - gpu::RangeTimerPointer _gpuTimer; -}; - class DrawOverlay3DConfig : public render::Job::Config { Q_OBJECT Q_PROPERTY(int numDrawn READ getNumDrawn NOTIFY numDrawnChanged) @@ -186,24 +156,6 @@ protected: bool _opaquePass{ true }; }; -class PrepareStencil { -public: - using JobModel = render::Job::ModelI; - - void run(const render::RenderContextPointer& renderContext, const gpu::FramebufferPointer& dstFramebuffer); - - static const gpu::int8 STENCIL_MASK = 64; - -private: - gpu::PipelinePointer _drawStencilPipeline; - gpu::PipelinePointer getDrawStencilPipeline(); - - model::MeshPointer _mesh; - model::MeshPointer getMesh(); - -}; - - class Blit { public: using JobModel = render::Job::ModelI; diff --git a/libraries/render-utils/src/RenderPipelines.cpp b/libraries/render-utils/src/RenderPipelines.cpp index c83e5c5f34..9ca9187df8 100644 --- a/libraries/render-utils/src/RenderPipelines.cpp +++ b/libraries/render-utils/src/RenderPipelines.cpp @@ -330,7 +330,7 @@ void addPlumberPipeline(ShapePlumber& plumber, bool isWireframed = (i & 4); auto state = std::make_shared(); - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::GREATER, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_INCR_SAT)); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(2, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_ZERO)); // Depth test depends on transparency state->setDepthTest(true, !key.isTranslucent(), gpu::LESS_EQUAL); diff --git a/libraries/render-utils/src/StencilMaskPass.cpp b/libraries/render-utils/src/StencilMaskPass.cpp new file mode 100644 index 0000000000..612324a79b --- /dev/null +++ b/libraries/render-utils/src/StencilMaskPass.cpp @@ -0,0 +1,123 @@ +// +// StencilMaskPass.cpp +// render-utils/src/ +// +// Created by Sam Gateau on 5/31/17. +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "StencilMaskPass.h" + +#include +#include +#include + + +#include + + +using namespace render; + +gpu::PipelinePointer DrawStencilDeferred::getOpaquePipeline() { + if (!_opaquePipeline) { + const gpu::int8 STENCIL_OPAQUE = 0; + auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS(); + auto ps = gpu::StandardShaderLib::getDrawNadaPS(); + auto program = gpu::Shader::createProgram(vs, ps); + gpu::Shader::makeProgram((*program)); + + auto state = std::make_shared(); + state->setDepthTest(true, false, gpu::LESS_EQUAL); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(STENCIL_OPAQUE, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + state->setColorWriteMask(0); + + _opaquePipeline = gpu::Pipeline::create(program, state); + } + return _opaquePipeline; +} + +void DrawStencilDeferred::run(const RenderContextPointer& renderContext, const gpu::FramebufferPointer& deferredFramebuffer) { + return; + assert(renderContext->args); + assert(renderContext->args->hasViewFrustum()); + + // from the touched pixel generate the stencil buffer + RenderArgs* args = renderContext->args; + doInBatch(args->_context, [&](gpu::Batch& batch) { + args->_batch = &batch; + + batch.enableStereo(false); + + // batch.setFramebuffer(deferredFramebuffer); + batch.setViewportTransform(args->_viewport); + batch.setStateScissorRect(args->_viewport); + + batch.setPipeline(getOpaquePipeline()); + + batch.draw(gpu::TRIANGLE_STRIP, 4); + batch.setResourceTexture(0, nullptr); + + }); + args->_batch = nullptr; +} + +gpu::PipelinePointer PrepareStencil::getDrawStencilPipeline() { + if (!_drawStencilPipeline) { + auto vs = gpu::StandardShaderLib::getDrawVertexPositionVS(); + auto ps = gpu::StandardShaderLib::getDrawWhitePS(); + auto program = gpu::Shader::createProgram(vs, ps); + gpu::Shader::makeProgram((*program)); + + auto state = std::make_shared(); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(2, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE)); + // state->setColorWriteMask(0); + + _drawStencilPipeline = gpu::Pipeline::create(program, state); + } + return _drawStencilPipeline; +} + +model::MeshPointer PrepareStencil::getMesh() { + if (!_mesh) { + + std::vector vertices { + { -1.0f, -1.0f, 0.0f }, { -1.0f, 0.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, + { 1.0f, 1.0f, 0.0f }, { 1.0f, 0.0f, 0.0f }, + { 1.0f, -1.0f, 0.0f }, { 0.0f, -1.0f, 0.0f } }; + + std::vector indices { 0, 7, 1, 1, 3, 2, 3, 5, 4, 5, 7, 6 }; + _mesh = model::Mesh::createIndexedTriangles_P3F((uint32_t) vertices.size(), (uint32_t) indices.size(), vertices.data(), indices.data()); + } + return _mesh; +} + + +void PrepareStencil::run(const RenderContextPointer& renderContext, const gpu::FramebufferPointer& srcFramebuffer) { + assert(renderContext->args); + assert(renderContext->args->_context); + + RenderArgs* args = renderContext->args; + doInBatch(args->_context, [&](gpu::Batch& batch) { + args->_batch = &batch; + batch.enableStereo(false); + + batch.setViewportTransform(args->_viewport); + + batch.setPipeline(getDrawStencilPipeline()); + + auto mesh = getMesh(); + batch.setIndexBuffer(mesh->getIndexBuffer()); + batch.setInputFormat((mesh->getVertexFormat())); + batch.setInputStream(0, mesh->getVertexStream()); + + // Draw + auto part = mesh->getPartBuffer().get(0); + batch.drawIndexed(gpu::TRIANGLES, part._numIndices, part._startIndex); + }); + args->_batch = nullptr; +} + diff --git a/libraries/render-utils/src/StencilMaskPass.h b/libraries/render-utils/src/StencilMaskPass.h new file mode 100644 index 0000000000..bf21602462 --- /dev/null +++ b/libraries/render-utils/src/StencilMaskPass.h @@ -0,0 +1,50 @@ +// +// StencilMaskPass.h +// render-utils/src/ +// +// Created by Sam Gateau on 5/31/17. +// Copyright 20154 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +#pragma once +#ifndef hifi_StencilMaskPass_h +#define hifi_StencilMaskPass_h + +#include +#include +#include + + +class DrawStencilDeferred { +public: + using JobModel = render::Job::ModelI; + + void run(const render::RenderContextPointer& renderContext, const gpu::FramebufferPointer& deferredFramebuffer); + +protected: + gpu::PipelinePointer _opaquePipeline; + + gpu::PipelinePointer getOpaquePipeline(); +}; + +class PrepareStencil { +public: + using JobModel = render::Job::ModelI; + + void run(const render::RenderContextPointer& renderContext, const gpu::FramebufferPointer& dstFramebuffer); + + static const gpu::int8 STENCIL_MASK = 64; + +private: + gpu::PipelinePointer _drawStencilPipeline; + gpu::PipelinePointer getDrawStencilPipeline(); + + model::MeshPointer _mesh; + model::MeshPointer getMesh(); + +}; + + +#endif // hifi_StencilMaskPass_h diff --git a/libraries/render-utils/src/SurfaceGeometryPass.cpp b/libraries/render-utils/src/SurfaceGeometryPass.cpp index ef50960b7d..746c25daa5 100644 --- a/libraries/render-utils/src/SurfaceGeometryPass.cpp +++ b/libraries/render-utils/src/SurfaceGeometryPass.cpp @@ -224,7 +224,7 @@ const gpu::PipelinePointer& LinearDepthPass::getLinearDepthPipeline() { gpu::StatePointer state = gpu::StatePointer(new gpu::State()); // Stencil test the curvature pass for objects pixels only, not the background - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); state->setColorWriteMask(true, false, false, false); @@ -554,7 +554,7 @@ const gpu::PipelinePointer& SurfaceGeometryPass::getCurvaturePipeline() { #ifdef USE_STENCIL_TEST // Stencil test the curvature pass for objects pixels only, not the background - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); #endif // Good to go add the brand new pipeline _curvaturePipeline = gpu::Pipeline::create(program, state); diff --git a/libraries/render-utils/src/drawOpaqueStencil.slf b/libraries/render-utils/src/drawOpaqueStencil.slf deleted file mode 100644 index 43e9c5c27a..0000000000 --- a/libraries/render-utils/src/drawOpaqueStencil.slf +++ /dev/null @@ -1,16 +0,0 @@ -<@include gpu/Config.slh@> -<$VERSION_HEADER$> -// Generated on <$_SCRIBE_DATE$> -// -// drawOpaqueStencil.frag -// fragment shader -// -// Created by Sam Gateau on 9/29/15. -// Copyright 2015 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -void main(void) { -} From b528c2fc60a70f9532644a11dbcc7eee8c74f851 Mon Sep 17 00:00:00 2001 From: Sam Cake Date: Wed, 31 May 2017 19:33:14 -0700 Subject: [PATCH 37/73] Merged --- libraries/render-utils/src/DeferredLightingEffect.cpp | 5 +++-- libraries/render-utils/src/RenderPipelines.cpp | 3 ++- libraries/render-utils/src/StencilMaskPass.cpp | 7 +++---- libraries/render-utils/src/StencilMaskPass.h | 4 +++- libraries/render-utils/src/SurfaceGeometryPass.cpp | 6 +++--- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 04255fbb87..9f28240065 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -18,6 +18,7 @@ #include #include +#include "StencilMaskPass.h" #include "AbstractViewStateInterface.h" #include "GeometryCache.h" #include "TextureCache.h" @@ -242,7 +243,7 @@ static void loadLightProgram(const char* vertSource, const char* fragSource, boo state->setColorWriteMask(true, true, true, false); if (lightVolume) { - state->setStencilTest(true, 0x00, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + state->setStencilTest(true, 0x00, gpu::State::StencilTest(PrepareStencil::STENCIL_SCENE, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); state->setCullMode(gpu::State::CULL_BACK); // state->setCullMode(gpu::State::CULL_FRONT); @@ -255,7 +256,7 @@ static void loadLightProgram(const char* vertSource, const char* fragSource, boo } else { // Stencil test all the light passes for objects pixels only, not the background - state->setStencilTest(true, 0x00, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + state->setStencilTest(true, 0x00, gpu::State::StencilTest(PrepareStencil::STENCIL_SCENE, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); state->setCullMode(gpu::State::CULL_BACK); // additive blending diff --git a/libraries/render-utils/src/RenderPipelines.cpp b/libraries/render-utils/src/RenderPipelines.cpp index 9ca9187df8..be2bb0efbe 100644 --- a/libraries/render-utils/src/RenderPipelines.cpp +++ b/libraries/render-utils/src/RenderPipelines.cpp @@ -15,6 +15,7 @@ #include #include +#include "StencilMaskPass.h" #include "DeferredLightingEffect.h" #include "TextureCache.h" #include "render/DrawTask.h" @@ -330,7 +331,7 @@ void addPlumberPipeline(ShapePlumber& plumber, bool isWireframed = (i & 4); auto state = std::make_shared(); - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(2, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_ZERO)); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_MASK, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_ZERO)); // Depth test depends on transparency state->setDepthTest(true, !key.isTranslucent(), gpu::LESS_EQUAL); diff --git a/libraries/render-utils/src/StencilMaskPass.cpp b/libraries/render-utils/src/StencilMaskPass.cpp index 612324a79b..6cdcfdf8d2 100644 --- a/libraries/render-utils/src/StencilMaskPass.cpp +++ b/libraries/render-utils/src/StencilMaskPass.cpp @@ -23,7 +23,6 @@ using namespace render; gpu::PipelinePointer DrawStencilDeferred::getOpaquePipeline() { if (!_opaquePipeline) { - const gpu::int8 STENCIL_OPAQUE = 0; auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS(); auto ps = gpu::StandardShaderLib::getDrawNadaPS(); auto program = gpu::Shader::createProgram(vs, ps); @@ -31,7 +30,7 @@ gpu::PipelinePointer DrawStencilDeferred::getOpaquePipeline() { auto state = std::make_shared(); state->setDepthTest(true, false, gpu::LESS_EQUAL); - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(STENCIL_OPAQUE, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_SCENE, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); state->setColorWriteMask(0); _opaquePipeline = gpu::Pipeline::create(program, state); @@ -67,12 +66,12 @@ void DrawStencilDeferred::run(const RenderContextPointer& renderContext, const g gpu::PipelinePointer PrepareStencil::getDrawStencilPipeline() { if (!_drawStencilPipeline) { auto vs = gpu::StandardShaderLib::getDrawVertexPositionVS(); - auto ps = gpu::StandardShaderLib::getDrawWhitePS(); + auto ps = gpu::StandardShaderLib::getDrawNadaPS(); auto program = gpu::Shader::createProgram(vs, ps); gpu::Shader::makeProgram((*program)); auto state = std::make_shared(); - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(2, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE)); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_MASK, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE)); // state->setColorWriteMask(0); _drawStencilPipeline = gpu::Pipeline::create(program, state); diff --git a/libraries/render-utils/src/StencilMaskPass.h b/libraries/render-utils/src/StencilMaskPass.h index bf21602462..8c05a46efa 100644 --- a/libraries/render-utils/src/StencilMaskPass.h +++ b/libraries/render-utils/src/StencilMaskPass.h @@ -35,7 +35,9 @@ public: void run(const render::RenderContextPointer& renderContext, const gpu::FramebufferPointer& dstFramebuffer); - static const gpu::int8 STENCIL_MASK = 64; + static const gpu::int8 STENCIL_MASK = 2; + static const gpu::int8 STENCIL_BACKGROUND = 1; + static const gpu::int8 STENCIL_SCENE = 0; private: gpu::PipelinePointer _drawStencilPipeline; diff --git a/libraries/render-utils/src/SurfaceGeometryPass.cpp b/libraries/render-utils/src/SurfaceGeometryPass.cpp index 746c25daa5..a13bc2846e 100644 --- a/libraries/render-utils/src/SurfaceGeometryPass.cpp +++ b/libraries/render-utils/src/SurfaceGeometryPass.cpp @@ -14,7 +14,7 @@ #include #include - +#include "StencilMaskPass.h" const int DepthLinearPass_FrameTransformSlot = 0; const int DepthLinearPass_DepthMapSlot = 0; @@ -224,7 +224,7 @@ const gpu::PipelinePointer& LinearDepthPass::getLinearDepthPipeline() { gpu::StatePointer state = gpu::StatePointer(new gpu::State()); // Stencil test the curvature pass for objects pixels only, not the background - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_SCENE, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); state->setColorWriteMask(true, false, false, false); @@ -554,7 +554,7 @@ const gpu::PipelinePointer& SurfaceGeometryPass::getCurvaturePipeline() { #ifdef USE_STENCIL_TEST // Stencil test the curvature pass for objects pixels only, not the background - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_SCENE, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); #endif // Good to go add the brand new pipeline _curvaturePipeline = gpu::Pipeline::create(program, state); From e02115bcda5b1e921847ad09e3022111ee8e3089 Mon Sep 17 00:00:00 2001 From: Sam Cake Date: Wed, 31 May 2017 23:00:05 -0700 Subject: [PATCH 38/73] clearing up the stencil jobs --- .../render-utils/src/StencilMaskPass.cpp | 66 ++++++++++++------- libraries/render-utils/src/StencilMaskPass.h | 7 +- 2 files changed, 49 insertions(+), 24 deletions(-) diff --git a/libraries/render-utils/src/StencilMaskPass.cpp b/libraries/render-utils/src/StencilMaskPass.cpp index 6cdcfdf8d2..3194dddb49 100644 --- a/libraries/render-utils/src/StencilMaskPass.cpp +++ b/libraries/render-utils/src/StencilMaskPass.cpp @@ -63,21 +63,7 @@ void DrawStencilDeferred::run(const RenderContextPointer& renderContext, const g args->_batch = nullptr; } -gpu::PipelinePointer PrepareStencil::getDrawStencilPipeline() { - if (!_drawStencilPipeline) { - auto vs = gpu::StandardShaderLib::getDrawVertexPositionVS(); - auto ps = gpu::StandardShaderLib::getDrawNadaPS(); - auto program = gpu::Shader::createProgram(vs, ps); - gpu::Shader::makeProgram((*program)); - auto state = std::make_shared(); - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_MASK, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE)); - // state->setColorWriteMask(0); - - _drawStencilPipeline = gpu::Pipeline::create(program, state); - } - return _drawStencilPipeline; -} model::MeshPointer PrepareStencil::getMesh() { if (!_mesh) { @@ -94,6 +80,37 @@ model::MeshPointer PrepareStencil::getMesh() { return _mesh; } +gpu::PipelinePointer PrepareStencil::getMeshStencilPipeline() { + if (!_meshStencilPipeline) { + auto vs = gpu::StandardShaderLib::getDrawVertexPositionVS(); + auto ps = gpu::StandardShaderLib::getDrawNadaPS(); + auto program = gpu::Shader::createProgram(vs, ps); + gpu::Shader::makeProgram((*program)); + + auto state = std::make_shared(); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_MASK, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE)); + state->setColorWriteMask(0); + + _meshStencilPipeline = gpu::Pipeline::create(program, state); + } + return _meshStencilPipeline; +} + +gpu::PipelinePointer PrepareStencil::getPaintStencilPipeline() { + if (!_paintStencilPipeline) { + auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS(); + auto ps = gpu::StandardShaderLib::getDrawNadaPS(); + auto program = gpu::Shader::createProgram(vs, ps); + gpu::Shader::makeProgram((*program)); + + auto state = std::make_shared(); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_MASK, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE)); + state->setColorWriteMask(0); + + _paintStencilPipeline = gpu::Pipeline::create(program, state); + } + return _paintStencilPipeline; +} void PrepareStencil::run(const RenderContextPointer& renderContext, const gpu::FramebufferPointer& srcFramebuffer) { assert(renderContext->args); @@ -106,16 +123,21 @@ void PrepareStencil::run(const RenderContextPointer& renderContext, const gpu::F batch.setViewportTransform(args->_viewport); - batch.setPipeline(getDrawStencilPipeline()); + if (true) { + batch.setPipeline(getMeshStencilPipeline()); - auto mesh = getMesh(); - batch.setIndexBuffer(mesh->getIndexBuffer()); - batch.setInputFormat((mesh->getVertexFormat())); - batch.setInputStream(0, mesh->getVertexStream()); + auto mesh = getMesh(); + batch.setIndexBuffer(mesh->getIndexBuffer()); + batch.setInputFormat((mesh->getVertexFormat())); + batch.setInputStream(0, mesh->getVertexStream()); - // Draw - auto part = mesh->getPartBuffer().get(0); - batch.drawIndexed(gpu::TRIANGLES, part._numIndices, part._startIndex); + // Draw + auto part = mesh->getPartBuffer().get(0); + batch.drawIndexed(gpu::TRIANGLES, part._numIndices, part._startIndex); + } else { + batch.setPipeline(getPaintStencilPipeline()); + batch.draw(gpu::TRIANGLE_STRIP, 4); + } }); args->_batch = nullptr; } diff --git a/libraries/render-utils/src/StencilMaskPass.h b/libraries/render-utils/src/StencilMaskPass.h index 8c05a46efa..0532e23fac 100644 --- a/libraries/render-utils/src/StencilMaskPass.h +++ b/libraries/render-utils/src/StencilMaskPass.h @@ -40,8 +40,11 @@ public: static const gpu::int8 STENCIL_SCENE = 0; private: - gpu::PipelinePointer _drawStencilPipeline; - gpu::PipelinePointer getDrawStencilPipeline(); + gpu::PipelinePointer _meshStencilPipeline; + gpu::PipelinePointer getMeshStencilPipeline(); + + gpu::PipelinePointer _paintStencilPipeline; + gpu::PipelinePointer getPaintStencilPipeline(); model::MeshPointer _mesh; model::MeshPointer getMesh(); From c7c07b28e94bc9d0b6aa0ac767e39aacb84c0b8c Mon Sep 17 00:00:00 2001 From: NeetBhagat Date: Thu, 1 Jun 2017 12:14:54 +0530 Subject: [PATCH 39/73] Resolve the reviewed comments of @ZappoMan --- interface/src/Application.cpp | 8 +------- libraries/plugins/src/plugins/DisplayPlugin.h | 1 + plugins/oculus/src/OculusBaseDisplayPlugin.h | 1 + 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ac39f51d7e..b8bfff8c5f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -245,7 +245,6 @@ Setting::Handle maxOctreePacketsPerSecond("maxOctreePPS", DEFAULT_MAX_OCTRE static const QString MARKETPLACE_CDN_HOSTNAME = "mpassets.highfidelity.com"; static const int INTERVAL_TO_CHECK_HMD_WORN_STATUS = 500; // milliseconds -static const QString DISPLAY_PLUGIN_NAME_OCULUS_RIFT = "Oculus Rift"; static const QString DESKTOP_DISPLAY_PLUGIN_NAME = "Desktop"; const QHash Application::_acceptedExtensions { @@ -1344,12 +1343,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo _autoSwitchDisplayModeSupportedHMDPlugin = nullptr; foreach(DisplayPluginPointer displayPlugin, PluginManager::getInstance()->getDisplayPlugins()) { if (displayPlugin->isHmd() && - displayPlugin->getName() == DISPLAY_PLUGIN_NAME_OCULUS_RIFT) { - - // Currently auto switch display mode support is only for Oculus Rift - // To support other plugins, add a condition - // (|| displayPlugin->getName() == "Other HMD Display Plugin Name") - + displayPlugin->getSupportsAutoSwitch()) { _autoSwitchDisplayModeSupportedHMDPlugin = displayPlugin; _autoSwitchDisplayModeSupportedHMDPluginName = _autoSwitchDisplayModeSupportedHMDPlugin->getName(); diff --git a/libraries/plugins/src/plugins/DisplayPlugin.h b/libraries/plugins/src/plugins/DisplayPlugin.h index 754c919fd4..297bdb2cca 100644 --- a/libraries/plugins/src/plugins/DisplayPlugin.h +++ b/libraries/plugins/src/plugins/DisplayPlugin.h @@ -200,6 +200,7 @@ public: virtual float newFramePresentRate() const { return -1.0f; } // Rate at which rendered frames are being skipped virtual float droppedFrameRate() const { return -1.0f; } + virtual bool getSupportsAutoSwitch() { return false; } // Hardware specific stats virtual QJsonObject getHardwareStats() const { return QJsonObject(); } diff --git a/plugins/oculus/src/OculusBaseDisplayPlugin.h b/plugins/oculus/src/OculusBaseDisplayPlugin.h index 1f54742c2d..bfdcc5db1e 100644 --- a/plugins/oculus/src/OculusBaseDisplayPlugin.h +++ b/plugins/oculus/src/OculusBaseDisplayPlugin.h @@ -26,6 +26,7 @@ public: void resetSensors() override final; bool beginFrameRender(uint32_t frameIndex) override; float getTargetFrameRate() const override { return _hmdDesc.DisplayRefreshRate; } + bool getSupportsAutoSwitch() override final { return true; } protected: From ea6be93c9c872768cec0c88a029323027a10242c Mon Sep 17 00:00:00 2001 From: Sam Cake Date: Thu, 1 Jun 2017 01:24:57 -0700 Subject: [PATCH 40/73] adding another flavor of the prepare stencil --- .../render-utils/src/StencilMaskPass.cpp | 5 +++-- libraries/render-utils/src/StencilMaskPass.h | 10 +++++++-- .../render-utils/src/stencil_drawMask.slf | 21 +++++++++++++++++++ 3 files changed, 32 insertions(+), 4 deletions(-) create mode 100644 libraries/render-utils/src/stencil_drawMask.slf diff --git a/libraries/render-utils/src/StencilMaskPass.cpp b/libraries/render-utils/src/StencilMaskPass.cpp index 3194dddb49..358f772354 100644 --- a/libraries/render-utils/src/StencilMaskPass.cpp +++ b/libraries/render-utils/src/StencilMaskPass.cpp @@ -18,6 +18,7 @@ #include +#include "stencil_drawMask_frag.h" using namespace render; @@ -99,7 +100,7 @@ gpu::PipelinePointer PrepareStencil::getMeshStencilPipeline() { gpu::PipelinePointer PrepareStencil::getPaintStencilPipeline() { if (!_paintStencilPipeline) { auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS(); - auto ps = gpu::StandardShaderLib::getDrawNadaPS(); + auto ps = gpu::Shader::createPixel(std::string(stencil_drawMask_frag)); auto program = gpu::Shader::createProgram(vs, ps); gpu::Shader::makeProgram((*program)); @@ -123,7 +124,7 @@ void PrepareStencil::run(const RenderContextPointer& renderContext, const gpu::F batch.setViewportTransform(args->_viewport); - if (true) { + if (false) { batch.setPipeline(getMeshStencilPipeline()); auto mesh = getMesh(); diff --git a/libraries/render-utils/src/StencilMaskPass.h b/libraries/render-utils/src/StencilMaskPass.h index 0532e23fac..d1de0cd1f4 100644 --- a/libraries/render-utils/src/StencilMaskPass.h +++ b/libraries/render-utils/src/StencilMaskPass.h @@ -16,7 +16,6 @@ #include #include - class DrawStencilDeferred { public: using JobModel = render::Job::ModelI; @@ -31,7 +30,14 @@ protected: class PrepareStencil { public: - using JobModel = render::Job::ModelI; + class Config : public render::JobConfig { + public: + Config(bool enabled = true) : JobConfig(enabled) {} + }; + + using JobModel = render::Job::ModelI; + + void configure(const Config& config) {} void run(const render::RenderContextPointer& renderContext, const gpu::FramebufferPointer& dstFramebuffer); diff --git a/libraries/render-utils/src/stencil_drawMask.slf b/libraries/render-utils/src/stencil_drawMask.slf new file mode 100644 index 0000000000..cc81fca677 --- /dev/null +++ b/libraries/render-utils/src/stencil_drawMask.slf @@ -0,0 +1,21 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// stencil_drawMask.slf +// fragment shader +// +// Created by Sam Gateau on 5/31/17. +// Copyright 2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +in vec2 varTexCoord0; + +void main(void) { + vec2 pos = varTexCoord0 * 2.0 - vec2(1.0); + pos.x = pos.x * (pos.x > 0.0 ? 2.0 : -2.0) - 1.0; + if (1.0 - dot(pos.xy, pos.xy) > 0.0 ) discard; +} From b0e4b752d5c58208b2a8d0028177727d3a70af69 Mon Sep 17 00:00:00 2001 From: Vladyslav Stelmakhovskyi Date: Thu, 1 Jun 2017 19:07:17 +0200 Subject: [PATCH 41/73] Implements landscape mode for tablet as rotation instead of stretching --- scripts/system/libraries/WebTablet.js | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/scripts/system/libraries/WebTablet.js b/scripts/system/libraries/WebTablet.js index 757743accc..7545575127 100644 --- a/scripts/system/libraries/WebTablet.js +++ b/scripts/system/libraries/WebTablet.js @@ -22,7 +22,9 @@ var DEFAULT_WIDTH = 0.4375; var DEFAULT_VERTICAL_FIELD_OF_VIEW = 45; // degrees var SENSOR_TO_ROOM_MATRIX = -2; var CAMERA_MATRIX = -7; -var ROT_Y_180 = {x: 0, y: 1, z: 0, w: 0}; +var ROT_Y_180 = {x: 0.0, y: 1.0, z: 0, w: 0}; +var ROT_LANDSCAPE = {x: 1.0, y: 1.0, z: 0, w: 0}; +var ROT_LANDSCAPE_WINDOW = {x: 0.0, y: 0.0, z: 0.0, w: 0}; var ROT_IDENT = {x: 0, y: 0, z: 0, w: 1}; var TABLET_TEXTURE_RESOLUTION = { x: 480, y: 706 }; var INCHES_TO_METERS = 1 / 39.3701; @@ -243,29 +245,30 @@ WebTablet = function (url, width, dpi, hand, clientOnly, location, visible) { }; WebTablet.prototype.getDimensions = function() { - if (this.landscape) { - return { x: this.width * 2, y: this.height, z: this.depth }; - } else { - return { x: this.width, y: this.height, z: this.depth }; - } + return { x: this.width, y: this.height, z: this.depth }; }; WebTablet.prototype.getTabletTextureResolution = function() { if (this.landscape) { - return { x: TABLET_TEXTURE_RESOLUTION.x * 2, y: TABLET_TEXTURE_RESOLUTION.y }; + return { x: TABLET_TEXTURE_RESOLUTION.y , y: TABLET_TEXTURE_RESOLUTION.x }; } else { return TABLET_TEXTURE_RESOLUTION; } }; WebTablet.prototype.setLandscape = function(newLandscapeValue) { - if (this.landscape == newLandscapeValue) { + if (this.landscape === newLandscapeValue) { return; } + + var tabletProperties = {}; + tabletProperties.visible = true; this.landscape = newLandscapeValue; - Overlays.editOverlay(this.tabletEntityID, { dimensions: this.getDimensions() }); + this.calculateTabletAttachmentProperties(NO_HANDS, false, tabletProperties); + Overlays.editOverlay(this.tabletEntityID, tabletProperties); Overlays.editOverlay(this.webOverlayID, { - resolution: this.getTabletTextureResolution() + resolution: this.getTabletTextureResolution(), + rotation: Quat.multiply(Camera.orientation, ROT_LANDSCAPE_WINDOW) }); }; @@ -407,7 +410,7 @@ WebTablet.prototype.calculateWorldAttitudeRelativeToCamera = function (windowPos return { position: worldMousePosition, - rotation: Quat.multiply(Camera.orientation, ROT_Y_180) + rotation: this.landscape ? Quat.multiply(Camera.orientation, ROT_LANDSCAPE) : Quat.multiply(Camera.orientation, ROT_Y_180) }; }; From 9c1e99fe3f9a353b5fbaa15ecaf892c19b0fc969 Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 1 Jun 2017 13:06:22 -0700 Subject: [PATCH 42/73] Removing cruft and organizing the stencil config --- .../RenderableParticleEffectEntityItem.cpp | 3 + .../src/RenderablePolyLineEntityItem.cpp | 2 + .../src/RenderablePolyVoxEntityItem.cpp | 5 + .../src/RenderableShapeEntityItem.cpp | 2 + libraries/model/src/model/Skybox.cpp | 2 +- .../src/procedural/ProceduralSkybox.cpp | 2 +- .../render-utils/src/AntialiasingEffect.cpp | 4 + .../src/DeferredLightingEffect.cpp | 4 +- libraries/render-utils/src/GeometryCache.cpp | 20 ++++ libraries/render-utils/src/HitEffect.cpp | 94 ------------------- libraries/render-utils/src/HitEffect.h | 38 -------- libraries/render-utils/src/LightClusters.cpp | 2 + .../render-utils/src/StencilMaskPass.cpp | 63 ++++--------- libraries/render-utils/src/StencilMaskPass.h | 21 ++--- .../render-utils/src/SurfaceGeometryPass.cpp | 1 + .../render-utils/src/ToneMappingEffect.cpp | 3 +- libraries/render-utils/src/ZoneRenderer.cpp | 4 + libraries/render-utils/src/hit_effect.slf | 27 ------ libraries/render-utils/src/hit_effect.slv | 26 ----- 19 files changed, 74 insertions(+), 249 deletions(-) delete mode 100644 libraries/render-utils/src/HitEffect.cpp delete mode 100644 libraries/render-utils/src/HitEffect.h delete mode 100644 libraries/render-utils/src/hit_effect.slf delete mode 100644 libraries/render-utils/src/hit_effect.slv diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp index 34dc86d92a..d813a73773 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include "EntitiesRendererLogging.h" @@ -292,6 +293,7 @@ void RenderableParticleEffectEntityItem::createPipelines() { state->setDepthTest(true, false, gpu::LESS_EQUAL); state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE, gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); + PrepareStencil::testMask(*state); auto vertShader = gpu::Shader::createVertex(std::string(untextured_particle_vert)); auto fragShader = gpu::Shader::createPixel(std::string(untextured_particle_frag)); @@ -305,6 +307,7 @@ void RenderableParticleEffectEntityItem::createPipelines() { state->setDepthTest(true, false, gpu::LESS_EQUAL); state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE, gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); + PrepareStencil::testMask(*state); auto vertShader = gpu::Shader::createVertex(std::string(textured_particle_vert)); auto fragShader = gpu::Shader::createPixel(std::string(textured_particle_frag)); diff --git a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp index a34a1814b4..1e20956301 100644 --- a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -69,6 +70,7 @@ void RenderablePolyLineEntityItem::createPipeline() { gpu::StatePointer state = gpu::StatePointer(new gpu::State()); state->setDepthTest(true, true, gpu::LESS_EQUAL); + PrepareStencil::testMask(*state); state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp index fd5346093b..7567566919 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp @@ -46,6 +46,9 @@ #endif #include "model/Geometry.h" + +#include "StencilMaskPass.h" + #include "EntityTreeRenderer.h" #include "polyvox_vert.h" #include "polyvox_frag.h" @@ -743,6 +746,7 @@ void RenderablePolyVoxEntityItem::render(RenderArgs* args) { auto state = std::make_shared(); state->setCullMode(gpu::State::CULL_BACK); state->setDepthTest(true, true, gpu::LESS_EQUAL); + PrepareStencil::testMaskDrawShape(*state); _pipeline = gpu::Pipeline::create(program, state); @@ -750,6 +754,7 @@ void RenderablePolyVoxEntityItem::render(RenderArgs* args) { wireframeState->setCullMode(gpu::State::CULL_BACK); wireframeState->setDepthTest(true, true, gpu::LESS_EQUAL); wireframeState->setFillMode(gpu::State::FILL_LINE); + PrepareStencil::testMaskDrawShape(*wireframeState); _wireframePipeline = gpu::Pipeline::create(program, wireframeState); } diff --git a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp index 1ad60bf7c6..27dd678d91 100644 --- a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include @@ -93,6 +94,7 @@ void RenderableShapeEntityItem::render(RenderArgs* args) { _procedural->_fragmentSource = simple_frag; _procedural->_opaqueState->setCullMode(gpu::State::CULL_NONE); _procedural->_opaqueState->setDepthTest(true, true, gpu::LESS_EQUAL); + PrepareStencil::testMaskDrawShape(*_procedural->_opaqueState); _procedural->_opaqueState->setBlendFunction(false, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); diff --git a/libraries/model/src/model/Skybox.cpp b/libraries/model/src/model/Skybox.cpp index d327593573..c47463666e 100755 --- a/libraries/model/src/model/Skybox.cpp +++ b/libraries/model/src/model/Skybox.cpp @@ -97,7 +97,7 @@ void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Sky } auto skyState = std::make_shared(); - skyState->setStencilTest(true, 0xFF, gpu::State::StencilTest(1, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + skyState->setStencilTest(true, 0x00, gpu::State::StencilTest(1, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); thePipeline = gpu::Pipeline::create(skyShader, skyState); } diff --git a/libraries/procedural/src/procedural/ProceduralSkybox.cpp b/libraries/procedural/src/procedural/ProceduralSkybox.cpp index f5feb434fa..eaacc5d851 100644 --- a/libraries/procedural/src/procedural/ProceduralSkybox.cpp +++ b/libraries/procedural/src/procedural/ProceduralSkybox.cpp @@ -23,7 +23,7 @@ ProceduralSkybox::ProceduralSkybox() : model::Skybox() { _procedural._fragmentSource = skybox_frag; // Adjust the pipeline state for background using the stencil test _procedural.setDoesFade(false); - _procedural._opaqueState->setStencilTest(true, 0xFF, gpu::State::StencilTest(1, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + _procedural._opaqueState->setStencilTest(true, 0x00, gpu::State::StencilTest(1, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); } bool ProceduralSkybox::empty() { diff --git a/libraries/render-utils/src/AntialiasingEffect.cpp b/libraries/render-utils/src/AntialiasingEffect.cpp index cd378d4e5b..08f69d07d0 100644 --- a/libraries/render-utils/src/AntialiasingEffect.cpp +++ b/libraries/render-utils/src/AntialiasingEffect.cpp @@ -17,6 +17,7 @@ #include #include "AntialiasingEffect.h" +#include "StencilMaskPass.h" #include "TextureCache.h" #include "FramebufferCache.h" #include "DependencyManager.h" @@ -70,6 +71,8 @@ const gpu::PipelinePointer& Antialiasing::getAntialiasingPipeline() { gpu::StatePointer state = gpu::StatePointer(new gpu::State()); + PrepareStencil::testShape(*state); + state->setDepthTest(false, false, gpu::LESS_EQUAL); // Good to go add the brand new pipeline @@ -93,6 +96,7 @@ const gpu::PipelinePointer& Antialiasing::getBlendPipeline() { gpu::StatePointer state = gpu::StatePointer(new gpu::State()); state->setDepthTest(false, false, gpu::LESS_EQUAL); + PrepareStencil::testShape(*state); // Good to go add the brand new pipeline _blendPipeline = gpu::Pipeline::create(program, state); diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 9f28240065..36a9401d00 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -243,7 +243,7 @@ static void loadLightProgram(const char* vertSource, const char* fragSource, boo state->setColorWriteMask(true, true, true, false); if (lightVolume) { - state->setStencilTest(true, 0x00, gpu::State::StencilTest(PrepareStencil::STENCIL_SCENE, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + PrepareStencil::testShape(*state); state->setCullMode(gpu::State::CULL_BACK); // state->setCullMode(gpu::State::CULL_FRONT); @@ -256,7 +256,7 @@ static void loadLightProgram(const char* vertSource, const char* fragSource, boo } else { // Stencil test all the light passes for objects pixels only, not the background - state->setStencilTest(true, 0x00, gpu::State::StencilTest(PrepareStencil::STENCIL_SCENE, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + PrepareStencil::testShape(*state); state->setCullMode(gpu::State::CULL_BACK); // additive blending diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index f1c995b943..5755d5a031 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -24,6 +24,7 @@ #include "TextureCache.h" #include "RenderUtilsLogging.h" +#include "StencilMaskPass.h" #include "gpu/StandardShaderLib.h" @@ -1610,6 +1611,9 @@ void GeometryCache::renderGlowLine(gpu::Batch& batch, const glm::vec3& p1, const state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); + + PrepareStencil::testMask(*state); + gpu::Shader::BindingSet slotBindings; slotBindings.insert(gpu::Shader::Binding(std::string("lineData"), LINE_DATA_SLOT)); gpu::Shader::makeProgram(*program, slotBindings); @@ -1663,11 +1667,14 @@ void GeometryCache::useSimpleDrawPipeline(gpu::Batch& batch, bool noBlend) { // enable decal blend state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA); + PrepareStencil::testMask(*state); _standardDrawPipeline = gpu::Pipeline::create(program, state); auto stateNoBlend = std::make_shared(); + PrepareStencil::testMaskDrawShape(*state); + auto noBlendPS = gpu::StandardShaderLib::getDrawTextureOpaquePS(); auto programNoBlend = gpu::Shader::createProgram(vs, noBlendPS); gpu::Shader::makeProgram((*programNoBlend)); @@ -1690,12 +1697,14 @@ void GeometryCache::useGridPipeline(gpu::Batch& batch, GridBuffer gridBuffer, bo auto stateLayered = std::make_shared(); stateLayered->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA); + PrepareStencil::testMask(*stateLayered); _gridPipelineLayered = gpu::Pipeline::create(program, stateLayered); auto state = std::make_shared(stateLayered->getValues()); const float DEPTH_BIAS = 0.001f; state->setDepthBias(DEPTH_BIAS); state->setDepthTest(true, false, gpu::LESS_EQUAL); + PrepareStencil::testMaskDrawShape(*state); _gridPipeline = gpu::Pipeline::create(program, state); } @@ -1773,6 +1782,11 @@ static void buildWebShader(const std::string& vertShaderText, const std::string& state->setBlendFunction(blendEnable, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); + if (blendEnable) { + PrepareStencil::testMaskBlendShape(*state); + } else { + PrepareStencil::testMaskDrawShape(*state); + } pipelinePointerOut = gpu::Pipeline::create(shaderPointerOut, state); } @@ -1858,6 +1872,12 @@ gpu::PipelinePointer GeometryCache::getSimplePipeline(bool textured, bool transp gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); + if (config.isTransparent()) { + PrepareStencil::testMask(*state); + } else { + PrepareStencil::testMaskDrawShape(*state); + } + gpu::ShaderPointer program = (config.isUnlit()) ? _unlitShader : _simpleShader; gpu::PipelinePointer pipeline = gpu::Pipeline::create(program, state); _simplePrograms.insert(config, pipeline); diff --git a/libraries/render-utils/src/HitEffect.cpp b/libraries/render-utils/src/HitEffect.cpp deleted file mode 100644 index 319e94384f..0000000000 --- a/libraries/render-utils/src/HitEffect.cpp +++ /dev/null @@ -1,94 +0,0 @@ -// -// HitEffect.cpp -// interface/src/renderer -// -// Created by Andrzej Kapolka on 7/14/13. -// Copyright 2013 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -// include this before QOpenGLFramebufferObject, which includes an earlier version of OpenGL - - -#include - -#include -#include -#include - -#include "AbstractViewStateInterface.h" -#include "HitEffect.h" - -#include "TextureCache.h" -#include "DependencyManager.h" -#include "ViewFrustum.h" -#include "GeometryCache.h" - -#include - -#include "hit_effect_vert.h" -#include "hit_effect_frag.h" - - -HitEffect::HitEffect() { - _geometryId = DependencyManager::get()->allocateID(); -} - -HitEffect::~HitEffect() { - auto geometryCache = DependencyManager::get(); - if (_geometryId && geometryCache) { - geometryCache->releaseID(_geometryId); - } -} - -const gpu::PipelinePointer& HitEffect::getHitEffectPipeline() { - if (!_hitEffectPipeline) { - auto vs = gpu::Shader::createVertex(std::string(hit_effect_vert)); - auto ps = gpu::Shader::createPixel(std::string(hit_effect_frag)); - gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps); - - - gpu::Shader::BindingSet slotBindings; - gpu::Shader::makeProgram(*program, slotBindings); - - - gpu::StatePointer state = gpu::StatePointer(new gpu::State()); - - state->setDepthTest(false, false, gpu::LESS_EQUAL); - - // Blend on transparent - state->setBlendFunction(true, - gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA); - - // Good to go add the brand new pipeline - _hitEffectPipeline = gpu::Pipeline::create(program, state); - } - return _hitEffectPipeline; -} - -void HitEffect::run(const render::RenderContextPointer& renderContext) { - assert(renderContext->args); - assert(renderContext->args->hasViewFrustum()); - RenderArgs* args = renderContext->args; - - gpu::doInBatch(args->_context, [&](gpu::Batch& batch) { - - glm::mat4 projMat; - Transform viewMat; - args->getViewFrustum().evalProjectionMatrix(projMat); - args->getViewFrustum().evalViewTransform(viewMat); - batch.setProjectionTransform(projMat); - batch.setViewTransform(viewMat); - batch.setModelTransform(Transform()); - - batch.setPipeline(getHitEffectPipeline()); - - static const glm::vec4 color(0.0f, 0.0f, 0.0f, 1.0f); - static const glm::vec2 bottomLeft(-1.0f, -1.0f); - static const glm::vec2 topRight(1.0f, 1.0f); - DependencyManager::get()->renderQuad(batch, bottomLeft, topRight, color, _geometryId); - }); -} - diff --git a/libraries/render-utils/src/HitEffect.h b/libraries/render-utils/src/HitEffect.h deleted file mode 100644 index d025d2d980..0000000000 --- a/libraries/render-utils/src/HitEffect.h +++ /dev/null @@ -1,38 +0,0 @@ -// -// hitEffect.h -// hifi -// -// Created by eric levin on 7/17/15. -// -// - -#ifndef hifi_hitEffect_h -#define hifi_hitEffect_h - -#include - -class HitEffectConfig : public render::Job::Config { - Q_OBJECT - Q_PROPERTY(bool enabled MEMBER enabled) -public: - HitEffectConfig() : render::Job::Config(false) {} -}; - -class HitEffect { -public: - using Config = HitEffectConfig; - using JobModel = render::Job::Model; - - HitEffect(); - ~HitEffect(); - void configure(const Config& config) {} - void run(const render::RenderContextPointer& renderContext); - - const gpu::PipelinePointer& getHitEffectPipeline(); - -private: - int _geometryId { 0 }; - gpu::PipelinePointer _hitEffectPipeline; -}; - -#endif diff --git a/libraries/render-utils/src/LightClusters.cpp b/libraries/render-utils/src/LightClusters.cpp index 4145264b2d..7e04b1c2a4 100644 --- a/libraries/render-utils/src/LightClusters.cpp +++ b/libraries/render-utils/src/LightClusters.cpp @@ -16,6 +16,8 @@ #include +#include "StencilMaskPass.h" + #include "lightClusters_drawGrid_vert.h" #include "lightClusters_drawGrid_frag.h" diff --git a/libraries/render-utils/src/StencilMaskPass.cpp b/libraries/render-utils/src/StencilMaskPass.cpp index 358f772354..44e7a571e8 100644 --- a/libraries/render-utils/src/StencilMaskPass.cpp +++ b/libraries/render-utils/src/StencilMaskPass.cpp @@ -22,50 +22,6 @@ using namespace render; -gpu::PipelinePointer DrawStencilDeferred::getOpaquePipeline() { - if (!_opaquePipeline) { - auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS(); - auto ps = gpu::StandardShaderLib::getDrawNadaPS(); - auto program = gpu::Shader::createProgram(vs, ps); - gpu::Shader::makeProgram((*program)); - - auto state = std::make_shared(); - state->setDepthTest(true, false, gpu::LESS_EQUAL); - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_SCENE, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); - state->setColorWriteMask(0); - - _opaquePipeline = gpu::Pipeline::create(program, state); - } - return _opaquePipeline; -} - -void DrawStencilDeferred::run(const RenderContextPointer& renderContext, const gpu::FramebufferPointer& deferredFramebuffer) { - return; - assert(renderContext->args); - assert(renderContext->args->hasViewFrustum()); - - // from the touched pixel generate the stencil buffer - RenderArgs* args = renderContext->args; - doInBatch(args->_context, [&](gpu::Batch& batch) { - args->_batch = &batch; - - batch.enableStereo(false); - - // batch.setFramebuffer(deferredFramebuffer); - batch.setViewportTransform(args->_viewport); - batch.setStateScissorRect(args->_viewport); - - batch.setPipeline(getOpaquePipeline()); - - batch.draw(gpu::TRIANGLE_STRIP, 4); - batch.setResourceTexture(0, nullptr); - - }); - args->_batch = nullptr; -} - - - model::MeshPointer PrepareStencil::getMesh() { if (!_mesh) { @@ -89,7 +45,7 @@ gpu::PipelinePointer PrepareStencil::getMeshStencilPipeline() { gpu::Shader::makeProgram((*program)); auto state = std::make_shared(); - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_MASK, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE)); + drawMask(state); state->setColorWriteMask(0); _meshStencilPipeline = gpu::Pipeline::create(program, state); @@ -105,7 +61,7 @@ gpu::PipelinePointer PrepareStencil::getPaintStencilPipeline() { gpu::Shader::makeProgram((*program)); auto state = std::make_shared(); - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_MASK, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE)); + drawMask(state); state->setColorWriteMask(0); _paintStencilPipeline = gpu::Pipeline::create(program, state); @@ -143,3 +99,18 @@ void PrepareStencil::run(const RenderContextPointer& renderContext, const gpu::F args->_batch = nullptr; } +void PrepareStencil::drawMask(gpu::State& state) { + state.setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_MASK, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE)); +} + +void PrepareStencil::testMask(gpu::State& state) { + state.setStencilTest(true, 0x00, gpu::State::StencilTest(PrepareStencil::STENCIL_MASK, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); +} + +void PrepareStencil::testBackground(gpu::State& state) { + state.setStencilTest(true, 0x00, gpu::State::StencilTest(PrepareStencil::STENCIL_BACKGROUND, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); +} + +void PrepareStencil::testMaskDrawShape(gpu::State& state) { + state.setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_MASK, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_ZERO)); +} \ No newline at end of file diff --git a/libraries/render-utils/src/StencilMaskPass.h b/libraries/render-utils/src/StencilMaskPass.h index d1de0cd1f4..c65788ebf8 100644 --- a/libraries/render-utils/src/StencilMaskPass.h +++ b/libraries/render-utils/src/StencilMaskPass.h @@ -16,18 +16,6 @@ #include #include -class DrawStencilDeferred { -public: - using JobModel = render::Job::ModelI; - - void run(const render::RenderContextPointer& renderContext, const gpu::FramebufferPointer& deferredFramebuffer); - -protected: - gpu::PipelinePointer _opaquePipeline; - - gpu::PipelinePointer getOpaquePipeline(); -}; - class PrepareStencil { public: class Config : public render::JobConfig { @@ -43,7 +31,14 @@ public: static const gpu::int8 STENCIL_MASK = 2; static const gpu::int8 STENCIL_BACKGROUND = 1; - static const gpu::int8 STENCIL_SCENE = 0; + static const gpu::int8 STENCIL_SHAPE = 0; + + + static void drawMask(gpu::State& state); + static void testMask(gpu::State& state); + static void testBackground(gpu::State& state); + static void testMaskDrawShape(gpu::State& state); + private: gpu::PipelinePointer _meshStencilPipeline; diff --git a/libraries/render-utils/src/SurfaceGeometryPass.cpp b/libraries/render-utils/src/SurfaceGeometryPass.cpp index a13bc2846e..4b13fa2bf0 100644 --- a/libraries/render-utils/src/SurfaceGeometryPass.cpp +++ b/libraries/render-utils/src/SurfaceGeometryPass.cpp @@ -250,6 +250,7 @@ const gpu::PipelinePointer& LinearDepthPass::getDownsamplePipeline() { gpu::StatePointer state = gpu::StatePointer(new gpu::State()); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_SCENE, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); state->setColorWriteMask(true, true, true, false); diff --git a/libraries/render-utils/src/ToneMappingEffect.cpp b/libraries/render-utils/src/ToneMappingEffect.cpp index d54481d246..df4e1e0e6a 100644 --- a/libraries/render-utils/src/ToneMappingEffect.cpp +++ b/libraries/render-utils/src/ToneMappingEffect.cpp @@ -15,7 +15,7 @@ #include #include - +#include "StencilMaskPass.h" #include "FramebufferCache.h" #include "toneMapping_frag.h" @@ -39,6 +39,7 @@ void ToneMappingEffect::init() { slotBindings.insert(gpu::Shader::Binding(std::string("colorMap"), ToneMappingEffect_LightingMapSlot)); gpu::Shader::makeProgram(*blitProgram, slotBindings); auto blitState = std::make_shared(); + blitState->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_SCENE, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); blitState->setColorWriteMask(true, true, true, true); _blitLightBuffer = gpu::PipelinePointer(gpu::Pipeline::create(blitProgram, blitState)); } diff --git a/libraries/render-utils/src/ZoneRenderer.cpp b/libraries/render-utils/src/ZoneRenderer.cpp index 3b4870fd3f..2fa6805cde 100644 --- a/libraries/render-utils/src/ZoneRenderer.cpp +++ b/libraries/render-utils/src/ZoneRenderer.cpp @@ -17,6 +17,7 @@ #include #include +#include "StencilMaskPass.h" #include "DeferredLightingEffect.h" #include "zone_drawKeyLight_frag.h" @@ -74,6 +75,7 @@ const gpu::PipelinePointer& DebugZoneLighting::getKeyLightPipeline() { gpu::StatePointer state = gpu::StatePointer(new gpu::State()); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_SCENE, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA); _keyLightPipeline = gpu::Pipeline::create(program, state); } @@ -95,6 +97,7 @@ const gpu::PipelinePointer& DebugZoneLighting::getAmbientPipeline() { gpu::StatePointer state = gpu::StatePointer(new gpu::State()); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_SCENE, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA); _ambientPipeline = gpu::Pipeline::create(program, state); } @@ -115,6 +118,7 @@ const gpu::PipelinePointer& DebugZoneLighting::getBackgroundPipeline() { gpu::StatePointer state = gpu::StatePointer(new gpu::State()); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_SCENE, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA); _backgroundPipeline = gpu::Pipeline::create(program, state); } diff --git a/libraries/render-utils/src/hit_effect.slf b/libraries/render-utils/src/hit_effect.slf deleted file mode 100644 index cc4484442f..0000000000 --- a/libraries/render-utils/src/hit_effect.slf +++ /dev/null @@ -1,27 +0,0 @@ -<@include gpu/Config.slh@> -<$VERSION_HEADER$> -// Generated on <$_SCRIBE_DATE$> -// - -// hit_effect.frag -// fragment shader -// -// Created by Eric Levin on 7/20 -// Copyright 2015 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - - -<@include DeferredBufferWrite.slh@> - -in vec2 varQuadPosition; -out vec4 outFragColor; - -void main(void) { - vec2 center = vec2(0.0, 0.0); - float distFromCenter = distance( vec2(0.0, 0.0), varQuadPosition); - float alpha = mix(0.0, 0.5, pow(distFromCenter,5.)); - outFragColor = vec4(1.0, 0.0, 0.0, alpha); -} \ No newline at end of file diff --git a/libraries/render-utils/src/hit_effect.slv b/libraries/render-utils/src/hit_effect.slv deleted file mode 100644 index b9b0638f9e..0000000000 --- a/libraries/render-utils/src/hit_effect.slv +++ /dev/null @@ -1,26 +0,0 @@ -<@include gpu/Config.slh@> -<$VERSION_HEADER$> -// Generated on <$_SCRIBE_DATE$> -// -// hit_effect.vert -// vertex shader -// -// Created by Eric Levin on 7/20/15. -// Copyright 2015 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -<@include gpu/Inputs.slh@> - -<@include gpu/Transform.slh@> - -<$declareStandardTransform()$> - -out vec2 varQuadPosition; - -void main(void) { - varQuadPosition = inPosition.xy; - gl_Position = inPosition; -} \ No newline at end of file From c5e9551bab387b854ae71915b38e6494cf583754 Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 1 Jun 2017 18:05:18 -0700 Subject: [PATCH 43/73] more cleanup --- libraries/render-utils/src/GeometryCache.cpp | 2 +- libraries/render-utils/src/RenderDeferredTask.cpp | 4 ---- libraries/render-utils/src/StencilMaskPass.cpp | 8 ++++++-- libraries/render-utils/src/StencilMaskPass.h | 1 + libraries/render-utils/src/SurfaceGeometryPass.cpp | 4 ++-- libraries/render-utils/src/ToneMappingEffect.cpp | 2 +- libraries/render-utils/src/ZoneRenderer.cpp | 6 +++--- 7 files changed, 14 insertions(+), 13 deletions(-) diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 5755d5a031..cd87cfdb3d 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -1783,7 +1783,7 @@ static void buildWebShader(const std::string& vertShaderText, const std::string& gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); if (blendEnable) { - PrepareStencil::testMaskBlendShape(*state); + PrepareStencil::testMask(*state); } else { PrepareStencil::testMaskDrawShape(*state); } diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 89b4b72944..1b99fe92ee 100644 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -33,7 +33,6 @@ #include "DeferredLightingEffect.h" #include "SurfaceGeometryPass.h" #include "FramebufferCache.h" -#include "HitEffect.h" #include "TextureCache.h" #include "ZoneRenderer.h" @@ -91,9 +90,6 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren const auto opaqueInputs = DrawStateSortDeferred::Inputs(opaques, lightingModel).hasVarying(); task.addJob("DrawOpaqueDeferred", opaqueInputs, shapePlumber); - // Once opaque is all rendered create stencil background - task.addJob("DrawOpaqueStencil", primaryFramebuffer); - task.addJob("OpaqueRangeTimer", opaqueRangeTimer); diff --git a/libraries/render-utils/src/StencilMaskPass.cpp b/libraries/render-utils/src/StencilMaskPass.cpp index 44e7a571e8..7a13a2d759 100644 --- a/libraries/render-utils/src/StencilMaskPass.cpp +++ b/libraries/render-utils/src/StencilMaskPass.cpp @@ -45,7 +45,7 @@ gpu::PipelinePointer PrepareStencil::getMeshStencilPipeline() { gpu::Shader::makeProgram((*program)); auto state = std::make_shared(); - drawMask(state); + drawMask(*state); state->setColorWriteMask(0); _meshStencilPipeline = gpu::Pipeline::create(program, state); @@ -61,7 +61,7 @@ gpu::PipelinePointer PrepareStencil::getPaintStencilPipeline() { gpu::Shader::makeProgram((*program)); auto state = std::make_shared(); - drawMask(state); + drawMask(*state); state->setColorWriteMask(0); _paintStencilPipeline = gpu::Pipeline::create(program, state); @@ -113,4 +113,8 @@ void PrepareStencil::testBackground(gpu::State& state) { void PrepareStencil::testMaskDrawShape(gpu::State& state) { state.setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_MASK, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_ZERO)); +} + +void PrepareStencil::testShape(gpu::State& state) { + state.setStencilTest(true, 0x00, gpu::State::StencilTest(PrepareStencil::STENCIL_SHAPE, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); } \ No newline at end of file diff --git a/libraries/render-utils/src/StencilMaskPass.h b/libraries/render-utils/src/StencilMaskPass.h index c65788ebf8..d7d6ee448b 100644 --- a/libraries/render-utils/src/StencilMaskPass.h +++ b/libraries/render-utils/src/StencilMaskPass.h @@ -38,6 +38,7 @@ public: static void testMask(gpu::State& state); static void testBackground(gpu::State& state); static void testMaskDrawShape(gpu::State& state); + static void testShape(gpu::State& state); private: diff --git a/libraries/render-utils/src/SurfaceGeometryPass.cpp b/libraries/render-utils/src/SurfaceGeometryPass.cpp index 4b13fa2bf0..de04c31622 100644 --- a/libraries/render-utils/src/SurfaceGeometryPass.cpp +++ b/libraries/render-utils/src/SurfaceGeometryPass.cpp @@ -224,7 +224,7 @@ const gpu::PipelinePointer& LinearDepthPass::getLinearDepthPipeline() { gpu::StatePointer state = gpu::StatePointer(new gpu::State()); // Stencil test the curvature pass for objects pixels only, not the background - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_SCENE, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + PrepareStencil::testShape(*state); state->setColorWriteMask(true, false, false, false); @@ -250,7 +250,7 @@ const gpu::PipelinePointer& LinearDepthPass::getDownsamplePipeline() { gpu::StatePointer state = gpu::StatePointer(new gpu::State()); - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_SCENE, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + PrepareStencil::testShape(*state); state->setColorWriteMask(true, true, true, false); diff --git a/libraries/render-utils/src/ToneMappingEffect.cpp b/libraries/render-utils/src/ToneMappingEffect.cpp index df4e1e0e6a..62ae9147f3 100644 --- a/libraries/render-utils/src/ToneMappingEffect.cpp +++ b/libraries/render-utils/src/ToneMappingEffect.cpp @@ -39,7 +39,7 @@ void ToneMappingEffect::init() { slotBindings.insert(gpu::Shader::Binding(std::string("colorMap"), ToneMappingEffect_LightingMapSlot)); gpu::Shader::makeProgram(*blitProgram, slotBindings); auto blitState = std::make_shared(); - blitState->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_SCENE, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + PrepareStencil::testShape(*blitState); blitState->setColorWriteMask(true, true, true, true); _blitLightBuffer = gpu::PipelinePointer(gpu::Pipeline::create(blitProgram, blitState)); } diff --git a/libraries/render-utils/src/ZoneRenderer.cpp b/libraries/render-utils/src/ZoneRenderer.cpp index 2fa6805cde..b72e4eac69 100644 --- a/libraries/render-utils/src/ZoneRenderer.cpp +++ b/libraries/render-utils/src/ZoneRenderer.cpp @@ -75,7 +75,7 @@ const gpu::PipelinePointer& DebugZoneLighting::getKeyLightPipeline() { gpu::StatePointer state = gpu::StatePointer(new gpu::State()); - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_SCENE, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + PrepareStencil::testMask(*state); state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA); _keyLightPipeline = gpu::Pipeline::create(program, state); } @@ -97,7 +97,7 @@ const gpu::PipelinePointer& DebugZoneLighting::getAmbientPipeline() { gpu::StatePointer state = gpu::StatePointer(new gpu::State()); - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_SCENE, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + PrepareStencil::testMask(*state); state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA); _ambientPipeline = gpu::Pipeline::create(program, state); } @@ -118,7 +118,7 @@ const gpu::PipelinePointer& DebugZoneLighting::getBackgroundPipeline() { gpu::StatePointer state = gpu::StatePointer(new gpu::State()); - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_SCENE, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + PrepareStencil::testMask(*state); state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA); _backgroundPipeline = gpu::Pipeline::create(program, state); } From 4a419f2d07a4a796834929b85d7aa49dfa24972f Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 1 Jun 2017 18:25:24 -0700 Subject: [PATCH 44/73] Merging with upstream --- libraries/render-utils/src/RenderPipelines.cpp | 2 +- libraries/render-utils/src/StencilMaskPass.cpp | 6 +++--- libraries/render-utils/src/SurfaceGeometryPass.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libraries/render-utils/src/RenderPipelines.cpp b/libraries/render-utils/src/RenderPipelines.cpp index be2bb0efbe..42ed0bdad9 100644 --- a/libraries/render-utils/src/RenderPipelines.cpp +++ b/libraries/render-utils/src/RenderPipelines.cpp @@ -331,7 +331,7 @@ void addPlumberPipeline(ShapePlumber& plumber, bool isWireframed = (i & 4); auto state = std::make_shared(); - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_MASK, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_ZERO)); + PrepareStencil::testMaskDrawShape(*state); // Depth test depends on transparency state->setDepthTest(true, !key.isTranslucent(), gpu::LESS_EQUAL); diff --git a/libraries/render-utils/src/StencilMaskPass.cpp b/libraries/render-utils/src/StencilMaskPass.cpp index 7a13a2d759..d8a4afbc43 100644 --- a/libraries/render-utils/src/StencilMaskPass.cpp +++ b/libraries/render-utils/src/StencilMaskPass.cpp @@ -104,11 +104,11 @@ void PrepareStencil::drawMask(gpu::State& state) { } void PrepareStencil::testMask(gpu::State& state) { - state.setStencilTest(true, 0x00, gpu::State::StencilTest(PrepareStencil::STENCIL_MASK, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + state.setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_MASK, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); } void PrepareStencil::testBackground(gpu::State& state) { - state.setStencilTest(true, 0x00, gpu::State::StencilTest(PrepareStencil::STENCIL_BACKGROUND, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + state.setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_BACKGROUND, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); } void PrepareStencil::testMaskDrawShape(gpu::State& state) { @@ -116,5 +116,5 @@ void PrepareStencil::testMaskDrawShape(gpu::State& state) { } void PrepareStencil::testShape(gpu::State& state) { - state.setStencilTest(true, 0x00, gpu::State::StencilTest(PrepareStencil::STENCIL_SHAPE, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + state.setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_SHAPE, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); } \ No newline at end of file diff --git a/libraries/render-utils/src/SurfaceGeometryPass.cpp b/libraries/render-utils/src/SurfaceGeometryPass.cpp index de04c31622..b0c0aa6358 100644 --- a/libraries/render-utils/src/SurfaceGeometryPass.cpp +++ b/libraries/render-utils/src/SurfaceGeometryPass.cpp @@ -555,7 +555,7 @@ const gpu::PipelinePointer& SurfaceGeometryPass::getCurvaturePipeline() { #ifdef USE_STENCIL_TEST // Stencil test the curvature pass for objects pixels only, not the background - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_SCENE, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + PrepareStencil::testMask(*state); #endif // Good to go add the brand new pipeline _curvaturePipeline = gpu::Pipeline::create(program, state); From f9aa400b951e2a9e18c809973fd434780786393b Mon Sep 17 00:00:00 2001 From: Sam Cake Date: Fri, 2 Jun 2017 00:22:38 -0700 Subject: [PATCH 45/73] Refining the stencil configuration and triggering only in hmd mode --- interface/src/Application.cpp | 3 +++ libraries/model/src/model/Skybox.cpp | 2 +- .../src/procedural/ProceduralSkybox.cpp | 2 +- .../render-utils/src/AntialiasingEffect.cpp | 4 ++-- libraries/render-utils/src/StencilMaskPass.cpp | 17 +++++++++-------- .../render-utils/src/SurfaceGeometryPass.cpp | 2 +- .../render-utils/src/ToneMappingEffect.cpp | 2 +- libraries/render-utils/src/stencil_drawMask.slf | 4 +++- libraries/shared/src/RenderArgs.h | 8 ++++---- tests/shaders/src/main.cpp | 11 ----------- 10 files changed, 25 insertions(+), 30 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 8c6bea0905..f232f8c956 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2185,6 +2185,9 @@ void Application::paintGL() { }); renderArgs._context->setStereoProjections(eyeProjections); renderArgs._context->setStereoViews(eyeOffsets); + + // Configure the type of display / stereo + renderArgs._displayMode = (isHMDMode() ? RenderArgs::STEREO_HMD : RenderArgs::STEREO_MONITOR); } renderArgs._blitFramebuffer = finalFramebuffer; displaySide(&renderArgs, _myCamera); diff --git a/libraries/model/src/model/Skybox.cpp b/libraries/model/src/model/Skybox.cpp index c47463666e..d327593573 100755 --- a/libraries/model/src/model/Skybox.cpp +++ b/libraries/model/src/model/Skybox.cpp @@ -97,7 +97,7 @@ void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Sky } auto skyState = std::make_shared(); - skyState->setStencilTest(true, 0x00, gpu::State::StencilTest(1, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + skyState->setStencilTest(true, 0xFF, gpu::State::StencilTest(1, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); thePipeline = gpu::Pipeline::create(skyShader, skyState); } diff --git a/libraries/procedural/src/procedural/ProceduralSkybox.cpp b/libraries/procedural/src/procedural/ProceduralSkybox.cpp index eaacc5d851..f5feb434fa 100644 --- a/libraries/procedural/src/procedural/ProceduralSkybox.cpp +++ b/libraries/procedural/src/procedural/ProceduralSkybox.cpp @@ -23,7 +23,7 @@ ProceduralSkybox::ProceduralSkybox() : model::Skybox() { _procedural._fragmentSource = skybox_frag; // Adjust the pipeline state for background using the stencil test _procedural.setDoesFade(false); - _procedural._opaqueState->setStencilTest(true, 0x00, gpu::State::StencilTest(1, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + _procedural._opaqueState->setStencilTest(true, 0xFF, gpu::State::StencilTest(1, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); } bool ProceduralSkybox::empty() { diff --git a/libraries/render-utils/src/AntialiasingEffect.cpp b/libraries/render-utils/src/AntialiasingEffect.cpp index 08f69d07d0..139f1ae091 100644 --- a/libraries/render-utils/src/AntialiasingEffect.cpp +++ b/libraries/render-utils/src/AntialiasingEffect.cpp @@ -71,7 +71,7 @@ const gpu::PipelinePointer& Antialiasing::getAntialiasingPipeline() { gpu::StatePointer state = gpu::StatePointer(new gpu::State()); - PrepareStencil::testShape(*state); + PrepareStencil::testMask(*state); state->setDepthTest(false, false, gpu::LESS_EQUAL); @@ -96,7 +96,7 @@ const gpu::PipelinePointer& Antialiasing::getBlendPipeline() { gpu::StatePointer state = gpu::StatePointer(new gpu::State()); state->setDepthTest(false, false, gpu::LESS_EQUAL); - PrepareStencil::testShape(*state); + PrepareStencil::testMask(*state); // Good to go add the brand new pipeline _blendPipeline = gpu::Pipeline::create(program, state); diff --git a/libraries/render-utils/src/StencilMaskPass.cpp b/libraries/render-utils/src/StencilMaskPass.cpp index d8a4afbc43..dcd994763f 100644 --- a/libraries/render-utils/src/StencilMaskPass.cpp +++ b/libraries/render-utils/src/StencilMaskPass.cpp @@ -70,12 +70,14 @@ gpu::PipelinePointer PrepareStencil::getPaintStencilPipeline() { } void PrepareStencil::run(const RenderContextPointer& renderContext, const gpu::FramebufferPointer& srcFramebuffer) { - assert(renderContext->args); - assert(renderContext->args->_context); - RenderArgs* args = renderContext->args; + + // Only draw the stencil mask if in HMD mode. + if (args->_displayMode != RenderArgs::STEREO_HMD) { + return; + } + doInBatch(args->_context, [&](gpu::Batch& batch) { - args->_batch = &batch; batch.enableStereo(false); batch.setViewportTransform(args->_viewport); @@ -96,7 +98,6 @@ void PrepareStencil::run(const RenderContextPointer& renderContext, const gpu::F batch.draw(gpu::TRIANGLE_STRIP, 4); } }); - args->_batch = nullptr; } void PrepareStencil::drawMask(gpu::State& state) { @@ -104,11 +105,11 @@ void PrepareStencil::drawMask(gpu::State& state) { } void PrepareStencil::testMask(gpu::State& state) { - state.setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_MASK, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + state.setStencilTest(true, 0x00, gpu::State::StencilTest(PrepareStencil::STENCIL_MASK, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); } void PrepareStencil::testBackground(gpu::State& state) { - state.setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_BACKGROUND, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + state.setStencilTest(true, 0x00, gpu::State::StencilTest(PrepareStencil::STENCIL_BACKGROUND, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); } void PrepareStencil::testMaskDrawShape(gpu::State& state) { @@ -116,5 +117,5 @@ void PrepareStencil::testMaskDrawShape(gpu::State& state) { } void PrepareStencil::testShape(gpu::State& state) { - state.setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_SHAPE, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + state.setStencilTest(true, 0x00, gpu::State::StencilTest(PrepareStencil::STENCIL_SHAPE, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); } \ No newline at end of file diff --git a/libraries/render-utils/src/SurfaceGeometryPass.cpp b/libraries/render-utils/src/SurfaceGeometryPass.cpp index b0c0aa6358..1941766353 100644 --- a/libraries/render-utils/src/SurfaceGeometryPass.cpp +++ b/libraries/render-utils/src/SurfaceGeometryPass.cpp @@ -555,7 +555,7 @@ const gpu::PipelinePointer& SurfaceGeometryPass::getCurvaturePipeline() { #ifdef USE_STENCIL_TEST // Stencil test the curvature pass for objects pixels only, not the background - PrepareStencil::testMask(*state); + PrepareStencil::testShape(*state); #endif // Good to go add the brand new pipeline _curvaturePipeline = gpu::Pipeline::create(program, state); diff --git a/libraries/render-utils/src/ToneMappingEffect.cpp b/libraries/render-utils/src/ToneMappingEffect.cpp index 62ae9147f3..7a3d868236 100644 --- a/libraries/render-utils/src/ToneMappingEffect.cpp +++ b/libraries/render-utils/src/ToneMappingEffect.cpp @@ -39,7 +39,7 @@ void ToneMappingEffect::init() { slotBindings.insert(gpu::Shader::Binding(std::string("colorMap"), ToneMappingEffect_LightingMapSlot)); gpu::Shader::makeProgram(*blitProgram, slotBindings); auto blitState = std::make_shared(); - PrepareStencil::testShape(*blitState); + PrepareStencil::testMask(*blitState); blitState->setColorWriteMask(true, true, true, true); _blitLightBuffer = gpu::PipelinePointer(gpu::Pipeline::create(blitProgram, blitState)); } diff --git a/libraries/render-utils/src/stencil_drawMask.slf b/libraries/render-utils/src/stencil_drawMask.slf index cc81fca677..3eedeecb82 100644 --- a/libraries/render-utils/src/stencil_drawMask.slf +++ b/libraries/render-utils/src/stencil_drawMask.slf @@ -14,8 +14,10 @@ in vec2 varTexCoord0; +float aspectRatio = 0.95; + void main(void) { vec2 pos = varTexCoord0 * 2.0 - vec2(1.0); - pos.x = pos.x * (pos.x > 0.0 ? 2.0 : -2.0) - 1.0; + pos.x = aspectRatio * (pos.x * (pos.x > 0.0 ? 2.0 : -2.0) - 1.0); if (1.0 - dot(pos.xy, pos.xy) > 0.0 ) discard; } diff --git a/libraries/shared/src/RenderArgs.h b/libraries/shared/src/RenderArgs.h index f44d736e1a..d4d88c26a8 100644 --- a/libraries/shared/src/RenderArgs.h +++ b/libraries/shared/src/RenderArgs.h @@ -76,7 +76,7 @@ public: class RenderArgs { public: enum RenderMode { DEFAULT_RENDER_MODE, SHADOW_RENDER_MODE, DIFFUSE_RENDER_MODE, NORMAL_RENDER_MODE, MIRROR_RENDER_MODE }; - enum RenderSide { MONO, STEREO_LEFT, STEREO_RIGHT }; + enum DisplayMode { MONO, STEREO_MONITOR, STEREO_HMD }; enum DebugFlags { RENDER_DEBUG_NONE = 0, RENDER_DEBUG_HULLS = 1 @@ -87,7 +87,7 @@ public: float sizeScale = 1.0f, int boundaryLevelAdjust = 0, RenderMode renderMode = DEFAULT_RENDER_MODE, - RenderSide renderSide = MONO, + DisplayMode displayMode = MONO, DebugFlags debugFlags = RENDER_DEBUG_NONE, gpu::Batch* batch = nullptr) : _context(context), @@ -95,7 +95,7 @@ public: _sizeScale(sizeScale), _boundaryLevelAdjust(boundaryLevelAdjust), _renderMode(renderMode), - _renderSide(renderSide), + _displayMode(displayMode), _debugFlags(debugFlags), _batch(batch) { } @@ -121,7 +121,7 @@ public: float _sizeScale = 1.0f; int _boundaryLevelAdjust = 0; RenderMode _renderMode = DEFAULT_RENDER_MODE; - RenderSide _renderSide = MONO; + DisplayMode _displayMode = MONO; DebugFlags _debugFlags = RENDER_DEBUG_NONE; gpu::Batch* _batch = nullptr; diff --git a/tests/shaders/src/main.cpp b/tests/shaders/src/main.cpp index 8a239f0728..d10ab1ddbe 100644 --- a/tests/shaders/src/main.cpp +++ b/tests/shaders/src/main.cpp @@ -31,13 +31,9 @@ #include #include -#include #include #include -#include -#include - #include #include @@ -66,9 +62,6 @@ #include #include -#include -#include - #include #include @@ -155,11 +148,8 @@ void QTestWindow::draw() { testShaderBuild(simple_vert, simple_frag); testShaderBuild(simple_vert, simple_textured_frag); testShaderBuild(simple_vert, simple_textured_unlit_frag); - testShaderBuild(deferred_light_vert, directional_light_frag); testShaderBuild(deferred_light_vert, directional_ambient_light_frag); testShaderBuild(deferred_light_vert, directional_skybox_light_frag); - testShaderBuild(deferred_light_point_vert, point_light_frag); - testShaderBuild(deferred_light_spot_vert, spot_light_frag); testShaderBuild(standardTransformPNTC_vert, standardDrawTexture_frag); testShaderBuild(standardTransformPNTC_vert, DrawTextureOpaque_frag); @@ -190,7 +180,6 @@ void QTestWindow::draw() { testShaderBuild(ambient_occlusion_vert, ambient_occlusion_frag); testShaderBuild(ambient_occlusion_vert, occlusion_blend_frag); */ - testShaderBuild(hit_effect_vert, hit_effect_frag); testShaderBuild(overlay3D_vert, overlay3D_frag); From 6228ff19bf2c9315b6edc01747a985301421e436 Mon Sep 17 00:00:00 2001 From: NeetBhagat Date: Fri, 2 Jun 2017 14:37:17 +0530 Subject: [PATCH 46/73] Resolve the reviewed comments of @ZappoMan --- interface/src/Application.cpp | 26 +++++++++---------- interface/src/Application.h | 2 +- .../display-plugins/OpenGLDisplayPlugin.cpp | 3 ++- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 8384204fb9..a3787847db 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1349,16 +1349,12 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo _autoSwitchDisplayModeSupportedHMDPlugin->getName(); _previousHMDWornStatus = _autoSwitchDisplayModeSupportedHMDPlugin->isDisplayVisible(); - qCDebug(interfaceapp) << "_autoSwitchModeSupportedPluginName::" - << _autoSwitchDisplayModeSupportedHMDPluginName; break; } } - if (_autoSwitchDisplayModeSupportedHMDPlugin != nullptr) { - // If HMD Plugin is available and current display plugin is not HMD plugin - // then startHMDStandBySession to poll HMD Worn status. - if (getActiveDisplayPlugin()->getName() != _autoSwitchDisplayModeSupportedHMDPluginName && + if (_autoSwitchDisplayModeSupportedHMDPlugin) { + if (getActiveDisplayPlugin() != _autoSwitchDisplayModeSupportedHMDPlugin && !_autoSwitchDisplayModeSupportedHMDPlugin->isStandBySessionActive()) { startHMDStandBySession(); } @@ -1600,7 +1596,7 @@ void Application::aboutToQuit() { } getActiveDisplayPlugin()->deactivate(); - if (_autoSwitchDisplayModeSupportedHMDPlugin != nullptr + if (_autoSwitchDisplayModeSupportedHMDPlugin && _autoSwitchDisplayModeSupportedHMDPlugin->isStandBySessionActive()) { _autoSwitchDisplayModeSupportedHMDPlugin->endStandBySession(); } @@ -6769,18 +6765,20 @@ void Application::updateDisplayMode() { } void Application::switchDisplayMode() { + if (!_autoSwitchDisplayModeSupportedHMDPlugin) { + return; + } bool currentHMDWornStatus = _autoSwitchDisplayModeSupportedHMDPlugin->isDisplayVisible(); if (currentHMDWornStatus != _previousHMDWornStatus) { - // Switch to respective mode as soon as currentHMDWornStatus changes - if (currentHMDWornStatus == false && _previousHMDWornStatus == true) { - qCDebug(interfaceapp) << "Switching from HMD to desktop mode"; - setActiveDisplayPlugin(DESKTOP_DISPLAY_PLUGIN_NAME); - startHMDStandBySession(); - } - if (currentHMDWornStatus == true && _previousHMDWornStatus == false) { + // Switch to respective mode as soon as currentHMDWornStatus changes + if (currentHMDWornStatus) { qCDebug(interfaceapp) << "Switching from Desktop to HMD mode"; endHMDStandBySession(); setActiveDisplayPlugin(_autoSwitchDisplayModeSupportedHMDPluginName); + } else { + qCDebug(interfaceapp) << "Switching from HMD to desktop mode"; + setActiveDisplayPlugin(DESKTOP_DISPLAY_PLUGIN_NAME); + startHMDStandBySession(); } } _previousHMDWornStatus = currentHMDWornStatus; diff --git a/interface/src/Application.h b/interface/src/Application.h index e1fb37ef3a..4cd47ada58 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -681,7 +681,7 @@ private: AudioInjector* _snapshotSoundInjector { nullptr }; SharedSoundPointer _snapshotSound; - DisplayPluginPointer _autoSwitchDisplayModeSupportedHMDPlugin = nullptr; + DisplayPluginPointer _autoSwitchDisplayModeSupportedHMDPlugin; QString _autoSwitchDisplayModeSupportedHMDPluginName; bool _previousHMDWornStatus; void startHMDStandBySession(); diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index 3bdf9a672c..fbdc1ad71e 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -315,6 +315,7 @@ bool OpenGLDisplayPlugin::activate() { if (isHmd() && (getHmdScreen() >= 0)) { _container->showDisplayPluginsTools(); } + return Parent::activate(); } @@ -347,7 +348,7 @@ bool OpenGLDisplayPlugin::startStandBySession() { void OpenGLDisplayPlugin::endStandBySession() { deactivateStandBySession(); - return Parent::endStandBySession(); + Parent::endStandBySession(); } void OpenGLDisplayPlugin::customizeContext() { From 8068e7201d764986b4633ae1148610d45c02db3d Mon Sep 17 00:00:00 2001 From: Vladyslav Stelmakhovskyi Date: Fri, 2 Jun 2017 18:58:18 +0200 Subject: [PATCH 47/73] Fix position after rotation. May be fix rotation in HMD mode --- scripts/system/libraries/WebTablet.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/scripts/system/libraries/WebTablet.js b/scripts/system/libraries/WebTablet.js index 7545575127..8c3f5d03bb 100644 --- a/scripts/system/libraries/WebTablet.js +++ b/scripts/system/libraries/WebTablet.js @@ -261,11 +261,10 @@ WebTablet.prototype.setLandscape = function(newLandscapeValue) { return; } - var tabletProperties = {}; - tabletProperties.visible = true; this.landscape = newLandscapeValue; - this.calculateTabletAttachmentProperties(NO_HANDS, false, tabletProperties); - Overlays.editOverlay(this.tabletEntityID, tabletProperties); + Overlays.editOverlay(this.tabletEntityID, + { rotation: this.landscape ? Quat.multiply(Camera.orientation, ROT_LANDSCAPE) : + Quat.multiply(Camera.orientation, ROT_Y_180) }); Overlays.editOverlay(this.webOverlayID, { resolution: this.getTabletTextureResolution(), rotation: Quat.multiply(Camera.orientation, ROT_LANDSCAPE_WINDOW) From f5d732f3329132b5b604242261ec785c08be7f6b Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 31 May 2017 19:00:41 -0700 Subject: [PATCH 48/73] initial version of the ClosureEventSender using std::thread --- interface/src/Application.cpp | 6 ++ interface/src/Application.h | 3 + interface/src/main.cpp | 7 ++ .../src/networking/ClosureEventSender.cpp | 71 +++++++++++++++++++ interface/src/networking/ClosureEventSender.h | 35 +++++++++ libraries/networking/src/AccountManager.cpp | 1 - libraries/networking/src/AccountManager.h | 1 + .../networking/src/UserActivityLogger.cpp | 2 - libraries/networking/src/UserActivityLogger.h | 2 + 9 files changed, 125 insertions(+), 3 deletions(-) create mode 100644 interface/src/networking/ClosureEventSender.cpp create mode 100644 interface/src/networking/ClosureEventSender.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 46c4c0bd4e..297ee943fa 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -144,6 +144,7 @@ #include "InterfaceLogging.h" #include "LODManager.h" #include "ModelPackager.h" +#include "networking/ClosureEventSender.h" #include "networking/HFWebEngineProfile.h" #include "networking/HFTabletWebEngineProfile.h" #include "networking/FileTypeProfile.h" @@ -534,6 +535,7 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); + DependencyManager::set(); return previousSessionCrashed; } @@ -1568,6 +1570,10 @@ void Application::aboutToQuit() { getActiveDisplayPlugin()->deactivate(); + // use the ClosureEventSender via an std::thread (to not use QThread while the application is going down) + // to send an event that says the user asked for the app to close + _userQuitThread = std::thread { &ClosureEventSender::sendQuitStart, DependencyManager::get() }; + // Hide Running Scripts dialog so that it gets destroyed in an orderly manner; prevents warnings at shutdown. DependencyManager::get()->hide("RunningScripts"); diff --git a/interface/src/Application.h b/interface/src/Application.h index 9cf03f1cef..23673399f6 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -13,6 +13,7 @@ #define hifi_Application_h #include +#include #include #include @@ -680,6 +681,8 @@ private: FileScriptingInterface* _fileDownload; AudioInjector* _snapshotSoundInjector { nullptr }; SharedSoundPointer _snapshotSound; + + std::thread _userQuitThread; }; diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 49517eb38e..68525dfd1e 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -30,6 +30,7 @@ #include "InterfaceLogging.h" #include "UserActivityLogger.h" #include "MainWindow.h" +#include "networking/ClosureEventSender.h" #ifdef HAS_BUGSPLAT #include @@ -267,6 +268,12 @@ int main(int argc, const char* argv[]) { Application::shutdownPlugins(); + if (UserActivityLogger::getInstance().isEnabled()) { + // send a quit finished event here to indicate that this session closed cleanly + std::thread quitCompleteThread { &::ClosureEventSender::sendQuitFinish, DependencyManager::get() }; + quitCompleteThread.join(); + } + qCDebug(interfaceapp, "Normal exit."); #if !defined(DEBUG) && !defined(Q_OS_LINUX) // HACK: exit immediately (don't handle shutdown callbacks) for Release build diff --git a/interface/src/networking/ClosureEventSender.cpp b/interface/src/networking/ClosureEventSender.cpp new file mode 100644 index 0000000000..f514fa17b6 --- /dev/null +++ b/interface/src/networking/ClosureEventSender.cpp @@ -0,0 +1,71 @@ +// +// ClosureEventSender.cpp +// interface/src/networking +// +// Created by Stephen Birarda on 5/31/17. +// Copyright 2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "ClosureEventSender.h" + +QNetworkRequest createNetworkRequest() { + + QNetworkRequest request; + + QUrl requestURL = NetworkingConstants::METAVERSE_SERVER_URL; + requestURL.setPath(USER_ACTIVITY_URL); + + request.setUrl(requestURL); + + auto accountManager = DependencyManager::get(); + + if (accountManager->hasValidAccessToken()) { + request.setRawHeader(ACCESS_TOKEN_AUTHORIZATION_HEADER, + accountManager->getAccountInfo().getAccessToken().authorizationHeaderValue()); + } + + request.setRawHeader(METAVERSE_SESSION_ID_HEADER, + uuidStringWithoutCurlyBraces(accountManager->getSessionID()).toLocal8Bit()); + + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); + + return request; +} + +QByteArray postDataForAction(QString action) { + return QString("{\"action\": \"" + action + "\"}").toUtf8(); +} + +QNetworkReply* replyForAction(QString action) { + QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); + return networkAccessManager.post(createNetworkRequest(), postDataForAction(action)); +} + +void ClosureEventSender::sendQuitStart() { + + QNetworkReply* reply = replyForAction("quit_start"); + + QEventLoop loop; + QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit); +} + +void ClosureEventSender::sendQuitFinish() { + QNetworkReply* reply = replyForAction("quit_finish"); + + QEventLoop loop; + QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit); +} diff --git a/interface/src/networking/ClosureEventSender.h b/interface/src/networking/ClosureEventSender.h new file mode 100644 index 0000000000..dc726fc386 --- /dev/null +++ b/interface/src/networking/ClosureEventSender.h @@ -0,0 +1,35 @@ +// +// ClosureEventSender.h +// interface/src/networking +// +// Created by Stephen Birarda on 5/31/17. +// Copyright 2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_ClosureEventSender_h +#define hifi_ClosureEventSender_h + +#include +#include + +#include + +class ClosureEventSender : public Dependency { + SINGLETON_DEPENDENCY + +public: + void setSessionID(QUuid sessionID) { _sessionID = sessionID; } + + void sendQuitStart(); + void sendQuitFinish(); + void sendCrashEvent(); + +private: + QUuid _sessionID; + QString _accessToken; +}; + +#endif // hifi_ClosureEventSender_h diff --git a/libraries/networking/src/AccountManager.cpp b/libraries/networking/src/AccountManager.cpp index 6266ad0f89..2457d0ac42 100644 --- a/libraries/networking/src/AccountManager.cpp +++ b/libraries/networking/src/AccountManager.cpp @@ -45,7 +45,6 @@ Q_DECLARE_METATYPE(QNetworkAccessManager::Operation) Q_DECLARE_METATYPE(JSONCallbackParameters) const QString ACCOUNTS_GROUP = "accounts"; -static const auto METAVERSE_SESSION_ID_HEADER = QString("HFM-SessionID").toLocal8Bit(); JSONCallbackParameters::JSONCallbackParameters(QObject* jsonCallbackReceiver, const QString& jsonCallbackMethod, QObject* errorCallbackReceiver, const QString& errorCallbackMethod, diff --git a/libraries/networking/src/AccountManager.h b/libraries/networking/src/AccountManager.h index dd2216957f..bd452646f6 100644 --- a/libraries/networking/src/AccountManager.h +++ b/libraries/networking/src/AccountManager.h @@ -52,6 +52,7 @@ namespace AccountManagerAuth { Q_DECLARE_METATYPE(AccountManagerAuth::Type); const QByteArray ACCESS_TOKEN_AUTHORIZATION_HEADER = "Authorization"; +const auto METAVERSE_SESSION_ID_HEADER = QString("HFM-SessionID").toLocal8Bit(); using UserAgentGetter = std::function; diff --git a/libraries/networking/src/UserActivityLogger.cpp b/libraries/networking/src/UserActivityLogger.cpp index e2dd110cfd..28117c0933 100644 --- a/libraries/networking/src/UserActivityLogger.cpp +++ b/libraries/networking/src/UserActivityLogger.cpp @@ -20,8 +20,6 @@ #include #include "AddressManager.h" -static const QString USER_ACTIVITY_URL = "/api/v1/user_activities"; - UserActivityLogger& UserActivityLogger::getInstance() { static UserActivityLogger sharedInstance; return sharedInstance; diff --git a/libraries/networking/src/UserActivityLogger.h b/libraries/networking/src/UserActivityLogger.h index b41960a8ad..9fad498b86 100644 --- a/libraries/networking/src/UserActivityLogger.h +++ b/libraries/networking/src/UserActivityLogger.h @@ -22,6 +22,8 @@ #include #include "AddressManager.h" +const QString USER_ACTIVITY_URL = "/api/v1/user_activities"; + class UserActivityLogger : public QObject { Q_OBJECT From 40dfcb1e6e5e8d18f8285d2e52ad14ea3f8cbfc2 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 1 Jun 2017 10:43:47 -0700 Subject: [PATCH 49/73] send quit event during shutdown on thread, with timeout --- interface/src/Application.cpp | 21 +++++++-- interface/src/Application.h | 3 -- interface/src/main.cpp | 8 ---- .../src/networking/ClosureEventSender.cpp | 43 +++++++++++++------ interface/src/networking/ClosureEventSender.h | 22 +++++++--- 5 files changed, 64 insertions(+), 33 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 297ee943fa..a637f9414b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -11,6 +11,8 @@ #include "Application.h" +#include + #include #include #include @@ -1570,9 +1572,13 @@ void Application::aboutToQuit() { getActiveDisplayPlugin()->deactivate(); - // use the ClosureEventSender via an std::thread (to not use QThread while the application is going down) - // to send an event that says the user asked for the app to close - _userQuitThread = std::thread { &ClosureEventSender::sendQuitStart, DependencyManager::get() }; + // use the ClosureEventSender via a QThread to send an event that says the user asked for the app to close + auto closureEventSender = DependencyManager::get(); + QThread* closureEventThread = new QThread(this); + closureEventSender->moveToThread(closureEventThread); + // sendQuitEventAsync will bail immediately if the UserActivityLogger is not enabled + connect(closureEventThread, &QThread::started, closureEventSender.data(), &ClosureEventSender::sendQuitEventAsync); + closureEventThread->start(); // Hide Running Scripts dialog so that it gets destroyed in an orderly manner; prevents warnings at shutdown. DependencyManager::get()->hide("RunningScripts"); @@ -1738,6 +1744,15 @@ Application::~Application() { _window->deleteLater(); + // make sure that the quit event has finished sending before we take the application down + auto closureEventSender = DependencyManager::get(); + while (!closureEventSender->hasFinishedQuitEvent() && !closureEventSender->hasTimedOutQuitEvent()) { + // yield so we're not spinning + std::this_thread::yield(); + } + // quit the thread used by the closure event sender + closureEventSender->thread()->quit(); + // Can't log to file passed this point, FileLogger about to be deleted qInstallMessageHandler(LogHandler::verboseMessageHandler); } diff --git a/interface/src/Application.h b/interface/src/Application.h index 23673399f6..9cf03f1cef 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -13,7 +13,6 @@ #define hifi_Application_h #include -#include #include #include @@ -681,8 +680,6 @@ private: FileScriptingInterface* _fileDownload; AudioInjector* _snapshotSoundInjector { nullptr }; SharedSoundPointer _snapshotSound; - - std::thread _userQuitThread; }; diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 68525dfd1e..63738d2d91 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -24,13 +24,11 @@ #include #include - #include "AddressManager.h" #include "Application.h" #include "InterfaceLogging.h" #include "UserActivityLogger.h" #include "MainWindow.h" -#include "networking/ClosureEventSender.h" #ifdef HAS_BUGSPLAT #include @@ -268,12 +266,6 @@ int main(int argc, const char* argv[]) { Application::shutdownPlugins(); - if (UserActivityLogger::getInstance().isEnabled()) { - // send a quit finished event here to indicate that this session closed cleanly - std::thread quitCompleteThread { &::ClosureEventSender::sendQuitFinish, DependencyManager::get() }; - quitCompleteThread.join(); - } - qCDebug(interfaceapp, "Normal exit."); #if !defined(DEBUG) && !defined(Q_OS_LINUX) // HACK: exit immediately (don't handle shutdown callbacks) for Release build diff --git a/interface/src/networking/ClosureEventSender.cpp b/interface/src/networking/ClosureEventSender.cpp index f514fa17b6..238629b809 100644 --- a/interface/src/networking/ClosureEventSender.cpp +++ b/interface/src/networking/ClosureEventSender.cpp @@ -9,14 +9,15 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include #include #include -#include #include #include #include #include +#include #include #include @@ -43,11 +44,13 @@ QNetworkRequest createNetworkRequest() { request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); + request.setPriority(QNetworkRequest::HighPriority); + return request; } QByteArray postDataForAction(QString action) { - return QString("{\"action\": \"" + action + "\"}").toUtf8(); + return QString("{\"action_name\": \"" + action + "\"}").toUtf8(); } QNetworkReply* replyForAction(QString action) { @@ -55,17 +58,33 @@ QNetworkReply* replyForAction(QString action) { return networkAccessManager.post(createNetworkRequest(), postDataForAction(action)); } -void ClosureEventSender::sendQuitStart() { - - QNetworkReply* reply = replyForAction("quit_start"); - - QEventLoop loop; - QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit); +void ClosureEventSender::sendQuitEventAsync() { + if (UserActivityLogger::getInstance().isEnabled()) { + QNetworkReply* reply = replyForAction("quit"); + connect(reply, &QNetworkReply::finished, this, &ClosureEventSender::handleQuitEventFinished); + _quitEventStartTimestamp = QDateTime::currentMSecsSinceEpoch(); + } else { + _hasFinishedQuitEvent = true; + } } -void ClosureEventSender::sendQuitFinish() { - QNetworkReply* reply = replyForAction("quit_finish"); +void ClosureEventSender::handleQuitEventFinished() { + _hasFinishedQuitEvent = true; - QEventLoop loop; - QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit); + auto reply = qobject_cast(sender()); + if (reply->error() == QNetworkReply::NoError) { + qCDebug(networking) << "Quit event sent successfully"; + } else { + qCDebug(networking) << "Failed to send quit event -" << reply->errorString(); + } + + reply->deleteLater(); } + +bool ClosureEventSender::hasTimedOutQuitEvent() { + const int CLOSURE_EVENT_TIMEOUT_MS = 5000; + return _quitEventStartTimestamp != 0 + && QDateTime::currentMSecsSinceEpoch() - _quitEventStartTimestamp > CLOSURE_EVENT_TIMEOUT_MS; +} + + diff --git a/interface/src/networking/ClosureEventSender.h b/interface/src/networking/ClosureEventSender.h index dc726fc386..be2daca12b 100644 --- a/interface/src/networking/ClosureEventSender.h +++ b/interface/src/networking/ClosureEventSender.h @@ -12,24 +12,32 @@ #ifndef hifi_ClosureEventSender_h #define hifi_ClosureEventSender_h +#include + #include #include #include -class ClosureEventSender : public Dependency { +class ClosureEventSender : public QObject, public Dependency { + Q_OBJECT SINGLETON_DEPENDENCY public: - void setSessionID(QUuid sessionID) { _sessionID = sessionID; } + void sendCrashEventSync(); - void sendQuitStart(); - void sendQuitFinish(); - void sendCrashEvent(); + bool hasTimedOutQuitEvent(); + bool hasFinishedQuitEvent() { return _hasFinishedQuitEvent; } + +public slots: + void sendQuitEventAsync(); + +private slots: + void handleQuitEventFinished(); private: - QUuid _sessionID; - QString _accessToken; + std::atomic _hasFinishedQuitEvent { false }; + std::atomic _quitEventStartTimestamp; }; #endif // hifi_ClosureEventSender_h From ecc697dbe1a467b6448a3b3af77eca645d0de35c Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 1 Jun 2017 13:40:50 -0700 Subject: [PATCH 50/73] remove crash event definition for now --- interface/src/networking/ClosureEventSender.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/interface/src/networking/ClosureEventSender.h b/interface/src/networking/ClosureEventSender.h index be2daca12b..ea07e55c84 100644 --- a/interface/src/networking/ClosureEventSender.h +++ b/interface/src/networking/ClosureEventSender.h @@ -24,8 +24,6 @@ class ClosureEventSender : public QObject, public Dependency { SINGLETON_DEPENDENCY public: - void sendCrashEventSync(); - bool hasTimedOutQuitEvent(); bool hasFinishedQuitEvent() { return _hasFinishedQuitEvent; } From e3d8229abe032dc997522d4b5e7a0784d577acc4 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 1 Jun 2017 17:52:01 -0700 Subject: [PATCH 51/73] rename ClosureEventSender to CloseEventSender --- interface/src/Application.cpp | 18 +++++++++--------- ...ureEventSender.cpp => CloseEventSender.cpp} | 12 ++++++------ ...ClosureEventSender.h => CloseEventSender.h} | 10 +++++----- 3 files changed, 20 insertions(+), 20 deletions(-) rename interface/src/networking/{ClosureEventSender.cpp => CloseEventSender.cpp} (88%) rename interface/src/networking/{ClosureEventSender.h => CloseEventSender.h} (79%) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a637f9414b..41b0bcaf04 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -146,7 +146,7 @@ #include "InterfaceLogging.h" #include "LODManager.h" #include "ModelPackager.h" -#include "networking/ClosureEventSender.h" +#include "networking/CloseEventSender.h" #include "networking/HFWebEngineProfile.h" #include "networking/HFTabletWebEngineProfile.h" #include "networking/FileTypeProfile.h" @@ -537,7 +537,7 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); - DependencyManager::set(); + DependencyManager::set(); return previousSessionCrashed; } @@ -1572,12 +1572,12 @@ void Application::aboutToQuit() { getActiveDisplayPlugin()->deactivate(); - // use the ClosureEventSender via a QThread to send an event that says the user asked for the app to close - auto closureEventSender = DependencyManager::get(); + // use the CloseEventSender via a QThread to send an event that says the user asked for the app to close + auto closeEventSender = DependencyManager::get(); QThread* closureEventThread = new QThread(this); - closureEventSender->moveToThread(closureEventThread); + closeEventSender->moveToThread(closureEventThread); // sendQuitEventAsync will bail immediately if the UserActivityLogger is not enabled - connect(closureEventThread, &QThread::started, closureEventSender.data(), &ClosureEventSender::sendQuitEventAsync); + connect(closureEventThread, &QThread::started, closeEventSender.data(), &CloseEventSender::sendQuitEventAsync); closureEventThread->start(); // Hide Running Scripts dialog so that it gets destroyed in an orderly manner; prevents warnings at shutdown. @@ -1745,13 +1745,13 @@ Application::~Application() { _window->deleteLater(); // make sure that the quit event has finished sending before we take the application down - auto closureEventSender = DependencyManager::get(); - while (!closureEventSender->hasFinishedQuitEvent() && !closureEventSender->hasTimedOutQuitEvent()) { + auto closeEventSender = DependencyManager::get(); + while (!closeEventSender->hasFinishedQuitEvent() && !closeEventSender->hasTimedOutQuitEvent()) { // yield so we're not spinning std::this_thread::yield(); } // quit the thread used by the closure event sender - closureEventSender->thread()->quit(); + closeEventSender->thread()->quit(); // Can't log to file passed this point, FileLogger about to be deleted qInstallMessageHandler(LogHandler::verboseMessageHandler); diff --git a/interface/src/networking/ClosureEventSender.cpp b/interface/src/networking/CloseEventSender.cpp similarity index 88% rename from interface/src/networking/ClosureEventSender.cpp rename to interface/src/networking/CloseEventSender.cpp index 238629b809..8c3d6ae888 100644 --- a/interface/src/networking/ClosureEventSender.cpp +++ b/interface/src/networking/CloseEventSender.cpp @@ -1,5 +1,5 @@ // -// ClosureEventSender.cpp +// CloseEventSender.cpp // interface/src/networking // // Created by Stephen Birarda on 5/31/17. @@ -21,7 +21,7 @@ #include #include -#include "ClosureEventSender.h" +#include "CloseEventSender.h" QNetworkRequest createNetworkRequest() { @@ -58,17 +58,17 @@ QNetworkReply* replyForAction(QString action) { return networkAccessManager.post(createNetworkRequest(), postDataForAction(action)); } -void ClosureEventSender::sendQuitEventAsync() { +void CloseEventSender::sendQuitEventAsync() { if (UserActivityLogger::getInstance().isEnabled()) { QNetworkReply* reply = replyForAction("quit"); - connect(reply, &QNetworkReply::finished, this, &ClosureEventSender::handleQuitEventFinished); + connect(reply, &QNetworkReply::finished, this, &CloseEventSender::handleQuitEventFinished); _quitEventStartTimestamp = QDateTime::currentMSecsSinceEpoch(); } else { _hasFinishedQuitEvent = true; } } -void ClosureEventSender::handleQuitEventFinished() { +void CloseEventSender::handleQuitEventFinished() { _hasFinishedQuitEvent = true; auto reply = qobject_cast(sender()); @@ -81,7 +81,7 @@ void ClosureEventSender::handleQuitEventFinished() { reply->deleteLater(); } -bool ClosureEventSender::hasTimedOutQuitEvent() { +bool CloseEventSender::hasTimedOutQuitEvent() { const int CLOSURE_EVENT_TIMEOUT_MS = 5000; return _quitEventStartTimestamp != 0 && QDateTime::currentMSecsSinceEpoch() - _quitEventStartTimestamp > CLOSURE_EVENT_TIMEOUT_MS; diff --git a/interface/src/networking/ClosureEventSender.h b/interface/src/networking/CloseEventSender.h similarity index 79% rename from interface/src/networking/ClosureEventSender.h rename to interface/src/networking/CloseEventSender.h index ea07e55c84..05e6f81ad4 100644 --- a/interface/src/networking/ClosureEventSender.h +++ b/interface/src/networking/CloseEventSender.h @@ -1,5 +1,5 @@ // -// ClosureEventSender.h +// CloseEventSender.h // interface/src/networking // // Created by Stephen Birarda on 5/31/17. @@ -9,8 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#ifndef hifi_ClosureEventSender_h -#define hifi_ClosureEventSender_h +#ifndef hifi_CloseEventSender_h +#define hifi_CloseEventSender_h #include @@ -19,7 +19,7 @@ #include -class ClosureEventSender : public QObject, public Dependency { +class CloseEventSender : public QObject, public Dependency { Q_OBJECT SINGLETON_DEPENDENCY @@ -38,4 +38,4 @@ private: std::atomic _quitEventStartTimestamp; }; -#endif // hifi_ClosureEventSender_h +#endif // hifi_CloseEventSender_h From d89febac7197d7e840150bc62ef3118167981572 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 1 Jun 2017 17:57:23 -0700 Subject: [PATCH 52/73] use a sleep instead of a yield waiting for close event --- interface/src/Application.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 41b0bcaf04..27c158322d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -11,6 +11,7 @@ #include "Application.h" +#include #include #include @@ -1747,8 +1748,8 @@ Application::~Application() { // make sure that the quit event has finished sending before we take the application down auto closeEventSender = DependencyManager::get(); while (!closeEventSender->hasFinishedQuitEvent() && !closeEventSender->hasTimedOutQuitEvent()) { - // yield so we're not spinning - std::this_thread::yield(); + // sleep a little so we're not spinning at 100% + std::this_thread::sleep_for(std::chrono::milliseconds(10)); } // quit the thread used by the closure event sender closeEventSender->thread()->quit(); From f9e1f028882492fc5a5e9ccc17416660e69cdfb4 Mon Sep 17 00:00:00 2001 From: David Kelly Date: Fri, 2 Jun 2017 14:59:27 -0700 Subject: [PATCH 53/73] protect _text member of Text3DOverlay with mutex --- interface/src/ui/overlays/Text3DOverlay.cpp | 19 +++++++++++++++---- interface/src/ui/overlays/Text3DOverlay.h | 13 +++++++------ 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/interface/src/ui/overlays/Text3DOverlay.cpp b/interface/src/ui/overlays/Text3DOverlay.cpp index 2e2d586abc..d7e4edb197 100644 --- a/interface/src/ui/overlays/Text3DOverlay.cpp +++ b/interface/src/ui/overlays/Text3DOverlay.cpp @@ -23,12 +23,13 @@ const float LINE_SCALE_RATIO = 1.2f; QString const Text3DOverlay::TYPE = "text3d"; -Text3DOverlay::Text3DOverlay() { +Text3DOverlay::Text3DOverlay() : _mutex() { _textRenderer = TextRenderer3D::getInstance(SANS_FONT_FAMILY, FIXED_FONT_POINT_SIZE); _geometryId = DependencyManager::get()->allocateID(); } Text3DOverlay::Text3DOverlay(const Text3DOverlay* text3DOverlay) : + _mutex(), Billboard3DOverlay(text3DOverlay), _text(text3DOverlay->_text), _backgroundColor(text3DOverlay->_backgroundColor), @@ -51,6 +52,16 @@ Text3DOverlay::~Text3DOverlay() { } } +const QString Text3DOverlay::getText() const { + QMutexLocker lock(&_mutex); + return _text; +} + +void Text3DOverlay::setText(const QString& text) { + QMutexLocker lock(&_mutex); + _text = text; +} + xColor Text3DOverlay::getBackgroundColor() { if (_colorPulse == 0.0f) { return _backgroundColor; @@ -125,7 +136,7 @@ void Text3DOverlay::render(RenderArgs* args) { // FIXME: Factor out textRenderer so that Text3DOverlay overlay parts can be grouped by pipeline // for a gpu performance increase. Currently, // Text renderer sets its own pipeline, - _textRenderer->draw(batch, 0, 0, _text, textColor, glm::vec2(-1.0f), getDrawInFront()); + _textRenderer->draw(batch, 0, 0, getText(), textColor, glm::vec2(-1.0f), getDrawInFront()); // so before we continue, we must reset the pipeline batch.setPipeline(args->_pipeline->pipeline); args->_pipeline->prepare(batch); @@ -188,7 +199,7 @@ void Text3DOverlay::setProperties(const QVariantMap& properties) { QVariant Text3DOverlay::getProperty(const QString& property) { if (property == "text") { - return _text; + return getText(); } if (property == "textAlpha") { return _textAlpha; @@ -231,7 +242,7 @@ QSizeF Text3DOverlay::textSize(const QString& text) const { return QSizeF(extents.x, extents.y) * pointToWorldScale; } -bool Text3DOverlay::findRayIntersection(const glm::vec3 &origin, const glm::vec3 &direction, float &distance, +bool Text3DOverlay::findRayIntersection(const glm::vec3 &origin, const glm::vec3 &direction, float &distance, BoxFace &face, glm::vec3& surfaceNormal) { Transform transform = getTransform(); applyTransformTo(transform, true); diff --git a/interface/src/ui/overlays/Text3DOverlay.h b/interface/src/ui/overlays/Text3DOverlay.h index 5ba4fe5939..e7b09c9040 100644 --- a/interface/src/ui/overlays/Text3DOverlay.h +++ b/interface/src/ui/overlays/Text3DOverlay.h @@ -12,14 +12,14 @@ #define hifi_Text3DOverlay_h #include - +#include #include "Billboard3DOverlay.h" class TextRenderer3D; class Text3DOverlay : public Billboard3DOverlay { Q_OBJECT - + public: static QString const TYPE; virtual QString getType() const override { return TYPE; } @@ -34,7 +34,7 @@ public: virtual const render::ShapeKey getShapeKey() override; // getters - const QString& getText() const { return _text; } + const QString getText() const; float getLineHeight() const { return _lineHeight; } float getLeftMargin() const { return _leftMargin; } float getTopMargin() const { return _topMargin; } @@ -45,7 +45,7 @@ public: float getBackgroundAlpha() { return getAlpha(); } // setters - void setText(const QString& text) { _text = text; } + void setText(const QString& text); void setTextAlpha(float alpha) { _textAlpha = alpha; } void setLineHeight(float value) { _lineHeight = value; } void setLeftMargin(float margin) { _leftMargin = margin; } @@ -58,15 +58,16 @@ public: QSizeF textSize(const QString& test) const; // Meters - virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, + virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face, glm::vec3& surfaceNormal) override; virtual Text3DOverlay* createClone() const override; private: TextRenderer3D* _textRenderer = nullptr; - + QString _text; + mutable QMutex _mutex; // used to make get/setText threadsafe, mutable so can be used in const functions xColor _backgroundColor = xColor { 0, 0, 0 }; float _textAlpha { 1.0f }; float _lineHeight { 1.0f }; From 9b34abeb40f200a708285e3f6d8ae76103510ca4 Mon Sep 17 00:00:00 2001 From: David Kelly Date: Fri, 2 Jun 2017 15:43:29 -0700 Subject: [PATCH 54/73] oops initializer order... --- interface/src/ui/overlays/Text3DOverlay.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/ui/overlays/Text3DOverlay.cpp b/interface/src/ui/overlays/Text3DOverlay.cpp index d7e4edb197..9df8d2beb9 100644 --- a/interface/src/ui/overlays/Text3DOverlay.cpp +++ b/interface/src/ui/overlays/Text3DOverlay.cpp @@ -29,9 +29,9 @@ Text3DOverlay::Text3DOverlay() : _mutex() { } Text3DOverlay::Text3DOverlay(const Text3DOverlay* text3DOverlay) : - _mutex(), Billboard3DOverlay(text3DOverlay), _text(text3DOverlay->_text), + _mutex(), _backgroundColor(text3DOverlay->_backgroundColor), _textAlpha(text3DOverlay->_textAlpha), _lineHeight(text3DOverlay->_lineHeight), From 12cbc206d2fc94f87e0df6916f27cf81df6b0a0e Mon Sep 17 00:00:00 2001 From: David Kelly Date: Fri, 2 Jun 2017 15:59:15 -0700 Subject: [PATCH 55/73] cr feedback --- interface/src/ui/overlays/Text3DOverlay.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/interface/src/ui/overlays/Text3DOverlay.cpp b/interface/src/ui/overlays/Text3DOverlay.cpp index 9df8d2beb9..ebc28ca86a 100644 --- a/interface/src/ui/overlays/Text3DOverlay.cpp +++ b/interface/src/ui/overlays/Text3DOverlay.cpp @@ -23,7 +23,7 @@ const float LINE_SCALE_RATIO = 1.2f; QString const Text3DOverlay::TYPE = "text3d"; -Text3DOverlay::Text3DOverlay() : _mutex() { +Text3DOverlay::Text3DOverlay() { _textRenderer = TextRenderer3D::getInstance(SANS_FONT_FAMILY, FIXED_FONT_POINT_SIZE); _geometryId = DependencyManager::get()->allocateID(); } @@ -31,7 +31,6 @@ Text3DOverlay::Text3DOverlay() : _mutex() { Text3DOverlay::Text3DOverlay(const Text3DOverlay* text3DOverlay) : Billboard3DOverlay(text3DOverlay), _text(text3DOverlay->_text), - _mutex(), _backgroundColor(text3DOverlay->_backgroundColor), _textAlpha(text3DOverlay->_textAlpha), _lineHeight(text3DOverlay->_lineHeight), From f70702beb7a63618a515a33a825db2bcec32f5e0 Mon Sep 17 00:00:00 2001 From: samcake Date: Fri, 2 Jun 2017 17:54:41 -0700 Subject: [PATCH 56/73] Introducing debug flags --- .../render-utils/src/StencilMaskPass.cpp | 11 ++++++--- libraries/render-utils/src/StencilMaskPass.h | 24 +++++++++++++++---- .../render-utils/src/ToneMappingEffect.cpp | 1 - 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/libraries/render-utils/src/StencilMaskPass.cpp b/libraries/render-utils/src/StencilMaskPass.cpp index dcd994763f..2374f24211 100644 --- a/libraries/render-utils/src/StencilMaskPass.cpp +++ b/libraries/render-utils/src/StencilMaskPass.cpp @@ -22,6 +22,11 @@ using namespace render; +void PrepareStencil::configure(const Config& config) { + _maskMode = config.maskMode; + _forceDraw = config.forceDraw; +} + model::MeshPointer PrepareStencil::getMesh() { if (!_mesh) { @@ -72,8 +77,8 @@ gpu::PipelinePointer PrepareStencil::getPaintStencilPipeline() { void PrepareStencil::run(const RenderContextPointer& renderContext, const gpu::FramebufferPointer& srcFramebuffer) { RenderArgs* args = renderContext->args; - // Only draw the stencil mask if in HMD mode. - if (args->_displayMode != RenderArgs::STEREO_HMD) { + // Only draw the stencil mask if in HMD mode or not forced. + if (!_forceDraw && (args->_displayMode != RenderArgs::STEREO_HMD)) { return; } @@ -82,7 +87,7 @@ void PrepareStencil::run(const RenderContextPointer& renderContext, const gpu::F batch.setViewportTransform(args->_viewport); - if (false) { + if (_maskMode < 0) { batch.setPipeline(getMeshStencilPipeline()); auto mesh = getMesh(); diff --git a/libraries/render-utils/src/StencilMaskPass.h b/libraries/render-utils/src/StencilMaskPass.h index d7d6ee448b..01601d1ae6 100644 --- a/libraries/render-utils/src/StencilMaskPass.h +++ b/libraries/render-utils/src/StencilMaskPass.h @@ -16,16 +16,28 @@ #include #include +class PrepareStencilConfig : public render::Job::Config { + Q_OBJECT + Q_PROPERTY(int maskMode MEMBER maskMode NOTIFY dirty) + Q_PROPERTY(bool forceDraw MEMBER forceDraw NOTIFY dirty) + +public: + PrepareStencilConfig(bool enabled = true) : JobConfig(enabled) {} + + int maskMode { 0 }; + bool forceDraw { false }; + +signals: + void dirty(); +}; + class PrepareStencil { public: - class Config : public render::JobConfig { - public: - Config(bool enabled = true) : JobConfig(enabled) {} - }; + using Config = PrepareStencilConfig; using JobModel = render::Job::ModelI; - void configure(const Config& config) {} + void configure(const Config& config); void run(const render::RenderContextPointer& renderContext, const gpu::FramebufferPointer& dstFramebuffer); @@ -51,6 +63,8 @@ private: model::MeshPointer _mesh; model::MeshPointer getMesh(); + int _maskMode { 0 }; + bool _forceDraw { false }; }; diff --git a/libraries/render-utils/src/ToneMappingEffect.cpp b/libraries/render-utils/src/ToneMappingEffect.cpp index 7a3d868236..ce41cf16fa 100644 --- a/libraries/render-utils/src/ToneMappingEffect.cpp +++ b/libraries/render-utils/src/ToneMappingEffect.cpp @@ -39,7 +39,6 @@ void ToneMappingEffect::init() { slotBindings.insert(gpu::Shader::Binding(std::string("colorMap"), ToneMappingEffect_LightingMapSlot)); gpu::Shader::makeProgram(*blitProgram, slotBindings); auto blitState = std::make_shared(); - PrepareStencil::testMask(*blitState); blitState->setColorWriteMask(true, true, true, true); _blitLightBuffer = gpu::PipelinePointer(gpu::Pipeline::create(blitProgram, blitState)); } From 52c60b35df8d68c945f86c3d5c281b499c6e9ae6 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 2 Jun 2017 09:50:23 -0700 Subject: [PATCH 57/73] Add startup_sent_to user activity event --- interface/src/Application.cpp | 36 +++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 27c158322d..bf578fb28e 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2404,15 +2404,16 @@ void Application::handleSandboxStatus(QNetworkReply* reply) { // Check HMD use (may be technically available without being in use) bool hasHMD = PluginUtils::isHMDAvailable(); - bool isUsingHMD = hasHMD && hasHandControllers && _displayPlugin->isHmd(); + bool isUsingHMD = _displayPlugin->isHmd(); + bool isUsingHMDAndHandControllers = hasHMD && hasHandControllers && isUsingHMD; Setting::Handle tutorialComplete{ "tutorialComplete", false }; Setting::Handle firstRun{ Settings::firstRun, true }; bool isTutorialComplete = tutorialComplete.get(); - bool shouldGoToTutorial = isUsingHMD && hasTutorialContent && !isTutorialComplete; + bool shouldGoToTutorial = isUsingHMDAndHandControllers && hasTutorialContent && !isTutorialComplete; - qCDebug(interfaceapp) << "HMD:" << hasHMD << ", Hand Controllers: " << hasHandControllers << ", Using HMD: " << isUsingHMD; + qCDebug(interfaceapp) << "HMD:" << hasHMD << ", Hand Controllers: " << hasHandControllers << ", Using HMD: " << isUsingHMDAndHandControllers; qCDebug(interfaceapp) << "Tutorial version:" << contentVersion << ", sufficient:" << hasTutorialContent << ", complete:" << isTutorialComplete << ", should go:" << shouldGoToTutorial; @@ -2426,10 +2427,18 @@ void Application::handleSandboxStatus(QNetworkReply* reply) { const QString TUTORIAL_PATH = "/tutorial_begin"; + static const QString SENT_TO_TUTORIAL = "tutorial"; + static const QString SENT_TO_PREVIOUS_LOCATION = "previous_location"; + static const QString SENT_TO_ENTRY = "entry"; + static const QString SENT_TO_SANDBOX = "sandbox"; + + QString sentTo; + if (shouldGoToTutorial) { if (sandboxIsRunning) { qCDebug(interfaceapp) << "Home sandbox appears to be running, going to Home."; DependencyManager::get()->goToLocalSandbox(TUTORIAL_PATH); + sentTo = SENT_TO_TUTORIAL; } else { qCDebug(interfaceapp) << "Home sandbox does not appear to be running, going to Entry."; if (firstRun.get()) { @@ -2437,8 +2446,10 @@ void Application::handleSandboxStatus(QNetworkReply* reply) { } if (addressLookupString.isEmpty()) { DependencyManager::get()->goToEntry(); + sentTo = SENT_TO_ENTRY; } else { DependencyManager::get()->loadSettings(addressLookupString); + sentTo = SENT_TO_PREVIOUS_LOCATION; } } } else { @@ -2451,23 +2462,40 @@ void Application::handleSandboxStatus(QNetworkReply* reply) { // If this is a first run we short-circuit the address passed in if (isFirstRun) { - if (isUsingHMD) { + if (isUsingHMDAndHandControllers) { if (sandboxIsRunning) { qCDebug(interfaceapp) << "Home sandbox appears to be running, going to Home."; DependencyManager::get()->goToLocalSandbox(); + sentTo = SENT_TO_SANDBOX; } else { qCDebug(interfaceapp) << "Home sandbox does not appear to be running, going to Entry."; DependencyManager::get()->goToEntry(); + sentTo = SENT_TO_ENTRY; } } else { DependencyManager::get()->goToEntry(); + sentTo = SENT_TO_ENTRY; } } else { qCDebug(interfaceapp) << "Not first run... going to" << qPrintable(addressLookupString.isEmpty() ? QString("previous location") : addressLookupString); DependencyManager::get()->loadSettings(addressLookupString); + sentTo = SENT_TO_PREVIOUS_LOCATION; } } + UserActivityLogger::getInstance().logAction("startup_sent_to", { + { "sent_to", sentTo }, + { "sandbox_is_running", sandboxIsRunning }, + { "has_hmd", hasHMD }, + { "has_hand_controllers", hasHandControllers }, + { "is_using_hmd", isUsingHMD }, + { "is_using_hmd_and_hand_controllers", isUsingHMDAndHandControllers }, + { "content_version", contentVersion }, + { "is_tutorial_complete", isTutorialComplete }, + { "has_tutorial_content", hasTutorialContent }, + { "should_go_to_tutorial", shouldGoToTutorial } + }); + _connectionMonitor.init(); // After all of the constructor is completed, then set firstRun to false. From 7da73d0ff11832b66ed8a5e81e0e650391da4ae1 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Fri, 2 Jun 2017 18:01:40 -0700 Subject: [PATCH 58/73] teleport.js should still function on avatars with no feet. --- scripts/system/controllers/teleport.js | 52 ++++++++------------------ 1 file changed, 16 insertions(+), 36 deletions(-) diff --git a/scripts/system/controllers/teleport.js b/scripts/system/controllers/teleport.js index dcbcaeb621..d6248fc6e0 100644 --- a/scripts/system/controllers/teleport.js +++ b/scripts/system/controllers/teleport.js @@ -366,45 +366,25 @@ function Teleporter() { } // related to repositioning the avatar after you teleport +var FOOT_JOINT_NAMES = ["RightToe_End", "RightToeBase", "RightFoot"]; +var DEFAULT_ROOT_TO_FOOT_OFFSET = 0.5; function getAvatarFootOffset() { - var data = getJointData(); - var upperLeg, lowerLeg, foot, toe, toeTop; - data.forEach(function(d) { - var jointName = d.joint; - if (jointName === "RightUpLeg") { - upperLeg = d.translation.y; - } else if (jointName === "RightLeg") { - lowerLeg = d.translation.y; - } else if (jointName === "RightFoot") { - foot = d.translation.y; - } else if (jointName === "RightToeBase") { - toe = d.translation.y; - } else if (jointName === "RightToe_End") { - toeTop = d.translation.y; + // find a valid foot jointIndex + var footJointIndex = -1; + var i, l = FOOT_JOINT_NAMES.length; + for (i = 0; i < l; i++) { + footJointIndex = MyAvatar.getJointIndex(FOOT_JOINT_NAMES[i]); + if (footJointIndex != -1) { + break; } - }); - - var offset = upperLeg + lowerLeg + foot + toe + toeTop; - offset = offset / 100; - return offset; -} - -function getJointData() { - var allJointData = []; - var jointNames = MyAvatar.jointNames; - jointNames.forEach(function(joint, index) { - var translation = MyAvatar.getJointTranslation(index); - var rotation = MyAvatar.getJointRotation(index); - allJointData.push({ - joint: joint, - index: index, - translation: translation, - rotation: rotation - }); - }); - - return allJointData; + } + if (footJointIndex != -1) { + // default vertical offset from foot to avatar root. + return -MyAvatar.getAbsoluteDefaultJointTranslationInObjectFrame(footJointIndex).y; + } else { + return DEFAULT_ROOT_TO_FOOT_OFFSET; + } } var leftPad = new ThumbPad('left'); From d38a396e9d8b67e976646595e20dd856e4460893 Mon Sep 17 00:00:00 2001 From: Sam Cake Date: Sat, 3 Jun 2017 08:59:47 -0700 Subject: [PATCH 59/73] Fixing warning --- libraries/model/src/model/Geometry.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/model/src/model/Geometry.cpp b/libraries/model/src/model/Geometry.cpp index 2525491460..f88c8233ea 100755 --- a/libraries/model/src/model/Geometry.cpp +++ b/libraries/model/src/model/Geometry.cpp @@ -257,7 +257,7 @@ MeshPointer Mesh::createIndexedTriangles_P3F(uint32_t numVertices, uint32_t numI int16_t* shortIndices = nullptr; if (indices) { shortIndicesVector.resize(numIndices); - for (int i = 0; i < numIndices; i++) { + for (uint32_t i = 0; i < numIndices; i++) { shortIndicesVector[i] = indices[i]; } shortIndices = shortIndicesVector.data(); From 024499bdc440acd1112946935244af1b6b5fc79d Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Sun, 4 Jun 2017 12:59:15 -0700 Subject: [PATCH 60/73] Optimized NVTT library with fast gamma conversion --- cmake/externals/nvtt/CMakeLists.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cmake/externals/nvtt/CMakeLists.txt b/cmake/externals/nvtt/CMakeLists.txt index 0e1c240c77..91e63e6324 100644 --- a/cmake/externals/nvtt/CMakeLists.txt +++ b/cmake/externals/nvtt/CMakeLists.txt @@ -8,8 +8,8 @@ string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) if (WIN32) ExternalProject_Add( ${EXTERNAL_NAME} - URL http://s3.amazonaws.com/hifi-public/dependencies/nvtt-win-2.1.0.zip - URL_MD5 3ea6eeadbcc69071acf9c49ba565760e + URL http://s3.amazonaws.com/hifi-public/dependencies/nvtt-win-2.1.0.hifi.zip + URL_MD5 907f2c683e2bcf8b8089576ec38747b4 CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" @@ -29,8 +29,8 @@ else () ExternalProject_Add( ${EXTERNAL_NAME} - URL http://hifi-public.s3.amazonaws.com/dependencies/nvidia-texture-tools-2.1.0.zip - URL_MD5 81b8fa6a9ee3f986088eb6e2215d6a57 + URL http://hifi-public.s3.amazonaws.com/dependencies/nvidia-texture-tools-2.1.0.hifi.zip + URL_MD5 cda96482825225511d3effabbc1ddc7e CONFIGURE_COMMAND CMAKE_ARGS ${ANDROID_CMAKE_ARGS} -DNVTT_SHARED=1 -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH= LOG_DOWNLOAD 1 LOG_CONFIGURE 1 From 347104204e40ff2f2939ea67db3f36f2128f4e51 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 31 May 2017 09:56:39 -0700 Subject: [PATCH 61/73] fix StorageTests on linux --- tests/shared/src/StorageTests.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/tests/shared/src/StorageTests.cpp b/tests/shared/src/StorageTests.cpp index fa538f6911..48e6b91900 100644 --- a/tests/shared/src/StorageTests.cpp +++ b/tests/shared/src/StorageTests.cpp @@ -8,6 +8,8 @@ #include "StorageTests.h" +#include + QTEST_MAIN(StorageTests) using namespace storage; @@ -32,8 +34,8 @@ void StorageTests::testConversion() { QFileInfo fileInfo(_testFile); QCOMPARE(fileInfo.exists(), false); } - StoragePointer storagePointer = std::make_unique(_testData.size(), _testData.data()); - QCOMPARE(storagePointer->size(), (quint64)_testData.size()); + StoragePointer storagePointer = std::unique_ptr(new MemoryStorage(_testData.size(), _testData.data())); + QCOMPARE(storagePointer->size(), _testData.size()); QCOMPARE(memcmp(_testData.data(), storagePointer->data(), _testData.size()), 0); // Convert to a file storagePointer = storagePointer->toFileStorage(_testFile); @@ -42,12 +44,12 @@ void StorageTests::testConversion() { QCOMPARE(fileInfo.exists(), true); QCOMPARE(fileInfo.size(), (qint64)_testData.size()); } - QCOMPARE(storagePointer->size(), (quint64)_testData.size()); + QCOMPARE(storagePointer->size(), _testData.size()); QCOMPARE(memcmp(_testData.data(), storagePointer->data(), _testData.size()), 0); // Convert to memory storagePointer = storagePointer->toMemoryStorage(); - QCOMPARE(storagePointer->size(), (quint64)_testData.size()); + QCOMPARE(storagePointer->size(), _testData.size()); QCOMPARE(memcmp(_testData.data(), storagePointer->data(), _testData.size()), 0); { // ensure the file is unaffected @@ -58,13 +60,13 @@ void StorageTests::testConversion() { // truncate the data as a new memory object auto newSize = _testData.size() / 2; - storagePointer = std::make_unique(newSize, storagePointer->data()); - QCOMPARE(storagePointer->size(), (quint64)newSize); + storagePointer = std::unique_ptr(new MemoryStorage(newSize, storagePointer->data())); + QCOMPARE(storagePointer->size(), newSize); QCOMPARE(memcmp(_testData.data(), storagePointer->data(), newSize), 0); // Convert back to file storagePointer = storagePointer->toFileStorage(_testFile); - QCOMPARE(storagePointer->size(), (quint64)newSize); + QCOMPARE(storagePointer->size(), newSize); QCOMPARE(memcmp(_testData.data(), storagePointer->data(), newSize), 0); { // ensure the file is truncated From 81764f0f7165167480804decfe93062dd4d97683 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 31 May 2017 09:57:54 -0700 Subject: [PATCH 62/73] fix GLMHelpers::generateBasisVectors() --- libraries/shared/src/GLMHelpers.cpp | 42 ++++++++++++++--------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/libraries/shared/src/GLMHelpers.cpp b/libraries/shared/src/GLMHelpers.cpp index 70237e8ff6..10c73d6c6a 100644 --- a/libraries/shared/src/GLMHelpers.cpp +++ b/libraries/shared/src/GLMHelpers.cpp @@ -49,7 +49,7 @@ const mat4 Matrices::Z_180 { createMatFromQuatAndPos(Quaternions::Z_180, Vectors glm::quat safeMix(const glm::quat& q1, const glm::quat& q2, float proportion) { float cosa = q1.x * q2.x + q1.y * q2.y + q1.z * q2.z + q1.w * q2.w; float ox = q2.x, oy = q2.y, oz = q2.z, ow = q2.w, s0, s1; - + // adjust signs if necessary if (cosa < 0.0f) { cosa = -cosa; @@ -58,19 +58,19 @@ glm::quat safeMix(const glm::quat& q1, const glm::quat& q2, float proportion) { oz = -oz; ow = -ow; } - + // calculate coefficients; if the angle is too close to zero, we must fall back // to linear interpolation if ((1.0f - cosa) > EPSILON) { float angle = acosf(cosa), sina = sinf(angle); s0 = sinf((1.0f - proportion) * angle) / sina; s1 = sinf(proportion * angle) / sina; - + } else { s0 = 1.0f - proportion; s1 = proportion; } - + return glm::normalize(glm::quat(s0 * q1.w + s1 * ow, s0 * q1.x + s1 * ox, s0 * q1.y + s1 * oy, s0 * q1.z + s1 * oz)); } @@ -105,10 +105,10 @@ int unpackFloatVec3FromSignedTwoByteFixed(const unsigned char* sourceBuffer, glm int packFloatAngleToTwoByte(unsigned char* buffer, float degrees) { const float ANGLE_CONVERSION_RATIO = (std::numeric_limits::max() / 360.0f); - + uint16_t angleHolder = floorf((degrees + 180.0f) * ANGLE_CONVERSION_RATIO); memcpy(buffer, &angleHolder, sizeof(uint16_t)); - + return sizeof(uint16_t); } @@ -125,7 +125,7 @@ int packOrientationQuatToBytes(unsigned char* buffer, const glm::quat& quatInput quatParts[1] = floorf((quatNormalized.y + 1.0f) * QUAT_PART_CONVERSION_RATIO); quatParts[2] = floorf((quatNormalized.z + 1.0f) * QUAT_PART_CONVERSION_RATIO); quatParts[3] = floorf((quatNormalized.w + 1.0f) * QUAT_PART_CONVERSION_RATIO); - + memcpy(buffer, &quatParts, sizeof(quatParts)); return sizeof(quatParts); } @@ -133,12 +133,12 @@ int packOrientationQuatToBytes(unsigned char* buffer, const glm::quat& quatInput int unpackOrientationQuatFromBytes(const unsigned char* buffer, glm::quat& quatOutput) { uint16_t quatParts[4]; memcpy(&quatParts, buffer, sizeof(quatParts)); - + quatOutput.x = ((quatParts[0] / (float) std::numeric_limits::max()) * 2.0f) - 1.0f; quatOutput.y = ((quatParts[1] / (float) std::numeric_limits::max()) * 2.0f) - 1.0f; quatOutput.z = ((quatParts[2] / (float) std::numeric_limits::max()) * 2.0f) - 1.0f; quatOutput.w = ((quatParts[3] / (float) std::numeric_limits::max()) * 2.0f) - 1.0f; - + return sizeof(quatParts); } @@ -235,7 +235,7 @@ glm::vec3 safeEulerAngles(const glm::quat& q) { atan2f(q.y * q.z + q.x * q.w, 0.5f - (q.x * q.x + q.y * q.y)), asinf(sy), atan2f(q.x * q.y + q.z * q.w, 0.5f - (q.y * q.y + q.z * q.z))); - + } else { // not a unique solution; x + z = atan2(-m21, m11) eulers = glm::vec3( @@ -250,7 +250,7 @@ glm::vec3 safeEulerAngles(const glm::quat& q) { PI_OVER_TWO, -atan2f(q.x * q.w - q.y * q.z, 0.5f - (q.x * q.x + q.z * q.z))); } - + // adjust so that z, rather than y, is in [-pi/2, pi/2] if (eulers.z < -PI_OVER_TWO) { if (eulers.x < 0.0f) { @@ -265,7 +265,7 @@ glm::vec3 safeEulerAngles(const glm::quat& q) { eulers.y -= PI; } eulers.z += PI; - + } else if (eulers.z > PI_OVER_TWO) { if (eulers.x < 0.0f) { eulers.x += PI; @@ -320,7 +320,7 @@ glm::quat extractRotation(const glm::mat4& matrix, bool assumeOrthogonal) { for (int i = 0; i < 10; i++) { // store the results of the previous iteration glm::mat3 previous = upper; - + // compute average of the matrix with its inverse transpose float sd00 = previous[1][1] * previous[2][2] - previous[2][1] * previous[1][2]; float sd10 = previous[0][1] * previous[2][2] - previous[2][1] * previous[0][2]; @@ -334,15 +334,15 @@ glm::quat extractRotation(const glm::mat4& matrix, bool assumeOrthogonal) { upper[0][0] = +sd00 * hrdet + previous[0][0] * 0.5f; upper[1][0] = -sd10 * hrdet + previous[1][0] * 0.5f; upper[2][0] = +sd20 * hrdet + previous[2][0] * 0.5f; - + upper[0][1] = -(previous[1][0] * previous[2][2] - previous[2][0] * previous[1][2]) * hrdet + previous[0][1] * 0.5f; upper[1][1] = +(previous[0][0] * previous[2][2] - previous[2][0] * previous[0][2]) * hrdet + previous[1][1] * 0.5f; upper[2][1] = -(previous[0][0] * previous[1][2] - previous[1][0] * previous[0][2]) * hrdet + previous[2][1] * 0.5f; - + upper[0][2] = +(previous[1][0] * previous[2][1] - previous[2][0] * previous[1][1]) * hrdet + previous[0][2] * 0.5f; upper[1][2] = -(previous[0][0] * previous[2][1] - previous[2][0] * previous[0][1]) * hrdet + previous[1][2] * 0.5f; upper[2][2] = +(previous[0][0] * previous[1][1] - previous[1][0] * previous[0][1]) * hrdet + previous[2][2] * 0.5f; - + // compute the difference; if it's small enough, we're done glm::mat3 diff = upper - previous; if (diff[0][0] * diff[0][0] + diff[1][0] * diff[1][0] + diff[2][0] * diff[2][0] + diff[0][1] * diff[0][1] + @@ -352,7 +352,7 @@ glm::quat extractRotation(const glm::mat4& matrix, bool assumeOrthogonal) { } } } - + // now that we have a nice orthogonal matrix, we can extract the rotation quaternion // using the method described in http://en.wikipedia.org/wiki/Rotation_matrix#Conversions float x2 = fabs(1.0f + upper[0][0] - upper[1][1] - upper[2][2]); @@ -473,7 +473,7 @@ glm::mat4 createMatFromScaleQuatAndPos(const glm::vec3& scale, const glm::quat& glm::vec4(zAxis, 0.0f), glm::vec4(trans, 1.0f)); } -// cancel out roll +// cancel out roll glm::quat cancelOutRoll(const glm::quat& q) { glm::vec3 forward = q * Vectors::FRONT; return glm::quat_cast(glm::inverse(glm::lookAt(Vectors::ZERO, forward, Vectors::UP))); @@ -540,15 +540,15 @@ void generateBasisVectors(const glm::vec3& primaryAxis, const glm::vec3& seconda // if secondaryAxis is parallel with the primaryAxis, pick another axis. const float EPSILON = 1.0e-4f; - if (fabsf(fabsf(glm::dot(uAxisOut, secondaryAxis)) - 1.0f) > EPSILON) { + if (fabsf(fabsf(glm::dot(uAxisOut, secondaryAxis)) - 1.0f) < EPSILON) { // pick a better secondaryAxis. normSecondary = glm::vec3(1.0f, 0.0f, 0.0f); - if (fabsf(fabsf(glm::dot(uAxisOut, secondaryAxis)) - 1.0f) > EPSILON) { + if (fabsf(fabsf(glm::dot(uAxisOut, secondaryAxis)) - 1.0f) < EPSILON) { normSecondary = glm::vec3(0.0f, 1.0f, 0.0f); } } - wAxisOut = glm::normalize(glm::cross(uAxisOut, secondaryAxis)); + wAxisOut = glm::normalize(glm::cross(uAxisOut, normSecondary)); vAxisOut = glm::cross(wAxisOut, uAxisOut); } From 1621d31a8e38b3ea72e8972bd9b27fcea9e5cfee Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 31 May 2017 09:58:58 -0700 Subject: [PATCH 63/73] cleanup usage of GLMHelpers::generateBasisVectors() --- libraries/animation/src/Rig.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index add3a461af..4a22aa1df1 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1137,7 +1137,7 @@ void Rig::updateEyeJoint(int index, const glm::vec3& modelTranslation, const glm glm::vec3 headUp = headQuat * Vectors::UNIT_Y; glm::vec3 z, y, x; generateBasisVectors(lookAtVector, headUp, z, y, x); - glm::mat3 m(glm::cross(y, z), y, z); + glm::mat3 m(-x, y, z); glm::quat desiredQuat = glm::normalize(glm::quat_cast(m)); glm::quat deltaQuat = desiredQuat * glm::inverse(headQuat); From 506f522802245d2421c21030b7e1217c384f02a0 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 31 May 2017 09:59:14 -0700 Subject: [PATCH 64/73] use correct format for float literals --- libraries/render-utils/src/AnimDebugDraw.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/render-utils/src/AnimDebugDraw.cpp b/libraries/render-utils/src/AnimDebugDraw.cpp index 162745e76f..4f7f9ef5c4 100644 --- a/libraries/render-utils/src/AnimDebugDraw.cpp +++ b/libraries/render-utils/src/AnimDebugDraw.cpp @@ -260,7 +260,7 @@ static void addLink(const AnimPose& rootPose, const AnimPose& pose, const AnimPo // there is room, so lets draw a nice bone glm::vec3 uAxis, vAxis, wAxis; - generateBasisVectors(boneAxis0, glm::vec3(1, 0, 0), uAxis, vAxis, wAxis); + generateBasisVectors(boneAxis0, glm::vec3(1.0f, 0.0f, 0.0f), uAxis, vAxis, wAxis); glm::vec3 boneBaseCorners[NUM_BASE_CORNERS]; boneBaseCorners[0] = pose0 * ((uAxis * radius) + (vAxis * radius) + (wAxis * radius)); From 205e5d730927a3852cf914bcedfcc94e3f4549c2 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 31 May 2017 11:24:36 -0700 Subject: [PATCH 65/73] add unit tests and fix final bugs --- libraries/shared/src/GLMHelpers.cpp | 7 ++- tests/shared/src/GLMHelpersTests.cpp | 74 ++++++++++++++++++++++++++++ tests/shared/src/GLMHelpersTests.h | 1 + 3 files changed, 78 insertions(+), 4 deletions(-) diff --git a/libraries/shared/src/GLMHelpers.cpp b/libraries/shared/src/GLMHelpers.cpp index 10c73d6c6a..7ebaa11da6 100644 --- a/libraries/shared/src/GLMHelpers.cpp +++ b/libraries/shared/src/GLMHelpers.cpp @@ -538,12 +538,11 @@ void generateBasisVectors(const glm::vec3& primaryAxis, const glm::vec3& seconda uAxisOut = glm::normalize(primaryAxis); glm::vec3 normSecondary = glm::normalize(secondaryAxis); - // if secondaryAxis is parallel with the primaryAxis, pick another axis. + // if normSecondary is parallel with the primaryAxis, pick another secondary. const float EPSILON = 1.0e-4f; - if (fabsf(fabsf(glm::dot(uAxisOut, secondaryAxis)) - 1.0f) < EPSILON) { - // pick a better secondaryAxis. + if (fabsf(fabsf(glm::dot(uAxisOut, normSecondary)) - 1.0f) < EPSILON) { normSecondary = glm::vec3(1.0f, 0.0f, 0.0f); - if (fabsf(fabsf(glm::dot(uAxisOut, secondaryAxis)) - 1.0f) < EPSILON) { + if (fabsf(fabsf(glm::dot(uAxisOut, normSecondary)) - 1.0f) < EPSILON) { normSecondary = glm::vec3(0.0f, 1.0f, 0.0f); } } diff --git a/tests/shared/src/GLMHelpersTests.cpp b/tests/shared/src/GLMHelpersTests.cpp index b4af4729a3..83a294ee1d 100644 --- a/tests/shared/src/GLMHelpersTests.cpp +++ b/tests/shared/src/GLMHelpersTests.cpp @@ -140,3 +140,77 @@ void GLMHelpersTests::testSimd() { } qDebug() << "Done "; } + +void GLMHelpersTests::testGenerateBasisVectors() { + { // very simple case: primary along X, secondary is linear combination of X and Y + glm::vec3 u(1.0f, 0.0f, 0.0f); + glm::vec3 v(1.0f, 1.0f, 0.0f); + glm::vec3 w; + + generateBasisVectors(u, v, u, v, w); + + QCOMPARE_WITH_ABS_ERROR(u, Vectors::UNIT_X, EPSILON); + QCOMPARE_WITH_ABS_ERROR(v, Vectors::UNIT_Y, EPSILON); + QCOMPARE_WITH_ABS_ERROR(w, Vectors::UNIT_Z, EPSILON); + } + + { // point primary along Y instead of X + glm::vec3 u(0.0f, 1.0f, 0.0f); + glm::vec3 v(1.0f, 1.0f, 0.0f); + glm::vec3 w; + + generateBasisVectors(u, v, u, v, w); + + QCOMPARE_WITH_ABS_ERROR(u, Vectors::UNIT_Y, EPSILON); + QCOMPARE_WITH_ABS_ERROR(v, Vectors::UNIT_X, EPSILON); + QCOMPARE_WITH_ABS_ERROR(w, -Vectors::UNIT_Z, EPSILON); + } + + { // pass bad data (both vectors along Y). The helper will guess X for secondary. + glm::vec3 u(0.0f, 1.0f, 0.0f); + glm::vec3 v(0.0f, 1.0f, 0.0f); + glm::vec3 w; + + generateBasisVectors(u, v, u, v, w); + + QCOMPARE_WITH_ABS_ERROR(u, Vectors::UNIT_Y, EPSILON); + QCOMPARE_WITH_ABS_ERROR(v, Vectors::UNIT_X, EPSILON); + QCOMPARE_WITH_ABS_ERROR(w, -Vectors::UNIT_Z, EPSILON); + } + + { // pass bad data (both vectors along X). The helper will guess X for secondary, fail, then guess Y. + glm::vec3 u(1.0f, 0.0f, 0.0f); + glm::vec3 v(1.0f, 0.0f, 0.0f); + glm::vec3 w; + + generateBasisVectors(u, v, u, v, w); + + QCOMPARE_WITH_ABS_ERROR(u, Vectors::UNIT_X, EPSILON); + QCOMPARE_WITH_ABS_ERROR(v, Vectors::UNIT_Y, EPSILON); + QCOMPARE_WITH_ABS_ERROR(w, Vectors::UNIT_Z, EPSILON); + } + + { // general case for arbitrary rotation + float angle = 1.234f; + glm::vec3 axis = glm::normalize(glm::vec3(1.0f, 2.0f, 3.0f)); + glm::quat rotation = glm::angleAxis(angle, axis); + + // expected values + glm::vec3 x = rotation * Vectors::UNIT_X; + glm::vec3 y = rotation * Vectors::UNIT_Y; + glm::vec3 z = rotation * Vectors::UNIT_Z; + + // primary is along x + // secondary is linear combination of x and y + // tertiary is unknown + glm::vec3 u = 1.23f * x; + glm::vec3 v = 2.34f * x + 3.45f * y; + glm::vec3 w; + + generateBasisVectors(u, v, u, v, w); + + QCOMPARE_WITH_ABS_ERROR(u, x, EPSILON); + QCOMPARE_WITH_ABS_ERROR(v, y, EPSILON); + QCOMPARE_WITH_ABS_ERROR(w, z, EPSILON); + } +} diff --git a/tests/shared/src/GLMHelpersTests.h b/tests/shared/src/GLMHelpersTests.h index acc7b533f5..030f2d477f 100644 --- a/tests/shared/src/GLMHelpersTests.h +++ b/tests/shared/src/GLMHelpersTests.h @@ -21,6 +21,7 @@ private slots: void testEulerDecomposition(); void testSixByteOrientationCompression(); void testSimd(); + void testGenerateBasisVectors(); }; float getErrorDifference(const float& a, const float& b); From 6970576bb8e8fd8b6a95cb0aa672f5e1ef2e2982 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 31 May 2017 11:51:35 -0700 Subject: [PATCH 66/73] use helper constants in helper code --- libraries/shared/src/GLMHelpers.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/shared/src/GLMHelpers.cpp b/libraries/shared/src/GLMHelpers.cpp index 7ebaa11da6..394517aac4 100644 --- a/libraries/shared/src/GLMHelpers.cpp +++ b/libraries/shared/src/GLMHelpers.cpp @@ -541,9 +541,9 @@ void generateBasisVectors(const glm::vec3& primaryAxis, const glm::vec3& seconda // if normSecondary is parallel with the primaryAxis, pick another secondary. const float EPSILON = 1.0e-4f; if (fabsf(fabsf(glm::dot(uAxisOut, normSecondary)) - 1.0f) < EPSILON) { - normSecondary = glm::vec3(1.0f, 0.0f, 0.0f); + normSecondary = Vectors::UNIT_X; if (fabsf(fabsf(glm::dot(uAxisOut, normSecondary)) - 1.0f) < EPSILON) { - normSecondary = glm::vec3(0.0f, 1.0f, 0.0f); + normSecondary = Vectors::UNIT_Y; } } From 793ed1313d7b83c87248d529f38c6da77e1883e5 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 5 Jun 2017 10:30:52 -0700 Subject: [PATCH 67/73] change variable name for more readable code --- libraries/animation/src/Rig.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 4a22aa1df1..2d37213c7a 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1135,9 +1135,9 @@ void Rig::updateEyeJoint(int index, const glm::vec3& modelTranslation, const glm } glm::vec3 headUp = headQuat * Vectors::UNIT_Y; - glm::vec3 z, y, x; - generateBasisVectors(lookAtVector, headUp, z, y, x); - glm::mat3 m(-x, y, z); + glm::vec3 z, y, zCrossY; + generateBasisVectors(lookAtVector, headUp, z, y, zCrossY); + glm::mat3 m(-zCrossY, y, z); glm::quat desiredQuat = glm::normalize(glm::quat_cast(m)); glm::quat deltaQuat = desiredQuat * glm::inverse(headQuat); From 45db8c3befd31102e98069127b7df4a4985e1ebc Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Mon, 5 Jun 2017 11:18:54 -0700 Subject: [PATCH 68/73] Rebase optimizations on NVTT 2.1.0 instead of master --- cmake/externals/nvtt/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/externals/nvtt/CMakeLists.txt b/cmake/externals/nvtt/CMakeLists.txt index 91e63e6324..fa9d7b5ea1 100644 --- a/cmake/externals/nvtt/CMakeLists.txt +++ b/cmake/externals/nvtt/CMakeLists.txt @@ -9,7 +9,7 @@ if (WIN32) ExternalProject_Add( ${EXTERNAL_NAME} URL http://s3.amazonaws.com/hifi-public/dependencies/nvtt-win-2.1.0.hifi.zip - URL_MD5 907f2c683e2bcf8b8089576ec38747b4 + URL_MD5 10da01cf601f88f6dc12a6bc13c89136 CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" @@ -30,7 +30,7 @@ else () ExternalProject_Add( ${EXTERNAL_NAME} URL http://hifi-public.s3.amazonaws.com/dependencies/nvidia-texture-tools-2.1.0.hifi.zip - URL_MD5 cda96482825225511d3effabbc1ddc7e + URL_MD5 5794b950f8b265a9a41b2839b3bf7ebb CONFIGURE_COMMAND CMAKE_ARGS ${ANDROID_CMAKE_ARGS} -DNVTT_SHARED=1 -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH= LOG_DOWNLOAD 1 LOG_CONFIGURE 1 From 995fe11c05437f54e9a3eed78e809ac3dbb060c0 Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Mon, 5 Jun 2017 14:03:20 -0700 Subject: [PATCH 69/73] Migrate to single QML engine --- interface/resources/qml/Browser.qml | 6 +- interface/resources/qml/TabletBrowser.qml | 6 +- .../qml/controls-uit/BaseWebView.qml | 3 - .../qml/controls/TabletWebScreen.qml | 6 +- .../resources/qml/controls/TabletWebView.qml | 6 +- .../resources/qml/controls/WebEntityView.qml | 6 +- interface/resources/qml/controls/WebView.qml | 6 +- interface/resources/qml/hifi/Desktop.qml | 6 - .../resources/qml/hifi/tablet/EditTabView.qml | 1 - .../resources/qml/hifi/tablet/TabletMenu.qml | 1 - .../resources/qml/hifi/tablet/TabletRoot.qml | 1 - interface/src/Application.cpp | 120 ++++++------- interface/src/ui/overlays/Web3DOverlay.cpp | 63 ++++--- .../src/RenderableWebEntityItem.cpp | 8 +- libraries/gl/CMakeLists.txt | 2 +- libraries/gl/src/gl/OffscreenQmlSurface.cpp | 163 ++++++++++++------ libraries/gl/src/gl/OffscreenQmlSurface.h | 5 +- .../gl/src/gl/OffscreenQmlSurfaceCache.cpp | 1 - libraries/networking/CMakeLists.txt | 2 +- .../networking/src}/FileTypeProfile.cpp | 0 .../networking/src}/FileTypeProfile.h | 0 .../src}/FileTypeRequestInterceptor.cpp | 0 .../src}/FileTypeRequestInterceptor.h | 0 .../src}/HFTabletWebEngineProfile.cpp | 1 + .../src}/HFTabletWebEngineProfile.h | 0 .../HFTabletWebEngineRequestInterceptor.cpp | 2 +- .../HFTabletWebEngineRequestInterceptor.h | 0 .../networking/src}/HFWebEngineProfile.cpp | 1 + .../networking/src}/HFWebEngineProfile.h | 0 .../src}/HFWebEngineRequestInterceptor.cpp | 2 +- .../src}/HFWebEngineRequestInterceptor.h | 0 .../networking/src}/RequestFilters.cpp | 2 +- .../networking/src}/RequestFilters.h | 0 libraries/ui/src/OffscreenUi.cpp | 16 +- libraries/ui/src/VrMenu.cpp | 2 +- 35 files changed, 223 insertions(+), 215 deletions(-) rename {interface/src/networking => libraries/networking/src}/FileTypeProfile.cpp (100%) rename {interface/src/networking => libraries/networking/src}/FileTypeProfile.h (100%) rename {interface/src/networking => libraries/networking/src}/FileTypeRequestInterceptor.cpp (100%) rename {interface/src/networking => libraries/networking/src}/FileTypeRequestInterceptor.h (100%) rename {interface/src/networking => libraries/networking/src}/HFTabletWebEngineProfile.cpp (95%) rename {interface/src/networking => libraries/networking/src}/HFTabletWebEngineProfile.h (100%) rename {interface/src/networking => libraries/networking/src}/HFTabletWebEngineRequestInterceptor.cpp (98%) rename {interface/src/networking => libraries/networking/src}/HFTabletWebEngineRequestInterceptor.h (100%) rename {interface/src/networking => libraries/networking/src}/HFWebEngineProfile.cpp (94%) rename {interface/src/networking => libraries/networking/src}/HFWebEngineProfile.h (100%) rename {interface/src/networking => libraries/networking/src}/HFWebEngineRequestInterceptor.cpp (95%) rename {interface/src/networking => libraries/networking/src}/HFWebEngineRequestInterceptor.h (100%) rename {interface/src/networking => libraries/networking/src}/RequestFilters.cpp (98%) rename {interface/src/networking => libraries/networking/src}/RequestFilters.h (100%) diff --git a/interface/resources/qml/Browser.qml b/interface/resources/qml/Browser.qml index 47fb610469..4f7639dd0e 100644 --- a/interface/resources/qml/Browser.qml +++ b/interface/resources/qml/Browser.qml @@ -2,7 +2,6 @@ import QtQuick 2.5 import QtQuick.Controls 1.2 import QtWebChannel 1.0 import QtWebEngine 1.2 -import FileTypeProfile 1.0 import "controls-uit" import "styles" as HifiStyles @@ -209,6 +208,7 @@ ScrollingWindow { WebView { id: webview url: "https://highfidelity.com/" + profile: FileTypeProfile; property alias eventBridgeWrapper: eventBridgeWrapper @@ -218,10 +218,6 @@ ScrollingWindow { property var eventBridge; } - profile: FileTypeProfile { - id: webviewProfile - storageName: "qmlWebEngine" - } webChannel.registeredObjects: [eventBridgeWrapper] diff --git a/interface/resources/qml/TabletBrowser.qml b/interface/resources/qml/TabletBrowser.qml index ee4d05a701..d89aa8626f 100644 --- a/interface/resources/qml/TabletBrowser.qml +++ b/interface/resources/qml/TabletBrowser.qml @@ -8,7 +8,6 @@ import "controls-uit" as HifiControls import "styles" as HifiStyles import "styles-uit" import "windows" -import HFTabletWebEngineProfile 1.0 Item { id: root @@ -47,10 +46,7 @@ Item { width: parent.width height: keyboardEnabled && keyboardRaised ? parent.height - keyboard.height : parent.height - profile: HFTabletWebEngineProfile { - id: webviewTabletProfile - storageName: "qmlTabletWebEngine" - } + profile: HFTabletWebEngineProfile; property string userScriptUrl: "" diff --git a/interface/resources/qml/controls-uit/BaseWebView.qml b/interface/resources/qml/controls-uit/BaseWebView.qml index 670aea71aa..3ca57f03bf 100644 --- a/interface/resources/qml/controls-uit/BaseWebView.qml +++ b/interface/resources/qml/controls-uit/BaseWebView.qml @@ -10,13 +10,10 @@ import QtQuick 2.5 import QtWebEngine 1.2 -import HFWebEngineProfile 1.0 WebEngineView { id: root - // profile: desktop.browserProfile - Component.onCompleted: { console.log("Connecting JS messaging to Hifi Logging") // Ensure the JS from the web-engine makes it to our logging diff --git a/interface/resources/qml/controls/TabletWebScreen.qml b/interface/resources/qml/controls/TabletWebScreen.qml index 93ded724a1..0b265f6fbb 100644 --- a/interface/resources/qml/controls/TabletWebScreen.qml +++ b/interface/resources/qml/controls/TabletWebScreen.qml @@ -2,7 +2,6 @@ import QtQuick 2.5 import QtWebEngine 1.1 import QtWebChannel 1.0 import "../controls-uit" as HiFiControls -import HFTabletWebEngineProfile 1.0 Item { property alias url: root.url @@ -39,10 +38,7 @@ Item { width: parent.width height: keyboardEnabled && keyboardRaised ? parent.height - keyboard.height : parent.height - profile: HFTabletWebEngineProfile { - id: webviewProfile - storageName: "qmlTabletWebEngine" - } + profile: HFTabletWebEngineProfile; property string userScriptUrl: "" diff --git a/interface/resources/qml/controls/TabletWebView.qml b/interface/resources/qml/controls/TabletWebView.qml index 215ac68ac0..3b23cbc19e 100644 --- a/interface/resources/qml/controls/TabletWebView.qml +++ b/interface/resources/qml/controls/TabletWebView.qml @@ -2,7 +2,6 @@ import QtQuick 2.5 import QtQuick.Controls 1.4 import QtWebEngine 1.2 import QtWebChannel 1.0 -import HFTabletWebEngineProfile 1.0 import "../controls-uit" as HiFiControls import "../styles" as HifiStyles import "../styles-uit" @@ -150,10 +149,7 @@ Item { width: parent.width height: keyboardEnabled && keyboardRaised ? parent.height - keyboard.height - web.headerHeight : parent.height - web.headerHeight anchors.top: buttons.bottom - profile: HFTabletWebEngineProfile { - id: webviewTabletProfile - storageName: "qmlTabletWebEngine" - } + profile: HFTabletWebEngineProfile; property string userScriptUrl: "" diff --git a/interface/resources/qml/controls/WebEntityView.qml b/interface/resources/qml/controls/WebEntityView.qml index a3d5fe903b..3bd6aad053 100644 --- a/interface/resources/qml/controls/WebEntityView.qml +++ b/interface/resources/qml/controls/WebEntityView.qml @@ -10,13 +10,9 @@ import QtQuick 2.5 import "." -import FileTypeProfile 1.0 WebView { - viewProfile: FileTypeProfile { - id: webviewProfile - storageName: "qmlWebEngine" - } + viewProfile: FileTypeProfile; urlTag: "noDownload=true"; } diff --git a/interface/resources/qml/controls/WebView.qml b/interface/resources/qml/controls/WebView.qml index 06766fa6ef..d08562eea3 100644 --- a/interface/resources/qml/controls/WebView.qml +++ b/interface/resources/qml/controls/WebView.qml @@ -2,7 +2,6 @@ import QtQuick 2.5 import QtWebEngine 1.1 import QtWebChannel 1.0 import "../controls-uit" as HiFiControls -import HFWebEngineProfile 1.0 Item { property alias url: root.url @@ -39,10 +38,7 @@ Item { width: parent.width height: keyboardEnabled && keyboardRaised ? parent.height - keyboard.height : parent.height - profile: HFWebEngineProfile { - id: webviewProfile - storageName: "qmlWebEngine" - } + profile: HFWebEngineProfile; property string userScriptUrl: "" diff --git a/interface/resources/qml/hifi/Desktop.qml b/interface/resources/qml/hifi/Desktop.qml index 7857eda3c2..ea9ec2f6c9 100644 --- a/interface/resources/qml/hifi/Desktop.qml +++ b/interface/resources/qml/hifi/Desktop.qml @@ -2,7 +2,6 @@ import QtQuick 2.5 import QtQuick.Controls 1.4 import QtWebEngine 1.1; import Qt.labs.settings 1.0 -import HFWebEngineProfile 1.0 import "../desktop" as OriginalDesktop import ".." @@ -27,11 +26,6 @@ OriginalDesktop.Desktop { property alias toolWindow: toolWindow ToolWindow { id: toolWindow } - property var browserProfile: HFWebEngineProfile { - id: webviewProfile - storageName: "qmlWebEngine" - } - Action { text: "Open Browser" shortcut: "Ctrl+B" diff --git a/interface/resources/qml/hifi/tablet/EditTabView.qml b/interface/resources/qml/hifi/tablet/EditTabView.qml index 35f2b82f0f..d084f1c7b3 100644 --- a/interface/resources/qml/hifi/tablet/EditTabView.qml +++ b/interface/resources/qml/hifi/tablet/EditTabView.qml @@ -5,7 +5,6 @@ import QtWebChannel 1.0 import QtQuick.Controls.Styles 1.4 import "../../controls" import "../toolbars" -import HFWebEngineProfile 1.0 import QtGraphicalEffects 1.0 import "../../controls-uit" as HifiControls import "../../styles-uit" diff --git a/interface/resources/qml/hifi/tablet/TabletMenu.qml b/interface/resources/qml/hifi/tablet/TabletMenu.qml index af36f72c82..62b61d129b 100644 --- a/interface/resources/qml/hifi/tablet/TabletMenu.qml +++ b/interface/resources/qml/hifi/tablet/TabletMenu.qml @@ -4,7 +4,6 @@ import QtQuick.Controls 1.4 import QtQml 2.2 import QtWebChannel 1.0 import QtWebEngine 1.1 -import HFWebEngineProfile 1.0 import "." diff --git a/interface/resources/qml/hifi/tablet/TabletRoot.qml b/interface/resources/qml/hifi/tablet/TabletRoot.qml index 97c8854c86..e7654d9ff1 100644 --- a/interface/resources/qml/hifi/tablet/TabletRoot.qml +++ b/interface/resources/qml/hifi/tablet/TabletRoot.qml @@ -1,7 +1,6 @@ import QtQuick 2.0 import Hifi 1.0 import QtQuick.Controls 1.4 -import HFTabletWebEngineProfile 1.0 import "../../dialogs" import "../../controls" diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 851c07c501..d6475c4b00 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -148,9 +148,6 @@ #include "LODManager.h" #include "ModelPackager.h" #include "networking/CloseEventSender.h" -#include "networking/HFWebEngineProfile.h" -#include "networking/HFTabletWebEngineProfile.h" -#include "networking/FileTypeProfile.h" #include "scripting/TestScriptingInterface.h" #include "scripting/AccountScriptingInterface.h" #include "scripting/AssetMappingsScriptingInterface.h" @@ -1852,14 +1849,10 @@ void Application::initializeUi() { UpdateDialog::registerType(); qmlRegisterType("Hifi", 1, 0, "Preference"); - qmlRegisterType("HFWebEngineProfile", 1, 0, "HFWebEngineProfile"); - qmlRegisterType("HFTabletWebEngineProfile", 1, 0, "HFTabletWebEngineProfile"); - qmlRegisterType("FileTypeProfile", 1, 0, "FileTypeProfile"); - auto offscreenUi = DependencyManager::get(); offscreenUi->create(_glWidget->qglContext()); - auto rootContext = offscreenUi->getRootContext(); + auto surfaceContext = offscreenUi->getSurfaceContext(); offscreenUi->setProxyWindow(_window->windowHandle()); offscreenUi->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "/qml/")); @@ -1871,7 +1864,7 @@ void Application::initializeUi() { // do better detection in the offscreen UI of what has focus offscreenUi->setNavigationFocused(false); - auto engine = rootContext->engine(); + auto engine = surfaceContext->engine(); connect(engine, &QQmlEngine::quit, [] { qApp->quit(); }); @@ -1880,79 +1873,78 @@ void Application::initializeUi() { // For some reason there is already an "Application" object in the QML context, // though I can't find it. Hence, "ApplicationInterface" - rootContext->setContextProperty("ApplicationInterface", this); - rootContext->setContextProperty("Audio", DependencyManager::get().data()); - rootContext->setContextProperty("AudioStats", DependencyManager::get()->getStats().data()); - rootContext->setContextProperty("AudioScope", DependencyManager::get().data()); + surfaceContext->setContextProperty("Audio", DependencyManager::get().data()); + surfaceContext->setContextProperty("AudioStats", DependencyManager::get()->getStats().data()); + surfaceContext->setContextProperty("AudioScope", DependencyManager::get().data()); - rootContext->setContextProperty("Controller", DependencyManager::get().data()); - rootContext->setContextProperty("Entities", DependencyManager::get().data()); + surfaceContext->setContextProperty("Controller", DependencyManager::get().data()); + surfaceContext->setContextProperty("Entities", DependencyManager::get().data()); _fileDownload = new FileScriptingInterface(engine); - rootContext->setContextProperty("File", _fileDownload); + surfaceContext->setContextProperty("File", _fileDownload); connect(_fileDownload, &FileScriptingInterface::unzipResult, this, &Application::handleUnzip); - rootContext->setContextProperty("MyAvatar", getMyAvatar().get()); - rootContext->setContextProperty("Messages", DependencyManager::get().data()); - rootContext->setContextProperty("Recording", DependencyManager::get().data()); - rootContext->setContextProperty("Preferences", DependencyManager::get().data()); - rootContext->setContextProperty("AddressManager", DependencyManager::get().data()); - rootContext->setContextProperty("FrameTimings", &_frameTimingsScriptingInterface); - rootContext->setContextProperty("Rates", new RatesScriptingInterface(this)); - rootContext->setContextProperty("pathToFonts", "../../"); + surfaceContext->setContextProperty("MyAvatar", getMyAvatar().get()); + surfaceContext->setContextProperty("Messages", DependencyManager::get().data()); + surfaceContext->setContextProperty("Recording", DependencyManager::get().data()); + surfaceContext->setContextProperty("Preferences", DependencyManager::get().data()); + surfaceContext->setContextProperty("AddressManager", DependencyManager::get().data()); + surfaceContext->setContextProperty("FrameTimings", &_frameTimingsScriptingInterface); + surfaceContext->setContextProperty("Rates", new RatesScriptingInterface(this)); - rootContext->setContextProperty("TREE_SCALE", TREE_SCALE); - rootContext->setContextProperty("Quat", new Quat()); - rootContext->setContextProperty("Vec3", new Vec3()); - rootContext->setContextProperty("Uuid", new ScriptUUID()); - rootContext->setContextProperty("Assets", DependencyManager::get().data()); + surfaceContext->setContextProperty("TREE_SCALE", TREE_SCALE); + // FIXME Quat and Vec3 won't work with QJSEngine used by QML + surfaceContext->setContextProperty("Quat", new Quat()); + surfaceContext->setContextProperty("Vec3", new Vec3()); + surfaceContext->setContextProperty("Uuid", new ScriptUUID()); + surfaceContext->setContextProperty("Assets", DependencyManager::get().data()); - rootContext->setContextProperty("AvatarList", DependencyManager::get().data()); - rootContext->setContextProperty("Users", DependencyManager::get().data()); + surfaceContext->setContextProperty("AvatarList", DependencyManager::get().data()); + surfaceContext->setContextProperty("Users", DependencyManager::get().data()); - rootContext->setContextProperty("UserActivityLogger", DependencyManager::get().data()); + surfaceContext->setContextProperty("UserActivityLogger", DependencyManager::get().data()); - rootContext->setContextProperty("Camera", &_myCamera); + surfaceContext->setContextProperty("Camera", &_myCamera); #if defined(Q_OS_MAC) || defined(Q_OS_WIN) - rootContext->setContextProperty("SpeechRecognizer", DependencyManager::get().data()); + surfaceContext->setContextProperty("SpeechRecognizer", DependencyManager::get().data()); #endif - rootContext->setContextProperty("Overlays", &_overlays); - rootContext->setContextProperty("Window", DependencyManager::get().data()); - rootContext->setContextProperty("MenuInterface", MenuScriptingInterface::getInstance()); - rootContext->setContextProperty("Stats", Stats::getInstance()); - rootContext->setContextProperty("Settings", SettingsScriptingInterface::getInstance()); - rootContext->setContextProperty("ScriptDiscoveryService", DependencyManager::get().data()); - rootContext->setContextProperty("AudioDevice", AudioDeviceScriptingInterface::getInstance()); - rootContext->setContextProperty("AvatarBookmarks", DependencyManager::get().data()); - rootContext->setContextProperty("LocationBookmarks", DependencyManager::get().data()); + surfaceContext->setContextProperty("Overlays", &_overlays); + surfaceContext->setContextProperty("Window", DependencyManager::get().data()); + surfaceContext->setContextProperty("MenuInterface", MenuScriptingInterface::getInstance()); + surfaceContext->setContextProperty("Stats", Stats::getInstance()); + surfaceContext->setContextProperty("Settings", SettingsScriptingInterface::getInstance()); + surfaceContext->setContextProperty("ScriptDiscoveryService", DependencyManager::get().data()); + surfaceContext->setContextProperty("AudioDevice", AudioDeviceScriptingInterface::getInstance()); + surfaceContext->setContextProperty("AvatarBookmarks", DependencyManager::get().data()); + surfaceContext->setContextProperty("LocationBookmarks", DependencyManager::get().data()); // Caches - rootContext->setContextProperty("AnimationCache", DependencyManager::get().data()); - rootContext->setContextProperty("TextureCache", DependencyManager::get().data()); - rootContext->setContextProperty("ModelCache", DependencyManager::get().data()); - rootContext->setContextProperty("SoundCache", DependencyManager::get().data()); + surfaceContext->setContextProperty("AnimationCache", DependencyManager::get().data()); + surfaceContext->setContextProperty("TextureCache", DependencyManager::get().data()); + surfaceContext->setContextProperty("ModelCache", DependencyManager::get().data()); + surfaceContext->setContextProperty("SoundCache", DependencyManager::get().data()); - rootContext->setContextProperty("Account", AccountScriptingInterface::getInstance()); - rootContext->setContextProperty("Tablet", DependencyManager::get().data()); - rootContext->setContextProperty("DialogsManager", _dialogsManagerScriptingInterface); - rootContext->setContextProperty("GlobalServices", GlobalServicesScriptingInterface::getInstance()); - rootContext->setContextProperty("FaceTracker", DependencyManager::get().data()); - rootContext->setContextProperty("AvatarManager", DependencyManager::get().data()); - rootContext->setContextProperty("UndoStack", &_undoStackScriptingInterface); - rootContext->setContextProperty("LODManager", DependencyManager::get().data()); - rootContext->setContextProperty("Paths", DependencyManager::get().data()); - rootContext->setContextProperty("HMD", DependencyManager::get().data()); - rootContext->setContextProperty("Scene", DependencyManager::get().data()); - rootContext->setContextProperty("Render", _renderEngine->getConfiguration().get()); - rootContext->setContextProperty("Reticle", getApplicationCompositor().getReticleInterface()); - rootContext->setContextProperty("Snapshot", DependencyManager::get().data()); + surfaceContext->setContextProperty("Account", AccountScriptingInterface::getInstance()); + surfaceContext->setContextProperty("Tablet", DependencyManager::get().data()); + surfaceContext->setContextProperty("DialogsManager", _dialogsManagerScriptingInterface); + surfaceContext->setContextProperty("GlobalServices", GlobalServicesScriptingInterface::getInstance()); + surfaceContext->setContextProperty("FaceTracker", DependencyManager::get().data()); + surfaceContext->setContextProperty("AvatarManager", DependencyManager::get().data()); + surfaceContext->setContextProperty("UndoStack", &_undoStackScriptingInterface); + surfaceContext->setContextProperty("LODManager", DependencyManager::get().data()); + surfaceContext->setContextProperty("Paths", DependencyManager::get().data()); + surfaceContext->setContextProperty("HMD", DependencyManager::get().data()); + surfaceContext->setContextProperty("Scene", DependencyManager::get().data()); + surfaceContext->setContextProperty("Render", _renderEngine->getConfiguration().get()); + surfaceContext->setContextProperty("Reticle", getApplicationCompositor().getReticleInterface()); + surfaceContext->setContextProperty("Snapshot", DependencyManager::get().data()); - rootContext->setContextProperty("ApplicationCompositor", &getApplicationCompositor()); + surfaceContext->setContextProperty("ApplicationCompositor", &getApplicationCompositor()); - rootContext->setContextProperty("AvatarInputs", AvatarInputs::getInstance()); + surfaceContext->setContextProperty("AvatarInputs", AvatarInputs::getInstance()); if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) { - rootContext->setContextProperty("Steam", new SteamScriptingInterface(engine, steamClient.get())); + surfaceContext->setContextProperty("Steam", new SteamScriptingInterface(engine, steamClient.get())); } diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index 75c793bf77..e26a641206 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -135,7 +135,7 @@ Web3DOverlay::~Web3DOverlay() { void Web3DOverlay::update(float deltatime) { if (_webSurface) { // update globalPosition - _webSurface->getRootContext()->setContextProperty("globalPosition", vec3toVariant(getPosition())); + _webSurface->getSurfaceContext()->setContextProperty("globalPosition", vec3toVariant(getPosition())); } } @@ -163,57 +163,56 @@ void Web3DOverlay::loadSourceURL() { _webSurface->resume(); _webSurface->getRootItem()->setProperty("url", _url); _webSurface->getRootItem()->setProperty("scriptURL", _scriptURL); - _webSurface->getRootContext()->setContextProperty("ApplicationInterface", qApp); } else { _webSurface->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath())); _webSurface->load(_url, [&](QQmlContext* context, QObject* obj) {}); _webSurface->resume(); - _webSurface->getRootContext()->setContextProperty("Users", DependencyManager::get().data()); - _webSurface->getRootContext()->setContextProperty("HMD", DependencyManager::get().data()); - _webSurface->getRootContext()->setContextProperty("UserActivityLogger", DependencyManager::get().data()); - _webSurface->getRootContext()->setContextProperty("Preferences", DependencyManager::get().data()); - _webSurface->getRootContext()->setContextProperty("Vec3", new Vec3()); - _webSurface->getRootContext()->setContextProperty("Quat", new Quat()); - _webSurface->getRootContext()->setContextProperty("MyAvatar", DependencyManager::get()->getMyAvatar().get()); - _webSurface->getRootContext()->setContextProperty("Entities", DependencyManager::get().data()); - _webSurface->getRootContext()->setContextProperty("Snapshot", DependencyManager::get().data()); + _webSurface->getSurfaceContext()->setContextProperty("Users", DependencyManager::get().data()); + _webSurface->getSurfaceContext()->setContextProperty("HMD", DependencyManager::get().data()); + _webSurface->getSurfaceContext()->setContextProperty("UserActivityLogger", DependencyManager::get().data()); + _webSurface->getSurfaceContext()->setContextProperty("Preferences", DependencyManager::get().data()); + _webSurface->getSurfaceContext()->setContextProperty("Vec3", new Vec3()); + _webSurface->getSurfaceContext()->setContextProperty("Quat", new Quat()); + _webSurface->getSurfaceContext()->setContextProperty("MyAvatar", DependencyManager::get()->getMyAvatar().get()); + _webSurface->getSurfaceContext()->setContextProperty("Entities", DependencyManager::get().data()); + _webSurface->getSurfaceContext()->setContextProperty("Snapshot", DependencyManager::get().data()); if (_webSurface->getRootItem() && _webSurface->getRootItem()->objectName() == "tabletRoot") { auto tabletScriptingInterface = DependencyManager::get(); auto flags = tabletScriptingInterface->getFlags(); - _webSurface->getRootContext()->setContextProperty("offscreenFlags", flags); - _webSurface->getRootContext()->setContextProperty("AddressManager", DependencyManager::get().data()); - _webSurface->getRootContext()->setContextProperty("Account", AccountScriptingInterface::getInstance()); - _webSurface->getRootContext()->setContextProperty("AudioStats", DependencyManager::get()->getStats().data()); - _webSurface->getRootContext()->setContextProperty("HMD", DependencyManager::get().data()); - _webSurface->getRootContext()->setContextProperty("fileDialogHelper", new FileDialogHelper()); - _webSurface->getRootContext()->setContextProperty("MyAvatar", DependencyManager::get()->getMyAvatar().get()); - _webSurface->getRootContext()->setContextProperty("ScriptDiscoveryService", DependencyManager::get().data()); - _webSurface->getRootContext()->setContextProperty("Tablet", DependencyManager::get().data()); - _webSurface->getRootContext()->setContextProperty("Assets", DependencyManager::get().data()); - _webSurface->getRootContext()->setContextProperty("LODManager", DependencyManager::get().data()); - _webSurface->getRootContext()->setContextProperty("OctreeStats", DependencyManager::get().data()); - _webSurface->getRootContext()->setContextProperty("DCModel", DependencyManager::get().data()); - _webSurface->getRootContext()->setContextProperty("AudioDevice", AudioDeviceScriptingInterface::getInstance()); - _webSurface->getRootContext()->setContextProperty("AvatarInputs", AvatarInputs::getInstance()); - _webSurface->getRootContext()->setContextProperty("GlobalServices", GlobalServicesScriptingInterface::getInstance()); - _webSurface->getRootContext()->setContextProperty("AvatarList", DependencyManager::get().data()); - _webSurface->getRootContext()->setContextProperty("DialogsManager", DialogsManagerScriptingInterface::getInstance()); + _webSurface->getSurfaceContext()->setContextProperty("offscreenFlags", flags); + _webSurface->getSurfaceContext()->setContextProperty("AddressManager", DependencyManager::get().data()); + _webSurface->getSurfaceContext()->setContextProperty("Account", AccountScriptingInterface::getInstance()); + _webSurface->getSurfaceContext()->setContextProperty("AudioStats", DependencyManager::get()->getStats().data()); + _webSurface->getSurfaceContext()->setContextProperty("HMD", DependencyManager::get().data()); + _webSurface->getSurfaceContext()->setContextProperty("fileDialogHelper", new FileDialogHelper()); + _webSurface->getSurfaceContext()->setContextProperty("MyAvatar", DependencyManager::get()->getMyAvatar().get()); + _webSurface->getSurfaceContext()->setContextProperty("ScriptDiscoveryService", DependencyManager::get().data()); + _webSurface->getSurfaceContext()->setContextProperty("Tablet", DependencyManager::get().data()); + _webSurface->getSurfaceContext()->setContextProperty("Assets", DependencyManager::get().data()); + _webSurface->getSurfaceContext()->setContextProperty("LODManager", DependencyManager::get().data()); + _webSurface->getSurfaceContext()->setContextProperty("OctreeStats", DependencyManager::get().data()); + _webSurface->getSurfaceContext()->setContextProperty("DCModel", DependencyManager::get().data()); + _webSurface->getSurfaceContext()->setContextProperty("AudioDevice", AudioDeviceScriptingInterface::getInstance()); + _webSurface->getSurfaceContext()->setContextProperty("AvatarInputs", AvatarInputs::getInstance()); + _webSurface->getSurfaceContext()->setContextProperty("GlobalServices", GlobalServicesScriptingInterface::getInstance()); + _webSurface->getSurfaceContext()->setContextProperty("AvatarList", DependencyManager::get().data()); + _webSurface->getSurfaceContext()->setContextProperty("DialogsManager", DialogsManagerScriptingInterface::getInstance()); - _webSurface->getRootContext()->setContextProperty("pathToFonts", "../../"); + _webSurface->getSurfaceContext()->setContextProperty("pathToFonts", "../../"); tabletScriptingInterface->setQmlTabletRoot("com.highfidelity.interface.tablet.system", _webSurface->getRootItem(), _webSurface.data()); // mark the TabletProxy object as cpp ownership. QObject* tablet = tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system"); - _webSurface->getRootContext()->engine()->setObjectOwnership(tablet, QQmlEngine::CppOwnership); + _webSurface->getSurfaceContext()->engine()->setObjectOwnership(tablet, QQmlEngine::CppOwnership); // Override min fps for tablet UI, for silky smooth scrolling setMaxFPS(90); } } - _webSurface->getRootContext()->setContextProperty("globalPosition", vec3toVariant(getPosition())); + _webSurface->getSurfaceContext()->setContextProperty("globalPosition", vec3toVariant(getPosition())); } void Web3DOverlay::setMaxFPS(uint8_t maxFPS) { diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp index 0d286c46eb..3b3480443d 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp @@ -127,7 +127,7 @@ bool RenderableWebEntityItem::buildWebSurface(QSharedPointer _webSurface->resume(); _webSurface->getRootItem()->setProperty("url", _sourceUrl); - _webSurface->getRootContext()->setContextProperty("desktop", QVariant()); + _webSurface->getSurfaceContext()->setContextProperty("desktop", QVariant()); // FIXME - Keyboard HMD only: Possibly add "HMDinfo" object to context for WebView.qml. // forward web events to EntityScriptingInterface @@ -271,7 +271,7 @@ void RenderableWebEntityItem::loadSourceURL() { }); _webSurface->getRootItem()->setProperty("url", _sourceUrl); - _webSurface->getRootContext()->setContextProperty("desktop", QVariant()); + _webSurface->getSurfaceContext()->setContextProperty("desktop", QVariant()); } else { _contentType = qmlContent; @@ -284,7 +284,7 @@ void RenderableWebEntityItem::loadSourceURL() { _webSurface->getRootItem(), _webSurface.data()); } } - _webSurface->getRootContext()->setContextProperty("globalPosition", vec3toVariant(getPosition())); + _webSurface->getSurfaceContext()->setContextProperty("globalPosition", vec3toVariant(getPosition())); } @@ -420,7 +420,7 @@ void RenderableWebEntityItem::update(const quint64& now) { if (_webSurface) { // update globalPosition - _webSurface->getRootContext()->setContextProperty("globalPosition", vec3toVariant(getPosition())); + _webSurface->getSurfaceContext()->setContextProperty("globalPosition", vec3toVariant(getPosition())); } auto interval = now - _lastRenderTime; diff --git a/libraries/gl/CMakeLists.txt b/libraries/gl/CMakeLists.txt index 3e2097e89e..fd3197410b 100644 --- a/libraries/gl/CMakeLists.txt +++ b/libraries/gl/CMakeLists.txt @@ -1,6 +1,6 @@ set(TARGET_NAME gl) setup_hifi_library(OpenGL Qml Quick) -link_hifi_libraries(shared) +link_hifi_libraries(shared networking) target_opengl() diff --git a/libraries/gl/src/gl/OffscreenQmlSurface.cpp b/libraries/gl/src/gl/OffscreenQmlSurface.cpp index 3bbd26e010..65c311424f 100644 --- a/libraries/gl/src/gl/OffscreenQmlSurface.cpp +++ b/libraries/gl/src/gl/OffscreenQmlSurface.cpp @@ -33,6 +33,9 @@ #include #include #include +#include +#include +#include #include "OffscreenGLCanvas.h" #include "GLHelpers.h" @@ -41,6 +44,7 @@ Q_LOGGING_CATEGORY(trace_render_qml, "trace.render.qml") Q_LOGGING_CATEGORY(trace_render_qml_gl, "trace.render.qml.gl") +Q_LOGGING_CATEGORY(offscreenFocus, "hifi.offscreen.focus") struct TextureSet { // The number of surfaces with this size @@ -254,8 +258,72 @@ QNetworkAccessManager* QmlNetworkAccessManagerFactory::create(QObject* parent) { return new QmlNetworkAccessManager(parent); } -Q_DECLARE_LOGGING_CATEGORY(offscreenFocus) -Q_LOGGING_CATEGORY(offscreenFocus, "hifi.offscreen.focus") +static QQmlEngine* globalEngine { nullptr }; +static size_t globalEngineRefCount { 0 }; + +QString getEventBridgeJavascript() { + // FIXME: Refactor with similar code in RenderableWebEntityItem + QString javaScriptToInject; + QFile webChannelFile(":qtwebchannel/qwebchannel.js"); + QFile createGlobalEventBridgeFile(PathUtils::resourcesPath() + "/html/createGlobalEventBridge.js"); + if (webChannelFile.open(QFile::ReadOnly | QFile::Text) && + createGlobalEventBridgeFile.open(QFile::ReadOnly | QFile::Text)) { + QString webChannelStr = QTextStream(&webChannelFile).readAll(); + QString createGlobalEventBridgeStr = QTextStream(&createGlobalEventBridgeFile).readAll(); + javaScriptToInject = webChannelStr + createGlobalEventBridgeStr; + } else { + qCWarning(glLogging) << "Unable to find qwebchannel.js or createGlobalEventBridge.js"; + } + return javaScriptToInject; +} + + +QQmlEngine* acquireEngine(QQuickWindow* window) { + Q_ASSERT(QThread::currentThread() == qApp->thread()); + if (!globalEngine) { + Q_ASSERT(0 == globalEngineRefCount); + globalEngine = new QQmlEngine(); + globalEngine->setNetworkAccessManagerFactory(new QmlNetworkAccessManagerFactory); + + auto importList = globalEngine->importPathList(); + importList.insert(importList.begin(), PathUtils::resourcesPath()); + globalEngine->setImportPathList(importList); + for (const auto& path : importList) { + qDebug() << path; + } + + if (!globalEngine->incubationController()) { + globalEngine->setIncubationController(window->incubationController()); + } + auto rootContext = globalEngine->rootContext(); + rootContext->setContextProperty("GL", ::getGLContextData()); + rootContext->setContextProperty("urlHandler", new UrlHandler()); + rootContext->setContextProperty("resourceDirectoryUrl", QUrl::fromLocalFile(PathUtils::resourcesPath())); + rootContext->setContextProperty("pathToFonts", "../../"); + rootContext->setContextProperty("ApplicationInterface", qApp); + auto javaScriptToInject = getEventBridgeJavascript(); + if (!javaScriptToInject.isEmpty()) { + rootContext->setContextProperty("eventBridgeJavaScriptToInject", QVariant(javaScriptToInject)); + } + rootContext->setContextProperty("FileTypeProfile", new FileTypeProfile(rootContext)); + rootContext->setContextProperty("HFWebEngineProfile", new HFWebEngineProfile(rootContext)); + rootContext->setContextProperty("HFTabletWebEngineProfile", new HFTabletWebEngineProfile(rootContext)); + + + } + + ++globalEngineRefCount; + return globalEngine; +} + +void releaseEngine() { + Q_ASSERT(QThread::currentThread() == qApp->thread()); + Q_ASSERT(0 != globalEngineRefCount); + if (0 == --globalEngineRefCount) { + globalEngine->deleteLater(); + globalEngine = nullptr; + } +} void OffscreenQmlSurface::cleanup() { _canvas->makeCurrent(); @@ -294,6 +362,7 @@ void OffscreenQmlSurface::render() { GLuint texture = offscreenTextures.getNextTexture(_size); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _fbo); glFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); _renderControl->render(); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glBindTexture(GL_TEXTURE_2D, texture); @@ -362,8 +431,8 @@ OffscreenQmlSurface::~OffscreenQmlSurface() { _canvas->deleteLater(); _rootItem->deleteLater(); _qmlComponent->deleteLater(); - _qmlEngine->deleteLater(); _quickWindow->deleteLater(); + releaseEngine(); } void OffscreenQmlSurface::onAboutToQuit() { @@ -375,6 +444,8 @@ void OffscreenQmlSurface::create(QOpenGLContext* shareContext) { qCDebug(glLogging) << "Building QML surface"; _renderControl = new QMyQuickRenderControl(); + connect(_renderControl, &QQuickRenderControl::renderRequested, this, [this] { _render = true; }); + connect(_renderControl, &QQuickRenderControl::sceneChanged, this, [this] { _render = _polish = true; }); QQuickWindow::setDefaultAlphaBuffer(true); @@ -385,7 +456,7 @@ void OffscreenQmlSurface::create(QOpenGLContext* shareContext) { // so we wait until after its ctor to move object/context to this thread. _quickWindow = new QQuickWindow(_renderControl); _quickWindow->setColor(QColor(255, 255, 255, 0)); - _quickWindow->setFlags(_quickWindow->flags() | static_cast(Qt::WA_TranslucentBackground)); + _quickWindow->setClearBeforeRendering(false); _renderControl->_renderWindow = _proxyWindow; @@ -398,32 +469,20 @@ void OffscreenQmlSurface::create(QOpenGLContext* shareContext) { connect(_quickWindow, &QQuickWindow::focusObjectChanged, this, &OffscreenQmlSurface::onFocusObjectChanged); // Create a QML engine. - _qmlEngine = new QQmlEngine; + auto qmlEngine = acquireEngine(_quickWindow); + _qmlContext = new QQmlContext(qmlEngine->rootContext()); - _qmlEngine->setNetworkAccessManagerFactory(new QmlNetworkAccessManagerFactory); + _qmlContext->setContextProperty("offscreenWindow", QVariant::fromValue(getWindow())); + _qmlContext->setContextProperty("globalEventBridge", this); + _qmlContext->setContextProperty("webEntity", this); - auto importList = _qmlEngine->importPathList(); - importList.insert(importList.begin(), PathUtils::resourcesPath()); - _qmlEngine->setImportPathList(importList); - if (!_qmlEngine->incubationController()) { - _qmlEngine->setIncubationController(_quickWindow->incubationController()); - } + _qmlComponent = new QQmlComponent(qmlEngine); - // FIXME - _glData = ::getGLContextData(); // Initialize JSON structure so that it can be filled in later and then used in QML. - _qmlEngine->rootContext()->setContextProperty("GL", _glData); - _qmlEngine->rootContext()->setContextProperty("offscreenWindow", QVariant::fromValue(getWindow())); - _qmlComponent = new QQmlComponent(_qmlEngine); - - - connect(_renderControl, &QQuickRenderControl::renderRequested, this, [this] { _render = true; }); - connect(_renderControl, &QQuickRenderControl::sceneChanged, this, [this] { _render = _polish = true; }); if (!_canvas->makeCurrent()) { qWarning("Failed to make context current for QML Renderer"); return; } - _glData = ::getGLContextData(); _renderControl->initialize(_canvas->getContext()); // When Quick says there is a need to render, we will not render immediately. Instead, @@ -433,11 +492,6 @@ void OffscreenQmlSurface::create(QOpenGLContext* shareContext) { _updateTimer.setTimerType(Qt::PreciseTimer); _updateTimer.setInterval(MIN_TIMER_MS); // 5ms, Qt::PreciseTimer required _updateTimer.start(); - - auto rootContext = getRootContext(); - rootContext->setContextProperty("urlHandler", new UrlHandler()); - rootContext->setContextProperty("resourceDirectoryUrl", QUrl::fromLocalFile(PathUtils::resourcesPath())); - rootContext->setContextProperty("pathToFonts", "../../"); } static uvec2 clampSize(const uvec2& size, uint32_t maxDimension) { @@ -460,7 +514,7 @@ void OffscreenQmlSurface::resize(const QSize& newSize_, bool forceResize) { return; } - _qmlEngine->rootContext()->setContextProperty("surfaceSize", newSize); + _qmlContext->setContextProperty("surfaceSize", newSize); if (_rootItem) { _rootItem->setSize(newSize); @@ -520,14 +574,19 @@ QQuickItem* OffscreenQmlSurface::getRootItem() { } void OffscreenQmlSurface::setBaseUrl(const QUrl& baseUrl) { - _qmlEngine->setBaseUrl(baseUrl); + _qmlContext->setBaseUrl(baseUrl); } QObject* OffscreenQmlSurface::load(const QUrl& qmlSource, std::function f) { // Synchronous loading may take a while; restart the deadlock timer QMetaObject::invokeMethod(qApp, "updateHeartbeat", Qt::DirectConnection); - _qmlComponent->loadUrl(qmlSource, QQmlComponent::PreferSynchronous); + if ((qmlSource.isRelative() && !qmlSource.isEmpty()) || qmlSource.scheme() == QLatin1String("file")) { + _qmlComponent->loadUrl(_qmlContext->resolvedUrl(qmlSource), QQmlComponent::PreferSynchronous); + } else { + _qmlComponent->loadUrl(qmlSource, QQmlComponent::PreferSynchronous); + } + if (_qmlComponent->isLoading()) { connect(_qmlComponent, &QQmlComponent::statusChanged, this, @@ -541,10 +600,22 @@ QObject* OffscreenQmlSurface::load(const QUrl& qmlSource, std::functionengine()->clearComponentCache(); + _qmlContext->engine()->clearComponentCache(); } QObject* OffscreenQmlSurface::finishQmlLoad(std::function f) { +#if 0 + if (!_rootItem) { + QQmlComponent component(_qmlContext->engine()); + component.setData(R"QML( +import QtQuick 2.0 +import QtWebChannel 1.0 +Item { Component.onCompleted: globalEventBridge.WebChannel.id = "globalEventBridge"; } +)QML", QUrl()); + QObject *helper = component.create(_qmlContext); + qDebug() << "Created helper"; + } +#endif disconnect(_qmlComponent, &QQmlComponent::statusChanged, this, 0); if (_qmlComponent->isError()) { QList errorList = _qmlComponent->errors(); @@ -554,21 +625,8 @@ QObject* OffscreenQmlSurface::finishQmlLoad(std::functionbeginCreate(newContext); + QObject* newObject = _qmlComponent->beginCreate(_qmlContext); if (_qmlComponent->isError()) { QList errorList = _qmlComponent->errors(); foreach(const QQmlError& error, errorList) @@ -579,12 +637,10 @@ QObject* OffscreenQmlSurface::finishQmlLoad(std::functionsetObjectOwnership(this, QQmlEngine::CppOwnership); + _qmlContext->engine()->setObjectOwnership(this, QQmlEngine::CppOwnership); newObject->setProperty("eventBridge", QVariant::fromValue(this)); - newContext->setContextProperty("eventBridgeJavaScriptToInject", QVariant(javaScriptToInject)); - - f(newContext, newObject); + f(_qmlContext, newObject); _qmlComponent->completeCreate(); @@ -735,7 +791,7 @@ bool OffscreenQmlSurface::eventFilter(QObject* originalDestination, QEvent* even mouseEvent->screenPos(), mouseEvent->button(), mouseEvent->buttons(), mouseEvent->modifiers()); if (event->type() == QEvent::MouseMove) { - _qmlEngine->rootContext()->setContextProperty("lastMousePosition", transformedPos); + _qmlContext->setContextProperty("lastMousePosition", transformedPos); } mappedEvent.ignore(); if (QCoreApplication::sendEvent(_quickWindow, &mappedEvent)) { @@ -762,9 +818,6 @@ void OffscreenQmlSurface::resume() { if (getRootItem()) { getRootItem()->setProperty("eventBridge", QVariant::fromValue(this)); } - if (getRootContext()) { - getRootContext()->setContextProperty("webEntity", this); - } } bool OffscreenQmlSurface::isPaused() const { @@ -790,8 +843,8 @@ QSize OffscreenQmlSurface::size() const { return _quickWindow->geometry().size(); } -QQmlContext* OffscreenQmlSurface::getRootContext() { - return _qmlEngine->rootContext(); +QQmlContext* OffscreenQmlSurface::getSurfaceContext() { + return _qmlContext; } Q_DECLARE_METATYPE(std::function); diff --git a/libraries/gl/src/gl/OffscreenQmlSurface.h b/libraries/gl/src/gl/OffscreenQmlSurface.h index efd35fce8b..2a078d2b4f 100644 --- a/libraries/gl/src/gl/OffscreenQmlSurface.h +++ b/libraries/gl/src/gl/OffscreenQmlSurface.h @@ -73,7 +73,7 @@ public: QQuickItem* getRootItem(); QQuickWindow* getWindow(); QObject* getEventHandler(); - QQmlContext* getRootContext(); + QQmlContext* getSurfaceContext(); QPointF mapToVirtualScreen(const QPointF& originalPoint, QObject* originalWidget); bool eventFilter(QObject* originalDestination, QEvent* event) override; @@ -133,11 +133,10 @@ private slots: private: QQuickWindow* _quickWindow { nullptr }; QMyQuickRenderControl* _renderControl{ nullptr }; - QQmlEngine* _qmlEngine { nullptr }; + QQmlContext* _qmlContext { nullptr }; QQmlComponent* _qmlComponent { nullptr }; QQuickItem* _rootItem { nullptr }; OffscreenGLCanvas* _canvas { nullptr }; - QJsonObject _glData; QTimer _updateTimer; uint32_t _fbo { 0 }; diff --git a/libraries/gl/src/gl/OffscreenQmlSurfaceCache.cpp b/libraries/gl/src/gl/OffscreenQmlSurfaceCache.cpp index ad370a1f43..c047738e77 100644 --- a/libraries/gl/src/gl/OffscreenQmlSurfaceCache.cpp +++ b/libraries/gl/src/gl/OffscreenQmlSurfaceCache.cpp @@ -49,7 +49,6 @@ QSharedPointer OffscreenQmlSurfaceCache::buildSurface(const surface->create(currentContext); surface->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "/qml/")); surface->load(rootSource); - surface->getRootContext()->setContextProperty("ApplicationInterface", qApp); surface->resize(QSize(100, 100)); currentContext->makeCurrent(currentSurface); return surface; diff --git a/libraries/networking/CMakeLists.txt b/libraries/networking/CMakeLists.txt index 288e98d5a5..ff9a05b959 100644 --- a/libraries/networking/CMakeLists.txt +++ b/libraries/networking/CMakeLists.txt @@ -1,5 +1,5 @@ set(TARGET_NAME networking) -setup_hifi_library(Network) +setup_hifi_library(Network WebEngine) link_hifi_libraries(shared) target_include_directories(${TARGET_NAME} PRIVATE "${CMAKE_BINARY_DIR}/includes") diff --git a/interface/src/networking/FileTypeProfile.cpp b/libraries/networking/src/FileTypeProfile.cpp similarity index 100% rename from interface/src/networking/FileTypeProfile.cpp rename to libraries/networking/src/FileTypeProfile.cpp diff --git a/interface/src/networking/FileTypeProfile.h b/libraries/networking/src/FileTypeProfile.h similarity index 100% rename from interface/src/networking/FileTypeProfile.h rename to libraries/networking/src/FileTypeProfile.h diff --git a/interface/src/networking/FileTypeRequestInterceptor.cpp b/libraries/networking/src/FileTypeRequestInterceptor.cpp similarity index 100% rename from interface/src/networking/FileTypeRequestInterceptor.cpp rename to libraries/networking/src/FileTypeRequestInterceptor.cpp diff --git a/interface/src/networking/FileTypeRequestInterceptor.h b/libraries/networking/src/FileTypeRequestInterceptor.h similarity index 100% rename from interface/src/networking/FileTypeRequestInterceptor.h rename to libraries/networking/src/FileTypeRequestInterceptor.h diff --git a/interface/src/networking/HFTabletWebEngineProfile.cpp b/libraries/networking/src/HFTabletWebEngineProfile.cpp similarity index 95% rename from interface/src/networking/HFTabletWebEngineProfile.cpp rename to libraries/networking/src/HFTabletWebEngineProfile.cpp index 46634299bb..a3e3906497 100644 --- a/interface/src/networking/HFTabletWebEngineProfile.cpp +++ b/libraries/networking/src/HFTabletWebEngineProfile.cpp @@ -19,6 +19,7 @@ HFTabletWebEngineProfile::HFTabletWebEngineProfile(QObject* parent) : QQuickWebE static const QString WEB_ENGINE_USER_AGENT = "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Mobile Safari/537.36"; setHttpUserAgent(WEB_ENGINE_USER_AGENT); + setStorageName(QML_WEB_ENGINE_NAME); auto requestInterceptor = new HFTabletWebEngineRequestInterceptor(this); setRequestInterceptor(requestInterceptor); diff --git a/interface/src/networking/HFTabletWebEngineProfile.h b/libraries/networking/src/HFTabletWebEngineProfile.h similarity index 100% rename from interface/src/networking/HFTabletWebEngineProfile.h rename to libraries/networking/src/HFTabletWebEngineProfile.h diff --git a/interface/src/networking/HFTabletWebEngineRequestInterceptor.cpp b/libraries/networking/src/HFTabletWebEngineRequestInterceptor.cpp similarity index 98% rename from interface/src/networking/HFTabletWebEngineRequestInterceptor.cpp rename to libraries/networking/src/HFTabletWebEngineRequestInterceptor.cpp index fd79fc1cb6..6ee8589615 100644 --- a/interface/src/networking/HFTabletWebEngineRequestInterceptor.cpp +++ b/libraries/networking/src/HFTabletWebEngineRequestInterceptor.cpp @@ -11,7 +11,7 @@ #include "HFTabletWebEngineRequestInterceptor.h" #include -#include +#include "AccountManager.h" bool isTabletAuthableHighFidelityURL(const QUrl& url) { static const QStringList HF_HOSTS = { diff --git a/interface/src/networking/HFTabletWebEngineRequestInterceptor.h b/libraries/networking/src/HFTabletWebEngineRequestInterceptor.h similarity index 100% rename from interface/src/networking/HFTabletWebEngineRequestInterceptor.h rename to libraries/networking/src/HFTabletWebEngineRequestInterceptor.h diff --git a/interface/src/networking/HFWebEngineProfile.cpp b/libraries/networking/src/HFWebEngineProfile.cpp similarity index 94% rename from interface/src/networking/HFWebEngineProfile.cpp rename to libraries/networking/src/HFWebEngineProfile.cpp index 6b377fa900..a69d4d653b 100644 --- a/interface/src/networking/HFWebEngineProfile.cpp +++ b/libraries/networking/src/HFWebEngineProfile.cpp @@ -20,6 +20,7 @@ HFWebEngineProfile::HFWebEngineProfile(QObject* parent) : { static const QString WEB_ENGINE_USER_AGENT = "Chrome/48.0 (HighFidelityInterface)"; setHttpUserAgent(WEB_ENGINE_USER_AGENT); + setStorageName(QML_WEB_ENGINE_STORAGE_NAME); // we use the HFWebEngineRequestInterceptor to make sure that web requests are authenticated for the interface user auto requestInterceptor = new HFWebEngineRequestInterceptor(this); diff --git a/interface/src/networking/HFWebEngineProfile.h b/libraries/networking/src/HFWebEngineProfile.h similarity index 100% rename from interface/src/networking/HFWebEngineProfile.h rename to libraries/networking/src/HFWebEngineProfile.h diff --git a/interface/src/networking/HFWebEngineRequestInterceptor.cpp b/libraries/networking/src/HFWebEngineRequestInterceptor.cpp similarity index 95% rename from interface/src/networking/HFWebEngineRequestInterceptor.cpp rename to libraries/networking/src/HFWebEngineRequestInterceptor.cpp index 59897d427f..eaf0de7245 100644 --- a/interface/src/networking/HFWebEngineRequestInterceptor.cpp +++ b/libraries/networking/src/HFWebEngineRequestInterceptor.cpp @@ -13,7 +13,7 @@ #include -#include +#include "AccountManager.h" #include "RequestFilters.h" void HFWebEngineRequestInterceptor::interceptRequest(QWebEngineUrlRequestInfo& info) { diff --git a/interface/src/networking/HFWebEngineRequestInterceptor.h b/libraries/networking/src/HFWebEngineRequestInterceptor.h similarity index 100% rename from interface/src/networking/HFWebEngineRequestInterceptor.h rename to libraries/networking/src/HFWebEngineRequestInterceptor.h diff --git a/interface/src/networking/RequestFilters.cpp b/libraries/networking/src/RequestFilters.cpp similarity index 98% rename from interface/src/networking/RequestFilters.cpp rename to libraries/networking/src/RequestFilters.cpp index fedde94f15..3e72b8a8bd 100644 --- a/interface/src/networking/RequestFilters.cpp +++ b/libraries/networking/src/RequestFilters.cpp @@ -14,7 +14,7 @@ #include -#include +#include "AccountManager.h" namespace { diff --git a/interface/src/networking/RequestFilters.h b/libraries/networking/src/RequestFilters.h similarity index 100% rename from interface/src/networking/RequestFilters.h rename to libraries/networking/src/RequestFilters.h diff --git a/libraries/ui/src/OffscreenUi.cpp b/libraries/ui/src/OffscreenUi.cpp index 84812b4f60..a80105293b 100644 --- a/libraries/ui/src/OffscreenUi.cpp +++ b/libraries/ui/src/OffscreenUi.cpp @@ -91,14 +91,14 @@ QObject* OffscreenUi::getFlags() { void OffscreenUi::create(QOpenGLContext* context) { OffscreenQmlSurface::create(context); - auto rootContext = getRootContext(); + auto myContext = getSurfaceContext(); - rootContext->setContextProperty("OffscreenUi", this); - rootContext->setContextProperty("offscreenFlags", offscreenFlags = new OffscreenFlags()); - rootContext->setContextProperty("fileDialogHelper", new FileDialogHelper()); + myContext->setContextProperty("OffscreenUi", this); + myContext->setContextProperty("offscreenFlags", offscreenFlags = new OffscreenFlags()); + myContext->setContextProperty("fileDialogHelper", new FileDialogHelper()); auto tabletScriptingInterface = DependencyManager::get(); TabletProxy* tablet = tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system"); - rootContext->engine()->setObjectOwnership(tablet, QQmlEngine::CppOwnership); + myContext->engine()->setObjectOwnership(tablet, QQmlEngine::CppOwnership); } void OffscreenUi::show(const QUrl& url, const QString& name, std::function f) { @@ -547,14 +547,14 @@ void OffscreenUi::createDesktop(const QUrl& url) { } #ifdef DEBUG - getRootContext()->setContextProperty("DebugQML", QVariant(true)); + getSurfaceContext()->setContextProperty("DebugQML", QVariant(true)); #else - getRootContext()->setContextProperty("DebugQML", QVariant(false)); + getSurfaceContext()->setContextProperty("DebugQML", QVariant(false)); #endif _desktop = dynamic_cast(load(url)); Q_ASSERT(_desktop); - getRootContext()->setContextProperty("desktop", _desktop); + getSurfaceContext()->setContextProperty("desktop", _desktop); _toolWindow = _desktop->findChild("ToolWindow"); diff --git a/libraries/ui/src/VrMenu.cpp b/libraries/ui/src/VrMenu.cpp index 878514dd41..3959e950e9 100644 --- a/libraries/ui/src/VrMenu.cpp +++ b/libraries/ui/src/VrMenu.cpp @@ -115,7 +115,7 @@ private: VrMenu::VrMenu(OffscreenUi* parent) : QObject(parent) { _rootMenu = parent->getRootItem()->findChild("rootMenu"); - parent->getRootContext()->setContextProperty("rootMenu", _rootMenu); + parent->getSurfaceContext()->setContextProperty("rootMenu", _rootMenu); } QObject* VrMenu::findMenuObject(const QString& menuOption) { From 90d241ca3c643ff5d0adec8afc5dbd4de83200b6 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Tue, 6 Jun 2017 09:10:46 -0700 Subject: [PATCH 70/73] Account for avatar scale --- scripts/system/controllers/teleport.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/controllers/teleport.js b/scripts/system/controllers/teleport.js index d6248fc6e0..b058ec670f 100644 --- a/scripts/system/controllers/teleport.js +++ b/scripts/system/controllers/teleport.js @@ -383,7 +383,7 @@ function getAvatarFootOffset() { // default vertical offset from foot to avatar root. return -MyAvatar.getAbsoluteDefaultJointTranslationInObjectFrame(footJointIndex).y; } else { - return DEFAULT_ROOT_TO_FOOT_OFFSET; + return DEFAULT_ROOT_TO_FOOT_OFFSET * MyAvatar.scale; } } From c3621d7c325c634d2b53e09eec78641b4ed0454f Mon Sep 17 00:00:00 2001 From: NeetBhagat Date: Tue, 6 Jun 2017 22:31:14 +0530 Subject: [PATCH 71/73] Resolved two issues: 1) While in HMD mode -> open Tablet -> Click Desktop. Desktop mode will be on. 2) Menu sync problem while switching modes. --- interface/src/Application.cpp | 13 +++++++------ interface/src/Application.h | 2 +- .../src/display-plugins/OpenGLDisplayPlugin.cpp | 6 +++--- .../src/display-plugins/OpenGLDisplayPlugin.h | 4 ++-- libraries/plugins/src/plugins/Plugin.h | 14 +++++++------- plugins/oculus/src/OculusBaseDisplayPlugin.cpp | 4 +--- plugins/oculus/src/OculusBaseDisplayPlugin.h | 2 +- 7 files changed, 22 insertions(+), 23 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c681f99ee2..314c51a4f2 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1360,7 +1360,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo if (_autoSwitchDisplayModeSupportedHMDPlugin) { if (getActiveDisplayPlugin() != _autoSwitchDisplayModeSupportedHMDPlugin && - !_autoSwitchDisplayModeSupportedHMDPlugin->isStandBySessionActive()) { + !_autoSwitchDisplayModeSupportedHMDPlugin->isSessionActive()) { startHMDStandBySession(); } // Poll periodically to check whether the user has worn HMD or not. Switch Display mode accordingly. @@ -1602,8 +1602,8 @@ void Application::aboutToQuit() { getActiveDisplayPlugin()->deactivate(); if (_autoSwitchDisplayModeSupportedHMDPlugin - && _autoSwitchDisplayModeSupportedHMDPlugin->isStandBySessionActive()) { - _autoSwitchDisplayModeSupportedHMDPlugin->endStandBySession(); + && _autoSwitchDisplayModeSupportedHMDPlugin->isSessionActive()) { + _autoSwitchDisplayModeSupportedHMDPlugin->endSession(); } // use the CloseEventSender via a QThread to send an event that says the user asked for the app to close auto closeEventSender = DependencyManager::get(); @@ -6827,13 +6827,14 @@ void Application::switchDisplayMode() { // Switch to respective mode as soon as currentHMDWornStatus changes if (currentHMDWornStatus) { qCDebug(interfaceapp) << "Switching from Desktop to HMD mode"; - endHMDStandBySession(); + endHMDSession(); setActiveDisplayPlugin(_autoSwitchDisplayModeSupportedHMDPluginName); } else { qCDebug(interfaceapp) << "Switching from HMD to desktop mode"; setActiveDisplayPlugin(DESKTOP_DISPLAY_PLUGIN_NAME); startHMDStandBySession(); } + emit activeDisplayPluginChanged(); } _previousHMDWornStatus = currentHMDWornStatus; } @@ -6842,8 +6843,8 @@ void Application::startHMDStandBySession() { _autoSwitchDisplayModeSupportedHMDPlugin->startStandBySession(); } -void Application::endHMDStandBySession() { - _autoSwitchDisplayModeSupportedHMDPlugin->endStandBySession(); +void Application::endHMDSession() { + _autoSwitchDisplayModeSupportedHMDPlugin->endSession(); } mat4 Application::getEyeProjection(int eye) const { diff --git a/interface/src/Application.h b/interface/src/Application.h index 4cd47ada58..46e5e882a4 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -685,6 +685,6 @@ private: QString _autoSwitchDisplayModeSupportedHMDPluginName; bool _previousHMDWornStatus; void startHMDStandBySession(); - void endHMDStandBySession(); + void endHMDSession(); }; #endif // hifi_Application_h diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index fbdc1ad71e..bfd158ffb5 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -346,9 +346,9 @@ bool OpenGLDisplayPlugin::startStandBySession() { return Parent::startStandBySession(); } -void OpenGLDisplayPlugin::endStandBySession() { - deactivateStandBySession(); - Parent::endStandBySession(); +void OpenGLDisplayPlugin::endSession() { + deactivateSession(); + Parent::endSession(); } void OpenGLDisplayPlugin::customizeContext() { diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h index 9681158c55..10a7558398 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h @@ -43,7 +43,7 @@ public: bool activate() override final; void deactivate() override final; bool startStandBySession() override final; - void endStandBySession() override final; + void endSession() override final; bool eventFilter(QObject* receiver, QEvent* event) override; bool isDisplayVisible() const override { return true; } @@ -104,7 +104,7 @@ protected: // Returns true on successful activation of standby session virtual bool activateStandBySession() { return true; } - virtual void deactivateStandBySession() {} + virtual void deactivateSession() {} // Plugin specific functionality to send the composed scene to the output window or device virtual void internalPresent(); diff --git a/libraries/plugins/src/plugins/Plugin.h b/libraries/plugins/src/plugins/Plugin.h index 11ea79186a..2d4a24a1fe 100644 --- a/libraries/plugins/src/plugins/Plugin.h +++ b/libraries/plugins/src/plugins/Plugin.h @@ -54,16 +54,16 @@ public: return _active; } virtual bool startStandBySession() { - _standbysessionstatus = true; - return _standbysessionstatus; + _sessionStatus = true; + return _sessionStatus; } - virtual void endStandBySession() { - _standbysessionstatus = false; + virtual void endSession() { + _sessionStatus = false; } - virtual bool isStandBySessionActive() { - return _standbysessionstatus; + virtual bool isSessionActive() { + return _sessionStatus; } /** @@ -85,7 +85,7 @@ signals: protected: bool _active { false }; - bool _standbysessionstatus { false }; + bool _sessionStatus { false }; PluginContainer* _container { nullptr }; static const char* UNKNOWN_PLUGIN_ID; diff --git a/plugins/oculus/src/OculusBaseDisplayPlugin.cpp b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp index df98abf408..93f4787f0f 100644 --- a/plugins/oculus/src/OculusBaseDisplayPlugin.cpp +++ b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp @@ -123,8 +123,6 @@ bool OculusBaseDisplayPlugin::internalActivate() { void OculusBaseDisplayPlugin::internalDeactivate() { Parent::internalDeactivate(); - releaseOculusSession(); - _session = nullptr; } bool OculusBaseDisplayPlugin::activateStandBySession() { @@ -134,7 +132,7 @@ bool OculusBaseDisplayPlugin::activateStandBySession() { } return true; } -void OculusBaseDisplayPlugin::deactivateStandBySession() { +void OculusBaseDisplayPlugin::deactivateSession() { releaseOculusSession(); _session = nullptr; } diff --git a/plugins/oculus/src/OculusBaseDisplayPlugin.h b/plugins/oculus/src/OculusBaseDisplayPlugin.h index bfdcc5db1e..5230b11681 100644 --- a/plugins/oculus/src/OculusBaseDisplayPlugin.h +++ b/plugins/oculus/src/OculusBaseDisplayPlugin.h @@ -35,7 +35,7 @@ protected: bool internalActivate() override; void internalDeactivate() override; bool activateStandBySession() override; - void deactivateStandBySession() override; + void deactivateSession() override; void updatePresentPose() override; protected: From 40823bf5827526f6aae65bd89718c624bf63a724 Mon Sep 17 00:00:00 2001 From: seefo Date: Tue, 6 Jun 2017 10:11:46 -0700 Subject: [PATCH 72/73] Updated Windows build guide's markdown --- BUILD_WIN.md | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/BUILD_WIN.md b/BUILD_WIN.md index 311dfd9267..7c3f18592a 100644 --- a/BUILD_WIN.md +++ b/BUILD_WIN.md @@ -1,5 +1,7 @@ This is a stand-alone guide for creating your first High Fidelity build for Windows 64-bit. +## Building High Fidelity + ### Step 1. Installing Visual Studio 2013 If you don't already have the Community or Professional edition of Visual Studio 2013, download and install [Visual Studio Community 2013](https://www.visualstudio.com/en-us/news/releasenotes/vs2013-community-vs). You do not need to install any of the optional components when going through the installer. @@ -18,8 +20,8 @@ Keep the default components checked when going through the installer. ### Step 4. Setting Qt Environment Variable -Go to "Control Panel > System > Advanced System Settings > Environment Variables > New..." (or search “Environment Variables” in Start Search). -* Set "Variable name": QT_CMAKE_PREFIX_PATH +Go to `Control Panel > System > Advanced System Settings > Environment Variables > New...` (or search “Environment Variables” in Start Search). +* Set "Variable name": `QT_CMAKE_PREFIX_PATH` * Set "Variable value": `%QT_DIR%\5.6\msvc2013_64\lib\cmake` ### Step 5. Installing OpenSSL @@ -29,34 +31,36 @@ Download and install the [Win64 OpenSSL v1.0.2L Installer](https://slproweb.com/ ### Step 6. Running CMake to Generate Build Files Run Command Prompt from Start and run the following commands: - cd "%HIFI_DIR%" - mkdir build - cd build - cmake .. -G "Visual Studio 12 Win64" + +> cd "%HIFI_DIR%" +> mkdir build +> cd build +> cmake .. -G "Visual Studio 12 Win64" + -Where %HIFI_DIR% is the directory for the highfidelity repository. +Where `%HIFI_DIR%` is the directory for the highfidelity repository. ### Step 7. Making a Build -Open '%HIFI_DIR%\build\hifi.sln' using Visual Studio. +Open `%HIFI_DIR%\build\hifi.sln` using Visual Studio. Change the Solution Configuration (next to the green play button) from "Debug" to "Release" for best performance. -Run Build > Build Solution. +Run `Build > Build Solution`. ### Step 8. Testing Interface Create another environment variable (see Step #4) -* Set "Variable name": _NO_DEBUG_HEAP -* Set "Variable value": 1 +* Set "Variable name": `_NO_DEBUG_HEAP` +* Set "Variable value": `1` -In Visual Studio, right+click "interface" under the Apps folder in Solution Explorer and select "Set as Startup Project". Run Debug > Start Debugging. +In Visual Studio, right+click "interface" under the Apps folder in Solution Explorer and select "Set as Startup Project". Run `Debug > Start Debugging`. Now, you should have a full build of High Fidelity and be able to run the Interface using Visual Studio. Please check our [Docs](https://wiki.highfidelity.com/wiki/Main_Page) for more information regarding the programming workflow. -Note: You can also run Interface by launching it from command line or File Explorer from %HIFI_DIR%\build\interface\Release\interface.exe +Note: You can also run Interface by launching it from command line or File Explorer from `%HIFI_DIR%\build\interface\Release\interface.exe` -### Troubleshooting +## Troubleshooting For any problems after Step #6, first try this: * Delete your locally cloned copy of the highfidelity repository @@ -66,16 +70,16 @@ For any problems after Step #6, first try this: #### CMake gives you the same error message repeatedly after the build fails -Remove `CMakeCache.txt` found in the '%HIFI_DIR%\build' directory +Remove `CMakeCache.txt` found in the `%HIFI_DIR%\build` directory. #### nmake cannot be found Make sure nmake.exe is located at the following path: + C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin If not, add the directory where nmake is located to the PATH environment variable. #### Qt is throwing an error -Make sure you have the correct version (5.6.2) installed and 'QT_CMAKE_PREFIX_PATH' environment variable is set correctly. - +Make sure you have the correct version (5.6.2) installed and `QT_CMAKE_PREFIX_PATH` environment variable is set correctly. From aa13812e3fcb48453c78955b91ed07650e1043d3 Mon Sep 17 00:00:00 2001 From: seefo Date: Tue, 6 Jun 2017 15:20:26 -0700 Subject: [PATCH 73/73] Fixed multiline in BUILD_WIN.md --- BUILD_WIN.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/BUILD_WIN.md b/BUILD_WIN.md index 7c3f18592a..818a176f75 100644 --- a/BUILD_WIN.md +++ b/BUILD_WIN.md @@ -31,12 +31,12 @@ Download and install the [Win64 OpenSSL v1.0.2L Installer](https://slproweb.com/ ### Step 6. Running CMake to Generate Build Files Run Command Prompt from Start and run the following commands: - -> cd "%HIFI_DIR%" -> mkdir build -> cd build -> cmake .. -G "Visual Studio 12 Win64" - +```` +cd "%HIFI_DIR%" +mkdir build +cd build +cmake .. -G "Visual Studio 12 Win64" +```` Where `%HIFI_DIR%` is the directory for the highfidelity repository.