1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
// Copyright (c) 2012-2017 VideoStitch SAS
// Copyright (c) 2018 stitchEm
#pragma once
#include "steamvrwindow.hpp"
#include <QApplication>
#include <QOpenGLContext>
SteamVRWindow::SteamVRWindow(bool stereoscopic)
: QWindow(),
shuttingDown(false),
renderThread([&] { renderLoop(); }),
context(nullptr),
renderer(),
started(false) {
setSurfaceType(QSurface::OpenGLSurface);
QSurfaceFormat format;
// Qt Quick may need a depth and stencil buffer. Always make sure these are available.
format.setDepthBufferSize(16);
format.setStencilBufferSize(8);
format.setVersion(4, 3);
format.setProfile(QSurfaceFormat::OpenGLContextProfile::CoreProfile);
setFormat(format);
context = new QOpenGLContext;
context->setFormat(format);
context->setShareContext(QOpenGLContext::globalShareContext());
context->create();
setFlags(Qt::FramelessWindowHint);
show();
context->doneCurrent();
context->moveToThread(&renderThread);
renderThread.setObjectName("render-to-vive thread");
}
SteamVRWindow::~SteamVRWindow() {
if (started) {
stop();
}
}
bool SteamVRWindow::start() {
if (!renderer.initializeSteamVR()) {
return false;
}
// start the render thread after the context has been shared
renderThread.start(QThread::HighestPriority);
started = true;
return true;
}
// Should only be called from the primary thread
void SteamVRWindow::stop() {
if (!shuttingDown) {
shuttingDown = true;
renderThread.quit();
renderThread.wait();
}
started = false;
renderer.uninitializeSteamVR();
}
SteamVRRenderer& SteamVRWindow::getRenderer() { return renderer; }
void SteamVRWindow::renderLoop() {
// the render context can be shared with texture uploaders, they must already have acquired the context here
// now the render context can be made current
context->makeCurrent(this);
renderer.configureRendering(0, 0);
while (!shuttingDown) {
renderer.render();
}
context->doneCurrent();
context->moveToThread(QApplication::instance()->thread());
}