У меня есть буфер вершин, созданный следующим образом:
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, и она не направлена на буферы вершин. Я надеялся, что кто-то может объяснить мне, как реализовать это в отношении буферов вершин, и / или связать меня с некоторыми полезными ресурсами, которые делают то же самое.
Не совсем понятно, о чем вы спрашиваете, потому что вы не можете обновить буфер 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 Это объяснение слишком упрощено. Мы никогда не можем быть уверены, где находится данный ресурс (графический процессор, системная память и т. Д.), Так как именно драйвер должен решить, где, когда и какие ресурсы хранить.
Совет: размер — это количество вершин, умноженное на их байты.
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);