2015-10-23 2 views
0

Если мы хотим обновить структуру константного буфера, содержит вектор, просто используйте copyMemory или memcpy со стартовым указателем структуры и размером структуры, не будет копировать векторные данные, это правильно?Данные массива DirectX копируются в постоянный буфер

struct PerObjectCB { 
XMFLOAT4X4 World; 
XMFLOAT4X4 WorldInvTranspose; 
XMFLOAT4X4 TexTransform; 
Material Mat; 
vector<XMFLOAT4X4> BoneTransforms; 
}; 
PerObjectCB Data = {.,.,., ..., {/*BoneTransforms data*/}}; 
ID3D11Buffer* mBuffer; 
ID3D11_BUFFER_DESC desc = {...}; 
device->CreateBuffer(&desc, 0, &mBuffer); 
D3D11_MAPPED_SUBRESOURCE mappedResource; 
dc->Map(mBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); 
CopyMemory(mappedResource.pData, &Data, sizeof(Data)); 
dc->Unmap(mBuffer, 0); 

я эти обновления постоянных кодов буфера в шаблоне класс, то я могу использовать этот класс для управления обновлением постоянного буфера, однако, когда я сталкиваюсь с векторной анимацией данных, я проверяю с соиЬ < < SizeOf (вектор < XMFLOAT4X4> BoneTransforms), независимо от того, сколько данных я помещаю в вектор, размер этого вектора всегда равен 12, я полагаю, что структура хранит только начальный адрес вектора, действительно данные находятся где-то в другом месте. Если это так, как я могу справиться с этим?

Должен ли я отказаться от класса шаблона, который я написал для управления постоянным буфером, и написать конкретную функцию для данных типа массива обновлений?

ответ

0

Так что проблема в том, что std::vector не POD (простые старые данные).

struct PerObjectCB { 
XMFLOAT4X4 World; 
XMFLOAT4X4 WorldInvTranspose; 
XMFLOAT4X4 TexTransform; 
Material Mat; 
vector<XMFLOAT4X4> BoneTransforms; 
}; 

Это будет sizeof(XMFLOAT4X4) * 3 + sizeof(Material) + sizeof(std::vector). Он не имеет ничего общего с BoneTransforms.size() * sizeof(XMFLOAT4X4).

Если вы собираетесь отправить кости трансформирует в этом CB, вам нужно выбрать «максимальный размер кости»

struct PerObjectCB { 
XMFLOAT4X4 World; 
XMFLOAT4X4 WorldInvTranspose; 
XMFLOAT4X4 TexTransform; 
Material Mat; 
XMFLOAT4X4 BoneTransforms[MAX_BONES]; 
}; 

Обратите внимание, что вы вряд ли понадобится не-аффинные преобразования для костей, так вы должны использовать XMFLOAT4X3 вместо того, чтобы сохранить память и что более важно пропускную способность передачи

Например, в DirectX Tool KitSkinnedEffect шейдер имеет максимальное количество костей 72. CB использует выглядеть так:

struct SkinnedEffectConstants 
{ 
    XMVECTOR diffuseColor; 
    XMVECTOR emissiveColor; 
    XMVECTOR specularColorAndPower; 

    XMVECTOR lightDirection[IEffectLights::MaxDirectionalLights]; 
    XMVECTOR lightDiffuseColor[IEffectLights::MaxDirectionalLights]; 
    XMVECTOR lightSpecularColor[IEffectLights::MaxDirectionalLights]; 

    XMVECTOR eyePosition; 

    XMVECTOR fogColor; 
    XMVECTOR fogVector; 

    XMMATRIX world; 
    XMVECTOR worldInverseTranspose[3]; 
    XMMATRIX worldViewProj; 

    XMVECTOR bones[SkinnedEffect::MaxBones][3]; 
}; 

DGSLEffect обесшкуривание шейдер использует пять различных к.б.н., с одним из них, содержащие кости:

// Slot 4 
struct BoneConstants 
{ 
    XMVECTOR Bones[DGSLEffect::MaxBones][3]; 
}; 

Оригинальный VS Starter Kit DGSL кожурой шейдер поддерживается 59 костей.

Вы можете спросить, почему 72?

Это связано с тем, что встроенные шейдеры в наборе инструментов DirectX, заимствованные из XNA Game Studio 4, поддерживают аппаратное обеспечение Direct3D Feature Level 9.1. Внутри этих шейдеров используется профиль vs_2_0, который требует 256 векторных констант. 72 кости занимают 216 из них, а остальные константы подталкивают его до 242, что оставляет дюжину или около того для реализации 10level9.

Если вам требуется оборудование уровня 10.0 или новее, вы можете сделать его более крупным, не оказывая большого влияния на производительность. Имейте в виду, что общий размер CB влияет на то, насколько дорого он должен обновляться.

Смежные вопросы