cgv
Loading...
Searching...
No Matches
image_drawable.cxx
1#include "image_drawable.h"
2
3#include <cgv/media/image/image_reader.h>
4#include <cgv/media/image/image_writer.h>
5#include <cgv/media/axis_aligned_box.h>
6#include <cgv/base/import.h>
7#include <cgv/math/ftransform.h>
8#include <cgv/render/attribute_array_binding.h>
9#include <cgv_gl/gl/gl_tools.h>
10#include <cgv_gl/gl/gl.h>
11
12using namespace cgv::base;
13using namespace cgv::data;
14using namespace cgv::render;
15using namespace cgv::utils;
16using namespace cgv::media::image;
17
18namespace cgv {
19 namespace render {
20 namespace gl {
21
22image_drawable::image_drawable() : min_value(0,0,0,0), max_value(1,1,1,1), gamma4(1,1,1,1)
23{
24 aspect = 1;
25 start_time = -2;
26 use_blending = false;
27 animate = false;
28 show_selection = false;
29 selection.add_point(ivec2(100, 50));
30 selection.add_point(ivec2(300, 150));
31 W = 1;
32 H = 1;
33
34 use_mixing = false;
35 mix_with = -1;
36 mix_param = 0.0f;
37 tess_level = 64.0f;
38 wireframe = false;
39
40 spherical = false;
41 pan_tilt = vec2(0.0f);
42 scale = 1.0f;
43 k1 = k2 = k3 = k4 = k5 = k6 = p1 = p2 = 0.0f;
44 checker_lambda = 0.0f;
45 cx = cy = 0.0f;
46 s = 1.0f;
47}
48
49void image_drawable::timer_event(double t, double dt)
50{
51 if (tex_ids.size() > 1 && start_time != -2) {
52 if (animate) {
53 if (start_time == -1) {
54 start_time = t;
55 anim_time = 0;
56 for (unsigned i = 0; i<current_image; ++i) {
57 start_time -= durations[i];
58 anim_time += durations[i];
59 }
60 }
61 else {
62 dt = t-start_time;
63 if (dt > anim_time+durations[current_image]) {
64 while (dt > anim_time+durations[current_image]) {
65 anim_time += durations[current_image];
66 ++current_image;
67 if (current_image >= tex_ids.size()) {
68 dt -= anim_time;
69 start_time += anim_time;
70 anim_time = 0;
71 current_image = 0;
72 }
73 }
75 }
76 }
77 }
78 else
79 start_time = -1;
80 }
81}
82
84{
85 struct vertex {
86 vec2 position;
87 vec2 texcoord;
88 };
89 std::vector<vertex> V;
90 V.push_back({ vec2(-1.0f,-1.0f), vec2(0.0f,0.0f) });
91 V.push_back({ vec2( 1.0f,-1.0f), vec2(1.0f,0.0f) });
92 V.push_back({ vec2( 1.0f, 1.0f), vec2(1.0f,1.0f) });
93 V.push_back({ vec2(-1.0f, 1.0f), vec2(0.0f,1.0f) });
94 vbo.create(ctx, V);
95 aab.create(ctx);
96 aab.set_attribute_array(ctx, 0, cgv::render::get_element_type(V.front().position), vbo, 0, V.size(), sizeof(vertex));
97 aab.enable_array(ctx, 0);
98 aab.set_attribute_array(ctx, 1, cgv::render::get_element_type(V.front().texcoord), vbo, offsetof(vertex, texcoord), V.size(), sizeof(vertex));
99 aab.enable_array(ctx, 1);
100 return prog.build_program(ctx, "image.glpr");
101}
102
105{
106 aab.destruct(ctx);
107 vbo.destruct(ctx);
108 prog.destruct(ctx);
109 if (!tex_ids.empty())
110 glDeleteTextures(GLsizei(tex_ids.size()), &tex_ids.front());
111}
112
114{
115 if (!cgv::render::gl::read_image_to_textures(_file_name, tex_ids, durations, true, &aspect, &use_blending))
116 return false;
117 data_format df;
118 image_reader ir(df);
119 ir.open(_file_name);
120 W = int(df.get_width());
121 H = int(df.get_height());
125 current_image = 0;
126 start_time = -2;
127 file_name = _file_name;
128 files.clear();
129 post_redraw();
130 return true;
131}
132
133bool image_drawable::read_images(const std::string& _file_name, const std::vector<std::string>& _files)
134{
135 for (unsigned i=0; i<_files.size(); ++i) {
137 true, &aspect, &use_blending);
138 if (tex_id == -1)
139 return false;
140 tex_ids.push_back(tex_id);
141 durations.push_back(0.04f);
142 std::cout << "read image " << _file_name+"/"+_files[i] << std::endl;
143 }
144 if (!_files.empty()) {
145 data_format df;
146 image_reader ir(df);
147 ir.open(_file_name+"/"+_files[0]);
148 W = int(df.get_width());
149 H = int(df.get_height());
153 }
154 current_image = 0;
155 start_time = -2;
156 file_name = _file_name;
157 files = _files;
158 post_redraw();
159 return true;
160}
161
163{
164 bool crop = (selection.get_min_pnt() != ivec2(0) || selection.get_max_pnt() != ivec2(W,H));
165 int w = selection.get_extent()(0);
166 int h = selection.get_extent()(1);
167
168 // prepare output
170
171 unsigned nr = 1;
172 if (files.size() > nr)
173 nr = (unsigned)files.size();
174
175 for (unsigned i=0; i<nr; ++i) {
176 std::string input_file_name = file_name;
177 if (i < files.size()) {
178 input_file_name += '/';
179 input_file_name += files[i];
180 }
181
182 std::vector<data_format> palette_formats;
183 std::vector<data_view> palettes;
184 data_view dv;
185 data_format df;
186 image_reader ir(df, &palette_formats);
187 // open image
188 if (!ir.open(input_file_name)) {
189 std::cerr << ir.get_last_error().c_str() << std::endl;
190 return false;
191 }
192 palettes.resize(palette_formats.size());
193
194 data_format* df_out = &df;
195 data_view* dv_out = &dv;
196 if (crop) {
197 df_out = new data_format(df);
198 df_out->set_width(w);
199 df_out->set_height(h);
200 dv_out = new data_view(df_out);
201 }
202 // query number of images
203 unsigned nr = ir.get_nr_images();
204
205 for (unsigned i=0; i<nr; ++i) {
206 // query palettes
207 for (unsigned j=0; j<palette_formats.size(); ++j) {
208 if (!ir.read_palette(j, palettes[j]))
209 return false;
210 }
211 double duration = ir.get_image_duration();
212 if (!ir.read_image(dv)) {
213 std::cerr << ir.get_last_error() << std::endl;
214 return false;
215 }
216 if (crop) {
217 unsigned char* src_ptr = dv.get_ptr<unsigned char>() +
220
221 unsigned char* dst_ptr = dv_out->get_ptr<unsigned char>();
222 for (int j=0; j<h; ++j) {
223 memcpy(dst_ptr, src_ptr, dv_out->get_step_size(0));
224 dst_ptr += dv_out->get_step_size(0);
225 src_ptr += dv.get_step_size(0);
226 }
227 }
228 if (!iw.write_image(*dv_out, (std::vector<const_data_view>*)(&palettes))) {
229 std::cerr << iw.get_last_error() << std::endl;
230 return false;
231 }
232 }
233 if (crop) {
234 delete dv_out;
235 delete df_out;
236 }
237 }
238 return true;
239}
240
242{
244 ctx.mul_modelview_matrix(cgv::math::scale4<double>(aspect, 1, 1));
245 if (show_selection) {
247 ctx.mul_modelview_matrix(cgv::math::translate4<double>(-1, -1, 0) * cgv::math::scale4<double>(2.0 / W, 2.0 / H, 1));
248 float x = (float)selection.get_min_pnt()(0);
249 float y = (float)selection.get_min_pnt()(1);
250 float w = (float)selection.get_extent()(0);
251 float h = (float)selection.get_extent()(1);
252 std::vector<vec2> P;
253 P.push_back(vec2(x, y));
254 P.push_back(vec2(x + w, y));
255 P.push_back(vec2(x + w, y + h));
256 P.push_back(vec2(x, y + h));
258 prog.enable(ctx);
259 ctx.set_color(rgb(1, 0, 0));
260 attribute_array_binding::set_global_attribute_array(ctx, prog.get_position_index(), P);
261 attribute_array_binding::enable_global_array(ctx, prog.get_position_index());
263 attribute_array_binding::disable_global_array(ctx, prog.get_position_index());
264 prog.disable(ctx);
266 }
267
268 bool mix_enabled = false;
269 if (tex_ids.size() > 0) {
271 glBindTexture(GL_TEXTURE_2D, tex_ids[current_image]);
272 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, spherical ? GL_REPEAT : GL_CLAMP_TO_EDGE);
273 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, spherical ? GL_REPEAT : GL_CLAMP_TO_EDGE);
274 if (use_mixing && mix_with != -1 && mix_with < tex_ids.size()) {
276 glBindTexture(GL_TEXTURE_2D, tex_ids[mix_with]);
277 mix_enabled = true;
279 }
280 if (start_time == -2)
281 start_time = -1;
282 }
283 if (use_blending) {
286 }
287 if (wireframe)
290 ctx.mul_modelview_matrix(cgv::math::scale4<double>(1, -1, 1));
291 if (prog.is_linked()) {
292 prog.enable(ctx);
293 prog.set_uniform(ctx, "min_value", min_value);
294 prog.set_uniform(ctx, "max_value", max_value);
295 prog.set_uniform(ctx, "gamma4", gamma4);
296 prog.set_uniform(ctx, "image", 0);
297 prog.set_uniform(ctx, "checker_lambda", checker_lambda);
298 prog.set_uniform(ctx, "cx", cx);
299 prog.set_uniform(ctx, "cy", cy);
300 prog.set_uniform(ctx, "k1", k1);
301 prog.set_uniform(ctx, "k2", k2);
302 prog.set_uniform(ctx, "k3", k3);
303 prog.set_uniform(ctx, "k4", k4);
304 prog.set_uniform(ctx, "k5", k5);
305 prog.set_uniform(ctx, "k6", k6);
306 prog.set_uniform(ctx, "p1", p1);
307 prog.set_uniform(ctx, "p2", p2);
308 prog.set_uniform(ctx, "s", s);
309 prog.set_uniform(ctx, "use_texture", tex_ids.size() > 0);
310 prog.set_uniform(ctx, "tessellation_level", tess_level);
311 prog.set_uniform(ctx, "use_mixing", use_mixing);
312 prog.set_uniform(ctx, "mix_with", 1);
313 prog.set_uniform(ctx, "mix_param", mix_param);
314 prog.set_uniform(ctx, "spherical", spherical);
315 prog.set_uniform(ctx, "pan_tilt", pan_tilt);
316 prog.set_uniform(ctx, "scale", vec2(float(aspect * scale), scale));
317 aab.enable(ctx);
320 aab.disable(ctx);
321 prog.disable(ctx);
322 }
323 else
325
326 if (use_blending)
328 if (wireframe)
332}
333
334 }
335 }
336}
complete implementation of method actions that only call one method when entering a node
Definition action.h:113
A data_format describes a multidimensional data block of data entries.
Definition data_format.h:17
size_t get_width() const
return the resolution in the first dimension, or 1 if not defined
size_t get_height() const
return the resolution in the second dimension, or 1 if not defined
size_t get_step_size(unsigned int dim) const
return the step size in bytes in the i-th dimension
Definition data_view.cxx:89
cgv::type::func::transfer_const< P, S * >::type get_ptr() const
return a data pointer to type S
Definition data_view.h:61
the data view gives access to a data array of one, two, three or four dimensions.
Definition data_view.h:153
void invalidate()
set to invalid min and max points
void add_point(const fpnt_type &p)
extent box to include given point
fvec_type get_extent() const
return a vector with the extents in the different dimensions
const fpnt_type & get_max_pnt() const
return a const reference to corner 7
const fpnt_type & get_min_pnt() const
return a const reference to corner 0
the image reader chooses a specific reader automatically based on the extension of the given file nam...
the image writer chooses a specific writer automatically based on the extension of the given file nam...
bool enable(context &ctx)
enable whole the attribute array binding object
static bool enable_global_array(const context &ctx, int loc)
enable attribute array of given location
bool create(const context &ctx)
create the attribute array binding object
void destruct(const context &ctx)
destruct attribute array binding object
static bool set_global_attribute_array(const context &ctx, int loc, const vertex_buffer &vbo, type_descriptor td, size_t size, size_t offset, unsigned stride=0)
point array of vertex attribute at location loc to vertex buffer array array stored in CPU memory; in...
bool disable(context &ctx)
disable whole attribute array binding object
static bool disable_global_array(const context &ctx, int loc)
disable attribute array of given location
bool enable_array(const context &ctx, int loc)
enable array for vertex attribute at location loc
bool set_attribute_array(const context &ctx, int loc, const T &array)
set vertex attribute location to given array and enable array
base class for all drawables, which is independent of the used rendering API.
Definition context.h:621
virtual void mul_modelview_matrix(const dmat4 &MV)
multiply given matrix from right to current modelview matrix
Definition context.cxx:1808
virtual void set_color(const rgba &clr)
set the current color
Definition context.cxx:1617
virtual shader_program & ref_default_shader_program(bool texture_support=false)=0
return a reference to a shader program used to render without illumination
void pop_modelview_matrix()
see push_V for an explanation
Definition context.cxx:1814
void push_modelview_matrix()
push the current viewing matrix onto a matrix stack for viewing matrices.
Definition context.cxx:1802
void tesselate_unit_square(bool flip_normals=false, bool edges=false)
tesselate a unit square in the xy-plane with texture coordinates
Definition context.cxx:1423
void post_redraw()
posts a redraw event to the current context if one is available
Definition drawable.cxx:43
void clear(context &)
destruct textures and shader program
image_drawable()
construct base image drawable
bool init(context &)
construct shader program
void timer_event(double t, double dt)
timer event that can be used for animation, connect this to some animation trigger
bool save_images(const std::string &output_file_name)
function to save all images
bool read_images(const std::string &_file_name, const std::vector< std::string > &_files)
function to read a list of images
bool read_image(const std::string &_file_name)
function to read a single image
bool show_selection
whether to show the selection rectangle
ibox2 selection
extent selection box
void draw(context &)
draw the image
a shader program combines several shader code fragments to a complete definition of the shading pipel...
bool enable(context &ctx)
enable the shader program
bool disable(context &ctx)
disable shader program and restore fixed functionality
bool set_uniform(const context &ctx, const std::string &name, const T &value, bool generate_error=false)
Set the value of a uniform by name, where the type can be any of int, unsigned, float,...
void destruct(const context &ctx)
destruct shader program
bool is_linked() const
return whether program is linked
bool build_program(const context &ctx, const std::string &file_name, bool show_error=false, const shader_define_map &defines=shader_define_map())
successively calls create, attach_program and link.
bool create(const context &ctx, size_t size_in_bytes)
create empty vertex buffer of size size given in bytes
void destruct(const context &ctx)
destruct the render buffer
the base namespace holds the base hierarchy, support for plugin registration and signals
Definition action.cxx:4
namespace for data management components
namespace for image processing
bool read_image_to_textures(const std::string &file_name, std::vector< unsigned > &tex_ids, std::vector< float > &durations, bool mipmaps, double *aspect_ptr, bool *has_alpha_ptr)
read several images from one image file that can contain an animation
Definition gl_tools.cxx:49
unsigned int read_image_to_texture(const std::string &file_name, bool mipmaps, double *aspect_ptr, bool *has_alpha_ptr)
read the given image file into a texture and return the texture id or -1 in case of failure.
Definition gl_tools.cxx:27
namespace for api independent GPU programming
namespace that holds tools that dont fit any other namespace
the cgv namespace
Definition print.h:11
cgv::media::color< float, cgv::media::RGB > rgb
declare rgb color type with 32 bit components
Definition color.h:853
cgv::math::fvec< int32_t, 2 > ivec2
declare type of 2d 32 bit integer vectors
Definition fvec.h:694
cgv::math::fvec< float, 2 > vec2
declare type of 2d single precision floating point vectors
Definition fvec.h:667