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

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