Grafická knihovna OpenGL (24): vlastnosti textur

16. 12. 2003
Doba čtení: 6 minut

Sdílet

V dnešním pokračování seriálu o grafické knihovně OpenGL si popíšeme způsob, jakým lze nastavit vlastnosti textur. Dále si popíšeme podporu rozšířených formátů textur, která je však dostupná pouze v některých verzích této knihovny.

Texturování 3

Obsah

Nastavování parametrů textur
Rozšíř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_REPE­AT), 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_FIL­TER:
    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_MIP­MAP_NEAREST,GL_NE­AREST_MIPMAP_LI­NEAR, GL_LINEAR_MIP­MAP_NEAREST a GL_LINEAR_MIP­MAP_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_FIL­TER:

    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_wid­th="" 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 glTexParamete­riv() resp. glTexParameter­fv(), 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
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:

Tabulka č. 515
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_AL­PHA4 GL_LUMINANCE_ALPHA
GL_LUMINANCE6_AL­PHA2 GL_LUMINANCE_ALPHA
GL_LUMINANCE8_AL­PHA8 GL_LUMINANCE_ALPHA
GL_LUMINANCE12_AL­PHA4 GL_LUMINANCE_ALPHA
GL_LUMINANCE12_AL­PHA12 GL_LUMINANCE_ALPHA
GL_LUMINANCE16_AL­PHA16 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


Tabulka č. 516
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_AL­PHA4       4 4  
GL_LUMINANCE6_AL­PHA2       2 6  
GL_LUMINANCE8_AL­PHA8       8 8  
GL_LUMINANCE12_AL­PHA4       4 12  
GL_LUMINANCE12_AL­PHA12       12 12  
GL_LUMINANCE16_AL­PHA16       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
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
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
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.

bitcoin_skoleni

Obrázek 5: Screenshot ze čtvrtého příkladu
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.

Autor článku

Vystudoval VUT FIT a v současné době pracuje na projektech vytvářených v jazycích Python a Go.