Texturování 3
Obsah
Nastavování parametrů texturRozšířená podpora formátů textur
Pokračování
Demonstrační příklady
Nastavování parametrů textur
Už v minulém dílu jsme v demonstračních příkladech používali funkce pro nastavení parametrů textury. Tyto funkce však nebyly podrobněji popsány, což se dnes budeme snažit napravit. Parametry textury (tj. například způsob, jakým je textura mapována na povrch vykreslovaného tělesa) lze nastavit voláním funkce:
void glTexParameterf( GLenum target, GLenum pname, GLfloat value );
nebo funkce
void glTexParameteri( GLenum target, GLenum pname, GLint value );
Alternativně lze také zavolat funkce, které jako svůj poslední parametr akceptují místo skalární hodnoty pole hodnot:
void glTexParameterfv( GLenum target, GLenum pname, const GLfloat *values ); void glTexParameteriv( GLenum target, GLenum pname, const GLint *values );
První parametr (target) může podle zvolené dimenze textury nabývat hodnot GL_TEXTURE_1D (jednodimenzionální texura, tj. barevný přechod), GL_TEXTURE_2D (nejběžnější, rastrová textura) nebo GL_TEXTURE_3D (objemová textura). Hodnoty dalších dvou parametrů pname a value jsou uvedeny v následujícím seznamu:
- Parametr GL_TEXTURE_WRAP_S:
tímto parametrem specifikujeme, zda se má při překročení rozsahu texturovací souřadnice ve směru osy s (tento rozsah je, jak víme z minulého dílu <0.0, 1.0>) provést opakování motivu na textuře (value=GL_REPEAT), nebo „protažení“ první či poslední hodnoty (value=GL_CLAMP). Opakování motivu na textuře je vhodné použít v případech, kdy zobrazujeme různé na sebe navazující motivy, například cihlové zdi, podlahy apod. Protažením textury lze v některých případech zamezit vizuálním artefaktům, které by se mohly objevit při napojování textur. Překročení rozsahu není tedy v žádném případě chybou, vyvoláme ho například příkazem glTexCoord2f(2.0, 0.5). Použití obou způsobů bude ukázáno v demonstračních příkladech. - Parametr GL_TEXTURE_WRAP_T:
tento parametr má podobný význam jako parametr předchozí s tím rozdílem, že se místo na souřadnici ve směru osy s vztahuje na souřadnici ve směru osy t. U 1D textur nemá hodnota tohoto parametru vliv na zobrazení textury, použitelný je pouze u 2D a 3D textur. Opakování resp. protažení textury lze pro souřadnice ve směrech s, t a r nastavovat nezávisle, což je patrné z demonstračních příkladů. - Parametr GL_TEXTURE_WRAP_R:
tento parametr má opět podobný význam jako předchozí dva parametry, ale vztahuje se na třetí souřadnici r, která je použita například u objemových textur. - Parametr GL_TEXTURE_MIN_FILTER:
tímto parametrem je možné zvolit filtr použitý při zmenšování textury, tj. tehdy, jestliže na plochu jednoho vykreslovaného pixelu musíme použít barvy několika sousedních texelů, jak je naznačeno na prvním obrázku níže. Nejjednodušší a nejrychlejší filtr se volí hodnotou GL_NEAREST. U tohoto filtru se barva vykreslovaného pixelu vypočte z barvy texelu, jehož souřadnice nejpřesněji odpovídají souřednicím zadaným do textury. Poněkud sofistikovanější filtr se zadává hodnotou GL_LINEAR, kdy se barva vykreslovaného pixelu spočítá pomocí bilineární interpolace z barev sousedních texelů. Další čtyři filtry (GL_NEAREST_MIPMAP_NEAREST,GL_NEAREST_MIPMAP_LINEAR, GL_LINEAR_MIPMAP_NEAREST a GL_LINEAR_MIPMAP_LINEAR) využívají tazkvané mipmapy, tj. texturu uloženou ve formátu jakési pyramidy, kde jsou kromě základního rozlišení textury obsažena i rozlišení nižší (vždy s polovičním počtem pixelů v horizontální i vertikální ose) až do mejmenší velikosti 1×1 pixel. - Parametr GL_TEXTURE_MAX_FILTER:
tímto parametrem se volí filtr použitý při zvětšování textury, tj. v případě, že vykreslovaný pixel obsahuje pouze malou plochu texelu. Možné hodnoty jsou GL_NEAREST (použije se nejbližší texel) nebo
GL_LINEAR (použije se lineární interpolace mezi barvami sousedních texelů). - Parametr GL_TEXTURE_width="" height="" border_COLOR:
tímto parametrem lze zvolit barvu rámečku okolo textury (pokud je rámeček použit, tj. má nenulovou šířku). V případě zadávání barvy je nutné použít příkazy glTexParameteriv() resp. glTexParameterfv(), protože barva se zadává jako vektor (pole) čtyř složek R, G, B a A. Implicitní barva rámečku je (0, 0, 0, 0), tedy černá.
Obrázek 1: Zvětšování a zmenšování textur
Rozšířená podpora formátů textur
Kromě základních formátů textur, které jsme si popsali v minulém dílu, je možné používat v OpenGL verze 1.2 a vyšších i další „rozšířené“ formáty. Jaká výhoda plyne z použití takových formátů? Především jde o to, že použitím některých formátů s malou nebo dostatečnou bitovou hloubkou můžeme ušetřit paměť alokovanou pro textury. Druhou výhodou je možnost použít textury načtené z různých externích souborů, které mají mnohdy exotický formát (pořád například nemůžu vystát formát BGR, proč se jedna nejmenovaná firma musí opět odlišovat?). V následující tabulce budou ukázány rozšířené formáty textur spolu se základním formátem a typem dat pro každou barevnou složku:
Korespondence mezi rozšířenými a základními formáty | |
Rozšířený formát | Základní formát |
GL_ALPHA4 | GL_ALPHA |
GL_ALPHA8 | GL_ALPHA |
GL_ALPHA12 | GL_ALPHA |
GL_ALPHA16 | GL_ALPHA |
GL_LUMINANCE4 | GL_LUMINANCE |
GL_LUMINANCE8 | GL_LUMINANCE |
GL_LUMINANCE12 | GL_LUMINANCE |
GL_LUMINANCE16 | GL_LUMINANCE |
GL_LUMINANCE4_ALPHA4 | GL_LUMINANCE_ALPHA |
GL_LUMINANCE6_ALPHA2 | GL_LUMINANCE_ALPHA |
GL_LUMINANCE8_ALPHA8 | GL_LUMINANCE_ALPHA |
GL_LUMINANCE12_ALPHA4 | GL_LUMINANCE_ALPHA |
GL_LUMINANCE12_ALPHA12 | GL_LUMINANCE_ALPHA |
GL_LUMINANCE16_ALPHA16 | GL_LUMINANCE_ALPHA |
GL_INTENSITY4 | GL_INTENSITY |
GL_INTENSITY8 | GL_INTENSITY |
GL_INTENSITY12 | GL_INTENSITY |
GL_INTENSITY16 | GL_INTENSITY |
GL_R3_G3_B2 | GL_RGB |
GL_RGB4 | GL_RGB |
GL_RGB5 | GL_RGB |
GL_RGB8 | GL_RGB |
GL_RGB10 | GL_RGB |
GL_RGB12 | GL_RGB |
GL_RGB16 | GL_RGB |
GL_RGBA2 | GL_RGBA |
GL_RGBA4 | GL_RGBA |
GL_RGB5_A1 | GL_RGBA |
GL_RGBA8 | GL_RGBA |
GL_RGB10_A2 | GL_RGBA |
GL_RGBA12 | GL_RGBA |
GL_RGBA16 | GL_RGBA |
Rozšířený formát | Počet bitů na bar. složku | |||||
R | G | B | A | L | I | |
GL_ALPHA4 | 4 | |||||
GL_ALPHA8 | 8 | |||||
GL_ALPHA12 | 12 | |||||
GL_ALPHA16 | 16 | |||||
GL_LUMINANCE4 | 4 | |||||
GL_LUMINANCE8 | 8 | |||||
GL_LUMINANCE12 | 12 | |||||
GL_LUMINANCE16 | 16 | |||||
GL_LUMINANCE4_ALPHA4 | 4 | 4 | ||||
GL_LUMINANCE6_ALPHA2 | 2 | 6 | ||||
GL_LUMINANCE8_ALPHA8 | 8 | 8 | ||||
GL_LUMINANCE12_ALPHA4 | 4 | 12 | ||||
GL_LUMINANCE12_ALPHA12 | 12 | 12 | ||||
GL_LUMINANCE16_ALPHA16 | 16 | 16 | ||||
GL_INTENSITY4 | 4 | |||||
GL_INTENSITY8 | 8 | |||||
GL_INTENSITY12 | 12 | |||||
GL_INTENSITY16 | 16 | |||||
GL_R3_G3_B2 | 3 | 3 | 2 | |||
GL_RGB4 | 4 | 4 | 4 | |||
GL_RGB5 | 5 | 5 | 5 | |||
GL_RGB8 | 8 | 8 | 8 | |||
GL_RGB10 | 10 | 10 | 10 | |||
GL_RGB12 | 12 | 12 | 12 | |||
GL_RGB16 | 16 | 16 | 16 | |||
GL_RGBA2 | 2 | 2 | 2 | 2 | ||
GL_RGBA4 | 4 | 4 | 4 | 4 | ||
GL_RGB5_A1 | 5 | 5 | 5 | 1 | ||
GL_RGBA8 | 8 | 8 | 8 | 8 | ||
GL_RGB10_A2 | 10 | 10 | 10 | 2 | ||
GL_RGBA12 | 12 | 12 | 12 | 12 | ||
GL_RGBA16 | 16 | 16 | 16 | 16 |
Pro šetření pamětí jsou zajímavé například formáty GL_R3_G3_B2, kdy paměť pro jeden texel zabírá pouze jeden byte, nebo GL_RGB5_A1, kde každá barevná složka zabírá 5 bitů (celkem je tedy pro barvu vyhrazeno 15 bitů) a alfa složka jeden bit (rozlišujeme tedy pouze průhlednost či neprůhlednost texelu).
Pokračování
V dalším pokračování si popíšeme techniku mipmappingu, která se používá zejména v interaktivní grafice a při tvorbě animací pro zamezení „problikávání“ barevných pixelů na texturovaných plochách.
Demonstrační příklady
Po spuštění prvního demonstračního příkladu se zobrazí čtverec s nanesenou texturou. Vedle čtverce je vykreslen polygon, jehož vrcholy odpovídají souřadnicím vrcholů čtverce v textuře. Pomocí levého tlačítka myši lze těmito vrcholy pohybovat a měnit tak tvar textury nanesené na čtverci. Je nastaveno opakování textury v obou směrech (s i t), což je možné vyzkoušet na okrajích povolené plochy. K dispozici je i zdrojový kód se zvýrazněnou syntaxí.
Obrázek 2: Screenshot z prvního příkladu
Druhý demonstrační příklad (HTML verze) vychází z příkladu prvního s tím rozdílem, že místo opakování textury je nastaveno její protažení. Opět se lze přesvědčit vysunutím vrcholu textury na okraj povolené plochy.
Obrázek 3: Screenshot ze druhého příkladu
Třetí demonstrační příklad (HTML verze)) mapuje textury tak, že v jednom směru jsou opakovány, ve druhém nataženy – jde tedy o jakýsi hybrid mezi prvním a druhým příkladem.
Obrázek 4: Screenshot ze třetího příkladu
Čtvrtý demonstrační příklad (HTML verze) je velmi podobný předchozímu příkladu s tím rozdílem, že jsou prohozeny směry opakování a natahování textur.
Obrázek 5: Screenshot ze čtvrtého příkladu
Pro majitele pomalejšího připojení k internetu je zde k dispozici celý článek i s přílohami zabalený do jednoho zip souboru.