QGIS API Documentation 3.99.0-Master (8e76e220402)
Loading...
Searching...
No Matches
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 "qgsapplication.h"
19#include "qgscolorutils.h"
21#include "qgsimagecache.h"
22#include "qgsimagetexture.h"
25
26#include <QMap>
27#include <QString>
28#include <Qt3DRender/QEffect>
29#include <Qt3DRender/QGraphicsApiFilter>
30#include <Qt3DRender/QPaintedTextureImage>
31#include <Qt3DRender/QParameter>
32#include <Qt3DRender/QTechnique>
33#include <Qt3DRender/QTexture>
34
35using namespace Qt::StringLiterals;
36
38{
39 return u"phongtextured"_s;
40}
41
59
64
69
71{
72 const QgsPhongTexturedMaterialSettings *otherPhong = dynamic_cast<const QgsPhongTexturedMaterialSettings *>( other );
73 if ( !otherPhong )
74 return false;
75
76 return *this == *otherPhong;
77}
78
80{
81 return mTextureRotation;
82}
83
84void QgsPhongTexturedMaterialSettings::readXml( const QDomElement &elem, const QgsReadWriteContext &context )
85{
86 mAmbient = QgsColorUtils::colorFromString( elem.attribute( u"ambient"_s, u"25,25,25"_s ) );
87 mSpecular = QgsColorUtils::colorFromString( elem.attribute( u"specular"_s, u"255,255,255"_s ) );
88 mShininess = elem.attribute( u"shininess"_s ).toDouble();
89 mOpacity = elem.attribute( u"opacity"_s, u"1.0"_s ).toDouble();
90 mDiffuseTexturePath = elem.attribute( u"diffuse_texture_path"_s, QString() );
91 mTextureScale = elem.attribute( u"texture_scale"_s, QString( "1.0" ) ).toDouble();
92 mTextureRotation = elem.attribute( u"texture-rotation"_s, QString( "0.0" ) ).toDouble();
93
95}
96
97void QgsPhongTexturedMaterialSettings::writeXml( QDomElement &elem, const QgsReadWriteContext &context ) const
98{
99 elem.setAttribute( u"ambient"_s, QgsColorUtils::colorToString( mAmbient ) );
100 elem.setAttribute( u"specular"_s, QgsColorUtils::colorToString( mSpecular ) );
101 elem.setAttribute( u"shininess"_s, mShininess );
102 elem.setAttribute( u"opacity"_s, mOpacity );
103 elem.setAttribute( u"diffuse_texture_path"_s, mDiffuseTexturePath );
104 elem.setAttribute( u"texture_scale"_s, mTextureScale );
105 elem.setAttribute( u"texture-rotation"_s, mTextureRotation );
106
108}
109
111{
112 switch ( technique )
113 {
120 {
121 if ( context.isHighlighted() )
122 {
123 return new QgsHighlightMaterial( technique );
124 }
125
126 bool fitsInCache = false;
127 const QImage textureSourceImage = QgsApplication::imageCache()->pathAsImage( mDiffuseTexturePath, QSize(), true, 1.0, fitsInCache );
128 ( void ) fitsInCache;
129
130 // No texture image was provided.
131 // Fallback to QgsPhongMaterialSettings.
132 if ( textureSourceImage.isNull() )
133 {
135 phongSettings.setAmbient( mAmbient );
136 phongSettings.setDiffuse( QColor::fromRgbF( 0.7f, 0.7f, 0.7f, 1.0f ) ); // default diffuse color from QDiffuseSpecularMaterial
137 phongSettings.setOpacity( mOpacity );
138 phongSettings.setShininess( mShininess );
139 phongSettings.setSpecular( mSpecular );
140 QgsMaterial *material = phongSettings.toMaterial( technique, context );
141 return material;
142 }
143
144 QgsPhongTexturedMaterial *material = new QgsPhongTexturedMaterial();
145
146 int opacity = static_cast<int>( mOpacity * 255.0 );
147 QColor ambient = context.isSelected() ? context.selectionColor().darker() : mAmbient;
148 material->setAmbient( QColor( ambient.red(), ambient.green(), ambient.blue(), opacity ) );
149 material->setSpecular( QColor( mSpecular.red(), mSpecular.green(), mSpecular.blue(), opacity ) );
150 material->setShininess( static_cast<float>( mShininess ) );
151 material->setOpacity( static_cast<float>( mOpacity ) );
152
153 // TODO : if ( context.isSelected() ) dampen the color of diffuse texture
154 // with context.map().selectionColor()
155 QgsImageTexture *textureImage = new QgsImageTexture( textureSourceImage );
156 Qt3DRender::QTexture2D *texture = new Qt3DRender::QTexture2D();
157 texture->addTextureImage( textureImage );
158
159 texture->wrapMode()->setX( Qt3DRender::QTextureWrapMode::Repeat );
160 texture->wrapMode()->setY( Qt3DRender::QTextureWrapMode::Repeat );
161 texture->wrapMode()->setZ( Qt3DRender::QTextureWrapMode::Repeat );
162
163 texture->setSamples( 4 );
164
165 texture->setGenerateMipMaps( true );
166 texture->setMagnificationFilter( Qt3DRender::QTexture2D::Linear );
167 texture->setMinificationFilter( Qt3DRender::QTexture2D::Linear );
168
169 material->setDiffuseTexture( texture );
170 material->setDiffuseTextureScale( static_cast<float>( mTextureScale ) );
171
172 return material;
173 }
174
176 return nullptr;
177 }
178 return nullptr;
179}
180
182{
183 QMap<QString, QString> parameters;
184 parameters[u"Ka"_s] = u"%1 %2 %3"_s.arg( mAmbient.redF() ).arg( mAmbient.greenF() ).arg( mAmbient.blueF() );
185 parameters[u"Ks"_s] = u"%1 %2 %3"_s.arg( mSpecular.redF() ).arg( mSpecular.greenF() ).arg( mSpecular.blueF() );
186 parameters[u"Ns"_s] = QString::number( mShininess );
187 return parameters;
188}
189
190void QgsPhongTexturedMaterialSettings::addParametersToEffect( Qt3DRender::QEffect *effect, const QgsMaterialContext &materialContext ) const
191{
192 const QColor ambientColor = materialContext.isSelected() ? materialContext.selectionColor().darker() : mAmbient;
193
194 Qt3DRender::QParameter *ambientParameter = new Qt3DRender::QParameter( u"ambientColor"_s, ambientColor );
195 Qt3DRender::QParameter *specularParameter = new Qt3DRender::QParameter( u"specularColor"_s, mSpecular );
196 Qt3DRender::QParameter *shininessParameter = new Qt3DRender::QParameter( u"shininess"_s, static_cast<float>( mShininess ) );
197
198 effect->addParameter( ambientParameter );
199 effect->addParameter( specularParameter );
200 effect->addParameter( shininessParameter );
201}
Abstract base class for material settings.
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.
static QgsImageCache * imageCache()
Returns the application's image cache, used for caching resampled versions of raster images.
static QColor colorFromString(const QString &string)
Decodes a string into a color value.
static QString colorToString(const QColor &color)
Encodes a color into a string value.
QImage pathAsImage(const QString &path, const QSize size, const bool keepAspectRatio, const double opacity, bool &fitsInCache, bool blocking=false, double targetDpi=96, int frameNumber=-1, bool *isMissing=nullptr)
Returns the specified path rendered as an image.
Holds an image that can be used as a texture in the 3D view.
Context settings for a material.
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.
bool isHighlighted() const
Returns true if the material should represent a highlighted state.
Base class for all materials used within QGIS 3D views.
Definition qgsmaterial.h:39
Basic shading material used for rendering based on the Phong shading model with three color component...
void setOpacity(double opacity)
Sets opacity of the surface.
QgsMaterial * toMaterial(QgsMaterialSettingsRenderingTechnique technique, const QgsMaterialContext &context) const override
Creates a new QgsMaterial object representing the material settings.
void setDiffuse(const QColor &diffuse)
Sets diffuse color component.
void setShininess(double shininess)
Sets shininess of the surface.
void setAmbient(const QColor &ambient)
Sets ambient color component.
void setSpecular(const QColor &specular)
Sets specular color component.
void addParametersToEffect(Qt3DRender::QEffect *effect, const QgsMaterialContext &materialContext) const override
Adds parameters from the material to a destination effect.
QgsMaterial * toMaterial(QgsMaterialSettingsRenderingTechnique technique, const QgsMaterialContext &context) const override
Creates a new QgsMaterial object representing the material settings.
bool equals(const QgsAbstractMaterialSettings *other) const override
Returns true if this settings exactly matches an other settings.
void writeXml(QDomElement &elem, const QgsReadWriteContext &context) const override
Writes settings to a DOM element.
double textureRotation() const
Returns the texture rotation, in degrees.
QString type() const override
Returns the unique type name for the material.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context) override
Reads settings from a DOM element.
static bool supportsTechnique(QgsMaterialSettingsRenderingTechnique technique)
Returns true if the specified technique is supported by the Phong material.
double opacity() const
Returns the opacity of the surface.
QgsPhongTexturedMaterialSettings * clone() const override
Clones the material settings.
static QgsAbstractMaterialSettings * create()
Returns a new instance of QgsPhongTexturedMaterialSettings.
QMap< QString, QString > toExportParameters() const override
Returns the parameters to be exported to .mtl file.
QColor ambient() const
Returns ambient color component.
A container for the context for various read/write operations on objects.
QgsMaterialSettingsRenderingTechnique
Material rendering techniques.
@ 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).