QGIS API Documentation 4.1.0-Master (3fcefe620d1)
Loading...
Searching...
No Matches
qgsphongtexturedmaterial.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsphongtexturedmaterial.cpp
3 --------------------------------------
4 Date : August 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
17
18#include "qgs3dutils.h"
19
20#include <QString>
21#include <QUrl>
22#include <Qt3DRender/QEffect>
23#include <Qt3DRender/QGraphicsApiFilter>
24#include <Qt3DRender/QParameter>
25#include <Qt3DRender/QShaderProgram>
26#include <Qt3DRender/QTechnique>
27
28#include "moc_qgsphongtexturedmaterial.cpp"
29
30using namespace Qt::StringLiterals;
31
33QgsPhongTexturedMaterial::QgsPhongTexturedMaterial( QNode *parent )
34 : QgsMaterial( parent )
35 , mAmbientParameter( new Qt3DRender::QParameter( u"ambientColor"_s, QVariant() ) )
36 , mDiffuseTextureParameter( new Qt3DRender::QParameter( u"diffuseTexture"_s, QVariant() ) )
37 , mDiffuseTextureScaleParameter( new Qt3DRender::QParameter( u"texCoordScale"_s, 1.0f ) )
38 , mDiffuseTextureRotationParameter( new Qt3DRender::QParameter( u"texCoordRotation"_s, 0.0f ) )
39 , mDiffuseTextureOffsetParameter( new Qt3DRender::QParameter( u"texCoordOffset"_s, QVariant::fromValue( QVector2D( 0, 0 ) ), this ) )
40 , mSpecularParameter( new Qt3DRender::QParameter( u"specularColor"_s, QVariant() ) )
41 , mShininessParameter( new Qt3DRender::QParameter( u"shininess"_s, 150.0f ) )
42 , mOpacityParameter( new Qt3DRender::QParameter( u"opacity"_s, 1.0f ) )
43 , mEffect( new Qt3DRender::QEffect( this ) )
44 , mGL3Technique( new Qt3DRender::QTechnique( this ) )
45 , mGL3RenderPass( new Qt3DRender::QRenderPass( this ) )
46 , mShaderProgram( new Qt3DRender::QShaderProgram( this ) )
47 , mFilterKey( new Qt3DRender::QFilterKey( this ) )
48 , mTransformParameter( new Qt3DRender::QParameter( u"meshMatrix"_s, QVariant::fromValue( QMatrix4x4() ), this ) )
49 , mNormalTransformParameter( new Qt3DRender::QParameter( u"meshNormalMatrix"_s, QVariant::fromValue( QMatrix3x3() ), this ) )
50{
51 setAmbient( QColor::fromRgbF( 0.05f, 0.05f, 0.05f, 1.0f ) );
52 setSpecular( QColor::fromRgbF( 0.01f, 0.01f, 0.01f, 1.0f ) );
53 init();
54}
55
56QgsPhongTexturedMaterial::~QgsPhongTexturedMaterial() = default;
57
58
59void QgsPhongTexturedMaterial::init()
60{
61 updateShaders();
62
63 mGL3Technique->graphicsApiFilter()->setApi( Qt3DRender::QGraphicsApiFilter::OpenGL );
64 mGL3Technique->graphicsApiFilter()->setMajorVersion( 3 );
65 mGL3Technique->graphicsApiFilter()->setMinorVersion( 1 );
66 mGL3Technique->graphicsApiFilter()->setProfile( Qt3DRender::QGraphicsApiFilter::CoreProfile );
67
68 mFilterKey->setParent( this );
69 mFilterKey->setName( u"renderingStyle"_s );
70 mFilterKey->setValue( u"forward"_s );
71
72 mGL3Technique->addFilterKey( mFilterKey );
73 mGL3RenderPass->setShaderProgram( mShaderProgram );
74 mGL3Technique->addRenderPass( mGL3RenderPass );
75 mEffect->addTechnique( mGL3Technique );
76
77 mShaderProgram->setFragmentShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( u"qrc:/shaders/diffuseSpecular.frag"_s ) ) );
78
79 mEffect->addParameter( mAmbientParameter );
80 mEffect->addParameter( mDiffuseTextureParameter );
81 mEffect->addParameter( mDiffuseTextureScaleParameter );
82 mEffect->addParameter( mDiffuseTextureRotationParameter );
83 mEffect->addParameter( mDiffuseTextureOffsetParameter );
84 mEffect->addParameter( mSpecularParameter );
85 mEffect->addParameter( mShininessParameter );
86 mEffect->addParameter( mOpacityParameter );
87 mEffect->addParameter( mTransformParameter );
88 mEffect->addParameter( mNormalTransformParameter );
89
90 setEffect( mEffect );
91}
92
93void QgsPhongTexturedMaterial::setInstancingEnabled( bool enabled, Qgis::InstancedMaterialFlags flags )
94{
95 mInstanced = enabled;
96 mInstanceFlags = flags;
97
98 updateShaders();
99}
100
101void QgsPhongTexturedMaterial::updateShaders()
102{
103 const QByteArray fragCode = Qt3DRender::QShaderProgram::loadSource( QUrl( u"qrc:/shaders/diffuseSpecular.frag"_s ) );
104
105 if ( mInstanced )
106 {
107 QStringList defines = { u"HAS_TEXTURE"_s };
108 if ( mInstanceFlags.testFlag( Qgis::InstancedMaterialFlag::DataDefinedScale ) )
109 defines << u"USE_INSTANCE_SCALE"_s;
110 if ( mInstanceFlags.testFlag( Qgis::InstancedMaterialFlag::DataDefinedRotation ) )
111 defines << u"USE_INSTANCE_ROTATION"_s;
112 const QByteArray vertCode = Qt3DRender::QShaderProgram::loadSource( QUrl( u"qrc:/shaders/instanced.vert"_s ) );
113 mShaderProgram->setVertexShaderCode( Qgs3DUtils::addDefinesToShaderCode( vertCode, defines ) );
114 }
115 else
116 {
117 QByteArray vertexCode = Qt3DRender::QShaderProgram::loadSource( QUrl( u"qrc:/shaders/default.vert"_s ) );
118 QStringList defines { u"TEXTURE_ROTATION"_s, u"TEXTURE_OFFSET"_s };
119 if ( mDataDefinedTextureTransformEnabled )
120 defines << u"DATA_DEFINED_TEXTURE_TRANSFORMS"_s;
121
122 vertexCode = Qgs3DUtils::addDefinesToShaderCode( vertexCode, defines );
123 mShaderProgram->setVertexShaderCode( vertexCode );
124 }
125 mShaderProgram->setFragmentShaderCode( fragCode );
126}
127
128void QgsPhongTexturedMaterial::setInstancingMeshTransform( const QMatrix4x4 &transform )
129{
130 const QMatrix3x3 normalTransform = transform.normalMatrix();
131 mTransformParameter->setValue( QVariant::fromValue( transform ) );
132 mNormalTransformParameter->setValue( QVariant::fromValue( normalTransform ) );
133}
134
135void QgsPhongTexturedMaterial::setAmbient( const QColor &ambient )
136{
137 mAmbientParameter->setValue( Qgs3DUtils::srgbToLinear( ambient ) );
138}
139
140void QgsPhongTexturedMaterial::setDiffuseTexture( Qt3DRender::QAbstractTexture *diffuseTexture )
141{
142 mDiffuseTextureParameter->setValue( QVariant::fromValue( diffuseTexture ) );
143}
144
145void QgsPhongTexturedMaterial::setDiffuseTextureScale( float diffuseTextureScale )
146{
147 mDiffuseTextureScaleParameter->setValue( diffuseTextureScale );
148}
149
150void QgsPhongTexturedMaterial::setDiffuseTextureRotation( float textureRotation )
151{
152 mDiffuseTextureRotationParameter->setValue( textureRotation );
153}
154
155void QgsPhongTexturedMaterial::setDiffuseTextureOffset( float textureOffsetX, float textureOffsetY )
156{
157 mDiffuseTextureOffsetParameter->setValue( QVariant::fromValue( QVector2D( textureOffsetX, textureOffsetY ) ) );
158}
159
160void QgsPhongTexturedMaterial::setSpecular( const QColor &specular )
161{
162 mSpecularParameter->setValue( Qgs3DUtils::srgbToLinear( specular ) );
163}
164
165void QgsPhongTexturedMaterial::setShininess( float shininess )
166{
167 mShininessParameter->setValue( shininess );
168}
169
170void QgsPhongTexturedMaterial::setOpacity( float opacity )
171{
172 mOpacityParameter->setValue( opacity );
173}
174
175void QgsPhongTexturedMaterial::setDataDefinedTextureTransformEnabled( bool enabled )
176{
177 if ( enabled == mDataDefinedTextureTransformEnabled )
178 return;
179
180 mDataDefinedTextureTransformEnabled = enabled;
181 updateShaders();
182}
183
QFlags< InstancedMaterialFlag > InstancedMaterialFlags
Definition qgis.h:4398
@ DataDefinedRotation
Per-instance data-defined rotation.
Definition qgis.h:4395
@ DataDefinedScale
Per-instance data-defined scale.
Definition qgis.h:4394
static QByteArray addDefinesToShaderCode(const QByteArray &shaderCode, const QStringList &defines)
Inserts some define macros into a shader source code.
static QColor srgbToLinear(const QColor &color)
Converts a SRGB color to a linear color.
Base class for all materials used within QGIS 3D views.
Definition qgsmaterial.h:40