summaryrefslogtreecommitdiffstats
path: root/src/datavisualization/engine/scatter3drenderer.cpp
diff options
context:
space:
mode:
authorMika Salmela <mika.salmela@digia.com>2013-12-18 11:50:03 +0200
committerMika Salmela <mika.salmela@digia.com>2013-12-18 11:51:20 +0200
commit07aba602fc82ac31684988f8e8e22521d2b3c982 (patch)
tree7ae1da139e8661bf157f996fe71844031d2995f4 /src/datavisualization/engine/scatter3drenderer.cpp
parentcf0cf6ca67aec8ae480bb705443ea17f5ab9f9e2 (diff)
parentea0442bc81ae034d22c5742b6075dee993fdd54d (diff)
Merge branch 'develop' into mergebranch
Conflicts: examples/qmlbars/qml/qmlbars/main.qml examples/qmlscatter/qml/qmlscatter/main.qml examples/qmlsurface/qml/qmlsurface/main.qml src/datavisualization/data/qitemmodelbardatamapping.cpp src/datavisualization/data/qitemmodelscatterdatamapping.cpp src/datavisualization/data/qitemmodelsurfacedatamapping.cpp src/datavisualization/engine/drawer.cpp Change-Id: I731ebdb2cc5cee8f2cb32becee96d1fc1b3e5de1
Diffstat (limited to 'src/datavisualization/engine/scatter3drenderer.cpp')
-rw-r--r--src/datavisualization/engine/scatter3drenderer.cpp1032
1 files changed, 633 insertions, 399 deletions
diff --git a/src/datavisualization/engine/scatter3drenderer.cpp b/src/datavisualization/engine/scatter3drenderer.cpp
index a457b545..00452cf7 100644
--- a/src/datavisualization/engine/scatter3drenderer.cpp
+++ b/src/datavisualization/engine/scatter3drenderer.cpp
@@ -25,6 +25,7 @@
#include "texturehelper_p.h"
#include "utils_p.h"
#include "q3dlight.h"
+#include "qscatter3dseries_p.h"
#include <QMatrix4x4>
#include <QMouseEvent>
@@ -46,25 +47,28 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE
const GLfloat aspectRatio = 2.0f; // Forced ratio of x and z to y. Dynamic will make it look odd.
const GLfloat labelMargin = 0.05f;
-// TODO: Make margin modifiable?
-const GLfloat backgroundMargin = 1.1f; // Margin for background (1.1f = make it 10% larger to avoid items being drawn inside background)
+const GLfloat defaultMinSize = 0.01f;
+const GLfloat defaultMaxSize = 0.1f;
+const GLfloat defaultMargin = 1.0f + defaultMaxSize; // Default margin for background
+const GLfloat itemScaler = 3.0f;
const GLfloat gridLineWidth = 0.005f;
-static QVector3D selectionSkipColor = QVector3D(255, 255, 255); // Selection texture's background color
Scatter3DRenderer::Scatter3DRenderer(Scatter3DController *controller)
: Abstract3DRenderer(controller),
- m_controller(controller),
m_selectedItem(0),
m_xFlipped(false),
m_zFlipped(false),
m_yFlipped(false),
m_updateLabels(false),
m_dotShader(0),
+ m_dotGradientShader(0),
+ #if defined(QT_OPENGL_ES_2)
+ m_pointShader(0),
+ #endif
m_depthShader(0),
m_selectionShader(0),
m_backgroundShader(0),
m_labelShader(0),
- m_dotObj(0),
m_backgroundObj(0),
m_gridLineObj(0),
m_labelObj(0),
@@ -78,11 +82,15 @@ Scatter3DRenderer::Scatter3DRenderer(Scatter3DController *controller)
m_shadowQualityMultiplier(3),
m_heightNormalizer(1.0f),
m_scaleFactor(0),
- m_selection(selectionSkipColor),
- m_previousSelection(selectionSkipColor),
+ m_selectedItemIndex(Scatter3DController::invalidSelectionIndex()),
+ m_selectedItemTotalIndex(Scatter3DController::invalidSelectionIndex()),
+ m_selectedItemSeriesIndex(Scatter3DController::invalidSelectionIndex()),
+ m_selectedSeries(0),
m_areaSize(QSizeF(0.0, 0.0)),
m_dotSizeScale(1.0f),
- m_hasHeightAdjustmentChanged(true)
+ m_hasHeightAdjustmentChanged(true),
+ m_backgroundMargin(defaultMargin),
+ m_maxItemSize(0.0f)
{
initializeOpenGLFunctions();
initializeOpenGL();
@@ -96,11 +104,11 @@ Scatter3DRenderer::~Scatter3DRenderer()
m_textureHelper->glDeleteFramebuffers(1, &m_depthFrameBuffer);
m_textureHelper->deleteTexture(&m_bgrTexture);
delete m_dotShader;
+ delete m_dotGradientShader;
delete m_depthShader;
delete m_selectionShader;
delete m_backgroundShader;
delete m_labelShader;
- delete m_dotObj;
delete m_backgroundObj;
delete m_gridLineObj;
delete m_labelObj;
@@ -111,14 +119,15 @@ void Scatter3DRenderer::initializeOpenGL()
Abstract3DRenderer::initializeOpenGL();
// Initialize shaders
- handleShadowQualityChange();
-
initLabelShaders(QStringLiteral(":/shaders/vertexLabel"),
QStringLiteral(":/shaders/fragmentLabel"));
#if !defined(QT_OPENGL_ES_2)
// Init depth shader (for shadows). Init in any case, easier to handle shadow activation if done via api.
initDepthShader();
+#else
+ // Init point shader
+ initPointShader();
#endif
// Init selection shader
@@ -131,52 +140,81 @@ void Scatter3DRenderer::initializeOpenGL()
loadLabelMesh();
// Set view port
- glViewport(m_mainViewPort.x(), m_mainViewPort.y(),
- m_mainViewPort.width(), m_mainViewPort.height());
+ glViewport(m_primarySubViewport.x(),
+ m_primarySubViewport.y(),
+ m_primarySubViewport.width(),
+ m_primarySubViewport.height());
// Load background mesh (we need to be initialized first)
loadBackgroundMesh();
}
-void Scatter3DRenderer::updateDataModel(QScatterDataProxy *dataProxy)
+void Scatter3DRenderer::updateSeries(const QList<QAbstract3DSeries *> &seriesList,
+ bool updateVisibility)
{
- const QScatterDataArray &dataArray = *dataProxy->array();
+ Abstract3DRenderer::updateSeries(seriesList, updateVisibility);
+
+ int seriesCount = m_visibleSeriesList.size();
+ float maxItemSize = 0.0f;
+ float itemSize = 0.0f;
+
+ for (int series = 0; series < seriesCount; series++) {
+ itemSize = static_cast<QScatter3DSeries *>(m_visibleSeriesList.at(series).series())->itemSize();
+ if (maxItemSize < itemSize)
+ maxItemSize = itemSize;
+ }
+ m_backgroundMargin = defaultMargin;
+ m_maxItemSize = maxItemSize;
+ if (maxItemSize > defaultMaxSize)
+ m_backgroundMargin += maxItemSize / itemScaler;
+}
+
+void Scatter3DRenderer::updateData()
+{
+ int seriesCount = m_visibleSeriesList.size();
calculateSceneScalingFactors();
- int dataSize = dataArray.size();
float minX = float(m_axisCacheX.min());
float maxX = float(m_axisCacheX.max());
float minY = float(m_axisCacheY.min());
float maxY = float(m_axisCacheY.max());
float minZ = float(m_axisCacheZ.min());
float maxZ = float(m_axisCacheZ.max());
-
- if (dataSize != m_renderItemArray.size())
- m_renderItemArray.resize(dataSize);
- for (int i = 0; i < dataSize ; i++) {
- QVector3D dotPos = dataArray.at(i).position();
- // TODO: Check if this still works always when ranges are no longer required to be zero centered
- // TODO: qreal -> float conversion for axis min/max may cause issues like in surface
- if ((dotPos.x() >= minX && dotPos.x() <= maxX )
- && (dotPos.y() >= minY && dotPos.y() <= maxY)
- && (dotPos.z() >= minZ && dotPos.z() <= maxZ)) {
- m_renderItemArray[i].setPosition(dotPos);
- m_renderItemArray[i].setVisible(true);
- calculateTranslation(m_renderItemArray[i]);
- } else {
- m_renderItemArray[i].setVisible(false);
+ int totalDataSize = 0;
+
+ if (m_renderingArrays.size() != seriesCount)
+ m_renderingArrays.resize(seriesCount);
+
+ for (int series = 0; series < seriesCount; series++) {
+ QScatterDataProxy *dataProxy =
+ static_cast<QScatter3DSeries *>(m_visibleSeriesList.at(series).series())->dataProxy();
+ const QScatterDataArray &dataArray = *dataProxy->array();
+ int dataSize = dataArray.size();
+ totalDataSize += dataSize;
+
+ if (dataSize != m_renderingArrays.at(series).size())
+ m_renderingArrays[series].resize(dataSize);
+
+ for (int i = 0; i < dataSize; i++) {
+ QVector3D dotPos = dataArray.at(i).position();
+ if ((dotPos.x() >= minX && dotPos.x() <= maxX )
+ && (dotPos.y() >= minY && dotPos.y() <= maxY)
+ && (dotPos.z() >= minZ && dotPos.z() <= maxZ)) {
+ m_renderingArrays[series][i].setPosition(dotPos);
+ m_renderingArrays[series][i].setVisible(true);
+ calculateTranslation(m_renderingArrays[series][i]);
+ } else {
+ m_renderingArrays[series][i].setVisible(false);
+ }
}
}
- m_dotSizeScale = (GLfloat)qBound(0.01, (2.0 / qSqrt((qreal)dataSize)), 0.1);
- m_selectedItem = 0;
+ m_dotSizeScale = GLfloat(qBound(defaultMinSize, 2.0f / float(qSqrt(qreal(totalDataSize))),
+ defaultMaxSize));
- Abstract3DRenderer::updateDataModel(dataProxy);
+ updateSelectedItem(m_selectedItemIndex, m_selectedSeries);
}
void Scatter3DRenderer::updateScene(Q3DScene *scene)
{
- // TODO: Move these to more suitable place e.g. controller should be controlling the viewports.
- scene->setPrimarySubViewport(m_mainViewPort);
-
// TODO: See QTRD-2374
scene->activeCamera()->setMinYRotation(-90.0f);
@@ -186,10 +224,6 @@ void Scatter3DRenderer::updateScene(Q3DScene *scene)
m_hasHeightAdjustmentChanged = false;
}
- scene->activeCamera()->d_ptr->updateViewMatrix(m_autoScaleAdjustment);
- // Set light position (rotate light with m_cachedScene->activeCamera(), a bit above it (as set in defaultLightPos))
- scene->setLightPositionRelativeToCamera(defaultLightPos);
-
Abstract3DRenderer::updateScene(scene);
}
@@ -209,19 +243,22 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
const Q3DCamera *activeCamera = m_cachedScene->activeCamera();
// Specify viewport
- glViewport(m_mainViewPort.x(), m_mainViewPort.y(),
- m_mainViewPort.width(), m_mainViewPort.height());
+ glViewport(m_primarySubViewport.x(),
+ m_primarySubViewport.y(),
+ m_primarySubViewport.width(),
+ m_primarySubViewport.height());
// Set up projection matrix
QMatrix4x4 projectionMatrix;
- GLfloat viewPortRatio = (GLfloat)m_mainViewPort.width() / (GLfloat)m_mainViewPort.height();
+ GLfloat viewPortRatio = (GLfloat)m_primarySubViewport.width() / (GLfloat)m_primarySubViewport.height();
projectionMatrix.perspective(45.0f, viewPortRatio, 0.1f, 100.0f);
// Calculate view matrix
QMatrix4x4 viewMatrix = activeCamera->viewMatrix();
-
QMatrix4x4 projectionViewMatrix = projectionMatrix * viewMatrix;
+ int seriesCount = m_visibleSeriesList.size();
+
// Calculate label flipping
if (viewMatrix.row(0).x() > 0)
m_zFlipped = false;
@@ -249,25 +286,36 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
backgroundRotation = 0.0f;
// Get light position from the scene
- QVector3D lightPos = m_cachedScene->activeLight()->position();
-
- // Map adjustment direction to model matrix scaling
- // TODO: Let's use these for testing the autoscaling of dots based on their number
- GLfloat heightMultiplier = m_dotSizeScale; //1.0f;
- GLfloat widthMultiplier = m_dotSizeScale; //1.0f;
- GLfloat depthMultiplier = m_dotSizeScale; //1.0f;
- GLfloat heightScaler = 0.0f;
- GLfloat widthScaler = 0.0f;
- GLfloat depthScaler = 0.0f;
- QVector3D modelScaler(widthMultiplier + widthScaler,
- heightMultiplier + heightScaler,
- depthMultiplier + depthScaler);
+ QVector3D lightPos = m_cachedScene->activeLight()->position();
+
// Introduce regardless of shadow quality to simplify logic
QMatrix4x4 depthViewMatrix;
QMatrix4x4 depthProjectionMatrix;
QMatrix4x4 depthProjectionViewMatrix;
+ // Check if we have any series with points
+ bool havePointSeries = false;
+ bool haveMeshSeries = false;
+ bool haveUniformColorMeshSeries = false;
+ bool haveGradientMeshSeries = false;
+ for (int i = 0; i < seriesCount; i++) {
+ if (m_visibleSeriesList.at(i).mesh() == QAbstract3DSeries::MeshPoint) {
+ havePointSeries = true;
+ } else {
+ haveMeshSeries = true;
+ if (m_visibleSeriesList.at(i).colorStyle() == Q3DTheme::ColorStyleUniform)
+ haveUniformColorMeshSeries = true;
+ else
+ haveGradientMeshSeries = true;
+ }
+ }
+
#if !defined(QT_OPENGL_ES_2)
+ if (havePointSeries) {
+ glEnable(GL_POINT_SMOOTH);
+ glEnable(GL_PROGRAM_POINT_SIZE);
+ }
+
if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) {
// Render scene into a depth texture for using with shadow mapping
// Bind depth shader
@@ -275,8 +323,8 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
// Set viewport for depth map rendering. Must match texture size. Larger values give smoother shadows.
glViewport(0, 0,
- m_mainViewPort.width() * m_shadowQualityMultiplier,
- m_mainViewPort.height() * m_shadowQualityMultiplier);
+ m_primarySubViewport.width() * m_shadowQualityMultiplier,
+ m_primarySubViewport.height() * m_shadowQualityMultiplier);
// Enable drawing to framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, m_depthFrameBuffer);
@@ -310,40 +358,61 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
depthProjectionViewMatrix = depthProjectionMatrix * depthViewMatrix;
// Draw dots to depth buffer
- for (int dot = 0; dot < m_renderItemArray.size(); dot++) {
- const ScatterRenderItem &item = m_renderItemArray.at(dot);
- if (!item.isVisible())
- continue;
+ for (int series = 0; series < seriesCount; series++) {
+ ObjectHelper *dotObj = m_visibleSeriesList.at(series).object();
+ bool drawingPoints = (m_visibleSeriesList.at(series).mesh() == QAbstract3DSeries::MeshPoint);
+
+ // TODO: Accessing series directly during rendering
+ float itemSize =
+ static_cast<QScatter3DSeries *>(m_visibleSeriesList.at(series).series())->itemSize()
+ / itemScaler;
+ if (itemSize == 0.0f)
+ itemSize = m_dotSizeScale;
+ if (drawingPoints) {
+ // Scale points based on shadow quality for shadows, not by zoom level
+ glPointSize(itemSize * 100.0f * m_shadowQualityMultiplier);
+ }
+ QVector3D modelScaler(itemSize, itemSize, itemSize);
- QMatrix4x4 modelMatrix;
- QMatrix4x4 MVPMatrix;
+ for (int dot = 0; dot < m_renderingArrays.at(series).size(); dot++) {
+ const ScatterRenderItem &item = m_renderingArrays.at(series).at(dot);
+ if (!item.isVisible())
+ continue;
- modelMatrix.translate(item.translation());
- modelMatrix.scale(modelScaler);
- //modelMatrix.scale(QVector3D(widthMultiplier * item.size() + widthScaler,
- // heightMultiplier * item.size() + heightScaler,
- // depthMultiplier * item.size() + depthScaler));
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
- MVPMatrix = depthProjectionViewMatrix * modelMatrix;
+ modelMatrix.translate(item.translation());
+ if (!drawingPoints)
+ modelMatrix.scale(modelScaler);
- m_depthShader->setUniformValue(m_depthShader->MVP(), MVPMatrix);
+ MVPMatrix = depthProjectionViewMatrix * modelMatrix;
- // 1st attribute buffer : vertices
- glEnableVertexAttribArray(m_depthShader->posAtt());
- glBindBuffer(GL_ARRAY_BUFFER, m_dotObj->vertexBuf());
- glVertexAttribPointer(m_depthShader->posAtt(), 3, GL_FLOAT, GL_FALSE, 0, (void *)0);
+ m_depthShader->setUniformValue(m_depthShader->MVP(), MVPMatrix);
- // Index buffer
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_dotObj->elementBuf());
+ if (drawingPoints) {
+ m_drawer->drawPoint(m_depthShader);
+ } else {
+ // 1st attribute buffer : vertices
+ glEnableVertexAttribArray(m_depthShader->posAtt());
+ glBindBuffer(GL_ARRAY_BUFFER, dotObj->vertexBuf());
+ glVertexAttribPointer(m_depthShader->posAtt(), 3, GL_FLOAT, GL_FALSE, 0,
+ (void *)0);
- // Draw the triangles
- glDrawElements(GL_TRIANGLES, m_dotObj->indexCount(), GL_UNSIGNED_SHORT, (void *)0);
+ // Index buffer
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, dotObj->elementBuf());
- // Free buffers
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
+ // Draw the triangles
+ glDrawElements(GL_TRIANGLES, dotObj->indexCount(), GL_UNSIGNED_SHORT,
+ (void *)0);
- glDisableVertexAttribArray(m_depthShader->posAtt());
+ // Free buffers
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ glDisableVertexAttribArray(m_depthShader->posAtt());
+ }
+ }
}
// Disable drawing to framebuffer (= enable drawing to screen)
@@ -352,12 +421,11 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
// Reset culling to normal
glCullFace(GL_BACK);
- // Release depth shader
- m_depthShader->release();
-
// Revert to original viewport
- glViewport(m_mainViewPort.x(), m_mainViewPort.y(),
- m_mainViewPort.width(), m_mainViewPort.height());
+ glViewport(m_primarySubViewport.x(),
+ m_primarySubViewport.y(),
+ m_primarySubViewport.width(),
+ m_primarySubViewport.height());
#if 0 // Use this if you want to see what is being drawn to the framebuffer
// You'll also have to comment out GL_COMPARE_R_TO_TEXTURE -line in texturehelper (if using it)
@@ -370,16 +438,18 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
m_labelShader->setUniformValue(m_labelShader->MVP(), MVPMatrix);
m_drawer->drawObject(m_labelShader, m_labelObj, m_depthTexture);
glDisable(GL_TEXTURE_2D);
- m_labelShader->release();
#endif
}
+
+ ShaderHelper *pointSelectionShader = m_selectionShader;
+#else
+ ShaderHelper *pointSelectionShader = m_pointShader;
#endif
+ ShaderHelper *selectionShader = m_selectionShader;
// Skip selection mode drawing if we have no selection mode
- if (m_cachedSelectionMode > QDataVis::SelectionModeNone) {
- // Bind selection shader
- m_selectionShader->bind();
-
+ if (m_cachedSelectionMode > QDataVis::SelectionNone
+ && SelectOnScene == m_selectionState && seriesCount > 0) {
// Draw dots to selection buffer
glBindFramebuffer(GL_FRAMEBUFFER, m_selectionFrameBuffer);
glEnable(GL_DEPTH_TEST); // Needed, otherwise the depth render buffer is not used
@@ -387,62 +457,101 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Needed for clearing the frame buffer
glDisable(GL_DITHER); // disable dithering, it may affect colors if enabled
- int arraySize = m_renderItemArray.size();
- if (arraySize > 0xfffffe) // Max possible different selection colors, 0xffffff being skipColor
- qFatal("Too many objects");
+ int arraySize = 0;
+ int totalArraySize = 0;
+ int dotNo = 0;
+
+ // Init previous to opposite of first to ensure we change binding for first series
+ bool previousDrawingPoints = (m_visibleSeriesList.at(0).mesh() != QAbstract3DSeries::MeshPoint);
+ for (int series = 0; series < seriesCount; series++) {
+ ObjectHelper *dotObj = m_visibleSeriesList.at(series).object();
+ bool drawingPoints = (m_visibleSeriesList.at(series).mesh() == QAbstract3DSeries::MeshPoint);
+
+ // TODO: Accessing series directly during rendering
+ float itemSize =
+ static_cast<QScatter3DSeries *>(m_visibleSeriesList.at(series).series())->itemSize()
+ / itemScaler;
+ if (itemSize == 0.0f)
+ itemSize = m_dotSizeScale;
+#if !defined(QT_OPENGL_ES_2)
+ if (drawingPoints)
+ glPointSize(itemSize * activeCamera->zoomLevel()); // Scale points based on zoom
+#endif
+ QVector3D modelScaler(itemSize, itemSize, itemSize);
- for (int dot = 0; dot < arraySize; dot++) {
- const ScatterRenderItem &item = m_renderItemArray.at(dot);
- if (!item.isVisible())
- continue;
+ // Rebind selection shader if it has changed
+ if (drawingPoints != previousDrawingPoints) {
+ previousDrawingPoints = drawingPoints;
+ if (drawingPoints)
+ selectionShader = pointSelectionShader;
+ else
+ selectionShader = m_selectionShader;
- QMatrix4x4 modelMatrix;
- QMatrix4x4 MVPMatrix;
+ selectionShader->bind();
+ }
+ arraySize = m_renderingArrays.at(series).size();
+ totalArraySize += arraySize;
- modelMatrix.translate(item.translation());
- modelMatrix.scale(modelScaler);
- //modelMatrix.scale(QVector3D(widthMultiplier * item.size() + widthScaler,
- // heightMultiplier * item.size() + heightScaler,
- // depthMultiplier * item.size() + depthScaler));
+ if (totalArraySize > 0xfffffe) // Max possible different selection colors, 0xffffff being skipColor
+ qFatal("Too many objects");
- MVPMatrix = projectionViewMatrix * modelMatrix;
+ for (int dot = 0; dot < arraySize; dot++) {
+ const ScatterRenderItem &item = m_renderingArrays.at(series).at(dot);
+ if (!item.isVisible())
+ continue;
- QVector3D dotColor = indexToSelectionColor(dot);
- dotColor /= 255.0f;
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+
+ modelMatrix.translate(item.translation());
+ if (!drawingPoints)
+ modelMatrix.scale(modelScaler);
+
+ MVPMatrix = projectionViewMatrix * modelMatrix;
- m_selectionShader->setUniformValue(m_selectionShader->MVP(), MVPMatrix);
- m_selectionShader->setUniformValue(m_selectionShader->color(), dotColor);
+ QVector3D dotColor = indexToSelectionColor(dotNo);
+ dotColor /= 255.0f;
- // 1st attribute buffer : vertices
- glEnableVertexAttribArray(m_selectionShader->posAtt());
- glBindBuffer(GL_ARRAY_BUFFER, m_dotObj->vertexBuf());
- glVertexAttribPointer(m_selectionShader->posAtt(), 3, GL_FLOAT, GL_FALSE, 0, (void *)0);
+ selectionShader->setUniformValue(selectionShader->MVP(), MVPMatrix);
+ selectionShader->setUniformValue(selectionShader->color(), dotColor);
- // Index buffer
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_dotObj->elementBuf());
+ if (drawingPoints) {
+ m_drawer->drawPoint(selectionShader);
+ } else {
+ // 1st attribute buffer : vertices
+ glEnableVertexAttribArray(selectionShader->posAtt());
+ glBindBuffer(GL_ARRAY_BUFFER, dotObj->vertexBuf());
+ glVertexAttribPointer(selectionShader->posAtt(), 3, GL_FLOAT, GL_FALSE, 0,
+ (void *)0);
- // Draw the triangles
- glDrawElements(GL_TRIANGLES, m_dotObj->indexCount(), GL_UNSIGNED_SHORT, (void *)0);
+ // Index buffer
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, dotObj->elementBuf());
- // Free buffers
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
+ // Draw the triangles
+ glDrawElements(GL_TRIANGLES, dotObj->indexCount(), GL_UNSIGNED_SHORT,
+ (void *)0);
- glDisableVertexAttribArray(m_selectionShader->posAtt());
+ // Free buffers
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ glDisableVertexAttribArray(selectionShader->posAtt());
+ }
+ dotNo++;
+ }
}
glEnable(GL_DITHER);
// Read color under cursor
- if (QDataVis::InputStateOnScene == m_controller->inputState()) {
- m_selection = Utils::getSelection(m_controller->inputPosition(),
- m_cachedBoundingRect.height());
- }
+ QVector3D clickedColor = Utils::getSelection(m_inputPosition,
+ m_viewport.height());
+ int clickedIndex = 0;
+ QScatter3DSeries *clickedSeries = 0;
+ selectionColorToSeriesAndIndex(clickedColor, clickedIndex, clickedSeries);
+ emit itemClicked(clickedIndex, clickedSeries);
glBindFramebuffer(GL_FRAMEBUFFER, defaultFboHandle);
- // Release selection shader
- m_selectionShader->release();
-
#if 0 // Use this if you want to see what is being drawn to the framebuffer
m_labelShader->bind();
glDisable(GL_DEPTH_TEST);
@@ -454,114 +563,189 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
m_labelShader->setUniformValue(m_labelShader->MVP(), MVPMatrix);
m_drawer->drawObject(m_labelShader, m_labelObj, m_selectionTexture);
glDisable(GL_TEXTURE_2D);
- m_labelShader->release();
#endif
}
- // Bind dot shader
- m_dotShader->bind();
-
- // Set unchanging shader bindings
- m_dotShader->setUniformValue(m_dotShader->lightP(), lightPos);
- m_dotShader->setUniformValue(m_dotShader->view(), viewMatrix);
- m_dotShader->setUniformValue(m_dotShader->ambientS(), m_cachedTheme.m_ambientStrength);
-
- // Enable texture
- glEnable(GL_TEXTURE_2D);
-
// Draw dots
+ ShaderHelper *dotShader = 0;
+ GLuint gradientTexture = 0;
bool dotSelectionFound = false;
- int selectedIndex;
- if (m_selection == selectionSkipColor) {
- selectedIndex = Scatter3DController::noSelectionIndex();
+ ScatterRenderItem *selectedItem(0);
+ int dotNo = 0;
+ QVector3D baseColor;
+ QVector3D dotColor;
+
+ bool previousDrawingPoints = false;
+ Q3DTheme::ColorStyle previousMeshColorStyle = Q3DTheme::ColorStyleUniform;
+ if (haveMeshSeries) {
+ // Set unchanging shader bindings
+ if (haveGradientMeshSeries) {
+ m_dotGradientShader->bind();
+ m_dotGradientShader->setUniformValue(m_dotGradientShader->lightP(), lightPos);
+ m_dotGradientShader->setUniformValue(m_dotGradientShader->view(), viewMatrix);
+ m_dotGradientShader->setUniformValue(m_dotGradientShader->ambientS(), m_cachedTheme->ambientLightStrength());
+ }
+ if (haveUniformColorMeshSeries) {
+ m_dotShader->bind();
+ m_dotShader->setUniformValue(m_dotShader->lightP(), lightPos);
+ m_dotShader->setUniformValue(m_dotShader->view(), viewMatrix);
+ m_dotShader->setUniformValue(m_dotShader->ambientS(), m_cachedTheme->ambientLightStrength());
+ dotShader = m_dotShader;
+ } else {
+ dotShader = m_dotGradientShader;
+ previousMeshColorStyle = Q3DTheme::ColorStyleRangeGradient;
+ m_dotGradientShader->setUniformValue(m_dotGradientShader->gradientHeight(), 0.0f);
+ }
+ glEnable(GL_TEXTURE_2D);
} else {
- selectedIndex = int(m_selection.x())
- + (int(m_selection.y()) << 8)
- + (int(m_selection.z()) << 16);
+ dotShader = pointSelectionShader;
+ previousDrawingPoints = true;
+ dotShader->bind();
}
- if (m_selection != m_previousSelection) {
- emit selectedItemIndexChanged(selectedIndex);
- m_previousSelection = m_selection;
- }
+ for (int series = 0; series < seriesCount; series++) {
+ const SeriesRenderCache &currentSeries = m_visibleSeriesList.at(series);
+ ObjectHelper *dotObj = currentSeries.object();
+ bool drawingPoints = (currentSeries.mesh() == QAbstract3DSeries::MeshPoint);
+ Q3DTheme::ColorStyle colorStyle = currentSeries.colorStyle();
+ bool colorStyleIsUniform = (colorStyle == Q3DTheme::ColorStyleUniform);
+ bool useColor = colorStyleIsUniform || drawingPoints;
+
+ // TODO: Accessing series directly during rendering
+ float itemSize =
+ static_cast<QScatter3DSeries *>(currentSeries.series())->itemSize()
+ / itemScaler;
+ if (itemSize == 0.0f)
+ itemSize = m_dotSizeScale;
+#if !defined(QT_OPENGL_ES_2)
+ if (drawingPoints)
+ glPointSize(itemSize * activeCamera->zoomLevel()); // Scale points based on zoom
+#endif
+ QVector3D modelScaler(itemSize, itemSize, itemSize);
+
+ // Rebind shader if it has changed
+ if (drawingPoints != previousDrawingPoints
+ || (!drawingPoints &&
+ (colorStyleIsUniform != (previousMeshColorStyle == Q3DTheme::ColorStyleUniform)))) {
+ previousDrawingPoints = drawingPoints;
+ if (drawingPoints) {
+ dotShader = pointSelectionShader;
+ } else {
+ if (colorStyleIsUniform)
+ dotShader = m_dotShader;
+ else
+ dotShader = m_dotGradientShader;
+ }
+ dotShader->bind();
+ }
- ScatterRenderItem *selectedItem(0);
+ if (!drawingPoints && !colorStyleIsUniform && previousMeshColorStyle != colorStyle) {
+ if (colorStyle == Q3DTheme::ColorStyleObjectGradient) {
+ m_dotGradientShader->setUniformValue(m_dotGradientShader->gradientMin(), 0.0f);
+ m_dotGradientShader->setUniformValue(m_dotGradientShader->gradientHeight(), 0.5f);
+ } else {
+ // Each ball is of uniform color according to its Y-coordinate
+ m_dotGradientShader->setUniformValue(m_dotGradientShader->gradientHeight(), 0.0f);
+ }
+ }
- QVector3D baseColor = Utils::vectorFromColor(m_cachedTheme.m_baseColor);
+ if (!drawingPoints)
+ previousMeshColorStyle = colorStyle;
- for (int dot = 0; dot < m_renderItemArray.size(); dot++) {
- ScatterRenderItem &item = m_renderItemArray[dot];
- if (!item.isVisible())
- continue;
+ if (useColor) {
+ baseColor = currentSeries.baseColor();
+ dotColor = baseColor;
+ }
- QMatrix4x4 modelMatrix;
- QMatrix4x4 MVPMatrix;
- QMatrix4x4 itModelMatrix;
+ int seriesSize = m_renderingArrays.at(series).size();
+ for (int dot = 0; dot < seriesSize; dot++) {
+ ScatterRenderItem &item = m_renderingArrays[series][dot];
+ if (!item.isVisible())
+ continue;
- modelMatrix.translate(item.translation());
- modelMatrix.scale(modelScaler);
- //modelMatrix.scale(QVector3D(widthMultiplier * item.size() + widthScaler,
- // heightMultiplier * item.size() + heightScaler,
- // depthMultiplier * item.size() + depthScaler));
- itModelMatrix.scale(modelScaler);
- //itModelMatrix.scale(QVector3D(widthMultiplier * item.size() + widthScaler,
- // heightMultiplier * item.size() + heightScaler,
- // depthMultiplier * item.size() + depthScaler));
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+ QMatrix4x4 itModelMatrix;
+ modelMatrix.translate(item.translation());
+ if (!drawingPoints) {
+ modelMatrix.scale(modelScaler);
+ itModelMatrix.scale(modelScaler);
+ }
#ifdef SHOW_DEPTH_TEXTURE_SCENE
- MVPMatrix = depthProjectionViewMatrix * modelMatrix;
-#else
- MVPMatrix = projectionViewMatrix * modelMatrix;
-#endif
-
-#if 0
- QVector3D heightColor =
- Utils::vectorFromColor(m_cachedTheme.m_heightColor) * item.translation().y();
-
- QVector3D dotColor = baseColor + heightColor;
+ MVPMatrix = depthProjectionViewMatrix * modelMatrix;
#else
- QVector3D dotColor = baseColor;
+ MVPMatrix = projectionViewMatrix * modelMatrix;
#endif
- GLfloat lightStrength = m_cachedTheme.m_lightStrength;
- if (m_cachedSelectionMode > QDataVis::SelectionModeNone && (selectedIndex == dot)) {
- dotColor = Utils::vectorFromColor(m_cachedTheme.m_highlightBarColor);
- lightStrength = m_cachedTheme.m_highlightLightStrength;
- // Insert data to ScatterRenderItem. We have no ownership, don't delete the previous one
- selectedItem = &item;
- dotSelectionFound = true;
- }
+ if (useColor)
+ dotColor = baseColor;
+ else
+ gradientTexture = currentSeries.baseGradientTexture();
- // Set shader bindings
- m_dotShader->setUniformValue(m_dotShader->model(), modelMatrix);
- m_dotShader->setUniformValue(m_dotShader->nModel(),
- itModelMatrix.inverted().transposed());
- m_dotShader->setUniformValue(m_dotShader->MVP(), MVPMatrix);
- m_dotShader->setUniformValue(m_dotShader->color(), dotColor);
+ GLfloat lightStrength = m_cachedTheme->lightStrength();
+ if (m_cachedSelectionMode > QDataVis::SelectionNone && (m_selectedItemTotalIndex == dotNo)) {
+ if (useColor)
+ dotColor = currentSeries.singleHighlightColor();
+ else
+ gradientTexture = currentSeries.singleHighlightGradientTexture();
+ lightStrength = m_cachedTheme->highlightLightStrength();
+ // Insert data to ScatterRenderItem. We have no ownership, don't delete the previous one
+ selectedItem = &item;
+ dotSelectionFound = true;
+ }
+ if (!drawingPoints) {
+ // Set shader bindings
+ dotShader->setUniformValue(dotShader->model(), modelMatrix);
+ dotShader->setUniformValue(dotShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ }
+ dotShader->setUniformValue(dotShader->MVP(), MVPMatrix);
+ if (useColor) {
+ dotShader->setUniformValue(dotShader->color(), dotColor);
+ } else if (colorStyle == Q3DTheme::ColorStyleRangeGradient) {
+ dotShader->setUniformValue(dotShader->gradientMin(),
+ (item.position().y() + 1.0f) / 2.0f);
+ }
#if !defined(QT_OPENGL_ES_2)
- if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) {
- // Set shadow shader bindings
- QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix;
- m_dotShader->setUniformValue(m_dotShader->shadowQ(), m_shadowQualityToShader);
- m_dotShader->setUniformValue(m_dotShader->depth(), depthMVPMatrix);
- m_dotShader->setUniformValue(m_dotShader->lightS(), lightStrength / 10.0f);
+ if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) {
+ if (!drawingPoints) {
+ // Set shadow shader bindings
+ QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix;
+ dotShader->setUniformValue(dotShader->shadowQ(), m_shadowQualityToShader);
+ dotShader->setUniformValue(dotShader->depth(), depthMVPMatrix);
+ dotShader->setUniformValue(dotShader->lightS(), lightStrength / 10.0f);
- // Draw the object
- m_drawer->drawObject(m_dotShader, m_dotObj, 0, m_depthTexture);
- } else
+ // Draw the object
+ m_drawer->drawObject(dotShader, dotObj, gradientTexture, m_depthTexture);
+ } else {
+ // Draw the object
+ m_drawer->drawPoint(dotShader);
+ }
+ } else
#endif
- {
- // Set shadowless shader bindings
- m_dotShader->setUniformValue(m_dotShader->lightS(), lightStrength);
-
- // Draw the object
- m_drawer->drawObject(m_dotShader, m_dotObj);
+ {
+ if (!drawingPoints) {
+ // Set shadowless shader bindings
+ dotShader->setUniformValue(dotShader->lightS(), lightStrength);
+ // Draw the object
+ m_drawer->drawObject(dotShader, dotObj, gradientTexture);
+ } else {
+ // Draw the object
+ m_drawer->drawPoint(dotShader);
+ }
+ }
+ dotNo++;
}
}
- // Release dot shader
- m_dotShader->release();
+#if !defined(QT_OPENGL_ES_2)
+ if (havePointSeries) {
+ glDisable(GL_POINT_SMOOTH);
+ glDisable(GL_PROGRAM_POINT_SIZE);
+ }
+#endif
// Bind background shader
m_backgroundShader->bind();
@@ -569,19 +753,23 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
glCullFace(GL_BACK);
// Draw background
- if (m_cachedIsBackgroundEnabled && m_backgroundObj) {
+ if (m_cachedTheme->isBackgroundEnabled() && m_backgroundObj) {
QMatrix4x4 modelMatrix;
QMatrix4x4 MVPMatrix;
QMatrix4x4 itModelMatrix;
#ifndef USE_UNIFORM_SCALING // Use this if we want to use autoscaling for x and z
- QVector3D bgScale((aspectRatio * backgroundMargin * m_areaSize.width()) / m_scaleFactor,
- backgroundMargin,
- (aspectRatio * backgroundMargin * m_areaSize.height()) / m_scaleFactor);
+ GLfloat xScale = (aspectRatio * m_backgroundMargin * m_areaSize.width()) / m_scaleFactor;
+ GLfloat zScale = (aspectRatio * m_backgroundMargin * m_areaSize.height()) / m_scaleFactor;
+ if (m_maxItemSize > xScale)
+ xScale = m_maxItemSize;
+ if (m_maxItemSize > zScale)
+ zScale = m_maxItemSize;
+ QVector3D bgScale(xScale, m_backgroundMargin, zScale);
#else // ..and this if we want uniform scaling based on largest dimension
- QVector3D bgScale((aspectRatio * backgroundMargin),
- backgroundMargin,
- (aspectRatio * backgroundMargin));
+ QVector3D bgScale((aspectRatio * m_backgroundMargin),
+ m_backgroundMargin,
+ (aspectRatio * m_backgroundMargin));
#endif
modelMatrix.scale(bgScale);
// If we're viewing from below, background object must be flipped
@@ -598,7 +786,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
#else
MVPMatrix = projectionViewMatrix * modelMatrix;
#endif
- QVector3D backgroundColor = Utils::vectorFromColor(m_cachedTheme.m_backgroundColor);
+ QVector3D backgroundColor = Utils::vectorFromColor(m_cachedTheme->backgroundColor());
// Set shader bindings
m_backgroundShader->setUniformValue(m_backgroundShader->lightP(), lightPos);
@@ -609,7 +797,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
m_backgroundShader->setUniformValue(m_backgroundShader->MVP(), MVPMatrix);
m_backgroundShader->setUniformValue(m_backgroundShader->color(), backgroundColor);
m_backgroundShader->setUniformValue(m_backgroundShader->ambientS(),
- m_cachedTheme.m_ambientStrength * 2.0f);
+ m_cachedTheme->ambientLightStrength() * 2.0f);
#if !defined(QT_OPENGL_ES_2)
if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) {
@@ -619,7 +807,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
m_shadowQualityToShader);
m_backgroundShader->setUniformValue(m_backgroundShader->depth(), depthMVPMatrix);
m_backgroundShader->setUniformValue(m_backgroundShader->lightS(),
- m_cachedTheme.m_lightStrength / 10.0f);
+ m_cachedTheme->lightStrength() / 10.0f);
// Draw the object
m_drawer->drawObject(m_backgroundShader, m_backgroundObj, 0, m_depthTexture);
@@ -628,16 +816,13 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
{
// Set shadowless shader bindings
m_backgroundShader->setUniformValue(m_backgroundShader->lightS(),
- m_cachedTheme.m_lightStrength);
+ m_cachedTheme->lightStrength());
// Draw the object
m_drawer->drawObject(m_backgroundShader, m_backgroundObj);
}
}
- // Release background shader
- m_backgroundShader->release();
-
// Disable textures
glDisable(GL_TEXTURE_2D);
@@ -650,37 +835,54 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
axisCacheMax = &m_axisCacheX;
#endif
- if (m_cachedIsGridEnabled && m_heightNormalizer) {
+ if (m_cachedTheme->isGridEnabled() && m_heightNormalizer) {
ShaderHelper *lineShader = m_backgroundShader;
// Bind line shader
lineShader->bind();
// Set unchanging shader bindings
- QVector3D lineColor = Utils::vectorFromColor(m_cachedTheme.m_gridLine);
+ QVector3D lineColor = Utils::vectorFromColor(m_cachedTheme->gridLineColor());
lineShader->setUniformValue(lineShader->lightP(), lightPos);
lineShader->setUniformValue(lineShader->view(), viewMatrix);
lineShader->setUniformValue(lineShader->color(), lineColor);
- lineShader->setUniformValue(lineShader->ambientS(), m_cachedTheme.m_ambientStrength);
+ lineShader->setUniformValue(lineShader->ambientS(), m_cachedTheme->ambientLightStrength());
#if !defined(QT_OPENGL_ES_2)
if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) {
// Set shadowed shader bindings
lineShader->setUniformValue(lineShader->shadowQ(), m_shadowQualityToShader);
lineShader->setUniformValue(lineShader->lightS(),
- m_cachedTheme.m_lightStrength / 20.0f);
+ m_cachedTheme->lightStrength() / 20.0f);
} else
#endif
{
// Set shadowless shader bindings
- lineShader->setUniformValue(lineShader->lightS(), m_cachedTheme.m_lightStrength / 2.5f);
+ lineShader->setUniformValue(lineShader->lightS(), m_cachedTheme->lightStrength() / 2.5f);
}
+ QQuaternion lineYRotation = QQuaternion();
+ QQuaternion lineXRotation = QQuaternion();
+
+ if (m_xFlipped)
+ lineYRotation = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, -90.0f);
+ else
+ lineYRotation = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, 90.0f);
+
+ if (m_yFlipped)
+ lineXRotation = QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, 90.0f);
+ else
+ lineXRotation = QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, -90.0f);
+
+ GLfloat yFloorLinePosition = -m_backgroundMargin + gridLineOffset;
+ if (m_yFlipped)
+ yFloorLinePosition = -yFloorLinePosition;
+
// Rows (= Z)
if (m_axisCacheZ.segmentCount() > 0) {
// Floor lines
#ifndef USE_UNIFORM_SCALING
GLfloat lineStep = aspectRatio * m_axisCacheZ.subSegmentStep();
- GLfloat linePos = -aspectRatio * m_axisCacheZ.min(); // Start line
+ GLfloat linePos = -aspectRatio * (m_axisCacheZ.min() - m_translationOffset.z()); // Start line
int lastSegment = m_axisCacheZ.subSegmentCount() * m_axisCacheZ.segmentCount();
#else
GLfloat lineStep = aspectRatio * axisCacheMax->subSegmentStep();
@@ -689,11 +891,12 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
#endif
#ifndef USE_UNIFORM_SCALING // Use this if we want to use autoscaling for x and z
- QVector3D gridLineScaler(
- (aspectRatio * backgroundMargin * m_areaSize.width()) / m_scaleFactor,
- gridLineWidth, gridLineWidth);
+ GLfloat xScale = (aspectRatio * m_backgroundMargin * m_areaSize.width()) / m_scaleFactor;
+ if (m_maxItemSize > xScale)
+ xScale = m_maxItemSize;
+ QVector3D gridLineScaler(xScale, gridLineWidth, gridLineWidth);
#else // ..and this if we want uniform scaling based on largest dimension
- QVector3D gridLineScaler((aspectRatio * backgroundMargin),
+ QVector3D gridLineScaler((aspectRatio * m_backgroundMargin),
gridLineWidth, gridLineWidth);
#endif
@@ -702,19 +905,13 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
QMatrix4x4 MVPMatrix;
QMatrix4x4 itModelMatrix;
- if (m_yFlipped)
- modelMatrix.translate(0.0f, backgroundMargin, linePos / m_scaleFactor);
- else
- modelMatrix.translate(0.0f, -backgroundMargin, linePos / m_scaleFactor);
+ modelMatrix.translate(0.0f, yFloorLinePosition, linePos / m_scaleFactor);
modelMatrix.scale(gridLineScaler);
itModelMatrix.scale(gridLineScaler);
- // If we're viewing from below, grid line object must be flipped
- if (m_yFlipped) {
- modelMatrix.rotate(180.0f, 1.0, 0.0, 0.0);
- itModelMatrix.rotate(180.0f, 1.0, 0.0, 0.0);
- }
+ modelMatrix.rotate(lineXRotation);
+ itModelMatrix.rotate(lineXRotation);
MVPMatrix = projectionViewMatrix * modelMatrix;
@@ -741,13 +938,15 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
}
// Side wall lines
- gridLineScaler = QVector3D(gridLineWidth, backgroundMargin, gridLineWidth);
+ gridLineScaler = QVector3D(gridLineWidth, m_backgroundMargin, gridLineWidth);
#ifndef USE_UNIFORM_SCALING
- GLfloat lineXTrans = (aspectRatio * backgroundMargin * m_areaSize.width())
- / m_scaleFactor;
- linePos = -aspectRatio * m_axisCacheZ.min(); // Start line
+ GLfloat lineXTrans = (aspectRatio * m_backgroundMargin * m_areaSize.width())
+ / m_scaleFactor - gridLineOffset;
+ if (m_maxItemSize > lineXTrans)
+ lineXTrans = m_maxItemSize - gridLineOffset;
+ linePos = -aspectRatio * (m_axisCacheZ.min() - m_translationOffset.z()); // Start line
#else
- GLfloat lineXTrans = aspectRatio * backgroundMargin;
+ GLfloat lineXTrans = aspectRatio * m_backgroundMargin - gridLineOffset;
linePos = -aspectRatio * m_scaleFactor; // Start line
#endif
if (!m_xFlipped)
@@ -759,9 +958,13 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
QMatrix4x4 itModelMatrix;
modelMatrix.translate(lineXTrans, 0.0f, linePos / m_scaleFactor);
+
modelMatrix.scale(gridLineScaler);
itModelMatrix.scale(gridLineScaler);
+ modelMatrix.rotate(lineYRotation);
+ itModelMatrix.rotate(lineYRotation);
+
MVPMatrix = projectionViewMatrix * modelMatrix;
// Set the rest of the shader bindings
@@ -792,17 +995,18 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
// Floor lines
#ifndef USE_UNIFORM_SCALING
GLfloat lineStep = aspectRatio * m_axisCacheX.subSegmentStep();
- GLfloat linePos = aspectRatio * m_axisCacheX.min();
+ GLfloat linePos = aspectRatio * (m_axisCacheX.min() - m_translationOffset.x());
int lastSegment = m_axisCacheX.subSegmentCount() * m_axisCacheX.segmentCount();
- QVector3D gridLineScaler(
- gridLineWidth, gridLineWidth,
- (aspectRatio * backgroundMargin * m_areaSize.height()) / m_scaleFactor);
+ GLfloat zScale = (aspectRatio * m_backgroundMargin * m_areaSize.height()) / m_scaleFactor;
+ if (m_maxItemSize > zScale)
+ zScale = m_maxItemSize;
+ QVector3D gridLineScaler(gridLineWidth, gridLineWidth, zScale);
#else
GLfloat lineStep = aspectRatio * axisCacheMax->subSegmentStep();
GLfloat linePos = -aspectRatio * m_scaleFactor;
int lastSegment = axisCacheMax->subSegmentCount() * axisCacheMax->segmentCount();
QVector3D gridLineScaler(gridLineWidth, gridLineWidth,
- aspectRatio * backgroundMargin);
+ aspectRatio * m_backgroundMargin);
#endif
for (int segment = 0; segment <= lastSegment; segment++) {
@@ -810,18 +1014,13 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
QMatrix4x4 MVPMatrix;
QMatrix4x4 itModelMatrix;
- if (m_yFlipped)
- modelMatrix.translate(linePos / m_scaleFactor, backgroundMargin, 0.0f);
- else
- modelMatrix.translate(linePos / m_scaleFactor, -backgroundMargin, 0.0f);
+ modelMatrix.translate(linePos / m_scaleFactor, yFloorLinePosition, 0.0f);
+
modelMatrix.scale(gridLineScaler);
itModelMatrix.scale(gridLineScaler);
- // If we're viewing from below, grid line object must be flipped
- if (m_yFlipped) {
- modelMatrix.rotate(180.0f, 1.0, 0.0, 0.0);
- itModelMatrix.rotate(180.0f, 1.0, 0.0, 0.0);
- }
+ modelMatrix.rotate(lineXRotation);
+ itModelMatrix.rotate(lineXRotation);
MVPMatrix = projectionViewMatrix * modelMatrix;
@@ -849,17 +1048,19 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
// Back wall lines
#ifndef USE_UNIFORM_SCALING
- GLfloat lineZTrans = (aspectRatio * backgroundMargin * m_areaSize.height())
- / m_scaleFactor;
- linePos = aspectRatio * m_axisCacheX.min();
+ GLfloat lineZTrans = (aspectRatio * m_backgroundMargin * m_areaSize.height())
+ / m_scaleFactor - gridLineOffset;
+ if (m_maxItemSize > lineZTrans)
+ lineZTrans = m_maxItemSize - gridLineOffset;
+ linePos = aspectRatio * (m_axisCacheX.min() - m_translationOffset.x());
#else
- GLfloat lineZTrans = aspectRatio * backgroundMargin;
+ GLfloat lineZTrans = aspectRatio * m_backgroundMargin - gridLineOffset;
linePos = -aspectRatio * m_scaleFactor;
#endif
if (!m_zFlipped)
lineZTrans = -lineZTrans;
- gridLineScaler = QVector3D(gridLineWidth, backgroundMargin, gridLineWidth);
+ gridLineScaler = QVector3D(gridLineWidth, m_backgroundMargin, gridLineWidth);
for (int segment = 0; segment <= lastSegment; segment++) {
QMatrix4x4 modelMatrix;
@@ -867,9 +1068,15 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
QMatrix4x4 itModelMatrix;
modelMatrix.translate(linePos / m_scaleFactor, 0.0f, lineZTrans);
+
modelMatrix.scale(gridLineScaler);
itModelMatrix.scale(gridLineScaler);
+ if (m_zFlipped) {
+ modelMatrix.rotate(180.0f, 1.0f, 0.0f, 0.0f);
+ itModelMatrix.rotate(180.0f, 1.0f, 0.0f, 0.0f);
+ }
+
MVPMatrix = projectionViewMatrix * modelMatrix;
// Set the rest of the shader bindings
@@ -899,18 +1106,21 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
if (m_axisCacheY.segmentCount() > 0) {
// Back wall
GLfloat lineStep = m_axisCacheY.subSegmentStep();
- GLfloat linePos = m_axisCacheY.min();
+ GLfloat linePos = m_axisCacheY.min() - m_translationOffset.y();
int lastSegment = m_axisCacheY.subSegmentCount() * m_axisCacheY.segmentCount();
#ifndef USE_UNIFORM_SCALING // Use this if we want to use autoscaling for x and z
- GLfloat lineZTrans = (aspectRatio * backgroundMargin * m_areaSize.height())
- / m_scaleFactor;
- QVector3D gridLineScaler(
- (aspectRatio * backgroundMargin * m_areaSize.width() / m_scaleFactor),
- gridLineWidth, gridLineWidth);
+ GLfloat lineZTrans = (aspectRatio * m_backgroundMargin * m_areaSize.height())
+ / m_scaleFactor - gridLineOffset;
+ if (m_maxItemSize > lineZTrans)
+ lineZTrans = m_maxItemSize - gridLineOffset;
+ GLfloat xScale = (aspectRatio * m_backgroundMargin * m_areaSize.width()) / m_scaleFactor;
+ if (m_maxItemSize > xScale)
+ xScale = m_maxItemSize;
+ QVector3D gridLineScaler(xScale, gridLineWidth, gridLineWidth);
#else // ..and this if we want uniform scaling based on largest dimension
- GLfloat lineZTrans = aspectRatio * backgroundMargin;
- QVector3D gridLineScaler((aspectRatio * backgroundMargin),
+ GLfloat lineZTrans = aspectRatio * m_backgroundMargin - gridLineOffset;
+ QVector3D gridLineScaler((aspectRatio * m_backgroundMargin),
gridLineWidth, gridLineWidth);
#endif
if (!m_zFlipped)
@@ -926,6 +1136,11 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
modelMatrix.scale(gridLineScaler);
itModelMatrix.scale(gridLineScaler);
+ if (m_zFlipped) {
+ modelMatrix.rotate(180.0f, 1.0f, 0.0f, 0.0f);
+ itModelMatrix.rotate(180.0f, 1.0f, 0.0f, 0.0f);
+ }
+
MVPMatrix = projectionViewMatrix * modelMatrix;
// Set the rest of the shader bindings
@@ -951,18 +1166,22 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
}
// Side wall
- linePos = m_axisCacheY.min();
+ linePos = m_axisCacheY.min() - m_translationOffset.y();
lastSegment = m_axisCacheY.subSegmentCount() * m_axisCacheY.segmentCount();
#ifndef USE_UNIFORM_SCALING // Use this if we want to use autoscaling for x and z
- GLfloat lineXTrans = (aspectRatio * backgroundMargin * m_areaSize.width())
+ GLfloat lineXTrans = (aspectRatio * m_backgroundMargin * m_areaSize.width())
+ / m_scaleFactor - gridLineOffset;
+ if (m_maxItemSize > lineXTrans)
+ lineXTrans = m_maxItemSize - gridLineOffset;
+ GLfloat zScale = (aspectRatio * m_backgroundMargin * m_areaSize.height())
/ m_scaleFactor;
- gridLineScaler = QVector3D(
- gridLineWidth, gridLineWidth,
- (aspectRatio * backgroundMargin * m_areaSize.height()) / m_scaleFactor);
+ if (m_maxItemSize > zScale)
+ zScale = m_maxItemSize;
+ gridLineScaler = QVector3D(gridLineWidth, gridLineWidth, zScale);
#else // ..and this if we want uniform scaling based on largest dimension
- GLfloat lineXTrans = aspectRatio * backgroundMargin;
+ GLfloat lineXTrans = aspectRatio * m_backgroundMargin - gridLineOffset;
gridLineScaler = QVector3D(gridLineWidth, gridLineWidth,
- aspectRatio * backgroundMargin);
+ aspectRatio * m_backgroundMargin);
#endif
if (!m_xFlipped)
lineXTrans = -lineXTrans;
@@ -977,6 +1196,9 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
modelMatrix.scale(gridLineScaler);
itModelMatrix.scale(gridLineScaler);
+ modelMatrix.rotate(lineYRotation);
+ itModelMatrix.rotate(lineYRotation);
+
MVPMatrix = projectionViewMatrix * modelMatrix;
// Set the rest of the shader bindings
@@ -1001,9 +1223,6 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
linePos += lineStep;
}
}
-
- // Release line shader
- lineShader->release();
}
// Draw axis labels
@@ -1015,23 +1234,26 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_POLYGON_OFFSET_FILL);
// Z Labels
if (m_axisCacheZ.segmentCount() > 0) {
#ifndef USE_UNIFORM_SCALING
GLfloat posStep = aspectRatio * m_axisCacheZ.segmentStep();
- GLfloat labelPos = -aspectRatio * m_axisCacheZ.min();
+ GLfloat labelPos = -aspectRatio * (m_axisCacheZ.min() - m_translationOffset.z());
int lastSegment = m_axisCacheZ.segmentCount();
- GLfloat labelXTrans = (aspectRatio * backgroundMargin * m_areaSize.width())
+ GLfloat labelXTrans = (aspectRatio * m_backgroundMargin * m_areaSize.width())
/ m_scaleFactor + labelMargin;
+ if (m_maxItemSize > labelXTrans)
+ labelXTrans = m_maxItemSize + labelMargin;
#else
GLfloat posStep = aspectRatio * axisCacheMax->segmentStep();
GLfloat labelPos = aspectRatio * m_scaleFactor;
int lastSegment = axisCacheMax->segmentCount();
- GLfloat labelXTrans = aspectRatio * backgroundMargin + labelMargin;
+ GLfloat labelXTrans = aspectRatio * m_backgroundMargin + labelMargin;
#endif
int labelNbr = 0;
- GLfloat labelYTrans = -backgroundMargin;
+ GLfloat labelYTrans = -m_backgroundMargin;
GLfloat rotLabelX = -90.0f;
GLfloat rotLabelY = 0.0f;
GLfloat rotLabelZ = 0.0f;
@@ -1057,6 +1279,8 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
#endif
labelTrans.setZ(labelPos / m_scaleFactor);
+ glPolygonOffset(GLfloat(segment) / -10.0f, 1.0f);
+
// Draw the label here
m_dummyRenderItem.setTranslation(labelTrans);
#ifndef USE_UNIFORM_SCALING
@@ -1078,18 +1302,20 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
if (m_axisCacheX.segmentCount() > 0) {
#ifndef USE_UNIFORM_SCALING
GLfloat posStep = aspectRatio * m_axisCacheX.segmentStep();
- GLfloat labelPos = aspectRatio * m_axisCacheX.min();
+ GLfloat labelPos = aspectRatio * (m_axisCacheX.min() - m_translationOffset.x());
int lastSegment = m_axisCacheX.segmentCount();
- GLfloat labelZTrans = (aspectRatio * backgroundMargin * m_areaSize.height())
+ GLfloat labelZTrans = (aspectRatio * m_backgroundMargin * m_areaSize.height())
/ m_scaleFactor + labelMargin;
+ if (m_maxItemSize > labelZTrans)
+ labelZTrans = m_maxItemSize + labelMargin;
#else
GLfloat posStep = aspectRatio * axisCacheMax->segmentStep();
GLfloat labelPos = -aspectRatio * m_scaleFactor;
int lastSegment = axisCacheMax->segmentCount();
- GLfloat labelZTrans = aspectRatio * backgroundMargin + labelMargin;
+ GLfloat labelZTrans = aspectRatio * m_backgroundMargin + labelMargin;
#endif
int labelNbr = 0;
- GLfloat labelYTrans = -backgroundMargin;
+ GLfloat labelYTrans = -m_backgroundMargin;
GLfloat rotLabelX = -90.0f;
GLfloat rotLabelY = 90.0f;
GLfloat rotLabelZ = 0.0f;
@@ -1115,6 +1341,8 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
#endif
labelTrans.setX(labelPos / m_scaleFactor);
+ glPolygonOffset(GLfloat(segment) / -10.0f, 1.0f);
+
// Draw the label here
m_dummyRenderItem.setTranslation(labelTrans);
#ifndef USE_UNIFORM_SCALING
@@ -1135,15 +1363,19 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
// Y Labels
if (m_axisCacheY.segmentCount() > 0) {
GLfloat posStep = m_axisCacheY.segmentStep();
- GLfloat labelPos = m_axisCacheY.min();
+ GLfloat labelPos = m_axisCacheY.min() - m_translationOffset.y();
int labelNbr = 0;
#ifndef USE_UNIFORM_SCALING // Use this if we want to use autoscaling for x and z
- GLfloat labelXTrans = (aspectRatio * backgroundMargin * m_areaSize.width())
+ GLfloat labelXTrans = (aspectRatio * m_backgroundMargin * m_areaSize.width())
/ m_scaleFactor;
- GLfloat labelZTrans = (aspectRatio * backgroundMargin * m_areaSize.height())
+ GLfloat labelZTrans = (aspectRatio * m_backgroundMargin * m_areaSize.height())
/ m_scaleFactor;
+ if (m_maxItemSize > labelXTrans)
+ labelXTrans = m_maxItemSize;
+ if (m_maxItemSize > labelZTrans)
+ labelZTrans = m_maxItemSize;
#else // ..and this if we want uniform scaling based on largest dimension
- GLfloat labelXTrans = aspectRatio * backgroundMargin;
+ GLfloat labelXTrans = aspectRatio * m_backgroundMargin;
GLfloat labelZTrans = labelXTrans;
#endif
// Back wall init
@@ -1185,6 +1417,8 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
const LabelItem &axisLabelItem = *m_axisCacheY.labelItems().at(labelNbr);
const GLfloat labelYTrans = labelPos / m_heightNormalizer;
+ glPolygonOffset(GLfloat(segment) / -10.0f, 1.0f);
+
// Back wall
labelTransBack.setY(labelYTrans);
m_dummyRenderItem.setTranslation(labelTransBack);
@@ -1205,6 +1439,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
labelPos += posStep;
}
}
+ glDisable(GL_POLYGON_OFFSET_FILL);
// Handle selection clearing and selection label drawing
if (!dotSelectionFound) {
@@ -1225,7 +1460,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
static const QString yLabelTag(QStringLiteral("@yLabel"));
static const QString zLabelTag(QStringLiteral("@zLabel"));
- labelText = itemLabelFormat();
+ labelText = m_visibleSeriesList[m_selectedItemSeriesIndex].itemLabelFormat();
labelText.replace(xTitleTag, m_axisCacheX.title());
labelText.replace(yTitleTag, m_axisCacheY.title());
@@ -1274,34 +1509,31 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
- // Release label shader
- m_labelShader->release();
-}
+ // Release shader
+ glUseProgram(0);
-void Scatter3DRenderer::updateSelectedItemIndex(int index)
-{
- if (index == Scatter3DController::noSelectionIndex())
- m_selection = selectionSkipColor;
- else
- m_selection = indexToSelectionColor(index);
+ m_selectionDirty = false;
}
-void Scatter3DRenderer::handleResize()
+void Scatter3DRenderer::updateSelectedItem(int index, const QScatter3DSeries *series)
{
- if (m_cachedBoundingRect.width() == 0 || m_cachedBoundingRect.height() == 0)
- return;
-
- // Set view port
- m_mainViewPort = QRect(0, 0, m_cachedBoundingRect.width(), m_cachedBoundingRect.height());
-
- Abstract3DRenderer::handleResize();
-}
-
-void Scatter3DRenderer::updateBackgroundEnabled(bool enable)
-{
- if (enable != m_cachedIsBackgroundEnabled) {
- Abstract3DRenderer::updateBackgroundEnabled(enable);
- loadMeshFile(); // Load changed dot type
+ m_selectionDirty = true;
+ m_selectedSeries = series;
+ m_selectedItemIndex = Scatter3DController::invalidSelectionIndex();
+ m_selectedItemTotalIndex = Scatter3DController::invalidSelectionIndex();
+ m_selectedItemSeriesIndex = Scatter3DController::invalidSelectionIndex();
+
+ if (!m_renderingArrays.isEmpty() && index != Scatter3DController::invalidSelectionIndex()) {
+ int totalIndex = 0;
+ for (int i = 0; i < m_visibleSeriesList.size(); i++) {
+ if (m_visibleSeriesList.at(i).series() == series) {
+ m_selectedItemSeriesIndex = i;
+ m_selectedItemIndex = index;
+ m_selectedItemTotalIndex = index + totalIndex;
+ break;
+ }
+ totalIndex += m_renderingArrays.at(i).size();
+ }
}
}
@@ -1347,15 +1579,6 @@ void Scatter3DRenderer::updateShadowQuality(QDataVis::ShadowQuality quality)
#endif
}
-void Scatter3DRenderer::loadMeshFile()
-{
- QString objectFileName = m_cachedObjFile;
- if (m_dotObj)
- delete m_dotObj;
- m_dotObj = new ObjectHelper(objectFileName);
- m_dotObj->load();
-}
-
void Scatter3DRenderer::loadBackgroundMesh()
{
if (m_backgroundObj)
@@ -1368,7 +1591,7 @@ void Scatter3DRenderer::loadGridLineMesh()
{
if (m_gridLineObj)
delete m_gridLineObj;
- m_gridLineObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/bar"));
+ m_gridLineObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/plane"));
m_gridLineObj->load();
}
@@ -1376,7 +1599,7 @@ void Scatter3DRenderer::loadLabelMesh()
{
if (m_labelObj)
delete m_labelObj;
- m_labelObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/label"));
+ m_labelObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/plane"));
m_labelObj->load();
}
@@ -1386,37 +1609,44 @@ void Scatter3DRenderer::updateTextures()
m_updateLabels = true;
}
+void Scatter3DRenderer::fixMeshFileName(QString &fileName, QAbstract3DSeries::Mesh mesh)
+{
+ // Load full version of meshes that have it available
+ if (mesh != QAbstract3DSeries::MeshSphere
+ && mesh != QAbstract3DSeries::MeshMinimal
+ && mesh != QAbstract3DSeries::MeshPoint) {
+ fileName.append(QStringLiteral("Full"));
+ }
+}
+
void Scatter3DRenderer::updateAxisRange(Q3DAbstractAxis::AxisOrientation orientation,
- qreal min, qreal max)
+ float min, float max)
{
Abstract3DRenderer::updateAxisRange(orientation, min, max);
}
void Scatter3DRenderer::calculateTranslation(ScatterRenderItem &item)
{
- // Origin should be in the center of scene, ie. both positive and negative values are drawn
- // above background
-
// We need to normalize translations
- GLfloat xTrans = (aspectRatio * item.position().x()) / m_scaleFactor;
- GLfloat zTrans = -(aspectRatio * item.position().z()) / m_scaleFactor;
- GLfloat yTrans = item.position().y() / m_heightNormalizer;
+ GLfloat xTrans = (aspectRatio * (item.position().x() - m_translationOffset.x()))
+ / m_scaleFactor;
+ GLfloat zTrans = -(aspectRatio * (item.position().z() - m_translationOffset.z()))
+ / m_scaleFactor;
+ GLfloat yTrans = (item.position().y() - m_translationOffset.y()) / m_heightNormalizer;
item.setTranslation(QVector3D(xTrans, yTrans, zTrans));
- //qDebug() << item.translation();
}
void Scatter3DRenderer::calculateSceneScalingFactors()
{
- m_heightNormalizer = (GLfloat)qMax(qAbs(m_axisCacheY.max()), qAbs(m_axisCacheY.min()));
- m_areaSize.setHeight(qMax(qAbs(m_axisCacheZ.max()), qAbs(m_axisCacheZ.min())));
- m_areaSize.setWidth(qMax(qAbs(m_axisCacheX.max()), qAbs(m_axisCacheX.min())));
+ m_heightNormalizer = GLfloat(m_axisCacheY.max() - m_axisCacheY.min()) / 2.0f;
+ m_areaSize.setHeight((m_axisCacheZ.max() - m_axisCacheZ.min()) / 2.0f);
+ m_areaSize.setWidth((m_axisCacheX.max() - m_axisCacheX.min()) / 2.0f);
m_scaleFactor = qMax(m_areaSize.width(), m_areaSize.height());
- //qDebug() << m_heightNormalizer << m_areaSize << m_scaleFactor << m_axisCacheY.max() << m_axisCacheX.max() << m_axisCacheZ.max();
-}
-QRect Scatter3DRenderer::mainViewPort()
-{
- return m_mainViewPort;
+ // Calculate translation offsets
+ m_translationOffset = QVector3D((m_axisCacheX.max() + m_axisCacheX.min()) / 2.0f,
+ (m_axisCacheY.max() + m_axisCacheY.min()) / 2.0f,
+ (m_axisCacheZ.max() + m_axisCacheZ.min()) / 2.0f);
}
void Scatter3DRenderer::initShaders(const QString &vertexShader, const QString &fragmentShader)
@@ -1427,12 +1657,20 @@ void Scatter3DRenderer::initShaders(const QString &vertexShader, const QString &
m_dotShader->initialize();
}
+void Scatter3DRenderer::initGradientShaders(const QString &vertexShader, const QString &fragmentShader)
+{
+ if (m_dotGradientShader)
+ delete m_dotGradientShader;
+ m_dotGradientShader = new ShaderHelper(this, vertexShader, fragmentShader);
+ m_dotGradientShader->initialize();
+}
+
void Scatter3DRenderer::initSelectionShader()
{
if (m_selectionShader)
delete m_selectionShader;
- m_selectionShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexSelection"),
- QStringLiteral(":/shaders/fragmentSelection"));
+ m_selectionShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexPlainColor"),
+ QStringLiteral(":/shaders/fragmentPlainColor"));
m_selectionShader->initialize();
}
@@ -1443,10 +1681,10 @@ void Scatter3DRenderer::initSelectionBuffer()
m_selectionTexture = 0;
}
- if (m_mainViewPort.size().isEmpty())
+ if (m_primarySubViewport.size().isEmpty())
return;
- m_selectionTexture = m_textureHelper->createSelectionTexture(m_mainViewPort.size(),
+ m_selectionTexture = m_textureHelper->createSelectionTexture(m_primarySubViewport.size(),
m_selectionFrameBuffer,
m_selectionDepthBuffer);
}
@@ -1468,52 +1706,26 @@ void Scatter3DRenderer::updateDepthBuffer()
m_depthTexture = 0;
}
- if (m_mainViewPort.size().isEmpty())
+ if (m_primarySubViewport.size().isEmpty())
return;
if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) {
- m_depthTexture = m_textureHelper->createDepthTexture(m_mainViewPort.size(),
- m_depthFrameBuffer,
- m_shadowQualityMultiplier);
- if (!m_depthTexture) {
- switch (m_cachedShadowQuality) {
- case QDataVis::ShadowQualityHigh:
- qWarning("Creating high quality shadows failed. Changing to medium quality.");
- (void)m_controller->setShadowQuality(QDataVis::ShadowQualityMedium);
- updateShadowQuality(QDataVis::ShadowQualityMedium);
- break;
- case QDataVis::ShadowQualityMedium:
- qWarning("Creating medium quality shadows failed. Changing to low quality.");
- (void)m_controller->setShadowQuality(QDataVis::ShadowQualityLow);
- updateShadowQuality(QDataVis::ShadowQualityLow);
- break;
- case QDataVis::ShadowQualityLow:
- qWarning("Creating low quality shadows failed. Switching shadows off.");
- (void)m_controller->setShadowQuality(QDataVis::ShadowQualityNone);
- updateShadowQuality(QDataVis::ShadowQualityNone);
- break;
- case QDataVis::ShadowQualitySoftHigh:
- qWarning("Creating soft high quality shadows failed. Changing to soft medium quality.");
- (void)m_controller->setShadowQuality(QDataVis::ShadowQualitySoftMedium);
- updateShadowQuality(QDataVis::ShadowQualitySoftMedium);
- break;
- case QDataVis::ShadowQualitySoftMedium:
- qWarning("Creating soft medium quality shadows failed. Changing to soft low quality.");
- (void)m_controller->setShadowQuality(QDataVis::ShadowQualitySoftLow);
- updateShadowQuality(QDataVis::ShadowQualitySoftLow);
- break;
- case QDataVis::ShadowQualitySoftLow:
- qWarning("Creating soft low quality shadows failed. Switching shadows off.");
- (void)m_controller->setShadowQuality(QDataVis::ShadowQualityNone);
- updateShadowQuality(QDataVis::ShadowQualityNone);
- break;
- default:
- // You'll never get here
- break;
- }
- }
+ m_depthTexture = m_textureHelper->createDepthTextureFrameBuffer(m_primarySubViewport.size(),
+ m_depthFrameBuffer,
+ m_shadowQualityMultiplier);
+ if (!m_depthTexture)
+ lowerShadowQuality();
}
}
+#else
+void Scatter3DRenderer::initPointShader()
+{
+ if (m_pointShader)
+ delete m_pointShader;
+ m_pointShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexPointES2"),
+ QStringLiteral(":/shaders/fragmentPlainColor"));
+ m_pointShader->initialize();
+}
#endif
void Scatter3DRenderer::initBackgroundShaders(const QString &vertexShader,
@@ -1542,4 +1754,26 @@ QVector3D Scatter3DRenderer::indexToSelectionColor(GLint index)
return QVector3D(dotIdxRed, dotIdxGreen, dotIdxBlue);
}
+void Scatter3DRenderer::selectionColorToSeriesAndIndex(const QVector3D &color, int &index, QScatter3DSeries *&series)
+{
+ if (color != selectionSkipColor) {
+ index = int(color.x())
+ + (int(color.y()) << 8)
+ + (int(color.z()) << 16);
+ // Find the series and adjust the index accordingly
+ for (int i = 0; i < m_renderingArrays.size(); i++) {
+ if (index < m_renderingArrays.at(i).size()) {
+ series = static_cast<QScatter3DSeries *>(m_visibleSeriesList.at(i).series());
+ return; // Valid found and already set to return parameters, so we can return
+ } else {
+ index -= m_renderingArrays.at(i).size();
+ }
+ }
+ }
+
+ // No valid match found
+ index = Scatter3DController::invalidSelectionIndex();
+ series = 0;
+}
+
QT_DATAVISUALIZATION_END_NAMESPACE