From 6058ad34c490f505c4acffc30719c8abca165984 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomi=20Korpip=C3=A4=C3=A4?= Date: Thu, 13 Mar 2014 11:33:07 +0200 Subject: Support for rendering to image Task-number: QTRD-2869 Change-Id: I5182c182f15893e70129a95c3cfdd590ed4f0853 Note: Not to be merged until v1.0 is out Change-Id: I5182c182f15893e70129a95c3cfdd590ed4f0853 Reviewed-by: Miikka Heikkinen Reviewed-by: Mika Salmela --- .../engine/abstract3dcontroller.cpp | 6 +++ .../engine/abstract3dcontroller_p.h | 3 ++ src/datavisualization/engine/q3dscene.cpp | 1 - src/datavisualization/engine/q3dscene.h | 1 + src/datavisualization/engine/qabstract3dgraph.cpp | 63 +++++++++++++++++++++- src/datavisualization/engine/qabstract3dgraph.h | 5 +- src/datavisualization/engine/qabstract3dgraph_p.h | 4 ++ 7 files changed, 80 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/datavisualization/engine/abstract3dcontroller.cpp b/src/datavisualization/engine/abstract3dcontroller.cpp index ec18a850..63d66bc4 100644 --- a/src/datavisualization/engine/abstract3dcontroller.cpp +++ b/src/datavisualization/engine/abstract3dcontroller.cpp @@ -33,6 +33,7 @@ #include "q3dscene_p.h" #include "q3dscene.h" #include +#include QT_BEGIN_NAMESPACE_DATAVISUALIZATION @@ -767,6 +768,11 @@ void Abstract3DController::markSeriesVisualsDirty() emitNeedRender(); } +void Abstract3DController::requestRender(QOpenGLFramebufferObject *fbo) +{ + m_renderer->render(fbo->handle()); +} + void Abstract3DController::handleAxisTitleChanged(const QString &title) { Q_UNUSED(title) diff --git a/src/datavisualization/engine/abstract3dcontroller_p.h b/src/datavisualization/engine/abstract3dcontroller_p.h index 06be450e..c0a2fac2 100644 --- a/src/datavisualization/engine/abstract3dcontroller_p.h +++ b/src/datavisualization/engine/abstract3dcontroller_p.h @@ -212,6 +212,8 @@ public: void markDataDirty(); void markSeriesVisualsDirty(); + void requestRender(QOpenGLFramebufferObject *fbo); + void emitNeedRender(); virtual void clearSelection() = 0; @@ -279,6 +281,7 @@ private: QAbstract3DAxis **axisPtr); friend class Bars3DController; + friend class QAbstract3DGraphPrivate; }; QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/engine/q3dscene.cpp b/src/datavisualization/engine/q3dscene.cpp index be64b928..98f39cc9 100644 --- a/src/datavisualization/engine/q3dscene.cpp +++ b/src/datavisualization/engine/q3dscene.cpp @@ -554,7 +554,6 @@ void Q3DScenePrivate::setWindowSize(const QSize &size) m_windowSize = size; updateGLViewport(); m_changeTracker.windowSizeChanged = true; - m_sceneDirty = true; emit needRender(); } } diff --git a/src/datavisualization/engine/q3dscene.h b/src/datavisualization/engine/q3dscene.h index d663744e..39c9791f 100644 --- a/src/datavisualization/engine/q3dscene.h +++ b/src/datavisualization/engine/q3dscene.h @@ -93,6 +93,7 @@ private: friend class AbstractDeclarative; friend class QAbstract3DGraph; + friend class QAbstract3DGraphPrivate; friend class Abstract3DController; friend class Q3DScenePrivate; friend class Abstract3DRenderer; diff --git a/src/datavisualization/engine/qabstract3dgraph.cpp b/src/datavisualization/engine/qabstract3dgraph.cpp index bde5b585..5afc1417 100644 --- a/src/datavisualization/engine/qabstract3dgraph.cpp +++ b/src/datavisualization/engine/qabstract3dgraph.cpp @@ -27,6 +27,8 @@ #include #include #include +#include +#include QT_BEGIN_NAMESPACE_DATAVISUALIZATION @@ -357,6 +359,22 @@ void QAbstract3DGraph::clearSelection() d_ptr->m_visualController->clearSelection(); } +/*! + * Renders current frame to an image of \a imageSize. Default size is the window size. Image is + * rendered with antialiasing level given in \a msaaSamples. Default level is \c{0}. + * + * \since Qt Data Visualization 1.1 + * + * \return rendered image. + */ +QImage QAbstract3DGraph::renderToImage(int msaaSamples, const QSize &imageSize) +{ + QSize renderSize = imageSize; + if (renderSize.isEmpty()) + renderSize = size(); + return d_ptr->renderToImage(msaaSamples, renderSize); +} + /*! * \internal */ @@ -453,12 +471,17 @@ QAbstract3DGraphPrivate::QAbstract3DGraphPrivate(QAbstract3DGraph *q) q_ptr(q), m_updatePending(false), m_visualController(0), - m_devicePixelRatio(1.f) + m_devicePixelRatio(1.f), + m_offscreenSurface(0) { } QAbstract3DGraphPrivate::~QAbstract3DGraphPrivate() { + if (m_offscreenSurface) { + m_offscreenSurface->destroy(); + delete m_offscreenSurface; + } if (m_context) m_context->makeCurrent(q_ptr); @@ -526,4 +549,42 @@ void QAbstract3DGraphPrivate::renderNow() m_context->swapBuffers(q_ptr); } +QImage QAbstract3DGraphPrivate::renderToImage(int msaaSamples, const QSize &imageSize) +{ + QImage image; + QOpenGLFramebufferObject *fbo; + QOpenGLFramebufferObjectFormat fboFormat; + if (!m_offscreenSurface) { + // Create an offscreen surface for rendering to images without rendering on screen + m_offscreenSurface = new QOffscreenSurface(q_ptr->screen()); + m_offscreenSurface->setFormat(q_ptr->requestedFormat()); + m_offscreenSurface->create(); + } + // Render the wanted frame offscreen + m_context->makeCurrent(m_offscreenSurface); + fboFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); + fboFormat.setInternalTextureFormat(GL_RGB); + fboFormat.setSamples(msaaSamples); + fbo = new QOpenGLFramebufferObject(imageSize, fboFormat); + if (fbo->isValid()) { + QRect originalViewport = m_visualController->m_scene->viewport(); + m_visualController->m_scene->d_ptr->setWindowSize(imageSize); + m_visualController->m_scene->d_ptr->setViewport(QRect(0, 0, + imageSize.width(), + imageSize.height())); + m_visualController->synchDataToRenderer(); + fbo->bind(); + m_context->swapBuffers(m_offscreenSurface); + m_visualController->requestRender(fbo); + image = fbo->toImage(); + fbo->release(); + m_visualController->m_scene->d_ptr->setWindowSize(originalViewport.size()); + m_visualController->m_scene->d_ptr->setViewport(originalViewport); + } + delete fbo; + m_context->makeCurrent(q_ptr); + + return image; +} + QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/engine/qabstract3dgraph.h b/src/datavisualization/engine/qabstract3dgraph.h index 18eda7df..1109d7b0 100644 --- a/src/datavisualization/engine/qabstract3dgraph.h +++ b/src/datavisualization/engine/qabstract3dgraph.h @@ -42,7 +42,8 @@ class QT_DATAVISUALIZATION_EXPORT QAbstract3DGraph : public QWindow, protected Q Q_PROPERTY(Q3DScene* scene READ scene) protected: - explicit QAbstract3DGraph(QAbstract3DGraphPrivate *d, const QSurfaceFormat *format, QWindow *parent = 0); + explicit QAbstract3DGraph(QAbstract3DGraphPrivate *d, const QSurfaceFormat *format, + QWindow *parent = 0); public: enum SelectionFlag { @@ -95,6 +96,8 @@ public: void clearSelection(); + QImage renderToImage(int msaaSamples = 0, const QSize &imageSize = QSize()); + protected: bool event(QEvent *event); void resizeEvent(QResizeEvent *event); diff --git a/src/datavisualization/engine/qabstract3dgraph_p.h b/src/datavisualization/engine/qabstract3dgraph_p.h index d28495ab..8e571355 100644 --- a/src/datavisualization/engine/qabstract3dgraph_p.h +++ b/src/datavisualization/engine/qabstract3dgraph_p.h @@ -33,6 +33,7 @@ class QOpenGLContext; class QOpenGLPaintDevice; +class QOffscreenSurface; QT_BEGIN_NAMESPACE_DATAVISUALIZATION @@ -52,6 +53,8 @@ public: void render(); + QImage renderToImage(int msaaSamples, const QSize &imageSize); + public slots: void renderLater(); void renderNow(); @@ -67,6 +70,7 @@ public: QOpenGLContext *m_context; Abstract3DController *m_visualController; float m_devicePixelRatio; + QOffscreenSurface *m_offscreenSurface; }; QT_END_NAMESPACE_DATAVISUALIZATION -- cgit v1.2.3