ShaderProcessor词法分析
2026-02-01
8
0
ShaderProcessor主要实现如下功能:
着色器分析Process
Process 通过输入的着色器代码进行词法分析,分拆分出以下几种类型:
struct shader_parser {
struct cf_parser cfp;
DARRAY(struct shader_var) params;
DARRAY(struct shader_struct) structs;
DARRAY(struct shader_sampler) samplers;
DARRAY(struct shader_func) funcs;
};
结构体
结构体由shader_struct表示
enum shader_var_type {
SHADER_VAR_NONE,
SHADER_VAR_IN = SHADER_VAR_NONE,
SHADER_VAR_INOUT,
SHADER_VAR_OUT,
SHADER_VAR_UNIFORM,
SHADER_VAR_CONST
};
struct shader_var {
char *type;
char *name;
char *mapping;
enum shader_var_type var_type;
int array_count;
size_t gl_sampler_id; /* optional: used/parsed by GL */
DARRAY(uint8_t) default_val;
};
struct shader_struct {
char *name;
DARRAY(struct shader_var) vars;
};
采样器状态
struct shader_sampler {
char *name;
DARRAY(char *) states;
DARRAY(char *) values;
};
函数
struct shader_func {
char *name;
char *return_type;
char *mapping;
DARRAY(struct shader_var) params;
struct cf_token *start, *end; //函数体开始结束指针
};
参数
参数由shader_var结构本表示(见上)
字符转换
执行完成语义分析之后,需要输出最终的代码给编译器进行编译。由于着色器为了兼容OPENGL和D3D11使用的是通用写法,枚对一些关键词需要替换输出。
void ShaderProcessor::BuildString(string &outputString)
{
stringstream output;
output << "static const bool obs_glsl_compile = false;\n\n";
cf_token *token = cf_preprocessor_get_tokens(&parser.cfp.pp);
while (token->type != CFTOKEN_NONE) {
/* cheaply just replace specific tokens */
if (strref_cmp(&token->str, "POSITION") == 0)
output << "SV_Position";
else if (strref_cmp(&token->str, "TARGET") == 0)
output << "SV_Target";
else if (strref_cmp(&token->str, "texture2d") == 0)
output << "Texture2D";
else if (strref_cmp(&token->str, "texture3d") == 0)
output << "Texture3D";
else if (strref_cmp(&token->str, "texture_cube") == 0)
output << "TextureCube";
else if (strref_cmp(&token->str, "texture_rect") == 0)
throw "texture_rect is not supported in D3D";
else if (strref_cmp(&token->str, "sampler_state") == 0)
output << "SamplerState";
else if (strref_cmp(&token->str, "VERTEXID") == 0)
output << "SV_VertexID";
else
output.write(token->str.array, token->str.len);
token++;
}
outputString = move(output.str());
}
如下的代码:
替换前POSITION
struct VertInOut {
float4 pos : POSITION;
};
VertInOut main(VertInOut vert_in) {
VertInOut vert_out;
vert_out.pos = float4(vert_in.pos.xyz, 1.0);
return vert_out;
}
替换后SV_Position
static const bool obs_glsl_compile = false;
struct VertInOut {
float4 pos : SV_Position;
};
VertInOut main(VertInOut vert_in) {
VertInOut vert_out;
vert_out.pos = float4(vert_in.pos.xyz, 1.0);
return vert_out;
}
OBS-D3D11渲染梳理





