Хорошо, мне трудно понять, как постоянные буферы связаны со стадией конвейера и обновляются. Я понимаю, что DirectX11 может иметь до 15 буферных констант на каждую стадию, и каждый буфер может содержать до 4096 констант. Однако я не понимаю, является ли ID3D11Buffer COM, используемый для взаимодействия с постоянными буферами, просто механизмом (или дескриптором), используемым для заполнения этих слотов буфера, или если объект на самом деле ссылается на конкретный экземпляр данных буфера, который перемещается взад и вперед между графическим процессором и процессором.
Я думаю, что моя путаница в теме - причина проблемы, которую я использую, используя два разных постоянных буфера.
Вот пример кода шейдера.
cbuffer PerFrame : register(b0) {
float4x4 view;
};
cbuffer PerObject : register(b1) {
float4x4 scale;
float4x4 rotation;
float4x4 translation;
};
Как организован мой код, камера будет обрабатывать обновление соответствующих данных для каждого кадра, а GameObjects будет обновлять свои собственные данные для каждого объекта. Оба класса имеют свой собственный ID3D11Buffer, который используется для этого (используя хаб-архитектуру, поэтому один класс GameObject будет обрабатывать рендеринг всех экземпляров GameObject в мире).
Проблема в том, что я могу получить только одно обновление за раз, в зависимости от слота, и я предполагаю, что в порядке обновления один буфер заполняется, а другой - обнуляется.
Это по сути мой код. Оба класса используют одинаковую логику обновления.
static PerObjectShaderBuffer _updatedBuffer; // PerFrameShaderBuffer if Camera class
_updatedBuffer.scale = _rScale;
_updatedBuffer.rotation = _rRotation;
_updatedBuffer.translation = _rTranslation;
pDeviceContext->UpdateSubresource(pShaderBuffer, 0 , 0, &_updatedBuffer, 0, 0);
pDeviceContext->VSSetShader(pVShader->GetShaderPtr(), 0, 0);
pDeviceContext->PSSetShader(pPShader->GetShaderPtr(), 0, 0);
pDeviceContext->VSSetConstantBuffers(1, 1, &pShaderBuffer);
pDeviceContext->IASetVertexBuffers(0, 1, &pVertexBuffer, &vStride, &_offset );
pDeviceContext->IASetPrimitiveTopology(topologyType);
pDeviceContext->Draw(bufSize, 0);
Мои основные вопросы -
- Нужно ли устанавливать или связывать ShaderBuffer, чтобы обновить его с помощью вызова UpdateSubresource? (Имеется в виду манипулировать им только тогда, когда он находится в конвейере) Или это большой объем данных, которые будут отправлены с вызовом VSSetConstantBuffer? (То есть порядок связывания и обновления данных не имеет значения, я могу обновить его в конвейере или как-то на процессоре)
- При установке или привязке буфера нужно ли ссылаться на слот 0 для обновления буфера PerFrame и слот 1 для обновления буфера PerObject? Может ли какая-то путаница с этим вызовом в моем коде вызвать перезапись всех буферов?
- Как D3D11 узнает, какой буфер я хочу обновить или отобразить? Знает ли он из используемого ID3D11Buffer COM?
Редактировать -
Изменены теги константного буфера в приведенном выше примере. Использование (cb #) вместо (b #) по какой-то причине сказалось на корректном обновлении буферов. Не уверен, где я взял оригинальный синтаксис или он действителен вообще, но, похоже, это была моя главная проблема.