Гаразд, мені важко зрозуміти, як постійні буфери прив’язані до стадії конвеєра та оновлюються. Я розумію, що DirectX11 може мати до 15 шейдерних константних буферів на етапі, і кожен буфер може містити до 4096 констант. Однак я не розумію, чи ID3D11Buffer COM, який використовується для взаємодії з постійними буферами, є лише механізмом (або ручкою), що використовується для заповнення цих буферних прорізів, або якщо об'єкт насправді посилається на певний екземпляр даних буфера, який висувається вперед і назад між графічним процесором і процесором.
Я думаю, що моя плутанина з цієї теми є причиною проблеми, з якою я використовую два різних постійних буфера.
Ось приклад коду шейдера.
cbuffer PerFrame : register(b0) {
float4x4 view;
};
cbuffer PerObject : register(b1) {
float4x4 scale;
float4x4 rotation;
float4x4 translation;
};
Як організується мій код, камера буде обробляти оновлення відповідних даних на кадр, а GameObjects оновлюватиме власні дані на кожен об'єкт. Обидва класи мають свій ID3D11Buffer, який використовується для цього (Використовуючи архітектуру концентратора, тому один клас GameObject буде обробляти рендеринг усіх встановлених GameObjects у світі).
Проблема полягає в тому, що я можу отримувати оновлений лише один раз, залежно від місця, і я припускаю, що в порядку оновлення один буфер заповнюється, а інший виводиться з нуля.
Це по суті мій код. Обидва класи використовують однакову логіку оновлення.
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 знає, який буфер я хочу оновити чи зіставити? Чи знає це від використовуваного COM ID3D11Buffer?
Редагувати -
Змінено теги регістра постійного буфера в наведеному вище прикладі. Використання (cb #) замість (b #) вплинуло на неправильне оновлення буферів з певних причин. Не впевнений, де я взяв оригінальний синтаксис, чи він взагалі дійсний, але, здається, це була моя основна проблема.