QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
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 
16 #include "qgsoffscreen3dengine.h"
17 #include "qgslogger.h"
18 
19 #include <QOffscreenSurface>
20 #include <QSurfaceFormat>
21 #include <QOpenGLFunctions>
22 
23 #include <Qt3DCore/QAspectEngine>
24 #include <Qt3DLogic/QLogicAspect>
25 #include <Qt3DRender/QCamera>
26 #include <Qt3DRender/QCameraSelector>
27 #include <Qt3DRender/QClearBuffers>
28 #include <Qt3DRender/QRenderAspect>
29 #include <Qt3DRender/QRenderCapture>
30 #include <Qt3DRender/QRenderSettings>
31 #include <Qt3DRender/QRenderTarget>
32 #include <Qt3DRender/QRenderTargetOutput>
33 #include <Qt3DRender/QRenderTargetSelector>
34 #include <Qt3DRender/QRenderSurfaceSelector>
35 #include <Qt3DRender/QTexture>
36 #include <Qt3DRender/QViewport>
37 #include <QtGui/QOpenGLContext>
38 
40 {
41  // Set up the default OpenGL surface format.
42  QSurfaceFormat format;
43 
44  // by default we get just some older version of OpenGL from the system,
45  // but for 3D lines we use "primitive restart" functionality supported in OpenGL >= 3.1
46  // Qt3DWindow uses this - requesting OpenGL 4.3 - so let's request the same version.
47 #ifdef QT_OPENGL_ES_2
48  format.setRenderableType( QSurfaceFormat::OpenGLES );
49 #else
50  if ( QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL )
51  {
52  format.setVersion( 4, 3 );
53  format.setProfile( QSurfaceFormat::CoreProfile );
54  }
55 #endif
56 
57  format.setMajorVersion( 3 );
58  format.setDepthBufferSize( 32 ); // TODO: or 24? (used by QWindow3D)
59  format.setSamples( 8 );
60  QSurfaceFormat::setDefaultFormat( format );
61 
62  // Set up a camera to point at the shapes.
63  mCamera = new Qt3DRender::QCamera;
64  mCamera->lens()->setPerspectiveProjection( 45.0f, float( mSize.width() ) / float( mSize.height() ), 0.1f, 1000.0f );
65  mCamera->setPosition( QVector3D( 0, 0, 20.0f ) );
66  mCamera->setUpVector( QVector3D( 0, 1, 0 ) );
67  mCamera->setViewCenter( QVector3D( 0, 0, 0 ) );
68 
69  // Set up the engine and the aspects that we want to use.
70  mAspectEngine = new Qt3DCore::QAspectEngine();
71  mRenderAspect = new Qt3DRender::QRenderAspect( Qt3DRender::QRenderAspect::Threaded ); // Only threaded mode seems to work right now.
72  mLogicAspect = new Qt3DLogic::QLogicAspect();
73 
74  mAspectEngine->registerAspect( mRenderAspect );
75  mAspectEngine->registerAspect( mLogicAspect );
76 
77  // Create the root entity of the engine.
78  // This is not the same as the 3D scene root: the QRenderSettings
79  // component must be held by the root of the QEntity tree,
80  // so it is added to this one. The 3D scene is added as a subtree later,
81  // in setRootEntity().
82  mRoot = new Qt3DCore::QEntity;
83  mRenderSettings = new Qt3DRender::QRenderSettings( mRoot );
84  mRoot->addComponent( mRenderSettings );
85 
86  mCamera->setParent( mRoot );
87 
88  // Create the offscreen frame graph, which will manage all of the resources required
89  // for rendering without a QWindow.
90  mOffscreenSurface = new QOffscreenSurface();
91  mOffscreenSurface->setFormat( QSurfaceFormat::defaultFormat() );
92  mOffscreenSurface->create();
93 
94  mFrameGraph = new QgsShadowRenderingFrameGraph( mOffscreenSurface, mSize, mCamera, mRoot );
97  // Set this frame graph to be in use.
98  // the render settings also sets itself as the parent of mSurfaceSelector
99  mRenderSettings->setActiveFrameGraph( mFrameGraph->frameGraphRoot() );
100 
101  // Set the root entity of the engine. This causes the engine to begin running.
102  mAspectEngine->setRootEntity( Qt3DCore::QEntityPtr( mRoot ) );
103 
104 }
105 
107 {
108  delete mAspectEngine;
109  delete mOffscreenSurface;
110 }
111 
113 {
114  mSize = s;
115 
116  mFrameGraph->setSize( mSize );
117  mCamera->setAspectRatio( float( mSize.width() ) / float( mSize.height() ) );
118 }
119 
120 void QgsOffscreen3DEngine::setClearColor( const QColor &color )
121 {
122  mFrameGraph->setClearColor( color );
123 }
124 
126 {
128 }
129 
130 void QgsOffscreen3DEngine::setRootEntity( Qt3DCore::QEntity *root )
131 {
132  // Make sure any existing scene root is unparented.
133  if ( mSceneRoot )
134  {
135  mSceneRoot->setParent( static_cast<Qt3DCore::QNode *>( nullptr ) );
136  }
137 
138  // Parent the incoming scene root to our current root entity.
139  mSceneRoot = root;
140  mSceneRoot->setParent( mRoot );
141  root->addComponent( mFrameGraph->forwardRenderLayer() );
142  root->addComponent( mFrameGraph->castShadowsLayer() );
143 }
144 
145 Qt3DRender::QRenderSettings *QgsOffscreen3DEngine::renderSettings()
146 {
147  return mRenderSettings;
148 }
149 
150 Qt3DRender::QCamera *QgsOffscreen3DEngine::camera()
151 {
152  return mCamera;
153 }
154 
156 {
157  return mSize;
158 }
159 
161 {
162  return mOffscreenSurface;
163 }
QgsOffscreen3DEngine::~QgsOffscreen3DEngine
~QgsOffscreen3DEngine() override
Definition: qgsoffscreen3dengine.cpp:106
QgsShadowRenderingFrameGraph::frameGraphRoot
Qt3DRender::QFrameGraphNode * frameGraphRoot()
Returns the root of the frame graph object.
Definition: qgsshadowrenderingframegraph.h:68
QgsShadowRenderingFrameGraph::setSize
void setSize(QSize s)
Sets the size of the buffers used for rendering.
Definition: qgsshadowrenderingframegraph.cpp:661
QgsShadowRenderingFrameGraph::castShadowsLayer
Qt3DRender::QLayer * castShadowsLayer()
Returns a layer object used to indicate that an entity will cast shadows.
Definition: qgsshadowrenderingframegraph.h:82
QgsOffscreen3DEngine::setRootEntity
void setRootEntity(Qt3DCore::QEntity *root) override
Sets root entity of the 3D scene.
Definition: qgsoffscreen3dengine.cpp:130
QgsOffscreen3DEngine::setClearColor
void setClearColor(const QColor &color) override
Sets background color of the scene.
Definition: qgsoffscreen3dengine.cpp:120
QgsAbstract3DEngine::mFrameGraph
QgsShadowRenderingFrameGraph * mFrameGraph
Definition: qgsabstract3dengine.h:139
QgsOffscreen3DEngine::camera
Qt3DRender::QCamera * camera() override
Returns pointer to the engine's camera entity.
Definition: qgsoffscreen3dengine.cpp:150
QgsShadowRenderingFrameGraph
Container class that holds different objects related to shadow rendering.
Definition: qgsshadowrenderingframegraph.h:59
QgsOffscreen3DEngine::setSize
void setSize(QSize s) override
Sets the size of the rendering area (in pixels)
Definition: qgsoffscreen3dengine.cpp:112
QgsShadowRenderingFrameGraph::forwardRenderLayer
Qt3DRender::QLayer * forwardRenderLayer()
Returns a layer object used to indicate that an entity will be rendered during the forward rendering ...
Definition: qgsshadowrenderingframegraph.h:84
QgsOffscreen3DEngine::renderSettings
Qt3DRender::QRenderSettings * renderSettings() override
Returns access to the engine's render settings (the frame graph can be accessed from here)
Definition: qgsoffscreen3dengine.cpp:145
QgsOffscreen3DEngine::surface
QSurface * surface() const override
Returns the surface of the engine.
Definition: qgsoffscreen3dengine.cpp:160
QgsShadowRenderingFrameGraph::setFrustumCullingEnabled
void setFrustumCullingEnabled(bool enabled)
Sets whether frustum culling is enabled.
Definition: qgsshadowrenderingframegraph.cpp:593
QgsOffscreen3DEngine::QgsOffscreen3DEngine
QgsOffscreen3DEngine()
Definition: qgsoffscreen3dengine.cpp:39
QgsShadowRenderingFrameGraph::setRenderCaptureEnabled
void setRenderCaptureEnabled(bool enabled)
Sets whether it will be possible to render to an image.
Definition: qgsshadowrenderingframegraph.cpp:673
QgsOffscreen3DEngine::setFrustumCullingEnabled
void setFrustumCullingEnabled(bool enabled) override
Sets whether frustum culling is enabled (this should make rendering faster by not rendering entities ...
Definition: qgsoffscreen3dengine.cpp:125
qgsoffscreen3dengine.h
qgslogger.h
QgsShadowRenderingFrameGraph::setClearColor
void setClearColor(const QColor &clearColor)
Sets the clear color of the scene (background color)
Definition: qgsshadowrenderingframegraph.cpp:565
QgsShadowRenderingFrameGraph::setShadowRenderingEnabled
void setShadowRenderingEnabled(bool enabled)
Sets whether the shadow rendering is enabled.
Definition: qgsshadowrenderingframegraph.cpp:570
QgsOffscreen3DEngine::size
QSize size() const override
Returns size of the engine's rendering area in pixels.
Definition: qgsoffscreen3dengine.cpp:155