mirror of
https://github.com/Almamu/linux-wallpaperengine.git
synced 2025-09-14 13:56:48 +08:00
fix: crash when taking screenshot
This commit is contained in:
parent
e17c4f319e
commit
b7735298be
@ -223,27 +223,38 @@ void CWallpaperApplication::takeScreenshot (const std::filesystem::path& filenam
|
||||
// this should be getting called at the end of the frame, so the right thing should be bound already
|
||||
const int width = this->m_renderContext->getOutput ().getFullWidth ();
|
||||
const int height = this->m_renderContext->getOutput ().getFullHeight ();
|
||||
const bool vflip = this->m_renderContext->getOutput ().renderVFlip ();
|
||||
|
||||
// build the output file with stbi_image_write
|
||||
auto* bitmap = new uint8_t [width * height * sizeof (uint8_t) * 3] {0};
|
||||
auto* bitmap = new uint8_t [width * height * 3] {0};
|
||||
int xoffset = 0;
|
||||
|
||||
for (const auto& [screen, viewport] : this->m_renderContext->getOutput ().getViewports ()) {
|
||||
// activate opengl context so we can read from the framebuffer
|
||||
viewport->makeCurrent ();
|
||||
// make room for storing the pixel of this viewport
|
||||
auto* buffer = new uint8_t [viewport->viewport.z * viewport->viewport.w * sizeof (uint8_t) * 3];
|
||||
const auto bufferSize = (viewport->viewport.z - viewport->viewport.x) * (viewport->viewport.w - viewport->viewport.y) * 3;
|
||||
auto* buffer = new uint8_t [bufferSize];
|
||||
const uint8_t* pixel = buffer;
|
||||
|
||||
// read the viewport data into the pixel buffer
|
||||
glReadPixels (viewport->viewport.x, viewport->viewport.y, viewport->viewport.z, viewport->viewport.w, GL_RGB,
|
||||
GL_UNSIGNED_BYTE, buffer);
|
||||
glPixelStorei (GL_PACK_ALIGNMENT, 1);
|
||||
glReadnPixels (viewport->viewport.x, viewport->viewport.y, viewport->viewport.z, viewport->viewport.w, GL_RGB,
|
||||
GL_UNSIGNED_BYTE, bufferSize, buffer);
|
||||
|
||||
GLenum error = glGetError();
|
||||
|
||||
if (error != GL_NO_ERROR) {
|
||||
sLog.error ("Cannot obtain pixel data for screen ", screen, ". OpenGL error: ", error);
|
||||
delete [] buffer;
|
||||
continue;
|
||||
}
|
||||
|
||||
// now get access to the pixels
|
||||
for (int y = viewport->viewport.w; y > 0; y--) {
|
||||
for (int y = 0; y < viewport->viewport.w; y++) {
|
||||
for (int x = 0; x < viewport->viewport.z; x++) {
|
||||
int xfinal = x + xoffset;
|
||||
int yfinal = this->m_renderContext->getOutput ().renderVFlip () ? (viewport->viewport.w - y) : y;
|
||||
int yfinal = vflip ? (viewport->viewport.w - y - 1) : y;
|
||||
|
||||
bitmap [yfinal * width * 3 + xfinal * 3] = *pixel++;
|
||||
bitmap [yfinal * width * 3 + xfinal * 3 + 1] = *pixel++;
|
||||
@ -267,6 +278,8 @@ void CWallpaperApplication::takeScreenshot (const std::filesystem::path& filenam
|
||||
} else if (extension == ".jpg" || extension == ".jpeg") {
|
||||
stbi_write_jpg (filename.c_str (), width, height, 3, bitmap, 100);
|
||||
}
|
||||
|
||||
delete [] bitmap;
|
||||
}
|
||||
|
||||
void CWallpaperApplication::show () {
|
||||
|
Loading…
Reference in New Issue
Block a user