其实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就行了·