| 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 |  |