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 "qnormaldiffusespecularmapmaterial.h"
41#include "qnormaldiffusespecularmapmaterial_p.h"
42
43#include <Qt3DRender/qfilterkey.h>
44#include <Qt3DRender/qmaterial.h>
45#include <Qt3DRender/qeffect.h>
46#include <Qt3DRender/qtexture.h>
47#include <Qt3DRender/qtechnique.h>
48#include <Qt3DRender/qshaderprogram.h>
49#include <Qt3DRender/qshaderprogrambuilder.h>
50#include <Qt3DRender/qparameter.h>
51#include <Qt3DRender/qrenderpass.h>
52#include <Qt3DRender/qgraphicsapifilter.h>
53#include <QtCore/QUrl>
54#include <QtGui/QVector3D>
55#include <QtGui/QVector4D>
56
57QT_BEGIN_NAMESPACE
58
59using namespace Qt3DRender;
60
61namespace Qt3DExtras {
62
63QNormalDiffuseSpecularMapMaterialPrivate::QNormalDiffuseSpecularMapMaterialPrivate()
64 : QMaterialPrivate()
65 , m_normalDiffuseSpecularEffect(new QEffect())
66 , m_diffuseTexture(new QTexture2D())
67 , m_normalTexture(new QTexture2D())
68 , m_specularTexture(new QTexture2D())
69 , m_ambientParameter(new QParameter(QStringLiteral("ka"), QColor::fromRgbF(r: 0.05f, g: 0.05f, b: 0.05f, a: 1.0f)))
70 , m_diffuseParameter(new QParameter(QStringLiteral("diffuseTexture"), m_diffuseTexture))
71 , m_normalParameter(new QParameter(QStringLiteral("normalTexture"), m_normalTexture))
72 , m_specularParameter(new QParameter(QStringLiteral("specularTexture"), m_specularTexture))
73 , m_shininessParameter(new QParameter(QStringLiteral("shininess"), 150.0f))
74 , m_textureScaleParameter(new QParameter(QStringLiteral("texCoordScale"), 1.0f))
75 , m_normalDiffuseSpecularGL3Technique(new QTechnique())
76 , m_normalDiffuseSpecularGL2Technique(new QTechnique())
77 , m_normalDiffuseSpecularES2Technique(new QTechnique())
78 , m_normalDiffuseSpecularRHITechnique(new QTechnique())
79 , m_normalDiffuseSpecularGL3RenderPass(new QRenderPass())
80 , m_normalDiffuseSpecularGL2RenderPass(new QRenderPass())
81 , m_normalDiffuseSpecularES2RenderPass(new QRenderPass())
82 , m_normalDiffuseSpecularRHIRenderPass(new QRenderPass())
83 , m_normalDiffuseSpecularGL3Shader(new QShaderProgram())
84 , m_normalDiffuseSpecularGL3ShaderBuilder(new QShaderProgramBuilder())
85 , m_normalDiffuseSpecularGL2ES2Shader(new QShaderProgram())
86 , m_normalDiffuseSpecularGL2ES2ShaderBuilder(new QShaderProgramBuilder())
87 , m_normalDiffuseSpecularRHIShader(new QShaderProgram())
88 , m_normalDiffuseSpecularRHIShaderBuilder(new QShaderProgramBuilder())
89 , m_filterKey(new QFilterKey)
90{
91 m_diffuseTexture->setMagnificationFilter(QAbstractTexture::Linear);
92 m_diffuseTexture->setMinificationFilter(QAbstractTexture::LinearMipMapLinear);
93 m_diffuseTexture->setWrapMode(QTextureWrapMode(QTextureWrapMode::Repeat));
94 m_diffuseTexture->setGenerateMipMaps(true);
95 m_diffuseTexture->setMaximumAnisotropy(16.0f);
96
97 m_normalTexture->setMagnificationFilter(QAbstractTexture::Linear);
98 m_normalTexture->setMinificationFilter(QAbstractTexture::LinearMipMapLinear);
99 m_normalTexture->setWrapMode(QTextureWrapMode(QTextureWrapMode::Repeat));
100 m_normalTexture->setGenerateMipMaps(true);
101 m_normalTexture->setMaximumAnisotropy(16.0f);
102
103 m_specularTexture->setMagnificationFilter(QAbstractTexture::Linear);
104 m_specularTexture->setMinificationFilter(QAbstractTexture::LinearMipMapLinear);
105 m_specularTexture->setWrapMode(QTextureWrapMode(QTextureWrapMode::Repeat));
106 m_specularTexture->setGenerateMipMaps(true);
107 m_specularTexture->setMaximumAnisotropy(16.0f);
108}
109
110void QNormalDiffuseSpecularMapMaterialPrivate::init()
111{
112 Q_Q(QNormalDiffuseSpecularMapMaterial);
113
114 connect(sender: m_ambientParameter, signal: &Qt3DRender::QParameter::valueChanged,
115 receiverPrivate: this, slot: &QNormalDiffuseSpecularMapMaterialPrivate::handleAmbientChanged);
116 connect(sender: m_diffuseParameter, signal: &Qt3DRender::QParameter::valueChanged,
117 receiverPrivate: this, slot: &QNormalDiffuseSpecularMapMaterialPrivate::handleDiffuseChanged);
118 connect(sender: m_normalParameter, signal: &Qt3DRender::QParameter::valueChanged,
119 receiverPrivate: this, slot: &QNormalDiffuseSpecularMapMaterialPrivate::handleNormalChanged);
120 connect(sender: m_specularParameter, signal: &Qt3DRender::QParameter::valueChanged,
121 receiverPrivate: this, slot: &QNormalDiffuseSpecularMapMaterialPrivate::handleSpecularChanged);
122 connect(sender: m_shininessParameter, signal: &Qt3DRender::QParameter::valueChanged,
123 receiverPrivate: this, slot: &QNormalDiffuseSpecularMapMaterialPrivate::handleShininessChanged);
124 connect(sender: m_textureScaleParameter, signal: &Qt3DRender::QParameter::valueChanged,
125 receiverPrivate: this, slot: &QNormalDiffuseSpecularMapMaterialPrivate::handleTextureScaleChanged);
126
127 m_normalDiffuseSpecularGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(sourceUrl: QUrl(QStringLiteral("qrc:/shaders/gl3/default.vert"))));
128 m_normalDiffuseSpecularGL3ShaderBuilder->setParent(q);
129 m_normalDiffuseSpecularGL3ShaderBuilder->setShaderProgram(m_normalDiffuseSpecularGL3Shader);
130 m_normalDiffuseSpecularGL3ShaderBuilder->setFragmentShaderGraph(QUrl(QStringLiteral("qrc:/shaders/graphs/phong.frag.json")));
131 m_normalDiffuseSpecularGL3ShaderBuilder->setEnabledLayers({QStringLiteral("diffuseTexture"),
132 QStringLiteral("specularTexture"),
133 QStringLiteral("normalTexture")});
134
135 m_normalDiffuseSpecularGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(sourceUrl: QUrl(QStringLiteral("qrc:/shaders/es2/default.vert"))));
136 m_normalDiffuseSpecularGL2ES2ShaderBuilder->setParent(q);
137 m_normalDiffuseSpecularGL2ES2ShaderBuilder->setShaderProgram(m_normalDiffuseSpecularGL2ES2Shader);
138 m_normalDiffuseSpecularGL2ES2ShaderBuilder->setFragmentShaderGraph(QUrl(QStringLiteral("qrc:/shaders/graphs/phong.frag.json")));
139 m_normalDiffuseSpecularGL2ES2ShaderBuilder->setEnabledLayers({QStringLiteral("diffuseTexture"),
140 QStringLiteral("specularTexture"),
141 QStringLiteral("normalTexture")});
142
143 m_normalDiffuseSpecularRHIShader->setVertexShaderCode(QShaderProgram::loadSource(sourceUrl: QUrl(QStringLiteral("qrc:/shaders/rhi/default.vert"))));
144 m_normalDiffuseSpecularRHIShaderBuilder->setParent(q);
145 m_normalDiffuseSpecularRHIShaderBuilder->setShaderProgram(m_normalDiffuseSpecularRHIShader);
146 m_normalDiffuseSpecularRHIShaderBuilder->setFragmentShaderGraph(QUrl(QStringLiteral("qrc:/shaders/graphs/phong.frag.json")));
147 m_normalDiffuseSpecularRHIShaderBuilder->setEnabledLayers({QStringLiteral("diffuseTexture"),
148 QStringLiteral("specularTexture"),
149 QStringLiteral("normalTexture")});
150
151 m_normalDiffuseSpecularGL3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
152 m_normalDiffuseSpecularGL3Technique->graphicsApiFilter()->setMajorVersion(3);
153 m_normalDiffuseSpecularGL3Technique->graphicsApiFilter()->setMinorVersion(1);
154 m_normalDiffuseSpecularGL3Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::CoreProfile);
155
156 m_normalDiffuseSpecularGL2Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
157 m_normalDiffuseSpecularGL2Technique->graphicsApiFilter()->setMajorVersion(2);
158 m_normalDiffuseSpecularGL2Technique->graphicsApiFilter()->setMinorVersion(0);
159 m_normalDiffuseSpecularGL2Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::NoProfile);
160
161 m_normalDiffuseSpecularES2Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGLES);
162 m_normalDiffuseSpecularES2Technique->graphicsApiFilter()->setMajorVersion(2);
163 m_normalDiffuseSpecularES2Technique->graphicsApiFilter()->setMinorVersion(0);
164 m_normalDiffuseSpecularES2Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::NoProfile);
165
166 m_normalDiffuseSpecularRHITechnique->graphicsApiFilter()->setApi(QGraphicsApiFilter::RHI);
167 m_normalDiffuseSpecularRHITechnique->graphicsApiFilter()->setMajorVersion(1);
168 m_normalDiffuseSpecularRHITechnique->graphicsApiFilter()->setMinorVersion(0);
169
170 m_filterKey->setParent(q);
171 m_filterKey->setName(QStringLiteral("renderingStyle"));
172 m_filterKey->setValue(QStringLiteral("forward"));
173
174 m_normalDiffuseSpecularGL3Technique->addFilterKey(filterKey: m_filterKey);
175 m_normalDiffuseSpecularGL2Technique->addFilterKey(filterKey: m_filterKey);
176 m_normalDiffuseSpecularES2Technique->addFilterKey(filterKey: m_filterKey);
177 m_normalDiffuseSpecularRHITechnique->addFilterKey(filterKey: m_filterKey);
178
179 m_normalDiffuseSpecularGL3RenderPass->setShaderProgram(m_normalDiffuseSpecularGL3Shader);
180 m_normalDiffuseSpecularGL2RenderPass->setShaderProgram(m_normalDiffuseSpecularGL2ES2Shader);
181 m_normalDiffuseSpecularES2RenderPass->setShaderProgram(m_normalDiffuseSpecularGL2ES2Shader);
182 m_normalDiffuseSpecularRHIRenderPass->setShaderProgram(m_normalDiffuseSpecularRHIShader);
183
184 m_normalDiffuseSpecularGL3Technique->addRenderPass(pass: m_normalDiffuseSpecularGL3RenderPass);
185 m_normalDiffuseSpecularGL2Technique->addRenderPass(pass: m_normalDiffuseSpecularGL2RenderPass);
186 m_normalDiffuseSpecularES2Technique->addRenderPass(pass: m_normalDiffuseSpecularES2RenderPass);
187 m_normalDiffuseSpecularRHITechnique->addRenderPass(pass: m_normalDiffuseSpecularRHIRenderPass);
188
189 m_normalDiffuseSpecularEffect->addTechnique(t: m_normalDiffuseSpecularGL3Technique);
190 m_normalDiffuseSpecularEffect->addTechnique(t: m_normalDiffuseSpecularGL2Technique);
191 m_normalDiffuseSpecularEffect->addTechnique(t: m_normalDiffuseSpecularES2Technique);
192 m_normalDiffuseSpecularEffect->addTechnique(t: m_normalDiffuseSpecularRHITechnique);
193
194 m_normalDiffuseSpecularEffect->addParameter(parameter: m_ambientParameter);
195 m_normalDiffuseSpecularEffect->addParameter(parameter: m_diffuseParameter);
196 m_normalDiffuseSpecularEffect->addParameter(parameter: m_normalParameter);
197 m_normalDiffuseSpecularEffect->addParameter(parameter: m_specularParameter);
198 m_normalDiffuseSpecularEffect->addParameter(parameter: m_shininessParameter);
199 m_normalDiffuseSpecularEffect->addParameter(parameter: m_textureScaleParameter);
200
201 q->setEffect(m_normalDiffuseSpecularEffect);
202}
203
204void QNormalDiffuseSpecularMapMaterialPrivate::handleAmbientChanged(const QVariant &var)
205{
206 Q_Q(QNormalDiffuseSpecularMapMaterial);
207 emit q->ambientChanged(ambient: var.value<QColor>());
208}
209
210void QNormalDiffuseSpecularMapMaterialPrivate::handleDiffuseChanged(const QVariant &var)
211{
212 Q_Q(QNormalDiffuseSpecularMapMaterial);
213 emit q->diffuseChanged(diffuse: var.value<QAbstractTexture *>());
214}
215
216void QNormalDiffuseSpecularMapMaterialPrivate::handleNormalChanged(const QVariant &var)
217{
218 Q_Q(QNormalDiffuseSpecularMapMaterial);
219 emit q->normalChanged(normal: var.value<QAbstractTexture *>());
220}
221
222void QNormalDiffuseSpecularMapMaterialPrivate::handleSpecularChanged(const QVariant &var)
223{
224 Q_Q(QNormalDiffuseSpecularMapMaterial);
225 emit q->specularChanged(specular: var.value<QAbstractTexture *>());
226}
227
228void QNormalDiffuseSpecularMapMaterialPrivate::handleShininessChanged(const QVariant &var)
229{
230 Q_Q(QNormalDiffuseSpecularMapMaterial);
231 emit q->shininessChanged(shininess: var.toFloat());
232}
233
234void QNormalDiffuseSpecularMapMaterialPrivate::handleTextureScaleChanged(const QVariant &var)
235{
236 Q_Q(QNormalDiffuseSpecularMapMaterial);
237 emit q->textureScaleChanged(textureScale: var.toFloat());
238}
239
240/*!
241 \class Qt3DExtras::QNormalDiffuseSpecularMapMaterial
242 \brief The QNormalDiffuseSpecularMapMaterial provides a default implementation of the phong
243 lighting and bump effect where the diffuse and specular light components are read from texture
244 maps and the normals of the mesh being rendered from a normal texture map.
245 \inmodule Qt3DExtras
246 \since 5.7
247 \inherits Qt3DRender::QMaterial
248
249 \deprecated
250 This class is deprecated; use QDiffuseSpecularMaterial instead.
251
252 The specular lighting effect is based on the combination of 3 lighting components ambient,
253 diffuse and specular. The relative strengths of these components are controlled by means of
254 their reflectivity coefficients which are modelled as RGB triplets:
255
256 \list
257 \li Ambient is the color that is emitted by an object without any other light source.
258 \li Diffuse is the color that is emitted for rought surface reflections with the lights.
259 \li Specular is the color emitted for shiny surface reflections with the lights.
260 \li The shininess of a surface is controlled by a float property.
261 \endlist
262
263 This material uses an effect with a single render pass approach and performs per fragment
264 lighting. Techniques are provided for OpenGL 2, OpenGL 3 or above as well as OpenGL ES 2.
265*/
266
267/*!
268 Constructs a new QNormalDiffuseSpecularMapMaterial instance with parent object \a parent.
269*/
270QNormalDiffuseSpecularMapMaterial::QNormalDiffuseSpecularMapMaterial(QNode *parent)
271 : QMaterial(*new QNormalDiffuseSpecularMapMaterialPrivate, parent)
272{
273 Q_D(QNormalDiffuseSpecularMapMaterial);
274 d->init();
275}
276
277/*! \internal */
278QNormalDiffuseSpecularMapMaterial::QNormalDiffuseSpecularMapMaterial(QNormalDiffuseSpecularMapMaterialPrivate &dd, QNode *parent)
279 : QMaterial(dd, parent)
280{
281 Q_D(QNormalDiffuseSpecularMapMaterial);
282 d->init();
283}
284
285/*!
286 Destroys the QNormalDiffuseSpecularMapMaterial instance.
287*/
288QNormalDiffuseSpecularMapMaterial::~QNormalDiffuseSpecularMapMaterial()
289{
290}
291
292/*!
293 \property QNormalDiffuseSpecularMapMaterial::ambient
294
295 Holds the current ambient color.
296*/
297QColor QNormalDiffuseSpecularMapMaterial::ambient() const
298{
299 Q_D(const QNormalDiffuseSpecularMapMaterial);
300 return d->m_ambientParameter->value().value<QColor>();
301}
302
303/*!
304 \property QNormalDiffuseSpecularMapMaterial::diffuse
305
306 Holds the current diffuse map texture.
307
308 By default, the diffuse texture has the following properties:
309
310 \list
311 \li Linear minification and magnification filters
312 \li Linear mipmap with mipmapping enabled
313 \li Repeat wrap mode
314 \li Maximum anisotropy of 16.0
315 \endlist
316*/
317QAbstractTexture *QNormalDiffuseSpecularMapMaterial::diffuse() const
318{
319 Q_D(const QNormalDiffuseSpecularMapMaterial);
320 return d->m_diffuseParameter->value().value<QAbstractTexture *>();
321}
322
323/*!
324 \property QNormalDiffuseSpecularMapMaterial::normal
325
326 Holds the current normal map texture.
327
328 By default, the normal texture has the following properties:
329
330 \list
331 \li Linear minification and magnification filters
332 \li Repeat wrap mode
333 \li Maximum anisotropy of 16.0
334 \endlist
335*/
336QAbstractTexture *QNormalDiffuseSpecularMapMaterial::normal() const
337{
338 Q_D(const QNormalDiffuseSpecularMapMaterial);
339 return d->m_normalParameter->value().value<QAbstractTexture *>();
340}
341
342/*!
343 \property QNormalDiffuseSpecularMapMaterial::specular
344
345 Holds the current specular map texture.
346
347 By default, the specular texture has the following properties:
348
349 \list
350 \li Linear minification and magnification filters
351 \li Linear mipmap with mipmapping enabled
352 \li Repeat wrap mode
353 \li Maximum anisotropy of 16.0
354 \endlist
355*/
356QAbstractTexture *QNormalDiffuseSpecularMapMaterial::specular() const
357{
358 Q_D(const QNormalDiffuseSpecularMapMaterial);
359 return d->m_specularParameter->value().value<QAbstractTexture *>();
360}
361
362/*!
363 \property QNormalDiffuseSpecularMapMaterial::shininess
364
365 Holds the current shininess as a float value.
366*/
367float QNormalDiffuseSpecularMapMaterial::shininess() const
368{
369 Q_D(const QNormalDiffuseSpecularMapMaterial);
370 return d->m_shininessParameter->value().toFloat();
371}
372
373/*!
374 \property QNormalDiffuseSpecularMapMaterial::textureScale
375
376 Holds the current texture scale. It is applied as a multiplier to texture
377 coordinates at render time. Defaults to 1.0.
378
379 When used in conjunction with QTextureWrapMode::Repeat, textureScale provides a simple
380 way to tile a texture across a surface. For example, a texture scale of \c 4.0
381 would result in 16 (4x4) tiles.
382*/
383float QNormalDiffuseSpecularMapMaterial::textureScale() const
384{
385 Q_D(const QNormalDiffuseSpecularMapMaterial);
386 return d->m_textureScaleParameter->value().toFloat();
387}
388
389void QNormalDiffuseSpecularMapMaterial::setAmbient(const QColor &ambient)
390{
391 Q_D(QNormalDiffuseSpecularMapMaterial);
392 d->m_ambientParameter->setValue(ambient);
393}
394
395void QNormalDiffuseSpecularMapMaterial::setDiffuse(QAbstractTexture *diffuse)
396{
397 Q_D(QNormalDiffuseSpecularMapMaterial);
398 d->m_diffuseParameter->setValue(QVariant::fromValue(value: diffuse));
399}
400
401void QNormalDiffuseSpecularMapMaterial::setNormal(QAbstractTexture *normal)
402{
403 Q_D(QNormalDiffuseSpecularMapMaterial);
404 d->m_normalParameter->setValue(QVariant::fromValue(value: normal));
405}
406
407void QNormalDiffuseSpecularMapMaterial::setSpecular(QAbstractTexture *specular)
408{
409 Q_D(QNormalDiffuseSpecularMapMaterial);
410 d->m_specularParameter->setValue(QVariant::fromValue(value: specular));
411}
412
413void QNormalDiffuseSpecularMapMaterial::setShininess(float shininess)
414{
415 Q_D(QNormalDiffuseSpecularMapMaterial);
416 d->m_shininessParameter->setValue(shininess);
417}
418
419void QNormalDiffuseSpecularMapMaterial::setTextureScale(float textureScale)
420{
421 Q_D(QNormalDiffuseSpecularMapMaterial);
422 d->m_textureScaleParameter->setValue(textureScale);
423}
424
425} // namespace Qt3DExtras
426
427QT_END_NAMESPACE
428

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