summaryrefslogtreecommitdiffstats
path: root/src/datavisualization
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@digia.com>2014-09-03 09:28:44 +0300
committerMiikka Heikkinen <miikka.heikkinen@digia.com>2014-09-03 09:43:19 +0300
commitac96d7ae26fff464a5ef9ab327fe46499f0077bf (patch)
tree6a65ded7e8808ea757d915e5def5e8d3702b13d3 /src/datavisualization
parentd85e665b114692fcac7c8e16217c7148907584b0 (diff)
Make volume items draw after regular custom items
Since volume items typically contain transparencies, make them draw after regular custom items, which are less likely to be transparent. Change-Id: Id7c48b6c77d7ed8654b72923d7dccf4158c9c088 Reviewed-by: Tomi Korpipää <tomi.korpipaa@digia.com>
Diffstat (limited to 'src/datavisualization')
-rw-r--r--src/datavisualization/engine/abstract3drenderer.cpp326
1 files changed, 171 insertions, 155 deletions
diff --git a/src/datavisualization/engine/abstract3drenderer.cpp b/src/datavisualization/engine/abstract3drenderer.cpp
index f031a34c..640502ad 100644
--- a/src/datavisualization/engine/abstract3drenderer.cpp
+++ b/src/datavisualization/engine/abstract3drenderer.cpp
@@ -1193,187 +1193,203 @@ void Abstract3DRenderer::drawCustomItems(RenderingState state,
shader->setUniformValue(shader->view(), viewMatrix);
}
- // Draw custom items
- foreach (CustomRenderItem *item, m_customRenderCache) {
- // Check that the render item is visible, and skip drawing if not
- if (!item->isVisible())
- continue;
-
- // Check if the render item is in data coordinates and not within axis ranges, and skip drawing if it is
- if (!item->isPositionAbsolute()
- && (item->position().x() < m_axisCacheX.min()
- || item->position().x() > m_axisCacheX.max()
- || item->position().z() < m_axisCacheZ.min()
- || item->position().z() > m_axisCacheZ.max()
- || item->position().y() < m_axisCacheY.min()
- || item->position().y() > m_axisCacheY.max())) {
- continue;
- }
-
- QMatrix4x4 modelMatrix;
- QMatrix4x4 itModelMatrix;
- QMatrix4x4 MVPMatrix;
-
- QQuaternion rotation = item->rotation();
- // Check if the (label) item should be facing camera, and adjust rotation accordingly
- if (item->isFacingCamera()) {
- float camRotationX = m_cachedScene->activeCamera()->xRotation();
- float camRotationY = m_cachedScene->activeCamera()->yRotation();
- rotation = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, -camRotationX)
- * QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, -camRotationY);
- }
-
- if (m_reflectionEnabled) {
- if (reflection < 0.0f) {
- if (item->itemPointer()->d_ptr->m_isLabelItem)
+ // Draw custom items - first regular and then volumes
+ bool volumeDetected = false;
+ int loopCount = 0;
+ while (loopCount < 2) {
+ foreach (CustomRenderItem *item, m_customRenderCache) {
+ // Check that the render item is visible, and skip drawing if not
+ if (!item->isVisible())
+ continue;
+ if (loopCount == 0) {
+ if (item->isVolume()) {
+ volumeDetected = true;
continue;
- else
- glCullFace(GL_FRONT);
+ }
} else {
- glCullFace(GL_BACK);
+ if (!item->isVolume())
+ continue;
+ }
+
+ // Check if the render item is in data coordinates and not within axis ranges, and skip drawing if it is
+ if (!item->isPositionAbsolute()
+ && (item->position().x() < m_axisCacheX.min()
+ || item->position().x() > m_axisCacheX.max()
+ || item->position().z() < m_axisCacheZ.min()
+ || item->position().z() > m_axisCacheZ.max()
+ || item->position().y() < m_axisCacheY.min()
+ || item->position().y() > m_axisCacheY.max())) {
+ continue;
}
- QVector3D trans = item->translation();
- trans.setY(reflection * trans.y());
- modelMatrix.translate(trans);
- if (reflection < 0.0f) {
- QQuaternion mirror = QQuaternion(rotation.scalar(),
- -rotation.x(), rotation.y(), -rotation.z());
- modelMatrix.rotate(mirror);
- itModelMatrix.rotate(mirror);
+
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 itModelMatrix;
+ QMatrix4x4 MVPMatrix;
+
+ QQuaternion rotation = item->rotation();
+ // Check if the (label) item should be facing camera, and adjust rotation accordingly
+ if (item->isFacingCamera()) {
+ float camRotationX = m_cachedScene->activeCamera()->xRotation();
+ float camRotationY = m_cachedScene->activeCamera()->yRotation();
+ rotation = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, -camRotationX)
+ * QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, -camRotationY);
+ }
+
+ if (m_reflectionEnabled) {
+ if (reflection < 0.0f) {
+ if (item->itemPointer()->d_ptr->m_isLabelItem)
+ continue;
+ else
+ glCullFace(GL_FRONT);
+ } else {
+ glCullFace(GL_BACK);
+ }
+ QVector3D trans = item->translation();
+ trans.setY(reflection * trans.y());
+ modelMatrix.translate(trans);
+ if (reflection < 0.0f) {
+ QQuaternion mirror = QQuaternion(rotation.scalar(),
+ -rotation.x(), rotation.y(), -rotation.z());
+ modelMatrix.rotate(mirror);
+ itModelMatrix.rotate(mirror);
+ } else {
+ modelMatrix.rotate(rotation);
+ itModelMatrix.rotate(rotation);
+ }
+ QVector3D scale = item->scaling();
+ scale.setY(reflection * scale.y());
+ modelMatrix.scale(scale);
} else {
+ modelMatrix.translate(item->translation());
modelMatrix.rotate(rotation);
+ modelMatrix.scale(item->scaling());
itModelMatrix.rotate(rotation);
}
- QVector3D scale = item->scaling();
- scale.setY(reflection * scale.y());
- modelMatrix.scale(scale);
- } else {
- modelMatrix.translate(item->translation());
- modelMatrix.rotate(rotation);
- modelMatrix.scale(item->scaling());
- itModelMatrix.rotate(rotation);
- }
- if (!item->isFacingCamera())
- itModelMatrix.scale(item->scaling());
- MVPMatrix = projectionViewMatrix * modelMatrix;
+ if (!item->isFacingCamera())
+ itModelMatrix.scale(item->scaling());
+ MVPMatrix = projectionViewMatrix * modelMatrix;
- if (RenderingNormal == state) {
- // Normal render
+ 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 = m_volumeTextureSliceShader;
- } else if (item->useHighDefShader()) {
- shader = m_volumeTextureShader;
+ ShaderHelper *prevShader = shader;
+ if (item->isVolume()) {
+ if (item->sliceIndexX() >= 0
+ || item->sliceIndexY() >= 0
+ || item->sliceIndexZ() >= 0) {
+ shader = m_volumeTextureSliceShader;
+ } else if (item->useHighDefShader()) {
+ shader = m_volumeTextureShader;
+ } else {
+ shader = m_volumeTextureLowDefShader;
+ }
} else {
- shader = m_volumeTextureLowDefShader;
+ shader = regularShader;
}
- } else {
- shader = regularShader;
- }
- if (shader != prevShader)
- shader->bind();
+ if (shader != prevShader)
+ shader->bind();
#endif
- shader->setUniformValue(shader->model(), modelMatrix);
- shader->setUniformValue(shader->MVP(), MVPMatrix);
- shader->setUniformValue(shader->nModel(), itModelMatrix.inverted().transposed());
+ shader->setUniformValue(shader->model(), modelMatrix);
+ shader->setUniformValue(shader->MVP(), MVPMatrix);
+ shader->setUniformValue(shader->nModel(), itModelMatrix.inverted().transposed());
- if (item->isBlendNeeded()) {
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ if (item->isBlendNeeded()) {
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
#if !defined(QT_OPENGL_ES_2)
- if (!item->isVolume())
+ if (!item->isVolume())
#endif
- glDisable(GL_CULL_FACE);
- } else {
- glDisable(GL_BLEND);
- glEnable(GL_CULL_FACE);
- }
+ glDisable(GL_CULL_FACE);
+ } else {
+ glDisable(GL_BLEND);
+ glEnable(GL_CULL_FACE);
+ }
#if !defined(QT_OPENGL_ES_2)
- if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone && !item->isVolume()) {
- // Set shadow shader bindings
- shader->setUniformValue(shader->shadowQ(), shadowQuality);
- shader->setUniformValue(shader->depth(), depthProjectionViewMatrix * modelMatrix);
- shader->setUniformValue(shader->lightS(), m_cachedTheme->lightStrength() / 10.0f);
- m_drawer->drawObject(shader, item->mesh(), item->texture(), depthTexture);
- } else
+ if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone && !item->isVolume()) {
+ // Set shadow shader bindings
+ shader->setUniformValue(shader->shadowQ(), shadowQuality);
+ shader->setUniformValue(shader->depth(), depthProjectionViewMatrix * modelMatrix);
+ shader->setUniformValue(shader->lightS(), m_cachedTheme->lightStrength() / 10.0f);
+ m_drawer->drawObject(shader, item->mesh(), item->texture(), depthTexture);
+ } else
#else
- Q_UNUSED(depthTexture)
- Q_UNUSED(shadowQuality)
+ Q_UNUSED(depthTexture)
+ Q_UNUSED(shadowQuality)
#endif
- {
- // Set shadowless shader bindings
+ {
+ // Set shadowless shader bindings
#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);
- shader->setUniformValue(shader->alphaMultiplier(), item->alphaMultiplier());
- shader->setUniformValue(shader->preserveOpacity(),
- item->preserveOpacity() ? 1 : 0);
- if (shader == m_volumeTextureSliceShader) {
- 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);
- } else {
- // Precalculate texture dimensions so we can optimize
- // ray stepping to hit every texture layer.
- QVector3D textureDimensions(1.0f / float(item->textureWidth()),
- 1.0f / float(item->textureHeight()),
- 1.0f / float(item->textureDepth()));
-
- // Worst case scenario sample count
- int sampleCount;
- if (shader == m_volumeTextureLowDefShader) {
- sampleCount = qMax(item->textureWidth(),
- qMax(item->textureDepth(), item->textureHeight()));
- // Further improve speed with big textures by simply dropping every
- // other sample:
- if (sampleCount > 256)
- sampleCount /= 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);
+ shader->setUniformValue(shader->alphaMultiplier(), item->alphaMultiplier());
+ shader->setUniformValue(shader->preserveOpacity(),
+ item->preserveOpacity() ? 1 : 0);
+ if (shader == m_volumeTextureSliceShader) {
+ 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);
} else {
- sampleCount = item->textureWidth() + item->textureHeight()
- + item->textureDepth();
+ // Precalculate texture dimensions so we can optimize
+ // ray stepping to hit every texture layer.
+ QVector3D textureDimensions(1.0f / float(item->textureWidth()),
+ 1.0f / float(item->textureHeight()),
+ 1.0f / float(item->textureDepth()));
+
+ // Worst case scenario sample count
+ int sampleCount;
+ if (shader == m_volumeTextureLowDefShader) {
+ sampleCount = qMax(item->textureWidth(),
+ qMax(item->textureDepth(), item->textureHeight()));
+ // Further improve speed with big textures by simply dropping every
+ // other sample:
+ if (sampleCount > 256)
+ sampleCount /= 2;
+ } else {
+ sampleCount = item->textureWidth() + item->textureHeight()
+ + item->textureDepth();
+ }
+ shader->setUniformValue(shader->textureDimensions(), textureDimensions);
+ shader->setUniformValue(shader->sampleCount(), sampleCount);
}
- shader->setUniformValue(shader->textureDimensions(), textureDimensions);
- shader->setUniformValue(shader->sampleCount(), sampleCount);
- }
- m_drawer->drawObject(shader, item->mesh(), 0, 0, item->texture());
- } else
+ 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());
+ {
+ shader->setUniformValue(shader->lightS(), m_cachedTheme->lightStrength());
+ m_drawer->drawObject(shader, item->mesh(), item->texture());
+ }
}
+ } else if (RenderingSelection == state) {
+ // Selection render
+ shader->setUniformValue(shader->MVP(), MVPMatrix);
+ QVector4D itemColor = indexToSelectionColor(item->index());
+ itemColor.setW(customItemAlpha);
+ itemColor /= 255.0f;
+ shader->setUniformValue(shader->color(), itemColor);
+ m_drawer->drawObject(shader, item->mesh());
+ } else if (item->isShadowCasting()) {
+ // Depth render
+ shader->setUniformValue(shader->MVP(), depthProjectionViewMatrix * modelMatrix);
+ m_drawer->drawObject(shader, item->mesh());
}
- } else if (RenderingSelection == state) {
- // Selection render
- shader->setUniformValue(shader->MVP(), MVPMatrix);
- QVector4D itemColor = indexToSelectionColor(item->index());
- itemColor.setW(customItemAlpha);
- itemColor /= 255.0f;
- shader->setUniformValue(shader->color(), itemColor);
- m_drawer->drawObject(shader, item->mesh());
- } else if (item->isShadowCasting()) {
- // Depth render
- shader->setUniformValue(shader->MVP(), depthProjectionViewMatrix * modelMatrix);
- m_drawer->drawObject(shader, item->mesh());
}
+ loopCount++;
+ if (!volumeDetected)
+ loopCount++; // Skip second run if no volumes detected
}
if (RenderingNormal == state) {