DirectX11 由 Reflect Shader 创建 InputLayout
其实ID3D11ShaderReflection原本就能获取HLSL文件信息·由获取到的信息创建InputLayout其实是比较容易的·
Reflection接口由函数D3DReflect创建·需要四个参数·分别是编译着色器时得到的 缓冲指针 · 缓冲大小 · GUID(也就是IID_ID3D11ShaderReflection) 和 ID3D11ShaderReflection接口·
获得ID3D11ShaderReflection接口后·调用GetInputParameterDesc获得D3D11_SIGNATURE_PARAMETER_DESC结构体·然后依照信息填充D3D11_INPUT_ELEMENT_DESC就可以了·
以下是填充部分:
D3D11_SHADER_DESC t_ShaderDesc;
t_ShaderReflection->GetDesc(&t_ShaderDesc);
std::vector<D3D11_INPUT_ELEMENT_DESC> t_InputElementDescVec; //用什么存放实际上无所谓
unsigned int t_ByteOffset = 0;
for(int i = 0; i != t_ShaderDesc.InputParameters; ++i){
D3D11_SIGNATURE_PARAMETER_DESC t_SP_DESC;
t_ShaderReflection->GetInputParameterDesc(i, &t_SP_DESC);
D3D11_INPUT_ELEMENT_DESC t_InputElementDesc;
t_InputElementDesc.SemanticName = t_SP_DESC.SemanticName;
t_InputElementDesc.SemanticIndex = t_SP_DESC.SemanticIndex;
t_InputElementDesc.InputSlot = 0;
t_InputElementDesc.AlignedByteOffset = t_ByteOffset;
t_InputElementDesc.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
t_InputElementDesc.InstanceDataStepRate = 0;
if( t_SP_DESC.Mask == 1 ){
if ( t_SP_DESC.ComponentType == D3D_REGISTER_COMPONENT_UINT32 ){
t_InputElementDesc.Format = DXGI_FORMAT_R32_UINT;
}
else if ( t_SP_DESC.ComponentType == D3D_REGISTER_COMPONENT_SINT32 ){
t_InputElementDesc.Format = DXGI_FORMAT_R32_SINT;
}
else if ( t_SP_DESC.ComponentType == D3D_REGISTER_COMPONENT_FLOAT32 ){
t_InputElementDesc.Format = DXGI_FORMAT_R32_FLOAT;
}
t_ByteOffset += 4;
}
else if( t_SP_DESC.Mask <= 3 ){
if ( t_SP_DESC.ComponentType == D3D_REGISTER_COMPONENT_UINT32 ){
t_InputElementDesc.Format = DXGI_FORMAT_R32G32_UINT;
}
else if ( t_SP_DESC.ComponentType == D3D_REGISTER_COMPONENT_SINT32 ){
t_InputElementDesc.Format = DXGI_FORMAT_R32G32_SINT;
}
else if ( t_SP_DESC.ComponentType == D3D_REGISTER_COMPONENT_FLOAT32 ){
t_InputElementDesc.Format = DXGI_FORMAT_R32G32_FLOAT;
}
t_ByteOffset += 8;
}
else if( t_SP_DESC.Mask <= 7 ){
if ( t_SP_DESC.ComponentType == D3D_REGISTER_COMPONENT_UINT32 ){
t_InputElementDesc.Format = DXGI_FORMAT_R32G32B32_UINT;
}
else if ( t_SP_DESC.ComponentType == D3D_REGISTER_COMPONENT_SINT32 ){
t_InputElementDesc.Format = DXGI_FORMAT_R32G32B32_SINT;
}
else if ( t_SP_DESC.ComponentType == D3D_REGISTER_COMPONENT_FLOAT32 ){
t_InputElementDesc.Format = DXGI_FORMAT_R32G32B32_FLOAT;
}
t_ByteOffset += 12;
}
else if( t_SP_DESC.Mask <= 15 ){
if ( t_SP_DESC.ComponentType == D3D_REGISTER_COMPONENT_UINT32 ){
t_InputElementDesc.Format = DXGI_FORMAT_R32G32B32A32_UINT;
}
else if ( t_SP_DESC.ComponentType == D3D_REGISTER_COMPONENT_SINT32 ){
t_InputElementDesc.Format = DXGI_FORMAT_R32G32B32A32_SINT;
}
else if ( t_SP_DESC.ComponentType == D3D_REGISTER_COMPONENT_FLOAT32 ){
t_InputElementDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
}
t_ByteOffset += 16;
}
t_InputElementDescVec.push_back(t_InputElementDesc);
}
这样就可以获得所有D3D11_INPUT_ELEMENT_DESC信息·然后将t_InputElementDescVec作为参数调用CreateInputLayout创建ID3D11InputLayout就可以了·
注意下ComponentType要和Mask合起来判断Format就行了·

浙公网安备 33010602011771号