Hlavní navigace

SDL: Hry nejen pro Linux (5)

Michal Turek

Dnes se podíváme na grafické funkce poskytované knihovnou SDL. Vzhledem k rozsáhlosti tohoto tématu zde budou uvedeny pouze nejzákladnější věci, podrobnostem se budeme věnovat až v následujících dílech.

Návratové hodnoty funkcí

Většina SDL funkcí zabývajících se grafikou dodržuje pravidlo, že nulová návratová hodnota značí úspěch a mínus jednička neúspěch. Pokud tedy nebude uvedeno jinak, platí u funkcí vracejících int tyto hodnoty. Volání funkcí, které vracejí ukazatele, by měla být ošetřena klasicky na NULL.

Nahrávání obrázků z disku

SDL umí nahrávat pouze obrázky ve formátu BMP, ale díky knihovně SDL_image, která se už stala de facto jeho součástí, může programátor používat i PCX, GIF, JPG, PNG, TGA, TIFF a další méně známé formáty. Stejně jako celé SDL je i SDL_image šířena pod licencí GNU LGPL.

Po přilinkování knihovny a vložení hlavičkového souboru SDL_image.h je možné volat funkci IMG_Load(), která vrací surface nahrávaného obrázku. Formát je detekován automaticky podle přípony, hlaviček apod.

SDL_Surface *SDL_LoadBMP(const char *file);
SDL_Surface *IMG_Load(const char *file);

Ukládání obrázků

SDL kromě nahrávání surface z disku umožňuje i ukládání. Jedná se opět pouze o formát BMP, SDL_image ukládání bohužel neumožňuje.

int SDL_SaveBMP(SDL_Surface *surface, const char *file);

Uvolnění surface

Ke smazání surface lze použít následující funkci, která se o vše postará.

void SDL_FreeSurface(SDL_Surface *surface);

Konverze formátu surface

Není to podmínkou, ale pokud bude mít surface obrázku stejný formát, jako má okno, bude jeho zobrazení stát procesor mnohem méně výkonu. Nejlepší ze všeho je ihned po vytvoření surface zavolat funkci SDL_DisplayFormat() (resp. SDL_DisplayFor­matAlpha() pro surface s alfa kanálem), která se postará o konverzi. Parametrem je převáděný surface a vrácen je nový surface s požadovaným formátem nebo NULL při neúspěchu.

SDL_Surface *SDL_DisplayFormat(SDL_Surface *surface);
SDL_Surface *SDL_DisplayFormatAlpha(SDL_Surface *surface);

Výše uvedené funkce využívají služeb SDL_ConvertSur­face(), která je jejich obecnější variantou.

SDL_Surface *SDL_ConvertSurface(SDL_Surface *src,
                SDL_PixelFormat *fmt, Uint32 flags);

První parametr opět představuje zdrojový surface, druhým je požadovaný pixel formát (většinou surface_vzoru->format) a třetím jsou flagy, které už byly probrány dříve (SDL_SWSURFACE, SDL_HWSURFACE apod.).

Vykreslování

Základem veškerého blittingu je v SDL funkce SDL_BlitSurface(), která vezme pixely ze zdrojového surface src a zkopíruje je do cílového surface dst, jímž je většinou, ale ne vždy, framebuffer okna. Funkce samozřejmě umožňuje specifikovat pozici a rozměry oblasti, díky čemuž nemusí být kopírován celý surface.

Pozn.: Termín blitting obecně označuje kopírování pixelů z jedné paměti do druhé. Nemusí se však jednat pouze o strohé přepsání dat, ale mohou se provádět různé další operace – např. přeskakovat pixely určité barvy, míchat zdrojový pixel s cílovým v závislosti na alfa kanálu (blending) a podobně. SDL_BlitSurface() vykonává všechny tyto operace.

int SDL_BlitSurface(SDL_Surface *src, SDL_Rect *srcrect,
                SDL_Surface *dst, SDL_Rect *dstrect);

