Projekt do předmětu Počítačová grafika 2007/2008
Minimální OpenGL demo
Autoři:
Bc. Marek Čevela (xcevel04) Bc. Jan Fajkus (xfajku00) Bc. Dominik Chvíla (xchvila00) Bc. Petr Škarek (xskare00)
Obsah Úvod............................................................................................................................................3 Postup práce................................................................................................................................3 Původní zdrojové kódy...........................................................................................................3 Pomocné funkce.....................................................................................................................3 VykresliKruh.....................................................................................................................3 VykresliMezikruzi.............................................................................................................4 VykresliPlast......................................................................................................................4 VykresliVnitrniPlast..........................................................................................................4 VykresliKuzel....................................................................................................................4 VykresliValec....................................................................................................................4 VykresliRouru...................................................................................................................5 Řešení jednotlivých součástí.......................................................................................................5 Moduly...................................................................................................................................5 Komplet dílů...........................................................................................................................5 Kliková hřídel.........................................................................................................................5 Píst..........................................................................................................................................5 Ojnice.....................................................................................................................................6 Hlava válce.............................................................................................................................6 Ventil......................................................................................................................................6 Vačka......................................................................................................................................6 Osvětlení.....................................................................................................................................7 Průhledný válec...........................................................................................................................7 Ovládání......................................................................................................................................8 Rozložení kláves:...................................................................................................................8 Obrázková příloha.......................................................................................................................9
Úvod Úkolem bylo implementovat minimální openGL demo. Požadavky byly následující: • Výsledný .exe soubor musí mít velikost maximálně 64kB • Program nesmí využívat externí knihovny nebo soubory a musí být přeložitelný na standardních Windows XP SP1 • Demo musí být zajímavé, tedy „různě se otáčející trojůhelníky nejsou uspokojivé řešení“ Při řešení jsme se rozhodli vycházet z bakalářské práce jednoho z řešitelů. Tento krok byl logický, neboť přeložený program se vešel do datového limitu 64kB. Pro předvedení funkcí openGL jsme tedy zvolili vizualizaci spalovacích motorů. Práci na projektu jsme rozdělili podle schopností a zájmů každého z řešitelů.
Postup práce Hned ze začátku práce na projektu se vyskyt problém. Ne úplně správným pochopením zadání se stalo, že jsme si mysleli, že můžeme použít knihovnu GLUT. Naše mylné vyložení zadání spočívalo v tom, že nelze použít externě uložené textury, zvukové stopy nebo podobné datové soubory. Až v pozdější fázi vývoje projektu jsme zjistili, že se jedná o jakékoli soubory, které nejsou standardně obsaženy ve Windows XP SP1. Tento operační systém ovšem standardně neobsahuje knihovnu glut32.dll, která je ovšem nutná pro využití GLUTu. Bohužel kvůli tomu vznik velký problém s realizací projektu. Všechny školní projekty do počítačové grafiky tuto knihovnu využívaly a psát program bez využití této knihovny pro nás byla novinka. I většina běžně dostupných tutorialů obsahuje hned na prvních řádcích příkaz #include
. Velice zásadní částí práce na projektu bylo tedy pochopit, jak pracovat s openGL bez využití GLUTu. Kód z většiny tutoriálů se na Windows nedal ani přeložit, natož aby uspokojivě fungoval. Bylo tedy potřeba složitě skládat kousky použitelného kódu z různých zdrojů. Jako nejvýhodnější zdroj informací se nakonec ukázal tutoriál nehe.ceskehry.cz.
Původní zdrojové kódy Protože při původním návrhu nebylo řešeno osvětlení, bylo potřeba funkce generující primitivní objekty přepracovat. Nebyl totiž kladen důraz na lícové a rubové strany polygonů, nebo jejich normálové vektory. Aby bylo možné použít osvětlení, bylo potřeba tento problém vyřešit.
Pomocné funkce VykresliKruh Kvůli zachování plynulosti vizualizace i na slabších strojích jsme zvolili variantu s možností regulovat kvalitu vykreslování. Jednoduchou změnou integerové proměnné presnost (což je realizováno pomcí klávesnice) je možné regulovat počet vykreslených polygonů. Tato funkce
pomocí goniometrických funkcí rozloží kruh na požadovaný počet trojůhelníků, jejichž souřadnice počítá ve for cyklu. Dále také zadává jednotlivým trojůhelníkům normálové vektory. Ač se to může zdát zbytečné, vzhledem k tomu, že jsou rovnoběžné (dokonce v jedné rovině), má to svůj důvod. Jde o znovapoužitelnost kódu pro další funkce, kde již trojúhelníky v jedné rovině neleží. Je nutné zadat tři parametry: integerová proměnná presnost určující počet vykreslovaných trojúhelníků proměnná typu float nazvaná polomer určující poloměr výsledného vyplněného kruhu (resp. Nejdelší úhlopříčku n-úhelníka) pole floatů color[4] určující požadovanou barvu
VykresliMezikruzi Tato funkce vychází z předchozí. Má o jeden vstupní parametr více. Jde o proměnnou vnitrni_polomer, kteřá určuje vnitřní poloměr mezikruží. To je realizováno pomocí čtyřúhelníků.
VykresliPlast Funkce vykresluje plášť válce. Válcová plocha je aproximována čtyřúhelník, jejichž počet se opět určuje hodnotou proměnné presnost. Tvar je tedy ne přímo kulatý, ale jedná se o plášť pravidelného n-bokého hranolu. Vzhledem k maximální velikosti čísla uložitelného do proměnné typu integer, je možné se téměř libovolně přiblížit k dokonale kulatému tvaru. Vzhledem k omezení, které je dáno rastrovým zobrazením na konečném zobrazovacím zařízení, lze říci, že výsledné tvary jsou pro lidské oko dokonale kulaté. Dála je této funkci předávána proměnná polomer, vyska a color[4].
VykresliVnitrniPlast Funkce se chová identicky jako předchozí, ale zaměňuje pořadí vykreslovaných bodů na polygonu (obdélníku) tak, aby lícová strana směřovala dovnitř.
VykresliKuzel Záměnou čtyřúhelníků za trojúhelníky ve funkci VykresliPlast a spojením dvou horních bodů do jednoho jsme dosáhli vykreslování pláště kužele.
VykresliValec Tato funkce na rozdíl od předchozích již využívá posouvání souřadnic v prostoru (tedy funkci openGL glTranslate) a rotaci souřadnic (funkci glRotate). Nejprve dojde k vykreslení pláště válce. Dále se souřadnice pootočí o 90° a posunou o polovinu výšky válce. Zavolá se funkce
VykresliKruh. Poté se souřadnice otočí o 180°, proběhne posun o výšku válce a znova se vykreslí kruh. Zdánlivě zbytečné otočení souřadnic místo posunu opačným směrem je odůvodněné – nemusíme nijak jinak hlídat směr, kterým míří normály jednotlivých trojúhelníků.
VykresliRouru Funkce vychází z předchozí s tím rozdílem, že navíc využívá proměnnou vnitrni_polomer a volá navíc funkci VykresliVnitrniPlast a místo dvou volání funkce VykresliKruh volá funkci VykresliMezikruzi. Ve výsledku se vykreslí válec, z kterého byl odečten menší válec se stejnou (resp. Větší) výškou a společnou osou.
Řešení jednotlivých součástí Moduly Pro jednoduchost implementace je motor kompletován z jednotlivých modulů, obsahujících buď jiné moduly, nebo konkrétní součásti. Základními moduly jsou samotné motory různých typů. Každý z motorů se skládá z jednoho nebo více kompletů. Komplet obsahuje klikovou hřídel, ojnici, píst a hlavu válce. Modul se spouští zavoláním funkce pojmenované podle konkrétního typu motoru. Např. MotorHDTwin88
Komplet dílů Komplet dílů má parametr s názvem faze. Tento parametr určuje v jaké fázi se motor nachází. Pomocí něj se nastavuje uspořádání jednotlivých pístů na klikové hřídeli a aktuální natočení vaček. Před vykreslením je potřeba nastavit úhel naklonění, který určuje skon osy válce. Komplet dílů se volá funkcí Valec
Kliková hřídel Modul kliková hřídel se řídí dvěma parametry: faze a zdvih. Zdvih určuje délku jejího ramene. Fáze určuje její natočení. Protože je fáze udávána ve stupních a jednotkou otáčení souřadnic v openGL jsou též stupně, je její vykreslení triviální. Parametr zdvih určuje délku ramene, tedy vzdálenost čepu od osy hřídele. Modul nejprve zajistí příslušné otočení a zavolá vykreslení kliky. V ten okamžik se nejprve vykreslí obě nosné části klikové hřídele a následně čep v požadované vzdálenosti od osy otáčení. Vykreslení klikové hřídele se volá funkcí Klika která následně dvakrát zavolá funkci VykresliKliku
Píst Pro výpočet polohy pístu je nutné použít tři parametry: zdvih, delka-ojnice a faze. Protože pohyb pístu v čase není funkcí sinus, je nutné uvažovat i délku ojnice. Při nekonečně dlouhé ojnici by se pohyb pístu sinusovce přiblížil úplně, ale protože modelujeme reálné motory, musíme použít složitější funkci d = r*(1+( λ /4)-cos(φ)-( λ *cos(φ)/4)) kde d je dráha pistu, φ je natočení kliky a λ je poměr délky ramene kliky r a délky ojnice. Po výpočtu polohy pístu se nastaví počátek souřadnic na ono místo a píst se vykreslí funkcí Píst,
která vypočte aktuální souřadnice, posune počátek souřadné soustavy a zavolá funkci VykresliPist
Ojnice Ojnice používá pro výpočet stejné parametry jako píst. Nejprve se spočítá poloha ramene klikové hřídele pomocí dvou rovnic x=d*cos(φ) y=d*sin(φ) kde d je zdvih a do vypočtených souřadnic se posune střed souřadného systému. Pak se vypočítá úhel naklonění pomocí následujících rovnic β=arsin(sin(α)*d/2*l) γ=2*π-(α+β) ω=2*π-(α+γ) kde d je zdvih, l je délka ojnice, α je úhel pootočení klikové hřídele od horní úvratě, ω je výsledný úhel. O výsledný úhel se souřadný systém pootočí a ojnice se zadanou délkou je vykreslena. Správnost výpočtu polohy všech třech součástí způsobí to, že ojnice „lícuje“ jak s klikovou hřídelí, tak s pístním čepem. Vykreslení zajišťuje funkce VykresliOjnici.
Hlava válce Tento modul používá opět stejné parametry jako moduly předchozí. Přesune souřadný systém nad horní úvrať pístu použitím součtu délky ojnice, poloviny zdvihu, výšky pístu a výšky spalovacího prostoru. Potom zavolá modul ventil pro sací a pro výfukový ventil. Vzhledem k vzájemnému pootočení vaček sání a výfuku předá výfukovému ventilu fázi o 180° větší. Pokud je aktivována volba DOHC, zavolá obě vačky dvakrát. Samozřejmě vše s příslušným posunutím a nakloněním. To zajišťuje funkce Hlava.
Ventil Přepočítání fáze klikové hřídele na fázi vačky, která se točí dvakrát pomaleji, je realizováno jednoduchým vydělením fáze dvěma. Následuje vykreslení ventilu v odpovídající poloze. Kromě ventilu je také vykresleno sedlo ventilu pro názornější zobrazení funkce. Po posunutí souřadnic o délku ventilu je zavolán modul vačka. Ventil je vykreslován funkcí Ventil.
Vačka Návrh vačky byl velice komplikovaný, protože reálné vačky mají tvar jen těžko matematicky popsatelný. Nakonec se osvědčilo vačku modelovat jako modifikovanou kružnici. V polovině jejího obvodu je jedna ze souřadnic násobena konstantou 2.0, což sice neodpovídá realitě, ale je jednoduché na výpočet, tvar se podobá reálné vačce a pohyb ventilu je pro naši simulaci příznivější. Tímto zkreslením se zvětšuje doba překřížení ventilů, která by při reálném zobrazení nebyla dostatečně výrazná a postřehnutelná. Vykreslování vačky má na starost funkce VykresliVacku
Osvětlení •
Celkem 2 statická světla na různé pozici
• Obstarává funkce : void Svetlo (int svetlo_x, bool svetlo_zap_vyp, bool osvetleni)
parametry funkce:
svetlo_x – zapnutí světla x (x značí číslo světla) bool svetlo_zap_vyp – zapnutí / vypnutí světel osvetleni – zapnuti / vypnuti osvetleni
Funkce nastavuje složky světla a vlastnosti materiálu, pozici světla, zapíná – vypíná světla a zapíná – vypíná osvětlení.
Průhledný válec •
Vykreslení průhledného válce pro píst
• Obstarává funkce : void VykresliRouruV(int presnost, float polomer, float vyska, float color[4])
parametry funkce:
presnost – kvalita vykreslení polomer – poloměr válce
vyska – výška válce color – nastavení barvy válce Vykreslení válce čtyřúhelníky. void VykresliValecPistu() Zapnutí průhlednosti, volání funkce VykresliRouruV() pro vykreslení válce.
Ovládání Program je ovládán z klávesnice. Ovádání myší by bylo příliš komplikované realizovat bez využití služeb knihovny GLUT. Navíc by se zbytečně zvětšoval datový objem finálního binárního .exe souboru. Vzhledem k možnosti plnohodnotného ovládání pomocí klávesnice by to navíc bylo duplicitní.
Rozložení kláves: Esc, X F1 Q W PageDown PageUp 1 2 3 4 5 6 7 8 9 0 P R C A S D F V směrové šipky
ukončení programu zapnutí/vypnutí fullscreen zobrazení zvýšení rychlosti animace snížení rychlosti animace zvýšení kvality zobrazení snížení kvality zobrazení motor V2 45° motor R4 jednoválcový motor motor V12 hvězdicový motor hvězdicový motor s pevnou klikou motor W12 motor R6 desetiválcový motor s protiběžnými písty motor R3 zobrazení/skrytí pístu zobrazení/skrytí ojnice zobrazení/skrytí klikové hřídele vypnutí světel zapnutí světel vypnutí osvětlení zapnutí osvětlení přepínání SOHC/DOHC otáčení modelu
Zdroje: http://nehe.ceske-hry.cz/tut_01.php (nehe tutorial) http://www.root.cz/clanky/opengl-28-blending/ (dokumentace funkcí pro průhlednost) http://www.fi.muni.cz/~ptx/PV112/Slides/PGA06.pdf (str. 22, nastavení složek vlastností světla) Příklady cvičení PGR – nastavení světel, průhlednost Bakalářská práce: Vizualizace cyklických motorů, Bc. Jan Fajkus, VUT FIT, Brno, 2007
Obrázková příloha