Vytvoření prázdného surface
Prázdný SDL_Surface se dá v programu vytvořit pomocí funkce SDL_CreateRGBSurface(). První čtyři parametry jistě není třeba popisovat, jsou jimi flagy, šířka, výška a barevná hloubka. Bity masek definují pořadí barevných složek v pixelu, označují tedy, jestli bude obrázek uložen jako RGB, BGR, popř. v jiném formátu. U osmi- a čtyřbitové barevné hloubky bude alokována prázdná paleta.
SDL_Surface *SDL_CreateRGBSurface(Uint32 flags, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask); SDL_Surface *SDL_CreateRGBSurfaceFrom(void *pixels, int width, int height, int depth, int pitch, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask);
Při vytváření surface je vhodné specifikovat masky v závislosti na pořadí bytů, které se používá na dané platformě (little/big endian). SDL definuje symbolickou konstantu SDL_BYTEORDER, jež se rovná buď hodnotě SDL_LIL_ENDIAN, nebo SDL_BIG_ENDIAN.
Například při vytváření textury pro OpenGL je vhodné podle následujícího příkladu vytvořit pomocný surface, voláním SDL_Blit() do něj pixely zkopírovat, tím se transformují do správného formátu, a až poté vytvořit texturu.
SDL_Surface *surface = SDL_CreateRGBSurface( SDL_SWSURFACE, 128, 128, 32, #if SDL_BYTEORDER == SDL_LIL_ENDIAN 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 #else 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF #endif );
Ořezávací obdélník surface
Příkazem SDL_SetClipRect() lze surface „virtuálně ořezat“, pro funkce se pak bude chovat, jako by měl definovánu tuto novou velikost. Maximální rozměry mohou být následně obnoveny předáním NULL. Uvedená vlastnost se bere v úvahu, když se do surface kreslí, ne když je kreslen!
Pokud funkce vrátí SDL_FALSE, obdélník neprotínal surface a při vykreslování se tedy nezobrazí nic. Zasahuje-li alespoň část obdélníku do surface, je vráceno SDL_TRUE a při kreslení se bude brát v úvahu oblast průniku.
SDL_bool SDL_SetClipRect(SDL_Surface *surface, SDL_Rect *rect); void SDL_GetClipRect(SDL_Surface *surface, SDL_Rect *rect);
Pomocí druhé uvedené funkce lze získat aktuální ořezávací roviny obdélníku.
Specifikace barvy
Kvůli mnoha různým formátům surface – zvláště paletovým – může být výběr barvy komplikovanější, než by se na první pohled mohlo zdát. Naštěstí SDL poskytuje příkazy, které se umí postarat o všechny detaily.
Uint32 SDL_MapRGB(SDL_PixelFormat *fmt, Uint8 r, Uint8 g, Uint8 b); Uint32 SDL_MapRGBA(SDL_PixelFormat *fmt, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
První parametr funkce je formátem pixelů, který daný surface používá (většinou surface->format), a ostatní představují jednotlivé RGB(A) složky. Barva je vrácena jako 32bitové číslo, jež je buď přímo požadovanou barvou, nebo (v případě paletového pixel formátu) barvou, která se nachází v paletě a nejvíce se blíží požadované.
Opačný směr, tedy získání RGB(A) složek barvy z pixelu, zprostředkovávají funkce
void SDL_GetRGB(Uint32 pixel, SDL_PixelFormat *fmt, Uint8 *r, Uint8 *g, Uint8 *b); void SDL_GetRGBA(Uint32 pixel, SDL_PixelFormat *fmt, Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a);
Vyplnění surface barvou
Funkce SDL_FillRect() se většinou používá ke změně barvy pozadí okna, ale lze ji použít na libovolný surface.
int SDL_FillRect(SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color);
První parametr představuje surface, na který bude operace aplikována, a druhý omezuje velikost obarvované plochy. Pokud by byl tento obdélník nastaven na NULL, předpokládá se vyplnění celého surface. Color určuje barvu.
Obsahuje-li surface ořezávací obdélník, bude vyplněn pouze jeho průnik s dstrect a dstrect bude nastaven na rozměry vyplněné oblasti. Následující příklad nastaví pozadí okna na červenou barvu.
// Červené pozadí okna SDL_FillRect(g_screen, NULL, SDL_MapRGB(g_screen->format, 255, 0, 0));
Nastavení klíčové (průhledné) barvy
Transparentní barva surface se dá nastavit pomocí funkce SDL_SetColorKey(). Při blittingu nebudou pixely této barvy vykresleny.
int SDL_SetColorKey(SDL_Surface *surface, Uint32 flag, Uint32 key);
Za parametr flag se při této operaci musí předat symbolická konstanta SDL_SRCCOLORKEY, předáním nuly se transparentní barva zruší. Následujícím příkazem se v surface zprůhlední růžové pixely.
SDL_SetColorKey(surface, SDL_SRCCOLORKEY, SDL_MapRGB(surface->format, 255, 0, 255));
Pokud je flag binárně ORován se SDL_RLEACCEL, bude surface vykreslován s použitím RLE akcelerace. To je výhodné u spojitých oblastí průhledných pixelů (na řádcích). Surface je pro použití RLE akcelerace zakódován při prvním předání do funkce SDL_BlitSurface() nebo SDL_DisplayFormat().
Alfa hodnota surface
Pomocí funkce SDL_SetAlpha() lze nastavit globální úroveň průhlednosti, která bude aplikována na každý pixel surface.
int SDL_SetAlpha(SDL_Surface *surface, Uint32 flag, Uint8 alpha);
Parametr flag musí být nastaven na SDL_SRCALPHA a může být, stejně jako u předešlé funkce, ORován se SDL_RLEACCEL. Poslední parametr specifikuje úroveň alfy. Nula (SDL_ALPHA_TRANSPARENT) má význam úplné průhlednosti a 255 (SDL_ALPHA_OPAQUE) značí neprůhlednost. Speciální hodnotou je 128, která je určitým způsobem optimalizována, takže blitting bude rychlejší než u jiných hodnot. Při použití této techniky nesmí mít surface alfa kanál, použila by se alfa jednotlivých pixelů.
Nastavení palety
Barvy v paletě osmibitového a čtyřbitového surface se dají nastavit pomocí funkce SDL_SetColors().
int SDL_SetColors(SDL_Surface *surface, SDL_Color *colors, int firstcolor, int ncolors);
Funkci se předává ukazatel na daný surface, pole barev, první barva a celkový počet barev. Pokud byly úspěšně nastaveny všechny barvy, je vrácena jednička. Pokud některé byly nastaveny a některé ne, je vrácena nula. V takovém případě by měl programátor zjistit ze surface nově vzniklou paletu. Nejedná-li se o paletový surface, nic se neprovede a je vrácena také nula.
Je-li předaný surface asociován s oknem a byl-li v SDL_SetVideoMode() definován flag SDL_HWPALETTE, vrátí tato funkce vždy jedničku a nastavení palety je vždy garantováno.
V případě, že se jedná o framebuffer s hardwarovým surface, obsahuje vždy dvě palety, logickou (používají ji funkce pro blitting) a fyzickou (používá ji hardware k mapování na obrazovku). Aby je bylo možné specifikovat odděleně, musí mít framebuffer nastaven již zmíněný flag SDL_HWPALETTE. K oddělené specifikaci palet pak slouží funkce
int SDL_SetPalette(SDL_Surface *surface, int flags, SDL_Color *colors, int firstcolor, int ncolors);
Parametr flags může být nastaven buď na hodnotu SDL_LOGPAL (logická paleta), nebo SDL_PHYSPAL (fyzická paleta), většinou se modifikuje pouze jedna z nich, čímž se dociluje různých efektů. Volání SDL_SetPalette() s parametrem flags nastaveným na SDL_LOGPAL | SDL_PHYSPAL je ekvivalentem SDL_SetColors().
V SDL manuálu se u popisu těchto funkcí nachází příklad na nastavení palety úrovně šedi.
Ukázkové programy
Vlastnosti surface
Podstata tohoto programu tkví především ve vykreslovací funkci. Surface okna je zmenšen pomocí SDL_SetClipRect() tak, aby u okrajů vznikla desetipixelová mezera. Poté je vykresleno červené pozadí a do každého rohu stejný obrázek, ale s jinými vlastnostmi.
V levém horním rohu se nachází originál tak, jak byl nahrán z disku, u obrázku vpravo je bílá barva pixelů nastavena na transparentní. Vlevo dole byla nastavena 50% průhlednost a vpravo dole se nachází kombinace obou. Je důležité poznamenat, že obrázek je ve formátu RGB, bez alfa kanálu. (Zdrojový kód se zvýrazněním syntaxe.)
Download
Pokračování
V příští části se budeme věnovat přímému přístupu k pixelům surface a změně kurzoru myši.