#include "XCEngine/RHI/OpenGL/OpenGLScreenshot.h" #include "XCEngine/RHI/OpenGL/OpenGLDevice.h" #include "XCEngine/RHI/OpenGL/OpenGLSwapChain.h" #include "XCEngine/Debug/Logger.h" #include "XCEngine/Debug/ConsoleLogSink.h" #include "XCEngine/Containers/String.h" #include #include #include #include using namespace XCEngine::Debug; namespace XCEngine { namespace RHI { namespace { bool SavePPM(const char* filename, int width, int height) { unsigned char* pixels = (unsigned char*)malloc(width * height * 3); if (!pixels) { Logger::Get().Error(LogCategory::Rendering, "[OpenGLScreenshot] Failed to allocate pixel buffer"); return false; } glFinish(); glReadBuffer(GL_BACK); glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ROW_LENGTH, 0); glPixelStorei(GL_PACK_SKIP_PIXELS, 0); glPixelStorei(GL_PACK_SKIP_ROWS, 0); glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels); FILE* f = fopen(filename, "wb"); if (!f) { Logger::Get().Error(LogCategory::Rendering, "[OpenGLScreenshot] Failed to open file"); free(pixels); return false; } fprintf(f, "P6\n%d %d\n255\n", width, height); unsigned char* row = (unsigned char*)malloc(width * 3); for (int y = height - 1; y >= 0; y--) { memcpy(row, pixels + y * width * 3, width * 3); fwrite(row, 1, width * 3, f); } free(row); free(pixels); fclose(f); Logger::Get().Debug(LogCategory::Rendering, "[OpenGLScreenshot] Screenshot saved"); return true; } } // anonymous namespace bool OpenGLScreenshot::Capture(OpenGLDevice& device, OpenGLSwapChain& swapChain, const char* filename) { return Capture(device, swapChain, filename, swapChain.GetWidth(), swapChain.GetHeight()); } bool OpenGLScreenshot::Capture(OpenGLDevice& device, OpenGLSwapChain& swapChain, const char* filename, int width, int height) { (void)device; (void)swapChain; return SavePPM(filename, width, height); } } // namespace RHI } // namespace XCEngine