mirror of
https://github.com/overte-org/overte.git
synced 2025-04-14 03:47:13 +02:00
restructured gamma correction so snapshots look correct
This commit is contained in:
parent
a66bd04810
commit
250d18d7df
6 changed files with 129 additions and 128 deletions
|
@ -109,11 +109,25 @@ bool Basic2DWindowOpenGLDisplayPlugin::internalActivate() {
|
||||||
return Parent::internalActivate();
|
return Parent::internalActivate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gpu::PipelinePointer Basic2DWindowOpenGLDisplayPlugin::getRenderTexturePipeline() {
|
||||||
|
#if defined(Q_OS_ANDROID)
|
||||||
|
return _linearToSRGBPipeline;
|
||||||
|
#else
|
||||||
|
|
||||||
|
#ifndef USE_GLES
|
||||||
|
return _SRGBToLinearPipeline;
|
||||||
|
#else
|
||||||
|
return _drawTexturePipeline;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
gpu::PipelinePointer Basic2DWindowOpenGLDisplayPlugin::getCompositeScenePipeline() {
|
gpu::PipelinePointer Basic2DWindowOpenGLDisplayPlugin::getCompositeScenePipeline() {
|
||||||
#if defined(Q_OS_ANDROID)
|
#if defined(Q_OS_ANDROID)
|
||||||
return _linearToSRGBPipeline;
|
return _linearToSRGBPipeline;
|
||||||
#else
|
#else
|
||||||
return _SRGBToLinearPipeline;
|
return _drawTexturePipeline;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ public:
|
||||||
|
|
||||||
virtual void pluginUpdate() override {};
|
virtual void pluginUpdate() override {};
|
||||||
|
|
||||||
|
virtual gpu::PipelinePointer getRenderTexturePipeline() override;
|
||||||
virtual gpu::PipelinePointer getCompositeScenePipeline() override;
|
virtual gpu::PipelinePointer getCompositeScenePipeline() override;
|
||||||
virtual gpu::Element getCompositeFBColorSpace() override;
|
virtual gpu::Element getCompositeFBColorSpace() override;
|
||||||
|
|
||||||
|
|
|
@ -59,19 +59,14 @@ class PresentThread : public QThread, public Dependency {
|
||||||
using Lock = std::unique_lock<Mutex>;
|
using Lock = std::unique_lock<Mutex>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
PresentThread() {
|
PresentThread() {
|
||||||
connect(qApp, &QCoreApplication::aboutToQuit, [this] {
|
connect(qApp, &QCoreApplication::aboutToQuit, [this] { shutdown(); });
|
||||||
shutdown();
|
|
||||||
});
|
|
||||||
setObjectName("Present");
|
setObjectName("Present");
|
||||||
|
|
||||||
_refreshRateController = std::make_shared<RefreshRateController>();
|
_refreshRateController = std::make_shared<RefreshRateController>();
|
||||||
}
|
}
|
||||||
|
|
||||||
~PresentThread() {
|
~PresentThread() { shutdown(); }
|
||||||
shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto getRefreshRateController() { return _refreshRateController; }
|
auto getRefreshRateController() { return _refreshRateController; }
|
||||||
|
|
||||||
|
@ -82,17 +77,16 @@ public:
|
||||||
|
|
||||||
Lock lock(_mutex);
|
Lock lock(_mutex);
|
||||||
_shutdown = true;
|
_shutdown = true;
|
||||||
_condition.wait(lock, [&] { return !_shutdown; });
|
_condition.wait(lock, [&] { return !_shutdown; });
|
||||||
qCDebug(displayPlugins) << "Present thread shutdown";
|
qCDebug(displayPlugins) << "Present thread shutdown";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void setNewDisplayPlugin(OpenGLDisplayPlugin* plugin) {
|
void setNewDisplayPlugin(OpenGLDisplayPlugin* plugin) {
|
||||||
Lock lock(_mutex);
|
Lock lock(_mutex);
|
||||||
if (isRunning()) {
|
if (isRunning()) {
|
||||||
_newPluginQueue.push(plugin);
|
_newPluginQueue.push(plugin);
|
||||||
_condition.wait(lock, [=]()->bool { return _newPluginQueue.empty(); });
|
_condition.wait(lock, [=]() -> bool { return _newPluginQueue.empty(); });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,7 +98,6 @@ public:
|
||||||
_context->moveToThread(this);
|
_context->moveToThread(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual void run() override {
|
virtual void run() override {
|
||||||
PROFILE_SET_THREAD_NAME("Present Thread");
|
PROFILE_SET_THREAD_NAME("Present Thread");
|
||||||
|
|
||||||
|
@ -120,8 +113,7 @@ public:
|
||||||
CHECK_GL_ERROR();
|
CHECK_GL_ERROR();
|
||||||
while (!_shutdown) {
|
while (!_shutdown) {
|
||||||
if (_pendingOtherThreadOperation) {
|
if (_pendingOtherThreadOperation) {
|
||||||
PROFILE_RANGE(render, "MainThreadOp")
|
PROFILE_RANGE(render, "MainThreadOp") {
|
||||||
{
|
|
||||||
Lock lock(_mutex);
|
Lock lock(_mutex);
|
||||||
_context->doneCurrent();
|
_context->doneCurrent();
|
||||||
// Move the context to the main thread
|
// Move the context to the main thread
|
||||||
|
@ -131,7 +123,6 @@ public:
|
||||||
_condition.notify_one();
|
_condition.notify_one();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
// Main thread does it's thing while we wait on the lock to release
|
// Main thread does it's thing while we wait on the lock to release
|
||||||
Lock lock(_mutex);
|
Lock lock(_mutex);
|
||||||
|
@ -201,7 +192,7 @@ public:
|
||||||
#if defined(Q_OS_MAC)
|
#if defined(Q_OS_MAC)
|
||||||
_context->doneCurrent();
|
_context->doneCurrent();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_refreshRateController->sleepThreadIfNeeded(this, currentPlugin->isHmd());
|
_refreshRateController->sleepThreadIfNeeded(this, currentPlugin->isHmd());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,23 +226,21 @@ public:
|
||||||
_condition.notify_one();
|
_condition.notify_one();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void makeCurrent();
|
void makeCurrent();
|
||||||
void doneCurrent();
|
void doneCurrent();
|
||||||
|
|
||||||
bool _shutdown { false };
|
bool _shutdown{ false };
|
||||||
Mutex _mutex;
|
Mutex _mutex;
|
||||||
// Used to allow the main thread to perform context operations
|
// Used to allow the main thread to perform context operations
|
||||||
Condition _condition;
|
Condition _condition;
|
||||||
|
|
||||||
|
QThread* _targetOperationThread{ nullptr };
|
||||||
QThread* _targetOperationThread { nullptr };
|
bool _pendingOtherThreadOperation{ false };
|
||||||
bool _pendingOtherThreadOperation { false };
|
bool _finishedOtherThreadOperation{ false };
|
||||||
bool _finishedOtherThreadOperation { false };
|
|
||||||
std::queue<OpenGLDisplayPlugin*> _newPluginQueue;
|
std::queue<OpenGLDisplayPlugin*> _newPluginQueue;
|
||||||
gl::Context* _context { nullptr };
|
gl::Context* _context{ nullptr };
|
||||||
std::shared_ptr<RefreshRateController> _refreshRateController { nullptr };
|
std::shared_ptr<RefreshRateController> _refreshRateController{ nullptr };
|
||||||
};
|
};
|
||||||
|
|
||||||
bool OpenGLDisplayPlugin::activate() {
|
bool OpenGLDisplayPlugin::activate() {
|
||||||
|
@ -302,7 +291,6 @@ bool OpenGLDisplayPlugin::activate() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// This should not return until the new context has been customized
|
// This should not return until the new context has been customized
|
||||||
// and the old context (if any) has been uncustomized
|
// and the old context (if any) has been uncustomized
|
||||||
presentThread->setNewDisplayPlugin(this);
|
presentThread->setNewDisplayPlugin(this);
|
||||||
|
@ -334,7 +322,7 @@ void OpenGLDisplayPlugin::deactivate() {
|
||||||
|
|
||||||
_container->showDisplayPluginsTools(false);
|
_container->showDisplayPluginsTools(false);
|
||||||
if (!_container->currentDisplayActions().isEmpty()) {
|
if (!_container->currentDisplayActions().isEmpty()) {
|
||||||
foreach(auto itemInfo, _container->currentDisplayActions()) {
|
foreach (auto itemInfo, _container->currentDisplayActions()) {
|
||||||
_container->removeMenuItem(itemInfo.first, itemInfo.second);
|
_container->removeMenuItem(itemInfo.first, itemInfo.second);
|
||||||
}
|
}
|
||||||
_container->currentDisplayActions().clear();
|
_container->currentDisplayActions().clear();
|
||||||
|
@ -368,12 +356,9 @@ void OpenGLDisplayPlugin::customizeContext() {
|
||||||
image = image.convertToFormat(QImage::Format_ARGB32);
|
image = image.convertToFormat(QImage::Format_ARGB32);
|
||||||
}
|
}
|
||||||
if ((image.width() > 0) && (image.height() > 0)) {
|
if ((image.width() > 0) && (image.height() > 0)) {
|
||||||
|
cursorData.texture = gpu::Texture::createStrict(gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA), image.width(),
|
||||||
cursorData.texture = gpu::Texture::createStrict(
|
image.height(), gpu::Texture::MAX_NUM_MIPS,
|
||||||
gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA),
|
gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR));
|
||||||
image.width(), image.height(),
|
|
||||||
gpu::Texture::MAX_NUM_MIPS,
|
|
||||||
gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR));
|
|
||||||
cursorData.texture->setSource("cursor texture");
|
cursorData.texture->setSource("cursor texture");
|
||||||
auto usage = gpu::Texture::Usage::Builder().withColor().withAlpha();
|
auto usage = gpu::Texture::Usage::Builder().withColor().withAlpha();
|
||||||
cursorData.texture->setUsage(usage.build());
|
cursorData.texture->setUsage(usage.build());
|
||||||
|
@ -384,45 +369,39 @@ void OpenGLDisplayPlugin::customizeContext() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_drawTexturePipeline) {
|
if (!_linearToSRGBPipeline) {
|
||||||
gpu::StatePointer blendState = gpu::StatePointer(new gpu::State());
|
gpu::StatePointer blendState = gpu::StatePointer(new gpu::State());
|
||||||
blendState->setDepthTest(gpu::State::DepthTest(false));
|
blendState->setDepthTest(gpu::State::DepthTest(false));
|
||||||
blendState->setBlendFunction(true,
|
blendState->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
||||||
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD,
|
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
||||||
gpu::State::INV_SRC_ALPHA,
|
|
||||||
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD,
|
|
||||||
gpu::State::ONE);
|
|
||||||
|
|
||||||
gpu::StatePointer scissorState = gpu::StatePointer(new gpu::State());
|
gpu::StatePointer scissorState = gpu::StatePointer(new gpu::State());
|
||||||
scissorState->setDepthTest(gpu::State::DepthTest(false));
|
scissorState->setDepthTest(gpu::State::DepthTest(false));
|
||||||
scissorState->setScissorEnable(true);
|
scissorState->setScissorEnable(true);
|
||||||
|
|
||||||
_drawTexturePipeline = gpu::Pipeline::create(gpu::Shader::createProgram(DrawTexture), scissorState);
|
_drawTexturePipeline = gpu::Pipeline::create(gpu::Shader::createProgram(DrawTexture), scissorState);
|
||||||
|
|
||||||
_linearToSRGBPipeline = gpu::Pipeline::create(gpu::Shader::createProgram(DrawTextureGammaLinearToSRGB), scissorState);
|
_linearToSRGBPipeline = gpu::Pipeline::create(gpu::Shader::createProgram(DrawTextureGammaLinearToSRGB), scissorState);
|
||||||
|
|
||||||
_SRGBToLinearPipeline = gpu::Pipeline::create(gpu::Shader::createProgram(DrawTextureGammaSRGBToLinear), scissorState);
|
_SRGBToLinearPipeline = gpu::Pipeline::create(gpu::Shader::createProgram(DrawTextureGammaSRGBToLinear), scissorState);
|
||||||
|
|
||||||
_hudPipeline = gpu::Pipeline::create(gpu::Shader::createProgram(DrawTexture), blendState);
|
_hudPipeline = gpu::Pipeline::create(gpu::Shader::createProgram(DrawTexture), blendState);
|
||||||
|
|
||||||
_mirrorHUDPipeline = gpu::Pipeline::create(gpu::Shader::createProgram(DrawTextureMirroredX), blendState);
|
_mirrorHUDPipeline = gpu::Pipeline::create(gpu::Shader::createProgram(DrawTextureMirroredX), blendState);
|
||||||
|
|
||||||
_cursorPipeline = gpu::Pipeline::create(gpu::Shader::createProgram(DrawTransformedTexture), blendState);
|
_cursorPipeline = gpu::Pipeline::create(gpu::Shader::createProgram(DrawTransformedTexture), blendState);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateCompositeFramebuffer();
|
updateCompositeFramebuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLDisplayPlugin::uncustomizeContext() {
|
void OpenGLDisplayPlugin::uncustomizeContext() {
|
||||||
|
|
||||||
_drawTexturePipeline.reset();
|
_drawTexturePipeline.reset();
|
||||||
_linearToSRGBPipeline.reset();
|
_linearToSRGBPipeline.reset();
|
||||||
_SRGBToLinearPipeline.reset();
|
_SRGBToLinearPipeline.reset();
|
||||||
|
_cursorPipeline.reset();
|
||||||
_hudPipeline.reset();
|
_hudPipeline.reset();
|
||||||
_mirrorHUDPipeline.reset();
|
_mirrorHUDPipeline.reset();
|
||||||
_cursorPipeline.reset();
|
|
||||||
_compositeFramebuffer.reset();
|
_compositeFramebuffer.reset();
|
||||||
|
|
||||||
withPresentThreadLock([&] {
|
withPresentThreadLock([&] {
|
||||||
_currentFrame.reset();
|
_currentFrame.reset();
|
||||||
_lastFrame = nullptr;
|
_lastFrame = nullptr;
|
||||||
|
@ -433,7 +412,6 @@ void OpenGLDisplayPlugin::uncustomizeContext() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Pressing Alt (and Meta) key alone activates the menubar because its style inherits the
|
// Pressing Alt (and Meta) key alone activates the menubar because its style inherits the
|
||||||
// SHMenuBarAltKeyNavigation from QWindowsStyle. This makes it impossible for a scripts to
|
// SHMenuBarAltKeyNavigation from QWindowsStyle. This makes it impossible for a scripts to
|
||||||
// receive keyPress events for the Alt (and Meta) key in a reliable manner.
|
// receive keyPress events for the Alt (and Meta) key in a reliable manner.
|
||||||
|
@ -477,9 +455,7 @@ bool OpenGLDisplayPlugin::eventFilter(QObject* receiver, QEvent* event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLDisplayPlugin::submitFrame(const gpu::FramePointer& newFrame) {
|
void OpenGLDisplayPlugin::submitFrame(const gpu::FramePointer& newFrame) {
|
||||||
withNonPresentThreadLock([&] {
|
withNonPresentThreadLock([&] { _newFrameQueue.push(newFrame); });
|
||||||
_newFrameQueue.push(newFrame);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLDisplayPlugin::captureFrame(const std::string& filename) const {
|
void OpenGLDisplayPlugin::captureFrame(const std::string& filename) const {
|
||||||
|
@ -493,10 +469,10 @@ void OpenGLDisplayPlugin::captureFrame(const std::string& filename) const {
|
||||||
image = QImage{ 1, 1, QImage::Format_ARGB32 };
|
image = QImage{ 1, 1, QImage::Format_ARGB32 };
|
||||||
auto storedImage = texture->accessStoredMipFace(0, 0);
|
auto storedImage = texture->accessStoredMipFace(0, 0);
|
||||||
memcpy(image.bits(), storedImage->data(), image.sizeInBytes());
|
memcpy(image.bits(), storedImage->data(), image.sizeInBytes());
|
||||||
//if (texture == textureCache->getWhiteTexture()) {
|
//if (texture == textureCache->getWhiteTexture()) {
|
||||||
//} else if (texture == textureCache->getBlackTexture()) {
|
//} else if (texture == textureCache->getBlackTexture()) {
|
||||||
//} else if (texture == textureCache->getBlueTexture()) {
|
//} else if (texture == textureCache->getBlueTexture()) {
|
||||||
//} else if (texture == textureCache->getGrayTexture()) {
|
//} else if (texture == textureCache->getGrayTexture()) {
|
||||||
} else {
|
} else {
|
||||||
ivec4 rect = { 0, 0, texture->getWidth(), texture->getHeight() };
|
ivec4 rect = { 0, 0, texture->getWidth(), texture->getHeight() };
|
||||||
framebuffer->setRenderBuffer(0, texture, layer);
|
framebuffer->setRenderBuffer(0, texture, layer);
|
||||||
|
@ -514,11 +490,18 @@ void OpenGLDisplayPlugin::captureFrame(const std::string& filename) const {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLDisplayPlugin::renderFromTexture(gpu::Batch& batch, const gpu::TexturePointer& texture, const glm::ivec4& viewport, const glm::ivec4& scissor) {
|
void OpenGLDisplayPlugin::renderFromTexture(gpu::Batch& batch,
|
||||||
|
const gpu::TexturePointer& texture,
|
||||||
|
const glm::ivec4& viewport,
|
||||||
|
const glm::ivec4& scissor) {
|
||||||
renderFromTexture(batch, texture, viewport, scissor, nullptr);
|
renderFromTexture(batch, texture, viewport, scissor, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLDisplayPlugin::renderFromTexture(gpu::Batch& batch, const gpu::TexturePointer& texture, const glm::ivec4& viewport, const glm::ivec4& scissor, const gpu::FramebufferPointer& copyFbo /*=gpu::FramebufferPointer()*/) {
|
void OpenGLDisplayPlugin::renderFromTexture(gpu::Batch& batch,
|
||||||
|
const gpu::TexturePointer& texture,
|
||||||
|
const glm::ivec4& viewport,
|
||||||
|
const glm::ivec4& scissor,
|
||||||
|
const gpu::FramebufferPointer& copyFbo /*=gpu::FramebufferPointer()*/) {
|
||||||
auto fbo = gpu::FramebufferPointer();
|
auto fbo = gpu::FramebufferPointer();
|
||||||
batch.enableStereo(false);
|
batch.enableStereo(false);
|
||||||
batch.resetViewTransform();
|
batch.resetViewTransform();
|
||||||
|
@ -528,18 +511,18 @@ void OpenGLDisplayPlugin::renderFromTexture(gpu::Batch& batch, const gpu::Textur
|
||||||
batch.setViewportTransform(viewport);
|
batch.setViewportTransform(viewport);
|
||||||
batch.setResourceTexture(0, texture);
|
batch.setResourceTexture(0, texture);
|
||||||
|
|
||||||
batch.setPipeline(_drawTexturePipeline);
|
batch.setPipeline(getRenderTexturePipeline());
|
||||||
|
|
||||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||||
if (copyFbo) {
|
if (copyFbo) {
|
||||||
gpu::Vec4i copyFboRect(0, 0, copyFbo->getWidth(), copyFbo->getHeight());
|
gpu::Vec4i copyFboRect(0, 0, copyFbo->getWidth(), copyFbo->getHeight());
|
||||||
gpu::Vec4i sourceRect(scissor.x, scissor.y, scissor.x + scissor.z, scissor.y + scissor.w);
|
gpu::Vec4i sourceRect(scissor.x, scissor.y, scissor.x + scissor.z, scissor.y + scissor.w);
|
||||||
float aspectRatio = (float)scissor.w / (float) scissor.z; // height/width
|
float aspectRatio = (float)scissor.w / (float)scissor.z; // height/width
|
||||||
// scale width first
|
// scale width first
|
||||||
int xOffset = 0;
|
int xOffset = 0;
|
||||||
int yOffset = 0;
|
int yOffset = 0;
|
||||||
int newWidth = copyFbo->getWidth();
|
int newWidth = copyFbo->getWidth();
|
||||||
int newHeight = std::round(aspectRatio * (float) copyFbo->getWidth());
|
int newHeight = std::round(aspectRatio * (float)copyFbo->getWidth());
|
||||||
if (newHeight > copyFbo->getHeight()) {
|
if (newHeight > copyFbo->getHeight()) {
|
||||||
// ok, so now fill height instead
|
// ok, so now fill height instead
|
||||||
newHeight = copyFbo->getHeight();
|
newHeight = copyFbo->getHeight();
|
||||||
|
@ -554,7 +537,7 @@ void OpenGLDisplayPlugin::renderFromTexture(gpu::Batch& batch, const gpu::Textur
|
||||||
batch.resetViewTransform();
|
batch.resetViewTransform();
|
||||||
batch.setViewportTransform(copyFboRect);
|
batch.setViewportTransform(copyFboRect);
|
||||||
batch.setStateScissorRect(copyFboRect);
|
batch.setStateScissorRect(copyFboRect);
|
||||||
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, {0.0f, 0.0f, 0.0f, 1.0f});
|
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, { 0.0f, 0.0f, 0.0f, 1.0f });
|
||||||
batch.blit(fbo, sourceRect, copyFbo, copyRect);
|
batch.blit(fbo, sourceRect, copyFbo, copyRect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -589,14 +572,11 @@ std::function<void(gpu::Batch&, const gpu::TexturePointer&, bool mirror)> OpenGL
|
||||||
auto hudStereo = isStereo();
|
auto hudStereo = isStereo();
|
||||||
auto hudCompositeFramebufferSize = _compositeFramebuffer->getSize();
|
auto hudCompositeFramebufferSize = _compositeFramebuffer->getSize();
|
||||||
std::array<glm::ivec4, 2> hudEyeViewports;
|
std::array<glm::ivec4, 2> hudEyeViewports;
|
||||||
for_each_eye([&](Eye eye) {
|
for_each_eye([&](Eye eye) { hudEyeViewports[eye] = eyeViewport(eye); });
|
||||||
hudEyeViewports[eye] = eyeViewport(eye);
|
|
||||||
});
|
|
||||||
return [=](gpu::Batch& batch, const gpu::TexturePointer& hudTexture, bool mirror) {
|
return [=](gpu::Batch& batch, const gpu::TexturePointer& hudTexture, bool mirror) {
|
||||||
auto pipeline = mirror ? hudMirrorPipeline : hudPipeline;
|
if (hudPipeline && hudTexture) {
|
||||||
if (pipeline && hudTexture) {
|
|
||||||
batch.enableStereo(false);
|
batch.enableStereo(false);
|
||||||
batch.setPipeline(pipeline);
|
batch.setPipeline(mirror ? hudMirrorPipeline : hudPipeline);
|
||||||
batch.setResourceTexture(0, hudTexture);
|
batch.setResourceTexture(0, hudTexture);
|
||||||
if (hudStereo) {
|
if (hudStereo) {
|
||||||
for_each_eye([&](Eye eye) {
|
for_each_eye([&](Eye eye) {
|
||||||
|
@ -635,11 +615,6 @@ void OpenGLDisplayPlugin::compositePointer() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overridden by Basic2DWindowDisplayPlugin and OculusDisplayPlugin
|
|
||||||
gpu::PipelinePointer OpenGLDisplayPlugin::getCompositeScenePipeline() {
|
|
||||||
return _drawTexturePipeline;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OpenGLDisplayPlugin::compositeScene() {
|
void OpenGLDisplayPlugin::compositeScene() {
|
||||||
render([&](gpu::Batch& batch) {
|
render([&](gpu::Batch& batch) {
|
||||||
batch.enableStereo(false);
|
batch.enableStereo(false);
|
||||||
|
@ -682,9 +657,10 @@ void OpenGLDisplayPlugin::internalPresent() {
|
||||||
render([&](gpu::Batch& batch) {
|
render([&](gpu::Batch& batch) {
|
||||||
// Note: _displayTexture must currently be the same size as the display.
|
// Note: _displayTexture must currently be the same size as the display.
|
||||||
uvec2 dims = _displayTexture ? uvec2(_displayTexture->getDimensions()) : getSurfacePixels();
|
uvec2 dims = _displayTexture ? uvec2(_displayTexture->getDimensions()) : getSurfacePixels();
|
||||||
auto viewport = ivec4(uvec2(0), dims);
|
auto viewport = ivec4(uvec2(0), dims);
|
||||||
renderFromTexture(batch, _displayTexture ? _displayTexture : _compositeFramebuffer->getRenderBuffer(0), viewport, viewport);
|
renderFromTexture(batch, _displayTexture ? _displayTexture : _compositeFramebuffer->getRenderBuffer(0), viewport,
|
||||||
});
|
viewport);
|
||||||
|
});
|
||||||
swapBuffers();
|
swapBuffers();
|
||||||
_presentRate.increment();
|
_presentRate.increment();
|
||||||
}
|
}
|
||||||
|
@ -723,7 +699,7 @@ void OpenGLDisplayPlugin::present(const std::shared_ptr<RefreshRateController>&
|
||||||
compositeLayers();
|
compositeLayers();
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // If we have any snapshots this frame, handle them
|
{ // If we have any snapshots this frame, handle them
|
||||||
PROFILE_RANGE_EX(render, "snapshotOperators", 0xffff00ff, frameId)
|
PROFILE_RANGE_EX(render, "snapshotOperators", 0xffff00ff, frameId)
|
||||||
while (!_currentFrame->snapshotOperators.empty()) {
|
while (!_currentFrame->snapshotOperators.empty()) {
|
||||||
auto& snapshotOperator = _currentFrame->snapshotOperators.front();
|
auto& snapshotOperator = _currentFrame->snapshotOperators.front();
|
||||||
|
@ -765,7 +741,7 @@ float OpenGLDisplayPlugin::presentRate() const {
|
||||||
return _presentRate.rate();
|
return _presentRate.rate();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::function<void(int)> OpenGLDisplayPlugin::getRefreshRateOperator() {
|
std::function<void(int)> OpenGLDisplayPlugin::getRefreshRateOperator() {
|
||||||
return [](int targetRefreshRate) {
|
return [](int targetRefreshRate) {
|
||||||
auto refreshRateController = DependencyManager::get<PresentThread>()->getRefreshRateController();
|
auto refreshRateController = DependencyManager::get<PresentThread>()->getRefreshRateController();
|
||||||
refreshRateController->setRefreshRateLimitPeriod(targetRefreshRate);
|
refreshRateController->setRefreshRateLimitPeriod(targetRefreshRate);
|
||||||
|
@ -781,7 +757,6 @@ float OpenGLDisplayPlugin::renderRate() const {
|
||||||
return _renderRate.rate();
|
return _renderRate.rate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void OpenGLDisplayPlugin::swapBuffers() {
|
void OpenGLDisplayPlugin::swapBuffers() {
|
||||||
static auto context = _container->getPrimaryWidget()->context();
|
static auto context = _container->getPrimaryWidget()->context();
|
||||||
context->swapBuffers();
|
context->swapBuffers();
|
||||||
|
@ -818,7 +793,7 @@ QImage OpenGLDisplayPlugin::getScreenshot(float aspectRatio) {
|
||||||
}
|
}
|
||||||
auto bestSize = size;
|
auto bestSize = size;
|
||||||
uvec2 corner(0);
|
uvec2 corner(0);
|
||||||
if (aspectRatio != 0.0f) { // Pick out the largest piece of the center that produces the requested width/height aspectRatio
|
if (aspectRatio != 0.0f) { // Pick out the largest piece of the center that produces the requested width/height aspectRatio
|
||||||
if (ceil(size.y * aspectRatio) < size.x) {
|
if (ceil(size.y * aspectRatio) < size.x) {
|
||||||
bestSize.x = round(size.y * aspectRatio);
|
bestSize.x = round(size.y * aspectRatio);
|
||||||
} else {
|
} else {
|
||||||
|
@ -869,9 +844,7 @@ void OpenGLDisplayPlugin::assertIsPresentThread() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenGLDisplayPlugin::beginFrameRender(uint32_t frameIndex) {
|
bool OpenGLDisplayPlugin::beginFrameRender(uint32_t frameIndex) {
|
||||||
withNonPresentThreadLock([&] {
|
withNonPresentThreadLock([&] { _compositeHUDAlpha = _hudAlpha; });
|
||||||
_compositeHUDAlpha = _hudAlpha;
|
|
||||||
});
|
|
||||||
return Parent::beginFrameRender(frameIndex);
|
return Parent::beginFrameRender(frameIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -909,27 +882,25 @@ void OpenGLDisplayPlugin::render(std::function<void(gpu::Batch& batch)> f) {
|
||||||
OpenGLDisplayPlugin::~OpenGLDisplayPlugin() {
|
OpenGLDisplayPlugin::~OpenGLDisplayPlugin() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Added this to allow desktop composite framebuffer to be RGBA while mobile is SRGBA
|
|
||||||
// Overridden by Basic2DWindowDisplayPlugin
|
|
||||||
// FIXME: Eventually it would be ideal to have both framebuffers be of the same type
|
|
||||||
gpu::Element OpenGLDisplayPlugin::getCompositeFBColorSpace() {
|
|
||||||
return gpu::Element::COLOR_RGBA_32;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OpenGLDisplayPlugin::updateCompositeFramebuffer() {
|
void OpenGLDisplayPlugin::updateCompositeFramebuffer() {
|
||||||
auto renderSize = glm::uvec2(getRecommendedRenderSize());
|
auto renderSize = glm::uvec2(getRecommendedRenderSize());
|
||||||
if (!_compositeFramebuffer || _compositeFramebuffer->getSize() != renderSize) {
|
if (!_compositeFramebuffer || _compositeFramebuffer->getSize() != renderSize) {
|
||||||
_compositeFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("OpenGLDisplayPlugin::composite", getCompositeFBColorSpace(), renderSize.x, renderSize.y));
|
_compositeFramebuffer =
|
||||||
|
gpu::FramebufferPointer(gpu::Framebuffer::create("OpenGLDisplayPlugin::composite", gpu::Element::COLOR_RGBA_32,
|
||||||
|
renderSize.x, renderSize.y));
|
||||||
|
// _compositeFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("OpenGLDisplayPlugin::composite", gpu::Element::COLOR_SRGBA_32, renderSize.x, renderSize.y));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLDisplayPlugin::copyTextureToQuickFramebuffer(NetworkTexturePointer networkTexture, QOpenGLFramebufferObject* target, GLsync* fenceSync) {
|
void OpenGLDisplayPlugin::copyTextureToQuickFramebuffer(NetworkTexturePointer networkTexture,
|
||||||
|
QOpenGLFramebufferObject* target,
|
||||||
|
GLsync* fenceSync) {
|
||||||
#if !defined(USE_GLES)
|
#if !defined(USE_GLES)
|
||||||
auto glBackend = const_cast<OpenGLDisplayPlugin&>(*this).getGLBackend();
|
auto glBackend = const_cast<OpenGLDisplayPlugin&>(*this).getGLBackend();
|
||||||
withOtherThreadContext([&] {
|
withOtherThreadContext([&] {
|
||||||
GLuint sourceTexture = glBackend->getTextureID(networkTexture->getGPUTexture());
|
GLuint sourceTexture = glBackend->getTextureID(networkTexture->getGPUTexture());
|
||||||
GLuint targetTexture = target->texture();
|
GLuint targetTexture = target->texture();
|
||||||
GLuint fbo[2] {0, 0};
|
GLuint fbo[2]{ 0, 0 };
|
||||||
|
|
||||||
// need mipmaps for blitting texture
|
// need mipmaps for blitting texture
|
||||||
glGenerateTextureMipmap(sourceTexture);
|
glGenerateTextureMipmap(sourceTexture);
|
||||||
|
@ -950,14 +921,13 @@ void OpenGLDisplayPlugin::copyTextureToQuickFramebuffer(NetworkTexturePointer ne
|
||||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
|
||||||
// maintain aspect ratio, filling the width first if possible. If that makes the height too
|
// maintain aspect ratio, filling the width first if possible. If that makes the height too
|
||||||
// much, fill height instead. TODO: only do this when texture changes
|
// much, fill height instead. TODO: only do this when texture changes
|
||||||
GLint newX = 0;
|
GLint newX = 0;
|
||||||
GLint newY = 0;
|
GLint newY = 0;
|
||||||
float aspectRatio = (float)texHeight / (float)texWidth;
|
float aspectRatio = (float)texHeight / (float)texWidth;
|
||||||
GLint newWidth = target->width();
|
GLint newWidth = target->width();
|
||||||
GLint newHeight = std::round(aspectRatio * (float) target->width());
|
GLint newHeight = std::round(aspectRatio * (float)target->width());
|
||||||
if (newHeight > target->height()) {
|
if (newHeight > target->height()) {
|
||||||
newHeight = target->height();
|
newHeight = target->height();
|
||||||
newWidth = std::round((float)target->height() / aspectRatio);
|
newWidth = std::round((float)target->height() / aspectRatio);
|
||||||
|
@ -966,7 +936,8 @@ void OpenGLDisplayPlugin::copyTextureToQuickFramebuffer(NetworkTexturePointer ne
|
||||||
newY = (target->height() - newHeight) / 2;
|
newY = (target->height() - newHeight) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
glBlitNamedFramebuffer(fbo[0], fbo[1], 0, 0, texWidth, texHeight, newX, newY, newX + newWidth, newY + newHeight, GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
glBlitNamedFramebuffer(fbo[0], fbo[1], 0, 0, texWidth, texHeight, newX, newY, newX + newWidth, newY + newHeight,
|
||||||
|
GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||||
|
|
||||||
// don't delete the textures!
|
// don't delete the textures!
|
||||||
glDeleteFramebuffers(2, fbo);
|
glDeleteFramebuffers(2, fbo);
|
||||||
|
@ -975,3 +946,14 @@ void OpenGLDisplayPlugin::copyTextureToQuickFramebuffer(NetworkTexturePointer ne
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gpu::PipelinePointer OpenGLDisplayPlugin::getRenderTexturePipeline() {
|
||||||
|
return _drawTexturePipeline;
|
||||||
|
}
|
||||||
|
|
||||||
|
gpu::PipelinePointer OpenGLDisplayPlugin::getCompositeScenePipeline() {
|
||||||
|
return _drawTexturePipeline;
|
||||||
|
}
|
||||||
|
|
||||||
|
gpu::Element OpenGLDisplayPlugin::getCompositeFBColorSpace() {
|
||||||
|
return gpu::Element::COLOR_RGBA_32;
|
||||||
|
}
|
||||||
|
|
|
@ -23,11 +23,9 @@
|
||||||
|
|
||||||
#include <gpu/Batch.h>
|
#include <gpu/Batch.h>
|
||||||
|
|
||||||
namespace gpu {
|
namespace gpu { namespace gl {
|
||||||
namespace gl {
|
class GLBackend;
|
||||||
class GLBackend;
|
}} // namespace gpu::gl
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class RefreshRateController;
|
class RefreshRateController;
|
||||||
|
|
||||||
|
@ -35,10 +33,12 @@ class OpenGLDisplayPlugin : public DisplayPlugin {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(float hudAlpha MEMBER _hudAlpha)
|
Q_PROPERTY(float hudAlpha MEMBER _hudAlpha)
|
||||||
using Parent = DisplayPlugin;
|
using Parent = DisplayPlugin;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
using Mutex = std::mutex;
|
using Mutex = std::mutex;
|
||||||
using Lock = std::unique_lock<Mutex>;
|
using Lock = std::unique_lock<Mutex>;
|
||||||
using Condition = std::condition_variable;
|
using Condition = std::condition_variable;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~OpenGLDisplayPlugin();
|
~OpenGLDisplayPlugin();
|
||||||
// These must be final to ensure proper ordering of operations
|
// These must be final to ensure proper ordering of operations
|
||||||
|
@ -55,13 +55,9 @@ public:
|
||||||
void captureFrame(const std::string& outputName) const override;
|
void captureFrame(const std::string& outputName) const override;
|
||||||
void submitFrame(const gpu::FramePointer& newFrame) override;
|
void submitFrame(const gpu::FramePointer& newFrame) override;
|
||||||
|
|
||||||
glm::uvec2 getRecommendedRenderSize() const override {
|
glm::uvec2 getRecommendedRenderSize() const override { return getSurfacePixels(); }
|
||||||
return getSurfacePixels();
|
|
||||||
}
|
|
||||||
|
|
||||||
glm::uvec2 getRecommendedUiSize() const override {
|
glm::uvec2 getRecommendedUiSize() const override { return getSurfaceSize(); }
|
||||||
return getSurfaceSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool setDisplayTexture(const QString& name) override;
|
virtual bool setDisplayTexture(const QString& name) override;
|
||||||
virtual bool onDisplayTextureReset() { return false; };
|
virtual bool onDisplayTextureReset() { return false; };
|
||||||
|
@ -84,9 +80,9 @@ public:
|
||||||
// Three threads, one for rendering, one for texture transfers, one reserved for the GL driver
|
// Three threads, one for rendering, one for texture transfers, one reserved for the GL driver
|
||||||
int getRequiredThreadCount() const override { return 3; }
|
int getRequiredThreadCount() const override { return 3; }
|
||||||
|
|
||||||
void copyTextureToQuickFramebuffer(NetworkTexturePointer source, QOpenGLFramebufferObject* target, GLsync* fenceSync) override;
|
void copyTextureToQuickFramebuffer(NetworkTexturePointer source,
|
||||||
|
QOpenGLFramebufferObject* target,
|
||||||
virtual std::function<void(gpu::Batch&, const gpu::TexturePointer&, bool mirror)> getHUDOperator() override;
|
GLsync* fenceSync) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class PresentThread;
|
friend class PresentThread;
|
||||||
|
@ -104,11 +100,9 @@ protected:
|
||||||
virtual QThread::Priority getPresentPriority() { return QThread::HighPriority; }
|
virtual QThread::Priority getPresentPriority() { return QThread::HighPriority; }
|
||||||
virtual void compositeLayers();
|
virtual void compositeLayers();
|
||||||
virtual void compositeScene();
|
virtual void compositeScene();
|
||||||
|
virtual std::function<void(gpu::Batch&, const gpu::TexturePointer&, bool mirror)> getHUDOperator();
|
||||||
virtual void compositePointer();
|
virtual void compositePointer();
|
||||||
virtual void compositeExtra() {};
|
virtual void compositeExtra(){};
|
||||||
|
|
||||||
virtual gpu::PipelinePointer getCompositeScenePipeline();
|
|
||||||
virtual gpu::Element getCompositeFBColorSpace();
|
|
||||||
|
|
||||||
// These functions must only be called on the presentation thread
|
// These functions must only be called on the presentation thread
|
||||||
virtual void customizeContext();
|
virtual void customizeContext();
|
||||||
|
@ -125,8 +119,15 @@ protected:
|
||||||
// Plugin specific functionality to send the composed scene to the output window or device
|
// Plugin specific functionality to send the composed scene to the output window or device
|
||||||
virtual void internalPresent();
|
virtual void internalPresent();
|
||||||
|
|
||||||
void renderFromTexture(gpu::Batch& batch, const gpu::TexturePointer& texture, const glm::ivec4& viewport, const glm::ivec4& scissor, const gpu::FramebufferPointer& fbo);
|
void renderFromTexture(gpu::Batch& batch,
|
||||||
void renderFromTexture(gpu::Batch& batch, const gpu::TexturePointer& texture, const glm::ivec4& viewport, const glm::ivec4& scissor);
|
const gpu::TexturePointer& texture,
|
||||||
|
const glm::ivec4& viewport,
|
||||||
|
const glm::ivec4& scissor,
|
||||||
|
const gpu::FramebufferPointer& fbo);
|
||||||
|
void renderFromTexture(gpu::Batch& batch,
|
||||||
|
const gpu::TexturePointer& texture,
|
||||||
|
const glm::ivec4& viewport,
|
||||||
|
const glm::ivec4& scissor);
|
||||||
virtual void updateFrameData();
|
virtual void updateFrameData();
|
||||||
virtual glm::mat4 getViewCorrection() { return glm::mat4(); }
|
virtual glm::mat4 getViewCorrection() { return glm::mat4(); }
|
||||||
|
|
||||||
|
@ -138,7 +139,7 @@ protected:
|
||||||
|
|
||||||
void render(std::function<void(gpu::Batch& batch)> f);
|
void render(std::function<void(gpu::Batch& batch)> f);
|
||||||
|
|
||||||
bool _vsyncEnabled { true };
|
bool _vsyncEnabled{ true };
|
||||||
QThread* _presentThread{ nullptr };
|
QThread* _presentThread{ nullptr };
|
||||||
std::queue<gpu::FramePointer> _newFrameQueue;
|
std::queue<gpu::FramePointer> _newFrameQueue;
|
||||||
RateCounter<200> _droppedFrameRate;
|
RateCounter<200> _droppedFrameRate;
|
||||||
|
@ -147,7 +148,7 @@ protected:
|
||||||
RateCounter<200> _renderRate;
|
RateCounter<200> _renderRate;
|
||||||
|
|
||||||
gpu::FramePointer _currentFrame;
|
gpu::FramePointer _currentFrame;
|
||||||
gpu::Frame* _lastFrame { nullptr };
|
gpu::Frame* _lastFrame{ nullptr };
|
||||||
mat4 _prevRenderView;
|
mat4 _prevRenderView;
|
||||||
gpu::FramebufferPointer _compositeFramebuffer;
|
gpu::FramebufferPointer _compositeFramebuffer;
|
||||||
gpu::PipelinePointer _hudPipeline;
|
gpu::PipelinePointer _hudPipeline;
|
||||||
|
@ -157,9 +158,12 @@ protected:
|
||||||
gpu::PipelinePointer _linearToSRGBPipeline;
|
gpu::PipelinePointer _linearToSRGBPipeline;
|
||||||
gpu::PipelinePointer _SRGBToLinearPipeline;
|
gpu::PipelinePointer _SRGBToLinearPipeline;
|
||||||
gpu::PipelinePointer _cursorPipeline;
|
gpu::PipelinePointer _cursorPipeline;
|
||||||
|
|
||||||
gpu::TexturePointer _displayTexture{};
|
gpu::TexturePointer _displayTexture{};
|
||||||
float _compositeHUDAlpha { 1.0f };
|
float _compositeHUDAlpha{ 1.0f };
|
||||||
|
|
||||||
|
virtual gpu::PipelinePointer getRenderTexturePipeline();
|
||||||
|
virtual gpu::PipelinePointer getCompositeScenePipeline();
|
||||||
|
virtual gpu::Element getCompositeFBColorSpace();
|
||||||
|
|
||||||
struct CursorData {
|
struct CursorData {
|
||||||
QImage image;
|
QImage image;
|
||||||
|
@ -169,19 +173,19 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
std::map<uint16_t, CursorData> _cursorsData;
|
std::map<uint16_t, CursorData> _cursorsData;
|
||||||
bool _lockCurrentTexture { false };
|
bool _lockCurrentTexture{ false };
|
||||||
|
|
||||||
void assertNotPresentThread() const;
|
void assertNotPresentThread() const;
|
||||||
void assertIsPresentThread() const;
|
void assertIsPresentThread() const;
|
||||||
|
|
||||||
template<typename F>
|
template <typename F>
|
||||||
void withPresentThreadLock(F f) const {
|
void withPresentThreadLock(F f) const {
|
||||||
assertIsPresentThread();
|
assertIsPresentThread();
|
||||||
Lock lock(_presentMutex);
|
Lock lock(_presentMutex);
|
||||||
f();
|
f();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename F>
|
template <typename F>
|
||||||
void withNonPresentThreadLock(F f) const {
|
void withNonPresentThreadLock(F f) const {
|
||||||
assertNotPresentThread();
|
assertNotPresentThread();
|
||||||
Lock lock(_presentMutex);
|
Lock lock(_presentMutex);
|
||||||
|
@ -198,4 +202,3 @@ protected:
|
||||||
QImage getScreenshot(float aspectRatio);
|
QImage getScreenshot(float aspectRatio);
|
||||||
QImage getSecondaryCameraScreenshot();
|
QImage getSecondaryCameraScreenshot();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -167,6 +167,7 @@ void OculusDisplayPlugin::hmdPresent() {
|
||||||
batch.setStateScissorRect(ivec4(uvec2(), _outputFramebuffer->getSize()));
|
batch.setStateScissorRect(ivec4(uvec2(), _outputFramebuffer->getSize()));
|
||||||
batch.resetViewTransform();
|
batch.resetViewTransform();
|
||||||
batch.setProjectionTransform(mat4());
|
batch.setProjectionTransform(mat4());
|
||||||
|
//batch.setPipeline(_drawTexturePipeline);
|
||||||
batch.setPipeline(_drawTexturePipeline);
|
batch.setPipeline(_drawTexturePipeline);
|
||||||
batch.setResourceTexture(0, _compositeFramebuffer->getRenderBuffer(0));
|
batch.setResourceTexture(0, _compositeFramebuffer->getRenderBuffer(0));
|
||||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||||
|
|
|
@ -24,6 +24,8 @@ public:
|
||||||
|
|
||||||
virtual QJsonObject getHardwareStats() const;
|
virtual QJsonObject getHardwareStats() const;
|
||||||
|
|
||||||
|
virtual gpu::PipelinePointer getCompositeScenePipeline() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QThread::Priority getPresentPriority() override { return QThread::TimeCriticalPriority; }
|
QThread::Priority getPresentPriority() override { return QThread::TimeCriticalPriority; }
|
||||||
|
|
||||||
|
@ -34,8 +36,6 @@ protected:
|
||||||
void uncustomizeContext() override;
|
void uncustomizeContext() override;
|
||||||
void cycleDebugOutput() override;
|
void cycleDebugOutput() override;
|
||||||
|
|
||||||
virtual gpu::PipelinePointer getCompositeScenePipeline() override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const char* NAME;
|
static const char* NAME;
|
||||||
ovrTextureSwapChain _textureSwapChain;
|
ovrTextureSwapChain _textureSwapChain;
|
||||||
|
|
Loading…
Reference in a new issue