Hlavní navigace

OpenGL a nadstavbová knihovna GLU (7)

7. 9. 2004
Doba čtení: 7 minut

Sdílet

V dnešním pokračování seriálu o nadstavbové grafické knihovně GLU si podrobně popíšeme postup, který je zapotřebí dodržet při vytváření a následném zobrazování kvadrik ve vykreslované trojrozměrné scéně.

Obsah

1. Vytvoření nového objektu s kvadrikou
2. Nastavení vlastností kvadrik – atributů pro rendering
3. Registrace callback funkce volané při výskytu chyby
4. Zavolání funkce pro vytvoření požadované kvadriky
5. Smazání objektu s kvadrikou
6. Demonstrační příklady
7. Obsah dalšího pokračování
8. Seznam funkcí OpenGL, GLU a GLUT zmíněných v této části
9. Nové funkce z knihovny GLU popsané v této části
10. Zkomprimovaná verze článku i s přílohami
 

1. Vytvoření nového objektu s kvadrikou

V předchozí části tohoto seriálu jsme si vypsali jednotlivé kroky, které se při práci s kvadrikami provádějí. Dnes si tyto kroky popíšeme podrobněji, dosažené výsledky našeho snažení budou patrné i z přiložených demonstračních příkladů.

Před jakoukoli další manipulací s kvadrikami je zapotřebí vytvořit objekt, který v knihovně GLU reprezentuje vytvářenou a zobrazovanou kvadriku. Při alokaci paměti pro tento objekt a jeho základní inicializaci se používá funkce gluNewQuadric(), která má následující hlavičku:

GLUquadric* gluNewQuadric(
    void
);

Pokud by se alokace paměti pro nový objekt z nějakého důvodu nepodařila, vrátí se místo korektního ukazatele nulová hodnota (vzhledem k tomu, že se vrací ukazatel, je vhodné pro přehlednost místo nuly používat makra NULL). Před dalším použitím objektu s kvadrikou je proto vhodné návratovou hodnotu testovat, například následujícím způsobem:

GLUquadric* quadric=gluNewQuadric();
if (!quadric) {
    perror("nedostatek systémových zdrojů pro vytvoření objektu kvadriky");
    ukonci_korektne_aplikaci();
} 

2. Nastavení vlastností kvadrik – atributů pro rendering

Atributy kvadrik se nastavují před jejich vlastním vykreslením pomocí několika funkcí, které budou popsány v následujících odstavcích.

gluQuadricDraw­Style()

Pomocí funkce gluQuadricDraw­Style() se nastavuje styl vykreslování kvadriky, tj. typ grafické primitivy, který bude použit pro reprezentaci povrchu kvadriky. Tato funkce má dva parametry. V prvním parametruquadric se specifikuje objekt kvadriky, který byl předem získán pomocí funkce gluNewQuadric() – viz předchozí odstavec. Ve druhém parametru drawStyle se předává styl, kterým bude kvadrika vykreslena.

Kvadriku lze vykreslit pomocí jednotlivých bodů, úseček spojujících jednotlivé vrcholy, nebo pomocí vyplněných polygonů – viz demonstrační příklady:

  • GLU_FILL – kvadrika je vykreslena pomocí vyplněných polygonů.
  • GLU_LINE – povrch kvadriky je složen z úseček, výsledkem je tedy drátový (wireframe) mo­del.
  • GLU_SILHOUETTE – povrch kvadriky je složen z úseček, ale pouze v těch částech povrchu, kde na sebe navazující plošky nejsou koplanární, tj. mají rozdílnou orientaci a směr svých normálových vektorů.
  • GLU_POINT – povrch kvadriky je složen z jednotlivých bo­dů.

Funkce gluQuadricDraw­Style() má v hlavičkovém souboru glu.h následující deklaraci:

void gluQuadricDrawStyle(
    GLUquadric* quadric,
    GLUenum     drawStyle
);

gluQuadricNormals()

Pomocí funkce gluQuadricNor­mals() se specifikuje, jakým způsobem se mají generovat normálové vektory na povrchu kvadriky. Normálové vektory se buď nemusí generovat vůbec, nebo se mohou generovat pro každý polygon (použito u flat stínování), nebo samostatně pro každý vrchol (použito u Gouraudova stínování).

Tato funkce má dva parametry. V prvním parametru quadric se specifikuje objekt kvadriky, podobně jako u funkcegluQu­adricDrawStyle().

