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");
}
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, ", ");
	}
}
예제 #3
0
static char *bmp_slots_as_args(const BMOSlotType slot_types[BMO_OP_MAX_SLOTS], const bool is_out)
{
	DynStr *dyn_str = BLI_dynstr_new();
	char *ret;

	int i = 0;

	while (*slot_types[i].name) {
		/* cut off '.out' by using a string size arg */
		const int name_len = is_out ?
		        (strchr(slot_types[i].name, '.') - slot_types[i].name) :
		        sizeof(slot_types[i].name);
		const char *value = "<Unknown>";
		switch (slot_types[i].type) {
			case BMO_OP_SLOT_BOOL:          value = "False"; break;
			case BMO_OP_SLOT_INT:           value = "0"; break;
			case BMO_OP_SLOT_FLT:           value = "0.0"; break;
			case BMO_OP_SLOT_PTR:           value = "None"; break;
			case BMO_OP_SLOT_MAT:           value = "Matrix()"; break;
			case BMO_OP_SLOT_VEC:           value = "Vector()"; break;
			case BMO_OP_SLOT_ELEMENT_BUF:   value =
			     (slot_types[i].subtype.elem & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE) ? "None" : "[]"; break;
			case BMO_OP_SLOT_MAPPING:       value = "{}"; break;
		}
		BLI_dynstr_appendf(dyn_str, i ? ", %.*s=%s" : "%.*s=%s", name_len, slot_types[i].name, value);
		i++;
	}

	ret = BLI_dynstr_get_cstring(dyn_str);
	BLI_dynstr_free(dyn_str);
	return ret;
}
예제 #4
0
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;
}
예제 #5
0
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;
}
예제 #6
0
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 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;
}
예제 #8
0
static PyObject *Euler_str(EulerObject *self)
{
	DynStr *ds;

	if (BaseMath_ReadCallback(self) == -1)
		return NULL;

	ds = BLI_dynstr_new();

	BLI_dynstr_appendf(ds, "<Euler (x=%.4f, y=%.4f, z=%.4f), order='%s'>",
	                   self->eul[0], self->eul[1], self->eul[2], euler_order_str(self));

	return mathutils_dynstr_to_py(ds); /* frees ds */
}
예제 #9
0
static PyObject *Quaternion_str(QuaternionObject *self)
{
	DynStr *ds;

	if (BaseMath_ReadCallback(self) == -1)
		return NULL;

	ds = BLI_dynstr_new();

	BLI_dynstr_appendf(ds, "<Quaternion (w=%.4f, x=%.4f, y=%.4f, z=%.4f)>",
	                   self->quat[0], self->quat[1], self->quat[2], self->quat[3]);

	return mathutils_dynstr_to_py(ds); /* frees ds */
}
예제 #10
0
static PyObject *Color_str(ColorObject *self)
{
	DynStr *ds;

	if (BaseMath_ReadCallback(self) == -1)
		return NULL;

	ds = BLI_dynstr_new();

	BLI_dynstr_appendf(ds, "<Color (r=%.4f, g=%.4f, b=%.4f)>",
	                   self->col[0], self->col[1], self->col[2]);

	return mathutils_dynstr_to_py(ds); /* frees ds */
}
예제 #11
0
파일: bpy_util.c 프로젝트: 244xiao/blender
char *BPy_enum_as_string(EnumPropertyItem *item)
{
	DynStr *dynstr = BLI_dynstr_new();
	EnumPropertyItem *e;
	char *cstring;

	for (e = item; item->identifier; item++) {
		if (item->identifier[0])
			BLI_dynstr_appendf(dynstr, (e == item) ? "'%s'" : ", '%s'", item->identifier);
	}

	cstring = BLI_dynstr_get_cstring(dynstr);
	BLI_dynstr_free(dynstr);
	return cstring;
}
예제 #12
0
파일: report.c 프로젝트: nttputus/blensor
char *BKE_reports_string(ReportList *reports, ReportType level)
{
	Report *report;
	DynStr *ds;
	char *cstring;

	if (!reports || !reports->list.first)
		return NULL;

	ds= BLI_dynstr_new();
	for (report=reports->list.first; report; report=report->next)
		if (report->type >= level)
			BLI_dynstr_appendf(ds, "%s: %s\n", report->typestr, report->message);

	if (BLI_dynstr_get_len(ds))
		cstring= BLI_dynstr_get_cstring(ds);
	else
		cstring= NULL;

	BLI_dynstr_free(ds);
	return cstring;
}
예제 #13
0
static char *code_generate_fragment(ListBase *nodes, GPUOutput *output)
{
	DynStr *ds = BLI_dynstr_new();
	char *code;
	int builtins;

#if 0
	BLI_dynstr_append(ds, FUNCTION_PROTOTYPES);
#endif

	codegen_set_unique_ids(nodes);
	builtins = codegen_print_uniforms_functions(ds, nodes);

#if 0
	if (G.debug & G_DEBUG)
		BLI_dynstr_appendf(ds, "/* %s */\n", name);
#endif

	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 0
	if (G.debug & G_DEBUG) printf("%s\n", code);
#endif

	return code;
}
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);
	}
}
예제 #15
0
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;
}