From 57cdfca13d79e6247050b65111cc8ec585ffe2f7 Mon Sep 17 00:00:00 2001 From: Dimitri Lozeve Date: Wed, 24 Feb 2021 09:11:21 +0100 Subject: [PATCH] Add keyboard shortcut to take screenshots --- .gitignore | 1 + meson.build | 5 ++++- src/renderer.c | 40 ++++++++++++++++++++++++++++++++++++++++ src/renderer.h | 3 ++- 4 files changed, 47 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 376e902..a432909 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *\~ .cache/ build/ +*.png diff --git a/meson.build b/meson.build index 1be4f04..571b47d 100644 --- a/meson.build +++ b/meson.build @@ -9,12 +9,15 @@ project( ] ) +cc = meson.get_compiler('c') + glfw_dep = dependency('glfw3') glew_dep = dependency('glew') +freeimage_dep = cc.find_library('freeimage') executable( 'shadertool', sources: ['src/main.c', 'src/renderer.c', 'src/shaders.c', 'src/log.c'], - dependencies: [glfw_dep, glew_dep], + dependencies: [glfw_dep, glew_dep, freeimage_dep], c_args: '-DLOG_USE_COLOR', ) diff --git a/src/renderer.c b/src/renderer.c index 9cdda45..e0bb1dc 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -1,5 +1,8 @@ +#include #include #include +#include +#include #include "log.h" #include "renderer.h" @@ -103,6 +106,41 @@ void framebuffer_size_callback(GLFWwindow *window, int width, int height) { glViewport(0, 0, width, height); } +/** + * @brief Captures a screenshot of the current window. + * + * Takes the dimensions of the viewport to save a pixel array of the + * same dimensions. Uses FreeImage to create an image from the raw + * pixels and save it to disk. + */ +void capture_screenshot() { + time_t now = time(NULL); + struct tm *timenow = gmtime(&now); + char image_filename[255] = {0}; + strftime(image_filename, sizeof(image_filename), + "shadertool_%Y%m%d_%H%M%S.png", timenow); + + int viewport[4] = {0}; + glGetIntegerv(GL_VIEWPORT, viewport); + + GLubyte *pixels = calloc(3 * viewport[2] * viewport[3], 1); + glReadPixels(0, 0, viewport[2], viewport[3], GL_BGR, GL_UNSIGNED_BYTE, + pixels); + + FIBITMAP *image = FreeImage_ConvertFromRawBits( + pixels, viewport[2], viewport[3], 3 * viewport[2], 24, FI_RGBA_RED_MASK, + FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, false); + + if (FreeImage_Save(FIF_PNG, image, image_filename, 0)) { + log_debug("Image saved to %s", image_filename); + } else { + log_error("Failed to saved image to %s", image_filename); + } + + FreeImage_Unload(image); + free(pixels); +} + /** * @brief Ensure the window is closed when the user presses the escape * key. @@ -118,5 +156,7 @@ void process_input(GLFWwindow *window, unsigned int *shader_program, glfwSetWindowShouldClose(window, true); } else if (glfwGetKey(window, GLFW_KEY_R) == GLFW_PRESS) { compile_shaders(shader_program, fragment_shader_file); + } else if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) { + capture_screenshot(); } } diff --git a/src/renderer.h b/src/renderer.h index fb51a8d..dad7047 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -5,8 +5,9 @@ GLFWwindow *initialize_window(int width, int height); unsigned int initialize_vertices(); +void framebuffer_size_callback(GLFWwindow *window, int width, int height); +void capture_screenshot(); void process_input(GLFWwindow *window, unsigned int *shader_program, const char *const fragment_shader_file); -void framebuffer_size_callback(GLFWwindow *window, int width, int height); #endif /* RENDERER_H */