Obsah
Změna hodnot během přenosu pixelů a fragmentůZpracování pixelů nesoucích informaci o barvě
Zpracování pixelů nesoucích index do barevné palety
Zpracování pixelů s informacemi o hloubce
Zpracování pixelů s informacemi o šabloně
Pokračování
Seznam funkcí zmíněných v této části
Zkomprimovaná verze článku
Změna hodnot během přenosu pixelů a fragmentů
Mezi framebufferem a operační pamětí počítače lze přenášet pixely, jejichž hodnoty mohou mít různý význam. Pokud je pixel zapisován či čten z barvového bufferu (color bufferu), má jeho hodnota význam barvy, pokud je zapisován či čten z paměti hloubky (depth bufferu), obsahuje hloubku fragmentu, a pokud se pracuje s pamětí šablony, obsahuje hodnotu zapisovanou nebo čtenou z paměti šablony (stencil bufferu).
Hodnoty přenášených pixelů se mohou v průběhu přenosu (transferu) změnit. Imaging subset je při inicializaci grafické knihovny OpenGL nastavený tak, že se i při povoleném zpracování pixelů (změně světlosti, kontrastu, mapování apod.) jejich hodnoty nijak nezmění. Způsob změny hodnot přenášených pixelů se řídí pomocí funkce:
void glPixelTransferi( GLenum param, GLint value );
resp.
void glPixelTransferf( GLenum param, GLfloat value );
V argumentu param je zadána symbolická konstanta specifikující, který parametr ovlivňující konverzi hodnot pixelů budeme nastavovat, v argumentu value je potom zadána číselná hodnota tohoto parametru. Pokud je hodnota parametru value mimo povolené meze, generuje se chybová hodnota GL_INVALID_VALUE. Pokud je zadán nesprávný argumentparam, generuje se chybová hodnota GL_INVALID_ENUM. Tyto chybové hodnoty lze zjistit pomocí funkce glGetError(), kterou jsme si popsali v předchozí části tohoto seriálu.
V následující tabulce je uveden soupis všech parametrů, které je možné nastavit, i s jejich datovým typem, počáteční hodnotou a povoleným rozsahem hodnot:
Jméno parametru | Typ Počáteční hodnota Rozsah hodnot |
---|---|
GL_MAP_COLOR | GLboolean GL_FALSE GL_TRUE/GL_FALSE |
GL_MAP_STENCIL | GLboolean GL_FALSE GL_TRUE/GL_FALSE |
GL_INDEX_SHIFT | GLint 0 MIN_INT-MAX_INT |
GL_INDEX_OFFSET | GLint 0 MIN_INT-MAX_INT |
GL_RED_SCALE | GLfloat 1.0 celý rozsah GLfloat |
GL_GREEN_SCALE | GLfloat 1.0 celý rozsah GLfloat |
GL_BLUE_SCALE | GLfloat 1.0 celý rozsah GLfloat |
GL_ALPHA_SCALE | GLfloat 1.0 celý rozsah GLfloat |
GL_DEPTH_SCALE | GLfloat 1.0 celý rozsah GLfloat |
GL_RED_BIAS | GLfloat 0.0 celý rozsah GLfloat |
GL_GREEN_BIAS | GLfloat 0.0 celý rozsah GLfloat |
GL_BLUE_BIAS | GLfloat 0.0 celý rozsah GLfloat |
GL_ALPHA_BIAS | GLfloat 0.0 celý rozsah GLfloat |
GL_DEPTH_BIAS | GLfloat 0.0 celý rozsah GLfloat |
GL_POST_CONVOLUTION_RED_SCALE | GLfloat 1.0 celý rozsah GLfloat |
GL_POST_CONVOLUTION_GREEN_SCALE | GLfloat 1.0 celý rozsah GLfloat |
GL_POST_CONVOLUTION_BLUE_SCALE | GLfloat 1.0 celý rozsah GLfloat |
GL_POST_CONVOLUTION_ALPHA_SCALE | GLfloat 1.0 celý rozsah GLfloat |
GL_POST_CONVOLUTION_RED_BIAS | GLfloat 0.0 celý rozsah GLfloat |
GL_POST_CONVOLUTION_GREEN_BIAS | GLfloat 0.0 celý rozsah GLfloat |
GL_POST_CONVOLUTION_BLUE_BIAS | GLfloat 0.0 celý rozsah GLfloat |
GL_POST_CONVOLUTION_ALPHA_BIAS | GLfloat 0.0 celý rozsah GLfloat |
GL_POST_COLOR_MATRIX_RED_SCALE | GLfloat 1.0 celý rozsah GLfloat |
GL_POST_COLOR_MATRIX_GREEN_SCALE | GLfloat 1.0 celý rozsah GLfloat |
GL_POST_COLOR_MATRIX_BLUE_SCALE | GLfloat 1.0 celý rozsah GLfloat |
GL_POST_COLOR_MATRIX_ALPHA_SCALE | GLfloat 1.0 celý rozsah GLfloat |
GL_POST_COLOR_MATRIX_RED_BIAS | GLfloat 0.0 celý rozsah GLfloat |
GL_POST_COLOR_MATRIX_GREEN_BIAS | GLfloat 0.0 celý rozsah GLfloat |
GL_POST_COLOR_MATRIX_BLUE_BIAS | GLfloat 0.0 celý rozsah GLfloat |
GL_POST_COLOR_MATRIX_ALPHA_BIAS | GLfloat 0.0 celý rozsah GLfloat |
Zpracování pixelů nesoucích informaci o barvě
Pixely, které nesou informaci o barvě v režimu true-color (formát RGB nebo RGBA), jsou během přenosu modifikovány podle následujícího schématu:
- Každá barvová složka (včetně alfa složky, kterou v tomto případě nerozlišujeme od pravých barvových složek) je nejprve vynásobena příslušnou hodnotou scale. Tato hodnota je nastavena pomocí funkce glPixelTransferi() nebo glPixelTransferf() se jmény parametrůGL_RED_SCALE, GL_GREEN_SCALE, GL_BLUE_SCALE a GL_ALPHA_SCALE a hodnotami typu GLint resp. GLfloat. Pokud ponecháme původní nastavení OpenGL, jako při inicializaci, jsou všechny hodnoty scale nastaveny na jedničku, tj. barvové složky se vynásobením nezmění.
- K hodnotám barev, které vznikly výpočtem v předchozím bloku, jsou připočteny konstanty bias, které se taktéž nastavují pomocí funkce glPixelTransfer*(). V tomto případě jsou však použita jména parametrů GL_RED_BIAS, GL_GREEN_BIAS, GL_BLUE_BIAS a GL_ALPHA_BIAS s hodnotami typu GLfloat. Původní nastavení OpenGL je takové, že inicializační hodnoty bias jsou nastaveny na nulu, tj. barvy se přičtením těchto hodnot nijak nezmění.
- Po provedení předchozích dvou operací jsou hodnoty vypočtených barev oříznuty do rozsahu 0.0–1.0.
- Pokud je nastavena operace mapování hodnot pomocí tabulek LUT, tj. byla zavolána funkce glPixelTransfer(GL_MAP_COLOR, GL_TRUE), je každá barvová hodnota vynásobena velikostí LUT tabulky a v této tabulce je vyhledán řádek s vypočteným indexem (vzhledem k tomu, že hodnota pixelu byla předem ořezána do rozsahu 0.0–1.0, je tato operace v pořádku a nikdy nemůže dojít k tomu, že by se index odkazoval mimo tabulku). Nová hodnota barvy pixelu je poté z vyhledávací tabulky nebo tabulek přečtena. Pokud je pro každou barvovou složku alokována tabulka s jinou velikostí, vypočtou se indexy pro každou barvu samostatně (samozřejmě, že korektně).
- Po mapování pomocí LUT je opět provedeno oříznutí hodnot barev do rozsahu 0.0–1.0. V případě, že imaging subset není podporován nebo je vypnut, zpracování v tomto bodu končí a vypočtené RGBA hodnoty se mohou zapsat do framebufferu.
- V případě, že je podporován imaging subset, je možné na výsledný obrázek aplikovat jednoduchý konvoluční filtr, který může být buď jednorozměrný, nebo dvourozměrný. Pokud jsou parametry konvolučního filtru zadány a filtrace je povolena, je v tomto bodu aplikován na pixely ukládané do framebufferu.
- Po provedení filtrace, kde na každou barvovou složku může být aplikován jiný konvoluční filtr, se provede opětovné vynásobení každé barvové složky hodnotou uloženou v konstantách GL_POST_CONVOLUTION_RED_SCALE,GL_POST_CONVOLUTION_GREEN_SCALE, GL_POST_CONVOLUTION_BLUE_SCALE a GL_POST_CONVOLUTION_ALPHA_SCALE. Inicializační hodnota těchto konstant je rovna jedné, tj. barvové složky se vynásobením nezmění.
- Následně je ke každé barvové složce přičtena jedna z konstant GL_POST_CONVOLUTION_RED_BIAS, GL_POST_CONVOLUTION_GREEN_BIAS, GL_POST_CONVOLUTION_BLUE_BIAS aGL_POST_CONVOLUTION_ALPHA_BIAS. Inicializační hodnota těchto konstant je rovna nule, opět se tedy nemění hodnoty zpracovávaných barvových složek.
Zpracování pixelů nesoucích index do barevné palety
Pixely, které nesou informaci o barvě v paletovém (index color) režimu, jsou během přenosu modifikovány poněkud odlišným způsobem než pixely, které obsahují true-color barvu:
- Hodnota pixelu (což je, jak již víme, číslo v pevné řádové čárce) je posunuta pomocí operace bitového posunu doleva o GL_INDEX_SHIFT bitů, nové bity z pravé strany jsou doplněny nulami. Pokud je pomocí funkce glPixelTransfer*() zadáno do parametru GL_INDEX_SHIFT záporné číslo, provádí se bitový posun doprava, nové bity se opět vyplňují nulami (jde tedy o unsigned hodnoty).
- K nové hodnotě pixelu je připočtena konstanta GL_INDEX_OFFSET, která je opět zadána pomocí funkce glPixelTransfer*().
- Pokud je barvový buffer nastaven do paletového režimu, je provedeno překódování barev pomocí vyhledávací tabulky – viz dále popsaná funkce glPixelMap(). Přitom je použita tabulka GL_PIXEL_MAP_I_TO_I.
- Pokud jsou barvové buffery nastaveny do režimu pravých barev (RGBA, true color), jsou indexy do barevné palety zkonvertovány na pravé barvy. To se provede tak, že z vyhledávacích tabulek GL_PIXEL_MAP_I_TO_R, GL_PIXEL_MAP_I_TO_G, GL_PIXEL_MAP_I_TO_B a GL_PIXEL_MAP_I_TO_A jsou přečteny jednotlivé barvy na indexu odpovídajícím hodnotě pixelu. Všechny čtyři vyhledávací tabulky jsou opět specifikovány pomocí funkce glPixelMap*(). Velikost vyhledávacích tabulek může být u jednotlivých barevných položek různá – indexy se však vždy vypočtou tak, aby přesně spadaly do velikosti tabulky.
Zpracování pixelů s informacemi o hloubce
Pixely, které nesou informace o hloubce, tj. jsou zapisovány do paměti hloubky (depth buffer, Z-buffer), nebo jsou z této paměti naopak čteny, se zpracovávají následovně:
- Hodnota pixelu je nejprve vynásobena konstantou GL_DEPTH_SCALE. Tato konstanta je nastavena pomocí funkce glPixelTransfer*().
- Následně je k výsledku předchozího výpočtu přičtena hodnota GL_DEPTH_BIAS, která je rovněž nastavena pomocí funkce glPixelTransfer*().
- Vzhledem k tomu, že všechny hodnoty zapisované do paměti hloubky musejí být v rozsahu 0.0–1.0, je provedeno ořezání výsledku z předchozí operace právě na tento rozsah.
Zpracování pixelů s informacemi o šabloně
Pixely, které nesou hodnoty zapisované do paměti šablony (stencil bufferu), nebo jsou z této paměti čteny, jsou zpracovávány podle následujícího postupu:
- Každá čtená či zapisovaná hodnota pixelu je posunuta o konstantuGL_INDEX_SHIFT. Tato operace je podobná operaci, která se provádí s pixely obsahujícími informace o indexu barvy. Kladná hodnota konstanty GL_INDEX_SHIFT značí posun doleva, záporná hodnota posun doprava.
- Hodnota získaná z předchozího bodu je přičtena ke konstantě GL_INDEX_OFFSET.
- Podobně jako u pixelů s indexovými barvami, i zde se může provést mapování podle nastavené vyhledávací tabulky – ovšem pouze v případě, že je mapování povoleno, viz GL_MAP_STENCIL. Velikost vyhledávací tabulky odpovídá hodnotě GL_PIXEL_MAP_S_TO_S_SIZE.
Pokračování
V dalším pokračování tohoto seriálu si popíšeme vytvoření LUT tabulek používaných pro mapování pixelů.
Seznam funkcí zmíněných v této části
glPixelTransferi()glPixelTransferf()
glPixelMap()
glGetError()
Zkomprimovaná verze článku
Zkomprimovaná verze tohoto článku je umístěna zde.