mirror of
https://github.com/lubosz/overte.git
synced 2025-04-15 23:41:43 +02:00
works, sorta, but blinks like crazy, cursor gets f-ed up...
This commit is contained in:
parent
54dfc33b38
commit
3d922f5db6
6 changed files with 116 additions and 19 deletions
|
@ -190,6 +190,7 @@ Rectangle {
|
|||
boxSize: 24;
|
||||
onClicked: {
|
||||
sendToScript({method: (checked ? 'spectatorCameraOn' : 'spectatorCameraOff')});
|
||||
spectatorCameraPreviewItem.ready = checked;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -202,7 +203,10 @@ Rectangle {
|
|||
anchors.topMargin: 20;
|
||||
anchors.right: parent.right;
|
||||
Hifi.ResourceImageItem {
|
||||
id: spectatorCameraPreviewItem;
|
||||
anchors.fill: parent;
|
||||
url: "resource://spectatorCameraFrame";
|
||||
ready: false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,11 +8,55 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "Application.h"
|
||||
#include "ResourceImageItem.h"
|
||||
#include <QOpenGLFramebufferObjectFormat>
|
||||
#include <DependencyManager.h>
|
||||
#include <TextureCache.h>
|
||||
|
||||
|
||||
ResourceImageItem::ResourceImageItem(QQuickItem* parent) : QQuickFramebufferObject(parent) {
|
||||
connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(update()));
|
||||
}
|
||||
|
||||
void ResourceImageItem::setUrl(const QString& url) {
|
||||
if (url != m_url) {
|
||||
m_url = url;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void ResourceImageItem::setReady(bool ready) {
|
||||
if (ready != m_ready) {
|
||||
m_ready = ready;
|
||||
if (m_ready) {
|
||||
m_updateTimer.start(1000);
|
||||
} else {
|
||||
m_updateTimer.stop();
|
||||
}
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void ResourceImageItemRenderer::synchronize(QQuickFramebufferObject* item) {
|
||||
ResourceImageItem* resourceImageItem = static_cast<ResourceImageItem*>(item);
|
||||
bool urlChanged = false;
|
||||
if( _url != resourceImageItem->getUrl()) {
|
||||
_url = resourceImageItem->getUrl();
|
||||
urlChanged = true;
|
||||
}
|
||||
bool readyChanged = false;
|
||||
if (_ready != resourceImageItem->getReady()) {
|
||||
_ready = resourceImageItem->getReady();
|
||||
readyChanged = true;
|
||||
}
|
||||
_window = resourceImageItem->window();
|
||||
qDebug() << "synchronize called!!!!!!!";
|
||||
if (_ready && !_url.isNull() && !_url.isEmpty() && (readyChanged || urlChanged)) {
|
||||
_networkTexture = DependencyManager::get<TextureCache>()->getTexture(_url);
|
||||
}
|
||||
}
|
||||
|
||||
QOpenGLFramebufferObject* ResourceImageItemRenderer::createFramebufferObject(const QSize& size) {
|
||||
QOpenGLFramebufferObjectFormat format;
|
||||
format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
|
||||
|
@ -20,9 +64,12 @@ QOpenGLFramebufferObject* ResourceImageItemRenderer::createFramebufferObject(con
|
|||
}
|
||||
|
||||
void ResourceImageItemRenderer::render() {
|
||||
auto texture = DependencyManager::get<TextureCache>()->getTexture(QUrl("resource://spectatorCameraFrame"));
|
||||
if (texture) {
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture->getGPUTexture(), 0);
|
||||
qDebug() << "render called!!!!!!!!!!!!!!";
|
||||
if (_networkTexture && _ready) {
|
||||
auto texture = _networkTexture->getGPUTexture();
|
||||
if (texture) {
|
||||
qApp->getActiveDisplayPlugin()->copyTextureToQuickFramebuffer(texture, framebufferObject());
|
||||
_window->resetOpenGLState();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -13,15 +13,37 @@
|
|||
#define hifi_ResourceImageItem_h
|
||||
|
||||
#include <QQuickFramebufferObject>
|
||||
#include <QOpenGLFunctions>
|
||||
#include <QQuickWindow>
|
||||
#include <QTimer>
|
||||
|
||||
class ResourceImageItemRenderer : public QQuickFramebufferObject::Renderer, protected QOpenGLFunctions {
|
||||
class ResourceImageItemRenderer : public QQuickFramebufferObject::Renderer {
|
||||
public:
|
||||
QOpenGLFramebufferObject* createFramebufferObject(const QSize& size);
|
||||
void synchronize(QQuickFramebufferObject* item);
|
||||
void render();
|
||||
private:
|
||||
bool _ready;
|
||||
QString _url;
|
||||
NetworkTexturePointer _networkTexture;
|
||||
QQuickWindow* _window;
|
||||
};
|
||||
|
||||
class ResourceImageItem : public QQuickFramebufferObject {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QString url READ getUrl WRITE setUrl)
|
||||
Q_PROPERTY(bool ready READ getReady WRITE setReady)
|
||||
|
||||
public:
|
||||
ResourceImageItem(QQuickItem* parent = Q_NULLPTR);
|
||||
QString getUrl() const { return m_url; }
|
||||
void setUrl(const QString& url);
|
||||
bool getReady() const { return m_ready; }
|
||||
void setReady(bool ready);
|
||||
QQuickFramebufferObject::Renderer* createRenderer() const { return new ResourceImageItemRenderer; }
|
||||
private:
|
||||
QString m_url;
|
||||
bool m_ready { false };
|
||||
QTimer m_updateTimer; // TODO: something more clever
|
||||
};
|
||||
|
||||
#endif // hifi_ResourceImageItem_h
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include <QtOpenGL/QGLWidget>
|
||||
#include <QtGui/QImage>
|
||||
#include <QOpenGLFramebufferObject>
|
||||
#if defined(Q_OS_MAC)
|
||||
#include <OpenGL/CGLCurrent.h>
|
||||
#endif
|
||||
|
@ -55,7 +56,7 @@ out vec4 outFragColor;
|
|||
|
||||
float sRGBFloatToLinear(float value) {
|
||||
const float SRGB_ELBOW = 0.04045;
|
||||
|
||||
|
||||
return (value <= SRGB_ELBOW) ? value / 12.92 : pow((value + 0.055) / 1.055, 2.4);
|
||||
}
|
||||
|
||||
|
@ -121,10 +122,10 @@ public:
|
|||
PROFILE_SET_THREAD_NAME("Present Thread");
|
||||
|
||||
// FIXME determine the best priority balance between this and the main thread...
|
||||
// It may be dependent on the display plugin being used, since VR plugins should
|
||||
// It may be dependent on the display plugin being used, since VR plugins should
|
||||
// have higher priority on rendering (although we could say that the Oculus plugin
|
||||
// doesn't need that since it has async timewarp).
|
||||
// A higher priority here
|
||||
// A higher priority here
|
||||
setPriority(QThread::HighPriority);
|
||||
OpenGLDisplayPlugin* currentPlugin{ nullptr };
|
||||
Q_ASSERT(_context);
|
||||
|
@ -233,7 +234,7 @@ public:
|
|||
// Move the context back to the presentation thread
|
||||
_context->moveToThread(this);
|
||||
|
||||
// restore control of the context to the presentation thread and signal
|
||||
// restore control of the context to the presentation thread and signal
|
||||
// the end of the operation
|
||||
_finishedMainThreadOperation = true;
|
||||
lock.unlock();
|
||||
|
@ -291,7 +292,7 @@ bool OpenGLDisplayPlugin::activate() {
|
|||
if (!RENDER_THREAD) {
|
||||
RENDER_THREAD = _presentThread;
|
||||
}
|
||||
|
||||
|
||||
// Child classes may override this in order to do things like initialize
|
||||
// libraries, etc
|
||||
if (!internalActivate()) {
|
||||
|
@ -411,7 +412,7 @@ void OpenGLDisplayPlugin::customizeContext() {
|
|||
gpu::Shader::makeProgram(*program);
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
state->setDepthTest(gpu::State::DepthTest(false));
|
||||
state->setBlendFunction(true,
|
||||
state->setBlendFunction(true,
|
||||
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
||||
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
||||
_overlayPipeline = gpu::Pipeline::create(program, state);
|
||||
|
@ -686,7 +687,7 @@ void OpenGLDisplayPlugin::resetPresentRate() {
|
|||
// _presentRate = RateCounter<100>();
|
||||
}
|
||||
|
||||
float OpenGLDisplayPlugin::renderRate() const {
|
||||
float OpenGLDisplayPlugin::renderRate() const {
|
||||
return _renderRate.rate();
|
||||
}
|
||||
|
||||
|
@ -820,3 +821,20 @@ void OpenGLDisplayPlugin::updateCompositeFramebuffer() {
|
|||
_compositeFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("OpenGLDisplayPlugin::composite", gpu::Element::COLOR_RGBA_32, renderSize.x, renderSize.y));
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGLDisplayPlugin::copyTextureToQuickFramebuffer(gpu::TexturePointer source, QOpenGLFramebufferObject* target) {
|
||||
auto glBackend = const_cast<OpenGLDisplayPlugin&>(*this).getGLBackend();
|
||||
withMainThreadContext([&] {
|
||||
GLuint sourceTexture = glBackend->getTextureID(source);
|
||||
GLuint targetTexture = target->texture();
|
||||
GLuint fbo { 0 };
|
||||
glCreateFramebuffers(1, &fbo);
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
|
||||
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, sourceTexture, 0);
|
||||
glCopyTextureSubImage2D(targetTexture, 0, 0, 0, 0, 0, target->width(), target->height());
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||
glDeleteFramebuffers(1, &fbo);
|
||||
glDeleteTextures(1, &fbo);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ protected:
|
|||
using Condition = std::condition_variable;
|
||||
public:
|
||||
~OpenGLDisplayPlugin();
|
||||
// These must be final to ensure proper ordering of operations
|
||||
// These must be final to ensure proper ordering of operations
|
||||
// between the main thread and the presentation thread
|
||||
bool activate() override final;
|
||||
void deactivate() override final;
|
||||
|
@ -78,6 +78,8 @@ public:
|
|||
// Three threads, one for rendering, one for texture transfers, one reserved for the GL driver
|
||||
int getRequiredThreadCount() const override { return 3; }
|
||||
|
||||
void copyTextureToQuickFramebuffer(gpu::TexturePointer source, QOpenGLFramebufferObject* target);
|
||||
|
||||
protected:
|
||||
friend class PresentThread;
|
||||
|
||||
|
@ -102,7 +104,7 @@ protected:
|
|||
// Returns true on successful activation
|
||||
virtual bool internalActivate() { return true; }
|
||||
virtual void internalDeactivate() {}
|
||||
|
||||
|
||||
// Returns true on successful activation of standby session
|
||||
virtual bool activateStandBySession() { return true; }
|
||||
virtual void deactivateSession() {}
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
|
||||
#include "Plugin.h"
|
||||
|
||||
class QOpenGLFramebufferObject;
|
||||
|
||||
class QImage;
|
||||
|
||||
enum Eye {
|
||||
|
@ -61,7 +63,7 @@ namespace gpu {
|
|||
}
|
||||
|
||||
// Stereo display functionality
|
||||
// TODO move out of this file don't derive DisplayPlugin from this. Instead use dynamic casting when
|
||||
// TODO move out of this file don't derive DisplayPlugin from this. Instead use dynamic casting when
|
||||
// displayPlugin->isStereo returns true
|
||||
class StereoDisplay {
|
||||
public:
|
||||
|
@ -78,7 +80,7 @@ public:
|
|||
};
|
||||
|
||||
// HMD display functionality
|
||||
// TODO move out of this file don't derive DisplayPlugin from this. Instead use dynamic casting when
|
||||
// TODO move out of this file don't derive DisplayPlugin from this. Instead use dynamic casting when
|
||||
// displayPlugin->isHmd returns true
|
||||
class HmdDisplay : public StereoDisplay {
|
||||
public:
|
||||
|
@ -142,7 +144,7 @@ public:
|
|||
virtual float getTargetFrameRate() const { return 1.0f; }
|
||||
virtual bool hasAsyncReprojection() const { return false; }
|
||||
|
||||
/// Returns a boolean value indicating whether the display is currently visible
|
||||
/// Returns a boolean value indicating whether the display is currently visible
|
||||
/// to the user. For monitor displays, false might indicate that a screensaver,
|
||||
/// or power-save mode is active. For HMDs it may reflect a sensor indicating
|
||||
/// whether the HMD is being worn
|
||||
|
@ -204,10 +206,12 @@ public:
|
|||
// Rate at which rendered frames are being skipped
|
||||
virtual float droppedFrameRate() const { return -1.0f; }
|
||||
virtual bool getSupportsAutoSwitch() { return false; }
|
||||
|
||||
|
||||
// Hardware specific stats
|
||||
virtual QJsonObject getHardwareStats() const { return QJsonObject(); }
|
||||
|
||||
virtual void copyTextureToQuickFramebuffer(gpu::TexturePointer source, QOpenGLFramebufferObject* target) = 0;
|
||||
|
||||
uint32_t presentCount() const { return _presentedFrameIndex; }
|
||||
// Time since last call to incrementPresentCount (only valid if DEBUG_PAINT_DELAY is defined)
|
||||
int64_t getPaintDelayUsecs() const;
|
||||
|
|
Loading…
Reference in a new issue