#include "colormap.h" #include #include class ColormapTexture { public: ColormapTexture(const std::vector &cmap, Colormap::Orientation orientation = Colormap::Horizontal); ~ColormapTexture(); bool hasAlphaChannel() const { return false; } bool hasMipmaps() const { return false; } void bind(); bool updateTexture(); int textureId() const { return m_texture; } size_t width() const { return m_width; } size_t height() const { return m_height; } void setOrientation(Colormap::Orientation orientation); private: Colormap::Orientation m_orientation; // QSize m_size; size_t m_width, m_height; GLuint m_texture; const std::vector &m_cmap; }; ColormapTexture::ColormapTexture(const std::vector &cmap, Colormap::Orientation orientation) : m_cmap(cmap) , m_width(0) , m_height(0) { // Setup OpenGL texture glGenTextures(1, &m_texture); glBindTexture(GL_TEXTURE_2D, m_texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); setOrientation(orientation); } ColormapTexture::~ColormapTexture() { glDeleteTextures(1, &m_texture); } void ColormapTexture::bind() { glBindTexture(GL_TEXTURE_2D, m_texture); } void ColormapTexture::setOrientation(Colormap::Orientation orientation) { if (m_orientation == orientation) { return; } m_orientation = orientation; updateTexture(); } bool ColormapTexture::updateTexture() { switch (m_orientation) { case Colormap::Horizontal: m_width = m_cmap.size() / 3; m_height = 1; break; case Colormap::Vertical: m_width = 1; m_height = m_cmap.size() / 3; break; } glBindTexture(GL_TEXTURE_2D, m_texture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, m_width, m_height, 0, GL_RGB, GL_FLOAT, m_cmap.data()); return true; } Colormap::Colormap() : m_shouldUpdateTexture(false) , m_orientation(Colormap::Horizontal) { } Colormap::~Colormap() { } void Colormap::update() { } static void reverseCMap(std::vector &cmap) { decltype(cmap.size()) i = 0, j = cmap.size() - 3; while (i < j) { std::swap(cmap[i++], cmap[j++]); std::swap(cmap[i++], cmap[j++]); std::swap(cmap[i++], cmap[j++]); j -= 6; } } void Colormap::setOrientation(Colormap::Orientation orientation) { if (m_orientation == orientation) { return; } if (!m_cmap.empty()) { reverseCMap(m_cmap); } m_orientation = orientation; m_shouldUpdateOrientation = true; update(); } void Colormap::setColorScale(std::shared_ptr scale) { m_cmap.resize(SAMPLES * 3); scale->sample(SAMPLES, m_cmap.data()); if (m_orientation == Colormap::Vertical) { reverseCMap(m_cmap); } 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); node->setSourceRect(0, 0, m_texture->width(), m_texture->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()); ColormapTexture *texture = static_cast(m_texture); if (m_shouldUpdateOrientation) { texture->setOrientation(m_orientation); m_shouldUpdateOrientation = false; } if (m_shouldUpdateTexture) { texture->updateTexture(); m_shouldUpdateTexture = false; } return root; } */