(DirectX 11)动态顶点/索引缓冲区实现恒定的场景内容变化
(DirectX 11) Dynamic Vertex/Index Buffers implementation with constant scene content changes
第一次深入研究未管理的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()是理想的?提示或代码示例将是伟大的!提前感谢!
在进入顶点缓冲区的内存中执行以下操作:
memcpy(resource.pData, &totalVertices[0], sizeof(totalVertices));
sizeof( totalVertices )
只是要求std::vector<这不是你想要的>这不是你想要的>
尝试以下代码:
memcpy(resource.pData, &totalVertices[0], sizeof( VERTEX ) * totalVertices.size() );
当isVertexBufferSet为true时,您似乎不会调用IASetVertexBuffers
。
相关文章:
- 如果没有malloc,链表实现将失败
- 如何在c++中实现处理器调度模拟器
- 如何在c++中使用引用实现类似python的行为
- 实现无开销push_back的最佳方法是什么
- 使用简单类型列表实现的指数编译时间.为什么
- C++取消引用指针.为什么会发生变化
- 为什么在读取文件大小时文件IO速度会发生变化
- 如何在BST的这个简单递归实现中消除警告
- 实现一个在集合上迭代的模板函数
- 我应该实现右值推送功能吗?我应该使用std::move吗
- 如何正确实现和访问运算符的各种自定义枚举器
- C++Union/Struct位域的实现和可移植性
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 在c++中实现LinkedList时,应出现未处理的错误
- 为左值和右值的包装器实现C++范围
- 使用模板进行堆栈实现; "name followed by :: must be a class or namespace"
- 使用GSoap实现ONVIF
- 在用于格式4的arm模拟器中实现功能时的一个问题
- C/C 中POW()函数的实现是否随平台或编译器而变化
- (DirectX 11)动态顶点/索引缓冲区实现恒定的场景内容变化