我第一次深入研究了非托管的DirectX 11 (请容忍我),尽管在论坛上被问了几次,但仍然有一个问题让我感到困惑。
我正在开发的应用程序,其中对象是随着时间的推移添加到场景中。在每个渲染循环中,我希望收集场景中的所有顶点,并重用单个顶点和索引缓冲区来渲染它们,以获得性能和最佳实践。我的问题是关于动态顶点和索引缓冲区的使用。当场景内容改变时,我还不能完全理解它们的正确用法。
vertexBufferDescription.Usage = D3D11_USAGE_DYNAMIC;
vertexBufferDescription.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vertexBufferDescription.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
vertexBufferDescription.MiscFlags = 0;
vertexBufferDescription.StructureByteStride = 0;我应该在场景初始化时创建缓冲区,然后以某种方式更新每一帧中的内容吗?如果是这样,我应该在缓冲区描述中设置什么ByteSize?我该用什么来初始化它呢?
或者,我应该在第一次渲染场景(第1帧)时创建它,使用当前顶点计数作为其大小?如果是这样,当我将另一个对象添加到场景中时,我不需要重新创建缓冲区并将缓冲区描述的ByteWidth更改为新的顶点计数吗?如果我的场景在每一帧上不断更新它的顶点,那么单个动态缓冲区的使用将以这种方式失去其用途…
我一直在测试在第一次渲染场景时初始化缓冲区,从那时起,在每一帧上使用Map/Unmap。我首先用所有的场景对象填充一个向量列表,然后像这样更新资源:
void Scene::Render()
{
(...)
std::vector<VERTEX> totalVertices;
std::vector<int> totalIndices;
int totalVertexCount = 0;
int totalIndexCount = 0;
for (shapeIterator = models.begin(); shapeIterator != models.end(); ++shapeIterator)
{
Model* currentModel = (*shapeIterator);
// totalVertices gets filled here...
}
// At this point totalVertices and totalIndices have all scene data
if (isVertexBufferSet)
{
// This is where it copies the new vertices to the buffer.
// but it's causing flickering in the entire screen...
D3D11_MAPPED_SUBRESOURCE resource;
context->Map(vertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &resource);
memcpy(resource.pData, &totalVertices[0], sizeof(totalVertices));
context->Unmap(vertexBuffer, 0);
}
else
{
// This is run in the first frame. But what if new vertices are added to the scene?
vertexBufferDescription.ByteWidth = sizeof(VERTEX) * totalVertexCount;
UINT stride = sizeof(VERTEX);
UINT offset = 0;
D3D11_SUBRESOURCE_DATA resourceData;
ZeroMemory(&resourceData, sizeof(resourceData));
resourceData.pSysMem = &totalVertices[0];
device->CreateBuffer(&vertexBufferDescription, &resourceData, &vertexBuffer);
context->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset);
isVertexBufferSet = true;
}在渲染循环的末尾,在跟踪每个对象顶点的缓冲区位置的同时,我最后调用了Draw():
context->Draw(objectVertexCount, currentVertexOffset);
}我当前的实现导致我的整个场景闪烁。但没有内存泄漏。不知道这是否与我使用Map/Unmap API的方式有关?
另外,在这种情况下,什么时候调用buffer->Release()是理想的?提示或代码样例将是很棒的!提前感谢!
发布于 2013-03-21 21:16:32
在将memcpy放入顶点缓冲区时,执行以下操作:
memcpy(resource.pData, &totalVertices[0], sizeof(totalVertices));sizeof( totalVertices )只是询问std::vector<顶点的大小>,这不是您想要的。
尝试以下代码:
memcpy(resource.pData, &totalVertices[0], sizeof( VERTEX ) * totalVertices.size() );此外,当isVertexBufferSet为true时,您似乎不会调用IASetVertexBuffers。一定要这样做。
https://stackoverflow.com/questions/15536715
复制相似问题