Introduzione ai buffer in Direct3D 11
Una risorsa buffer è una raccolta di dati completamente tipizzata raggruppati in elementi. È possibile usare i buffer per archiviare un'ampia gamma di dati, tra cui vettori di posizione, vettori normali, coordinate di trama in un vertex buffer, indici in un buffer di indice o stato del dispositivo. Un elemento buffer è costituito da 1 a 4 componenti. Gli elementi del buffer possono includere valori di dati compressi (ad esempio, valori di superficie R8G8B8A8), interi a 8 bit singoli o quattro valori a virgola mobile a 32 bit.
Un buffer viene creato come risorsa non strutturata. Poiché non è strutturato, un buffer non può contenere alcun livello mipmap, non può essere filtrato durante la lettura e non può essere sottoposto a multicampionamento.
Tipi di buffer
Di seguito sono riportati i tipi di risorse buffer supportati da Direct3D 11. Tutti i tipi di buffer vengono incapsulati dall'interfaccia ID3D11Buffer .
Vertex Buffer
Un vertex buffer contiene i dati dei vertici usati per definire la geometria. I dati dei vertici includono coordinate di posizione, dati di colore, dati delle coordinate delle trame, dati normali e così via.
L'esempio più semplice di un buffer dei vertici è quello che contiene solo i dati di posizione. Può essere visualizzato come nell'illustrazione seguente.
Più spesso, un buffer dei vertici contiene tutti i dati necessari per specificare completamente i vertici 3D. Un esempio può essere un buffer dei vertici che contiene coordinate normali e di trama per ogni vertice. Questi dati sono in genere organizzati come set di elementi per vertice, come illustrato nella figura seguente.
Questo buffer dei vertici contiene dati per vertice; ogni vertice archivia tre elementi (coordinate di posizione, normale e trama). La posizione e la normale vengono in genere specificate usando tre float a 32 bit (DXGI_FORMAT_R32G32B32_FLOAT) e le coordinate della trama usando due float a 32 bit (DXGI_FORMAT_R32G32_FLOAT).
Per accedere ai dati da un vertex buffer, è necessario conoscere il vertice a cui accedere, oltre ai parametri del buffer aggiuntivi seguenti:
- Offset: numero di byte dall'inizio del buffer ai dati per il primo vertice. È possibile specificare l'offset usando il metodo ID3D11DeviceContext::IASetVertexBuffers .
- BaseVertexLocation: valore aggiunto a ogni indice prima di leggere un vertice dal vertex buffer.
Prima di creare un buffer dei vertici, è necessario definirne il layout creando un'interfaccia ID3D11InputLayout ; questa operazione viene eseguita chiamando il metodo ID3D11Device::CreateInputLayout . Dopo aver creato l'oggetto input-layout, è possibile associarlo alla fase input-assembler chiamando ID3D11DeviceContext::IASetInputLayout.
Per creare un buffer dei vertici, chiamare ID3D11Device::CreateBuffer.
Buffer di indice
I buffer di indice contengono offset integer in vertex buffer e vengono usati per eseguire il rendering delle primitive in modo più efficiente. Un buffer di indice contiene un set sequenziale di indici a 16 bit o a 32 bit; ogni indice viene usato per identificare un vertice in un buffer dei vertici. È possibile visualizzare un buffer di indice simile alla figura seguente.
Gli indici sequenziali archiviati in un buffer di indice si trovano con i parametri seguenti:
- Offset: numero di byte dall'indirizzo di base del buffer di indice. L'offset viene fornito al metodo ID3D11DeviceContext::IASetIndexBuffer .
- StartIndexLocation: specifica il primo elemento del buffer di indice dall'indirizzo di base e l'offset fornito in IASetIndexBuffer. Il percorso iniziale viene fornito al metodo ID3D11DeviceContext::D rawIndexed o ID3D11DeviceContext::D rawIndexedInstanced e rappresenta il primo indice di cui eseguire il rendering.
- IndexCount: numero di indici di cui eseguire il rendering. Il numero viene fornito al metodo DrawIndexed
Inizio di Index Buffer = Index Buffer Base Address + Offset (byte) + StartIndexLocation * ElementSize (byte);
In questo calcolo ElementSize è la dimensione di ogni elemento del buffer di indice, ovvero due o quattro byte.
Per creare un buffer di indice, chiamare ID3D11Device::CreateBuffer.
Buffer costante
Un buffer costante consente di fornire in modo efficiente i dati delle costanti shader alla pipeline. È possibile usare un buffer costante per archiviare i risultati della fase di output del flusso. Concettualmente, un buffer costante è simile a un buffer di vertici a singolo elemento, come illustrato nella figura seguente.
Ogni elemento archivia una costante componente da 1 a 4, determinata dal formato dei dati archiviati. Per creare un buffer costante shader, chiamare ID3D11Device::CreateBuffer e specificare il membro D3D11_BIND_CONSTANT_BUFFER del tipo enumerato D3D11_BIND_FLAG .
Un buffer costante può usare solo un singolo flag di associazione (D3D11_BIND_CONSTANT_BUFFER), che non può essere combinato con qualsiasi altro flag di associazione. Per associare un buffer costante shader alla pipeline, chiamare uno dei metodi seguenti: ID3D11DeviceContext::GSSetConstantBuffers, ID3D11DeviceContext::P SSetConstantBuffers o ID3D11DeviceContext::VSSetConstantBuffers.
Per leggere un buffer costante shader da uno shader, usare una funzione di caricamento HLSL ,ad esempio Load. Ogni fase dello shader consente fino a 15 buffer costanti shader; ogni buffer può contenere fino a 4096 costanti.
Argomenti correlati