Obsah
Parametry ovlivňující naplnění barvové paletyZjištění parametrů ovlivňujících naplnění barvové palety
Vytvoření barvové palety z hodnot přečtených z framebufferu
Změna části barvové palety
Změna části barvové palety z hodnot přečtených z framebufferu
Pokračování
Seznam funkcí zmíněných v této části
Nové funkce popsané v této části
Demonstrační příklady
Zkomprimovaná verze článku
Parametry ovlivňující naplnění barvové palety
Při zápisu dat do barvové palety pomocí minule popsané funkce glColorTable() se mohou s barvami provádět dvě jednoduché operace: vynásobení vstupujících barvových hodnot konstantou (scale) a přičtení konstanty (bias). Tyto operace se na barvové složky aplikují ihned po sobě, tj. napřed se provede vynásobení konstantou scale, následně součet s konstantou bias. Konstanty scale a bias, kterými se budou jednotlivé barvové složky pixelů (barvová paleta je zadaná pomocí pixmapy) násobit, resp. s nimi sčítat, se zadávají pomocí funkcí:
void glColorTableParameteriv( GLenum target, GLenum pname, const GLint *params ); void glColorTableParameterfv( GLenum target, GLenum pname, Const GLfloat *params );
kde:
- V argumentu target se předává jméno barvové palety. Tento argument může nabývat stejných hodnot jako odpovídající argument funkce glColorTable(), tj. GL_COLOR_TABLE,GL_POST_CONVOLUTION_COLOR_TABLE, nebo GL_POST_COLOR_MATRIX_COLOR_TABLE.
- Argument pname označuje, která ze dvou konstant se nastavuje: GL_COLOR_TABLE_SCALE pro nastavení konstanty scale, nebo GL_COLOR_TABLE_BIAS pro nastavení konstanty bias.
- Argument params obsahuje ukazatel na pole čtyř hodnot, kde na každou složku R, G, B a A připadá jedna hodnota. Pro každou barvovou složku (i pro alfa hodnotu) je možné nastavit jiné hodnoty konstant scale a bias. Pokud jsou hodnoty reprezentované typem GLfloat, jsou přímo zapsány do odpovídajících konstant, pokud se jedná o hodnoty typu GLint, provede se nejdříve jejich převod na typ GLfloat. Způsob převodu je stejný jako u funkce glDrawPixels().
Zjištění parametrů ovlivňujících naplnění barvové palety
Aktuálně nastavené hodnoty všech konstant scale a bias lze zjistit pomocí následujících dvou funkcí:
void glGetColorTableParameterfv( GLenum target, GLenum pname, GLfloat *params ); void glGetColorTableParameteriv( GLenum target, GLenum pname, GLint *params );
Význam jednotlivých argumentů funkcí glGetColorTableParameterfv() a glGetColorTableParameteriv():
- V argumentu target musí být zadáno jméno barvové palety, jejíž konstanty bias nebo scale potřebujeme zjistit. Podobně jako u funkce glColorTable(), i zde se jedná o jednu z hodnotGL_COLOR_TABLE, GL_POST_CONVOLUTION_COLOR_TABLE a GL_POST_COLOR_MATRIX_COLOR_TABLE.
- Argumentem pname, který může obsahovat hodnotu GL_COLOR_TABLE_SCALE nebo GL_COLOR_TABLE_BIAS, je specifikováno, zda se mají vrátit multiplikativní konstanty scale, nebo aditivní konstanty bias.
- Poslední argument pname obsahuje ukazatel na oblast paměti, do které se hodnoty konstant zaznamenají. Alokovaná paměť musí mít volné místo pro čtyři položky, protože se pro každou barvovou složku R, G, B a A ukládá jedna hodnota.
Vytvoření barvové palety z hodnot přečtených z framebufferu
Barvová paleta nemusí být specifikována pouze pomocí vhodné pixmapy přenášené z operační paměti počítače, jak tomu bylo u funkce glColorTable(). Vhodnou pixmapu je také možné přečíst přímo z framebufferu. K tomuto účelu se používá funkce:
void glCopyColorTable( GLenum target, GLenum internalFormat, GLint x, GLint y, GLsizei width );
Barvy jsou získány stejným způsobem (tj. prochází stejnou částí grafického vykreslovacího řetězce) jako při zadání pixmapy pomocí funkce glColorTable(), pouze se liší zdroj dat, kterým je nyní místo operační paměti framebuffer. Význam jednotlivých argumentů funkce glCopyColorTable():
- Parametr target obsahuje jméno barvové palety, jejíž položky se mají z framebufferu přečíst. Povolené hodnoty tohoto argumentu jsouGL_COLOR_TABLE, GL_POST_CONVOLUTION_COLOR_TABLE nebo GL_POST_COLOR_MATRIX_COLOR_TABLE.
- Význam argumentu internalFormat je stejný jako u funkce glColorTable(). V tomto argumentu je uložen interní formát dat barvové palety, tj. formát, do kterého se (nezávisle na vstupním rastrovém obrázku) barvová paleta uloží. Mezi povolené hodnoty, které je možné v tomto argumentu zadat, patří: GL_RGBA, GL_RGB, GL_RED,GL_GREEN, GL_BLUE, GL_ALPHA atd. Nejpoužívanější jsou hodnoty GL_RGBA a GL_RGB, pomocí kterých lze vytvořit barvovou paletu s výběrem libovolné barvy z celého barevného spektra.
- Hodnoty argumentů x a y specifikují levý dolní roh pixmapy ve framebufferu, která se bude číst. Souřadnice levého rohu jsou zadány přímo v pixelech, neprovádí se s nimi tedy žádná transformace (na rozdíl od souřadnic vrcholů vykreslovaných plošek).
- V argumentu width je uložena šířka pixmapy, která odpovídá počtu přečtených barev. Podobně jako u funkce glColorTable(), i u této funkce se nemusí zadávat výška pixmapy, neboť je vždy rovna jednomu řádku pixelů.
Změna části barvové palety
V některých případech může být žádoucí změnit pouze část barvové palety. Z hlediska rychlosti zpracování je, oproti opakovanému čtení a zápisu celé palety, mnohdy výhodnější upravit pouze některé barvové položky. Pro tento účel je možné použít funkci glColorSubTable() s následující hlavičkou:
void glColorSubTable( GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, void *data );
Význam jednotlivých argumentů funkce glColorSubTable():
- Argument target musí obsahovat jednu z následujících hodnot: GL_COLOR_TABLE, GL_POST_CONVOLUTION_COLOR_TABLE aGL_POST_COLOR_MATRIX_COLOR_TABLE pro přímou modifikaci barvové palety.
- Argument start obsahuje index první barvové složky, která se má v barvové paletě změnit. Celkový počet položek je zjištěn v okamžiku vytváření barvové palety pomocí funkce glColorTable() nebo glCopyColorTable().
- Argument count obsahuje počet položek barvové palety, které se mají změnit. Součet start+count by neměl překročit celkový počet položek (indexů) v barvové paletě. V případě, že k překročení dojde, je generována chyba.
- V argumentu format je zadán formát dat, které jsou funkci glColorSubTable() předávány. Význam jednotlivých hodnot je stejný jako u funkce glDrawPixels(), povolené hodnoty tohoto argumentu jsou: GL_RGBA, GL_RGB, GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA a rozšířené formáty jakoGL_BGR_EXT, GL_BGRA_EXT apod.
- Argument type má, podobně jako argument předchozí, stejný význam jako u funkce glDrawPixels() – lze pomocí něj specifikovat, jaký formát budou mít jednotlivé barvové složky předávaných pixelů. Povolené hodnoty jsou GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT,GL_SHORT, GL_UNSIGNED_INT, GL_INT a GL_FLOAT. Všimněte si, že není povolen typ GL_BITMAP, který by při práci s barvovou paletou nedával smysl.
- V argumentu data je předán ukazatel na rastrová data přenášeného obrázku. Při přenosu se provádí datové konverze a případné rozpakování barvových hodnot pixelů podobně jako při vykreslování rastrových bitmap (funkce glBitmap) a pixmapy (funkce glDrawPixels).
Změna části barvové palety z hodnot přečtených z framebufferu
Existuje ještě jedna funkce, pomocí které je možné nastavit část barvové palety. Tato funkce však nečte potřebná data z operační paměti počítače, ale přímo z framebufferu. Jedná se tedy o sloučení vlastností funkcí glCopyColorTable() a glColorSubTable(), čemuž také odpovídá název funkce: glCopyColorSubTable(). Tato funkce má hlavičku:
void glCopyColorSubTable( GLenum target, GLsizei start, GLint x, GLint y, GLsizei width );
Význam jednotlivých argumentů funkce glCopyColorSubTable() je velmi podobný oběma předešlým funkcím. Za zmínku stojí pouze fakt, že počet položek, které mají být v barvové paletě změněny, není zadán v argumentu count, ale v argumentu width. Počet měněných položek tedy odpovídá šířce pixmapy přečtené z framebufferu. Vzhledem k tomu, že se hodnoty čtou přímo z framebufferu, není zapotřebí definovat formát dat.
Pokračování
V dalším pokračování tohoto seriálu se budeme zabývat velmi zajímavou tematikou – tvorbou a použitím konvolučních filtrů pomocí Imaging Subsetu. Konvoluční filtry lze použít pro aplikaci mnoha grafických efektů, například rozmazání obrázku, zvýraznění hran nebo zobrazení obrázku jako vystouplého či naopak jakoby vytesaného reliéfu.
Seznam funkcí zmíněných v této části
glColorTable()glDrawPixels()
glBitmap()
Nové funkce popsané v této části
glColorTableParameteriv()glColorTableParameterfv()
glGetColorTableParameterfv()
glGetColorTableParameteriv()
glCopyColorTable()
glColorSubTable()
glCopyColorSubTable()
Demonstrační příklady
Po překladu a spuštění prvního demonstračního příkladu se zobrazí obrázek Leny. Zobrazení se provádí pomocí nám již známé funkce glDrawPixels(), ale s modifikací barvové palety, která se provádí pomocí příkazu glColorTable(). Tento příkaz je vyvolán ve funkciprepareColorTable().
Pomocí klávesy P lze použití barvové palety, tj. přemapování barvových složek jednotlivých pixelů, povolit či zakázat. V demonstračním programu se tak děje s využitím příkazů glEnable(GL_COLOR_TABLE) a glDisable(GL_COLOR_TABLE).
Barevná paleta je nastavena tak, aby prováděla gama korekci, přičemž gama křivka má exponent větší než jedna. To znamená, že se zvyšuje kontrast světlých barev a současně se obrázek jako celek jeví poněkud tmavší.
Rozdíl mezi obrázkem bez aplikované gama korekce a s aplikovanou gama korekcí je vidět na prvním a druhém obrázku.
Zdrojový kód prvního demonstračního příkladu je dostupný zde, HTML verze se zvýrazněním syntaxe zde.
Obrázek 1: Screenshot prvního demonstračního příkladu s vypnutou gama korekcí
Obrázek 2: Screenshot prvního demonstračního příkladu se zapnutou gama korekcí
Druhý demonstrační příklad je prakticky totožný s příkladem prvním. Jediný rozdíl spočívá v tom, že se při výpočtu gama křivky používá exponent menší než jedna. Výsledek je přesně opačný než u prvního příkladu: zvyšuje se kontrast tmavých barev a obrázek se současně jeví poněkud světlejší.
Aplikace gama křivek pomocí palet je samozřejmě pouze jednou z možností, pro které lze barvové palety využít. Mnohem zajímavější je použití palet pro tvorbu jednoduchých animací.
Pro spuštění demonstračních příkladů je nutné mít stažený i původní obrázek Leny, který pro jistotu opět přikládám i do zkomprimované verze článku, i když je totožný s obrázkem z předchozí části.
Zdrojový kód druhého demonstračního příkladu je dostupný zde, HTML verze se zvýrazněním syntaxe zde.
Obrázek 3: Screenshot druhého demonstračního příkladu
Zkomprimovaná verze článku
Zkomprimovaná verze tohoto článku spolu s demonstračními příklady a obrázky je umístěna zde.