gKit2 light
Public Member Functions | Protected Attributes | List of all members
ImageViewer Struct Reference
+ Inheritance diagram for ImageViewer:

Public Member Functions

 ImageViewer (std::vector< const char * > &filenames)
 
void range (const Image &image)
 
Image tone (const Image &image, const float saturation, const float gamma)
 
Image gray (const Image &image)
 
void title (const int index)
 
Image read (const char *filename)
 
int init ()
 a deriver pour creer les objets openGL. renvoie -1 pour indiquer une erreur, 0 sinon. More...
 
int quit ()
 a deriver pour detruire les objets openGL. renvoie -1 pour indiquer une erreur, 0 sinon. More...
 
int render ()
 a deriver pour afficher les objets. renvoie 1 pour continuer, 0 pour fermer l'application. More...
 
- Public Member Functions inherited from App
 App (const int width, const int height, const int major=3, const int minor=3, const int samples=0)
 constructeur, dimensions de la fenetre et version d'openGL. More...
 
virtual int update (const float time, const float delta)
 a deriver et redefinir pour animer les objets en fonction du temps. More...
 
int run ()
 execution de l'application. More...
 

Protected Attributes

Widgets m_widgets
 
std::vector< std::string > m_filenames
 
std::vector< size_t > m_times
 
std::vector< Imagem_images
 
std::vector< GLuint > m_textures
 
int m_width
 
int m_height
 
GLuint m_program
 
GLuint m_vao
 
GLuint m_sampler_nearest
 
int m_red
 
int m_green
 
int m_blue
 
int m_alpha
 
int m_gray
 
int m_smooth
 
int m_difference
 
float m_compression
 
float m_saturation
 
float m_saturation_step
 
float m_saturation_max
 
float m_zoom
 
int m_index
 
int m_reference_index
 
int m_graph
 
- Protected Attributes inherited from App
Window m_window
 
Context m_context
 
bool sync
 

Additional Inherited Members

- Protected Member Functions inherited from App
virtual int prerender ()
 
virtual int postrender ()
 
void vsync_off ()
 

Detailed Description

Definition at line 20 of file image_viewer.cpp.

Member Function Documentation

◆ init()

int ImageViewer::init ( )
inlinevirtual

a deriver pour creer les objets openGL. renvoie -1 pour indiquer une erreur, 0 sinon.

Implements App.

Definition at line 132 of file image_viewer.cpp.