Ve druhém parametru normal se pomocí symbolické konstanty předává způsob generování normálových vektorů. Tento parametr může nabývat tří hodnot:

  1. GLU_NONE – normálové vektory nejsou generovány, není je tedy možné použít například při výpočtu osvětlení povrchu.
  2. GLU_FLAT – normálové vektory jsou generovány pro každou vytvořenou plošku, při osvětlení má tedy každá ploška konstantní barvu, jelikož se používá konstantní stínování.
  3. GLU_SMOOTH – normálové vektory jsou generovány pro každý vrchol (jsou tedy získány průměrem normálových vektorů jednotlivých plošek, které mají společný vrchol). Tento způsob vytváření normálových vektorů se používá zejména při Gouraudově stínování.

Funkce gluQuadricNor­mals() má v hlavičkovém souboru glu.hnásledující deklaraci:

void gluQuadricNormals(
    GLUquadric* quadric,
    GLenum      normal
);

gluQuadricOri­entation()

Pomocí funkce gluQuadricOri­entation() se nastavuje orientace normálových vektorů při vytváření kvadrik. Normálové vektory mohou být směřovány buď dovnitř tělesa, nebo od povrchu tělesa směrem do volného prostoru. Tato funkce má opět dva parametry.

V prvním parametru quadric se specifikuje objekt kvadriky, podobně jako u výše popsaných funkcí gluQuadricDraw­Style() a gluQuadricNor­mals().

Ve druhém parametru orientation se specifikuje orientace vytvářených normálových vektorů. Tento parametr může nabývat následujících hodnot:

  1. GLU_INSIDE – vytvářené normálové vektory budou směřovat dovnitř kvadriky.
  2. GLU_OUTSIDE – vytvářené normálové vektory budou mířit směrem do prostoru. Toto chování je nastaveno implicitně a odpovídá smyslu normálových vektorů vytvářených pro účely osvětlování.

Funkce gluQuadricOri­entation() má v hlavičkovém souboruglu.h následující deklaraci:

void gluQuadricOrientation(
    GLUquadric* quadric,
    GLenum      orientation
);

gluQuadricTexture()

Pomocí funkce gluQuadricTex­ture() se zakazuje nebo povoluje generování texturovacích souřadnic pro vytvářenou kvadriku. Ve druhém parametru této funkce se pomocí symbolických konstant GL_TRUE aGL_FALSE specifikuje, zda se mají souřadnice do textur generovat, či nikoli. Implicitně je generování texturovacích souřadnic vypnuto, protože se jedná o poměrně zdlouhavou operaci.

Funkce gluQuadricTex­ture() má v hlavičkovém souboru glu.h následující deklaraci:

void gluQuadricTexture(
    GLUquadric* quadric,
    GLboolean   texture
);

Pokud se generování texturovacích souřadnic povolí, je pro každý vypočtený vrchol na povrchu kvadriky zavolána i funkce glTexCoord*() s příslušnou souřadnicí.

3. Registrace callback funkce volané při výskytu chyby

Při práci s kvadrikami se mohou vyskytnout různé chyby, které by měla korektně napsaná aplikace ošetřit. Funkce z knihovny GLU většinou nepoužívají klasický přístup funkcí jazyka C (tj. ze standardní knihovny jazyka C), při kterém se chybový kód vrací speciální hodnotou volané funkce. Místo toho se při výskytu chyby zavolá předem zaregistrovaná callback funkce, která musí na vzniklou situaci patřičným způsobem reagovat. Proto se volané callback funkci nepřímo předává i hodnota s kódem chyby (lze zjistit pomocí funkcegluGetE­rror()), který lze převést na čitelný řetězec pomocí funkce gluErrorString().

Registrace callback funkce se provede pomocí funkce gluQuadricCallbac­k(), která má následující hlavičku:

void APIENTRY gluQuadricCallback(
    GLUquadric  *qobj,
    GLenum      which,
    void        (CALLBACK* fn)()
);

V prvním parametru registrační funkce je předán ukazatel na objekt kvadriky, pro který se má callback funkce v případě výskytu chyby volat. Ve druhém parametru musí být předána hodnota GLU_ERROR, další hodnoty se mohou objevit v budoucnu. Ve třetím parametru je uložen ukazatel na callback funkci.

V případě, že je již nějaká callback funkce registrovaná, provede se nová registrace a ukazatel na starou funkci je zahozen. Volání callback funkce lze zabránit tak, že se do třetího parametru vloží hodnota NULL.

