Projekt PGR - Jednoduché 3D bludiště se zrcadly

Radek Brich, xbrich02 at stud.fit.vutbr.cz

Instalace

Soubor Makefile obsahuje pravidla pro překlad programu v linuxu a ve Windows s MinGW. V systému musí být nainstalované knihovny OpenGL, GLU a GLUT. Po přeložení lze program spustit ze souboru bludiste (případně bludiste.exe)

Knihovna glpng

Tuto knihovnu jsem použil pro načítání textur ve formátu PNG. Formát PNG používá kvalitní kompresi a umožňuje uložení alfa kanálu. Archív se zdrojovými kódy lze získat z domovské stránky projektu. Tyto zdrojové kódy jsem přibalil k projektu (adresáře glpng a include) a do Makefile přidal příslušné pravidlo pro jejich překlad. Výsledkem překladu je binární soubor libglpng.a (ten se vytvoří v adresáři lib). Knihovnu lze přeložit v linuxu i ve Windows + MinGW.

Použití

Po spuštění programu se objevíme uprostřed bludiště. Můžeme se pohybovat dopředu a zpět, otáčet se na strany a koukat nahoru a dolu. V bludišti narazíme na několik zrcadel, které realisticky odráží scénu a vidíme v nich i sebe. Chodce představuje jednoduchý robot.

Ovládání

šipka nahoru pohyb vpřed
šipka dolu pohyb zpět
šipka vlevo otáčení doleva
šipka vpravo otáčení doprava
PAGE UP pohled nahoru
PAGE DOWN pohled dolu
z, y zmenšení zorného úhlu
x zvětšení zorného úhlu
f přepnutí na celou obrazovku
w přepnutí do okna
ESC, q ukončení programu

Implementace

Bludiště

Jako základ jsem použil program z prvního cvičení - lab01_task.c. V něm jsem změnil způsob ovladaní - proměnné xpos a zpos reprezentují přesnou polohu chodce, xrot případné natočení nahoru či dolu (rozhlížení) a yrot horizontální otočení a tedy i směr chůze. Stisknutím tlačítka pro chůzi dopředu nebo zpět se rozjede aktivuje časovač a pak se pravidelně mění poloha chodce podle úhlu otočení. Před přesunem na novou pozici se ještě kontroluje, zda nedojde ke kolizi - kolizní obálkou je čtverec.

Dále jsem přidal call listy pro základní objekty, tj. chodbu (obsahuje strop a podlahu) a pro stěnu. Zdi jsou vykreslovany pomocí jediné stěny. Další tři stěny vzniknou rotací této základní. Pomocí těchto dvou objektů lze tedy zobrazit celé bludiště. Kde se nachází zeď je definováno v poli map (v souboru defs.h). Jedná se o obyčejné dvourozměrné pole, zeď je v něm označena nulou a průchozí chodba jedničkou. Při vykreslování se pak jen prochází toto pole, posouvá scéna pomocí modelovací matice a volají příslušné call listy. Zdi jsou však kresleny jen pomocí jedné stěny a bylo by zbytečné vždy kreslit všechny čtyři - v mnoha případech bude stěna skryta. Z toho důvodu se vždy nejdříve zjišťuje, zda je stěna okrajová (na rozmezí zdi a chodby) a má tedy cenu ji vykreslovat.

Po otexturování a nasvícení vypadá bludiště takto:

snímek bludiště

Zrcadla

Do mapy jsem umístil deset různě natočených zrcadel. Ta na sebe vzájemně nevidí a chodec může mít v zorném poli vždy jen jedno zrcadlo. Na následujícím obrázku je vidět mapa bludiště tak, jak je definovaná v programu - šipka značí počáteční pozici a zeleně jsou označena zrcadla:

mapka

Zobrazení scény včetně zrcadel probíhá takto:

  1. U každého zrcadla zkontrolujeme, zda je viditelné. Takové zrcadlo je vždy jen jedno. Pokud je nalezeno nějaké viditelné zrcadlo, pokračujeme jeho zobrazením:
    1. Vypneme color a depth buffer. Vymažeme stencil buffer a nastavíme ho tak, aby se do něj zapisovala jednička.
    2. Vykreslíme polygon zrcadla.
    3. Aktivujeme color a depth buffer. Funkci stencil bufferu nastavíme na kontrolu jedničky.
    4. Modelovací matici upravíme na zobrazování zrcadlené scény.
    5. Vykreslíme chodce.
    6. Nastavíme pomocnou ořezávací plochu tak, aby se překrývala s polygonem zrcadla. Tím zabráníme vykreslení zrcadlené scény před zrcadlo.
    7. Vykreslíme zrcadlenou scénu.
    8. Deaktivujeme pomocnou ořezávací plochu a stencil test. Obnovíme modelovací matici hlavní scény.
    9. Zobrazíme polygon zrcadla s alpha blendingem, aby se zrcadlená scéna odlišila od hlavní.
  2. Zobrazíme zbytek scény.

Kontrola viditelnosti zrcadla probíhá na základě tabulky se souřadnicemi políček, z kterých je možno dané zrcadlo vidět. Tato políčka jsou v programu definována podle následující mapky (levý horní roh má souřadnice 0,0 a pravý dolní 19,19):

viditelnost zrcadel z jednotlivých polí

Pokud je zrcadlo podle této tabulky viditelné, ještě to neznamená, že je potřeba ho zobrazovat. Můžeme k němu být zády. Proto se ještě kontroluje, zda je zrcadlo v zorném úhlu. Přes tyto dva testy může dojít k zbytečnému zobrazování skrytého zrcadla - to ale už tolik nevadí, protože už je zajištěno, že se nikdy nezobrazí dvě najednou.

Výsledek vypadá takto:

snímek bludiště se zrcadlem robot v zrcadle

Použitá literatura