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

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