DirectX、C++中的映射缓冲区

Mapping buffers in DirectX, C++

本文关键字:映射 缓冲区 C++ DirectX      更新时间:2023-10-16

所以我的问题是我有一个名为"lightbuffer"的缓冲区,里面有很多东西,我希望能够修改其中的一个或多个元素,而不必再次重写整个内容。特别是如果我这样做:

result = devicecontext->Map(lightbuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if(FAILED(result)) { die("map lightbuffer"); }
dataPtr2 = (dxapp::LightBufferType*)mappedResource.pData;
dataPtr2->diffuse = diffuse;
devicecontext->Unmap(lightbuffer, 0);

这段代码几乎删除了除"diffusion"之外的所有内容,因为我使用了"D3D11_MAP_WRITE_DISCARD"。我尝试使用"D3D11_MAP_WRITE",这样光缓冲区的其余部分就不会出错,但FAILED(结果)返回为true,所以映射不起作用。我在MSDN上读到,如果我想这样做,我需要在缓冲区描述中使用"D3D11_CPU_ACCESS_WRITE",但我确实这样做了,我的缓冲区描述如下:

lightBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
lightBufferDesc.ByteWidth = sizeof(LightBufferType);
lightBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
lightBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
lightBufferDesc.MiscFlags = 0;
lightBufferDesc.StructureByteStride = 0;
result = mydevice->CreateBuffer(&lightBufferDesc, NULL, &mylightbuffer);
if(FAILED(result)) { return false; } 

那么,我需要做些什么才能修改缓冲区的元素,而不需要再次重写整个内容呢?

我不太确定,我是否理解正确。你想使用一个缓冲区描述并创建一些缓冲区吗?比如:

bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
bufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
bufferDesc.MiscFlags = 0;
bufferDesc.StructureByteStride = 0;
bufferDesc.ByteWidth = sizeof(matrixBufferType); 
// create matrixBuffer
result = device->CreateBuffer(&bufferDesc, NULL, &m_matrixBuffer);
if(FAILED(result)){ return false; }
// Change the description for the smoothing dynamic constant buffer.
bufferDesc.ByteWidth = sizeof(smoothingBufferType);
result = device->CreateBuffer(&bufferDesc, NULL, &m_smoothingBuffer);
if(FAILED(result)){ return false; }
// and so on

还是要将其他数据绑定到您的dataPtr2?类似:

result = deviceContext->Map(m_lightBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if(FAILED(result)){ return false; }
dataPtr2= (lightBufferType*)mappedResource.pData;
dataPtr2->ambientColor = ambientColor;
dataPtr2->diffuseColor = diffuseColor;
dataPtr2->lightDirection = lightDirection;
lightDataPtr->padding = 0.0f;
deviceContext->Unmap(m_lightBuffer, 0);

dataPtr2的结构需要匹配16字节,这可能会引起很多麻烦。因此是填充属性。