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