Delen via


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.

illustratie van een vierkant dat bestaat uit twee driehoeken

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.

diagram van een hoekpuntbuffer die drie hoekpunten definieert voor twee driehoeken

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.

diagram van een indexbuffer voor de eerdere hoekpuntbuffer

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.

diagram van de indexbuffer en hoekpuntbuffer voor de tweede driehoek

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:

diagram van een indexbuffer met een waarde van 50 voor basevertexindex

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.

diagram van de indexbuffer en hoekpuntbuffer met een vb-index van 50

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

Primitieven weergeven