C/C++ & Visual C++Kurz DirectX (35.) |
|
┌vodem | DatovΘ struktury | Kurz DirectX | Downloads | Otßzky a odpov∞di |
|
V tΘto lekci se jeÜt∞ vrßtφme k normßlov²m vektor∙m terΘnu. Do te∩ jsme toti₧ tyto vektory poΦφtali velice zjednoduÜen∞ a dß se °φct i nep°esn∞. Dnes si ukß₧eme zp∙sob, jak vektory urΦit p°esn∞ji. V dalÜφ Φßsti lekce tyto vektory zobrazφme nad terΘnem, abychom vid∞li, ₧e jsou skuteΦn∞ sprßvn∞. 35.1. NormßlovΘ vektory (2.)Do dneÜnφ lekce jsme normßlov² vektor ka₧dΘho vertexu poΦφtali pouze ze dvou sm∞rov²ch vektor∙, kterΘ byly urΦeny polohou danΘho vertexu a jeho sousedy. Tento zp∙sob lze pou₧φt v p°φpad∞, ₧e terΘn nenφ p°φliÜ Φlenit² (tedy nejsou zde nßhlΘ zm∞ny v²Üky vertexu). V tomto p°φpad∞ toti₧ je vypoΦten² normßlov² vektor znaΦn∞ nep°esn². Meznφm p°φpadem je ostrß hrana. Normßla bude kolmß bu∩ k jednΘ nebo k druhΘ rovin∞ (podle toho, kde le₧φ uva₧ovanΘ vertexy), co₧ je samoz°ejm∞ neodpovφdß skuteΦnosti. Sprßvn∞ °eÜenφ spoΦφvß v tom, ₧e vezmeme v ·vahu vÜechny dφlΦφ normßlovΘ vektory rovin p°ilehl²ch k danΘm vertexu a z t∞chto vektor∙ pak urΦφme pr∙m∞rn² normßlov² vektor. Tedy pro vyznaΦen² vertex se jeho normßla spoΦφtß jako pr∙m∞r vektor∙ n0 a₧ n5 (d°φv jsme vlastn∞ vzali vektor n1 a ten jsme prohlßsili za normßlu n). Jak budeme postupovat p°i v²poΦtu? Nebude to nic moc slo₧itΘho. Nejprve vybereme sousedy vertexu, pro kter² chceme normßlu vypoΦφtat. Musφme brßt v ·vahu to, ₧e ne ka₧d² vertex mß vÜech 6 soused∙. Nap°φklad vrcholy na kraji terΘnu budou mφt o dva sousedy mΘn∞, vrcholy na "rohu" dokonce o t°i sousedy mΘn∞.
Postupn∞ tedy otestujeme existenci soused∙ v1 a₧ v6 a rovnou spoΦφtßme sm∞rov² vektor z vektoru v0 v²razem vx - v0 kde vx je v1 a₧ v6. P°itom jeÜt∞ ulo₧φme informaci, ₧e dan² soused skuteΦn∞ existuje a ₧e ho pozd∞ji musφme brßt v ·vahu. K≤d tΘto Φßsti bude vypadat nßsledovn∞: // Vektor, pro ktery normalu pocitame - stredovy vektor Prom∞nnß vecMask je typu unsigned char nebo BYTE. Ve vektorech s1 a₧ s6 jsou ulo₧eny sm∞rovΘ vektory p°φsluÜn²ch vertex∙ v0 - v6. V dalÜφm kroku vybere sprßvnΘ sousedy a vypoΦteme dφlΦφ normßly. V prom∞nnΘ vecMask je nastaven bit pokud existuje sm∞rov² vektor, tak₧e dva sousednφ bity p°edstavujφ dva sousednφ sm∞rovΘ vektory, ze kter²ch urΦφme normßlu. // Spocitame normaly pro sousedni dvojice Pro ka₧dΘ dva sousednφ sm∞rovΘ vektory spoΦφtßme vektorov² souΦin a v²sledn² vektor normalizujeme na jednotkovou velikost. V prom∞nnΘ n0 je suma vÜech dφlΦφch normßl. Tento vektor v zßp∞tφ pod∞lφme hodnotou iNormCount a zφskßme koneΦn² normßlov² vektor jednoho vertexu! // ulozime vysledny vektor - udelame prumer vsech dilcich normal Jako t°eÜniΦku na dortu vytvo°φme koneΦn² vektor jako pr∙m∞r vÜech dφlΦφch vektor∙ p°ilehl²ch rovin. Tφmto algoritmem spoΦφtßme normßly o hodn∞ p°esn∞ji ne₧ p∙vodnφ verzφ. Na druhou stranu v²poΦet trvß podstatn∞ dΘle, pro ka₧d² vertex toti₧ volßme funkci D3DXVec3Cross() hned 6x!!! 35.2. Zobrazenφ normßlov²ch vektor∙V druhΘ Φßsti lekce se budeme zab²vat tφm, jak normßly zobrazit u ka₧dΘho vertexu. Normßlu zobrazφme jako Φßru z p°φsluÜnΘho vertexu sm∞rem vzh∙ru. V²sledek pak bude vypadat jako kdyby na terΘnu byla dokonale kolmß trßva. Pro ka₧dou normßlu budeme pot°ebovat dva body (vertexy). V lokaci mßme 128x128 polφΦek tak₧e dohromady to bude 16384 normßl s 32768 vrcholy. Vytvo°φme tedy pro ka₧dou lokaci dalÜφ vertex buffer. Index buffer nebude v tomto p°φpad∞ pot°eba, proto₧e jednotlivΘ Φßry spolu nebudou mφt nic spoleΦnΘho, tudφ₧ je jakßkoliv indexace zbyteΦnß. struct Location Tento buffer vytvo°φme v metod∞ CreateQuadTree(). Ka₧dß lokace mß vlastnφ buffer na normßly a velikost jsme odvodili o pßr °ßdk∙ v²Üe: // Create VB for terrain and copy all locations Buffer m∙₧eme vytvo°it a naplnit ve stejnΘ smyΦce jako vertex buffer pro samotnΘ vertexy. m_pTerrainVB->GetBuffer()->Lock(l*LOC_V_SIZE*LOC_V_SIZE*sizeof(VERTEX), pVertices[i] = m_arTerrain[x][y]; Mod°e je vyznaΦen nov² k≤d ve smyΦce. Nejprve uzamkneme p°φsluÜn² buffer lokace, potΘ ve dvou vno°en²ch smyΦkßch nastavφme dva body pro ka₧dou normßlu. Prvnφ z t∞chto bod∙ je samotn² vertex, kterΘmu normßla pat°φ. Druh² bod je posunut² ve sm∞ru normßly (normßlov² vektor mßme ji₧ spoΦφtan²). Navφc jeÜt∞ ka₧dΘmu bodu p°i°adφme jinou barvu, aby byl vektor p∞kn∞ vid∞t na zelenΘm terΘnu. Na zßv∞r buffer samoz°ejm∞ odemkneme. Na ·pln² zßv∞r lekce jeÜt∞ ukß₧i, jak normßly vykreslit: if(m_dwFlags & TF_SHOWNORMALS) Viditelnost normßl je zßvislß na p°φznaku TF_SHOWNORMALS. Nastavφme standardnφ parametry jako vertex shader, texturu na NULL, vypneme sv∞tlo (normßly normßl nevedeme) a pak vykreslφme vektory pro ka₧dou viditelnou lokaci. Vykreslovßnφ normßl nenφ p°φliÜ efektivnφ, ale v tomto p°φpad∞ nßm samoz°ejm∞ nejde o v²kon. 35.3. Zßv∞rNa zßv∞r tu mßme obrßzek terΘnu s vykreslen²mi normßlov²mi vektory:
P°φklad si samoz°ejm∞ m∙₧ete stßhnout v sekci Downloads. Vykreslovßnφ normßlov²ch vektor∙ lze zapnout a vypnout klßvesou U. T∞Üφm se p°φÜt∞ nashledanou.
|
|