OpenGL a nadstavbová knihovna GLU (8)

14. 9. 2004
Doba čtení: 8 minut

Sdílet

Dnešní díl seriálu o nadstavbové grafické knihovně GLU bude věnován podrobnějšímu popisu funkcí, pomocí nichž je možné specifikovat jednotlivé typy kvadrik - kouli, válec, disk a kruhovou výseč. Tímto dílem také ukončíme rozpravu o kvadrikách a příště se již budeme zabývat mnohem zajímavějšími a důležitějšími funkcemi z knihovny GLU pro tvorbu NURB křivek a ploch.

Obsah

1. Vytvoření modelu koule
2. Vytvoření modelu válce nebo kužele
3. Vytvoření disku
4. Vytvoření kruhové výseče
5. Demonstrační příklady
6. Obsah dalšího pokračování
7. Seznam funkcí OpenGL, GLU a GLUT zmíněných v této části
8. Seznam funkcí GLU zmíněných v této části
9. Zkomprimovaná verze článku i s přílohami
 

1. Vytvoření modelu koule

Již v předchozí části tohoto seriálu jsme si ukázali, jakým způsobem je možné pomocí kvadrik vytvořit a zobrazit prostorový model koule. Funkce pro vytvoření modelu však nebyla podrobně popsána, proto to dnes musíme napravit.

Koule, jež patří mezi nejjednodušší kvadriky (pokud vynecháme lineární struktury, které jsou podmnožinou kvadrik), je popsána rovnicí:
x2+y2+z2-r2=0,
kde r značí poloměr koule.

Z předchozí rovnice plyne, že jediným parametrem, kterým je takto definovaná koule specifikována, je právě poloměr r. Střed koule leží v počátku souřadného systému, což však nepředstavuje při práci s modelem významnější problém, jelikož je možné souřadný systém natáčet a posouvat změnou transformačních matic, tj. pomocí funkcí glTranslatef() a glRotatef().

Funkce pro vytvoření modelu koule pomocí kvadrik se jmenuje gluSphere() a má následující deklaraci:

void gluSphere(
    GLUquadric  *quadric,
    GLdouble    radius,
    GLint       slices,
    GLint       stacks
);

Význam jednotlivých parametrů této funkce:

  1. V prvním parametru quadric se předává ukazatel na dříve vytvořený objekt kvadriky – viz funkce gluNewQuadric() popsaná v předchozí části tohoto seriálu.
  2. Ve druhém parametru radius se předává hodnota značící poloměr vytvářené koule. Ve skutečnosti se jedná o nadbytečný údaj, protože se velikost koule dá změnit i pomocí úpravy transformačních matic, zde však nedochází ke změně měřítka normálových vektorů.
  3. Ve třetím parametru slices se předává počet „poledníků“, pomocí nichž je koule rozdělena na jednotlivé plošky. Čím je tento údaj větší, tím více ploškami bude koule tvořena a tím přesnější bude její model (sníží se samozřejmě rychlost vykreslování).
  4. Ve čtvrtém parametru stacks se předává počet „rovnoběžek“, pomocí nichž je koule rozdělena na plošky. Počet rovnoběžek je o jedničku nižší než zde zadaná hodnota. To znamená, že pokud je do parametru stackszapsána hodnota 2, vytvoří se pouze jedna rovnoběžka – rovník a dva póly, mezi kterými jsou vytvořeny vykreslované plošky.

Vliv hodnot parametrů slices a stacks na vytvořený model je patrný z následujících tří ilustračních obrázků.

Model koule vytvořený pomocí funkce gluSphere() při nastavení parametrů slices=15 a stacks=15
Obrázek 1: Model koule vytvořený pomocí funkce gluSphere() při nastavení parametrů slices=15 a stacks=15

Model koule vytvořený pomocí funkce gluSphere() při nastavení parametrů slices=4 a stacks=15
Obrázek 2: Model koule vytvořený pomocí funkce gluSphere() při nastavení parametrů slices=4 a stacks=15

Model koule vytvořený pomocí funkce gluSphere() při nastavení parametrů slices=15 a stacks=3
Obrázek 3: Model koule vytvořený pomocí funkce gluSphere() při nastavení parametrů slices=15 a stacks=3

2. Vytvoření modelu válce nebo kužele

Mezi další kvadriky, které je možné s využitím funkcí z knihovny GLU vytvořit, patří válec a kužel. Pro oba tvary je použita stejná funkce, které se jmenuje gluCylinder() a má následující deklaraci:

void gluCylinder(
    GLUquadric  *quadric,
    GLdouble    baseRadius,
    GLdouble    topRadius,
    GLdouble    height,
    GLint       slices,
    GLint       stacks
);

