From 4c066a82962a9a0634dcfe0a305de7b2a4cacc5b Mon Sep 17 00:00:00 2001 From: Samuel Fadel Date: Sat, 16 Jan 2016 20:55:45 +0100 Subject: Added the Colormap component. * The Colormap component is a simple rect with a texture mapped that displays a ColorScale with a fixed number of samples. This number of samples is exported as a member const, which is used on other components (such as VoronoiSplat). * The texture mapping is reflecting the colormap lookup used in VoronoiSplat. * The ColorScale class now has a method for sampling the color scale and outputs the samples to iterator-style objects, providing easy intergration with existing code. --- colormap.cpp | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 colormap.cpp (limited to 'colormap.cpp') diff --git a/colormap.cpp b/colormap.cpp new file mode 100644 index 0000000..545151f --- /dev/null +++ b/colormap.cpp @@ -0,0 +1,113 @@ +#include "colormap.h" + +#include +#include + +class ColormapTexture + : public QSGDynamicTexture +{ +public: + ColormapTexture(const std::vector *cmap); + ~ColormapTexture(); + + bool hasAlphaChannel() const { return false; } + bool hasMipmaps() const { return false; } + void bind(); + bool updateTexture(); + + int textureId() const { return m_texture; } + QSize textureSize() const { return m_size; } + +private: + QOpenGLFunctions gl; + + QSize m_size; + GLuint m_texture; + const std::vector *m_cmap; +}; + +ColormapTexture::ColormapTexture(const std::vector *cmap) + : gl(QOpenGLContext::currentContext()) + , m_size(Colormap::SAMPLES, 1) + , m_cmap(cmap) +{ + // Setup OpenGL texture + gl.glGenTextures(1, &m_texture); + gl.glBindTexture(GL_TEXTURE_2D, m_texture); + gl.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, m_size.width(), m_size.height(), + 0, GL_RGB, GL_FLOAT, 0); + gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); +} + +ColormapTexture::~ColormapTexture() +{ + gl.glDeleteTextures(1, &m_texture); +} + +void ColormapTexture::bind() +{ + gl.glBindTexture(GL_TEXTURE_2D, m_texture); +} + +bool ColormapTexture::updateTexture() +{ + gl.glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_size.width(), m_size.height(), + GL_RGB, GL_FLOAT, m_cmap->data()); + return true; +} + +Colormap::Colormap(QQuickItem *parent) + : QQuickItem(parent) + , m_texture(0) + , m_shouldUpdateTexture(false) + , m_cmap(3*SAMPLES) +{ + setFlag(QQuickItem::ItemHasContents); +} + +Colormap::~Colormap() +{ + if (m_texture) { + delete m_texture; + } +} + + +void Colormap::setColorScale(const ColorScale &scale) +{ + scale.sample(SAMPLES, m_cmap.begin()); + emit colorScaleChanged(scale); + + m_shouldUpdateTexture = true; + update(); +} + +QSGNode *Colormap::newSceneGraph() +{ + QSGSimpleTextureNode *node = new QSGSimpleTextureNode; + m_texture = new ColormapTexture(&m_cmap); + + node->setTexture(m_texture); + node->setOwnsTexture(false); + + const QSize &texSize = m_texture->textureSize(); + node->setSourceRect(0, 0, texSize.width(), texSize.height()); + + return node; +} + +QSGNode *Colormap::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) +{ + QSGNode *root = oldNode ? oldNode : newSceneGraph(); + + QSGSimpleTextureNode *node = static_cast(root); + node->setRect(x(), y(), width(), height()); + + if (m_shouldUpdateTexture) { + m_texture->updateTexture(); + m_shouldUpdateTexture = false; + } + + return root; +} -- cgit v1.2.3