QGIS API Documentation 4.1.0-Master (26185ffb827)
Loading...
Searching...
No Matches
qgspostprocessingrenderview.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgspostprocessingrenderview.cpp
3 --------------------------------------
4 Date : April 2026
5 Copyright : (C) 2026 by Benoit De Mezzo and (C) 2020 by Belgacem Nedjima
6 Email : benoit dot de dot mezzo at oslandia 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
22#include "qgsshadowrenderview.h"
23
24#include <QNode>
25#include <Qt3DRender/QCameraSelector>
26#include <Qt3DRender/QClearBuffers>
27#include <Qt3DRender/QLayer>
28#include <Qt3DRender/QLayerFilter>
29#include <Qt3DRender/QNoDraw>
30#include <Qt3DRender/QRenderCapture>
31#include <Qt3DRender/QRenderTarget>
32#include <Qt3DRender/QRenderTargetOutput>
33#include <Qt3DRender/QRenderTargetSelector>
34#include <Qt3DRender/QTexture>
35#include <Qt3DRender/qsubtreeenabler.h>
36
37QgsPostprocessingRenderView::QgsPostprocessingRenderView( const QString &viewName, QgsFrameGraph *frameGraph, QSize size, Qt3DCore::QEntity *rootSceneEntity )
38 : QgsAbstractRenderView( viewName )
39{
40 // postprocessing main rendering pass
41 Qt3DRender::QFrameGraphNode *subPassesNode = constructMainPass( size );
42
43 // sub passes:
44 Qt3DRender::QFrameGraphNode *node;
45 // 1. postprocessing real render view
46 node = constructSubPassForProcessing( frameGraph, rootSceneEntity );
47 node->setParent( subPassesNode );
48
49 // 2. texture overlay render view
50 node = constructSubPassForOverlayTexture();
51 node->setParent( subPassesNode );
52
53 // 3. render capture render view
54 node = constructSubPassForRenderCapture();
55 node->setParent( subPassesNode );
56}
57
59{
61 mRenderCaptureColorTexture->setSize( width, height );
62 mRenderCaptureDepthTexture->setSize( width, height );
63}
64
66{
67 if ( mRenderCaptureTargetSelector->isEnabled() == enabled )
68 return;
69
70 mRenderCaptureTargetSelector->setEnabled( enabled );
71}
72
73
74Qt3DRender::QRenderTarget *QgsPostprocessingRenderView::buildRenderCaptureTextures( QSize size )
75{
76 // =============== v NEEDED ONLY FOR OFFSCREEN ENGINE v
77 Qt3DRender::QRenderTarget *renderTarget = new Qt3DRender::QRenderTarget;
78
79 // Create a render target output for rendering color.
80 Qt3DRender::QRenderTargetOutput *colorOutput = new Qt3DRender::QRenderTargetOutput;
81 colorOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Color0 );
82
83 // Create a texture to render into.
84 mRenderCaptureColorTexture = new Qt3DRender::QTexture2D( colorOutput );
85 mRenderCaptureColorTexture->setSize( size.width(), size.height() );
86 mRenderCaptureColorTexture->setFormat( Qt3DRender::QAbstractTexture::RGB8_UNorm );
87 mRenderCaptureColorTexture->setMinificationFilter( Qt3DRender::QAbstractTexture::Linear );
88 mRenderCaptureColorTexture->setMagnificationFilter( Qt3DRender::QAbstractTexture::Linear );
89 mRenderCaptureColorTexture->setObjectName( mViewName + "::ColorTarget" );
90
91 // Hook the texture up to our output, and the output up to this object.
92 colorOutput->setTexture( mRenderCaptureColorTexture );
93 renderTarget->addOutput( colorOutput );
94
95 Qt3DRender::QRenderTargetOutput *depthOutput = new Qt3DRender::QRenderTargetOutput;
96
97 depthOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Depth );
98 mRenderCaptureDepthTexture = new Qt3DRender::QTexture2D( depthOutput );
99 mRenderCaptureDepthTexture->setSize( size.width(), size.height() );
100 mRenderCaptureDepthTexture->setFormat( Qt3DRender::QAbstractTexture::DepthFormat );
101 mRenderCaptureDepthTexture->setMinificationFilter( Qt3DRender::QAbstractTexture::Linear );
102 mRenderCaptureDepthTexture->setMagnificationFilter( Qt3DRender::QAbstractTexture::Linear );
103 mRenderCaptureDepthTexture->setComparisonFunction( Qt3DRender::QAbstractTexture::CompareLessEqual );
104 mRenderCaptureDepthTexture->setComparisonMode( Qt3DRender::QAbstractTexture::CompareRefToTexture );
105 mRenderCaptureDepthTexture->setObjectName( mViewName + "::DepthTarget" );
106
107 depthOutput->setTexture( mRenderCaptureDepthTexture );
108 renderTarget->addOutput( depthOutput );
109
110 return renderTarget;
111 // =============== ^ NEEDED ONLY FOR OFFSCREEN ENGINE ^
112}
113
114Qt3DRender::QFrameGraphNode *QgsPostprocessingRenderView::constructMainPass( QSize size )
115{
116 // We need to move the render target selector at the top of this branch.
117 // Doing so this allows Qt3d to have a FBO format matching the one need to do the capture
118 mRenderCaptureTargetSelector = new Qt3DRender::QRenderTargetSelector( mRendererEnabler );
119 mRenderCaptureTargetSelector->setObjectName( mViewName + "::RenderTargetSelector" );
120 mRenderCaptureTargetSelector->setEnabled( false );
121
122 // build texture part
123 Qt3DRender::QRenderTarget *renderTarget = buildRenderCaptureTextures( size );
124 mRenderCaptureTargetSelector->setTarget( renderTarget );
125
126 return mRenderCaptureTargetSelector;
127}
128
129
130Qt3DRender::QFrameGraphNode *QgsPostprocessingRenderView::constructSubPassForProcessing( QgsFrameGraph *frameGraph, Qt3DCore::QEntity *rootSceneEntity )
131{
132 Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter;
133 layerFilter->setObjectName( mViewName + "::Sub pass::Postprocessing" );
134
135 Qt3DRender::QLayer *postProcessingLayer = new Qt3DRender::QLayer();
136 postProcessingLayer->setRecursive( true );
137 layerFilter->addLayer( postProcessingLayer );
138
139 // end of this branch
140 new Qt3DRender::QClearBuffers( layerFilter );
141
142 mPostprocessingEntity = new QgsPostprocessingEntity( frameGraph, postProcessingLayer, rootSceneEntity );
143 mPostprocessingEntity->setObjectName( "PostProcessingPassEntity" );
144
145 return layerFilter;
146}
147
148Qt3DRender::QFrameGraphNode *QgsPostprocessingRenderView::constructSubPassForRenderCapture()
149{
150 Qt3DRender::QFrameGraphNode *top = new Qt3DRender::QNoDraw;
151 top->setObjectName( mViewName + "::Sub pass::RenderCapture" );
152
153 mRenderCapture = new Qt3DRender::QRenderCapture( top );
154
155 return top;
156}
157
158Qt3DRender::QFrameGraphNode *QgsPostprocessingRenderView::constructSubPassForOverlayTexture()
159{
160 mOverlayTextureRenderView = std::make_unique<QgsOverlayTextureRenderView>( mViewName + "::Sub pass::OverlayTexture" );
161 return mOverlayTextureRenderView->topGraphNode();
162}
163
164
165Qt3DRender::QRenderCapture *QgsPostprocessingRenderView::renderCapture() const
166{
167 return mRenderCapture;
168}
169
171{
172 return mPostprocessingEntity;
173}
Qt3DRender::QSubtreeEnabler * mRendererEnabler
virtual void updateWindowResize(int width, int height)
Called when 3D window is resized.
QgsAbstractRenderView(const QString &viewName)
Constructor for QgsAbstractRenderView with the specified parent object.
Container class that holds different objects related to frame graphs of 3D scenes.
An entity that is responsible for applying post processing effects.
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.
QgsPostprocessingRenderView(const QString &viewName, QgsFrameGraph *frameGraph, QSize size, Qt3DCore::QEntity *rootSceneEntity)
Default constructor.
void setOffScreenRenderCaptureEnabled(bool enabled)
Sets whether it will be possible to render to an image.
virtual void updateWindowResize(int width, int height) override
Called when 3D window is resized.