QGIS API Documentation 4.1.0-Master (9af12b5a203)
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
42{
43 return mCastsShadows;
44}
45
46void QgsMaterial::setCastsShadows( bool enabled )
47{
48 mCastsShadows = enabled;
49}
50
51void QgsMaterial::enableClipping( const QList<QVector4D> &clipPlanesEquations )
52{
53 Qt3DRender::QEffect *materialEffect = effect();
54 if ( !materialEffect )
55 return;
56
57 // First, disable possible existing clipping parameters
59 if ( clipPlanesEquations.isEmpty() )
60 {
61 return;
62 }
63
64 // Add #define CLIPPING to the relevant shaders
65 for ( Qt3DRender::QTechnique *technique : materialEffect->techniques() )
66 {
67 for ( Qt3DRender::QRenderPass *renderPass : technique->renderPasses() )
68 {
69 Qt3DRender::QShaderProgram *shaderProgram = renderPass->shaderProgram();
70 const QByteArray geomCode = shaderProgram->geometryShaderCode();
71 if ( !geomCode.isEmpty() )
72 {
73 const QByteArray newGeomCode = Qgs3DUtils::addDefinesToShaderCode( geomCode, QStringList( QgsMaterial::CLIP_PLANE_DEFINE ) );
74 shaderProgram->setGeometryShaderCode( newGeomCode );
75 }
76
77 const QByteArray vertexCode = shaderProgram->vertexShaderCode();
78 if ( !vertexCode.isEmpty() )
79 {
80 const QByteArray newVertexCode = Qgs3DUtils::addDefinesToShaderCode( vertexCode, QStringList( QgsMaterial::CLIP_PLANE_DEFINE ) );
81 shaderProgram->setVertexShaderCode( newVertexCode );
82 }
83 }
84 }
85
86 // Add the clipping parameters
87 const int nrClipPlanes = clipPlanesEquations.size();
88 QVariantList clipPlanesEquationsVariant = QVariantList();
89 for ( int i = 0; i < nrClipPlanes; ++i )
90 {
91 clipPlanesEquationsVariant << clipPlanesEquations[i];
92 }
93 Qt3DRender::QParameter *clipPlane = new Qt3DRender::QParameter( QgsMaterial::CLIP_PLANE_ARRAY_PARAMETER_NAME, clipPlanesEquationsVariant );
94 Qt3DRender::QParameter *clipPlaneNumber = new Qt3DRender::QParameter( QgsMaterial::CLIP_PLANE_MAX_PLANE_PARAMETER_NAME, nrClipPlanes );
95
96 materialEffect->addParameter( clipPlane );
97 materialEffect->addParameter( clipPlaneNumber );
98
99 mClippingEnabled = true;
100}
101
103{
104 Qt3DRender::QEffect *materialEffect = effect();
105 if ( !materialEffect || !mClippingEnabled )
106 return;
107
108 // Remove #define CLIPPING from the shaders
109 for ( Qt3DRender::QTechnique *technique : materialEffect->techniques() )
110 {
111 for ( Qt3DRender::QRenderPass *renderPass : technique->renderPasses() )
112 {
113 Qt3DRender::QShaderProgram *shaderProgram = renderPass->shaderProgram();
114 const QByteArray geomCode = shaderProgram->geometryShaderCode();
115 if ( !geomCode.isEmpty() )
116 {
117 const QByteArray newGeomCode = Qgs3DUtils::removeDefinesFromShaderCode( geomCode, QStringList( QgsMaterial::CLIP_PLANE_DEFINE ) );
118 shaderProgram->setGeometryShaderCode( newGeomCode );
119 }
120
121 const QByteArray vertexCode = shaderProgram->vertexShaderCode();
122 if ( !vertexCode.isEmpty() )
123 {
124 const QByteArray newVertexCode = Qgs3DUtils::removeDefinesFromShaderCode( vertexCode, QStringList( QgsMaterial::CLIP_PLANE_DEFINE ) );
125 shaderProgram->setVertexShaderCode( newVertexCode );
126 }
127 }
128 }
129
130 // Remove the parameters
131 for ( Qt3DRender::QParameter *parameter : materialEffect->parameters() )
132 {
133 const QString parameterName = parameter->name();
134 if ( parameterName == QgsMaterial::CLIP_PLANE_ARRAY_PARAMETER_NAME || parameterName == QgsMaterial::CLIP_PLANE_MAX_PLANE_PARAMETER_NAME )
135 {
136 materialEffect->removeParameter( parameter );
137 }
138 }
139
140 mClippingEnabled = false;
141}
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.
bool castsShadows() const
Returns true if the material should cast shadows.
void setCastsShadows(bool enabled)
Sets whether the material should cast shadows.
QgsMaterial(Qt3DCore::QNode *parent=nullptr)
Constructor for QgsMaterial, with the specified parent node.
~QgsMaterial() override