Grafická knihovna OpenGL (4): základní geometrické útvary

22. 7. 2003
Doba čtení: 6 minut

Sdílet

V tomto dílu seriálu o knihovně OpenGL si popíšeme vlastnosti základních geometrických útvarů (grafických primitiv) a způsob jejich nastavování. Změnou vlastností primitiv lze zásadně ovlivnit způsob jejich grafické reprezentace ve výsledné scéně.

Základní vlastnosti grafických primitiv

V předchozím dílu jsme si stručně popsali deset typů primitiv, které lze v OpenGL při vykreslování použít. Těchto deset typů primitiv lze z hlediska jejich vlastností rozdělit do tří skupin:

  1. body: pouze jeden typ primitiva zadaného příkazem glBegin(GL_POINTS)
  2. úsečky: primitiva zadaná příkazy glBegin(GL_LINES), glBegin(GL_LI­NE_STRIP) a glBegin(GL_LI­NE_LOOP)
  3. plošné útvary: primitiva zadaná příkazy glBegin(GL_TRI­ANGLES), glBegin(GL_TRI­ANGLE_FAN), glBegin(GL_TRI­ANGLE_STRIP), glBegin(GL_QUADS), glBegin(GL_QU­AD_STRIP) a glBegin(GL_POLYGON)

Vlastnosti bodů

První vlastností, kterou lze měnit u všech typů primitiv, je barva vrcholu. Jelikož je bod zadán pouze jedním vrcholem (příkazem void glVertex()), je zadaná barva pro celý bod konstantní. Barva se zadává příkazem void glColor(). Formát barvy je definován v barevném modelu RGB (Red, Green, Blue – tedy tři barevné složky) nebo RGBA (Red, Green, Blue, Alpha – tři barevné složky a průhlednost). Jako typ dat lze pro specifikaci jednotlivých barevných složek zadat libovolný datový typ OpenGL.

Nejčastěji se pro zadávání barvy používají čísla typu GLfloat, kde každá barevná složka je specifikovaná reálným číslem v rozsahu od 0.0 do 1.0. V tomto případě se používají příkazy glColor3f() resp. void glColor4f(). Další často používanou možností je specifikace barvy třemi nebo čtyřmi byty. Potom lze použít typu GLubyte a příkazu void glColor3ub() resp. void glColor4ub(). Barvu bodů lze specifikovat buď vně, nebo uvnitř „závorkových“ příkazů glBegin() aglEnd().

Druhou vlastností je velikost bodu. Velikost se zadává příkazem void glPointSize(GLfloat size), kde parametr size musí být větší než nula. Implicitní velikost bodu je nastavena na 1.0, což odpovídá jednomu pixelu na obrazovce. Velikost bodů může být dosti velká, přičemž maximální velikost lze získat zavoláním funkce glGetFloatv(GL_PO­INT_SIZE_RANGE, minmax), kde minmax je pole dvou čísel typu float, ve kterém bude uložena minimální a maximální podporovaná velikost bodů. Velikost bodu nelze měnit uvnitř „závorkových“ příkazů glBegin() a glEnd().

Třetí vlastností, kterou lze vypnout, nebo zapnout, je antialiasing bodů, který se používá pro rozmazání hran. Antialiasing se zapíná příkazem glEnable(GL_PO­INT_SMOOTH) a vypíná příkazem glDisable(GL_PO­INT_SMOOTH). Pokud je antialiasing vypnutý, body se zobrazují jako čtverce, pokud je zapnutý, tak by se body měly zobrazit jako kruhy s rozmazanými okraji. Zde je zapotřebí zdůraznit, že ne všechny grafické akcelerátory podporují kruhové body. Antialiasing nelze zapnout ani vypnout uvnitř „závorkových“ příkazů glBegin() a glEnd(). Při vypnutém antialiasingu se velikost bodů zaokrouhluje na celé pixely, pokud je však antialiasing zapnutý, velikost může být neceločíselná.

Změna vlastností bodů je demonstrována na ukázkovém příkladě – viz zdrojový kód třetího příkladu a zdrojový kód s obarvenou syntaxí.

Vlastnosti úseček

Podobně jako u bodů, i u úseček lze měnit jejich barvu. Pokud se barva specifikuje před „závorkovým“ příkazem glBegin(), je celá úsečka vykreslena konstantní barvou. Pokud se barva specifikuje mezi příkazy glBegin() a glEnd(), může se měnit barva jednotlivých vrcholů. Na grafické kartě se potom provede lineární interpolace barev mezi vrcholy.

Druhou vlastností je tloušťka úsečky. Ta se nastavuje příkazem glLineWidth(GLfloat width), kde width musí být větší než nula. Implicitní tloušťka úseček je nastavena na hodnotu 1.0, což odpovídá jednomu pixelu na obrazovce. Maximální a minimální tloušťku čar lze zjistit zavoláním funkce glGetFloatv(GL_LI­NE_WIDTH_RANGE, minmax), kde minmax je pole dvou čísel typu float, ve kterém je uložena minimální a maximální tloušťka úseček.

