From 4e0ddbcec6e182430a31e0f1c661f2c93c9e0308 Mon Sep 17 00:00:00 2001 From: Sam Moore Date: Wed, 16 Apr 2014 01:50:18 +0800 Subject: [PATCH] Screenshot using glReadPixels instead Which SDL2 is calling underneath somewhere in that "SDL_RenderReadPixels" call. --- src/screen.cpp | 50 +++++++++++++------------------------------------- src/screen.h | 4 ++-- 2 files changed, 15 insertions(+), 39 deletions(-) diff --git a/src/screen.cpp b/src/screen.cpp index 6293fab..e97995c 100644 --- a/src/screen.cpp +++ b/src/screen.cpp @@ -122,47 +122,23 @@ void Screen::Present() void Screen::ScreenShot(const char * filename) const { Debug("Attempting to save BMP to file %s", filename); - SDL_Surface * info = SDL_GetWindowSurface(m_window); - if (info == NULL) - { - Fatal("Failed to create info surface from m_window - %s", SDL_GetError()); - } - - unsigned num_pix = info->w * info->h * info->format->BytesPerPixel; - unsigned char * pixels = new unsigned char[num_pix]; + + int w = ViewportWidth(); + int h = ViewportHeight(); + unsigned char * pixels = new unsigned char[w*h*4]; if (pixels == NULL) - { - Fatal("Failed to allocate %u pixel array - %s", num_pix, strerror(errno)); - } + Fatal("Failed to allocate %d x %d x 4 = %d pixel array", w, h, w*h*4); - SDL_Renderer * renderer = SDL_GetRenderer(m_window); - if (renderer == NULL) - { - Fatal("Couldn't get renderer from m_window - %s", SDL_GetError()); - } - if (SDL_RenderReadPixels(renderer, &(info->clip_rect), info->format->format, pixels, info->w * info->format->BytesPerPixel) != 0) - { - Fatal("SDL_RenderReadPixels failed - %s", SDL_GetError()); - } + glReadPixels(0,0,w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels); - // This line is disgusting - SDL_Surface * save = SDL_CreateRGBSurfaceFrom(pixels, info->w, info->h, info->format->BitsPerPixel, info->w * info->format->BytesPerPixel, - info->format->Rmask, info->format->Gmask, info->format->Bmask, info->format->Amask); - if (save == NULL) - { - Fatal("Couldn't create SDL_Surface from renderer pixel data - %s", SDL_GetError()); - } - if (SDL_SaveBMP(save, filename) != 0) - { - Fatal("SDL_SaveBMP to %s failed - %s", filename, SDL_GetError()); - } + SDL_Surface * surf = SDL_CreateRGBSurfaceFrom(pixels, w, h, 8*4, w*4, 0,0,0,0); + if (surf == NULL) + Fatal("Failed to create SDL_Surface from pixel data - %s", SDL_GetError()); - //SDL_DestroyRenderer(renderer); - SDL_FreeSurface(save); - SDL_FreeSurface(info); + if (SDL_SaveBMP(surf, filename) != 0) + Fatal("SDL_SaveBMP failed - %s", SDL_GetError()); + + SDL_FreeSurface(surf); delete [] pixels; - Debug("Succeeded!"); - - } diff --git a/src/screen.h b/src/screen.h index c8acbcf..f5ae753 100644 --- a/src/screen.h +++ b/src/screen.h @@ -24,8 +24,8 @@ namespace IPDF void Present(); // Get the current width/height of the window's viewport. - int ViewportWidth() { return m_viewport_width; } - int ViewportHeight() { return m_viewport_height; } + int ViewportWidth() const { return m_viewport_width; } + int ViewportHeight() const { return m_viewport_height; } // Handle mouse input. typedef std::function MouseHandler; -- 2.20.1