Rendering vanuit hoekpunt en indexbuffers (Direct3D 9)
Zowel geïndexeerde als niet-geïndexeerde tekenmethoden worden ondersteund door Direct3D. De geïndexeerde methoden gebruiken één set indexen voor alle hoekpuntonderdelen. Hoekpuntgegevens worden opgeslagen in hoekpuntbuffers en indexgegevens worden opgeslagen in indexbuffers. Hieronder vindt u enkele veelvoorkomende scenario's voor het tekenen van primitieven met behulp van hoekpunt- en indexbuffers.
Deze voorbeelden vergelijken het gebruik van IDirect3DDevice9::DrawPrimitive en IDirect3DDevice9::DrawIndexedPrimitive
Scenario 1: Twee driehoeken tekenen zonder indexering
Stel dat u de quad wilt tekenen die in de volgende afbeelding wordt weergegeven.
Als u het primitieve type Driehoeklijst gebruikt om de twee driehoeken weer te geven, wordt elke driehoek opgeslagen als drie afzonderlijke hoekpunten, wat resulteert in een vergelijkbare hoekpuntbuffer als in de volgende afbeelding.
De tekenaanroep is heel eenvoudig; begin bij locatie 0 binnen de hoekpuntbuffer en teken twee driehoeken. Als het ruimen is ingeschakeld, is de volgorde van de hoekpunten belangrijk. In dit voorbeeld wordt ervan uitgegaan dat de standaardtegenkloks culling-stand is ingesteld, waardoor zichtbare driehoeken met de klok mee moeten worden getekend. Het primitieve type Driehoeklijst leest eenvoudig drie hoekpunten in lineaire volgorde uit de buffer voor elke driehoek, dus met deze aanroep worden driehoeken getekend (0, 1, 2) en (3, 4, 5):
DrawPrimitive( D3DPT_TRIANGLELIST, // PrimitiveType
0, // StartVertex
2 ); // PrimitiveCount
Scenario 2: Twee driehoeken tekenen met indexering
Zoals u ziet, bevat de hoekpuntbuffer dubbele gegevens op locaties 0 en 4, 2 en 5. Dat is logisch omdat de twee driehoeken twee gemeenschappelijke hoekpunten delen. Deze dubbele gegevens zijn verspilling en de hoekpuntbuffer kan worden gecomprimeerd met behulp van een indexbuffer. Een kleinere hoekpuntbuffer vermindert de hoeveelheid hoekpuntgegevens die naar de grafische adapter moeten worden verzonden. Nog belangrijker, met behulp van een indexbuffer kan de adapter hoekpunten opslaan in een hoekpuntcache; als de primitieve die wordt getekend een recent gebruikt hoekpunt bevat, kan dat hoekpunt worden opgehaald uit de cache in plaats van het te lezen uit de hoekpuntbuffer, wat resulteert in een grote prestatieverhoging.
Een indexbuffer indexeert in de hoekpuntbuffer, zodat elk uniek hoekpunt slechts één keer in de hoekpuntbuffer moet worden opgeslagen. In het volgende diagram ziet u een geïndexeerde benadering van het eerdere tekenscenario.
In de indexbuffer worden VB-indexwaarden opgeslagen, die verwijzen naar een bepaald hoekpunt binnen de hoekpuntbuffer. Een hoekpuntbuffer kan worden beschouwd als een matrix van hoekpunten, dus de VB-index is simpelweg de index in de hoekpuntbuffer voor het doelhoekpunt. Op dezelfde manier is een IB-index een index in de indexbuffer. Dit kan zeer snel zeer verwarrend worden als u niet voorzichtig bent, dus zorg ervoor dat u duidelijk bent over de gebruikte woordenschat: VB Index-waarden indexeren in de hoekpuntbuffer, IB Index-waarden indexeren in de indexbuffer, en de indexbuffer zelf bevat VB Index-waarden.
De tekenoproep wordt hieronder weergegeven. De betekenis van alle argumenten wordt lang besproken voor het volgende tekenscenario; Voor nu hoeft u alleen maar te weten dat met deze aanroep Direct3D opnieuw wordt geïnstrueerd om een driehoekslijst weer te geven die twee driehoeken bevat, te beginnen op locatie 0 binnen de indexbuffer. Met deze aanroep worden dezelfde twee driehoeken in exact dezelfde volgorde getekend als voorheen, waarbij een kloksgewijze oriëntatie wordt gegarandeerd.
DrawIndexedPrimitive( D3DPT_TRIANGLELIST, // PrimitiveType
0, // BaseVertexIndex
0, // MinIndex
4, // NumVertices
0, // StartIndex
2 ); // PrimitiveCount
Scenario 3: Één driehoek tekenen met indexering
Doe alsof u nu alleen de tweede driehoek wilt tekenen, maar u dezelfde hoekpuntbuffer en indexbuffer wilt gebruiken die worden gebruikt bij het tekenen van de hele quad, zoals wordt weergegeven in het volgende diagram.
Voor deze tekenoproep is de eerste IB-index die wordt gebruikt 3; deze waarde wordt de StartIndex genoemd. De laagste VB-index die wordt gebruikt, is 0; deze waarde wordt de MinIndex genoemd. Hoewel er slechts drie hoekpunten nodig zijn om de driehoek te tekenen, zijn die drie hoekpunten verspreid over vier aangrenzende locaties in de hoekpuntbuffer; het aantal locaties binnen het aaneengesloten blok van hoekpuntbuffergeheugen dat is vereist voor de tekenoproep, wordt NumVertices genoemd en wordt ingesteld op 4 in deze aanroep. De waarden MinIndex en NumVertices zijn eigenlijk alleen hints om Direct3D te helpen de geheugentoegang tijdens het verwerken van software-hoekpunten te optimaliseren en kunnen gewoon worden ingesteld om de hele hoekpuntbuffer op te nemen tegen de prijs van prestaties.
Hier volgt de tekenoproep voor het kleine driehoekje; de betekenis van het argument BaseVertexIndex wordt hierna uitgelegd:
DrawIndexedPrimitive( D3DPT_TRIANGLELIST, // PrimitiveType
0, // BaseVertexIndex
0, // MinIndex
4, // NumVertices
3, // StartIndex
1 ); // PrimitiveCount
Scenario 4: Een driehoek tekenen met verschuivingsindexering
BaseVertexIndex is een waarde die effectief wordt toegevoegd aan elke VB-index die is opgeslagen in de indexbuffer. Als we bijvoorbeeld tijdens de vorige aanroep een waarde van 50 voor BaseVertexIndex hadden doorgegeven, zou dat hetzelfde zijn als het gebruik van de indexbuffer in het volgende diagram voor de duur van de call DrawIndexedPrimitive:
Deze waarde is zelden ingesteld op iets anders dan 0, maar kan nuttig zijn als u de indexbuffer wilt loskoppelen van de hoekpuntbuffer: Als u bij het invullen van de indexbuffer voor een bepaalde mesh de locatie van de mesh in de hoekpuntbuffer nog niet bekend is, kunt u zich gewoon voordoen dat de mesh-hoekpunten zich aan het begin van de hoekpuntbuffer bevinden; wanneer het tijd is om de tekenoproep te maken, geeft u gewoon de werkelijke beginlocatie door als de BaseVertexIndex.
Deze techniek kan ook worden gebruikt bij het tekenen van meerdere exemplaren van een mesh met behulp van één indexbuffer; Als de hoekpuntbuffer bijvoorbeeld twee meshes met een identieke tekenvolgorde bevat, maar enigszins verschillende hoekpunten (misschien verschillende diffuse kleuren of patrooncoördinaten), kunnen beide meshes worden getekend met behulp van verschillende waarden voor BaseVertexIndex. Als u dit concept nog een stap verder maakt, kunt u één indexbuffer gebruiken om meerdere exemplaren van een mesh te tekenen, elk in een andere hoekpuntbuffer, eenvoudigweg door te fietsen welke hoekpuntbuffer actief is en de BaseVertexIndex indien nodig aan te passen. Houd er rekening mee dat de waarde BaseVertexIndex ook automatisch wordt toegevoegd aan het argument MinIndex, wat zinvol is wanneer u ziet hoe deze wordt gebruikt:
Doe alsof we nu weer alleen de tweede driehoek van de quad willen tekenen met behulp van dezelfde indexbuffer als voorheen; er wordt echter een andere hoekpuntbuffer gebruikt waarin de quad zich bevindt op VB Index 50. De relatieve volgorde van de vier hoekpunten blijft ongewijzigd, alleen de beginlocatie binnen de hoekpuntbuffer is anders. De indexbuffer en hoekpuntbuffer zien eruit als in het volgende diagram.
Hier volgt de juiste tekenoproep; BaseVertexIndex is de enige waarde die is gewijzigd ten opzichte van het vorige scenario:
DrawIndexedPrimitive( D3DPT_TRIANGLELIST, // PrimitiveType
50, // BaseVertexIndex
0, // MinIndex
4, // NumVertices
3, // StartIndex
1 ); // PrimitiveCount
Verwante onderwerpen