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 | |
15 | QT_BEGIN_NAMESPACE |
16 | |
17 | namespace Qt3DExtras { |
18 | |
19 | 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 | |
44 | void QGoochMaterialPrivate::() |
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 | |
125 | void QGoochMaterialPrivate::handleDiffuseChanged(const QVariant &var) |
126 | { |
127 | Q_Q(QGoochMaterial); |
128 | emit q->diffuseChanged(diffuse: var.value<QColor>()); |
129 | } |
130 | |
131 | void QGoochMaterialPrivate::handleSpecularChanged(const QVariant &var) |
132 | { |
133 | Q_Q(QGoochMaterial); |
134 | emit q->specularChanged(specular: var.value<QColor>()); |
135 | } |
136 | |
137 | void QGoochMaterialPrivate::handleCoolChanged(const QVariant &var) |
138 | { |
139 | Q_Q(QGoochMaterial); |
140 | emit q->coolChanged(cool: var.value<QColor>()); |
141 | } |
142 | |
143 | void QGoochMaterialPrivate::handleWarmChanged(const QVariant &var) |
144 | { |
145 | Q_Q(QGoochMaterial); |
146 | emit q->warmChanged(warm: var.value<QColor>()); |
147 | } |
148 | |
149 | void QGoochMaterialPrivate::handleAlphaChanged(const QVariant &var) |
150 | { |
151 | Q_Q(QGoochMaterial); |
152 | emit q->alphaChanged(alpha: var.toFloat()); |
153 | } |
154 | |
155 | void QGoochMaterialPrivate::handleBetaChanged(const QVariant &var) |
156 | { |
157 | Q_Q(QGoochMaterial); |
158 | emit q->betaChanged(beta: var.toFloat()); |
159 | } |
160 | |
161 | void 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 | */ |
200 | QGoochMaterial::(QNode *parent) |
201 | : QMaterial(*new QGoochMaterialPrivate, parent) |
202 | { |
203 | Q_D(QGoochMaterial); |
204 | d->init(); |
205 | } |
206 | |
207 | /*! \internal */ |
208 | QGoochMaterial::() |
209 | { |
210 | } |
211 | |
212 | 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 | */ |
224 | QColor QGoochMaterial::() 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 | */ |
235 | QColor QGoochMaterial::() 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 | */ |
246 | QColor QGoochMaterial::() 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 | */ |
257 | QColor QGoochMaterial::() 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 | */ |
269 | float QGoochMaterial::() 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 | */ |
281 | float QGoochMaterial::() 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 | */ |
293 | float QGoochMaterial::() const |
294 | { |
295 | Q_D(const QGoochMaterial); |
296 | return d->m_shininessParameter->value().toFloat(); |
297 | } |
298 | |
299 | void QGoochMaterial::(const QColor &diffuse) |
300 | { |
301 | Q_D(QGoochMaterial); |
302 | return d->m_diffuseParameter->setValue(diffuse); |
303 | } |
304 | |
305 | void QGoochMaterial::(const QColor &specular) |
306 | { |
307 | Q_D(QGoochMaterial); |
308 | return d->m_specularParameter->setValue(specular); |
309 | } |
310 | |
311 | void QGoochMaterial::(const QColor &cool) |
312 | { |
313 | Q_D(QGoochMaterial); |
314 | return d->m_coolParameter->setValue(cool); |
315 | } |
316 | |
317 | void QGoochMaterial::(const QColor &warm) |
318 | { |
319 | Q_D(QGoochMaterial); |
320 | return d->m_warmParameter->setValue(warm); |
321 | } |
322 | |
323 | void QGoochMaterial::(float alpha) |
324 | { |
325 | Q_D(QGoochMaterial); |
326 | return d->m_alphaParameter->setValue(alpha); |
327 | } |
328 | |
329 | void QGoochMaterial::(float beta) |
330 | { |
331 | Q_D(QGoochMaterial); |
332 | return d->m_betaParameter->setValue(beta); |
333 | } |
334 | |
335 | void QGoochMaterial::(float shininess) |
336 | { |
337 | Q_D(QGoochMaterial); |
338 | return d->m_shininessParameter->setValue(shininess); |
339 | } |
340 | |
341 | } |
342 | |
343 | QT_END_NAMESPACE |
344 | |
345 | #include "moc_qgoochmaterial.cpp" |
346 | |