QGIS API Documentation 4.1.0-Master (3fcefe620d1)
Loading...
Searching...
No Matches
qgsgoochmaterial.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsgoochmaterial.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 "qgsgoochmaterial.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_qgsgoochmaterial.cpp"
31
32using namespace Qt::StringLiterals;
33
35QgsGoochMaterial::QgsGoochMaterial( QNode *parent )
36 : QgsMaterial( parent )
37 , mDiffuseParameter( new Qt3DRender::QParameter( u"kd"_s, QVariant() ) )
38 , mSpecularParameter( new Qt3DRender::QParameter( u"ks"_s, QVariant() ) )
39 , mWarmParameter( new Qt3DRender::QParameter( u"kyellow"_s, QVariant() ) )
40 , mCoolParameter( new Qt3DRender::QParameter( u"kblue"_s, QVariant() ) )
41 , mShininessParameter( new Qt3DRender::QParameter( u"shininess"_s, 100.0f ) )
42 , mAlphaParameter( new Qt3DRender::QParameter( u"alpha"_s, 0.25f ) )
43 , mBetaParameter( new Qt3DRender::QParameter( u"beta"_s, 0.5f ) )
44 , mTransformParameter( new Qt3DRender::QParameter( u"meshMatrix"_s, QVariant::fromValue( QMatrix4x4() ), this ) )
45 , mNormalTransformParameter( new Qt3DRender::QParameter( u"meshNormalMatrix"_s, QVariant::fromValue( QMatrix3x3() ), this ) )
46{
47 setDiffuse( QColor::fromRgbF( 0.7f, 0.7f, 0.7f, 1.0f ) );
48 setSpecular( QColor::fromRgbF( 1.0f, 1.0f, 1.0f, 1.0f ) );
49 setWarm( QColor::fromRgbF( 0.42f, 0.0f, 0.42f, 1.0f ) );
50 setCool( QColor::fromRgbF( 1.0f, 0.51f, 0.0f, 1.0f ) );
51 init();
52}
53
54QgsGoochMaterial::~QgsGoochMaterial() = default;
55
56void QgsGoochMaterial::init()
57{
58 Qt3DRender::QEffect *effect = new Qt3DRender::QEffect();
59 effect->addParameter( mDiffuseParameter );
60 effect->addParameter( mSpecularParameter );
61 effect->addParameter( mWarmParameter );
62 effect->addParameter( mCoolParameter );
63 effect->addParameter( mShininessParameter );
64 effect->addParameter( mAlphaParameter );
65 effect->addParameter( mBetaParameter );
66
67 mShaderProgram = new Qt3DRender::QShaderProgram();
68
69 Qt3DRender::QRenderPass *renderPass = new Qt3DRender::QRenderPass();
70 renderPass->setShaderProgram( mShaderProgram );
71
72 Qt3DRender::QFilterKey *filterKey = new Qt3DRender::QFilterKey();
73 filterKey->setName( u"renderingStyle"_s );
74 filterKey->setValue( u"forward"_s );
75
76 Qt3DRender::QTechnique *technique = new Qt3DRender::QTechnique();
77 technique->graphicsApiFilter()->setApi( Qt3DRender::QGraphicsApiFilter::OpenGL );
78 technique->graphicsApiFilter()->setProfile( Qt3DRender::QGraphicsApiFilter::CoreProfile );
79 technique->graphicsApiFilter()->setMajorVersion( 3 );
80 technique->graphicsApiFilter()->setMinorVersion( 3 );
81 technique->addFilterKey( filterKey );
82 technique->addRenderPass( renderPass );
83
84 effect->addTechnique( technique );
85 effect->addParameter( mTransformParameter );
86 effect->addParameter( mNormalTransformParameter );
87 setEffect( effect );
88
89 updateShaders();
90}
91
92void QgsGoochMaterial::setInstancingEnabled( bool enabled, Qgis::InstancedMaterialFlags flags )
93{
94 mInstanced = enabled;
95 mInstanceFlags = flags;
96 updateShaders();
97}
98
99void QgsGoochMaterial::setInstancingMeshTransform( const QMatrix4x4 &transform )
100{
101 const QMatrix3x3 normalTransform = transform.normalMatrix();
102 mTransformParameter->setValue( QVariant::fromValue( transform ) );
103 mNormalTransformParameter->setValue( QVariant::fromValue( normalTransform ) );
104}
105
106void QgsGoochMaterial::updateShaders()
107{
108 const QByteArray fragCode = Qt3DRender::QShaderProgram::loadSource( QUrl( u"qrc:/shaders/gooch.frag"_s ) );
109
110 if ( mInstanced )
111 {
112 QStringList defines;
113 if ( mInstanceFlags.testFlag( Qgis::InstancedMaterialFlag::DataDefinedScale ) )
114 defines << u"USE_INSTANCE_SCALE"_s;
115 if ( mInstanceFlags.testFlag( Qgis::InstancedMaterialFlag::DataDefinedRotation ) )
116 defines << u"USE_INSTANCE_ROTATION"_s;
117 const QByteArray vertCode = Qt3DRender::QShaderProgram::loadSource( QUrl( u"qrc:/shaders/instanced.vert"_s ) );
118 mShaderProgram->setShaderCode( Qt3DRender::QShaderProgram::Vertex, Qgs3DUtils::addDefinesToShaderCode( vertCode, defines ) );
119 mShaderProgram->setFragmentShaderCode( fragCode );
120 }
121 else if ( mDataDefinedEnabled )
122 {
123 mShaderProgram->setShaderCode( Qt3DRender::QShaderProgram::Vertex, Qt3DRender::QShaderProgram::loadSource( QUrl( u"qrc:/shaders/goochDataDefined.vert"_s ) ) );
124 mShaderProgram->setFragmentShaderCode( Qgs3DUtils::addDefinesToShaderCode( fragCode, QStringList( { u"DATA_DEFINED"_s } ) ) );
125 }
126 else
127 {
128 mShaderProgram->setShaderCode( Qt3DRender::QShaderProgram::Vertex, Qt3DRender::QShaderProgram::loadSource( QUrl( u"qrc:/shaders/default.vert"_s ) ) );
129 mShaderProgram->setFragmentShaderCode( fragCode );
130 }
131}
132
133void QgsGoochMaterial::setDataDefinedEnabled( bool enabled )
134{
135 if ( enabled != mDataDefinedEnabled )
136 {
137 mDataDefinedEnabled = enabled;
138 updateShaders();
139 }
140}
141
142void QgsGoochMaterial::setDiffuse( const QColor &diffuse )
143{
144 mDiffuseParameter->setValue( Qgs3DUtils::srgbToLinear( diffuse ) );
145}
146
147void QgsGoochMaterial::setSpecular( const QColor &specular )
148{
149 mSpecularParameter->setValue( Qgs3DUtils::srgbToLinear( specular ) );
150}
151
152void QgsGoochMaterial::setWarm( const QColor &warm )
153{
154 mWarmParameter->setValue( Qgs3DUtils::srgbToLinear( warm ) );
155}
156
157void QgsGoochMaterial::setCool( const QColor &cool )
158{
159 mCoolParameter->setValue( Qgs3DUtils::srgbToLinear( cool ) );
160}
161
162void QgsGoochMaterial::setShininess( float shininess )
163{
164 mShininessParameter->setValue( shininess );
165}
166
167void QgsGoochMaterial::setAlpha( float alpha )
168{
169 mAlphaParameter->setValue( alpha );
170}
171
172void QgsGoochMaterial::setBeta( float beta )
173{
174 mBetaParameter->setValue( beta );
175}
176
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