Pokud bude za některý z obdélníků předán NULL, bude se pracovat s celým objektem, u cílové oblasti se používá pouze pozice, žádné roztahování nebo zmenšování tedy není možné. Po návratu z funkce bude cílový obdélník obsahovat rozměry oblasti, se kterými se při blittingu pracovalo ve skutečnosti, tato hodnota se bude hodit při aktualizaci okna (viz níže). Výsledek blittingu do značné míry závisí na vlastnostech surfaců, především na alfa kanálu a transparentní bar­vě.

Návratovou hodnotou je klasicky 0 (úspěch) a –1 (neúspěch). Pokud bude u hardwarového surface vráceno –2, byla jeho video paměť ztracena. V takovém případě by měl být surface znovu nahrán/vytvořen. Stává se to během přepínání z celoobrazovkového režimu do okna, pokud SDL využívá služeb DirectX 5.0. Pro podrobnosti odkazuji na SDL manuál.

Pozn.: Možná to bude jen přežitek starších verzí, protože SDL v současnosti přepínání aplikace mezi fullscreenem a oknem pod operačním systémem MS Windows vůbec neumožňuje.

Aktualizace obsahu okna

Aby se zobrazila právě vykreslená scéna, je potřeba vykonat ještě jednu operaci – aktualizovat oblast okna, na kterou se kreslilo. V parametrech funkce se předává neplatný obdélník, jehož žádná část by neměla přesahovat okraje okna – neprovádějí se žádné testy, a tedy ani ořezávání. Pokud budou předány samé nuly, aktualizuje se celé okno. Tyto funkce by nikdy neměly být volány na zamknutý surface.

void SDL_UpdateRect(SDL_Surface *screen,
                Sint32 x, Sint32 y, Sint32 w, Sint32 h);
void SDL_UpdateRects(SDL_Surface *screen,
                int numrects, SDL_Rect *rects);

Co se týká druhé uvedené funkce, má stejný význam jako první, kromě toho, že lze specifikovat více obdélníků najednou. Tyto obdélníky však nejsou testovány na vzájemné přesahy, jejich aktualizace probíhají nezávisle.

V případě, že okno používá double buffering (SDL_DOUBLEBUF předaný do SDL_SetVideoMo­de()), buffery se prohodí voláním SDL_Flip(). Hardware pak počká na vertikální zatmění stínítka monitoru a až poté provede požadovanou operaci.

int SDL_Flip(SDL_Surface *screen);

Pokud hardware double buffering nepodporuje nebo není zapnutý, je SDL_Flip() ekvivalentní volání SDL_UpdateRec­t(screen, 0, 0, 0, 0), čili překreslí se celé okno.

Ukázkové programy

Jelikož by se mnoho kódu z příkladů pokaždé opakovalo, budou obecně použitelné funkce umisťovány do souborů functions.h a functions.cpp. Prozatím bude obsahovat pouze pomocnou funkci na nahrávání obrázků z disku a funkci pro výpočet počtu snímků za sekundu. Animace a pohyby v programu díky FPS poběží stejně rychle na každém počítači. (Zdrojový kód se zvýrazněním syntaxe.)

Hello, SDL graphic!

Asi nejjednodušší program, jaký lze vytvořit na demonstraci použití SDL grafiky. Vykresluje se v něm jednoduchý obrázek, který byl nahrán z disku za použití knihovny SDL_image. Na své centrované pozici zůstává i při roztahování okna. (Zdrojový kód se zvýrazněním syntaxe.)

Hello, SDL graphic!

Objekt odrážející se od okrajů

Druhý příklad je o něco složitější než ten první. Místo statického obrázku je vykreslován dynamický objekt, který se pohybuje po přímce oknem a odráží se od okrajů. Díky tomu, že obsahuje i alfa kanál, jím může prosvítat pozadí. (Zdrojový kód se zvýrazněním syntaxe.)

Objekt odrážející se od okrajů

