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

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