Obsah
Základní informace o texturování a návaznost na evaluátoryGenerování texturovacích souřadnic pomocí 1D evaluátorů
Generování texturovacích souřadnic pomocí 2D evaluátorů
Ukázka použití evaluátorů
Demonstrační příklady
Obsah dalšího pokračování
Seznam funkcí OpenGL zmíněných v této části
Zkomprimovaná verze článku i s přílohami
Základní informace o texturování a návaznost na evaluátory
V seriálu o grafické knihovně OpenGL, zejména v dílech XXII, XXIII,XXIV, XXV, XXVI, XXVII, XXVIII, XXIX a XXX jsem se podrobně zabýval způsobem pokrytí ploch vykreslovaných objektů rastrovým obrázkem – texturou. Ve stručnosti je možné říci, že pro úspěšné vykreslení otexturované plochy je zapotřebí provést čtyři operace:
- Vytvořit texturovací objekt a nastavit tento objekt jako aktivní.
- Vhodně nastavit všechny vlastnosti texturovacího objektu.
- Nahrát do texturovacího objektu texturu, tj. vlastní rastrový obrázek.
- Při vykreslování tělesa specifikovat pro každý vrchol souřadnici do textury.
Pokud bude pomocí příkazů OpenGL vykreslováno těleso, jehož povrch je složený z jednotlivých plošek (ať již trojúhelníků, čtyřúhelníků, či plošných polygonů), nebývá se zadáním souřadnic do textury problém, protože každý vrchol je specifikován příkazem glVertex*(), u nějž je možné doplnit barvu, normálový vektor a také texturovací souřadnici. Při použití texturování (bez výpočtu osvětlení) pak vypadá posloupnost příkazů pro specifikaci jednotlivých vrcholů následovně (předpokládám použití plošné rastrové textury, což je v počítačové grafice zdaleka nejběžnější případ):
// vykreslení povrchu tělesa s texturou glBegin(typ_grafické_primitivy); glTexCoord2f(u, v); // souřadnice do textury glVertex3f(x, y, z); // souřadnice vrcholu // zde následují další vrcholy glEnd();
Problém však může nastat v případě, že se má vykreslit Bézierova plocha, která je specifikována pouze pomocí řídících bodů, které obecně neleží na povrchu Bézierovy plochy – viz první obrázek.
Obrázek 1: Objekt složený z několika Bézierových plátů
Typický fragment kódu pro vykreslení Bézierovy plochy bez specifikace texturovacích souřadnic vypadá takto:
//----------------------------------------------- // Tato funkce vykreslí Bézierovu plochu z bodů //----------------------------------------------- void drawBezierSurfaceUsingEvaluators( GLfloat points[][4][3]) { int i,j; // předání řídících bodů Bézierovy plochy glMap2f(GL_MAP2_VERTEX_3, // počítat polohy vertexů 0, // rozsah mapování 1, // parametru u 3, // počet hodnot mezi par. u 4, // dimenze ve směru u 0, // rozsah mapování 1, // parametru v 12, // počet hodnot mezi par. v 4, // dimenze ve směru v &points[0][0][0]); // začátek vykreslování bodů glBegin(GL_POINTS); // osa u v parametrickém prostoru for (i=0; i<=30; i++) { // osa v v parametrickém prostoru for (j=0; j<=30; j++) { // výpočet polohy bodu a přenos // do vykreslovacího řetězce glEvalCoord2f((GLfloat)i/30.0, (GLfloat)j/30.0); } } glEnd(); }
Z předchozího kódu je patrné, že při „ručním“ výpočtu texturovacích souřadnic by bylo nutné před každým zavoláním funkce glEvalCoord2f() zavolat i funkci pro specifikaci souřadnic [u, v] v prostoru textury. Tím by se však ztratila největší výhoda evaluátorů, tj. minimalizace dat, která proudí po sběrnici z operační paměti počítače do grafického akcelerátoru.
Horší případ nastane, pokud se Bézierova křivka či plocha vykresluje pomocí dvojice funkcí glMapGrid2*() a glEvalMesh2(), protože v tomto případě nemáme přístup ke smyčce, ve které se jednotlivé řídící body vyčíslují, a tím pádem pro ně také nelze zapsat souřadnice do textury.
Proto je v OpenGL umožněno dopočítávat i souřadnice do textury pomocí evaluátorů. V dalším textu budu předpokládat, že se používají plošné rastrové textury, tj. klasické pixmapy (obrázky), ovšem evaluátory lze použít i pro jednorozměrné a trojrozměrné (objemové) textury.
Generování texturovacích souřadnic pomocí 1D evaluátorů
Nejprve se podívejme na možnosti, které nám evaluátory pro práci s texturami poskytují, posléze si ukážeme i konkrétní příklad jejich použití. Pro práci s texturovacími souřadnicemi lze použít jak jednodimenzionální, tak i dvojdimenzionální evaluátor. Dimenzí evaluátoru je zde myšlen počet parametrů, které je nutno zadat do rovnice parametrické křivky či plochy. U jednodimenzionálního evaluátoru se jedná o parametr t, u dvojdimenzionálního evaluátoru se používají dva na sobě nezávislé parametryu a v.
Evaluátor však může pro své zadané parametry vracet více hodnot, typicky to jsou souřadnice v ploše či v prostoru. Současně musí mít řídící body zadané křivky či plochy stejnou dimenzi (tj. stejný počet souřadnic) jako body počítané evaluátorem.
Bližší informace o jednodimenzionálních evaluátorech jsem podal ve čtvrté části tohoto seriálu, informace o dvojdimenzionálních evaluátorech jsou popsány v části páté.
Jednodimenzionální evaluátor, který je specifikován řídícími body Bézierovy křivky, může být nastaven tak, že jako svou hodnotu nevrací souřadnice vrcholu v prostoru, ale souřadnice do textury. To, kolik souřadnic bude vráceno a jaký mají význam, je specifikováno prvním parametrem ve funkci glMap1f(), který může pro potřeby generování texturovacích souřadnic nabývat hodnot:
- GL_MAP1_TEXTURE_COORD1 – řídící body Bézierovy křivky jsou zadány pouze jednou souřadnicí. Při použití evaluátoru jsou v grafickém vykreslovacím řetězci vypočteny souřadnice do jednorozměrné textury. Účinek je podobný jako při použití příkazu glTexCoord1().
- GL_MAP1_TEXTURE_COORD2 – řídící body Bézierovy křivky jsou zadány dvěma souřadnicemi v rovině textury. Výsledkem použití takto vytvořeného evaluátoru je dvojice souřadnic [s, t], které udávají pozici v plošné textuře. Účinek je podobný použití příkazuglTexCoord2(). Tento typ evaluátoru je pro naše účely nejvhodnější, protože souřadnice v rastrové textuře se udává právě dvojicí hodnot.
- GL_MAP1_TEXTURE_COORD3 – řídící body Bézierovy křivky jsou zadány třemi souřadnicemi, takže se při použití evaluátoru generují tři souřadnice [s, t, r], podobně jako při použití příkazu glTexCoord3(). Použití tohoto typu evaluátoru je možné u objemových (voxelových) textur.
- GL_MAP1_TEXTURE_COORD4 – řídící body Bézierovy křivky jsou zadány čtyřmi souřadnicemi, takže se generují čtyři souřadnice do textury [s, t, r, q], podobně jako při použití funkce glTexCoord4(). Čtvrtá souřadnice je použita při nelineárním mapování textur – to bylo popsáno v seriálu o OpenGL.
Generování texturovacích souřadnic pomocí 2D evaluátorů
Dvojdimenzionální evaluátor, který je specifikován řídícími body Bézierovy plochy, může být nastaven tak, aby jako svou hodnotu vracel souřadnice do textury. Podobně jako u 1D evaluátoru, i zde lze nastavit, kolik souřadnic má být počítáno a jaký mají význam. Nastavení se provádí přes první parametr funkce glMap2f():
- GL_MAP2_TEXTURE_COORD1 – řídící body Bézierovy plochy jsou zadány jednou souřadnicí. Při práci s evaluátorem se generují stejná data jako v případě použití příkazu glTexCoord1().
- GL_MAP2_TEXTURE_COORD2 – řídící body Bézierovy plochy jsou zadány dvojicí souřadnic. Použití je stejné jako v případě příkazu glTexCoord2() – generují se souřadnice pro rastrovou plošnou texturu.
- GL_MAP2_TEXTURE_COORD3 – řídící body Bézierovy plochy jsou zadány třemi souřadnicemi. S tímto typem evaluátoru se pracuje v případě, že se používají objemové (voxelové) textury.
- GL_MAP2_TEXTURE_COORD4 – řídící body Bézierovy plochy jsou zadány čtyřmi souřadnicemi, čehož lze využít při nelineárním mapování textur.
V počítačové grafice se nejčastěji používají plošné rastrové textury, proto se pracuje s evaluátorem, jehož vstupem i výstupem jsou dvě souřadnice – provádí se tedy mapování z jednoho 2D prostoru do jiného 2D prostoru.
Výpočet texturovacích souřadnic se provádí tak, že se nastaví jak evaluátory pro výpočet souřadnic vrcholů, tak i evaluátory pro výpočet souřadnic do textury. Ukázka kódu, který provádí vykreslení otexturované Bézierovy plochy, je uvedena v dalším odstavci.
Ukázka použití evaluátorů
V následující funkci je ukázáno, jakým způsobem je možné evaluátory použít pro vykreslení otexturované Bézierovy plochy. Tato funkce je součástí níže uvedených demonstračních příkladů.
//----------------------------------------------- // Tato funkce vykreslí otexturovanou Bézierovu // plochu pomocí evaluátorů. //----------------------------------------------- void drawBezierSurfaceUsingEvaluators() { #define DELENI 20 int i,j; // povolení 2D evaluátoru glEnable(GL_MAP2_VERTEX_3); // povolení evaluátoru pro výpočet text. souřadnic glEnable(GL_MAP2_TEXTURE_COORD_2); // předání řídících bodů Bézierovy plochy glMap2f( GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1,12, 4, &points[0][0][0]); // předání řídících bodů pro výpočet // texturovacích souřadnic pomocí evaluátorů glMap2f( GL_MAP2_TEXTURE_COORD_2, 0, 1, 2, 2, 0, 1, 4, 2, &texturePoints[0][0][0]); // vykreslení Bézierovy plochy glMapGrid2f(DELENI, 0.0f, 1.0f, DELENI, 0.0f, 1.0f); glEvalMesh2(GL_FILL, 0, DELENI, 0, DELENI); // zákaz aplikace obou typů evaluátorů glDisable(GL_MAP2_VERTEX_3); glDisable(GL_MAP2_TEXTURE_COORD_2); }
Demonstrační příklad
Po spuštění prvního demonstračního příkladu se vykreslí Bézierova bikubická plocha, která je vypočtena pomocí evaluátorů. Výpočet probíhá ve funkci drawBezierSurfaceUsingEvaluators(). Bézierova plocha se zobrazí pomocí plošek vykreslovaných primitivou GL_QUADS. Každá ploška je otexturovaná, přičemž textura je počítána lineární interpolací pomocí evaluátorů.
Zdrojový kód prvního demonstračního příkladu je dostupný zde, HTML verze se zvýrazněním syntaxe zde.
Obrázek 2: Screenshot prvního demonstračního příkladu
Po spuštění druhého demonstračního příkladu se taktéž vykreslí Bézierova bikubická plocha. V čase jsou měněny pozice některých řídících bodů, čímž dochází k zajímavým efektům. Tento demonstrační příklad pouze ukazuje vliv změny řídících bodů na Bézierovu plochu, reálně toho využijeme ve třetím příkladu.
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
Ve třetím demonstračním příkladu se vykreslí Bézierova bilineární plocha, která je otexturována, přičemž se textura počítá na základě Bézierovy bikubické plochy. Změna souřadnic do textury je průběžně měněna, čímž se dosahuje zajímavých efektů.
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 třetího demonstračního příkladu
Obsah dalšího pokračování
V dalším, už předposledním pokračování tohoto seriálu si ukážeme způsob, jakým je možné evaluátory použít při výpočtu normálových vektorů na povrchu Bézierových ploch.
Seznam funkcí zmíněných v této části
glBegin()glColor()
glEnd()
glEvalCoord2f()
glEvalMesh2()
glMap1f()
glMap2f()
glMapGrid2*()
glTexCoord1()
glVertex()
Zkomprimovaná verze článku i s přílohami
Zkomprimovaná verze tohoto článku je umístěna zde.