Ve vnitřním fungování programů existuje jeden rozdíl. U prvního má okno pouze jeden buffer a scéna se po vykreslení aktualizuje pomocí funkce SDL_UpdateRect(). Druhý příklad využívá double buffering (je-li podporován) a scéna se musí aktualizovat voláním SDL_Flip(). SDL_UpdateRect() by v tomto případě nemělo žádný efekt.

Download

Pokračování

Tento článek obsahoval pouze základní úvod do kreslení pomocí knihovny SDL, další podrobnosti přijdou v následujících dílech.

Našli jste v článku chybu?

22. 3. 2005 10:41

Jiri Svoboda (neregistrovaný)
Zajimalo by me, zda se budete v serialu venovat i 'SDL_RWops', coz je velmi uzitecna, lec nedokumentovana, vlastnost SDL knihovny.
Tutorial zde: http://www.kekkai.org/roger/sdl/rwops/rwops.html

26. 12. 2008 4:57

Techi (neregistrovaný)
Jenom bych chtěl upozornit na malý problém, pokud použijete samotné zdrojové kódy SDL_image (nepoužijete existující project file) je potřeba definovat makra pro každý typ. jako LOAD_BMP nebo LOAD_PNG (před include knihovny SDL_image.h)

Já blbec jsem to pod Windows CE asi hodinu ladil .)

Tím, že definujete makra jenom pro obrázky, které skutečně použijete v aplikaci, se dá ušetřit trocha paměti

Jinak zajímavé je, že IMG_Load() vůbec netestuje příponu obrázku, ale postupně ten obrázek testuje n…





Podnikatel.cz: Přehledná titulka, průvodci, responzivita

Přehledná titulka, průvodci, responzivita

Vitalia.cz: Taky věříte na pravidlo 5 sekund?

Taky věříte na pravidlo 5 sekund?

Vitalia.cz: 7 druhů hotových těst na vánoční cukroví

7 druhů hotových těst na vánoční cukroví

Vitalia.cz: Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky

Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky

Lupa.cz: Proč firmy málo chrání data? Chovají se logicky

Proč firmy málo chrání data? Chovají se logicky

Vitalia.cz: Proč vás každý zubař posílá na dentální hygienu

Proč vás každý zubař posílá na dentální hygienu

Vitalia.cz: Mondelez stahuje rizikovou čokoládu Milka

Mondelez stahuje rizikovou čokoládu Milka

Podnikatel.cz: Udávání a účtenková loterie, hloupá komedie

Udávání a účtenková loterie, hloupá komedie

Lupa.cz: Co se dá měřit přes Internet věcí

Co se dá měřit přes Internet věcí

Vitalia.cz: Jsou čajové sáčky toxické?

Jsou čajové sáčky toxické?

DigiZone.cz: Rádio Šlágr má licenci pro digi vysílání

Rádio Šlágr má licenci pro digi vysílání

Vitalia.cz: Jedlé kaštany jsou trpké, je třeba je tepelně upravit

Jedlé kaštany jsou trpké, je třeba je tepelně upravit

Vitalia.cz: „Připluly“ z Německa a možná obsahují jed

„Připluly“ z Německa a možná obsahují jed

Vitalia.cz: Spor o mortadelu: podle Lidlu falšovaná nebyla

Spor o mortadelu: podle Lidlu falšovaná nebyla

Podnikatel.cz: Udávání kvůli EET začalo

Udávání kvůli EET začalo

Podnikatel.cz: 1. den EET? Problémy s pokladnami

1. den EET? Problémy s pokladnami

Lupa.cz: Insolvenční řízení kvůli cookies? Vítejte v ČR

Insolvenční řízení kvůli cookies? Vítejte v ČR

Podnikatel.cz: Babiše přesvědčila 89letá podnikatelka?!

Babiše přesvědčila 89letá podnikatelka?!

Lupa.cz: Teletext je „internetem hipsterů“

Teletext je „internetem hipsterů“

Lupa.cz: Propustili je z Avastu, už po nich sahá ESET

Propustili je z Avastu, už po nich sahá ESET