Merge pull request #10961 from davidkelly/dk/hmdPreviewFix

hmd preview fix
This commit is contained in:
David Kelly 2017-07-13 10:32:33 -07:00 committed by GitHub
commit 60751f07bd
6 changed files with 45 additions and 26 deletions

View file

@ -16,6 +16,10 @@
#include <QOpenGLExtraFunctions>
#include <QOpenGLContext>
ResourceImageItem::ResourceImageItem() : QQuickFramebufferObject() {
auto textureCache = DependencyManager::get<TextureCache>();
connect(textureCache.data(), SIGNAL(spectatorCameraFramebufferReset()), this, SLOT(update()));
}
void ResourceImageItem::setUrl(const QString& url) {
if (url != m_url) {
@ -50,32 +54,20 @@ void ResourceImageItemRenderer::onUpdateTimer() {
ResourceImageItemRenderer::ResourceImageItemRenderer() : QQuickFramebufferObject::Renderer() {
connect(&_updateTimer, SIGNAL(timeout()), this, SLOT(onUpdateTimer()));
auto textureCache = DependencyManager::get<TextureCache>();
}
void ResourceImageItemRenderer::synchronize(QQuickFramebufferObject* item) {
ResourceImageItem* resourceImageItem = static_cast<ResourceImageItem*>(item);
resourceImageItem->setFlag(QQuickItem::ItemHasContents);
bool urlChanged = false;
if (_url != resourceImageItem->getUrl()) {
_url = resourceImageItem->getUrl();
urlChanged = true;
}
bool readyChanged = false;
if (_ready != resourceImageItem->getReady()) {
_ready = resourceImageItem->getReady();
readyChanged = true;
}
bool visibleChanged = false;
if (_visible != resourceImageItem->isVisible()) {
_visible = resourceImageItem->isVisible();
visibleChanged = true;
}
_url = resourceImageItem->getUrl();
_ready = resourceImageItem->getReady();
_visible = resourceImageItem->isVisible();
_window = resourceImageItem->window();
if (_ready && _visible && !_url.isNull() && !_url.isEmpty() && (visibleChanged || urlChanged || readyChanged || !_networkTexture)) {
_networkTexture = DependencyManager::get<TextureCache>()->getTexture(_url);
}
_networkTexture = DependencyManager::get<TextureCache>()->getTexture(_url);
static const int UPDATE_TIMER_DELAY_IN_MS = 100; // 100 ms = 10 hz for now
if (_ready && _visible && !_updateTimer.isActive()) {
_updateTimer.start(UPDATE_TIMER_DELAY_IN_MS);

View file

@ -47,6 +47,7 @@ class ResourceImageItem : public QQuickFramebufferObject {
Q_PROPERTY(QString url READ getUrl WRITE setUrl)
Q_PROPERTY(bool ready READ getReady WRITE setReady)
public:
ResourceImageItem();
QString getUrl() const { return m_url; }
void setUrl(const QString& url);
bool getReady() const { return m_ready; }

View file

@ -514,13 +514,29 @@ void OpenGLDisplayPlugin::renderFromTexture(gpu::Batch& batch, const gpu::Textur
batch.setPipeline(_presentPipeline);
batch.draw(gpu::TRIANGLE_STRIP, 4);
if (copyFbo) {
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 copyRect(0, 0, copyFbo->getWidth(), copyFbo->getHeight());
float aspectRatio = (float)scissor.w / (float) scissor.z; // height/width
// scale width first
int xOffset = 0;
int yOffset = 0;
int newWidth = copyFbo->getWidth();
int newHeight = std::round(aspectRatio * (float) copyFbo->getWidth());
if (newHeight > copyFbo->getHeight()) {
// ok, so now fill height instead
newHeight = copyFbo->getHeight();
newWidth = std::round((float)copyFbo->getHeight() / aspectRatio);
xOffset = (copyFbo->getWidth() - newWidth) / 2;
} else {
yOffset = (copyFbo->getHeight() - newHeight) / 2;
}
gpu::Vec4i copyRect(xOffset, yOffset, xOffset + newWidth, yOffset + newHeight);
batch.setFramebuffer(copyFbo);
batch.resetViewTransform();
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, vec4(0));
batch.setViewportTransform(copyRect);
batch.setStateScissorRect(copyRect);
batch.setViewportTransform(copyFboRect);
batch.setStateScissorRect(copyFboRect);
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, {0.0f, 0.0f, 0.0f, 1.0f});
batch.blit(fbo, sourceRect, copyFbo, copyRect);
}
}
@ -862,6 +878,8 @@ void OpenGLDisplayPlugin::copyTextureToQuickFramebuffer(NetworkTexturePointer ne
// setup destination fbo
glBindFramebuffer(GL_FRAMEBUFFER, fbo[1]);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, targetTexture, 0);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
// maintain aspect ratio, filling the width first if possible. If that makes the height too
@ -878,7 +896,7 @@ void OpenGLDisplayPlugin::copyTextureToQuickFramebuffer(NetworkTexturePointer ne
} else {
newY = (target->height() - newHeight) / 2;
}
glBlitNamedFramebuffer(fbo[0], fbo[1], 0, 0, texWidth, texHeight, newX, newY, newWidth, 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!
glDeleteFramebuffers(2, fbo);

View file

@ -242,6 +242,9 @@ void HmdDisplayPlugin::internalPresent() {
glm::ivec4 viewport = getViewportForSourceSize(sourceSize);
glm::ivec4 scissor = viewport;
auto fbo = gpu::FramebufferPointer();
render([&](gpu::Batch& batch) {
if (_monoPreview) {
@ -284,10 +287,11 @@ void HmdDisplayPlugin::internalPresent() {
viewport = ivec4(scissorOffset - scaledShiftLeftBy, viewportOffset, viewportSizeX, viewportSizeY);
}
// TODO: only bother getting and passing in the hmdPreviewFramebuffer if the camera is on
fbo = DependencyManager::get<TextureCache>()->getHmdPreviewFramebuffer(windowSize.x, windowSize.y);
viewport.z *= 2;
}
// TODO: only bother getting and passing in the hmdPreviewFramebuffer if the camera is on
auto fbo = DependencyManager::get<TextureCache>()->getHmdPreviewFramebuffer(scissor.z, scissor.w);
renderFromTexture(batch, _compositeFramebuffer->getRenderBuffer(0), viewport, scissor, fbo);
});
swapBuffers();

View file

@ -1002,7 +1002,7 @@ NetworkTexturePointer TextureCache::getResourceTexture(QUrl resourceTextureUrl)
}
const gpu::FramebufferPointer& TextureCache::getHmdPreviewFramebuffer(int width, int height) {
if (!_hmdPreviewFramebuffer) {
if (!_hmdPreviewFramebuffer || _hmdPreviewFramebuffer->getWidth() != width || _hmdPreviewFramebuffer->getHeight() != height) {
_hmdPreviewFramebuffer.reset(gpu::Framebuffer::create("hmdPreview",gpu::Element::COLOR_SRGBA_32, width, height));
}
return _hmdPreviewFramebuffer;
@ -1018,4 +1018,5 @@ const gpu::FramebufferPointer& TextureCache::getSpectatorCameraFramebuffer() {
void TextureCache::resetSpectatorCameraFramebuffer(int width, int height) {
_spectatorCameraFramebuffer.reset(gpu::Framebuffer::create("spectatorCamera", gpu::Element::COLOR_SRGBA_32, width, height));
_spectatorCameraNetworkTexture.reset();
emit spectatorCameraFramebufferReset();
}

View file

@ -172,6 +172,9 @@ public:
void resetSpectatorCameraFramebuffer(int width, int height);
const gpu::FramebufferPointer& getHmdPreviewFramebuffer(int width, int height);
signals:
void spectatorCameraFramebufferReset();
protected:
// Overload ResourceCache::prefetch to allow specifying texture type for loads
Q_INVOKABLE ScriptableResource* prefetch(const QUrl& url, int type, int maxNumPixels = ABSOLUTE_MAX_TEXTURE_NUM_PIXELS);