QGIS API Documentation 4.3.0-Master (03a7e469fa9)
Loading...
Searching...
No Matches
qgsunlitmaterial.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsunlitmaterial.cpp
3 ---------------------
4 begin : June 2026
5 copyright : (C) 2026 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
16#include "qgsunlitmaterial.h"
17
18#include "qgs3dutils.h"
19#include "qgssettings.h"
20
21#include <QColor>
22#include <QString>
23#include <QUrl>
24#include <Qt3DRender/QEffect>
25#include <Qt3DRender/QGraphicsApiFilter>
26#include <Qt3DRender/QParameter>
27#include <Qt3DRender/QRenderPass>
28#include <Qt3DRender/QShaderProgram>
29#include <Qt3DRender/QTechnique>
30
31#include "moc_qgsunlitmaterial.cpp"
32
33using namespace Qt::StringLiterals;
34
36
37QgsUnlitMaterial::QgsUnlitMaterial( QNode *parent )
38 : QgsMaterial( parent )
39 , mTransformParameter( new Qt3DRender::QParameter( u"meshMatrix"_s, QVariant::fromValue( QMatrix4x4() ), this ) )
40 , mNormalTransformParameter( new Qt3DRender::QParameter( u"meshNormalMatrix"_s, QVariant::fromValue( QMatrix3x3() ), this ) )
41{
42 init();
43}
44
45QgsUnlitMaterial::~QgsUnlitMaterial() = default;
46
47void QgsUnlitMaterial::setColor( const QColor &color )
48{
49 const QColor linearColor = Qgs3DUtils::srgbToLinear( color );
50 mColorParameter->setValue( linearColor );
51}
52
53void QgsUnlitMaterial::init()
54{
55 Qt3DRender::QEffect *effect = new Qt3DRender::QEffect;
56 Qt3DRender::QTechnique *technique = new Qt3DRender::QTechnique;
57 technique->graphicsApiFilter()->setApi( Qt3DRender::QGraphicsApiFilter::OpenGL );
58 technique->graphicsApiFilter()->setProfile( Qt3DRender::QGraphicsApiFilter::CoreProfile );
59 technique->graphicsApiFilter()->setMajorVersion( 4 );
60 technique->graphicsApiFilter()->setMinorVersion( 3 );
61
62 Qt3DRender::QRenderPass *pass = new Qt3DRender::QRenderPass;
63
64 mShaderProgram = new Qt3DRender::QShaderProgram();
65 pass->setShaderProgram( mShaderProgram );
66
67 mColorParameter = new Qt3DRender::QParameter( u"color"_s, Qgs3DUtils::srgbToLinear( QColor( 255, 255, 255 ) ) );
68 pass->addParameter( mColorParameter );
69
70 technique->addRenderPass( pass );
71 effect->addTechnique( technique );
72 effect->addParameter( mTransformParameter );
73 effect->addParameter( mNormalTransformParameter );
74 setEffect( effect );
75
76 updateShaders();
77}
78
79void QgsUnlitMaterial::setInstancingEnabled( bool enabled, Qgis::InstancedMaterialFlags flags )
80{
81 mInstanced = enabled;
82 mInstanceFlags = flags;
83 updateShaders();
84}
85
86void QgsUnlitMaterial::setInstancingMeshTransform( const QMatrix4x4 &transform )
87{
88 const QMatrix3x3 normalTransform = transform.normalMatrix();
89 mTransformParameter->setValue( QVariant::fromValue( transform ) );
90 mNormalTransformParameter->setValue( QVariant::fromValue( normalTransform ) );
91}
92
93void QgsUnlitMaterial::setDataDefinedEnabled( bool enabled )
94{
95 if ( enabled != mDataDefinedEnabled )
96 {
97 mDataDefinedEnabled = enabled;
98 updateShaders();
99 }
100}
101
102void QgsUnlitMaterial::updateShaders()
103{
104 if ( mInstanced )
105 {
106 QStringList defines;
107 if ( mInstanceFlags.testFlag( Qgis::InstancedMaterialFlag::DataDefinedScale ) )
108 defines << u"USE_INSTANCE_SCALE"_s;
109 if ( mInstanceFlags.testFlag( Qgis::InstancedMaterialFlag::DataDefinedRotation ) )
110 defines << u"USE_INSTANCE_ROTATION"_s;
111 const QByteArray vertCode = Qt3DRender::QShaderProgram::loadSource( QUrl( u"qrc:/shaders/instanced.vert"_s ) );
112 mShaderProgram->setShaderCode( Qt3DRender::QShaderProgram::Vertex, Qgs3DUtils::addDefinesToShaderCode( vertCode, defines ) );
113 mShaderProgram->setFragmentShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( u"qrc:/shaders/singlecolor.frag"_s ) ) );
114 }
115 else if ( mDataDefinedEnabled )
116 {
117 mShaderProgram->setShaderCode( Qt3DRender::QShaderProgram::Vertex, Qt3DRender::QShaderProgram::loadSource( QUrl( u"qrc:/shaders/singlecolorDataDefined.vert"_s ) ) );
118 const QByteArray fragCode = Qt3DRender::QShaderProgram::loadSource( QUrl( u"qrc:/shaders/singlecolor.frag"_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( Qt3DRender::QShaderProgram::loadSource( QUrl( u"qrc:/shaders/singlecolor.frag"_s ) ) );
125 }
126}
127
QFlags< InstancedMaterialFlag > InstancedMaterialFlags
Definition qgis.h:4427
@ DataDefinedRotation
Per-instance data-defined rotation.
Definition qgis.h:4424
@ DataDefinedScale
Per-instance data-defined scale.
Definition qgis.h:4423
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