diff options
author | Samuel Fadel <samuelfadel@gmail.com> | 2015-09-03 14:31:52 -0300 |
---|---|---|
committer | Samuel Fadel <samuelfadel@gmail.com> | 2015-09-03 14:31:52 -0300 |
commit | e05a1bd658a7bacb4e13f05b7125ceed7a33dd4b (patch) | |
tree | fbd6c8bca9368f33b2e26094610d08a0300c5d7f /scatterplot.cpp | |
parent | a1956a4ff879eb2d34c7a0ca448f48ee6e64ce99 (diff) |
Updated Scatteplot's drawing code.
- All glyphs use the same geometry, placement is done via affine transforms
- Geometry memory handled using unique_ptr
- Added outline to each glyph, avoiding color issues with the background
Diffstat (limited to 'scatterplot.cpp')
-rw-r--r-- | scatterplot.cpp | 52 |
1 files changed, 37 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); |