mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 17:24:24 +02:00
Working on display plugins
This commit is contained in:
parent
5be97243bc
commit
17ebcdd1be
16 changed files with 259 additions and 108 deletions
BIN
interface/resources/images/cube_texture.png
Normal file
BIN
interface/resources/images/cube_texture.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.8 MiB |
|
@ -14,7 +14,7 @@
|
||||||
#include <display-plugins/NullDisplayPlugin.h>
|
#include <display-plugins/NullDisplayPlugin.h>
|
||||||
#include <display-plugins/stereo/SideBySideStereoDisplayPlugin.h>
|
#include <display-plugins/stereo/SideBySideStereoDisplayPlugin.h>
|
||||||
#include <display-plugins/stereo/InterleavedStereoDisplayPlugin.h>
|
#include <display-plugins/stereo/InterleavedStereoDisplayPlugin.h>
|
||||||
#include <display-plugins/WidgetOpenGLDisplayPlugin.h>
|
#include <display-plugins/Basic2DWindowOpenGLDisplayPlugin.h>
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
#include <display-plugins/oculus/OculusWin32DisplayPlugin.h>
|
#include <display-plugins/oculus/OculusWin32DisplayPlugin.h>
|
||||||
|
@ -50,7 +50,7 @@ const DisplayPluginList& getDisplayPlugins() {
|
||||||
init = true;
|
init = true;
|
||||||
|
|
||||||
DisplayPlugin* PLUGIN_POOL[] = {
|
DisplayPlugin* PLUGIN_POOL[] = {
|
||||||
new WidgetOpenGLDisplayPlugin(),
|
new Basic2DWindowOpenGLDisplayPlugin(),
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
new NullDisplayPlugin(),
|
new NullDisplayPlugin(),
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -628,7 +628,7 @@ void ApplicationOverlay::renderPointers() {
|
||||||
// FIXME
|
// FIXME
|
||||||
//glCanvas->cursor().setPos(glCanvas->mapToGlobal(position));
|
//glCanvas->cursor().setPos(glCanvas->mapToGlobal(position));
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "No collision point";
|
//qDebug() << "No collision point";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 2015/05/29
|
||||||
|
// 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 "Basic2DWindowOpenGLDisplayPlugin.h"
|
||||||
|
|
||||||
|
const QString Basic2DWindowOpenGLDisplayPlugin::NAME("2D Display");
|
||||||
|
|
||||||
|
const QString & Basic2DWindowOpenGLDisplayPlugin::getName() {
|
||||||
|
return NAME;
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 2015/05/29
|
||||||
|
// 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 Basic2DWindowOpenGLDisplayPlugin : public MainWindowOpenGLDisplayPlugin {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual const QString & getName() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const QString NAME;
|
||||||
|
};
|
|
@ -0,0 +1,38 @@
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 2015/05/29
|
||||||
|
// 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 "MainWindowOpenGLDisplayPlugin.h"
|
||||||
|
|
||||||
|
#include <GlWindow.h>
|
||||||
|
#include <QOpenGLContext>
|
||||||
|
#include <plugins/PluginContainer.h>
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QMainWindow>
|
||||||
|
|
||||||
|
MainWindowOpenGLDisplayPlugin::MainWindowOpenGLDisplayPlugin() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindowOpenGLDisplayPlugin::activate(PluginContainer * container) {
|
||||||
|
WindowOpenGLDisplayPlugin::activate(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) {
|
||||||
|
WindowOpenGLDisplayPlugin::customizeContext(container);
|
||||||
|
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() {
|
||||||
|
WindowOpenGLDisplayPlugin::deactivate();
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 2015/05/29
|
||||||
|
// 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 "WindowOpenGLDisplayPlugin.h"
|
||||||
|
|
||||||
|
class GlWindow;
|
||||||
|
class QSurfaceFormat;
|
||||||
|
|
||||||
|
class MainWindowOpenGLDisplayPlugin : public WindowOpenGLDisplayPlugin {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
MainWindowOpenGLDisplayPlugin();
|
||||||
|
virtual void activate(PluginContainer * container) override;
|
||||||
|
virtual void deactivate() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void customizeWindow(PluginContainer * container) override;
|
||||||
|
virtual void customizeContext(PluginContainer * container) override;
|
||||||
|
};
|
|
@ -39,5 +39,111 @@ typedef oglplus::Uniform<mat4> Mat4Uniform;
|
||||||
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);
|
||||||
ShapeWrapperPtr loadPlane(ProgramPtr program, float aspect = 1.0f);
|
ShapeWrapperPtr loadPlane(ProgramPtr program, float aspect = 1.0f);
|
||||||
ShapeWrapperPtr loadSphereSection(ProgramPtr program, float fov = PI / 3.0f * 2.0f, float aspect = 16.0f / 9.0f, int slices = 80, int stacks = 80);
|
ShapeWrapperPtr loadSphereSection(ProgramPtr program, float fov = PI / 3.0f * 2.0f, float aspect = 16.0f / 9.0f, int slices = 32, int stacks = 32);
|
||||||
|
|
||||||
|
|
||||||
|
// A basic wrapper for constructing a framebuffer with a renderbuffer
|
||||||
|
// for the depth attachment and an undefined type for the color attachement
|
||||||
|
// This allows us to reuse the basic framebuffer code for both the Mirror
|
||||||
|
// FBO as well as the Oculus swap textures we will use to render the scene
|
||||||
|
// Though we don't really need depth at all for the mirror FBO, or even an
|
||||||
|
// FBO, but using one means I can just use a glBlitFramebuffer to get it onto
|
||||||
|
// the screen.
|
||||||
|
template <
|
||||||
|
typename C,
|
||||||
|
typename D
|
||||||
|
>
|
||||||
|
struct FramebufferWrapper {
|
||||||
|
uvec2 size;
|
||||||
|
oglplus::Framebuffer fbo;
|
||||||
|
C color{ 0 };
|
||||||
|
D depth{ 0 };
|
||||||
|
|
||||||
|
FramebufferWrapper() {}
|
||||||
|
|
||||||
|
virtual ~FramebufferWrapper() {
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void Init(const uvec2 & size) {
|
||||||
|
this->size = size;
|
||||||
|
initColor();
|
||||||
|
initDepth();
|
||||||
|
initDone();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename F>
|
||||||
|
void Bound(F f) {
|
||||||
|
Bound(oglplus::Framebuffer::Target::Draw, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename F>
|
||||||
|
void Bound(oglplus::Framebuffer::Target target , F f) {
|
||||||
|
fbo.Bind(target);
|
||||||
|
onBind(target);
|
||||||
|
f();
|
||||||
|
onUnbind(target);
|
||||||
|
oglplus::DefaultFramebuffer().Bind(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Viewport() {
|
||||||
|
oglplus::Context::Viewport(size.x, size.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void onBind(oglplus::Framebuffer::Target target) {}
|
||||||
|
virtual void onUnbind(oglplus::Framebuffer::Target target) {}
|
||||||
|
|
||||||
|
static GLenum toEnum(oglplus::Framebuffer::Target target) {
|
||||||
|
switch (target) {
|
||||||
|
case oglplus::Framebuffer::Target::Draw:
|
||||||
|
return GL_DRAW_FRAMEBUFFER;
|
||||||
|
case oglplus::Framebuffer::Target::Read:
|
||||||
|
return GL_READ_FRAMEBUFFER;
|
||||||
|
default:
|
||||||
|
Q_ASSERT(false);
|
||||||
|
return GL_FRAMEBUFFER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void initDepth() {}
|
||||||
|
|
||||||
|
virtual void initColor() {}
|
||||||
|
|
||||||
|
virtual void initDone() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct BasicFramebufferWrapper : public FramebufferWrapper < oglplus::Texture, oglplus::Renderbuffer > {
|
||||||
|
protected:
|
||||||
|
virtual void initDepth() override {
|
||||||
|
using namespace oglplus;
|
||||||
|
Context::Bound(Renderbuffer::Target::Renderbuffer, depth)
|
||||||
|
.Storage(
|
||||||
|
PixelDataInternalFormat::DepthComponent,
|
||||||
|
size.x, size.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void initColor() override {
|
||||||
|
using namespace oglplus;
|
||||||
|
Context::Bound(oglplus::Texture::Target::_2D, color)
|
||||||
|
.MinFilter(TextureMinFilter::Linear)
|
||||||
|
.MagFilter(TextureMagFilter::Linear)
|
||||||
|
.WrapS(TextureWrap::ClampToEdge)
|
||||||
|
.WrapT(TextureWrap::ClampToEdge)
|
||||||
|
.Image2D(
|
||||||
|
0, PixelDataInternalFormat::RGBA8,
|
||||||
|
size.x, size.y,
|
||||||
|
0, PixelDataFormat::RGB, PixelDataType::UnsignedByte, nullptr
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void initDone() override {
|
||||||
|
using namespace oglplus;
|
||||||
|
static const Framebuffer::Target target = Framebuffer::Target::Draw;
|
||||||
|
Bound(target, [&] {
|
||||||
|
fbo.AttachTexture(target, FramebufferAttachment::Color, color, 0);
|
||||||
|
fbo.AttachRenderbuffer(target, FramebufferAttachment::Depth, depth);
|
||||||
|
fbo.Complete(target);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
|
@ -21,7 +21,7 @@
|
||||||
WidgetOpenGLDisplayPlugin::WidgetOpenGLDisplayPlugin() {
|
WidgetOpenGLDisplayPlugin::WidgetOpenGLDisplayPlugin() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString WidgetOpenGLDisplayPlugin::NAME("QWindow 2D Renderer");
|
const QString WidgetOpenGLDisplayPlugin::NAME("QWidget 2D Renderer");
|
||||||
|
|
||||||
const QString & WidgetOpenGLDisplayPlugin::getName() {
|
const QString & WidgetOpenGLDisplayPlugin::getName() {
|
||||||
return NAME;
|
return NAME;
|
||||||
|
|
|
@ -63,7 +63,10 @@ void WindowOpenGLDisplayPlugin::deactivate() {
|
||||||
|
|
||||||
|
|
||||||
void WindowOpenGLDisplayPlugin::makeCurrent() {
|
void WindowOpenGLDisplayPlugin::makeCurrent() {
|
||||||
_window->makeCurrent();
|
bool makeCurrentResult = _window->makeCurrent();
|
||||||
|
if (!makeCurrentResult) {
|
||||||
|
qDebug() << "Failed to make current";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowOpenGLDisplayPlugin::doneCurrent() {
|
void WindowOpenGLDisplayPlugin::doneCurrent() {
|
||||||
|
|
|
@ -16,8 +16,13 @@ void OculusBaseDisplayPlugin::activate(PluginContainer * container) {
|
||||||
ovr_for_each_eye([&](ovrEyeType eye) {
|
ovr_for_each_eye([&](ovrEyeType eye) {
|
||||||
ovrEyeRenderDesc& erd = _eyeRenderDescs[eye] = ovrHmd_GetRenderDesc(_hmd, eye, _hmd->MaxEyeFov[eye]);
|
ovrEyeRenderDesc& erd = _eyeRenderDescs[eye] = ovrHmd_GetRenderDesc(_hmd, eye, _hmd->MaxEyeFov[eye]);
|
||||||
ovrMatrix4f ovrPerspectiveProjection =
|
ovrMatrix4f ovrPerspectiveProjection =
|
||||||
ovrMatrix4f_Projection(erd.Fov, 0.1f, DEFAULT_FAR_CLIP, ovrProjection_RightHanded);
|
ovrMatrix4f_Projection(erd.Fov, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP, ovrProjection_RightHanded);
|
||||||
_eyeProjections[eye] = toGlm(ovrPerspectiveProjection);
|
_eyeProjections[eye] = toGlm(ovrPerspectiveProjection);
|
||||||
|
|
||||||
|
ovrPerspectiveProjection =
|
||||||
|
ovrMatrix4f_Projection(erd.Fov, 0.001f, 10.0f, ovrProjection_RightHanded);
|
||||||
|
_compositeEyeProjections[eye] = toGlm(ovrPerspectiveProjection);
|
||||||
|
|
||||||
_eyeOffsets[eye] = erd.HmdToEyeViewOffset;
|
_eyeOffsets[eye] = erd.HmdToEyeViewOffset;
|
||||||
eyeSizes[eye] = toGlm(ovrHmd_GetFovTextureSize(_hmd, eye, erd.Fov, 1.0f));
|
eyeSizes[eye] = toGlm(ovrHmd_GetFovTextureSize(_hmd, eye, erd.Fov, 1.0f));
|
||||||
});
|
});
|
||||||
|
@ -30,7 +35,7 @@ void OculusBaseDisplayPlugin::activate(PluginContainer * container) {
|
||||||
qFatal("Could not attach to sensor device");
|
qFatal("Could not attach to sensor device");
|
||||||
}
|
}
|
||||||
_frameIndex = 0;
|
_frameIndex = 0;
|
||||||
WidgetOpenGLDisplayPlugin::activate(container);
|
MainWindowOpenGLDisplayPlugin::activate(container);
|
||||||
}
|
}
|
||||||
|
|
||||||
QSize OculusBaseDisplayPlugin::getRecommendedFramebufferSize() const {
|
QSize OculusBaseDisplayPlugin::getRecommendedFramebufferSize() const {
|
||||||
|
|
|
@ -7,11 +7,11 @@
|
||||||
//
|
//
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../WidgetOpenGLDisplayPlugin.h"
|
#include "../MainWindowOpenGLDisplayPlugin.h"
|
||||||
|
|
||||||
#include <OVR_CAPI.h>
|
#include <OVR_CAPI.h>
|
||||||
|
|
||||||
class OculusBaseDisplayPlugin : public WidgetOpenGLDisplayPlugin {
|
class OculusBaseDisplayPlugin : public MainWindowOpenGLDisplayPlugin {
|
||||||
public:
|
public:
|
||||||
// Stereo specific methods
|
// Stereo specific methods
|
||||||
virtual bool isHmd() const override { return true; }
|
virtual bool isHmd() const override { return true; }
|
||||||
|
@ -32,6 +32,7 @@ protected:
|
||||||
ovrEyeRenderDesc _eyeRenderDescs[2];
|
ovrEyeRenderDesc _eyeRenderDescs[2];
|
||||||
ovrPosef _eyePoses[2];
|
ovrPosef _eyePoses[2];
|
||||||
ovrVector3f _eyeOffsets[2];
|
ovrVector3f _eyeOffsets[2];
|
||||||
glm::mat4 _eyeProjections[2];
|
mat4 _eyeProjections[2];
|
||||||
|
mat4 _compositeEyeProjections[2];
|
||||||
QSize _desiredFramebufferSize;
|
QSize _desiredFramebufferSize;
|
||||||
};
|
};
|
||||||
|
|
|
@ -35,66 +35,6 @@
|
||||||
using oglplus::Framebuffer;
|
using oglplus::Framebuffer;
|
||||||
using oglplus::DefaultFramebuffer;
|
using oglplus::DefaultFramebuffer;
|
||||||
|
|
||||||
// A basic wrapper for constructing a framebuffer with a renderbuffer
|
|
||||||
// for the depth attachment and an undefined type for the color attachement
|
|
||||||
// This allows us to reuse the basic framebuffer code for both the Mirror
|
|
||||||
// FBO as well as the Oculus swap textures we will use to render the scene
|
|
||||||
// Though we don't really need depth at all for the mirror FBO, or even an
|
|
||||||
// FBO, but using one means I can just use a glBlitFramebuffer to get it onto
|
|
||||||
// the screen.
|
|
||||||
template <typename C = GLuint, typename D = GLuint>
|
|
||||||
struct FramebufferWrapper {
|
|
||||||
uvec2 size;
|
|
||||||
Framebuffer fbo;
|
|
||||||
C color{ 0 };
|
|
||||||
D depth{ 0 };
|
|
||||||
|
|
||||||
virtual ~FramebufferWrapper() {
|
|
||||||
}
|
|
||||||
|
|
||||||
FramebufferWrapper() {}
|
|
||||||
|
|
||||||
virtual void Init(const uvec2 & size) {
|
|
||||||
this->size = size;
|
|
||||||
initColor();
|
|
||||||
initDepth();
|
|
||||||
initDone();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename F>
|
|
||||||
void Bound(F f) {
|
|
||||||
Bound(GL_FRAMEBUFFER, f);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename F>
|
|
||||||
void Bound(GLenum target, F f) {
|
|
||||||
glBindFramebuffer(target, oglplus::GetName(fbo));
|
|
||||||
onBind(target);
|
|
||||||
f();
|
|
||||||
onUnbind(target);
|
|
||||||
glBindFramebuffer(target, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Viewport() {
|
|
||||||
glViewport(0, 0, size.x, size.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void onBind(GLenum target) {}
|
|
||||||
virtual void onUnbind(GLenum target) {}
|
|
||||||
|
|
||||||
|
|
||||||
virtual void initDepth() {
|
|
||||||
glGenRenderbuffers(1, &depth);
|
|
||||||
assert(depth);
|
|
||||||
glBindRenderbuffer(GL_RENDERBUFFER, depth);
|
|
||||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, size.x, size.y);
|
|
||||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void initColor() = 0;
|
|
||||||
virtual void initDone() = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -102,7 +42,7 @@ protected:
|
||||||
// API to manage textures via ovrHmd_CreateSwapTextureSetGL,
|
// API to manage textures via ovrHmd_CreateSwapTextureSetGL,
|
||||||
// ovrHmd_CreateMirrorTextureGL, etc
|
// ovrHmd_CreateMirrorTextureGL, etc
|
||||||
template <typename C>
|
template <typename C>
|
||||||
struct RiftFramebufferWrapper : public FramebufferWrapper<C> {
|
struct RiftFramebufferWrapper : public FramebufferWrapper<C, char> {
|
||||||
ovrHmd hmd;
|
ovrHmd hmd;
|
||||||
RiftFramebufferWrapper(const ovrHmd & hmd) : hmd(hmd) {};
|
RiftFramebufferWrapper(const ovrHmd & hmd) : hmd(hmd) {};
|
||||||
|
|
||||||
|
@ -116,7 +56,7 @@ struct RiftFramebufferWrapper : public FramebufferWrapper<C> {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void initDepth() override {
|
virtual void initDepth() override final {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -129,6 +69,7 @@ struct SwapFramebufferWrapper : public RiftFramebufferWrapper<ovrSwapTextureSet*
|
||||||
SwapFramebufferWrapper(const ovrHmd & hmd)
|
SwapFramebufferWrapper(const ovrHmd & hmd)
|
||||||
: RiftFramebufferWrapper(hmd) {
|
: RiftFramebufferWrapper(hmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
~SwapFramebufferWrapper() {
|
~SwapFramebufferWrapper() {
|
||||||
if (color) {
|
if (color) {
|
||||||
ovrHmd_DestroySwapTextureSet(hmd, color);
|
ovrHmd_DestroySwapTextureSet(hmd, color);
|
||||||
|
@ -166,13 +107,13 @@ protected:
|
||||||
virtual void initDone() override {
|
virtual void initDone() override {
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void onBind(GLenum target) {
|
virtual void onBind(oglplus::Framebuffer::Target target) override {
|
||||||
ovrGLTexture& tex = (ovrGLTexture&)(color->Textures[color->CurrentIndex]);
|
ovrGLTexture& tex = (ovrGLTexture&)(color->Textures[color->CurrentIndex]);
|
||||||
glFramebufferTexture2D(target, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex.OGL.TexId, 0);
|
glFramebufferTexture2D(toEnum(target), GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex.OGL.TexId, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void onUnbind(GLenum target) {
|
virtual void onUnbind(oglplus::Framebuffer::Target target) override {
|
||||||
glFramebufferTexture2D(target, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
|
glFramebufferTexture2D(toEnum(target), GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -180,11 +121,10 @@ protected:
|
||||||
// We use a FBO to wrap the mirror texture because it makes it easier to
|
// We use a FBO to wrap the mirror texture because it makes it easier to
|
||||||
// render to the screen via glBlitFramebuffer
|
// render to the screen via glBlitFramebuffer
|
||||||
struct MirrorFramebufferWrapper : public RiftFramebufferWrapper<ovrGLTexture*> {
|
struct MirrorFramebufferWrapper : public RiftFramebufferWrapper<ovrGLTexture*> {
|
||||||
float targetAspect;
|
|
||||||
MirrorFramebufferWrapper(const ovrHmd & hmd)
|
MirrorFramebufferWrapper(const ovrHmd & hmd)
|
||||||
: RiftFramebufferWrapper(hmd) {
|
: RiftFramebufferWrapper(hmd) { }
|
||||||
}
|
|
||||||
~MirrorFramebufferWrapper() {
|
virtual ~MirrorFramebufferWrapper() {
|
||||||
if (color) {
|
if (color) {
|
||||||
ovrHmd_DestroyMirrorTexture(hmd, (ovrTexture*)color);
|
ovrHmd_DestroyMirrorTexture(hmd, (ovrTexture*)color);
|
||||||
color = nullptr;
|
color = nullptr;
|
||||||
|
@ -206,7 +146,6 @@ private:
|
||||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color->OGL.TexId, 0);
|
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color->OGL.TexId, 0);
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const QString OculusWin32DisplayPlugin::NAME("Oculus Rift");
|
const QString OculusWin32DisplayPlugin::NAME("Oculus Rift");
|
||||||
|
@ -253,6 +192,8 @@ void OculusWin32DisplayPlugin::activate(PluginContainer * container) {
|
||||||
sceneLayer.Viewport[eye].Pos = { eye == ovrEye_Left ? 0 : size.w, 0 };
|
sceneLayer.Viewport[eye].Pos = { eye == ovrEye_Left ? 0 : size.w, 0 };
|
||||||
});
|
});
|
||||||
|
|
||||||
|
PerformanceTimer::setActive(true);
|
||||||
|
|
||||||
//ovrLayerQuad& uiLayer = getUiLayer();
|
//ovrLayerQuad& uiLayer = getUiLayer();
|
||||||
//memset(&uiLayer, 0, sizeof(ovrLayerQuad));
|
//memset(&uiLayer, 0, sizeof(ovrLayerQuad));
|
||||||
//uiLayer.Header.Type = ovrLayerType_QuadInWorld;
|
//uiLayer.Header.Type = ovrLayerType_QuadInWorld;
|
||||||
|
@ -271,7 +212,7 @@ void OculusWin32DisplayPlugin::customizeContext(PluginContainer * container) {
|
||||||
|
|
||||||
_uiSurface = loadSphereSection(_program, glm::radians(DEFAULT_HMD_UI_ANGULAR_SIZE), aspect(getCanvasSize()));
|
_uiSurface = loadSphereSection(_program, glm::radians(DEFAULT_HMD_UI_ANGULAR_SIZE), aspect(getCanvasSize()));
|
||||||
|
|
||||||
uvec2 mirrorSize = toGlm(_widget->geometry().size());
|
uvec2 mirrorSize = toGlm(_window->geometry().size());
|
||||||
_mirrorFbo = MirrorFboPtr(new MirrorFramebufferWrapper(_hmd));
|
_mirrorFbo = MirrorFboPtr(new MirrorFramebufferWrapper(_hmd));
|
||||||
_mirrorFbo->Init(mirrorSize);
|
_mirrorFbo->Init(mirrorSize);
|
||||||
|
|
||||||
|
@ -294,6 +235,7 @@ void OculusWin32DisplayPlugin::deactivate() {
|
||||||
_mirrorFbo.reset();
|
_mirrorFbo.reset();
|
||||||
_uiSurface.reset();
|
_uiSurface.reset();
|
||||||
doneCurrent();
|
doneCurrent();
|
||||||
|
PerformanceTimer::setActive(false);
|
||||||
|
|
||||||
OculusBaseDisplayPlugin::deactivate();
|
OculusBaseDisplayPlugin::deactivate();
|
||||||
|
|
||||||
|
@ -306,15 +248,11 @@ void OculusWin32DisplayPlugin::display(
|
||||||
GLuint sceneTexture, const glm::uvec2& sceneSize,
|
GLuint sceneTexture, const glm::uvec2& sceneSize,
|
||||||
GLuint overlayTexture, const glm::uvec2& overlaySize) {
|
GLuint overlayTexture, const glm::uvec2& overlaySize) {
|
||||||
using namespace oglplus;
|
using namespace oglplus;
|
||||||
bool wasActive = PerformanceTimer::isActive();
|
|
||||||
PerformanceTimer::setActive(true);
|
// Need to make sure only the display plugin is responsible for
|
||||||
PerformanceTimer("OculusDisplayAndSwap");
|
// controlling vsync
|
||||||
|
|
||||||
wglSwapIntervalEXT(0);
|
wglSwapIntervalEXT(0);
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
_sceneFbo->Bound([&] {
|
_sceneFbo->Bound([&] {
|
||||||
auto size = _sceneFbo->size;
|
auto size = _sceneFbo->size;
|
||||||
Context::Viewport(size.x, size.y);
|
Context::Viewport(size.x, size.y);
|
||||||
|
@ -332,10 +270,9 @@ void OculusWin32DisplayPlugin::display(
|
||||||
|
|
||||||
Context::Enable(Capability::Blend);
|
Context::Enable(Capability::Blend);
|
||||||
glBindTexture(GL_TEXTURE_2D, overlayTexture);
|
glBindTexture(GL_TEXTURE_2D, overlayTexture);
|
||||||
//glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(_texture));
|
|
||||||
for_each_eye([&](Eye eye) {
|
for_each_eye([&](Eye eye) {
|
||||||
Context::Viewport(eye == Left ? 0 : size.x / 2, 0, size.x / 2, size.y);
|
Context::Viewport(eye == Left ? 0 : size.x / 2, 0, size.x / 2, size.y);
|
||||||
Mat4Uniform(*_program, "Projection").Set(getProjection(eye, mat4()));
|
Mat4Uniform(*_program, "Projection").Set(_compositeEyeProjections[eye]);
|
||||||
Mat4Uniform(*_program, "ModelView").Set(glm::scale(glm::inverse(getModelview(eye, mat4())), vec3(1)));
|
Mat4Uniform(*_program, "ModelView").Set(glm::scale(glm::inverse(getModelview(eye, mat4())), vec3(1)));
|
||||||
_uiSurface->Use();
|
_uiSurface->Use();
|
||||||
_uiSurface->Draw();
|
_uiSurface->Draw();
|
||||||
|
@ -343,7 +280,13 @@ void OculusWin32DisplayPlugin::display(
|
||||||
Context::Disable(Capability::Blend);
|
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();
|
ovrLayerQuad& uiLayer = getUiLayer();
|
||||||
if (nullptr == uiLayer.ColorTexture || overlaySize != _uiFbo->size) {
|
if (nullptr == uiLayer.ColorTexture || overlaySize != _uiFbo->size) {
|
||||||
_uiFbo->Resize(overlaySize);
|
_uiFbo->Resize(overlaySize);
|
||||||
|
@ -368,7 +311,7 @@ void OculusWin32DisplayPlugin::display(
|
||||||
_plane->Draw();
|
_plane->Draw();
|
||||||
Q_ASSERT(0 == glGetError());
|
Q_ASSERT(0 == glGetError());
|
||||||
});
|
});
|
||||||
*/
|
#endif
|
||||||
|
|
||||||
ovrLayerEyeFov& sceneLayer = getSceneLayer();
|
ovrLayerEyeFov& sceneLayer = getSceneLayer();
|
||||||
ovr_for_each_eye([&](ovrEyeType eye) {
|
ovr_for_each_eye([&](ovrEyeType eye) {
|
||||||
|
@ -383,8 +326,8 @@ void OculusWin32DisplayPlugin::display(
|
||||||
scene to the window framebuffer, before distortion. Note this only works if we're doing
|
scene to the window framebuffer, before distortion. Note this only works if we're doing
|
||||||
ui compositing ourselves, and not relying on the Oculus SDK compositor (or we don't want
|
ui compositing ourselves, and not relying on the Oculus SDK compositor (or we don't want
|
||||||
the UI visible in the output window (unlikely). This should be done before
|
the UI visible in the output window (unlikely). This should be done before
|
||||||
|
_sceneFbo->Increment or we're be using the wrong texture
|
||||||
*/
|
*/
|
||||||
// _sceneFbo->Increment or we're be using the wrong texture
|
|
||||||
//_sceneFbo->Bound(GL_READ_FRAMEBUFFER, [&] {
|
//_sceneFbo->Bound(GL_READ_FRAMEBUFFER, [&] {
|
||||||
// glBlitFramebuffer(
|
// glBlitFramebuffer(
|
||||||
// 0, 0, _sceneFbo->size.x, _sceneFbo->size.y,
|
// 0, 0, _sceneFbo->size.x, _sceneFbo->size.y,
|
||||||
|
@ -405,23 +348,14 @@ void OculusWin32DisplayPlugin::display(
|
||||||
we send.
|
we send.
|
||||||
*/
|
*/
|
||||||
auto mirrorSize = _mirrorFbo->size;
|
auto mirrorSize = _mirrorFbo->size;
|
||||||
_mirrorFbo->Bound(GL_READ_FRAMEBUFFER, [&] {
|
_mirrorFbo->Bound(Framebuffer::Target::Read, [&] {
|
||||||
glBlitFramebuffer(
|
Context::BlitFramebuffer(
|
||||||
0, mirrorSize.y, mirrorSize.x, 0,
|
0, mirrorSize.y, mirrorSize.x, 0,
|
||||||
0, 0, windowSize.x, windowSize.y,
|
0, 0, windowSize.x, windowSize.y,
|
||||||
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
BufferSelectBit::ColorBuffer, BlitFilter::Nearest);
|
||||||
});
|
});
|
||||||
|
|
||||||
++_frameIndex;
|
++_frameIndex;
|
||||||
// swapBuffers();
|
|
||||||
PerformanceTimer::setActive(wasActive);
|
|
||||||
if (0 == (_frameIndex % (75 * 5))) {
|
|
||||||
auto record1 = PerformanceTimer::getTimerRecord("OculusDisplayAndSwap");
|
|
||||||
auto record2 = PerformanceTimer::getTimerRecord("OculusSubmit");
|
|
||||||
qDebug() << "Average display and submit: " << record1.getAverage();
|
|
||||||
qDebug() << "Average submit: " << record2.getAverage();
|
|
||||||
qDebug() << "Diff " << record1.getAverage() - record2.getAverage();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pass input events on to the application
|
// Pass input events on to the application
|
||||||
|
@ -437,7 +371,12 @@ bool OculusWin32DisplayPlugin::eventFilter(QObject* receiver, QEvent* event) {
|
||||||
return OculusBaseDisplayPlugin::eventFilter(receiver, event);
|
return OculusBaseDisplayPlugin::eventFilter(receiver, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
The swapbuffer call here is only required if we want to mirror the content to the screen.
|
||||||
|
However, it should only be done if we can reliably disable v-sync on the mirror surface,
|
||||||
|
otherwise the swapbuffer delay will interefere with the framerate of the headset
|
||||||
|
*/
|
||||||
void OculusWin32DisplayPlugin::finishFrame() {
|
void OculusWin32DisplayPlugin::finishFrame() {
|
||||||
|
// swapBuffers();
|
||||||
doneCurrent();
|
doneCurrent();
|
||||||
};
|
};
|
||||||
|
|
|
@ -33,6 +33,6 @@ void InterleavedStereoDisplayPlugin::display(
|
||||||
|
|
||||||
void InterleavedStereoDisplayPlugin::customizeContext(PluginContainer * container) {
|
void InterleavedStereoDisplayPlugin::customizeContext(PluginContainer * container) {
|
||||||
StereoDisplayPlugin::customizeContext(container);
|
StereoDisplayPlugin::customizeContext(container);
|
||||||
// Set up the stencil buffers
|
// Set up the stencil buffers? Or use a custom shader?
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue