static void gl_write_function(struct gl_shader_parser *glsp, struct shader_func *func) { size_t i; struct cf_token *token; gl_write_type(glsp, func->return_type); dstr_cat(&glsp->gl_string, " "); if (strcmp(func->name, "main") == 0) dstr_cat(&glsp->gl_string, "_main_wrap"); else dstr_cat(&glsp->gl_string, func->name); dstr_cat(&glsp->gl_string, "("); for (i = 0; i < func->params.num; i++) { struct shader_var *param = func->params.array+i; if (i > 0) dstr_cat(&glsp->gl_string, ", "); gl_write_var(glsp, param); } dstr_cat(&glsp->gl_string, ")\n"); token = func->start; gl_write_function_contents(glsp, &token, "}"); dstr_cat(&glsp->gl_string, "}\n\n"); }
/* processes texture.Sample(sampler, texcoord) */ static bool gl_write_texture_code(struct gl_shader_parser *glsp, struct cf_token **p_token, struct shader_var *var) { struct cf_parser *cfp = &glsp->parser.cfp; bool written = false; cfp->cur_token = *p_token; if (!next_token(cfp)) return false; if (!token_is(cfp, ".")) return false; if (!next_token(cfp)) return false; if (token_is(cfp, "Sample")) written = gl_write_texture_call(glsp, var, "texture"); else if (token_is(cfp, "SampleBias")) written = gl_write_texture_call(glsp, var, "texture"); else if (token_is(cfp, "SampleGrad")) written = gl_write_texture_call(glsp, var, "textureGrad"); else if (token_is(cfp, "SampleLevel")) written = gl_write_texture_call(glsp, var, "textureLod"); if (!written) return false; if (!next_token(cfp)) return false; gl_write_function_contents(glsp, &cfp->cur_token, ")"); dstr_cat(&glsp->gl_string, ")"); *p_token = cfp->cur_token; return true; }
static bool gl_write_mul(struct gl_shader_parser *glsp, struct cf_token **p_token) { struct cf_parser *cfp = &glsp->parser.cfp; cfp->cur_token = *p_token; if (!next_token(cfp)) return false; if (!token_is(cfp, "(")) return false; dstr_cat(&glsp->gl_string, "("); gl_write_function_contents(glsp, &cfp->cur_token, ","); dstr_cat(&glsp->gl_string, ") * ("); next_token(cfp); gl_write_function_contents(glsp, &cfp->cur_token, ")"); dstr_cat(&glsp->gl_string, "))"); *p_token = cfp->cur_token; return true; }
static void gl_write_function_contents(struct gl_shader_parser *glsp, struct cf_token **p_token, const char *end) { struct cf_token *token = *p_token; if (token->type != CFTOKEN_NAME || ( !gl_write_type_token(glsp, token) && !gl_write_intrinsic(glsp, &token))) dstr_cat_strref(&glsp->gl_string, &token->str); while (token->type != CFTOKEN_NONE) { token++; if (end && strref_cmp(&token->str, end) == 0) break; if (token->type == CFTOKEN_NAME) { if (!gl_write_type_token(glsp, token) && !gl_write_intrinsic(glsp, &token)) dstr_cat_strref(&glsp->gl_string, &token->str); } else if (token->type == CFTOKEN_OTHER) { if (*token->str.array == '{') gl_write_function_contents(glsp, &token, "}"); else if (*token->str.array == '(') gl_write_function_contents(glsp, &token, ")"); dstr_cat_strref(&glsp->gl_string, &token->str); } else { dstr_cat_strref(&glsp->gl_string, &token->str); } } *p_token = token; }
/* processes texture.Sample(sampler, texcoord) */ static bool gl_write_texture_code(struct gl_shader_parser *glsp, struct cf_token **p_token, struct shader_var *var) { struct cf_parser *cfp = &glsp->parser.cfp; bool written = false; cfp->cur_token = *p_token; if (!cf_next_token(cfp)) return false; if (!cf_token_is(cfp, ".")) return false; if (!cf_next_token(cfp)) return false; const char *function_end = ")"; if (cf_token_is(cfp, "Sample")) written = gl_write_texture_call(glsp, var, "texture", true); else if (cf_token_is(cfp, "SampleBias")) written = gl_write_texture_call(glsp, var, "texture", true); else if (cf_token_is(cfp, "SampleGrad")) written = gl_write_texture_call(glsp, var, "textureGrad", true); else if (cf_token_is(cfp, "SampleLevel")) written = gl_write_texture_call(glsp, var, "textureLod", true); else if (cf_token_is(cfp, "Load")) { written = gl_write_texture_call(glsp, var, "texelFetch", false); dstr_cat(&glsp->gl_string, "("); function_end = ").xy, 0)"; } if (!written) return false; if (!cf_next_token(cfp)) return false; gl_write_function_contents(glsp, &cfp->cur_token, ")"); dstr_cat(&glsp->gl_string, function_end); *p_token = cfp->cur_token; return true; }