QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
qgsphongtexturedmaterialsettings.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsphongtexturedmaterialsettings.cpp
3  --------------------------------------
4  Date : August 2020
5  Copyright : (C) 2020 by Nyall Dawson
6  Email : nyall dot dawson 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 "qgsapplication.h"
20 #include "qgsimagecache.h"
21 #include <Qt3DExtras/QDiffuseMapMaterial>
22 #include <Qt3DExtras/QPhongMaterial>
23 #include <Qt3DRender/QPaintedTextureImage>
24 #include <Qt3DRender/QTexture>
25 #include <Qt3DRender/QParameter>
26 #include <Qt3DRender/QEffect>
27 #include <QMap>
28 
29 
31 {
32  return QStringLiteral( "phongtextured" );
33 }
34 
36 {
37  switch ( technique )
38  {
39  case QgsMaterialSettingsRenderingTechnique::Triangles:
40  return true;
41 
44  case QgsMaterialSettingsRenderingTechnique::InstancedPoints:
45  case QgsMaterialSettingsRenderingTechnique::Lines:
46  return false;
47  }
48  return false;
49 }
50 
52 {
54 }
55 
57 {
58  return new QgsPhongTexturedMaterialSettings( *this );
59 }
60 
62 {
63  return mTextureRotation;
64 }
65 
66 void QgsPhongTexturedMaterialSettings::readXml( const QDomElement &elem, const QgsReadWriteContext & )
67 {
68  mAmbient = QgsSymbolLayerUtils::decodeColor( elem.attribute( QStringLiteral( "ambient" ), QStringLiteral( "25,25,25" ) ) );
69  mSpecular = QgsSymbolLayerUtils::decodeColor( elem.attribute( QStringLiteral( "specular" ), QStringLiteral( "255,255,255" ) ) );
70  mShininess = elem.attribute( QStringLiteral( "shininess" ) ).toFloat();
71  mDiffuseTexturePath = elem.attribute( QStringLiteral( "diffuse_texture_path" ), QString() );
72  mTextureScale = elem.attribute( QStringLiteral( "texture_scale" ), QString( "1.0" ) ).toFloat();
73  mTextureRotation = elem.attribute( QStringLiteral( "texture-rotation" ), QString( "0.0" ) ).toFloat();
74 }
75 
76 void QgsPhongTexturedMaterialSettings::writeXml( QDomElement &elem, const QgsReadWriteContext & ) const
77 {
78  elem.setAttribute( QStringLiteral( "ambient" ), QgsSymbolLayerUtils::encodeColor( mAmbient ) );
79  elem.setAttribute( QStringLiteral( "specular" ), QgsSymbolLayerUtils::encodeColor( mSpecular ) );
80  elem.setAttribute( QStringLiteral( "shininess" ), mShininess );
81  elem.setAttribute( QStringLiteral( "diffuse_texture_path" ), mDiffuseTexturePath );
82  elem.setAttribute( QStringLiteral( "texture_scale" ), mTextureScale );
83  elem.setAttribute( QStringLiteral( "texture-rotation" ), mTextureRotation );
84 }
85 
87 class QgsQImageTextureImage : public Qt3DRender::QPaintedTextureImage
88 {
89  public:
90  QgsQImageTextureImage( const QImage &image, Qt3DCore::QNode *parent = nullptr )
91  : Qt3DRender::QPaintedTextureImage( parent )
92  , mImage( image )
93  {
94  setSize( mImage.size() );
95  }
96 
97  void paint( QPainter *painter ) override
98  {
99  painter->drawImage( mImage.rect(), mImage, mImage.rect() );
100  }
101 
102  private:
103 
104  QImage mImage;
105 
106 };
107 
110 {
111  switch ( technique )
112  {
113  case QgsMaterialSettingsRenderingTechnique::Triangles:
114  case QgsMaterialSettingsRenderingTechnique::InstancedPoints:
117  {
118  bool fitsInCache = false;
119  QImage textureSourceImage = QgsApplication::imageCache()->pathAsImage( mDiffuseTexturePath, QSize(), true, 1.0, fitsInCache );
120  ( void )fitsInCache;
121 
122  if ( !textureSourceImage.isNull() )
123  {
124  Qt3DExtras::QDiffuseMapMaterial *material = new Qt3DExtras::QDiffuseMapMaterial;
125 
126  QgsQImageTextureImage *textureImage = new QgsQImageTextureImage( textureSourceImage );
127  material->diffuse()->addTextureImage( textureImage );
128 
129  material->diffuse()->wrapMode()->setX( Qt3DRender::QTextureWrapMode::Repeat );
130  material->diffuse()->wrapMode()->setY( Qt3DRender::QTextureWrapMode::Repeat );
131  material->diffuse()->wrapMode()->setZ( Qt3DRender::QTextureWrapMode::Repeat );
132  material->setSpecular( mSpecular );
133  material->setAmbient( mAmbient );
134  material->setShininess( mShininess );
135  material->setTextureScale( mTextureScale );
136 
137  if ( context.isSelected() )
138  {
139  // update the material with selection colors
140  // TODO : dampen the color of diffuse texture
141  // mat->setDiffuse( context.map().selectionColor() );
142  material->setAmbient( context.selectionColor().darker() );
143  }
144 
145  return material;
146  }
147  else
148  {
149  Qt3DExtras::QPhongMaterial *material = new Qt3DExtras::QPhongMaterial;
150  material->setAmbient( mAmbient );
151  material->setSpecular( mSpecular );
152  material->setShininess( mShininess );
153 
154  if ( context.isSelected() )
155  {
156  // update the material with selection colors
157  material->setDiffuse( context.selectionColor() );
158  material->setAmbient( context.selectionColor().darker() );
159  }
160  return material;
161  }
162  }
163 
164  case QgsMaterialSettingsRenderingTechnique::Lines:
165  return nullptr;
166 
167  }
168  return nullptr;
169 }
170 
172 {
173  QMap<QString, QString> parameters;
174  parameters[ QStringLiteral( "Ka" ) ] = QStringLiteral( "%1 %2 %3" ).arg( mAmbient.redF() ).arg( mAmbient.greenF() ).arg( mAmbient.blueF() );
175  parameters[ QStringLiteral( "Ks" ) ] = QStringLiteral( "%1 %2 %3" ).arg( mSpecular.redF() ).arg( mSpecular.greenF() ).arg( mSpecular.blueF() );
176  parameters[ QStringLiteral( "Ns" ) ] = QString::number( mShininess );
177  return parameters;
178 }
179 
180 void QgsPhongTexturedMaterialSettings::addParametersToEffect( Qt3DRender::QEffect *effect ) const
181 {
182  Qt3DRender::QParameter *ambientParameter = new Qt3DRender::QParameter( QStringLiteral( "ka" ), QColor::fromRgbF( 0.05f, 0.05f, 0.05f, 1.0f ) );
183  Qt3DRender::QParameter *specularParameter = new Qt3DRender::QParameter( QStringLiteral( "ks" ), QColor::fromRgbF( 0.01f, 0.01f, 0.01f, 1.0f ) );
184  Qt3DRender::QParameter *shininessParameter = new Qt3DRender::QParameter( QStringLiteral( "shininess" ), 150.0f );
185 
186  ambientParameter->setValue( mAmbient );
187  specularParameter->setValue( mSpecular );
188  shininessParameter->setValue( mShininess );
189 
190  effect->addParameter( ambientParameter );
191  effect->addParameter( specularParameter );
192  effect->addParameter( shininessParameter );
193 }
QgsSymbolLayerUtils::encodeColor
static QString encodeColor(const QColor &color)
Definition: qgssymbollayerutils.cpp:52
QgsPhongTexturedMaterialSettings::supportsTechnique
static bool supportsTechnique(QgsMaterialSettingsRenderingTechnique technique)
Returns true if the specified technique is supported by the Phong material.
Definition: qgsphongtexturedmaterialsettings.cpp:35
QgsPhongTexturedMaterialSettings::QgsPhongTexturedMaterialSettings
QgsPhongTexturedMaterialSettings()=default
Constructor for QgsPhongTexturedMaterialSettings.
QgsPhongTexturedMaterialSettings::textureRotation
float textureRotation() const
Returns the texture rotation, in degrees.
Definition: qgsphongtexturedmaterialsettings.cpp:61
QgsReadWriteContext
The class is used as a container of context for various read/write operations on other objects.
Definition: qgsreadwritecontext.h:35
QgsPhongTexturedMaterialSettings::create
static QgsAbstractMaterialSettings * create()
Returns a new instance of QgsPhongTexturedMaterialSettings.
Definition: qgsphongtexturedmaterialsettings.cpp:51
qgsphongtexturedmaterialsettings.h
qgssymbollayerutils.h
QgsSymbolLayerUtils::decodeColor
static QColor decodeColor(const QString &str)
Definition: qgssymbollayerutils.cpp:57
QgsMaterialContext::selectionColor
QColor selectionColor() const
Returns the color for representing materials in a selected state.
Definition: qgsabstractmaterialsettings.h:77
QgsPhongTexturedMaterialSettings::toExportParameters
QMap< QString, QString > toExportParameters() const override
Returns the parameters to be exported to .mtl file.
Definition: qgsphongtexturedmaterialsettings.cpp:171
qgsapplication.h
QgsMaterialContext
3 Context settings for a material.
Definition: qgsabstractmaterialsettings.h:55
QgsPhongTexturedMaterialSettings::clone
QgsPhongTexturedMaterialSettings * clone() const override
Clones the material settings.
Definition: qgsphongtexturedmaterialsettings.cpp:56
QgsAbstractMaterialSettings
3 Abstract base class for material settings.
Definition: qgsabstractmaterialsettings.h:105
QgsImageCache::pathAsImage
QImage pathAsImage(const QString &path, const QSize size, const bool keepAspectRatio, const double opacity, bool &fitsInCache, bool blocking=false, bool *isMissing=nullptr)
Returns the specified path rendered as an image.
Definition: qgsimagecache.cpp:104
QgsPhongTexturedMaterialSettings::addParametersToEffect
void addParametersToEffect(Qt3DRender::QEffect *effect) const override
Adds parameters from the material to a destination effect.
Definition: qgsphongtexturedmaterialsettings.cpp:180
QgsPhongTexturedMaterialSettings::writeXml
void writeXml(QDomElement &elem, const QgsReadWriteContext &context) const override
Writes settings to a DOM element.
Definition: qgsphongtexturedmaterialsettings.cpp:76
Qt3DRender
Definition: qgs3dmapscene.h:27
QgsApplication::imageCache
static QgsImageCache * imageCache()
Returns the application's image cache, used for caching resampled versions of raster images.
Definition: qgsapplication.cpp:2183
QgsMaterialSettingsRenderingTechnique::Triangles
@ Triangles
Triangle based rendering (default)
QgsPhongTexturedMaterialSettings::toMaterial
Qt3DRender::QMaterial * toMaterial(QgsMaterialSettingsRenderingTechnique technique, const QgsMaterialContext &context) const override
Creates a new QMaterial object representing the material settings.
Definition: qgsphongtexturedmaterialsettings.cpp:109
QgsMaterialSettingsRenderingTechnique
QgsMaterialSettingsRenderingTechnique
Material rendering techniques 3.
Definition: qgsabstractmaterialsettings.h:36
QgsPhongTexturedMaterialSettings
3 A phong shading model with diffuse texture map.
Definition: qgsphongtexturedmaterialsettings.h:36
qgsimagecache.h
QgsPhongTexturedMaterialSettings::readXml
void readXml(const QDomElement &elem, const QgsReadWriteContext &context) override
Reads settings from a DOM element.
Definition: qgsphongtexturedmaterialsettings.cpp:66
QgsMaterialSettingsRenderingTechnique::Points
@ Points
Point based rendering, requires point data.
QgsMaterialContext::isSelected
bool isSelected() const
Returns true if the material should represent a selected state.
Definition: qgsabstractmaterialsettings.h:63
QgsPhongTexturedMaterialSettings::type
QString type() const override
Returns the unique type name for the material.
Definition: qgsphongtexturedmaterialsettings.cpp:30