diff options
-rw-r--r-- | scatterplot.cpp | 52 | ||||
-rw-r--r-- | scatterplot.h | 2 |
2 files changed, 39 insertions, 15 deletions
diff --git a/scatterplot.cpp b/scatterplot.cpp index 0a252e1..ce8f590 100644 --- a/scatterplot.cpp +++ b/scatterplot.cpp @@ -1,10 +1,14 @@ #include "scatterplot.h" +#include <QMatrix4x4> #include <cmath> static const qreal GLYPH_OPACITY = 0.4; static const qreal GLYPH_OPACITY_SELECTED = 1.0; -static const QColor SELECTION_COLOR(QColor(128, 128, 128, 96)); + +static const QColor OUTLINE_COLOR(0, 0, 0); +static const QColor SELECTION_COLOR(128, 128, 128, 96); + static const int GLYPH_SIZE = 8; static const float PADDING = 10; static const float PI = 3.1415f; @@ -123,22 +127,40 @@ QSGNode *Scatterplot::createGlyphNodeTree() QSGNode *node = new QSGNode; int vertexCount = calculateCircleVertexCount(GLYPH_SIZE / 2); - for (arma::uword i = 0; i < m_xy.n_rows; i++) { - QSGGeometryNode *glyphNode = new QSGGeometryNode; + m_glyphGeometryPtr.reset(new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), vertexCount)); + QSGGeometry *glyphGeometry = m_glyphGeometryPtr.get(); + glyphGeometry->setDrawingMode(GL_POLYGON); + updateCircleGeometry(glyphGeometry, GLYPH_SIZE, 0, 0); + + m_glyphOutlineGeometryPtr.reset(new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), vertexCount)); + QSGGeometry *glyphOutlineGeometry = m_glyphOutlineGeometryPtr.get(); + glyphOutlineGeometry->setDrawingMode(GL_LINE_LOOP); + updateCircleGeometry(glyphOutlineGeometry, GLYPH_SIZE + 1, 0, 0); - QSGGeometry *geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), vertexCount); - geometry->setDrawingMode(GL_POLYGON); - glyphNode->setGeometry(geometry); - glyphNode->setFlag(QSGNode::OwnsGeometry); + for (arma::uword i = 0; i < m_xy.n_rows; i++) { + QSGGeometryNode *glyphOutlineNode = new QSGGeometryNode; + glyphOutlineNode->setGeometry(glyphOutlineGeometry); QSGFlatColorMaterial *material = new QSGFlatColorMaterial; + material->setColor(OUTLINE_COLOR); + glyphOutlineNode->setMaterial(material); + glyphOutlineNode->setFlag(QSGNode::OwnsMaterial); + + QSGGeometryNode *glyphNode = new QSGGeometryNode; + glyphNode->setGeometry(glyphGeometry); + + material = new QSGFlatColorMaterial; material->setColor(QColor()); glyphNode->setMaterial(material); glyphNode->setFlag(QSGNode::OwnsMaterial); + QSGTransformNode *transformNode = new QSGTransformNode; + transformNode->appendChildNode(glyphNode); + transformNode->appendChildNode(glyphOutlineNode); + // Place the glyph geometry node under an opacity node QSGOpacityNode *glyphOpacityNode = new QSGOpacityNode; - glyphOpacityNode->appendChildNode(glyphNode); + glyphOpacityNode->appendChildNode(transformNode); node->appendChildNode(glyphOpacityNode); } @@ -150,7 +172,8 @@ QSGNode *Scatterplot::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) if (m_xy.n_rows < 1) return 0; - qreal x, y, tx, ty, moveTranslationF; + QMatrix4x4 matrix; + qreal tx, ty, moveTranslationF; QSGNode *root = 0; if (!oldNode) { @@ -173,16 +196,15 @@ QSGNode *Scatterplot::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) QSGOpacityNode *glyphOpacityNode = static_cast<QSGOpacityNode *>(node); glyphOpacityNode->setOpacity(isSelected ? GLYPH_OPACITY_SELECTED : GLYPH_OPACITY); - QSGGeometryNode *glyphNode = static_cast<QSGGeometryNode *>(node->firstChild()); + QSGTransformNode *transformNode = static_cast<QSGTransformNode *>(node->firstChild()); if (m_shouldUpdateGeometry) { - QSGGeometry *geometry = glyphNode->geometry(); moveTranslationF = isSelected ? 1.0 : 0.0; - x = fromDataXToScreenX(row[0]) + tx * moveTranslationF; - y = fromDataYToScreenY(row[1]) + ty * moveTranslationF; - updateCircleGeometry(geometry, GLYPH_SIZE, x, y); - glyphNode->markDirty(QSGNode::DirtyGeometry); + matrix(0, 3) = fromDataXToScreenX(row[0]) + tx * moveTranslationF; + matrix(1, 3) = fromDataYToScreenY(row[1]) + ty * moveTranslationF; + transformNode->setMatrix(matrix); } if (m_shouldUpdateMaterials) { + QSGGeometryNode *glyphNode = static_cast<QSGGeometryNode *>(transformNode->firstChild()); QSGFlatColorMaterial *material = static_cast<QSGFlatColorMaterial *>(glyphNode->material()); material->setColor(m_colorScale->color(m_colorData[i])); glyphNode->setMaterial(material); diff --git a/scatterplot.h b/scatterplot.h index 7ed58c8..4275561 100644 --- a/scatterplot.h +++ b/scatterplot.h @@ -1,6 +1,7 @@ #ifndef SCATTERPLOT_H #define SCATTERPLOT_H +#include <memory> #include <armadillo> #include <QtQuick> @@ -54,6 +55,7 @@ private: QSet<int> m_selectedGlyphs; + std::unique_ptr<QSGGeometry> m_glyphGeometryPtr, m_glyphOutlineGeometryPtr; bool m_shouldUpdateGeometry, m_shouldUpdateMaterials; arma::vec m_colorData; |