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