Program Listing for File DiscreteColor.h
↰ Return to documentation for file (include/flamegpu/visualiser/color/DiscreteColor.h
)
#ifndef INCLUDE_FLAMEGPU_VISUALISER_COLOR_DISCRETECOLOR_H_
#define INCLUDE_FLAMEGPU_VISUALISER_COLOR_DISCRETECOLOR_H_
#include <map>
#include <string>
#include <sstream>
#include "flamegpu/exception/FLAMEGPUException.h"
#include "flamegpu/visualiser/color/ColorFunction.h"
#include "flamegpu/visualiser/color/Color.h"
namespace flamegpu {
namespace visualiser {
struct Palette;
template<typename T = int32_t>
class DiscreteColor : public ColorFunction, public std::map<T, Color> {
public:
DiscreteColor(const std::string& variable_name, const Color &fallback);
DiscreteColor(const std::string& variable_name, const Palette& palette, const Color& fallback, T offset = 0, T stride = 1);
DiscreteColor(const std::string& variable_name, const Palette& palette, T offset = 0, T stride = 1);
std::string getSrc(unsigned int array_len) const override;
std::string getSamplerName() const override;
std::string getAgentVariableName() const override;
std::type_index getAgentVariableRequiredType() const override;
bool validate() const;
private:
Color fallback;
const std::string variable_name;
};
typedef DiscreteColor<uint32_t> uDiscreteColor;
typedef DiscreteColor<int32_t> iDiscreteColor;
// Define this here, so the static assert can give a better compile error for unwanted template instantiations
template<typename T>
std::string DiscreteColor<T>::getSrc(const unsigned int array_len) const {
static_assert(std::is_same<T, int32_t>::value || std::is_same<T, uint32_t>::value, "T must be of type int32_t or uint32_t");
// Validate colors
if (!validate()) {
THROW exception::InvalidOperation("DiscreteColor contains invalid color!");
}
std::stringstream ss;
ss << "uniform samplerBuffer color_arg;" << "\n";
ss << "vec4 calculateColor() {" << "\n";
// Fetch discrete value
if (std::is_same<T, int32_t>::value) {
ss << " const int category = floatBitsToInt(texelFetch(color_arg, gl_InstanceID * " << array_len << " + " << element << ").x);" << "\n";
} else if (std::is_same<T, uint32_t>::value) {
ss << " const unsigned int category = floatBitsToUint(texelFetch(color_arg, gl_InstanceID * " << array_len << " + " << element << ").x);" << "\n";
}
// Select the desired color
ss << " switch (category) {" << "\n";
for (const auto& m : *this)
ss << " case " << m.first << ": return vec4(" << m.second[0] << ", " << m.second[1] << ", " << m.second[2] << ", 1);" << "\n";
// Fallback value
ss << " default: return vec4(" << fallback[0] << ", " << fallback[1] << ", " << fallback[2] << ", 1);" << "\n";
ss << " }" << "\n";
ss << "}" << "\n";
return ss.str();
}
} // namespace visualiser
} // namespace flamegpu
#endif // INCLUDE_FLAMEGPU_VISUALISER_COLOR_DISCRETECOLOR_H_