Merge pull request #12947 from jherico/feature/splash2

Additional work on splash screen
This commit is contained in:
John Conklin II 2018-05-11 11:26:37 -07:00 committed by GitHub
commit 5cd225e4de
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 235 additions and 109 deletions

View file

@ -0,0 +1,47 @@
const vec3 COLOR = vec3(0x00, 0xD8, 0x02) / vec3(0xFF);
const float CUTOFF = 0.65;
const float NOISE_MULT = 8.0;
const float NOISE_POWER = 1.0;
float noise4D(vec4 p) {
return fract(sin(dot(p ,vec4(12.9898,78.233,126.7235, 593.2241))) * 43758.5453);
}
float worley4D(vec4 p) {
float r = 3.0;
vec4 f = floor(p);
vec4 x = fract(p);
for(int i = -1; i<=1; i++)
{
for(int j = -1; j<=1; j++)
{
for(int k = -1; k<=1; k++)
{
for (int l = -1; l <= 1; l++) {
vec4 q = vec4(float(i),float(j),float(k), float(l));
vec4 v = q + vec4(noise4D((q+f)*1.11), noise4D((q+f)*1.14), noise4D((q+f)*1.17), noise4D((q+f)*1.20)) - x;
float d = dot(v, v);
r = min(r, d);
}
}
}
}
return sqrt(r);
}
vec3 mainColor(vec3 direction) {
float n = worley4D(vec4(direction * NOISE_MULT, iGlobalTime / 3.0));
n = 1.0 - n;
n = pow(n, NOISE_POWER);
if (n < CUTOFF) {
return vec3(0.0);
}
n = (n - CUTOFF) / (1.0 - CUTOFF);
return COLOR * (1.0 - n);
}
vec3 getSkyboxColor() {
return mainColor(normalize(_normal));
}

View file

