summaryrefslogtreecommitdiffstats
path: root/src/datavisualization/engine
diff options
context:
space:
mode:
Diffstat (limited to 'src/datavisualization/engine')
-rw-r--r--src/datavisualization/engine/abstract3drenderer.cpp176
-rw-r--r--src/datavisualization/engine/abstract3drenderer_p.h11
-rw-r--r--src/datavisualization/engine/bars3drenderer.cpp15
-rw-r--r--src/datavisualization/engine/drawer.cpp19
-rw-r--r--src/datavisualization/engine/drawer_p.h2
-rw-r--r--src/datavisualization/engine/engine.qrc3
-rw-r--r--src/datavisualization/engine/scatter3drenderer.cpp19
-rw-r--r--src/datavisualization/engine/shaders/default.frag1
-rw-r--r--src/datavisualization/engine/shaders/texture3d.frag70
-rw-r--r--src/datavisualization/engine/shaders/texture3d.vert12
-rw-r--r--src/datavisualization/engine/shaders/texture3dslice.frag119
-rw-r--r--src/datavisualization/engine/surface3drenderer.cpp23
12 files changed, 432 insertions, 38 deletions
diff --git a/src/datavisualization/engine/abstract3drenderer.cpp b/src/datavisualization/engine/abstract3drenderer.cpp
index 14cf7109..cbb90af0 100644
--- a/src/datavisualization/engine/abstract3drenderer.cpp
+++ b/src/datavisualization/engine/abstract3drenderer.cpp
@@ -24,6 +24,7 @@
#include "shaderhelper_p.h"
#include "qcustom3ditem_p.h"
#include "qcustom3dlabel_p.h"
+#include "qcustom3dvolume_p.h"
#include <QtCore/qmath.h>
@@ -57,6 +58,8 @@ Abstract3DRenderer::Abstract3DRenderer(Abstract3DController *controller)
m_selectionLabelItem(0),
m_visibleSeriesCount(0),
m_customItemShader(0),
+ m_volumeTextureShader(0),
+ m_volumeTextureSliceShader(0),
m_useOrthoProjection(false),
m_xFlipped(false),
m_yFlipped(false),
@@ -96,6 +99,8 @@ Abstract3DRenderer::~Abstract3DRenderer()
delete m_cachedTheme;
delete m_selectionLabelItem;
delete m_customItemShader;
+ delete m_volumeTextureShader;
+ delete m_volumeTextureSliceShader;
foreach (SeriesRenderCache *cache, m_renderCacheList) {
cache->cleanup(m_textureHelper);
@@ -196,6 +201,20 @@ void Abstract3DRenderer::initCustomItemShaders(const QString &vertexShader,
m_customItemShader->initialize();
}
+void Abstract3DRenderer::initVolumeTextureShaders(const QString &vertexShader,
+ const QString &fragmentShader,
+ const QString &sliceShader)
+{
+ if (m_volumeTextureShader)
+ delete m_volumeTextureShader;
+ m_volumeTextureShader = new ShaderHelper(this, vertexShader, fragmentShader);
+ m_volumeTextureShader->initialize();
+ if (m_volumeTextureSliceShader)
+ delete m_volumeTextureSliceShader;
+ m_volumeTextureSliceShader = new ShaderHelper(this, vertexShader, sliceShader);
+ m_volumeTextureSliceShader->initialize();
+}
+
void Abstract3DRenderer::updateTheme(Q3DTheme *theme)
{
// Synchronize the controller theme with renderer
@@ -279,6 +298,9 @@ void Abstract3DRenderer::reInitShaders()
initCustomItemShaders(QStringLiteral(":/shaders/vertexTexture"),
QStringLiteral(":/shaders/fragmentTexture"));
}
+ initVolumeTextureShaders(QStringLiteral(":/shaders/vertexTexture3D"),
+ QStringLiteral(":/shaders/fragmentTexture3D"),
+ QStringLiteral(":/shaders/fragmentTexture3DSlice"));
#else
initGradientShaders(QStringLiteral(":/shaders/vertex"),
QStringLiteral(":/shaders/fragmentColorOnYES2"));
@@ -906,6 +928,7 @@ CustomRenderItem *Abstract3DRenderer::addCustomItem(QCustom3DItem *item)
QVector3D scaling = item->scaling();
QImage textureImage = item->d_ptr->textureImage();
bool facingCamera = false;
+ GLuint texture;
if (item->d_ptr->m_isLabelItem) {
QCustom3DLabel *labelItem = static_cast<QCustom3DLabel *>(item);
float pointSize = labelItem->font().pointSizeF();
@@ -925,13 +948,39 @@ CustomRenderItem *Abstract3DRenderer::addCustomItem(QCustom3DItem *item)
scaling.setY(scaling.y() * textureImage.height() * scaledFontSize);
// Check if facing camera
facingCamera = labelItem->isFacingCamera();
+#if !defined(QT_OPENGL_ES_2)
+ } else if (item->d_ptr->m_isVolumeItem) {
+ QCustom3DVolume *volumeItem = static_cast<QCustom3DVolume *>(item);
+ newItem->setTextureWidth(volumeItem->textureWidth());
+ newItem->setTextureHeight(volumeItem->textureHeight());
+ newItem->setTextureDepth(volumeItem->textureDepth());
+ if (volumeItem->textureFormat() == QImage::Format_Indexed8)
+ newItem->setColorTable(volumeItem->colorTable());
+ newItem->setTextureFormat(volumeItem->textureFormat());
+ newItem->setVolume(true);
+ newItem->setBlendNeeded(true);
+ texture = m_textureHelper->create3DTexture(volumeItem->textureData(),
+ volumeItem->textureWidth(),
+ volumeItem->textureHeight(),
+ volumeItem->textureDepth(),
+ volumeItem->textureFormat());
+ newItem->setSliceIndexX(volumeItem->sliceIndexX());
+ newItem->setSliceIndexY(volumeItem->sliceIndexY());
+ newItem->setSliceIndexZ(volumeItem->sliceIndexZ());
+#endif
}
newItem->setScaling(scaling);
newItem->setRotation(item->rotation());
newItem->setPosition(item->position());
newItem->setPositionAbsolute(item->isPositionAbsolute());
- newItem->setBlendNeeded(textureImage.hasAlphaChannel());
- GLuint texture = m_textureHelper->create2DTexture(textureImage, true, true, true);
+#if !defined(QT_OPENGL_ES_2)
+ // In OpenGL ES we simply draw volumes as regular custom item placeholders.
+ if (!item->d_ptr->m_isVolumeItem)
+#endif
+ {
+ newItem->setBlendNeeded(textureImage.hasAlphaChannel());
+ texture = m_textureHelper->create2DTexture(textureImage, true, true, true);
+ }
newItem->setTexture(texture);
item->d_ptr->clearTextureImage();
QVector3D translation = convertPositionToTranslation(item->position(),
@@ -996,12 +1045,17 @@ void Abstract3DRenderer::updateCustomItem(CustomRenderItem *renderItem)
m_cachedTheme->isLabelBorderEnabled());
textureImage = item->d_ptr->textureImage();
}
+ } else
+#if !defined(QT_OPENGL_ES_2)
+ if (!item->d_ptr->m_isVolumeItem)
+#endif
+ {
+ renderItem->setBlendNeeded(textureImage.hasAlphaChannel());
+ GLuint oldTexture = renderItem->texture();
+ m_textureHelper->deleteTexture(&oldTexture);
+ GLuint texture = m_textureHelper->create2DTexture(textureImage, true, true, true);
+ renderItem->setTexture(texture);
}
- renderItem->setBlendNeeded(textureImage.hasAlphaChannel());
- GLuint oldTexture = renderItem->texture();
- m_textureHelper->deleteTexture(&oldTexture);
- GLuint texture = m_textureHelper->create2DTexture(textureImage, true, true, true);
- renderItem->setTexture(texture);
item->d_ptr->clearTextureImage();
item->d_ptr->m_dirtyBits.textureDirty = false;
}
@@ -1028,6 +1082,39 @@ void Abstract3DRenderer::updateCustomItem(CustomRenderItem *renderItem)
renderItem->setFacingCamera(labelItem->isFacingCamera());
labelItem->dptr()->m_facingCameraDirty = false;
}
+#if !defined(QT_OPENGL_ES_2)
+ } else if (item->d_ptr->m_isVolumeItem) {
+ QCustom3DVolume *volumeItem = static_cast<QCustom3DVolume *>(item);
+ if (volumeItem->dptr()->m_dirtyBitsVolume.colorTableDirty) {
+ renderItem->setColorTable(volumeItem->colorTable());
+ volumeItem->dptr()->m_dirtyBitsVolume.colorTableDirty = false;
+ }
+ if (volumeItem->dptr()->m_dirtyBitsVolume.textureDimensionsDirty
+ || volumeItem->dptr()->m_dirtyBitsVolume.textureDataDirty
+ || volumeItem->dptr()->m_dirtyBitsVolume.textureFormatDirty) {
+ GLuint oldTexture = renderItem->texture();
+ m_textureHelper->deleteTexture(&oldTexture);
+ GLuint texture = m_textureHelper->create3DTexture(volumeItem->textureData(),
+ volumeItem->textureWidth(),
+ volumeItem->textureHeight(),
+ volumeItem->textureDepth(),
+ volumeItem->textureFormat());
+ renderItem->setTexture(texture);
+ renderItem->setTextureWidth(volumeItem->textureWidth());
+ renderItem->setTextureHeight(volumeItem->textureHeight());
+ renderItem->setTextureDepth(volumeItem->textureDepth());
+ renderItem->setTextureFormat(volumeItem->textureFormat());
+ volumeItem->dptr()->m_dirtyBitsVolume.textureDimensionsDirty = false;
+ volumeItem->dptr()->m_dirtyBitsVolume.textureDataDirty = false;
+ volumeItem->dptr()->m_dirtyBitsVolume.textureFormatDirty = false;
+ }
+ if (volumeItem->dptr()->m_dirtyBitsVolume.sliceIndicesDirty) {
+ renderItem->setSliceIndexX(volumeItem->sliceIndexX());
+ renderItem->setSliceIndexY(volumeItem->sliceIndexY());
+ renderItem->setSliceIndexZ(volumeItem->sliceIndexZ());
+ volumeItem->dptr()->m_dirtyBitsVolume.sliceIndicesDirty = false;
+ }
+#endif
}
}
@@ -1042,7 +1129,9 @@ void Abstract3DRenderer::updateCustomItemPositions()
#ifdef USE_REFLECTIONS
void Abstract3DRenderer::drawCustomItems(RenderingState state,
- ShaderHelper *shader,
+ ShaderHelper *regularShader,
+ ShaderHelper *volumeShader,
+ ShaderHelper *volumeSliceShader,
const QMatrix4x4 &viewMatrix,
const QMatrix4x4 &projectionViewMatrix,
const QMatrix4x4 &depthProjectionViewMatrix,
@@ -1051,7 +1140,9 @@ void Abstract3DRenderer::drawCustomItems(RenderingState state,
GLfloat reflection)
#else
void Abstract3DRenderer::drawCustomItems(RenderingState state,
- ShaderHelper *shader,
+ ShaderHelper *regularShader,
+ ShaderHelper *volumeShader,
+ ShaderHelper *volumeSliceShader,
const QMatrix4x4 &viewMatrix,
const QMatrix4x4 &projectionViewMatrix,
const QMatrix4x4 &depthProjectionViewMatrix,
@@ -1059,11 +1150,17 @@ void Abstract3DRenderer::drawCustomItems(RenderingState state,
GLfloat shadowQuality)
#endif
{
+#if defined(QT_OPENGL_ES_2)
+ Q_UNUSED(volumeShader)
+ Q_UNUSED(volumeSliceShader)
+#endif
if (m_customRenderCache.isEmpty())
return;
+ ShaderHelper *shader = regularShader;
+ shader->bind();
+
if (RenderingNormal == state) {
- shader->bind();
shader->setUniformValue(shader->lightP(), m_cachedScene->activeLight()->position());
shader->setUniformValue(shader->ambientS(), m_cachedTheme->ambientLightStrength());
shader->setUniformValue(shader->lightColor(),
@@ -1137,6 +1234,22 @@ void Abstract3DRenderer::drawCustomItems(RenderingState state,
if (RenderingNormal == state) {
// Normal render
+#if !defined(QT_OPENGL_ES_2)
+ ShaderHelper *prevShader = shader;
+ if (item->isVolume()) {
+ if (item->sliceIndexX() >= 0
+ || item->sliceIndexY() >= 0
+ || item->sliceIndexZ() >= 0) {
+ shader = volumeSliceShader;
+ } else {
+ shader = volumeShader;
+ }
+ } else {
+ shader = regularShader;
+ }
+ if (shader != prevShader)
+ shader->bind();
+#endif
shader->setUniformValue(shader->model(), modelMatrix);
shader->setUniformValue(shader->MVP(), MVPMatrix);
shader->setUniformValue(shader->nModel(), itModelMatrix.inverted().transposed());
@@ -1144,14 +1257,17 @@ void Abstract3DRenderer::drawCustomItems(RenderingState state,
if (item->isBlendNeeded()) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glDisable(GL_CULL_FACE);
+#if !defined(QT_OPENGL_ES_2)
+ if (!item->isVolume())
+#endif
+ glDisable(GL_CULL_FACE);
} else {
glDisable(GL_BLEND);
glEnable(GL_CULL_FACE);
}
#if !defined(QT_OPENGL_ES_2)
- if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) {
+ if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone && !item->isVolume()) {
// Set shadow shader bindings
shader->setUniformValue(shader->shadowQ(), shadowQuality);
shader->setUniformValue(shader->depth(), depthProjectionViewMatrix * modelMatrix);
@@ -1164,8 +1280,34 @@ void Abstract3DRenderer::drawCustomItems(RenderingState state,
#endif
{
// Set shadowless shader bindings
- shader->setUniformValue(shader->lightS(), m_cachedTheme->lightStrength());
- m_drawer->drawObject(shader, item->mesh(), item->texture());
+#if !defined(QT_OPENGL_ES_2)
+ if (item->isVolume()) {
+ // Volume shaders repurpose light position for camera position relative to item
+ QVector3D cameraPos = m_cachedScene->activeCamera()->position();
+ cameraPos = MVPMatrix.inverted().map(cameraPos);
+ shader->setUniformValue(shader->cameraPositionRelativeToModel(), -cameraPos);
+ GLint color8Bit = (item->textureFormat() == QImage::Format_Indexed8) ? 1 : 0;
+ if (color8Bit) {
+ shader->setUniformValueArray(shader->colorIndex(),
+ item->colorTable().constData(), 256);
+ }
+ shader->setUniformValue(shader->color8Bit(), color8Bit);
+ if (shader == volumeSliceShader) {
+ QVector3D slices((float(item->sliceIndexX()) + 0.5f)
+ / float(item->textureWidth()) * 2.0 - 1.0,
+ (float(item->sliceIndexY()) + 0.5f)
+ / float(item->textureHeight()) * 2.0 - 1.0,
+ (float(item->sliceIndexZ()) + 0.5f)
+ / float(item->textureDepth()) * 2.0 - 1.0);
+ shader->setUniformValue(shader->volumeSliceIndices(), slices);
+ }
+ m_drawer->drawObject(shader, item->mesh(), 0, 0, item->texture());
+ } else
+#endif
+ {
+ shader->setUniformValue(shader->lightS(), m_cachedTheme->lightStrength());
+ m_drawer->drawObject(shader, item->mesh(), item->texture());
+ }
}
} else if (RenderingSelection == state) {
// Selection render
@@ -1203,6 +1345,9 @@ void Abstract3DRenderer::drawRadialGrid(ShaderHelper *shader, float yFloorLinePo
const QMatrix4x4 &projectionViewMatrix,
const QMatrix4x4 &depthMatrix)
{
+#if defined(QT_OPENGL_ES_2)
+ Q_UNUSED(depthMatrix)
+#endif
static QVector<QQuaternion> lineRotations;
if (!lineRotations.size()) {
lineRotations.resize(polarGridRoundness);
@@ -1264,6 +1409,9 @@ void Abstract3DRenderer::drawAngularGrid(ShaderHelper *shader, float yFloorLineP
const QMatrix4x4 &projectionViewMatrix,
const QMatrix4x4 &depthMatrix)
{
+#if defined(QT_OPENGL_ES_2)
+ Q_UNUSED(depthMatrix)
+#endif
float halfRatio((m_polarRadius + (labelMargin / 2.0f)) / 2.0f);
QVector3D gridLineScaler(gridLineWidth, gridLineWidth, halfRatio);
int gridLineCount = m_axisCacheX.gridLineCount();
diff --git a/src/datavisualization/engine/abstract3drenderer_p.h b/src/datavisualization/engine/abstract3drenderer_p.h
index 50370954..7874a1ad 100644
--- a/src/datavisualization/engine/abstract3drenderer_p.h
+++ b/src/datavisualization/engine/abstract3drenderer_p.h
@@ -94,6 +94,9 @@ public:
const QString &fragmentShader) = 0;
virtual void initCustomItemShaders(const QString &vertexShader,
const QString &fragmentShader);
+ virtual void initVolumeTextureShaders(const QString &vertexShader,
+ const QString &fragmentShader,
+ const QString &sliceShader);
virtual void updateAxisType(QAbstract3DAxis::AxisOrientation orientation,
QAbstract3DAxis::AxisType type);
virtual void updateAxisTitle(QAbstract3DAxis::AxisOrientation orientation,
@@ -145,13 +148,15 @@ public:
QString &selectionLabel();
#ifdef USE_REFLECTIONS
- void drawCustomItems(RenderingState state, ShaderHelper *shader,
+ void drawCustomItems(RenderingState state, ShaderHelper *regularShader,
+ ShaderHelper *volumeShader, ShaderHelper *volumeSliceShader,
const QMatrix4x4 &viewMatrix,
const QMatrix4x4 &projectionViewMatrix,
const QMatrix4x4 &depthProjectionViewMatrix,
GLuint depthTexture, GLfloat shadowQuality, GLfloat reflection = 1.0f);
#else
- void drawCustomItems(RenderingState state, ShaderHelper *shader,
+ void drawCustomItems(RenderingState state, ShaderHelper *regularShader,
+ ShaderHelper *volumeShader, ShaderHelper *volumeSliceShader,
const QMatrix4x4 &viewMatrix,
const QMatrix4x4 &projectionViewMatrix,
const QMatrix4x4 &depthProjectionViewMatrix,
@@ -247,6 +252,8 @@ protected:
int m_visibleSeriesCount;
ShaderHelper *m_customItemShader;
+ ShaderHelper *m_volumeTextureShader;
+ ShaderHelper *m_volumeTextureSliceShader;
bool m_useOrthoProjection;
bool m_xFlipped;
diff --git a/src/datavisualization/engine/bars3drenderer.cpp b/src/datavisualization/engine/bars3drenderer.cpp
index 38fa3147..085b881e 100644
--- a/src/datavisualization/engine/bars3drenderer.cpp
+++ b/src/datavisualization/engine/bars3drenderer.cpp
@@ -1093,9 +1093,11 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
}
}
- Abstract3DRenderer::drawCustomItems(RenderingDepth, m_depthShader, viewMatrix,
- projectionViewMatrix, depthProjectionViewMatrix,
- m_depthTexture, m_shadowQualityToShader);
+ Abstract3DRenderer::drawCustomItems(RenderingDepth, m_depthShader, m_volumeTextureShader,
+ m_volumeTextureSliceShader, viewMatrix,
+ projectionViewMatrix,
+ depthProjectionViewMatrix, m_depthTexture,
+ m_shadowQualityToShader);
// Disable drawing to depth framebuffer (= enable drawing to screen)
glBindFramebuffer(GL_FRAMEBUFFER, defaultFboHandle);
@@ -1179,7 +1181,9 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
}
}
glCullFace(GL_BACK);
- Abstract3DRenderer::drawCustomItems(RenderingSelection, m_selectionShader, viewMatrix,
+ Abstract3DRenderer::drawCustomItems(RenderingSelection, m_selectionShader,
+ m_volumeTextureShader, m_volumeTextureSliceShader,
+ viewMatrix,
projectionViewMatrix, depthProjectionViewMatrix,
m_depthTexture, m_shadowQualityToShader);
drawLabels(true, activeCamera, viewMatrix, projectionMatrix);
@@ -1267,7 +1271,8 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
drawGridLines(depthProjectionViewMatrix, projectionViewMatrix, viewMatrix);
// Draw custom items
- Abstract3DRenderer::drawCustomItems(RenderingNormal, m_customItemShader, viewMatrix,
+ Abstract3DRenderer::drawCustomItems(RenderingNormal, m_customItemShader, m_volumeTextureShader,
+ m_volumeTextureSliceShader, viewMatrix,
projectionViewMatrix, depthProjectionViewMatrix,
m_depthTexture, m_shadowQualityToShader);
diff --git a/src/datavisualization/engine/drawer.cpp b/src/datavisualization/engine/drawer.cpp
index b8726840..4191efc4 100644
--- a/src/datavisualization/engine/drawer.cpp
+++ b/src/datavisualization/engine/drawer.cpp
@@ -93,8 +93,11 @@ QFont Drawer::font() const
}
void Drawer::drawObject(ShaderHelper *shader, AbstractObjectHelper *object, GLuint textureId,
- GLuint depthTextureId)
+ GLuint depthTextureId, GLuint textureId3D)
{
+#if defined(QT_OPENGL_ES_2)
+ Q_UNUSED(textureId3D)
+#endif
if (textureId) {
// Activate texture
glActiveTexture(GL_TEXTURE0);
@@ -108,6 +111,14 @@ void Drawer::drawObject(ShaderHelper *shader, AbstractObjectHelper *object, GLui
glBindTexture(GL_TEXTURE_2D, depthTextureId);
shader->setUniformValue(shader->shadow(), 1);
}
+#if !defined(QT_OPENGL_ES_2)
+ if (textureId3D) {
+ // Activate texture
+ glActiveTexture(GL_TEXTURE2);
+ glBindTexture(GL_TEXTURE_3D, textureId3D);
+ shader->setUniformValue(shader->texture(), 2);
+ }
+#endif
// 1st attribute buffer : vertices
glEnableVertexAttribArray(shader->posAtt());
@@ -139,6 +150,12 @@ void Drawer::drawObject(ShaderHelper *shader, AbstractObjectHelper *object, GLui
glDisableVertexAttribArray(shader->posAtt());
// Release textures
+#if !defined(QT_OPENGL_ES_2)
+ if (textureId3D) {
+ glActiveTexture(GL_TEXTURE2);
+ glBindTexture(GL_TEXTURE_3D, 0);
+ }
+#endif
if (depthTextureId) {
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, 0);
diff --git a/src/datavisualization/engine/drawer_p.h b/src/datavisualization/engine/drawer_p.h
index ffcea315..709503dd 100644
--- a/src/datavisualization/engine/drawer_p.h
+++ b/src/datavisualization/engine/drawer_p.h
@@ -75,7 +75,7 @@ public:
inline GLfloat scaledFontSize() const { return m_scaledFontSize; }
void drawObject(ShaderHelper *shader, AbstractObjectHelper *object, GLuint textureId = 0,
- GLuint depthTextureId = 0);
+ GLuint depthTextureId = 0, GLuint textureId3D = 0);
void drawSelectionObject(ShaderHelper *shader, AbstractObjectHelper *object);
void drawSurfaceGrid(ShaderHelper *shader, SurfaceObject *object);
void drawPoint(ShaderHelper *shader);
diff --git a/src/datavisualization/engine/engine.qrc b/src/datavisualization/engine/engine.qrc
index f788b5df..936ed53f 100644
--- a/src/datavisualization/engine/engine.qrc
+++ b/src/datavisualization/engine/engine.qrc
@@ -59,5 +59,8 @@
<file alias="vertexTexture">shaders/texture.vert</file>
<file alias="fragmentTexturedSurfaceShadowFlat">shaders/surfaceTexturedShadowFlat.frag</file>
<file alias="fragmentSurfaceTexturedFlat">shaders/surfaceTexturedFlat.frag</file>
+ <file alias="fragmentTexture3D">shaders/texture3d.frag</file>
+ <file alias="vertexTexture3D">shaders/texture3d.vert</file>
+ <file alias="fragmentTexture3DSlice">shaders/texture3dslice.frag</file>
</qresource>
</RCC>
diff --git a/src/datavisualization/engine/scatter3drenderer.cpp b/src/datavisualization/engine/scatter3drenderer.cpp
index 09225b99..13f6e02c 100644
--- a/src/datavisualization/engine/scatter3drenderer.cpp
+++ b/src/datavisualization/engine/scatter3drenderer.cpp
@@ -538,9 +538,11 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
}
}
- Abstract3DRenderer::drawCustomItems(RenderingDepth, m_depthShader, viewMatrix,
- projectionViewMatrix, depthProjectionViewMatrix,
- m_depthTexture, m_shadowQualityToShader);
+ Abstract3DRenderer::drawCustomItems(RenderingDepth, m_depthShader, m_volumeTextureShader,
+ m_volumeTextureSliceShader, viewMatrix,
+ projectionViewMatrix,
+ depthProjectionViewMatrix, m_depthTexture,
+ m_shadowQualityToShader);
// Disable drawing to framebuffer (= enable drawing to screen)
glBindFramebuffer(GL_FRAMEBUFFER, defaultFboHandle);
@@ -641,9 +643,11 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
}
}
- Abstract3DRenderer::drawCustomItems(RenderingSelection, m_selectionShader, viewMatrix,
- projectionViewMatrix, depthProjectionViewMatrix,
- m_depthTexture, m_shadowQualityToShader);
+ Abstract3DRenderer::drawCustomItems(RenderingSelection, m_selectionShader,
+ m_volumeTextureShader, m_volumeTextureSliceShader,
+ viewMatrix, projectionViewMatrix,
+ depthProjectionViewMatrix, m_depthTexture,
+ m_shadowQualityToShader);
drawLabels(true, activeCamera, viewMatrix, projectionMatrix);
@@ -1407,7 +1411,8 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
}
}
- Abstract3DRenderer::drawCustomItems(RenderingNormal, m_customItemShader, viewMatrix,
+ Abstract3DRenderer::drawCustomItems(RenderingNormal, m_customItemShader, m_volumeTextureShader,
+ m_volumeTextureSliceShader, viewMatrix,
projectionViewMatrix, depthProjectionViewMatrix,
m_depthTexture, m_shadowQualityToShader);
diff --git a/src/datavisualization/engine/shaders/default.frag b/src/datavisualization/engine/shaders/default.frag
index c03b1054..0276ed95 100644
--- a/src/datavisualization/engine/shaders/default.frag
+++ b/src/datavisualization/engine/shaders/default.frag
@@ -33,5 +33,6 @@ void main() {
materialDiffuseColor * lightStrength * pow(cosTheta, 2) / distance +
materialSpecularColor * lightStrength * pow(cosAlpha, 5) / distance;
gl_FragColor.a = color_mdl.a;
+ gl_FragColor = clamp(gl_FragColor, 0.0, 1.0);
}
diff --git a/src/datavisualization/engine/shaders/texture3d.frag b/src/datavisualization/engine/shaders/texture3d.frag
new file mode 100644
index 00000000..054b59cb
--- /dev/null
+++ b/src/datavisualization/engine/shaders/texture3d.frag
@@ -0,0 +1,70 @@
+#version 120
+
+varying highp vec3 pos;
+
+uniform highp sampler3D textureSampler;
+uniform highp vec3 cameraPositionRelativeToModel;
+uniform highp vec4 colorIndex[256];
+uniform highp int color8Bit;
+
+const float maxDist = sqrt(2.0);
+const int sampleCount = 1024;
+const float alphaThreshold = 0.001;
+void main() {
+ // Raytrace into volume, need to sample pixels along the eye ray until we hit opacity 1
+
+ // Find out where ray intersects the object
+ highp vec3 rayDir = -(cameraPositionRelativeToModel - pos);
+ highp vec3 invRayDir = 1.0 / rayDir;
+ highp vec3 minCorner = vec3(-1.0);
+ highp vec3 maxCorner = vec3(1.0);
+ highp vec3 t1 = invRayDir * (minCorner - pos);
+ highp vec3 t2 = invRayDir * (maxCorner - pos);
+ highp vec3 tmin = min(t1, t2);
+ highp vec3 tmax = max(t1, t2);
+ highp vec2 t = max(tmin.xx, tmin.yz);
+ t = min(tmax.xx, tmax.yz);
+ float tFar = min(t.x, t.y);
+ highp vec3 rayStart = pos;
+ // Flip Y and Z so QImage bits work directly for texture and first image is in the front
+ rayStart.yz = -rayStart.yz;
+ highp vec3 rayStop = pos + rayDir * tFar;
+ rayStop.yz = -rayStop.yz;
+
+ // Convert intersections to texture coords
+ rayStart = 0.5 * (rayStart + 1.0);
+ rayStop = 0.5 * (rayStop + 1.0);
+
+ highp vec3 curPos = rayStart;
+ highp float fullDist = distance(rayStop, rayStart);
+ highp float stepSize = maxDist / float(sampleCount); // TODO: Stepsize needs to be improved
+ highp vec3 step = normalize(rayStop - rayStart) * stepSize;
+ highp float totalDist = 0.0;
+ highp float totalAlpha = 0.0;
+ highp vec4 destColor = vec4(0, 0, 0, 0);
+ highp vec4 curColor = vec4(0, 0, 0, 0);
+ highp vec3 curRgb = vec3(0, 0, 0);
+ highp float curAlpha = 0.0;
+
+ for (int i = 0; i < sampleCount; i++) {
+ curColor = texture3D(textureSampler, curPos);
+ if (color8Bit != 0)
+ curColor = colorIndex[int(curColor.r * 255.0)];
+
+ curAlpha = curColor.a;
+ if (curAlpha > alphaThreshold) {
+ curRgb = curColor.rgb * curAlpha * (1.0 - totalAlpha);
+ destColor.rgb += curRgb;
+ totalAlpha += curAlpha;
+ }
+ curPos += step;
+ totalDist += stepSize;
+ if (totalDist > fullDist || totalAlpha >= 1.0) {
+ break;
+ }
+ }
+
+ destColor.a = totalAlpha;
+ gl_FragColor = clamp(destColor, 0.0, 1.0);
+}
+
diff --git a/src/datavisualization/engine/shaders/texture3d.vert b/src/datavisualization/engine/shaders/texture3d.vert
new file mode 100644
index 00000000..cad1ce06
--- /dev/null
+++ b/src/datavisualization/engine/shaders/texture3d.vert
@@ -0,0 +1,12 @@
+uniform highp mat4 MVP;
+
+attribute highp vec3 vertexPosition_mdl;
+attribute highp vec2 vertexUV;
+attribute highp vec3 vertexNormal_mdl;
+
+varying highp vec3 pos;
+
+void main() {
+ gl_Position = MVP * vec4(vertexPosition_mdl, 1.0);
+ pos = vertexPosition_mdl;
+}
diff --git a/src/datavisualization/engine/shaders/texture3dslice.frag b/src/datavisualization/engine/shaders/texture3dslice.frag
new file mode 100644
index 00000000..641b32a5
--- /dev/null
+++ b/src/datavisualization/engine/shaders/texture3dslice.frag
@@ -0,0 +1,119 @@
+#version 120
+
+varying highp vec3 pos;
+
+uniform highp sampler3D textureSampler;
+uniform highp vec3 cameraPositionRelativeToModel;
+uniform highp vec3 volumeSliceIndices;
+uniform highp vec4 colorIndex[256];
+uniform highp int color8Bit;
+
+const highp vec3 xPlaneNormal = vec3(1.0, 0, 0);
+const highp vec3 yPlaneNormal = vec3(0, 1.0, 0);
+const highp vec3 zPlaneNormal = vec3(0, 0, 1.0);
+
+const float alphaThreshold = 0.001;
+void main() {
+ // Raytrace into volume, need to sample pixels along the eye ray until we hit opacity 1
+
+ // Find out where ray intersects the slice planes
+ highp vec3 rayDir = -(cameraPositionRelativeToModel - pos);
+ highp vec3 rayStart = pos;
+ // Flip Y and Z so QImage bits work directly for texture and first image is in the front
+ rayStart.yz = -rayStart.yz;
+ rayDir.yz = -rayDir.yz;
+ highp vec3 invRayDir = 1.0 / rayDir;
+ highp vec3 minCorner = vec3(-1.0);
+ highp vec3 maxCorner = vec3(1.0);
+ highp vec3 t1 = invRayDir * (minCorner - rayStart);
+ highp vec3 t2 = invRayDir * (maxCorner - rayStart);
+ highp vec3 tmin = min(t1, t2);
+ highp vec3 tmax = max(t1, t2);
+ highp vec2 t = max(tmin.xx, tmin.yz);
+ t = min(tmax.xx, tmax.yz);
+ float tFar = min(t.x, t.y);
+
+ highp vec3 xPoint = vec3(volumeSliceIndices.x, 0, 0);
+ highp vec3 yPoint = vec3(0, volumeSliceIndices.y, 0);
+ highp vec3 zPoint = vec3(0, 0, volumeSliceIndices.z);
+ highp float firstD = tFar + 1.0;
+ highp float secondD = firstD;
+ highp float thirdD = firstD;
+ if (volumeSliceIndices.x >= -1.0) {
+ highp float dx = dot(xPoint - rayStart, xPlaneNormal) / dot(rayDir, xPlaneNormal);
+ if (dx >= 0.0 && dx <= tFar)
+ firstD = min(dx, firstD);
+ }
+ if (volumeSliceIndices.y >= -1.0) {
+ highp float dy = dot(yPoint - rayStart, yPlaneNormal) / dot(rayDir, yPlaneNormal);
+ if (dy >= 0.0 && dy <= tFar) {
+ if (dy < firstD) {
+ secondD = firstD;
+ firstD = dy;
+ } else {
+ secondD = dy;
+ }
+ }
+ }
+ if (volumeSliceIndices.z >= -1.0) {
+ highp float dz = dot(zPoint - rayStart, zPlaneNormal) / dot(rayDir, zPlaneNormal);
+ if (dz >= 0.0) {
+ if (dz < firstD && dz <= tFar) {
+ thirdD = secondD;
+ secondD = firstD;
+ firstD = dz;
+ } else if (dz < secondD){
+ thirdD = secondD;
+ secondD = dz;
+ } else {
+ thirdD = dz;
+ }
+ }
+ }
+
+ highp vec4 destColor = vec4(0.0, 0.0, 0.0, 0.0);
+ highp float totalAlpha = 0.0;
+ highp vec3 curRgb = vec3(0, 0, 0);
+
+ // Convert intersection to texture coords
+
+ if (firstD <= tFar) {
+ highp vec3 firstTex = rayStart + rayDir * firstD;
+ firstTex = 0.5 * (firstTex + 1.0);
+ highp vec4 firstColor = texture3D(textureSampler, firstTex);
+ if (color8Bit != 0)
+ firstColor = colorIndex[int(firstColor.r * 255.0)];
+
+ if (firstColor.a > alphaThreshold) {
+ destColor.rgb = firstColor.rgb * firstColor.a;
+ totalAlpha = firstColor.a;
+ }
+ if (secondD <= tFar && totalAlpha < 1.0) {
+ highp vec3 secondTex = rayStart + rayDir * secondD;
+ secondTex = 0.5 * (secondTex + 1.0);
+ highp vec4 secondColor = texture3D(textureSampler, secondTex);
+ if (color8Bit != 0)
+ secondColor = colorIndex[int(secondColor.r * 255.0)];
+ if (secondColor.a > alphaThreshold) {
+ curRgb = secondColor.rgb * secondColor.a * (1.0 - totalAlpha);
+ destColor.rgb += curRgb;
+ totalAlpha += secondColor.a;
+ }
+ if (thirdD <= tFar && totalAlpha < 1.0) {
+ highp vec3 thirdTex = rayStart + rayDir * thirdD;
+ thirdTex = 0.5 * (thirdTex + 1.0);
+ highp vec4 thirdColor = texture3D(textureSampler, thirdTex);
+ if (color8Bit != 0)
+ thirdColor = colorIndex[int(thirdColor.r * 255.0)];
+ if (thirdColor.a > alphaThreshold) {
+ curRgb = thirdColor.rgb * thirdColor.a * (1.0 - totalAlpha);
+ destColor.rgb += curRgb;
+ totalAlpha += thirdColor.a;
+ }
+ }
+ }
+ }
+ destColor.a = totalAlpha;
+ gl_FragColor = clamp(destColor, 0.0, 1.0);
+}
+
diff --git a/src/datavisualization/engine/surface3drenderer.cpp b/src/datavisualization/engine/surface3drenderer.cpp
index 1607f66a..17be3278 100644
--- a/src/datavisualization/engine/surface3drenderer.cpp
+++ b/src/datavisualization/engine/surface3drenderer.cpp
@@ -1196,9 +1196,11 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
- Abstract3DRenderer::drawCustomItems(RenderingDepth, m_depthShader, viewMatrix,
- projectionViewMatrix, depthProjectionViewMatrix,
- m_depthTexture, m_shadowQualityToShader);
+ Abstract3DRenderer::drawCustomItems(RenderingDepth, m_depthShader, m_volumeTextureShader,
+ m_volumeTextureSliceShader, viewMatrix,
+ projectionViewMatrix,
+ depthProjectionViewMatrix, m_depthTexture,
+ m_shadowQualityToShader);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,
m_depthModelTexture, 0);
@@ -1232,9 +1234,11 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
glDisableVertexAttribArray(m_depthShader->posAtt());
- Abstract3DRenderer::drawCustomItems(RenderingDepth, m_depthShader, viewMatrix,
- projectionViewMatrix, depthProjectionViewMatrix,
- m_depthTexture, m_shadowQualityToShader);
+ Abstract3DRenderer::drawCustomItems(RenderingDepth, m_depthShader, m_volumeTextureShader,
+ m_volumeTextureSliceShader, viewMatrix,
+ projectionViewMatrix,
+ depthProjectionViewMatrix, m_depthTexture,
+ m_shadowQualityToShader);
// Disable drawing to depth framebuffer (= enable drawing to screen)
glBindFramebuffer(GL_FRAMEBUFFER, defaultFboHandle);
@@ -1287,7 +1291,9 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
}
}
m_surfaceGridShader->bind();
- Abstract3DRenderer::drawCustomItems(RenderingSelection, m_surfaceGridShader, viewMatrix,
+ Abstract3DRenderer::drawCustomItems(RenderingSelection, m_surfaceGridShader,
+ m_volumeTextureShader, m_volumeTextureSliceShader,
+ viewMatrix,
projectionViewMatrix, depthProjectionViewMatrix,
m_depthTexture, m_shadowQualityToShader);
drawLabels(true, activeCamera, viewMatrix, projectionMatrix);
@@ -1858,7 +1864,8 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
}
}
- Abstract3DRenderer::drawCustomItems(RenderingNormal, m_customItemShader, viewMatrix,
+ Abstract3DRenderer::drawCustomItems(RenderingNormal, m_customItemShader, m_volumeTextureShader,
+ m_volumeTextureSliceShader, viewMatrix,
projectionViewMatrix, depthProjectionViewMatrix,
m_depthTexture, m_shadowQualityToShader);