Význam jednotlivých parametrů této funkce je následující:

  1. Přes první parametr quadric je předán ukazatel na dříve vytvořený objekt kvadriky, který má stejný význam jako u výše uvedené funkce gluSphere().
  2. Ve druhém parametru baseRadius je uveden poloměr válce/kužele u jeho základny. Tato hodnota by neměla být záporná.
  3. Ve třetím parametru topRadius je uveden poloměr válce/kužele u jeho horní základny (vrchlíku). Pokud jsou hodnoty parametrůbase­Radius a topRadius shodné, vytvoří se válec, pokus jsou rozdílné, vytvoří se komolý kužel. V případě, že je parametr topRadius nastaven na nulu, vytvoří se normální kužel s jedním vrcholem.
  4. Čtvrtým parametrem height je specifikována výška válce či kužele. Základna modelu je umístěna v počátku a osa vytvořeného tělesa směřuje vzhůru ve směru osy z. Aby byl model vycentrovaný, je zapotřebí před jeho vykreslením provést posun v záporném směru z-ové osy:glTransla­tef(0.0f, 0.0f, -height).
  5. V pátém parametru slices se předává počet „poledníků“, tj. dělení kolmých na základnu, pomocí nichž je válec či kužel rozdělen na jednotlivé plošky. Čím je tento údaj větší, tím více ploškami bude těleso tvořeno a tím přesnější bude jeho model (sníží se samozřejmě rychlost vykreslování).
  6. V posledním, šestém parametru stacks se předává počet „rovnoběžek“, tj. dělení rovnoběžných se základnou, pomocí nichž je válec či kužel rozdělen na plošky. Počet rovnoběžek je o jedničku nižší než zde zadaná hodnota. To znamená, že pokud je do parametru stacks zapsána hodnota 2, vytvoří se pouze jedna rovnoběžka – „rovník“ a dvě základny o poloměrechba­seRadius a topRadius, mezi kterými jsou vytvořeny vykreslované plošky.

Vliv hodnot parametrů slices a stacks na vytvořený model válce je patrný z následujících tří ilustračních obrázků.

Model válce vytvořený funkcí gluCylinder() při nastavení parametrů slices=15 a stacks=15
Obrázek 4: Model válce vytvořený funkcí gluCylinder() při nastavení parametrů slices=15 a stacks=15

Model válce vytvořený funkcí gluCylinder() při nastavení parametrů slices=4 a stacks=15
Obrázek 5: Model válce vytvořený funkcí gluCylinder() při nastavení parametrů slices=3 a stacks=15

Model válce vytvořený funkcí gluCylinder() při nastavení parametrů slices=15 a stacks=3
Obrázek 6: Model válce vytvořený funkcí gluCylinder() při nastavení parametrů slices=15 a stacks=3

3. Vytvoření disku

Kromě prostorových modelů těles lze pomocí kvadrik vytvořit i plošný disk (kruh či mezikruží). Ten je možné použít například při vyplňování děr ve vytvářeném modelu nebo pro uzavírání válců a kuželů. Vzhledem k tomu, že pomocí OpenGL není možné vykreslit kruh přímo jako grafickou primitivu (i když by analytické řešení průsečíku jednotlivých skenovacích řádků bylo jednodušší než u trojúhelníku), je model kruhu nejdříve rozdělen na několik plošek, a teprve ty jsou pak poslány do grafického vykreslovacího řetězce.

Počet plošek, na které je kruh rozdělen, je možné programově měnit již při jeho vytváření.

Funkce pro vytvoření disku/kruhu se jmenuje gluDisk() a má následující deklaraci:

void gluDisk(
    GLUquadric  *quadric,
    GLdouble    innerRadius,
    GLdouble    outerRadius,
    GLint       slices,
    GLint       loops
);

Význam jednotlivých parametrů této funkce je následující:

  1. V prvním parametru quadric funkce gluDisk() se předává ukazatel na dříve vytvořený objekt kvadriky. Význam tohoto parametru je tedy stejný jako u funkcí gluSphere() a gluCylinder().
  2. Ve druhém parametru innerRadius je předán vnitřní poloměr disku. Pokud je vnitřní poloměr nulový, bude disk celý vyplněn a vytvoří se tak kruh. Poloměr sice může být nulový, ale neměl by být záporný.
  3. Ve třetím parametru outerRadius je specifikován vnější poloměr disku, který by měl být větší než vnitřní poloměr. Pokud se vnitřní a vnější poloměry liší pouze o malou hodnotu (a přitom platí outerRadius>in­nerRadius), je výsledkem tenký prstenec.
  4. Dalším parametrem slices je možné zadat počet řezů, tj. počet vrcholů, které jsou vytvořeny na jednotlivých prstencích.
  5. Posledním parametrem loops se specifikuje počet prstenců, na kterých se vrcholy vytváří. Celkový počet vrcholů, ze kterých je vytvořena plocha prstence, je roven hodnotě slices*loop. Podobně jako u dalších objektů reprezentovaných svou hranicí platí, že čím větší je počet vrcholů na ploše, tím přesněji je plocha vykreslena (resp. tím přesněji odpovídá matematické ploše). Na druhou stranu se samozřejmě zvyšuje zatížení sběrnice a grafického akcelerátoru, který musí zpracovat větší množství dat.

