Directx 10: обновление буфера вершин с помощью CopySubresourceRegion

У меня есть буфер вершин, созданный следующим образом:

ID3D10Buffer * VertexBuffer;
Vertex_PosCol * Vertices;
D3D10_SUBRESOURCE_DATA VertexData;Vertices = new Vertex_PosCol[VerticeCount];

Vertices[0].Position = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
Vertices[0].Color = D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f);

Vertices[1].Position = D3DXVECTOR3(-1.0f, 2.0f, 0.0f);
Vertices[1].Color = D3DXVECTOR4(1.0f, 0.0f, 0.0f, 1.0f);

Vertices[2].Position = D3DXVECTOR3(1.0f, 2.0f, 0.0f);
Vertices[2].Color = D3DXVECTOR4(0.0f, 1.0f, 0.0f, 1.0f);

Vertices[3].Position = D3DXVECTOR3(2.0f, 1.0f, 0.0f);
Vertices[3].Color = D3DXVECTOR4(0.0f, 0.0f, 1.0f, 1.0f);

Vertices[4].Position = D3DXVECTOR3(2.0f, -1.0f, 0.0f);
Vertices[4].Color = D3DXVECTOR4(1.0f, 1.0f, 0.0f, 1.0f);

Vertices[5].Position = D3DXVECTOR3(1.0f, -2.0f, 0.0f);
Vertices[5].Color = D3DXVECTOR4(0.0f, 1.0f, 1.0f, 1.0f);

Vertices[6].Position = D3DXVECTOR3(-1.0f, -2.0f, 0.0f);
Vertices[6].Color = D3DXVECTOR4(1.0f, 0.0f, 1.0f, 1.0f);

Vertices[7].Position = D3DXVECTOR3(-2.0f, -1.0f, 0.0f);
Vertices[7].Color = D3DXVECTOR4(1.0f, 0.0f, 0.0f, 1.0f);

Vertices[8].Position = D3DXVECTOR3(-2.0f, 1.0f, 0.0f);
Vertices[8].Color = D3DXVECTOR4(0.0f, 1.0f, 0.0f, 1.0f);

D3D10_BUFFER_DESC vbd;
vbd.Usage = D3D10_USAGE_DYNAMIC;
vbd.ByteWidth = sizeof(Vertex_PosCol) * VerticeCount;
vbd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
vbd.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
vbd.MiscFlags = 0;VertexData.pSysMem = Vertices;

HRESULT result = this->GDM.Device->CreateBuffer(&vbd, &VertexData, &VertexBuffer);

В настоящее время я использую ID3D10Buffer :: Map (), чтобы обновить мои вершины, которые сейчас отлично работают. Эта проблема заключается в том, что в будущем моему приложению может потребоваться большое количество обновлений вершин, но не каждая вершина в каждой ячейке / буфере (однажды буфер будет содержать несколько ячеек). Насколько я посмотрел везде, говорит использовать ID3D10Device :: CopySubresourceRegion (). Это именно то, что я хочу сделать! За исключением того, что я не могу заставить его работать. Я просто не понимаю, как это работает. Я прочитал на ней страницу Microsoft, и она не направлена ​​на буферы вершин. Я надеялся, что кто-то может объяснить мне, как реализовать это в отношении буферов вершин, и / или связать меня с некоторыми полезными ресурсами, которые делают то же самое.

0

Решение

Не совсем понятно, о чем вы спрашиваете, потому что вы не можете обновить буфер ID3D10Device::CopySubresourceRegion(). Я пытаюсь уточнить копирование ресурса и обновление ресурса в моем ответе.

Обновление ресурса

От «Обновление» ресурс, который мы обычно имеем в виду перенос данных из системной памяти в память графического процессора1, с перезаписью.
Для обновления ресурса вы используете либо ID3D10Buffer::Map()/ID3D10Buffer::Unmap() пара или ID3D10Device::UpdateSubresource() метод. Что лучше использовать, зависит от свойств ресурса и частоты обновления (читайте «Каноническая» бумага Нвидии).

Использование действительно просто. Вот случай для простого 1D буфера, такого как буфер вершин.

// Source array/vector (srcData): [xxxxDATADATADATADATADATAxxxxxxxxxxx]
//                                     ^                   ^
//                                 srcBegin        (srcBegin+bytesToCopy)
//
// Destination buffer (pBuffer):  [xxDATADATADATADATADATAxxxxxxxxxxxxx]
//                                   ^                   ^
//                              destinationBegin  (destinationBegin+bytesToCopy)
D3D11_BOX box{};
box.left = destinationBegin;
box.right = destinationBegin + bytesToCopy;
box.top = 0;
box.bottom = 1;
box.front = 0;
box.back = 1;
Device->UpdateSubresource(pBuffer, 0, &box, (uint8_t*)srcData+srcBegin, 0, 0);

Копирование ресурса

Как следует из названия, ID3D10Device::CopySubresourceRegion() метод подходит для копирование данных между двумя ресурсами (например, буферы или текстуры). Упрощенно, вы можете думать об этом как о копировании фрагментов данных в память видеокарты (но это не всегда так). Вы не можете «обновить» память GPU этим методом, поскольку данные уже копируются.

Вот простой пример:

D3D11_BOX srcBox{};
srcBox.left = srcBegin;
srcBox.right = srcBegin + size;
srcBox.top = 0;
srcBox.bottom = 1;
srcBox.front = 0;
srcBox.back = 1;
Device->CopySubresourceRegion(pDst, 0, dstBegin, 0, 0, pSrc, 0, &srcBox);

Надеюсь, поможет.

Кстати, нет никаких оснований изучать DirectX 10 в 2013 году. Вы можете начать с DirectX 11, его API почти такой же, но с дополнительными функциями.


1 Это объяснение слишком упрощено. Мы никогда не можем быть уверены, где находится данный ресурс (графический процессор, системная память и т. Д.), Так как именно драйвер должен решить, где, когда и какие ресурсы хранить.

11

Другие решения

Совет: размер — это количество вершин, умноженное на их байты.

    D3D11_BOX srcBox{};
srcBox.left = srcBegin;
srcBox.right = srcBegin + size;   <-here
srcBox.top = 0;
srcBox.bottom = 1;
srcBox.front = 0;
srcBox.back = 1;
Device->CopySubresourceRegion(pDst, 0, dstBegin, 0, 0, pSrc, 0, &srcBox);
1

По вопросам рекламы [email protected]