假设我的着色器中有以下统一缓冲区:
typedef struct
{
matrix_float4x4 modelview_projection_matrix;
float someValue;
} uniforms_t;
如何在C ++或Objective-C中获得someValue的位置?我想做这样的事情:
void Shader::SetFloat( const char* name, float value )
其中name为'someValue'。
答案 0 :(得分:3)
我通过检查BGFX的源代码来提出解决方案:
NSError* error = NULL;
MTLRenderPipelineReflection* reflectionObj;
MTLPipelineOption option = MTLPipelineOptionBufferTypeInfo | MTLPipelineOptionArgumentInfo;
id <MTLRenderPipelineState> pso = [device newRenderPipelineStateWithDescriptor:pipelineStateDescriptor options:option reflection:&reflectionObj error:&error];
for (MTLArgument *arg in reflectionObj.vertexArguments)
{
NSLog(@"Found arg: %@\n", arg.name);
if (arg.bufferDataType == MTLDataTypeStruct)
{
for( MTLStructMember* uniform in arg.bufferStructType.members )
{
NSLog(@"uniform: %@ type:%lu, location: %lu", uniform.name, (unsigned long)uniform.dataType, (unsigned long)uniform.offset);
}
}
}
答案 1 :(得分:2)
查看Apple Specifying Resources for a Render Command Encoder的Metal Programming Guide部分。
作为一个非常基本的解释......
声明您的uniforms_t
结构(通常是包含特定着色器函数的所有制服的单个结构)作为 Metal 着色器函数的参数,并且关联它具有特定的缓冲区索引(例如[[ buffer(0) ]]
)作为着色器函数声明的一部分。
从您的应用代码中,将uniforms_t
结构的内容复制到MTLBuffer
,然后以某种偏移量。
从您的应用代码中,调用MTLRenderCommandEncoder
setVertexBuffer:offset:atIndex:
或setFragmentBuffer:offset:atIndex:
方法关联MTLBuffer
的内容(在您复制{的偏移量处{1}}结构),带有在着色器函数中声明的缓冲区索引。这基本上告诉着色器函数uniforms_t
查看该函数参数的值(以及该缓冲区中的位置)。