QGIS API Documentation 3.99.0-Master (e9821da5c6b)
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
18#include "qgs3dutils.h"
19
20#include <QString>
21#include <Qt3DRender/QEffect>
22#include <Qt3DRender/QParameter>
23#include <Qt3DRender/QRenderPass>
24#include <Qt3DRender/QTechnique>
25
26#include "moc_qgsmaterial.cpp"
27
28using namespace Qt::StringLiterals;
29
30const QString QgsMaterial::CLIP_PLANE_ARRAY_PARAMETER_NAME = u"clipPlane[0]"_s;
31const QString QgsMaterial::CLIP_PLANE_MAX_PLANE_PARAMETER_NAME = u"max_plane_real"_s;
32const QString QgsMaterial::CLIP_PLANE_DEFINE = u"CLIPPING"_s;
33
34
36 : QMaterial( parent )
37{
38}
39
41
42void QgsMaterial::enableClipping( const QList<QVector4D> &clipPlanesEquations )
43{
44 Qt3DRender::QEffect *materialEffect = effect();
45 if ( !materialEffect )
46 return;
47
48 // First, disable possible existing clipping parameters
50 if ( clipPlanesEquations.isEmpty() )
51 {
52 return;
53 }
54
55 // Add #define CLIPPING to the relevant shaders
56 for ( Qt3DRender::QTechnique *technique : materialEffect->techniques() )
57 {
58 for ( Qt3DRender::QRenderPass *renderPass : technique->renderPasses() )
59 {
60 Qt3DRender::QShaderProgram *shaderProgram = renderPass->shaderProgram();
61 const QByteArray geomCode = shaderProgram->geometryShaderCode();
62 if ( !geomCode.isEmpty() )
63 {
64 const QByteArray newGeomCode = Qgs3DUtils::addDefinesToShaderCode( geomCode, QStringList( QgsMaterial::CLIP_PLANE_DEFINE ) );
65 shaderProgram->setGeometryShaderCode( newGeomCode );
66 }
67
68 const QByteArray vertexCode = shaderProgram->vertexShaderCode();
69 if ( !vertexCode.isEmpty() )
70 {
71 const QByteArray newVertexCode = Qgs3DUtils::addDefinesToShaderCode( vertexCode, QStringList( QgsMaterial::CLIP_PLANE_DEFINE ) );
72 shaderProgram->setVertexShaderCode( newVertexCode );
73 }
74 }
75 }
76
77 // Add the clipping parameters
78 const int nrClipPlanes = clipPlanesEquations.size();
79 QVariantList clipPlanesEquationsVariant = QVariantList();
80 for ( int i = 0; i < nrClipPlanes; ++i )
81 {
82 clipPlanesEquationsVariant << clipPlanesEquations[i];
83 }
84 Qt3DRender::QParameter *clipPlane = new Qt3DRender::QParameter( QgsMaterial::CLIP_PLANE_ARRAY_PARAMETER_NAME, clipPlanesEquationsVariant );
85 Qt3DRender::QParameter *clipPlaneNumber = new Qt3DRender::QParameter( QgsMaterial::CLIP_PLANE_MAX_PLANE_PARAMETER_NAME, nrClipPlanes );
86
87 materialEffect->addParameter( clipPlane );
88 materialEffect->addParameter( clipPlaneNumber );
89
90 mClippingEnabled = true;
91}
92
94{
95 Qt3DRender::QEffect *materialEffect = effect();
96 if ( !materialEffect || !mClippingEnabled )
97 return;
98
99 // Remove #define CLIPPING from the shaders
100 for ( Qt3DRender::QTechnique *technique : materialEffect->techniques() )
101 {
102 for ( Qt3DRender::QRenderPass *renderPass : technique->renderPasses() )
103 {
104 Qt3DRender::QShaderProgram *shaderProgram = renderPass->shaderProgram();
105 const QByteArray geomCode = shaderProgram->geometryShaderCode();
106 if ( !geomCode.isEmpty() )
107 {
108 const QByteArray newGeomCode = Qgs3DUtils::removeDefinesFromShaderCode( geomCode, QStringList( QgsMaterial::CLIP_PLANE_DEFINE ) );
109 shaderProgram->setGeometryShaderCode( newGeomCode );
110 }
111
112 const QByteArray vertexCode = shaderProgram->vertexShaderCode();
113 if ( !vertexCode.isEmpty() )
114 {
115 const QByteArray newVertexCode = Qgs3DUtils::removeDefinesFromShaderCode( vertexCode, QStringList( QgsMaterial::CLIP_PLANE_DEFINE ) );
116 shaderProgram->setVertexShaderCode( newVertexCode );
117 }
118 }
119 }
120
121 // Remove the parameters
122 for ( Qt3DRender::QParameter *parameter : materialEffect->parameters() )
123 {
124 const QString parameterName = parameter->name();
125 if ( parameterName == QgsMaterial::CLIP_PLANE_ARRAY_PARAMETER_NAME || parameterName == QgsMaterial::CLIP_PLANE_MAX_PLANE_PARAMETER_NAME )
126 {
127 materialEffect->removeParameter( parameter );
128 }
129 }
130
131 mClippingEnabled = false;
132}
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