SDL2: Pořízení snímku obrazovky

SDL s sebou ve druhé verzi přinesl i změnu vykreslování na obrazovku. Místo v RAM uložených SDL_Surface je v SDL2 použita SDL_Texture uložené na video RAM, kde je plně v jurisdikci GPU. Krom citelných změn na rychlost vykreslování se také změnil způsob, jakým lze zachytit snímek obrazovky.

Při použití textur se SDL_Surface okna neaktualizuje, pokud bychom použili dřívější způsob, dostali bychom prázdný snímek.

Bohužel standardní funkce SDL_SaveBMP (ani její nedokumentovaná obdoba v rozšíření SDL_image - IMG_SavePNG) nepodporuje uložení SDL_Texture. Je proto nejprve nutná konverze z SDL_Texture na SDL_Surface. Teprve pak je možné snímek obrazovky uložit.

// Uloží snímek obrazovky do souboru
// file: jméno souboru pro uložení snímku obrazovky
// renderer: ukazatel na SDL_Renderer, který používáte pro vykreslení do okna aplikace
bool saveScreenshot( const std::string &file, SDL_Renderer *renderer ) {

    // Použité proměnné
    SDL_Rect _viewport;
    SDL_Surface *_surface = NULL;

    // Získáme velikost obrazovky
    SDL_RenderGetViewport( renderer, &_viewport);

    // Vytvoří SDL_Surface s hloubkou 32 a dle toho vybranou maskou pro barvy
    _surface = SDL_CreateRGBSurface( 0, _viewport.w, _viewport.h, 32, 0, 0, 0, 0 );

    // Pokud se vytvoření SDL_Surface nezdařilo
    if ( _surface == NULL ) {
        std::cout "Nelze vytvořit SDL_Surface. Důvod: " << SDL_GetError() << std::endl;
        return false;
    }

    // Získá data z SDL_Renderer a zapíše je do vytvořené SDL_Surface
    if ( SDL_RenderReadPixels( renderer, NULL, _surface->format->format, _surface->pixels, _surface->pitch ) != 0 ) {
         std::cout << "Nelze přečíst data z SDL_Renderer. Důvod: " << SDL_GetError() << std::endl;

        // Nutné vyprázdnit paměť
        SDL_FreeSurface(_surface);
        return false;
    }

    // Uloží snímek jako soubor PNG
    if ( IMG_SavePNG( _surface, file.c_str() ) != 0 ) {
        std::cout << "Snímek nebyl uložen. Důvod: " << SDL_GetError() << std::endl;

        // Vyprázdní SDL_Surface
        SDL_FreeSurface(_surface);
        return false;
    }

    // Vyprázdnění SDL_Surface
    SDL_FreeSurface(_surface);
    return true;

}
Použité funkce:

Napsat komentář

Vaše emailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *