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