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

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