137 for(
unsigned i= 0; i < m_filenames.size(); i++)
139 printf(
"loading buffer %u...\n", i);
141 Image image= read(m_filenames[i].c_str());
142 if(image.size() == 0)
145 m_images.push_back(image);
146 m_times.push_back(timestamp(m_filenames[i].c_str()));
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);
153 m_width= std::max(m_width, image.width());
154 m_height= std::max(m_height, image.height());
167 SDL_SetWindowSize(m_window, m_width, m_height);
169 glGenVertexArrays(1, &m_vao);
170 glBindVertexArray(m_vao);
185 m_saturation_step= 1;
186 m_saturation_max= 1000;
188 m_reference_index= -1;
193 range(m_images.front());
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);
207 glBindVertexArray(0);
208 glBindTexture(GL_TEXTURE_2D, 0);
210 glDisable(GL_DEPTH_TEST);
211 glDisable(GL_CULL_FACE);
228 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
233 reload_program(m_program,
smart_path(
"data/shaders/tonemap.glsl") );
240 m_index= (m_index -1 + m_textures.size()) % m_textures.size();
248 m_index= (m_index +1 + m_textures.size()) % m_textures.size();
254 static float last_time= 0;
258 size_t time= timestamp(m_filenames[m_index].c_str());
259 if(time != m_times[m_index])
262 printf(
"reload image '%s'...\n", m_filenames[m_index].c_str());
264 Image image= read(m_filenames[m_index].c_str());
267 m_times[m_index]= time;
268 m_images[m_index]= image;
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());
276 glGenerateMipmap(GL_TEXTURE_2D);
288 if(filename && filename[0])
292 Image image= read(filename);
295 m_images.push_back( image );
296 m_filenames.push_back( filename );
297 m_times.push_back( timestamp(filename) );
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);
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());
316 unsigned int bmouse= SDL_GetMouseState(&xmouse, &ymouse);
318 glBindVertexArray(m_vao);
319 glUseProgram(m_program);
324 sampler= m_sampler_nearest;
327 if(m_reference_index == -1)
328 program_use_texture(m_program,
"image_next", 1, m_textures[(m_index +1) % m_textures.size()], sampler);
333 if(bmouse & SDL_BUTTON(1))
334 program_uniform(m_program,
"split", (
int) xmouse);
336 program_uniform(m_program,
"split", (
int)
window_width() +2);
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);
346 if(bmouse & SDL_BUTTON(3))
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;
358 if(bmouse & SDL_BUTTON(3))
359 program_uniform(m_program,
"zoom", m_zoom);
361 program_uniform(m_program,
"zoom", 1.f);
367 m_graph= (m_graph +1) % 2;
370 program_uniform(m_program,
"graph",
int(m_graph));
374 glDrawArrays(GL_TRIANGLES, 0, 3);
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";
387 printf(
"writing '%s'...\n", file.c_str());
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);
396 button(m_widgets,
"reset", reset);
397 if(reset) range(m_images[m_index]);
400 button(m_widgets,
"reload", reload);
403 Image image= read(m_filenames[m_index].c_str());
405 m_images[m_index]= image;
406 m_times[m_index]= timestamp(m_filenames[m_index].c_str());
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());
414 glGenerateMipmap(GL_TEXTURE_2D);
418 int reference= (m_index == m_reference_index) ? 1 : 0;
419 if(
button(m_widgets,
"reference", reference))
421 if(reference) m_reference_index= m_index;
422 else m_reference_index= -1;
426 button(m_widgets,
"export all", export_all);
429 #pragma omp parallel for
430 for(
unsigned i= 0; i < m_images.size(); i++)
434 image= tone(gray(m_images[i]), m_saturation, m_compression);
436 image= tone(m_images[i], m_saturation, m_compression);
439 sprintf(filename,
"%s-tone.png", m_filenames[i].c_str());
440 printf(
"exporting '%s'...\n", filename);
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);
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);
463 if(m_reference_index != -1)
464 button(m_widgets,
"diff to reference", m_difference);
469 button(m_widgets,
"select image...", list);
473 for(
unsigned i= 0; i < m_filenames.size(); i++)
476 sprintf(tmp,
"[%u] %s", i, m_filenames[i].c_str());
477 select(m_widgets, tmp, i, m_index);
492 printf(
"screenshot %d...\n", calls);
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;
506 if(m_textures.empty())
509 m_index= m_index % int(m_textures.size());