#include "colormap.h" #include <algorithm> #include <glad/gl.h> Colormap::Colormap() : m_width(0) , m_height(0) , m_shouldUpdateTexture(false) , m_orientation(Colormap::Horizontal) { 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); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); } Colormap::~Colormap() { glDeleteTextures(1, &m_texture); } void Colormap::update() { if (m_shouldUpdateTexture) { updateTexture(); } } void Colormap::updateTexture() { if (m_cmap.empty()) { return; } 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_RGB32F, m_width, m_height, 0, GL_RGB, GL_FLOAT, m_cmap.data()); } static void reverseCMap(std::vector<float> &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_shouldUpdateTexture = true; update(); } void Colormap::setColorScale(std::shared_ptr<const ColorScale> 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(); }