diff --git a/examples/quick3d/hellocube/main.qml b/examples/quick3d/hellocube/main.qml index a81f97d5c47eec97bea6a2e020c30751c2fabfba..c83a5c5c4422d08bfa76efe43a7ceaad93d3196a 100644 --- a/examples/quick3d/hellocube/main.qml +++ b/examples/quick3d/hellocube/main.qml @@ -8,16 +8,27 @@ Window { width: 640 height: 640 visible: true + color: "black" + + Image { + source: "qt_logo.png" + x: 50 + SequentialAnimation on y { + loops: Animation.Infinite + PropertyAnimation { duration: 3000; to: 400; from: 50 } + } + } DemonView3D { id: layer1 anchors.fill: parent + anchors.margins: 50 camera: camera + renderMode: DemonView3D.Overlay environment: DemonSceneEnvironment { probeBrightness: 1000 - clearColor: "black" - backgroundMode: DemonSceneEnvironment.Color + backgroundMode: DemonSceneEnvironment.Transparent lightProbe: DemonImage { source: "maps/OpenfootageNET_garage-1024.hdr" } @@ -44,12 +55,5 @@ Window { } } - Image { - source: "qt_logo.png" - x: 50 - SequentialAnimation on y { - loops: Animation.Infinite - PropertyAnimation { duration: 3000; to: 400; from: 50 } - } - } + } diff --git a/examples/quick3d/view3d/main.qml b/examples/quick3d/view3d/main.qml index b67b1820188a1633f3ffceb10d67599dde5e23a7..fb8af1f3b579a331e6cd11cbfd52ee244753db68 100644 --- a/examples/quick3d/view3d/main.qml +++ b/examples/quick3d/view3d/main.qml @@ -24,8 +24,6 @@ Window { } } - - DemonCamera { id: camera2 z: -600 @@ -109,7 +107,7 @@ Window { anchors.right: parent.right width: parent.width * 0.5 height: parent.height * 0.5 - color: "grey" + color: "transparent" border.color: "black" Label { @@ -128,6 +126,12 @@ Window { anchors.bottom: parent.bottom; camera: camera1 scene: standAloneScene + renderMode: DemonView3D.Underlay + + environment: DemonSceneEnvironment { + clearColor: "grey" + backgroundMode: DemonSceneEnvironment.Color + } } Row { diff --git a/src/quick3d/qdemonscenerenderer.cpp b/src/quick3d/qdemonscenerenderer.cpp index aff619945e1f60c03c36c405d6079266d7219edb..68ec4213e3194a1f02322e168747f62074e5fbd3 100644 --- a/src/quick3d/qdemonscenerenderer.cpp +++ b/src/quick3d/qdemonscenerenderer.cpp @@ -48,60 +48,13 @@ void SGFramebufferObjectNode::preprocess() render(); } -void SGFramebufferObjectNode::resetOpenGLState() { - QOpenGLContext *ctx = QOpenGLContext::currentContext(); - QOpenGLFunctions *gl = ctx->functions(); - - if (!m_vaoHelper) - m_vaoHelper = new QOpenGLVertexArrayObjectHelper(ctx); - if (m_vaoHelper->isValid()) - m_vaoHelper->glBindVertexArray(0); - - gl->glBindBuffer(GL_ARRAY_BUFFER, 0); - gl->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - - if (ctx->isOpenGLES() || (gl->openGLFeatures() & QOpenGLFunctions::FixedFunctionPipeline)) { - int maxAttribs; - gl->glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxAttribs); - for (int i=0; i<maxAttribs; ++i) { - gl->glVertexAttribPointer(i, 4, GL_FLOAT, GL_FALSE, 0, nullptr); - gl->glDisableVertexAttribArray(i); - } - } - - gl->glActiveTexture(GL_TEXTURE0); - gl->glBindTexture(GL_TEXTURE_2D, 0); - - gl->glDisable(GL_DEPTH_TEST); - gl->glDisable(GL_STENCIL_TEST); - gl->glDisable(GL_SCISSOR_TEST); - - gl->glColorMask(true, true, true, true); - gl->glClearColor(0, 0, 0, 0); - - gl->glDepthMask(true); - gl->glDepthFunc(GL_LESS); - gl->glClearDepthf(1); - - gl->glStencilMask(0xff); - gl->glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); - gl->glStencilFunc(GL_ALWAYS, 0, 0xff); - - gl->glDisable(GL_BLEND); - gl->glBlendFunc(GL_ONE, GL_ZERO); - - gl->glUseProgram(0); - - QOpenGLFramebufferObject::bindDefault(); -} - void SGFramebufferObjectNode::render() { if (renderPending) { renderPending = false; GLuint textureId = renderer->render(); - resetOpenGLState(); + window->resetOpenGLState(); if (texture() && (GLuint(texture()->textureId()) != textureId || texture()->textureSize() != renderer->surfaceSize())) { delete texture(); @@ -166,7 +119,29 @@ GLuint QDemonSceneRenderer::render() return HandleToID_cast(GLuint, size_t, m_fbo->color0->handle()); } -void QDemonSceneRenderer::synchronize(QDemonView3D *item, const QSize &size) +void QDemonSceneRenderer::render(const QRect &viewport, bool clearFirst) +{ + if (!m_layer) + return; + + m_sgContext->beginFrame(); + + // set render target to be current window (default) + m_renderContext->setRenderTarget(nullptr); + + // set viewport + m_sgContext->renderList()->setViewport(viewport); + m_sgContext->renderList()->setScissorRect(viewport); + m_sgContext->setWindowDimensions(m_surfaceSize); + + m_sgContext->renderer()->prepareLayerForRender(*m_layer, m_surfaceSize, false, nullptr, true); + m_sgContext->runRenderTasks(); + m_sgContext->renderer()->renderLayer(*m_layer, m_surfaceSize, clearFirst, QVector3D(0, 0, 0), false); + m_sgContext->endFrame(); + +} + +void QDemonSceneRenderer::synchronize(QDemonView3D *item, const QSize &size, bool useFBO) { if (!item) return; @@ -217,12 +192,14 @@ void QDemonSceneRenderer::synchronize(QDemonView3D *item, const QSize &size) m_referencedRootNode = referencedRootNode; } - if (!m_fbo || m_layerSizeIsDirty) { - if (m_fbo) - delete m_fbo; + if (useFBO) { + if (!m_fbo || m_layerSizeIsDirty) { + if (m_fbo) + delete m_fbo; - m_fbo = new FramebufferObject(m_surfaceSize, m_renderContext); - m_layerSizeIsDirty = false; + m_fbo = new FramebufferObject(m_surfaceSize, m_renderContext); + m_layerSizeIsDirty = false; + } } } @@ -344,4 +321,72 @@ QDemonSceneRenderer::FramebufferObject::~FramebufferObject() } +QSGRenderNode::StateFlags QDemonSGRenderNode::changedStates() const +{ + return BlendState | StencilState | DepthState | ScissorState | ColorState | CullState | ViewportState | RenderTargetState; +} + +void QDemonSGRenderNode::render(const QSGRenderNode::RenderState *state) +{ + // calculate viewport + QRect viewport = matrix()->mapRect(QRect(QPoint(0, 0), renderer->surfaceSize())); + + // render + renderer->render(viewport); + markDirty(QSGNode::DirtyMaterial); +} + +void QDemonSGRenderNode::releaseResources() +{ +} + +QSGRenderNode::RenderingFlags QDemonSGRenderNode::flags() const +{ + return QSGRenderNode::RenderingFlags(); +} + +QDemonSGDirectRenderer::QDemonSGDirectRenderer(QDemonSceneRenderer *renderer, QQuickWindow *window, QDemonSGDirectRenderer::QDemonSGDirectRendererMode mode) + : m_renderer(renderer) + , m_window(window) + , m_mode(mode) +{ + if (mode == Underlay) + connect(window, &QQuickWindow::beforeRendering, this, &QDemonSGDirectRenderer::render, Qt::DirectConnection); + else + connect(window, &QQuickWindow::afterRendering, this, &QDemonSGDirectRenderer::render, Qt::DirectConnection); +} + +QDemonSGDirectRenderer::~QDemonSGDirectRenderer() +{ + delete m_renderer; +} + +void QDemonSGDirectRenderer::setViewport(const QRectF &viewport) +{ + m_viewport = viewport; +} + +void QDemonSGDirectRenderer::requestRender() +{ + m_window->update(); +} + +namespace { +QRect convertQtRectToGLViewport(const QRectF &rect, const QSize surfaceSize) { + // + const int x = int(rect.x()); + const int y = surfaceSize.height() - (int(rect.y()) + int(rect.height())); + const int width = int(rect.width()); + const int height = int(rect.height()); + return QRect(x, y, width, height); +} +} + +void QDemonSGDirectRenderer::render() +{ + const QRect glViewport = convertQtRectToGLViewport(m_viewport, m_window->size() * m_window->devicePixelRatio()); + m_renderer->render(glViewport, false); + m_window->resetOpenGLState(); +} + QT_END_NAMESPACE diff --git a/src/quick3d/qdemonscenerenderer.h b/src/quick3d/qdemonscenerenderer.h index 83e083182b0dcd18fe3f639c474682cd275a4932..636b8cd5cbfe8d03a6c3953dc85e94a0b217ce94 100644 --- a/src/quick3d/qdemonscenerenderer.h +++ b/src/quick3d/qdemonscenerenderer.h @@ -5,6 +5,7 @@ #include <QtDemonRuntimeRender/qdemonrendercontextcore.h> #include <qsgtextureprovider.h> +#include <qsgrendernode.h> #include <QSGSimpleTextureNode> #include <QtQuick3d/qdemonview3d.h> @@ -33,7 +34,8 @@ public: ~QDemonSceneRenderer(); protected: GLuint render(); - void synchronize(QDemonView3D *item, const QSize &size); + void render(const QRect &viewport, bool clearFirst = false); + void synchronize(QDemonView3D *item, const QSize &size, bool useFBO = true); void update(); void invalidateFramebufferObject(); QSize surfaceSize() const { return m_surfaceSize; } @@ -56,6 +58,8 @@ private: QDemonRenderNode *m_referencedRootNode = nullptr; friend class SGFramebufferObjectNode; + friend class QDemonSGRenderNode; + friend class QDemonSGDirectRenderer; friend class QDemonView3D; }; @@ -89,12 +93,45 @@ public: bool invalidatePending; qreal devicePixelRatio; +}; -private: - void resetOpenGLState(); - QOpenGLVertexArrayObjectHelper *m_vaoHelper = nullptr; +class QDemonSGRenderNode : public QSGRenderNode +{ +public: + + StateFlags changedStates() const override; + void render(const RenderState *state) override; + void releaseResources() override; + RenderingFlags flags() const override; +public: + QQuickWindow *window = nullptr; + QDemonSceneRenderer *renderer = nullptr; +}; + +class QDemonSGDirectRenderer : public QObject +{ + Q_OBJECT +public: + enum QDemonSGDirectRendererMode { + Underlay, + Overlay + }; + QDemonSGDirectRenderer(QDemonSceneRenderer *renderer, QQuickWindow *window, QDemonSGDirectRendererMode mode = Underlay); + ~QDemonSGDirectRenderer(); + QDemonSceneRenderer *renderer() { return m_renderer; } + void setViewport(const QRectF &viewport); + void requestRender(); + +private Q_SLOTS: + void render(); + +private: + QDemonSceneRenderer *m_renderer = nullptr; + QQuickWindow *m_window = nullptr; + QDemonSGDirectRendererMode m_mode; + QRectF m_viewport; }; QT_END_NAMESPACE diff --git a/src/quick3d/qdemonview3d.cpp b/src/quick3d/qdemonview3d.cpp index ff4c1fa3476d797fef2257ea50a9d1d6fba0b11b..cd21993364af499d54970336aae4fac4daf5aff1 100644 --- a/src/quick3d/qdemonview3d.cpp +++ b/src/quick3d/qdemonview3d.cpp @@ -120,6 +120,11 @@ QDemonNode *QDemonView3D::referencedScene() const return m_referencedScene; } +QDemonView3D::QDemonView3DRenderMode QDemonView3D::renderMode() const +{ + return m_renderMode; +} + QDemonSceneRenderer *QDemonView3D::createRenderer() const { return new QDemonSceneRenderer(this->window()); @@ -127,7 +132,11 @@ QDemonSceneRenderer *QDemonView3D::createRenderer() const bool QDemonView3D::isTextureProvider() const { - return true; + // We can only be a texture provider if we are rendering to a texture first + if (m_renderMode == QDemonView3D::Texture) + return true; + + return false; } QSGTextureProvider *QDemonView3D::textureProvider() const @@ -138,6 +147,10 @@ QSGTextureProvider *QDemonView3D::textureProvider() const if (QQuickItem::isTextureProvider()) return QQuickItem::textureProvider(); + // We can only be a texture provider if we are rendering to a texture first + if (m_renderMode != QDemonView3D::Texture) + return nullptr; + QQuickWindow *w = window(); if (!w || !w->openglContext() || QThread::currentThread() != w->openglContext()->thread()) { qWarning("QDemonView3D::textureProvider: can only be queried on the rendering thread of an exposed window"); @@ -163,37 +176,94 @@ void QDemonView3D::geometryChanged(const QRectF &newGeometry, const QRectF &oldG QSGNode *QDemonView3D::updatePaintNode(QSGNode *node, QQuickItem::UpdatePaintNodeData *) { - SGFramebufferObjectNode *n = static_cast<SGFramebufferObjectNode *>(node); - - if (!n) { - if (!m_node) - m_node = new SGFramebufferObjectNode; - n = m_node; + // When changing render modes + if (m_renderModeDirty) { + if (node) { + delete node; + node = nullptr; + } + if (m_directRenderer) { + delete m_directRenderer; + m_directRenderer = nullptr; + } } - if (!n->renderer) { - n->window = window(); - n->renderer = createRenderer(); - n->renderer->data = n; - n->quickFbo = this; - connect(window(), SIGNAL(screenChanged(QScreen*)), n, SLOT(handleScreenChange())); - } - QSize minFboSize = QQuickItemPrivate::get(this)->sceneGraphContext()->minimumFBOSize(); - QSize desiredFboSize(qMax<int>(minFboSize.width(), width()), - qMax<int>(minFboSize.height(), height())); - n->devicePixelRatio = window()->effectiveDevicePixelRatio(); - desiredFboSize *= n->devicePixelRatio; + m_renderModeDirty = false; + + if (m_renderMode == Texture) { + SGFramebufferObjectNode *n = static_cast<SGFramebufferObjectNode *>(node); + + if (!n) { + if (!m_node) + m_node = new SGFramebufferObjectNode; + n = m_node; + } + + if (!n->renderer) { + n->window = window(); + n->renderer = createRenderer(); + n->renderer->data = n; + n->quickFbo = this; + connect(window(), SIGNAL(screenChanged(QScreen*)), n, SLOT(handleScreenChange())); + } + QSize minFboSize = QQuickItemPrivate::get(this)->sceneGraphContext()->minimumFBOSize(); + QSize desiredFboSize(qMax<int>(minFboSize.width(), width()), + qMax<int>(minFboSize.height(), height())); + + n->devicePixelRatio = window()->effectiveDevicePixelRatio(); + desiredFboSize *= n->devicePixelRatio; + + n->renderer->synchronize(this, desiredFboSize); + + n->setTextureCoordinatesTransform(QSGSimpleTextureNode::MirrorVertically); + n->setFiltering(smooth() ? QSGTexture::Linear : QSGTexture::Nearest); + n->setRect(0, 0, width(), height()); + + n->scheduleRender(); + + return n; + } else if (m_renderMode == Underlay) { + if (!m_directRenderer) + m_directRenderer = new QDemonSGDirectRenderer(createRenderer(), window(), QDemonSGDirectRenderer::Underlay); + const QSizeF targetSize = window()->effectiveDevicePixelRatio() * QSizeF(width(), height()); + m_directRenderer->renderer()->synchronize(this, targetSize.toSize(), false); + m_directRenderer->setViewport(QRectF(window()->effectiveDevicePixelRatio() * mapToScene(QPointF(0, 0)), targetSize)); + m_directRenderer->requestRender(); + if (window()->clearBeforeRendering()) + window()->setClearBeforeRendering(false); + window()->update(); + return node; // node should be nullptr + } else if (m_renderMode == Overlay) { + if (!m_directRenderer) + m_directRenderer = new QDemonSGDirectRenderer(createRenderer(), window(), QDemonSGDirectRenderer::Overlay); + const QSizeF targetSize = window()->effectiveDevicePixelRatio() * QSizeF(width(), height()); + m_directRenderer->renderer()->synchronize(this, targetSize.toSize(), false); + m_directRenderer->setViewport(QRectF(window()->effectiveDevicePixelRatio() * mapToScene(QPointF(0, 0)), targetSize)); + m_directRenderer->requestRender(); + return node; // node should be nullptr + } else { + // Render Node + QDemonSGRenderNode *n = static_cast<QDemonSGRenderNode *>(node); + if (!n) { + if (!m_renderNode) + m_renderNode = new QDemonSGRenderNode(); + n = m_renderNode; + } - n->renderer->synchronize(this, desiredFboSize); + if (!n->renderer) { + n->window = window(); + n->renderer = createRenderer(); + n->renderer->data = n; + } - n->setTextureCoordinatesTransform(QSGSimpleTextureNode::MirrorVertically); - n->setFiltering(smooth() ? QSGTexture::Linear : QSGTexture::Nearest); - n->setRect(0, 0, width(), height()); + const QSize targetSize = window()->effectiveDevicePixelRatio() * QSize(width(), height()); - n->scheduleRender(); + n->renderer->synchronize(this, targetSize, false); + n->markDirty(QSGNode::DirtyMaterial); - return n; + return n; + } } void QDemonView3D::setCamera(QDemonCamera *camera) @@ -239,6 +309,17 @@ void QDemonView3D::setScene(QDemonNode *sceneRoot) } +void QDemonView3D::setRenderMode(QDemonView3D::QDemonView3DRenderMode renderMode) +{ + if (m_renderMode == renderMode) + return; + + m_renderMode = renderMode; + m_renderModeDirty = true; + emit renderModeChanged(m_renderMode); + update(); +} + static QSurfaceFormat findIdealGLVersion() { QSurfaceFormat fmt; diff --git a/src/quick3d/qdemonview3d.h b/src/quick3d/qdemonview3d.h index a4b6219f871966b8689e50795ac62cbdb184d983..e50923eb49d166b4b3adbc7ebe2f680610d3a8fc 100644 --- a/src/quick3d/qdemonview3d.h +++ b/src/quick3d/qdemonview3d.h @@ -17,6 +17,8 @@ class QDemonNode; class QDemonSceneRenderer; class SGFramebufferObjectNode; +class QDemonSGRenderNode; +class QDemonSGDirectRenderer; class Q_QUICK3D_EXPORT QDemonView3D : public QQuickItem { @@ -25,8 +27,17 @@ class Q_QUICK3D_EXPORT QDemonView3D : public QQuickItem Q_PROPERTY(QDemonCamera *camera READ camera WRITE setCamera NOTIFY cameraChanged) Q_PROPERTY(QDemonSceneEnvironment *environment READ environment WRITE setEnvironment NOTIFY environmentChanged) Q_PROPERTY(QDemonNode* scene READ scene WRITE setScene NOTIFY sceneChanged) + Q_PROPERTY(QDemonView3DRenderMode renderMode READ renderMode WRITE setRenderMode NOTIFY renderModeChanged) Q_CLASSINFO("DefaultProperty", "data") public: + enum QDemonView3DRenderMode { + Texture, + Underlay, + Overlay, + RenderNode + }; + Q_ENUM(QDemonView3DRenderMode) + explicit QDemonView3D(QQuickItem *parent = nullptr); ~QDemonView3D() override; @@ -36,6 +47,7 @@ public: QDemonSceneEnvironment *environment() const; QDemonNode *scene() const; QDemonNode *referencedScene() const; + QDemonView3DRenderMode renderMode() const; QDemonSceneRenderer *createRenderer() const; @@ -53,6 +65,7 @@ public Q_SLOTS: void setCamera(QDemonCamera *camera); void setEnvironment(QDemonSceneEnvironment * environment); void setScene(QDemonNode *sceneRoot); + void setRenderMode(QDemonView3DRenderMode renderMode); private Q_SLOTS: void invalidateSceneGraph(); @@ -61,6 +74,7 @@ Q_SIGNALS: void cameraChanged(QDemonCamera *camera); void environmentChanged(QDemonSceneEnvironment * environment); void sceneChanged(QDemonNode *sceneRoot); + void renderModeChanged(QDemonView3DRenderMode renderMode); private: Q_DISABLE_COPY(QDemonView3D) @@ -70,6 +84,11 @@ private: QDemonNode *m_sceneRoot = nullptr; QDemonNode *m_referencedScene = nullptr; mutable SGFramebufferObjectNode *m_node = nullptr; + mutable QDemonSGRenderNode *m_renderNode = nullptr; + mutable QDemonSGDirectRenderer *m_directRenderer = nullptr; + bool m_renderModeDirty = false; + QDemonView3DRenderMode m_renderMode = Texture; + QHash<QObject*, QMetaObject::Connection> m_connections; }; diff --git a/src/runtimerender/rendererimpl/qdemonrendererimpl.cpp b/src/runtimerender/rendererimpl/qdemonrendererimpl.cpp index 7eae0f2d11ce98e5386cbfe0e32c2301883f89ae..2b8253c747d7e86473643aed1aff4c067c6a2f43 100644 --- a/src/runtimerender/rendererimpl/qdemonrendererimpl.cpp +++ b/src/runtimerender/rendererimpl/qdemonrendererimpl.cpp @@ -235,6 +235,8 @@ void QDemonRendererImpl::renderLayer(QDemonRenderLayer &inLayer, QDemonRef<QDemonLayerRenderData> theRenderData = getOrCreateLayerRenderDataForNode(*theLayer, id); if (Q_LIKELY(theRenderData)) { + // Make sure that we don't clear the window, when requested not to. + theRenderData->layerPrepResult->flags.setRequiresTransparentClear(clear); if (theRenderData->layerPrepResult->isLayerVisible()) theRenderData->runnableRenderToViewport(theFB); } else { diff --git a/src/runtimerender/rendererimpl/qdemonrendererimpllayerrenderdata.cpp b/src/runtimerender/rendererimpl/qdemonrendererimpllayerrenderdata.cpp index f1b2195f2ad8f926f2fe22adb3e48a4eec08a111..05666a32e9e17a779765467dacf6c0f29fc5774b 100644 --- a/src/runtimerender/rendererimpl/qdemonrendererimpllayerrenderdata.cpp +++ b/src/runtimerender/rendererimpl/qdemonrendererimpllayerrenderdata.cpp @@ -1657,13 +1657,13 @@ void QDemonLayerRenderData::runnableRenderToViewport(const QDemonRef<QDemonRende QVector4D(layer.clearColor, 1.0f)); theContext->clear(QDemonRenderClearValues::Color); } else { - // ### will need to address this later because when not rendering to an FBO - // we would clear anything in the window target which is not what we want - QDemonRenderContextScopedProperty<QVector4D> __clearColor(*theContext, - &QDemonRenderContext::clearColor, - &QDemonRenderContext::setClearColor, - QVector4D(0.0, 0.0, 0.0, 0.0f)); - theContext->clear(QDemonRenderClearValues::Color); + if (thePrepResult.flags.requiresTransparentClear()) { + QDemonRenderContextScopedProperty<QVector4D> __clearColor(*theContext, + &QDemonRenderContext::clearColor, + &QDemonRenderContext::setClearColor, + QVector4D(0.0, 0.0, 0.0, 0.0f)); + theContext->clear(QDemonRenderClearValues::Color); + } } renderToViewport(); } else { diff --git a/src/runtimerender/rendererimpl/qdemonrendererimpllayerrenderhelper.cpp b/src/runtimerender/rendererimpl/qdemonrendererimpllayerrenderhelper.cpp index e1433718debfae593a24858791a7d648d4fe343b..146193bcc031e83db75aa39a0408b3b50b944351 100644 --- a/src/runtimerender/rendererimpl/qdemonrendererimpllayerrenderhelper.cpp +++ b/src/runtimerender/rendererimpl/qdemonrendererimpllayerrenderhelper.cpp @@ -78,77 +78,81 @@ QDemonLayerRenderHelper::QDemonLayerRenderHelper(const QRectF &inPresentationVie , m_scaleMode(inScaleMode) , m_scaleFactor(inScaleFactor) { - { - float left = m_layer->m_left; - float right = m_layer->m_right; - float width = m_layer->m_width; - - if (m_scaleMode == ScaleModes::FitSelected) { - if (m_layer->leftUnits == QDemonRenderLayer::UnitType::Pixels) - left *= m_scaleFactor.x(); - - if (m_layer->rightUnits == QDemonRenderLayer::UnitType::Pixels) - right *= m_scaleFactor.x(); - - if (m_layer->widthUnits == QDemonRenderLayer::UnitType::Pixels) - width *= m_scaleFactor.x(); - } - - float horzMin = getMinValue(inPresentationViewport.x(), inPresentationViewport.width(), left, m_layer->leftUnits); - float horzWidth = getValueLen(inPresentationViewport.width(), width, m_layer->widthUnits); - float horzMax = getMaxValue(inPresentationViewport.x(), inPresentationViewport.width(), right, m_layer->rightUnits); - - switch (inLayer.horizontalFieldValues) { - case QDemonRenderLayer::HorizontalField::LeftWidth: - m_viewport.setX(horzMin); - m_viewport.setWidth(horzWidth); - break; - case QDemonRenderLayer::HorizontalField::LeftRight: - m_viewport.setX(horzMin); - m_viewport.setWidth(horzMax - horzMin); - break; - case QDemonRenderLayer::HorizontalField::WidthRight: - m_viewport.setWidth(horzWidth); - m_viewport.setX(horzMax - horzWidth); - break; - } - } - { - float top = m_layer->m_top; - float bottom = m_layer->m_bottom; - float height = m_layer->m_height; - - if (m_scaleMode == ScaleModes::FitSelected) { - - if (m_layer->topUnits == QDemonRenderLayer::UnitType::Pixels) - top *= m_scaleFactor.y(); - - if (m_layer->bottomUnits == QDemonRenderLayer::UnitType::Pixels) - bottom *= m_scaleFactor.y(); - - if (m_layer->heightUnits == QDemonRenderLayer::UnitType::Pixels) - height *= m_scaleFactor.y(); - } - - float vertMin = getMinValue(inPresentationViewport.y(), inPresentationViewport.height(), bottom, m_layer->bottomUnits); - float vertWidth = getValueLen(inPresentationViewport.height(), height, m_layer->heightUnits); - float vertMax = getMaxValue(inPresentationViewport.y(), inPresentationViewport.height(), top, m_layer->topUnits); - - switch (inLayer.verticalFieldValues) { - case QDemonRenderLayer::VerticalField::HeightBottom: - m_viewport.setY(vertMin); - m_viewport.setHeight(vertWidth); - break; - case QDemonRenderLayer::VerticalField::TopBottom: - m_viewport.setY(vertMin); - m_viewport.setHeight(vertMax - vertMin); - break; - case QDemonRenderLayer::VerticalField::TopHeight: - m_viewport.setHeight(vertWidth); - m_viewport.setY(vertMax - vertWidth); - break; - } - } + // The following code is used to get the correct viewport for the layer compositor. + // We dont actually use this code anymore, so for now it is just disabled until + // we figure out whether we want to use this code. +// { +// float left = m_layer->m_left; +// float right = m_layer->m_right; +// float width = m_layer->m_width; + +// if (m_scaleMode == ScaleModes::FitSelected) { +// if (m_layer->leftUnits == QDemonRenderLayer::UnitType::Pixels) +// left *= m_scaleFactor.x(); + +// if (m_layer->rightUnits == QDemonRenderLayer::UnitType::Pixels) +// right *= m_scaleFactor.x(); + +// if (m_layer->widthUnits == QDemonRenderLayer::UnitType::Pixels) +// width *= m_scaleFactor.x(); +// } + +// float horzMin = getMinValue(inPresentationViewport.x(), inPresentationViewport.width(), left, m_layer->leftUnits); +// float horzWidth = getValueLen(inPresentationViewport.width(), width, m_layer->widthUnits); +// float horzMax = getMaxValue(inPresentationViewport.x(), inPresentationViewport.width(), right, m_layer->rightUnits); + +// switch (inLayer.horizontalFieldValues) { +// case QDemonRenderLayer::HorizontalField::LeftWidth: +// m_viewport.setX(horzMin); +// m_viewport.setWidth(horzWidth); +// break; +// case QDemonRenderLayer::HorizontalField::LeftRight: +// m_viewport.setX(horzMin); +// m_viewport.setWidth(horzMax - horzMin); +// break; +// case QDemonRenderLayer::HorizontalField::WidthRight: +// m_viewport.setWidth(horzWidth); +// m_viewport.setX(horzMax - horzWidth); +// break; +// } +// } +// { +// float top = m_layer->m_top; +// float bottom = m_layer->m_bottom; +// float height = m_layer->m_height; + +// if (m_scaleMode == ScaleModes::FitSelected) { + +// if (m_layer->topUnits == QDemonRenderLayer::UnitType::Pixels) +// top *= m_scaleFactor.y(); + +// if (m_layer->bottomUnits == QDemonRenderLayer::UnitType::Pixels) +// bottom *= m_scaleFactor.y(); + +// if (m_layer->heightUnits == QDemonRenderLayer::UnitType::Pixels) +// height *= m_scaleFactor.y(); +// } + +// float vertMin = getMinValue(inPresentationViewport.y(), inPresentationViewport.height(), bottom, m_layer->bottomUnits); +// float vertWidth = getValueLen(inPresentationViewport.height(), height, m_layer->heightUnits); +// float vertMax = getMaxValue(inPresentationViewport.y(), inPresentationViewport.height(), top, m_layer->topUnits); + +// switch (inLayer.verticalFieldValues) { +// case QDemonRenderLayer::VerticalField::HeightBottom: +// m_viewport.setY(vertMin); +// m_viewport.setHeight(vertWidth); +// break; +// case QDemonRenderLayer::VerticalField::TopBottom: +// m_viewport.setY(vertMin); +// m_viewport.setHeight(vertMax - vertMin); +// break; +// case QDemonRenderLayer::VerticalField::TopHeight: +// m_viewport.setHeight(vertWidth); +// m_viewport.setY(vertMax - vertWidth); +// break; +// } +// } + m_viewport = m_presentationViewport; m_viewport.setWidth(qMax<qreal>(1.0f, m_viewport.width())); m_viewport.setHeight(qMax<qreal>(1.0f, m_viewport.height())); diff --git a/src/runtimerender/rendererimpl/qdemonrendererimpllayerrenderpreparationdata.h b/src/runtimerender/rendererimpl/qdemonrendererimpllayerrenderpreparationdata.h index 8424adf16aaad98c29111a8bd6e43c4c7be17073..ed455800fa8e395090263e4f8442b4993fd76979 100644 --- a/src/runtimerender/rendererimpl/qdemonrendererimpllayerrenderpreparationdata.h +++ b/src/runtimerender/rendererimpl/qdemonrendererimpllayerrenderpreparationdata.h @@ -73,7 +73,10 @@ enum class QDemonLayerRenderPreparationResultFlag RequiresShadowMapPass = 1 << 6, // Currently we use a stencil-cover algorithm to render bezier curves. - RequiresStencilBuffer = 1 << 7 + RequiresStencilBuffer = 1 << 7, + + // This is the case when direct rendering, and need to clear an FBO, but not a Window + RequiresTransparentClear = 1 << 8 }; struct QDemonLayerRenderPreparationResultFlags : public QFlags<QDemonLayerRenderPreparationResultFlag> @@ -140,6 +143,17 @@ struct QDemonLayerRenderPreparationResultFlags : public QFlags<QDemonLayerRender { setFlag(QDemonLayerRenderPreparationResultFlag::RequiresStencilBuffer, inValue); } + + bool requiresTransparentClear() const + { + return this->operator&(QDemonLayerRenderPreparationResultFlag::RequiresTransparentClear); + } + + void setRequiresTransparentClear(bool inValue) + { + setFlag(QDemonLayerRenderPreparationResultFlag::RequiresTransparentClear, inValue); + } + }; struct QDemonLayerRenderPreparationResult : public QDemonLayerRenderHelper