mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 16:58:09 +02:00
Working on display plugins
This commit is contained in:
parent
edfb1305af
commit
1b7efe9a02
25 changed files with 430 additions and 269 deletions
|
@ -90,6 +90,7 @@
|
||||||
#include <UserActivityLogger.h>
|
#include <UserActivityLogger.h>
|
||||||
#include <UUID.h>
|
#include <UUID.h>
|
||||||
#include <VrMenu.h>
|
#include <VrMenu.h>
|
||||||
|
#include <ui/ApplicationOverlayCompositor.h>
|
||||||
|
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
#include "AudioClient.h"
|
#include "AudioClient.h"
|
||||||
|
@ -101,6 +102,7 @@
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include "InterfaceLogging.h"
|
#include "InterfaceLogging.h"
|
||||||
|
|
||||||
|
#include "GlWindow.h"
|
||||||
#include "avatar/AvatarManager.h"
|
#include "avatar/AvatarManager.h"
|
||||||
|
|
||||||
#include "audio/AudioToolBox.h"
|
#include "audio/AudioToolBox.h"
|
||||||
|
@ -506,29 +508,39 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
||||||
|
|
||||||
ResourceCache::setRequestLimit(3);
|
ResourceCache::setRequestLimit(3);
|
||||||
|
|
||||||
_window->setCentralWidget(new QWidget());
|
_offscreenContext->create();
|
||||||
|
_offscreenContext->makeCurrent();
|
||||||
|
|
||||||
|
_glWindow = new GlWindow(_offscreenContext->getContext());
|
||||||
|
|
||||||
|
QWidget* container = QWidget::createWindowContainer(_glWindow);
|
||||||
|
container->setFocusPolicy(Qt::StrongFocus);
|
||||||
|
_window->setCentralWidget(container);
|
||||||
_window->restoreGeometry();
|
_window->restoreGeometry();
|
||||||
|
|
||||||
_window->setVisible(true);
|
_window->setVisible(true);
|
||||||
|
container->setFocus();
|
||||||
|
_offscreenContext->makeCurrent();
|
||||||
|
initializeGL();
|
||||||
|
// initialization continues in initializeGL when OpenGL context is ready
|
||||||
|
|
||||||
|
|
||||||
|
_menuBarHeight = Menu::getInstance()->height();
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
_fullscreenMenuWidget->setParent(_glWidget);
|
_fullscreenMenuWidget->setParent(_glWidget);
|
||||||
#endif
|
|
||||||
|
|
||||||
_menuBarHeight = Menu::getInstance()->height();
|
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Fullscreen)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::Fullscreen)) {
|
||||||
setFullscreen(true); // Initialize menu bar show/hide
|
setFullscreen(true); // Initialize menu bar show/hide
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
_toolWindow = new ToolWindow();
|
_toolWindow = new ToolWindow();
|
||||||
_toolWindow->setWindowFlags(_toolWindow->windowFlags() | Qt::WindowStaysOnTopHint);
|
_toolWindow->setWindowFlags(_toolWindow->windowFlags() | Qt::WindowStaysOnTopHint);
|
||||||
_toolWindow->setWindowTitle("Tools");
|
_toolWindow->setWindowTitle("Tools");
|
||||||
|
|
||||||
_offscreenContext->create();
|
|
||||||
|
_compositor = CompositorPtr(new ApplicationOverlayCompositor());
|
||||||
_offscreenContext->makeCurrent();
|
_offscreenContext->makeCurrent();
|
||||||
initializeGL();
|
|
||||||
// initialization continues in initializeGL when OpenGL context is ready
|
|
||||||
|
|
||||||
// Tell our entity edit sender about our known jurisdictions
|
// Tell our entity edit sender about our known jurisdictions
|
||||||
_entityEditSender.setServerJurisdictions(&_entityServerJurisdictions);
|
_entityEditSender.setServerJurisdictions(&_entityServerJurisdictions);
|
||||||
|
@ -949,15 +961,16 @@ void Application::paintGL() {
|
||||||
// has completed before we start trying to read from it in another context. However
|
// has completed before we start trying to read from it in another context. However
|
||||||
// once we have multi-threaded rendering, this will almost certainly be critical,
|
// once we have multi-threaded rendering, this will almost certainly be critical,
|
||||||
// but may be better handled with a fence object
|
// but may be better handled with a fence object
|
||||||
glFinish();
|
// glFinish();
|
||||||
|
|
||||||
|
|
||||||
_offscreenContext->doneCurrent();
|
_offscreenContext->doneCurrent();
|
||||||
Q_ASSERT(!QOpenGLContext::currentContext());
|
Q_ASSERT(!QOpenGLContext::currentContext());
|
||||||
displayPlugin->preDisplay();
|
|
||||||
|
|
||||||
displayPlugin->display(gpu::GLBackend::getTextureID(finalFbo->getRenderBuffer(0)), finalFbo->getSize(),
|
GLuint finalTexture = _compositor->composite(displayPlugin,
|
||||||
|
gpu::GLBackend::getTextureID(finalFbo->getRenderBuffer(0)), finalFbo->getSize(),
|
||||||
_applicationOverlay.getOverlayTexture(), getCanvasSize());
|
_applicationOverlay.getOverlayTexture(), getCanvasSize());
|
||||||
|
|
||||||
|
displayPlugin->preDisplay();
|
||||||
|
displayPlugin->display(finalTexture, finalFbo->getSize());
|
||||||
displayPlugin->finishFrame();
|
displayPlugin->finishFrame();
|
||||||
Q_ASSERT(!QOpenGLContext::currentContext());
|
Q_ASSERT(!QOpenGLContext::currentContext());
|
||||||
_offscreenContext->makeCurrent();
|
_offscreenContext->makeCurrent();
|
||||||
|
@ -1427,7 +1440,7 @@ void Application::mouseMoveEvent(QMouseEvent* event, unsigned int deviceID) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Fullscreen)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::Fullscreen)) {
|
||||||
// Show/hide menu bar in fullscreen
|
// Show/hide menu bar in fullscreen
|
||||||
if (event->globalY() > _menuBarHeight) {
|
if (event->globalY() > _menuBarHeight) {
|
||||||
|
@ -1438,6 +1451,7 @@ void Application::mouseMoveEvent(QMouseEvent* event, unsigned int deviceID) {
|
||||||
Menu::getInstance()->setFixedHeight(_menuBarHeight);
|
Menu::getInstance()->setFixedHeight(_menuBarHeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
_entities.mouseMoveEvent(event, deviceID);
|
_entities.mouseMoveEvent(event, deviceID);
|
||||||
|
|
||||||
|
@ -1764,6 +1778,7 @@ void Application::idle() {
|
||||||
emit checkBackgroundDownloads();
|
emit checkBackgroundDownloads();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
void Application::setFullscreen(bool fullscreen) {
|
void Application::setFullscreen(bool fullscreen) {
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Fullscreen) != fullscreen) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::Fullscreen) != fullscreen) {
|
||||||
Menu::getInstance()->getActionForOption(MenuOption::Fullscreen)->setChecked(fullscreen);
|
Menu::getInstance()->getActionForOption(MenuOption::Fullscreen)->setChecked(fullscreen);
|
||||||
|
@ -1822,7 +1837,6 @@ void Application::setFullscreen(bool fullscreen) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
void Application::setEnable3DTVMode(bool enable3DTVMode) {
|
void Application::setEnable3DTVMode(bool enable3DTVMode) {
|
||||||
resizeGL();
|
resizeGL();
|
||||||
}
|
}
|
||||||
|
@ -3006,8 +3020,11 @@ PickRay Application::computePickRay(float x, float y) const {
|
||||||
if (isHMDMode()) {
|
if (isHMDMode()) {
|
||||||
getApplicationOverlay().computeHmdPickRay(glm::vec2(x, y), result.origin, result.direction);
|
getApplicationOverlay().computeHmdPickRay(glm::vec2(x, y), result.origin, result.direction);
|
||||||
} else {
|
} else {
|
||||||
auto frustum = activeRenderingThread ? getDisplayViewFrustum() : getViewFrustum();
|
if (QThread::currentThread() == activeRenderingThread) {
|
||||||
frustum->computePickRay(x, y, result.origin, result.direction);
|
getDisplayViewFrustum()->computePickRay(x, y, result.origin, result.direction);
|
||||||
|
} else {
|
||||||
|
getViewFrustum()->computePickRay(x, y, result.origin, result.direction);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -3214,7 +3231,7 @@ void Application::displaySide(const Camera& theCamera, bool selfAvatarOnly) {
|
||||||
skybox = skyStage->getSkybox();
|
skybox = skyStage->getSkybox();
|
||||||
if (skybox) {
|
if (skybox) {
|
||||||
gpu::Batch batch;
|
gpu::Batch batch;
|
||||||
model::Skybox::render(batch, _viewFrustum, *skybox);
|
model::Skybox::render(batch, _displayViewFrustum, *skybox);
|
||||||
|
|
||||||
gpu::GLBackend::renderBatch(batch);
|
gpu::GLBackend::renderBatch(batch);
|
||||||
glUseProgram(0);
|
glUseProgram(0);
|
||||||
|
@ -4656,6 +4673,6 @@ void Application::addMenuItem(const QString& path, std::function<void()> onClick
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QMainWindow* Application::getAppMainWindow() {
|
GlWindow* Application::getVisibleWindow() {
|
||||||
return _window;
|
return _glWindow;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,6 @@
|
||||||
#include "DatagramProcessor.h"
|
#include "DatagramProcessor.h"
|
||||||
#include "Environment.h"
|
#include "Environment.h"
|
||||||
#include "FileLogger.h"
|
#include "FileLogger.h"
|
||||||
#include "GLCanvas.h"
|
|
||||||
#include "Menu.h"
|
#include "Menu.h"
|
||||||
#include "PacketHeaders.h"
|
#include "PacketHeaders.h"
|
||||||
#include "Physics.h"
|
#include "Physics.h"
|
||||||
|
@ -91,6 +90,9 @@ class MainWindow;
|
||||||
class Node;
|
class Node;
|
||||||
class ProgramObject;
|
class ProgramObject;
|
||||||
class ScriptEngine;
|
class ScriptEngine;
|
||||||
|
class GlWindow;
|
||||||
|
class ApplicationOverlayCompositor;
|
||||||
|
using CompositorPtr = std::shared_ptr<ApplicationOverlayCompositor>;
|
||||||
|
|
||||||
static const float NODE_ADDED_RED = 0.0f;
|
static const float NODE_ADDED_RED = 0.0f;
|
||||||
static const float NODE_ADDED_GREEN = 1.0f;
|
static const float NODE_ADDED_GREEN = 1.0f;
|
||||||
|
@ -137,6 +139,7 @@ class Application;
|
||||||
|
|
||||||
typedef bool (Application::* AcceptURLMethod)(const QString &);
|
typedef bool (Application::* AcceptURLMethod)(const QString &);
|
||||||
|
|
||||||
|
|
||||||
class Application : public QApplication, public AbstractViewStateInterface, AbstractScriptingServicesInterface, PluginContainer {
|
class Application : public QApplication, public AbstractViewStateInterface, AbstractScriptingServicesInterface, PluginContainer {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
@ -299,7 +302,7 @@ public:
|
||||||
|
|
||||||
// Plugin container support
|
// Plugin container support
|
||||||
virtual void addMenuItem(const QString& path, std::function<void()> onClicked, bool checkable, bool checked, const QString& groupName);
|
virtual void addMenuItem(const QString& path, std::function<void()> onClicked, bool checkable, bool checked, const QString& groupName);
|
||||||
virtual QMainWindow* getAppMainWindow();
|
virtual GlWindow* getVisibleWindow();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DisplayPlugin * getActiveDisplayPlugin();
|
DisplayPlugin * getActiveDisplayPlugin();
|
||||||
|
@ -446,8 +449,11 @@ private slots:
|
||||||
|
|
||||||
void connectedToDomain(const QString& hostname);
|
void connectedToDomain(const QString& hostname);
|
||||||
|
|
||||||
|
#if 0
|
||||||
friend class HMDToolsDialog;
|
friend class HMDToolsDialog;
|
||||||
void setFullscreen(bool fullscreen);
|
void setFullscreen(bool fullscreen);
|
||||||
|
#endif
|
||||||
|
|
||||||
void cameraMenuChanged();
|
void cameraMenuChanged();
|
||||||
|
|
||||||
void closeMirrorView();
|
void closeMirrorView();
|
||||||
|
@ -544,6 +550,8 @@ private:
|
||||||
ViewFrustum _shadowViewFrustum;
|
ViewFrustum _shadowViewFrustum;
|
||||||
quint64 _lastQueriedTime;
|
quint64 _lastQueriedTime;
|
||||||
|
|
||||||
|
CompositorPtr _compositor;
|
||||||
|
|
||||||
float _trailingAudioLoudness;
|
float _trailingAudioLoudness;
|
||||||
|
|
||||||
OctreeQuery _octreeQuery; // NodeData derived class for querying octee cells from octree servers
|
OctreeQuery _octreeQuery; // NodeData derived class for querying octee cells from octree servers
|
||||||
|
@ -653,6 +661,7 @@ private:
|
||||||
QThread _settingsThread;
|
QThread _settingsThread;
|
||||||
QTimer _settingsTimer;
|
QTimer _settingsTimer;
|
||||||
|
|
||||||
|
GlWindow* _glWindow{ nullptr };
|
||||||
void checkSkeleton();
|
void checkSkeleton();
|
||||||
|
|
||||||
QWidget* _fullscreenMenuWidget = new QWidget();
|
QWidget* _fullscreenMenuWidget = new QWidget();
|
||||||
|
|
|
@ -98,9 +98,12 @@ void MainWindow::changeEvent(QEvent* event) {
|
||||||
emit windowShown(true);
|
emit windowShown(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
if (isFullScreen() != Menu::getInstance()->isOptionChecked(MenuOption::Fullscreen)) {
|
if (isFullScreen() != Menu::getInstance()->isOptionChecked(MenuOption::Fullscreen)) {
|
||||||
Menu::getInstance()->setIsOptionChecked(MenuOption::Fullscreen, isFullScreen());
|
Menu::getInstance()->setIsOptionChecked(MenuOption::Fullscreen, isFullScreen());
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
} else if (event->type() == QEvent::ActivationChange) {
|
} else if (event->type() == QEvent::ActivationChange) {
|
||||||
if (isActiveWindow()) {
|
if (isActiveWindow()) {
|
||||||
emit windowShown(true);
|
emit windowShown(true);
|
||||||
|
|
|
@ -239,6 +239,7 @@ Menu::Menu() {
|
||||||
displayModeGroup->setExclusive(true);
|
displayModeGroup->setExclusive(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
addCheckableActionToQMenuAndActionHash(viewMenu,
|
addCheckableActionToQMenuAndActionHash(viewMenu,
|
||||||
MenuOption::Fullscreen,
|
MenuOption::Fullscreen,
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
|
@ -249,6 +250,7 @@ Menu::Menu() {
|
||||||
false,
|
false,
|
||||||
qApp,
|
qApp,
|
||||||
SLOT(setFullscreen(bool)));
|
SLOT(setFullscreen(bool)));
|
||||||
|
#endif
|
||||||
|
|
||||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FirstPerson,
|
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FirstPerson,
|
||||||
0, // QML Qt::Key_P,
|
0, // QML Qt::Key_P,
|
||||||
|
@ -260,6 +262,7 @@ Menu::Menu() {
|
||||||
0, // QML Qt::Key_H,
|
0, // QML Qt::Key_H,
|
||||||
false, qApp, SLOT(cameraMenuChanged()));
|
false, qApp, SLOT(cameraMenuChanged()));
|
||||||
|
|
||||||
|
#if 0
|
||||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::HMDTools,
|
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::HMDTools,
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
Qt::META | Qt::Key_H,
|
Qt::META | Qt::Key_H,
|
||||||
|
@ -269,6 +272,7 @@ Menu::Menu() {
|
||||||
false,
|
false,
|
||||||
dialogsManager.data(),
|
dialogsManager.data(),
|
||||||
SLOT(hmdTools(bool)));
|
SLOT(hmdTools(bool)));
|
||||||
|
#endif
|
||||||
|
|
||||||
addActionToQMenuAndActionHash(editMenu, MenuOption::Attachments, 0,
|
addActionToQMenuAndActionHash(editMenu, MenuOption::Attachments, 0,
|
||||||
dialogsManager.data(), SLOT(editAttachments()));
|
dialogsManager.data(), SLOT(editAttachments()));
|
||||||
|
|
|
@ -194,12 +194,10 @@ namespace MenuOption {
|
||||||
const QString FilterSixense = "Smooth Sixense Movement";
|
const QString FilterSixense = "Smooth Sixense Movement";
|
||||||
const QString FirstPerson = "First Person";
|
const QString FirstPerson = "First Person";
|
||||||
const QString FrameTimer = "Show Timer";
|
const QString FrameTimer = "Show Timer";
|
||||||
const QString Fullscreen = "Fullscreen";
|
|
||||||
const QString FullscreenMirror = "Fullscreen Mirror";
|
const QString FullscreenMirror = "Fullscreen Mirror";
|
||||||
const QString GlowWhenSpeaking = "Glow When Speaking";
|
const QString GlowWhenSpeaking = "Glow When Speaking";
|
||||||
const QString NamesAboveHeads = "Names Above Heads";
|
const QString NamesAboveHeads = "Names Above Heads";
|
||||||
const QString GoToUser = "Go To User";
|
const QString GoToUser = "Go To User";
|
||||||
const QString HMDTools = "HMD Tools";
|
|
||||||
const QString IncreaseAvatarSize = "Increase Avatar Size";
|
const QString IncreaseAvatarSize = "Increase Avatar Size";
|
||||||
const QString KeyboardMotorControl = "Enable Keyboard Motor Control";
|
const QString KeyboardMotorControl = "Enable Keyboard Motor Control";
|
||||||
const QString LeapMotionOnHMD = "Leap Motion on HMD";
|
const QString LeapMotionOnHMD = "Leap Motion on HMD";
|
||||||
|
|
209
interface/src/ui/ApplicationOverlayCompositor.cpp
Normal file
209
interface/src/ui/ApplicationOverlayCompositor.cpp
Normal file
|
@ -0,0 +1,209 @@
|
||||||
|
#include "ApplicationOverlayCompositor.h"
|
||||||
|
|
||||||
|
#include <TextureCache.h>
|
||||||
|
#include <PathUtils.h>
|
||||||
|
#include <ViewFrustum.h>
|
||||||
|
#include <MatrixStack.h>
|
||||||
|
#include <gpu/GLBackend.h>
|
||||||
|
|
||||||
|
#define DEFAULT_HMD_UI_ANGULAR_SIZE 72.0f
|
||||||
|
|
||||||
|
ApplicationOverlayCompositor::ApplicationOverlayCompositor() {
|
||||||
|
using namespace oglplus;
|
||||||
|
|
||||||
|
auto currentContext = QOpenGLContext::currentContext();
|
||||||
|
Q_ASSERT(currentContext);
|
||||||
|
_canvas.create(currentContext);
|
||||||
|
_canvas.makeCurrent();
|
||||||
|
Q_ASSERT(0 == glGetError());
|
||||||
|
currentContext = QOpenGLContext::currentContext();
|
||||||
|
Q_ASSERT(currentContext);
|
||||||
|
|
||||||
|
Context::ClearColor(0, 0, 0, 1);
|
||||||
|
Q_ASSERT(0 == glGetError());
|
||||||
|
Context::BlendFunc(BlendFunction::SrcAlpha, BlendFunction::OneMinusSrcAlpha);
|
||||||
|
Q_ASSERT(0 == glGetError());
|
||||||
|
Context::Disable(Capability::Blend);
|
||||||
|
Q_ASSERT(0 == glGetError());
|
||||||
|
Context::Disable(Capability::DepthTest);
|
||||||
|
Q_ASSERT(0 == glGetError());
|
||||||
|
Context::Disable(Capability::CullFace);
|
||||||
|
Q_ASSERT(0 == glGetError());
|
||||||
|
|
||||||
|
_program = loadDefaultShader();
|
||||||
|
_plane = loadPlane(_program);
|
||||||
|
|
||||||
|
_program = loadDefaultShader();
|
||||||
|
_plane = loadPlane(_program);
|
||||||
|
_hmdUiSurface = loadSphereSection(_program, glm::radians(DEFAULT_HMD_UI_ANGULAR_SIZE));
|
||||||
|
|
||||||
|
_crosshairTexture = DependencyManager::get<TextureCache>()->
|
||||||
|
getImageTexture(PathUtils::resourcesPath() + "images/sixense-reticle.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GLuint ApplicationOverlayCompositor::composite(DisplayPlugin* plugin,
|
||||||
|
GLuint sceneTexture, const glm::uvec2& sceneSize,
|
||||||
|
GLuint overlayTexture, const glm::uvec2& overlaySize) {
|
||||||
|
using namespace oglplus;
|
||||||
|
_canvas.makeCurrent();
|
||||||
|
if (!_fbo || sceneSize != _fbo->size) {
|
||||||
|
_fbo = BasicFramebufferWrapperPtr(new BasicFramebufferWrapper());
|
||||||
|
_fbo->Init(sceneSize);
|
||||||
|
}
|
||||||
|
_fbo->Bound(Framebuffer::Target::Draw, [&] {
|
||||||
|
Context::Clear().ColorBuffer();
|
||||||
|
if (plugin->isHmd()) {
|
||||||
|
compositeHmd(plugin, sceneTexture, sceneSize, overlayTexture, overlaySize);
|
||||||
|
} else if (plugin->isStereo()) {
|
||||||
|
compositeStereo(plugin, sceneTexture, sceneSize, overlayTexture, overlaySize);
|
||||||
|
} else {
|
||||||
|
composite2D(plugin, sceneTexture, sceneSize, overlayTexture, overlaySize);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
GLuint result = GetName(_fbo->color);
|
||||||
|
_canvas.doneCurrent();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApplicationOverlayCompositor::composite2D(DisplayPlugin* plugin,
|
||||||
|
GLuint sceneTexture, const glm::uvec2& sceneSize,
|
||||||
|
GLuint overlayTexture, const glm::uvec2& overlaySize) {
|
||||||
|
using namespace oglplus;
|
||||||
|
const uvec2 size = toGlm(plugin->getDeviceSize());
|
||||||
|
|
||||||
|
Q_ASSERT(0 == glGetError());
|
||||||
|
|
||||||
|
Context::Viewport(size.x, size.y);
|
||||||
|
_program->Bind();
|
||||||
|
Mat4Uniform(*_program, "ModelView").Set(mat4());
|
||||||
|
Mat4Uniform(*_program, "Projection").Set(mat4());
|
||||||
|
glBindTexture(GL_TEXTURE_2D, sceneTexture);
|
||||||
|
_plane->Use();
|
||||||
|
_plane->Draw();
|
||||||
|
Context::Enable(Capability::Blend);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, overlayTexture);
|
||||||
|
_plane->Draw();
|
||||||
|
Context::Disable(Capability::Blend);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
|
// FIXME add the cursor
|
||||||
|
|
||||||
|
Q_ASSERT(0 == glGetError());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename F>
|
||||||
|
void sbs_for_each_eye(const uvec2& size, F f) {
|
||||||
|
QRect r(QPoint(0, 0), QSize(size.x / 2, size.y));
|
||||||
|
for_each_eye([&](Eye eye) {
|
||||||
|
oglplus::Context::Viewport(r.x(), r.y(), r.width(), r.height());
|
||||||
|
f(eye);
|
||||||
|
}, [&] {
|
||||||
|
r.moveLeft(r.width());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApplicationOverlayCompositor::compositeStereo(DisplayPlugin* plugin,
|
||||||
|
GLuint sceneTexture, const glm::uvec2& sceneSize,
|
||||||
|
GLuint overlayTexture, const glm::uvec2& overlaySize) {
|
||||||
|
using namespace oglplus;
|
||||||
|
|
||||||
|
Q_ASSERT(0 == glGetError());
|
||||||
|
const uvec2 size = sceneSize;
|
||||||
|
|
||||||
|
Context::Viewport(size.x, size.y);
|
||||||
|
|
||||||
|
_program->Bind();
|
||||||
|
|
||||||
|
Mat4Uniform(*_program, "ModelView").Set(mat4());
|
||||||
|
Mat4Uniform(*_program, "Projection").Set(mat4());
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, sceneTexture);
|
||||||
|
|
||||||
|
_plane->Use();
|
||||||
|
_plane->Draw();
|
||||||
|
|
||||||
|
// FIXME the
|
||||||
|
const float screenAspect = aspect(size);
|
||||||
|
const GLfloat distance = 1.0f;
|
||||||
|
const GLfloat halfQuadHeight = distance * tan(DEFAULT_FIELD_OF_VIEW_DEGREES);
|
||||||
|
const GLfloat halfQuadWidth = halfQuadHeight * screenAspect;
|
||||||
|
const GLfloat quadWidth = halfQuadWidth * 2.0f;
|
||||||
|
const GLfloat quadHeight = halfQuadHeight * 2.0f;
|
||||||
|
|
||||||
|
vec3 quadSize(quadWidth, quadHeight, 1.0f);
|
||||||
|
quadSize = vec3(1.0f) / quadSize;
|
||||||
|
|
||||||
|
using namespace oglplus;
|
||||||
|
Context::Enable(Capability::Blend);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, overlayTexture);
|
||||||
|
|
||||||
|
mat4 pr = glm::perspective(glm::radians(DEFAULT_FIELD_OF_VIEW_DEGREES), screenAspect, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP);
|
||||||
|
Mat4Uniform(*_program, "Projection").Set(pr);
|
||||||
|
|
||||||
|
// Position the camera relative to the overlay texture
|
||||||
|
MatrixStack mv;
|
||||||
|
mv.translate(vec3(0, 0, -distance)).scale(vec3(0.7f, 0.7f / screenAspect, 1.0f)); // .scale(vec3(quadWidth, quadHeight, 1.0));
|
||||||
|
sbs_for_each_eye(size, [&](Eye eye) {
|
||||||
|
mv.withPush([&] {
|
||||||
|
// translate
|
||||||
|
mv.top() = plugin->getModelview(eye, mv.top());
|
||||||
|
Mat4Uniform(*_program, "ModelView").Set(mv.top());
|
||||||
|
_plane->Draw();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(_crosshairTexture));
|
||||||
|
glm::vec2 canvasSize = plugin->getCanvasSize();
|
||||||
|
glm::vec2 mouse = vec2(0); // toGlm(_window->mapFromGlobal(QCursor::pos()));
|
||||||
|
mouse /= canvasSize;
|
||||||
|
mouse *= 2.0f;
|
||||||
|
mouse -= 1.0f;
|
||||||
|
mouse.y *= -1.0f;
|
||||||
|
sbs_for_each_eye(size, [&](Eye eye) {
|
||||||
|
mv.withPush([&] {
|
||||||
|
// translate
|
||||||
|
mv.top() = plugin->getModelview(eye, mv.top());
|
||||||
|
mv.translate(mouse);
|
||||||
|
//mv.scale(0.05f);
|
||||||
|
mv.scale(vec3(0.025f, 0.05f, 1.0f));
|
||||||
|
Mat4Uniform(*_program, "ModelView").Set(mv.top());
|
||||||
|
_plane->Draw();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
Context::Disable(Capability::Blend);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApplicationOverlayCompositor::compositeHmd(DisplayPlugin* plugin,
|
||||||
|
GLuint sceneTexture, const glm::uvec2& sceneSize,
|
||||||
|
GLuint overlayTexture, const glm::uvec2& overlaySize) {
|
||||||
|
using namespace oglplus;
|
||||||
|
auto size = sceneSize;
|
||||||
|
|
||||||
|
Context::Viewport(size.x, size.y);
|
||||||
|
|
||||||
|
glClearColor(0, 0, 0, 0);
|
||||||
|
Context::Clear().ColorBuffer();
|
||||||
|
|
||||||
|
_program->Bind();
|
||||||
|
Mat4Uniform(*_program, "Projection").Set(mat4());
|
||||||
|
Mat4Uniform(*_program, "ModelView").Set(mat4());
|
||||||
|
glBindTexture(GL_TEXTURE_2D, sceneTexture);
|
||||||
|
_plane->Use();
|
||||||
|
_plane->Draw();
|
||||||
|
|
||||||
|
|
||||||
|
Context::Enable(Capability::Blend);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, overlayTexture);
|
||||||
|
for_each_eye([&](Eye eye) {
|
||||||
|
Context::Viewport(eye == Left ? 0 : size.x / 2, 0, size.x / 2, size.y);
|
||||||
|
glm::mat4 m = plugin->getProjection(eye, glm::mat4());
|
||||||
|
Mat4Uniform(*_program, "Projection").Set(m);
|
||||||
|
Mat4Uniform(*_program, "ModelView").Set(glm::scale(glm::inverse(plugin->getModelview(eye, mat4())), vec3(1)));
|
||||||
|
_hmdUiSurface->Use();
|
||||||
|
_hmdUiSurface->Draw();
|
||||||
|
});
|
||||||
|
Context::Disable(Capability::Blend);
|
||||||
|
}
|
37
interface/src/ui/ApplicationOverlayCompositor.h
Normal file
37
interface/src/ui/ApplicationOverlayCompositor.h
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <gpu/Texture.h>
|
||||||
|
#include <display-plugins/DisplayPlugin.h>
|
||||||
|
#include <display-plugins/OglplusHelpers.h>
|
||||||
|
#include <OffscreenGlCanvas.h>
|
||||||
|
|
||||||
|
class ApplicationOverlayCompositor {
|
||||||
|
public:
|
||||||
|
ApplicationOverlayCompositor();
|
||||||
|
GLuint composite(DisplayPlugin* plugin,
|
||||||
|
GLuint sceneTexture, const glm::uvec2& sceneSize,
|
||||||
|
GLuint overlayTexture, const glm::uvec2& overlaySize);
|
||||||
|
|
||||||
|
private:
|
||||||
|
OffscreenGlCanvas _canvas;
|
||||||
|
BasicFramebufferWrapperPtr _fbo;
|
||||||
|
ProgramPtr _program;
|
||||||
|
ShapeWrapperPtr _plane;
|
||||||
|
ShapeWrapperPtr _hmdUiSurface;
|
||||||
|
gpu::TexturePointer _crosshairTexture;
|
||||||
|
|
||||||
|
void composite2D(DisplayPlugin* plugin,
|
||||||
|
GLuint sceneTexture, const glm::uvec2& sceneSize,
|
||||||
|
GLuint overlayTexture, const glm::uvec2& overlaySize);
|
||||||
|
|
||||||
|
void compositeStereo(DisplayPlugin* plugin,
|
||||||
|
GLuint sceneTexture, const glm::uvec2& sceneSize,
|
||||||
|
GLuint overlayTexture, const glm::uvec2& overlaySize);
|
||||||
|
|
||||||
|
void compositeHmd(DisplayPlugin* plugin,
|
||||||
|
GLuint sceneTexture, const glm::uvec2& sceneSize,
|
||||||
|
GLuint overlayTexture, const glm::uvec2& overlaySize);
|
||||||
|
};
|
||||||
|
|
||||||
|
using CompositorPtr = std::shared_ptr<ApplicationOverlayCompositor>;
|
|
@ -68,13 +68,12 @@ public:
|
||||||
* OpenGL context
|
* OpenGL context
|
||||||
*/
|
*/
|
||||||
virtual void preDisplay() = 0;
|
virtual void preDisplay() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends the scene texture and the overlay texture to the display plugin.
|
* Sends the scene texture to the display plugin.
|
||||||
* The plugin is responsible for compositing these and adding rendering of
|
|
||||||
* additional elements like mouse and hydra pointers as required
|
|
||||||
*/
|
*/
|
||||||
virtual void display(GLuint sceneTexture, const glm::uvec2& sceneSize,
|
virtual void display(GLuint sceneTexture, const glm::uvec2& sceneSize) = 0;
|
||||||
GLuint overlayTexture, const glm::uvec2& overlaySize) = 0;
|
|
||||||
/**
|
/**
|
||||||
* Called by the application immeidately after display. For OpenGL based
|
* Called by the application immeidately after display. For OpenGL based
|
||||||
* displays, this is the best place to put the buffer swap
|
* displays, this is the best place to put the buffer swap
|
||||||
|
|
|
@ -7,32 +7,47 @@
|
||||||
//
|
//
|
||||||
#include "MainWindowOpenGLDisplayPlugin.h"
|
#include "MainWindowOpenGLDisplayPlugin.h"
|
||||||
|
|
||||||
#include <GlWindow.h>
|
|
||||||
#include <QOpenGLContext>
|
#include <QOpenGLContext>
|
||||||
#include <plugins/PluginContainer.h>
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
|
|
||||||
|
#include <GlWindow.h>
|
||||||
|
#include <plugins/PluginContainer.h>
|
||||||
|
|
||||||
MainWindowOpenGLDisplayPlugin::MainWindowOpenGLDisplayPlugin() {
|
MainWindowOpenGLDisplayPlugin::MainWindowOpenGLDisplayPlugin() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindowOpenGLDisplayPlugin::activate(PluginContainer * container) {
|
GlWindow* MainWindowOpenGLDisplayPlugin::createWindow(PluginContainer * container) {
|
||||||
WindowOpenGLDisplayPlugin::activate(container);
|
return container->getVisibleWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindowOpenGLDisplayPlugin::customizeWindow(PluginContainer * container) {
|
void MainWindowOpenGLDisplayPlugin::customizeWindow(PluginContainer * container) {
|
||||||
// Can't set the central widget here, because it seems to mess up the context creation.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindowOpenGLDisplayPlugin::customizeContext(PluginContainer * container) {
|
void MainWindowOpenGLDisplayPlugin::destroyWindow() {
|
||||||
WindowOpenGLDisplayPlugin::customizeContext(container);
|
_window = nullptr;
|
||||||
QWidget* widget = QWidget::createWindowContainer(_window);
|
|
||||||
auto mainWindow = container->getAppMainWindow();
|
|
||||||
mainWindow->setCentralWidget(widget);
|
|
||||||
mainWindow->resize(mainWindow->geometry().size());
|
|
||||||
_window->resize(_window->geometry().size());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindowOpenGLDisplayPlugin::deactivate() {
|
void MainWindowOpenGLDisplayPlugin::display(
|
||||||
WindowOpenGLDisplayPlugin::deactivate();
|
GLuint finalTexture, const glm::uvec2& sceneSize) {
|
||||||
|
OpenGLDisplayPlugin::display(finalTexture, sceneSize);
|
||||||
|
return;
|
||||||
|
|
||||||
|
using namespace oglplus;
|
||||||
|
glClearColor(0, 1, 0, 1);
|
||||||
|
uvec2 size = toGlm(getDeviceSize());
|
||||||
|
Context::Viewport(size.x, size.y);
|
||||||
|
Context::Clear().ColorBuffer();
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, finalTexture);
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
glTexCoord2f(0, 0);
|
||||||
|
glVertex2f(-1, -1);
|
||||||
|
glTexCoord2f(1, 0);
|
||||||
|
glVertex2f(1, -1);
|
||||||
|
glTexCoord2f(1, 1);
|
||||||
|
glVertex2f(1, 1);
|
||||||
|
glTexCoord2f(0, 1);
|
||||||
|
glVertex2f(-1, 1);
|
||||||
|
glEnd();
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,17 +9,16 @@
|
||||||
|
|
||||||
#include "WindowOpenGLDisplayPlugin.h"
|
#include "WindowOpenGLDisplayPlugin.h"
|
||||||
|
|
||||||
class GlWindow;
|
class QGLWidget;
|
||||||
class QSurfaceFormat;
|
|
||||||
|
|
||||||
class MainWindowOpenGLDisplayPlugin : public WindowOpenGLDisplayPlugin {
|
class MainWindowOpenGLDisplayPlugin : public WindowOpenGLDisplayPlugin {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
MainWindowOpenGLDisplayPlugin();
|
MainWindowOpenGLDisplayPlugin();
|
||||||
virtual void activate(PluginContainer * container) override;
|
virtual void display(GLuint sceneTexture, const glm::uvec2& sceneSize) override;
|
||||||
virtual void deactivate() override;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void customizeWindow(PluginContainer * container) override;
|
virtual GlWindow* createWindow(PluginContainer * container) override final;
|
||||||
virtual void customizeContext(PluginContainer * container) override;
|
virtual void customizeWindow(PluginContainer * container) override final;
|
||||||
|
virtual void destroyWindow() override final;
|
||||||
};
|
};
|
||||||
|
|
|
@ -49,8 +49,7 @@ QWindow* NullDisplayPlugin::getWindow() const {
|
||||||
|
|
||||||
void NullDisplayPlugin::preRender() {}
|
void NullDisplayPlugin::preRender() {}
|
||||||
void NullDisplayPlugin::preDisplay() {}
|
void NullDisplayPlugin::preDisplay() {}
|
||||||
void NullDisplayPlugin::display(GLuint sceneTexture, const glm::uvec2& sceneSize,
|
void NullDisplayPlugin::display(GLuint sceneTexture, const glm::uvec2& sceneSize) {}
|
||||||
GLuint overlayTexture, const glm::uvec2& overlaySize) {}
|
|
||||||
void NullDisplayPlugin::finishFrame() {}
|
void NullDisplayPlugin::finishFrame() {}
|
||||||
|
|
||||||
void NullDisplayPlugin::activate(PluginContainer * container) {}
|
void NullDisplayPlugin::activate(PluginContainer * container) {}
|
||||||
|
|
|
@ -29,7 +29,6 @@ public:
|
||||||
virtual QWindow* getWindow() const;
|
virtual QWindow* getWindow() const;
|
||||||
virtual void preRender();
|
virtual void preRender();
|
||||||
virtual void preDisplay();
|
virtual void preDisplay();
|
||||||
virtual void display(GLuint sceneTexture, const glm::uvec2& sceneSize,
|
virtual void display(GLuint sceneTexture, const glm::uvec2& sceneSize);
|
||||||
GLuint overlayTexture, const glm::uvec2& overlaySize);
|
|
||||||
virtual void finishFrame();
|
virtual void finishFrame();
|
||||||
};
|
};
|
||||||
|
|
|
@ -29,12 +29,12 @@
|
||||||
|
|
||||||
#include <NumericalConstants.h>
|
#include <NumericalConstants.h>
|
||||||
|
|
||||||
typedef std::shared_ptr<oglplus::Framebuffer> FramebufferPtr;
|
using FramebufferPtr = std::shared_ptr<oglplus::Framebuffer>;
|
||||||
typedef std::shared_ptr<oglplus::shapes::ShapeWrapper> ShapeWrapperPtr;
|
using ShapeWrapperPtr = std::shared_ptr<oglplus::shapes::ShapeWrapper>;
|
||||||
typedef std::shared_ptr<oglplus::Buffer> BufferPtr;
|
using BufferPtr = std::shared_ptr<oglplus::Buffer>;
|
||||||
typedef std::shared_ptr<oglplus::VertexArray> VertexArrayPtr;
|
using VertexArrayPtr = std::shared_ptr<oglplus::VertexArray>;
|
||||||
typedef std::shared_ptr<oglplus::Program> ProgramPtr;
|
using ProgramPtr = std::shared_ptr<oglplus::Program>;
|
||||||
typedef oglplus::Uniform<mat4> Mat4Uniform;
|
using Mat4Uniform = oglplus::Uniform<mat4>;
|
||||||
|
|
||||||
ProgramPtr loadDefaultShader();
|
ProgramPtr loadDefaultShader();
|
||||||
void compileProgram(ProgramPtr & result, const std::string& vs, const std::string& fs);
|
void compileProgram(ProgramPtr & result, const std::string& vs, const std::string& fs);
|
||||||
|
@ -56,8 +56,8 @@ template <
|
||||||
struct FramebufferWrapper {
|
struct FramebufferWrapper {
|
||||||
uvec2 size;
|
uvec2 size;
|
||||||
oglplus::Framebuffer fbo;
|
oglplus::Framebuffer fbo;
|
||||||
C color{ 0 };
|
C color;
|
||||||
D depth{ 0 };
|
D depth;
|
||||||
|
|
||||||
FramebufferWrapper() {}
|
FramebufferWrapper() {}
|
||||||
|
|
||||||
|
@ -112,7 +112,6 @@ protected:
|
||||||
virtual void initDone() = 0;
|
virtual void initDone() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct BasicFramebufferWrapper : public FramebufferWrapper <oglplus::Texture, oglplus::Renderbuffer> {
|
struct BasicFramebufferWrapper : public FramebufferWrapper <oglplus::Texture, oglplus::Renderbuffer> {
|
||||||
protected:
|
protected:
|
||||||
virtual void initDepth() override {
|
virtual void initDepth() override {
|
||||||
|
@ -147,3 +146,5 @@ protected:
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using BasicFramebufferWrapperPtr = std::shared_ptr<BasicFramebufferWrapper>;
|
|
@ -8,11 +8,6 @@
|
||||||
#include "OpenGLDisplayPlugin.h"
|
#include "OpenGLDisplayPlugin.h"
|
||||||
|
|
||||||
#include <QOpenGLContext>
|
#include <QOpenGLContext>
|
||||||
#include <TextureCache.h>
|
|
||||||
#include <PathUtils.h>
|
|
||||||
|
|
||||||
#include <QOpenGLContext>
|
|
||||||
#include <QCursor>
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
|
|
||||||
#include <GLWindow.h>
|
#include <GLWindow.h>
|
||||||
|
@ -50,8 +45,6 @@ void OpenGLDisplayPlugin::customizeContext(PluginContainer * container) {
|
||||||
_program = loadDefaultShader();
|
_program = loadDefaultShader();
|
||||||
_plane = loadPlane(_program);
|
_plane = loadPlane(_program);
|
||||||
Context::ClearColor(0, 0, 0, 1);
|
Context::ClearColor(0, 0, 0, 1);
|
||||||
_crosshairTexture = DependencyManager::get<TextureCache>()->
|
|
||||||
getImageTexture(PathUtils::resourcesPath() + "images/sixense-reticle.png");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLDisplayPlugin::activate(PluginContainer * container) {
|
void OpenGLDisplayPlugin::activate(PluginContainer * container) {
|
||||||
|
@ -60,11 +53,11 @@ void OpenGLDisplayPlugin::activate(PluginContainer * container) {
|
||||||
|
|
||||||
void OpenGLDisplayPlugin::deactivate() {
|
void OpenGLDisplayPlugin::deactivate() {
|
||||||
_timer.stop();
|
_timer.stop();
|
||||||
|
|
||||||
makeCurrent();
|
makeCurrent();
|
||||||
Q_ASSERT(0 == glGetError());
|
Q_ASSERT(0 == glGetError());
|
||||||
_plane.reset();
|
_plane.reset();
|
||||||
_program.reset();
|
_program.reset();
|
||||||
_crosshairTexture.reset();
|
|
||||||
doneCurrent();
|
doneCurrent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,25 +102,15 @@ bool OpenGLDisplayPlugin::eventFilter(QObject* receiver, QEvent* event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLDisplayPlugin::display(
|
void OpenGLDisplayPlugin::display(
|
||||||
GLuint sceneTexture, const glm::uvec2& sceneSize,
|
GLuint finalTexture, const glm::uvec2& sceneSize) {
|
||||||
GLuint overlayTexture, const glm::uvec2& overlaySize) {
|
|
||||||
makeCurrent();
|
|
||||||
Q_ASSERT(0 == glGetError());
|
|
||||||
uvec2 size = toGlm(getDeviceSize());
|
|
||||||
using namespace oglplus;
|
using namespace oglplus;
|
||||||
|
|
||||||
|
uvec2 size = toGlm(getDeviceSize());
|
||||||
Context::Viewport(size.x, size.y);
|
Context::Viewport(size.x, size.y);
|
||||||
glClearColor(0, 1, 1, 1);
|
Context::Clear().ColorBuffer();
|
||||||
Context::Clear().ColorBuffer().DepthBuffer();
|
|
||||||
_program->Bind();
|
_program->Bind();
|
||||||
Mat4Uniform(*_program, "ModelView").Set(mat4());
|
glBindTexture(GL_TEXTURE_2D, finalTexture);
|
||||||
Mat4Uniform(*_program, "Projection").Set(mat4());
|
|
||||||
glBindTexture(GL_TEXTURE_2D, sceneTexture);
|
|
||||||
_plane->Use();
|
_plane->Use();
|
||||||
_plane->Draw();
|
_plane->Draw();
|
||||||
Context::Enable(Capability::Blend);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, overlayTexture);
|
|
||||||
_plane->Draw();
|
|
||||||
Context::Disable(Capability::Blend);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
Q_ASSERT(0 == glGetError());
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,13 +9,12 @@
|
||||||
|
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
#include <gpu/Texture.h>
|
|
||||||
|
|
||||||
#include "DisplayPlugin.h"
|
#include "DisplayPlugin.h"
|
||||||
#include "OglplusHelpers.h"
|
#include "OglplusHelpers.h"
|
||||||
|
|
||||||
class GlWindow;
|
class GlWindow;
|
||||||
class QOpenGLContext;
|
class QOpenGLContext;
|
||||||
|
|
||||||
class OpenGLDisplayPlugin : public DisplayPlugin {
|
class OpenGLDisplayPlugin : public DisplayPlugin {
|
||||||
public:
|
public:
|
||||||
OpenGLDisplayPlugin();
|
OpenGLDisplayPlugin();
|
||||||
|
@ -29,9 +28,7 @@ public:
|
||||||
|
|
||||||
virtual bool eventFilter(QObject* receiver, QEvent* event) override;
|
virtual bool eventFilter(QObject* receiver, QEvent* event) override;
|
||||||
|
|
||||||
void display(
|
virtual void display(GLuint sceneTexture, const glm::uvec2& sceneSize) override;
|
||||||
GLuint sceneTexture, const glm::uvec2& sceneSize,
|
|
||||||
GLuint overlayTexture, const glm::uvec2& overlaySize) override;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -46,7 +43,6 @@ protected:
|
||||||
QTimer _timer;
|
QTimer _timer;
|
||||||
ProgramPtr _program;
|
ProgramPtr _program;
|
||||||
ShapeWrapperPtr _plane;
|
ShapeWrapperPtr _plane;
|
||||||
gpu::TexturePointer _crosshairTexture;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#include <QGLContext>
|
#include <QGLContext>
|
||||||
#include <QGLWidget>
|
#include <QGLWidget>
|
||||||
#include "plugins/PluginContainer.h"
|
#include "plugins/PluginContainer.h"
|
||||||
|
#if 0
|
||||||
WidgetOpenGLDisplayPlugin::WidgetOpenGLDisplayPlugin() {
|
WidgetOpenGLDisplayPlugin::WidgetOpenGLDisplayPlugin() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,3 +106,4 @@ void WidgetOpenGLDisplayPlugin::removeEventFilter(QObject* filter) {
|
||||||
QWindow* WidgetOpenGLDisplayPlugin::getWindow() const {
|
QWindow* WidgetOpenGLDisplayPlugin::getWindow() const {
|
||||||
return _widget->windowHandle();
|
return _widget->windowHandle();
|
||||||
}
|
}
|
||||||
|
#endif
|
|
@ -42,7 +42,7 @@ void WindowOpenGLDisplayPlugin::initSurfaceFormat(QSurfaceFormat& format) {
|
||||||
|
|
||||||
void WindowOpenGLDisplayPlugin::activate(PluginContainer * container) {
|
void WindowOpenGLDisplayPlugin::activate(PluginContainer * container) {
|
||||||
OpenGLDisplayPlugin::activate(container);
|
OpenGLDisplayPlugin::activate(container);
|
||||||
_window = new GlWindow(QOpenGLContext::currentContext());
|
_window = createWindow(container);
|
||||||
|
|
||||||
QSurfaceFormat format;
|
QSurfaceFormat format;
|
||||||
initSurfaceFormat(format);
|
initSurfaceFormat(format);
|
||||||
|
@ -57,6 +57,14 @@ void WindowOpenGLDisplayPlugin::activate(PluginContainer * container) {
|
||||||
|
|
||||||
void WindowOpenGLDisplayPlugin::deactivate() {
|
void WindowOpenGLDisplayPlugin::deactivate() {
|
||||||
OpenGLDisplayPlugin::deactivate();
|
OpenGLDisplayPlugin::deactivate();
|
||||||
|
destroyWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
GlWindow* WindowOpenGLDisplayPlugin::createWindow(PluginContainer * container) {
|
||||||
|
return new GlWindow(QOpenGLContext::currentContext());
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowOpenGLDisplayPlugin::destroyWindow() {
|
||||||
_window->deleteLater();
|
_window->deleteLater();
|
||||||
_window = nullptr;
|
_window = nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,10 +28,14 @@ public:
|
||||||
virtual void removeEventFilter(QObject* filter) override;
|
virtual void removeEventFilter(QObject* filter) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
virtual GlWindow* createWindow(PluginContainer * container);
|
||||||
|
virtual void customizeWindow(PluginContainer * container) = 0;
|
||||||
|
|
||||||
|
virtual void destroyWindow();
|
||||||
|
|
||||||
virtual void makeCurrent() override;
|
virtual void makeCurrent() override;
|
||||||
virtual void doneCurrent() override;
|
virtual void doneCurrent() override;
|
||||||
virtual void swapBuffers() override;
|
virtual void swapBuffers() override;
|
||||||
virtual void customizeWindow(PluginContainer * container) = 0;
|
|
||||||
virtual void initSurfaceFormat(QSurfaceFormat& format);
|
virtual void initSurfaceFormat(QSurfaceFormat& format);
|
||||||
|
|
||||||
GlWindow* _window{ nullptr };
|
GlWindow* _window{ nullptr };
|
||||||
|
|
|
@ -30,13 +30,6 @@
|
||||||
|
|
||||||
#include "../OglplusHelpers.h"
|
#include "../OglplusHelpers.h"
|
||||||
|
|
||||||
#define DEFAULT_HMD_UI_ANGULAR_SIZE 72.0f
|
|
||||||
|
|
||||||
using oglplus::Framebuffer;
|
|
||||||
using oglplus::DefaultFramebuffer;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// A base class for FBO wrappers that need to use the Oculus C
|
// A base class for FBO wrappers that need to use the Oculus C
|
||||||
// API to manage textures via ovrHmd_CreateSwapTextureSetGL,
|
// API to manage textures via ovrHmd_CreateSwapTextureSetGL,
|
||||||
|
@ -44,7 +37,10 @@ using oglplus::DefaultFramebuffer;
|
||||||
template <typename C>
|
template <typename C>
|
||||||
struct RiftFramebufferWrapper : public FramebufferWrapper<C, char> {
|
struct RiftFramebufferWrapper : public FramebufferWrapper<C, char> {
|
||||||
ovrHmd hmd;
|
ovrHmd hmd;
|
||||||
RiftFramebufferWrapper(const ovrHmd & hmd) : hmd(hmd) {};
|
RiftFramebufferWrapper(const ovrHmd & hmd) : hmd(hmd) {
|
||||||
|
color = 0;
|
||||||
|
depth = 0;
|
||||||
|
};
|
||||||
|
|
||||||
void Resize(const uvec2 & size) {
|
void Resize(const uvec2 & size) {
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, oglplus::GetName(fbo));
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, oglplus::GetName(fbo));
|
||||||
|
@ -181,6 +177,7 @@ void OculusWin32DisplayPlugin::activate(PluginContainer * container) {
|
||||||
Q_ASSERT(false);
|
Q_ASSERT(false);
|
||||||
qFatal("Failed to acquire HMD");
|
qFatal("Failed to acquire HMD");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parent class relies on our _hmd intialization, so it must come after that.
|
// Parent class relies on our _hmd intialization, so it must come after that.
|
||||||
ovrLayerEyeFov& sceneLayer = getSceneLayer();
|
ovrLayerEyeFov& sceneLayer = getSceneLayer();
|
||||||
memset(&sceneLayer, 0, sizeof(ovrLayerEyeFov));
|
memset(&sceneLayer, 0, sizeof(ovrLayerEyeFov));
|
||||||
|
@ -200,7 +197,6 @@ void OculusWin32DisplayPlugin::activate(PluginContainer * container) {
|
||||||
//uiLayer.Header.Flags = ovrLayerFlag_TextureOriginAtBottomLeft | ovrLayerFlag_HighQuality;
|
//uiLayer.Header.Flags = ovrLayerFlag_TextureOriginAtBottomLeft | ovrLayerFlag_HighQuality;
|
||||||
//uiLayer.QuadPoseCenter.Orientation = { 0, 0, 0, 1 };
|
//uiLayer.QuadPoseCenter.Orientation = { 0, 0, 0, 1 };
|
||||||
//uiLayer.QuadPoseCenter.Position = { 0, 0, -1 };
|
//uiLayer.QuadPoseCenter.Position = { 0, 0, -1 };
|
||||||
|
|
||||||
OculusBaseDisplayPlugin::activate(container);
|
OculusBaseDisplayPlugin::activate(container);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,9 +205,6 @@ void OculusWin32DisplayPlugin::customizeContext(PluginContainer * container) {
|
||||||
|
|
||||||
//_texture = DependencyManager::get<TextureCache>()->
|
//_texture = DependencyManager::get<TextureCache>()->
|
||||||
// getImageTexture(PathUtils::resourcesPath() + "/images/cube_texture.png");
|
// getImageTexture(PathUtils::resourcesPath() + "/images/cube_texture.png");
|
||||||
|
|
||||||
_uiSurface = loadSphereSection(_program, glm::radians(DEFAULT_HMD_UI_ANGULAR_SIZE), aspect(getCanvasSize()));
|
|
||||||
|
|
||||||
uvec2 mirrorSize = toGlm(_window->geometry().size());
|
uvec2 mirrorSize = toGlm(_window->geometry().size());
|
||||||
_mirrorFbo = MirrorFboPtr(new MirrorFramebufferWrapper(_hmd));
|
_mirrorFbo = MirrorFboPtr(new MirrorFramebufferWrapper(_hmd));
|
||||||
_mirrorFbo->Init(mirrorSize);
|
_mirrorFbo->Init(mirrorSize);
|
||||||
|
@ -233,7 +226,6 @@ void OculusWin32DisplayPlugin::deactivate() {
|
||||||
makeCurrent();
|
makeCurrent();
|
||||||
_sceneFbo.reset();
|
_sceneFbo.reset();
|
||||||
_mirrorFbo.reset();
|
_mirrorFbo.reset();
|
||||||
_uiSurface.reset();
|
|
||||||
doneCurrent();
|
doneCurrent();
|
||||||
PerformanceTimer::setActive(false);
|
PerformanceTimer::setActive(false);
|
||||||
|
|
||||||
|
@ -244,11 +236,8 @@ void OculusWin32DisplayPlugin::deactivate() {
|
||||||
ovr_Shutdown();
|
ovr_Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OculusWin32DisplayPlugin::display(
|
void OculusWin32DisplayPlugin::display(GLuint finalTexture, const glm::uvec2& sceneSize) {
|
||||||
GLuint sceneTexture, const glm::uvec2& sceneSize,
|
|
||||||
GLuint overlayTexture, const glm::uvec2& overlaySize) {
|
|
||||||
using namespace oglplus;
|
using namespace oglplus;
|
||||||
|
|
||||||
// Need to make sure only the display plugin is responsible for
|
// Need to make sure only the display plugin is responsible for
|
||||||
// controlling vsync
|
// controlling vsync
|
||||||
wglSwapIntervalEXT(0);
|
wglSwapIntervalEXT(0);
|
||||||
|
@ -257,68 +246,19 @@ void OculusWin32DisplayPlugin::display(
|
||||||
auto size = _sceneFbo->size;
|
auto size = _sceneFbo->size;
|
||||||
Context::Viewport(size.x, size.y);
|
Context::Viewport(size.x, size.y);
|
||||||
|
|
||||||
glClearColor(0, 0, 0, 0);
|
|
||||||
Context::Clear().ColorBuffer();
|
|
||||||
|
|
||||||
_program->Bind();
|
_program->Bind();
|
||||||
Mat4Uniform(*_program, "Projection").Set(mat4());
|
Mat4Uniform(*_program, "Projection").Set(mat4());
|
||||||
Mat4Uniform(*_program, "ModelView").Set(mat4());
|
Mat4Uniform(*_program, "ModelView").Set(mat4());
|
||||||
glBindTexture(GL_TEXTURE_2D, sceneTexture);
|
glBindTexture(GL_TEXTURE_2D, finalTexture);
|
||||||
_plane->Use();
|
_plane->Use();
|
||||||
_plane->Draw();
|
_plane->Draw();
|
||||||
|
|
||||||
|
|
||||||
Context::Enable(Capability::Blend);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, overlayTexture);
|
|
||||||
for_each_eye([&](Eye eye) {
|
|
||||||
Context::Viewport(eye == Left ? 0 : size.x / 2, 0, size.x / 2, size.y);
|
|
||||||
Mat4Uniform(*_program, "Projection").Set(_compositeEyeProjections[eye]);
|
|
||||||
Mat4Uniform(*_program, "ModelView").Set(glm::scale(glm::inverse(getModelview(eye, mat4())), vec3(1)));
|
|
||||||
_uiSurface->Use();
|
|
||||||
_uiSurface->Draw();
|
|
||||||
});
|
});
|
||||||
Context::Disable(Capability::Blend);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
An alternative way to render the UI is to pass it specifically as a composition layer to
|
|
||||||
the Oculus SDK which should technically result in higher quality. However, the SDK doesn't
|
|
||||||
have a mechanism to present the image as a sphere section, which is our desired look.
|
|
||||||
*/
|
|
||||||
#if 0
|
|
||||||
ovrLayerQuad& uiLayer = getUiLayer();
|
|
||||||
if (nullptr == uiLayer.ColorTexture || overlaySize != _uiFbo->size) {
|
|
||||||
_uiFbo->Resize(overlaySize);
|
|
||||||
uiLayer.ColorTexture = _uiFbo->color;
|
|
||||||
uiLayer.Viewport.Size.w = overlaySize.x;
|
|
||||||
uiLayer.Viewport.Size.h = overlaySize.y;
|
|
||||||
float overlayAspect = aspect(overlaySize);
|
|
||||||
uiLayer.QuadSize.x = 1.0f;
|
|
||||||
uiLayer.QuadSize.y = 1.0f / overlayAspect;
|
|
||||||
}
|
|
||||||
|
|
||||||
_uiFbo->Bound([&] {
|
|
||||||
Q_ASSERT(0 == glGetError());
|
|
||||||
using namespace oglplus;
|
|
||||||
Context::Viewport(_uiFbo->size.x, _uiFbo->size.y);
|
|
||||||
glClearColor(0, 0, 0, 0);
|
|
||||||
Context::Clear().ColorBuffer();
|
|
||||||
|
|
||||||
_program->Bind();
|
|
||||||
glBindTexture(GL_TEXTURE_2D, overlayTexture);
|
|
||||||
_plane->Use();
|
|
||||||
_plane->Draw();
|
|
||||||
Q_ASSERT(0 == glGetError());
|
|
||||||
});
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ovrLayerEyeFov& sceneLayer = getSceneLayer();
|
ovrLayerEyeFov& sceneLayer = getSceneLayer();
|
||||||
ovr_for_each_eye([&](ovrEyeType eye) {
|
ovr_for_each_eye([&](ovrEyeType eye) {
|
||||||
sceneLayer.RenderPose[eye] = _eyePoses[eye];
|
sceneLayer.RenderPose[eye] = _eyePoses[eye];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
auto windowSize = toGlm(getDeviceSize());
|
auto windowSize = toGlm(getDeviceSize());
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -377,6 +317,39 @@ bool OculusWin32DisplayPlugin::eventFilter(QObject* receiver, QEvent* event) {
|
||||||
otherwise the swapbuffer delay will interefere with the framerate of the headset
|
otherwise the swapbuffer delay will interefere with the framerate of the headset
|
||||||
*/
|
*/
|
||||||
void OculusWin32DisplayPlugin::finishFrame() {
|
void OculusWin32DisplayPlugin::finishFrame() {
|
||||||
// swapBuffers();
|
swapBuffers();
|
||||||
doneCurrent();
|
doneCurrent();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/*
|
||||||
|
An alternative way to render the UI is to pass it specifically as a composition layer to
|
||||||
|
the Oculus SDK which should technically result in higher quality. However, the SDK doesn't
|
||||||
|
have a mechanism to present the image as a sphere section, which is our desired look.
|
||||||
|
*/
|
||||||
|
ovrLayerQuad& uiLayer = getUiLayer();
|
||||||
|
if (nullptr == uiLayer.ColorTexture || overlaySize != _uiFbo->size) {
|
||||||
|
_uiFbo->Resize(overlaySize);
|
||||||
|
uiLayer.ColorTexture = _uiFbo->color;
|
||||||
|
uiLayer.Viewport.Size.w = overlaySize.x;
|
||||||
|
uiLayer.Viewport.Size.h = overlaySize.y;
|
||||||
|
float overlayAspect = aspect(overlaySize);
|
||||||
|
uiLayer.QuadSize.x = 1.0f;
|
||||||
|
uiLayer.QuadSize.y = 1.0f / overlayAspect;
|
||||||
|
}
|
||||||
|
|
||||||
|
_uiFbo->Bound([&] {
|
||||||
|
Q_ASSERT(0 == glGetError());
|
||||||
|
using namespace oglplus;
|
||||||
|
Context::Viewport(_uiFbo->size.x, _uiFbo->size.y);
|
||||||
|
glClearColor(0, 0, 0, 0);
|
||||||
|
Context::Clear().ColorBuffer();
|
||||||
|
|
||||||
|
_program->Bind();
|
||||||
|
glBindTexture(GL_TEXTURE_2D, overlayTexture);
|
||||||
|
_plane->Use();
|
||||||
|
_plane->Draw();
|
||||||
|
Q_ASSERT(0 == glGetError());
|
||||||
|
});
|
||||||
|
#endif
|
||||||
|
|
|
@ -26,12 +26,11 @@ public:
|
||||||
virtual void activate(PluginContainer * container) override;
|
virtual void activate(PluginContainer * container) override;
|
||||||
virtual void deactivate() override;
|
virtual void deactivate() override;
|
||||||
|
|
||||||
virtual void display(GLuint sceneTexture, const glm::uvec2& sceneSize,
|
|
||||||
GLuint overlayTexture, const glm::uvec2& overlaySize) override;
|
|
||||||
|
|
||||||
virtual bool eventFilter(QObject* receiver, QEvent* event) override;
|
virtual bool eventFilter(QObject* receiver, QEvent* event) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
virtual void display(GLuint finalTexture, const glm::uvec2& sceneSize) override;
|
||||||
virtual void customizeContext(PluginContainer * container) override;
|
virtual void customizeContext(PluginContainer * container) override;
|
||||||
// Do not perform swap in finish
|
// Do not perform swap in finish
|
||||||
virtual void finishFrame() override;
|
virtual void finishFrame() override;
|
||||||
|
@ -45,5 +44,4 @@ private:
|
||||||
SwapFboPtr _sceneFbo;
|
SwapFboPtr _sceneFbo;
|
||||||
MirrorFboPtr _mirrorFbo;
|
MirrorFboPtr _mirrorFbo;
|
||||||
ovrLayerEyeFov _sceneLayer;
|
ovrLayerEyeFov _sceneLayer;
|
||||||
ShapeWrapperPtr _uiSurface;
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,11 +26,6 @@ const QString & InterleavedStereoDisplayPlugin::getName() {
|
||||||
InterleavedStereoDisplayPlugin::InterleavedStereoDisplayPlugin() {
|
InterleavedStereoDisplayPlugin::InterleavedStereoDisplayPlugin() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterleavedStereoDisplayPlugin::display(
|
|
||||||
GLuint sceneTexture, const glm::uvec2& sceneSize,
|
|
||||||
GLuint overlayTexture, const glm::uvec2& overlaySize) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void InterleavedStereoDisplayPlugin::customizeContext(PluginContainer * container) {
|
void InterleavedStereoDisplayPlugin::customizeContext(PluginContainer * container) {
|
||||||
StereoDisplayPlugin::customizeContext(container);
|
StereoDisplayPlugin::customizeContext(container);
|
||||||
// Set up the stencil buffers? Or use a custom shader?
|
// Set up the stencil buffers? Or use a custom shader?
|
||||||
|
|
|
@ -15,9 +15,6 @@ public:
|
||||||
InterleavedStereoDisplayPlugin();
|
InterleavedStereoDisplayPlugin();
|
||||||
virtual const QString & getName() override;
|
virtual const QString & getName() override;
|
||||||
|
|
||||||
virtual void display(GLuint sceneTexture, const glm::uvec2& sceneSize,
|
|
||||||
GLuint overlayTexture, const glm::uvec2& overlaySize) override;
|
|
||||||
|
|
||||||
// initialize OpenGL context settings needed by the plugin
|
// initialize OpenGL context settings needed by the plugin
|
||||||
virtual void customizeContext(PluginContainer * container) override;
|
virtual void customizeContext(PluginContainer * container) override;
|
||||||
|
|
||||||
|
|
|
@ -26,83 +26,3 @@ const QString & SideBySideStereoDisplayPlugin::getName() {
|
||||||
SideBySideStereoDisplayPlugin::SideBySideStereoDisplayPlugin() {
|
SideBySideStereoDisplayPlugin::SideBySideStereoDisplayPlugin() {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename F>
|
|
||||||
void sbs_for_each_eye(const uvec2& size, F f) {
|
|
||||||
QRect r(QPoint(0, 0), QSize(size.x / 2, size.y));
|
|
||||||
for_each_eye([&](Eye eye) {
|
|
||||||
oglplus::Context::Viewport(r.x(), r.y(), r.width(), r.height());
|
|
||||||
f(eye);
|
|
||||||
}, [&] {
|
|
||||||
r.moveLeft(r.width());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void SideBySideStereoDisplayPlugin::display(
|
|
||||||
GLuint sceneTexture, const glm::uvec2& sceneSize,
|
|
||||||
GLuint overlayTexture, const glm::uvec2& overlaySize) {
|
|
||||||
makeCurrent();
|
|
||||||
Q_ASSERT(0 == glGetError());
|
|
||||||
uvec2 size = toGlm(getDeviceSize());
|
|
||||||
using namespace oglplus;
|
|
||||||
Context::Viewport(size.x, size.y);
|
|
||||||
Context::Clear().ColorBuffer();
|
|
||||||
|
|
||||||
_program->Bind();
|
|
||||||
Mat4Uniform(*_program, "ModelView").Set(mat4());
|
|
||||||
Mat4Uniform(*_program, "Projection").Set(mat4());
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, sceneTexture);
|
|
||||||
|
|
||||||
_plane->Use();
|
|
||||||
_plane->Draw();
|
|
||||||
|
|
||||||
// FIXME the
|
|
||||||
const float screenAspect = aspect(size);
|
|
||||||
const GLfloat distance = 1.0f;
|
|
||||||
const GLfloat halfQuadHeight = distance * tan(DEFAULT_FIELD_OF_VIEW_DEGREES);
|
|
||||||
const GLfloat halfQuadWidth = halfQuadHeight * screenAspect;
|
|
||||||
const GLfloat quadWidth = halfQuadWidth * 2.0f;
|
|
||||||
const GLfloat quadHeight = halfQuadHeight * 2.0f;
|
|
||||||
|
|
||||||
vec3 quadSize(quadWidth, quadHeight, 1.0f);
|
|
||||||
quadSize = vec3(1.0f) / quadSize;
|
|
||||||
|
|
||||||
using namespace oglplus;
|
|
||||||
Context::Enable(Capability::Blend);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, overlayTexture);
|
|
||||||
|
|
||||||
mat4 pr = glm::perspective(glm::radians(DEFAULT_FIELD_OF_VIEW_DEGREES), screenAspect, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP);
|
|
||||||
Mat4Uniform(*_program, "Projection").Set(pr);
|
|
||||||
|
|
||||||
// Position the camera relative to the overlay texture
|
|
||||||
MatrixStack mv;
|
|
||||||
mv.translate(vec3(0, 0, -distance)).scale(vec3(0.7f, 0.7f / screenAspect, 1.0f)); // .scale(vec3(quadWidth, quadHeight, 1.0));
|
|
||||||
sbs_for_each_eye(size, [&](Eye eye) {
|
|
||||||
mv.withPush([&] {
|
|
||||||
// translate
|
|
||||||
mv.top() = getModelview(eye, mv.top());
|
|
||||||
Mat4Uniform(*_program, "ModelView").Set(mv.top());
|
|
||||||
_plane->Draw();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(_crosshairTexture));
|
|
||||||
glm::vec2 canvasSize = getCanvasSize();
|
|
||||||
glm::vec2 mouse = toGlm(_window->mapFromGlobal(QCursor::pos()));
|
|
||||||
mouse /= canvasSize;
|
|
||||||
mouse *= 2.0f;
|
|
||||||
mouse -= 1.0f;
|
|
||||||
mouse.y *= -1.0f;
|
|
||||||
sbs_for_each_eye(size, [&](Eye eye) {
|
|
||||||
mv.withPush([&] {
|
|
||||||
// translate
|
|
||||||
mv.top() = getModelview(eye, mv.top());
|
|
||||||
mv.translate(mouse);
|
|
||||||
//mv.scale(0.05f);
|
|
||||||
mv.scale(vec3(0.025f, 0.05f, 1.0f));
|
|
||||||
Mat4Uniform(*_program, "ModelView").Set(mv.top());
|
|
||||||
_plane->Draw();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
Context::Disable(Capability::Blend);
|
|
||||||
}
|
|
||||||
|
|
|
@ -14,9 +14,6 @@ class SideBySideStereoDisplayPlugin : public StereoDisplayPlugin {
|
||||||
public:
|
public:
|
||||||
SideBySideStereoDisplayPlugin();
|
SideBySideStereoDisplayPlugin();
|
||||||
virtual const QString & getName() override;
|
virtual const QString & getName() override;
|
||||||
|
|
||||||
void display(GLuint sceneTexture, const glm::uvec2& sceneSize,
|
|
||||||
GLuint overlayTexture, const glm::uvec2& overlaySize) override;
|
|
||||||
private:
|
private:
|
||||||
static const QString NAME;
|
static const QString NAME;
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
class QMainWindow;
|
class GlWindow;
|
||||||
|
|
||||||
class PluginContainer {
|
class PluginContainer {
|
||||||
public:
|
public:
|
||||||
virtual void addMenuItem(const QString& path, std::function<void()> onClicked, bool checkable = false, bool checked = false, const QString& groupName = "") = 0;
|
virtual void addMenuItem(const QString& path, std::function<void()> onClicked, bool checkable = false, bool checked = false, const QString& groupName = "") = 0;
|
||||||
virtual QMainWindow* getAppMainWindow() = 0;
|
virtual GlWindow* getVisibleWindow() = 0;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue