Skapa buffertresurser (Direct3D 10)

För att skapa buffertar måste du definiera de data som bufferten ska lagra, tillhandahålla initieringsdata och konfigurera lämpliga användnings- och bindningsflaggor. Information om hur du skapar strukturer finns i Skapa strukturresurser (Direct3D 10).

Skapa en brytpunktsbuffert

Stegen för att skapa en hörnbuffert är följande.

Skapa en buffertbeskrivning

När du skapar en brytpunktsbuffert används en buffertbeskrivning (se D3D10_BUFFER_DESC) för att definiera hur data organiseras i bufferten, hur pipelinen kan komma åt bufferten och hur bufferten ska användas.

I följande exempel visas hur du skapar en buffertbeskrivning för en enda triangel med hörn som innehåller position och färgvärden.

struct SimpleVertex
{
    D3DXVECTOR3 Position;  
    D3DXVECTOR3 Color;  
};

    D3D10_BUFFER_DESC bufferDesc;
    bufferDesc.Usage            = D3D10_USAGE_DEFAULT;
    bufferDesc.ByteWidth        = sizeof( SimpleVertex ) * 3;
    bufferDesc.BindFlags        = D3D10_BIND_VERTEX_BUFFER;
    bufferDesc.CPUAccessFlags   = 0;
    bufferDesc.MiscFlags        = 0;

I det här exemplet initieras buffertbeskrivningen med nästan alla standardinställningar för användning, CPU-åtkomst och diverse flaggor. De andra inställningarna gäller för bindningsflaggan som endast identifierar resursen som en brytpunktsbuffert och buffertens storlek.

Användnings- och CPU-åtkomstflaggor är viktiga för prestanda. Dessa två flaggor avgör tillsammans hur ofta en resurs används, vilken typ av minne resursen kan läsas in i och vilken processor som behöver komma åt resursen. Standardanvändningen för den här resursen uppdateras inte särskilt ofta. Om du anger CPU-åtkomst till 0 behöver processorn inte antingen läsa eller skriva resursen. I kombination innebär det att körningen kan läsa in resursen i det minne som ger högst prestanda för GPU:n eftersom resursen inte kräver CPU-åtkomst.

Som förväntat finns det en kompromiss mellan bästa prestanda och tillgänglighet när som helst av någon av processorerna. Standardanvändningen utan CPU-åtkomst innebär till exempel att resursen kan göras tillgänglig för GPU:n exklusivt. Det kan handla om att läsa in resursen i minnet som inte är direkt åtkomlig av processorn. Resursen kunde bara ändras med UpdateSubresource.

Skapa initieringsdata för bufferten

En buffert är bara en samling element och anges som en 1D-matris. Därför är både systemminnets bandbredd och systemminnessegmentets bandbredd densamma, vilket motsvarar storleken på vertexdata-deklarationen. Ett program kan tillhandahålla initieringsdata när en buffert skapas med hjälp av en underresursbeskrivning, som innehåller en pekare till faktiska resursdata och innehåller information om datastorleken och layouten.

Alla buffertar som skapas med oföränderlig användning (se D3D10_USAGE_IMMUTABLE) måste initieras när den skapas. Buffertar som använder någon av de andra användningsflaggorna kan uppdateras efter initieringen med hjälp av CopyResource, CopySubresourceRegionoch UpdateSubresourceeller genom att komma åt dess underliggande minne med hjälp av metoden Map.

Skapa bufferten

Med hjälp av buffertbeskrivningen och initieringsdata (vilket är valfritt) anropar CreateBuffer för att skapa en brytpunktsbuffert. Följande kodfragment visar hur du skapar en brytpunktsbuffert från en matris med hörndata som deklareras av programmet.

struct SimpleVertexCombined
{
    D3DXVECTOR3 Pos;  
    D3DXVECTOR3 Col;  
};


ID3D10InputLayout* g_pVertexLayout = NULL;
ID3D10Buffer*      g_pVertexBuffer[2] = { NULL, NULL };
ID3D10Buffer*      g_pIndexBuffer = NULL;


