static int report_copy_exec(bContext *C, wmOperator *UNUSED(op)) { SpaceInfo *sinfo = CTX_wm_space_info(C); ReportList *reports = CTX_wm_reports(C); int report_mask = info_report_mask(sinfo); Report *report; DynStr *buf_dyn = BLI_dynstr_new(); char *buf_str; for (report = reports->list.first; report; report = report->next) { if ((report->type & report_mask) && (report->flag & SELECT)) { BLI_dynstr_append(buf_dyn, report->message); BLI_dynstr_append(buf_dyn, "\n"); } } buf_str = BLI_dynstr_get_cstring(buf_dyn); BLI_dynstr_free(buf_dyn); WM_clipboard_text_set(buf_str, 0); MEM_freeN(buf_str); return OPERATOR_FINISHED; }
static char *code_generate_fragment(ListBase *nodes, GPUOutput *output, const char *UNUSED(name)) { DynStr *ds = BLI_dynstr_new(); char *code; int builtins; /*BLI_dynstr_append(ds, FUNCTION_PROTOTYPES);*/ codegen_set_unique_ids(nodes); builtins = codegen_print_uniforms_functions(ds, nodes); //if (G.debug & G_DEBUG) // BLI_dynstr_appendf(ds, "/* %s */\n", name); BLI_dynstr_append(ds, "void main(void)\n"); BLI_dynstr_append(ds, "{\n"); if (builtins & GPU_VIEW_NORMAL) BLI_dynstr_append(ds, "\tvec3 facingnormal = (gl_FrontFacing)? varnormal: -varnormal;\n"); codegen_declare_tmps(ds, nodes); codegen_call_functions(ds, nodes, output); BLI_dynstr_append(ds, "}\n"); /* create shader */ code = BLI_dynstr_get_cstring(ds); BLI_dynstr_free(ds); //if (G.debug & G_DEBUG) printf("%s\n", code); return code; }
static char *code_generate_fragment(ListBase *nodes, GPUOutput *output, const char *UNUSED(name)) { DynStr *ds = BLI_dynstr_new(); char *code; /*BLI_dynstr_append(ds, FUNCTION_PROTOTYPES);*/ codegen_set_unique_ids(nodes); codegen_print_uniforms_functions(ds, nodes); //if(G.f & G_DEBUG) // BLI_dynstr_appendf(ds, "/* %s */\n", name); BLI_dynstr_append(ds, "void main(void)\n"); BLI_dynstr_append(ds, "{\n"); codegen_declare_tmps(ds, nodes); codegen_call_functions(ds, nodes, output); BLI_dynstr_append(ds, "}\n"); /* create shader */ code = BLI_dynstr_get_cstring(ds); BLI_dynstr_free(ds); //if(G.f & G_DEBUG) printf("%s\n", code); return code; }
static int codegen_print_uniforms_functions(DynStr *ds, ListBase *nodes) { GPUNode *node; GPUInput *input; const char *name; int builtins = 0; /* print uniforms */ for (node=nodes->first; node; node=node->next) { for (input=node->inputs.first; input; input=input->next) { if ((input->source == GPU_SOURCE_TEX) || (input->source == GPU_SOURCE_TEX_PIXEL)) { /* create exactly one sampler for each texture */ if (codegen_input_has_texture(input) && input->bindtex) BLI_dynstr_appendf(ds, "uniform %s samp%d;\n", (input->textype == GPU_TEX2D) ? "sampler2D" : "sampler2DShadow", input->texid); } else if (input->source == GPU_SOURCE_BUILTIN) { /* only define each builting uniform/varying once */ if (!(builtins & input->builtin)) { builtins |= input->builtin; name = GPU_builtin_name(input->builtin); if (gpu_str_prefix(name, "unf")) { BLI_dynstr_appendf(ds, "uniform %s %s;\n", GPU_DATATYPE_STR[input->type], name); } else { BLI_dynstr_appendf(ds, "varying %s %s;\n", GPU_DATATYPE_STR[input->type], name); } } } else if (input->source == GPU_SOURCE_VEC_UNIFORM) { if (input->dynamicvec) { /* only create uniforms for dynamic vectors */ BLI_dynstr_appendf(ds, "uniform %s unf%d;\n", GPU_DATATYPE_STR[input->type], input->id); } else { /* for others use const so the compiler can do folding */ BLI_dynstr_appendf(ds, "const %s cons%d = ", GPU_DATATYPE_STR[input->type], input->id); codegen_print_datatype(ds, input->type, input->vec); BLI_dynstr_append(ds, ";\n"); } } else if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) { BLI_dynstr_appendf(ds, "varying %s var%d;\n", GPU_DATATYPE_STR[input->type], input->attribid); } } } BLI_dynstr_append(ds, "\n"); return builtins; }
static void codegen_call_functions(DynStr *ds, ListBase *nodes, GPUOutput *finaloutput) { GPUNode *node; GPUInput *input; GPUOutput *output; for (node = nodes->first; node; node = node->next) { BLI_dynstr_appendf(ds, "\t%s(", node->name); for (input = node->inputs.first; input; input = input->next) { if (input->source == GPU_SOURCE_TEX) { BLI_dynstr_appendf(ds, "samp%d", input->texid); if (input->link) BLI_dynstr_appendf(ds, ", gl_TexCoord[%d].st", input->texid); } else if (input->source == GPU_SOURCE_TEX_PIXEL) { codegen_convert_datatype(ds, input->link->output->type, input->type, "tmp", input->link->output->id); } else if (input->source == GPU_SOURCE_BUILTIN) { if (input->builtin == GPU_VIEW_NORMAL) BLI_dynstr_append(ds, "facingnormal"); else BLI_dynstr_append(ds, GPU_builtin_name(input->builtin)); } else if (input->source == GPU_SOURCE_VEC_UNIFORM) { if (input->dynamicvec) BLI_dynstr_appendf(ds, "unf%d", input->id); else BLI_dynstr_appendf(ds, "cons%d", input->id); } else if (input->source == GPU_SOURCE_ATTRIB) { BLI_dynstr_appendf(ds, "var%d", input->attribid); } else if (input->source == GPU_SOURCE_OPENGL_BUILTIN) { if (input->oglbuiltin == GPU_MATCAP_NORMAL) BLI_dynstr_append(ds, "gl_SecondaryColor"); else if (input->oglbuiltin == GPU_COLOR) BLI_dynstr_append(ds, "gl_Color"); } BLI_dynstr_append(ds, ", "); } for (output = node->outputs.first; output; output = output->next) { BLI_dynstr_appendf(ds, "tmp%d", output->id); if (output->next) BLI_dynstr_append(ds, ", "); } BLI_dynstr_append(ds, ");\n"); } BLI_dynstr_append(ds, "\n\tgl_FragColor = "); codegen_convert_datatype(ds, finaloutput->type, GPU_VEC4, "tmp", finaloutput->id); BLI_dynstr_append(ds, ";\n"); }
static void codegen_print_datatype(DynStr *ds, int type, float *data) { int i; BLI_dynstr_appendf(ds, "%s(", GPU_DATATYPE_STR[type]); for (i=0; i<type; i++) { BLI_dynstr_appendf(ds, "%f", data[i]); if (i == type-1) BLI_dynstr_append(ds, ")"); else BLI_dynstr_append(ds, ", "); } }
static void codegen_declare_tmps(DynStr *ds, ListBase *nodes) { GPUNode *node; GPUInput *input; GPUOutput *output; for (node=nodes->first; node; node=node->next) { /* load pixels from textures */ for (input=node->inputs.first; input; input=input->next) { if (input->source == GPU_SOURCE_TEX_PIXEL) { if (codegen_input_has_texture(input) && input->definetex) { BLI_dynstr_appendf(ds, "\tvec4 tex%d = texture2D(", input->texid); BLI_dynstr_appendf(ds, "samp%d, gl_TexCoord[%d].st);\n", input->texid, input->texid); } } } /* declare temporary variables for node output storage */ for (output=node->outputs.first; output; output=output->next) BLI_dynstr_appendf(ds, "\t%s tmp%d;\n", GPU_DATATYPE_STR[output->type], output->id); } BLI_dynstr_append(ds, "\n"); }
void BKE_reports_prependf(ReportList *reports, const char *_prepend, ...) { Report *report; DynStr *ds; va_list args; const char *prepend = TIP_(_prepend); if (!reports) return; for (report = reports->list.first; report; report = report->next) { ds = BLI_dynstr_new(); va_start(args, _prepend); BLI_dynstr_vappendf(ds, prepend, args); va_end(args); BLI_dynstr_append(ds, report->message); MEM_freeN((void *)report->message); report->message = BLI_dynstr_get_cstring(ds); report->len = BLI_dynstr_get_len(ds); BLI_dynstr_free(ds); } }
static int console_copy_exec(bContext *C, wmOperator *UNUSED(op)) { SpaceConsole *sc = CTX_wm_space_console(C); DynStr *buf_dyn; char *buf_str; ConsoleLine *cl; int sel[2]; int offset = 0; ConsoleLine cl_dummy = {NULL}; if (sc->sel_start == sc->sel_end) return OPERATOR_CANCELLED; console_scrollback_prompt_begin(sc, &cl_dummy); for (cl = sc->scrollback.first; cl; cl = cl->next) { offset += cl->len + 1; } if (offset == 0) { console_scrollback_prompt_end(sc, &cl_dummy); return OPERATOR_CANCELLED; } buf_dyn = BLI_dynstr_new(); offset -= 1; sel[0] = offset - sc->sel_end; sel[1] = offset - sc->sel_start; for (cl = sc->scrollback.first; cl; cl = cl->next) { if (sel[0] <= cl->len && sel[1] >= 0) { int sta = max_ii(sel[0], 0); int end = min_ii(sel[1], cl->len); if (BLI_dynstr_get_len(buf_dyn)) BLI_dynstr_append(buf_dyn, "\n"); BLI_dynstr_nappend(buf_dyn, cl->line + sta, end - sta); } sel[0] -= cl->len + 1; sel[1] -= cl->len + 1; } buf_str = BLI_dynstr_get_cstring(buf_dyn); BLI_dynstr_free(buf_dyn); WM_clipboard_text_set(buf_str, 0); MEM_freeN(buf_str); console_scrollback_prompt_end(sc, &cl_dummy); return OPERATOR_FINISHED; }
/* Build menu-string of available keying-sets (allocates memory for string) * NOTE: mode must not be longer than 64 chars */ char *ANIM_build_keyingsets_menu (ListBase *list, short for_edit) { DynStr *pupds= BLI_dynstr_new(); KeyingSet *ks; char buf[64]; char *str; int i; /* add title first */ BLI_dynstr_append(pupds, "Keying Sets%t|"); /* add dummy entries for none-active */ if (for_edit) { BLI_dynstr_append(pupds, "Add New%x-1|"); BLI_dynstr_append(pupds, " %x0|"); } else BLI_dynstr_append(pupds, "No Keying Set%x0|"); /* loop through keyingsets, adding them */ for (ks=list->first, i=1; ks; ks=ks->next, i++) { if (for_edit == 0) BLI_dynstr_append(pupds, "KS: "); BLI_dynstr_append(pupds, ks->name); BLI_snprintf( buf, 64, "%%x%d%s", i, ((ks->next)?"|":"") ); BLI_dynstr_append(pupds, buf); } /* convert to normal MEM_malloc'd string */ str= BLI_dynstr_get_cstring(pupds); BLI_dynstr_free(pupds); return str; }
char *BKE_undo_menu_string(void) { UndoElem *uel; DynStr *ds = BLI_dynstr_new(); char *menu; BLI_dynstr_append(ds, "Global Undo History %t"); for (uel = undobase.first; uel; uel = uel->next) { BLI_dynstr_append(ds, "|"); BLI_dynstr_append(ds, uel->name); } menu = BLI_dynstr_get_cstring(ds); BLI_dynstr_free(ds); return menu; }
static char *code_generate_vertex(ListBase *nodes) { DynStr *ds = BLI_dynstr_new(); GPUNode *node; GPUInput *input; char *code; for (node=nodes->first; node; node=node->next) { for (input=node->inputs.first; input; input=input->next) { if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) { BLI_dynstr_appendf(ds, "attribute %s att%d;\n", GPU_DATATYPE_STR[input->type], input->attribid); BLI_dynstr_appendf(ds, "varying %s var%d;\n", GPU_DATATYPE_STR[input->type], input->attribid); } } } BLI_dynstr_append(ds, "\n"); BLI_dynstr_append(ds, datatoc_gpu_shader_vertex_glsl); for (node=nodes->first; node; node=node->next) for (input=node->inputs.first; input; input=input->next) if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) { if(input->attribtype == CD_TANGENT) /* silly exception */ { BLI_dynstr_appendf(ds, "\tvar%d.xyz = normalize((gl_ModelViewMatrix * vec4(att%d.xyz, 0)).xyz);\n", input->attribid, input->attribid); BLI_dynstr_appendf(ds, "\tvar%d.w = att%d.w;\n", input->attribid, input->attribid); } else BLI_dynstr_appendf(ds, "\tvar%d = att%d;\n", input->attribid, input->attribid); } BLI_dynstr_append(ds, "}\n\n"); code = BLI_dynstr_get_cstring(ds); BLI_dynstr_free(ds); //if(G.f & G_DEBUG) printf("%s\n", code); return code; }
void BLI_dynstr_appendf(DynStr *ds, const char *format, ...) { va_list args; char *message, fixedmessage[256]; int len= sizeof(fixedmessage); const int maxlen= 65536; int retval; /* note that it's tempting to just call BLI_dynstr_vappendf here * and avoid code duplication, that crashes on some system because * va_start/va_end have to be called for each vsnprintf call */ while(1) { if(len == sizeof(fixedmessage)) message= fixedmessage; else message= MEM_callocN(sizeof(char)*(len), "BLI_dynstr_appendf"); va_start(args, format); retval= vsnprintf(message, len, format, args); va_end(args); if(retval == -1) { /* -1 means not enough space, but on windows it may also mean * there is a formatting error, so we impose a maximum length */ if(message != fixedmessage) MEM_freeN(message); message= NULL; len *= 2; if(len > maxlen) { fprintf(stderr, "BLI_dynstr_append text too long or format error.\n"); break; } } else if(retval >= len) { /* in C99 the actual length required is returned */ if(message != fixedmessage) MEM_freeN(message); message= NULL; /* retval doesnt include \0 terminator */ len= retval + 1; } else break; } if(message) { BLI_dynstr_append(ds, message); if(message != fixedmessage) MEM_freeN(message); } }
/* skips viewer images */ void IMAnames_to_pupstring(const char **str, const char *title, const char *extraops, ListBase *lb, ID *link, short *nr) { DynStr *pupds= BLI_dynstr_new(); if (title) { BLI_dynstr_append(pupds, title); BLI_dynstr_append(pupds, "%t|"); } if (extraops) { BLI_dynstr_append(pupds, extraops); if (BLI_dynstr_get_len(pupds)) BLI_dynstr_append(pupds, "|"); } IDnames_to_dyn_pupstring(pupds, lb, link, nr, IDPUP_NO_VIEWER); *str= BLI_dynstr_get_cstring(pupds); BLI_dynstr_free(pupds); }
void BKE_reports_prepend(ReportList *reports, const char *prepend) { Report *report; DynStr *ds; if (!reports) return; for (report=reports->list.first; report; report=report->next) { ds= BLI_dynstr_new(); BLI_dynstr_append(ds, prepend); BLI_dynstr_append(ds, report->message); MEM_freeN((void *)report->message); report->message= BLI_dynstr_get_cstring(ds); report->len= BLI_dynstr_get_len(ds); BLI_dynstr_free(ds); } }
void BLI_dynstr_vappendf(DynStr *ds, const char *format, va_list args) { char *message, fixedmessage[256]; int len= sizeof(fixedmessage); const int maxlen= 65536; int retval; while(1) { va_list args_cpy; if(len == sizeof(fixedmessage)) message= fixedmessage; else message= MEM_callocN(sizeof(char) * len, "BLI_dynstr_appendf"); /* cant reuse the same args, so work on a copy */ va_copy(args_cpy, args); retval= vsnprintf(message, len, format, args_cpy); va_end(args_cpy); if(retval == -1) { /* -1 means not enough space, but on windows it may also mean * there is a formatting error, so we impose a maximum length */ if(message != fixedmessage) MEM_freeN(message); message= NULL; len *= 2; if(len > maxlen) { fprintf(stderr, "BLI_dynstr_append text too long or format error.\n"); break; } } else if(retval >= len) { /* in C99 the actual length required is returned */ if(message != fixedmessage) MEM_freeN(message); message= NULL; /* retval doesnt include \0 terminator */ len= retval + 1; } else break; } if(message) { BLI_dynstr_append(ds, message); if(message != fixedmessage) MEM_freeN(message); } }
/* this returns a string for the list of usable pyconstraint script names */ char *buildmenu_pyconstraints (Text *con_text, int *pyconindex) { DynStr *pupds= BLI_dynstr_new(); Text *text; char *str; char buf[64]; int i; /* add title first */ sprintf(buf, "Scripts: %%t|[None]%%x0|"); BLI_dynstr_append(pupds, buf); /* init active-index first */ if (con_text == NULL) *pyconindex= 0; /* loop through markers, adding them */ for (text=G.main->text.first, i=1; text; i++, text=text->id.next) { /* this is important to ensure that right script is shown as active */ if (text == con_text) *pyconindex = i; /* only include valid pyconstraint scripts */ if (BPY_is_pyconstraint(text)) { BLI_dynstr_append(pupds, text->id.name+2); sprintf(buf, "%%x%d", i); BLI_dynstr_append(pupds, buf); if (text->id.next) BLI_dynstr_append(pupds, "|"); } } /* convert to normal MEM_malloc'd string */ str= BLI_dynstr_get_cstring(pupds); BLI_dynstr_free(pupds); return str; }
void GPU_code_generate_glsl_lib(void) { DynStr *ds; /* only initialize the library once */ if (glsl_material_library) return; ds = BLI_dynstr_new(); if (GPU_bicubic_bump_support()) { BLI_dynstr_append(ds, "/* These are needed for high quality bump mapping */\n" "#version 130\n" "#extension GL_ARB_texture_query_lod: enable\n" "#define BUMP_BICUBIC\n"); } BLI_dynstr_append(ds, datatoc_gpu_shader_material_glsl); glsl_material_library = BLI_dynstr_get_cstring(ds); BLI_dynstr_free(ds); }
static char *gpu_generate_function_prototyps(GHash *hash) { DynStr *ds = BLI_dynstr_new(); GHashIterator *ghi; GPUFunction *function; char *name, *prototypes; int a; /* automatically generate function prototypes to add to the top of the * generated code, to avoid have to add the actual code & recompile all */ ghi = BLI_ghashIterator_new(hash); for (; !BLI_ghashIterator_done(ghi); BLI_ghashIterator_step(ghi)) { name = BLI_ghashIterator_getValue(ghi); function = BLI_ghashIterator_getValue(ghi); BLI_dynstr_appendf(ds, "void %s(", name); for (a = 0; a < function->totparam; a++) { if (function->paramqual[a] == FUNCTION_QUAL_OUT) BLI_dynstr_append(ds, "out "); else if (function->paramqual[a] == FUNCTION_QUAL_INOUT) BLI_dynstr_append(ds, "inout "); if (function->paramtype[a] == GPU_TEX2D) BLI_dynstr_append(ds, "sampler2D"); else if (function->paramtype[a] == GPU_SHADOW2D) BLI_dynstr_append(ds, "sampler2DShadow"); else BLI_dynstr_append(ds, GPU_DATATYPE_STR[function->paramtype[a]]); # if 0 BLI_dynstr_appendf(ds, " param%d", a); # endif if (a != function->totparam-1) BLI_dynstr_append(ds, ", "); } BLI_dynstr_append(ds, ");\n"); } BLI_dynstr_append(ds, "\n"); prototypes = BLI_dynstr_get_cstring(ds); BLI_dynstr_free(ds); return prototypes; }
void GPU_code_generate_glsl_lib(void) { DynStr *ds; /* only initialize the library once */ if (glsl_material_library) return; ds = BLI_dynstr_new(); BLI_dynstr_append(ds, datatoc_gpu_shader_material_glsl); glsl_material_library = BLI_dynstr_get_cstring(ds); BLI_dynstr_free(ds); }
static void IDnames_to_dyn_pupstring(DynStr *pupds, ListBase *lb, ID *link, short *nr, int hideflag) { int i, nids= BLI_countlist(lb); if (nr) *nr= -1; if (nr && nids>MAX_IDPUP) { BLI_dynstr_append(pupds, "DataBrowse %x-2"); *nr= -2; } else { ID *id; for (i=0, id= lb->first; id; id= id->next, i++) { char buf[32]; if (nr && id==link) *nr= i+1; if (U.uiflag & USER_HIDE_DOT && id->name[2]=='.') continue; if (hideflag & IDPUP_NO_VIEWER) if (GS(id->name)==ID_IM) if ( ((Image *)id)->source==IMA_SRC_VIEWER ) continue; get_flags_for_id(id, buf); BLI_dynstr_append(pupds, buf); BLI_dynstr_append(pupds, id->name+2); BLI_snprintf(buf, sizeof(buf), "%%x%d", i+1); BLI_dynstr_append(pupds, buf); /* icon */ switch(GS(id->name)) { case ID_MA: /* fall through */ case ID_TE: /* fall through */ case ID_IM: /* fall through */ case ID_WO: /* fall through */ case ID_LA: /* fall through */ BLI_snprintf(buf, sizeof(buf), "%%i%d", BKE_icon_getid(id) ); BLI_dynstr_append(pupds, buf); break; default: break; } if(id->next) BLI_dynstr_append(pupds, "|"); } } }
static void codegen_convert_datatype(DynStr *ds, int from, int to, const char *tmp, int id) { char name[1024]; BLI_snprintf(name, sizeof(name), "%s%d", tmp, id); if (from == to) { BLI_dynstr_append(ds, name); } else if (to == GPU_FLOAT) { if (from == GPU_VEC4) BLI_dynstr_appendf(ds, "dot(%s.rgb, vec3(0.35, 0.45, 0.2))", name); else if (from == GPU_VEC3) BLI_dynstr_appendf(ds, "dot(%s, vec3(0.33))", name); else if (from == GPU_VEC2) BLI_dynstr_appendf(ds, "%s.r", name); } else if (to == GPU_VEC2) { if (from == GPU_VEC4) BLI_dynstr_appendf(ds, "vec2(dot(%s.rgb, vec3(0.35, 0.45, 0.2)), %s.a)", name, name); else if (from == GPU_VEC3) BLI_dynstr_appendf(ds, "vec2(dot(%s.rgb, vec3(0.33)), 1.0)", name); else if (from == GPU_FLOAT) BLI_dynstr_appendf(ds, "vec2(%s, 1.0)", name); } else if (to == GPU_VEC3) { if (from == GPU_VEC4) BLI_dynstr_appendf(ds, "%s.rgb", name); else if (from == GPU_VEC2) BLI_dynstr_appendf(ds, "vec3(%s.r, %s.r, %s.r)", name, name, name); else if (from == GPU_FLOAT) BLI_dynstr_appendf(ds, "vec3(%s, %s, %s)", name, name, name); } else { if (from == GPU_VEC3) BLI_dynstr_appendf(ds, "vec4(%s, 1.0)", name); else if (from == GPU_VEC2) BLI_dynstr_appendf(ds, "vec4(%s.r, %s.r, %s.r, %s.g)", name, name, name, name); else if (from == GPU_FLOAT) BLI_dynstr_appendf(ds, "vec4(%s, %s, %s, 1.0)", name, name, name); } }
static struct GPUShader *eevee_effects_screen_raytrace_shader_get(int options) { if (e_data.ssr_sh[options] == NULL) { char *ssr_shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl, datatoc_common_uniforms_lib_glsl, datatoc_bsdf_common_lib_glsl, datatoc_bsdf_sampling_lib_glsl, datatoc_ambient_occlusion_lib_glsl, datatoc_octahedron_lib_glsl, datatoc_lightprobe_lib_glsl, datatoc_raytrace_lib_glsl, datatoc_effect_ssr_frag_glsl); DynStr *ds_defines = BLI_dynstr_new(); BLI_dynstr_append(ds_defines, SHADER_DEFINES); if (options & SSR_RESOLVE) { BLI_dynstr_append(ds_defines, "#define STEP_RESOLVE\n"); } else { BLI_dynstr_append(ds_defines, "#define STEP_RAYTRACE\n"); BLI_dynstr_append(ds_defines, "#define PLANAR_PROBE_RAYTRACE\n"); } if (options & SSR_FULL_TRACE) { BLI_dynstr_append(ds_defines, "#define FULLRES\n"); } if (options & SSR_AO) { BLI_dynstr_append(ds_defines, "#define SSR_AO\n"); } char *ssr_define_str = BLI_dynstr_get_cstring(ds_defines); BLI_dynstr_free(ds_defines); e_data.ssr_sh[options] = DRW_shader_create_fullscreen(ssr_shader_str, ssr_define_str); MEM_freeN(ssr_shader_str); MEM_freeN(ssr_define_str); } return e_data.ssr_sh[options]; }
// A rather wasteful string-replacement utility, though this shall do for now... // Feel free to replace this with an even safe + nicer alternative char *BLI_replacestr(char *str, const char *oldText, const char *newText) { DynStr *ds= NULL; int lenOld= strlen(oldText); char *match; /* sanity checks */ if ((str == NULL) || (str[0]==0)) return NULL; else if ((oldText == NULL) || (newText == NULL) || (oldText[0]==0)) return BLI_strdup(str); /* while we can still find a match for the old substring that we're searching for, * keep dicing and replacing */ while ( (match = strstr(str, oldText)) ) { /* the assembly buffer only gets created when we actually need to rebuild the string */ if (ds == NULL) ds= BLI_dynstr_new(); /* if the match position does not match the current position in the string, * copy the text up to this position and advance the current position in the string */ if (str != match) { /* replace the token at the 'match' position with \0 so that the copied string will be ok, * add the segment of the string from str to match to the buffer, then restore the value at match */ match[0]= 0; BLI_dynstr_append(ds, str); match[0]= oldText[0]; /* now our current position should be set on the start of the match */ str= match; } /* add the replacement text to the accumulation buffer */ BLI_dynstr_append(ds, newText); /* advance the current position of the string up to the end of the replaced segment */ str += lenOld; } /* finish off and return a new string that has had all occurances of */ if (ds) { char *newStr; /* add what's left of the string to the assembly buffer * - we've been adjusting str to point at the end of the replaced segments */ if (str != NULL) BLI_dynstr_append(ds, str); /* convert to new c-string (MEM_malloc'd), and free the buffer */ newStr= BLI_dynstr_get_cstring(ds); BLI_dynstr_free(ds); return newStr; } else { /* just create a new copy of the entire string - we avoid going through the assembly buffer * for what should be a bit more efficiency... */ return BLI_strdup(str); } }
static char *code_generate_vertex(ListBase *nodes, const GPUMatType type) { DynStr *ds = BLI_dynstr_new(); GPUNode *node; GPUInput *input; char *code; char *vertcode; for (node = nodes->first; node; node = node->next) { for (input = node->inputs.first; input; input = input->next) { if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) { BLI_dynstr_appendf(ds, "attribute %s att%d;\n", GPU_DATATYPE_STR[input->type], input->attribid); BLI_dynstr_appendf(ds, "varying %s var%d;\n", GPU_DATATYPE_STR[input->type], input->attribid); } } } BLI_dynstr_append(ds, "\n"); switch (type) { case GPU_MATERIAL_TYPE_MESH: vertcode = datatoc_gpu_shader_vertex_glsl; break; case GPU_MATERIAL_TYPE_WORLD: vertcode = datatoc_gpu_shader_vertex_world_glsl; break; default: fprintf(stderr, "invalid material type, set one after GPU_material_construct_begin\n"); break; } BLI_dynstr_append(ds, vertcode); for (node = nodes->first; node; node = node->next) for (input = node->inputs.first; input; input = input->next) if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) { if (input->attribtype == CD_TANGENT) { /* silly exception */ BLI_dynstr_appendf(ds, "\tvar%d.xyz = normalize(gl_NormalMatrix * att%d.xyz);\n", input->attribid, input->attribid); BLI_dynstr_appendf(ds, "\tvar%d.w = att%d.w;\n", input->attribid, input->attribid); } else BLI_dynstr_appendf(ds, "\tvar%d = att%d;\n", input->attribid, input->attribid); } /* unfortunately special handling is needed here because we abuse gl_Color/gl_SecondaryColor flat shading */ else if (input->source == GPU_SOURCE_OPENGL_BUILTIN) { if (input->oglbuiltin == GPU_MATCAP_NORMAL) { /* remap to 0.0 - 1.0 range. This is done because OpenGL 2.0 clamps colors * between shader stages and we want the full range of the normal */ BLI_dynstr_appendf(ds, "\tvec3 matcapcol = vec3(0.5, 0.5, 0.5) * varnormal + vec3(0.5, 0.5, 0.5);\n"); BLI_dynstr_appendf(ds, "\tgl_FrontSecondaryColor = vec4(matcapcol, 1.0);\n"); } else if (input->oglbuiltin == GPU_COLOR) { BLI_dynstr_appendf(ds, "\tgl_FrontColor = gl_Color;\n"); } } BLI_dynstr_append(ds, "}\n\n"); code = BLI_dynstr_get_cstring(ds); BLI_dynstr_free(ds); #if 0 if (G.debug & G_DEBUG) printf("%s\n", code); #endif return code; }