2013-11-27 2 views

Antwort

11

Unten ist eine Funktion zum Speichern eines Screenshots in SDL 2 aus einer Bibliothek, die ich gerade schreibe.

bool saveScreenshotBMP(std::string filepath, SDL_Window* SDLWindow, SDL_Renderer* SDLRenderer) { 
    SDL_Surface* saveSurface = NULL; 
    SDL_Surface* infoSurface = NULL; 
    infoSurface = SDL_GetWindowSurface(SDLWindow); 
    if (infoSurface == NULL) { 
     std::cerr << "Failed to create info surface from window in saveScreenshotBMP(string), SDL_GetError() - " << SDL_GetError() << "\n"; 
    } else { 
     unsigned char * pixels = new (std::nothrow) unsigned char[infoSurface->w * infoSurface->h * infoSurface->format->BytesPerPixel]; 
     if (pixels == 0) { 
      std::cerr << "Unable to allocate memory for screenshot pixel data buffer!\n"; 
      return false; 
     } else { 
      if (SDL_RenderReadPixels(SDLRenderer, &infoSurface->clip_rect, infoSurface->format->format, pixels, infoSurface->w * infoSurface->format->BytesPerPixel) != 0) { 
       std::cerr << "Failed to read pixel data from SDL_Renderer object. SDL_GetError() - " << SDL_GetError() << "\n"; 
       pixels = NULL; 
       return false; 
      } else { 
       saveSurface = SDL_CreateRGBSurfaceFrom(pixels, infoSurface->w, infoSurface->h, infoSurface->format->BitsPerPixel, infoSurface->w * infoSurface->format->BytesPerPixel, infoSurface->format->Rmask, infoSurface->format->Gmask, infoSurface->format->Bmask, infoSurface->format->Amask); 
       if (saveSurface == NULL) { 
        std::cerr << "Couldn't create SDL_Surface from renderer pixel data. SDL_GetError() - " << SDL_GetError() << "\n"; 
        return false; 
       } 
       SDL_SaveBMP(saveSurface, filepath.c_str()); 
       SDL_FreeSurface(saveSurface); 
       saveSurface = NULL; 
      } 
      delete[] pixels; 
     } 
     SDL_FreeSurface(infoSurface); 
     infoSurface = NULL; 
    } 
    return true; 
} 

Prost! -Neil

+2

'Pixel = NULL;' sollte 'delete [] pixels;' sein, andernfalls ist das Array durchgesickert. – emlai

6

Wenn Sie OpenGL mit SDL2 verwenden, können Sie glReadPixels direkt aufrufen, anstatt die Infooberfläche und den Renderer zu verwenden. Hier ist ein Beispiel (ohne Fehlerprüfung).

void Screenshot(int x, int y, int w, int h, const char * filename) 
{ 
    unsigned char * pixels = new unsigned char[w*h*4]; // 4 bytes for RGBA 
    glReadPixels(x,y,w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels); 

    SDL_Surface * surf = SDL_CreateRGBSurfaceFrom(pixels, w, h, 8*4, w*4, 0,0,0,0); 
    SDL_SaveBMP(surf, filename); 

    SDL_FreeSurface(surf); 
    delete [] pixels; 
} 

Hier ist die SDL wiki page mit einem Beispiel für die Einstellung der Fenster und eine OpenGL-Kontext auf.

Verwandte Themen