diff options
author | pommicket <pommicket@gmail.com> | 2025-02-19 18:55:55 -0500 |
---|---|---|
committer | pommicket <pommicket@gmail.com> | 2025-02-19 18:55:55 -0500 |
commit | 0ab2c540d442997360830fb1ab76284c318c28ca (patch) | |
tree | 3916d91d269192db9b4ea68a594116fd38e0bebc | |
parent | 0b2293a1b44748e494d9db2ae72c72a16b693a9d (diff) |
flash effects
-rw-r--r-- | camera.c | 16 | ||||
-rw-r--r-- | camera.h | 4 | ||||
-rw-r--r-- | main.c | 49 | ||||
-rw-r--r-- | meson.build | 10 |
4 files changed, 51 insertions, 28 deletions
@@ -298,16 +298,24 @@ static uint8_t *camera_curr_frame(Camera *camera) { assert(camera->userp_frames[camera->curr_frame_idx]); return camera->userp_frames[camera->curr_frame_idx]; } -void camera_save_jpg(Camera *camera, const char *name, int quality) { +bool camera_save_jpg(Camera *camera, const char *name, int quality) { uint8_t *frame = camera_curr_frame(camera); if (frame) { - stbi_write_jpg(name, camera_frame_width(camera), camera_frame_height(camera), 3, frame, quality); + uint32_t frame_width = camera_frame_width(camera); + uint32_t frame_height = camera_frame_height(camera); + return stbi_write_jpg(name, frame_width, frame_height, 3, frame, quality) != 0; + } else { + return false; } } -void camera_save_png(Camera *camera, const char *name) { +bool camera_save_png(Camera *camera, const char *name) { uint8_t *frame = camera_curr_frame(camera); if (frame) { - stbi_write_png(name, camera_frame_width(camera), camera_frame_height(camera), 3, frame, camera_frame_width(camera) * 3); + uint32_t frame_width = camera_frame_width(camera); + uint32_t frame_height = camera_frame_height(camera); + return stbi_write_png(name, frame_width, frame_height, 3, frame, frame_width * 3) != 0; + } else { + return false; } } bool camera_next_frame(Camera *camera) { @@ -103,8 +103,8 @@ PictureFormat camera_closest_resolution(Camera *camera, uint32_t pixfmt, int32_t int32_t camera_frame_width(Camera *camera); int32_t camera_frame_height(Camera *camera); PictureFormat camera_picture_format(Camera *camera); -void camera_save_jpg(Camera *camera, const char *path, int quality); -void camera_save_png(Camera *camera, const char *path); +bool camera_save_jpg(Camera *camera, const char *path, int quality); +bool camera_save_png(Camera *camera, const char *path); bool camera_next_frame(Camera *camera); void camera_update_gl_textures(Camera *camera, const GLuint textures[3]); const char *camera_name(Camera *camera); @@ -1,8 +1,6 @@ /* TODO --set saved image format -add support for more pixfmts --screen effect when picture is taken -view previous pictures (thumbnails) -click in menus -left/right in resolution menu @@ -381,6 +379,7 @@ void main() {\n\ in vec2 tex_coord;\n\ uniform sampler2D u_sampler;\n\ uniform int u_pixel_format;\n\ +uniform float u_flash;\n\ uniform float u_opacity;\n\ void main() {\n\ vec3 color;\n\ @@ -396,7 +395,7 @@ void main() {\n\ color = texture2D(u_sampler, tex_coord).xyz;\n\ break;\n\ }\n\ - gl_FragColor = vec4(color, opacity);\n\ + gl_FragColor = vec4(mix(color, vec3(1.0), u_flash), opacity);\n\ }\n\ "; char err[256] = {0}; @@ -410,6 +409,7 @@ void main() {\n\ gl.GenVertexArrays(1, &vao); const GLuint u_sampler = gl.GetUniformLocation(program, "u_sampler"); const GLuint u_offset = gl.GetUniformLocation(program, "u_offset"); + const GLuint u_flash = gl.GetUniformLocation(program, "u_flash"); const GLuint u_pixel_format = gl.GetUniformLocation(program, "u_pixel_format"); const GLuint u_scale = gl.GetUniformLocation(program, "u_scale"); const GLuint u_opacity = gl.GetUniformLocation(program, "u_opacity"); @@ -508,6 +508,7 @@ void main() {\n\ if (!camera_open(state->camera)) return EXIT_FAILURE; } + double flash_time = INFINITY; while(true) { struct udev_device *dev = NULL; while (udev_monitor && (dev = udev_monitor_receive_device(udev_monitor))) { @@ -525,24 +526,29 @@ void main() {\n\ while (SDL_PollEvent(&event)) { if (event.type == SDL_QUIT) goto quit; if (event.type == SDL_KEYDOWN) switch (event.key.keysym.sym) { - case SDLK_SPACE: { - time_t t = time(NULL); - struct tm *tm = localtime(&t); - static char name[64]; - strftime(name, sizeof name, "%Y-%m-%d-%H-%M-%S", tm); - sprintf(name + strlen(name), ".%s", image_format_extensions[state->image_format]); - switch (state->image_format) { - case IMG_FMT_JPEG: - camera_save_jpg(state->camera, name, 90); - break; - case IMG_FMT_PNG: - camera_save_png(state->camera, name); - break; - case IMG_FMT_COUNT: - assert(false); - break; + case SDLK_SPACE: + if (state->camera) { + time_t t = time(NULL); + struct tm *tm = localtime(&t); + static char name[64]; + strftime(name, sizeof name, "%Y-%m-%d-%H-%M-%S", tm); + sprintf(name + strlen(name), ".%s", image_format_extensions[state->image_format]); + bool success = false; + switch (state->image_format) { + case IMG_FMT_JPEG: + success = camera_save_jpg(state->camera, name, 90); + break; + case IMG_FMT_PNG: + success = camera_save_png(state->camera, name); + break; + case IMG_FMT_COUNT: + assert(false); + break; + } + if (success) + flash_time = 0; } - } break; + break; case SDLK_ESCAPE: if (state->curr_menu == MENU_NONE) { state->curr_menu = MENU_MAIN; @@ -779,6 +785,7 @@ void main() {\n\ clock_gettime(CLOCK_MONOTONIC, &ts); double curr_time = (double)ts.tv_sec + (double)ts.tv_nsec * 1e-9; double frame_time = curr_time - last_time; + flash_time += frame_time; last_time = curr_time; gl.UseProgram(program); @@ -824,7 +831,9 @@ void main() {\n\ gl.Disable(GL_BLEND); gl.BindBuffer(GL_ARRAY_BUFFER, vbo); gl.BindVertexArray(vao); + gl.Uniform1f(u_flash, expf(-flash_time * 3)); gl.DrawArrays(GL_TRIANGLES, 0, 6); + gl.Uniform1f(u_flash, 0); if (state->curr_menu) { gl.Enable(GL_BLEND); gl.ActiveTexture(GL_TEXTURE0); diff --git a/meson.build b/meson.build index b4acbd6..7d721bf 100644 --- a/meson.build +++ b/meson.build @@ -4,7 +4,7 @@ project('camlet', 'warning_level=3', ] ) - +cc = meson.get_compiler('c') v4l2 = dependency('libv4l2') sdl2 = dependency('SDL2') sdl2_ttf = dependency('SDL2_ttf') @@ -12,9 +12,15 @@ udev = dependency('libudev') gl = dependency('GL') sodium = dependency('libsodium') fontconfig = dependency('fontconfig') +m_dep = cc.find_library('m', required: false) +if m_dep.found() + add_project_link_arguments('-lm', language: 'c') +endif if get_option('debug') debug_def = '-DDEBUG=1' else debug_def = '-DDEBUG=0' endif -executable('camlet', 'main.c', 'camera.c', '3rd_party/stb_image_write.c', dependencies: [v4l2, sdl2, sdl2_ttf, gl, udev, sodium, fontconfig], c_args: ['-Wno-unused-function', '-Wno-format-truncation', '-Wshadow', debug_def]) +executable('camlet', 'main.c', 'camera.c', '3rd_party/stb_image_write.c', + dependencies: [v4l2, sdl2, sdl2_ttf, gl, udev, sodium, fontconfig], + c_args: ['-Wno-unused-function', '-Wno-format-truncation', '-Wshadow', debug_def]) |