pridaj zákazku
zoznam uchádzačov
ako pridať zákazku?
pridaj článok
zoznam zákaziek Možno ste už počuli o výškových mapách. Sú to také čiernobiele obrázky, pomocou ktorých sa vytvára 3D terén (výška terénu na určitej pozícii je určená farbou zodpovedajúceho bodu na výškovej mape). Najjednoduchšie je výškovú mapu načítať zo súboru a je pokoj. Sú však situácie, ako napr. keď robíte grafické demo, ktoré má byť čo najmenšie, keď príde vhod výškovú mapu vygenerovať procedurálne. Takže si ukážeme ako na to. Ešte snáď spomeniem že čítať ďalej môžu aj tí, ktorí chcú vedieť ako vygenerovať takzvané "oblaky" (niekedy sa tomu hovorí aj plazma), nakoľko tento tutoriál bude z veľkej časti práve o tom.
Naša výšková mapa bude vyzerať približne takto:

Takže ako to teda funguje? Prvú vec, ktorú by ste mali poznať, je rekurzia. Pre tých, ktorí nevedia čo to je, skúsim v krátkosti vysvetliť. Rekurzia je, keď nejaká procedúra alebo funkcia zavolá sama seba. Príklad:
Táto procedúra spraví to, že sa vypíšu všetky čísla od X do 10 (takže davaj(3); vypíše čísla od 3 do 10). To if x < 10 zabezpečí, že keď bude procedúra zavolaná s parametrom väčším alebo rovným 10, procedúra nebude ďalej volať sama seba. Niesom si istý, tuším sa tomu hovorí návrat z rekurzie alebo tak nejako, podstatné je to, že bez toho by rekurzívna procedúra volala sama seba donekonečna, čo by viedlo k pádu programu (pre nedostatok pamäte). Na túto vec treba vždy pri písaní rekurzívnych procedúr myslieť, aby vám niekedy skončili.
Takže toľko vsuvka o rekurzii, teraz spať k vytváraniu výškovej mapy. Algoritmus je taký, že procedúra dostane ako parametre súradnice obdĺžnika, ktorý chceme vyplniť oblakmi, rozdelí ho na 4 menšie obdĺžniky a zavolá sama seba na každý z nich. Situácia vyzerá takto:
[X1,Y1] [X2,Y1]
Cl1-------1-------Cl2
| | |
| | |
3-------5-------4
| | |
| | |
Cl3-------2-------Cl4
[X1,Y2] [X2,Y2]
Funkcia dostane ako parametre X1,Y1,X2,Y2, čo sú súradnice obdĺžnika, ktorý chceme vyplniť. Najskôr skontroluje, či náhodou jeho rozmer nie je menší ako 2x2, ak áno, ukončí sa (to bude návrat z rekurzie). Potom stredu každej strany (1,2,3,4) nastaví farbu, ktorá je rovná priemeru farieb koncových bodov tejto strany (takže farba bodu 1 bude (cl1+cl2)/2..atď) a stredu obdĺžnika nastaví farbu rovnú priemeru farieb jeho rohov, teda (cl1+cl2+cl3+cl4)/4. K tejto farbe potom pripočíta/odpočíta náhodné číslo, ktorého veľkosť bude závisieť od veľkosti obdĺžnika. No a nakoniec zavolá 4 krát sama seba na všetky štyri obdĺžniky ktoré vynikli "rozdelením" pôvodného obdĺžnika (cl1,1,5,3; 1,cl2,4,5; 3,5,2,cl3; 5,4,cl4,2). To je celé.
Teraz si ukážeme ako to bude vyzerať prakticky (prakticky = ako to zapísať v Delphi; týmto sa zároveň ospravedlňujem všetkým céčkarom, ale keď niekto používa tak hackerský jazyk ako C alebo nebodaj C++, určite pochopí aj ten pascalovský kód ;)). Najskôr treba poriešiť, kam budeme našu výškovú mapu generovať. Ja som použil globálne jednorozmerné dynamické pole, (aby som mohol jednoducho meniť veľkosť mapy, ale ak chcete, kľudne môžete použiť aj statické pole, alebo si alokovať pamäť tými vašimi malloc-mi a getmem-ami), ktoré pomenujeme poeticky _.
Pred samotným aktom tvorenia procedúry, ktorá sa bude starať o vygenerovanie oblakov do nášho poľa, napíšeme si zopár pomocných procedúr:
Skôr ako začneme, musíme si ešte ujasniť jednu vec. Zjavne ideme generovať dvojrozmerný (2D) obrázok, a chceme ho mať uložený v 1 rozmernom poli. Takže otázka znie, aký je index poľa pre bod so súradnicami [X,Y]? Nebudem vás napínať, je to takto:
Tudíž keď chceme bodu na súradniciach [X,Y] nastaviť farbu F, napíšeme
Teraz máme všetko čo potrebujeme na to, aby sme mohli napísať našu rekurzívnu funkciu, ktorá nám vygeneruje oblaky. Nazveme si ju Divide. Tu je okomentovaný zdroják:
Možno ste si všimli, že celé oblaky závisia od toho, akej farby sú v rohoch výškovej mapy. Takže pred samotným zavolaním procedúry Divide im nastavíme náhodné hodnoty:
Ak sa čudujete prečo tam je random(64) a nie random(256), tak vedzte, že je to tak kôli tomu, aby bol terén na okrajoch nižší (to kvôli kamere, ktorá bude lietať okolo terénu). Preto sa prosím nesnažte v tom hľadať nejaký hlbší význam.
Pre istotu si ešte ukážeme, ako náš vysnený terén vyrenderovať pomocou OpenGL. Konkrétne si ukážeme hneď dva spôsoby. Na prvý budeme potrebovať ďalšie dve procedúry. Tieto procedúry použijeme, keď budeme chcieť vyrátať normálový vektor ľubovoľného trojuholníka - to sa hodí, keď chceme scénu osvetliť:
Definujeme si aj štruktúru TCoord3D, do ktorej si môžeme uložiť súradnice bodu alebo vektora:
Terén budeme vykresľovať po trojuholníkoch - každej štvorici bodov ([X,Y], [X+1,Y], [X+1,Y] a [X+1,Y+1]) na výškovej mape budú zodpovedať dva trojuholníky. Takže nám stačí prebehnúť pole dvoma vnorenými cyklami. No a takto to bude vyzerať:
Z komentárov by malo byť všetko jasné. Snáď len toľko, že treba niekde zadefinovať premennú Smooth typu boolean, ktorá určuje, či sa má terén vykresľovať vyhľadený alebo nie.

Napíš priamu reakciu