QGIS API Documentation 3.30.0-'s-Hertogenbosch (f186b8efe0)
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 emit sizeChanged();
124}
125
126void QgsOffscreen3DEngine::setClearColor( const QColor &color )
127{
128 mFrameGraph->setClearColor( color );
129}
130
132{
134}
135
136void QgsOffscreen3DEngine::setRootEntity( Qt3DCore::QEntity *root )
137{
138 // Make sure any existing scene root is unparented.
139 if ( mSceneRoot )
140 {
141 mSceneRoot->setParent( static_cast<Qt3DCore::QNode *>( nullptr ) );
142 }
143
144 // Parent the incoming scene root to our current root entity.
145 mSceneRoot = root;
146 mSceneRoot->setParent( mRoot );
147 root->addComponent( mFrameGraph->forwardRenderLayer() );
148 root->addComponent( mFrameGraph->castShadowsLayer() );
149}
150
151Qt3DRender::QRenderSettings *QgsOffscreen3DEngine::renderSettings()
152{
153 return mRenderSettings;
154}
155
156Qt3DRender::QCamera *QgsOffscreen3DEngine::camera()
157{
158 return mCamera;
159}
160
162{
163 return mSize;
164}
165
167{
168 return mOffscreenSurface;
169}
void sizeChanged()
Emitted after a call to setSize()
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.