Working on OSX Rift functionality

This commit is contained in:
Bradley Austin Davis 2016-05-07 18:42:43 -07:00
parent b234d94d25
commit 0f768b13b9
8 changed files with 144 additions and 55 deletions

View file

@ -237,12 +237,6 @@ bool OpenGLDisplayPlugin::activate() {
_vsyncSupported = _container->getPrimaryWidget()->isVsyncSupported();
// Child classes may override this in order to do things like initialize
// libraries, etc
if (!internalActivate()) {
return false;
}
#if THREADED_PRESENT
// Start the present thread if necessary
@ -258,8 +252,18 @@ bool OpenGLDisplayPlugin::activate() {
// Start execution
presentThread->start();
}
_presentThread = presentThread.data();
#endif
// Child classes may override this in order to do things like initialize
// libraries, etc
if (!internalActivate()) {
return false;
}
// This should not return until the new context has been customized
#if THREADED_PRESENT
// This should not return until the new context has been customized
// and the old context (if any) has been uncustomized
presentThread->setNewDisplayPlugin(this);
#else

View file

@ -103,6 +103,7 @@ protected:
virtual void updateFrameData();
QThread* _presentThread{ nullptr };
ProgramPtr _program;
int32_t _mvpUniform { -1 };
int32_t _alphaUniform { -1 };

View file

@ -63,7 +63,7 @@ bool HmdDisplayPlugin::internalActivate() {
}
static const char * REPROJECTION_VS = R"VS(#version 450 core
static const char * REPROJECTION_VS = R"VS(#version 410 core
in vec3 Position;
in vec2 TexCoord;
@ -78,15 +78,15 @@ void main() {
)VS";
static const GLint REPROJECTION_MATRIX_LOCATION = 0;
static const GLint INVERSE_PROJECTION_MATRIX_LOCATION = 4;
static const GLint PROJECTION_MATRIX_LOCATION = 12;
static const char * REPROJECTION_FS = R"FS(#version 450 core
static GLint REPROJECTION_MATRIX_LOCATION = -1;
static GLint INVERSE_PROJECTION_MATRIX_LOCATION = -1;
static GLint PROJECTION_MATRIX_LOCATION = -1;
static const char * REPROJECTION_FS = R"FS(#version 410 core
uniform sampler2D sampler;
layout (location = 0) uniform mat3 reprojection = mat3(1);
layout (location = 4) uniform mat4 inverseProjections[2];
layout (location = 12) uniform mat4 projections[2];
uniform mat3 reprojection = mat3(1);
uniform mat4 inverseProjections[2];
uniform mat4 projections[2];
in vec2 vTexCoord;
in vec3 vPosition;
@ -205,6 +205,11 @@ void HmdDisplayPlugin::customizeContext() {
_enablePreview = !isVsyncEnabled();
_sphereSection = loadSphereSection(_program, CompositorHelper::VIRTUAL_UI_TARGET_FOV.y, CompositorHelper::VIRTUAL_UI_ASPECT_RATIO);
compileProgram(_reprojectionProgram, REPROJECTION_VS, REPROJECTION_FS);
using namespace oglplus;
REPROJECTION_MATRIX_LOCATION = Uniform<glm::mat3>(*_reprojectionProgram, "reprojection").Location();
INVERSE_PROJECTION_MATRIX_LOCATION = Uniform<glm::mat4>(*_reprojectionProgram, "inverseProjections").Location();
PROJECTION_MATRIX_LOCATION = Uniform<glm::mat4>(*_reprojectionProgram, "projections").Location();
}
void HmdDisplayPlugin::uncustomizeContext() {

View file

@ -17,8 +17,15 @@ QOpenGLContext* QOpenGLContextWrapper::currentContext() {
return QOpenGLContext::currentContext();
}
QOpenGLContextWrapper::QOpenGLContextWrapper() :
_context(new QOpenGLContext)
_context(new QOpenGLContext)
{
}
QOpenGLContextWrapper::QOpenGLContextWrapper(QOpenGLContext* context) :
_context(context)
{
}
@ -50,3 +57,7 @@ bool isCurrentContext(QOpenGLContext* context) {
return QOpenGLContext::currentContext() == context;
}
void QOpenGLContextWrapper::moveToThread(QThread* thread) {
_context->moveToThread(thread);
}

View file

@ -15,16 +15,19 @@
class QOpenGLContext;
class QSurface;
class QSurfaceFormat;
class QThread;
class QOpenGLContextWrapper {
public:
QOpenGLContextWrapper();
QOpenGLContextWrapper(QOpenGLContext* context);
void setFormat(const QSurfaceFormat& format);
bool create();
void swapBuffers(QSurface* surface);
bool makeCurrent(QSurface* surface);
void doneCurrent();
void setShareContext(QOpenGLContext* otherContext);
void moveToThread(QThread* thread);
static QOpenGLContext* currentContext();

View file

@ -12,13 +12,17 @@ if (APPLE)
set(TARGET_NAME oculusLegacy)
setup_hifi_plugin()
link_hifi_libraries(shared gl gpu plugins display-plugins input-plugins)
link_hifi_libraries(shared gl gpu plugins ui display-plugins input-plugins)
include_hifi_library_headers(octree)
add_dependency_external_projects(LibOVR)
find_package(LibOVR REQUIRED)
target_include_directories(${TARGET_NAME} PRIVATE ${LIBOVR_INCLUDE_DIRS})
target_link_libraries(${TARGET_NAME} ${LIBOVR_LIBRARIES})
find_library(COCOA_LIBRARY Cocoa)
find_library(IOKIT_LIBRARY IOKit)
target_link_libraries(${TARGET_NAME} ${LIBOVR_LIBRARIES} ${COCOA_LIBRARY} ${IOKIT_LIBRARY})
endif()

View file

@ -9,6 +9,7 @@
#include <memory>
#include <QtCore/QThread.h>
#include <QtWidgets/QMainWindow>
#include <QtOpenGL/QGLWidget>
#include <GLMHelpers.h>
@ -16,7 +17,12 @@
#include <QtGui/QResizeEvent>
#include <QtGui/QGuiApplication>
#include <QtGui/QScreen>
#include <gl/GLWindow.h>
#include <gl/GLWidget.h>
#include <gpu/GLBackend.h>
#include <MainWindow.h>
#include <gl/QOpenGLContextWrapper.h>
#include <PerfStat.h>
#include <gl/OglplusHelpers.h>
#include <ViewFrustum.h>
@ -39,7 +45,7 @@ void OculusLegacyDisplayPlugin::beginFrameRender(uint32_t frameIndex) {
_currentRenderFrameInfo = FrameInfo();
_currentRenderFrameInfo.predictedDisplayTime = _currentRenderFrameInfo.sensorSampleTime = ovr_GetTimeInSeconds();
_trackingState = ovrHmd_GetTrackingState(_hmd, _currentRenderFrameInfo.predictedDisplayTime);
_currentRenderFrameInfo.renderPose = toGlm(_trackingState.HeadPose.ThePose);
_currentRenderFrameInfo.rawRenderPose = _currentRenderFrameInfo.renderPose = toGlm(_trackingState.HeadPose.ThePose);
Lock lock(_mutex);
_frameInfos[frameIndex] = _currentRenderFrameInfo;
}
@ -72,14 +78,34 @@ bool OculusLegacyDisplayPlugin::isSupported() const {
}
bool OculusLegacyDisplayPlugin::internalActivate() {
Parent::internalActivate();
if (!Parent::internalActivate()) {
return false;
}
if (!(ovr_Initialize(nullptr))) {
Q_ASSERT(false);
qFatal("Failed to Initialize SDK");
return false;
}
_hmdWindow = new GLWindow();
_hmdWindow->create();
_hmdWindow->createContext(_container->getPrimaryContext());
auto hmdScreen = qApp->screens()[_hmdScreen];
auto hmdGeometry = hmdScreen->geometry();
_hmdWindow->setGeometry(hmdGeometry);
_hmdWindow->showFullScreen();
_hmdWindow->makeCurrent();
glClearColor(1, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
_hmdWindow->swapBuffers();
_container->makeRenderingContextCurrent();
QOpenGLContextWrapper(_hmdWindow->context()).moveToThread(_presentThread);
_hswDismissed = false;
_hmd = ovrHmd_Create(0);
if (!_hmd) {
@ -96,7 +122,8 @@ bool OculusLegacyDisplayPlugin::internalActivate() {
ovrMatrix4f ovrPerspectiveProjection =
ovrMatrix4f_Projection(erd.Fov, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP, ovrProjection_RightHanded);
_eyeProjections[eye] = toGlm(ovrPerspectiveProjection);
_eyeOffsets[eye] = glm::translate(mat4(), toGlm(erd.HmdToEyeViewOffset));
_ovrEyeOffsets[eye] = erd.HmdToEyeViewOffset;
_eyeOffsets[eye] = glm::translate(mat4(), -1.0f * toGlm(_ovrEyeOffsets[eye]));
eyeSizes[eye] = toGlm(ovrHmd_GetFovTextureSize(_hmd, eye, erd.Fov, 1.0f));
});
@ -121,6 +148,11 @@ void OculusLegacyDisplayPlugin::internalDeactivate() {
ovrHmd_Destroy(_hmd);
_hmd = nullptr;
ovr_Shutdown();
_hmdWindow->showNormal();
_hmdWindow->destroy();
_hmdWindow->deleteLater();
_hmdWindow = nullptr;
_container->makeRenderingContextCurrent();
}
// DLL based display plugins MUST initialize GLEW inside the DLL code.
@ -131,20 +163,21 @@ void OculusLegacyDisplayPlugin::customizeContext() {
glewInit();
glGetError();
});
_hmdWindow->requestActivate();
QThread::msleep(1000);
Parent::customizeContext();
#if 0
ovrGLConfig config; memset(&config, 0, sizeof(ovrRenderAPIConfig));
auto& header = config.Config.Header;
header.API = ovrRenderAPI_OpenGL;
header.BackBufferSize = _hmd->Resolution;
header.Multisample = 1;
int distortionCaps = ovrDistortionCap_TimeWarp;
int distortionCaps = ovrDistortionCap_TimeWarp | ovrDistortionCap_Vignette;
memset(_eyeTextures, 0, sizeof(ovrTexture) * 2);
ovr_for_each_eye([&](ovrEyeType eye) {
auto& header = _eyeTextures[eye].Header;
header.API = ovrRenderAPI_OpenGL;
header.TextureSize = { (int)_desiredFramebufferSize.x, (int)_desiredFramebufferSize.y };
header.TextureSize = { (int)_renderTargetSize.x, (int)_renderTargetSize.y };
header.RenderViewport.Size = header.TextureSize;
header.RenderViewport.Size.w /= 2;
if (eye == ovrEye_Right) {
@ -152,29 +185,57 @@ void OculusLegacyDisplayPlugin::customizeContext() {
}
});
if (_hmdWindow->makeCurrent()) {
#ifndef NDEBUG
ovrBool result =
#endif
ovrHmd_ConfigureRendering(_hmd, &config.Config, distortionCaps, _eyeFovs, _eyeRenderDescs);
assert(result);
ovrBool result =
#endif
ovrHmd_ConfigureRendering(_hmd, &config.Config, distortionCaps, _eyeFovs, _eyeRenderDescs);
assert(result);
_hmdWindow->doneCurrent();
}
}
#if 0
void OculusLegacyDisplayPlugin::uncustomizeContext() {
HmdDisplayPlugin::uncustomizeContext();
_hmdWindow->doneCurrent();
QOpenGLContextWrapper(_hmdWindow->context()).moveToThread(qApp->thread());
Parent::uncustomizeContext();
}
void OculusLegacyDisplayPlugin::internalPresent() {
ovrHmd_BeginFrame(_hmd, 0);
ovr_for_each_eye([&](ovrEyeType eye) {
reinterpret_cast<ovrGLTexture&>(_eyeTextures[eye]).OGL.TexId = _currentSceneTexture;
});
ovrHmd_EndFrame(_hmd, _eyePoses, _eyeTextures);
}
void OculusLegacyDisplayPlugin::hmdPresent() {
if (!_hswDismissed) {
ovrHSWDisplayState hswState;
ovrHmd_GetHSWDisplayState(_hmd, &hswState);
if (hswState.Displayed) {
ovrHmd_DismissHSWDisplay(_hmd);
}
#endif
}
auto r = glm::quat_cast(_currentPresentFrameInfo.presentPose);
ovrQuatf ovrRotation = { r.x, r.y, r.z, r.w };
ovrPosef eyePoses[2];
memset(eyePoses, 0, sizeof(ovrPosef) * 2);
eyePoses[0].Orientation = eyePoses[1].Orientation = ovrRotation;
GLint texture = oglplus::GetName(_compositeFramebuffer->color);
auto sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
glFlush();
if (_hmdWindow->makeCurrent()) {
glClearColor(0, 0.4, 0.8, 1);
glClear(GL_COLOR_BUFFER_BIT);
ovrHmd_BeginFrame(_hmd, _currentPresentFrameIndex);
glWaitSync(sync, 0, GL_TIMEOUT_IGNORED);
glDeleteSync(sync);
ovr_for_each_eye([&](ovrEyeType eye) {
reinterpret_cast<ovrGLTexture&>(_eyeTextures[eye]).OGL.TexId = texture;
});
ovrHmd_EndFrame(_hmd, eyePoses, _eyeTextures);
_hmdWindow->doneCurrent();
}
static auto widget = _container->getPrimaryWidget();
widget->makeCurrent();
}
int OculusLegacyDisplayPlugin::getHmdScreen() const {
return _hmdScreen;
@ -184,4 +245,3 @@ float OculusLegacyDisplayPlugin::getTargetFrameRate() const {
return TARGET_RATE_OculusLegacy;
}

View file

@ -14,42 +14,43 @@
#include <OVR_CAPI.h>
const float TARGET_RATE_OculusLegacy = 75.0f;
class GLWindow;
class OculusLegacyDisplayPlugin : public HmdDisplayPlugin {
using Parent = HmdDisplayPlugin;
public:
OculusLegacyDisplayPlugin();
virtual bool isSupported() const override;
virtual const QString& getName() const override { return NAME; }
bool isSupported() const override;
const QString& getName() const override { return NAME; }
virtual int getHmdScreen() const override;
int getHmdScreen() const override;
// Stereo specific methods
virtual void resetSensors() override;
virtual void beginFrameRender(uint32_t frameIndex) override;
void resetSensors() override;
void beginFrameRender(uint32_t frameIndex) override;
virtual float getTargetFrameRate() const override;
float getTargetFrameRate() const override;
protected:
virtual bool internalActivate() override;
virtual void internalDeactivate() override;
bool internalActivate() override;
void internalDeactivate() override;
virtual void customizeContext() override;
void hmdPresent() override {}
void customizeContext() override;
void uncustomizeContext() override;
void hmdPresent() override;
bool isHmdMounted() const override { return true; }
#if 0
virtual void uncustomizeContext() override;
virtual void internalPresent() override;
#endif
private:
static const QString NAME;
GLWindow* _hmdWindow{ nullptr };
ovrHmd _hmd;
mutable ovrTrackingState _trackingState;
ovrEyeRenderDesc _eyeRenderDescs[2];
ovrVector3f _ovrEyeOffsets[2];
ovrFovPort _eyeFovs[2];
//ovrTexture _eyeTextures[2]; // FIXME - not currently in use
ovrTexture _eyeTextures[2]; // FIXME - not currently in use
mutable int _hmdScreen { -1 };
bool _hswDismissed { false };
};