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