1/****************************************************************************
2**
3** Copyright (C) 2015 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 "qgoochmaterial.h"
41#include "qgoochmaterial_p.h"
42
43#include <Qt3DRender/qfilterkey.h>
44#include <Qt3DRender/qeffect.h>
45#include <Qt3DRender/qgraphicsapifilter.h>
46#include <Qt3DRender/qparameter.h>
47#include <Qt3DRender/qrenderpass.h>
48#include <Qt3DRender/qtechnique.h>
49#include <QtCore/qurl.h>
50
51QT_BEGIN_NAMESPACE
52
53namespace Qt3DExtras {
54
55QGoochMaterialPrivate::QGoochMaterialPrivate()
56 : QMaterialPrivate()
57 , m_effect(new Qt3DRender::QEffect)
58 , m_diffuseParameter(new Qt3DRender::QParameter(QStringLiteral("kd"), QColor::fromRgbF(r: 0.0f, g: 0.0f, b: 0.0f)))
59 , m_specularParameter(new Qt3DRender::QParameter(QStringLiteral("ks"), QColor::fromRgbF(r: 0.0f, g: 0.0f, b: 0.0f)))
60 , m_coolParameter(new Qt3DRender::QParameter(QStringLiteral("kblue"), QColor::fromRgbF(r: 0.0f, g: 0.0f, b: 0.4f)))
61 , m_warmParameter(new Qt3DRender::QParameter(QStringLiteral("kyellow"), QColor::fromRgbF(r: 0.4f, g: 0.4f, b: 0.0f)))
62 , m_alphaParameter(new Qt3DRender::QParameter(QStringLiteral("alpha"), 0.25f))
63 , m_betaParameter(new Qt3DRender::QParameter(QStringLiteral("beta"), 0.5f))
64 , m_shininessParameter(new Qt3DRender::QParameter(QStringLiteral("shininess"), 100.0f))
65 , m_gl3Technique(new Qt3DRender::QTechnique)
66 , m_gl2Technique(new Qt3DRender::QTechnique)
67 , m_es2Technique(new Qt3DRender::QTechnique)
68 , m_rhiTechnique(new Qt3DRender::QTechnique)
69 , m_gl3RenderPass(new Qt3DRender::QRenderPass)
70 , m_gl2RenderPass(new Qt3DRender::QRenderPass)
71 , m_es2RenderPass(new Qt3DRender::QRenderPass)
72 , m_rhiRenderPass(new Qt3DRender::QRenderPass)
73 , m_gl3Shader(new Qt3DRender::QShaderProgram)
74 , m_gl2ES2Shader(new Qt3DRender::QShaderProgram)
75 , m_rhiShader(new Qt3DRender::QShaderProgram)
76 , m_filterKey(new Qt3DRender::QFilterKey)
77{
78}
79
80void QGoochMaterialPrivate::init()
81{
82 Q_Q(QGoochMaterial);
83
84 connect(sender: m_diffuseParameter, signal: &Qt3DRender::QParameter::valueChanged,
85 receiverPrivate: this, slot: &QGoochMaterialPrivate::handleDiffuseChanged);
86 connect(sender: m_specularParameter, signal: &Qt3DRender::QParameter::valueChanged,
87 receiverPrivate: this, slot: &QGoochMaterialPrivate::handleSpecularChanged);
88 connect(sender: m_coolParameter, signal: &Qt3DRender::QParameter::valueChanged,
89 receiverPrivate: this, slot: &QGoochMaterialPrivate::handleCoolChanged);
90 connect(sender: m_warmParameter, signal: &Qt3DRender::QParameter::valueChanged,
91 receiverPrivate: this, slot: &QGoochMaterialPrivate::handleWarmChanged);
92 connect(sender: m_alphaParameter, signal: &Qt3DRender::QParameter::valueChanged,
93 receiverPrivate: this, slot: &QGoochMaterialPrivate::handleAlphaChanged);
94 connect(sender: m_betaParameter, signal: &Qt3DRender::QParameter::valueChanged,
95 receiverPrivate: this, slot: &QGoochMaterialPrivate::handleBetaChanged);
96 connect(sender: m_shininessParameter, signal: &Qt3DRender::QParameter::valueChanged,
97 receiverPrivate: this, slot: &QGoochMaterialPrivate::handleShininessChanged);
98
99 m_gl3Shader->setVertexShaderCode(Qt3DRender::QShaderProgram::loadSource(sourceUrl: QUrl(QStringLiteral("qrc:/shaders/gl3/gooch.vert"))));
100 m_gl3Shader->setFragmentShaderCode(Qt3DRender::QShaderProgram::loadSource(sourceUrl: QUrl(QStringLiteral("qrc:/shaders/gl3/gooch.frag"))));
101 m_gl2ES2Shader->setVertexShaderCode(Qt3DRender::QShaderProgram::loadSource(sourceUrl: QUrl(QStringLiteral("qrc:/shaders/es2/gooch.vert"))));
102 m_gl2ES2Shader->setFragmentShaderCode(Qt3DRender::QShaderProgram::loadSource(sourceUrl: QUrl(QStringLiteral("qrc:/shaders/es2/gooch.frag"))));
103 m_rhiShader->setVertexShaderCode(Qt3DRender::QShaderProgram::loadSource(sourceUrl: QUrl(QStringLiteral("qrc:/shaders/rhi/gooch.vert"))));
104 m_rhiShader->setFragmentShaderCode(Qt3DRender::QShaderProgram::loadSource(sourceUrl: QUrl(QStringLiteral("qrc:/shaders/rhi/gooch.frag"))));
105
106 m_gl3Technique->graphicsApiFilter()->setApi(Qt3DRender::QGraphicsApiFilter::OpenGL);
107 m_gl3Technique->graphicsApiFilter()->setMajorVersion(3);
108 m_gl3Technique->graphicsApiFilter()->setMinorVersion(1);
109 m_gl3Technique->graphicsApiFilter()->setProfile(Qt3DRender::QGraphicsApiFilter::CoreProfile);
110
111 m_gl2Technique->graphicsApiFilter()->setApi(Qt3DRender::QGraphicsApiFilter::OpenGL);
112 m_gl2Technique->graphicsApiFilter()->setMajorVersion(2);
113 m_gl2Technique->graphicsApiFilter()->setMinorVersion(0);
114 m_gl2Technique->graphicsApiFilter()->setProfile(Qt3DRender::QGraphicsApiFilter::NoProfile);
115
116 m_es2Technique->graphicsApiFilter()->setApi(Qt3DRender::QGraphicsApiFilter::OpenGLES);
117 m_es2Technique->graphicsApiFilter()->setMajorVersion(2);
118 m_es2Technique->graphicsApiFilter()->setMinorVersion(0);
119 m_es2Technique->graphicsApiFilter()->setProfile(Qt3DRender::QGraphicsApiFilter::NoProfile);
120
121 m_rhiTechnique->graphicsApiFilter()->setApi(Qt3DRender::QGraphicsApiFilter::RHI);
122 m_rhiTechnique->graphicsApiFilter()->setMajorVersion(1);
123 m_rhiTechnique->graphicsApiFilter()->setMinorVersion(0);
124 m_rhiTechnique->graphicsApiFilter()->setProfile(Qt3DRender::QGraphicsApiFilter::CoreProfile);
125
126 m_filterKey->setParent(q);
127 m_filterKey->setName(QStringLiteral("renderingStyle"));
128 m_filterKey->setValue(QStringLiteral("forward"));
129
130 m_gl3Technique->addFilterKey(filterKey: m_filterKey);
131 m_gl2Technique->addFilterKey(filterKey: m_filterKey);
132 m_es2Technique->addFilterKey(filterKey: m_filterKey);
133 m_rhiTechnique->addFilterKey(filterKey: m_filterKey);
134
135 m_gl3RenderPass->setShaderProgram(m_gl3Shader);
136 m_gl2RenderPass->setShaderProgram(m_gl2ES2Shader);
137 m_es2RenderPass->setShaderProgram(m_gl2ES2Shader);
138 m_rhiRenderPass->setShaderProgram(m_rhiShader);
139
140 m_gl3Technique->addRenderPass(pass: m_gl3RenderPass);
141 m_gl2Technique->addRenderPass(pass: m_gl2RenderPass);
142 m_es2Technique->addRenderPass(pass: m_es2RenderPass);
143 m_rhiTechnique->addRenderPass(pass: m_rhiRenderPass);
144
145 m_effect->addTechnique(t: m_gl3Technique);
146 m_effect->addTechnique(t: m_gl2Technique);
147 m_effect->addTechnique(t: m_es2Technique);
148 m_effect->addTechnique(t: m_rhiTechnique);
149
150 m_effect->addParameter(parameter: m_diffuseParameter);
151 m_effect->addParameter(parameter: m_specularParameter);
152 m_effect->addParameter(parameter: m_coolParameter);
153 m_effect->addParameter(parameter: m_warmParameter);
154 m_effect->addParameter(parameter: m_alphaParameter);
155 m_effect->addParameter(parameter: m_betaParameter);
156 m_effect->addParameter(parameter: m_shininessParameter);
157
158 q->setEffect(m_effect);
159}
160
161void QGoochMaterialPrivate::handleDiffuseChanged(const QVariant &var)
162{
163 Q_Q(QGoochMaterial);
164 emit q->diffuseChanged(diffuse: var.value<QColor>());
165}
166
167void QGoochMaterialPrivate::handleSpecularChanged(const QVariant &var)
168{
169 Q_Q(QGoochMaterial);
170 emit q->specularChanged(specular: var.value<QColor>());
171}
172
173void QGoochMaterialPrivate::handleCoolChanged(const QVariant &var)
174{
175 Q_Q(QGoochMaterial);
176 emit q->coolChanged(cool: var.value<QColor>());
177}
178
179void QGoochMaterialPrivate::handleWarmChanged(const QVariant &var)
180{
181 Q_Q(QGoochMaterial);
182 emit q->warmChanged(warm: var.value<QColor>());
183}
184
185void QGoochMaterialPrivate::handleAlphaChanged(const QVariant &var)
186{
187 Q_Q(QGoochMaterial);
188 emit q->alphaChanged(alpha: var.toFloat());
189}
190
191void QGoochMaterialPrivate::handleBetaChanged(const QVariant &var)
192{
193 Q_Q(QGoochMaterial);
194 emit q->betaChanged(beta: var.toFloat());
195}
196
197void QGoochMaterialPrivate::handleShininessChanged(const QVariant &var)
198{
199 Q_Q(QGoochMaterial);
200 emit q->shininessChanged(shininess: var.toFloat());
201}
202
203/*!
204 \class Qt3DExtras::QGoochMaterial
205 \ingroup qt3d-extras-materials
206 \brief The QGoochMaterial provides a material that implements the Gooch
207 shading model, popular in CAD and CAM applications.
208 \inmodule Qt3DExtras
209 \since 5.7
210 \inherits Qt3DRender::QMaterial
211
212 The Gooch lighting model uses both color and brightness to help show the
213 curvature of 3D surfaces. This is often better than models such as Phong
214 that rely purely upon changes in brightness. In situations such as in CAD
215 and CAM applications where photorealism is not a goal, the Gooch shading
216 model in conjunction with some kind of silhouette edge inking is a popular
217 solution.
218
219 The Gooch lighting model is explained fully in the \l{original Gooch
220 paper}. The Gooch model mixes a diffuse object color with a user-provided
221 cool color and warm color to produce the end points of a color ramp that is
222 used to shade the object based upon the cosine of the angle between the
223 vector from the fragment to the light source and the fragment's normal
224 vector. Optionally, a specular highlight can be added on top. The relative
225 contributions to the cool and warm colors by the diffuse color are
226 controlled by the alpha and beta properties respecitvely.
227
228 This material uses an effect with a single render pass approach and
229 performs per fragment lighting. Techniques are provided for OpenGL 2,
230 OpenGL 3 or above as well as OpenGL ES 2.
231*/
232
233/*!
234 Constructs a new QGoochMaterial instance with parent object \a parent.
235*/
236QGoochMaterial::QGoochMaterial(QNode *parent)
237 : QMaterial(*new QGoochMaterialPrivate, parent)
238{
239 Q_D(QGoochMaterial);
240 d->init();
241}
242
243/*! \internal */
244QGoochMaterial::~QGoochMaterial()
245{
246}
247
248QGoochMaterial::QGoochMaterial(QGoochMaterialPrivate &dd, QNode *parent)
249 : QMaterial(dd, parent)
250{
251 Q_D(QGoochMaterial);
252 d->init();
253}
254
255/*!
256 \property QGoochMaterial::diffuse
257
258 Holds the current diffuse color.
259*/
260QColor QGoochMaterial::diffuse() const
261{
262 Q_D(const QGoochMaterial);
263 return d->m_diffuseParameter->value().value<QColor>();
264}
265
266/*!
267 \property QGoochMaterial::specular
268
269 Holds the current specular color.
270*/
271QColor QGoochMaterial::specular() const
272{
273 Q_D(const QGoochMaterial);
274 return d->m_specularParameter->value().value<QColor>();
275}
276
277/*!
278 \property QGoochMaterial::cool
279
280 Holds the current cool color.
281*/
282QColor QGoochMaterial::cool() const
283{
284 Q_D(const QGoochMaterial);
285 return d->m_coolParameter->value().value<QColor>();
286}
287
288/*!
289 \property QGoochMaterial::warm
290
291 Holds the current warm color.
292*/
293QColor QGoochMaterial::warm() const
294{
295 Q_D(const QGoochMaterial);
296 return d->m_warmParameter->value().value<QColor>();
297}
298
299/*!
300 \property QGoochMaterial::alpha
301
302 Holds the current alpha value. The start point of the color ramp
303 used by the Gooch shader is calculated as {c = cool + alpha * diffuse}.
304*/
305float QGoochMaterial::alpha() const
306{
307 Q_D(const QGoochMaterial);
308 return d->m_alphaParameter->value().toFloat();
309}
310
311/*!
312 \property QGoochMaterial::beta
313
314 Holds the current beta value. The start point of the color ramp
315 used by the Gooch shader is calculated as {c = warm + beta * diffuse}.
316*/
317float QGoochMaterial::beta() const
318{
319 Q_D(const QGoochMaterial);
320 return d->m_betaParameter->value().toFloat();
321}
322
323/*!
324 \property QGoochMaterial::shininess
325
326 Holds the current shininess value. Higher values of shininess result in
327 a smaller and brighter highlight.
328*/
329float QGoochMaterial::shininess() const
330{
331 Q_D(const QGoochMaterial);
332 return d->m_shininessParameter->value().toFloat();
333}
334
335void QGoochMaterial::setDiffuse(const QColor &diffuse)
336{
337 Q_D(QGoochMaterial);
338 return d->m_diffuseParameter->setValue(diffuse);
339}
340
341void QGoochMaterial::setSpecular(const QColor &specular)
342{
343 Q_D(QGoochMaterial);
344 return d->m_specularParameter->setValue(specular);
345}
346
347void QGoochMaterial::setCool(const QColor &cool)
348{
349 Q_D(QGoochMaterial);
350 return d->m_coolParameter->setValue(cool);
351}
352
353void QGoochMaterial::setWarm(const QColor &warm)
354{
355 Q_D(QGoochMaterial);
356 return d->m_warmParameter->setValue(warm);
357}
358
359void QGoochMaterial::setAlpha(float alpha)
360{
361 Q_D(QGoochMaterial);
362 return d->m_alphaParameter->setValue(alpha);
363}
364
365void QGoochMaterial::setBeta(float beta)
366{
367 Q_D(QGoochMaterial);
368 return d->m_betaParameter->setValue(beta);
369}
370
371void QGoochMaterial::setShininess(float shininess)
372{
373 Q_D(QGoochMaterial);
374 return d->m_shininessParameter->setValue(shininess);
375}
376
377}
378
379QT_END_NAMESPACE
380

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