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