133  {
134  m_width= 0;
135  m_height= 0;
136 
137  for(unsigned i= 0; i < m_filenames.size(); i++)
138  {
139  printf("loading buffer %u...\n", i);
140 
141  Image image= read(m_filenames[i].c_str());
142  if(image.size() == 0)
143  continue;
144 
145  m_images.push_back(image);
146  m_times.push_back(timestamp(m_filenames[i].c_str()));
147 
148  m_textures.push_back(make_texture(0, image));
149 
150  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
151  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
152 
153  m_width= std::max(m_width, image.width());
154  m_height= std::max(m_height, image.height());
155  }
156 
157  if(m_images.empty())
158  {
159  printf("no image...\n");
160  return -1;
161  }
162 
163  // change le titre de la fenetre
164  title(0);
165 
166  // redminsionne la fenetre
167  SDL_SetWindowSize(m_window, m_width, m_height);
168 
169  glGenVertexArrays(1, &m_vao);
170  glBindVertexArray(m_vao);
171 
172  m_program= read_program( smart_path("data/shaders/tonemap.glsl") );
173  program_print_errors(m_program);
174 
175  //
176  m_red= 1;
177  m_green= 1;
178  m_blue= 1;
179  m_alpha= 1;
180  m_gray= 0;
181  m_smooth= 1;
182  m_difference= 0;
183  m_compression= 2.2f;
184  m_saturation= 1;
185  m_saturation_step= 1;
186  m_saturation_max= 1000;
187  m_index= 0;
188  m_reference_index= -1;
189  m_zoom= 4;
190  m_graph= 0;
191 
192  // parametres d'exposition / compression
193  range(m_images.front());
194 
195  //
196  m_widgets= create_widgets();
197 
198  //
199  glGenSamplers(1, &m_sampler_nearest);
200  glSamplerParameteri(m_sampler_nearest, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
201  glSamplerParameteri(m_sampler_nearest, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
202  glSamplerParameteri(m_sampler_nearest, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
203  glSamplerParameteri(m_sampler_nearest, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
204 
205  // etat openGL par defaut
206  glUseProgram(0);
207  glBindVertexArray(0);
208  glBindTexture(GL_TEXTURE_2D, 0);
209 
210  glDisable(GL_DEPTH_TEST);
211  glDisable(GL_CULL_FACE);
212  return 0;
213  }
representation d'une image.
Definition: image.h:21
int height() const
renvoie la hauteur de l'image.
Definition: image.h:100
unsigned size() const
renvoie le nombre de pixels de l'image.
Definition: image.h:102
int width() const
renvoie la largeur de l'image.
Definition: image.h:98
Widgets create_widgets()
cree une interface graphique. a detruire avec release_widgets( ).
Definition: widgets.cpp:12
void printf(Text &text, const int px, const int py, const char *format,...)
affiche un texte a la position x, y. meme utilisation que printf().
Definition: text.cpp:140
const char * smart_path(const char *filename)
renvoie le chemin(path) vers le fichier 'filename' apres l'avoir cherche dans un repertoire standard....
Definition: window.cpp:431
Point max(const Point &a, const Point &b)
renvoie la plus grande composante de chaque point. x, y, z= max(a.x, b.x), max(a.y,...
Definition: vec.cpp:35
GLuint make_texture(const int unit, const int width, const int height, const GLenum texel_type, const GLenum data_format, const GLenum data_type)
creation de textures filtrables / mipmaps
Definition: texture.cpp:25
GLuint read_program(const char *filename, const char *definitions)
Definition: program.cpp:204
int program_print_errors(const GLuint program)
affiche les erreurs de compilation.
Definition: program.cpp:432

◆ quit()

int ImageViewer::quit ( )
inlinevirtual

a deriver pour detruire les objets openGL. renvoie -1 pour indiquer une erreur, 0 sinon.

Implements App.

Definition at line 215 of file image_viewer.cpp.

216  {
217  glDeleteVertexArrays(1, &m_vao);
218  glDeleteTextures(m_textures.size(), m_textures.data());
219 
220  release_program(m_program);
221  release_widgets(m_widgets);
222  return 0;
223  }
void release_widgets(Widgets &w)
detruit l'interface graphique.
Definition: widgets.cpp:23
int release_program(const GLuint program)
detruit les shaders et le program.
Definition: program.cpp:211

◆ render()

int ImageViewer::render ( )
inlinevirtual

a deriver pour afficher les objets. renvoie 1 pour continuer, 0 pour fermer l'application.

Implements App.

Definition at line 225 of file image_viewer.cpp.

226  {
227  // effacer l'image
228  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
229 
230  if(key_state('r'))
231  {
232  clear_key_state('r');
233  reload_program(m_program, smart_path("data/shaders/tonemap.glsl") );
234  program_print_errors(m_program);
235  }
236 
237  if(key_state(SDLK_LEFT))
238  {
239  clear_key_state(SDLK_LEFT);
240  m_index= (m_index -1 + m_textures.size()) % m_textures.size();
241  // change aussi le titre de la fenetre
242  title(m_index);
243  }
244 
245  if(key_state(SDLK_RIGHT))
246  {
247  clear_key_state(SDLK_RIGHT);
248  m_index= (m_index +1 + m_textures.size()) % m_textures.size();
249  // change aussi le titre de la fenetre
250  title(m_index);
251  }
252 
253  // verification de la date de l'image
254  static float last_time= 0;
255  // quelques fois par seconde, ca suffit, pas tres malin de le faire 60 fois par seconde...
256  if(global_time() > last_time + 400)
257  {
258  size_t time= timestamp(m_filenames[m_index].c_str());
259  if(time != m_times[m_index])
260  {
261  // date modifiee, recharger l'image
262  printf("reload image '%s'...\n", m_filenames[m_index].c_str());
263 
264  Image image= read(m_filenames[m_index].c_str());
265  if(image.size())
266  {
267  m_times[m_index]= time;
268  m_images[m_index]= image;
269 
270  // transfere la nouvelle version
271  glBindTexture(GL_TEXTURE_2D, m_textures[m_index]);
272  glTexImage2D(GL_TEXTURE_2D, 0,
273  GL_RGBA32F, image.width(), image.height(), 0,
274  GL_RGBA, GL_FLOAT, image.data());
275 
276  glGenerateMipmap(GL_TEXTURE_2D);
277  }
278  }
279 
280  last_time= global_time();
281  }
282 
283  if(drop_events().size())
284  {
285  for(unsigned i= 0; i < drop_events().size(); i++)
286  {
287  const char *filename= drop_events()[i].c_str();
288  if(filename && filename[0])
289  {
290  //~ printf("drop file [%d] '%s'...\n", int(m_filenames.size()), filename);
291 
292  Image image= read(filename);
293  if(image.size())
294  {
295  m_images.push_back( image );
296  m_filenames.push_back( filename );
297  m_times.push_back( timestamp(filename) );
298  m_textures.push_back( make_texture(0, image) );
299 
300  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
301  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
302  }
303  }
304 
305  printf("index %d\n", m_index);
306  for(unsigned i= 0; i < m_filenames.size(); i++)
307  printf("images[%d] '%s'\n", i, m_filenames[i].c_str());
308  }
309 
311  assert(drop_events().size() == 0);
312  }
313 
314 
315  int xmouse, ymouse;
316  unsigned int bmouse= SDL_GetMouseState(&xmouse, &ymouse);
317 
318  glBindVertexArray(m_vao);
319  glUseProgram(m_program);
320 
321  // selection des buffers + filtrage
322  GLuint sampler= 0;
323  if(!m_smooth)
324  sampler= m_sampler_nearest;
325 
326  program_use_texture(m_program, "image", 0, m_textures[m_index], sampler);
327  if(m_reference_index == -1)
328  program_use_texture(m_program, "image_next", 1, m_textures[(m_index +1) % m_textures.size()], sampler);
329  else
330  program_use_texture(m_program, "image_next", 1, m_textures[m_reference_index], sampler);
331 
332  // activer le split de l'ecran
333  if(bmouse & SDL_BUTTON(1))
334  program_uniform(m_program, "split", (int) xmouse);
335  else
336  program_uniform(m_program, "split", (int) window_width() +2);
337 
338  // parametres
339  program_uniform(m_program, "channels", Color(m_red, m_green, m_blue, m_alpha));
340  program_uniform(m_program, "gray", float(m_gray));
341  program_uniform(m_program, "difference", float(m_difference));
342  program_uniform(m_program, "compression", m_compression);
343  program_uniform(m_program, "saturation", m_saturation);
344 
345  // zoom
346  if(bmouse & SDL_BUTTON(3))
347  {
348  SDL_MouseWheelEvent wheel= wheel_event();
349  if(wheel.y != 0)
350  {
351  m_zoom= m_zoom + float(wheel.y) / 4.f;
352  if(m_zoom < .1f) m_zoom= .1f;
353  if(m_zoom > 10.f) m_zoom= 10.f;
354  }
355  }
356 
357  program_uniform(m_program, "center", vec2( float(xmouse) / float(window_width()), float(window_height() - ymouse -1) / float(window_height())));
358  if(bmouse & SDL_BUTTON(3))
359  program_uniform(m_program, "zoom", m_zoom);
360  else
361  program_uniform(m_program, "zoom", 1.f);
362 
363  // graphes / courbes
364  if(key_state('g'))
365  {
366  clear_key_state('g');
367  m_graph= (m_graph +1) % 2;
368  }
369 
370  program_uniform(m_program, "graph", int(m_graph));
371  program_uniform(m_program, "line", vec2(float(window_height() - ymouse -1) / float(window_height()), float(window_height() - ymouse -1)));
372 
373  // dessine 1 triangle plein ecran
374  glDrawArrays(GL_TRIANGLES, 0, 3);
375 
376  // actions
377  if(key_state('c'))
378  {
379  clear_key_state('c');
380 
381  // change l'extension
382  std::string file= m_filenames[m_index];
383  size_t ext= file.rfind(".");
384  if(ext != std::string::npos)
385  file= file.substr(0, ext) + "-tone.png";
386 
387  printf("writing '%s'...\n", file.c_str());
388  screenshot(file.c_str());
389  }
390 
391  begin(m_widgets);
392  value(m_widgets, "saturation", m_saturation, 0.f, m_saturation_max*10, m_saturation_step);
393  value(m_widgets, "compression", m_compression, .1f, 10.f, .1f);
394 
395  int reset= 0;
396  button(m_widgets, "reset", reset);
397  if(reset) range(m_images[m_index]);
398 
399  int reload= 0;
400  button(m_widgets, "reload", reload);
401  if(reload)
402  {
403  Image image= read(m_filenames[m_index].c_str());
404  {
405  m_images[m_index]= image;
406  m_times[m_index]= timestamp(m_filenames[m_index].c_str());
407 
408  // transfere la nouvelle version
409  glBindTexture(GL_TEXTURE_2D, m_textures[m_index]);
410  glTexImage2D(GL_TEXTURE_2D, 0,
411  GL_RGBA32F, image.width(), image.height(), 0,
412  GL_RGBA, GL_FLOAT, image.data());
413 
414  glGenerateMipmap(GL_TEXTURE_2D);
415  }
416  }
417 
418  int reference= (m_index == m_reference_index) ? 1 : 0;
419  if(button(m_widgets, "reference", reference))
420  {
421  if(reference) m_reference_index= m_index; // change de reference
422  else m_reference_index= -1; // deselectionne la reference
423  }
424 
425  int export_all= 0;
426  button(m_widgets, "export all", export_all);
427  if(export_all)
428  {
429  #pragma omp parallel for
430  for(unsigned i= 0; i < m_images.size(); i++)
431  {
432  Image image;
433  if(m_gray)
434  image= tone(gray(m_images[i]), m_saturation, m_compression);
435  else
436  image= tone(m_images[i], m_saturation, m_compression);
437 
438  char filename[1024];
439  sprintf(filename, "%s-tone.png", m_filenames[i].c_str());
440  printf("exporting '%s'...\n", filename);
441  write_image(image, filename);
442  }
443  }
444 
445  begin_line(m_widgets);
446  {
447  int px= xmouse;
448  int py= window_height() - ymouse -1;
449  float x= px / float(window_width()) * m_images[m_index].width();
450  float y= py / float(window_height()) * m_images[m_index].height();
451  Color pixel= m_images[m_index](x, y);
452  label(m_widgets, "pixel %d %d: %f %f %f", int(x), int(y), pixel.r, pixel.g, pixel.b);
453  }
454 
455  begin_line(m_widgets);
456  button(m_widgets, "R", m_red);
457  button(m_widgets, "G", m_green);
458  button(m_widgets, "B", m_blue);
459  button(m_widgets, "A", m_alpha);
460  button(m_widgets, "gray", m_gray);
461  button(m_widgets, "smooth", m_smooth);
462 
463  if(m_reference_index != -1)
464  button(m_widgets, "diff to reference", m_difference);
465 
466  begin_line(m_widgets);
467  {
468  static int list= 0;
469  button(m_widgets, "select image...", list);
470  if(list)
471  {
472  char tmp[1024];
473  for(unsigned i= 0; i < m_filenames.size(); i++)
474  {
475  begin_line(m_widgets);
476  sprintf(tmp, "[%u] %s", i, m_filenames[i].c_str());
477  select(m_widgets, tmp, i, m_index);
478  }
479  }
480  }
481 
482  end(m_widgets);
483 
484  draw(m_widgets, window_width(), window_height());
485 
486  if(key_state('s'))
487  {
488  clear_key_state('s');
489 
490  static int calls= 0;
491  screenshot("screenshot", ++calls);
492  printf("screenshot %d...\n", calls);
493  }
494 
495  if(key_state(SDLK_LCTRL) && key_state('w'))
496  {
497  clear_key_state('w');
498 
499  m_filenames.erase(m_filenames.begin() + m_index);
500  m_times.erase(m_times.begin() + m_index);
501  m_images.erase(m_images.begin() + m_index);
502  m_textures.erase(m_textures.begin() + m_index);
503  if(m_reference_index == m_index)
504  m_reference_index= -1;
505 
506  if(m_textures.empty())
507  return 0;
508 
509  m_index= m_index % int(m_textures.size());
510  // change aussi le titre de la fenetre
511  title(m_index);
512  }
513 
514  return 1;
515  }
const void * data() const
renvoie un pointeur sur le stockage des couleurs des pixels.
Definition: image.h:84
void begin(Widgets &w)
debut de la description des elements de l'interface graphique.
Definition: widgets.cpp:29
bool button(Widgets &w, const char *text, int &status)
Definition: widgets.cpp:155
void label(Widgets &w, const char *format,...)
cree un texte. meme fonctionnement que printf().
Definition: widgets.cpp:142
void clear_drop_events()
desactive drag/drop.
Definition: window.cpp:95
int window_height()
renvoie la hauteur de la fenetre de l'application.
Definition: window.cpp:29
bool value(Widgets &w, const char *label, int &value, const int value_min, const int value_max, const int value_step)
valeur editable par increment.
Definition: widgets.cpp:191
void clear_key_state(const SDL_Keycode key)
desactive une touche du clavier.
Definition: window.cpp:48
const std::vector< std::string > & drop_events()
drag/drop. recupere tous les fichiers.
Definition: window.cpp:77
bool select(Widgets &w, const char *text, const int option, int &status)
Definition: widgets.cpp:173
void end(Widgets &w)
termine la description des elements de l'interface graphique.
Definition: widgets.cpp:404
int key_state(const SDL_Keycode key)
renvoie l'etat d'une touche du clavier. cf la doc SDL2 pour les codes.
Definition: window.cpp:42
void begin_line(Widgets &w)
place les prochains elements sur une nouvelle ligne.
Definition: widgets.cpp:129
SDL_MouseWheelEvent wheel_event()
renvoie le dernier evenement. etat de la molette de la souris / glisser sur le pad.
Definition: window.cpp:112
int window_width()
renvoie la largeur de la fenetre de l'application.
Definition: window.cpp:25
float global_time()
renvoie le temps ecoule depuis le lancement de l'application, en millisecondes.
Definition: window.cpp:128
int write_image(const Image &image, const char *filename)
enregistre une image dans un fichier png.
Definition: image_io.cpp:85
int screenshot(const char *filename)
enregistre le contenu de la fenetre dans un fichier. doit etre de type .png / .bmp
Definition: texture.cpp:194
void program_uniform(const GLuint program, const char *uniform, const std::vector< unsigned > &v)
affecte un tableau de valeurs a un uniform du shader program.
Definition: uniforms.cpp:94
void program_use_texture(const GLuint program, const char *uniform, const int unit, const GLuint texture, const GLuint sampler)
configure le pipeline et le shader program pour utiliser une texture, et des parametres de filtrage,...
Definition: uniforms.cpp:198
representation d'une couleur (rgba) transparente ou opaque.
Definition: color.h:14
vecteur generique, utilitaire.
Definition: vec.h:131

The documentation for this struct was generated from the following file: