I vertex buffer sono utilizzati come sappiamo per contenere i dati sui vertici di un modello. Questi possono essere inclusi in una mesh o utilizzati separatamente e passati al device. Riuscire a creare da zero un vertexbuffer può risultare fondamentale in moltissime situazioni, specie se si deve creare un oggetto da zero o lo si deve caricare da un formato diverso dal formatoX.
Per creare un vertexbuffer da zero è sufficiente dichiarare e creare un oggetto vertex buffer
Dim vb As New VertexBuffer(GetType(Vertex), numeroVertici, device, 0, formato, Pool.Managed)
Il fattore principale è la dimensione ed il formato. Prendiamo ad esempio il formato di vertice canonico.
Public Structure Vertex
Public p As Vector3
Public n As Vector3
Public tu, tv As Single
End Structure
Public Const Format As VertexFormats = VertexFormats.Position Or VertexFormats.Normal Or VertexFormats.Texture1
Tramite getType si prende il formato della struttura che vogliamo usare, passiamo poi il numero dei vertici, il device, l'uso (0) ed il formato. Infine il pool (managed non richiederà di ricaricare al reset).
Ora il vertexbuffer esiste ma tutti i suoi vertici sono a zero
Dim vertici As Vertex()
vertici = vb.Lock(0, GetType(Vertex), 0, NumberVertices)
For i = 0 To vertici.Length - 1
setta qui i vertici
Next
vb.Unlock()
Nel ciclo potete impostare i vertici come volete.
Per renderizzare
device.SetStreamSource(0, vb, 0)
device.VertexFormat = Vertex.Format
device.DrawPrimitives(PrimitiveType.TriangleList, 0, numeroV)
L'istruzione drawPrimitives renderizza il vertexbuffer che viene passato al device tramite setStreamsouce. NumeroV è il numero dei vertici da renderizzare. Potete sostituire 0 con il vertice di inizio. Importantissimo è passare il vertexFormat as device. Potete scegliere anche ulteriori stream (utili per alcuni effetti in vertex shader).
I vertexbuffer vengono solitamente usati in coppia con l'index buffer. In pratica nel vertexbuffer ci sono disordinatamente tutti i vertici e nell'indexbuffer viene dato l'ordine con cui devono essere renderizzati. Si tratta in pratica di un array di short che di ad esempio 1,2,3,0,1,3 per indicare l'ordine. Per i modelli formati da triangoli sono ovviamente sempre il numero della facce x 3;
Dim ib As New IndexBuffer(device,numberIndices, 0, Pool.Managed, True)
L'ultima è importante. Se impostata a true dovrete usare short come tipo, altrimenti integer. Questo perchè con gli short che sono a 16 bit si possono creare modelli con 65356 indici. Se però superate questo valore allora dovrete passare agli interi con ulteriore spesa di memoria.
Dim indexArray() As Short
indexArray = indexBuffer.Lock(0, GetType(Short), 0, NumberFaces * 3)
'qui usate l'array indexArray per modificare l'array
indexBuffer.Unlock()
device.SetStreamSource(0, vb, 0)
device.Indices = iB
device.VertexFormat = Vertex.Format
device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, NumberVertices, 0, numeroFacce)
In questo modo renderizzate primitive con indici.
Attenzione, non avrete i subset come nelle mesh quindi il vertexbuffer è un blocco unico.
In ultimo potete creare direttamente una mesh
Dim mesh As New Mesh(numeroFacce, numeroVertici, MeshFlags.Managed, formato, device)
Con l'accesso alla memoria potete riempire i vertici e gli indici ed usare la mesh normalmente.
Non credo servano esempi.