SimpleVertexCombined verticesCombo[] =
{
    D3DXVECTOR3( 0.0f, 0.5f, 0.5f ),
    D3DXVECTOR3( 0.0f, 0.0f, 0.5f ),
    D3DXVECTOR3( 0.5f, -0.5f, 0.5f ),
    D3DXVECTOR3( 0.5f, 0.0f, 0.0f ),
    D3DXVECTOR3( -0.5f, -0.5f, 0.5f ),
    D3DXVECTOR3( 0.0f, 0.5f, 0.0f ),
};


    D3D10_BUFFER_DESC bufferDesc;
    bufferDesc.Usage            = D3D10_USAGE_DEFAULT;
    bufferDesc.ByteWidth        = sizeof( SimpleVertexCombined ) * 3;
    bufferDesc.BindFlags        = D3D10_BIND_VERTEX_BUFFER;
    bufferDesc.CPUAccessFlags   = 0;
    bufferDesc.MiscFlags        = 0;
    
    D3D10_SUBRESOURCE_DATA InitData;
    InitData.pSysMem = verticesCombo;
    InitData.SysMemPitch = 0;
    InitData.SysMemSlicePitch = 0;
    hr = g_pd3dDevice->CreateBuffer( &bufferDesc, &InitData, &g_pVertexBuffer[0] );

Skapa en indexbuffert

Att skapa en indexbuffert liknar att skapa en brytpunktsbuffert. med två skillnader. En indexbuffert innehåller endast 16-bitars eller 32-bitars data (i stället för det breda utbud av format som är tillgängliga för en brytpunktsbuffert. En indexbuffert kräver också en indexbuffertbindningsflagga.

I följande exempel visas hur du skapar en indexbuffert från en matris med indexdata.

ID3D10Buffer *g_pIndexBuffer = NULL;

    // Create indices
    unsigned int indices[] = { 0, 1, 2 };

    D3D10_BUFFER_DESC bufferDesc;
    bufferDesc.Usage           = D3D10_USAGE_DEFAULT;
    bufferDesc.ByteWidth       = sizeof( unsigned int ) * 3;
    bufferDesc.BindFlags       = D3D10_BIND_INDEX_BUFFER;
    bufferDesc.CPUAccessFlags  = 0;
    bufferDesc.MiscFlags       = 0;

    D3D10_SUBRESOURCE_DATA InitData;
    InitData.pSysMem = indices;
    InitData.SysMemPitch = 0;
    InitData.SysMemSlicePitch = 0;
    hr = g_pd3dDevice->CreateBuffer( &bufferDesc, &InitData, &g_pIndexBuffer );
    if( FAILED( hr ) )
        return hr;
  
    g_pd3dDevice->IASetIndexBuffer( g_pIndexBuffer, DXGI_FORMAT_R32_UINT, 0 );

Skapa en konstant buffert

Direct3D 10 introducerar en konstant buffert. En konstant buffert, eller skuggningskonstantbuffert, är en buffert som innehåller skuggningskonstanter. Här är ett exempel på hur du skapar en konstant buffert från HLSLWithoutFX10 Sample.

ID3D10Buffer*   g_pConstantBuffer10 = NULL;

struct VS_CONSTANT_BUFFER
{
    D3DXMATRIX mWorldViewProj;      //mWorldViewProj will probably be global to all shaders in a project.
                                    //It's a good idea not to move it around between shaders.
    D3DXVECTOR4 vSomeVectorThatMayBeNeededByASpecificShader;
    float fSomeFloatThatMayBeNeededByASpecificShader;
    float fTime;                    //fTime may also be global to all shaders in a project.
    float fSomeFloatThatMayBeNeededByASpecificShader2;
    float fSomeFloatThatMayBeNeededByASpecificShader3;
};

    D3D10_BUFFER_DESC cbDesc;
    cbDesc.ByteWidth = sizeof( VS_CONSTANT_BUFFER );
    cbDesc.Usage = D3D10_USAGE_DYNAMIC;
    cbDesc.BindFlags = D3D10_BIND_CONSTANT_BUFFER;
    cbDesc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
    cbDesc.MiscFlags = 0;
    hr = g_pd3dDevice->CreateBuffer( &cbDesc, NULL, &g_pConstantBuffer10 );
    if( FAILED( hr ) )
       return hr;

    g_pd3dDevice->VSSetConstantBuffers( 0, 1, g_pConstantBuffer10 );

Observera att när du använder ID3D10Effect-gränssnittet så hanteras processen för att skapa, binda och kommittera en konstant buffert av ID3D10Effect-gränssnittets instans. I så fall är det bara nödvändigt att hämta variabeln från effekten med någon av GetVariable-metoderna, till exempel GetVariableByName och uppdatera variabeln med någon av SetVariable-metoderna, till exempel SetMatrix. Ett exempel på hur du använder ID3D10Effect Interface för att hantera en konstant buffert finns i Självstudie 7: Strukturmappning och konstanta buffertar.

resurser (Direct3D 10)