QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
qgsphongmaterialsettings.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsphongmaterialsettings.cpp
3 --------------------------------------
4 Date : July 2017
5 Copyright : (C) 2017 by Martin Dobias
6 Email : wonder dot sk at gmail 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
17
18#include "qgssymbollayerutils.h"
19#include <Qt3DExtras/QDiffuseSpecularMaterial>
20#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
21#include <Qt3DRender/QAttribute>
22#include <Qt3DRender/QBuffer>
23#include <Qt3DRender/QGeometry>
24
25typedef Qt3DRender::QAttribute Qt3DQAttribute;
26typedef Qt3DRender::QBuffer Qt3DQBuffer;
27typedef Qt3DRender::QGeometry Qt3DQGeometry;
28#else
29#include <Qt3DCore/QAttribute>
30#include <Qt3DCore/QBuffer>
31#include <Qt3DCore/QGeometry>
32
33typedef Qt3DCore::QAttribute Qt3DQAttribute;
34typedef Qt3DCore::QBuffer Qt3DQBuffer;
35typedef Qt3DCore::QGeometry Qt3DQGeometry;
36#endif
37#include <Qt3DRender/QParameter>
38#include <Qt3DRender/QEffect>
39#include <Qt3DRender/QTechnique>
40#include <Qt3DRender/QGraphicsApiFilter>
41#include <QMap>
42
43
45{
46 return QStringLiteral( "phong" );
47}
48
50{
51 switch ( technique )
52 {
59 return true;
60
62 return false;
63 }
64 return false;
65}
66
68{
69 return new QgsPhongMaterialSettings();
70}
71
73{
74 return new QgsPhongMaterialSettings( *this );
75}
76
77void QgsPhongMaterialSettings::readXml( const QDomElement &elem, const QgsReadWriteContext &context )
78{
79 mAmbient = QgsSymbolLayerUtils::decodeColor( elem.attribute( QStringLiteral( "ambient" ), QStringLiteral( "25,25,25" ) ) );
80 mDiffuse = QgsSymbolLayerUtils::decodeColor( elem.attribute( QStringLiteral( "diffuse" ), QStringLiteral( "178,178,178" ) ) );
81 mSpecular = QgsSymbolLayerUtils::decodeColor( elem.attribute( QStringLiteral( "specular" ), QStringLiteral( "255,255,255" ) ) );
82 mShininess = elem.attribute( QStringLiteral( "shininess" ) ).toFloat();
83 mOpacity = elem.attribute( QStringLiteral( "opacity" ), QStringLiteral( "1.0" ) ).toFloat();
84
86}
87
88void QgsPhongMaterialSettings::writeXml( QDomElement &elem, const QgsReadWriteContext &context ) const
89{
90 elem.setAttribute( QStringLiteral( "ambient" ), QgsSymbolLayerUtils::encodeColor( mAmbient ) );
91 elem.setAttribute( QStringLiteral( "diffuse" ), QgsSymbolLayerUtils::encodeColor( mDiffuse ) );
92 elem.setAttribute( QStringLiteral( "specular" ), QgsSymbolLayerUtils::encodeColor( mSpecular ) );
93 elem.setAttribute( QStringLiteral( "shininess" ), mShininess );
94 elem.setAttribute( QStringLiteral( "opacity" ), mOpacity );
95
97}
98
99
101{
102 switch ( technique )
103 {
110 {
111 if ( dataDefinedProperties().hasActiveProperties() )
112 return dataDefinedMaterial();
113
114 int opacity = mOpacity * 255;
115 Qt3DExtras::QDiffuseSpecularMaterial *material = new Qt3DExtras::QDiffuseSpecularMaterial;
116 material->setDiffuse( QColor( mDiffuse.red(), mDiffuse.green(), mDiffuse.blue(), opacity ) );
117 material->setAmbient( QColor( mAmbient.red(), mAmbient.green(), mAmbient.blue(), opacity ) );
118 material->setSpecular( QColor( mSpecular.red(), mSpecular.green(), mSpecular.blue(), opacity ) );
119 material->setShininess( mShininess );
120 if ( mOpacity != 1 )
121 {
122 material->setAlphaBlendingEnabled( true );
123 }
124
125 if ( context.isSelected() )
126 {
127 // update the material with selection colors
128 material->setDiffuse( context.selectionColor() );
129 material->setAmbient( context.selectionColor().darker() );
130 }
131 return material;
132 }
133
135 return nullptr;
136 }
137 return nullptr;
138}
139
141{
142 QMap<QString, QString> parameters;
143 parameters[ QStringLiteral( "Kd" ) ] = QStringLiteral( "%1 %2 %3" ).arg( mDiffuse.redF() ).arg( mDiffuse.greenF() ).arg( mDiffuse.blueF() );
144 parameters[ QStringLiteral( "Ka" ) ] = QStringLiteral( "%1 %2 %3" ).arg( mAmbient.redF() ).arg( mAmbient.greenF() ).arg( mAmbient.blueF() );
145 parameters[ QStringLiteral( "Ks" ) ] = QStringLiteral( "%1 %2 %3" ).arg( mSpecular.redF() ).arg( mSpecular.greenF() ).arg( mSpecular.blueF() );
146 parameters[ QStringLiteral( "Ns" ) ] = QString::number( mShininess );
147 return parameters;
148}
149
150void QgsPhongMaterialSettings::addParametersToEffect( Qt3DRender::QEffect *effect ) const
151{
152 Qt3DRender::QParameter *ambientParameter = new Qt3DRender::QParameter( QStringLiteral( "ka" ), mAmbient );
153 Qt3DRender::QParameter *diffuseParameter = new Qt3DRender::QParameter( QStringLiteral( "kd" ), mDiffuse );
154 Qt3DRender::QParameter *specularParameter = new Qt3DRender::QParameter( QStringLiteral( "ks" ), mSpecular );
155 Qt3DRender::QParameter *shininessParameter = new Qt3DRender::QParameter( QStringLiteral( "shininess" ), mShininess );
156 Qt3DRender::QParameter *opacityParameter = new Qt3DRender::QParameter( QStringLiteral( "opacity" ), mOpacity );
157
158 effect->addParameter( ambientParameter );
159 effect->addParameter( diffuseParameter );
160 effect->addParameter( specularParameter );
161 effect->addParameter( shininessParameter );
162 effect->addParameter( opacityParameter );
163}
164
166{
167 const QColor ambient = dataDefinedProperties().valueAsColor( Ambient, expressionContext, mAmbient );
168 const QColor diffuse = dataDefinedProperties().valueAsColor( Diffuse, expressionContext, mDiffuse );
169 const QColor specular = dataDefinedProperties().valueAsColor( Specular, expressionContext, mSpecular );
170
171 QByteArray array;
172 array.resize( sizeof( unsigned char ) * 9 );
173 unsigned char *fptr = reinterpret_cast<unsigned char *>( array.data() );
174
175 *fptr++ = static_cast<unsigned char>( diffuse.red() );
176 *fptr++ = static_cast<unsigned char>( diffuse.green() );
177 *fptr++ = static_cast<unsigned char>( diffuse.blue() );
178
179 *fptr++ = static_cast<unsigned char>( ambient.red() );
180 *fptr++ = static_cast<unsigned char>( ambient.green() );
181 *fptr++ = static_cast<unsigned char>( ambient.blue() );
182
183 *fptr++ = static_cast<unsigned char>( specular.red() );
184 *fptr++ = static_cast<unsigned char>( specular.green() );
185 *fptr++ = static_cast<unsigned char>( specular.blue() );
186
187 return array;
188}
189
190int QgsPhongMaterialSettings::dataDefinedByteStride() const {return 9 * sizeof( unsigned char );}
191
192void QgsPhongMaterialSettings::applyDataDefinedToGeometry( Qt3DQGeometry *geometry, int vertexCount, const QByteArray &data ) const
193{
194 Qt3DQBuffer *dataBuffer = new Qt3DQBuffer( geometry );
195
196 Qt3DQAttribute *diffuseAttribute = new Qt3DQAttribute( geometry );
197 diffuseAttribute->setName( QStringLiteral( "dataDefinedDiffuseColor" ) );
198 diffuseAttribute->setVertexBaseType( Qt3DQAttribute::UnsignedByte );
199 diffuseAttribute->setVertexSize( 3 );
200 diffuseAttribute->setAttributeType( Qt3DQAttribute::VertexAttribute );
201 diffuseAttribute->setBuffer( dataBuffer );
202 diffuseAttribute->setByteStride( 9 * sizeof( unsigned char ) );
203 diffuseAttribute->setByteOffset( 0 );
204 diffuseAttribute->setCount( vertexCount );
205 geometry->addAttribute( diffuseAttribute );
206
207 Qt3DQAttribute *ambientAttribute = new Qt3DQAttribute( geometry );
208 ambientAttribute->setName( QStringLiteral( "dataDefinedAmbiantColor" ) );
209 ambientAttribute->setVertexBaseType( Qt3DQAttribute::UnsignedByte );
210 ambientAttribute->setVertexSize( 3 );
211 ambientAttribute->setAttributeType( Qt3DQAttribute::VertexAttribute );
212 ambientAttribute->setBuffer( dataBuffer );
213 ambientAttribute->setByteStride( 9 * sizeof( unsigned char ) );
214 ambientAttribute->setByteOffset( 3 * sizeof( unsigned char ) );
215 ambientAttribute->setCount( vertexCount );
216 geometry->addAttribute( ambientAttribute );
217
218 Qt3DQAttribute *specularAttribute = new Qt3DQAttribute( geometry );
219 specularAttribute->setName( QStringLiteral( "dataDefinedSpecularColor" ) );
220 specularAttribute->setVertexBaseType( Qt3DQAttribute::UnsignedByte );
221 specularAttribute->setVertexSize( 3 );
222 specularAttribute->setAttributeType( Qt3DQAttribute::VertexAttribute );
223 specularAttribute->setBuffer( dataBuffer );
224 specularAttribute->setByteStride( 9 * sizeof( unsigned char ) );
225 specularAttribute->setByteOffset( 6 * sizeof( unsigned char ) );
226 specularAttribute->setCount( vertexCount );
227 geometry->addAttribute( specularAttribute );
228
229 dataBuffer->setData( data );
230}
231
232Qt3DRender::QMaterial *QgsPhongMaterialSettings::dataDefinedMaterial() const
233{
234 Qt3DRender::QMaterial *material = new Qt3DRender::QMaterial;
235
236 Qt3DRender::QEffect *eff = new Qt3DRender::QEffect( material );
237
238 Qt3DRender::QTechnique *technique = new Qt3DRender::QTechnique;
239 technique->graphicsApiFilter()->setApi( Qt3DRender::QGraphicsApiFilter::OpenGL );
240 technique->graphicsApiFilter()->setProfile( Qt3DRender::QGraphicsApiFilter::CoreProfile );
241 technique->graphicsApiFilter()->setMajorVersion( 3 );
242 technique->graphicsApiFilter()->setMinorVersion( 3 );
243 Qt3DRender::QFilterKey *filterKey = new Qt3DRender::QFilterKey();
244 filterKey->setName( QStringLiteral( "renderingStyle" ) );
245 filterKey->setValue( QStringLiteral( "forward" ) );
246 technique->addFilterKey( filterKey );
247
248 Qt3DRender::QRenderPass *renderPass = new Qt3DRender::QRenderPass();
249 Qt3DRender::QShaderProgram *shaderProgram = new Qt3DRender::QShaderProgram();
250
251 //Load shader programs
252 const QUrl urlVert( QStringLiteral( "qrc:/shaders/phongDataDefined.vert" ) );
253 shaderProgram->setShaderCode( Qt3DRender::QShaderProgram::Vertex, Qt3DRender::QShaderProgram::loadSource( urlVert ) );
254 const QUrl urlFrag( QStringLiteral( "qrc:/shaders/phongDataDefined.frag" ) );
255 shaderProgram->setShaderCode( Qt3DRender::QShaderProgram::Fragment, Qt3DRender::QShaderProgram::loadSource( urlFrag ) );
256
257 renderPass->setShaderProgram( shaderProgram );
258 technique->addRenderPass( renderPass );
259
260 eff->addParameter( new Qt3DRender::QParameter( QStringLiteral( "shininess" ), mShininess ) );
261 eff->addParameter( new Qt3DRender::QParameter( QStringLiteral( "opacity" ), mOpacity ) );
262
263 eff->addTechnique( technique );
264 material->setEffect( eff );
265
266 return material;
267}
virtual void writeXml(QDomElement &element, const QgsReadWriteContext &) const
Writes settings to a DOM element.
virtual void readXml(const QDomElement &element, const QgsReadWriteContext &)
Reads settings from a DOM element.
@ Ambient
Ambient color (phong material)
QgsPropertyCollection dataDefinedProperties() const
Returns the symbol material property collection, used for data defined overrides.
QColor valueAsColor(int key, const QgsExpressionContext &context, const QColor &defaultColor=QColor(), bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a color.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
QColor selectionColor() const
Returns the color for representing materials in a selected state.
bool isSelected() const
Returns true if the material should represent a selected state.
int dataDefinedByteStride() const override
Returns byte stride of the data defined colors,used to fill the vertex colors data defined buffer for...
Qt3DRender::QMaterial * toMaterial(QgsMaterialSettingsRenderingTechnique technique, const QgsMaterialContext &context) const override
Creates a new QMaterial object representing the material settings.
void addParametersToEffect(Qt3DRender::QEffect *effect) const override
Adds parameters from the material to a destination effect.
QString type() const override
Returns the unique type name for the material.
QColor diffuse() const
Returns diffuse color component.
QMap< QString, QString > toExportParameters() const override
Returns the parameters to be exported to .mtl file.
void applyDataDefinedToGeometry(Qt3DCore::QGeometry *geometry, int vertexCount, const QByteArray &data) const override
Applies the data defined bytes, dataDefinedBytes, on the geometry by filling a specific vertex buffer...
QColor specular() const
Returns specular color component.
QColor ambient() const
Returns ambient color component.
static QgsAbstractMaterialSettings * create()
Returns a new instance of QgsPhongMaterialSettings.
static bool supportsTechnique(QgsMaterialSettingsRenderingTechnique technique)
Returns true if the specified technique is supported by the Phong material.
float opacity() const
Returns the opacity of the surface.
void writeXml(QDomElement &elem, const QgsReadWriteContext &context) const override
Writes settings to a DOM element.
QgsPhongMaterialSettings * clone() const override
Clones the material settings.
QgsPhongMaterialSettings()=default
Constructor for QgsPhongMaterialSettings.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context) override
Reads settings from a DOM element.
QByteArray dataDefinedVertexColorsAsByte(const QgsExpressionContext &expressionContext) const override
Returns byte array corresponding to the data defined colors depending of the expressionContext,...
The class is used as a container of context for various read/write operations on other objects.
static QColor decodeColor(const QString &str)
static QString encodeColor(const QColor &color)
QgsMaterialSettingsRenderingTechnique
Material rendering techniques 3.
@ Points
Point based rendering, requires point data.
@ Triangles
Triangle based rendering (default)
@ TrianglesFromModel
Triangle based rendering, using a model object source.
@ Lines
Line based rendering, requires line data.
@ TrianglesDataDefined
Triangle based rendering with possibility of datadefined color.
@ InstancedPoints
Instanced based rendering, requiring triangles and point data.
@ TrianglesWithFixedTexture
Triangle based rendering, using a fixed, non-user-configurable texture (e.g. for terrain rendering)
Qt3DCore::QAttribute Qt3DQAttribute
Definition: qgs3daxis.cpp:28
Qt3DCore::QBuffer Qt3DQBuffer
Definition: qgs3daxis.cpp:30
Qt3DCore::QGeometry Qt3DQGeometry
Definition: qgs3daxis.cpp:29
Qt3DCore::QAttribute Qt3DQAttribute
Qt3DCore::QBuffer Qt3DQBuffer
Qt3DCore::QGeometry Qt3DQGeometry