QGIS API Documentation 4.1.0-Master (3fcefe620d1)
Loading...
Searching...
No Matches
qgsphongmaterial.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsphongmaterial.cpp
3 --------------------------------------
4 Date : April 2026
5 Copyright : (C) 2026 by Dominik Cindrić
6 Email : viper dot miniq 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
16#include "qgsphongmaterial.h"
17
18#include "qgs3dutils.h"
19
20#include <QString>
21#include <QUrl>
22#include <Qt3DRender/QEffect>
23#include <Qt3DRender/QFilterKey>
24#include <Qt3DRender/QGraphicsApiFilter>
25#include <Qt3DRender/QParameter>
26#include <Qt3DRender/QRenderPass>
27#include <Qt3DRender/QShaderProgram>
28#include <Qt3DRender/QTechnique>
29
30#include "moc_qgsphongmaterial.cpp"
31
32using namespace Qt::StringLiterals;
33
35QgsPhongMaterial::QgsPhongMaterial( QNode *parent )
36 : QgsMaterial( parent )
37 , mAmbientParameter( new Qt3DRender::QParameter( u"ambientColor"_s, QVariant() ) )
38 , mDiffuseParameter( new Qt3DRender::QParameter( u"diffuseColor"_s, QVariant() ) )
39 , mSpecularParameter( new Qt3DRender::QParameter( u"specularColor"_s, QVariant() ) )
40 , mShininessParameter( new Qt3DRender::QParameter( u"shininess"_s, 0.0f ) )
41 , mOpacityParameter( new Qt3DRender::QParameter( u"opacity"_s, 1.0f ) )
42 , mTransformParameter( new Qt3DRender::QParameter( u"meshMatrix"_s, QVariant::fromValue( QMatrix4x4() ), this ) )
43 , mNormalTransformParameter( new Qt3DRender::QParameter( u"meshNormalMatrix"_s, QVariant::fromValue( QMatrix3x3() ), this ) )
44{
45 setAmbient( QColor::fromRgbF( 0.1f, 0.1f, 0.1f, 1.0f ) );
46 setDiffuse( QColor::fromRgbF( 0.7f, 0.7f, 0.7f, 1.0f ) );
47 setSpecular( QColor::fromRgbF( 1.0f, 1.0f, 1.0f, 1.0f ) );
48 init();
49}
50
51QgsPhongMaterial::~QgsPhongMaterial() = default;
52
53void QgsPhongMaterial::init()
54{
55 Qt3DRender::QEffect *effect = new Qt3DRender::QEffect();
56 effect->addParameter( mAmbientParameter );
57 effect->addParameter( mDiffuseParameter );
58 effect->addParameter( mSpecularParameter );
59 effect->addParameter( mShininessParameter );
60 effect->addParameter( mOpacityParameter );
61
62 mShaderProgram = new Qt3DRender::QShaderProgram();
63
64 Qt3DRender::QRenderPass *renderPass = new Qt3DRender::QRenderPass();
65 renderPass->setShaderProgram( mShaderProgram );
66
67 Qt3DRender::QFilterKey *filterKey = new Qt3DRender::QFilterKey();
68 filterKey->setName( u"renderingStyle"_s );
69 filterKey->setValue( u"forward"_s );
70
71 Qt3DRender::QTechnique *technique = new Qt3DRender::QTechnique();
72 technique->graphicsApiFilter()->setApi( Qt3DRender::QGraphicsApiFilter::OpenGL );
73 technique->graphicsApiFilter()->setProfile( Qt3DRender::QGraphicsApiFilter::CoreProfile );
74 technique->graphicsApiFilter()->setMajorVersion( 3 );
75 technique->graphicsApiFilter()->setMinorVersion( 3 );
76 technique->addFilterKey( filterKey );
77 technique->addRenderPass( renderPass );
78
79 effect->addTechnique( technique );
80 effect->addParameter( mTransformParameter );
81 effect->addParameter( mNormalTransformParameter );
82 setEffect( effect );
83
84 updateShaders();
85}
86
87void QgsPhongMaterial::setInstancingEnabled( bool enabled, Qgis::InstancedMaterialFlags flags )
88{
89 mInstanced = enabled;
90 mInstanceFlags = flags;
91 updateShaders();
92}
93
94void QgsPhongMaterial::setInstancingMeshTransform( const QMatrix4x4 &transform )
95{
96 const QMatrix3x3 normalTransform = transform.normalMatrix();
97 mTransformParameter->setValue( QVariant::fromValue( transform ) );
98 mNormalTransformParameter->setValue( QVariant::fromValue( normalTransform ) );
99}
100
101void QgsPhongMaterial::updateShaders()
102{
103 const QByteArray fragCode = Qt3DRender::QShaderProgram::loadSource( QUrl( u"qrc:/shaders/phong.frag"_s ) );
104
105 if ( mInstanced )
106 {
107 QStringList defines;
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->setShaderCode( Qt3DRender::QShaderProgram::Vertex, Qgs3DUtils::addDefinesToShaderCode( vertCode, defines ) );
114 mShaderProgram->setFragmentShaderCode( fragCode );
115 }
116 else if ( mDataDefinedEnabled )
117 {
118 mShaderProgram->setShaderCode( Qt3DRender::QShaderProgram::Vertex, Qt3DRender::QShaderProgram::loadSource( QUrl( u"qrc:/shaders/phongDataDefined.vert"_s ) ) );
119 mShaderProgram->setFragmentShaderCode( Qgs3DUtils::addDefinesToShaderCode( fragCode, QStringList( { u"DATA_DEFINED"_s } ) ) );
120 }
121 else
122 {
123 mShaderProgram->setShaderCode( Qt3DRender::QShaderProgram::Vertex, Qt3DRender::QShaderProgram::loadSource( QUrl( u"qrc:/shaders/default.vert"_s ) ) );
124 mShaderProgram->setFragmentShaderCode( fragCode );
125 }
126}
127
128void QgsPhongMaterial::setDataDefinedEnabled( bool enabled )
129{
130 if ( enabled != mDataDefinedEnabled )
131 {
132 mDataDefinedEnabled = enabled;
133 updateShaders();
134 }
135}
136
137void QgsPhongMaterial::setAmbient( const QColor &ambient, float scaleFactor )
138{
139 const QColor color = Qgs3DUtils::srgbToLinear( ambient );
140 mAmbientParameter->setValue( QColor::fromRgbF( color.redF() * scaleFactor, color.greenF() * scaleFactor, color.blueF() * scaleFactor ) );
141}
142
143void QgsPhongMaterial::setDiffuse( const QColor &diffuse, float scaleFactor )
144{
145 const QColor color = Qgs3DUtils::srgbToLinear( diffuse );
146 mDiffuseParameter->setValue( QColor::fromRgbF( color.redF() * scaleFactor, color.greenF() * scaleFactor, color.blueF() * scaleFactor ) );
147}
148
149void QgsPhongMaterial::setSpecular( const QColor &specular, float scaleFactor )
150{
151 const QColor color = Qgs3DUtils::srgbToLinear( specular );
152 mSpecularParameter->setValue( QColor::fromRgbF( color.redF() * scaleFactor, color.greenF() * scaleFactor, color.blueF() * scaleFactor ) );
153}
154
155void QgsPhongMaterial::setShininess( float shininess )
156{
157 mShininessParameter->setValue( shininess );
158}
159
160void QgsPhongMaterial::setOpacity( float opacity )
161{
162 mOpacityParameter->setValue( opacity );
163}
164
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