mirror of
https://github.com/overte-org/overte.git
synced 2025-08-05 06:19:49 +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/stereo/SideBySideStereoDisplayPlugin.h>
|
||||
#include <display-plugins/stereo/InterleavedStereoDisplayPlugin.h>
|
||||
#include <display-plugins/WidgetOpenGLDisplayPlugin.h>
|
||||
#include <display-plugins/Basic2DWindowOpenGLDisplayPlugin.h>
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include <display-plugins/oculus/OculusWin32DisplayPlugin.h>
|
||||
|
@ -50,7 +50,7 @@ const DisplayPluginList& getDisplayPlugins() {
|
|||
init = true;
|
||||
|
||||
DisplayPlugin* PLUGIN_POOL[] = {
|
||||
new WidgetOpenGLDisplayPlugin(),
|
||||
new Basic2DWindowOpenGLDisplayPlugin(),
|
||||
#ifdef DEBUG
|
||||
new NullDisplayPlugin(),
|
||||
#endif
|
||||
|
|
|
@ -628,7 +628,7 @@ void ApplicationOverlay::renderPointers() {
|
|||
// FIXME
|
||||
//glCanvas->cursor().setPos(glCanvas->mapToGlobal(position));
|
||||
} 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();
|
||||
void compileProgram(ProgramPtr & result, const std::string& vs, const std::string& fs);
|
||||
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() {
|
||||
}
|
||||
|
||||
const QString WidgetOpenGLDisplayPlugin::NAME("QWindow 2D Renderer");
|
||||
const QString WidgetOpenGLDisplayPlugin::NAME("QWidget 2D Renderer");
|
||||
|
||||
const QString & WidgetOpenGLDisplayPlugin::getName() {
|
||||
return NAME;
|
||||
|
|
|
@ -63,7 +63,10 @@ void WindowOpenGLDisplayPlugin::deactivate() {
|
|||
|
||||
|
||||
void WindowOpenGLDisplayPlugin::makeCurrent() {
|
||||
_window->makeCurrent();
|
||||
bool makeCurrentResult = _window->makeCurrent();
|
||||
if (!makeCurrentResult) {
|
||||
qDebug() << "Failed to make current";
|
||||
}
|
||||
}
|
||||
|
||||
void WindowOpenGLDisplayPlugin::doneCurrent() {
|
||||
|
|
|
@ -16,8 +16,13 @@ void OculusBaseDisplayPlugin::activate(PluginContainer * container) {
|
|||
ovr_for_each_eye([&](ovrEyeType eye) {
|
||||
ovrEyeRenderDesc& erd = _eyeRenderDescs[eye] = ovrHmd_GetRenderDesc(_hmd, eye, _hmd->MaxEyeFov[eye]);
|
||||
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);
|
||||
|
||||
ovrPerspectiveProjection =
|
||||
ovrMatrix4f_Projection(erd.Fov, 0.001f, 10.0f, ovrProjection_RightHanded);
|
||||
_compositeEyeProjections[eye] = toGlm(ovrPerspectiveProjection);
|
||||
|
||||
_eyeOffsets[eye] = erd.HmdToEyeViewOffset;
|
||||
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");
|
||||
}
|
||||
_frameIndex = 0;
|
||||
WidgetOpenGLDisplayPlugin::activate(container);
|
||||
MainWindowOpenGLDisplayPlugin::activate(container);
|
||||
}
|
||||
|
||||
QSize OculusBaseDisplayPlugin::getRecommendedFramebufferSize() const {
|
||||
|
|
|
@ -7,11 +7,11 @@
|
|||
//
|
||||
#pragma once
|
||||
|
||||
#include "../WidgetOpenGLDisplayPlugin.h"
|
||||
#include "../MainWindowOpenGLDisplayPlugin.h"
|
||||
|
||||
#include <OVR_CAPI.h>
|
||||
|
||||
class OculusBaseDisplayPlugin : public WidgetOpenGLDisplayPlugin {
|
||||
class OculusBaseDisplayPlugin : public MainWindowOpenGLDisplayPlugin {
|
||||
public:
|
||||
// Stereo specific methods
|
||||
virtual bool isHmd() const override { return true; }
|
||||
|
@ -32,6 +32,7 @@ protected:
|
|||
ovrEyeRenderDesc _eyeRenderDescs[2];
|
||||
ovrPosef _eyePoses[2];
|
||||
ovrVector3f _eyeOffsets[2];
|
||||
glm::mat4 _eyeProjections[2];
|
||||
mat4 _eyeProjections[2];
|
||||
mat4 _compositeEyeProjections[2];
|
||||
QSize _desiredFramebufferSize;
|
||||
};
|
||||
|
|
|
@ -35,66 +35,6 @@
|
|||
using oglplus::Framebuffer;
|
||||
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,
|
||||
// ovrHmd_CreateMirrorTextureGL, etc
|
||||
template <typename C>
|
||||
struct RiftFramebufferWrapper : public FramebufferWrapper<C> {
|
||||
struct RiftFramebufferWrapper : public FramebufferWrapper<C, char> {
|
||||
ovrHmd hmd;
|
||||
RiftFramebufferWrapper(const ovrHmd & hmd) : hmd(hmd) {};
|
||||
|
||||
|
@ -116,7 +56,7 @@ struct RiftFramebufferWrapper : public FramebufferWrapper<C> {
|
|||
}
|
||||
|
||||
protected:
|
||||
virtual void initDepth() override {
|
||||
virtual void initDepth() override final {
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -129,6 +69,7 @@ struct SwapFramebufferWrapper : public RiftFramebufferWrapper<ovrSwapTextureSet*
|
|||
SwapFramebufferWrapper(const ovrHmd & hmd)
|
||||
: RiftFramebufferWrapper(hmd) {
|
||||
}
|
||||
|
||||
~SwapFramebufferWrapper() {
|
||||
if (color) {
|
||||
ovrHmd_DestroySwapTextureSet(hmd, color);
|
||||
|
@ -166,13 +107,13 @@ protected:
|
|||
virtual void initDone() override {
|
||||
}
|
||||
|
||||
virtual void onBind(GLenum target) {
|
||||
virtual void onBind(oglplus::Framebuffer::Target target) override {
|
||||
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) {
|
||||
glFramebufferTexture2D(target, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
|
||||
virtual void onUnbind(oglplus::Framebuffer::Target target) override {
|
||||
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
|
||||
// render to the screen via glBlitFramebuffer
|
||||
struct MirrorFramebufferWrapper : public RiftFramebufferWrapper<ovrGLTexture*> {
|
||||
float targetAspect;
|
||||
MirrorFramebufferWrapper(const ovrHmd & hmd)
|
||||
: RiftFramebufferWrapper(hmd) {
|
||||
}
|
||||
~MirrorFramebufferWrapper() {
|
||||
: RiftFramebufferWrapper(hmd) { }
|
||||
|
||||
virtual ~MirrorFramebufferWrapper() {
|
||||
if (color) {
|
||||
ovrHmd_DestroyMirrorTexture(hmd, (ovrTexture*)color);
|
||||
color = nullptr;
|
||||
|
@ -206,7 +146,6 @@ private:
|
|||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color->OGL.TexId, 0);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
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 };
|
||||
});
|
||||
|
||||
PerformanceTimer::setActive(true);
|
||||
|
||||
//ovrLayerQuad& uiLayer = getUiLayer();
|
||||
//memset(&uiLayer, 0, sizeof(ovrLayerQuad));
|
||||
//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()));
|
||||
|
||||
uvec2 mirrorSize = toGlm(_widget->geometry().size());
|
||||
uvec2 mirrorSize = toGlm(_window->geometry().size());
|
||||
_mirrorFbo = MirrorFboPtr(new MirrorFramebufferWrapper(_hmd));
|
||||
_mirrorFbo->Init(mirrorSize);
|
||||
|
||||
|
@ -294,6 +235,7 @@ void OculusWin32DisplayPlugin::deactivate() {
|
|||
_mirrorFbo.reset();
|
||||
_uiSurface.reset();
|
||||
doneCurrent();
|
||||
PerformanceTimer::setActive(false);
|
||||
|
||||
OculusBaseDisplayPlugin::deactivate();
|
||||
|
||||
|
@ -306,15 +248,11 @@ void OculusWin32DisplayPlugin::display(
|
|||
GLuint sceneTexture, const glm::uvec2& sceneSize,
|
||||
GLuint overlayTexture, const glm::uvec2& overlaySize) {
|
||||
using namespace oglplus;
|
||||
bool wasActive = PerformanceTimer::isActive();
|
||||
PerformanceTimer::setActive(true);
|
||||
PerformanceTimer("OculusDisplayAndSwap");
|
||||
|
||||
|
||||
// Need to make sure only the display plugin is responsible for
|
||||
// controlling vsync
|
||||
wglSwapIntervalEXT(0);
|
||||
|
||||
{
|
||||
|
||||
}
|
||||
_sceneFbo->Bound([&] {
|
||||
auto size = _sceneFbo->size;
|
||||
Context::Viewport(size.x, size.y);
|
||||
|
@ -332,10 +270,9 @@ void OculusWin32DisplayPlugin::display(
|
|||
|
||||
Context::Enable(Capability::Blend);
|
||||
glBindTexture(GL_TEXTURE_2D, overlayTexture);
|
||||
//glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(_texture));
|
||||
for_each_eye([&](Eye eye) {
|
||||
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)));
|
||||
_uiSurface->Use();
|
||||
_uiSurface->Draw();
|
||||
|
@ -343,7 +280,13 @@ void OculusWin32DisplayPlugin::display(
|
|||
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);
|
||||
|
@ -368,7 +311,7 @@ void OculusWin32DisplayPlugin::display(
|
|||
_plane->Draw();
|
||||
Q_ASSERT(0 == glGetError());
|
||||
});
|
||||
*/
|
||||
#endif
|
||||
|
||||
ovrLayerEyeFov& sceneLayer = getSceneLayer();
|
||||
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
|
||||
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
|
||||
_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, [&] {
|
||||
// glBlitFramebuffer(
|
||||
// 0, 0, _sceneFbo->size.x, _sceneFbo->size.y,
|
||||
|
@ -405,23 +348,14 @@ void OculusWin32DisplayPlugin::display(
|
|||
we send.
|
||||
*/
|
||||
auto mirrorSize = _mirrorFbo->size;
|
||||
_mirrorFbo->Bound(GL_READ_FRAMEBUFFER, [&] {
|
||||
glBlitFramebuffer(
|
||||
_mirrorFbo->Bound(Framebuffer::Target::Read, [&] {
|
||||
Context::BlitFramebuffer(
|
||||
0, mirrorSize.y, mirrorSize.x, 0,
|
||||
0, 0, windowSize.x, windowSize.y,
|
||||
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
BufferSelectBit::ColorBuffer, BlitFilter::Nearest);
|
||||
});
|
||||
|
||||
++_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
|
||||
|
@ -437,7 +371,12 @@ bool OculusWin32DisplayPlugin::eventFilter(QObject* receiver, QEvent* 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() {
|
||||
// swapBuffers();
|
||||
doneCurrent();
|
||||
};
|
||||
|
|
|
@ -33,6 +33,6 @@ void InterleavedStereoDisplayPlugin::display(
|
|||
|
||||
void InterleavedStereoDisplayPlugin::customizeContext(PluginContainer * 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