4. Zavolání funkce pro vytvoření požadované kvadriky

Vlastní vytvoření požadované kvadriky se provádí několika různými funkcemi, jejichž parametry se liší podle typu (tvaru) použité kvadriky.

Prvním a nejjednodušším typem kvadriky je koule, jejíž model se vytvoří zavoláním funkce gluSphere(). Dalším typem je válec či kužel, který se vytvoří zavoláním funkce gluCylinder(). Následují plošné (rovinné) objekty, jako je disk (gluDisk()) a kruhová výseč (gluPartialDis­k()).

Na podrobnější popis těchto funkcí už nemáme v dnešním pokračování dost místa, proto se jimi budu zabývat v další části tohoto seriálu.

5. Smazání objektu s kvadrikou

Po vykreslení kvadriky je možné celý objekt s kvadrikou smazat, a uvolnit tak obsazené systémové zdroje, které jsou pro tyto objekty v knihovně GLU interně alokovány. Smazání objektu je velmi jednoduché, pouze stačí zavolat funkci gluDeleteQuadric(), která má hlavičku:

void gluDeleteQuadric(
    GLUquadric *state
);

Po smazání objektu se ukazatel na tento objekt již nesmí dále používat, vedlo by to k chybám při běhu aplikace, protože by aplikace přistupovala do uvolněné paměti.

6. Demonstrační příklady

Po překladu a spuštění prvního demonstračního příkladu se zobrazí model koule pomocí jednotlivých bodů – grafické primitivy GL_POINT. Pomocí myši lze objektem otáčet (levé tlačítko) a přibližovat/vzda­lovat jej. Pomocí kláves 1 a 2 je možné měnit poloměr koule, klávesami 3, 4, 5 a 6 lze měnit počet dělení ideální koule na jednotlivé plošky. Pomocí kláves f a w je možné zvětšit okno aplikace přes celou obrazovku a poté nastavit původní velikost okna. Klávesou Esc se aplikace ukončuje.

Zdrojový kód prvního demonstračního příkladu je dostupný zde, jeho HTML verze se zvýrazněním syntaxe zde.

Screenshot prvního demonstračního příkladu se zobrazeným modelem koule
Obrázek 1: Screenshot prvního demonstračního příkladu se zobrazeným modelem koule

Druhý demonstrační příklad navazuje na příklad první, ale koule je zobrazena pomocí úseček spojujících jednotlivé vrcholy – jedná se tedy o známý wireframe model používaný u většiny konstrukčních systémů. Ovládání aplikace se oproti minulému příkladu nemění.

Zdrojový kód druhého demonstračního příkladu je dostupný zde, jeho HTML verze se zvýrazněním syntaxe zde.

Screenshot druhého demonstračního příkladu se zobrazeným drátovým modelem koule
Obrázek 2: Screenshot druhého demonstračního příkladu se zobrazeným drátovým modelem koule

Po spuštění třetího demonstračního příkladu se zobrazí model koule vytvořený z vyplněných a osvětlených plošek. Pro každý vrchol je automaticky vypočten normálový vektor, který je použit při výpočtu osvětlení. Ovládání aplikace opět zůstává zachováno.

Zdrojový kód třetího demonstračního příkladu je dostupný zde, jeho HTML verze se zvýrazněním syntaxe zde.

Screenshot třetího demonstračního příkladu se zobrazeným vyplněným a osvětleným modelem koule
Obrázek 3: Screenshot třetího demonstračního příkladu se zobrazeným vyplněným a osvětleným modelem koule

root_podpora

7. Obsah dalšího pokračování

V dalším pokračování tohoto seriálu si podrobněji popíšeme funkce pro specifikaci jednotlivých typů kvadrik – gluSphere(), gluCylinder(), gluDisk() a gluPartialDisk().

8. Seznam funkcí OpenGL, GLU a GLUT zmíněných v této části

gluGetError()
gluErrorString()

9. Nové funkce z knihovny GLU popsané v této části

gluNewQuadric()
gluQuadricDraw­Style()
gluQuadricOri­entation()
gluQuadricNormals()
gluQuadricTexture()
gluQuadricCallbac­k()
gluDeleteQuadric()
gluSphere()
 

10. Zkomprimovaná verze článku i s přílohami

Zkomprimovaná verze tohoto článku i s přílohami a demonstračními příklady je uložena zde.

Byl pro vás článek přínosný?

Autor článku

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