From 169a4d638c6c1b6634ffcfd19c4fe3cb94cf27d5 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Wed, 13 Aug 2014 15:09:36 +0300 Subject: Implement volume rendering support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New subclass of QCustom3DItem, QCustom3DVolume is provided. The documentation for the example will be done in a separate commit. Change-Id: Idb3fdb0654c6bec7606ca012b75852a5a8412397 Reviewed-by: Tomi Korpipää --- src/datavisualization/utils/shaderhelper.cpp | 37 +++++++++++++++++ src/datavisualization/utils/shaderhelper_p.h | 9 ++++ src/datavisualization/utils/texturehelper.cpp | 60 +++++++++++++++++++++++++++ src/datavisualization/utils/texturehelper_p.h | 11 +++++ 4 files changed, 117 insertions(+) (limited to 'src/datavisualization/utils') diff --git a/src/datavisualization/utils/shaderhelper.cpp b/src/datavisualization/utils/shaderhelper.cpp index 7fb237c6..3c3d93ac 100644 --- a/src/datavisualization/utils/shaderhelper.cpp +++ b/src/datavisualization/utils/shaderhelper.cpp @@ -93,6 +93,10 @@ void ShaderHelper::initialize() m_gradientMinUniform = m_program->uniformLocation("gradMin"); m_gradientHeightUniform = m_program->uniformLocation("gradHeight"); m_lightColorUniform = m_program->uniformLocation("lightColor"); + m_volumeSliceIndices = m_program->uniformLocation("volumeSliceIndices"); + m_colorIndex = m_program->uniformLocation("colorIndex"); + m_cameraPositionRelativeToModel = m_program->uniformLocation("cameraPositionRelativeToModel"); + m_color8Bit = m_program->uniformLocation("color8Bit"); m_initialized = true; } @@ -150,6 +154,11 @@ void ShaderHelper::setUniformValue(GLuint uniform, GLint value) m_program->setUniformValue(uniform, value); } +void ShaderHelper::setUniformValueArray(GLuint uniform, const QVector4D *values, int count) +{ + m_program->setUniformValueArray(uniform, values, count); +} + GLuint ShaderHelper::MVP() { if (!m_initialized) @@ -255,6 +264,34 @@ GLuint ShaderHelper::lightColor() return m_lightColorUniform; } +GLuint ShaderHelper::volumeSliceIndices() +{ + if (!m_initialized) + qFatal("Shader not initialized"); + return m_volumeSliceIndices; +} + +GLuint ShaderHelper::colorIndex() +{ + if (!m_initialized) + qFatal("Shader not initialized"); + return m_colorIndex; +} + +GLuint ShaderHelper::cameraPositionRelativeToModel() +{ + if (!m_initialized) + qFatal("Shader not initialized"); + return m_cameraPositionRelativeToModel; +} + +GLuint ShaderHelper::color8Bit() +{ + if (!m_initialized) + qFatal("Shader not initialized"); + return m_color8Bit; +} + GLuint ShaderHelper::posAtt() { if (!m_initialized) diff --git a/src/datavisualization/utils/shaderhelper_p.h b/src/datavisualization/utils/shaderhelper_p.h index fdef0dff..67e8a2f3 100644 --- a/src/datavisualization/utils/shaderhelper_p.h +++ b/src/datavisualization/utils/shaderhelper_p.h @@ -57,6 +57,7 @@ class ShaderHelper void setUniformValue(GLuint uniform, const QMatrix4x4 &value); void setUniformValue(GLuint uniform, GLfloat value); void setUniformValue(GLuint uniform, GLint value); + void setUniformValueArray(GLuint uniform, const QVector4D *values, int count); GLuint MVP(); GLuint view(); @@ -73,6 +74,10 @@ class ShaderHelper GLuint gradientMin(); GLuint gradientHeight(); GLuint lightColor(); + GLuint volumeSliceIndices(); + GLuint colorIndex(); + GLuint cameraPositionRelativeToModel(); + GLuint color8Bit(); GLuint posAtt(); GLuint uvAtt(); @@ -107,6 +112,10 @@ class ShaderHelper GLuint m_gradientMinUniform; GLuint m_gradientHeightUniform; GLuint m_lightColorUniform; + GLuint m_volumeSliceIndices; + GLuint m_colorIndex; + GLuint m_cameraPositionRelativeToModel; + GLuint m_color8Bit; GLboolean m_initialized; }; diff --git a/src/datavisualization/utils/texturehelper.cpp b/src/datavisualization/utils/texturehelper.cpp index 616c1981..5e21b5cd 100644 --- a/src/datavisualization/utils/texturehelper.cpp +++ b/src/datavisualization/utils/texturehelper.cpp @@ -21,11 +21,25 @@ #include #include +#include QT_BEGIN_NAMESPACE_DATAVISUALIZATION +// Defined in shaderhelper.cpp +extern void discardDebugMsgs(QtMsgType type, const QMessageLogContext &context, const QString &msg); + TextureHelper::TextureHelper() { +#if !defined(QT_OPENGL_ES_2) + // Discard warnings about deprecated functions + QtMessageHandler handler = qInstallMessageHandler(discardDebugMsgs); + + m_openGlFunctions_2_1 = new QOpenGLFunctions_2_1; + m_openGlFunctions_2_1->initializeOpenGLFunctions(); + + // Restore original message handler + qInstallMessageHandler(handler); +#endif initializeOpenGLFunctions(); } @@ -73,8 +87,54 @@ GLuint TextureHelper::create2DTexture(const QImage &image, bool useTrilinearFilt if (clampY) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glBindTexture(GL_TEXTURE_2D, 0); + + return textureId; +} + +#if !defined(QT_OPENGL_ES_2) +GLuint TextureHelper::create3DTexture(const QVector *data, int width, int height, int depth, + QImage::Format dataFormat) +{ + if (!width || !height || !depth) + return 0; + + glEnable(GL_TEXTURE_3D); + + GLuint textureId; + glGenTextures(1, &textureId); + glBindTexture(GL_TEXTURE_3D, textureId); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + GLenum status = glGetError(); + // glGetError docs advise to call glGetError in loop to clear all error flags + while (status) + status = glGetError(); + + GLint internalFormat = 4; + GLint format = GL_BGRA; + if (dataFormat == QImage::Format_Indexed8) { + internalFormat = 1; + format = GL_RED; + // Align width to 32bits + width = width + width % 4; + } + m_openGlFunctions_2_1->glTexImage3D(GL_TEXTURE_3D, 0, internalFormat, width, height, depth, 0, + format, GL_UNSIGNED_BYTE, data->constData()); + + status = glGetError(); + if (status) + qWarning() << __FUNCTION__ << "3D texture creation failed:" << status; + + glBindTexture(GL_TEXTURE_3D, 0); + glDisable(GL_TEXTURE_3D); + return textureId; } +#endif GLuint TextureHelper::createCubeMapTexture(const QImage &image, bool useTrilinearFiltering) { diff --git a/src/datavisualization/utils/texturehelper_p.h b/src/datavisualization/utils/texturehelper_p.h index c20f293c..c1dfe8c9 100644 --- a/src/datavisualization/utils/texturehelper_p.h +++ b/src/datavisualization/utils/texturehelper_p.h @@ -32,6 +32,10 @@ #include "datavisualizationglobal_p.h" #include #include +#if !defined(QT_OPENGL_ES_2) +// 3D Textures are not supported by ES set +# include +#endif QT_BEGIN_NAMESPACE_DATAVISUALIZATION @@ -44,6 +48,10 @@ class TextureHelper : protected QOpenGLFunctions // Ownership of created texture is transferred to caller GLuint create2DTexture(const QImage &image, bool useTrilinearFiltering = false, bool convert = true, bool smoothScale = true, bool clampY = false); +#if !defined(QT_OPENGL_ES_2) + GLuint create3DTexture(const QVector *data, int width, int height, int depth, + QImage::Format dataFormat); +#endif GLuint createCubeMapTexture(const QImage &image, bool useTrilinearFiltering = false); // Returns selection texture and inserts generated framebuffers to framebuffer parameters GLuint createSelectionTexture(const QSize &size, GLuint &frameBuffer, GLuint &depthBuffer); @@ -61,6 +69,9 @@ class TextureHelper : protected QOpenGLFunctions void convertToGLFormatHelper(QImage &dstImage, const QImage &srcImage, GLenum texture_format); QRgb qt_gl_convertToGLFormatHelper(QRgb src_pixel, GLenum texture_format); +#if !defined(QT_OPENGL_ES_2) + QOpenGLFunctions_2_1 *m_openGlFunctions_2_1; +#endif friend class Bars3DRenderer; friend class Surface3DRenderer; friend class Scatter3DRenderer; -- cgit v1.2.3