1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the Qt Data Visualization module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:GPL$ |
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 General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU |
19 | ** General Public License version 3 or (at your option) any later version |
20 | ** approved by the KDE Free Qt Foundation. The licenses are as published by |
21 | ** the Free Software Foundation and appearing in the file LICENSE.GPL3 |
22 | ** included in the packaging of this file. Please review the following |
23 | ** information to ensure the GNU General Public License requirements will |
24 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
25 | ** |
26 | ** $QT_END_LICENSE$ |
27 | ** |
28 | ****************************************************************************/ |
29 | |
30 | #include "shaderhelper_p.h" |
31 | |
32 | #include <QtGui/QOpenGLShader> |
33 | |
34 | QT_BEGIN_NAMESPACE_DATAVISUALIZATION |
35 | |
36 | void discardDebugMsgs(QtMsgType type, const QMessageLogContext &context, const QString &msg) |
37 | { |
38 | Q_UNUSED(type) |
39 | Q_UNUSED(context) |
40 | Q_UNUSED(msg) |
41 | // Used to discard warnings generated during shader test compilation |
42 | } |
43 | |
44 | ShaderHelper::ShaderHelper(QObject *parent, |
45 | const QString &vertexShader, |
46 | const QString &fragmentShader, |
47 | const QString &texture, |
48 | const QString &depthTexture) |
49 | : m_caller(parent), |
50 | m_program(0), |
51 | m_vertexShaderFile(vertexShader), |
52 | m_fragmentShaderFile(fragmentShader), |
53 | m_textureFile(texture), |
54 | m_depthTextureFile(depthTexture), |
55 | m_positionAttr(0), |
56 | m_uvAttr(0), |
57 | m_normalAttr(0), |
58 | m_colorUniform(0), |
59 | m_viewMatrixUniform(0), |
60 | m_modelMatrixUniform(0), |
61 | m_invTransModelMatrixUniform(0), |
62 | m_depthMatrixUniform(0), |
63 | m_mvpMatrixUniform(0), |
64 | m_lightPositionUniform(0), |
65 | m_lightStrengthUniform(0), |
66 | m_ambientStrengthUniform(0), |
67 | m_shadowQualityUniform(0), |
68 | m_textureUniform(0), |
69 | m_shadowUniform(0), |
70 | m_gradientMinUniform(0), |
71 | m_gradientHeightUniform(0), |
72 | m_lightColorUniform(0), |
73 | m_volumeSliceIndicesUniform(0), |
74 | m_colorIndexUniform(0), |
75 | m_cameraPositionRelativeToModelUniform(0), |
76 | m_color8BitUniform(0), |
77 | m_textureDimensionsUniform(0), |
78 | m_sampleCountUniform(0), |
79 | m_alphaMultiplierUniform(0), |
80 | m_preserveOpacityUniform(0), |
81 | m_minBoundsUniform(0), |
82 | m_maxBoundsUniform(0), |
83 | m_sliceFrameWidthUniform(0), |
84 | m_initialized(false) |
85 | { |
86 | } |
87 | |
88 | ShaderHelper::~ShaderHelper() |
89 | { |
90 | delete m_program; |
91 | } |
92 | |
93 | void ShaderHelper::setShaders(const QString &vertexShader, |
94 | const QString &fragmentShader) |
95 | { |
96 | m_vertexShaderFile = vertexShader; |
97 | m_fragmentShaderFile = fragmentShader; |
98 | } |
99 | |
100 | void ShaderHelper::setTextures(const QString &texture, |
101 | const QString &depthTexture) |
102 | { |
103 | m_textureFile = texture; |
104 | m_depthTextureFile = depthTexture; |
105 | } |
106 | |
107 | void ShaderHelper::initialize() |
108 | { |
109 | if (m_program) |
110 | delete m_program; |
111 | m_program = new QOpenGLShaderProgram(m_caller); |
112 | if (!m_program->addShaderFromSourceFile(type: QOpenGLShader::Vertex, fileName: m_vertexShaderFile)) |
113 | qFatal(msg: "Compiling Vertex shader failed" ); |
114 | if (!m_program->addShaderFromSourceFile(type: QOpenGLShader::Fragment, fileName: m_fragmentShaderFile)) |
115 | qFatal(msg: "Compiling Fragment shader failed" ); |
116 | m_program->link(); |
117 | |
118 | m_positionAttr = m_program->attributeLocation(name: "vertexPosition_mdl" ); |
119 | m_normalAttr = m_program->attributeLocation(name: "vertexNormal_mdl" ); |
120 | m_uvAttr = m_program->attributeLocation(name: "vertexUV" ); |
121 | |
122 | m_mvpMatrixUniform = m_program->uniformLocation(name: "MVP" ); |
123 | m_viewMatrixUniform = m_program->uniformLocation(name: "V" ); |
124 | m_modelMatrixUniform = m_program->uniformLocation(name: "M" ); |
125 | m_invTransModelMatrixUniform = m_program->uniformLocation(name: "itM" ); |
126 | m_depthMatrixUniform = m_program->uniformLocation(name: "depthMVP" ); |
127 | m_lightPositionUniform = m_program->uniformLocation(name: "lightPosition_wrld" ); |
128 | m_lightStrengthUniform = m_program->uniformLocation(name: "lightStrength" ); |
129 | m_ambientStrengthUniform = m_program->uniformLocation(name: "ambientStrength" ); |
130 | m_shadowQualityUniform = m_program->uniformLocation(name: "shadowQuality" ); |
131 | m_colorUniform = m_program->uniformLocation(name: "color_mdl" ); |
132 | m_textureUniform = m_program->uniformLocation(name: "textureSampler" ); |
133 | m_shadowUniform = m_program->uniformLocation(name: "shadowMap" ); |
134 | m_gradientMinUniform = m_program->uniformLocation(name: "gradMin" ); |
135 | m_gradientHeightUniform = m_program->uniformLocation(name: "gradHeight" ); |
136 | m_lightColorUniform = m_program->uniformLocation(name: "lightColor" ); |
137 | m_volumeSliceIndicesUniform = m_program->uniformLocation(name: "volumeSliceIndices" ); |
138 | m_colorIndexUniform = m_program->uniformLocation(name: "colorIndex" ); |
139 | m_cameraPositionRelativeToModelUniform = m_program->uniformLocation(name: "cameraPositionRelativeToModel" ); |
140 | m_color8BitUniform = m_program->uniformLocation(name: "color8Bit" ); |
141 | m_textureDimensionsUniform = m_program->uniformLocation(name: "textureDimensions" ); |
142 | m_sampleCountUniform = m_program->uniformLocation(name: "sampleCount" ); |
143 | m_alphaMultiplierUniform = m_program->uniformLocation(name: "alphaMultiplier" ); |
144 | m_preserveOpacityUniform = m_program->uniformLocation(name: "preserveOpacity" ); |
145 | m_minBoundsUniform = m_program->uniformLocation(name: "minBounds" ); |
146 | m_maxBoundsUniform = m_program->uniformLocation(name: "maxBounds" ); |
147 | m_sliceFrameWidthUniform = m_program->uniformLocation(name: "sliceFrameWidth" ); |
148 | m_initialized = true; |
149 | } |
150 | |
151 | bool ShaderHelper::testCompile() |
152 | { |
153 | bool result = true; |
154 | |
155 | // Discard warnings, we only need the result |
156 | QtMessageHandler handler = qInstallMessageHandler(discardDebugMsgs); |
157 | if (m_program) |
158 | delete m_program; |
159 | m_program = new QOpenGLShaderProgram(); |
160 | if (!m_program->addShaderFromSourceFile(type: QOpenGLShader::Vertex, fileName: m_vertexShaderFile)) |
161 | result = false; |
162 | if (!m_program->addShaderFromSourceFile(type: QOpenGLShader::Fragment, fileName: m_fragmentShaderFile)) |
163 | result = false; |
164 | |
165 | // Restore actual message handler |
166 | qInstallMessageHandler(handler); |
167 | return result; |
168 | } |
169 | |
170 | void ShaderHelper::bind() |
171 | { |
172 | m_program->bind(); |
173 | } |
174 | |
175 | void ShaderHelper::release() |
176 | { |
177 | m_program->release(); |
178 | } |
179 | |
180 | void ShaderHelper::setUniformValue(GLint uniform, const QVector2D &value) |
181 | { |
182 | m_program->setUniformValue(location: uniform, value); |
183 | } |
184 | |
185 | void ShaderHelper::setUniformValue(GLint uniform, const QVector3D &value) |
186 | { |
187 | m_program->setUniformValue(location: uniform, value); |
188 | } |
189 | |
190 | void ShaderHelper::setUniformValue(GLint uniform, const QVector4D &value) |
191 | { |
192 | m_program->setUniformValue(location: uniform, value); |
193 | } |
194 | |
195 | void ShaderHelper::setUniformValue(GLint uniform, const QMatrix4x4 &value) |
196 | { |
197 | m_program->setUniformValue(location: uniform, value); |
198 | } |
199 | |
200 | void ShaderHelper::setUniformValue(GLint uniform, GLfloat value) |
201 | { |
202 | m_program->setUniformValue(location: uniform, value); |
203 | } |
204 | |
205 | void ShaderHelper::setUniformValue(GLint uniform, GLint value) |
206 | { |
207 | m_program->setUniformValue(location: uniform, value); |
208 | } |
209 | |
210 | void ShaderHelper::setUniformValueArray(GLint uniform, const QVector4D *values, int count) |
211 | { |
212 | m_program->setUniformValueArray(location: uniform, values, count); |
213 | } |
214 | |
215 | GLint ShaderHelper::MVP() |
216 | { |
217 | if (!m_initialized) |
218 | qFatal(msg: "Shader not initialized" ); |
219 | return m_mvpMatrixUniform; |
220 | } |
221 | |
222 | GLint ShaderHelper::view() |
223 | { |
224 | if (!m_initialized) |
225 | qFatal(msg: "Shader not initialized" ); |
226 | return m_viewMatrixUniform; |
227 | } |
228 | |
229 | GLint ShaderHelper::model() |
230 | { |
231 | if (!m_initialized) |
232 | qFatal(msg: "Shader not initialized" ); |
233 | return m_modelMatrixUniform; |
234 | } |
235 | |
236 | GLint ShaderHelper::nModel() |
237 | { |
238 | if (!m_initialized) |
239 | qFatal(msg: "Shader not initialized" ); |
240 | return m_invTransModelMatrixUniform; |
241 | } |
242 | |
243 | GLint ShaderHelper::depth() |
244 | { |
245 | if (!m_initialized) |
246 | qFatal(msg: "Shader not initialized" ); |
247 | return m_depthMatrixUniform; |
248 | } |
249 | |
250 | GLint ShaderHelper::lightP() |
251 | { |
252 | if (!m_initialized) |
253 | qFatal(msg: "Shader not initialized" ); |
254 | return m_lightPositionUniform; |
255 | } |
256 | |
257 | GLint ShaderHelper::lightS() |
258 | { |
259 | if (!m_initialized) |
260 | qFatal(msg: "Shader not initialized" ); |
261 | return m_lightStrengthUniform; |
262 | } |
263 | |
264 | GLint ShaderHelper::ambientS() |
265 | { |
266 | if (!m_initialized) |
267 | qFatal(msg: "Shader not initialized" ); |
268 | return m_ambientStrengthUniform; |
269 | } |
270 | |
271 | GLint ShaderHelper::shadowQ() |
272 | { |
273 | if (!m_initialized) |
274 | qFatal(msg: "Shader not initialized" ); |
275 | return m_shadowQualityUniform; |
276 | } |
277 | |
278 | GLint ShaderHelper::color() |
279 | { |
280 | if (!m_initialized) |
281 | qFatal(msg: "Shader not initialized" ); |
282 | return m_colorUniform; |
283 | } |
284 | |
285 | GLint ShaderHelper::texture() |
286 | { |
287 | if (!m_initialized) |
288 | qFatal(msg: "Shader not initialized" ); |
289 | return m_textureUniform; |
290 | } |
291 | |
292 | GLint ShaderHelper::shadow() |
293 | { |
294 | if (!m_initialized) |
295 | qFatal(msg: "Shader not initialized" ); |
296 | return m_shadowUniform; |
297 | } |
298 | |
299 | GLint ShaderHelper::gradientMin() |
300 | { |
301 | if (!m_initialized) |
302 | qFatal(msg: "Shader not initialized" ); |
303 | return m_gradientMinUniform; |
304 | } |
305 | |
306 | GLint ShaderHelper::gradientHeight() |
307 | { |
308 | if (!m_initialized) |
309 | qFatal(msg: "Shader not initialized" ); |
310 | return m_gradientHeightUniform; |
311 | } |
312 | |
313 | GLint ShaderHelper::lightColor() |
314 | { |
315 | if (!m_initialized) |
316 | qFatal(msg: "Shader not initialized" ); |
317 | return m_lightColorUniform; |
318 | } |
319 | |
320 | GLint ShaderHelper::volumeSliceIndices() |
321 | { |
322 | if (!m_initialized) |
323 | qFatal(msg: "Shader not initialized" ); |
324 | return m_volumeSliceIndicesUniform; |
325 | } |
326 | |
327 | GLint ShaderHelper::colorIndex() |
328 | { |
329 | if (!m_initialized) |
330 | qFatal(msg: "Shader not initialized" ); |
331 | return m_colorIndexUniform; |
332 | } |
333 | |
334 | GLint ShaderHelper::cameraPositionRelativeToModel() |
335 | { |
336 | if (!m_initialized) |
337 | qFatal(msg: "Shader not initialized" ); |
338 | return m_cameraPositionRelativeToModelUniform; |
339 | } |
340 | |
341 | GLint ShaderHelper::color8Bit() |
342 | { |
343 | if (!m_initialized) |
344 | qFatal(msg: "Shader not initialized" ); |
345 | return m_color8BitUniform; |
346 | } |
347 | |
348 | GLint ShaderHelper::textureDimensions() |
349 | { |
350 | if (!m_initialized) |
351 | qFatal(msg: "Shader not initialized" ); |
352 | return m_textureDimensionsUniform; |
353 | } |
354 | |
355 | GLint ShaderHelper::sampleCount() |
356 | { |
357 | if (!m_initialized) |
358 | qFatal(msg: "Shader not initialized" ); |
359 | return m_sampleCountUniform; |
360 | } |
361 | |
362 | GLint ShaderHelper::alphaMultiplier() |
363 | { |
364 | if (!m_initialized) |
365 | qFatal(msg: "Shader not initialized" ); |
366 | return m_alphaMultiplierUniform; |
367 | } |
368 | |
369 | GLint ShaderHelper::preserveOpacity() |
370 | { |
371 | if (!m_initialized) |
372 | qFatal(msg: "Shader not initialized" ); |
373 | return m_preserveOpacityUniform; |
374 | } |
375 | |
376 | GLint ShaderHelper::maxBounds() |
377 | { |
378 | if (!m_initialized) |
379 | qFatal(msg: "Shader not initialized" ); |
380 | return m_maxBoundsUniform; |
381 | } |
382 | |
383 | GLint ShaderHelper::minBounds() |
384 | { |
385 | if (!m_initialized) |
386 | qFatal(msg: "Shader not initialized" ); |
387 | return m_minBoundsUniform; |
388 | } |
389 | |
390 | GLint ShaderHelper::sliceFrameWidth() |
391 | { |
392 | |
393 | if (!m_initialized) |
394 | qFatal(msg: "Shader not initialized" ); |
395 | return m_sliceFrameWidthUniform; |
396 | } |
397 | |
398 | GLint ShaderHelper::posAtt() |
399 | { |
400 | if (!m_initialized) |
401 | qFatal(msg: "Shader not initialized" ); |
402 | return m_positionAttr; |
403 | } |
404 | |
405 | GLint ShaderHelper::uvAtt() |
406 | { |
407 | if (!m_initialized) |
408 | qFatal(msg: "Shader not initialized" ); |
409 | return m_uvAttr; |
410 | } |
411 | |
412 | GLint ShaderHelper::normalAtt() |
413 | { |
414 | if (!m_initialized) |
415 | qFatal(msg: "Shader not initialized" ); |
416 | return m_normalAttr; |
417 | } |
418 | |
419 | QT_END_NAMESPACE_DATAVISUALIZATION |
420 | |