16 typedef float opacity_type;
17 typedef std::pair<opacity_type, color_type> sample_point_type;
18 typedef cgv::math::control_point_container<color_type>::control_point_type color_control_point_type;
19 typedef cgv::math::control_point_container<opacity_type>::control_point_type opacity_control_point_type;
24 std::shared_ptr<cgv::math::interpolator<rgb>> color_interpolator_ptr =
nullptr;
25 std::shared_ptr<cgv::math::interpolator<float>> opacity_interpolator_ptr =
nullptr;
32 void construct_interpolators() {
34 color_interpolator_ptr = std::make_shared<cgv::math::piecewise_linear_interpolator<rgb>>();
35 opacity_interpolator_ptr = std::make_shared<cgv::math::piecewise_linear_interpolator<float>>();
37 color_interpolator_ptr = std::make_shared<cgv::math::piecewise_nearest_interpolator<rgb>>();
38 opacity_interpolator_ptr = std::make_shared<cgv::math::piecewise_nearest_interpolator<float>>();
44 construct_interpolators();
47 color_map(
const std::initializer_list<color_control_point_type> color_points) : color_map() {
48 this->color_points.assign(color_points);
51 color_map(
const std::initializer_list<color_type> colors) : color_map() {
52 std::vector<color_control_point_type> color_points;
53 color_points.reserve(colors.size());
55 float step_size = 0.0f;
57 step_size = 1.0f /
static_cast<float>(colors.size());
60 for(
const color_type& color : colors) {
61 color_points.push_back({
static_cast<float>(i) * step_size, color });
65 this->color_points.assign(color_points);
68 color_map(
const std::initializer_list<opacity_control_point_type> opacity_points) : color_map() {
69 this->opacity_points.assign(opacity_points);
72 color_map(
const std::initializer_list<opacity_type> opacities) : color_map() {
73 std::vector<opacity_control_point_type> opacity_points;
74 opacity_points.reserve(opacities.size());
76 float step_size = 0.0f;
77 if(opacities.size() > 0)
78 step_size = 1.0f /
static_cast<float>(opacities.size());
81 for(
const opacity_type& opacity : opacities) {
82 opacity_points.push_back({
static_cast<float>(i) * step_size, opacity });
86 this->opacity_points.assign(opacity_points);
89 color_map(
const std::initializer_list<std::pair<float, sample_point_type>> control_points) : color_map() {
90 std::vector<color_control_point_type> color_points;
91 std::vector<opacity_control_point_type> opacity_points;
92 color_points.reserve(control_points.size());
93 opacity_points.reserve(control_points.size());
94 for(
const std::pair<float, sample_point_type>& control_point : control_points) {
95 color_points.push_back({ control_point.first, color_type(control_point.second.second) });
96 opacity_points.push_back({ control_point.first, control_point.second.first });
99 this->color_points.assign(color_points);
100 this->opacity_points.assign(opacity_points);
103 virtual ~color_map() {}
105 virtual bool has_texture_support()
const {
110 color_points.clear();
111 opacity_points.clear();
114 void clear_color_points() {
115 color_points.clear();
118 void clear_opacity_points() {
119 opacity_points.clear();
123 return color_points.empty() && opacity_points.empty();
126 unsigned get_resolution()
const {
return resolution; }
134 void enable_interpolation(
bool enabled) {
136 construct_interpolators();
143 for(
const color_control_point_type& color_point : color_points)
144 flipped_color_points.push_back(1.0f - color_point.first, color_point.second);
146 for(
const opacity_control_point_type& opacity_point : opacity_points)
147 flipped_opacity_points.push_back(1.0f - opacity_point.first, opacity_point.second);
149 color_points = flipped_color_points;
150 opacity_points = flipped_opacity_points;
153 void apply_gamma(
float gamma) {
156 for(
const color_control_point_type& color_point : color_points)
157 corrected_color_points.push_back(color_point.first,
cgv::media::pow(color_point.second, gamma));
159 color_points = corrected_color_points;
162 void add_color_point(
float t,
rgb color) {
163 t = cgv::math::clamp(t, 0.0f, 1.0f);
164 color_points.push_back(t, color);
167 void add_opacity_point(
float t,
float opacity) {
168 t = cgv::math::clamp(t, 0.0f, 1.0f);
169 opacity_points.push_back(t, opacity);
172 const std::vector<color_control_point_type>& ref_color_points()
const {
return color_points.ref_points(); }
173 const std::vector<opacity_control_point_type>& ref_opacity_points()
const {
return opacity_points.ref_points(); }
175 rgb interpolate_color(
float t)
const {
176 return color_interpolator_ptr->interpolate(color_points, t);
179 std::vector<rgb> interpolate_color(
size_t n)
const {
180 return color_interpolator_ptr->interpolate(color_points, n);
183 float interpolate_opacity(
float t)
const {
184 return opacity_interpolator_ptr->interpolate(opacity_points, t);
187 std::vector<float> interpolate_opacity(
size_t n)
const {
188 return opacity_interpolator_ptr->interpolate(opacity_points, n);
191 rgba interpolate(
float t)
const {
192 rgb color = interpolate_color(t);
193 float opacity = interpolate_opacity(t);
195 return rgba(color.R(), color.G(), color.B(), opacity);
198 std::vector<rgba> interpolate(
size_t n)
const {
199 const std::vector<rgb>& colors = interpolate_color(n);
200 const std::vector<float>& opacities = interpolate_opacity(n);
202 std::vector<rgba> data(n);
203 for(
size_t i = 0; i < n; ++i) {
204 const rgb& color = colors[i];
205 data[i] =
rgba(color.R(), color.G(), color.B(), opacities[i]);
222 void setup_texture(
bool use_opacity) {
223 std::string format = use_opacity ?
"uint8[R,G,B,A]" :
"uint8[R,G,B]";
225 tex =
texture(format, filter, filter);
228 void generate_rgb_texture(context& ctx) {
229 std::vector<rgb> data = interpolate_color(
static_cast<size_t>(
resolution));
231 std::vector<uint8_t> data_8(3 * data.size());
232 for(
size_t i = 0; i < data.size(); ++i) {
234 data_8[3 * i + 0] =
static_cast<uint8_t
>(255.0f * col.R());
235 data_8[3 * i + 1] =
static_cast<uint8_t
>(255.0f * col.G());
236 data_8[3 * i + 2] =
static_cast<uint8_t
>(255.0f * col.B());
241 unsigned width = (unsigned)tex.
get_width();
243 bool replaced =
false;
248 replaced = tex.
replace(ctx, 0, dv);
253 setup_texture(
false);
258 void generate_rgba_texture(context& ctx) {
259 std::vector<rgba> data = interpolate(
static_cast<size_t>(
resolution));
261 std::vector<uint8_t> data_8(4 * data.size());
262 for(
size_t i = 0; i < data.size(); ++i) {
264 data_8[4 * i + 0] =
static_cast<uint8_t
>(255.0f * col.R());
265 data_8[4 * i + 1] =
static_cast<uint8_t
>(255.0f * col.G());
266 data_8[4 * i + 2] =
static_cast<uint8_t
>(255.0f * col.B());
267 data_8[4 * i + 3] =
static_cast<uint8_t
>(255.0f * col.alpha());
272 unsigned width = (unsigned)tex.
get_width();
274 bool replaced =
false;
279 replaced = tex.
replace(ctx, 0, dv);
290 gl_color_map() : color_map() {}
292 gl_color_map(
unsigned resolution) : gl_color_map() {
296 gl_color_map(
const color_map& cm) : gl_color_map() {
300 construct_interpolators();
302 for(
auto& p : cm.ref_color_points())
303 add_color_point(p.first, p.second);
304 for(
auto& p : cm.ref_opacity_points())
305 add_opacity_point(p.first, p.second);
308 virtual ~gl_color_map() {
312 virtual bool has_texture_support()
const {
320 bool destruct(context& ctx) {
328 void enable_linear_filtering(
bool enabled) {
330 construct_interpolators();
333 bool init(context& ctx) {
338 setup_texture(
false);
339 return tex.
create(ctx, dv, 0);
342 void generate_texture(context& ctx) {
344 if(ref_opacity_points().size() > 0)
345 generate_rgba_texture(ctx);
347 generate_rgb_texture(ctx);
350 texture& ref_texture() {
return tex; }
the texture class encapsulates all functionality independent of the rendering api.
void set_mag_filter(TextureFilter _mag_filter)
set the magnification filter
bool create(const context &ctx, TextureType _tt=TT_UNDEF, unsigned width=-1, unsigned height=-1, unsigned depth=-1)
create the texture of dimension and resolution specified in the data format base class.
bool destruct(const context &ctx)
destruct the texture and free texture memory and handle
bool replace(const context &ctx, int x, const cgv::data::const_data_view &data, int level=-1, const std::vector< cgv::data::data_view > *palettes=0)
replace a block within a 1d texture with the given data.
void set_min_filter(TextureFilter _min_filter, float _anisotropy=2.0f)
set the minification filters, if minification is set to TF_ANISOTROP, the second floating point param...