4. Vytvoření kruhové výseče

Kruhová výseč je, podobně jako disk, rovinný útvar, který je tvořený pomocí čtyřúhelníků. Stejně jako u disků, i u kruhové výseče je nutné specifikovat vnitřní a vnější poloměr a způsob rozdělení tvaru na plošky. K těmto údajům je nutné navíc specifikovat i dva úhly, pomocí nichž se zadává tvar výseče, tj. část kruhu či prstence, která má být zobrazena.

Funkce pro vytvoření kruhové výseče se jmenuje gluPartialDisk() a má následující deklaraci:

void gluPartialDisk(
    GLUquadric  *quadric,
    GLdouble    innerRadius,
    GLdouble    outerRadius,
    GLint       slices,
    GLint       loops,
    GLdouble    startAngle,
    GLdouble    sweepAngle
);

Význam jednotlivých parametrů této funkce je následující:

  1. Přes první parametr quadric je předán ukazatel na dříve vytvořený model kvadriky.
  2. Pomocí druhého parametru innerRadius je specifikován vnitřní poloměr výseče.
  3. Pomocí třetího parametru outerRadius je specifikován vnější poloměr výseče. Pro oba poloměry platí stejné zákonitosti jako u výše popsané funkce gluDisk().
  4. Čtvrtým parametrem slices se zadává počet řezů disku, ze kterého se výseč tvoří.
  5. Počet prstenců, které tvoří kruhovou výseč, se předává v pátém parametru loops.
  6. V předposledním parametru startAngle je předán první úhel kruhové výseče, který je zadán ve stupních. Hodnota tohoto úhlu může být kladná i záporná, přičemž se berou do úvahy hodnoty vypočtené „modulo“ 360.
  7. V posledním parametru sweepAngle je předán obloukový úhel kruhové výseče, který je taktéž zadán ve stupních. Smysluplné hodnoty leží v rozsahu –360..360 stupňů, zadaná hodnota je do tohoto rozsahu ořezána.

5. Demonstrační příklady

První demonstrační příklad ukazuje, jakým způsobem je možné zobrazit model koule pomocí kvadrik. Parametry zobrazeného modelu lze měnit pomocí numerických kláves (viz vestavěnou nápovědu), pomocí myši je možné modelem rotovat a měnit jeho vzdálenost od pozorovatele.

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 7: Screenshot prvního demonstračního příkladu se zobrazeným modelem koule

Po spuštění druhého demonstračního příkladu se zobrazí model válce vykreslený taktéž pomocí kvadrik. Pomocí numerických kláves lze měnit parametry zobrazeného modelu, nápověda je přístupná přímo na obrazovce spuštěné aplikace.

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 modelem válce
Obrázek 8: Screenshot druhého demonstračního příkladu se zobrazeným modelem válce

Třetí demonstrační příklad ukazuje, jakým způsobem je možné pomocí funkcí z knihovny GLU zobrazit disk (kruh). Parametry zobrazeného modelu (zejména vnější a vnitřní poloměr) se opět mění pomocí numerických kláves.

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 modelem disku
Obrázek 9: Screenshot třetího demonstračního příkladu se zobrazeným modelem disku

Po spuštění čtvrtého demonstračního příkladu se zobrazí kruhová výseč složená z jednotlivých plošek. Kruhovou výsečí lze otáčet pomocí myši, podobně jako v ostatních demonstračních příkladech. Změna obloukového úhlu kruhové výseče se provádí pomocí kláves 9 a 0.

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

Screenshot čtvrtého demonstračního příkladu se zobrazeným modelem kruhové výseče
Obrázek 10: Screenshot čtvrtého demonstračního příkladu se zobrazeným modelem kruhové výseče

bitcoin_skoleni

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

V dalším pokračování tohoto seriálu se budeme zabývat NURB křivkami a plochami, pro jejichž vytvoření a vykreslení existují v knihovně GLU specializované funkce.

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

gluNewQuadric()
glTranslatef()
glRotatef()
 

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

gluSphere()
gluCylinder()
gluDisk()
gluPartialDisk()
 

9. 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.

Autor článku

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