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
discardDebugMsgs(QtMsgType type,const QMessageLogContext & context,const QString & msg)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
ShaderHelper(QObject * parent,const QString & vertexShader,const QString & fragmentShader,const QString & texture,const QString & depthTexture)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
~ShaderHelper()88 ShaderHelper::~ShaderHelper()
89 {
90 delete m_program;
91 }
92
setShaders(const QString & vertexShader,const QString & fragmentShader)93 void ShaderHelper::setShaders(const QString &vertexShader,
94 const QString &fragmentShader)
95 {
96 m_vertexShaderFile = vertexShader;
97 m_fragmentShaderFile = fragmentShader;
98 }
99
setTextures(const QString & texture,const QString & depthTexture)100 void ShaderHelper::setTextures(const QString &texture,
101 const QString &depthTexture)
102 {
103 m_textureFile = texture;
104 m_depthTextureFile = depthTexture;
105 }
106
initialize()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(QOpenGLShader::Vertex, m_vertexShaderFile))
113 qFatal("Compiling Vertex shader failed");
114 if (!m_program->addShaderFromSourceFile(QOpenGLShader::Fragment, m_fragmentShaderFile))
115 qFatal("Compiling Fragment shader failed");
116 m_program->link();
117
118 m_positionAttr = m_program->attributeLocation("vertexPosition_mdl");
119 m_normalAttr = m_program->attributeLocation("vertexNormal_mdl");
120 m_uvAttr = m_program->attributeLocation("vertexUV");
121
122 m_mvpMatrixUniform = m_program->uniformLocation("MVP");
123 m_viewMatrixUniform = m_program->uniformLocation("V");
124 m_modelMatrixUniform = m_program->uniformLocation("M");
125 m_invTransModelMatrixUniform = m_program->uniformLocation("itM");
126 m_depthMatrixUniform = m_program->uniformLocation("depthMVP");
127 m_lightPositionUniform = m_program->uniformLocation("lightPosition_wrld");
128 m_lightStrengthUniform = m_program->uniformLocation("lightStrength");
129 m_ambientStrengthUniform = m_program->uniformLocation("ambientStrength");
130 m_shadowQualityUniform = m_program->uniformLocation("shadowQuality");
131 m_colorUniform = m_program->uniformLocation("color_mdl");
132 m_textureUniform = m_program->uniformLocation("textureSampler");
133 m_shadowUniform = m_program->uniformLocation("shadowMap");
134 m_gradientMinUniform = m_program->uniformLocation("gradMin");
135 m_gradientHeightUniform = m_program->uniformLocation("gradHeight");
136 m_lightColorUniform = m_program->uniformLocation("lightColor");
137 m_volumeSliceIndicesUniform = m_program->uniformLocation("volumeSliceIndices");
138 m_colorIndexUniform = m_program->uniformLocation("colorIndex");
139 m_cameraPositionRelativeToModelUniform = m_program->uniformLocation("cameraPositionRelativeToModel");
140 m_color8BitUniform = m_program->uniformLocation("color8Bit");
141 m_textureDimensionsUniform = m_program->uniformLocation("textureDimensions");
142 m_sampleCountUniform = m_program->uniformLocation("sampleCount");
143 m_alphaMultiplierUniform = m_program->uniformLocation("alphaMultiplier");
144 m_preserveOpacityUniform = m_program->uniformLocation("preserveOpacity");
145 m_minBoundsUniform = m_program->uniformLocation("minBounds");
146 m_maxBoundsUniform = m_program->uniformLocation("maxBounds");
147 m_sliceFrameWidthUniform = m_program->uniformLocation("sliceFrameWidth");
148 m_initialized = true;
149 }
150
testCompile()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(QOpenGLShader::Vertex, m_vertexShaderFile))
161 result = false;
162 if (!m_program->addShaderFromSourceFile(QOpenGLShader::Fragment, m_fragmentShaderFile))
163 result = false;
164
165 // Restore actual message handler
166 qInstallMessageHandler(handler);
167 return result;
168 }
169
bind()170 void ShaderHelper::bind()
171 {
172 m_program->bind();
173 }
174
release()175 void ShaderHelper::release()
176 {
177 m_program->release();
178 }
179
setUniformValue(GLint uniform,const QVector2D & value)180 void ShaderHelper::setUniformValue(GLint uniform, const QVector2D &value)
181 {
182 m_program->setUniformValue(uniform, value);
183 }
184
setUniformValue(GLint uniform,const QVector3D & value)185 void ShaderHelper::setUniformValue(GLint uniform, const QVector3D &value)
186 {
187 m_program->setUniformValue(uniform, value);
188 }
189
setUniformValue(GLint uniform,const QVector4D & value)190 void ShaderHelper::setUniformValue(GLint uniform, const QVector4D &value)
191 {
192 m_program->setUniformValue(uniform, value);
193 }
194
setUniformValue(GLint uniform,const QMatrix4x4 & value)195 void ShaderHelper::setUniformValue(GLint uniform, const QMatrix4x4 &value)
196 {
197 m_program->setUniformValue(uniform, value);
198 }
199
setUniformValue(GLint uniform,GLfloat value)200 void ShaderHelper::setUniformValue(GLint uniform, GLfloat value)
201 {
202 m_program->setUniformValue(uniform, value);
203 }
204
setUniformValue(GLint uniform,GLint value)205 void ShaderHelper::setUniformValue(GLint uniform, GLint value)
206 {
207 m_program->setUniformValue(uniform, value);
208 }
209
setUniformValueArray(GLint uniform,const QVector4D * values,int count)210 void ShaderHelper::setUniformValueArray(GLint uniform, const QVector4D *values, int count)
211 {
212 m_program->setUniformValueArray(uniform, values, count);
213 }
214
MVP()215 GLint ShaderHelper::MVP()
216 {
217 if (!m_initialized)
218 qFatal("Shader not initialized");
219 return m_mvpMatrixUniform;
220 }
221
view()222 GLint ShaderHelper::view()
223 {
224 if (!m_initialized)
225 qFatal("Shader not initialized");
226 return m_viewMatrixUniform;
227 }
228
model()229 GLint ShaderHelper::model()
230 {
231 if (!m_initialized)
232 qFatal("Shader not initialized");
233 return m_modelMatrixUniform;
234 }
235
nModel()236 GLint ShaderHelper::nModel()
237 {
238 if (!m_initialized)
239 qFatal("Shader not initialized");
240 return m_invTransModelMatrixUniform;
241 }
242
depth()243 GLint ShaderHelper::depth()
244 {
245 if (!m_initialized)
246 qFatal("Shader not initialized");
247 return m_depthMatrixUniform;
248 }
249
lightP()250 GLint ShaderHelper::lightP()
251 {
252 if (!m_initialized)
253 qFatal("Shader not initialized");
254 return m_lightPositionUniform;
255 }
256
lightS()257 GLint ShaderHelper::lightS()
258 {
259 if (!m_initialized)
260 qFatal("Shader not initialized");
261 return m_lightStrengthUniform;
262 }
263
ambientS()264 GLint ShaderHelper::ambientS()
265 {
266 if (!m_initialized)
267 qFatal("Shader not initialized");
268 return m_ambientStrengthUniform;
269 }
270
shadowQ()271 GLint ShaderHelper::shadowQ()
272 {
273 if (!m_initialized)
274 qFatal("Shader not initialized");
275 return m_shadowQualityUniform;
276 }
277
color()278 GLint ShaderHelper::color()
279 {
280 if (!m_initialized)
281 qFatal("Shader not initialized");
282 return m_colorUniform;
283 }
284
texture()285 GLint ShaderHelper::texture()
286 {
287 if (!m_initialized)
288 qFatal("Shader not initialized");
289 return m_textureUniform;
290 }
291
shadow()292 GLint ShaderHelper::shadow()
293 {
294 if (!m_initialized)
295 qFatal("Shader not initialized");
296 return m_shadowUniform;
297 }
298
gradientMin()299 GLint ShaderHelper::gradientMin()
300 {
301 if (!m_initialized)
302 qFatal("Shader not initialized");
303 return m_gradientMinUniform;
304 }
305
gradientHeight()306 GLint ShaderHelper::gradientHeight()
307 {
308 if (!m_initialized)
309 qFatal("Shader not initialized");
310 return m_gradientHeightUniform;
311 }
312
lightColor()313 GLint ShaderHelper::lightColor()
314 {
315 if (!m_initialized)
316 qFatal("Shader not initialized");
317 return m_lightColorUniform;
318 }
319
volumeSliceIndices()320 GLint ShaderHelper::volumeSliceIndices()
321 {
322 if (!m_initialized)
323 qFatal("Shader not initialized");
324 return m_volumeSliceIndicesUniform;
325 }
326
colorIndex()327 GLint ShaderHelper::colorIndex()
328 {
329 if (!m_initialized)
330 qFatal("Shader not initialized");
331 return m_colorIndexUniform;
332 }
333
cameraPositionRelativeToModel()334 GLint ShaderHelper::cameraPositionRelativeToModel()
335 {
336 if (!m_initialized)
337 qFatal("Shader not initialized");
338 return m_cameraPositionRelativeToModelUniform;
339 }
340
color8Bit()341 GLint ShaderHelper::color8Bit()
342 {
343 if (!m_initialized)
344 qFatal("Shader not initialized");
345 return m_color8BitUniform;
346 }
347
textureDimensions()348 GLint ShaderHelper::textureDimensions()
349 {
350 if (!m_initialized)
351 qFatal("Shader not initialized");
352 return m_textureDimensionsUniform;
353 }
354
sampleCount()355 GLint ShaderHelper::sampleCount()
356 {
357 if (!m_initialized)
358 qFatal("Shader not initialized");
359 return m_sampleCountUniform;
360 }
361
alphaMultiplier()362 GLint ShaderHelper::alphaMultiplier()
363 {
364 if (!m_initialized)
365 qFatal("Shader not initialized");
366 return m_alphaMultiplierUniform;
367 }
368
preserveOpacity()369 GLint ShaderHelper::preserveOpacity()
370 {
371 if (!m_initialized)
372 qFatal("Shader not initialized");
373 return m_preserveOpacityUniform;
374 }
375
maxBounds()376 GLint ShaderHelper::maxBounds()
377 {
378 if (!m_initialized)
379 qFatal("Shader not initialized");
380 return m_maxBoundsUniform;
381 }
382
minBounds()383 GLint ShaderHelper::minBounds()
384 {
385 if (!m_initialized)
386 qFatal("Shader not initialized");
387 return m_minBoundsUniform;
388 }
389
sliceFrameWidth()390 GLint ShaderHelper::sliceFrameWidth()
391 {
392
393 if (!m_initialized)
394 qFatal("Shader not initialized");
395 return m_sliceFrameWidthUniform;
396 }
397
posAtt()398 GLint ShaderHelper::posAtt()
399 {
400 if (!m_initialized)
401 qFatal("Shader not initialized");
402 return m_positionAttr;
403 }
404
uvAtt()405 GLint ShaderHelper::uvAtt()
406 {
407 if (!m_initialized)
408 qFatal("Shader not initialized");
409 return m_uvAttr;
410 }
411
normalAtt()412 GLint ShaderHelper::normalAtt()
413 {
414 if (!m_initialized)
415 qFatal("Shader not initialized");
416 return m_normalAttr;
417 }
418
419 QT_END_NAMESPACE_DATAVISUALIZATION
420