Při vykreslování úsečky lze, podobně jako u bodů, povolit, nebo zakázat antialiasing. Pro tento účel se používají příkazy glEnable(GL_LI­NE_SMOOTH) a glDisable(GL_LI­NE_SMOOTH). Pokud je antialiasing úseček vypnutý, úsečka se vykreslí s ostrými hranami a konce úseček budou zarovnány s nejbližší souřadnou osou (konce jsou tedy horizontální nebo vertikální). Pokud je antialiasing úseček zapnutý, úsečka se vykreslí s rozmazanými hranami a konce úseček budou vždy kolmé na směrnici úsečky.

Poslední vlastností úseček je maska, která se používá při vykreslování jednotlivých pixelů úsečky. Maska je šestnáctibitová hodnota, kde jednotlivé bity určují, zda se má některá část úsečky vykreslit. Maska tedy specifikuje vzorek, kterým je úsečka vykreslena. Pokud je například maska nastavena na hodnotu 0×fff0 (binárně 1111111111110000), bude vždy dvanáct pixelů vykresleno a čtyři pixely nevykresleny. Maska se zadává příkazem glLineStipple(GLint factor, GLushort pattern), kde factor je faktor zvětšení masky ve směru úsečky (vzorek lze tedy na úsečce „natahovat“) apattern je bitová maska. Pro povolení maskování se musí zavolat příkaz glEnable(GL_LI­NE_STIPPLE), pro zakázání glDisable(GL_LI­NE_STIPPLE). Implicitně je maskování zakázáno.

Změna vlastností úseček je demonstrována na ukázkovém příkladě číslo 4 – viz zdrojový kód příkladu a zdrojový kód s obarvenou syntaxí.

Vlastnosti plošných útvarů (polygonů)

U plošných útvarů lze, podobně jako u bodů a úseček, měnit jejich barvu. Pokud se barva specifikuje před příkazem glBegin(), je celý útvar vykreslen jednou konstantní barvou (pokud nepoužijeme texturování a osvětlení – viz další díly). Pokud barvu specifikujeme mezi „závorkovými“ příkazy glBegin() a glEnd(), lze měnit barvu jednotlivých vrcholů. Grafická karta nebo softwarová implementace OpenGL potom provede interpolaci barvy. Tímto jednoduchým způsobem lze v OpenGL dosáhnout Gouraudova stínování.

Každý plošný útvar má dvě strany (faces) – rub a líc (back a front). Tyto strany (orientace se zjistí z normálového vektoru) mohou být vykresleny odlišně. Toho se dá využít například při řezu objektů, kdy je jasné, která strana leží uvnitř a která vně tělesa. Odvrácené strany úplně uzavřených těles lze ořezat (culling).

Pro rub a/nebo líc lze zadat mód vykreslování. Jsou možné tři varianty:

  • vykreslí se pouze vrcholy polygonu (plošného útvaru)
  • vykreslí se hrany polygonu
  • vykreslí se vyplněný polygon

Mód vykreslování se změní příkazem glPolygonMode(GLe­num face, GLenum mode), kde parametr face může nabývat hodnot GL_FRONT_AND_BACK (obě strany), GL_FRONT (přední strana) aGL_BACK (zadní strana). Parametr mode může nabývat hodnot GL_POINT (vykreslují se vrcholy), GL_LINE (vykreslují se hrany) a GL_FILL (vyplněný polygon).

U polygonů lze určit, jakým způsobem jsou zadány přední a zadní strany. Ty se vždy určují podle orientace vrcholů polygonu. Mód určování lze zadat příkazem glFrontFace(GLenum mode), kde parametr mode nabývá hodnot GL_CCW (vrcholy jsou orientovány proti směru hodinových ručiček, což je implicitní nastavení) nebo GL_CW (vrcholy jsou orientovány po směru hodinových ručiček). Lze také určit, které polygony mají být ze scény odstraněny (tzv. culling) ještě před jejich vykreslením. Výběr se provede příkazem glCullFace(GLenum mode), kde parametr mode nabývá hodnot GL_FRONT_AND_BACK (obě strany),GL_FRONT (přední strana) nebo GL_BACK (zadní strana).

Poslední vlastností plošných útvarů je výplňový vzorek. V případě, že je plošný útvar zobrazený s vykreslovacím módem GL_FILL, lze zadat bitovou masku o velikosti 32×32 bitů, která určuje vzorek, jímž se polygon vyplní. Vzorek se dlaždicovitě opakuje, dokud nevyplní celou plochu polygonu. Nulový bit označuje pixel, kam se nevykresluje, bit nastavený na jedničku označuje pixel, kam se vykreslování provede. Výplňový vzorek se změní příkazem glPolygonStip­ple(const GLubyte *mask), kde mask je ukazatel na pole 32×32 bitů (ve skutečnosti jde samozřejmě o pole 32×4 bytů). Aplikace výplňového vzorku se povolí příkazem glEnable(GL_PO­LYGON_STIPPLE), zákaz se provede příkazem glDisable(GL_PO­LYGON_STIPPLE).

ict ve školství 24

Změna vlastností plošných útvarů je demonstrována na ukázkovém příkladě číslo 5 – viz zdrojový kód příkladu a zdrojový kód s obarvenou syntaxí.

V dalším pokračování si popíšeme velmi důležitou část knihovny OpenGL – transformační matice a lineární transformace.

Autor článku

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