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

  • 相关阅读:
    operator[],识别读操作和写操作
    COW写时复制
    嵌套类,PIMPL
    类型转换
    String类运算符重载,自己实现
    socket的几个配置函数
    TCP三次握手,四次挥手,状态变迁图
    运算符重载
    友元
    P4016 负载平衡问题(最小费用最大流)
  • 原文地址:https://www.cnblogs.com/macom/p/3396419.html
Copyright © 2020-2023  润新知