Úkolem je implementovat real-time simulaci ohňostroje ve 3D. Ohňostroj obsahuje odpalovací rampy (Launchers), ze kterých se vystřelují rakety, které potom ve vzduchu vybuchují a dávají vznik svítícím částicím (Particles). Rakety i částice jsou pod vlivem konstantního gravitačního pole (g = 9.81 m/s2). Navzájem však reagovat vůbec nebudou.
Jako základ poslouží projekt 087fireworks z repository grcis (GIT). Je připravena aplikace, která umí v reálném čase vykreslovat 3D scénu (ovládání systémem "Trackball"), mezi vykreslováním se volá simulace ohňostroje (Fireworks.Simulate()). Pro řízení Vaší simulace jsou připravena tlačítka Start / stop, Reset sim a Update sim. Při inicializaci/update simulace je možné použít uživatelem zadaný řetězec Param.
Pro případné interaktivní ovládání je v simulační třídě Fireworks připraveno několik
obslužných funkcí, které se zavolají v případě, že danou událost neošetří "Trackball"
(pozn.: ve funkci Form1.InitParams() si můžete určit, které tlačítko myši má
Trackball používat /default: levé/, ostatní tlačítka můžete obsluhovat Vy).
Připravené obslužné funkce:
Postačí implementovat jednoduchou Eulerovu simulaci v diskrétních časových intervalech (předpokládá se konstantní rychlost všech komponent simulace během krátkého simulovaného časového intervalu), na pohybující se tělesa (Particles) by měly působit alespoň tyto dvě síly:
Musíte implementovat funkčnost následujících komponent:
Simulace se počítá v diskrétních časových okamžicích, jednou v každém zobrazovacím cyklu. Všechny simulované objekty (Fireworks, Launcher i Particle) mají pro tento účel deklarovanou funkci Simulate ( double time ). Objekty se musí přepočítat tak, aby jejich stav odpovídal požadovanému času time v sekundách.
Univerzální systém (interface IRenderObject) se používá k vykreslování všech komponent
simulovaného světa. Jednotlivé objekty mohou definovat body (GL_POINTS), úsečky
(GL_LINES) a trojúhelníky (GL_TRIANGLES), pomocí kterých budou zobrazeny.
Vykreslování probíhá odděleně pro každý ze tří kreslených grafických primitiv a je implementováno
obecné dvoufázové plnění datových bufferů:
1. poprvé se zavolá metoda TriangleVertices() (TriangleIndices(),
LineVertices(), LineIndices() nebo PointVertices())
bez zadání datového pointeru, aby se jen zjistila velikost vertex-bufferu (index-bufferu)
v bytech
2. podruhé se již příslušné metody používají k vlastnímu naplnění dat, VBO buffer z grafické
karty se přitom namapuje do operační paměti aplikace metodou GL.MapBuffer()
Globální simulační objekt Fireworks implementuje agregované vykreslování ve třech fázích, nejprve trojúhelníky (FillTriangleData()), potom úsečky (FillLineData()) a nakonec body ("point-sprites" .. FillPointData()). Stačí, když všechny Vaše simulační objekty budou korektně implementovat interface IRenderObject a nebudete muset do vykreslování více zasahovat. Samozřejmě při požadavcích na komplikovanější efekty, např. rozšíření sady shaderů (viz Form1.InitShaderRepository()), budete muset i do vykreslovacího kódu zasáhnout.
V simulaci ohňostroje jsou dva typy objektů, které mohou generovat kresbu: odpalovací rampy (Launcher) a rakety / částice (Particle). Globální simulační objekt Fireworks obsahuje seznamy odpalovacích ramp i částic, ze kterých se potom v metodě RenderScene() vše vykresluje. Systém je navržen pro použití shaderů a VBO bufferů, bez nich vykreslování nefunguje (VAO objekty potřeba nejsou, lze tedy program spustit i na středně starých grafických kartách).
Při modifikacích se inspirujte pilotními implementacemi tříd Launcher a Particle, které jsou obě potomkem třídy DefaultRenderObject. Je to pohodlné, protože stačí přeprogramovat jenom některé funkce – podle toho, zda potřebujete kreslit body, úsečky či trojúhelníky (nic Vám však nebrání používat při vykreslování jednoho objektu více typů grafických primitiv).
Věnujte pozornost sadě atributů vrcholů, které se do GPU posílají. Např. má smysl modifikovat barvu vrcholu u všech třech typů primitiv, velikost bodu (gl_PointSize) má smysl jenom pro bodové objekty. Formulář obsahuje několik přepínačů se zřejmým významem, jejich nastavení můžete pohodlně inicializovat v metodě Form1.InitParams(). Vykreslovací systém je založen na dvou jednoduchých shaderech (vertex.glsl a fragment.glsl), které s těmito přepínači spolupracují přes "uniform" proměnné. Pro inspiraci je zobrazovací kód obohacen o jednu texturu, která se definuje programově, viz Form1.GenerateTexture(). V případě potřeby si snadno můžete doplnit další textury, i když to pravděpodobně pro ohňostroj nebude nutné.
Odevzdat do: 28. 2. 2022
Základ: 8 bodů (jednoduchá ale funkční simulace),
dalších až 14 bodů: bonus za zajímavá rozšíření (animace odpalovacích ramp, vícestupňové výbuchy,
změny barev, interaktivní ovládání /myš, klávesnice/, pokročilejší shaderové efekty, apod.)
Visual Studio projekt: 087fireworks
Modifikujte a odevzdejte soubor: Fireworks.cs (a případně soubory shaderů)
Do funkce InitParams() napište své jméno!
Copyright (C) 2015-2022 J.Pelikán, last change: 2022-02-02 01:03:41 +0100 (Wed, 02 Feb 2022)