1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qmorphphongmaterial.h"
5#include "qmorphphongmaterial_p.h"
6#include <Qt3DRender/qfilterkey.h>
7#include <Qt3DRender/qmaterial.h>
8#include <Qt3DRender/qeffect.h>
9#include <Qt3DRender/qtechnique.h>
10#include <Qt3DRender/qshaderprogram.h>
11#include <Qt3DRender/qparameter.h>
12#include <Qt3DRender/qrenderpass.h>
13#include <Qt3DRender/qgraphicsapifilter.h>
14#include <Qt3DRender/qshaderprogrambuilder.h>
15#include <QUrl>
16#include <QVector3D>
17#include <QVector4D>
18
19QT_BEGIN_NAMESPACE
20
21using namespace Qt3DRender;
22
23namespace Qt3DExtras {
24
25QMorphPhongMaterialPrivate::QMorphPhongMaterialPrivate()
26 : QMaterialPrivate()
27 , m_phongEffect(new QEffect())
28 , m_ambientParameter(new QParameter(QStringLiteral("ka"), QColor::fromRgbF(r: 0.05f, g: 0.05f, b: 0.05f, a: 1.0f)))
29 , m_diffuseParameter(new QParameter(QStringLiteral("kd"), QColor::fromRgbF(r: 0.7f, g: 0.7f, b: 0.7f, a: 1.0f)))
30 , m_specularParameter(new QParameter(QStringLiteral("ks"), QColor::fromRgbF(r: 0.01f, g: 0.01f, b: 0.01f, a: 1.0f)))
31 , m_shininessParameter(new QParameter(QStringLiteral("shininess"), 150.0f))
32 , m_interpolatorParameter(new QParameter(QStringLiteral("interpolator"), 0.0f))
33 , m_phongGL3Technique(new QTechnique())
34 , m_phongGL2Technique(new QTechnique())
35 , m_phongES2Technique(new QTechnique())
36 , m_phongRHITechnique(new QTechnique())
37 , m_phongGL3RenderPass(new QRenderPass())
38 , m_phongGL2RenderPass(new QRenderPass())
39 , m_phongES2RenderPass(new QRenderPass())
40 , m_phongRHIRenderPass(new QRenderPass())
41 , m_phongGL3Shader(new QShaderProgram())
42 , m_phongGL2ES2Shader(new QShaderProgram())
43 , m_phongRHIShader(new QShaderProgram())
44 , m_phongGL3ShaderBuilder(new QShaderProgramBuilder())
45 , m_phongGL2ES2ShaderBuilder(new QShaderProgramBuilder())
46 , m_phongRHIShaderBuilder(new QShaderProgramBuilder())
47 , m_filterKey(new QFilterKey)
48{
49}
50
51void QMorphPhongMaterialPrivate::init()
52{
53 Q_Q(QMorphPhongMaterial);
54
55 connect(sender: m_ambientParameter, signal: &Qt3DRender::QParameter::valueChanged,
56 receiverPrivate: this, slot: &QMorphPhongMaterialPrivate::handleAmbientChanged);
57 connect(sender: m_diffuseParameter, signal: &Qt3DRender::QParameter::valueChanged,
58 receiverPrivate: this, slot: &QMorphPhongMaterialPrivate::handleDiffuseChanged);
59 connect(sender: m_specularParameter, signal: &Qt3DRender::QParameter::valueChanged,
60 receiverPrivate: this, slot: &QMorphPhongMaterialPrivate::handleSpecularChanged);
61 connect(sender: m_shininessParameter, signal: &Qt3DRender::QParameter::valueChanged,
62 receiverPrivate: this, slot: &QMorphPhongMaterialPrivate::handleShininessChanged);
63 connect(sender: m_interpolatorParameter, signal: &Qt3DRender::QParameter::valueChanged,
64 receiverPrivate: this, slot: &QMorphPhongMaterialPrivate::handleInterpolatorChanged);
65
66 m_phongGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(sourceUrl: QUrl(QStringLiteral("qrc:/shaders/gl3/morphphong.vert"))));
67 m_phongGL3ShaderBuilder->setParent(q);
68 m_phongGL3ShaderBuilder->setShaderProgram(m_phongGL3Shader);
69 m_phongGL3ShaderBuilder->setFragmentShaderGraph(QUrl(QStringLiteral("qrc:/shaders/graphs/phong.frag.json")));
70 m_phongGL3ShaderBuilder->setEnabledLayers({QStringLiteral("diffuse"),
71 QStringLiteral("specular"),
72 QStringLiteral("normal")});
73
74 m_phongGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(sourceUrl: QUrl(QStringLiteral("qrc:/shaders/es2/morphphong.vert"))));
75 m_phongGL2ES2ShaderBuilder->setParent(q);
76 m_phongGL2ES2ShaderBuilder->setShaderProgram(m_phongGL2ES2Shader);
77 m_phongGL2ES2ShaderBuilder->setFragmentShaderGraph(QUrl(QStringLiteral("qrc:/shaders/graphs/phong.frag.json")));
78 m_phongGL2ES2ShaderBuilder->setEnabledLayers({QStringLiteral("diffuse"),
79 QStringLiteral("specular"),
80 QStringLiteral("normal")});
81
82 m_phongRHIShader->setVertexShaderCode(QShaderProgram::loadSource(sourceUrl: QUrl(QStringLiteral("qrc:/shaders/rhi/morphphong.vert"))));
83 m_phongRHIShaderBuilder->setParent(q);
84 m_phongRHIShaderBuilder->setShaderProgram(m_phongRHIShader);
85 m_phongRHIShaderBuilder->setFragmentShaderGraph(QUrl(QStringLiteral("qrc:/shaders/graphs/phong.frag.json")));
86 m_phongRHIShaderBuilder->setEnabledLayers({QStringLiteral("diffuse"),
87 QStringLiteral("specular"),
88 QStringLiteral("normal")});
89
90 m_phongGL3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
91 m_phongGL3Technique->graphicsApiFilter()->setMajorVersion(3);
92 m_phongGL3Technique->graphicsApiFilter()->setMinorVersion(1);
93 m_phongGL3Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::CoreProfile);
94
95 m_phongGL2Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
96 m_phongGL2Technique->graphicsApiFilter()->setMajorVersion(2);
97 m_phongGL2Technique->graphicsApiFilter()->setMinorVersion(0);
98 m_phongGL2Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::NoProfile);
99
100 m_phongES2Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGLES);
101 m_phongES2Technique->graphicsApiFilter()->setMajorVersion(2);
102 m_phongES2Technique->graphicsApiFilter()->setMinorVersion(0);
103 m_phongES2Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::NoProfile);
104
105 m_phongRHITechnique->graphicsApiFilter()->setApi(QGraphicsApiFilter::RHI);
106 m_phongRHITechnique->graphicsApiFilter()->setMajorVersion(1);
107 m_phongRHITechnique->graphicsApiFilter()->setMinorVersion(0);
108
109 m_phongGL3RenderPass->setShaderProgram(m_phongGL3Shader);
110 m_phongGL2RenderPass->setShaderProgram(m_phongGL2ES2Shader);
111 m_phongES2RenderPass->setShaderProgram(m_phongGL2ES2Shader);
112 m_phongRHIRenderPass->setShaderProgram(m_phongRHIShader);
113
114 m_phongGL3Technique->addRenderPass(pass: m_phongGL3RenderPass);
115 m_phongGL2Technique->addRenderPass(pass: m_phongGL2RenderPass);
116 m_phongES2Technique->addRenderPass(pass: m_phongES2RenderPass);
117 m_phongRHITechnique->addRenderPass(pass: m_phongRHIRenderPass);
118
119 m_filterKey->setParent(q);
120 m_filterKey->setName(QStringLiteral("renderingStyle"));
121 m_filterKey->setValue(QStringLiteral("forward"));
122
123 m_phongGL3Technique->addFilterKey(filterKey: m_filterKey);
124 m_phongGL2Technique->addFilterKey(filterKey: m_filterKey);
125 m_phongES2Technique->addFilterKey(filterKey: m_filterKey);
126 m_phongRHITechnique->addFilterKey(filterKey: m_filterKey);
127
128 m_phongEffect->addTechnique(t: m_phongGL3Technique);
129 m_phongEffect->addTechnique(t: m_phongGL2Technique);
130 m_phongEffect->addTechnique(t: m_phongES2Technique);
131 m_phongEffect->addTechnique(t: m_phongRHITechnique);
132
133 m_phongEffect->addParameter(parameter: m_ambientParameter);
134 m_phongEffect->addParameter(parameter: m_diffuseParameter);
135 m_phongEffect->addParameter(parameter: m_specularParameter);
136 m_phongEffect->addParameter(parameter: m_shininessParameter);
137 m_phongEffect->addParameter(parameter: m_interpolatorParameter);
138
139 q->setEffect(m_phongEffect);
140}
141
142void QMorphPhongMaterialPrivate::handleAmbientChanged(const QVariant &var)
143{
144 Q_Q(QMorphPhongMaterial);
145 emit q->ambientChanged(ambient: var.value<QColor>());
146}
147
148void QMorphPhongMaterialPrivate::handleDiffuseChanged(const QVariant &var)
149{
150 Q_Q(QMorphPhongMaterial);
151 emit q->diffuseChanged(diffuse: var.value<QColor>());
152}
153
154void QMorphPhongMaterialPrivate::handleSpecularChanged(const QVariant &var)
155{
156 Q_Q(QMorphPhongMaterial);
157 emit q->specularChanged(specular: var.value<QColor>());
158}
159
160void QMorphPhongMaterialPrivate::handleShininessChanged(const QVariant &var)
161{
162 Q_Q(QMorphPhongMaterial);
163 emit q->shininessChanged(shininess: var.toFloat());
164}
165
166void QMorphPhongMaterialPrivate::handleInterpolatorChanged(const QVariant &var)
167{
168 Q_Q(QMorphPhongMaterial);
169 emit q->interpolatorChanged(interpolator: var.toFloat());
170}
171
172/*!
173 \class Qt3DExtras::QMorphPhongMaterial
174 \ingroup qt3d-extras-materials
175 \brief The QMorphPhongMaterial class provides a default implementation of the phong lighting effect.
176 \inmodule Qt3DExtras
177 \since 5.7
178 \inherits Qt3DRender::QMaterial
179
180 The phong lighting effect is based on the combination of 3 lighting components ambient, diffuse
181 and specular. The relative strengths of these components are controlled by means of their
182 reflectivity coefficients which are modelled as RGB triplets:
183
184 \list
185 \li Ambient is the color that is emitted by an object without any other light source.
186 \li Diffuse is the color that is emitted for rought surface reflections with the lights.
187 \li Specular is the color emitted for shiny surface reflections with the lights.
188 \li The shininess of a surface is controlled by a float property.
189 \endlist
190
191 This material uses an effect with a single render pass approach and performs per fragment
192 lighting. Techniques are provided for OpenGL 2, OpenGL 3 or above as well as OpenGL ES 2.
193*/
194
195/*!
196 Constructs a new QMorphPhongMaterial instance with parent object \a parent.
197*/
198QMorphPhongMaterial::QMorphPhongMaterial(QNode *parent)
199 : QMaterial(*new QMorphPhongMaterialPrivate, parent)
200{
201 Q_D(QMorphPhongMaterial);
202 d->init();
203}
204
205/*!
206 Destroys the QMorphPhongMaterial.
207*/
208QMorphPhongMaterial::~QMorphPhongMaterial()
209{
210}
211
212/*!
213 \property QMorphPhongMaterial::ambient
214
215 Holds the ambient color.
216*/
217QColor QMorphPhongMaterial::ambient() const
218{
219 Q_D(const QMorphPhongMaterial);
220 return d->m_ambientParameter->value().value<QColor>();
221}
222
223/*!
224 \property QMorphPhongMaterial::diffuse
225
226 Holds the diffuse color.
227*/
228QColor QMorphPhongMaterial::diffuse() const
229{
230 Q_D(const QMorphPhongMaterial);
231 return d->m_diffuseParameter->value().value<QColor>();
232}
233
234/*!
235 \property QMorphPhongMaterial::specular
236
237 Holds the specular color.
238*/
239QColor QMorphPhongMaterial::specular() const
240{
241 Q_D(const QMorphPhongMaterial);
242 return d->m_specularParameter->value().value<QColor>();
243}
244
245/*!
246 \property QMorphPhongMaterial::shininess
247
248 Holds the shininess exponent.
249*/
250float QMorphPhongMaterial::shininess() const
251{
252 Q_D(const QMorphPhongMaterial);
253 return d->m_shininessParameter->value().toFloat();
254}
255
256/*!
257 \property QMorphPhongMaterial::interpolator
258
259 Contains the interpolation method of the Phong lighting effect.
260*/
261float QMorphPhongMaterial::interpolator() const
262{
263 Q_D(const QMorphPhongMaterial);
264 return d->m_interpolatorParameter->value().toFloat();
265}
266
267void QMorphPhongMaterial::setAmbient(const QColor &ambient)
268{
269 Q_D(QMorphPhongMaterial);
270 d->m_ambientParameter->setValue(ambient);
271}
272
273void QMorphPhongMaterial::setDiffuse(const QColor &diffuse)
274{
275 Q_D(QMorphPhongMaterial);
276 d->m_diffuseParameter->setValue(diffuse);
277}
278
279void QMorphPhongMaterial::setSpecular(const QColor &specular)
280{
281 Q_D(QMorphPhongMaterial);
282 d->m_specularParameter->setValue(specular);
283}
284
285void QMorphPhongMaterial::setShininess(float shininess)
286{
287 Q_D(QMorphPhongMaterial);
288 d->m_shininessParameter->setValue(shininess);
289}
290
291void QMorphPhongMaterial::setInterpolator(float interpolator)
292{
293 Q_D(QMorphPhongMaterial);
294 d->m_interpolatorParameter->setValue(interpolator);
295}
296
297} // namespace Qt3DExtras
298
299QT_END_NAMESPACE
300
301#include "moc_qmorphphongmaterial.cpp"
302

source code of qt3d/src/extras/defaults/qmorphphongmaterial.cpp