MJL*_*ala 0 c++ dynamic vertex-buffer directx-10
我有一个顶点缓冲区创建如下:
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);
Run Code Online (Sandbox Code Playgroud)
我目前正在使用ID3D10Buffer :: Map()更新我的顶点,现在工作正常.这个问题是我的应用程序将来可能需要大量的顶点更新,但不是每个网格/缓冲区中的每个顶点(一天,缓冲区将保存多个网格).据我所知,到处都说使用ID3D10Device :: CopySubresourceRegion().这正是我想要做的!除了我不能让它工作.我根本不明白它是如何工作的.我在上面阅读了微软的页面,并没有针对顶点缓冲区.我希望有人可以向我解释如何在顶点缓冲区方面实现它和/或将我链接到一些有用的资源来做同样的事情.
Iva*_*rop 12
你要问的是什么并不是很清楚,因为你不能用缓冲区来更新缓冲区ID3D10Device::CopySubresourceRegion().我想在我的答案中澄清资源复制和资源更新.
通过"更新"资源,我们通常意味着通过覆盖将数据从系统存储器传输到GPU存储器1.要更新资源,请使用ID3D10Buffer::Map()/ ID3D10Buffer::Unmap()pair或ID3D10Device::UpdateSubresource()method.哪个更好用,取决于资源属性和更新频率(阅读Nvidia的"规范"论文).
用法非常简单.这是简单的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);
Run Code Online (Sandbox Code Playgroud)
正如名称所述,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);
Run Code Online (Sandbox Code Playgroud)
希望能帮助到你.
顺便说一下,2013年没有任何理由学习DirectX 10.你可以从DirectX 11开始,它的API几乎相同,但功能更多.
1这种解释过于简化.我们永远无法确定给定资源所在的位置(GPU,系统内存,无论存储),因为驱动程序实现者需要决定何时以及何种类型的资源存储.