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