members 的反射信息主要由 zzGetMembers 函数完成,它会反复调用 zzAppendMemberGetPrev 从后往前地添加 member 到列表中,并返回前一个 member 的 zzAppendMemberGetPrev 函数地址,直到在最开头的位置返回一个空指针结束。最后,把列表翻转就可以得到从前往后定义的 members 顺序。
每一个 members 的 zzAppendMemberGetPrev 函数都由一个 zzNextMemberId{MemberName} 结构体作为第一个参数进行标识,在定义参数时会留下一个 typedef zzNextMemberId{MemberName} 为下一个 member 用于定位到上一个 zzAppendMemberGetPrev 函数的指针,直到结束时将标识符定义为 zzLastMemberId 用于为 zzGetMembers 函数提供调用入口。
类型的实现
每个 member 的类型需要从给定 SHADER_PARAMETER 的数据类型中提取出来,它使用了基于模板的 meta class 方法:
/** Template to transcode some meta data information for a type <TypeParameter> not specific to shader parameters API. */ template<typename TypeParameter> structTShaderParameterTypeInfo { /** Defines what the type actually is. */ staticconstexpr EUniformBufferBaseType BaseType = UBMT_INVALID;
/** Defines the number rows and columns for vector or matrix based data typed. */ staticconstexpr int32 NumRows = 1; staticconstexpr int32 NumColumns = 1;
/** Defines the number of elements in an array fashion. 0 means this is not a TStaticArray, * which therefor means there is 1 element. */ staticconstexpr int32 NumElements = 0;
/** Defines the alignment of the elements in bytes. */ staticconstexpr int32 Alignment = alignof(TypeParameter);
/** Defines whether this element is stored in constant buffer or not. * This informations is usefull to ensure at compile time everything in the * structure get defined at the end of the structure, to reduce as much as possible * the size of the constant buffer. */ staticconstexprbool bIsStoredInConstantBuffer = true;
/** Type that is actually alligned. */ using TAlignedType = TypeParameter;
/** Type that has a multiple of 4 components. */ using TInstancedType = TypeParameter;