mirror of
https://github.com/lubosz/overte.git
synced 2025-04-08 10:43:56 +02:00
Initial pass at OpenVR
This commit is contained in:
parent
a26373bd3a
commit
15d214f335
23 changed files with 280 additions and 305 deletions
3
cmake/externals/openvr/CMakeLists.txt
vendored
3
cmake/externals/openvr/CMakeLists.txt
vendored
|
@ -23,16 +23,19 @@ if (WIN32)
|
|||
|
||||
# FIXME need to account for different architectures
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/lib/win32/openvr_api.lib CACHE TYPE INTERNAL)
|
||||
add_paths_to_fixup_libs(${SOURCE_DIR}/bin/win32)
|
||||
|
||||
elseif(APPLE)
|
||||
|
||||
# FIXME need to account for different architectures
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/lib/osx32/libopenvr_api.dylib CACHE TYPE INTERNAL)
|
||||
add_paths_to_fixup_libs(${SOURCE_DIR}/bin/osx32)
|
||||
|
||||
elseif(NOT ANDROID)
|
||||
|
||||
# FIXME need to account for different architectures
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/lib/linux32/libopenvr_api.so CACHE TYPE INTERNAL)
|
||||
add_paths_to_fixup_libs(${SOURCE_DIR}/bin/linux32)
|
||||
|
||||
endif()
|
||||
|
||||
|
|
|
@ -865,7 +865,7 @@ void Application::paintGL() {
|
|||
auto displayPlugin = getActiveDisplayPlugin();
|
||||
displayPlugin->preRender();
|
||||
|
||||
_glWidget->makeCurrent();
|
||||
_offscreenContext->makeCurrent();
|
||||
|
||||
auto lodManager = DependencyManager::get<LODManager>();
|
||||
gpu::Context context(new gpu::GLBackend());
|
||||
|
@ -875,7 +875,6 @@ void Application::paintGL() {
|
|||
|
||||
PerformanceTimer perfTimer("paintGL");
|
||||
|
||||
_offscreenContext->makeCurrent();
|
||||
PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings));
|
||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||
PerformanceWarning warn(showWarnings, "Application::paintGL()");
|
||||
|
@ -938,7 +937,7 @@ void Application::paintGL() {
|
|||
}
|
||||
|
||||
renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE;
|
||||
DependencyManager::get<GlowEffect>()->prepare();
|
||||
DependencyManager::get<GlowEffect>()->prepare(&renderArgs);
|
||||
// Primary rendering pass
|
||||
auto primaryFbo = DependencyManager::get<TextureCache>()->getPrimaryFramebuffer();
|
||||
auto finalFbo = primaryFbo;
|
||||
|
@ -963,13 +962,13 @@ void Application::paintGL() {
|
|||
eyeCamera.setTransform(displayPlugin->getModelview(eye, _myCamera.getTransform()));
|
||||
eyeCamera.setProjection(displayPlugin->getProjection(eye, _myCamera.getProjection()));
|
||||
|
||||
displaySide(eyeCamera);
|
||||
displaySide(&renderArgs, eyeCamera);
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) {
|
||||
glm::vec2 mpos = getActiveDisplayPlugin()->getUiMousePosition();
|
||||
_rearMirrorTools->render(true, QPoint(mpos.x, mpos.y));
|
||||
_rearMirrorTools->render(&renderArgs, true, QPoint(mpos.x, mpos.y));
|
||||
} else if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) {
|
||||
renderRearViewMirror(_mirrorViewRect);
|
||||
renderRearViewMirror(&renderArgs, _mirrorViewRect);
|
||||
}
|
||||
}, [&] {
|
||||
r.moveLeft(r.width());
|
||||
|
@ -977,15 +976,15 @@ void Application::paintGL() {
|
|||
glDisable(GL_SCISSOR_TEST);
|
||||
} else {
|
||||
glViewport(0, 0, size.width(), size.height());
|
||||
displaySide(_myCamera);
|
||||
displaySide(&renderArgs, _myCamera);
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) {
|
||||
glm::vec2 mpos = getActiveDisplayPlugin()->getUiMousePosition();
|
||||
_rearMirrorTools->render(true, QPoint(mpos.x, mpos.y));
|
||||
_rearMirrorTools->render(&renderArgs, true, QPoint(mpos.x, mpos.y));
|
||||
} else if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) {
|
||||
renderRearViewMirror(_mirrorViewRect);
|
||||
renderRearViewMirror(&renderArgs, _mirrorViewRect);
|
||||
}
|
||||
}
|
||||
finalFbo = DependencyManager::get<GlowEffect>()->render();
|
||||
finalFbo = DependencyManager::get<GlowEffect>()->render(&renderArgs);
|
||||
}
|
||||
|
||||
glPopMatrix();
|
||||
|
@ -3030,7 +3029,8 @@ void Application::updateShadowMap(RenderArgs* renderArgs) {
|
|||
glMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
|
||||
glViewport(0, 0, _glWidget->getDeviceWidth(), _glWidget->getDeviceHeight());
|
||||
|
||||
glViewport(0, 0, getDeviceSize().width(), getDeviceSize().height());
|
||||
activeRenderingThread = nullptr;
|
||||
}
|
||||
|
||||
|
@ -3271,7 +3271,7 @@ namespace render {
|
|||
PerformanceTimer perfTimer("atmosphere");
|
||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||
"Application::displaySide() ... atmosphere...");
|
||||
background->_environment->renderAtmospheres(*(args->_viewFrustum));
|
||||
background->_environment->renderAtmospheres(args->_viewFrustum->getPosition());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3291,7 +3291,7 @@ namespace render {
|
|||
}
|
||||
|
||||
|
||||
void Application::displaySide(RenderArgs* renderArgs, const Camera& theCamera, bool selfAvatarOnly) {
|
||||
void Application::displaySide(RenderArgs* renderArgs, const Camera& theCamera, bool selfAvatarOnly, bool billboard) {
|
||||
activeRenderingThread = QThread::currentThread();
|
||||
PROFILE_RANGE(__FUNCTION__);
|
||||
PerformanceTimer perfTimer("display");
|
||||
|
@ -3555,32 +3555,6 @@ bool Application::getCascadeShadowsEnabled() {
|
|||
return Menu::getInstance()->isOptionChecked(MenuOption::CascadedShadows);
|
||||
}
|
||||
|
||||
glm::vec2 Application::getScaledScreenPoint(glm::vec2 projectedPoint) {
|
||||
float horizontalScale = _glWidget->getDeviceWidth() / 2.0f;
|
||||
float verticalScale = _glWidget->getDeviceHeight() / 2.0f;
|
||||
|
||||
// -1,-1 is 0,windowHeight
|
||||
// 1,1 is windowWidth,0
|
||||
|
||||
// -1,1 1,1
|
||||
// +-----------------------+
|
||||
// | | |
|
||||
// | | |
|
||||
// | -1,0 | |
|
||||
// |-----------+-----------|
|
||||
// | 0,0 |
|
||||
// | | |
|
||||
// | | |
|
||||
// | | |
|
||||
// +-----------------------+
|
||||
// -1,-1 1,-1
|
||||
|
||||
glm::vec2 screenPoint((projectedPoint.x + 1.0) * horizontalScale,
|
||||
((projectedPoint.y + 1.0) * -verticalScale) + _glWidget->getDeviceHeight());
|
||||
|
||||
return screenPoint;
|
||||
}
|
||||
|
||||
void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& region, bool billboard) {
|
||||
// Grab current viewport to reset it at the end
|
||||
int viewport[4];
|
||||
|
@ -3643,7 +3617,7 @@ void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& regi
|
|||
glPopMatrix();
|
||||
|
||||
if (!billboard) {
|
||||
_rearMirrorTools->render(renderArgs, false, _glWidget->mapFromGlobal(QCursor::pos()));
|
||||
_rearMirrorTools->render(renderArgs, false, getActiveDisplayPlugin()->getWindow()->mapFromGlobal(QCursor::pos()));
|
||||
}
|
||||
// reset Viewport and projection matrix
|
||||
glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
|
||||
|
@ -4829,7 +4803,6 @@ void Application::updateDisplayMode() {
|
|||
|
||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||
offscreenUi->setMouseTranslator(getActiveDisplayPlugin()->getMouseTranslator());
|
||||
updateCursorVisibility();
|
||||
}
|
||||
Q_ASSERT_X(_displayPlugin, "Application::updateDisplayMode", "could not find an activated display plugin");
|
||||
}
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
#else
|
||||
#endif
|
||||
|
||||
#include <display-plugins/openvr/OpenVrDisplayPlugin.h>
|
||||
|
||||
|
||||
static void addDisplayPluginToMenu(DisplayPluginPointer displayPlugin, bool active = false) {
|
||||
auto menu = Menu::getInstance();
|
||||
|
@ -56,7 +58,8 @@ const DisplayPluginList& getDisplayPlugins() {
|
|||
#endif
|
||||
new SideBySideStereoDisplayPlugin(),
|
||||
new InterleavedStereoDisplayPlugin(),
|
||||
new OculusWin32DisplayPlugin(),
|
||||
// new OculusWin32DisplayPlugin(),
|
||||
new OpenVrDisplayPlugin(),
|
||||
nullptr
|
||||
};
|
||||
for (int i = 0; PLUGIN_POOL[i]; ++i) {
|
||||
|
|
|
@ -1,158 +0,0 @@
|
|||
//
|
||||
// TV3DManager.cpp
|
||||
// interface/src/devices
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 12/24/13.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "InterfaceConfig.h"
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include <GlowEffect.h>
|
||||
#include "gpu/GLBackend.h"
|
||||
#include "Application.h"
|
||||
|
||||
#include "TV3DManager.h"
|
||||
#include "Menu.h"
|
||||
|
||||
int TV3DManager::_screenWidth = 1;
|
||||
int TV3DManager::_screenHeight = 1;
|
||||
double TV3DManager::_aspect = 1.0;
|
||||
eyeFrustum TV3DManager::_leftEye;
|
||||
eyeFrustum TV3DManager::_rightEye;
|
||||
eyeFrustum* TV3DManager::_activeEye = NULL;
|
||||
|
||||
|
||||
bool TV3DManager::isConnected() {
|
||||
return Menu::getInstance()->isOptionChecked(MenuOption::Enable3DTVMode);
|
||||
}
|
||||
|
||||
void TV3DManager::connect() {
|
||||
auto deviceSize = qApp->getDeviceSize();
|
||||
configureCamera(*(qApp->getCamera()), deviceSize.width(), deviceSize.height());
|
||||
}
|
||||
|
||||
|
||||
// The basic strategy of this stereoscopic rendering is explained here:
|
||||
// http://www.orthostereo.com/geometryopengl.html
|
||||
void TV3DManager::setFrustum(const Camera& whichCamera) {
|
||||
const double DTR = 0.0174532925; // degree to radians
|
||||
const double IOD = 0.05; //intraocular distance
|
||||
double fovy = DEFAULT_FIELD_OF_VIEW_DEGREES; // field of view in y-axis
|
||||
double nearZ = DEFAULT_NEAR_CLIP; // near clipping plane
|
||||
double screenZ = 0.25f; // screen projection plane
|
||||
|
||||
double top = nearZ * tan(DTR * fovy / 2.0); //sets top of frustum based on fovy and near clipping plane
|
||||
double right = _aspect * top; // sets right of frustum based on aspect ratio
|
||||
double frustumshift = (IOD / 2) * nearZ / screenZ;
|
||||
|
||||
_leftEye.top = top;
|
||||
_leftEye.bottom = -top;
|
||||
_leftEye.left = -right + frustumshift;
|
||||
_leftEye.right = right + frustumshift;
|
||||
_leftEye.modelTranslation = IOD / 2;
|
||||
|
||||
_rightEye.top = top;
|
||||
_rightEye.bottom = -top;
|
||||
_rightEye.left = -right - frustumshift;
|
||||
_rightEye.right = right - frustumshift;
|
||||
_rightEye.modelTranslation = -IOD / 2;
|
||||
}
|
||||
|
||||
void TV3DManager::configureCamera(Camera& whichCamera_, int screenWidth, int screenHeight) {
|
||||
const Camera& whichCamera = whichCamera_;
|
||||
|
||||
if (screenHeight == 0) {
|
||||
screenHeight = 1; // prevent divide by 0
|
||||
}
|
||||
_screenWidth = screenWidth;
|
||||
_screenHeight = screenHeight;
|
||||
_aspect= (double)_screenWidth / (double)_screenHeight;
|
||||
setFrustum(whichCamera);
|
||||
|
||||
glViewport (0, 0, _screenWidth, _screenHeight); // sets drawing viewport
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
}
|
||||
|
||||
void TV3DManager::display(RenderArgs* renderArgs, Camera& whichCamera) {
|
||||
double nearZ = DEFAULT_NEAR_CLIP; // near clipping plane
|
||||
double farZ = DEFAULT_FAR_CLIP; // far clipping plane
|
||||
|
||||
// left eye portal
|
||||
int portalX = 0;
|
||||
int portalY = 0;
|
||||
QSize deviceSize = qApp->getDeviceSize() *
|
||||
qApp->getRenderResolutionScale();
|
||||
int portalW = deviceSize.width() / 2;
|
||||
int portalH = deviceSize.height();
|
||||
|
||||
|
||||
DependencyManager::get<GlowEffect>()->prepare(renderArgs);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
Camera eyeCamera;
|
||||
eyeCamera.setRotation(whichCamera.getRotation());
|
||||
eyeCamera.setPosition(whichCamera.getPosition());
|
||||
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glPushMatrix();
|
||||
forEachEye([&](eyeFrustum& eye){
|
||||
_activeEye = &eye;
|
||||
glViewport(portalX, portalY, portalW, portalH);
|
||||
glScissor(portalX, portalY, portalW, portalH);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity(); // reset projection matrix
|
||||
glFrustum(eye.left, eye.right, eye.bottom, eye.top, nearZ, farZ); // set left view frustum
|
||||
GLfloat p[4][4];
|
||||
// Really?
|
||||
glGetFloatv(GL_PROJECTION_MATRIX, &(p[0][0]));
|
||||
float cotangent = p[1][1];
|
||||
GLfloat fov = atan(1.0f / cotangent);
|
||||
glTranslatef(eye.modelTranslation, 0.0, 0.0); // translate to cancel parallax
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
renderArgs->_renderSide = RenderArgs::MONO;
|
||||
qApp->displaySide(renderArgs, eyeCamera, false);
|
||||
qApp->getApplicationOverlay().displayOverlayTextureStereo(whichCamera, _aspect, fov);
|
||||
_activeEye = NULL;
|
||||
}, [&]{
|
||||
// render right side view
|
||||
portalX = deviceSize.width() / 2;
|
||||
});
|
||||
glPopMatrix();
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
|
||||
auto finalFbo = DependencyManager::get<GlowEffect>()->render(renderArgs);
|
||||
auto fboSize = finalFbo->getSize();
|
||||
// Get the ACTUAL device size for the BLIT
|
||||
deviceSize = qApp->getDeviceSize();
|
||||
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(finalFbo));
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
glBlitFramebuffer(0, 0, fboSize.x, fboSize.y,
|
||||
0, 0, deviceSize.width(), deviceSize.height(),
|
||||
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||
|
||||
// reset the viewport to how we started
|
||||
glViewport(0, 0, deviceSize.width(), deviceSize.height());
|
||||
}
|
||||
|
||||
void TV3DManager::overrideOffAxisFrustum(float& left, float& right, float& bottom, float& top, float& nearVal,
|
||||
float& farVal, glm::vec4& nearClipPlane, glm::vec4& farClipPlane) {
|
||||
if (_activeEye) {
|
||||
left = _activeEye->left;
|
||||
right = _activeEye->right;
|
||||
bottom = _activeEye->bottom;
|
||||
top = _activeEye->top;
|
||||
}
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
//
|
||||
// TV3DManager.h
|
||||
// interface/src/devices
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 12/24/2013.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_TV3DManager_h
|
||||
#define hifi_TV3DManager_h
|
||||
#include <iostream>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
class Camera;
|
||||
|
||||
struct eyeFrustum {
|
||||
double left;
|
||||
double right;
|
||||
double bottom;
|
||||
double top;
|
||||
float modelTranslation;
|
||||
};
|
||||
|
||||
|
||||
/// Handles interaction with 3D TVs
|
||||
class TV3DManager {
|
||||
public:
|
||||
static void connect();
|
||||
static bool isConnected();
|
||||
static void configureCamera(Camera& camera, int screenWidth, int screenHeight);
|
||||
static void display(RenderArgs* renderArgs, Camera& whichCamera);
|
||||
static void overrideOffAxisFrustum(float& left, float& right, float& bottom, float& top, float& nearVal,
|
||||
float& farVal, glm::vec4& nearClipPlane, glm::vec4& farClipPlane);
|
||||
private:
|
||||
static void setFrustum(const Camera& whichCamera);
|
||||
static int _screenWidth;
|
||||
static int _screenHeight;
|
||||
static double _aspect;
|
||||
static eyeFrustum _leftEye;
|
||||
static eyeFrustum _rightEye;
|
||||
static eyeFrustum* _activeEye;
|
||||
|
||||
// The first function is the code executed for each eye
|
||||
// while the second is code to be executed between the two eyes.
|
||||
// The use case here is to modify the output viewport coordinates
|
||||
// for the new eye.
|
||||
// FIXME: we'd like to have a default empty lambda for the second parameter,
|
||||
// but gcc 4.8.1 complains about it due to a bug. See
|
||||
// http://stackoverflow.com/questions/25490662/lambda-as-default-parameter-to-a-member-function-template
|
||||
template<typename F, typename FF>
|
||||
static void forEachEye(F f, FF ff) {
|
||||
f(_leftEye);
|
||||
ff();
|
||||
f(_rightEye);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // hifi_TV3DManager_h
|
|
@ -621,9 +621,6 @@ bool ApplicationOverlay::calculateRayUICollisionPoint(const glm::vec3& position,
|
|||
//Renders optional pointers
|
||||
void ApplicationOverlay::renderPointers() {
|
||||
//lazily load crosshair texture
|
||||
if (_crosshairTexture == 0) {
|
||||
_crosshairTexture = TextureCache::getImageTexture(PathUtils::resourcesPath() + "images/sixense-reticle.png");
|
||||
}
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
@ -791,16 +788,16 @@ void ApplicationOverlay::renderControllerPointers() {
|
|||
}
|
||||
|
||||
void ApplicationOverlay::renderPointersOculus() {
|
||||
|
||||
#if 0
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(_crosshairTexture));
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
bindCursorTexture();
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
|
||||
//Controller Pointers
|
||||
MyAvatar* myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
||||
for (int i = 0; i < (int)myAvatar->getHand()->getNumPalms(); i++) {
|
||||
|
@ -825,6 +822,7 @@ void ApplicationOverlay::renderPointersOculus() {
|
|||
glEnable(GL_DEPTH_TEST);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glDisable(GL_BLEND);
|
||||
#endif
|
||||
}
|
||||
|
||||
//Renders a small magnification of the currently bound texture at the coordinates
|
||||
|
|
|
@ -81,8 +81,6 @@ private:
|
|||
void renderDomainConnectionStatusBorder();
|
||||
void bindCursorTexture(gpu::Batch& batch, uint8_t cursorId = 0);
|
||||
|
||||
TexturedHemisphere _overlays;
|
||||
|
||||
float _textureFov;
|
||||
float _textureAspectRatio;
|
||||
|
||||
|
|
|
@ -45,10 +45,12 @@ void LocalModelsOverlay::render(RenderArgs* args) {
|
|||
|
||||
glPushMatrix(); {
|
||||
Application* app = Application::getInstance();
|
||||
#if 0
|
||||
glm::vec3 oldTranslation = app->getViewMatrixTranslation();
|
||||
app->setViewMatrixTranslation(oldTranslation + _position);
|
||||
_entityTreeRenderer->render(args);
|
||||
Application::getInstance()->setViewMatrixTranslation(oldTranslation);
|
||||
#endif
|
||||
} glPopMatrix();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,6 @@
|
|||
|
||||
const QString Basic2DWindowOpenGLDisplayPlugin::NAME("2D Display");
|
||||
|
||||
const QString & Basic2DWindowOpenGLDisplayPlugin::getName() {
|
||||
const QString & Basic2DWindowOpenGLDisplayPlugin::getName() const {
|
||||
return NAME;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ class Basic2DWindowOpenGLDisplayPlugin : public MainWindowOpenGLDisplayPlugin {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
virtual const QString & getName() override;
|
||||
virtual const QString & getName() const override;
|
||||
|
||||
private:
|
||||
static const QString NAME;
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
const QString NullDisplayPlugin::NAME("NullDisplayPlugin");
|
||||
|
||||
const QString & NullDisplayPlugin::getName() {
|
||||
const QString & NullDisplayPlugin::getName() const {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
|
@ -27,10 +27,6 @@ bool NullDisplayPlugin::hasFocus() const {
|
|||
return false;
|
||||
}
|
||||
|
||||
glm::ivec2 NullDisplayPlugin::getRelativeMousePosition() const {
|
||||
return glm::ivec2();
|
||||
}
|
||||
|
||||
glm::ivec2 NullDisplayPlugin::getTrueMousePosition() const {
|
||||
return glm::ivec2();
|
||||
}
|
||||
|
|
|
@ -11,24 +11,26 @@
|
|||
|
||||
class NullDisplayPlugin : public DisplayPlugin {
|
||||
public:
|
||||
static const QString NAME;
|
||||
|
||||
virtual ~NullDisplayPlugin() final {}
|
||||
virtual const QString & getName();
|
||||
virtual const QString & getName() const override;
|
||||
|
||||
void activate(PluginContainer * container);
|
||||
void deactivate();
|
||||
void activate(PluginContainer * container) override;
|
||||
void deactivate() override;
|
||||
|
||||
virtual QSize getDeviceSize() const;
|
||||
virtual glm::ivec2 getCanvasSize() const;
|
||||
virtual bool hasFocus() const;
|
||||
virtual glm::ivec2 getRelativeMousePosition() const;
|
||||
virtual glm::ivec2 getTrueMousePosition() const;
|
||||
virtual PickRay computePickRay(const glm::vec2 & pos) const;
|
||||
virtual bool isMouseOnScreen() const;
|
||||
virtual QWindow* getWindow() const;
|
||||
virtual void preRender();
|
||||
virtual void preDisplay();
|
||||
virtual void display(GLuint sceneTexture, const glm::uvec2& sceneSize);
|
||||
virtual void finishFrame();
|
||||
virtual QSize getDeviceSize() const override;
|
||||
virtual glm::ivec2 getCanvasSize() const override;
|
||||
virtual bool hasFocus() const override;
|
||||
// virtual glm::ivec2 getRelativeMousePosition() const override;
|
||||
virtual glm::ivec2 getTrueMousePosition() const override;
|
||||
virtual PickRay computePickRay(const glm::vec2 & pos) const override;
|
||||
virtual bool isMouseOnScreen() const override;
|
||||
virtual QWindow* getWindow() const override;
|
||||
virtual void preRender() override;
|
||||
virtual void preDisplay() override;
|
||||
virtual void display(GLuint sceneTexture, const glm::uvec2& sceneSize) override;
|
||||
virtual void finishFrame() override;
|
||||
|
||||
private:
|
||||
static const QString NAME;
|
||||
};
|
||||
|
|
|
@ -18,7 +18,7 @@ public:
|
|||
|
||||
WidgetOpenGLDisplayPlugin();
|
||||
|
||||
virtual const QString & getName() override;
|
||||
virtual const QString & getName() const override;
|
||||
virtual glm::ivec2 getTrueMousePosition() const override;
|
||||
virtual QSize getDeviceSize() const override;
|
||||
virtual glm::ivec2 getCanvasSize() const override;
|
||||
|
|
|
@ -146,11 +146,11 @@ private:
|
|||
|
||||
const QString OculusWin32DisplayPlugin::NAME("Oculus Rift");
|
||||
|
||||
const QString & OculusWin32DisplayPlugin::getName() {
|
||||
const QString & OculusWin32DisplayPlugin::getName() const {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
bool OculusWin32DisplayPlugin::isSupported() {
|
||||
bool OculusWin32DisplayPlugin::isSupported() const {
|
||||
if (!OVR_SUCCESS(ovr_Initialize(nullptr))) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -20,8 +20,8 @@ using MirrorFboPtr = QSharedPointer<MirrorFramebufferWrapper>;
|
|||
|
||||
class OculusWin32DisplayPlugin : public OculusBaseDisplayPlugin {
|
||||
public:
|
||||
virtual bool isSupported();
|
||||
virtual const QString & getName();
|
||||
virtual bool isSupported() const override;
|
||||
virtual const QString & getName() const override;
|
||||
|
||||
virtual void activate(PluginContainer * container) override;
|
||||
virtual void deactivate() override;
|
||||
|
|
|
@ -0,0 +1,165 @@
|
|||
//
|
||||
// Created by Bradley Austin Davis on 2015/05/12
|
||||
// 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 "OpenVrDisplayPlugin.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QGLWidget>
|
||||
#include <GLMHelpers.h>
|
||||
#include <GlWindow.h>
|
||||
#include <QEvent>
|
||||
#include <QResizeEvent>
|
||||
|
||||
#include <PerfStat.h>
|
||||
#include <plugins/PluginContainer.h>
|
||||
#include <ViewFrustum.h>
|
||||
|
||||
#include "OpenVrHelpers.h"
|
||||
#include "../OglplusHelpers.h"
|
||||
|
||||
|
||||
const QString OpenVrDisplayPlugin::NAME("OpenVR (Vive)");
|
||||
|
||||
const QString & OpenVrDisplayPlugin::getName() const {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
static vr::IVRSystem *_hmd{ nullptr };
|
||||
static vr::IVRCompositor* _compositor{ nullptr };
|
||||
static vr::TrackedDevicePose_t _trackedDevicePose[vr::k_unMaxTrackedDeviceCount];
|
||||
static mat4 _trackedDevicePoseMat4[vr::k_unMaxTrackedDeviceCount];
|
||||
static uvec2 _windowSize;
|
||||
static ivec2 _windowPosition;
|
||||
static uvec2 _renderTargetSize;
|
||||
|
||||
struct PerEyeData {
|
||||
uvec2 _viewportOrigin;
|
||||
uvec2 _viewportSize;
|
||||
mat4 _projectionMatrix;
|
||||
mat4 _eyeOffset;
|
||||
mat4 _pose;
|
||||
};
|
||||
|
||||
static PerEyeData _eyesData[2];
|
||||
|
||||
|
||||
template<typename F>
|
||||
void openvr_for_each_eye(F f) {
|
||||
f(vr::Hmd_Eye::Eye_Left);
|
||||
f(vr::Hmd_Eye::Eye_Right);
|
||||
}
|
||||
|
||||
mat4 toGlm(const vr::HmdMatrix44_t& m) {
|
||||
return glm::transpose(glm::make_mat4(&m.m[0][0]));
|
||||
}
|
||||
|
||||
mat4 toGlm(const vr::HmdMatrix34_t& m) {
|
||||
mat4 result = mat4(
|
||||
m.m[0][0], m.m[1][0], m.m[2][0], 0.0,
|
||||
m.m[0][1], m.m[1][1], m.m[2][1], 0.0,
|
||||
m.m[0][2], m.m[1][2], m.m[2][2], 0.0,
|
||||
m.m[0][3], m.m[1][3], m.m[2][3], 1.0f);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool OpenVrDisplayPlugin::isSupported() const {
|
||||
return vr::VR_IsHmdPresent();
|
||||
}
|
||||
|
||||
void OpenVrDisplayPlugin::activate(PluginContainer * container) {
|
||||
vr::HmdError eError = vr::HmdError_None;
|
||||
_hmd = vr::VR_Init(&eError);
|
||||
Q_ASSERT(eError == vr::HmdError_None);
|
||||
Q_ASSERT(_hmd);
|
||||
|
||||
_hmd->GetWindowBounds(&_windowPosition.x, &_windowPosition.y, &_windowSize.x, &_windowSize.y);
|
||||
_hmd->GetRecommendedRenderTargetSize(&_renderTargetSize.x, &_renderTargetSize.y);
|
||||
openvr_for_each_eye([&](vr::Hmd_Eye eye) {
|
||||
PerEyeData& eyeData = _eyesData[eye];
|
||||
_hmd->GetEyeOutputViewport(eye,
|
||||
&eyeData._viewportOrigin.x, &eyeData._viewportOrigin.y,
|
||||
&eyeData._viewportSize.x, &eyeData._viewportSize.y);
|
||||
eyeData._projectionMatrix = toGlm(_hmd->GetProjectionMatrix(eye, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP, vr::API_OpenGL));
|
||||
eyeData._eyeOffset = toGlm(_hmd->GetEyeToHeadTransform(eye));
|
||||
});
|
||||
|
||||
|
||||
_compositor = (vr::IVRCompositor*)vr::VR_GetGenericInterface(vr::IVRCompositor_Version, &eError);
|
||||
Q_ASSERT(eError == vr::HmdError_None);
|
||||
Q_ASSERT(_compositor);
|
||||
|
||||
_compositor->SetGraphicsDevice(vr::Compositor_DeviceType_OpenGL, NULL);
|
||||
|
||||
uint32_t unSize = _compositor->GetLastError(NULL, 0);
|
||||
if (unSize > 1) {
|
||||
char* buffer = new char[unSize];
|
||||
_compositor->GetLastError(buffer, unSize);
|
||||
printf("Compositor - %s\n", buffer);
|
||||
delete[] buffer;
|
||||
}
|
||||
Q_ASSERT(unSize <= 1);
|
||||
MainWindowOpenGLDisplayPlugin::activate(container);
|
||||
}
|
||||
|
||||
void OpenVrDisplayPlugin::deactivate() {
|
||||
vr::VR_Shutdown();
|
||||
_hmd = nullptr;
|
||||
_compositor = nullptr;
|
||||
}
|
||||
|
||||
QSize OpenVrDisplayPlugin::getRecommendedFramebufferSize() const {
|
||||
return QSize(_renderTargetSize.x, _renderTargetSize.y);
|
||||
}
|
||||
|
||||
mat4 OpenVrDisplayPlugin::getProjection(Eye eye, const mat4& baseProjection) const {
|
||||
return _eyesData[eye]._projectionMatrix;
|
||||
}
|
||||
|
||||
glm::mat4 OpenVrDisplayPlugin::getModelview(Eye eye, const mat4& baseModelview) const {
|
||||
return baseModelview * _eyesData[eye]._pose;
|
||||
}
|
||||
|
||||
void OpenVrDisplayPlugin::preRender() {
|
||||
}
|
||||
|
||||
void OpenVrDisplayPlugin::resetSensors() {
|
||||
_hmd->ResetSeatedZeroPose();
|
||||
}
|
||||
|
||||
glm::mat4 OpenVrDisplayPlugin::getEyePose(Eye eye) const {
|
||||
return _eyesData[eye]._pose;
|
||||
}
|
||||
|
||||
glm::mat4 OpenVrDisplayPlugin::getHeadPose() const {
|
||||
return _trackedDevicePoseMat4[0];
|
||||
}
|
||||
|
||||
void OpenVrDisplayPlugin::customizeContext(PluginContainer * container) {
|
||||
MainWindowOpenGLDisplayPlugin::customizeContext(container);
|
||||
}
|
||||
|
||||
void OpenVrDisplayPlugin::display(GLuint finalTexture, const glm::uvec2& sceneSize) {
|
||||
// Flip y-axis since GL UV coords are backwards.
|
||||
static vr::Compositor_TextureBounds leftBounds{ 0, 1, 0.5f, 0 };
|
||||
static vr::Compositor_TextureBounds rightBounds{ 0.5f, 1, 1, 0 };
|
||||
_compositor->Submit(vr::Eye_Left, (void*)finalTexture, &leftBounds);
|
||||
_compositor->Submit(vr::Eye_Right, (void*)finalTexture, &rightBounds);
|
||||
glFinish();
|
||||
}
|
||||
|
||||
void OpenVrDisplayPlugin::finishFrame() {
|
||||
// swapBuffers();
|
||||
doneCurrent();
|
||||
_compositor->WaitGetPoses(_trackedDevicePose, vr::k_unMaxTrackedDeviceCount);
|
||||
_trackedDevicePoseMat4[0] = toGlm(_trackedDevicePose[0].mDeviceToAbsoluteTracking);
|
||||
openvr_for_each_eye([&](vr::Hmd_Eye eye) {
|
||||
_eyesData[eye]._pose = _trackedDevicePoseMat4[0];
|
||||
});
|
||||
};
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
//
|
||||
// Created by Bradley Austin Davis on 2015/06/12
|
||||
// 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 "../MainWindowOpenGLDisplayPlugin.h"
|
||||
|
||||
class OpenVrDisplayPlugin : public MainWindowOpenGLDisplayPlugin {
|
||||
public:
|
||||
virtual bool isSupported() const override;
|
||||
virtual const QString & getName() const override;
|
||||
|
||||
virtual void activate(PluginContainer * container) override;
|
||||
virtual void deactivate() override;
|
||||
|
||||
// Stereo specific methods
|
||||
virtual bool isHmd() const override { return true; }
|
||||
virtual glm::mat4 getProjection(Eye eye, const glm::mat4& baseProjection) const override;
|
||||
virtual glm::mat4 getModelview(Eye eye, const glm::mat4& baseModelview) const override;
|
||||
|
||||
virtual void preRender() override;
|
||||
virtual QSize getRecommendedFramebufferSize() const override;
|
||||
virtual void resetSensors() override;
|
||||
|
||||
virtual glm::ivec2 getCanvasSize() const override { return ivec2(1920, 1080); }
|
||||
virtual glm::mat4 getEyePose(Eye eye) const override;
|
||||
virtual glm::mat4 getHeadPose() const override;
|
||||
|
||||
protected:
|
||||
virtual void display(GLuint finalTexture, const glm::uvec2& sceneSize) override;
|
||||
virtual void customizeContext(PluginContainer * container) override;
|
||||
// Do not perform swap in finish
|
||||
virtual void finishFrame() override;
|
||||
|
||||
private:
|
||||
static const QString NAME;
|
||||
};
|
|
@ -0,0 +1,14 @@
|
|||
//
|
||||
// Created by Bradley Austin Davis on 2015/06/12
|
||||
// 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 <openvr.h>
|
||||
#include <GLMHelpers.h>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
const QString InterleavedStereoDisplayPlugin::NAME("Interleaved Stereo Display");
|
||||
|
||||
const QString & InterleavedStereoDisplayPlugin::getName() {
|
||||
const QString & InterleavedStereoDisplayPlugin::getName() const {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ class InterleavedStereoDisplayPlugin : public StereoDisplayPlugin {
|
|||
Q_OBJECT
|
||||
public:
|
||||
InterleavedStereoDisplayPlugin();
|
||||
virtual const QString & getName() override;
|
||||
virtual const QString & getName() const override;
|
||||
|
||||
// initialize OpenGL context settings needed by the plugin
|
||||
virtual void customizeContext(PluginContainer * container) override;
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
const QString SideBySideStereoDisplayPlugin::NAME("SBS Stereo Display");
|
||||
|
||||
const QString & SideBySideStereoDisplayPlugin::getName() {
|
||||
const QString & SideBySideStereoDisplayPlugin::getName() const {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ class SideBySideStereoDisplayPlugin : public StereoDisplayPlugin {
|
|||
Q_OBJECT
|
||||
public:
|
||||
SideBySideStereoDisplayPlugin();
|
||||
virtual const QString & getName() override;
|
||||
virtual const QString & getName() const override;
|
||||
private:
|
||||
static const QString NAME;
|
||||
};
|
||||
|
|
|
@ -7,7 +7,7 @@ class PluginContainer;
|
|||
|
||||
class Plugin : public QObject {
|
||||
public:
|
||||
virtual const QString& getName() = 0;
|
||||
virtual const QString& getName() const = 0;
|
||||
virtual bool isSupported() const;
|
||||
|
||||
/// Called when plugin is initially loaded, typically at application start
|
||||
|
|
Loading…
Reference in a new issue