From 3f61a6a753eb886dc75938e7f9cc4289e4d0c3f7 Mon Sep 17 00:00:00 2001 From: EmaMaker Date: Sun, 17 Sep 2023 15:50:25 +0200 Subject: [PATCH] renderer: screenshot by saving render texture to file --- .gitignore | 1 + include/renderer.hpp | 2 ++ src/main.cpp | 3 +++ src/renderer.cpp | 26 ++++++++++++++++++++++++++ 4 files changed, 32 insertions(+) diff --git a/.gitignore b/.gitignore index 03fcffe..b3dedbe 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ gmon.out* cscope* test.cpp a.out +*screenshot* \ No newline at end of file diff --git a/include/renderer.hpp b/include/renderer.hpp index f7c1a58..d772c77 100644 --- a/include/renderer.hpp +++ b/include/renderer.hpp @@ -17,6 +17,8 @@ namespace renderer{ void framebuffer_size_callback(GLFWwindow *window, int width, int height); void destroy(); + void saveScreenshot(bool forceFullHD=false); + Shader* getRenderShader(); RenderSet& getChunksToRender(); oneapi::tbb::concurrent_queue& getMeshDataQueue(); diff --git a/src/main.cpp b/src/main.cpp index 161920f..7123cf8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -155,4 +155,7 @@ void processInput(GLFWwindow *window) // Reset blockpicking if enough time has passed if(glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_1) == GLFW_RELEASE && glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_2) == GLFW_RELEASE) blockpick = false; + if(glfwGetKey(window, GLFW_KEY_F2) == GLFW_PRESS) renderer::saveScreenshot(); + if(glfwGetKey(window, GLFW_KEY_F3) == GLFW_PRESS) renderer::saveScreenshot(true); + } diff --git a/src/renderer.cpp b/src/renderer.cpp index 073a1af..eeaae93 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -7,6 +7,8 @@ #include "chunkmesher.hpp" #include "globals.hpp" #include "stb_image.h" +#define STB_IMAGE_WRITE_IMPLEMENTATION +#include "stb_image_write.h" namespace renderer{ RenderSet chunks_torender; @@ -240,6 +242,30 @@ namespace renderer{ renderTexDepthBuffer); } + void saveScreenshot(bool forceFullHD){ + int old_screenWidth = screenWidth; + int old_screenHeight = screenHeight; + + if(forceFullHD){ + resize_framebuffer(1920, 1080); + // Do a render pass + render(); + } + + // Bind the render frame buffer + glBindFramebuffer(GL_FRAMEBUFFER, renderTexFrameBuffer); + glPixelStorei(GL_PACK_ALIGNMENT, 1); + // Save the framebuffer in a byte array + GLubyte data[screenWidth*screenHeight*3]; + glReadPixels(0, 0, screenWidth, screenHeight, GL_RGB, GL_UNSIGNED_BYTE, data); + // Save the byte array onto a texture + stbi_flip_vertically_on_write(1); + stbi_write_png(forceFullHD ? "screenshot_fullhd.png" : "screenshot.png", screenWidth, + screenHeight, 3, data, screenWidth*3); + + if(forceFullHD) resize_framebuffer(old_screenWidth, old_screenHeight); + } + void destroy(){ delete theShader; }