QGIS API Documentation 3.99.0-Master (26c88405ac0)
Loading...
Searching...
No Matches
qgsforwardrenderview.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsforwardrenderview.cpp
3 --------------------------------------
4 Date : June 2024
5 Copyright : (C) 2024 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
18#include <Qt3DRender/QBlendEquation>
19#include <Qt3DRender/QBlendEquationArguments>
20#include <Qt3DRender/QCamera>
21#include <Qt3DRender/QCameraSelector>
22#include <Qt3DRender/QClearBuffers>
23#include <Qt3DRender/QClipPlane>
24#include <Qt3DRender/QColorMask>
25#include <Qt3DRender/QCullFace>
26#include <Qt3DRender/QDepthTest>
27#include <Qt3DRender/QFrustumCulling>
28#include <Qt3DRender/QLayer>
29#include <Qt3DRender/QLayerFilter>
30#include <Qt3DRender/QNoDepthMask>
31#include <Qt3DRender/QParameter>
32#include <Qt3DRender/QPolygonOffset>
33#include <Qt3DRender/QRenderStateSet>
34#include <Qt3DRender/QRenderTarget>
35#include <Qt3DRender/QRenderTargetSelector>
36#include <Qt3DRender/QSortPolicy>
37#include <Qt3DRender/QTexture>
38#include <Qt3DRender/QViewport>
39#include <Qt3DRender/qsubtreeenabler.h>
40
41#if QT_VERSION >= QT_VERSION_CHECK( 5, 15, 0 )
42#include <Qt3DRender/QDebugOverlay>
43#endif
44
45QgsForwardRenderView::QgsForwardRenderView( const QString &viewName, Qt3DRender::QCamera *mainCamera )
46 : QgsAbstractRenderView( viewName )
47 , mMainCamera( mainCamera )
48{
49 mRenderLayer = new Qt3DRender::QLayer;
50 mRenderLayer->setRecursive( true );
51 mRenderLayer->setObjectName( mViewName + "::Layer" );
52
53 mTransparentObjectsLayer = new Qt3DRender::QLayer;
54 mTransparentObjectsLayer->setRecursive( true );
55 mTransparentObjectsLayer->setObjectName( mViewName + "::TransparentLayer" );
56
57 // forward rendering pass
58 buildRenderPasses();
59}
60
61Qt3DRender::QRenderTarget *QgsForwardRenderView::buildTextures()
62{
63 mColorTexture = new Qt3DRender::QTexture2D;
64 mColorTexture->setFormat( Qt3DRender::QAbstractTexture::RGB8_UNorm );
65 mColorTexture->setGenerateMipMaps( false );
66 mColorTexture->setMagnificationFilter( Qt3DRender::QTexture2D::Linear );
67 mColorTexture->setMinificationFilter( Qt3DRender::QTexture2D::Linear );
68 mColorTexture->wrapMode()->setX( Qt3DRender::QTextureWrapMode::ClampToEdge );
69 mColorTexture->wrapMode()->setY( Qt3DRender::QTextureWrapMode::ClampToEdge );
70
71 mDepthTexture = new Qt3DRender::QTexture2D;
72 mDepthTexture->setFormat( Qt3DRender::QTexture2D::TextureFormat::DepthFormat );
73 mDepthTexture->setGenerateMipMaps( false );
74 mDepthTexture->setMagnificationFilter( Qt3DRender::QTexture2D::Linear );
75 mDepthTexture->setMinificationFilter( Qt3DRender::QTexture2D::Linear );
76 mDepthTexture->wrapMode()->setX( Qt3DRender::QTextureWrapMode::ClampToEdge );
77 mDepthTexture->wrapMode()->setY( Qt3DRender::QTextureWrapMode::ClampToEdge );
78
79 Qt3DRender::QRenderTarget *renderTarget = new Qt3DRender::QRenderTarget;
80 Qt3DRender::QRenderTargetOutput *renderTargetDepthOutput = new Qt3DRender::QRenderTargetOutput;
81 renderTargetDepthOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Depth );
82 renderTargetDepthOutput->setTexture( mDepthTexture );
83 renderTarget->addOutput( renderTargetDepthOutput );
84
85 Qt3DRender::QRenderTargetOutput *renderTargetColorOutput = new Qt3DRender::QRenderTargetOutput;
86 renderTargetColorOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Color0 );
87 renderTargetColorOutput->setTexture( mColorTexture );
88 renderTarget->addOutput( renderTargetColorOutput );
89
90 return renderTarget;
91}
92
93/*
94 * We define three forward passes: one for solid objects, followed by two for transparent objects (one to write colors but no depths, one to write depths) :
95 *
96 * |
97 * +-----------------+
98 * | QCameraSelector | (using the main camera)
99 * +-----------------+
100 * |
101 * +-----------------+
102 * | QLayerFilter | (using mForwardRenderLayer)
103 * +-----------------+
104 * |
105 * +-----------------+
106 * | QRenderStateSet | define clip planes
107 * +-----------------+
108 * |
109 * +-----------------------+
110 * | QRenderTargetSelector | (write mForwardColorTexture + mForwardDepthTexture)
111 * +-----------------------+
112 * |
113 * +------------------------+---------------------+
114 * | |
115 * +-----------------+ discard +-----------------+ accept
116 * | QLayerFilter | transparent | QLayerFilter | transparent
117 * +-----------------+ objects +-----------------+ objects
118 * | |
119 * +-----------------+ use depth test +-----------------+ sort entities
120 * | QRenderStateSet | cull back faces | QSortPolicy | back to front
121 * +-----------------+ +-----------------+
122 * | |
123 * +-----------------+ +--------------------+--------------------+
124 * | QFrustumCulling | | |
125 * +-----------------+ +-----------------+ use depth tests +-----------------+ use depth tests
126 * | | QRenderStateSet | don't write depths | QRenderStateSet | write depths
127 * | +-----------------+ write colors +-----------------+ don't write colors
128 * +-----------------+ use alpha blending don't use alpha blending
129 * | QClearBuffers | color and depth no culling no culling
130 * +-----------------+
131 * |
132 * +-----------------+
133 * | QDebugOverlay |
134 * +-----------------+
135 *
136 */
137void QgsForwardRenderView::buildRenderPasses()
138{
139 mMainCameraSelector = new Qt3DRender::QCameraSelector( mRendererEnabler );
140 mMainCameraSelector->setObjectName( mViewName + "::CameraSelector" );
141 mMainCameraSelector->setCamera( mMainCamera );
142
143 mLayerFilter = new Qt3DRender::QLayerFilter( mMainCameraSelector );
144 mLayerFilter->addLayer( mRenderLayer );
145
146 mClipRenderStateSet = new Qt3DRender::QRenderStateSet( mLayerFilter );
147 mClipRenderStateSet->setObjectName( mViewName + "::Clip Plane RenderStateSet" );
148
149 Qt3DRender::QRenderTarget *renderTarget = buildTextures();
150
151 mRenderTargetSelector = new Qt3DRender::QRenderTargetSelector( mClipRenderStateSet );
152 mRenderTargetSelector->setTarget( renderTarget );
153
154 // first branch: opaque layer filter
155 Qt3DRender::QLayerFilter *opaqueObjectsFilter = new Qt3DRender::QLayerFilter( mRenderTargetSelector );
156 opaqueObjectsFilter->addLayer( mTransparentObjectsLayer );
157 opaqueObjectsFilter->setFilterMode( Qt3DRender::QLayerFilter::DiscardAnyMatchingLayers );
158
159 Qt3DRender::QRenderStateSet *renderStateSet = new Qt3DRender::QRenderStateSet( opaqueObjectsFilter );
160
161 Qt3DRender::QDepthTest *depthTest = new Qt3DRender::QDepthTest;
162 depthTest->setDepthFunction( Qt3DRender::QDepthTest::Less );
163 renderStateSet->addRenderState( depthTest );
164
165 Qt3DRender::QCullFace *cullFace = new Qt3DRender::QCullFace;
166 cullFace->setMode( Qt3DRender::QCullFace::CullingMode::Back );
167 renderStateSet->addRenderState( cullFace );
168
169 mFrustumCulling = new Qt3DRender::QFrustumCulling( renderStateSet );
170
171 mClearBuffers = new Qt3DRender::QClearBuffers( mFrustumCulling );
172 mClearBuffers->setClearColor( QColor::fromRgbF( 0.0, 0.0, 1.0, 1.0 ) );
173 mClearBuffers->setBuffers( Qt3DRender::QClearBuffers::ColorDepthBuffer );
174 mClearBuffers->setClearDepthValue( 1.0f );
175
176 // second branch: transparent layer filter - color
177 Qt3DRender::QLayerFilter *transparentObjectsLayerFilter = new Qt3DRender::QLayerFilter( mRenderTargetSelector );
178 transparentObjectsLayerFilter->addLayer( mTransparentObjectsLayer );
179 transparentObjectsLayerFilter->setFilterMode( Qt3DRender::QLayerFilter::AcceptAnyMatchingLayers );
180
181 Qt3DRender::QSortPolicy *sortPolicy = new Qt3DRender::QSortPolicy( transparentObjectsLayerFilter );
182 QVector<Qt3DRender::QSortPolicy::SortType> sortTypes;
183 sortTypes.push_back( Qt3DRender::QSortPolicy::BackToFront );
184 sortPolicy->setSortTypes( sortTypes );
185
186 Qt3DRender::QRenderStateSet *transparentObjectsRenderStateSetColor = new Qt3DRender::QRenderStateSet( sortPolicy );
187 {
188 Qt3DRender::QDepthTest *depthTest = new Qt3DRender::QDepthTest;
189 depthTest->setDepthFunction( Qt3DRender::QDepthTest::Less );
190 transparentObjectsRenderStateSetColor->addRenderState( depthTest );
191
192 Qt3DRender::QNoDepthMask *noDepthMask = new Qt3DRender::QNoDepthMask;
193 transparentObjectsRenderStateSetColor->addRenderState( noDepthMask );
194
195 Qt3DRender::QCullFace *cullFace = new Qt3DRender::QCullFace;
196 cullFace->setMode( Qt3DRender::QCullFace::CullingMode::NoCulling );
197 transparentObjectsRenderStateSetColor->addRenderState( cullFace );
198
199 Qt3DRender::QBlendEquation *blendEquation = new Qt3DRender::QBlendEquation;
200 blendEquation->setBlendFunction( Qt3DRender::QBlendEquation::Add );
201 transparentObjectsRenderStateSetColor->addRenderState( blendEquation );
202
203 Qt3DRender::QBlendEquationArguments *blendEquationArgs = new Qt3DRender::QBlendEquationArguments;
204 blendEquationArgs->setSourceRgb( Qt3DRender::QBlendEquationArguments::Blending::SourceAlpha );
205 blendEquationArgs->setDestinationRgb( Qt3DRender::QBlendEquationArguments::Blending::OneMinusSourceAlpha );
206 transparentObjectsRenderStateSetColor->addRenderState( blendEquationArgs );
207 }
208
209 // third branch: transparent layer filter - depth
210 Qt3DRender::QRenderStateSet *transparentObjectsRenderStateSetDepth = new Qt3DRender::QRenderStateSet( sortPolicy );
211 {
212 Qt3DRender::QDepthTest *depthTest = new Qt3DRender::QDepthTest;
213 depthTest->setDepthFunction( Qt3DRender::QDepthTest::Less );
214 transparentObjectsRenderStateSetDepth->addRenderState( depthTest );
215
216 Qt3DRender::QColorMask *noColorMask = new Qt3DRender::QColorMask;
217 noColorMask->setAlphaMasked( false );
218 noColorMask->setRedMasked( false );
219 noColorMask->setGreenMasked( false );
220 noColorMask->setBlueMasked( false );
221 transparentObjectsRenderStateSetDepth->addRenderState( noColorMask );
222
223 Qt3DRender::QCullFace *cullFace = new Qt3DRender::QCullFace;
224 cullFace->setMode( Qt3DRender::QCullFace::CullingMode::NoCulling );
225 transparentObjectsRenderStateSetDepth->addRenderState( cullFace );
226 }
227
228 mDebugOverlay = new Qt3DRender::QDebugOverlay( mClearBuffers );
229 mDebugOverlay->setEnabled( false );
230}
231
232void QgsForwardRenderView::updateWindowResize( int width, int height )
233{
234 mColorTexture->setSize( width, height );
235 mDepthTexture->setSize( width, height );
236}
237
238
239void QgsForwardRenderView::setClearColor( const QColor &clearColor )
240{
241 mClearBuffers->setClearColor( clearColor );
242}
243
244
246{
247 if ( enabled == mFrustumCullingEnabled )
248 return;
249 mFrustumCullingEnabled = enabled;
250 mFrustumCulling->setEnabled( enabled );
251}
252
253
255{
256 mDebugOverlay->setEnabled( enabled );
257}
258
259Qt3DRender::QTexture2D *QgsForwardRenderView::depthTexture() const
260{
261 return mDepthTexture;
262}
263
264Qt3DRender::QTexture2D *QgsForwardRenderView::colorTexture() const
265{
266 return mColorTexture;
267}
268
270{
271 for ( Qt3DRender::QRenderState *state : mClipRenderStateSet->renderStates() )
272 {
273 if ( qobject_cast<Qt3DRender::QClipPlane *>( state ) )
274 {
275 mClipRenderStateSet->removeRenderState( state );
276 }
277 }
278}
279
281{
282 // remove existing QClipPlane
284
285 // create new QClipPlane
286 for ( int i = 0; i < nrClipPlanes; ++i )
287 {
288 Qt3DRender::QClipPlane *clipPlane = new Qt3DRender::QClipPlane;
289 clipPlane->setPlaneIndex( i );
290 mClipRenderStateSet->addRenderState( clipPlane );
291 }
292}
Qt3DRender::QSubtreeEnabler * mRendererEnabler
QgsAbstractRenderView(const QString &viewName)
Constructor for QgsAbstractRenderView with the specified parent object.
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 updateWindowResize(int width, int height) override
Called when 3D window is resized.
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.
QgsForwardRenderView(const QString &viewName, Qt3DRender::QCamera *mainCamera)
Constructor with 3D scene camera.