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

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