QGIS API Documentation 4.3.0-Master (bf28115e945)
Loading...
Searching...
No Matches
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
18#include "qgs3dutils.h"
21#include "qgsbloomrenderview.h"
22#include "qgsdepthrenderview.h"
25#include "qgsframegraphutils.h"
31#include "qgsshadowrenderview.h"
32#include "qgssunlightsettings.h"
33
34#include <Qt3DCore/QAttribute>
35#include <Qt3DCore/QBuffer>
36#include <Qt3DCore/QGeometry>
37#include <Qt3DRender/QAbstractTexture>
38#include <Qt3DRender/QBlendEquation>
39#include <Qt3DRender/QBlendEquationArguments>
40#include <Qt3DRender/QBlitFramebuffer>
41#include <Qt3DRender/QColorMask>
42#include <Qt3DRender/QGeometryRenderer>
43#include <Qt3DRender/QGraphicsApiFilter>
44#include <Qt3DRender/QNoDepthMask>
45#include <Qt3DRender/QNoDraw>
46#include <Qt3DRender/QSortPolicy>
47#include <Qt3DRender/QTechnique>
48
49#ifdef HAVE_TRACY
50#include "tracy/Tracy.hpp"
51#endif
52
53#include "moc_qgsframegraph.cpp"
54
55const QString QgsFrameGraph::sForwardRenderView = "forward";
56const QString QgsFrameGraph::sShadowRenderView = "shadow";
57const QString QgsFrameGraph::sAxiS3DRenderView = "3daxis";
58const QString QgsFrameGraph::sDepthRenderView = "depth";
59const QString QgsFrameGraph::sOverlayRenderView = "overlay_texture";
60const QString QgsFrameGraph::sAmbientOcclusionRenderView = "ambient_occlusion";
61const QString QgsFrameGraph::sBloomRenderView = "bloom";
62const QString QgsFrameGraph::sPostprocRenderView = "post_processing";
63const QString QgsFrameGraph::sHighlightsRenderView = "highlights";
64
65void QgsFrameGraph::constructForwardRenderPass()
66{
67 registerRenderView( std::make_unique<QgsForwardRenderView>( sForwardRenderView, mMainCamera ), sForwardRenderView );
68}
69
70void QgsFrameGraph::constructHighlightsPass()
71{
72 registerRenderView( std::make_unique<QgsHighlightsRenderView>( sHighlightsRenderView, forwardRenderView().renderTargetSelector()->target(), mMainCamera ), sHighlightsRenderView );
73}
74
75void QgsFrameGraph::constructShadowRenderPass()
76{
77 registerRenderView( std::make_unique<QgsShadowRenderView>( sShadowRenderView, mRootEntity ), sShadowRenderView );
78}
79
80void QgsFrameGraph::constructOverlayTexturePass( Qt3DRender::QFrameGraphNode *topNode )
81{
82 registerRenderView( std::make_unique<QgsOverlayTextureRenderView>( sOverlayRenderView ), sOverlayRenderView, topNode );
83}
84
85void QgsFrameGraph::constructPostprocessingPass( Qt3DRender::QFrameGraphNode *topNode )
86{
87 // create post processing render view and register it
88 QgsPostprocessingRenderView *pprv = new QgsPostprocessingRenderView( sPostprocRenderView, this, mSize, mRootEntity );
89 registerRenderView( std::unique_ptr<QgsPostprocessingRenderView>( pprv ), sPostprocRenderView, topNode );
90}
91
92void QgsFrameGraph::updateThumbnailTextureSize()
93{
94 // Tracy requires width/height to be multiples of 4, otherwise it will show
95 // just a black rectangle.
96 const int width = ( mSize.width() / 10 ) & ~3;
97 const int height = ( mSize.height() / 10 ) & ~3;
98 mThumbnailTexture->setSize( width, height );
99}
100
101void QgsFrameGraph::constructThumbnailCapturePass()
102{
103 // Diagram of the nodes we're creating:
104 // mMainViewPort
105 // ├── QBlitFramebuffer (copy from forwardRenderView to mThumbnailTexture)
106 // └── QRenderTargetSelector (set to mThumbnailTexture)
107 // └── QRenderCapture (mThumbnailCapture)
108
109 mThumbnailTexture = new Qt3DRender::QTexture2D( this );
110 mThumbnailTexture->setFormat( Qt3DRender::QAbstractTexture::RGBA8_UNorm );
111 updateThumbnailTextureSize();
112
113 Qt3DRender::QRenderTargetOutput *renderTargetOutput = new Qt3DRender::QRenderTargetOutput( this );
114 renderTargetOutput->setTexture( mThumbnailTexture );
115
116 Qt3DRender::QRenderTarget *renderTarget = new Qt3DRender::QRenderTarget( this );
117 renderTarget->addOutput( renderTargetOutput );
118
119 // Copy from forward render pass to thumbnail texture
120 Qt3DRender::QBlitFramebuffer *blit = new Qt3DRender::QBlitFramebuffer( mMainViewPort );
121 blit->setObjectName( "Framebuffer copy for thumbnail" );
122 blit->setSource( forwardRenderView().renderTargetSelector()->target() );
123 blit->setDestination( renderTarget );
124 blit->setSourceRect( QRectF( 0, 0, 1, 1 ) );
125 blit->setDestinationRect( QRectF( 0, 0, 1, 1 ) );
126 blit->setInterpolationMethod( Qt3DRender::QBlitFramebuffer::Linear );
127
128 Qt3DRender::QRenderTargetSelector *targetSelector = new Qt3DRender::QRenderTargetSelector( mMainViewPort );
129 targetSelector->setObjectName( "Thumbnail capture target selector" );
130 targetSelector->setTarget( renderTarget );
131
132 mThumbnailCapture = new Qt3DRender::QRenderCapture( targetSelector );
133 mThumbnailCapture->setObjectName( "Thumbnail capture" );
134
135 // Request initial capture
136 // Ugly hack: Requesting just once results in a capture every two frames.
137 // "Buffering" an extra capture like this works around that.
138 Qt3DRender::QRenderCaptureReply *reply1 = mThumbnailCapture->requestCapture();
139 Qt3DRender::QRenderCaptureReply *reply2 = mThumbnailCapture->requestCapture();
140 for ( Qt3DRender::QRenderCaptureReply *reply : { reply1, reply2 } )
141 connect( reply, &Qt3DRender::QRenderCaptureReply::completed, this, [this, reply]() { onThumbnailCaptureCompleted( reply ); } );
142}
143
144void QgsFrameGraph::onThumbnailCaptureCompleted( Qt3DRender::QRenderCaptureReply *reply )
145{
146 reply->deleteLater();
147
148#ifdef HAVE_TRACY
149 // Convert to RGBA8888 format (required by Tracy)
150 QImage rgbaImage = reply->image().convertToFormat( QImage::Format_RGBA8888 );
151
152 // Send to Tracy
153 FrameImage(
154 rgbaImage.constBits(),
155 static_cast<uint16_t>( rgbaImage.width() ),
156 static_cast<uint16_t>( rgbaImage.height() ),
157 0, // offset: 0 = current frame
158 true // flip Y coord: true for OpenGL
159 );
160#endif
161
162 // Request next frame capture
163 Qt3DRender::QRenderCaptureReply *nextReply = mThumbnailCapture->requestCapture();
164 connect( nextReply, &Qt3DRender::QRenderCaptureReply::completed, this, [this, nextReply]() { onThumbnailCaptureCompleted( nextReply ); } );
165}
166
167void QgsFrameGraph::constructAmbientOcclusionRenderPass()
168{
169 Qt3DRender::QTexture2D *forwardDepthTexture = forwardRenderView().depthTexture();
170
171 QgsAmbientOcclusionRenderView *aorv = new QgsAmbientOcclusionRenderView( sAmbientOcclusionRenderView, mMainCamera, mSize, forwardDepthTexture, mRootEntity );
172 registerRenderView( std::unique_ptr<QgsAmbientOcclusionRenderView>( aorv ), sAmbientOcclusionRenderView );
173}
174
175void QgsFrameGraph::constructBloomRenderPass()
176{
177 Qt3DRender::QTexture2D *forwardColorTexture = forwardRenderView().colorTexture();
178
179 QgsBloomRenderView *rv = new QgsBloomRenderView( sBloomRenderView, forwardColorTexture, mSize, mRootEntity );
180 registerRenderView( std::unique_ptr<QgsBloomRenderView>( rv ), sBloomRenderView );
181}
182
183Qt3DRender::QFrameGraphNode *QgsFrameGraph::constructRubberBandsPass()
184{
185 mRubberBandsCameraSelector = new Qt3DRender::QCameraSelector;
186 mRubberBandsCameraSelector->setObjectName( "RubberBands Pass CameraSelector" );
187 mRubberBandsCameraSelector->setCamera( mMainCamera );
188
189 mRubberBandsLayerFilter = new Qt3DRender::QLayerFilter( mRubberBandsCameraSelector );
190 mRubberBandsLayerFilter->addLayer( mRubberBandsLayer );
191
192 Qt3DRender::QBlendEquationArguments *blendState = new Qt3DRender::QBlendEquationArguments;
193 blendState->setSourceRgb( Qt3DRender::QBlendEquationArguments::SourceAlpha );
194 blendState->setDestinationRgb( Qt3DRender::QBlendEquationArguments::OneMinusSourceAlpha );
195
196 Qt3DRender::QBlendEquation *blendEquation = new Qt3DRender::QBlendEquation;
197 blendEquation->setBlendFunction( Qt3DRender::QBlendEquation::Add );
198
199 mRubberBandsStateSet = new Qt3DRender::QRenderStateSet( mRubberBandsLayerFilter );
200 Qt3DRender::QDepthTest *depthTest = new Qt3DRender::QDepthTest;
201 depthTest->setDepthFunction( Qt3DRender::QDepthTest::Always );
202 mRubberBandsStateSet->addRenderState( depthTest );
203 mRubberBandsStateSet->addRenderState( blendState );
204 mRubberBandsStateSet->addRenderState( blendEquation );
205
206 // Here we attach our drawings to the render target also used by forward pass.
207 // This is kind of okay, but as a result, post-processing effects get applied
208 // to rubber bands too. Ideally we would want them on top of everything.
209 mRubberBandsRenderTargetSelector = new Qt3DRender::QRenderTargetSelector( mRubberBandsStateSet );
210 mRubberBandsRenderTargetSelector->setTarget( forwardRenderView().renderTargetSelector()->target() );
211
212 return mRubberBandsCameraSelector;
213}
214
215void QgsFrameGraph::constructDepthRenderPass()
216{
217 // entity used to draw the depth texture and convert it to rgb image
218 Qt3DRender::QTexture2D *forwardDepthTexture = forwardRenderView().depthTexture();
219 QgsDepthRenderView *rv = new QgsDepthRenderView( sDepthRenderView, mSize, forwardDepthTexture, mRootEntity );
220 registerRenderView( std::unique_ptr<QgsDepthRenderView>( rv ), sDepthRenderView );
221}
222
223Qt3DRender::QRenderCapture *QgsFrameGraph::depthRenderCapture()
224{
226}
227
228void QgsFrameGraph::addGlobalParameters( const QList<Qt3DRender::QParameter *> &parameters )
229{
230 for ( Qt3DRender::QParameter *param : parameters )
231 {
232 mGlobalParamsStorage->addParameter( param );
233 }
234}
235
236QgsFrameGraph::QgsFrameGraph( QSurface *surface, QSize s, Qt3DRender::QCamera *mainCamera, Qt3DCore::QEntity *root )
237 : Qt3DCore::QEntity( root )
238 , mSize( s )
239{
240 // general overview of how the frame graph looks:
241 //
242 // +------------------------+ using window or
243 // | QRenderSurfaceSelector | offscreen surface
244 // +------------------------+
245 // |
246 // +-----------+
247 // | QViewport | (0,0,1,1)
248 // +-----------+
249 // |
250 // +---------------------+---------------+------------------------+-------------------+
251 // | | | | |
252 // | | | (optional) | |
253 // +--------------+ +------------------+ +-----------------+ +-----------------+ +-----------------+
254 // | shadows pass | | forward passes | | MSAA blit | | depth buffer | | post-processing |
255 // | | | (solid objects, | | (color + depth) | | processing pass | | passes |
256 // +--------------+ | transparent, | +-----------------+ +-----------------+ +-----------------+
257 // | highlights, |
258 // | rubber bands) |
259 // +------------------+
260 //
261 // Notes:
262 // - (optional) MSAA blits multisampled (4 samples) color and depth textures
263 // so that other passes can sample them
264 // - shadows pass MUST come before other forward passes, as we use the shadow
265 // information in the material shaders
266 // - depth buffer processing pass is used whenever we need depth map information
267 // (for camera navigation) and it converts depth texture to a color texture
268 // so that we can capture it with QRenderCapture - currently it is unable
269 // to capture depth buffer, only colors (see QTBUG-65155)
270 // - there are multiple post-processing passes that take rendered output
271 // of the scene, optionally apply effects (add shadows, ambient occlusion,
272 // eye dome lighting) and finally output to the given surface
273 // - there may be also two more passes when 3D axis is shown - see Qgs3DAxis
274
275 mRootEntity = root;
276 mMainCamera = mainCamera;
277
278 mRubberBandsLayer = new Qt3DRender::QLayer;
279 mRubberBandsLayer->setObjectName( "mRubberBandsLayer" );
280 mRubberBandsLayer->setRecursive( true );
281
282 mRenderSurfaceSelector = new Qt3DRender::QRenderSurfaceSelector;
283
284 QObject *surfaceObj = dynamic_cast<QObject *>( surface );
285 Q_ASSERT( surfaceObj );
286
287 mRenderSurfaceSelector->setSurface( surfaceObj );
288 mRenderSurfaceSelector->setExternalRenderTargetSize( mSize );
289
290 mMainViewPort = new Qt3DRender::QViewport( mRenderSurfaceSelector );
291 mMainViewPort->setNormalizedRect( QRectF( 0.0f, 0.0f, 1.0f, 1.0f ) );
292
293 mGlobalParamsStorage = new Qt3DRender::QRenderPassFilter( mMainViewPort );
294 mGlobalParamsStorage->setObjectName( "GlobalParametersStore" );
295
296 // shadow rendering pass -- must be constructed BEFORE the forward render pass,
297 // to ensure it always has the correct depth available.
298 constructShadowRenderPass();
299
300 // Forward render
301 constructForwardRenderPass();
302
303 // Highlighted items pass
304 constructHighlightsPass();
305
306 // rubber bands (they should be always on top)
307 Qt3DRender::QFrameGraphNode *rubberBandsPass = constructRubberBandsPass();
308 rubberBandsPass->setObjectName( "rubberBandsPass" );
309 rubberBandsPass->setParent( mGlobalParamsStorage );
310
311 mMsaaBlitNode = new Qt3DRender::QBlitFramebuffer( mGlobalParamsStorage );
312 mMsaaBlitNode->setObjectName( "MsaaBlitFramebuffer" );
313 mMsaaBlitNode->setEnabled( false );
314 new Qt3DRender::QNoDraw( mMsaaBlitNode );
315
316 mMsaaDepthBlitNode = new Qt3DRender::QBlitFramebuffer( mGlobalParamsStorage );
317 mMsaaDepthBlitNode->setObjectName( "MsaaDepthBlitFramebuffer" );
318 mMsaaDepthBlitNode->setEnabled( false );
319 new Qt3DRender::QNoDraw( mMsaaDepthBlitNode );
320
321 // depth buffer processing
322 constructDepthRenderPass();
323
324 // Ambient occlusion factor render pass
325 constructAmbientOcclusionRenderPass();
326
327 constructBloomRenderPass();
328
329 // post process
330 constructPostprocessingPass( mGlobalParamsStorage );
331
332#ifdef HAVE_TRACY
333 constructThumbnailCapturePass();
334#endif
335
336 // fix FBO incomplete issue when using globe and 3D animations export with MSAA enabled
337 // (with globe, canvas simply stays empty with FBO incomplete msg appearing on window resize)
338 Qt3DRender::QRenderTargetSelector *targetSelector = new Qt3DRender::QRenderTargetSelector( mGlobalParamsStorage );
339 targetSelector->setTarget( forwardRenderView().regularRenderTarget() );
340 mMsaaClearBuffers = new Qt3DRender::QClearBuffers( targetSelector );
341 mMsaaClearBuffers->setEnabled( false );
342 mMsaaClearBuffers->setBuffers( Qt3DRender::QClearBuffers::ColorDepthBuffer );
343 new Qt3DRender::QNoDraw( mMsaaClearBuffers );
344
345 mRubberBandsRootEntity = new Qt3DCore::QEntity( mRootEntity );
346 mRubberBandsRootEntity->setObjectName( "mRubberBandsRootEntity" );
347 mRubberBandsRootEntity->addComponent( mRubberBandsLayer );
348}
349
350void QgsFrameGraph::unregisterRenderView( const QString &name )
351{
352 if ( mRenderViewMap.find( name ) != mRenderViewMap.end() )
353 {
354 mRenderViewMap[name]->topGraphNode()->setParent( ( QNode * ) nullptr );
355 mRenderViewMap.erase( name );
356 }
357}
358
359bool QgsFrameGraph::registerRenderView( std::unique_ptr<QgsAbstractRenderView> renderView, const QString &name, Qt3DRender::QFrameGraphNode *topNode )
360{
361 bool out;
362 if ( mRenderViewMap.find( name ) == mRenderViewMap.end() )
363 {
364 mRenderViewMap[name] = std::move( renderView );
365 mRenderViewMap[name]->topGraphNode()->setParent( topNode ? topNode : mGlobalParamsStorage );
366 mRenderViewMap[name]->updateWindowResize( mSize.width(), mSize.height() );
367 out = true;
368 }
369 else
370 out = false;
371
372 return out;
373}
374
375void QgsFrameGraph::setRenderViewEnabled( const QString &name, bool enable )
376{
377 if ( mRenderViewMap[name] )
378 {
379 mRenderViewMap[name]->setEnabled( enable );
380 }
381}
382
384{
385 if ( mRenderViewMap.find( name ) != mRenderViewMap.end() )
386 {
387 return mRenderViewMap[name].get();
388 }
389 return nullptr;
390}
391
392bool QgsFrameGraph::isRenderViewEnabled( const QString &name )
393{
394 return mRenderViewMap[name] != nullptr && mRenderViewMap[name]->isEnabled();
395}
396
398{
400
401 aoRenderView.setRadius( settings.radius() );
402 aoRenderView.setIntensity( settings.intensity() );
403 aoRenderView.setThreshold( settings.threshold() );
404 aoRenderView.setEnabled( settings.isEnabled() );
405
407}
408
414
416{
418
419 renderView.setEnabled( settings.isEnabled() );
420 renderView.setFilterRadius( static_cast< float >( settings.radius() ) );
421
424}
425
430
432{
433 const QgsShadowSettings shadowSettings = mapSettings.shadowSettings();
434 const QList<QgsLightSource *> lightSources = mapSettings.lightSources();
435 if ( shadowSettings.renderShadows() )
436 {
437 const QString lightSourceId = shadowSettings.lightSource();
438 QgsLightSource *light = nullptr;
439 int globalLightIndex = 0;
440
441 QgsLightSource *backupLightSource = nullptr;
442 int backupLightSourceIndex = 0;
443 for ( int i = 0; !light && i < lightSources.size(); i++ )
444 {
445 if ( !backupLightSource )
446 {
447 if ( auto directionalLight = dynamic_cast< QgsDirectionalLightSettings * >( lightSources[i] ) )
448 {
449 backupLightSource = directionalLight;
450 backupLightSourceIndex = i;
451 }
452 else if ( auto sunLight = dynamic_cast< QgsSunLightSettings * >( lightSources[i] ) )
453 {
454 backupLightSource = sunLight;
455 backupLightSourceIndex = i;
456 }
457 }
458
459 if ( lightSources[i]->id() == lightSourceId )
460 {
461 light = lightSources[i];
462 globalLightIndex = i;
463 }
464 }
465
466 if ( !light )
467 {
468 // if we didn't find an light matching the exact ID requested, then
469 // fallback to just the first compatible light found in the scene
470 light = backupLightSource;
471 globalLightIndex = backupLightSourceIndex;
472 }
473
474 if ( light )
475 {
476 QgsVector3D lightDirection;
477 if ( auto directionalLight = dynamic_cast< QgsDirectionalLightSettings * >( light ) )
478 {
479 lightDirection = directionalLight->direction();
480 }
481 else if ( auto sunLight = dynamic_cast< QgsSunLightSettings * >( light ) )
482 {
483 lightDirection = sunLight->direction( mapSettings );
484 }
485
486 const int size = shadowSettings.qualityToMapResolution( shadowSettings.shadowQuality() );
487 shadowRenderView().setMapSize( size, size );
489
491 postprocessingRenderView().entity()->updateShadowSettings( shadowSettings, lightDirection, size, globalLightIndex );
492 }
493 }
494 else
495 {
496 shadowRenderView().setEnabled( false );
498 }
499}
500
502{
504
505 if ( !mDepthTextureDebugging && settings.debugDepthMapEnabled() )
506 {
507 Qt3DRender::QTexture2D *forwardDepthTexture = forwardRenderView().depthTexture();
508 mDepthTextureDebugging = new QgsOverlayTextureEntity( forwardDepthTexture, overlayRenderView.overlayLayer(), this );
509 }
510
511 overlayRenderView.setEnabled( settings.debugDepthMapEnabled() || settings.is2DMapOverlayEnabled() );
512
513 if ( mDepthTextureDebugging )
514 {
515 mDepthTextureDebugging->setEnabled( settings.debugDepthMapEnabled() );
516 if ( settings.debugDepthMapEnabled() )
517 mDepthTextureDebugging->setPosition( settings.debugDepthMapCorner(), settings.debugDepthMapSize() );
518 else
519 {
520 delete mDepthTextureDebugging;
521 mDepthTextureDebugging = nullptr;
522 }
523 }
524}
525
527{
528 QObject *top = mRenderSurfaceSelector;
529 while ( top->parent() && dynamic_cast<Qt3DRender::QFrameGraphNode *>( top->parent() ) )
530 top = top->parent();
531
533 context.lowestId = mMainCamera->id().id();
534 QStringList strList = QgsFrameGraphUtils::dumpFrameGraph( dynamic_cast<Qt3DRender::QFrameGraphNode *>( top ), context );
535
536 return strList.join( "\n" ) + QString( "\n" );
537}
538
540{
541 QStringList strList = QgsFrameGraphUtils::dumpSceneGraph( mRootEntity, QgsFrameGraphUtils::FgDumpContext() );
542 return strList.join( "\n" ) + QString( "\n" );
543}
544
545void QgsFrameGraph::setClearColor( const QColor &clearColor )
546{
547 forwardRenderView().setClearColor( clearColor );
548}
549
554
556{
557 mSize = s;
558 for ( auto it = mRenderViewMap.begin(); it != mRenderViewMap.end(); ++it )
559 {
560 QgsAbstractRenderView *rv = it->second.get();
561 rv->updateWindowResize( mSize.width(), mSize.height() );
562 }
563
564 mRenderSurfaceSelector->setExternalRenderTargetSize( mSize );
565
566 mMsaaBlitNode->setSourceRect( QRect( 0, 0, mSize.width(), mSize.height() ) );
567 mMsaaBlitNode->setDestinationRect( QRect( 0, 0, mSize.width(), mSize.height() ) );
568 mMsaaDepthBlitNode->setSourceRect( QRect( 0, 0, mSize.width(), mSize.height() ) );
569 mMsaaDepthBlitNode->setDestinationRect( QRect( 0, 0, mSize.width(), mSize.height() ) );
570
571 if ( mThumbnailTexture )
572 updateThumbnailTextureSize();
573}
574
575Qt3DRender::QRenderCapture *QgsFrameGraph::renderCapture()
576{
578}
579
584
589
591{
592 mMsaaEnabled = enabled;
593
594 if ( !enabled && mMsaaBlitConfigured )
595 {
596 mMsaaBlitNode->setSource( nullptr );
597 mMsaaBlitNode->setDestination( nullptr );
598 mMsaaDepthBlitNode->setSource( nullptr );
599 mMsaaDepthBlitNode->setDestination( nullptr );
600 mMsaaBlitConfigured = false;
601 mMsaaClearBuffers->setEnabled( false );
602 }
603
605
606 if ( enabled && !mMsaaBlitConfigured )
607 {
608 mMsaaBlitConfigured = true;
609 mMsaaBlitNode->setSource( forwardRenderView().msaaRenderTarget() );
610 mMsaaBlitNode->setDestination( forwardRenderView().regularRenderTarget() );
611 mMsaaBlitNode->setSourceRect( QRect( 0, 0, mSize.width(), mSize.height() ) );
612 mMsaaBlitNode->setDestinationRect( QRect( 0, 0, mSize.width(), mSize.height() ) );
613 mMsaaBlitNode->setSourceAttachmentPoint( Qt3DRender::QRenderTargetOutput::Color0 );
614 mMsaaBlitNode->setDestinationAttachmentPoint( Qt3DRender::QRenderTargetOutput::Color0 );
615 mMsaaBlitNode->setInterpolationMethod( Qt3DRender::QBlitFramebuffer::Nearest );
616
617 mMsaaDepthBlitNode->setSource( forwardRenderView().msaaRenderTarget() );
618 mMsaaDepthBlitNode->setDestination( forwardRenderView().regularRenderTarget() );
619 mMsaaDepthBlitNode->setSourceRect( QRect( 0, 0, mSize.width(), mSize.height() ) );
620 mMsaaDepthBlitNode->setDestinationRect( QRect( 0, 0, mSize.width(), mSize.height() ) );
621 mMsaaDepthBlitNode->setSourceAttachmentPoint( Qt3DRender::QRenderTargetOutput::DepthStencil );
622 mMsaaDepthBlitNode->setDestinationAttachmentPoint( Qt3DRender::QRenderTargetOutput::DepthStencil );
623 mMsaaDepthBlitNode->setInterpolationMethod( Qt3DRender::QBlitFramebuffer::Nearest );
624
625 mMsaaClearBuffers->setEnabled( true );
626 }
627
628 Qt3DRender::QRenderTarget *target = enabled ? forwardRenderView().msaaRenderTarget() : forwardRenderView().regularRenderTarget();
630 mRubberBandsRenderTargetSelector->setTarget( target );
631 mMsaaBlitNode->setEnabled( enabled );
632 mMsaaDepthBlitNode->setEnabled( enabled );
633}
634
639
640void QgsFrameGraph::addClipPlanes( int nrClipPlanes )
641{
642 forwardRenderView().addClipPlanes( nrClipPlanes );
643}
644
646{
648 return *( dynamic_cast<QgsForwardRenderView *>( rv ) );
649}
650
652{
654 return *( dynamic_cast<QgsShadowRenderView *>( rv ) );
655}
656
658{
659 QgsAbstractRenderView *rv = mRenderViewMap[QgsFrameGraph::sDepthRenderView].get();
660 return *( dynamic_cast<QgsDepthRenderView *>( rv ) );
661}
662
668
670{
671 QgsAbstractRenderView *rv = mRenderViewMap[QgsFrameGraph::sBloomRenderView].get();
672 return *( dynamic_cast<QgsBloomRenderView *>( rv ) );
673}
674
680
686
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.
QgsShadowSettings shadowSettings() const
Returns the current configuration of shadows.
QList< QgsLightSource * > lightSources() const
Returns list of directional light sources defined in the scene.
double debugDepthMapSize() const
Returns the size of the shadow map preview.
bool is2DMapOverlayEnabled() const
Returns whether 2D map overlay is enabled.
bool eyeDomeLightingEnabled() const
Returns whether eye dome lighting is used.
Base class for 3D render view.
virtual void setEnabled(bool enable)
Enable or disable via enable the render view sub tree.
virtual bool isEnabled() const
Returns true if render view is enabled.
virtual void updateWindowResize(int width, int height)
Called when 3D window is resized.
Container class that holds different objects related to ambient occlusion rendering.
void setRadius(float radius)
Delegates to QgsAmbientOcclusionRenderEntity::setRadius.
void setEnabled(bool enable) override
Enable or disable via enable the render view sub tree.
void setIntensity(float intensity)
Delegates to QgsAmbientOcclusionRenderEntity::setIntensity.
void setThreshold(float threshold)
Delegates to QgsAmbientOcclusionRenderEntity::setThreshold.
Contains the configuration of ambient occlusion rendering.
float radius() const
Returns the radius parameter of the ambient occlusion effect.
bool isEnabled() const
Returns whether ambient occlusion effect is enabled.
float intensity() const
Returns the shading factor of the ambient occlusion effect.
float threshold() const
Returns at what amount of occlusion the effect will kick in.
Container class that holds different objects related to bloom rendering.
Contains the configuration of the lighting "bloom" effect.
double radius() const
Returns the filter radius for the bloom.
bool isEnabled() const
Returns whether the bloom effect is enabled.
Contains the configuration of the scene's color grading settings, such as exposure and tone mapping.
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).
Qt3DRender::QTexture2D * colorTexture() const
Returns forward color texture.
void setDebugOverlayEnabled(bool enabled)
Sets whether debug overlay is enabled.
void setMsaaEnabled(bool enabled)
Sets whether multisample anti-aliasing (MSAA) 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.
Qt3DRender::QRenderTarget * msaaRenderTarget() const
Returns the multisampled render target used as blit source when MSAA is enabled.
Qt3DRender::QRenderTarget * regularRenderTarget() const
Returns the regular (single-sample) render target used as blit destination and postprocessing input.
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...
void addGlobalParameters(const QList< Qt3DRender::QParameter * > &parameters)
Adds additional global parameters to the graph.
void setMsaaEnabled(bool enabled)
Sets whether multisample anti-aliasing (MSAA) is enabled.
void updateAmbientOcclusionSettings(const QgsAmbientOcclusionSettings &settings)
Updates settings for ambient occlusion.
void updateEyeDomeSettings(const Qgs3DMapSettings &settings)
Updates settings for eye dome lighting.
void updateBloomSettings(const QgsBloomSettings &settings)
Updates settings for the bloom lighting effect.
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 addClipPlanes(int nrClipPlanes)
Setups nrClipPlanes clip planes in the forward pass to enable OpenGL clipping.
void updateColorGradingSettings(const QgsColorGradingSettings &settings)
Updates settings for color grading.
static const QString sPostprocRenderView
Postprocessing render view name.
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.
QgsPostprocessingRenderView & postprocessingRenderView()
Returns post processing renderview.
void setRenderCaptureEnabled(bool enabled)
Sets whether it will be possible to render to an image.
QgsAmbientOcclusionRenderView & ambientOcclusionRenderView()
Returns ambient occlusion renderview.
Qt3DRender::QRenderCapture * depthRenderCapture()
Returns the render capture object used to take an image of the depth buffer of the scene.
QgsAbstractRenderView * renderView(const QString &name)
Returns the render view named name, if any.
void removeClipPlanes()
Disables OpenGL clipping.
static const QString sOverlayRenderView
QgsDepthRenderView & depthRenderView()
Returns depth renderview.
void setClearColor(const QColor &clearColor)
Sets the clear color of the scene (background color).
static const QString sDepthRenderView
static const QString sForwardRenderView
static const QString sBloomRenderView
static const QString sShadowRenderView
void setFrustumCullingEnabled(bool enabled)
Sets whether frustum culling is enabled.
void updateShadowSettings(const Qgs3DMapSettings &mapSettings)
Updates shadow bias, light and texture size according to shadowSettings and lightSources.
void setDebugOverlayEnabled(bool enabled)
Sets whether debug overlay is enabled.
QgsHighlightsRenderView & highlightsRenderView()
Returns the highlights renderview, used for rendering highlight overlays of identified features.
static const QString sAxiS3DRenderView
void updateDebugDepthMapSettings(const Qgs3DMapSettings &settings)
Updates settings for depth debug map.
QgsForwardRenderView & forwardRenderView()
Returns forward renderview.
static const QString sAmbientOcclusionRenderView
Ambient occlusion render view name.
QgsOverlayTextureRenderView & overlayTextureRenderView()
Returns overlay texture renderview.
QString dumpSceneGraph() const
Dumps scene graph as string.
QgsShadowRenderView & shadowRenderView()
Returns shadow renderview.
void setSize(QSize s)
Sets the size of the buffers used for rendering.
QgsBloomRenderView & bloomRenderView()
Returns the bloom render view.
static const QString sHighlightsRenderView
Qt3DRender::QCamera * mainCamera()
Returns the main camera.
QgsFrameGraph(QSurface *surface, QSize s, Qt3DRender::QCamera *mainCamera, Qt3DCore::QEntity *root)
Constructor.
Qt3DRender::QRenderCapture * renderCapture()
Returns the render capture object used to take an image of the scene.
Container class that holds different objects related to highlighting identified features.
void setRenderTarget(Qt3DRender::QRenderTarget *target)
Switches the render target (called when toggling MSAA on/off).
Base class for light sources in 3d scenes.
An entity responsible for rendering an overlay texture in 3D view.
Simple render view to preview overlay textures in 3D view.
Qt3DRender::QLayer * overlayLayer() const
Returns layer in which entities must be added in the in order to be processed by this renderview.
void updateShadowSettings(const QgsShadowSettings &shadowSettings, const QgsVector3D &lightDir, int size, int globalLightIndex)
Sets shadow rendering to use a directional light.
void setAmbientOcclusionEnabled(bool enabled)
Sets whether screen space ambient occlusion is enabled.
void setShadowRenderingEnabled(bool enabled)
Sets whether shadow rendering is enabled.
void setBloomEnabled(bool enabled)
Sets whether physically based bloom is enabled.
void updateEyeDomeSettings(const Qgs3DMapSettings &settings)
Updates eye dome lighting settings from settings.
void updateBloomSettings(const QgsBloomSettings &settings)
Sets bloom rendering to use a directional light.
void setEyeDomeLightingEnabled(bool enabled)
Sets whether eye dome lighting is enabled.
void updateColorGradingSettings(const QgsColorGradingSettings &settings)
Updates settings for color grading.
Container class that holds different objects related to postprocessing rendering.
Qt3DRender::QRenderCapture * renderCapture() const
Returns the render capture object used to take an image of the postprocessing buffer of the scene.
QgsPostprocessingEntity * entity() const
Returns the QT3D entity used to do the rendering.
void setOffScreenRenderCaptureEnabled(bool enabled)
Sets whether it will be possible to render to an image.
QgsOverlayTextureRenderView * overlayTextureRenderView() const
Returns overlay texture render view.
Container class that holds different objects related to shadow rendering.
void setMapSize(int width, int height)
Update shadow depth texture size.
void setEnabled(bool enable) override
Enable or disable via enable the renderview sub tree.
Contains configuration for rendering shadows.
bool renderShadows() const
Returns whether shadow rendering is enabled.
static int qualityToMapResolution(Qgis::ShadowQuality quality)
Returns the shadow map resolution corresponding to the specified shadow quality.
QString lightSource() const
Returns the ID of the light source casting shadows.
Qgis::ShadowQuality shadowQuality() const
Returns the quality of the shadow map texture used to generate the shadows.
Definition of a sun light in a 3D map scene.
A 3D vector (similar to QVector3D) with the difference that it uses double precision instead of singl...
Definition qgsvector3d.h:33