QGIS API Documentation 3.41.0-Master (cea29feecf2)
Loading...
Searching...
No Matches
qgsmaterial.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsmaterial.cpp
3 --------------------------------------
4 Date : July 2024
5 Copyright : (C) 2024 by Jean Felder
6 Email : jean dot felder 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
16#include "qgsmaterial.h"
17#include "moc_qgsmaterial.cpp"
18#include "qgs3dutils.h"
19
20#include <Qt3DRender/QEffect>
21#include <Qt3DRender/QParameter>
22#include <Qt3DRender/QTechnique>
23#include <Qt3DRender/QRenderPass>
24
25const QString QgsMaterial::CLIP_PLANE_ARRAY_PARAMETER_NAME = QStringLiteral( "clipPlane[0]" );
26const QString QgsMaterial::CLIP_PLANE_MAX_PLANE_PARAMETER_NAME = QStringLiteral( "max_plane_real" );
27const QString QgsMaterial::CLIP_PLANE_DEFINE = QStringLiteral( "CLIPPING" );
28
29
31 : QMaterial( parent )
32{
33}
34
36
37void QgsMaterial::enableClipping( const QList<QVector4D> &clipPlanesEquations )
38{
39 Qt3DRender::QEffect *materialEffect = effect();
40 if ( !materialEffect )
41 return;
42
43 // First, disable possible existing clipping parameters
45 if ( clipPlanesEquations.isEmpty() )
46 {
47 return;
48 }
49
50 // Add #define CLIPPING to the relevant shaders
51 for ( Qt3DRender::QTechnique *technique : materialEffect->techniques() )
52 {
53 for ( Qt3DRender::QRenderPass *renderPass : technique->renderPasses() )
54 {
55 Qt3DRender::QShaderProgram *shaderProgram = renderPass->shaderProgram();
56 const QByteArray geomCode = shaderProgram->geometryShaderCode();
57 if ( !geomCode.isEmpty() )
58 {
59 const QByteArray newGeomCode = Qgs3DUtils::addDefinesToShaderCode( geomCode, QStringList( QgsMaterial::CLIP_PLANE_DEFINE ) );
60 shaderProgram->setGeometryShaderCode( newGeomCode );
61 }
62
63 const QByteArray vertexCode = shaderProgram->vertexShaderCode();
64 if ( !vertexCode.isEmpty() )
65 {
66 const QByteArray newVertexCode = Qgs3DUtils::addDefinesToShaderCode( vertexCode, QStringList( QgsMaterial::CLIP_PLANE_DEFINE ) );
67 shaderProgram->setVertexShaderCode( newVertexCode );
68 }
69 }
70 }
71
72 // Add the clipping parameters
73 const int nrClipPlanes = clipPlanesEquations.size();
74 QVariantList clipPlanesEquationsVariant = QVariantList();
75 for ( int i = 0; i < nrClipPlanes; ++i )
76 {
77 clipPlanesEquationsVariant << clipPlanesEquations[i];
78 }
79 Qt3DRender::QParameter *clipPlane = new Qt3DRender::QParameter( QgsMaterial::CLIP_PLANE_ARRAY_PARAMETER_NAME, clipPlanesEquationsVariant );
80 Qt3DRender::QParameter *clipPlaneNumber = new Qt3DRender::QParameter( QgsMaterial::CLIP_PLANE_MAX_PLANE_PARAMETER_NAME, nrClipPlanes );
81
82 materialEffect->addParameter( clipPlane );
83 materialEffect->addParameter( clipPlaneNumber );
84
85 mClippingEnabled = true;
86}
87
89{
90 Qt3DRender::QEffect *materialEffect = effect();
91 if ( !materialEffect || !mClippingEnabled )
92 return;
93
94 // Remove #define CLIPPING from the shaders
95 for ( Qt3DRender::QTechnique *technique : materialEffect->techniques() )
96 {
97 for ( Qt3DRender::QRenderPass *renderPass : technique->renderPasses() )
98 {
99 Qt3DRender::QShaderProgram *shaderProgram = renderPass->shaderProgram();
100 const QByteArray geomCode = shaderProgram->geometryShaderCode();
101 if ( !geomCode.isEmpty() )
102 {
103 const QByteArray newGeomCode = Qgs3DUtils::removeDefinesFromShaderCode( geomCode, QStringList( QgsMaterial::CLIP_PLANE_DEFINE ) );
104 shaderProgram->setGeometryShaderCode( newGeomCode );
105 }
106
107 const QByteArray vertexCode = shaderProgram->vertexShaderCode();
108 if ( !vertexCode.isEmpty() )
109 {
110 const QByteArray newVertexCode = Qgs3DUtils::removeDefinesFromShaderCode( vertexCode, QStringList( QgsMaterial::CLIP_PLANE_DEFINE ) );
111 shaderProgram->setVertexShaderCode( newVertexCode );
112 }
113 }
114 }
115
116 // Remove the parameters
117 for ( Qt3DRender::QParameter *parameter : materialEffect->parameters() )
118 {
119 const QString parameterName = parameter->name();
120 if ( parameterName == QgsMaterial::CLIP_PLANE_ARRAY_PARAMETER_NAME || parameterName == QgsMaterial::CLIP_PLANE_MAX_PLANE_PARAMETER_NAME )
121 {
122 materialEffect->removeParameter( parameter );
123 break;
124 }
125 }
126
127 mClippingEnabled = false;
128}
static QByteArray removeDefinesFromShaderCode(const QByteArray &shaderCode, const QStringList &defines)
Removes some define macros from a shader source code.
static QByteArray addDefinesToShaderCode(const QByteArray &shaderCode, const QStringList &defines)
Inserts some define macros into a shader source code.
void enableClipping(const QList< QVector4D > &clipPlanesEquations)
Adds two uniform parameters to define OpenGL clipping from clipPlanesEquations.
void disableClipping()
Removes the uniform parameters used to define OpenGL clipping.
QgsMaterial(Qt3DCore::QNode *parent=nullptr)
Constructor for QgsMaterial, with the specified parent node.
~QgsMaterial() override