mirror of
https://github.com/overte-org/overte.git
synced 2025-04-08 08:14:48 +02:00
Stereo rendering work
This commit is contained in:
parent
fe44442ffe
commit
d3135dcfa6
24 changed files with 397 additions and 202 deletions
|
@ -58,6 +58,8 @@
|
|||
#include <AutoUpdater.h>
|
||||
#include <DeferredLightingEffect.h>
|
||||
#include <DependencyManager.h>
|
||||
#include <plugins/PluginContainer.h>
|
||||
#include <plugins/PluginManager.h>
|
||||
#include <display-plugins/DisplayPlugin.h>
|
||||
|
||||
#include <EntityScriptingInterface.h>
|
||||
|
@ -148,6 +150,8 @@
|
|||
|
||||
#include "ui/overlays/Cube3DOverlay.h"
|
||||
|
||||
#include "PluginContainerProxy.h"
|
||||
|
||||
// ON WIndows PC, NVidia Optimus laptop, we want to enable NVIDIA GPU
|
||||
// FIXME seems to be broken.
|
||||
#if defined(Q_OS_WIN)
|
||||
|
@ -301,7 +305,7 @@ bool setupEssentials(int& argc, char** argv) {
|
|||
// continuing to overburden Application.cpp
|
||||
Cube3DOverlay* _keyboardFocusHighlight{ nullptr };
|
||||
int _keyboardFocusHighlightID{ -1 };
|
||||
|
||||
PluginContainer* _pluginContainer;
|
||||
|
||||
Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
||||
QApplication(argc, argv),
|
||||
|
@ -351,7 +355,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
|||
_applicationOverlay()
|
||||
{
|
||||
setInstance(this);
|
||||
Plugin::setContainer(this);
|
||||
|
||||
_pluginContainer = new PluginContainerProxy();
|
||||
Plugin::setContainer(_pluginContainer);
|
||||
#ifdef Q_OS_WIN
|
||||
installNativeEventFilter(&MyNativeEventFilter::getInstance());
|
||||
#endif
|
||||
|
@ -1262,6 +1268,7 @@ void Application::resizeGL() {
|
|||
// Possible change in aspect ratio
|
||||
loadViewFrustum(_myCamera, _viewFrustum);
|
||||
float fov = glm::radians(DEFAULT_FIELD_OF_VIEW_DEGREES);
|
||||
// FIXME the aspect ratio for stereo displays is incorrect based on this.
|
||||
float aspectRatio = aspect(_renderResolution);
|
||||
_myCamera.setProjection(glm::perspective(fov, aspectRatio, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP));
|
||||
}
|
||||
|
@ -1421,7 +1428,15 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
|||
break;
|
||||
case Qt::Key_Enter:
|
||||
case Qt::Key_Return:
|
||||
Menu::getInstance()->triggerOption(MenuOption::AddressBar);
|
||||
if (isOption) {
|
||||
if (_window->isFullScreen()) {
|
||||
_pluginContainer->unsetFullscreen();
|
||||
} else {
|
||||
_pluginContainer->setFullscreen(nullptr);
|
||||
}
|
||||
} else {
|
||||
Menu::getInstance()->triggerOption(MenuOption::AddressBar);
|
||||
}
|
||||
break;
|
||||
|
||||
case Qt::Key_B:
|
||||
|
@ -4617,10 +4632,6 @@ void Application::checkSkeleton() {
|
|||
}
|
||||
}
|
||||
|
||||
bool Application::isForeground() {
|
||||
return _isForeground && !getWindow()->isMinimized();
|
||||
}
|
||||
|
||||
void Application::activeChanged(Qt::ApplicationState state) {
|
||||
switch (state) {
|
||||
case Qt::ApplicationActive:
|
||||
|
@ -4726,6 +4737,10 @@ const DisplayPlugin * Application::getActiveDisplayPlugin() const {
|
|||
return ((Application*)this)->getActiveDisplayPlugin();
|
||||
}
|
||||
|
||||
bool _activatingDisplayPlugin{ false };
|
||||
QVector<QPair<QString, QString>> _currentDisplayPluginActions;
|
||||
QVector<QPair<QString, QString>> _currentInputPluginActions;
|
||||
|
||||
|
||||
static void addDisplayPluginToMenu(DisplayPluginPointer displayPlugin, bool active = false) {
|
||||
auto menu = Menu::getInstance();
|
||||
|
@ -4747,9 +4762,6 @@ static void addDisplayPluginToMenu(DisplayPluginPointer displayPlugin, bool acti
|
|||
Q_ASSERT(menu->menuItemExists(MenuOption::OutputMenu, name));
|
||||
}
|
||||
|
||||
static QVector<QPair<QString, QString>> _currentDisplayPluginActions;
|
||||
static bool _activatingDisplayPlugin{false};
|
||||
|
||||
void Application::updateDisplayMode() {
|
||||
auto menu = Menu::getInstance();
|
||||
auto displayPlugins = PluginManager::getInstance()->getDisplayPlugins();
|
||||
|
@ -4816,7 +4828,7 @@ void Application::updateDisplayMode() {
|
|||
// Only show the hmd tools after the correct plugin has
|
||||
// been activated so that it's UI is setup correctly
|
||||
if (newPluginWantsHMDTools) {
|
||||
showDisplayPluginsTools();
|
||||
_pluginContainer->showDisplayPluginsTools();
|
||||
}
|
||||
|
||||
if (oldDisplayPlugin) {
|
||||
|
@ -4834,9 +4846,6 @@ void Application::updateDisplayMode() {
|
|||
Q_ASSERT_X(_displayPlugin, "Application::updateDisplayMode", "could not find an activated display plugin");
|
||||
}
|
||||
|
||||
static QVector<QPair<QString, QString>> _currentInputPluginActions;
|
||||
|
||||
|
||||
static void addInputPluginToMenu(InputPluginPointer inputPlugin, bool active = false) {
|
||||
auto menu = Menu::getInstance();
|
||||
QString name = inputPlugin->getName();
|
||||
|
@ -4910,42 +4919,6 @@ void Application::updateInputModes() {
|
|||
//}
|
||||
}
|
||||
|
||||
void Application::addMenu(const QString& menuName) {
|
||||
Menu::getInstance()->addMenu(menuName);
|
||||
}
|
||||
|
||||
void Application::removeMenu(const QString& menuName) {
|
||||
Menu::getInstance()->removeMenu(menuName);
|
||||
}
|
||||
|
||||
void Application::addMenuItem(const QString& path, const QString& name, std::function<void(bool)> onClicked, bool checkable, bool checked, const QString& groupName) {
|
||||
auto menu = Menu::getInstance();
|
||||
MenuWrapper* parentItem = menu->getMenu(path);
|
||||
QAction* action = menu->addActionToQMenuAndActionHash(parentItem, name);
|
||||
connect(action, &QAction::triggered, [=] {
|
||||
onClicked(action->isChecked());
|
||||
});
|
||||
action->setCheckable(checkable);
|
||||
action->setChecked(checked);
|
||||
if (_activatingDisplayPlugin) {
|
||||
_currentDisplayPluginActions.push_back({ path, name });
|
||||
} else {
|
||||
_currentInputPluginActions.push_back({ path, name });
|
||||
}
|
||||
}
|
||||
|
||||
void Application::removeMenuItem(const QString& menuName, const QString& menuItem) {
|
||||
Menu::getInstance()->removeMenuItem(menuName, menuItem);
|
||||
}
|
||||
|
||||
bool Application::isOptionChecked(const QString& name) {
|
||||
return Menu::getInstance()->isOptionChecked(name);
|
||||
}
|
||||
|
||||
void Application::setIsOptionChecked(const QString& path, bool checked) {
|
||||
Menu::getInstance()->setIsOptionChecked(path, checked);
|
||||
}
|
||||
|
||||
mat4 Application::getEyeProjection(int eye) const {
|
||||
if (isHMDMode()) {
|
||||
return getActiveDisplayPlugin()->getProjection((Eye)eye, _viewFrustum.getProjection());
|
||||
|
@ -4978,89 +4951,6 @@ mat4 Application::getHMDSensorPose() const {
|
|||
return mat4();
|
||||
}
|
||||
|
||||
// FIXME there is a bug in the fullscreen setting, where leaving
|
||||
// fullscreen does not restore the window frame, making it difficult
|
||||
// or impossible to move or size the window.
|
||||
// Additionally, setting fullscreen isn't hiding the menu on windows
|
||||
// make it useless for stereoscopic modes.
|
||||
void Application::setFullscreen(const QScreen* target) {
|
||||
if (!_window->isFullScreen()) {
|
||||
_savedGeometry = _window->geometry();
|
||||
}
|
||||
#ifdef Q_OS_MAC
|
||||
_window->setGeometry(target->availableGeometry());
|
||||
#endif
|
||||
_window->windowHandle()->setScreen((QScreen*)target);
|
||||
_window->showFullScreen();
|
||||
|
||||
#ifndef Q_OS_MAC
|
||||
// also hide the QMainWindow's menuBar
|
||||
QMenuBar* menuBar = _window->menuBar();
|
||||
if (menuBar) {
|
||||
menuBar->setVisible(false);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Application::unsetFullscreen(const QScreen* avoid) {
|
||||
_window->showNormal();
|
||||
|
||||
QRect targetGeometry = _savedGeometry;
|
||||
if (avoid != nullptr) {
|
||||
QRect avoidGeometry = avoid->geometry();
|
||||
if (avoidGeometry.contains(targetGeometry.topLeft())) {
|
||||
QScreen* newTarget = primaryScreen();
|
||||
if (newTarget == avoid) {
|
||||
foreach(auto screen, screens()) {
|
||||
if (screen != avoid) {
|
||||
newTarget = screen;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
targetGeometry = newTarget->availableGeometry();
|
||||
}
|
||||
}
|
||||
#ifdef Q_OS_MAC
|
||||
QTimer* timer = new QTimer();
|
||||
timer->singleShot(2000, [=] {
|
||||
_window->setGeometry(targetGeometry);
|
||||
timer->deleteLater();
|
||||
});
|
||||
#else
|
||||
_window->setGeometry(targetGeometry);
|
||||
#endif
|
||||
|
||||
#ifndef Q_OS_MAC
|
||||
// also show the QMainWindow's menuBar
|
||||
QMenuBar* menuBar = _window->menuBar();
|
||||
if (menuBar) {
|
||||
menuBar->setVisible(true);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void Application::showDisplayPluginsTools() {
|
||||
DependencyManager::get<DialogsManager>()->hmdTools(true);
|
||||
}
|
||||
|
||||
QGLWidget* Application::getPrimarySurface() {
|
||||
return _glWidget;
|
||||
}
|
||||
|
||||
void Application::setActiveDisplayPlugin(const QString& pluginName) {
|
||||
auto menu = Menu::getInstance();
|
||||
foreach(DisplayPluginPointer displayPlugin, PluginManager::getInstance()->getDisplayPlugins()) {
|
||||
QString name = displayPlugin->getName();
|
||||
QAction* action = menu->getActionForOption(name);
|
||||
if (pluginName == name) {
|
||||
action->setChecked(true);
|
||||
}
|
||||
}
|
||||
updateDisplayMode();
|
||||
}
|
||||
|
||||
void Application::setPalmData(Hand* hand, UserInputMapper::PoseValue pose, float deltaTime, int index) {
|
||||
PalmData* palm;
|
||||
bool foundHand = false;
|
||||
|
|
|
@ -26,18 +26,18 @@
|
|||
#include <EntityEditPacketSender.h>
|
||||
#include <EntityTreeRenderer.h>
|
||||
#include <GeometryCache.h>
|
||||
#include <input-plugins/KeyboardMouseDevice.h>
|
||||
#include <NodeList.h>
|
||||
#include <OctreeQuery.h>
|
||||
#include <OffscreenUi.h>
|
||||
#include <PhysicalEntitySimulation.h>
|
||||
#include <PhysicsEngine.h>
|
||||
#include <plugins/Forward.h>
|
||||
#include <ScriptEngine.h>
|
||||
#include <ShapeManager.h>
|
||||
#include <StDev.h>
|
||||
#include <udt/PacketHeaders.h>
|
||||
#include <ViewFrustum.h>
|
||||
#include <plugins/PluginContainer.h>
|
||||
#include <plugins/PluginManager.h>
|
||||
#include <SimpleMovingAverage.h>
|
||||
|
||||
#include "AudioClient.h"
|
||||
|
@ -50,7 +50,6 @@
|
|||
#include "Stars.h"
|
||||
#include "avatar/Avatar.h"
|
||||
#include "avatar/MyAvatar.h"
|
||||
#include <input-plugins/KeyboardMouseDevice.h>
|
||||
#include "scripting/ControllerScriptingInterface.h"
|
||||
#include "scripting/DialogsManagerScriptingInterface.h"
|
||||
#include "scripting/WebWindowClass.h"
|
||||
|
@ -132,7 +131,7 @@ class Application;
|
|||
|
||||
typedef bool (Application::* AcceptURLMethod)(const QString &);
|
||||
|
||||
class Application : public QApplication, public AbstractViewStateInterface, public AbstractScriptingServicesInterface, PluginContainer {
|
||||
class Application : public QApplication, public AbstractViewStateInterface, public AbstractScriptingServicesInterface {
|
||||
Q_OBJECT
|
||||
|
||||
friend class OctreePacketProcessor;
|
||||
|
@ -280,23 +279,10 @@ public:
|
|||
virtual void endOverrideEnvironmentData() { _environment.endOverride(); }
|
||||
virtual qreal getDevicePixelRatio();
|
||||
|
||||
// Plugin container support
|
||||
virtual void addMenu(const QString& menuName);
|
||||
virtual void removeMenu(const QString& menuName);
|
||||
virtual void addMenuItem(const QString& path, const QString& name, std::function<void(bool)> onClicked, bool checkable, bool checked, const QString& groupName);
|
||||
virtual void removeMenuItem(const QString& menuName, const QString& menuItem);
|
||||
virtual bool isOptionChecked(const QString& name);
|
||||
virtual void setIsOptionChecked(const QString& path, bool checked);
|
||||
virtual void setFullscreen(const QScreen* target) override;
|
||||
virtual void unsetFullscreen(const QScreen* avoid) override;
|
||||
virtual void showDisplayPluginsTools() override;
|
||||
virtual QGLWidget* getPrimarySurface() override;
|
||||
virtual bool isForeground() override;
|
||||
|
||||
void setActiveDisplayPlugin(const QString& pluginName);
|
||||
|
||||
DisplayPlugin * getActiveDisplayPlugin();
|
||||
const DisplayPlugin * getActiveDisplayPlugin() const;
|
||||
DisplayPlugin* getActiveDisplayPlugin();
|
||||
const DisplayPlugin* getActiveDisplayPlugin() const;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -691,6 +677,8 @@ private:
|
|||
int _simsPerSecondReport = 0;
|
||||
quint64 _lastSimsPerSecondUpdate = 0;
|
||||
bool _isForeground = true; // starts out assumed to be in foreground
|
||||
|
||||
friend class PluginContainerProxy;
|
||||
};
|
||||
|
||||
#endif // hifi_Application_h
|
||||
|
|
|
@ -16,11 +16,13 @@
|
|||
#include <AddressManager.h>
|
||||
#include <AudioClient.h>
|
||||
#include <DependencyManager.h>
|
||||
#include <display-plugins/DisplayPlugin.h>
|
||||
#include <PathUtils.h>
|
||||
#include <SettingHandle.h>
|
||||
#include <UserActivityLogger.h>
|
||||
#include <VrMenu.h>
|
||||
|
||||
|
||||
#include "Application.h"
|
||||
#include "AccountManager.h"
|
||||
#include "audio/AudioScope.h"
|
||||
|
@ -220,7 +222,7 @@ Menu::Menu() {
|
|||
addActionToQMenuAndActionHash(toolsMenu, MenuOption::PackageModel, 0,
|
||||
qApp, SLOT(packageModel()));
|
||||
|
||||
MenuWrapper* displayMenu = addMenu("Display");
|
||||
MenuWrapper* displayMenu = addMenu(DisplayPlugin::MENU_PATH);
|
||||
{
|
||||
MenuWrapper* displayModeMenu = addMenu(MenuOption::OutputMenu);
|
||||
QActionGroup* displayModeGroup = new QActionGroup(displayModeMenu);
|
||||
|
|
161
interface/src/PluginContainerProxy.cpp
Normal file
161
interface/src/PluginContainerProxy.cpp
Normal file
|
@ -0,0 +1,161 @@
|
|||
#include "PluginContainerProxy.h"
|
||||
|
||||
#include <QScreen>
|
||||
#include <QWindow>
|
||||
|
||||
#include <plugins/Plugin.h>
|
||||
#include <plugins/PluginManager.h>
|
||||
#include <display-plugins/DisplayPlugin.h>
|
||||
|
||||
#include "Application.h"
|
||||
#include "MainWindow.h"
|
||||
#include "GLCanvas.h"
|
||||
#include "ui/DialogsManager.h"
|
||||
|
||||
PluginContainerProxy::PluginContainerProxy() {
|
||||
Plugin::setContainer(this);
|
||||
}
|
||||
|
||||
bool PluginContainerProxy::isForeground() {
|
||||
return qApp->_isForeground && !qApp->getWindow()->isMinimized();
|
||||
}
|
||||
|
||||
void PluginContainerProxy::addMenu(const QString& menuName) {
|
||||
Menu::getInstance()->addMenu(menuName);
|
||||
}
|
||||
|
||||
void PluginContainerProxy::removeMenu(const QString& menuName) {
|
||||
Menu::getInstance()->removeMenu(menuName);
|
||||
}
|
||||
|
||||
extern bool _activatingDisplayPlugin;
|
||||
extern QVector<QPair<QString, QString>> _currentDisplayPluginActions;
|
||||
extern QVector<QPair<QString, QString>> _currentInputPluginActions;
|
||||
std::map<QString, QActionGroup*> _exclusiveGroups;
|
||||
|
||||
QAction* PluginContainerProxy::addMenuItem(const QString& path, const QString& name, std::function<void(bool)> onClicked, bool checkable, bool checked, const QString& groupName) {
|
||||
auto menu = Menu::getInstance();
|
||||
MenuWrapper* parentItem = menu->getMenu(path);
|
||||
QAction* action = menu->addActionToQMenuAndActionHash(parentItem, name);
|
||||
if (!groupName.isEmpty()) {
|
||||
QActionGroup* group{ nullptr };
|
||||
if (!_exclusiveGroups.count(groupName)) {
|
||||
group = _exclusiveGroups[groupName] = new QActionGroup(menu);
|
||||
group->setExclusive(true);
|
||||
} else {
|
||||
group = _exclusiveGroups[groupName];
|
||||
}
|
||||
group->addAction(action);
|
||||
}
|
||||
connect(action, &QAction::triggered, [=] {
|
||||
onClicked(action->isChecked());
|
||||
});
|
||||
action->setCheckable(checkable);
|
||||
action->setChecked(checked);
|
||||
if (_activatingDisplayPlugin) {
|
||||
_currentDisplayPluginActions.push_back({ path, name });
|
||||
} else {
|
||||
_currentInputPluginActions.push_back({ path, name });
|
||||
}
|
||||
return action;
|
||||
}
|
||||
|
||||
void PluginContainerProxy::removeMenuItem(const QString& menuName, const QString& menuItem) {
|
||||
Menu::getInstance()->removeMenuItem(menuName, menuItem);
|
||||
}
|
||||
|
||||
bool PluginContainerProxy::isOptionChecked(const QString& name) {
|
||||
return Menu::getInstance()->isOptionChecked(name);
|
||||
}
|
||||
|
||||
void PluginContainerProxy::setIsOptionChecked(const QString& path, bool checked) {
|
||||
Menu::getInstance()->setIsOptionChecked(path, checked);
|
||||
}
|
||||
|
||||
// FIXME there is a bug in the fullscreen setting, where leaving
|
||||
// fullscreen does not restore the window frame, making it difficult
|
||||
// or impossible to move or size the window.
|
||||
// Additionally, setting fullscreen isn't hiding the menu on windows
|
||||
// make it useless for stereoscopic modes.
|
||||
void PluginContainerProxy::setFullscreen(const QScreen* target, bool hideMenu) {
|
||||
auto _window = qApp->_window;
|
||||
if (!_window->isFullScreen()) {
|
||||
_savedGeometry = _window->geometry();
|
||||
}
|
||||
if (nullptr == target) {
|
||||
// FIXME target the screen where the window currently is
|
||||
target = qApp->primaryScreen();
|
||||
}
|
||||
|
||||
_window->setGeometry(target->availableGeometry());
|
||||
_window->windowHandle()->setScreen((QScreen*)target);
|
||||
_window->showFullScreen();
|
||||
|
||||
#ifndef Q_OS_MAC
|
||||
// also hide the QMainWindow's menuBar
|
||||
QMenuBar* menuBar = _window->menuBar();
|
||||
if (menuBar && hideMenu) {
|
||||
menuBar->setVisible(false);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void PluginContainerProxy::unsetFullscreen(const QScreen* avoid) {
|
||||
auto _window = qApp->_window;
|
||||
_window->showNormal();
|
||||
|
||||
QRect targetGeometry = _savedGeometry;
|
||||
if (avoid != nullptr) {
|
||||
QRect avoidGeometry = avoid->geometry();
|
||||
if (avoidGeometry.contains(targetGeometry.topLeft())) {
|
||||
QScreen* newTarget = qApp->primaryScreen();
|
||||
if (newTarget == avoid) {
|
||||
foreach(auto screen, qApp->screens()) {
|
||||
if (screen != avoid) {
|
||||
newTarget = screen;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
targetGeometry = newTarget->availableGeometry();
|
||||
}
|
||||
}
|
||||
#ifdef Q_OS_MAC
|
||||
QTimer* timer = new QTimer();
|
||||
timer->singleShot(2000, [=] {
|
||||
_window->setGeometry(targetGeometry);
|
||||
timer->deleteLater();
|
||||
});
|
||||
#else
|
||||
_window->setGeometry(targetGeometry);
|
||||
#endif
|
||||
|
||||
#ifndef Q_OS_MAC
|
||||
// also show the QMainWindow's menuBar
|
||||
QMenuBar* menuBar = _window->menuBar();
|
||||
if (menuBar) {
|
||||
menuBar->setVisible(true);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void PluginContainerProxy::showDisplayPluginsTools() {
|
||||
DependencyManager::get<DialogsManager>()->hmdTools(true);
|
||||
}
|
||||
|
||||
QGLWidget* PluginContainerProxy::getPrimarySurface() {
|
||||
return qApp->_glWidget;
|
||||
}
|
||||
|
||||
void Application::setActiveDisplayPlugin(const QString& pluginName) {
|
||||
auto menu = Menu::getInstance();
|
||||
foreach(DisplayPluginPointer displayPlugin, PluginManager::getInstance()->getDisplayPlugins()) {
|
||||
QString name = displayPlugin->getName();
|
||||
QAction* action = menu->getActionForOption(name);
|
||||
if (pluginName == name) {
|
||||
action->setChecked(true);
|
||||
}
|
||||
}
|
||||
updateDisplayMode();
|
||||
}
|
30
interface/src/PluginContainerProxy.h
Normal file
30
interface/src/PluginContainerProxy.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
#pragma once
|
||||
#ifndef hifi_PluginContainerProxy_h
|
||||
#define hifi_PluginContainerProxy_h
|
||||
|
||||
#include <QObject>
|
||||
#include <QRect>
|
||||
|
||||
#include <plugins/Forward.h>
|
||||
#include <plugins/PluginContainer.h>
|
||||
|
||||
class PluginContainerProxy : public QObject, PluginContainer {
|
||||
Q_OBJECT
|
||||
PluginContainerProxy();
|
||||
virtual void addMenu(const QString& menuName) override;
|
||||
virtual void removeMenu(const QString& menuName) override;
|
||||
virtual QAction* addMenuItem(const QString& path, const QString& name, std::function<void(bool)> onClicked, bool checkable = false, bool checked = false, const QString& groupName = "") override;
|
||||
virtual void removeMenuItem(const QString& menuName, const QString& menuItem) override;
|
||||
virtual bool isOptionChecked(const QString& name) override;
|
||||
virtual void setIsOptionChecked(const QString& path, bool checked);
|
||||
virtual void setFullscreen(const QScreen* targetScreen, bool hideMenu = true) override;
|
||||
virtual void unsetFullscreen(const QScreen* avoidScreen = nullptr) override;
|
||||
virtual void showDisplayPluginsTools() override;
|
||||
virtual QGLWidget* getPrimarySurface() override;
|
||||
virtual bool isForeground() override;
|
||||
QRect _savedGeometry{ 10, 120, 800, 600 };
|
||||
|
||||
friend class Application;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -13,7 +13,6 @@
|
|||
|
||||
const QString Basic2DWindowOpenGLDisplayPlugin::NAME("2D Display");
|
||||
|
||||
static const QString MENU_PATH = "Display";
|
||||
static const QString FULLSCREEN = "Fullscreen";
|
||||
|
||||
const QString& Basic2DWindowOpenGLDisplayPlugin::getName() const {
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
#include "oculus/OculusDisplayPlugin.h"
|
||||
#include "oculus/OculusLegacyDisplayPlugin.h"
|
||||
|
||||
const QString DisplayPlugin::MENU_PATH{ "Display" };
|
||||
|
||||
// TODO migrate to a DLL model where plugins are discovered and loaded at runtime by the PluginManager class
|
||||
DisplayPluginList getDisplayPlugins() {
|
||||
DisplayPlugin* PLUGIN_POOL[] = {
|
||||
|
@ -27,9 +29,11 @@ DisplayPluginList getDisplayPlugins() {
|
|||
#endif
|
||||
|
||||
// Stereo modes
|
||||
// FIXME fix stereo display plugins
|
||||
|
||||
// SBS left/right
|
||||
new SideBySideStereoDisplayPlugin(),
|
||||
//new InterleavedStereoDisplayPlugin(),
|
||||
// Interleaved left/right
|
||||
new InterleavedStereoDisplayPlugin(),
|
||||
|
||||
// HMDs
|
||||
|
||||
|
|
|
@ -115,7 +115,7 @@ public:
|
|||
virtual void resetSensors() {}
|
||||
virtual float devicePixelRatio() { return 1.0; }
|
||||
|
||||
|
||||
static const QString MENU_PATH;
|
||||
signals:
|
||||
void recommendedFramebufferSizeChanged(const QSize & size);
|
||||
void requestRender();
|
||||
|
|
|
@ -105,7 +105,7 @@ bool OpenGLDisplayPlugin::eventFilter(QObject* receiver, QEvent* event) {
|
|||
void OpenGLDisplayPlugin::display(
|
||||
GLuint finalTexture, const glm::uvec2& sceneSize) {
|
||||
using namespace oglplus;
|
||||
uvec2 size = getRecommendedRenderSize();
|
||||
uvec2 size = getSurfaceSize();
|
||||
Context::Viewport(size.x, size.y);
|
||||
glBindTexture(GL_TEXTURE_2D, finalTexture);
|
||||
drawUnitQuad();
|
||||
|
|
|
@ -33,6 +33,7 @@ public:
|
|||
protected:
|
||||
virtual void customizeContext();
|
||||
virtual void drawUnitQuad();
|
||||
virtual glm::uvec2 getSurfaceSize() const = 0;
|
||||
virtual void makeCurrent() = 0;
|
||||
virtual void doneCurrent() = 0;
|
||||
virtual void swapBuffers() = 0;
|
||||
|
|
|
@ -16,6 +16,10 @@ WindowOpenGLDisplayPlugin::WindowOpenGLDisplayPlugin() {
|
|||
}
|
||||
|
||||
glm::uvec2 WindowOpenGLDisplayPlugin::getRecommendedRenderSize() const {
|
||||
return getSurfaceSize();
|
||||
}
|
||||
|
||||
glm::uvec2 WindowOpenGLDisplayPlugin::getSurfaceSize() const {
|
||||
uvec2 result;
|
||||
if (_window) {
|
||||
result = toGlm(_window->geometry().size() * _window->devicePixelRatio());
|
||||
|
@ -23,6 +27,7 @@ glm::uvec2 WindowOpenGLDisplayPlugin::getRecommendedRenderSize() const {
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
glm::uvec2 WindowOpenGLDisplayPlugin::getRecommendedUiSize() const {
|
||||
uvec2 result;
|
||||
if (_window) {
|
||||
|
|
|
@ -21,6 +21,7 @@ public:
|
|||
virtual void deactivate() override;
|
||||
|
||||
protected:
|
||||
virtual glm::uvec2 getSurfaceSize() const override final;
|
||||
virtual void makeCurrent() override;
|
||||
virtual void doneCurrent() override;
|
||||
virtual void swapBuffers() override;
|
||||
|
|
|
@ -17,6 +17,42 @@
|
|||
|
||||
#include <gpu/GLBackend.h>
|
||||
|
||||
static const char * INTERLEAVED_TEXTURED_VS = R"VS(#version 410 core
|
||||
#pragma line __LINE__
|
||||
|
||||
in vec3 Position;
|
||||
in vec2 TexCoord;
|
||||
|
||||
out vec2 vTexCoord;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(Position, 1);
|
||||
vTexCoord = TexCoord;
|
||||
}
|
||||
|
||||
)VS";
|
||||
|
||||
static const char * INTERLEAVED_TEXTURED_FS = R"FS(#version 410 core
|
||||
#pragma line __LINE__
|
||||
|
||||
uniform sampler2D sampler;
|
||||
uniform ivec2 textureSize;
|
||||
|
||||
in vec2 vTexCoord;
|
||||
out vec4 FragColor;
|
||||
|
||||
void main() {
|
||||
ivec2 texCoord = ivec2(floor(vTexCoord * textureSize));
|
||||
texCoord.x /= 2;
|
||||
int row = int(floor(gl_FragCoord.y));
|
||||
if (row % 2 > 0) {
|
||||
texCoord.x += (textureSize.x / 2);
|
||||
}
|
||||
FragColor = texelFetch(sampler, texCoord, 0); //texture(sampler, texCoord);
|
||||
}
|
||||
|
||||
)FS";
|
||||
|
||||
const QString InterleavedStereoDisplayPlugin::NAME("Interleaved Stereo Display");
|
||||
|
||||
const QString & InterleavedStereoDisplayPlugin::getName() const {
|
||||
|
@ -29,5 +65,20 @@ InterleavedStereoDisplayPlugin::InterleavedStereoDisplayPlugin() {
|
|||
void InterleavedStereoDisplayPlugin::customizeContext() {
|
||||
StereoDisplayPlugin::customizeContext();
|
||||
// Set up the stencil buffers? Or use a custom shader?
|
||||
|
||||
compileProgram(_program, INTERLEAVED_TEXTURED_VS, INTERLEAVED_TEXTURED_FS);
|
||||
}
|
||||
|
||||
glm::uvec2 InterleavedStereoDisplayPlugin::getRecommendedRenderSize() const {
|
||||
uvec2 result = WindowOpenGLDisplayPlugin::getRecommendedRenderSize();
|
||||
result.x *= 2;
|
||||
result.y /= 2;
|
||||
return result;
|
||||
}
|
||||
|
||||
void InterleavedStereoDisplayPlugin::display(
|
||||
GLuint finalTexture, const glm::uvec2& sceneSize) {
|
||||
using namespace oglplus;
|
||||
_program->Bind();
|
||||
Uniform<ivec2>(*_program, "textureSize").SetValue(sceneSize);
|
||||
WindowOpenGLDisplayPlugin::display(finalTexture, sceneSize);
|
||||
}
|
|
@ -18,6 +18,9 @@ public:
|
|||
// initialize OpenGL context settings needed by the plugin
|
||||
virtual void customizeContext() override;
|
||||
|
||||
virtual glm::uvec2 getRecommendedRenderSize() const override;
|
||||
void display(GLuint finalTexture, const glm::uvec2& sceneSize) override;
|
||||
|
||||
private:
|
||||
static const QString NAME;
|
||||
};
|
||||
|
|
|
@ -21,9 +21,6 @@
|
|||
|
||||
const QString SideBySideStereoDisplayPlugin::NAME("3D TV - Side by Side Stereo");
|
||||
|
||||
static const QString MENU_PATH = "Display";
|
||||
static const QString FULLSCREEN = "Fullscreen";
|
||||
|
||||
const QString & SideBySideStereoDisplayPlugin::getName() const {
|
||||
return NAME;
|
||||
}
|
||||
|
@ -31,20 +28,10 @@ const QString & SideBySideStereoDisplayPlugin::getName() const {
|
|||
SideBySideStereoDisplayPlugin::SideBySideStereoDisplayPlugin() {
|
||||
}
|
||||
|
||||
void SideBySideStereoDisplayPlugin::activate() {
|
||||
CONTAINER->addMenu(MENU_PATH);
|
||||
CONTAINER->addMenuItem(MENU_PATH, FULLSCREEN,
|
||||
[this](bool clicked) {
|
||||
if (clicked) {
|
||||
CONTAINER->setFullscreen(getFullscreenTarget());
|
||||
} else {
|
||||
CONTAINER->unsetFullscreen();
|
||||
}
|
||||
}, true, false);
|
||||
StereoDisplayPlugin::activate();
|
||||
glm::uvec2 SideBySideStereoDisplayPlugin::getRecommendedRenderSize() const {
|
||||
uvec2 result = WindowOpenGLDisplayPlugin::getRecommendedRenderSize();
|
||||
result.x *= 2;
|
||||
return result;
|
||||
}
|
||||
|
||||
// FIXME target the screen the window is currently on
|
||||
QScreen* SideBySideStereoDisplayPlugin::getFullscreenTarget() {
|
||||
return qApp->primaryScreen();
|
||||
}
|
||||
|
||||
|
|
|
@ -16,8 +16,7 @@ class SideBySideStereoDisplayPlugin : public StereoDisplayPlugin {
|
|||
public:
|
||||
SideBySideStereoDisplayPlugin();
|
||||
virtual const QString& getName() const override;
|
||||
virtual void activate() override;
|
||||
virtual glm::uvec2 getRecommendedRenderSize() const override;
|
||||
private:
|
||||
QScreen* getFullscreenTarget();
|
||||
static const QString NAME;
|
||||
};
|
||||
|
|
|
@ -10,11 +10,14 @@
|
|||
|
||||
#include <QApplication>
|
||||
#include <QDesktopWidget>
|
||||
#include <QAction>
|
||||
|
||||
#include <gpu/GLBackend.h>
|
||||
#include <ViewFrustum.h>
|
||||
#include <MatrixStack.h>
|
||||
#include <plugins/PluginContainer.h>
|
||||
#include <QGuiApplication>
|
||||
#include <QScreen>
|
||||
|
||||
StereoDisplayPlugin::StereoDisplayPlugin() {
|
||||
}
|
||||
|
@ -29,11 +32,14 @@ const float DEFAULT_IPD = 0.064f;
|
|||
const float HALF_DEFAULT_IPD = DEFAULT_IPD / 2.0f;
|
||||
|
||||
glm::mat4 StereoDisplayPlugin::getProjection(Eye eye, const glm::mat4& baseProjection) const {
|
||||
// FIXME check for mono eye and provide a combined matrix, needed for proper
|
||||
// culling
|
||||
// Refer to http://www.nvidia.com/content/gtc-2010/pdfs/2010_gtc2010.pdf on creating
|
||||
// stereo projection matrices. Do NOT use "toe-in", use translation.
|
||||
|
||||
if (eye == Mono) {
|
||||
// FIXME provide a combined matrix, needed for proper culling
|
||||
return baseProjection;
|
||||
}
|
||||
|
||||
float nearZ = DEFAULT_NEAR_CLIP; // near clipping plane
|
||||
float screenZ = 0.25f; // screen projection plane
|
||||
// FIXME verify this is the right calculation
|
||||
|
@ -52,10 +58,36 @@ glm::mat4 StereoDisplayPlugin::getEyePose(Eye eye) const {
|
|||
return glm::translate(mat4(), vec3(modelviewShift, 0, 0));
|
||||
}
|
||||
|
||||
std::vector<QAction*> _screenActions;
|
||||
void StereoDisplayPlugin::activate() {
|
||||
auto screens = qApp->screens();
|
||||
_screenActions.resize(screens.size());
|
||||
for (int i = 0; i < screens.size(); ++i) {
|
||||
auto screen = screens.at(i);
|
||||
QString name = QString("Screen %1: %2").arg(i + 1).arg(screen->name());
|
||||
bool checked = false;
|
||||
if (screen == qApp->primaryScreen()) {
|
||||
checked = true;
|
||||
}
|
||||
auto action = CONTAINER->addMenuItem(MENU_PATH, name,
|
||||
[this](bool clicked) { updateScreen(); }, true, checked, "Screens");
|
||||
_screenActions[i] = action;
|
||||
}
|
||||
CONTAINER->setFullscreen(qApp->primaryScreen());
|
||||
WindowOpenGLDisplayPlugin::activate();
|
||||
// FIXME there is a bug in the fullscreen setting, see
|
||||
// Application::setFullscreen
|
||||
//CONTAINER->setFullscreen(qApp->primaryScreen());
|
||||
// FIXME Add menu items
|
||||
}
|
||||
|
||||
void StereoDisplayPlugin::updateScreen() {
|
||||
for (int i = 0; i < _screenActions.size(); ++i) {
|
||||
if (_screenActions[i]->isChecked()) {
|
||||
CONTAINER->setFullscreen(qApp->screens().at(i));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StereoDisplayPlugin::deactivate() {
|
||||
_screenActions.clear();
|
||||
CONTAINER->unsetFullscreen();
|
||||
WindowOpenGLDisplayPlugin::deactivate();
|
||||
}
|
||||
|
|
|
@ -17,10 +17,12 @@ public:
|
|||
virtual bool isSupported() const override final;
|
||||
|
||||
virtual void activate() override;
|
||||
virtual void deactivate() override;
|
||||
|
||||
virtual glm::mat4 getProjection(Eye eye, const glm::mat4& baseProjection) const override;
|
||||
virtual glm::mat4 getEyePose(Eye eye) const override;
|
||||
|
||||
protected:
|
||||
void updateScreen();
|
||||
float _ipd{ 0.064f };
|
||||
};
|
||||
|
|
23
libraries/plugins/src/plugins/Forward.h
Normal file
23
libraries/plugins/src/plugins/Forward.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
//
|
||||
// Created by Bradley Austin Davis on 2015/08/08
|
||||
// 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
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include <QList>
|
||||
#include <QVector>
|
||||
#include <QSharedPointer>
|
||||
|
||||
class DisplayPlugin;
|
||||
class InputPlugin;
|
||||
class Plugin;
|
||||
class PluginContainer;
|
||||
class PluginManager;
|
||||
|
||||
using DisplayPluginPointer = QSharedPointer<DisplayPlugin>;
|
||||
using DisplayPluginList = QVector<DisplayPluginPointer>;
|
||||
using InputPluginPointer = QSharedPointer<InputPlugin>;
|
||||
using InputPluginList = QVector<InputPluginPointer>;
|
|
@ -1,3 +1,10 @@
|
|||
//
|
||||
// Created by Bradley Austin Davis on 2015/08/08
|
||||
// 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 "Plugin.h"
|
||||
|
||||
PluginContainer* Plugin::CONTAINER{ nullptr };
|
||||
|
|
|
@ -1,9 +1,16 @@
|
|||
//
|
||||
// Created by Bradley Austin Davis on 2015/08/08
|
||||
// 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
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
#include <QObject>
|
||||
|
||||
class PluginContainer;
|
||||
#include "Forward.h"
|
||||
|
||||
class Plugin : public QObject {
|
||||
public:
|
||||
|
|
|
@ -7,9 +7,10 @@
|
|||
//
|
||||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
#include <functional>
|
||||
#include <QString>
|
||||
|
||||
class QAction;
|
||||
class QGLWidget;
|
||||
class QScreen;
|
||||
|
||||
|
@ -18,11 +19,11 @@ public:
|
|||
PluginContainer();
|
||||
virtual void addMenu(const QString& menuName) = 0;
|
||||
virtual void removeMenu(const QString& menuName) = 0;
|
||||
virtual void addMenuItem(const QString& path, const QString& name, std::function<void(bool)> onClicked, bool checkable = false, bool checked = false, const QString& groupName = "") = 0;
|
||||
virtual QAction* addMenuItem(const QString& path, const QString& name, std::function<void(bool)> onClicked, bool checkable = false, bool checked = false, const QString& groupName = "") = 0;
|
||||
virtual void removeMenuItem(const QString& menuName, const QString& menuItem) = 0;
|
||||
virtual bool isOptionChecked(const QString& name) = 0;
|
||||
virtual void setIsOptionChecked(const QString& path, bool checked) = 0;
|
||||
virtual void setFullscreen(const QScreen* targetScreen) = 0;
|
||||
virtual void setFullscreen(const QScreen* targetScreen, bool hideMenu = false) = 0;
|
||||
virtual void unsetFullscreen(const QScreen* avoidScreen = nullptr) = 0;
|
||||
virtual void showDisplayPluginsTools() = 0;
|
||||
virtual QGLWidget* getPrimarySurface() = 0;
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
//
|
||||
// Created by Bradley Austin Davis on 2015/08/08
|
||||
// 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 "PluginManager.h"
|
||||
#include <mutex>
|
||||
|
||||
|
||||
PluginManager* PluginManager::getInstance() {
|
||||
static PluginManager _manager;
|
||||
return &_manager;
|
||||
|
|
|
@ -1,17 +1,13 @@
|
|||
//
|
||||
// Created by Bradley Austin Davis on 2015/08/08
|
||||
// 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
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include "Plugin.h"
|
||||
#include <QList>
|
||||
#include <QVector>
|
||||
#include <QSharedPointer>
|
||||
|
||||
class DisplayPlugin;
|
||||
class InputPlugin;
|
||||
|
||||
using DisplayPluginPointer = QSharedPointer<DisplayPlugin>;
|
||||
using DisplayPluginList = QVector<DisplayPluginPointer>;
|
||||
using InputPluginPointer = QSharedPointer<InputPlugin>;
|
||||
using InputPluginList = QVector<InputPluginPointer>;
|
||||
#include "Forward.h"
|
||||
|
||||
class PluginManager : public QObject {
|
||||
public:
|
||||
|
|
Loading…
Reference in a new issue