Direct 3D - Vykreslenie trojuholníka
V tejto časti sa naučíme vytvoriť vertex buffer a naplniť ho troma vertexami.
Vertex je bod definovaný súradnicami X,Y,Z, farbou atď. Keď vytvoríme 3 vertexy, Direct3D ich spojí čiarou a farebne vyplní plochu medzi nimi. Tak vznikne trojuholník. Ak sú farby vertexov rôzne, Direct3D vytvorí farebný prechod medzi nimi. Najprv musíme vertex deklarovať. Dx8vb.DLL obsahuje deklaráciu rôznych typov vertexov. My si však vytvoríme vlastnú.
Dim Vertex_Buffer As Direct3DVertexBuffer8 'Deklarovanie struktury MojVERTEXPrivate Type MojVERTEX x As Single 'x suradnica y As Single 'y suradnica z As Single 'z suradnica rhw As Single '"hustota" farby color As Long 'farba vertexu End Type 'konstanta flexible vector format (FVF), ktora definuje MojVERTEX. Const D3DFVF_MojVERTEX = (D3DFVF_XYZRHW Or D3DFVF_DIFFUSE)
Ako vidíte udali sme iba X,Y,Z súradnice, farbu a hustotu.Aby D3D vedel, z čoho sa náš vertex skladá, musíme vytvoriť špeciálnu konštantu FVF. Tá sa skladá z niekoľkých ďalších konštánt. Pomocou operátoru Or ich môžeme kombinovať. Spomeňme si aspoň zopár:
D3DFVF_XYZ - vertex je definovaný súradnicami X,Y,Z
D3DFVF_XYZRHW - vertex je definovaný súradnicami X,Y,Z a RHW komponentom.
D3DFVF_DIFFUSE - obsahuje difúznu farebnú časť.
D3DFVF_NORMAL - obsahuje normálový vektor
D3DFVF_SPECULAR - obsahuje farebnú časť, ktorá vytvára dojem lesku.
Teraz môžeme doplniť konkrétne hodnoty:
'inicializacia pola vertexov od 0 po 2 Dim Pole_Vertexov(3) As MojVERTEX With Pole_Vertexov(0): .x = 150: .y = 50: .z = 0.5: .rhw = 1: .color = RGB(255, 0, 0): End With With Pole_Vertexov(1): .x = 250: .y = 150: .z = 0.5: .rhw = 1: .color = RGB(0, 255, 0): End With With Pole_Vertexov(2): .x = 50: .y = 150: .z = 0.5: .rhw = 1: .color = RGB(0, 0, 255): End With Dim VelkostVertexu As Long 'Velkost jedneho vertexu VelkostVertexu = Len(Pole_Vertexov(0)) Set Vertex_Buffer = d3dDevice.CreateVertexBuffer(VelkostVertexu * 3, _ 0, D3DFVF_MojVERTEX, D3DPOOL_DEFAULT) D3DVertexBuffer8SetData Vertex_Buffer, 0, VelkostVertexu * 3, 0, Pole_Vertexov(0) Init_Geometry = True
Veľmi dobrým miestom, kde môžete uložiť svoje vertexy je VertexBuffer. Je to špeciálny zásobník (miesto v pamäti), do ktorého môžete uložiť, ale aj vybrať vertexy. Pozrime sa na to, ako sa dá vytvoriť a použiť.
CreateVertexBuffer
LengthInBytes = VelkostVertexu * 3 - Veľkosť vertexbuferu musí byť rovná veľkosti troch vertexov. Ak by bol príliš malý, D3D vygeneruje chybu: Overflow
FVF = D3DFVF_MojVERTEX - Sem dosadíme našu FVF konštantu
Flags = 0 - Vyuzitie - nepouzite
Pool = D3DPOOL_DEFAULT - Určuje miesto, kde sa má vertexBuffer vytvoriť.Default znamená, že D3D sám rozhodne kde. Najčastejšie do video a AGP pamäte.
flags = 0 - Využitie VertexBufferu - nepoužité. Tu možete napríklad nastaviť,aby sa do neho mohlo iba zapisovať alebo dynamické použitie pamäte.
Keď je vertex buffer vytvorený, naplníme ho vertexami:
D3DVertexBuffer8SetData
VBuffer = Vertex_Buffer - Kde sa majú vertexy uložiť. Nastavíme na náš vytvorený vertex buffer
Offset = 0 - Od ktoreho bajtu sa má zapisovať. 0 značí od začiatku bufferu. Ale to Assembleráci určite poznajú
Size = VertSizeInBytes*3 - Veľkosť odosielaných dát
flags = 0 - Typ uzamikania pamäte - nepoužité
data = Pole_Vertexov(0) - Data na odoslanie do vertexbufferu. Vždy je to prvý index poľa, ktorý udáva jeho začiatok.
Renderovanie
D3dDevice.BeginScene sizeOfVertex = Len(vert) D3dDevice.SetStreamSource 0, Vertex_Buffer, sizeOfVertex D3dDevice.SetVertexShader D3DFVF_MojVERTEX D3dDevice.DrawPrimitive D3DPT_TRIANGLELIST, 0, 1 D3dDevice.EndScene
Teraz priestor medzi BeginScene a EndScene nie je prázdny. Pri renderovaní je treba nastaviť:
1. odkiaľ chceme renderovať, 2. akým spôsobom a 3. čo chceme renderovať.
1.odkiaľ - SetStreamSource
StreamNumber = 0 - Číslo streamingu v rozsahu 0 až 1
VertexBuffer = Vertex_Buffer odkiaľ sa má renderovať
Stride = sizeOfVertex - Pokiaľ je nastavený VertexShader na FVF potom
je potrebné tu dosadiť veľkosť vertexu.
2. akým spôsobom - SetVertexShader
- ide o techniku tieňovania vertexov. VertexShader je osobitná kapitola. Pre
nás zatiaľ stačí nastaviť VertexShared na FVF.
3. čo - DrawPrimitive
PrimitiveType = D3DPT_TRIANGLELIST - spôsob spájania vertexov. Pozri nižšie.
StartVertex = 0 - začíname od prvého vertexu vo VertexBuffery.
PrimitiveCount = 1 - počet objektov, ktoré majú byť vykreslené. Pre nás je to 1 trojuholník.
Máme to za sebou. Nič zložité. Zopár príkazov, ktoré si rýchlo osvojíte.
Dodatok
Ako rozumieť zápisom: TriangleList,TriangleFan,TriangleStrip ?
Ide o spôsob spájania vertexov.
TriangleList(D3DPT_TRIANGLELIST) :
Presne špecifikuje, ktoré 3 body vytvoria trojuholník. Síce potrebujete viac vertexov, ale o to viac je flexibilný.
Vytvorené trojuholníky sú nezávislé.
TriangleFan(D3DPT_TRIANGLEFAN):
Všetky trojuholníky majú spoločný jeden vertex. V našom prípade je to bod 0. Prvý trojuholník je tvorený Vertexami 0,1,2; druhý 0,2,3; tretí 0,3,4 . Všimnite si, že oproti TriangleListu sme z 5 piatich vertexov vytvorili 3 trojuholníky. Pri povrchovom tieňovaní sú trojuholníky vytieňované podľa prvého vertexu.
TriangleStrip(D3DPT_TRIANGLESTRIP):
Najčastejší typ spájania. Podobá sa TriangleListu, ale spotrebuje menej vertexov, čím je pamäťovo a časovo efektívnejší. Vytvára skupinu spojených trojuholníkov. Vytvorené trojuholníky nie sú nezávislé.
Veľmi dobrý príklad, ktorý ukazuje rozdiely medzi triangle list, strip a fan si môžete stiahnuť tu
Vertexy, ktoré vytvárajú tvojuholník musia byť indexované podľa usporiadania na obrazovke v smere hodinových ručičiek. Skúste prehodiť indexy 2 a 3 - výsledok: prázdna scéna.
Farby v D3D: Dajú sa definovať 2 spôsobmi.
Hodnotou systémovej farby v hexadecimálnej sústave (napr. &HFFFFFFFF) alebo hodnotou RGB. Pozor! Vo VB je RBG hodnota udávaná opačne. Tzn., že RGB (255,0,0) vo VB je červená, ale v D3D je modrá - RGB (0,0,255).