IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

13. diel - 3D bludisko v XNA - Vertex a index buffer

Vitajte po dvadsiaty tretí. Nedávno som pod jedným článkom objavil otázku čo to je vlastne vertex buffer. Táto otázka sa mi celkom hodí, aj keď uznávam že mala byť zodpovedaná už skôr. Vlastne hneď na začiatku nášho snaženia. Iste si pamätáte ako sme sa pokúšali vykresľovať útvary z čiar a trojuholníkov. Zoberme si napríklad tretí diel, stiahnite si hotový projekt a ten použijeme ako východiskový bod. Len pre zopakovanie ak sa nemýlim tak sme pridali textúru na naše vertexy. Žiadne kolízie nás neťažilo, jo to boli časy. Pozrieme sa teda na to čo program robí. Vytvoril pár polí s vertexy a indexy a tie potom posielal do grafickej karty a následne ich vykresľoval. Nutné povedať že je posielal do grafickej karty zakaždým pred vykreslením, teda že pole sa nenachádzajú v pamäti grafickej karty. Nie je to moc žiadny veľký problém, keď máme len 4 vrcholy, ale čo keď to bude nejaká zložitá štruktúra, treba terén o 100 000 vrcholoch? Potom už viditeľný problém nastáva ale práve od toho tu máme vertex buffer.

Vertex a index buffer

Ako som už naznačil v úvode nie je to nič iné ako pole, ktoré je uložené v pamäti grafickej karty, takže práca s ním bude rýchlejší. Zaplatíme za to ale daň, zakaždým keď budeme potrebovať buffer modifikovať budeme si ho musieť stiahnuť do normálneho poľa, vykonať úpravy a tie potom neskôr opäť do buffera nastaviť. Dosť bolo teórie, poďme si to vyskúšať. Pridáme si dve nové premenné:

VertexBuffer krizekBuffer;
IndexBuffer krizekIdx;

A naopak premennú krizekVert a krizekIdx odstránime. Síce na nás vyskáče veľa chýb, ale Neľakajte sa. Zatiaľ. Pridáme typ premennej na tento riadok:

VertexPositionColor[] krizekVert = new VertexPositionColor[5];

A hneď nám hromada chýb zmiznú. Rovnako to vykonáme aj s poľom pre indexy, iba ja som ho nazval idx, ale ako je známe, mená nehrajú rolu:

int[] idx = new int[] {

Ďalej do metódy LoadContent vytvoríme inštanciu vertex bufferu:

krizekBuffer = new VertexBuffer(GraphicsDevice, VertexPositionColor.VertexDeclaration, krizekVert.Length, BufferUsage.WriteOnly);

Pri tomto konstruktoru sa pozastavíme. Nie je totiž intuitívne. Prvý parameter je jasný, s touto premennou sme sa zoznámili už dosť detailne, avšak druhý parameter je nám zatiaľ neznámy. Vertex declaration, alebo ak slovensky deklarácie vertexu, hovorí grafickej karte, z čoho je presne zložený vertex. Presnejšie povedané koľko bajtov ktorá zložka zaberá a hlavne aký je jej význam. My máme len pozíciu a farbu, ale môžeme si nadefinovať vlastný typ vertexu ale to neprebiehajte. Tretí parameter je počet vertexov a na poslednom mieste je ako bude môcť byť s bufferom nakladané. Nám postačí aby bol len pre zápis. (Samozrejme len pre zápis zo strany procesora, pre grafickú kartu bude k dispozícii pre čítanie) Teraz môžeme nastaviť dáta a tým je odoslať do pamäte grafickej karty:

krizekBuffer.SetData<VertexPositionColor>(krizekVert);

O index buffera som zatiaľ ešte okrem nadpisu nepovedal vôbec nič. Ale funguje to úplne rovnako. Iba neuchovávame vertexy ale indexy podľa ktorých sa potom vertexy prepájajú. V metóde LoadContent teda vytvoríme inštanciu index bufferu:

krizekIdx = new IndexBuffer(GraphicsDevice, IndexElementSize.ThirtyTwoBits, idx.Length, BufferUsage.WriteOnly);

A opäť sa zastavíme pri konstruktoru. Prvý parameter je nás starý známy, druhým určujeme veľkosť indexov. Pričom 32 bitov zodpovedá typu int a 16 bitov typu short. Tretí parameter je počet indexov a naposledy opäť ako bude môcť byť s bufferom nakladané. Dáta si opäť do buffera nastavíme:

krizekIdx.SetData<int>(idx);

Prípravu máme hotovú a tak sa posunieme k vykresľovanie. Starý riadok zakomentujeme a tým sa snáď zbavíte aj všetkých chýb. Vykresľovanie s pomocou bufferov je na viac ako jeden riadok. Najprv musíme obaja buffer nastaviť ako aktívny:

GraphicsDevice.SetVertexBuffer(krizekBuffer);
GraphicsDevice.Indices = krizekIdx;

A teraz s ich pomocou všetko vykreslíme. Použijeme metódu DrawIndexedPrimitives:

GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.LineList, 0, 0, 5, 0, 4);

Na môj vkus trochu moc parametrov, rozoberieme si ich. Prvá je, akým spôsobom sa majú objekty vykresľovať. Prvá nula, k čomu toto presne je nedokážem povedať, ale keďže to je podľa popisu báza, tak 0 by nemala byť na škodu. Druhý parameter je pre mňa tiež neznámy, takže nula. Tretí parameter je, koľko vertexov chceme, aby bolo k vykresľovanie použité, takže 5. Posledné nula je offset v bufferu s indexmi, takže tiež nula a na záver koľko objektov budeme kresliť. Ak by niekto z vás mal nejaké ďalšie informácie ohľadom významov, ma neznámych parametrov, tak sa určite ozvite v komentároch.

Napodiv je to všetko. Ak teraz program spustíte tak by ste mali dostať rovnaký výsledok ako s predchádzajúcim kódom. Jediný rozdiel je však v uložení vertexov v pamäti. Dobré je tiež podotknúť, že nahrávame ak modely, tak ich dáta sú uložené práve pomocou bufferov a sú teda už k dispozícii u grafickej karty.

XNA ponúka aj triedy s dynamickými buffer, nijako sa nelíši od týchto jenoduchých, len majú v sebe optimalizácie, ktoré umožňujú jednoduchú modifikáciu.

A to by bolo myslím pre dnešok všetko. Nabudúce si skúsime zlepšiť rýchlosť vykresľovanie u bludisko. Ako zatiaľ neprezradím, ale je jasné že budeme buffer potrebovať a že nám ukážu svoju pravú silu. Čakám tiež na prípadné otázky v komentároch.


 

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

Stiahnuté 498x (99.7 kB)

 

Predchádzajúci článok
3D bludisko v XNA - Hráčska kamera
Všetky články v sekcii
3D bludisko v XNA
Preskočiť článok
(neodporúčame)
3D bludisko v XNA - Hardvérové instancování prvýkrát
Článok pre vás napísal vodacek
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Vodáček dělá že umí C#, naplno se již pět let angažuje v projektu ŽvB. Nyní studuje na FEI Upa informatiku, ikdyž si připadá spíš na ekonomice. Není mu také cizí PHP a SQL. Naopak cizí mu je Java a Python.
Aktivity