QGIS API Documentation 4.1.0-Master (31622b25bb0)
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{
43 setAmbient( QColor::fromRgbF( 0.1f, 0.1f, 0.1f, 1.0f ) );
44 setDiffuse( QColor::fromRgbF( 0.7f, 0.7f, 0.7f, 1.0f ) );
45 setSpecular( QColor::fromRgbF( 1.0f, 1.0f, 1.0f, 1.0f ) );
46 init();
47}
48
49QgsPhongMaterial::~QgsPhongMaterial() = default;
50
51void QgsPhongMaterial::init()
52{
53 Qt3DRender::QEffect *effect = new Qt3DRender::QEffect();
54 effect->addParameter( mAmbientParameter );
55 effect->addParameter( mDiffuseParameter );
56 effect->addParameter( mSpecularParameter );
57 effect->addParameter( mShininessParameter );
58 effect->addParameter( mOpacityParameter );
59
60 mShaderProgram = new Qt3DRender::QShaderProgram();
61
62 Qt3DRender::QRenderPass *renderPass = new Qt3DRender::QRenderPass();
63 renderPass->setShaderProgram( mShaderProgram );
64
65 Qt3DRender::QFilterKey *filterKey = new Qt3DRender::QFilterKey();
66 filterKey->setName( u"renderingStyle"_s );
67 filterKey->setValue( u"forward"_s );
68
69 Qt3DRender::QTechnique *technique = new Qt3DRender::QTechnique();
70 technique->graphicsApiFilter()->setApi( Qt3DRender::QGraphicsApiFilter::OpenGL );
71 technique->graphicsApiFilter()->setProfile( Qt3DRender::QGraphicsApiFilter::CoreProfile );
72 technique->graphicsApiFilter()->setMajorVersion( 3 );
73 technique->graphicsApiFilter()->setMinorVersion( 3 );
74 technique->addFilterKey( filterKey );
75 technique->addRenderPass( renderPass );
76
77 effect->addTechnique( technique );
78 setEffect( effect );
79
80 updateShaders();
81}
82
83void QgsPhongMaterial::setInstancingEnabled( bool enabled, Qgis::InstancedMaterialFlags flags )
84{
85 mInstanced = enabled;
86 mInstanceFlags = flags;
87 updateShaders();
88}
89
90void QgsPhongMaterial::updateShaders()
91{
92 const QByteArray fragCode = Qt3DRender::QShaderProgram::loadSource( QUrl( u"qrc:/shaders/phong.frag"_s ) );
93
94 if ( mInstanced )
95 {
96 QStringList defines;
97 if ( mInstanceFlags.testFlag( Qgis::InstancedMaterialFlag::DataDefinedScale ) )
98 defines << u"USE_INSTANCE_SCALE"_s;
99 if ( mInstanceFlags.testFlag( Qgis::InstancedMaterialFlag::DataDefinedRotation ) )
100 defines << u"USE_INSTANCE_ROTATION"_s;
101 const QByteArray vertCode = Qt3DRender::QShaderProgram::loadSource( QUrl( u"qrc:/shaders/instanced.vert"_s ) );
102 mShaderProgram->setShaderCode( Qt3DRender::QShaderProgram::Vertex, Qgs3DUtils::addDefinesToShaderCode( vertCode, defines ) );
103 mShaderProgram->setFragmentShaderCode( fragCode );
104 }
105 else if ( mDataDefinedEnabled )
106 {
107 mShaderProgram->setShaderCode( Qt3DRender::QShaderProgram::Vertex, Qt3DRender::QShaderProgram::loadSource( QUrl( u"qrc:/shaders/phongDataDefined.vert"_s ) ) );
108 mShaderProgram->setFragmentShaderCode( Qgs3DUtils::addDefinesToShaderCode( fragCode, QStringList( { u"DATA_DEFINED"_s } ) ) );
109 }
110 else
111 {
112 mShaderProgram->setShaderCode( Qt3DRender::QShaderProgram::Vertex, Qt3DRender::QShaderProgram::loadSource( QUrl( u"qrc:/shaders/default.vert"_s ) ) );
113 mShaderProgram->setFragmentShaderCode( fragCode );
114 }
115}
116
117void QgsPhongMaterial::setDataDefinedEnabled( bool enabled )
118{
119 if ( enabled != mDataDefinedEnabled )
120 {
121 mDataDefinedEnabled = enabled;
122 updateShaders();
123 }
124}
125
126void QgsPhongMaterial::setAmbient( const QColor &ambient, float scaleFactor )
127{
128 const QColor color = Qgs3DUtils::srgbToLinear( ambient );
129 mAmbientParameter->setValue( QColor::fromRgbF( color.redF() * scaleFactor, color.greenF() * scaleFactor, color.blueF() * scaleFactor ) );
130}
131
132void QgsPhongMaterial::setDiffuse( const QColor &diffuse, float scaleFactor )
133{
134 const QColor color = Qgs3DUtils::srgbToLinear( diffuse );
135 mDiffuseParameter->setValue( QColor::fromRgbF( color.redF() * scaleFactor, color.greenF() * scaleFactor, color.blueF() * scaleFactor ) );
136}
137
138void QgsPhongMaterial::setSpecular( const QColor &specular, float scaleFactor )
139{
140 const QColor color = Qgs3DUtils::srgbToLinear( specular );
141 mSpecularParameter->setValue( QColor::fromRgbF( color.redF() * scaleFactor, color.greenF() * scaleFactor, color.blueF() * scaleFactor ) );
142}
143
144void QgsPhongMaterial::setShininess( float shininess )
145{
146 mShininessParameter->setValue( shininess );
147}
148
149void QgsPhongMaterial::setOpacity( float opacity )
150{
151 mOpacityParameter->setValue( opacity );
152}
153
QFlags< InstancedMaterialFlag > InstancedMaterialFlags
Definition qgis.h:4365
@ DataDefinedRotation
Per-instance data-defined rotation.
Definition qgis.h:4362
@ DataDefinedScale
Per-instance data-defined scale.
Definition qgis.h:4361
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