@ -144,6 +144,7 @@
#include <trackers/EyeTracker.h>
#include <avatars-renderer/ScriptAvatar.h>
#include <RenderableEntityItem.h>
#include <procedural/ProceduralSkybox.h>
#include "AudioClient.h"
#include "audio/AudioScope.h"
@ -375,7 +376,7 @@ Setting::Handle<int> 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 DESKTOP_DISPLAY_PLUGIN_NAME = "Desktop";
static const QString ACTIVE_DISPLAY_PLUGIN_SETTING_NAME = "activeDisplayPlugin";
static const QString SYSTEM_TABLET = "com.highfidelity.interface.tablet.system";
const std::vector<std::pair<QString, Application::AcceptURLMethod>> Application::_acceptedExtensions {
@ -1349,10 +1350,14 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
QCoreApplication::processEvents();
_glWidget->createContext();
// Create the main thread context, the GPU backend, and the display plugins
// Create the main thread context, the GPU backend
initializeGL();
DependencyManager::get<TextureCache>()->setGPUContext(_gpuContext);
qCDebug(interfaceapp, "Initialized Display.");
qCDebug(interfaceapp, "Initialized GL");
// Initialize the display plugin architecture
initializeDisplayPlugins();
qCDebug(interfaceapp, "Initialized Display");
// Create the rendering engine. This can be slow on some machines due to lots of
// GPU pipeline creation.
initializeRenderEngine();
@ -2372,6 +2377,10 @@ void Application::onAboutToQuit() {
}
}
// The active display plugin needs to be loaded before the menu system is active,
// so its persisted explicitly here
Setting::Handle<QString>{ ACTIVE_DISPLAY_PLUGIN_SETTING_NAME }.set(getActiveDisplayPlugin()->getName());
getActiveDisplayPlugin()->deactivate();
if (_autoSwitchDisplayModeSupportedHMDPlugin
&& _autoSwitchDisplayModeSupportedHMDPlugin->isSessionActive()) {
@ -2611,10 +2620,84 @@ void Application::initializeGL() {
_glWidget->makeCurrent();
_gpuContext = std::make_shared<gpu::Context>();
DependencyManager::get<TextureCache>()->setGPUContext(_gpuContext);
// Restore the default main thread context
_offscreenContext->makeCurrent();
}
updateDisplayMode();
static const QString SPLASH_SKYBOX{ "{\"ProceduralEntity\":{ \"version\":2, \"shaderUrl\":\"qrc:///shaders/splashSkybox.frag\" } }" };
void Application::initializeDisplayPlugins() {
auto displayPlugins = PluginManager::getInstance()->getDisplayPlugins();
Setting::Handle<QString> activeDisplayPluginSetting{ ACTIVE_DISPLAY_PLUGIN_SETTING_NAME, displayPlugins.at(0)->getName() };
auto lastActiveDisplayPluginName = activeDisplayPluginSetting.get();
auto defaultDisplayPlugin = displayPlugins.at(0);
// Once time initialization code
DisplayPluginPointer targetDisplayPlugin;
foreach(auto displayPlugin, displayPlugins) {
displayPlugin->setContext(_gpuContext);
if (displayPlugin->getName() == lastActiveDisplayPluginName) {
targetDisplayPlugin = displayPlugin;
}
QObject::connect(displayPlugin.get(), &DisplayPlugin::recommendedFramebufferSizeChanged,
[this](const QSize& size) { resizeGL(); });
QObject::connect(displayPlugin.get(), &DisplayPlugin::resetSensorsRequested, this, &Application::requestReset);
}
// The default display plugin needs to be activated first, otherwise the display plugin thread
// may be launched by an external plugin, which is bad
setDisplayPlugin(defaultDisplayPlugin);
// Now set the desired plugin if it's not the same as the default plugin
if (targetDisplayPlugin != defaultDisplayPlugin) {
setDisplayPlugin(targetDisplayPlugin);
}
// Submit a default frame to render until the engine starts up
updateRenderArgs(0.0f);
_offscreenContext->makeCurrent();
#define ENABLE_SPLASH_FRAME 0
#if ENABLE_SPLASH_FRAME
{
QMutexLocker viewLocker(&_renderArgsMutex);
if (_appRenderArgs._isStereo) {
_gpuContext->enableStereo(true);
_gpuContext->setStereoProjections(_appRenderArgs._eyeProjections);
_gpuContext->setStereoViews(_appRenderArgs._eyeOffsets);
}
// Frame resources
auto framebufferCache = DependencyManager::get<FramebufferCache>();
gpu::FramebufferPointer finalFramebuffer = framebufferCache->getFramebuffer();
std::shared_ptr<ProceduralSkybox> procedural = std::make_shared<ProceduralSkybox>();
procedural->parse(SPLASH_SKYBOX);
_gpuContext->beginFrame(_appRenderArgs._view, _appRenderArgs._headPose);
gpu::doInBatch("splashFrame", _gpuContext, [&](gpu::Batch& batch) {
batch.resetStages();
batch.enableStereo(false);
batch.setFramebuffer(finalFramebuffer);
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, { 0, 0, 0, 1 });
batch.enableSkybox(true);
batch.enableStereo(_appRenderArgs._isStereo);
batch.setViewportTransform({ 0, 0, finalFramebuffer->getSize() });
procedural->render(batch, _appRenderArgs._renderArgs.getViewFrustum());
});
auto frame = _gpuContext->endFrame();
frame->frameIndex = 0;
frame->framebuffer = finalFramebuffer;
frame->pose = _appRenderArgs._headPose;
frame->framebufferRecycler = [framebufferCache, procedural](const gpu::FramebufferPointer& framebuffer) {
framebufferCache->releaseFramebuffer(framebuffer);
};
_displayPlugin->submitFrame(frame);
}
#endif
}
void Application::initializeRenderEngine() {
@ -2638,6 +2721,7 @@ void Application::initializeRenderEngine() {
}
extern void setupPreferences();
static void addDisplayPluginToMenu(const DisplayPluginPointer& displayPlugin, bool active);
void Application::initializeUi() {
// Build a shared canvas / context for the Chromium processes
@ -2779,10 +2863,25 @@ void Application::initializeUi() {
offscreenSurfaceCache->reserve(TabletScriptingInterface::QML, 1);
offscreenSurfaceCache->reserve(Web3DOverlay::QML, 2);
// Now that the menu is instantiated, ensure the display plugin menu is properly updated
updateDisplayMode();
flushMenuUpdates();
// Now that the menu is instantiated, ensure the display plugin menu is properly updated
{
auto displayPlugins = PluginManager::getInstance()->getDisplayPlugins();
// first sort the plugins into groupings: standard, advanced, developer
std::stable_sort(displayPlugins.begin(), displayPlugins.end(),
[](const DisplayPluginPointer& a, const DisplayPluginPointer& b)->bool { return a->getGrouping() < b->getGrouping(); });
// concatenate the groupings into a single list in the order: standard, advanced, developer
for(const auto& displayPlugin : displayPlugins) {
addDisplayPluginToMenu(displayPlugin, _displayPlugin == displayPlugin);
}
// after all plugins have been added to the menu, add a separator to the menu
auto parent = getPrimaryMenu()->getMenu(MenuOption::OutputMenu);
parent->addSeparator();
}
// The display plugins are created before the menu now, so we need to do this here to hide the menu bar
// now that it exists
if (_window && _window->isFullScreen()) {
@ -2933,7 +3032,7 @@ void Application::updateCamera(RenderArgs& renderArgs, float deltaTime) {
_thirdPersonHMDCameraBoomValid = false;
_myCamera.setOrientation(myAvatar->getHead()->getOrientation());
if (Menu::getInstance()->isOptionChecked(MenuOption::CenterPlayerInView)) {
if (isOptionChecked(MenuOption::CenterPlayerInView)) {
_myCamera.setPosition(myAvatar->getDefaultEyePosition()
+ _myCamera.getOrientation() * boomOffset);
}
@ -5735,6 +5834,32 @@ void Application::update(float deltaTime) {
}
updateRenderArgs(deltaTime);
// HACK
// load the view frustum
// FIXME: This preDisplayRender call is temporary until we create a separate render::scene for the mirror rendering.
// Then we can move this logic into the Avatar::simulate call.
myAvatar->preDisplaySide(&_appRenderArgs._renderArgs);
{
PerformanceTimer perfTimer("limitless");
AnimDebugDraw::getInstance().update();
}
{
PerformanceTimer perfTimer("limitless");
DependencyManager::get<LimitlessVoiceRecognitionScriptingInterface>()->update();
}
{ // Game loop is done, mark the end of the frame for the scene transactions and the render loop to take over
PerformanceTimer perfTimer("enqueueFrame");
getMain3DScene()->enqueueFrame();
}
}
void Application::updateRenderArgs(float deltaTime) {
editRenderArgs([this, deltaTime](AppRenderArgs& appRenderArgs) {
PerformanceTimer perfTimer("editRenderArgs");
appRenderArgs._headPose = getHMDSensorPose();
@ -5758,9 +5883,9 @@ void Application::update(float deltaTime) {
QMutexLocker viewLocker(&_viewMutex);
// adjust near clip plane to account for sensor scaling.
auto adjustedProjection = glm::perspective(glm::radians(_fieldOfView.get()),
getActiveDisplayPlugin()->getRecommendedAspectRatio(),
DEFAULT_NEAR_CLIP * sensorToWorldScale,
DEFAULT_FAR_CLIP);
getActiveDisplayPlugin()->getRecommendedAspectRatio(),
DEFAULT_NEAR_CLIP * sensorToWorldScale,
DEFAULT_FAR_CLIP);
_viewFrustum.setProjection(adjustedProjection);
_viewFrustum.calculate();
}
@ -5776,8 +5901,14 @@ void Application::update(float deltaTime) {
}
{
PROFILE_RANGE(render, "/resizeGL");
PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings));
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
bool showWarnings = false;
bool suppressShortTimings = false;
auto menu = Menu::getInstance();
if (menu) {
suppressShortTimings = menu->isOptionChecked(MenuOption::SuppressShortTimings);
showWarnings = menu->isOptionChecked(MenuOption::PipelineWarnings);
}
PerformanceWarning::setSuppressShortTimings(suppressShortTimings);
PerformanceWarning warn(showWarnings, "Application::paintGL()");
resizeGL();
}
@ -5833,12 +5964,6 @@ void Application::update(float deltaTime) {
}
}
// HACK
// load the view frustum
// FIXME: This preDisplayRender call is temporary until we create a separate render::scene for the mirror rendering.
// Then we can move this logic into the Avatar::simulate call.
myAvatar->preDisplaySide(&appRenderArgs._renderArgs);
{
QMutexLocker viewLocker(&_viewMutex);
_myCamera.loadViewFrustum(_displayViewFrustum);
@ -5850,21 +5975,6 @@ void Application::update(float deltaTime) {
appRenderArgs._renderArgs.setViewFrustum(_displayViewFrustum);
}
});
{
PerformanceTimer perfTimer("limitless");
AnimDebugDraw::getInstance().update();
}
{
PerformanceTimer perfTimer("limitless");
DependencyManager::get<LimitlessVoiceRecognitionScriptingInterface>()->update();
}
{ // Game loop is done, mark the end of the frame for the scene transactions and the render loop to take over
PerformanceTimer perfTimer("enqueueFrame");
getMain3DScene()->enqueueFrame();
}
}
void Application::queryAvatars() {
@ -7505,15 +7615,19 @@ void Application::shareSnapshot(const QString& path, const QUrl& href) {
}
float Application::getRenderResolutionScale() const {
if (Menu::getInstance()->isOptionChecked(MenuOption::RenderResolutionOne)) {
auto menu = Menu::getInstance();
if (!menu) {
return 1.0f;
} else if (Menu::getInstance()->isOptionChecked(MenuOption::RenderResolutionTwoThird)) {
}
if (menu->isOptionChecked(MenuOption::RenderResolutionOne)) {
return 1.0f;
} else if (menu->isOptionChecked(MenuOption::RenderResolutionTwoThird)) {
return 0.666f;
} else if (Menu::getInstance()->isOptionChecked(MenuOption::RenderResolutionHalf)) {
} else if (menu->isOptionChecked(MenuOption::RenderResolutionHalf)) {
return 0.5f;
} else if (Menu::getInstance()->isOptionChecked(MenuOption::RenderResolutionThird)) {
} else if (menu->isOptionChecked(MenuOption::RenderResolutionThird)) {
return 0.333f;
} else if (Menu::getInstance()->isOptionChecked(MenuOption::RenderResolutionQuarter)) {
} else if (menu->isOptionChecked(MenuOption::RenderResolutionQuarter)) {
return 0.25f;
} else {
return 1.0f;
@ -7737,7 +7851,7 @@ DisplayPluginPointer Application::getActiveDisplayPlugin() const {
static const char* EXCLUSION_GROUP_KEY = "exclusionGroup";
static void addDisplayPluginToMenu(DisplayPluginPointer displayPlugin, bool active = false) {
static void addDisplayPluginToMenu(const DisplayPluginPointer& displayPlugin, bool active) {
auto menu = Menu::getInstance();
QString name = displayPlugin->getName();
auto grouping = displayPlugin->getGrouping();
@ -7782,65 +7896,12 @@ void Application::updateDisplayMode() {
qFatal("Attempted to switch display plugins from a non-main thread");
}
auto displayPlugins = PluginManager::getInstance()->getDisplayPlugins();
// Once time initialization code
static std::once_flag once;
std::call_once(once, [&] {
foreach(auto displayPlugin, displayPlugins) {
displayPlugin->setContext(_gpuContext);
QObject::connect(displayPlugin.get(), &DisplayPlugin::recommendedFramebufferSizeChanged,
[this](const QSize& size) { resizeGL(); });
QObject::connect(displayPlugin.get(), &DisplayPlugin::resetSensorsRequested, this, &Application::requestReset);
}
});
// Once time initialization code that depends on the UI being available
auto menu = Menu::getInstance();
if (menu) {
static std::once_flag onceUi;
std::call_once(onceUi, [&] {
bool first = true;
// first sort the plugins into groupings: standard, advanced, developer
DisplayPluginList standard;
DisplayPluginList advanced;
DisplayPluginList developer;
foreach(auto displayPlugin, displayPlugins) {
displayPlugin->setContext(_gpuContext);
auto grouping = displayPlugin->getGrouping();
switch (grouping) {
case Plugin::ADVANCED:
advanced.push_back(displayPlugin);
break;
case Plugin::DEVELOPER:
developer.push_back(displayPlugin);
break;
default:
standard.push_back(displayPlugin);
break;
}
}
// concatenate the groupings into a single list in the order: standard, advanced, developer
standard.insert(std::end(standard), std::begin(advanced), std::end(advanced));
standard.insert(std::end(standard), std::begin(developer), std::end(developer));
foreach(auto displayPlugin, standard) {
addDisplayPluginToMenu(displayPlugin, first);
first = false;
}
// after all plugins have been added to the menu, add a separator to the menu
auto parent = menu->getMenu(MenuOption::OutputMenu);
parent->addSeparator();
});
}
auto displayPlugins = getDisplayPlugins();
// Default to the first item on the list, in case none of the menu items match
DisplayPluginPointer newDisplayPlugin = displayPlugins.at(0);
auto menu = getPrimaryMenu();
if (menu) {
foreach(DisplayPluginPointer displayPlugin, PluginManager::getInstance()->getDisplayPlugins()) {
QString name = displayPlugin->getName();
@ -7864,6 +7925,14 @@ void Application::updateDisplayMode() {
}
void Application::setDisplayPlugin(DisplayPluginPointer newDisplayPlugin) {
if (newDisplayPlugin == _displayPlugin) {
return;
}
// FIXME don't have the application directly set the state of the UI,
// instead emit a signal that the display plugin is changing and let
// the desktop lock itself. Reduces coupling between the UI and display
// plugins
auto offscreenUi = DependencyManager::get<OffscreenUi>();
auto desktop = offscreenUi->getDesktop();
auto menu = Menu::getInstance();
@ -7874,8 +7943,8 @@ void Application::setDisplayPlugin(DisplayPluginPointer newDisplayPlugin) {
bool wasRepositionLocked = false;
if (desktop) {
// Tell the desktop to no reposition (which requires plugin info), until we have set the new plugin, below.
wasRepositionLocked = offscreenUi->getDesktop()->property("repositionLocked").toBool();
offscreenUi->getDesktop()->setProperty("repositionLocked", true);
wasRepositionLocked = desktop->property("repositionLocked").toBool();
desktop->setProperty("repositionLocked", true);
}
if (_displayPlugin) {

View file

@ -148,6 +148,7 @@ public:
Q_INVOKABLE QString getUserAgent();
void initializeGL();
void initializeDisplayPlugins();
void initializeRenderEngine();
void initializeUi();
@ -671,6 +672,7 @@ private:
using RenderArgsEditor = std::function <void (AppRenderArgs&)>;
void editRenderArgs(RenderArgsEditor editor);
void updateRenderArgs(float deltaTime);
Overlays _overlays;

View file

@ -13,8 +13,9 @@
#include <display-plugins/CompositorHelper.h>
#include <FramebufferCache.h>
#include "ui/Stats.h"
#include <plugins/PluginManager.h>
#include <SceneScriptingInterface.h>
#include "ui/Stats.h"
#include "Util.h"
@ -233,3 +234,4 @@ void Application::runRenderFrame(RenderArgs* renderArgs) {
_renderEngine->run();
}
}

View file

@ -2039,7 +2039,7 @@ void MyAvatar::postUpdate(float deltaTime, const render::ScenePointer& scene) {
}
}
void MyAvatar::preDisplaySide(RenderArgs* renderArgs) {
void MyAvatar::preDisplaySide(const RenderArgs* renderArgs) {
// toggle using the cauterizedBones depending on where the camera is and the rendering pass type.
const bool shouldDrawHead = shouldRenderHead(renderArgs);

View file

@ -272,7 +272,7 @@ public:
void update(float deltaTime);
virtual void postUpdate(float deltaTime, const render::ScenePointer& scene) override;
void preDisplaySide(RenderArgs* renderArgs);
void preDisplaySide(const RenderArgs* renderArgs);
const glm::mat4& getHMDSensorMatrix() const { return _hmdSensorMatrix; }
const glm::vec3& getHMDSensorPosition() const { return _hmdSensorPosition; }

View file

@ -336,9 +336,8 @@ void OpenGLDisplayPlugin::deactivate() {
_container->showDisplayPluginsTools(false);
if (!_container->currentDisplayActions().isEmpty()) {
auto menu = _container->getPrimaryMenu();
foreach(auto itemInfo, _container->currentDisplayActions()) {
menu->removeMenuItem(itemInfo.first, itemInfo.second);
_container->removeMenuItem(itemInfo.first, itemInfo.second);
}
_container->currentDisplayActions().clear();
}

View file

@ -19,7 +19,7 @@
#include <SharedUtil.h>
#include <NumericalConstants.h>
#include <GLMHelpers.h>
#include <NetworkingConstants.h>
#include "ProceduralCommon_frag.h"
#include "Logging.h"
@ -178,6 +178,8 @@ void Procedural::setProceduralData(const ProceduralData& proceduralData) {
return;
}
_shaderPath = shaderUrl.toLocalFile();
} else if (shaderUrl.scheme() == URL_SCHEME_QRC) {
_shaderPath = ":" + shaderUrl.path();
} else {
_networkShader = ShaderCache::instance().getShader(shaderUrl);
}

View file

@ -54,6 +54,12 @@ public:
void setFullscreen(const QScreen* targetScreen, bool hideMenu = false);
void unsetFullscreen(const QScreen* avoidScreen = nullptr);
// FIXME remove access tot he menu from the plugin container
// Instead let display plugins expose a structure about the kinds
// of actions and menu items they want to have appear when they are
// active and allow the application to act on that when the display
// plugin becomes active (or when the UI is initialized, and a
// display plugin is already active)
virtual ui::Menu* getPrimaryMenu() = 0;
virtual void showDisplayPluginsTools(bool show = true) = 0;
virtual void requestReset() = 0;

View file

@ -166,12 +166,11 @@ void OculusBaseDisplayPlugin::deactivateSession() {
//_session = nullptr;
}
void OculusBaseDisplayPlugin::updatePresentPose() {
//mat4 sensorResetMat;
//_currentPresentFrameInfo.sensorSampleTime = ovr_GetTimeInSeconds();
//_currentPresentFrameInfo.predictedDisplayTime = ovr_GetPredictedDisplayTime(_session, _currentFrame->frameIndex);
//auto trackingState = ovr_GetTrackingState(_session, _currentRenderFrameInfo.predictedDisplayTime, ovrFalse);
//_currentPresentFrameInfo.presentPose = toGlm(trackingState.HeadPose.ThePose);
_currentPresentFrameInfo.presentPose = _currentPresentFrameInfo.renderPose;
_currentPresentFrameInfo.sensorSampleTime = ovr_GetTimeInSeconds();
_currentPresentFrameInfo.predictedDisplayTime = ovr_GetPredictedDisplayTime(_session, 0);
auto trackingState = ovr_GetTrackingState(_session, _currentRenderFrameInfo.predictedDisplayTime, ovrFalse);
_currentPresentFrameInfo.presentPose = toGlm(trackingState.HeadPose.ThePose);
_currentPresentFrameInfo.renderPose = _currentPresentFrameInfo.presentPose;
}
OculusBaseDisplayPlugin::~OculusBaseDisplayPlugin() {