Add keyboard shortcut to take screenshots

This commit is contained in:
Dimitri Lozeve 2021-02-24 09:11:21 +01:00
parent 0b0ed67bc2
commit 57cdfca13d
4 changed files with 47 additions and 2 deletions

1
.gitignore vendored
View file

@ -1,3 +1,4 @@
*\~ *\~
.cache/ .cache/
build/ build/
*.png

View file

@ -9,12 +9,15 @@ project(
] ]
) )
cc = meson.get_compiler('c')
glfw_dep = dependency('glfw3') glfw_dep = dependency('glfw3')
glew_dep = dependency('glew') glew_dep = dependency('glew')
freeimage_dep = cc.find_library('freeimage')
executable( executable(
'shadertool', 'shadertool',
sources: ['src/main.c', 'src/renderer.c', 'src/shaders.c', 'src/log.c'], 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', c_args: '-DLOG_USE_COLOR',
) )

View file

@ -1,5 +1,8 @@
#include <FreeImage.h>
#include <GL/glew.h> #include <GL/glew.h>
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#include <stdlib.h>
#include <time.h>
#include "log.h" #include "log.h"
#include "renderer.h" #include "renderer.h"
@ -103,6 +106,41 @@ void framebuffer_size_callback(GLFWwindow *window, int width, int height) {
glViewport(0, 0, width, 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 * @brief Ensure the window is closed when the user presses the escape
* key. * key.
@ -118,5 +156,7 @@ void process_input(GLFWwindow *window, unsigned int *shader_program,
glfwSetWindowShouldClose(window, true); glfwSetWindowShouldClose(window, true);
} else if (glfwGetKey(window, GLFW_KEY_R) == GLFW_PRESS) { } else if (glfwGetKey(window, GLFW_KEY_R) == GLFW_PRESS) {
compile_shaders(shader_program, fragment_shader_file); compile_shaders(shader_program, fragment_shader_file);
} else if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) {
capture_screenshot();
} }
} }

View file

@ -5,8 +5,9 @@
GLFWwindow *initialize_window(int width, int height); GLFWwindow *initialize_window(int width, int height);
unsigned int initialize_vertices(); 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, void process_input(GLFWwindow *window, unsigned int *shader_program,
const char *const fragment_shader_file); const char *const fragment_shader_file);
void framebuffer_size_callback(GLFWwindow *window, int width, int height);
#endif /* RENDERER_H */ #endif /* RENDERER_H */