From fc0b8184302f46774b627b8916ee3a56d574a427 Mon Sep 17 00:00:00 2001 From: Benau Date: Sun, 26 Jul 2020 12:33:31 +0800 Subject: [PATCH] Allow saving current RTT to png file --- src/graphics/shader_based_renderer.cpp | 44 ++++++++++++++++++++++++++ src/graphics/shader_based_renderer.hpp | 2 ++ src/graphics/sp/sp_base.cpp | 6 ++++ src/graphics/sp/sp_base.hpp | 3 +- src/input/input_manager.cpp | 17 +++++----- 5 files changed, 62 insertions(+), 10 deletions(-) diff --git a/src/graphics/shader_based_renderer.cpp b/src/graphics/shader_based_renderer.cpp index 67e703709..c4e613c1a 100644 --- a/src/graphics/shader_based_renderer.cpp +++ b/src/graphics/shader_based_renderer.cpp @@ -592,6 +592,7 @@ void ShaderBasedRenderer::renderPostProcessing(Camera * const camera, // ---------------------------------------------------------------------------- ShaderBasedRenderer::ShaderBasedRenderer() { + m_dump_rtt = false; m_rtts = NULL; m_skybox = NULL; m_spherical_harmonics = new SphericalHarmonics(irr_driver->getAmbientLight().toSColor()); @@ -871,6 +872,49 @@ void ShaderBasedRenderer::renderToTexture(GL3RenderTarget *render_target, glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getDefaultFramebuffer()); irr_driver->getSceneManager()->setActiveCamera(NULL); + if (m_dump_rtt) + { + m_dump_rtt = false; +#ifndef USE_GLES2 + const unsigned width = m_rtts->getWidth(); + const unsigned height = m_rtts->getHeight(); + uint8_t* pixels = new uint8_t[width * height * 4](); + GLint tmp_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &tmp_texture); + glBindTexture(GL_TEXTURE_2D, m_rtts->getRenderTarget(RTT_COLOR)); + glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_BYTE, pixels); + const int pitch = width * 4; + uint8_t* fbi = pixels; + uint8_t* p2 = fbi + (height - 1) * pitch; + uint8_t* tmp_buf = new uint8_t[pitch]; + for (unsigned i = 0; i < height; i += 2) + { + memcpy(tmp_buf, fbi, pitch); + memcpy(fbi, p2, pitch); + memcpy(p2, tmp_buf, pitch); + fbi += pitch; + p2 -= pitch; + } + if (CVS->isDeferredEnabled()) + { + for (unsigned int i = 0; i < width * height; i++) + { + pixels[i * 4] = SP::linearToSrgb(pixels[i * 4] / 255.f); + pixels[i * 4 + 1] = SP::linearToSrgb(pixels[i * 4 + 1] / 255.f); + pixels[i * 4 + 2] = SP::linearToSrgb(pixels[i * 4 + 2] / 255.f); + pixels[i * 4 + 3] = SP::linearToSrgb(pixels[i * 4 + 3] / 255.f); + } + } + delete [] tmp_buf; + glBindTexture(GL_TEXTURE_2D, tmp_texture); + core::dimension2d size(width, height); + video::IImage* image = irr_driver->getVideoDriver() + ->createImageFromData(video::ECF_A8R8G8B8, size, pixels, + true/*ownForeignMemory*/); + irr_driver->getVideoDriver()->writeImageToFile(image, "rtt.png"); + image->drop(); +#endif + } } //renderToTexture diff --git a/src/graphics/shader_based_renderer.hpp b/src/graphics/shader_based_renderer.hpp index aa7c42928..442c21f3a 100644 --- a/src/graphics/shader_based_renderer.hpp +++ b/src/graphics/shader_based_renderer.hpp @@ -40,6 +40,7 @@ class PostProcessing; class ShaderBasedRenderer: public AbstractRenderer { private: + bool m_dump_rtt; RTT *m_rtts; Skybox *m_skybox; SphericalHarmonics *m_spherical_harmonics; @@ -112,6 +113,7 @@ public: RTT* getRTTs() { return m_rtts; } ShadowMatrices* getShadowMatrices() { return &m_shadow_matrices; } PostProcessing* getPostProcessing() { return m_post_processing.get(); } + void dumpRTT() { m_dump_rtt = true; } void createPostProcessing() OVERRIDE; }; diff --git a/src/graphics/sp/sp_base.cpp b/src/graphics/sp/sp_base.cpp index 8a42e0ccb..c7a0838c0 100644 --- a/src/graphics/sp/sp_base.cpp +++ b/src/graphics/sp/sp_base.cpp @@ -135,6 +135,12 @@ GLuint g_skinning_tex; GLuint g_skinning_buf; // ---------------------------------------------------------------------------- unsigned g_skinning_size; +// ---------------------------------------------------------------------------- +ShaderBasedRenderer* getRenderer() +{ + return g_stk_sbr; +} // getRenderer + // ---------------------------------------------------------------------------- void displaceUniformAssigner(SP::SPUniformAssigner* ua) { diff --git a/src/graphics/sp/sp_base.hpp b/src/graphics/sp/sp_base.hpp index 04a0dbb32..5d7621f29 100644 --- a/src/graphics/sp/sp_base.hpp +++ b/src/graphics/sp/sp_base.hpp @@ -208,7 +208,8 @@ inline uint8_t linearToSrgb(float color_linear) } return uint8_t(irr::core::clamp(int(color_linear * 255.0f), 0, 255)); } - +// ---------------------------------------------------------------------------- +ShaderBasedRenderer* getRenderer(); } diff --git a/src/input/input_manager.cpp b/src/input/input_manager.cpp index 2f0c28e58..cb4a7e456 100644 --- a/src/input/input_manager.cpp +++ b/src/input/input_manager.cpp @@ -21,6 +21,8 @@ #include "config/user_config.hpp" #include "graphics/camera_fps.hpp" #include "graphics/irr_driver.hpp" +#include "graphics/shader_based_renderer.hpp" +#include "graphics/sp/sp_base.hpp" #include "guiengine/engine.hpp" #include "guiengine/event_handler.hpp" #include "guiengine/modaldialog.hpp" @@ -413,16 +415,13 @@ void InputManager::handleStaticAction(int key, int value) } break; case IRR_KEY_F11: - if(value && shift_is_pressed && world && RewindManager::isEnabled()) + if(value && shift_is_pressed) { - printf("Enter rewind to time in ticks:"); - char s[256]; - fgets(s, 256, stdin); - int t; - StringUtils::fromString(s,t); - RewindManager::get()->rewindTo(t, world->getTicksSinceStart(), false); - Log::info("Rewind", "Rewinding from %d to %d", - world->getTicksSinceStart(), t); +#ifndef SERVER_ONLY + ShaderBasedRenderer* sbr = SP::getRenderer(); + if (sbr) + sbr->dumpRTT(); +#endif } break;