QGIS API Documentation 3.43.0-Master (c4a2e9c6d2f)
qgsframegraph.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsframegraph.cpp
3 --------------------------------------
4 Date : August 2020
5 Copyright : (C) 2020 by Belgacem Nedjima
6 Email : gb underscore nedjima at esi dot dz
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 "qgsframegraph.h"
17#include "moc_qgsframegraph.cpp"
20#include "qgs3dutils.h"
21#include "qgsframegraphutils.h"
23#include "qgsshadowrenderview.h"
24
27
28#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
29#include <Qt3DRender/QAttribute>
30#include <Qt3DRender/QBuffer>
31#include <Qt3DRender/QGeometry>
32
33typedef Qt3DRender::QAttribute Qt3DQAttribute;
34typedef Qt3DRender::QBuffer Qt3DQBuffer;
35typedef Qt3DRender::QGeometry Qt3DQGeometry;
36#else
37#include <Qt3DCore/QAttribute>
38#include <Qt3DCore/QBuffer>
39#include <Qt3DCore/QGeometry>
40
41typedef Qt3DCore::QAttribute Qt3DQAttribute;
42typedef Qt3DCore::QBuffer Qt3DQBuffer;
43typedef Qt3DCore::QGeometry Qt3DQGeometry;
44#endif
45
46#include <Qt3DRender/QGeometryRenderer>
47#include <Qt3DRender/QTechnique>
48#include <Qt3DRender/QGraphicsApiFilter>
49#include <Qt3DRender/QBlendEquation>
50#include <Qt3DRender/QColorMask>
51#include <Qt3DRender/QSortPolicy>
52#include <Qt3DRender/QNoDepthMask>
53#include <Qt3DRender/QBlendEquationArguments>
54#include <Qt3DRender/QAbstractTexture>
55#include <Qt3DRender/QNoDraw>
56#include "qgsshadowrenderview.h"
58#include "qgsdepthrenderview.h"
59#include "qgsdepthentity.h"
62
63const QString QgsFrameGraph::FORWARD_RENDERVIEW = "forward";
64const QString QgsFrameGraph::SHADOW_RENDERVIEW = "shadow";
65const QString QgsFrameGraph::AXIS3D_RENDERVIEW = "3daxis";
66const QString QgsFrameGraph::DEPTH_RENDERVIEW = "depth";
67const QString QgsFrameGraph::DEBUG_RENDERVIEW = "debug_texture";
68
69void QgsFrameGraph::constructForwardRenderPass()
70{
71 registerRenderView( std::make_unique<QgsForwardRenderView>( FORWARD_RENDERVIEW, mMainCamera ), FORWARD_RENDERVIEW );
72}
73
74void QgsFrameGraph::constructShadowRenderPass()
75{
76 registerRenderView( std::make_unique<QgsShadowRenderView>( SHADOW_RENDERVIEW ), SHADOW_RENDERVIEW );
77}
78
79void QgsFrameGraph::constructDebugTexturePass( Qt3DRender::QFrameGraphNode *topNode )
80{
81 registerRenderView( std::make_unique<QgsDebugTextureRenderView>( DEBUG_RENDERVIEW ), DEBUG_RENDERVIEW, topNode );
82}
83
84Qt3DRender::QFrameGraphNode *QgsFrameGraph::constructSubPostPassForProcessing()
85{
86 Qt3DRender::QCameraSelector *cameraSelector = new Qt3DRender::QCameraSelector;
87 cameraSelector->setObjectName( "Sub pass Postprocessing" );
88 cameraSelector->setCamera( shadowRenderView().lightCamera() );
89
90 Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter( cameraSelector );
91
92 // could be the first of this branch
93 new Qt3DRender::QClearBuffers( layerFilter );
94
95 Qt3DRender::QLayer *postProcessingLayer = new Qt3DRender::QLayer();
96 mPostprocessingEntity = new QgsPostprocessingEntity( this, postProcessingLayer, mRootEntity );
97 layerFilter->addLayer( postProcessingLayer );
98 mPostprocessingEntity->setObjectName( "PostProcessingPassEntity" );
99
100 return cameraSelector;
101}
102
103Qt3DRender::QFrameGraphNode *QgsFrameGraph::constructSubPostPassForRenderCapture()
104{
105 Qt3DRender::QFrameGraphNode *top = new Qt3DRender::QNoDraw;
106 top->setObjectName( "Sub pass RenderCapture" );
107
108 mRenderCapture = new Qt3DRender::QRenderCapture( top );
109
110 return top;
111}
112
113Qt3DRender::QFrameGraphNode *QgsFrameGraph::constructPostprocessingPass()
114{
115 mRenderCaptureTargetSelector = new Qt3DRender::QRenderTargetSelector;
116 mRenderCaptureTargetSelector->setObjectName( "Postprocessing render pass" );
117 mRenderCaptureTargetSelector->setEnabled( mRenderCaptureEnabled );
118
119 Qt3DRender::QRenderTarget *renderTarget = new Qt3DRender::QRenderTarget( mRenderCaptureTargetSelector );
120
121 // The lifetime of the objects created here is managed
122 // automatically, as they become children of this object.
123
124 // Create a render target output for rendering color.
125 Qt3DRender::QRenderTargetOutput *colorOutput = new Qt3DRender::QRenderTargetOutput( renderTarget );
126 colorOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Color0 );
127
128 // Create a texture to render into.
129 mRenderCaptureColorTexture = new Qt3DRender::QTexture2D( colorOutput );
130 mRenderCaptureColorTexture->setSize( mSize.width(), mSize.height() );
131 mRenderCaptureColorTexture->setFormat( Qt3DRender::QAbstractTexture::RGB8_UNorm );
132 mRenderCaptureColorTexture->setMinificationFilter( Qt3DRender::QAbstractTexture::Linear );
133 mRenderCaptureColorTexture->setMagnificationFilter( Qt3DRender::QAbstractTexture::Linear );
134 mRenderCaptureColorTexture->setObjectName( "PostProcessingPass::ColorTarget" );
135
136 // Hook the texture up to our output, and the output up to this object.
137 colorOutput->setTexture( mRenderCaptureColorTexture );
138 renderTarget->addOutput( colorOutput );
139
140 Qt3DRender::QRenderTargetOutput *depthOutput = new Qt3DRender::QRenderTargetOutput( renderTarget );
141
142 depthOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Depth );
143 mRenderCaptureDepthTexture = new Qt3DRender::QTexture2D( depthOutput );
144 mRenderCaptureDepthTexture->setSize( mSize.width(), mSize.height() );
145 mRenderCaptureDepthTexture->setFormat( Qt3DRender::QAbstractTexture::DepthFormat );
146 mRenderCaptureDepthTexture->setMinificationFilter( Qt3DRender::QAbstractTexture::Linear );
147 mRenderCaptureDepthTexture->setMagnificationFilter( Qt3DRender::QAbstractTexture::Linear );
148 mRenderCaptureDepthTexture->setComparisonFunction( Qt3DRender::QAbstractTexture::CompareLessEqual );
149 mRenderCaptureDepthTexture->setComparisonMode( Qt3DRender::QAbstractTexture::CompareRefToTexture );
150 mRenderCaptureDepthTexture->setObjectName( "PostProcessingPass::DepthTarget" );
151
152 depthOutput->setTexture( mRenderCaptureDepthTexture );
153 renderTarget->addOutput( depthOutput );
154
155 mRenderCaptureTargetSelector->setTarget( renderTarget );
156
157 // sub passes:
158 constructSubPostPassForProcessing()->setParent( mRenderCaptureTargetSelector );
159 constructDebugTexturePass( mRenderCaptureTargetSelector );
160 constructSubPostPassForRenderCapture()->setParent( mRenderCaptureTargetSelector );
161
162 return mRenderCaptureTargetSelector;
163}
164
165Qt3DRender::QFrameGraphNode *QgsFrameGraph::constructAmbientOcclusionRenderPass()
166{
167 mAmbientOcclusionRenderCameraSelector = new Qt3DRender::QCameraSelector;
168 mAmbientOcclusionRenderCameraSelector->setObjectName( "AmbientOcclusion render pass CameraSelector" );
169 mAmbientOcclusionRenderCameraSelector->setCamera( mMainCamera );
170
171 mAmbientOcclusionRenderStateSet = new Qt3DRender::QRenderStateSet( mAmbientOcclusionRenderCameraSelector );
172
173 Qt3DRender::QDepthTest *depthRenderDepthTest = new Qt3DRender::QDepthTest;
174 depthRenderDepthTest->setDepthFunction( Qt3DRender::QDepthTest::Always );
175 ;
176 Qt3DRender::QCullFace *depthRenderCullFace = new Qt3DRender::QCullFace;
177 depthRenderCullFace->setMode( Qt3DRender::QCullFace::NoCulling );
178
179 mAmbientOcclusionRenderStateSet->addRenderState( depthRenderDepthTest );
180 mAmbientOcclusionRenderStateSet->addRenderState( depthRenderCullFace );
181
182 mAmbientOcclusionRenderLayerFilter = new Qt3DRender::QLayerFilter( mAmbientOcclusionRenderStateSet );
183
184 mAmbientOcclusionRenderCaptureTargetSelector = new Qt3DRender::QRenderTargetSelector( mAmbientOcclusionRenderLayerFilter );
185 Qt3DRender::QRenderTarget *colorRenderTarget = new Qt3DRender::QRenderTarget( mAmbientOcclusionRenderCaptureTargetSelector );
186
187 // The lifetime of the objects created here is managed
188 // automatically, as they become children of this object.
189
190 // Create a render target output for rendering color.
191 Qt3DRender::QRenderTargetOutput *colorOutput = new Qt3DRender::QRenderTargetOutput( colorRenderTarget );
192 colorOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Color0 );
193
194 // Create a texture to render into.
195 mAmbientOcclusionRenderTexture = new Qt3DRender::QTexture2D( colorOutput );
196 mAmbientOcclusionRenderTexture->setSize( mSize.width(), mSize.height() );
197 mAmbientOcclusionRenderTexture->setFormat( Qt3DRender::QAbstractTexture::R32F );
198 mAmbientOcclusionRenderTexture->setMinificationFilter( Qt3DRender::QAbstractTexture::Linear );
199 mAmbientOcclusionRenderTexture->setMagnificationFilter( Qt3DRender::QAbstractTexture::Linear );
200
201 // Hook the texture up to our output, and the output up to this object.
202 colorOutput->setTexture( mAmbientOcclusionRenderTexture );
203 colorRenderTarget->addOutput( colorOutput );
204
205 mAmbientOcclusionRenderCaptureTargetSelector->setTarget( colorRenderTarget );
206
207 Qt3DRender::QLayer *ambientOcclusionRenderLayer = new Qt3DRender::QLayer();
208 Qt3DRender::QTexture2D *forwardDepthTexture = forwardRenderView().depthTexture();
209 mAmbientOcclusionRenderEntity = new QgsAmbientOcclusionRenderEntity( forwardDepthTexture, ambientOcclusionRenderLayer, mMainCamera, mRootEntity );
210 mAmbientOcclusionRenderLayerFilter->addLayer( ambientOcclusionRenderLayer );
211
212 return mAmbientOcclusionRenderCameraSelector;
213}
214
215Qt3DRender::QFrameGraphNode *QgsFrameGraph::constructAmbientOcclusionBlurPass()
216{
217 mAmbientOcclusionBlurCameraSelector = new Qt3DRender::QCameraSelector;
218 mAmbientOcclusionBlurCameraSelector->setObjectName( "AmbientOcclusion blur pass CameraSelector" );
219 mAmbientOcclusionBlurCameraSelector->setCamera( mMainCamera );
220
221 mAmbientOcclusionBlurStateSet = new Qt3DRender::QRenderStateSet( mAmbientOcclusionBlurCameraSelector );
222
223 Qt3DRender::QDepthTest *depthRenderDepthTest = new Qt3DRender::QDepthTest;
224 depthRenderDepthTest->setDepthFunction( Qt3DRender::QDepthTest::Always );
225 ;
226 Qt3DRender::QCullFace *depthRenderCullFace = new Qt3DRender::QCullFace;
227 depthRenderCullFace->setMode( Qt3DRender::QCullFace::NoCulling );
228
229 mAmbientOcclusionBlurStateSet->addRenderState( depthRenderDepthTest );
230 mAmbientOcclusionBlurStateSet->addRenderState( depthRenderCullFace );
231
232 mAmbientOcclusionBlurLayerFilter = new Qt3DRender::QLayerFilter( mAmbientOcclusionBlurStateSet );
233
234 mAmbientOcclusionBlurRenderCaptureTargetSelector = new Qt3DRender::QRenderTargetSelector( mAmbientOcclusionBlurLayerFilter );
235 Qt3DRender::QRenderTarget *depthRenderTarget = new Qt3DRender::QRenderTarget( mAmbientOcclusionBlurRenderCaptureTargetSelector );
236
237 // The lifetime of the objects created here is managed
238 // automatically, as they become children of this object.
239
240 // Create a render target output for rendering color.
241 Qt3DRender::QRenderTargetOutput *colorOutput = new Qt3DRender::QRenderTargetOutput( depthRenderTarget );
242 colorOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Color0 );
243
244 // Create a texture to render into.
245 mAmbientOcclusionBlurTexture = new Qt3DRender::QTexture2D( colorOutput );
246 mAmbientOcclusionBlurTexture->setSize( mSize.width(), mSize.height() );
247 mAmbientOcclusionBlurTexture->setFormat( Qt3DRender::QAbstractTexture::R32F );
248 mAmbientOcclusionBlurTexture->setMinificationFilter( Qt3DRender::QAbstractTexture::Linear );
249 mAmbientOcclusionBlurTexture->setMagnificationFilter( Qt3DRender::QAbstractTexture::Linear );
250
251 // Hook the texture up to our output, and the output up to this object.
252 colorOutput->setTexture( mAmbientOcclusionBlurTexture );
253 depthRenderTarget->addOutput( colorOutput );
254
255 mAmbientOcclusionBlurRenderCaptureTargetSelector->setTarget( depthRenderTarget );
256
257 Qt3DRender::QLayer *ambientOcclusionBlurLayer = new Qt3DRender::QLayer();
258 mAmbientOcclusionBlurEntity = new QgsAmbientOcclusionBlurEntity( mAmbientOcclusionRenderTexture, ambientOcclusionBlurLayer, mRootEntity );
259 mAmbientOcclusionBlurLayerFilter->addLayer( ambientOcclusionBlurLayer );
260
261 return mAmbientOcclusionBlurCameraSelector;
262}
263
264
265Qt3DRender::QFrameGraphNode *QgsFrameGraph::constructRubberBandsPass()
266{
267 mRubberBandsCameraSelector = new Qt3DRender::QCameraSelector;
268 mRubberBandsCameraSelector->setObjectName( "RubberBands Pass CameraSelector" );
269 mRubberBandsCameraSelector->setCamera( mMainCamera );
270
271 mRubberBandsLayerFilter = new Qt3DRender::QLayerFilter( mRubberBandsCameraSelector );
272 mRubberBandsLayerFilter->addLayer( mRubberBandsLayer );
273
274 Qt3DRender::QBlendEquationArguments *blendState = new Qt3DRender::QBlendEquationArguments;
275 blendState->setSourceRgb( Qt3DRender::QBlendEquationArguments::SourceAlpha );
276 blendState->setDestinationRgb( Qt3DRender::QBlendEquationArguments::OneMinusSourceAlpha );
277
278 Qt3DRender::QBlendEquation *blendEquation = new Qt3DRender::QBlendEquation;
279 blendEquation->setBlendFunction( Qt3DRender::QBlendEquation::Add );
280
281 mRubberBandsStateSet = new Qt3DRender::QRenderStateSet( mRubberBandsLayerFilter );
282 Qt3DRender::QDepthTest *depthTest = new Qt3DRender::QDepthTest;
283 depthTest->setDepthFunction( Qt3DRender::QDepthTest::Always );
284 mRubberBandsStateSet->addRenderState( depthTest );
285 mRubberBandsStateSet->addRenderState( blendState );
286 mRubberBandsStateSet->addRenderState( blendEquation );
287
288 // Here we attach our drawings to the render target also used by forward pass.
289 // This is kind of okay, but as a result, post-processing effects get applied
290 // to rubber bands too. Ideally we would want them on top of everything.
291 mRubberBandsRenderTargetSelector = new Qt3DRender::QRenderTargetSelector( mRubberBandsStateSet );
292 mRubberBandsRenderTargetSelector->setTarget( forwardRenderView().renderTargetSelector()->target() );
293
294 return mRubberBandsCameraSelector;
295}
296
297
298void QgsFrameGraph::constructDepthRenderPass()
299{
300 // entity used to draw the depth texture and convert it to rgb image
301 Qt3DRender::QTexture2D *forwardDepthTexture = forwardRenderView().depthTexture();
302 QgsDepthRenderView *rv = new QgsDepthRenderView( DEPTH_RENDERVIEW, mSize, forwardDepthTexture, mRootEntity );
303 registerRenderView( std::unique_ptr<QgsDepthRenderView>( rv ), DEPTH_RENDERVIEW );
304}
305
306Qt3DRender::QRenderCapture *QgsFrameGraph::depthRenderCapture()
307{
309}
310
311QgsFrameGraph::QgsFrameGraph( QSurface *surface, QSize s, Qt3DRender::QCamera *mainCamera, Qt3DCore::QEntity *root )
312 : Qt3DCore::QEntity( root )
313 , mSize( s )
314{
315 // general overview of how the frame graph looks:
316 //
317 // +------------------------+ using window or
318 // | QRenderSurfaceSelector | offscreen surface
319 // +------------------------+
320 // |
321 // +-----------+
322 // | QViewport | (0,0,1,1)
323 // +-----------+
324 // |
325 // +--------------------------+-------------------+-----------------+
326 // | | | |
327 // +--------------------+ +--------------+ +-----------------+ +-----------------+
328 // | two forward passes | | shadows pass | | depth buffer | | post-processing |
329 // | (solid objects | | | | processing pass | | passes |
330 // | and transparent) | +--------------+ +-----------------+ +-----------------+
331 // +--------------------+
332 //
333 // Notes:
334 // - depth buffer processing pass is used whenever we need depth map information
335 // (for camera navigation) and it converts depth texture to a color texture
336 // so that we can capture it with QRenderCapture - currently it is unable
337 // to capture depth buffer, only colors (see QTBUG-65155)
338 // - there are multiple post-processing passes that take rendered output
339 // of the scene, optionally apply effects (add shadows, ambient occlusion,
340 // eye dome lighting) and finally output to the given surface
341 // - there may be also two more passes when 3D axis is shown - see Qgs3DAxis
342
343 mRootEntity = root;
344 mMainCamera = mainCamera;
345
346 mRubberBandsLayer = new Qt3DRender::QLayer;
347 mRubberBandsLayer->setObjectName( "mRubberBandsLayer" );
348 mRubberBandsLayer->setRecursive( true );
349
350 mRenderSurfaceSelector = new Qt3DRender::QRenderSurfaceSelector;
351
352 QObject *surfaceObj = dynamic_cast<QObject *>( surface );
353 Q_ASSERT( surfaceObj );
354
355 mRenderSurfaceSelector->setSurface( surfaceObj );
356 mRenderSurfaceSelector->setExternalRenderTargetSize( mSize );
357
358 mMainViewPort = new Qt3DRender::QViewport( mRenderSurfaceSelector );
359 mMainViewPort->setNormalizedRect( QRectF( 0.0f, 0.0f, 1.0f, 1.0f ) );
360
361 // Forward render
362 constructForwardRenderPass();
363
364 // rubber bands (they should be always on top)
365 Qt3DRender::QFrameGraphNode *rubberBandsPass = constructRubberBandsPass();
366 rubberBandsPass->setObjectName( "rubberBandsPass" );
367 rubberBandsPass->setParent( mMainViewPort );
368
369 // shadow rendering pass
370 constructShadowRenderPass();
371
372 // depth buffer processing
373 constructDepthRenderPass();
374
375 // Ambient occlusion factor render pass
376 Qt3DRender::QFrameGraphNode *ambientOcclusionFactorRender = constructAmbientOcclusionRenderPass();
377 ambientOcclusionFactorRender->setParent( mMainViewPort );
378
379 Qt3DRender::QFrameGraphNode *ambientOcclusionBlurPass = constructAmbientOcclusionBlurPass();
380 ambientOcclusionBlurPass->setParent( mMainViewPort );
381
382 // post process
383 Qt3DRender::QFrameGraphNode *postprocessingPass = constructPostprocessingPass();
384 postprocessingPass->setParent( mMainViewPort );
385 postprocessingPass->setObjectName( "PostProcessingPass" );
386
387 mRubberBandsRootEntity = new Qt3DCore::QEntity( mRootEntity );
388 mRubberBandsRootEntity->setObjectName( "mRubberBandsRootEntity" );
389 mRubberBandsRootEntity->addComponent( mRubberBandsLayer );
390}
391
392void QgsFrameGraph::unregisterRenderView( const QString &name )
393{
394 if ( mRenderViewMap.find( name ) != mRenderViewMap.end() )
395 {
396 mRenderViewMap[name]->topGraphNode()->setParent( ( QNode * ) nullptr );
397 mRenderViewMap.erase( name );
398 }
399}
400
401bool QgsFrameGraph::registerRenderView( std::unique_ptr<QgsAbstractRenderView> renderView, const QString &name, Qt3DRender::QFrameGraphNode *topNode )
402{
403 bool out;
404 if ( mRenderViewMap.find( name ) == mRenderViewMap.end() )
405 {
406 mRenderViewMap[name] = std::move( renderView );
407 mRenderViewMap[name]->topGraphNode()->setParent( topNode ? topNode : mMainViewPort );
408 mRenderViewMap[name]->updateWindowResize( mSize.width(), mSize.height() );
409 out = true;
410 }
411 else
412 out = false;
413
414 return out;
415}
416
417void QgsFrameGraph::setRenderViewEnabled( const QString &name, bool enable )
418{
419 if ( mRenderViewMap[name] )
420 {
421 mRenderViewMap[name]->setEnabled( enable );
422 }
423}
424
426{
427 if ( mRenderViewMap.find( name ) != mRenderViewMap.end() )
428 {
429 return mRenderViewMap[name].get();
430 }
431 return nullptr;
432}
433
434bool QgsFrameGraph::isRenderViewEnabled( const QString &name )
435{
436 return mRenderViewMap[name] != nullptr && mRenderViewMap[name]->isEnabled();
437}
438
439void QgsFrameGraph::updateShadowSettings( const QgsShadowSettings &shadowSettings, const QList<QgsLightSource *> &lightSources )
440{
441 if ( shadowSettings.renderShadows() )
442 {
443 int selectedLight = shadowSettings.selectedDirectionalLight();
444 QgsDirectionalLightSettings *light = nullptr;
445 for ( int i = 0, dirLight = 0; !light && i < lightSources.size(); i++ )
446 {
447 if ( lightSources[i]->type() == Qgis::LightSourceType::Directional )
448 {
449 if ( dirLight == selectedLight )
450 light = qgis::down_cast< QgsDirectionalLightSettings * >( lightSources[i] );
451 dirLight++;
452 }
453 }
454
455 if ( light )
456 {
457 shadowRenderView().setMapSize( shadowSettings.shadowMapResolution(), shadowSettings.shadowMapResolution() );
459 mPostprocessingEntity->setShadowRenderingEnabled( true );
460 mPostprocessingEntity->setShadowBias( static_cast<float>( shadowSettings.shadowBias() ) );
461 mPostprocessingEntity->updateShadowSettings( *light, static_cast<float>( shadowSettings.maximumShadowRenderingDistance() ) );
462 }
463 }
464 else
465 {
466 shadowRenderView().setEnabled( false );
467 mPostprocessingEntity->setShadowRenderingEnabled( false );
468 }
469}
470
472{
473 QgsDebugTextureRenderView *debugRenderView = dynamic_cast<QgsDebugTextureRenderView *>( mRenderViewMap[DEBUG_RENDERVIEW].get() );
474 if ( !mShadowTextureDebugging && settings.debugShadowMapEnabled() )
475 {
476 Qt3DRender::QTexture2D *shadowDepthTexture = shadowRenderView().mapTexture();
477 mShadowTextureDebugging = new QgsDebugTextureEntity( shadowDepthTexture, debugRenderView->debugLayer(), this );
478 }
479
480 debugRenderView->setEnabled( settings.debugShadowMapEnabled() || settings.debugDepthMapEnabled() );
481
482 if ( mShadowTextureDebugging )
483 {
484 mShadowTextureDebugging->setEnabled( settings.debugShadowMapEnabled() );
485 if ( settings.debugShadowMapEnabled() )
486 mShadowTextureDebugging->setPosition( settings.debugShadowMapCorner(), settings.debugShadowMapSize() );
487 else
488 {
489 delete mShadowTextureDebugging;
490 mShadowTextureDebugging = nullptr;
491 }
492 }
493}
494
496{
497 QgsDebugTextureRenderView *debugRenderView = dynamic_cast<QgsDebugTextureRenderView *>( mRenderViewMap[DEBUG_RENDERVIEW].get() );
498 if ( !mDepthTextureDebugging && settings.debugDepthMapEnabled() )
499 {
500 Qt3DRender::QTexture2D *forwardDepthTexture = forwardRenderView().depthTexture();
501 mDepthTextureDebugging = new QgsDebugTextureEntity( forwardDepthTexture, debugRenderView->debugLayer(), this );
502 }
503
504 debugRenderView->setEnabled( settings.debugShadowMapEnabled() || settings.debugDepthMapEnabled() );
505
506 if ( mDepthTextureDebugging )
507 {
508 mDepthTextureDebugging->setEnabled( settings.debugDepthMapEnabled() );
509 if ( settings.debugDepthMapEnabled() )
510 mDepthTextureDebugging->setPosition( settings.debugDepthMapCorner(), settings.debugDepthMapSize() );
511 else
512 {
513 delete mDepthTextureDebugging;
514 mDepthTextureDebugging = nullptr;
515 }
516 }
517}
518
520{
521 QObject *top = mRenderSurfaceSelector;
522 while ( top->parent() && dynamic_cast<Qt3DRender::QFrameGraphNode *>( top->parent() ) )
523 top = top->parent();
524
526 context.lowestId = mMainCamera->id().id();
527 QStringList strList = QgsFrameGraphUtils::dumpFrameGraph( dynamic_cast<Qt3DRender::QFrameGraphNode *>( top ), context );
528
529 return strList.join( "\n" ) + QString( "\n" );
530}
531
533{
534 QStringList strList = QgsFrameGraphUtils::dumpSceneGraph( mRootEntity, QgsFrameGraphUtils::FgDumpContext() );
535 return strList.join( "\n" ) + QString( "\n" );
536}
537
538void QgsFrameGraph::setClearColor( const QColor &clearColor )
539{
540 forwardRenderView().setClearColor( clearColor );
541}
542
544{
545 mAmbientOcclusionEnabled = enabled;
546 mAmbientOcclusionRenderEntity->setEnabled( enabled );
547 mPostprocessingEntity->setAmbientOcclusionEnabled( enabled );
548}
549
551{
552 mAmbientOcclusionIntensity = intensity;
553 mAmbientOcclusionRenderEntity->setIntensity( intensity );
554}
555
557{
558 mAmbientOcclusionRadius = radius;
559 mAmbientOcclusionRenderEntity->setRadius( radius );
560}
561
563{
564 mAmbientOcclusionThreshold = threshold;
565 mAmbientOcclusionRenderEntity->setThreshold( threshold );
566}
567
572
573void QgsFrameGraph::setupEyeDomeLighting( bool enabled, double strength, int distance )
574{
575 mEyeDomeLightingEnabled = enabled;
576 mEyeDomeLightingStrength = strength;
577 mEyeDomeLightingDistance = distance;
578 mPostprocessingEntity->setEyeDomeLightingEnabled( enabled );
579 mPostprocessingEntity->setEyeDomeLightingStrength( strength );
580 mPostprocessingEntity->setEyeDomeLightingDistance( distance );
581}
582
584{
585 mSize = s;
586 for ( auto it = mRenderViewMap.begin(); it != mRenderViewMap.end(); ++it )
587 {
588 QgsAbstractRenderView *rv = it->second.get();
589 rv->updateWindowResize( mSize.width(), mSize.height() );
590 }
591
592 mRenderCaptureColorTexture->setSize( mSize.width(), mSize.height() );
593 mRenderCaptureDepthTexture->setSize( mSize.width(), mSize.height() );
594 mRenderSurfaceSelector->setExternalRenderTargetSize( mSize );
595
596 mAmbientOcclusionRenderTexture->setSize( mSize.width(), mSize.height() );
597 mAmbientOcclusionBlurTexture->setSize( mSize.width(), mSize.height() );
598}
599
601{
602 if ( enabled == mRenderCaptureEnabled )
603 return;
604 mRenderCaptureEnabled = enabled;
605 mRenderCaptureTargetSelector->setEnabled( mRenderCaptureEnabled );
606}
607
612
617
618void QgsFrameGraph::addClipPlanes( int nrClipPlanes )
619{
620 forwardRenderView().addClipPlanes( nrClipPlanes );
621}
622
624{
626 return *( dynamic_cast<QgsForwardRenderView *>( rv ) );
627}
628
630{
632 return *( dynamic_cast<QgsShadowRenderView *>( rv ) );
633}
634
636{
637 QgsAbstractRenderView *rv = mRenderViewMap[QgsFrameGraph::DEPTH_RENDERVIEW].get();
638 return *( dynamic_cast<QgsDepthRenderView *>( rv ) );
639}
@ Directional
Directional light source.
Definition of the world.
Qt::Corner debugDepthMapCorner() const
Returns the corner where the shadow map preview is displayed.
bool debugDepthMapEnabled() const
Returns whether the shadow map debugging is enabled.
Qt::Corner debugShadowMapCorner() const
Returns the corner where the shadow map preview is displayed.
double debugDepthMapSize() const
Returns the size of the shadow map preview.
double debugShadowMapSize() const
Returns the size of the shadow map preview.
bool debugShadowMapEnabled() const
Returns whether the shadow map debugging is enabled.
Base class for 3D render view.
virtual void setEnabled(bool enable)
Enable or disable via enable the render view sub tree.
virtual void updateWindowResize(int width, int height)
Called when 3D window is resized.
An entity that is responsible for blurring the ambient occlusion factor texture.
An entity that is responsible for producing an ambient occlusion factor map.
void setThreshold(float threshold)
Sets the amount of occlusion when the effects starts to kick in.
void setRadius(float radius)
Sets the radius for the ambient occlusion effect.
void setIntensity(float intensity)
Sets the intensity for the ambient occlusion effect.
An entity that is responsible for debugging texture.
void setPosition(Qt::Corner corner, double size)
Sets the texture debugging parameters.
Simple renderview to preview/debug textures.
Qt3DRender::QLayer * debugLayer() const
Returns layer in which entities must be added in the in order to be processed by this renderview.
Container class that holds different objects related to depth rendering.
Qt3DRender::QRenderCapture * renderCapture()
Returns the render capture object used to take an image of the depth buffer of the scene.
Definition of a directional light in a 3D map scene.
Container class that holds different objects related to forward rendering.
void setClearColor(const QColor &clearColor)
Sets the clear color of the scene (background color)
void setDebugOverlayEnabled(bool enabled)
Sets whether debug overlay is enabled.
void setFrustumCullingEnabled(bool enabled)
Sets whether frustum culling is enabled.
Qt3DRender::QTexture2D * depthTexture() const
Returns forward depth texture.
void addClipPlanes(int nrClipPlanes)
Setups nrClipPlanes clip planes in the forward pass to enable OpenGL clipping.
void removeClipPlanes()
Disables OpenGL clipping.
static QStringList dumpFrameGraph(const Qt3DCore::QNode *node, FgDumpContext context)
Returns a tree view of the frame graph starting from node. The object ids will be given relatively to...
static QStringList dumpSceneGraph(const Qt3DCore::QNode *node, FgDumpContext context)
Returns a tree view of the scene graph starting from node. The object ids will be given relatively to...
bool isRenderViewEnabled(const QString &name)
Returns true if the render view named name is found and enabled.
void setRenderViewEnabled(const QString &name, bool enable)
Enables or disables the render view named name according to enable.
void updateShadowSettings(const QgsShadowSettings &shadowSettings, const QList< QgsLightSource * > &lightSources)
Updates shadow bias, light and texture size according to shadowSettings and lightSources.
void addClipPlanes(int nrClipPlanes)
Setups nrClipPlanes clip planes in the forward pass to enable OpenGL clipping.
void unregisterRenderView(const QString &name)
Unregisters the render view named name, if any.
bool registerRenderView(std::unique_ptr< QgsAbstractRenderView > renderView, const QString &name, Qt3DRender::QFrameGraphNode *topNode=nullptr)
Registers a new the render view renderView with name name.
QString dumpFrameGraph() const
Dumps frame graph as string.
void setRenderCaptureEnabled(bool enabled)
Sets whether it will be possible to render to an image.
Qt3DRender::QRenderCapture * depthRenderCapture()
Returns the render capture object used to take an image of the depth buffer of the scene.
void updateDebugShadowMapSettings(const Qgs3DMapSettings &settings)
Updates settings for shadows debug map.
QgsAbstractRenderView * renderView(const QString &name)
Returns the render view named name, if any.
void removeClipPlanes()
Disables OpenGL clipping.
QgsDepthRenderView & depthRenderView()
Returns depth renderview.
void setClearColor(const QColor &clearColor)
Sets the clear color of the scene (background color)
void setAmbientOcclusionIntensity(float intensity)
Sets the ambient occlusion intensity.
static const QString FORWARD_RENDERVIEW
void setFrustumCullingEnabled(bool enabled)
Sets whether frustum culling is enabled.
static const QString SHADOW_RENDERVIEW
void setDebugOverlayEnabled(bool enabled)
Sets whether debug overlay is enabled.
void updateDebugDepthMapSettings(const Qgs3DMapSettings &settings)
Updates settings for depth debug map.
static const QString AXIS3D_RENDERVIEW
QgsForwardRenderView & forwardRenderView()
Returns forward renderview.
void setAmbientOcclusionThreshold(float threshold)
Sets the ambient occlusion threshold.
QString dumpSceneGraph() const
Dumps scene graph as string.
QgsShadowRenderView & shadowRenderView()
Returns shadow renderview.
static const QString DEBUG_RENDERVIEW
void setupEyeDomeLighting(bool enabled, double strength, int distance)
Sets eye dome lighting shading related settings.
void setSize(QSize s)
Sets the size of the buffers used for rendering.
void setAmbientOcclusionEnabled(bool enabled)
Sets whether Screen Space Ambient Occlusion will be enabled.
static const QString DEPTH_RENDERVIEW
void setAmbientOcclusionRadius(float radius)
Sets the ambient occlusion radius.
Qt3DRender::QCamera * mainCamera()
Returns the main camera.
QgsFrameGraph(QSurface *surface, QSize s, Qt3DRender::QCamera *mainCamera, Qt3DCore::QEntity *root)
Constructor.
An entity that is responsible for applying post processing effects.
void setAmbientOcclusionEnabled(bool enabled)
Sets whether screen space ambient occlusion is enabled.
void setShadowRenderingEnabled(bool enabled)
Sets whether shadow rendering is enabled.
void updateShadowSettings(const QgsDirectionalLightSettings &light, float maximumShadowRenderingDistance)
Sets shadow rendering to use a directional light.
void setEyeDomeLightingDistance(int distance)
Sets the eye dome lighting distance (contributes to the contrast of the image)
void setShadowBias(float shadowBias)
Sets the shadow bias value.
void setEyeDomeLightingStrength(double strength)
Sets the eye dome lighting strength.
void setEyeDomeLightingEnabled(bool enabled)
Sets whether eye dome lighting is enabled.
Container class that holds different objects related to shadow rendering.
void setMapSize(int width, int height)
Update shadow depth texture size.
virtual void setEnabled(bool enable) override
Enable or disable via enable the renderview sub tree.
Qt3DRender::QTexture2D * mapTexture() const
Returns shadow depth texture.
Contains configuration for rendering shadows.
int selectedDirectionalLight() const
Returns the selected direcctional light used to cast shadows.
bool renderShadows() const
Returns whether shadow rendering is enabled.
int shadowMapResolution() const
Returns the resolution of the shadow map texture used to generate the shadows.
double maximumShadowRenderingDistance() const
Returns the maximum shadow rendering distance accounted for when rendering shadows Objects further aw...
double shadowBias() const
Returns the shadow bias used to correct the numerical imprecision of shadows (for the depth test) Thi...
Qt3DCore::QAttribute Qt3DQAttribute
Qt3DCore::QBuffer Qt3DQBuffer
Qt3DCore::QGeometry Qt3DQGeometry