diff options
author | Miikka Heikkinen <miikka.heikkinen@digia.com> | 2013-11-28 08:19:37 +0200 |
---|---|---|
committer | Miikka Heikkinen <miikka.heikkinen@digia.com> | 2013-11-29 09:53:48 +0200 |
commit | 527113321ff103835b89543c5d6f670f55b5b0d5 (patch) | |
tree | 01b242ef7b1f30a414b718f99f155f19235951bd /src/datavisualization/engine | |
parent | 85dda87df2d420dc53959e549d24c4b09ce93d57 (diff) |
Move series specific visual elements to series, part 1
Meshes moved to series.
Task-number: QTRD-2557
Change-Id: I80050e413faf3bc942eb5a5627a66747de5805d8
Reviewed-by: Tomi Korpipää <tomi.korpipaa@digia.com>
Diffstat (limited to 'src/datavisualization/engine')
23 files changed, 292 insertions, 325 deletions
diff --git a/src/datavisualization/engine/abstract3dcontroller.cpp b/src/datavisualization/engine/abstract3dcontroller.cpp index 302b74ad..b8b2e826 100644 --- a/src/datavisualization/engine/abstract3dcontroller.cpp +++ b/src/datavisualization/engine/abstract3dcontroller.cpp @@ -52,7 +52,8 @@ Abstract3DController::Abstract3DController(QRect boundRect, QObject *parent) : m_axisZ(0), m_renderer(0), m_isDataDirty(true), - m_isSeriesDirty(true), + m_isSeriesVisibilityDirty(true), + m_isSeriesVisualsDirty(true), m_renderPending(false) { // Set initial theme @@ -98,6 +99,8 @@ void Abstract3DController::addSeries(QAbstract3DSeries *series) if (series && !m_seriesList.contains(series)) { m_seriesList.append(series); series->d_ptr->setController(this); + QObject::connect(series, &QAbstract3DSeries::visibilityChanged, + this, &Abstract3DController::handleSeriesVisibilityChanged); if (series->isVisible()) handleSeriesVisibilityChangedBySender(series); } @@ -107,9 +110,11 @@ void Abstract3DController::removeSeries(QAbstract3DSeries *series) { if (series && series->d_ptr->m_controller == this) { m_seriesList.removeAll(series); + QObject::disconnect(series, &QAbstract3DSeries::visibilityChanged, + this, &Abstract3DController::handleSeriesVisibilityChanged); series->d_ptr->setController(0); m_isDataDirty = true; - m_isSeriesDirty = true; + m_isSeriesVisibilityDirty = true; emitNeedRender(); } } @@ -189,11 +194,6 @@ void Abstract3DController::synchDataToRenderer() m_changeTracker.selectionModeChanged = false; } - if (m_changeTracker.objFileChanged) { - m_renderer->updateMeshFileName(m_objFile); - m_changeTracker.objFileChanged = false; - } - if (m_changeTracker.axisXTypeChanged) { m_renderer->updateAxisType(Q3DAbstractAxis::AxisOrientationX, m_axisX->type()); m_changeTracker.axisXTypeChanged = false; @@ -337,9 +337,10 @@ void Abstract3DController::synchDataToRenderer() } } - if (m_isSeriesDirty) { - m_renderer->updateSeries(m_seriesList); - m_isSeriesDirty = false; + if (m_isSeriesVisibilityDirty || m_isSeriesVisualsDirty) { + m_renderer->updateSeries(m_seriesList, m_isSeriesVisibilityDirty); + m_isSeriesVisibilityDirty = false; + m_isSeriesVisualsDirty = false; } if (m_isDataDirty) { @@ -833,24 +834,21 @@ void Abstract3DController::setSlicingActive(bool isSlicing) emitNeedRender(); } -void Abstract3DController::setMeshFileName(const QString &fileName) +Q3DScene *Abstract3DController::scene() { - if (fileName != m_objFile) { - m_objFile = fileName; - m_changeTracker.objFileChanged = true; - emit meshFileNameChanged(fileName); - emitNeedRender(); - } + return m_scene; } -QString Abstract3DController::meshFileName() const +void Abstract3DController::markDataDirty() { - return m_objFile; + m_isDataDirty = true; + emitNeedRender(); } -Q3DScene *Abstract3DController::scene() +void Abstract3DController::markSeriesVisualsDirty() { - return m_scene; + m_isSeriesVisualsDirty = true; + emitNeedRender(); } void Abstract3DController::handleAxisTitleChanged(const QString &title) @@ -1023,7 +1021,7 @@ void Abstract3DController::handleSeriesVisibilityChangedBySender(QObject *sender Q_UNUSED(sender) m_isDataDirty = true; - m_isSeriesDirty = true; + m_isSeriesVisibilityDirty = true; emitNeedRender(); } diff --git a/src/datavisualization/engine/abstract3dcontroller_p.h b/src/datavisualization/engine/abstract3dcontroller_p.h index 556d1ea5..27cfb9a1 100644 --- a/src/datavisualization/engine/abstract3dcontroller_p.h +++ b/src/datavisualization/engine/abstract3dcontroller_p.h @@ -61,7 +61,6 @@ struct Abstract3DChangeBitField { bool selectionModeChanged : 1; bool objFileChanged : 1; bool gridEnabledChanged : 1; - bool backgroundEnabledChanged : 1; bool axisXTypeChanged : 1; bool axisYTypeChanged : 1; bool axisZTypeChanged : 1; @@ -105,7 +104,6 @@ struct Abstract3DChangeBitField { selectionModeChanged(true), objFileChanged(true), gridEnabledChanged(true), - backgroundEnabledChanged(true), axisXTypeChanged(true), axisYTypeChanged(true), axisZTypeChanged(true), @@ -172,7 +170,6 @@ private: bool m_labelBackground; bool m_isBackgroundEnabled; bool m_isGridEnabled; - QString m_objFile; Q3DScene *m_scene; QDataVis::ColorStyle m_colorStyle; QColor m_objectColor; @@ -194,7 +191,8 @@ protected: QList<Q3DAbstractAxis *> m_axes; // List of all added axes Abstract3DRenderer *m_renderer; bool m_isDataDirty; - bool m_isSeriesDirty; + bool m_isSeriesVisibilityDirty; + bool m_isSeriesVisualsDirty; bool m_renderPending; QList<QAbstract3DSeries *> m_seriesList; @@ -282,12 +280,11 @@ public: bool isSlicingActive() const; void setSlicingActive(bool isSlicing); - virtual void setMeshFileName(const QString &fileName); - virtual QString meshFileName() const; - Q3DScene *scene(); - inline void setSeriesDirty() { m_isSeriesDirty = true; } + void markDataDirty(); + void markSeriesVisualsDirty(); + void emitNeedRender(); virtual void mouseDoubleClickEvent(QMouseEvent *event); @@ -327,7 +324,6 @@ signals: void activeInputHandlerChanged(QAbstract3DInputHandler *inputHandler); void themeChanged(Q3DTheme *theme); void selectionModeChanged(QDataVis::SelectionFlags mode); - void meshFileNameChanged(QString filename); void needRender(); void colorStyleChanged(QDataVis::ColorStyle style); void objectColorChanged(QColor color); @@ -345,6 +341,8 @@ protected: private: void setAxisHelper(Q3DAbstractAxis::AxisOrientation orientation, Q3DAbstractAxis *axis, Q3DAbstractAxis **axisPtr); + + friend class Bars3DController; }; QT_DATAVISUALIZATION_END_NAMESPACE diff --git a/src/datavisualization/engine/abstract3drenderer.cpp b/src/datavisualization/engine/abstract3drenderer.cpp index 50e56ce5..7e17baff 100644 --- a/src/datavisualization/engine/abstract3drenderer.cpp +++ b/src/datavisualization/engine/abstract3drenderer.cpp @@ -25,6 +25,7 @@ #include "q3dlight_p.h" #include "qabstract3dseries_p.h" #include "q3dtheme_p.h" +#include "objecthelper_p.h" Q_DECLARE_METATYPE(QtDataVisualization::QDataVis::ShadowQuality) @@ -71,6 +72,8 @@ Abstract3DRenderer::~Abstract3DRenderer() delete m_drawer; delete m_textureHelper; delete m_cachedScene; + for (int i = 0; i < m_visibleSeriesList.size(); i++) + delete m_visibleSeriesList.at(i).object(); } void Abstract3DRenderer::initializeOpenGL() @@ -250,14 +253,6 @@ void Abstract3DRenderer::handleShadowQualityChange() #endif } -void Abstract3DRenderer::updateMeshFileName(const QString &objFileName) -{ - if (objFileName != m_cachedObjFile) { - m_cachedObjFile = objFileName; - loadMeshFile(); - } -} - void Abstract3DRenderer::updateSelectionMode(QDataVis::SelectionFlags mode) { m_cachedSelectionMode = mode; @@ -365,21 +360,31 @@ void Abstract3DRenderer::updateMultiHighlightGradient(const QLinearGradient &gra fixGradient(&m_cachedMultiHighlightGradient, &m_multiHighlightGradientTexture); } -void Abstract3DRenderer::updateSeries(const QList<QAbstract3DSeries *> &seriesList) +void Abstract3DRenderer::fixMeshFileName(QString &fileName, QAbstract3DSeries::Mesh mesh) +{ + // Default implementation does nothing. + Q_UNUSED(fileName) + Q_UNUSED(mesh) +} + +void Abstract3DRenderer::updateSeries(const QList<QAbstract3DSeries *> &seriesList, + bool updateVisibility) { int visibleCount = 0; - foreach (QAbstract3DSeries *current, seriesList) { - if (current->isVisible()) - visibleCount++; - } + if (updateVisibility) { + foreach (QAbstract3DSeries *current, seriesList) { + if (current->isVisible()) + visibleCount++; + } - if (visibleCount != m_visibleSeriesList.size()) - m_visibleSeriesList.resize(visibleCount); + if (visibleCount != m_visibleSeriesList.size()) + m_visibleSeriesList.resize(visibleCount); - visibleCount = 0; + visibleCount = 0; + } foreach (QAbstract3DSeries *current, seriesList) { if (current->isVisible()) - m_visibleSeriesList[visibleCount++].populate(current); + m_visibleSeriesList[visibleCount++].populate(current, this); } } diff --git a/src/datavisualization/engine/abstract3drenderer_p.h b/src/datavisualization/engine/abstract3drenderer_p.h index 6582fbc3..fe213b33 100644 --- a/src/datavisualization/engine/abstract3drenderer_p.h +++ b/src/datavisualization/engine/abstract3drenderer_p.h @@ -66,7 +66,6 @@ protected: QDataVis::ShadowQuality m_cachedShadowQuality; GLfloat m_autoScaleAdjustment; - QString m_cachedObjFile; QDataVis::SelectionFlags m_cachedSelectionMode; QDataVis::ColorStyle m_cachedColorStyle; @@ -104,7 +103,7 @@ public: virtual ~Abstract3DRenderer(); virtual void updateData() = 0; - virtual void updateSeries(const QList<QAbstract3DSeries *> &seriesList); + virtual void updateSeries(const QList<QAbstract3DSeries *> &seriesList, bool updateVisibility); virtual void render(GLuint defaultFboHandle); @@ -113,7 +112,6 @@ public: virtual void updateTheme(Q3DTheme *theme); virtual void updateSelectionMode(QDataVis::SelectionFlags newMode); - virtual void updateMeshFileName(const QString &objFileName); virtual void updateScene(Q3DScene *scene); virtual void updateTextures() = 0; virtual void initSelectionBuffer() = 0; @@ -141,6 +139,8 @@ public: virtual void updateMultiHighlightColor(const QColor &color); virtual void updateMultiHighlightGradient(const QLinearGradient &gradient); + virtual void fixMeshFileName(QString &fileName, QAbstract3DSeries::Mesh mesh); + signals: void needRender(); // Emit this if something in renderer causes need for another render pass. void requestShadowQuality(QDataVis::ShadowQuality quality); // For automatic quality adjustments @@ -153,7 +153,6 @@ protected: void reInitShaders(); virtual void handleShadowQualityChange(); virtual void handleResize(); - virtual void loadMeshFile() = 0; AxisRenderCache &axisCacheForOrientation(Q3DAbstractAxis::AxisOrientation orientation); diff --git a/src/datavisualization/engine/bars3dcontroller.cpp b/src/datavisualization/engine/bars3dcontroller.cpp index cb7ba5cb..7c3eff09 100644 --- a/src/datavisualization/engine/bars3dcontroller.cpp +++ b/src/datavisualization/engine/bars3dcontroller.cpp @@ -24,6 +24,8 @@ #include "q3dcategoryaxis_p.h" #include "qbardataproxy_p.h" #include "qbar3dseries_p.h" +#include "thememanager_p.h" +#include "q3dtheme_p.h" #include <QMatrix4x4> #include <qmath.h> @@ -39,9 +41,6 @@ Bars3DController::Bars3DController(QRect boundRect) m_barSpacing(QSizeF(1.0, 1.0)), m_renderer(0) { - // Default bar type; specific to bars - setBarType(QDataVis::MeshStyleBevelBars, false); - // Setting a null axis creates a new default axis according to orientation and graph type. // Note: these cannot be set in the Abstract3DController constructor, as they will call virtual // functions implemented by subclasses. @@ -72,6 +71,13 @@ void Bars3DController::initializeOpenGL() void Bars3DController::synchDataToRenderer() { + // Background change requires reloading the meshes in bar graphs, so dirty the series visuals + if (m_themeManager->theme()->d_ptr->m_dirtyBits.backgroundEnabledDirty) { + m_isSeriesVisualsDirty = true; + foreach (QAbstract3DSeries *series, m_seriesList) + series->d_ptr->m_changeTracker.meshChanged = true; + } + Abstract3DController::synchDataToRenderer(); if (!isInitialized()) @@ -311,26 +317,6 @@ bool Bars3DController::isBarSpecRelative() return m_isBarSpecRelative; } -void Bars3DController::setBarType(QDataVis::MeshStyle style, bool smooth) -{ - QString objFile; - if (style == QDataVis::MeshStyleBars) - objFile = QStringLiteral(":/defaultMeshes/bar"); - else if (style == QDataVis::MeshStylePyramids) - objFile = QStringLiteral(":/defaultMeshes/pyramid"); - else if (style == QDataVis::MeshStyleCones) - objFile = QStringLiteral(":/defaultMeshes/cone"); - else if (style == QDataVis::MeshStyleCylinders) - objFile = QStringLiteral(":/defaultMeshes/cylinder"); - else if (style == QDataVis::MeshStyleBevelBars) - objFile = QStringLiteral(":/defaultMeshes/bevelbar"); - - if (smooth) - objFile += QStringLiteral("Smooth"); - - Abstract3DController::setMeshFileName(objFile); -} - void Bars3DController::setSelectionMode(QDataVis::SelectionFlags mode) { if (mode.testFlag(QDataVis::SelectionSlice) diff --git a/src/datavisualization/engine/bars3dcontroller_p.h b/src/datavisualization/engine/bars3dcontroller_p.h index e9f39541..71009024 100644 --- a/src/datavisualization/engine/bars3dcontroller_p.h +++ b/src/datavisualization/engine/bars3dcontroller_p.h @@ -88,7 +88,6 @@ public: GLfloat barThickness(); QSizeF barSpacing(); bool isBarSpecRelative(); - void setBarType(QDataVis::MeshStyle style, bool smooth = false); void setSelectionMode(QDataVis::SelectionFlags mode); void setSelectedBar(const QPoint &position, QBar3DSeries *series); diff --git a/src/datavisualization/engine/bars3drenderer.cpp b/src/datavisualization/engine/bars3drenderer.cpp index 142640b3..addad904 100644 --- a/src/datavisualization/engine/bars3drenderer.cpp +++ b/src/datavisualization/engine/bars3drenderer.cpp @@ -64,7 +64,6 @@ Bars3DRenderer::Bars3DRenderer(Bars3DController *controller) m_selectionShader(0), m_backgroundShader(0), m_labelShader(0), - m_barObj(0), m_backgroundObj(0), m_gridLineObj(0), m_labelObj(0), @@ -114,7 +113,6 @@ Bars3DRenderer::~Bars3DRenderer() delete m_depthShader; delete m_selectionShader; delete m_backgroundShader; - delete m_barObj; delete m_backgroundObj; delete m_gridLineObj; delete m_labelObj; @@ -297,9 +295,6 @@ void Bars3DRenderer::drawSlicedScene(const LabelItem &xLabel, const LabelItem &zLabel) { GLfloat barPosX = 0; - GLint startBar = 0; - GLint stopBar = m_sliceSelection->size(); - GLint stepBar = 1; QVector3D lightPos; // Specify viewport @@ -484,7 +479,8 @@ void Bars3DRenderer::drawSlicedScene(const LabelItem &xLabel, gradientTexture = m_objectGradientTexture; } - for (int bar = startBar; bar != stopBar; bar += stepBar) { + int stopBar = m_sliceSelection->size(); + for (int bar = 0; bar < stopBar; bar++) { BarRenderItem *item = m_sliceSelection->at(bar); if (!item) continue; @@ -517,6 +513,7 @@ void Bars3DRenderer::drawSlicedScene(const LabelItem &xLabel, MVPMatrix = projectionViewMatrix * modelMatrix; QVector3D barColor; + // TODO: Get color from correct series if (itemMode && m_visualSelectedBarPos.x() == item->position().x() && m_visualSelectedBarPos.y() == item->position().y()) { if (m_cachedColorStyle == QDataVis::ColorStyleUniform) @@ -544,7 +541,9 @@ void Bars3DRenderer::drawSlicedScene(const LabelItem &xLabel, } // Draw the object - m_drawer->drawObject(m_barShader, m_barObj, gradientTexture); + m_drawer->drawObject(m_barShader, + m_visibleSeriesList.at(item->seriesIndex()).object(), + gradientTexture); } } @@ -591,7 +590,8 @@ void Bars3DRenderer::drawSlicedScene(const LabelItem &xLabel, // TODO: Maybe use selection label instead of value? Should it be user controllable // as well? (QTRD-2546) if (itemMode && m_visualSelectedBarPos.x() == item->position().x() - && m_visualSelectedBarPos.y() == item->position().y()) { + && m_visualSelectedBarPos.y() == item->position().y() + && item->seriesIndex() == m_visualSelectedBarSeriesIndex) { m_drawer->drawLabel(*item, item->sliceLabelItem(), viewMatrix, projectionMatrix, valuePositionComp, sliceValueRotation, item->height(), m_cachedSelectionMode, m_labelShader, m_labelObj, activeCamera, @@ -785,6 +785,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) const BarRenderItem &item = m_renderingArrays.at(series).at(row).at(bar); if (!item.value()) continue; + ObjectHelper *barObj = m_visibleSeriesList.at(series).object(); // Set front face culling for negative valued bars and back face culling for // positive valued bars to remove peter-panning issues if (item.height() > 0) { @@ -818,15 +819,15 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) // 1st attribute buffer : vertices glEnableVertexAttribArray(m_depthShader->posAtt()); - glBindBuffer(GL_ARRAY_BUFFER, m_barObj->vertexBuf()); + glBindBuffer(GL_ARRAY_BUFFER, barObj->vertexBuf()); glVertexAttribPointer(m_depthShader->posAtt(), 3, GL_FLOAT, GL_FALSE, 0, (void *)0); // Index buffer - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_barObj->elementBuf()); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, barObj->elementBuf()); // Draw the triangles - glDrawElements(GL_TRIANGLES, m_barObj->indexCount(), GL_UNSIGNED_SHORT, + glDrawElements(GL_TRIANGLES, barObj->indexCount(), GL_UNSIGNED_SHORT, (void *)0); // Free buffers @@ -890,6 +891,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) seriesPos += m_seriesStep; continue; } + ObjectHelper *barObj = m_visibleSeriesList.at(series).object(); if (item.height() < 0) glCullFace(GL_FRONT); @@ -926,15 +928,15 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) // 1st attribute buffer : vertices glEnableVertexAttribArray(m_selectionShader->posAtt()); - glBindBuffer(GL_ARRAY_BUFFER, m_barObj->vertexBuf()); + glBindBuffer(GL_ARRAY_BUFFER, barObj->vertexBuf()); glVertexAttribPointer(m_selectionShader->posAtt(), 3, GL_FLOAT, GL_FALSE, 0, (void *)0); // Index buffer - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_barObj->elementBuf()); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, barObj->elementBuf()); // Draw the triangles - glDrawElements(GL_TRIANGLES, m_barObj->indexCount(), GL_UNSIGNED_SHORT, + glDrawElements(GL_TRIANGLES, barObj->indexCount(), GL_UNSIGNED_SHORT, (void *)0); // Free buffers @@ -1001,6 +1003,14 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) if (m_sliceSelection && m_sliceSelection->size()) { // Slice doesn't own its items, no need to delete them - just clear m_sliceSelection->clear(); + int reserveAmount = 0; + if (rowMode) + reserveAmount = m_renderColumns; + else + reserveAmount = m_renderRows; + if (m_cachedSelectionMode.testFlag(QDataVis::SelectionMultiSeries)) + reserveAmount *= m_visibleSeriesList.size(); + m_sliceSelection->reserve(reserveAmount); } // Set slice cache, i.e. axis cache from where slice labels are taken if (rowMode) @@ -1029,6 +1039,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) for (int bar = startBar; bar != stopBar; bar += stepBar) { float seriesPos = m_seriesStart; for (int series = 0; series < seriesCount; series++) { + ObjectHelper *barObj = m_visibleSeriesList.at(series).object(); BarRenderItem &item = m_renderingArrays[series][row][bar]; if (item.height() < 0) @@ -1094,6 +1105,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) } item.setTranslation(translation); item.setPosition(QPoint(row, bar)); + item.setSeriesIndex(series); m_sliceSelection->append(&item); barSelectionFound = true; } @@ -1112,6 +1124,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) item.setTranslation(modelMatrix.column(3).toVector3D()); item.setPosition(QPoint(row, bar)); if (m_selectionDirty && bar < m_renderColumns) { + item.setSeriesIndex(series); if (!m_sliceTitleItem && m_axisCacheX.labelItems().size() > row) m_sliceTitleItem = m_axisCacheX.labelItems().at(row); m_sliceSelection->append(&item); @@ -1138,6 +1151,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) item.setTranslation(translation); item.setPosition(QPoint(row, bar)); if (m_selectionDirty && row < m_renderRows) { + item.setSeriesIndex(series); if (!m_sliceTitleItem && m_axisCacheZ.labelItems().size() > bar) m_sliceTitleItem = m_axisCacheZ.labelItems().at(bar); m_sliceSelection->append(&item); @@ -1176,7 +1190,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) m_barShader->setUniformValue(m_barShader->lightS(), shadowLightStrength); // Draw the object - m_drawer->drawObject(m_barShader, m_barObj, gradientTexture, m_depthTexture); + m_drawer->drawObject(m_barShader, barObj, gradientTexture, m_depthTexture); } else #endif { @@ -1184,7 +1198,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) m_barShader->setUniformValue(m_barShader->lightS(), lightStrength); // Draw the object - m_drawer->drawObject(m_barShader, m_barObj, gradientTexture); + m_drawer->drawObject(m_barShader, barObj, gradientTexture); } } seriesPos += m_seriesStep; @@ -1829,16 +1843,6 @@ void Bars3DRenderer::updateAxisRange(Q3DAbstractAxis::AxisOrientation orientatio } } -void Bars3DRenderer::updateTheme(Q3DTheme *theme) -{ - bool wasEnabled = m_cachedTheme->isBackgroundEnabled(); - - Abstract3DRenderer::updateTheme(theme); - - if (theme->isBackgroundEnabled() != wasEnabled) - loadMeshFile(); // Load changed bar type -} - void Bars3DRenderer::updateSelectedBar(const QPoint &position, const QBar3DSeries *series) { m_selectedBarPos = position; @@ -1914,21 +1918,6 @@ void Bars3DRenderer::updateShadowQuality(QDataVis::ShadowQuality quality) #endif } -void Bars3DRenderer::loadMeshFile() -{ - if (m_cachedObjFile.isEmpty()) - return; - - QString objectFileName = m_cachedObjFile; - if (m_barObj) - delete m_barObj; - // If background is disabled, load full version of bar mesh - if (!m_cachedTheme->isBackgroundEnabled()) - objectFileName.append(QStringLiteral("Full")); - m_barObj = new ObjectHelper(objectFileName); - m_barObj->load(); -} - void Bars3DRenderer::loadBackgroundMesh() { if (m_backgroundObj) @@ -1962,6 +1951,16 @@ void Bars3DRenderer::updateTextures() m_updateLabels = true; } +void Bars3DRenderer::fixMeshFileName(QString &fileName, QAbstract3DSeries::Mesh mesh) +{ + if (!m_cachedTheme->isBackgroundEnabled()) { + // Load full version of meshes that have it available + // Note: Minimal and Point not supported in bar charts + if (mesh != QAbstract3DSeries::MeshSphere) + fileName.append(QStringLiteral("Full")); + } +} + void Bars3DRenderer::calculateSceneScalingFactors() { // Calculate scene scaling and translation factors diff --git a/src/datavisualization/engine/bars3drenderer_p.h b/src/datavisualization/engine/bars3drenderer_p.h index f3e9103b..47c77537 100644 --- a/src/datavisualization/engine/bars3drenderer_p.h +++ b/src/datavisualization/engine/bars3drenderer_p.h @@ -74,7 +74,6 @@ private: ShaderHelper *m_selectionShader; ShaderHelper *m_backgroundShader; ShaderHelper *m_labelShader; - ObjectHelper *m_barObj; ObjectHelper *m_backgroundObj; ObjectHelper *m_gridLineObj; ObjectHelper *m_labelObj; @@ -122,7 +121,6 @@ public: protected: virtual void initializeOpenGL(); - virtual void loadMeshFile(); public slots: void updateBarSpecs(GLfloat thicknessRatio = 1.0f, @@ -141,7 +139,7 @@ private: virtual void initShaders(const QString &vertexShader, const QString &fragmentShader); virtual void updateShadowQuality(QDataVis::ShadowQuality quality); virtual void updateTextures(); - virtual void updateTheme(Q3DTheme *theme); + virtual void fixMeshFileName(QString &fileName, QAbstract3DSeries::Mesh mesh); void drawSlicedScene(const LabelItem &xLabel, const LabelItem &yLabel, const LabelItem &zLabel); void drawScene(GLuint defaultFboHandle); diff --git a/src/datavisualization/engine/engine.qrc b/src/datavisualization/engine/engine.qrc index ecf9e29b..8fcaecec 100644 --- a/src/datavisualization/engine/engine.qrc +++ b/src/datavisualization/engine/engine.qrc @@ -24,9 +24,9 @@ <file alias="bevelbarSmoothFull">meshes/barFilledSmooth.obj</file> <file alias="barFull">meshes/cubeFilledFlat.obj</file> <file alias="barSmoothFull">meshes/cubeFilledSmooth.obj</file> - <file alias="dotSmooth">meshes/scatterdot.obj</file> - <file alias="dot">meshes/scatterdotFlat.obj</file> <file alias="negativeBackground">meshes/backgroundNegatives.obj</file> + <file alias="minimal">meshes/minimalFlat.obj</file> + <file alias="minimalSmooth">meshes/minimalSmooth.obj</file> </qresource> <qresource prefix="/shaders"> <file alias="fragment">shaders/default.frag</file> diff --git a/src/datavisualization/engine/meshes/scatterdotFlat.obj b/src/datavisualization/engine/meshes/minimalFlat.obj index 9ab60a21..9ab60a21 100644 --- a/src/datavisualization/engine/meshes/scatterdotFlat.obj +++ b/src/datavisualization/engine/meshes/minimalFlat.obj diff --git a/src/datavisualization/engine/meshes/scatterdot.obj b/src/datavisualization/engine/meshes/minimalSmooth.obj index dd2e77d3..dd2e77d3 100644 --- a/src/datavisualization/engine/meshes/scatterdot.obj +++ b/src/datavisualization/engine/meshes/minimalSmooth.obj diff --git a/src/datavisualization/engine/q3dbars.cpp b/src/datavisualization/engine/q3dbars.cpp index 52db2100..095c5d8d 100644 --- a/src/datavisualization/engine/q3dbars.cpp +++ b/src/datavisualization/engine/q3dbars.cpp @@ -106,8 +106,6 @@ Q3DBars::Q3DBars() &Q3DBars::selectionModeChanged); QObject::connect(d_ptr->m_shared, &Abstract3DController::shadowQualityChanged, this, &Q3DBars::shadowQualityChanged); - QObject::connect(d_ptr->m_shared, &Abstract3DController::meshFileNameChanged, this, - &Q3DBars::meshFileNameChanged); QObject::connect(d_ptr->m_shared, &Abstract3DController::themeChanged, this, &Q3DBars::themeChanged); QObject::connect(d_ptr->m_shared, &Abstract3DController::colorStyleChanged, this, @@ -300,18 +298,6 @@ bool Q3DBars::isBarSpacingRelative() } /*! - * Sets the bar \a style to one of the values in \c QDataVis::MeshStyle. It is preset to - * \c QDataVis::MeshStyleBars by default. A \a smooth flag can be used to set shading to smooth. - * It is \c false by default. - * - * \sa setMeshFileName() - */ -void Q3DBars::setBarType(QDataVis::MeshStyle style, bool smooth) -{ - d_ptr->m_shared->setBarType(style, smooth); -} - -/*! * \property Q3DBars::theme * * A user-defined theme. @@ -345,25 +331,6 @@ QDataVis::SelectionFlags Q3DBars::selectionMode() const } /*! - * \property Q3DBars::meshFileName - * - * Override bar type with a mesh object located in \a objFileName. - * \note Object needs to be in Wavefront obj format and include vertices, normals and UVs. - * It also needs to be in triangles. - * - * \sa setBarType() - */ -void Q3DBars::setMeshFileName(const QString &objFileName) -{ - d_ptr->m_shared->setMeshFileName(objFileName); -} - -QString Q3DBars::meshFileName() const -{ - return d_ptr->m_shared->meshFileName(); -} - -/*! * \property Q3DBars::scene * * This property contains the read only Q3DScene that can be used to access e.g. camera object. diff --git a/src/datavisualization/engine/q3dbars.h b/src/datavisualization/engine/q3dbars.h index c08db74a..37243a0d 100644 --- a/src/datavisualization/engine/q3dbars.h +++ b/src/datavisualization/engine/q3dbars.h @@ -42,7 +42,6 @@ class QT_DATAVISUALIZATION_EXPORT Q3DBars : public Q3DWindow Q_PROPERTY(float barThickness READ barThickness WRITE setBarThickness NOTIFY barThicknessChanged) Q_PROPERTY(QSizeF barSpacing READ barSpacing WRITE setBarSpacing NOTIFY barSpacingChanged) Q_PROPERTY(bool barSpacingRelative READ isBarSpacingRelative WRITE setBarSpacingRelative NOTIFY barSpacingRelativeChanged) - Q_PROPERTY(QString meshFileName READ meshFileName WRITE setMeshFileName NOTIFY meshFileNameChanged) Q_PROPERTY(Q3DTheme* theme READ theme WRITE setTheme NOTIFY themeChanged) Q_PROPERTY(Q3DScene* scene READ scene) Q_PROPERTY(QtDataVisualization::QDataVis::ColorStyle colorStyle READ colorStyle WRITE setColorStyle NOTIFY colorStyleChanged) @@ -61,9 +60,6 @@ public: void removeSeries(QBar3DSeries *series); QList<QBar3DSeries *> seriesList(); - // TODO: Move to dataset object once that is done QTRD-2121 - void setBarType(QDataVis::MeshStyle style, bool smooth = false); - void setTheme(Q3DTheme *theme); Q3DTheme *theme() const; @@ -76,10 +72,6 @@ public: void setBarSpacingRelative(bool relative); bool isBarSpacingRelative(); - // TODO: Move to dataset object once that is done QTRD-2121 - void setMeshFileName(const QString &objFileName); - QString meshFileName() const; - void setSelectionMode(QDataVis::SelectionFlags mode); QDataVis::SelectionFlags selectionMode() const; @@ -123,7 +115,6 @@ signals: void barThicknessChanged(float thicknessRatio); void barSpacingChanged(QSizeF spacing); void barSpacingRelativeChanged(bool relative); - void meshFileNameChanged(QString filename); void themeChanged(Q3DTheme *theme); void colorStyleChanged(QDataVis::ColorStyle style); void barColorChanged(QColor color); diff --git a/src/datavisualization/engine/q3dscatter.cpp b/src/datavisualization/engine/q3dscatter.cpp index acacaa8f..a71bdb18 100644 --- a/src/datavisualization/engine/q3dscatter.cpp +++ b/src/datavisualization/engine/q3dscatter.cpp @@ -90,8 +90,6 @@ Q3DScatter::Q3DScatter() &Q3DScatter::selectionModeChanged); QObject::connect(d_ptr->m_shared, &Abstract3DController::shadowQualityChanged, this, &Q3DScatter::shadowQualityChanged); - QObject::connect(d_ptr->m_shared, &Abstract3DController::meshFileNameChanged, this, - &Q3DScatter::meshFileNameChanged); QObject::connect(d_ptr->m_shared, &Abstract3DController::themeChanged, this, &Q3DScatter::themeChanged); QObject::connect(d_ptr->m_shared, &Abstract3DController::colorStyleChanged, this, @@ -221,18 +219,6 @@ void Q3DScatter::setHeight(const int height) } /*! - * Sets the item \a style to one of the values in \c QDataVis::MeshStyle. It is preset to - * \c QDataVis::MeshStyleSpheres by default. A \a smooth flag can be used to set shading to smooth. - * It is \c false by default. - * - * \sa setMeshFileName() - */ -void Q3DScatter::setObjectType(QDataVis::MeshStyle style, bool smooth) -{ - d_ptr->m_shared->setObjectType(style, smooth); -} - -/*! * \property Q3DScatter::theme * * TODO: Add docs @@ -266,25 +252,6 @@ QDataVis::SelectionFlags Q3DScatter::selectionMode() const } /*! - * \property Q3DScatter::meshFileName - * - * Override item type with a mesh object located in \a objFileName. - * \note Object needs to be in Wavefront obj format and include vertices, normals and UVs. - * It also needs to be in triangles. - * - * \sa setObjectType() - */ -void Q3DScatter::setMeshFileName(const QString &objFileName) -{ - d_ptr->m_shared->setMeshFileName(objFileName); -} - -QString Q3DScatter::meshFileName() const -{ - return d_ptr->m_shared->meshFileName(); -} - -/*! * \property Q3DScatter::scene * * This property contains the read only Q3DScene that can be used to access e.g. camera object. diff --git a/src/datavisualization/engine/q3dscatter.h b/src/datavisualization/engine/q3dscatter.h index bec6a647..917b31bc 100644 --- a/src/datavisualization/engine/q3dscatter.h +++ b/src/datavisualization/engine/q3dscatter.h @@ -39,7 +39,6 @@ class QT_DATAVISUALIZATION_EXPORT Q3DScatter : public Q3DWindow Q_OBJECT Q_PROPERTY(QtDataVisualization::QDataVis::SelectionFlags selectionMode READ selectionMode WRITE setSelectionMode NOTIFY selectionModeChanged) Q_PROPERTY(QtDataVisualization::QDataVis::ShadowQuality shadowQuality READ shadowQuality WRITE setShadowQuality NOTIFY shadowQualityChanged) - Q_PROPERTY(QString meshFileName READ meshFileName WRITE setMeshFileName NOTIFY meshFileNameChanged) Q_PROPERTY(Q3DTheme* theme READ theme WRITE setTheme NOTIFY themeChanged) Q_PROPERTY(Q3DScene* scene READ scene) Q_PROPERTY(QtDataVisualization::QDataVis::ColorStyle colorStyle READ colorStyle WRITE setColorStyle NOTIFY colorStyleChanged) @@ -58,14 +57,9 @@ public: void removeSeries(QScatter3DSeries *series); QList<QScatter3DSeries *> seriesList(); - void setObjectType(QDataVis::MeshStyle style, bool smooth = false); - void setTheme(Q3DTheme *theme); Q3DTheme *theme() const; - void setMeshFileName(const QString &objFileName); - QString meshFileName() const; - void setSelectionMode(QDataVis::SelectionFlags mode); QDataVis::SelectionFlags selectionMode() const; @@ -106,7 +100,6 @@ public: signals: void selectionModeChanged(QDataVis::SelectionFlags mode); void shadowQualityChanged(QDataVis::ShadowQuality quality); - void meshFileNameChanged(QString filename); void themeChanged(Q3DTheme* theme); void colorStyleChanged(QDataVis::ColorStyle style); void itemColorChanged(QColor color); diff --git a/src/datavisualization/engine/scatter3dcontroller.cpp b/src/datavisualization/engine/scatter3dcontroller.cpp index 08668dbb..6923f26e 100644 --- a/src/datavisualization/engine/scatter3dcontroller.cpp +++ b/src/datavisualization/engine/scatter3dcontroller.cpp @@ -35,9 +35,6 @@ Scatter3DController::Scatter3DController(QRect boundRect) m_selectedItem(invalidSelectionIndex()), m_selectedItemSeries(0) { - // Default object type; specific to scatter - setObjectType(QDataVis::MeshStyleSpheres, false); - // Setting a null axis creates a new default axis according to orientation and graph type. // Note: These cannot be set in Abstract3DController constructor, as they will call virtual // functions implemented by subclasses. @@ -197,33 +194,6 @@ void Scatter3DController::handleAxisRangeChangedBySender(QObject *sender) setSelectedItem(m_selectedItem, m_selectedItemSeries); } -void Scatter3DController::setObjectType(QDataVis::MeshStyle style, bool smooth) -{ - QString objFile; - if (style == QDataVis::MeshStyleSpheres) { - if (smooth) - objFile = QStringLiteral(":/defaultMeshes/sphereSmooth"); - else - objFile = QStringLiteral(":/defaultMeshes/sphere"); - } else if (style == QDataVis::MeshStyleDots) { - if (smooth) - objFile = QStringLiteral(":/defaultMeshes/dotSmooth"); - else - objFile = QStringLiteral(":/defaultMeshes/dot"); - } else if (style == QDataVis::MeshStyleBars) { - if (smooth) - objFile = QStringLiteral(":/defaultMeshes/barSmoothFull"); - else - objFile = QStringLiteral(":/defaultMeshes/barFull"); - } else { - objFile = QString(); -#if defined(QT_OPENGL_ES_2) - qWarning("MeshStylePoints is not fully supported on OpenGL ES2"); -#endif - } - Abstract3DController::setMeshFileName(objFile); -} - void Scatter3DController::setSelectionMode(QDataVis::SelectionFlags mode) { // We only support single item selection mode and no selection mode diff --git a/src/datavisualization/engine/scatter3dcontroller_p.h b/src/datavisualization/engine/scatter3dcontroller_p.h index 349b226a..838c8010 100644 --- a/src/datavisualization/engine/scatter3dcontroller_p.h +++ b/src/datavisualization/engine/scatter3dcontroller_p.h @@ -68,9 +68,6 @@ public: void initializeOpenGL(); - // Object type - void setObjectType(QDataVis::MeshStyle style, bool smooth = false); - // Change selection mode void setSelectionMode(QDataVis::SelectionFlags mode); diff --git a/src/datavisualization/engine/scatter3drenderer.cpp b/src/datavisualization/engine/scatter3drenderer.cpp index 24e33ba6..27262c4c 100644 --- a/src/datavisualization/engine/scatter3drenderer.cpp +++ b/src/datavisualization/engine/scatter3drenderer.cpp @@ -66,7 +66,6 @@ Scatter3DRenderer::Scatter3DRenderer(Scatter3DController *controller) m_selectionShader(0), m_backgroundShader(0), m_labelShader(0), - m_dotObj(0), m_backgroundObj(0), m_gridLineObj(0), m_labelObj(0), @@ -86,8 +85,7 @@ Scatter3DRenderer::Scatter3DRenderer(Scatter3DController *controller) m_selectedSeries(0), m_areaSize(QSizeF(0.0, 0.0)), m_dotSizeScale(1.0f), - m_hasHeightAdjustmentChanged(true), - m_drawingPoints(false) + m_hasHeightAdjustmentChanged(true) { initializeOpenGLFunctions(); initializeOpenGL(); @@ -105,7 +103,6 @@ Scatter3DRenderer::~Scatter3DRenderer() delete m_selectionShader; delete m_backgroundShader; delete m_labelShader; - delete m_dotObj; delete m_backgroundObj; delete m_gridLineObj; delete m_labelObj; @@ -284,8 +281,18 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) QMatrix4x4 depthProjectionMatrix; QMatrix4x4 depthProjectionViewMatrix; + // Check if we have any series with points + bool havePointSeries = false; + bool haveMeshSeries = false; + for (int i = 0; i < seriesCount; i++) { + if (m_visibleSeriesList.at(i).mesh() == QAbstract3DSeries::MeshPoint) + havePointSeries = true; + else + haveMeshSeries = true; + } + #if !defined(QT_OPENGL_ES_2) - if (m_drawingPoints) { + if (havePointSeries) { glEnable(GL_POINT_SMOOTH); glEnable(GL_PROGRAM_POINT_SIZE); // Scale points based on shadow quality for shadows, not by zoom level @@ -335,6 +342,8 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) // Draw dots to depth buffer for (int series = 0; series < seriesCount; series++) { + ObjectHelper *dotObj = m_visibleSeriesList.at(series).object(); + bool drawingPoints = (m_visibleSeriesList.at(series).mesh() == QAbstract3DSeries::MeshPoint); for (int dot = 0; dot < m_renderingArrays.at(series).size(); dot++) { const ScatterRenderItem &item = m_renderingArrays.at(series).at(dot); if (!item.isVisible()) @@ -344,7 +353,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) QMatrix4x4 MVPMatrix; modelMatrix.translate(item.translation()); - if (!m_drawingPoints) { + if (!drawingPoints) { modelMatrix.scale(modelScaler); // TODO: Remove all references to item size? //modelMatrix.scale(QVector3D(widthMultiplier * item.size() + widthScaler, @@ -356,20 +365,20 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) m_depthShader->setUniformValue(m_depthShader->MVP(), MVPMatrix); - if (m_drawingPoints) { + if (drawingPoints) { m_drawer->drawPoint(m_depthShader); } else { // 1st attribute buffer : vertices glEnableVertexAttribArray(m_depthShader->posAtt()); - glBindBuffer(GL_ARRAY_BUFFER, m_dotObj->vertexBuf()); + glBindBuffer(GL_ARRAY_BUFFER, dotObj->vertexBuf()); glVertexAttribPointer(m_depthShader->posAtt(), 3, GL_FLOAT, GL_FALSE, 0, (void *)0); // Index buffer - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_dotObj->elementBuf()); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, dotObj->elementBuf()); // Draw the triangles - glDrawElements(GL_TRIANGLES, m_dotObj->indexCount(), GL_UNSIGNED_SHORT, + glDrawElements(GL_TRIANGLES, dotObj->indexCount(), GL_UNSIGNED_SHORT, (void *)0); // Free buffers @@ -409,24 +418,18 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) #endif } - if (m_drawingPoints) + if (havePointSeries) glPointSize(m_dotSizeScale * activeCamera->zoomLevel()); // Scale points based on zoom - ShaderHelper *selectionShader = m_selectionShader; + ShaderHelper *pointSelectionShader = m_selectionShader; #else - ShaderHelper *selectionShader; - if (m_drawingPoints) - selectionShader = m_pointShader; - else - selectionShader = m_selectionShader; + ShaderHelper *pointSelectionShader = m_pointShader; #endif + ShaderHelper *selectionShader = m_selectionShader; // Skip selection mode drawing if we have no selection mode if (m_cachedSelectionMode > QDataVis::SelectionNone && SelectOnScene == m_selectionState) { - // Bind selection shader - selectionShader->bind(); - // Draw dots to selection buffer glBindFramebuffer(GL_FRAMEBUFFER, m_selectionFrameBuffer); glEnable(GL_DEPTH_TEST); // Needed, otherwise the depth render buffer is not used @@ -438,7 +441,23 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) 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); + // Rebind selection shader if it has changed + if (drawingPoints != previousDrawingPoints) { + previousDrawingPoints = drawingPoints; + if (series) // Don't release for first series + selectionShader->release(); + if (drawingPoints) + selectionShader = pointSelectionShader; + else + selectionShader = m_selectionShader; + + selectionShader->bind(); + } arraySize = m_renderingArrays.at(series).size(); totalArraySize += arraySize; @@ -454,7 +473,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) QMatrix4x4 MVPMatrix; modelMatrix.translate(item.translation()); - if (!m_drawingPoints) { + if (!drawingPoints) { modelMatrix.scale(modelScaler); // TODO: Remove all references to item size? //modelMatrix.scale(QVector3D(widthMultiplier * item.size() + widthScaler, @@ -470,20 +489,20 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) selectionShader->setUniformValue(selectionShader->MVP(), MVPMatrix); selectionShader->setUniformValue(selectionShader->color(), dotColor); - if (m_drawingPoints) { + if (drawingPoints) { m_drawer->drawPoint(selectionShader); } else { // 1st attribute buffer : vertices glEnableVertexAttribArray(selectionShader->posAtt()); - glBindBuffer(GL_ARRAY_BUFFER, m_dotObj->vertexBuf()); + glBindBuffer(GL_ARRAY_BUFFER, dotObj->vertexBuf()); glVertexAttribPointer(selectionShader->posAtt(), 3, GL_FLOAT, GL_FALSE, 0, (void *)0); // Index buffer - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_dotObj->elementBuf()); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, dotObj->elementBuf()); // Draw the triangles - glDrawElements(GL_TRIANGLES, m_dotObj->indexCount(), GL_UNSIGNED_SHORT, + glDrawElements(GL_TRIANGLES, dotObj->indexCount(), GL_UNSIGNED_SHORT, (void *)0); // Free buffers @@ -508,7 +527,8 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) glBindFramebuffer(GL_FRAMEBUFFER, defaultFboHandle); // Release selection shader - selectionShader->release(); + if (seriesCount) + selectionShader->release(); #if 0 // Use this if you want to see what is being drawn to the framebuffer m_labelShader->bind(); @@ -525,12 +545,15 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) #endif } - // Bind dot shader + // Draw dots ShaderHelper *dotShader = 0; GLuint gradientTexture = 0; + bool dotSelectionFound = false; + ScatterRenderItem *selectedItem(0); + int dotNo = 0; - if (!m_drawingPoints) { - // Set default shader + bool previousDrawingPoints = false; + if (haveMeshSeries) { dotShader = m_dotShader; dotShader->bind(); @@ -538,9 +561,8 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) dotShader->setUniformValue(dotShader->lightP(), lightPos); dotShader->setUniformValue(dotShader->view(), viewMatrix); dotShader->setUniformValue(dotShader->ambientS(), m_cachedTheme->ambientLightStrength()); - if (m_cachedColorStyle != QDataVis::ColorStyleUniform && !m_drawingPoints) { + if (m_cachedColorStyle != QDataVis::ColorStyleUniform) { if (m_cachedColorStyle == QDataVis::ColorStyleObjectGradient) { - // Round the gradient off a bit to avoid it looping over dotShader->setUniformValue(dotShader->gradientMin(), 0.0f); dotShader->setUniformValue(dotShader->gradientHeight(), 0.5f); } else { @@ -550,24 +572,27 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) gradientTexture = m_objectGradientTexture; } - // Enable texture glEnable(GL_TEXTURE_2D); } else { - // We can use selection shader for points -#if !defined(QT_OPENGL_ES_2) - dotShader = m_selectionShader; -#else - dotShader = m_pointShader; -#endif + dotShader = pointSelectionShader; dotShader->bind(); + previousDrawingPoints = true; } - // Draw dots - bool dotSelectionFound = false; - ScatterRenderItem *selectedItem(0); - int dotNo = 0; - for (int series = 0; series < seriesCount; series++) { + ObjectHelper *dotObj = m_visibleSeriesList.at(series).object(); + bool drawingPoints = (m_visibleSeriesList.at(series).mesh() == QAbstract3DSeries::MeshPoint); + // Rebind selection shader if it has changed + if (drawingPoints != previousDrawingPoints) { + previousDrawingPoints = drawingPoints; + dotShader->release(); + if (drawingPoints) + dotShader = pointSelectionShader; + else + dotShader = m_dotShader; + dotShader->bind(); + } + // TODO: Color per series. Let's just hack it while testing with 2 series QTRD-2557 QVector3D baseColor = Utils::vectorFromColor(m_cachedObjectColor) * (series + 0.25f); QVector3D dotColor = baseColor; @@ -582,7 +607,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) QMatrix4x4 itModelMatrix; modelMatrix.translate(item.translation()); - if (!m_drawingPoints) { + if (!drawingPoints) { modelMatrix.scale(modelScaler); itModelMatrix.scale(modelScaler); // TODO: Remove all references to item size? @@ -599,14 +624,14 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) MVPMatrix = projectionViewMatrix * modelMatrix; #endif - if (m_cachedColorStyle == QDataVis::ColorStyleUniform || m_drawingPoints) + if (m_cachedColorStyle == QDataVis::ColorStyleUniform || drawingPoints) dotColor = baseColor; else gradientTexture = m_objectGradientTexture; GLfloat lightStrength = m_cachedTheme->lightStrength(); if (m_cachedSelectionMode > QDataVis::SelectionNone && (m_selectedItemTotalIndex == dotNo)) { - if (m_cachedColorStyle == QDataVis::ColorStyleUniform || m_drawingPoints) + if (m_cachedColorStyle == QDataVis::ColorStyleUniform || drawingPoints) dotColor = Utils::vectorFromColor(m_cachedSingleHighlightColor); else gradientTexture = m_singleHighlightGradientTexture; @@ -616,14 +641,14 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) dotSelectionFound = true; } - if (!m_drawingPoints) { + if (!drawingPoints) { // Set shader bindings dotShader->setUniformValue(dotShader->model(), modelMatrix); dotShader->setUniformValue(dotShader->nModel(), itModelMatrix.inverted().transposed()); } dotShader->setUniformValue(dotShader->MVP(), MVPMatrix); - if (m_cachedColorStyle == QDataVis::ColorStyleUniform || m_drawingPoints) { + if (m_cachedColorStyle == QDataVis::ColorStyleUniform || drawingPoints) { dotShader->setUniformValue(dotShader->color(), dotColor); } else if (m_cachedColorStyle == QDataVis::ColorStyleRangeGradient) { dotShader->setUniformValue(dotShader->gradientMin(), @@ -631,7 +656,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) } #if !defined(QT_OPENGL_ES_2) if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) { - if (!m_drawingPoints) { + if (!drawingPoints) { // Set shadow shader bindings QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; dotShader->setUniformValue(dotShader->shadowQ(), m_shadowQualityToShader); @@ -639,7 +664,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) dotShader->setUniformValue(dotShader->lightS(), lightStrength / 10.0f); // Draw the object - m_drawer->drawObject(dotShader, m_dotObj, gradientTexture, m_depthTexture); + m_drawer->drawObject(dotShader, dotObj, gradientTexture, m_depthTexture); } else { // Draw the object m_drawer->drawPoint(dotShader); @@ -647,12 +672,11 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) } else #endif { - - if (!m_drawingPoints) { + if (!drawingPoints) { // Set shadowless shader bindings dotShader->setUniformValue(dotShader->lightS(), lightStrength); // Draw the object - m_drawer->drawObject(dotShader, m_dotObj, gradientTexture); + m_drawer->drawObject(dotShader, dotObj, gradientTexture); } else { // Draw the object m_drawer->drawPoint(dotShader); @@ -666,10 +690,9 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) dotShader->release(); #if !defined(QT_OPENGL_ES_2) - if (m_drawingPoints) { + if (havePointSeries) { glDisable(GL_POINT_SMOOTH); glDisable(GL_PROGRAM_POINT_SIZE); - glEnable(GL_TEXTURE_2D); // Enable texturing for background } #endif @@ -1497,21 +1520,6 @@ void Scatter3DRenderer::updateShadowQuality(QDataVis::ShadowQuality quality) #endif } -void Scatter3DRenderer::loadMeshFile() -{ - if (m_dotObj) { - delete m_dotObj; - m_dotObj = 0; - } - if (m_cachedObjFile.isEmpty()) { - m_drawingPoints = true; - } else { - m_drawingPoints = false; - m_dotObj = new ObjectHelper(m_cachedObjFile); - m_dotObj->load(); - } -} - void Scatter3DRenderer::loadBackgroundMesh() { if (m_backgroundObj) @@ -1542,6 +1550,16 @@ 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, float min, float max) { diff --git a/src/datavisualization/engine/scatter3drenderer_p.h b/src/datavisualization/engine/scatter3drenderer_p.h index 6a0bbbec..104737eb 100644 --- a/src/datavisualization/engine/scatter3drenderer_p.h +++ b/src/datavisualization/engine/scatter3drenderer_p.h @@ -67,7 +67,6 @@ private: ShaderHelper *m_selectionShader; ShaderHelper *m_backgroundShader; ShaderHelper *m_labelShader; - ObjectHelper *m_dotObj; ObjectHelper *m_backgroundObj; ObjectHelper *m_gridLineObj; ObjectHelper *m_labelObj; @@ -89,7 +88,6 @@ private: GLfloat m_dotSizeScale; QVector3D m_translationOffset; bool m_hasHeightAdjustmentChanged; - bool m_drawingPoints; ScatterRenderItem m_dummyRenderItem; QVector<ScatterRenderItemArray> m_renderingArrays; @@ -106,12 +104,12 @@ public: protected: virtual void initializeOpenGL(); - virtual void loadMeshFile(); private: virtual void initShaders(const QString &vertexShader, const QString &fragmentShader); virtual void updateShadowQuality(QDataVis::ShadowQuality quality); virtual void updateTextures(); + virtual void fixMeshFileName(QString &fileName, QAbstract3DSeries::Mesh mesh); void drawScene(GLuint defaultFboHandle); void handleResize(); diff --git a/src/datavisualization/engine/seriesrendercache.cpp b/src/datavisualization/engine/seriesrendercache.cpp index 53bc97a1..7a4c0a14 100644 --- a/src/datavisualization/engine/seriesrendercache.cpp +++ b/src/datavisualization/engine/seriesrendercache.cpp @@ -17,11 +17,17 @@ ****************************************************************************/ #include "seriesrendercache_p.h" +#include "objecthelper_p.h" +#include "abstract3drenderer_p.h" QT_DATAVISUALIZATION_BEGIN_NAMESPACE +const QString smoothString(QStringLiteral("Smooth")); + SeriesRenderCache::SeriesRenderCache() - : m_series(0) + : m_series(0), + m_object(0), + m_mesh(QAbstract3DSeries::MeshCube) { } @@ -29,12 +35,89 @@ SeriesRenderCache::~SeriesRenderCache() { } -void SeriesRenderCache::populate(QAbstract3DSeries *series) +void SeriesRenderCache::populate(QAbstract3DSeries *series, Abstract3DRenderer *renderer) { Q_ASSERT(series); - m_series = series; - m_itemLabelFormat = series->itemLabelFormat(); + bool seriesChanged = false; + + if (m_series != series) { + m_series = series; + seriesChanged = true; + } + + QAbstract3DSeriesChangeBitField &changeTracker = series->d_ptr->m_changeTracker; + + if (seriesChanged || changeTracker.itemLabelFormatChanged) { + m_itemLabelFormat = series->itemLabelFormat(); + changeTracker.itemLabelFormatChanged = false; + } + + if (seriesChanged || changeTracker.meshChanged || changeTracker.meshSmoothChanged + || changeTracker.userDefinedMeshChanged) { + m_mesh = series->mesh(); + changeTracker.meshChanged = false; + changeTracker.meshSmoothChanged = false; + changeTracker.userDefinedMeshChanged = false; + + QString meshFileName; + + // Compose mesh filename + if (m_mesh == QAbstract3DSeries::MeshUserDefined) { + // Always use the supplied mesh directly + meshFileName = series->userDefinedMesh(); + } else { + switch (m_mesh) { + case QAbstract3DSeries::MeshBar: + case QAbstract3DSeries::MeshCube: + meshFileName = QStringLiteral(":/defaultMeshes/bar"); + break; + case QAbstract3DSeries::MeshPyramid: + meshFileName = QStringLiteral(":/defaultMeshes/pyramid"); + break; + case QAbstract3DSeries::MeshCone: + meshFileName = QStringLiteral(":/defaultMeshes/cone"); + break; + case QAbstract3DSeries::MeshCylinder: + meshFileName = QStringLiteral(":/defaultMeshes/cylinder"); + break; + case QAbstract3DSeries::MeshBevelBar: + case QAbstract3DSeries::MeshBevelCube: + meshFileName = QStringLiteral(":/defaultMeshes/bevelbar"); + break; + case QAbstract3DSeries::MeshSphere: + meshFileName = QStringLiteral(":/defaultMeshes/sphere"); + break; + case QAbstract3DSeries::MeshMinimal: + meshFileName = QStringLiteral(":/defaultMeshes/minimal"); + break; + case QAbstract3DSeries::MeshPoint: +#if defined(QT_OPENGL_ES_2) + qWarning("QAbstract3DSeries::MeshPoint is not fully supported on OpenGL ES2"); +#endif + break; + default: + // Default to cube + meshFileName = QStringLiteral(":/defaultMeshes/bar"); + break; + } + + if (series->isMeshSmooth() && m_mesh != QAbstract3DSeries::MeshPoint) + meshFileName += smoothString; + + // Give renderer an opportunity to customize the mesh + renderer->fixMeshFileName(meshFileName, m_mesh); + } + + // TODO: Optimize by having some kind of object cache in renderer instead of having separate ObjectHelper for each series? + delete m_object; + if (meshFileName.isEmpty()) { + m_object = 0; + } else { + m_object = new ObjectHelper(meshFileName); + m_object->load(); + } + } // TODO: Add other visual element extractions } diff --git a/src/datavisualization/engine/seriesrendercache_p.h b/src/datavisualization/engine/seriesrendercache_p.h index 34b1d97d..976b69c3 100644 --- a/src/datavisualization/engine/seriesrendercache_p.h +++ b/src/datavisualization/engine/seriesrendercache_p.h @@ -34,27 +34,35 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE +class Abstract3DRenderer; +class ObjectHelper; + class SeriesRenderCache { public: SeriesRenderCache(); virtual ~SeriesRenderCache(); - void populate(QAbstract3DSeries *series); - - inline const QString &itemLabelFormat() const { return m_itemLabelFormat; } + void populate(QAbstract3DSeries *series, Abstract3DRenderer *renderer); // NOTE: Series pointer can only be used to access the series when syncing with controller. // It is not guaranteed to be valid while rendering and should only be used as an identifier. inline QAbstract3DSeries *series() const { return m_series; } + inline const QString &itemLabelFormat() const { return m_itemLabelFormat; } + inline const QAbstract3DSeries::Mesh &mesh() const { return m_mesh; } + inline ObjectHelper *object() const { return m_object; } + // TODO: Add other visual elements protected: - QString m_itemLabelFormat; QAbstract3DSeries *m_series; + QString m_itemLabelFormat; + ObjectHelper *m_object; + QAbstract3DSeries::Mesh m_mesh; }; QT_DATAVISUALIZATION_END_NAMESPACE #endif + diff --git a/src/datavisualization/engine/surface3drenderer.cpp b/src/datavisualization/engine/surface3drenderer.cpp index df4a12f0..b0df81d1 100644 --- a/src/datavisualization/engine/surface3drenderer.cpp +++ b/src/datavisualization/engine/surface3drenderer.cpp @@ -1940,12 +1940,6 @@ QString Surface3DRenderer::createSelectionLabel(float value, int column, int row return labelText; } -void Surface3DRenderer::loadMeshFile() -{ - // Do nothing, not yet supported by this renderer - // TODO: To be used for overriding the selection ball mesh after technology preview -} - void Surface3DRenderer::updateShadowQuality(QDataVis::ShadowQuality quality) { m_cachedShadowQuality = quality; diff --git a/src/datavisualization/engine/surface3drenderer_p.h b/src/datavisualization/engine/surface3drenderer_p.h index 9c1be32b..ce49cf13 100644 --- a/src/datavisualization/engine/surface3drenderer_p.h +++ b/src/datavisualization/engine/surface3drenderer_p.h @@ -147,7 +147,6 @@ public: protected: void initializeOpenGL(); - virtual void loadMeshFile(); signals: void pointClicked(QPoint position, QSurface3DSeries *series); |