From 724bcb35136ed1af699fe8631b9297deb07571ad Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Tue, 18 Mar 2014 15:33:00 +0200 Subject: Actually use axis formatter in renderer. Task-number: QTRD-2787 Change-Id: I0ced8e506928df5fba2e8df94258b53457f4412e Reviewed-by: Mika Salmela --- .../engine/abstract3dcontroller.cpp | 13 +- .../engine/abstract3drenderer.cpp | 22 +- .../engine/abstract3drenderer_p.h | 2 +- src/datavisualization/engine/axisrendercache.cpp | 74 ++--- src/datavisualization/engine/axisrendercache_p.h | 43 ++- src/datavisualization/engine/bars3drenderer.cpp | 131 ++++---- src/datavisualization/engine/bars3drenderer_p.h | 2 +- .../engine/meshes/backgroundNegatives.obj | 6 +- src/datavisualization/engine/scatter3drenderer.cpp | 274 +++++++--------- src/datavisualization/engine/surface3drenderer.cpp | 359 ++++++++------------- src/datavisualization/engine/surface3drenderer_p.h | 8 +- .../engine/surfaceseriesrendercache.cpp | 8 +- .../engine/surfaceseriesrendercache_p.h | 9 +- 13 files changed, 396 insertions(+), 555 deletions(-) (limited to 'src/datavisualization/engine') diff --git a/src/datavisualization/engine/abstract3dcontroller.cpp b/src/datavisualization/engine/abstract3dcontroller.cpp index 2a8564a0..8ae9f790 100644 --- a/src/datavisualization/engine/abstract3dcontroller.cpp +++ b/src/datavisualization/engine/abstract3dcontroller.cpp @@ -19,7 +19,7 @@ #include "abstract3dcontroller_p.h" #include "camerahelper_p.h" #include "qabstract3daxis_p.h" -#include "qvalue3daxis.h" +#include "qvalue3daxis_p.h" #include "qcategory3daxis.h" #include "abstract3drenderer_p.h" #include "q3dcamera.h" @@ -967,13 +967,15 @@ void Abstract3DController::handleAxisLabelFormatChangedBySender(QObject *sender) void Abstract3DController::handleAxisFormatterDirtyBySender(QObject *sender) { - if (sender == m_axisX) { + // Sender is QValue3DAxisPrivate + QValue3DAxis *valueAxis = static_cast(sender)->qptr(); + if (valueAxis == m_axisX) { m_isDataDirty = true; m_changeTracker.axisXFormatterChanged = true; - } else if (sender == m_axisY) { + } else if (valueAxis == m_axisY) { m_isDataDirty = true; m_changeTracker.axisYFormatterChanged = true; - } else if (sender == m_axisZ) { + } else if (valueAxis == m_axisZ) { m_isDataDirty = true; m_changeTracker.axisZFormatterChanged = true; } else { @@ -1050,10 +1052,13 @@ void Abstract3DController::setAxisHelper(QAbstract3DAxis::AxisOrientation orient this, &Abstract3DController::handleAxisSubSegmentCountChanged); QObject::connect(valueAxis, &QValue3DAxis::labelFormatChanged, this, &Abstract3DController::handleAxisLabelFormatChanged); + QObject::connect(valueAxis->dptr(), &QValue3DAxisPrivate::formatterDirty, + this, &Abstract3DController::handleAxisFormatterDirty); handleAxisSegmentCountChangedBySender(valueAxis); handleAxisSubSegmentCountChangedBySender(valueAxis); handleAxisLabelFormatChangedBySender(valueAxis); + handleAxisFormatterDirtyBySender(valueAxis->dptr()); } } diff --git a/src/datavisualization/engine/abstract3drenderer.cpp b/src/datavisualization/engine/abstract3drenderer.cpp index 48453a82..c5e265aa 100644 --- a/src/datavisualization/engine/abstract3drenderer.cpp +++ b/src/datavisualization/engine/abstract3drenderer.cpp @@ -138,13 +138,13 @@ void Abstract3DRenderer::render(const GLuint defaultFboHandle) glDisable(GL_SCISSOR_TEST); } -QString Abstract3DRenderer::generateValueLabel(const QString &format, float value) -{ - QString valueLabelFormat = format; - Utils::ParamType valueParamType = Utils::findFormatParamType(valueLabelFormat); - QByteArray valueFormatArray = valueLabelFormat.toUtf8(); - return Utils::formatLabel(valueFormatArray, valueParamType, value); -} +//QString Abstract3DRenderer::generateValueLabel(const QString &format, float value) +//{ +// QString valueLabelFormat = format; +// Utils::ParamType valueParamType = Utils::findFormatParamType(valueLabelFormat); +// QByteArray valueFormatArray = valueLabelFormat.toUtf8(); +// return Utils::formatLabel(valueFormatArray, valueParamType, value); +//} void Abstract3DRenderer::updateSelectionState(SelectionState state) { @@ -318,13 +318,15 @@ void Abstract3DRenderer::updateAxisRange(QAbstract3DAxis::AxisOrientation orient void Abstract3DRenderer::updateAxisSegmentCount(QAbstract3DAxis::AxisOrientation orientation, int count) { - axisCacheForOrientation(orientation).setSegmentCount(count); + AxisRenderCache &cache = axisCacheForOrientation(orientation); + cache.setSegmentCount(count); } void Abstract3DRenderer::updateAxisSubSegmentCount(QAbstract3DAxis::AxisOrientation orientation, int count) { - axisCacheForOrientation(orientation).setSubSegmentCount(count); + AxisRenderCache &cache = axisCacheForOrientation(orientation); + cache.setSubSegmentCount(count); } void Abstract3DRenderer::updateAxisLabelFormat(QAbstract3DAxis::AxisOrientation orientation, @@ -342,7 +344,7 @@ void Abstract3DRenderer::updateAxisFormatter(QAbstract3DAxis::AxisOrientation or cache.setFormatter(formatter->createNewInstance()); cache.setCtrlFormatter(formatter); } - formatter->populateCopy(*(cache.formatter())); + formatter->d_ptr->populateCopy(*(cache.formatter())); } void Abstract3DRenderer::fixMeshFileName(QString &fileName, QAbstract3DSeries::Mesh mesh) diff --git a/src/datavisualization/engine/abstract3drenderer_p.h b/src/datavisualization/engine/abstract3drenderer_p.h index b198f004..f6415cca 100644 --- a/src/datavisualization/engine/abstract3drenderer_p.h +++ b/src/datavisualization/engine/abstract3drenderer_p.h @@ -60,7 +60,7 @@ protected: SelectOnSlice }; - QString generateValueLabel(const QString &format, float value); +// QString generateValueLabel(const QString &format, float value); public: virtual ~Abstract3DRenderer(); diff --git a/src/datavisualization/engine/axisrendercache.cpp b/src/datavisualization/engine/axisrendercache.cpp index bc0ab703..1b4fd52d 100644 --- a/src/datavisualization/engine/axisrendercache.cpp +++ b/src/datavisualization/engine/axisrendercache.cpp @@ -33,8 +33,9 @@ AxisRenderCache::AxisRenderCache() m_formatter(0), m_ctrlFormatter(0), m_drawer(0), - m_segmentStep(10.0f), - m_subSegmentStep(10.0f) + m_positionsDirty(true), + m_translate(0.0f), + m_scale(1.0f) { } @@ -73,8 +74,6 @@ void AxisRenderCache::setType(QAbstract3DAxis::AxisType type) foreach (LabelItem *label, m_labelItems) delete label; m_labelItems.clear(); - m_segmentStep = 10.0f; - m_subSegmentStep = 10.0f; } void AxisRenderCache::setTitle(const QString &title) @@ -114,28 +113,38 @@ void AxisRenderCache::setLabels(const QStringList &labels) } } -void AxisRenderCache::setMin(float min) +void AxisRenderCache::updateAllPositions() { - m_min = min; - updateSegmentStep(); -} - -void AxisRenderCache::setMax(float max) -{ - m_max = max; - updateSegmentStep(); -} - -void AxisRenderCache::setSegmentCount(int count) -{ - m_segmentCount = count; - updateSegmentStep(); -} + // As long as grid and subgrid lines are drawn identically, we can further optimize + // by caching all grid and subgrid positions into a single vector. + // If subgrid lines are ever themed separately, this array will probably become obsolete. + if (m_formatter) { + int subGridCount = m_subSegmentCount - 1; + int fullSize = m_segmentCount + 1 + (m_segmentCount * subGridCount); + m_adjustedGridLinePositions.resize(fullSize); + m_adjustedLabelPositions.resize(m_segmentCount + 1); + int index = 0; + int segment = 0; + for (; segment < m_segmentCount; segment++) { + m_adjustedLabelPositions[segment] = + m_formatter->labelPositions().at(segment) * m_scale + m_translate; + m_adjustedGridLinePositions[index++] = + m_formatter->gridPositions().at(segment) * m_scale + m_translate; + if (subGridCount > 0) { + for (int subGrid = 0; subGrid < subGridCount; subGrid++) { + m_adjustedGridLinePositions[index++] = + m_formatter->subGridPositions().at(segment).at(subGrid) * m_scale + m_translate; + } + } + } + // Last gridline + m_adjustedLabelPositions[segment] = + m_formatter->labelPositions().at(segment) * m_scale + m_translate; + m_adjustedGridLinePositions[index] = + m_formatter->gridPositions().at(segment) * m_scale + m_translate; -void AxisRenderCache::setSubSegmentCount(int count) -{ - m_subSegmentCount = count; - updateSubSegmentStep(); + m_positionsDirty = false; + } } void AxisRenderCache::updateTextures() @@ -157,23 +166,6 @@ void AxisRenderCache::updateTextures() } } -void AxisRenderCache::updateSegmentStep() -{ - if (m_segmentCount > 0) - m_segmentStep = qFabs((m_max - m_min) / m_segmentCount); - else - m_segmentStep = 0.0f; // Irrelevant - updateSubSegmentStep(); -} - -void AxisRenderCache::updateSubSegmentStep() -{ - if (m_subSegmentCount > 1) - m_subSegmentStep = m_segmentStep / m_subSegmentCount; - else - m_subSegmentStep = m_segmentStep; -} - int AxisRenderCache::maxLabelWidth(const QStringList &labels) const { int labelWidth = 0; diff --git a/src/datavisualization/engine/axisrendercache_p.h b/src/datavisualization/engine/axisrendercache_p.h index 5b48fbdf..eede9917 100644 --- a/src/datavisualization/engine/axisrendercache_p.h +++ b/src/datavisualization/engine/axisrendercache_p.h @@ -51,32 +51,48 @@ public: inline const QString &title() const { return m_title; } void setLabels(const QStringList &labels); inline const QStringList &labels() const { return m_labels; } - void setMin(float min); + inline void setMin(float min) { m_min = min; } inline float min() const { return m_min; } - void setMax(float max); + inline void setMax(float max) { m_max = max; } inline float max() const { return m_max; } - void setSegmentCount(int count); + inline void setSegmentCount(int count) { m_segmentCount = count; m_positionsDirty = true; } inline int segmentCount() const { return m_segmentCount; } - void setSubSegmentCount(int count); + inline void setSubSegmentCount(int count) { m_subSegmentCount = count; m_positionsDirty = true; } inline int subSegmentCount() const { return m_subSegmentCount; } inline void setLabelFormat(const QString &format) { m_labelFormat = format; } inline const QString &labelFormat() const { return m_labelFormat; } - inline void setFormatter(QValue3DAxisFormatter *formatter) { m_formatter = formatter; } + inline void setFormatter(QValue3DAxisFormatter *formatter) + { + m_formatter = formatter; m_positionsDirty = true; + } inline QValue3DAxisFormatter *formatter() const { return m_formatter; } - inline void setCtrlFormatter(const QValue3DAxisFormatter *formatter) { m_ctrlFormatter = formatter; } + inline void setCtrlFormatter(const QValue3DAxisFormatter *formatter) + { + m_ctrlFormatter = formatter; + } inline const QValue3DAxisFormatter *ctrlFormatter() const { return m_ctrlFormatter; } inline LabelItem &titleItem() { return m_titleItem; } inline QList &labelItems() { return m_labelItems; } - inline GLfloat segmentStep() const { return m_segmentStep; } - inline GLfloat subSegmentStep() const { return m_subSegmentStep; } + inline float gridLinePosition(int index) { return m_adjustedGridLinePositions.at(index); } + inline int gridLineCount() { return m_adjustedGridLinePositions.size(); } + inline float labelPosition(int index) { return m_adjustedLabelPositions.at(index); } + inline int labelCount() { return m_adjustedLabelPositions.size(); } + void updateAllPositions(); + inline bool positionsDirty() const { return m_positionsDirty; } + inline void setTranslate(float translate) { m_translate = translate; m_positionsDirty = true; } + inline float translate() { return m_translate; } + inline void setScale(float scale) { m_scale = scale; m_positionsDirty = true; } + inline float scale() { return m_scale; } + inline float positionAt(float value) + { + return m_formatter->positionAt(value) * m_scale + m_translate; + } public slots: void updateTextures(); private: - void updateSegmentStep(); - void updateSubSegmentStep(); int maxLabelWidth(const QStringList &labels) const; // Cached axis values @@ -96,8 +112,11 @@ private: Drawer *m_drawer; // Not owned LabelItem m_titleItem; QList m_labelItems; - GLfloat m_segmentStep; - GLfloat m_subSegmentStep; + QVector m_adjustedGridLinePositions; + QVector m_adjustedLabelPositions; + bool m_positionsDirty; + float m_translate; + float m_scale; Q_DISABLE_COPY(AxisRenderCache) }; diff --git a/src/datavisualization/engine/bars3drenderer.cpp b/src/datavisualization/engine/bars3drenderer.cpp index 3a685c91..f0a5e3d4 100644 --- a/src/datavisualization/engine/bars3drenderer.cpp +++ b/src/datavisualization/engine/bars3drenderer.cpp @@ -84,7 +84,7 @@ Bars3DRenderer::Bars3DRenderer(Bars3DController *controller) m_maxSceneSize(40.0f), m_visualSelectedBarPos(Bars3DController::invalidSelectionPosition()), m_visualSelectedBarSeriesIndex(-1), - m_hasHeightAdjustmentChanged(true), + m_resetCameraBaseOrientation(true), m_selectedBarPos(Bars3DController::invalidSelectionPosition()), m_selectedBarSeries(0), m_noZeroInRange(false), @@ -95,6 +95,8 @@ Bars3DRenderer::Bars3DRenderer(Bars3DController *controller) m_clickedPosition(Bars3DController::invalidSelectionPosition()), m_keepSeriesUniform(false) { + m_axisCacheY.setScale(2.0f); + initializeOpenGLFunctions(); initializeOpenGL(); } @@ -187,6 +189,8 @@ void Bars3DRenderer::updateData() calculateSceneScalingFactors(); } + const QValue3DAxisFormatter *axisFormatter = m_axisCacheY.formatter(); + float zeroPosition = axisFormatter->positionAt(0.0f); for (int series = 0; series < seriesCount; series++) { BarRenderItemArray &renderArray = m_renderingArrays[series]; if (newRows != renderArray.size() @@ -215,22 +219,22 @@ void Bars3DRenderer::updateData() int dataColIndex = minCol; for (; j < updateSize ; j++) { float value = dataRow->at(dataColIndex).value(); - if (!m_noZeroInRange) { - heightValue = GLfloat(value); - } else { - // Adjust height to range - if (!m_hasNegativeValues) { - heightValue = value - m_axisCacheY.min(); - if (heightValue < 0.0f) - heightValue = 0.0f; - } else if (m_axisCacheY.max() < 0.0f) { - heightValue = value - m_axisCacheY.max(); + heightValue = axisFormatter->positionAt(value); + if (m_noZeroInRange) { + if (m_hasNegativeValues) { + heightValue = -1.0f + heightValue; if (heightValue > 0.0f) heightValue = 0.0f; + } else { + if (heightValue < 0.0f) + heightValue = 0.0f; } + } else { + heightValue -= zeroPosition; } renderRow[j].setValue(value); - renderRow[j].setHeight(heightValue / m_heightNormalizer); + renderRow[j].setHeight(heightValue); + float angle = dataRow->at(dataColIndex).rotation(); if (angle) { renderRow[j].setRotation( @@ -263,12 +267,12 @@ void Bars3DRenderer::updateScene(Q3DScene *scene) else scene->activeCamera()->d_ptr->setMinYRotation(0.0f); - if (m_hasHeightAdjustmentChanged) { + if (m_resetCameraBaseOrientation) { // Set initial camera position. Also update if height adjustment has changed. scene->activeCamera()->d_ptr->setBaseOrientation(cameraDistanceVector, zeroVector, upVector); - m_hasHeightAdjustmentChanged = false; + m_resetCameraBaseOrientation = false; } Abstract3DRenderer::updateScene(scene); @@ -281,6 +285,9 @@ void Bars3DRenderer::render(GLuint defaultFboHandle) // Handle GL state setup for FBO buffers and clearing of the render surface Abstract3DRenderer::render(defaultFboHandle); + if (m_axisCacheY.positionsDirty()) + m_axisCacheY.updateAllPositions(); + drawScene(defaultFboHandle); if (m_cachedIsSlicingActivated) drawSlicedScene(); @@ -323,6 +330,7 @@ void Bars3DRenderer::drawSlicedScene() bool itemMode = m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionItem); GLfloat barPosYAdjustment = -0.8f; // Translate to -1.0 + 0.2 for row/column labels + GLfloat gridAdjustment = 1.0f + barPosYAdjustment - m_negativeBackgroundAdjustment; GLfloat scaleFactor = 0.0f; if (rowMode) scaleFactor = (1.1f * m_rowWidth) / m_scaleFactor; @@ -356,20 +364,18 @@ void Bars3DRenderer::drawSlicedScene() lineShader->setUniformValue(lineShader->lightS(), 0.0f); lineShader->setUniformValue(lineShader->lightColor(), lightColor); - GLfloat gridStep = (2.0f * m_axisCacheY.subSegmentStep()) / m_heightNormalizer; - GLfloat gridPos = barPosYAdjustment; - int lastSegment = m_axisCacheY.subSegmentCount() * m_axisCacheY.segmentCount(); - // Use the position of the bottom grid line as the base y position for bar labels - // Horizontal lines if (m_axisCacheY.segmentCount() > 0) { + int gridLineCount = m_axisCacheY.gridLineCount(); + QVector3D gridLineScale(scaleFactor, gridLineWidth, gridLineWidth); bool noZero = true; QMatrix4x4 MVPMatrix; QMatrix4x4 itModelMatrix; - for (int segment = 0; segment <= lastSegment; segment++) { + for (int line = 0; line < gridLineCount; line++) { QMatrix4x4 modelMatrix; + GLfloat gridPos = m_axisCacheY.gridLinePosition(line) + gridAdjustment; modelMatrix.translate(0.0f, gridPos, 0.0f); modelMatrix.scale(gridLineScale); itModelMatrix = modelMatrix; @@ -391,8 +397,6 @@ void Bars3DRenderer::drawSlicedScene() // Check if we have a line at zero position already if (gridPos == (barPosYAdjustment + zeroPosAdjustment)) noZero = false; - - gridPos += gridStep; } // Draw a line at zero, if none exists @@ -431,14 +435,13 @@ void Bars3DRenderer::drawSlicedScene() // Draw grid labels int labelNbr = 0; int labelCount = m_axisCacheY.labels().size(); - gridStep = (2.0f * m_axisCacheY.segmentStep()) / m_heightNormalizer; - gridPos = barPosYAdjustment; QVector3D backLabelRotation(0.0f, 0.0f, 0.0f); QVector3D labelTrans = QVector3D(scaleFactor + labelMargin, 0.0f, 0.0f); for (int i = 0; i < labelCount; i++) { if (m_axisCacheY.labelItems().size() > labelNbr) { const LabelItem &axisLabelItem = *m_axisCacheY.labelItems().at(labelNbr); + GLfloat gridPos = m_axisCacheY.labelPosition(i) + gridAdjustment; labelTrans.setY(gridPos); m_dummyBarRenderItem.setTranslation(labelTrans); m_drawer->drawLabel(m_dummyBarRenderItem, axisLabelItem, viewMatrix, @@ -447,7 +450,6 @@ void Bars3DRenderer::drawSlicedScene() activeCamera, true, true, Drawer::LabelMid, Qt::AlignRight); } labelNbr++; - gridPos += gridStep; } glDisable(GL_TEXTURE_2D); glDisable(GL_BLEND); @@ -645,8 +647,9 @@ void Bars3DRenderer::drawSlicedScene() if (item.height() != 0.0f || (!m_noZeroInRange && item.value() == 0.0f)) { // Create label texture if we need it if (item.sliceLabel().isNull() || m_updateLabels) { - item.setSliceLabel(generateValueLabel(m_axisCacheY.labelFormat(), - item.value())); + QString valueLabelText = m_axisCacheY.formatter()->stringForValue( + item.value(), m_axisCacheY.labelFormat()); + item.setSliceLabel(valueLabelText); m_drawer->generateLabelItem(item.sliceLabelItem(), item.sliceLabel()); m_updateLabels = false; } @@ -670,8 +673,9 @@ void Bars3DRenderer::drawSlicedScene() && item.seriesIndex() == m_visualSelectedBarSeriesIndex) { // Create label texture if we need it if (item.sliceLabel().isNull() || m_updateLabels) { - item.setSliceLabel(generateValueLabel(m_axisCacheY.labelFormat(), - item.value())); + QString valueLabelText = m_axisCacheY.formatter()->stringForValue( + item.value(), m_axisCacheY.labelFormat()); + item.setSliceLabel(valueLabelText); m_drawer->generateLabelItem(item.sliceLabelItem(), item.sliceLabel()); m_updateLabels = false; } @@ -1336,12 +1340,8 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) QMatrix4x4 itModelMatrix; QVector3D backgroundScaler(rowScaleFactor, 1.0f, columnScaleFactor); - if (m_hasNegativeValues) { - backgroundScaler.setY(0.5f); - modelMatrix.translate(0.0f, m_negativeBackgroundAdjustment, 0.0f); - } else { - modelMatrix.translate(0.0f, 1.0f, 0.0f); - } + modelMatrix.translate(0.0f, m_negativeBackgroundAdjustment, 0.0f); + modelMatrix.scale(backgroundScaler); itModelMatrix.scale(backgroundScaler); modelMatrix.rotate(backgroundRotation, 0.0f, 1.0f, 0.0f); @@ -1434,7 +1434,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) glDisable(GL_TEXTURE_2D); // Draw grid lines - if (m_cachedTheme->isGridEnabled() && m_heightNormalizer) { + if (m_cachedTheme->isGridEnabled()) { #if !(defined QT_OPENGL_ES_2) ShaderHelper *lineShader = m_backgroundShader; #else @@ -1559,30 +1559,20 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) if (m_axisCacheY.segmentCount() > 0) { // Wall lines: back wall - GLfloat heightStep = m_axisCacheY.subSegmentStep(); - GLfloat startLine = 0.0f; - int segmentCount = m_axisCacheY.segmentCount() * m_axisCacheY.subSegmentCount(); + int gridLineCount = m_axisCacheY.gridLineCount(); GLfloat zWallLinePosition = -columnScaleFactor + gridLineOffset; if (m_zFlipped) zWallLinePosition = -zWallLinePosition; - if (m_hasNegativeValues) { - if (m_noZeroInRange) - startLine = m_axisCacheY.min() - m_axisCacheY.max(); - else - startLine = m_axisCacheY.min(); - } - - GLfloat lineHeight = startLine; gridLineScaler = QVector3D(rowScaleFactor, gridLineWidth, gridLineWidth); - for (int segment = 0; segment <= segmentCount; segment++) { + for (int line = 0; line < gridLineCount; line++) { QMatrix4x4 modelMatrix; QMatrix4x4 MVPMatrix; QMatrix4x4 itModelMatrix; modelMatrix.translate(0.0f, - 2.0f * lineHeight / m_heightNormalizer, + m_axisCacheY.gridLinePosition(line), zWallLinePosition); modelMatrix.scale(gridLineScaler); itModelMatrix.scale(gridLineScaler); @@ -1613,7 +1603,6 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) #else m_drawer->drawLine(lineShader); #endif - lineHeight += heightStep; } // Wall lines: side wall @@ -1626,15 +1615,14 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) else lineRotation = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, 90.0f); - lineHeight = startLine; gridLineScaler = QVector3D(gridLineWidth, gridLineWidth, columnScaleFactor); - for (int segment = 0; segment <= segmentCount; segment++) { + for (int line = 0; line < gridLineCount; line++) { QMatrix4x4 modelMatrix; QMatrix4x4 MVPMatrix; QMatrix4x4 itModelMatrix; modelMatrix.translate(xWallLinePosition, - 2.0f * lineHeight / m_heightNormalizer, + m_axisCacheY.gridLinePosition(line), 0.0f); modelMatrix.scale(gridLineScaler); itModelMatrix.scale(gridLineScaler); @@ -1663,7 +1651,6 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) #else m_drawer->drawLine(lineShader); #endif - lineHeight += heightStep; } } } @@ -1678,16 +1665,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) // Y Labels int labelNbr = 0; - GLfloat heightStep = m_axisCacheY.segmentStep(); - GLfloat startLine = 0.0f; int labelCount = m_axisCacheY.labels().size(); - if (m_hasNegativeValues) { - if (m_noZeroInRange) - startLine = m_axisCacheY.min() - m_axisCacheY.max(); - else - startLine = m_axisCacheY.min(); - } - GLfloat labelPos = startLine; GLfloat labelMarginXTrans = labelMargin; GLfloat labelMarginZTrans = labelMargin; GLfloat labelXTrans = rowScaleFactor; @@ -1715,7 +1693,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) for (int i = 0; i < labelCount; i++) { if (m_axisCacheY.labelItems().size() > labelNbr) { - backLabelTrans.setY(2.0f * labelPos / m_heightNormalizer); + backLabelTrans.setY(m_axisCacheY.labelPosition(i)); sideLabelTrans.setY(backLabelTrans.y()); glPolygonOffset(GLfloat(i) / -10.0f, 1.0f); @@ -1737,7 +1715,6 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) true, true, Drawer::LabelMid, sideAlignment); } labelNbr++; - labelPos += heightStep; } // Calculate the positions for row and column labels and store them @@ -1844,9 +1821,9 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) static const QString seriesNameTag(QStringLiteral("@seriesName")); // Custom format expects printf format specifier. There is no tag for it. - labelText = generateValueLabel( - m_visibleSeriesList[m_visualSelectedBarSeriesIndex].itemLabelFormat(), - selectedBar->value()); + labelText = m_axisCacheY.formatter()->stringForValue( + selectedBar->value(), + m_visibleSeriesList[m_visualSelectedBarSeriesIndex].itemLabelFormat()); int selBarPosRow = selectedBar->position().x(); int selBarPosCol = selectedBar->position().y(); @@ -1865,10 +1842,8 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) labelText.replace(valueTitleTag, m_axisCacheY.title()); if (labelText.contains(valueLabelTag)) { - QString labelFormat = m_axisCacheY.labelFormat(); - if (labelFormat.isEmpty()) - labelFormat = Utils::defaultLabelFormat(); - QString valueLabelText = generateValueLabel(labelFormat, selectedBar->value()); + QString valueLabelText = m_axisCacheY.formatter()->stringForValue( + selectedBar->value(), m_axisCacheY.labelFormat()); labelText.replace(valueLabelTag, valueLabelText); } @@ -1945,7 +1920,6 @@ void Bars3DRenderer::updateAxisRange(QAbstract3DAxis::AxisOrientation orientatio Abstract3DRenderer::updateAxisRange(orientation, min, max); if (orientation == QAbstract3DAxis::AxisOrientationY) { - calculateHeightAdjustment(); // Check if we have negative values if (min < 0 && !m_hasNegativeValues) { m_hasNegativeValues = true; @@ -1958,6 +1932,7 @@ void Bars3DRenderer::updateAxisRange(QAbstract3DAxis::AxisOrientation orientatio loadBackgroundMesh(); emit needRender(); } + calculateHeightAdjustment(); } } @@ -2100,7 +2075,7 @@ void Bars3DRenderer::calculateSceneScalingFactors() void Bars3DRenderer::calculateHeightAdjustment() { - GLfloat newAdjustment = 0.0f; + GLfloat newAdjustment = 1.0f; GLfloat maxAbs = qFabs(m_axisCacheY.max()); if (m_axisCacheY.max() < 0.0f) { @@ -2111,7 +2086,8 @@ void Bars3DRenderer::calculateHeightAdjustment() } // Height fractions are used in gradient calculations and are therefore doubled - if (m_axisCacheY.max() < 0.0f || m_axisCacheY.min() > 0.0f) { + // Note that if max or min is exactly zero, we still consider it outside the range + if (m_axisCacheY.max() <= 0.0f || m_axisCacheY.min() >= 0.0f) { m_noZeroInRange = true; m_gradientFraction = 2.0f; } else { @@ -2121,11 +2097,12 @@ void Bars3DRenderer::calculateHeightAdjustment() } // Calculate translation adjustment for negative background - newAdjustment = qBound(0.0f, (maxAbs / m_heightNormalizer), 1.0f) * 2.0f - 0.5f; + if (m_hasNegativeValues) + newAdjustment = (qBound(0.0f, (maxAbs / m_heightNormalizer), 1.0f) - 0.5f) * 2.0f; if (newAdjustment != m_negativeBackgroundAdjustment) { - m_hasHeightAdjustmentChanged = true; m_negativeBackgroundAdjustment = newAdjustment; + m_axisCacheY.setTranslate(m_negativeBackgroundAdjustment - 1.0f); } } diff --git a/src/datavisualization/engine/bars3drenderer_p.h b/src/datavisualization/engine/bars3drenderer_p.h index 37ac2b76..2c0417e4 100644 --- a/src/datavisualization/engine/bars3drenderer_p.h +++ b/src/datavisualization/engine/bars3drenderer_p.h @@ -96,7 +96,7 @@ private: GLfloat m_maxSceneSize; QPoint m_visualSelectedBarPos; int m_visualSelectedBarSeriesIndex; - bool m_hasHeightAdjustmentChanged; + bool m_resetCameraBaseOrientation; QPoint m_selectedBarPos; const QBar3DSeries *m_selectedBarSeries; BarRenderItem m_dummyBarRenderItem; diff --git a/src/datavisualization/engine/meshes/backgroundNegatives.obj b/src/datavisualization/engine/meshes/backgroundNegatives.obj index d314e1fc..0b94617f 100644 --- a/src/datavisualization/engine/meshes/backgroundNegatives.obj +++ b/src/datavisualization/engine/meshes/backgroundNegatives.obj @@ -4,9 +4,9 @@ o Cube v 1.000000 1.000000 1.000000 v -1.000000 1.000000 1.000000 v -1.000000 1.000000 -1.000000 -v 1.000000 -3.000000 1.000000 -v -1.000000 -3.000000 1.000000 -v -1.000000 -3.000000 -1.000000 +v 1.000000 -1.000000 1.000000 +v -1.000000 -1.000000 1.000000 +v -1.000000 -1.000000 -1.000000 vt 0.000000 0.000000 vt 0.500000 0.000000 vt 0.500000 1.000000 diff --git a/src/datavisualization/engine/scatter3drenderer.cpp b/src/datavisualization/engine/scatter3drenderer.cpp index 38e48cc2..ae4b3831 100644 --- a/src/datavisualization/engine/scatter3drenderer.cpp +++ b/src/datavisualization/engine/scatter3drenderer.cpp @@ -48,7 +48,6 @@ const GLfloat aspectRatio = 2.0f; // Forced ratio of x and z to y. Dynamic will const GLfloat labelMargin = 0.05f; 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; @@ -90,10 +89,13 @@ Scatter3DRenderer::Scatter3DRenderer(Scatter3DController *controller) m_areaSize(QSizeF(0.0, 0.0)), m_dotSizeScale(1.0f), m_hasHeightAdjustmentChanged(true), - m_backgroundMargin(defaultMargin), + m_backgroundMargin(defaultMaxSize), m_maxItemSize(0.0f), m_clickedIndex(Scatter3DController::invalidSelectionIndex()) { + m_axisCacheY.setScale(2.0f); + m_axisCacheY.setTranslate(-1.0f); + initializeOpenGLFunctions(); initializeOpenGL(); } @@ -176,10 +178,11 @@ void Scatter3DRenderer::updateSeries(const QList &seriesLis if (m_cachedItemSize.at(series) != itemSize) m_cachedItemSize[series] = itemSize; } - m_backgroundMargin = defaultMargin; m_maxItemSize = maxItemSize; if (maxItemSize > defaultMaxSize) - m_backgroundMargin += maxItemSize / itemScaler; + m_backgroundMargin = maxItemSize / itemScaler; + else + m_backgroundMargin = defaultMaxSize; } void Scatter3DRenderer::updateData() @@ -255,6 +258,13 @@ void Scatter3DRenderer::render(GLuint defaultFboHandle) // Handle GL state setup for FBO buffers and clearing of the render surface Abstract3DRenderer::render(defaultFboHandle); + if (m_axisCacheX.positionsDirty()) + m_axisCacheX.updateAllPositions(); + if (m_axisCacheY.positionsDirty()) + m_axisCacheY.updateAllPositions(); + if (m_axisCacheZ.positionsDirty()) + m_axisCacheZ.updateAllPositions(); + // Draw dots scene drawScene(defaultFboHandle); } @@ -776,17 +786,17 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) QMatrix4x4 itModelMatrix; #ifndef USE_UNIFORM_SCALING // Use this if we want to use autoscaling for x and z - GLfloat xScale = (aspectRatio * m_backgroundMargin * m_areaSize.width()) / m_scaleFactor; - GLfloat zScale = (aspectRatio * m_backgroundMargin * m_areaSize.height()) / m_scaleFactor; + GLfloat xScale = (aspectRatio * m_areaSize.width()) / m_scaleFactor + m_backgroundMargin; + GLfloat zScale = (aspectRatio * m_areaSize.height()) / m_scaleFactor + m_backgroundMargin; if (m_maxItemSize > xScale) xScale = m_maxItemSize; if (m_maxItemSize > zScale) zScale = m_maxItemSize; - QVector3D bgScale(xScale, m_backgroundMargin, zScale); + QVector3D bgScale(xScale, 1.0f + m_backgroundMargin, zScale); #else // ..and this if we want uniform scaling based on largest dimension - QVector3D bgScale((aspectRatio * m_backgroundMargin), - m_backgroundMargin, - (aspectRatio * m_backgroundMargin)); + QVector3D bgScale((aspectRatio + m_backgroundMargin), + 1.0f + m_backgroundMargin, + (aspectRatio + m_backgroundMargin)); #endif modelMatrix.scale(bgScale); // If we're viewing from below, background object must be flipped @@ -845,15 +855,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) glDisable(GL_TEXTURE_2D); // Draw grid lines -#ifdef USE_UNIFORM_SCALING - AxisRenderCache *axisCacheMax; - if (m_axisCacheZ.max() > m_axisCacheX.max()) - axisCacheMax = &m_axisCacheZ; - else - axisCacheMax = &m_axisCacheX; -#endif - - if (m_cachedTheme->isGridEnabled() && m_heightNormalizer) { + if (m_cachedTheme->isGridEnabled()) { #if !(defined QT_OPENGL_ES_2) ShaderHelper *lineShader = m_backgroundShader; #else @@ -897,39 +899,31 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) else lineXRotation = QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, -90.0f); - GLfloat yFloorLinePosition = -m_backgroundMargin + gridLineOffset; + GLfloat yFloorLinePosition = -1.0f - 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() - m_translationOffset.z()); // Start line - int lastSegment = m_axisCacheZ.subSegmentCount() * m_axisCacheZ.segmentCount(); -#else - GLfloat lineStep = aspectRatio * axisCacheMax->subSegmentStep(); - GLfloat linePos = -aspectRatio * m_scaleFactor; // Start line - int lastSegment = axisCacheMax->subSegmentCount() * axisCacheMax->segmentCount(); -#endif + int gridLineCount = m_axisCacheZ.gridLineCount(); #ifndef USE_UNIFORM_SCALING // Use this if we want to use autoscaling for x and z - GLfloat xScale = (aspectRatio * m_backgroundMargin * m_areaSize.width()) / m_scaleFactor; + GLfloat xScale = (aspectRatio * m_areaSize.width()) / m_scaleFactor + m_backgroundMargin; 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 * m_backgroundMargin), + QVector3D gridLineScaler((aspectRatio + m_backgroundMargin), gridLineWidth, gridLineWidth); #endif - for (int segment = 0; segment <= lastSegment; segment++) { + for (int line = 0; line < gridLineCount; line++) { QMatrix4x4 modelMatrix; QMatrix4x4 MVPMatrix; QMatrix4x4 itModelMatrix; - modelMatrix.translate(0.0f, yFloorLinePosition, linePos / m_scaleFactor); + modelMatrix.translate(0.0f, yFloorLinePosition, m_axisCacheZ.gridLinePosition(line)); modelMatrix.scale(gridLineScaler); itModelMatrix.scale(gridLineScaler); @@ -959,30 +953,27 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) #else m_drawer->drawLine(lineShader); #endif - linePos -= lineStep; } // Side wall lines - gridLineScaler = QVector3D(gridLineWidth, m_backgroundMargin, gridLineWidth); + gridLineScaler = QVector3D(gridLineWidth, 1.0f + m_backgroundMargin, gridLineWidth); #ifndef USE_UNIFORM_SCALING - GLfloat lineXTrans = (aspectRatio * m_backgroundMargin * m_areaSize.width()) - / m_scaleFactor - gridLineOffset; + GLfloat lineXTrans = (aspectRatio * m_areaSize.width()) + / m_scaleFactor - gridLineOffset + m_backgroundMargin; if (m_maxItemSize > lineXTrans) lineXTrans = m_maxItemSize - gridLineOffset; - linePos = -aspectRatio * (m_axisCacheZ.min() - m_translationOffset.z()); // Start line #else - GLfloat lineXTrans = aspectRatio * m_backgroundMargin - gridLineOffset; - linePos = -aspectRatio * m_scaleFactor; // Start line + GLfloat lineXTrans = aspectRatio + m_backgroundMargin - gridLineOffset; #endif if (!m_xFlipped) lineXTrans = -lineXTrans; - for (int segment = 0; segment <= lastSegment; segment++) { + for (int line = 0; line < gridLineCount; line++) { QMatrix4x4 modelMatrix; QMatrix4x4 MVPMatrix; QMatrix4x4 itModelMatrix; - modelMatrix.translate(lineXTrans, 0.0f, linePos / m_scaleFactor); + modelMatrix.translate(lineXTrans, 0.0f, m_axisCacheZ.gridLinePosition(line)); modelMatrix.scale(gridLineScaler); itModelMatrix.scale(gridLineScaler); @@ -1017,7 +1008,6 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) #else m_drawer->drawLine(lineShader); #endif - linePos -= lineStep; } } @@ -1027,28 +1017,24 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) lineXRotation = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, 90.0f); #endif // Floor lines + int gridLineCount = m_axisCacheX.gridLineCount(); + #ifndef USE_UNIFORM_SCALING - GLfloat lineStep = aspectRatio * m_axisCacheX.subSegmentStep(); - GLfloat linePos = aspectRatio * (m_axisCacheX.min() - m_translationOffset.x()); - int lastSegment = m_axisCacheX.subSegmentCount() * m_axisCacheX.segmentCount(); - GLfloat zScale = (aspectRatio * m_backgroundMargin * m_areaSize.height()) / m_scaleFactor; + GLfloat zScale = (aspectRatio * m_areaSize.height()) / m_scaleFactor + m_backgroundMargin; 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 * m_backgroundMargin); + aspectRatio + m_backgroundMargin); #endif - for (int segment = 0; segment <= lastSegment; segment++) { + for (int line = 0; line < gridLineCount; line++) { QMatrix4x4 modelMatrix; QMatrix4x4 MVPMatrix; QMatrix4x4 itModelMatrix; - modelMatrix.translate(linePos / m_scaleFactor, yFloorLinePosition, 0.0f); + modelMatrix.translate(m_axisCacheX.gridLinePosition(line), yFloorLinePosition, 0.0f); modelMatrix.scale(gridLineScaler); itModelMatrix.scale(gridLineScaler); @@ -1078,31 +1064,28 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) #else m_drawer->drawLine(lineShader); #endif - linePos += lineStep; } // Back wall lines #ifndef USE_UNIFORM_SCALING - GLfloat lineZTrans = (aspectRatio * m_backgroundMargin * m_areaSize.height()) - / m_scaleFactor - gridLineOffset; + GLfloat lineZTrans = (aspectRatio * m_areaSize.height()) + / m_scaleFactor - gridLineOffset + m_backgroundMargin; if (m_maxItemSize > lineZTrans) lineZTrans = m_maxItemSize - gridLineOffset; - linePos = aspectRatio * (m_axisCacheX.min() - m_translationOffset.x()); #else - GLfloat lineZTrans = aspectRatio * m_backgroundMargin - gridLineOffset; - linePos = -aspectRatio * m_scaleFactor; + GLfloat lineZTrans = aspectRatio + m_backgroundMargin - gridLineOffset; #endif if (!m_zFlipped) lineZTrans = -lineZTrans; - gridLineScaler = QVector3D(gridLineWidth, m_backgroundMargin, gridLineWidth); + gridLineScaler = QVector3D(gridLineWidth, 1.0f + m_backgroundMargin, gridLineWidth); - for (int segment = 0; segment <= lastSegment; segment++) { + for (int line = 0; line < gridLineCount; line++) { QMatrix4x4 modelMatrix; QMatrix4x4 MVPMatrix; QMatrix4x4 itModelMatrix; - modelMatrix.translate(linePos / m_scaleFactor, 0.0f, lineZTrans); + modelMatrix.translate(m_axisCacheX.gridLinePosition(line), 0.0f, lineZTrans); modelMatrix.scale(gridLineScaler); itModelMatrix.scale(gridLineScaler); @@ -1139,40 +1122,37 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) #else m_drawer->drawLine(lineShader); #endif - linePos += lineStep; } } // Horizontal wall lines if (m_axisCacheY.segmentCount() > 0) { // Back wall - GLfloat lineStep = m_axisCacheY.subSegmentStep(); - GLfloat linePos = m_axisCacheY.min() - m_translationOffset.y(); - int lastSegment = m_axisCacheY.subSegmentCount() * m_axisCacheY.segmentCount(); + int gridLineCount = m_axisCacheY.gridLineCount(); #ifndef USE_UNIFORM_SCALING // Use this if we want to use autoscaling for x and z - GLfloat lineZTrans = (aspectRatio * m_backgroundMargin * m_areaSize.height()) - / m_scaleFactor - gridLineOffset; + GLfloat lineZTrans = (aspectRatio * m_areaSize.height()) + / m_scaleFactor - gridLineOffset + m_backgroundMargin; if (m_maxItemSize > lineZTrans) lineZTrans = m_maxItemSize - gridLineOffset; - GLfloat xScale = (aspectRatio * m_backgroundMargin * m_areaSize.width()) / m_scaleFactor; + GLfloat xScale = (aspectRatio * m_areaSize.width()) / m_scaleFactor + m_backgroundMargin; 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 * m_backgroundMargin - gridLineOffset; - QVector3D gridLineScaler((aspectRatio * m_backgroundMargin), + GLfloat lineZTrans = aspectRatio + m_backgroundMargin - gridLineOffset; + QVector3D gridLineScaler((aspectRatio + m_backgroundMargin), gridLineWidth, gridLineWidth); #endif if (!m_zFlipped) lineZTrans = -lineZTrans; - for (int segment = 0; segment <= lastSegment; segment++) { + for (int line = 0; line < gridLineCount; line++) { QMatrix4x4 modelMatrix; QMatrix4x4 MVPMatrix; QMatrix4x4 itModelMatrix; - modelMatrix.translate(0.0f, linePos / m_heightNormalizer, lineZTrans); + modelMatrix.translate(0.0f, m_axisCacheY.gridLinePosition(line), lineZTrans); modelMatrix.scale(gridLineScaler); itModelMatrix.scale(gridLineScaler); @@ -1204,36 +1184,33 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) #else m_drawer->drawLine(lineShader); #endif - linePos += lineStep; } // Side wall - 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 * m_backgroundMargin * m_areaSize.width()) - / m_scaleFactor - gridLineOffset; + GLfloat lineXTrans = (aspectRatio * m_areaSize.width()) + / m_scaleFactor - gridLineOffset + m_backgroundMargin; if (m_maxItemSize > lineXTrans) lineXTrans = m_maxItemSize - gridLineOffset; - GLfloat zScale = (aspectRatio * m_backgroundMargin * m_areaSize.height()) - / m_scaleFactor; + GLfloat zScale = (aspectRatio * m_areaSize.height()) + / m_scaleFactor + m_backgroundMargin; 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 * m_backgroundMargin - gridLineOffset; + GLfloat lineXTrans = aspectRatio + m_backgroundMargin - gridLineOffset; gridLineScaler = QVector3D(gridLineWidth, gridLineWidth, - aspectRatio * m_backgroundMargin); + aspectRatio + m_backgroundMargin); #endif if (!m_xFlipped) lineXTrans = -lineXTrans; - for (int segment = 0; segment <= lastSegment; segment++) { + for (int line = 0; line < gridLineCount; line++) { QMatrix4x4 modelMatrix; QMatrix4x4 MVPMatrix; QMatrix4x4 itModelMatrix; - modelMatrix.translate(lineXTrans, linePos / m_heightNormalizer, 0.0f); + modelMatrix.translate(lineXTrans, m_axisCacheY.gridLinePosition(line), 0.0f); modelMatrix.scale(gridLineScaler); itModelMatrix.scale(gridLineScaler); @@ -1263,13 +1240,11 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) #else m_drawer->drawLine(lineShader); #endif - linePos += lineStep; } } } // Draw axis labels - // Bind label shader m_labelShader->bind(); glEnable(GL_TEXTURE_2D); @@ -1279,22 +1254,17 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) // Z Labels if (m_axisCacheZ.segmentCount() > 0) { + int labelCount = m_axisCacheZ.labelItems().size(); #ifndef USE_UNIFORM_SCALING - GLfloat posStep = aspectRatio * m_axisCacheZ.segmentStep(); - GLfloat labelPos = -aspectRatio * (m_axisCacheZ.min() - m_translationOffset.z()); - int lastSegment = m_axisCacheZ.segmentCount(); - GLfloat labelXTrans = (aspectRatio * m_backgroundMargin * m_areaSize.width()) - / m_scaleFactor + labelMargin; + GLfloat labelXTrans = (aspectRatio * m_areaSize.width()) + / m_scaleFactor + labelMargin + m_backgroundMargin; 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 * m_backgroundMargin + labelMargin; + GLfloat labelXTrans = aspectRatio + m_backgroundMargin + labelMargin; #endif int labelNbr = 0; - GLfloat labelYTrans = -m_backgroundMargin; + GLfloat labelYTrans = -1.0f - m_backgroundMargin; GLfloat rotLabelX = -90.0f; GLfloat rotLabelY = 0.0f; GLfloat rotLabelZ = 0.0f; @@ -1312,23 +1282,15 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) } QVector3D labelRotateVector(rotLabelX, rotLabelY, rotLabelZ); QVector3D labelTrans = QVector3D(labelXTrans, labelYTrans, 0.0f); - for (int segment = 0; segment <= lastSegment; segment++) { -#ifndef USE_UNIFORM_SCALING // Use this if we want to use autoscaling for x and z + for (int label = 0; label < labelCount; label++) { if (m_axisCacheZ.labelItems().size() > labelNbr) { -#else // ..and this if we want uniform scaling based on largest dimension - if (axisCacheMax->labelItems().size() > labelNbr) { -#endif - labelTrans.setZ(labelPos / m_scaleFactor); + labelTrans.setZ(m_axisCacheZ.labelPosition(label)); - glPolygonOffset(GLfloat(segment) / -10.0f, 1.0f); + glPolygonOffset(GLfloat(label) / -10.0f, 1.0f); // Draw the label here m_dummyRenderItem.setTranslation(labelTrans); -#ifndef USE_UNIFORM_SCALING const LabelItem &axisLabelItem = *m_axisCacheZ.labelItems().at(labelNbr); -#else - const LabelItem &axisLabelItem = *axisCacheMax->labelItems().at(labelNbr); -#endif m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix, zeroVector, labelRotateVector, 0, m_cachedSelectionMode, @@ -1336,27 +1298,21 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) Drawer::LabelMid, alignment); } labelNbr++; - labelPos -= posStep; } } // X Labels if (m_axisCacheX.segmentCount() > 0) { + int labelCount = m_axisCacheX.labelItems().size(); #ifndef USE_UNIFORM_SCALING - GLfloat posStep = aspectRatio * m_axisCacheX.segmentStep(); - GLfloat labelPos = aspectRatio * (m_axisCacheX.min() - m_translationOffset.x()); - int lastSegment = m_axisCacheX.segmentCount(); - GLfloat labelZTrans = (aspectRatio * m_backgroundMargin * m_areaSize.height()) - / m_scaleFactor + labelMargin; + GLfloat labelZTrans = (aspectRatio * m_areaSize.height()) + / m_scaleFactor + labelMargin + m_backgroundMargin; 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 * m_backgroundMargin + labelMargin; + GLfloat labelZTrans = aspectRatio + m_backgroundMargin + labelMargin; #endif int labelNbr = 0; - GLfloat labelYTrans = -m_backgroundMargin; + GLfloat labelYTrans = -1.0f - m_backgroundMargin; GLfloat rotLabelX = -90.0f; GLfloat rotLabelY = 90.0f; GLfloat rotLabelZ = 0.0f; @@ -1374,23 +1330,15 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) } QVector3D labelRotateVector(rotLabelX, rotLabelY, rotLabelZ); QVector3D labelTrans = QVector3D(0.0f, labelYTrans, labelZTrans); - for (int segment = 0; segment <= lastSegment; segment++) { -#ifndef USE_UNIFORM_SCALING // Use this if we want to use autoscaling for x and z + for (int label = 0; label < labelCount; label++) { if (m_axisCacheX.labelItems().size() > labelNbr) { -#else // ..and this if we want uniform scaling based on largest dimension - if (axisCacheMax->labelItems().size() > labelNbr) { -#endif - labelTrans.setX(labelPos / m_scaleFactor); + labelTrans.setX(m_axisCacheX.labelPosition(label)); - glPolygonOffset(GLfloat(segment) / -10.0f, 1.0f); + glPolygonOffset(GLfloat(label) / -10.0f, 1.0f); // Draw the label here m_dummyRenderItem.setTranslation(labelTrans); -#ifndef USE_UNIFORM_SCALING const LabelItem &axisLabelItem = *m_axisCacheX.labelItems().at(labelNbr); -#else - const LabelItem &axisLabelItem = *axisCacheMax->labelItems().at(labelNbr); -#endif m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix, zeroVector, labelRotateVector, 0, m_cachedSelectionMode, @@ -1398,25 +1346,23 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) Drawer::LabelMid, alignment); } labelNbr++; - labelPos += posStep; } } // Y Labels if (m_axisCacheY.segmentCount() > 0) { - GLfloat posStep = m_axisCacheY.segmentStep(); - GLfloat labelPos = m_axisCacheY.min() - m_translationOffset.y(); + int labelCount = m_axisCacheY.labelItems().size(); int labelNbr = 0; #ifndef USE_UNIFORM_SCALING // Use this if we want to use autoscaling for x and z - GLfloat labelXTrans = (aspectRatio * m_backgroundMargin * m_areaSize.width()) - / m_scaleFactor; - GLfloat labelZTrans = (aspectRatio * m_backgroundMargin * m_areaSize.height()) - / m_scaleFactor; + GLfloat labelXTrans = (aspectRatio* m_areaSize.width()) + / m_scaleFactor + m_backgroundMargin; + GLfloat labelZTrans = (aspectRatio * m_areaSize.height()) + / m_scaleFactor + m_backgroundMargin; 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 * m_backgroundMargin; + GLfloat labelXTrans = aspectRatio + m_backgroundMargin; GLfloat labelZTrans = labelXTrans; #endif // Back wall init @@ -1453,12 +1399,12 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) QVector3D labelRotateVectorSide(rotLabelX, rotLabelY, rotLabelZ); QVector3D labelTransSide(-labelXTrans - labelMarginXTrans, 0.0f, -labelZTrans); - for (int segment = 0; segment <= m_axisCacheY.segmentCount(); segment++) { + for (int label = 0; label < labelCount; label++) { if (m_axisCacheY.labelItems().size() > labelNbr) { const LabelItem &axisLabelItem = *m_axisCacheY.labelItems().at(labelNbr); - const GLfloat labelYTrans = labelPos / m_heightNormalizer; + const GLfloat labelYTrans = m_axisCacheY.labelPosition(label); - glPolygonOffset(GLfloat(segment) / -10.0f, 1.0f); + glPolygonOffset(GLfloat(label) / -10.0f, 1.0f); // Back wall labelTransBack.setY(labelYTrans); @@ -1477,7 +1423,6 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) Drawer::LabelMid, alignmentSide); } labelNbr++; - labelPos += posStep; } } glDisable(GL_POLYGON_OFFSET_FILL); @@ -1509,30 +1454,22 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) labelText.replace(zTitleTag, m_axisCacheZ.title()); if (labelText.contains(xLabelTag)) { - QString labelFormat = m_axisCacheX.labelFormat(); - if (labelFormat.isEmpty()) - labelFormat = Utils::defaultLabelFormat(); - QString valueLabelText = generateValueLabel(labelFormat, - selectedItem->position().x()); + QString valueLabelText = m_axisCacheX.formatter()->stringForValue( + selectedItem->position().x(), m_axisCacheX.labelFormat()); labelText.replace(xLabelTag, valueLabelText); } if (labelText.contains(yLabelTag)) { - QString labelFormat = m_axisCacheY.labelFormat(); - if (labelFormat.isEmpty()) - labelFormat = Utils::defaultLabelFormat(); - QString valueLabelText = generateValueLabel(labelFormat, - selectedItem->position().y()); + QString valueLabelText = m_axisCacheY.formatter()->stringForValue( + selectedItem->position().y(), m_axisCacheY.labelFormat()); labelText.replace(yLabelTag, valueLabelText); } if (labelText.contains(zLabelTag)) { - QString labelFormat = m_axisCacheZ.labelFormat(); - if (labelFormat.isEmpty()) - labelFormat = Utils::defaultLabelFormat(); - QString valueLabelText = generateValueLabel(labelFormat, - selectedItem->position().z()); + QString valueLabelText = m_axisCacheZ.formatter()->stringForValue( + selectedItem->position().z(), m_axisCacheZ.labelFormat()); labelText.replace(zLabelTag, valueLabelText); } - labelText.replace(seriesNameTag, m_visibleSeriesList[m_selectedItemSeriesIndex].name()); + labelText.replace(seriesNameTag, + m_visibleSeriesList[m_selectedItemSeriesIndex].name()); setSelectionLabel(labelText); m_selectionLabelDirty = false; @@ -1671,11 +1608,10 @@ void Scatter3DRenderer::fixMeshFileName(QString &fileName, QAbstract3DSeries::Me void Scatter3DRenderer::calculateTranslation(ScatterRenderItem &item) { // We need to normalize translations - 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; + const QVector3D &pos = item.position(); + float xTrans = m_axisCacheX.positionAt(pos.x()); + float yTrans = m_axisCacheY.positionAt(pos.y()); + float zTrans = m_axisCacheZ.positionAt(pos.z()); item.setTranslation(QVector3D(xTrans, yTrans, zTrans)); } @@ -1686,10 +1622,16 @@ void Scatter3DRenderer::calculateSceneScalingFactors() m_areaSize.setWidth((m_axisCacheX.max() - m_axisCacheX.min()) / 2.0f); m_scaleFactor = qMax(m_areaSize.width(), m_areaSize.height()); - // 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); +#ifndef USE_UNIFORM_SCALING // Use this if we want to use autoscaling for x and z + float factorScaler = 2.0f * aspectRatio / m_scaleFactor; + m_axisCacheX.setScale(factorScaler * m_areaSize.width()); + m_axisCacheZ.setScale(-factorScaler * m_areaSize.height()); +#else // ..and this if we want uniform scaling based on largest dimension + m_axisCacheX.setScale(2.0f * aspectRatio); + m_axisCacheZ.setScale(-m_axisCacheX.scale()); +#endif + m_axisCacheX.setTranslate(-m_axisCacheX.scale() / 2.0f); + m_axisCacheZ.setTranslate(-m_axisCacheZ.scale() / 2.0f); } void Scatter3DRenderer::initShaders(const QString &vertexShader, const QString &fragmentShader) diff --git a/src/datavisualization/engine/surface3drenderer.cpp b/src/datavisualization/engine/surface3drenderer.cpp index 243c27de..ed99e49e 100644 --- a/src/datavisualization/engine/surface3drenderer.cpp +++ b/src/datavisualization/engine/surface3drenderer.cpp @@ -41,7 +41,8 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION //#define SHOW_DEPTH_TEXTURE_SCENE const GLfloat aspectRatio = 2.0f; // Forced ratio of x and z to y. Dynamic will make it look odd. -const GLfloat backgroundMargin = 1.1f; // Margin for background (1.1f = make it 10% larger to avoid items being drawn inside background) +const GLfloat backgroundMargin = 1.1f; // Margin for background (1.10 make it 10% larger to avoid + // selection ball being drawn inside background) const GLfloat labelMargin = 0.05f; const GLfloat gridLineWidth = 0.005f; const GLfloat sliceZScale = 0.1f; @@ -96,6 +97,9 @@ Surface3DRenderer::Surface3DRenderer(Surface3DController *controller) m_selectionTexturesDirty(false), m_noShadowTexture(0) { + m_axisCacheY.setScale(2.0f); + m_axisCacheY.setTranslate(-1.0f); + // Check if flat feature is supported ShaderHelper tester(this, QStringLiteral(":/shaders/vertexSurfaceFlat"), QStringLiteral(":/shaders/fragmentSurfaceFlat")); @@ -196,7 +200,7 @@ void Surface3DRenderer::updateData() // Need minimum of 2x2 array to draw a surface if (array.size() >= 2 && array.at(0)->size() >= 2) { - QRect sampleSpace = calculateSampleRect(cache, array); + QRect sampleSpace = calculateSampleRect(array); QSurfaceDataArray &dataArray = cache->dataArray(); bool dimensionChanged = false; @@ -259,7 +263,7 @@ void Surface3DRenderer::updateSeries(const QList &seriesLis QSurface3DSeries *surfaceSeries = static_cast(series); SurfaceSeriesRenderCache *cache = m_renderCacheList.value(surfaceSeries); if (!cache) { - cache = new SurfaceSeriesRenderCache; + cache = new SurfaceSeriesRenderCache(this); m_renderCacheList[surfaceSeries] = cache; m_selectionTexturesDirty = true; @@ -341,15 +345,10 @@ void Surface3DRenderer::updateRows(const QVector srcArray->at(row)->at(j + sampleSpace.x()); } - if (cache->isFlatShadingEnabled()) { - cache->surfaceObject()->updateCoarseRow(dstArray, row - sampleSpace.y(), - m_heightNormalizer, - m_axisCacheY.min()); - } else { - cache->surfaceObject()->updateSmoothRow(dstArray, row - sampleSpace.y(), - m_heightNormalizer, - m_axisCacheY.min()); - } + if (cache->isFlatShadingEnabled()) + cache->surfaceObject()->updateCoarseRow(dstArray, row - sampleSpace.y()); + else + cache->surfaceObject()->updateSmoothRow(dstArray, row - sampleSpace.y()); } if (updateBuffers) cache->surfaceObject()->uploadBuffers(); @@ -385,13 +384,10 @@ void Surface3DRenderer::updateItem(const QVectorat(point.y())->at(point.x()); - if (cache->isFlatShadingEnabled()) { - cache->surfaceObject()->updateCoarseItem(dstArray, y, x, m_heightNormalizer, - m_axisCacheY.min()); - } else { - cache->surfaceObject()->updateSmoothItem(dstArray, y, x, m_heightNormalizer, - m_axisCacheY.min()); - } + if (cache->isFlatShadingEnabled()) + cache->surfaceObject()->updateCoarseItem(dstArray, y, x); + else + cache->surfaceObject()->updateSmoothItem(dstArray, y, x); } if (updateBuffers) cache->surfaceObject()->uploadBuffers(); @@ -407,10 +403,17 @@ void Surface3DRenderer::updateAxisRange(QAbstract3DAxis::AxisOrientation orienta { Abstract3DRenderer::updateAxisRange(orientation, min, max); - if (orientation == QAbstract3DAxis::AxisOrientationY) { - foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) - cache->setObjectDirty(true); - } + foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) + cache->setObjectDirty(true); +} + +void Surface3DRenderer::updateAxisFormatter(QAbstract3DAxis::AxisOrientation orientation, + QValue3DAxisFormatter *formatter) +{ + Abstract3DRenderer::updateAxisFormatter(orientation, formatter); + + foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) + cache->setObjectDirty(true); } void Surface3DRenderer::updateSliceDataModel(const QPoint &point) @@ -556,19 +559,27 @@ void Surface3DRenderer::updateSliceObject(SurfaceSeriesRenderCache *cache, const QSurfaceDataRow *sliceRow; QSurfaceDataArray &dataArray = cache->dataArray(); float adjust = (0.025f * m_heightNormalizer) / 2.0f; - float stepDown = 2.0f * adjust; + float doubleAdjust = 2.0f * adjust; + bool flipZX = false; + float zBack; + float zFront; if (m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionRow)) { QSurfaceDataRow *src = dataArray.at(row); sliceRow = new QSurfaceDataRow(src->size()); + zBack = m_axisCacheZ.min(); + zFront = m_axisCacheZ.max(); for (int i = 0; i < sliceRow->size(); i++) - (*sliceRow)[i].setPosition(QVector3D(src->at(i).x(), src->at(i).y() + adjust, -1.0f)); + (*sliceRow)[i].setPosition(QVector3D(src->at(i).x(), src->at(i).y() + adjust, zFront)); } else { + flipZX = true; const QRect &sampleSpace = cache->sampleSpace(); sliceRow = new QSurfaceDataRow(sampleSpace.height()); + zBack = m_axisCacheX.min(); + zFront = m_axisCacheX.max(); for (int i = 0; i < sampleSpace.height(); i++) { (*sliceRow)[i].setPosition(QVector3D(dataArray.at(i)->at(column).z(), dataArray.at(i)->at(column).y() + adjust, - -1.0f)); + zFront)); } } sliceDataArray << sliceRow; @@ -577,27 +588,21 @@ void Surface3DRenderer::updateSliceObject(SurfaceSeriesRenderCache *cache, const QSurfaceDataRow *duplicateRow = new QSurfaceDataRow(*sliceRow); for (int i = 0; i < sliceRow->size(); i++) { (*sliceRow)[i].setPosition(QVector3D(sliceRow->at(i).x(), - sliceRow->at(i).y() - stepDown, - 1.0f)); + sliceRow->at(i).y() - doubleAdjust, + zBack)); } sliceDataArray << duplicateRow; QRect sliceRect(0, 0, sliceRow->size(), 2); if (sliceRow->size() > 0) { - if (cache->isFlatShadingEnabled()) { - cache->sliceSurfaceObject()->setUpData(sliceDataArray, sliceRect, - m_heightNormalizer, - m_axisCacheY.min(), true); - } else { - cache->sliceSurfaceObject()->setUpSmoothData(sliceDataArray, sliceRect, - m_heightNormalizer, - m_axisCacheY.min(), true); - } + if (cache->isFlatShadingEnabled()) + cache->sliceSurfaceObject()->setUpData(sliceDataArray, sliceRect, true, flipZX); + else + cache->sliceSurfaceObject()->setUpSmoothData(sliceDataArray, sliceRect, true, flipZX); } } -QRect Surface3DRenderer::calculateSampleRect(SurfaceSeriesRenderCache *cache, - const QSurfaceDataArray &array) +QRect Surface3DRenderer::calculateSampleRect(const QSurfaceDataArray &array) { QRect sampleSpace; @@ -673,17 +678,6 @@ QRect Surface3DRenderer::calculateSampleRect(SurfaceSeriesRenderCache *cache, m_visibleColumnRange = m_maxVisibleColumnValue - m_minVisibleColumnValue; m_visibleRowRange = m_maxVisibleRowValue - m_minVisibleRowValue; - GLfloat surfaceScaleX = m_scaleX * m_visibleColumnRange / m_areaSize.width(); - GLfloat surfaceScaleZ = m_scaleZ * m_visibleRowRange / m_areaSize.height(); - GLfloat axis2XCenterX = axisMinX + axisMaxX; - GLfloat axis2XCenterZ = axisMinZ + axisMaxZ; - GLfloat data2XCenterX = GLfloat(m_minVisibleColumnValue + m_maxVisibleColumnValue); - GLfloat data2XCenterZ = GLfloat(m_minVisibleRowValue + m_maxVisibleRowValue); - GLfloat surfaceOffsetX = m_scaleX * (data2XCenterX - axis2XCenterX) / m_areaSize.width(); - GLfloat surfaceOffsetZ = -m_scaleZ * (data2XCenterZ - axis2XCenterZ) / m_areaSize.height(); - - cache->setScale(QVector3D(surfaceScaleX, 1.0f, surfaceScaleZ)); - cache->setOffset(QVector3D(surfaceOffsetX, 0.0f, surfaceOffsetZ)); return sampleSpace; } @@ -714,6 +708,13 @@ void Surface3DRenderer::render(GLuint defaultFboHandle) // Handle GL state setup for FBO buffers and clearing of the render surface Abstract3DRenderer::render(defaultFboHandle); + if (m_axisCacheX.positionsDirty()) + m_axisCacheX.updateAllPositions(); + if (m_axisCacheY.positionsDirty()) + m_axisCacheY.updateAllPositions(); + if (m_axisCacheZ.positionsDirty()) + m_axisCacheZ.updateAllPositions(); + drawScene(defaultFboHandle); if (m_cachedIsSlicingActivated) drawSlicedScene(); @@ -766,6 +767,7 @@ void Surface3DRenderer::drawSlicedScene() const Q3DCamera *activeCamera = m_cachedScene->activeCamera(); bool rowMode = m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionRow); + AxisRenderCache &sliceCache = rowMode ? m_axisCacheX : m_axisCacheZ; GLfloat scaleXBackground = 0.0f; @@ -780,24 +782,16 @@ void Surface3DRenderer::drawSlicedScene() drawGrid = true; } - GLfloat scaleX = 0.0f; - GLfloat offset = 0.0f; - if (rowMode) { - scaleX = cache->scale().x(); + if (rowMode) scaleXBackground = m_scaleXWithBackground; - offset = cache->offset().x(); - } else { - scaleX = cache->scale().z(); + else scaleXBackground = m_scaleZWithBackground; - offset = -cache->offset().z(); - } QMatrix4x4 MVPMatrix; QMatrix4x4 modelMatrix; QMatrix4x4 itModelMatrix; - modelMatrix.translate(offset, 0.0f, 0.0f); - QVector3D scaling(scaleX, 1.0f, sliceZScale); + QVector3D scaling(1.0f, 1.0f, sliceZScale); modelMatrix.scale(scaling); itModelMatrix.scale(scaling); @@ -872,19 +866,16 @@ void Surface3DRenderer::drawSlicedScene() lineShader->setUniformValue(lineShader->lightColor(), lightColor); // Horizontal lines + int gridLineCount = m_axisCacheY.gridLineCount(); if (m_axisCacheY.segmentCount() > 0) { QVector3D gridLineScaleX(scaleXBackground, gridLineWidth, gridLineWidth); - GLfloat lineStep = 2.0f * m_axisCacheY.subSegmentStep() / m_heightNormalizer; - GLfloat linePos = -1.0f; - int lastSegment = m_axisCacheY.subSegmentCount() * m_axisCacheY.segmentCount(); - - for (int segment = 0; segment <= lastSegment; segment++) { + for (int line = 0; line < gridLineCount; line++) { QMatrix4x4 modelMatrix; QMatrix4x4 MVPMatrix; QMatrix4x4 itModelMatrix; - modelMatrix.translate(0.0f, linePos, -sliceZScale); + modelMatrix.translate(0.0f, m_axisCacheY.gridLinePosition(line), -1.0f); modelMatrix.scale(gridLineScaleX); itModelMatrix.scale(gridLineScaleX); @@ -903,33 +894,18 @@ void Surface3DRenderer::drawSlicedScene() #else m_drawer->drawLine(lineShader); #endif - - linePos += lineStep; } } // Vertical lines QVector3D gridLineScaleY(gridLineWidth, backgroundMargin, gridLineWidth); - int lastSegment; - GLfloat lineStep; - GLfloat linePos; - if (rowMode) { - lineStep = -2.0f * aspectRatio * m_axisCacheX.subSegmentStep() / m_scaleFactor; - lastSegment = m_axisCacheX.subSegmentCount() * m_axisCacheX.segmentCount(); - linePos = m_scaleX; - } else { - lineStep = -2.0f * aspectRatio * m_axisCacheZ.subSegmentStep() / m_scaleFactor; - lastSegment = m_axisCacheZ.subSegmentCount() * m_axisCacheZ.segmentCount(); - linePos = m_scaleZ; - } - - for (int segment = 0; segment <= lastSegment; segment++) { + for (int line = 0; line < gridLineCount; line++) { QMatrix4x4 modelMatrix; QMatrix4x4 MVPMatrix; QMatrix4x4 itModelMatrix; - modelMatrix.translate(linePos, 0.0f, -sliceZScale); + modelMatrix.translate(sliceCache.gridLinePosition(line), 0.0f, -1.0f); modelMatrix.scale(gridLineScaleY); itModelMatrix.scale(gridLineScaleY); #if (defined QT_OPENGL_ES_2) @@ -951,8 +927,6 @@ void Surface3DRenderer::drawSlicedScene() #else m_drawer->drawLine(lineShader); #endif - - linePos += lineStep; } } @@ -965,16 +939,15 @@ void Surface3DRenderer::drawSlicedScene() glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Y Labels to back wall - GLfloat posStep = 2.0f * m_axisCacheY.segmentStep() / m_heightNormalizer; - GLfloat labelPos = -1.0f; int labelNbr = 0; QVector3D positionComp(0.0f, 0.0f, 0.0f); QVector3D rotation(0.0f, 0.0f, 0.0f); - QVector3D labelTrans = QVector3D(scaleXBackground + labelMargin, labelPos, 0.0f); - for (int segment = 0; segment <= m_axisCacheY.segmentCount(); segment++) { + QVector3D labelTrans = QVector3D(scaleXBackground + labelMargin, 0.0f, 0.0f); + int labelCount = m_axisCacheY.labelCount(); + for (int label = 0; label < labelCount; label++) { if (m_axisCacheY.labelItems().size() > labelNbr) { - labelTrans.setY(labelPos); + labelTrans.setY(m_axisCacheY.labelPosition(label)); const LabelItem &axisLabelItem = *m_axisCacheY.labelItems().at(labelNbr); // Draw the label here @@ -985,40 +958,25 @@ void Surface3DRenderer::drawSlicedScene() true, true, Drawer::LabelMid, Qt::AlignRight, true); } labelNbr++; - labelPos += posStep; } // X Labels to ground - int countLabelItems; - int lastSegment; - if (rowMode) { - posStep = 2.0f * aspectRatio * m_axisCacheX.segmentStep() / m_scaleFactor; - labelPos = -m_scaleX; - lastSegment = m_axisCacheX.segmentCount(); - countLabelItems = m_axisCacheX.labelItems().size(); - } else { - posStep = 2.0f * aspectRatio * m_axisCacheZ.segmentStep() / m_scaleFactor; - labelPos = -m_scaleZ; - lastSegment = m_axisCacheZ.segmentCount(); - countLabelItems = m_axisCacheZ.labelItems().size(); - } + int countLabelItems = sliceCache.labelItems().size(); labelNbr = 0; positionComp.setY(-0.1f); rotation.setZ(-45.0f); labelTrans.setY(-backgroundMargin); - for (int segment = 0; segment <= lastSegment; segment++) { + labelCount = sliceCache.labelCount(); + for (int label = 0; label < labelCount; label++) { if (countLabelItems > labelNbr) { // Draw the label here - labelTrans.setX(labelPos); + labelTrans.setX(sliceCache.labelPosition(label)); m_dummyRenderItem.setTranslation(labelTrans); LabelItem *axisLabelItem; - if (rowMode) - axisLabelItem = m_axisCacheX.labelItems().at(labelNbr); - else - axisLabelItem = m_axisCacheZ.labelItems().at(labelNbr); + axisLabelItem = sliceCache.labelItems().at(labelNbr); m_drawer->drawLabel(m_dummyRenderItem, *axisLabelItem, viewMatrix, projectionMatrix, positionComp, rotation, 0, QAbstract3DGraph::SelectionRow, @@ -1026,23 +984,16 @@ void Surface3DRenderer::drawSlicedScene() false, false, Drawer::LabelBelow, Qt::AlignBottom, true); } labelNbr++; - labelPos += posStep; } // Draw labels for axes AbstractRenderItem *dummyItem(0); positionComp.setY(m_autoScaleAdjustment); - if (rowMode) { - m_drawer->drawLabel(*dummyItem, m_axisCacheX.titleItem(), viewMatrix, projectionMatrix, - positionComp, zeroVector, 0, m_cachedSelectionMode, m_labelShader, - m_labelObj, activeCamera, false, false, Drawer::LabelBottom, - Qt::AlignCenter, true); - } else { - m_drawer->drawLabel(*dummyItem, m_axisCacheZ.titleItem(), viewMatrix, projectionMatrix, - positionComp, zeroVector, 0, m_cachedSelectionMode, m_labelShader, - m_labelObj, activeCamera, false, false, Drawer::LabelBottom, - Qt::AlignCenter, true); - } + m_drawer->drawLabel(*dummyItem, sliceCache.titleItem(), viewMatrix, projectionMatrix, + positionComp, zeroVector, 0, m_cachedSelectionMode, m_labelShader, + m_labelObj, activeCamera, false, false, Drawer::LabelBottom, + Qt::AlignCenter, true); + // Y-axis label labelTrans = QVector3D(-scaleXBackground - labelMargin, 0.0f, 0.0f); m_dummyRenderItem.setTranslation(labelTrans); @@ -1150,8 +1101,6 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) QMatrix4x4 modelMatrix; QMatrix4x4 MVPMatrix; - modelMatrix.translate(cache->offset()); - modelMatrix.scale(cache->scale()); MVPMatrix = depthProjectionViewMatrix * modelMatrix; cache->setMVPMatrix(MVPMatrix); m_depthShader->setUniformValue(m_depthShader->MVP(), MVPMatrix); @@ -1244,9 +1193,6 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) QMatrix4x4 modelMatrix; QMatrix4x4 MVPMatrix; - modelMatrix.translate(cache->offset()); - modelMatrix.scale(cache->scale()); - MVPMatrix = projectionViewMatrix * modelMatrix; m_selectionShader->setUniformValue(m_selectionShader->MVP(), MVPMatrix); @@ -1293,10 +1239,6 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) QMatrix4x4 MVPMatrix; QMatrix4x4 itModelMatrix; - modelMatrix.translate(cache->offset()); - modelMatrix.scale(cache->scale()); - itModelMatrix.scale(cache->scale()); - #ifdef SHOW_DEPTH_TEXTURE_SCENE MVPMatrix = depthProjectionViewMatrix * modelMatrix; #else @@ -1508,16 +1450,14 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) // Rows (= Z) if (m_axisCacheZ.segmentCount() > 0) { // Floor lines - GLfloat lineStep = 2.0f * aspectRatio * m_axisCacheZ.subSegmentStep() / m_scaleFactor; - GLfloat linePos = m_scaleZ; // Start line - int lastSegment = m_axisCacheZ.subSegmentCount() * m_axisCacheZ.segmentCount(); + int gridLineCount = m_axisCacheZ.gridLineCount(); - for (int segment = 0; segment <= lastSegment; segment++) { + for (int line = 0; line < gridLineCount; line++) { QMatrix4x4 modelMatrix; QMatrix4x4 MVPMatrix; QMatrix4x4 itModelMatrix; - modelMatrix.translate(0.0f, yFloorLinePosition, linePos); + modelMatrix.translate(0.0f, yFloorLinePosition, m_axisCacheZ.gridLinePosition(line)); modelMatrix.scale(gridLineScaleX); itModelMatrix.scale(gridLineScaleX); @@ -1547,22 +1487,20 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) #else m_drawer->drawLine(lineShader); #endif - linePos -= lineStep; } // Side wall lines GLfloat lineXTrans = m_scaleXWithBackground - gridLineOffset; - linePos = m_scaleZ; // Start line if (!m_xFlipped) lineXTrans = -lineXTrans; - for (int segment = 0; segment <= lastSegment; segment++) { + for (int line = 0; line < gridLineCount; line++) { QMatrix4x4 modelMatrix; QMatrix4x4 MVPMatrix; QMatrix4x4 itModelMatrix; - modelMatrix.translate(lineXTrans, 0.0f, linePos); + modelMatrix.translate(lineXTrans, 0.0f, m_axisCacheZ.gridLinePosition(line)); modelMatrix.scale(gridLineScaleY); itModelMatrix.scale(gridLineScaleY); @@ -1597,7 +1535,6 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) #else m_drawer->drawLine(lineShader); #endif - linePos -= lineStep; } } @@ -1607,16 +1544,14 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) lineXRotation = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, 90.0f); #endif // Floor lines - GLfloat lineStep = -2.0f * aspectRatio * m_axisCacheX.subSegmentStep() / m_scaleFactor; - GLfloat linePos = m_scaleX; - int lastSegment = m_axisCacheX.subSegmentCount() * m_axisCacheX.segmentCount(); + int gridLineCount = m_axisCacheX.gridLineCount(); - for (int segment = 0; segment <= lastSegment; segment++) { + for (int line = 0; line < gridLineCount; line++) { QMatrix4x4 modelMatrix; QMatrix4x4 MVPMatrix; QMatrix4x4 itModelMatrix; - modelMatrix.translate(linePos, yFloorLinePosition, 0.0f); + modelMatrix.translate(m_axisCacheX.gridLinePosition(line), yFloorLinePosition, 0.0f); modelMatrix.scale(gridLineScaleZ); itModelMatrix.scale(gridLineScaleZ); @@ -1646,22 +1581,20 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) #else m_drawer->drawLine(lineShader); #endif - linePos += lineStep; } // Back wall lines GLfloat lineZTrans = m_scaleZWithBackground - gridLineOffset; - linePos = m_scaleX; if (!m_zFlipped) lineZTrans = -lineZTrans; - for (int segment = 0; segment <= lastSegment; segment++) { + for (int line = 0; line < gridLineCount; line++) { QMatrix4x4 modelMatrix; QMatrix4x4 MVPMatrix; QMatrix4x4 itModelMatrix; - modelMatrix.translate(linePos, 0.0f, lineZTrans); + modelMatrix.translate(m_axisCacheX.gridLinePosition(line), 0.0f, lineZTrans); modelMatrix.scale(gridLineScaleY); itModelMatrix.scale(gridLineScaleY); @@ -1698,28 +1631,25 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) #else m_drawer->drawLine(lineShader); #endif - linePos += lineStep; } } // Horizontal wall lines if (m_axisCacheY.segmentCount() > 0) { // Back wall - GLfloat lineStep = 2.0f * m_axisCacheY.subSegmentStep() / m_heightNormalizer; - GLfloat linePos = -1.0f; - int lastSegment = m_axisCacheY.subSegmentCount() * m_axisCacheY.segmentCount(); + int gridLineCount = m_axisCacheY.gridLineCount(); GLfloat lineZTrans = m_scaleZWithBackground - gridLineOffset; if (!m_zFlipped) lineZTrans = -lineZTrans; - for (int segment = 0; segment <= lastSegment; segment++) { + for (int line = 0; line < gridLineCount; line++) { QMatrix4x4 modelMatrix; QMatrix4x4 MVPMatrix; QMatrix4x4 itModelMatrix; - modelMatrix.translate(0.0f, linePos, lineZTrans); + modelMatrix.translate(0.0f, m_axisCacheY.gridLinePosition(line), lineZTrans); modelMatrix.scale(gridLineScaleX); itModelMatrix.scale(gridLineScaleX); @@ -1751,23 +1681,20 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) #else m_drawer->drawLine(lineShader); #endif - linePos += lineStep; } // Side wall - linePos = -1.0f; - lastSegment = m_axisCacheY.subSegmentCount() * m_axisCacheY.segmentCount(); GLfloat lineXTrans = m_scaleXWithBackground - gridLineOffset; if (!m_xFlipped) lineXTrans = -lineXTrans; - for (int segment = 0; segment <= lastSegment; segment++) { + for (int line = 0; line < gridLineCount; line++) { QMatrix4x4 modelMatrix; QMatrix4x4 MVPMatrix; QMatrix4x4 itModelMatrix; - modelMatrix.translate(lineXTrans, linePos, 0.0f); + modelMatrix.translate(lineXTrans, m_axisCacheY.gridLinePosition(line), 0.0f); modelMatrix.scale(gridLineScaleZ); itModelMatrix.scale(gridLineScaleZ); @@ -1797,7 +1724,6 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) #else m_drawer->drawLine(lineShader); #endif - linePos += lineStep; } } } @@ -1812,9 +1738,7 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) // Z Labels QVector3D positionZComp(0.0f, 0.0f, 0.0f); if (m_axisCacheZ.segmentCount() > 0) { - GLfloat posStep = 2.0f * aspectRatio * m_axisCacheZ.segmentStep() / m_scaleFactor; - GLfloat labelPos = m_scaleZ; - int lastSegment = m_axisCacheZ.segmentCount(); + int labelCount = m_axisCacheZ.labelItems().size(); int labelNbr = 0; GLfloat labelXTrans = m_scaleXWithBackground + labelMargin; GLfloat labelYTrans = -backgroundMargin; @@ -1835,14 +1759,14 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) } QVector3D labelTrans = QVector3D(labelXTrans, labelYTrans, - labelPos); + 0.0f); QVector3D rotation(rotLabelX, rotLabelY, rotLabelZ); - for (int segment = 0; segment <= lastSegment; segment++) { + for (int label = 0; label < labelCount; label++) { if (m_axisCacheZ.labelItems().size() > labelNbr) { - glPolygonOffset(GLfloat(segment) / -10.0f, 1.0f); + glPolygonOffset(GLfloat(label) / -10.0f, 1.0f); // Draw the label here - labelTrans.setZ(labelPos); + labelTrans.setZ(m_axisCacheZ.labelPosition(label)); m_dummyRenderItem.setTranslation(labelTrans); const LabelItem &axisLabelItem = *m_axisCacheZ.labelItems().at(labelNbr); @@ -1852,14 +1776,11 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) true, true, Drawer::LabelMid, alignment); } labelNbr++; - labelPos -= posStep; } } // X Labels if (m_axisCacheX.segmentCount() > 0) { - GLfloat posStep = 2.0f * aspectRatio * m_axisCacheX.segmentStep() / m_scaleFactor; - GLfloat labelPos = -m_scaleX; - int lastSegment = m_axisCacheX.segmentCount(); + int labelCount = m_axisCacheX.labelItems().size(); int labelNbr = 0; GLfloat labelZTrans = m_scaleZWithBackground + labelMargin; @@ -1879,16 +1800,16 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) rotLabelY += 180.0f; labelYTrans = -labelYTrans; } - QVector3D labelTrans = QVector3D(labelPos, + QVector3D labelTrans = QVector3D(0.0f, labelYTrans, labelZTrans); QVector3D rotation(rotLabelX, rotLabelY, rotLabelZ); - for (int segment = 0; segment <= lastSegment; segment++) { + for (int label = 0; label < labelCount; label++) { if (m_axisCacheX.labelItems().size() > labelNbr) { - glPolygonOffset(GLfloat(segment) / -10.0f, 1.0f); + glPolygonOffset(GLfloat(label) / -10.0f, 1.0f); // Draw the label here - labelTrans.setX(labelPos); + labelTrans.setX(m_axisCacheX.labelPosition(label)); m_dummyRenderItem.setTranslation(labelTrans); const LabelItem &axisLabelItem = *m_axisCacheX.labelItems().at(labelNbr); @@ -1898,13 +1819,12 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) true, true, Drawer::LabelMid, alignment); } labelNbr++; - labelPos += posStep; } } // Y Labels if (m_axisCacheY.segmentCount() > 0) { - GLfloat posStep = 2.0f * m_axisCacheY.segmentStep() / m_heightNormalizer; - GLfloat labelPos = -1.0f; + int labelCount = m_axisCacheY.labelItems().size(); + int labelNbr = 0; GLfloat labelXTrans = m_scaleXWithBackground; GLfloat labelZTrans = m_scaleZWithBackground; @@ -1943,14 +1863,15 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) QVector3D labelRotateVectorSide(rotLabelX, rotLabelY, rotLabelZ); QVector3D labelTransSide(-labelXTrans - labelMarginXTrans, 0.0f, -labelZTrans); - for (int segment = 0; segment <= m_axisCacheY.segmentCount(); segment++) { + for (int label = 0; label < labelCount; label++) { if (m_axisCacheY.labelItems().size() > labelNbr) { const LabelItem &axisLabelItem = *m_axisCacheY.labelItems().at(labelNbr); + const GLfloat labelYTrans = m_axisCacheY.labelPosition(label); - glPolygonOffset(GLfloat(segment) / -10.0f, 1.0f); + glPolygonOffset(GLfloat(label) / -10.0f, 1.0f); // Back wall - labelTransBack.setY(labelPos); + labelTransBack.setY(labelYTrans); m_dummyRenderItem.setTranslation(labelTransBack); m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix, positionZComp, labelRotateVectorBack, 0, m_cachedSelectionMode, @@ -1958,7 +1879,7 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) true, true, Drawer::LabelMid, alignmentBack); // Side wall - labelTransSide.setY(labelPos); + labelTransSide.setY(labelYTrans); m_dummyRenderItem.setTranslation(labelTransSide); m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix, positionZComp, labelRotateVectorSide, 0, m_cachedSelectionMode, @@ -1966,7 +1887,6 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) true, true, Drawer::LabelMid, alignmentSide); } labelNbr++; - labelPos += posStep; } } glDisable(GL_POLYGON_OFFSET_FILL); @@ -2123,8 +2043,14 @@ void Surface3DRenderer::calculateSceneScalingFactors() m_scaleFactor = qMax(m_areaSize.width(), m_areaSize.height()); m_scaleX = aspectRatio * m_areaSize.width() / m_scaleFactor; m_scaleZ = aspectRatio * m_areaSize.height() / m_scaleFactor; - m_scaleXWithBackground = m_scaleX * backgroundMargin; - m_scaleZWithBackground = m_scaleZ * backgroundMargin; + m_scaleXWithBackground = m_scaleX + backgroundMargin - 1.0f; + m_scaleZWithBackground = m_scaleZ + backgroundMargin - 1.0f; + + float factorScaler = 2.0f * aspectRatio / m_scaleFactor; + m_axisCacheX.setScale(factorScaler * m_areaSize.width()); + m_axisCacheZ.setScale(-factorScaler * m_areaSize.height()); + m_axisCacheX.setTranslate(-m_axisCacheX.scale() / 2.0f); + m_axisCacheZ.setTranslate(-m_axisCacheZ.scale() / 2.0f); } void Surface3DRenderer::checkFlatSupport(SurfaceSeriesRenderCache *cache) @@ -2144,13 +2070,10 @@ void Surface3DRenderer::updateObjects(SurfaceSeriesRenderCache *cache, bool dime const QRect &sampleSpace = cache->sampleSpace(); - if (cache->isFlatShadingEnabled()) { - cache->surfaceObject()->setUpData(dataArray, sampleSpace, m_heightNormalizer, - m_axisCacheY.min(), dimensionChanged); - } else { - cache->surfaceObject()->setUpSmoothData(dataArray, sampleSpace, m_heightNormalizer, - m_axisCacheY.min(), dimensionChanged); - } + if (cache->isFlatShadingEnabled()) + cache->surfaceObject()->setUpData(dataArray, sampleSpace, dimensionChanged); + else + cache->surfaceObject()->setUpSmoothData(dataArray, sampleSpace, dimensionChanged); } void Surface3DRenderer::updateSelectedPoint(const QPoint &position, const QSurface3DSeries *series) @@ -2226,9 +2149,6 @@ void Surface3DRenderer::updateSelectionPoint(SurfaceSeriesRenderCache *cache, co if (column < 0 || row < 0) return; - QSurfaceDataArray &dataArray = cache->dataArray(); - float value = dataArray.at(row)->at(column).y(); - SelectionPointer *slicePointer = cache->sliceSelectionPointer(); if (!slicePointer && m_cachedIsSlicingActivated) { slicePointer = new SelectionPointer(m_drawer); @@ -2240,26 +2160,23 @@ void Surface3DRenderer::updateSelectionPoint(SurfaceSeriesRenderCache *cache, co cache->setMainSelectionPointer(mainPointer); } - const QVector3D &scale = cache->scale(); - const QVector3D &offset = cache->offset(); QString selectionLabel; if (label) - selectionLabel = createSelectionLabel(cache, value, column, row); + selectionLabel = createSelectionLabel(cache, column, row); if (m_cachedIsSlicingActivated) { - QVector3D subPos; + QVector3D subPosFront; + QVector3D subPosBack; if (m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionRow)) { - subPos = cache->sliceSurfaceObject()->vertexAt(column, 0); - subPos *= QVector3D(scale.x(), 1.0f, 0.0f); - subPos += QVector3D(offset.x(), 0.0f, 0.0f); + subPosFront = cache->sliceSurfaceObject()->vertexAt(column, 0); + subPosBack = cache->sliceSurfaceObject()->vertexAt(column, 1); } else if (m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionColumn)) { - subPos = cache->sliceSurfaceObject()->vertexAt(row, 0); - subPos *= QVector3D(scale.z(), 1.0f, 0.0f); - subPos += QVector3D(-offset.z(), 0.0f, 0.0f); + subPosFront = cache->sliceSurfaceObject()->vertexAt(row, 0); + subPosBack = cache->sliceSurfaceObject()->vertexAt(row, 1); } slicePointer->updateBoundingRect(m_secondarySubViewport); slicePointer->updateSliceData(true, m_autoScaleAdjustment); - slicePointer->setPosition(subPos); + slicePointer->setPosition((subPosFront + subPosBack) / 2.0f); slicePointer->setLabel(selectionLabel); slicePointer->setPointerObject(cache->object()); slicePointer->setHighlightColor(cache->singleHighlightColor()); @@ -2270,8 +2187,6 @@ void Surface3DRenderer::updateSelectionPoint(SurfaceSeriesRenderCache *cache, co QVector3D mainPos; mainPos = cache->surfaceObject()->vertexAt(column, row); - mainPos *= scale; - mainPos += offset; mainPointer->updateBoundingRect(m_primarySubViewport); mainPointer->updateSliceData(false, m_autoScaleAdjustment); mainPointer->setPosition(mainPos); @@ -2307,7 +2222,7 @@ QPoint Surface3DRenderer::selectionIdToSurfacePoint(uint id) return QPoint(row, column); } -QString Surface3DRenderer::createSelectionLabel(SurfaceSeriesRenderCache *cache, float value, +QString Surface3DRenderer::createSelectionLabel(SurfaceSeriesRenderCache *cache, int column, int row) { QSurfaceDataArray &dataArray = cache->dataArray(); @@ -2325,26 +2240,18 @@ QString Surface3DRenderer::createSelectionLabel(SurfaceSeriesRenderCache *cache, labelText.replace(zTitleTag, m_axisCacheZ.title()); if (labelText.contains(xLabelTag)) { - QString labelFormat = m_axisCacheX.labelFormat(); - if (labelFormat.isEmpty()) - labelFormat = Utils::defaultLabelFormat(); - QString valueLabelText = generateValueLabel(labelFormat, - dataArray.at(row)->at(column).x()); + QString valueLabelText = m_axisCacheX.formatter()->stringForValue( + dataArray.at(row)->at(column).x(), m_axisCacheX.labelFormat()); labelText.replace(xLabelTag, valueLabelText); } if (labelText.contains(yLabelTag)) { - QString labelFormat = m_axisCacheY.labelFormat(); - if (labelFormat.isEmpty()) - labelFormat = Utils::defaultLabelFormat(); - QString valueLabelText = generateValueLabel(labelFormat, value); + QString valueLabelText = m_axisCacheY.formatter()->stringForValue( + dataArray.at(row)->at(column).y(), m_axisCacheY.labelFormat()); labelText.replace(yLabelTag, valueLabelText); } if (labelText.contains(zLabelTag)) { - QString labelFormat = m_axisCacheZ.labelFormat(); - if (labelFormat.isEmpty()) - labelFormat = Utils::defaultLabelFormat(); - QString valueLabelText = generateValueLabel(labelFormat, - dataArray.at(row)->at(column).z()); + QString valueLabelText = m_axisCacheZ.formatter()->stringForValue( + dataArray.at(row)->at(column).z(), m_axisCacheZ.labelFormat()); labelText.replace(zLabelTag, valueLabelText); } diff --git a/src/datavisualization/engine/surface3drenderer_p.h b/src/datavisualization/engine/surface3drenderer_p.h index 5d93ee4a..9fd5d0d9 100644 --- a/src/datavisualization/engine/surface3drenderer_p.h +++ b/src/datavisualization/engine/surface3drenderer_p.h @@ -112,6 +112,8 @@ public: void updateRows(const QVector &rows); void updateItem(const QVector &points); void updateAxisRange(QAbstract3DAxis::AxisOrientation orientation, float min, float max); + void updateAxisFormatter(QAbstract3DAxis::AxisOrientation orientation, + QValue3DAxisFormatter *formatter); void updateScene(Q3DScene *scene); void updateSlicingActive(bool isSlicing); void updateSelectedPoint(const QPoint &position, const QSurface3DSeries *series); @@ -138,7 +140,7 @@ private: void updateShadowQuality(QAbstract3DGraph::ShadowQuality quality); void updateTextures(); void initShaders(const QString &vertexShader, const QString &fragmentShader); - QRect calculateSampleRect(SurfaceSeriesRenderCache *cache, const QSurfaceDataArray &array); + QRect calculateSampleRect(const QSurfaceDataArray &array); void loadBackgroundMesh(); void loadLabelMesh(); void drawScene(GLuint defaultFboHandle); @@ -156,7 +158,7 @@ private: void surfacePointSelected(const QPoint &point); void updateSelectionPoint(SurfaceSeriesRenderCache *cache, const QPoint &point, bool label); QPoint selectionIdToSurfacePoint(uint id); - QString createSelectionLabel(SurfaceSeriesRenderCache *cache, float value, int column, int row); + QString createSelectionLabel(SurfaceSeriesRenderCache *cache, int column, int row); #if !defined(QT_OPENGL_ES_2) void loadGridLineMesh(); void updateDepthBuffer(); @@ -164,6 +166,8 @@ private: void emitSelectedPointChanged(QPoint position); Q_DISABLE_COPY(Surface3DRenderer) + + friend class SurfaceObject; }; QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/engine/surfaceseriesrendercache.cpp b/src/datavisualization/engine/surfaceseriesrendercache.cpp index ba25d71d..ad81f714 100644 --- a/src/datavisualization/engine/surfaceseriesrendercache.cpp +++ b/src/datavisualization/engine/surfaceseriesrendercache.cpp @@ -25,20 +25,18 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION -SurfaceSeriesRenderCache::SurfaceSeriesRenderCache() +SurfaceSeriesRenderCache::SurfaceSeriesRenderCache(Surface3DRenderer *renderer) : m_surfaceVisible(false), m_surfaceGridVisible(false), m_surfaceFlatShading(true), - m_surfaceObj(new SurfaceObject), - m_sliceSurfaceObj(new SurfaceObject), + m_surfaceObj(new SurfaceObject(renderer)), + m_sliceSurfaceObj(new SurfaceObject(renderer)), m_sampleSpace(QRect(0, 0, 0 , 0)), m_selectionTexture(0), m_selectionIdStart(0), m_selectionIdEnd(0), m_flatChangeAllowed(true), m_flatStatusDirty(false), - m_scale(QVector3D(1.0f, 1.0f, 1.0f)), - m_offset(QVector3D(0.0f, 0.0f, 0.0f)), m_sliceSelectionPointer(0), m_mainSelectionPointer(0), m_slicePointerActive(false), diff --git a/src/datavisualization/engine/surfaceseriesrendercache_p.h b/src/datavisualization/engine/surfaceseriesrendercache_p.h index 2dda0670..bab16201 100644 --- a/src/datavisualization/engine/surfaceseriesrendercache_p.h +++ b/src/datavisualization/engine/surfaceseriesrendercache_p.h @@ -41,13 +41,14 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION class Abstract3DRenderer; +class Surface3DRenderer; class ObjectHelper; class TextureHelper; class SurfaceSeriesRenderCache : public SeriesRenderCache { public: - SurfaceSeriesRenderCache(); + SurfaceSeriesRenderCache(Surface3DRenderer *renderer); virtual ~SurfaceSeriesRenderCache(); void populate(QSurface3DSeries *series, Abstract3DRenderer *renderer); @@ -81,10 +82,6 @@ public: selection <= m_selectionIdEnd; } inline bool isFlatStatusDirty() const { return m_flatStatusDirty; } inline void setFlatStatusDirty(bool status) { m_flatStatusDirty = status; } - inline void setScale(const QVector3D &scale) { m_scale = scale; } - inline const QVector3D &scale() const { return m_scale; } - inline void setOffset(const QVector3D &offset) { m_offset = offset; } - inline const QVector3D &offset() const { return m_offset; } // m_MVPMatrix is volatile, used only for optimizing rendering a bit inline void setMVPMatrix(const QMatrix4x4 &matrix) { m_MVPMatrix = matrix; } inline const QMatrix4x4 &MVPMatrix() { return m_MVPMatrix; } @@ -113,8 +110,6 @@ protected: uint m_selectionIdEnd; bool m_flatChangeAllowed; bool m_flatStatusDirty; - QVector3D m_scale; - QVector3D m_offset; QMatrix4x4 m_MVPMatrix; SelectionPointer *m_sliceSelectionPointer; SelectionPointer *m_mainSelectionPointer; -- cgit v1.2.3