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