QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
qgsoffscreen3dengine.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsoffscreen3dengine.cpp
3 --------------------------------------
4 Date : July 2018
5 Copyright : (C) 2018 by Martin Dobias
6 Email : wonder dot sk at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
17
18#include "qgsframegraph.h"
19
20#include <QCoreApplication>
21#include <QOffscreenSurface>
22#include <QSurfaceFormat>
23#include <QOpenGLFunctions>
24
25#include <Qt3DCore/QAspectEngine>
26#include <Qt3DLogic/QLogicAspect>
27#include <Qt3DRender/QCamera>
28#include <Qt3DRender/QCameraSelector>
29#include <Qt3DRender/QClearBuffers>
30#include <Qt3DRender/QRenderAspect>
31#include <Qt3DRender/QRenderCapture>
32#include <Qt3DRender/QRenderSettings>
33#include <Qt3DRender/QRenderTarget>
34#include <Qt3DRender/QRenderTargetOutput>
35#include <Qt3DRender/QRenderTargetSelector>
36#include <Qt3DRender/QRenderSurfaceSelector>
37#include <Qt3DRender/QTexture>
38#include <Qt3DRender/QViewport>
39
41{
42 // Set up a camera to point at the shapes.
43 mCamera = new Qt3DRender::QCamera;
44 mCamera->lens()->setPerspectiveProjection( 45.0f, float( mSize.width() ) / float( mSize.height() ), 0.1f, 1000.0f );
45 mCamera->setPosition( QVector3D( 0, 0, 20.0f ) );
46 mCamera->setUpVector( QVector3D( 0, 1, 0 ) );
47 mCamera->setViewCenter( QVector3D( 0, 0, 0 ) );
48
49 // Set up the engine and the aspects that we want to use.
50 mAspectEngine = new Qt3DCore::QAspectEngine();
51
52#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
53 mRenderAspect = new Qt3DRender::QRenderAspect( Qt3DRender::QRenderAspect::Threaded ); // Only threaded mode seems to work right now.
54#else
55 mRenderAspect = new Qt3DRender::QRenderAspect();
56#endif
57
58 mLogicAspect = new Qt3DLogic::QLogicAspect();
59
60 mAspectEngine->registerAspect( mRenderAspect );
61 mAspectEngine->registerAspect( mLogicAspect );
62
63 // Create the root entity of the engine.
64 // This is not the same as the 3D scene root: the QRenderSettings
65 // component must be held by the root of the QEntity tree,
66 // so it is added to this one. The 3D scene is added as a subtree later,
67 // in setRootEntity().
68 mRoot = new Qt3DCore::QEntity;
69 mRenderSettings = new Qt3DRender::QRenderSettings( mRoot );
70 mRoot->addComponent( mRenderSettings );
71
72 mCamera->setParent( mRoot );
73
74 // Create the offscreen frame graph, which will manage all of the resources required
75 // for rendering without a QWindow.
76 mOffscreenSurface = new QOffscreenSurface();
77
78 QSurfaceFormat format;
79
80 //Use default format when shared OpenGL context is enabled
81 if ( QCoreApplication::instance() && QCoreApplication::instance()->testAttribute( Qt::AA_ShareOpenGLContexts ) )
82 {
83 format = QSurfaceFormat::defaultFormat();
84 }
85 //Set the surface format when used outside of QGIS application
86 else
87 {
88 format.setRenderableType( QSurfaceFormat::OpenGL );
89#ifdef Q_OS_MAC
90 format.setVersion( 4, 1 ); //OpenGL is deprecated on MacOS, use last supported version
91 format.setProfile( QSurfaceFormat::CoreProfile );
92#else
93 format.setVersion( 4, 3 );
94 format.setProfile( QSurfaceFormat::CoreProfile );
95#endif
96 format.setDepthBufferSize( 24 );
97 format.setSamples( 4 );
98 format.setStencilBufferSize( 8 );
99 }
100
101 mOffscreenSurface->setFormat( format );
102 mOffscreenSurface->create();
103
104 mFrameGraph = new QgsFrameGraph( mOffscreenSurface, mSize, mCamera, mRoot );
107 // Set this frame graph to be in use.
108 // the render settings also sets itself as the parent of mSurfaceSelector
109 mRenderSettings->setActiveFrameGraph( mFrameGraph->frameGraphRoot() );
110
111 // Set the root entity of the engine. This causes the engine to begin running.
112 mAspectEngine->setRootEntity( Qt3DCore::QEntityPtr( mRoot ) );
113
114}
115
117{
118 delete mAspectEngine;
119 delete mOffscreenSurface;
120}
121
123{
124 mSize = s;
125
126 mFrameGraph->setSize( mSize );
127 mCamera->setAspectRatio( float( mSize.width() ) / float( mSize.height() ) );
128 emit sizeChanged();
129}
130
131void QgsOffscreen3DEngine::setClearColor( const QColor &color )
132{
133 mFrameGraph->setClearColor( color );
134}
135
137{
139}
140
141void QgsOffscreen3DEngine::setRootEntity( Qt3DCore::QEntity *root )
142{
143 // Make sure any existing scene root is unparented.
144 if ( mSceneRoot )
145 {
146 mSceneRoot->setParent( static_cast<Qt3DCore::QNode *>( nullptr ) );
147 }
148
149 // Parent the incoming scene root to our current root entity.
150 mSceneRoot = root;
151 mSceneRoot->setParent( mRoot );
152 root->addComponent( mFrameGraph->forwardRenderLayer() );
153 root->addComponent( mFrameGraph->castShadowsLayer() );
154}
155
156Qt3DRender::QRenderSettings *QgsOffscreen3DEngine::renderSettings()
157{
158 return mRenderSettings;
159}
160
161Qt3DRender::QCamera *QgsOffscreen3DEngine::camera()
162{
163 return mCamera;
164}
165
167{
168 return mSize;
169}
170
172{
173 return mOffscreenSurface;
174}
void sizeChanged()
Emitted after a call to setSize()
QgsFrameGraph * mFrameGraph
Qt3DRender::QLayer * forwardRenderLayer()
Returns a layer object used to indicate that an entity will be rendered during the forward rendering ...
Definition: qgsframegraph.h:96
void setRenderCaptureEnabled(bool enabled)
Sets whether it will be possible to render to an image.
Qt3DRender::QFrameGraphNode * frameGraphRoot()
Returns the root of the frame graph object.
Definition: qgsframegraph.h:70
void setClearColor(const QColor &clearColor)
Sets the clear color of the scene (background color)
void setFrustumCullingEnabled(bool enabled)
Sets whether frustum culling is enabled.
void setShadowRenderingEnabled(bool enabled)
Sets whether the shadow rendering is enabled.
Qt3DRender::QLayer * castShadowsLayer()
Returns a layer object used to indicate that an entity will cast shadows.
Definition: qgsframegraph.h:94
void setSize(QSize s)
Sets the size of the buffers used for rendering.
void setSize(QSize s) override
Sets the size of the rendering area (in pixels)
void setClearColor(const QColor &color) override
Sets background color of the scene.
QSize size() const override
Returns size of the engine's rendering area in pixels.
void setRootEntity(Qt3DCore::QEntity *root) override
Sets root entity of the 3D scene.
void setFrustumCullingEnabled(bool enabled) override
Sets whether frustum culling is enabled (this should make rendering faster by not rendering entities ...
Qt3DRender::QCamera * camera() override
Returns pointer to the engine's camera entity.
Qt3DRender::QRenderSettings * renderSettings() override
Returns access to the engine's render settings (the frame graph can be accessed from here)
QSurface * surface() const override
Returns the surface of the engine.