1/****************************************************************************
2**
3** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt3D module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qphongalphamaterial.h"
41#include "qphongalphamaterial_p.h"
42
43#include <Qt3DRender/qfilterkey.h>
44#include <Qt3DRender/qmaterial.h>
45#include <Qt3DRender/qeffect.h>
46#include <Qt3DRender/qtechnique.h>
47#include <Qt3DRender/qshaderprogram.h>
48#include <Qt3DRender/qshaderprogrambuilder.h>
49#include <Qt3DRender/qparameter.h>
50#include <Qt3DRender/qrenderpass.h>
51#include <Qt3DRender/qgraphicsapifilter.h>
52#include <Qt3DRender/qblendequation.h>
53#include <Qt3DRender/qblendequationarguments.h>
54#include <Qt3DRender/qnodepthmask.h>
55#include <QtCore/QUrl>
56#include <QtGui/QVector3D>
57#include <QtGui/QVector4D>
58
59QT_BEGIN_NAMESPACE
60
61using namespace Qt3DRender;
62
63namespace Qt3DExtras {
64
65QPhongAlphaMaterialPrivate::QPhongAlphaMaterialPrivate()
66 : QMaterialPrivate()
67 , m_phongEffect(new QEffect())
68 , m_ambientParameter(new QParameter(QStringLiteral("ka"), QColor::fromRgbF(r: 0.05f, g: 0.05f, b: 0.05f, a: 1.0f)))
69 , m_diffuseParameter(new QParameter(QStringLiteral("kd"), QColor::fromRgbF(r: 0.7f, g: 0.7f, b: 0.7f, a: 0.5f)))
70 , m_specularParameter(new QParameter(QStringLiteral("ks"), QColor::fromRgbF(r: 0.01f, g: 0.01f, b: 0.01f, a: 1.0f)))
71 , m_shininessParameter(new QParameter(QStringLiteral("shininess"), 150.0f))
72 , m_phongAlphaGL3Technique(new QTechnique())
73 , m_phongAlphaGL2Technique(new QTechnique())
74 , m_phongAlphaES2Technique(new QTechnique())
75 , m_phongAlphaRHITechnique(new QTechnique())
76 , m_phongAlphaGL3RenderPass(new QRenderPass())
77 , m_phongAlphaGL2RenderPass(new QRenderPass())
78 , m_phongAlphaES2RenderPass(new QRenderPass())
79 , m_phongAlphaRHIRenderPass(new QRenderPass())
80 , m_phongAlphaGL3Shader(new QShaderProgram())
81 , m_phongAlphaGL3ShaderBuilder(new QShaderProgramBuilder())
82 , m_phongAlphaGL2ES2Shader(new QShaderProgram())
83 , m_phongAlphaGL2ES2ShaderBuilder(new QShaderProgramBuilder())
84 , m_phongAlphaRHIShader(new QShaderProgram())
85 , m_phongAlphaRHIShaderBuilder(new QShaderProgramBuilder())
86 , m_noDepthMask(new QNoDepthMask())
87 , m_blendState(new QBlendEquationArguments())
88 , m_blendEquation(new QBlendEquation())
89 , m_filterKey(new QFilterKey)
90{
91}
92
93// TODO: Define how lights are properties are set in the shaders. Ideally using a QShaderData
94void QPhongAlphaMaterialPrivate::init()
95{
96 Q_Q(QPhongAlphaMaterial);
97
98 connect(sender: m_ambientParameter, signal: &Qt3DRender::QParameter::valueChanged,
99 receiverPrivate: this, slot: &QPhongAlphaMaterialPrivate::handleAmbientChanged);
100 connect(sender: m_diffuseParameter, signal: &Qt3DRender::QParameter::valueChanged,
101 receiverPrivate: this, slot: &QPhongAlphaMaterialPrivate::handleDiffuseChanged);
102 connect(sender: m_specularParameter, signal: &Qt3DRender::QParameter::valueChanged,
103 receiverPrivate: this, slot: &QPhongAlphaMaterialPrivate::handleSpecularChanged);
104 connect(sender: m_shininessParameter, signal: &Qt3DRender::QParameter::valueChanged,
105 receiverPrivate: this, slot: &QPhongAlphaMaterialPrivate::handleShininessChanged);
106
107 m_phongAlphaGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(sourceUrl: QUrl(QStringLiteral("qrc:/shaders/gl3/default.vert"))));
108 m_phongAlphaGL3ShaderBuilder->setParent(q);
109 m_phongAlphaGL3ShaderBuilder->setShaderProgram(m_phongAlphaGL3Shader);
110 m_phongAlphaGL3ShaderBuilder->setFragmentShaderGraph(QUrl(QStringLiteral("qrc:/shaders/graphs/phong.frag.json")));
111 m_phongAlphaGL3ShaderBuilder->setEnabledLayers({QStringLiteral("diffuse"),
112 QStringLiteral("specular"),
113 QStringLiteral("normal")});
114
115 m_phongAlphaGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(sourceUrl: QUrl(QStringLiteral("qrc:/shaders/es2/default.vert"))));
116 m_phongAlphaGL2ES2ShaderBuilder->setParent(q);
117 m_phongAlphaGL2ES2ShaderBuilder->setShaderProgram(m_phongAlphaGL2ES2Shader);
118 m_phongAlphaGL2ES2ShaderBuilder->setFragmentShaderGraph(QUrl(QStringLiteral("qrc:/shaders/graphs/phong.frag.json")));
119 m_phongAlphaGL2ES2ShaderBuilder->setEnabledLayers({QStringLiteral("diffuse"),
120 QStringLiteral("specular"),
121 QStringLiteral("normal")});
122
123 m_phongAlphaRHIShader->setVertexShaderCode(QShaderProgram::loadSource(sourceUrl: QUrl(QStringLiteral("qrc:/shaders/rhi/default.vert"))));
124 m_phongAlphaRHIShaderBuilder->setParent(q);
125 m_phongAlphaRHIShaderBuilder->setShaderProgram(m_phongAlphaRHIShader);
126 m_phongAlphaRHIShaderBuilder->setFragmentShaderGraph(QUrl(QStringLiteral("qrc:/shaders/graphs/phong.frag.json")));
127 m_phongAlphaRHIShaderBuilder->setEnabledLayers({QStringLiteral("diffuse"),
128 QStringLiteral("specular"),
129 QStringLiteral("normal")});
130
131 m_phongAlphaGL3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
132 m_phongAlphaGL3Technique->graphicsApiFilter()->setMajorVersion(3);
133 m_phongAlphaGL3Technique->graphicsApiFilter()->setMinorVersion(1);
134 m_phongAlphaGL3Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::CoreProfile);
135
136 m_phongAlphaGL2Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
137 m_phongAlphaGL2Technique->graphicsApiFilter()->setMajorVersion(2);
138 m_phongAlphaGL2Technique->graphicsApiFilter()->setMinorVersion(0);
139 m_phongAlphaGL2Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::NoProfile);
140
141 m_phongAlphaES2Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGLES);
142 m_phongAlphaES2Technique->graphicsApiFilter()->setMajorVersion(2);
143 m_phongAlphaES2Technique->graphicsApiFilter()->setMinorVersion(0);
144 m_phongAlphaES2Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::NoProfile);
145
146 m_phongAlphaRHITechnique->graphicsApiFilter()->setApi(QGraphicsApiFilter::RHI);
147 m_phongAlphaRHITechnique->graphicsApiFilter()->setMajorVersion(1);
148 m_phongAlphaRHITechnique->graphicsApiFilter()->setMinorVersion(0);
149
150 m_filterKey->setParent(q);
151 m_filterKey->setName(QStringLiteral("renderingStyle"));
152 m_filterKey->setValue(QStringLiteral("forward"));
153
154 m_phongAlphaGL3Technique->addFilterKey(filterKey: m_filterKey);
155 m_phongAlphaGL2Technique->addFilterKey(filterKey: m_filterKey);
156 m_phongAlphaES2Technique->addFilterKey(filterKey: m_filterKey);
157 m_phongAlphaRHITechnique->addFilterKey(filterKey: m_filterKey);
158
159 m_blendState->setSourceRgb(QBlendEquationArguments::SourceAlpha);
160 m_blendState->setDestinationRgb(QBlendEquationArguments::OneMinusSourceAlpha);
161 m_blendEquation->setBlendFunction(QBlendEquation::Add);
162
163 m_phongAlphaGL3RenderPass->setShaderProgram(m_phongAlphaGL3Shader);
164 m_phongAlphaGL2RenderPass->setShaderProgram(m_phongAlphaGL2ES2Shader);
165 m_phongAlphaES2RenderPass->setShaderProgram(m_phongAlphaGL2ES2Shader);
166 m_phongAlphaRHIRenderPass->setShaderProgram(m_phongAlphaRHIShader);
167
168 m_phongAlphaGL3RenderPass->addRenderState(state: m_noDepthMask);
169 m_phongAlphaGL3RenderPass->addRenderState(state: m_blendState);
170 m_phongAlphaGL3RenderPass->addRenderState(state: m_blendEquation);
171
172 m_phongAlphaGL2RenderPass->addRenderState(state: m_noDepthMask);
173 m_phongAlphaGL2RenderPass->addRenderState(state: m_blendState);
174 m_phongAlphaGL2RenderPass->addRenderState(state: m_blendEquation);
175
176 m_phongAlphaES2RenderPass->addRenderState(state: m_noDepthMask);
177 m_phongAlphaES2RenderPass->addRenderState(state: m_blendState);
178 m_phongAlphaES2RenderPass->addRenderState(state: m_blendEquation);
179
180 m_phongAlphaRHIRenderPass->addRenderState(state: m_noDepthMask);
181 m_phongAlphaRHIRenderPass->addRenderState(state: m_blendState);
182 m_phongAlphaRHIRenderPass->addRenderState(state: m_blendEquation);
183
184 m_phongAlphaGL3Technique->addRenderPass(pass: m_phongAlphaGL3RenderPass);
185 m_phongAlphaGL2Technique->addRenderPass(pass: m_phongAlphaGL2RenderPass);
186 m_phongAlphaES2Technique->addRenderPass(pass: m_phongAlphaES2RenderPass);
187 m_phongAlphaRHITechnique->addRenderPass(pass: m_phongAlphaRHIRenderPass);
188
189 m_phongEffect->addTechnique(t: m_phongAlphaGL3Technique);
190 m_phongEffect->addTechnique(t: m_phongAlphaGL2Technique);
191 m_phongEffect->addTechnique(t: m_phongAlphaES2Technique);
192 m_phongEffect->addTechnique(t: m_phongAlphaRHITechnique);
193
194 m_phongEffect->addParameter(parameter: m_ambientParameter);
195 m_phongEffect->addParameter(parameter: m_diffuseParameter);
196 m_phongEffect->addParameter(parameter: m_specularParameter);
197 m_phongEffect->addParameter(parameter: m_shininessParameter);
198
199 q->setEffect(m_phongEffect);
200}
201
202void QPhongAlphaMaterialPrivate::handleAmbientChanged(const QVariant &var)
203{
204 Q_Q(QPhongAlphaMaterial);
205 emit q->ambientChanged(ambient: var.value<QColor>());
206}
207
208void QPhongAlphaMaterialPrivate::handleDiffuseChanged(const QVariant &var)
209{
210 Q_Q(QPhongAlphaMaterial);
211 emit q->diffuseChanged(diffuse: var.value<QColor>());
212 emit q->alphaChanged(alpha: var.value<QColor>().alphaF());
213}
214
215void QPhongAlphaMaterialPrivate::handleSpecularChanged(const QVariant &var)
216{
217 Q_Q(QPhongAlphaMaterial);
218 emit q->specularChanged(specular: var.value<QColor>());
219}
220
221void QPhongAlphaMaterialPrivate::handleShininessChanged(const QVariant &var)
222{
223 Q_Q(QPhongAlphaMaterial);
224 emit q->shininessChanged(shininess: var.toFloat());
225}
226
227/*!
228 \class Qt3DExtras::QPhongAlphaMaterial
229
230 \brief The QPhongAlphaMaterial class provides a default implementation of
231 the phong lighting effect with alpha.
232 \inmodule Qt3DExtras
233 \since 5.7
234 \inherits Qt3DRender::QMaterial
235
236 \deprecated
237 This class is deprecated; use QDiffuseSpecularMaterial instead.
238
239 The phong lighting effect is based on the combination of 3 lighting components ambient, diffuse
240 and specular. The relative strengths of these components are controlled by means of their
241 reflectivity coefficients which are modelled as RGB triplets:
242
243 \list
244 \li Ambient is the color that is emitted by an object without any other light source.
245 \li Diffuse is the color that is emitted for rought surface reflections with the lights.
246 \li Specular is the color emitted for shiny surface reflections with the lights.
247 \li The shininess of a surface is controlled by a float property.
248 \li Alpha is the transparency of the surface between 0 (fully transparent) and 1 (opaque).
249 \endlist
250
251 This material uses an effect with a single render pass approach and performs per fragment
252 lighting. Techniques are provided for OpenGL 2, OpenGL 3 or above as well as OpenGL ES 2.
253*/
254
255/*!
256 Constructs a new QPhongAlphaMaterial instance with parent object \a parent.
257*/
258QPhongAlphaMaterial::QPhongAlphaMaterial(QNode *parent)
259 : QMaterial(*new QPhongAlphaMaterialPrivate, parent)
260{
261 Q_D(QPhongAlphaMaterial);
262 d->init();
263
264 QObject::connect(sender: d->m_blendEquation, signal: &Qt3DRender::QBlendEquation::blendFunctionChanged,
265 receiver: this, slot: &QPhongAlphaMaterial::blendFunctionArgChanged);
266 QObject::connect(sender: d->m_blendState, signal: &Qt3DRender::QBlendEquationArguments::destinationAlphaChanged,
267 receiver: this, slot: &QPhongAlphaMaterial::destinationAlphaArgChanged);
268 QObject::connect(sender: d->m_blendState, signal: &Qt3DRender::QBlendEquationArguments::destinationRgbChanged,
269 receiver: this, slot: &QPhongAlphaMaterial::destinationRgbArgChanged);
270 QObject::connect(sender: d->m_blendState, signal: &Qt3DRender::QBlendEquationArguments::sourceAlphaChanged,
271 receiver: this, slot: &QPhongAlphaMaterial::sourceAlphaArgChanged);
272 QObject::connect(sender: d->m_blendState, signal: &Qt3DRender::QBlendEquationArguments::sourceRgbChanged,
273 receiver: this, slot: &QPhongAlphaMaterial::sourceRgbArgChanged);
274}
275
276/*!
277 Destroys the QPhongAlphaMaterial.
278*/
279QPhongAlphaMaterial::~QPhongAlphaMaterial()
280{
281}
282
283/*!
284 \property QPhongAlphaMaterial::ambient
285
286 Holds the ambient color.
287*/
288QColor QPhongAlphaMaterial::ambient() const
289{
290 Q_D(const QPhongAlphaMaterial);
291 return d->m_ambientParameter->value().value<QColor>();
292}
293
294/*!
295 \property QPhongAlphaMaterial::diffuse
296
297 Holds the diffuse color.
298*/
299QColor QPhongAlphaMaterial::diffuse() const
300{
301 Q_D(const QPhongAlphaMaterial);
302 return d->m_diffuseParameter->value().value<QColor>();
303}
304
305/*!
306 \property QPhongAlphaMaterial::specular
307
308 Holds the specular color.
309*/
310QColor QPhongAlphaMaterial::specular() const
311{
312 Q_D(const QPhongAlphaMaterial);
313 return d->m_specularParameter->value().value<QColor>();
314}
315
316/*!
317 \property QPhongAlphaMaterial::shininess
318
319 Holds the shininess exponent.
320*/
321float QPhongAlphaMaterial::shininess() const
322{
323 Q_D(const QPhongAlphaMaterial);
324 return d->m_shininessParameter->value().toFloat();
325}
326
327/*!
328 \property QPhongAlphaMaterial::alpha
329
330 Holds the alpha component of the object which varies between 0 and 1.
331
332 The default value is 0.5f.
333*/
334float QPhongAlphaMaterial::alpha() const
335{
336 Q_D(const QPhongAlphaMaterial);
337 return d->m_diffuseParameter->value().value<QColor>().alphaF();
338}
339
340/*!
341 \property QPhongAlphaMaterial::sourceRgbArg
342
343 Holds the blend equation source RGB blending argument.
344
345 \sa Qt3DRender::QBlendEquationArguments::Blending
346*/
347QBlendEquationArguments::Blending QPhongAlphaMaterial::sourceRgbArg() const
348{
349 Q_D(const QPhongAlphaMaterial);
350 return d->m_blendState->sourceRgb();
351}
352
353/*!
354 \property QPhongAlphaMaterial::destinationRgbArg
355
356 Holds the blend equation destination RGB blending argument.
357
358 \sa Qt3DRender::QBlendEquationArguments::Blending
359*/
360QBlendEquationArguments::Blending QPhongAlphaMaterial::destinationRgbArg() const
361{
362 Q_D(const QPhongAlphaMaterial);
363 return d->m_blendState->destinationRgb();
364}
365
366/*!
367 \property QPhongAlphaMaterial::sourceAlphaArg
368
369 Holds the blend equation source alpha blending argument.
370
371 \sa Qt3DRender::QBlendEquationArguments::Blending
372*/
373QBlendEquationArguments::Blending QPhongAlphaMaterial::sourceAlphaArg() const
374{
375 Q_D(const QPhongAlphaMaterial);
376 return d->m_blendState->sourceAlpha();
377}
378
379/*!
380 \property QPhongAlphaMaterial::destinationAlphaArg
381
382 Holds the blend equation destination alpha blending argument.
383
384 \sa Qt3DRender::QBlendEquationArguments::Blending
385*/
386QBlendEquationArguments::Blending QPhongAlphaMaterial::destinationAlphaArg() const
387{
388 Q_D(const QPhongAlphaMaterial);
389 return d->m_blendState->destinationAlpha();
390}
391
392/*!
393 \property QPhongAlphaMaterial::blendFunctionArg
394
395 Holds the blend equation function argument.
396
397 \sa Qt3DRender::QBlendEquation::BlendFunction
398*/
399QBlendEquation::BlendFunction QPhongAlphaMaterial::blendFunctionArg() const
400{
401 Q_D(const QPhongAlphaMaterial);
402 return d->m_blendEquation->blendFunction();
403}
404
405void QPhongAlphaMaterial::setAmbient(const QColor &ambient)
406{
407 Q_D(QPhongAlphaMaterial);
408 d->m_ambientParameter->setValue(ambient);
409}
410
411void QPhongAlphaMaterial::setDiffuse(const QColor &diffuse)
412{
413 Q_D(QPhongAlphaMaterial);
414 QColor currentDiffuse = d->m_diffuseParameter->value().value<QColor>();
415 QColor newDiffuse = diffuse;
416 newDiffuse.setAlphaF(currentDiffuse.alphaF());
417 d->m_diffuseParameter->setValue(newDiffuse);
418}
419
420void QPhongAlphaMaterial::setSpecular(const QColor &specular)
421{
422 Q_D(QPhongAlphaMaterial);
423 d->m_specularParameter->setValue(specular);
424}
425
426void QPhongAlphaMaterial::setShininess(float shininess)
427{
428 Q_D(QPhongAlphaMaterial);
429 d->m_shininessParameter->setValue(shininess);
430}
431
432void QPhongAlphaMaterial::setAlpha(float alpha)
433{
434 Q_D(QPhongAlphaMaterial);
435 QColor diffuse = d->m_diffuseParameter->value().value<QColor>();
436 diffuse.setAlphaF(alpha);
437 d->m_diffuseParameter->setValue(diffuse);
438}
439
440void QPhongAlphaMaterial::setSourceRgbArg(QBlendEquationArguments::Blending sourceRgbArg)
441{
442 Q_D(QPhongAlphaMaterial);
443 d->m_blendState->setSourceRgb(sourceRgbArg);
444}
445
446void QPhongAlphaMaterial::setDestinationRgbArg(QBlendEquationArguments::Blending destinationRgbArg)
447{
448 Q_D(QPhongAlphaMaterial);
449 d->m_blendState->setDestinationRgb(destinationRgbArg);
450}
451
452void QPhongAlphaMaterial::setSourceAlphaArg(QBlendEquationArguments::Blending sourceAlphaArg)
453{
454 Q_D(QPhongAlphaMaterial);
455 d->m_blendState->setSourceAlpha(sourceAlphaArg);
456}
457
458void QPhongAlphaMaterial::setDestinationAlphaArg(QBlendEquationArguments::Blending destinationAlphaArg)
459{
460 Q_D(QPhongAlphaMaterial);
461 d->m_blendState->setDestinationAlpha(destinationAlphaArg);
462}
463
464void QPhongAlphaMaterial::setBlendFunctionArg(QBlendEquation::BlendFunction blendFunctionArg)
465{
466 Q_D(QPhongAlphaMaterial);
467 d->m_blendEquation->setBlendFunction(blendFunctionArg);
468}
469
470} // namespace Qt3DExtras
471
472QT_END_NAMESPACE
473

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