[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [15251] branches/apricot/source/blender: Apricot Branch: GLSL

Brecht Van Lommel brechtvanlommel at pandora.be
Tue Jun 17 19:33:00 CEST 2008


Revision: 15251
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15251
Author:   blendix
Date:     2008-06-17 19:32:12 +0200 (Tue, 17 Jun 2008)

Log Message:
-----------
Apricot Branch: GLSL
====================

* Added support for Ramps, diffuse + specular, all inputs
  and blending methods are supported.

Modified Paths:
--------------
    branches/apricot/source/blender/gpu/intern/gpu_codegen.c
    branches/apricot/source/blender/gpu/intern/gpu_material.c
    branches/apricot/source/blender/gpu/intern/material_shaders.glsl
    branches/apricot/source/blender/gpu/intern/material_shaders.glsl.c
    branches/apricot/source/blender/nodes/intern/SHD_nodes/SHD_rgb.c
    branches/apricot/source/blender/nodes/intern/SHD_nodes/SHD_value.c

Modified: branches/apricot/source/blender/gpu/intern/gpu_codegen.c
===================================================================
--- branches/apricot/source/blender/gpu/intern/gpu_codegen.c	2008-06-17 14:21:33 UTC (rev 15250)
+++ branches/apricot/source/blender/gpu/intern/gpu_codegen.c	2008-06-17 17:32:12 UTC (rev 15251)
@@ -80,6 +80,7 @@
 	struct GPUNode *next, *prev;
 
 	char *name;
+	int tag;
 
 	ListBase inputs;
 	ListBase outputs;
@@ -574,7 +575,7 @@
 	code = BLI_dynstr_get_cstring(ds);
 	BLI_dynstr_free(ds);
 
-	//if(G.f & G_DEBUG) printf("%s\n", code);
+	if(G.f & G_DEBUG) printf("%s\n", code);
 
 	return code;
 }
@@ -624,7 +625,7 @@
 
 	BLI_dynstr_free(ds);
 
-	//if(G.f & G_DEBUG) printf("%s\n", code);
+	if(G.f & G_DEBUG) printf("%s\n", code);
 
 	return code;
 }
@@ -725,48 +726,6 @@
 	GPU_shader_unbind(shader);
 }
 
-/* Pass create/free */
-
-GPUPass *GPU_generate_pass(ListBase *nodes, struct GPUNodeLink *outlink, int vertexshader, int profile)
-{
-	GPUShader *shader;
-	GPUPass *pass;
-	char *vertexcode, *fragmentcode;
-
-	/* generate code and compile with opengl */
-	fragmentcode = code_generate_fragment(nodes, outlink->source);
-	vertexcode = (vertexshader)? code_generate_vertex(nodes, profile): NULL;
-	shader = GPU_shader_create(vertexcode, fragmentcode);
-	MEM_freeN(fragmentcode);
-	MEM_freeN(vertexcode);
-
-	/* failed? */
-	if (!shader) {
-		GPU_nodes_free(nodes);
-		return NULL;
-	}
-	
-	/* create pass */
-	pass = MEM_callocN(sizeof(GPUPass), "GPUPass");
-
-	pass->nodes = *nodes;
-	pass->output = outlink->source;
-	pass->shader = shader;
-	pass->firstbind = 1;
-
-	/* take ownership over nodes */
-	memset(nodes, 0, sizeof(*nodes));
-
-	return pass;
-}
-
-void GPU_pass_free(GPUPass *pass)
-{
-	GPU_shader_free(pass->shader);
-	GPU_nodes_free(&pass->nodes);
-	MEM_freeN(pass);
-}
-
 /* Node Link Functions */
 
 GPUNodeLink *GPU_node_link_create(int type)
@@ -1164,3 +1123,85 @@
 	return node;
 }
 
+/* Pass create/free */
+
+void gpu_nodes_tag(GPUNodeLink *link)
+{
+	GPUNode *node;
+	GPUInput *input;
+
+	if(!link->source)
+		return;
+
+	node = link->source->node;
+	if(node->tag)
+		return;
+	
+	node->tag= 1;
+	for(input=node->inputs.first; input; input=input->next)
+		if(input->link)
+			gpu_nodes_tag(input->link);
+}
+
+void gpu_nodes_prune(ListBase *nodes, GPUNodeLink *outlink)
+{
+	GPUNode *node, *next;
+
+	for(node=nodes->first; node; node=node->next)
+		node->tag= 0;
+
+	gpu_nodes_tag(outlink);
+
+	for(node=nodes->first; node; node=next) {
+		next = node->next;
+
+		if(!node->tag) {
+			BLI_remlink(nodes, node);
+			GPU_node_free(node);
+		}
+	}
+}
+
+GPUPass *GPU_generate_pass(ListBase *nodes, GPUNodeLink *outlink, int vertexshader, int profile)
+{
+	GPUShader *shader;
+	GPUPass *pass;
+	char *vertexcode, *fragmentcode;
+
+	/* prune unused nodes */
+	gpu_nodes_prune(nodes, outlink);
+
+	/* generate code and compile with opengl */
+	fragmentcode = code_generate_fragment(nodes, outlink->source);
+	vertexcode = (vertexshader)? code_generate_vertex(nodes, profile): NULL;
+	shader = GPU_shader_create(vertexcode, fragmentcode);
+	MEM_freeN(fragmentcode);
+	MEM_freeN(vertexcode);
+
+	/* failed? */
+	if (!shader) {
+		GPU_nodes_free(nodes);
+		return NULL;
+	}
+	
+	/* create pass */
+	pass = MEM_callocN(sizeof(GPUPass), "GPUPass");
+
+	pass->nodes = *nodes;
+	pass->output = outlink->source;
+	pass->shader = shader;
+	pass->firstbind = 1;
+
+	/* take ownership over nodes */
+	memset(nodes, 0, sizeof(*nodes));
+
+	return pass;
+}
+
+void GPU_pass_free(GPUPass *pass)
+{
+	GPU_shader_free(pass->shader);
+	GPU_nodes_free(&pass->nodes);
+	MEM_freeN(pass);
+}
+

Modified: branches/apricot/source/blender/gpu/intern/gpu_material.c
===================================================================
--- branches/apricot/source/blender/gpu/intern/gpu_material.c	2008-06-17 14:21:33 UTC (rev 15250)
+++ branches/apricot/source/blender/gpu/intern/gpu_material.c	2008-06-17 17:32:12 UTC (rev 15251)
@@ -47,6 +47,7 @@
 #include "BKE_DerivedMesh.h"
 #include "BKE_global.h"
 #include "BKE_node.h"
+#include "BKE_texture.h"
 #include "BKE_utildefines.h"
 
 #include "BLI_arithb.h"
@@ -212,10 +213,17 @@
 /* Code generation */
 
 typedef struct GPUShadeInput {
-	GPUNodeLink *rgb, *specrgb, *vn;
+	GPUMaterial *gpumat;
+	Material *mat;
+
+	GPUNodeLink *rgb, *specrgb, *vn, *view;
 	GPUNodeLink *alpha, *refl, *spec, *emit, *har, *amb;
 } GPUShadeInput;
 
+typedef struct GPUShadeResult {
+	GPUNodeLink *diff, *spec, *combined, *alpha;
+} GPUShadeResult;
+
 static GPUNodeLink *lamp_get_visibility(GPUMaterial *mat, Object *lampob, Lamp *la, GPUNodeLink **lv, GPUNodeLink **dist)
 {
 	GPUNodeLink *visifac, *inpr;
@@ -323,11 +331,140 @@
 }
 #endif
 
-static void shade_one_light(GPUMaterial *mat, Object *lampob, Lamp *la, Material *ma, GPUShadeInput *shi, GPUNodeLink **out)
+static void ramp_blend(GPUMaterial *mat, GPUNodeLink *fac, GPUNodeLink *col1, GPUNodeLink *col2, int type, GPUNodeLink **outcol)
 {
+	static char *names[] = {"mix_blend", "mix_add", "mix_mult", "mix_sub",
+		"mix_screen", "mix_div", "mix_diff", "mix_dark", "mix_light",
+		"mix_overlay", "mix_dodge", "mix_burn", "mix_hue", "mix_sat",
+		"mix_val", "mix_color"};
+
+	GPU_link(mat, names[type], fac, col1, col2, outcol);
+}
+
+static void do_colorband_blend(GPUMaterial *mat, ColorBand *coba, GPUNodeLink *fac, float rampfac, int type, GPUNodeLink *incol, GPUNodeLink **outcol)
+{
+	GPUNodeLink *tmp, *alpha, *col;
+	float *array;
+	int size;
+
+	/* do colorband */
+	colorband_table_RGBA(coba, &array, &size);
+	GPU_link(mat, "valtorgb", fac, GPU_texture(size, array), &col, &tmp);
+
+	/* use alpha in fac */
+	GPU_link(mat, "mtex_alpha_from_col", col, &alpha);
+	GPU_link(mat, "math_multiply", alpha, GPU_uniform(&rampfac), &fac);
+
+	/* blending method */
+	ramp_blend(mat, fac, incol, col, type, outcol);
+}
+
+static void ramp_diffuse_result(GPUShadeInput *shi, GPUNodeLink **diff)
+{
+	Material *ma= shi->mat;
+	GPUMaterial *mat= shi->gpumat;
+	GPUNodeLink *fac;
+
+	if(ma->ramp_col) {
+		if(ma->rampin_col==MA_RAMP_IN_RESULT) {
+			GPU_link(mat, "ramp_rgbtobw", *diff, &fac);
+			
+			/* colorband + blend */
+			do_colorband_blend(mat, ma->ramp_col, fac, ma->rampfac_col, ma->rampblend_col, *diff, diff);
+		}
+	}
+}
+
+static void add_to_diffuse(GPUMaterial *mat, Material *ma, GPUShadeInput *shi, GPUNodeLink *is, GPUNodeLink *rgb, GPUNodeLink **diff)
+{
+	GPUNodeLink *fac, *tmp, *addcol;
+	
+	if(ma->ramp_col && (ma->mode & MA_RAMP_COL)) {
+		/* MA_RAMP_IN_RESULT is exceptional */
+		if(ma->rampin_col==MA_RAMP_IN_RESULT) {
+			addcol = shi->rgb;
+		}
+		else {
+			/* input */
+			switch(ma->rampin_col) {
+			case MA_RAMP_IN_ENERGY:
+				GPU_link(mat, "ramp_rgbtobw", rgb, &fac);
+				break;
+			case MA_RAMP_IN_SHADER:
+				fac= is;
+				break;
+			case MA_RAMP_IN_NOR:
+				GPU_link(mat, "vec_math_dot", shi->view, shi->vn, &tmp, &fac);
+				break;
+			default:
+				GPU_link(mat, "set_value_zero", &fac);
+				break;
+			}
+
+			/* colorband + blend */
+			do_colorband_blend(mat, ma->ramp_col, fac, ma->rampfac_col, ma->rampblend_col, shi->rgb, &addcol);
+		}
+	}
+	else
+		addcol = shi->rgb;
+
+	/* output to */
+	GPU_link(mat, "shade_madd", *diff, rgb, addcol, diff);
+}
+
+static void ramp_spec_result(GPUShadeInput *shi, GPUNodeLink **spec)
+{
+	Material *ma= shi->mat;
+	GPUMaterial *mat= shi->gpumat;
+	GPUNodeLink *fac;
+
+	if(ma->ramp_spec && ma->rampin_spec==MA_RAMP_IN_RESULT) {
+		GPU_link(mat, "ramp_rgbtobw", *spec, &fac);
+		
+		/* colorband + blend */
+		do_colorband_blend(mat, ma->ramp_spec, fac, ma->rampfac_spec, ma->rampblend_spec, *spec, spec);
+	}
+}
+
+static void do_specular_ramp(GPUShadeInput *shi, GPUNodeLink *is, GPUNodeLink *t, GPUNodeLink **spec)
+{
+	Material *ma= shi->mat;
+	GPUMaterial *mat= shi->gpumat;
+	GPUNodeLink *fac, *tmp;
+
+	*spec = shi->specrgb;
+
+	/* MA_RAMP_IN_RESULT is exception */
+	if(ma->ramp_spec && (ma->rampin_spec!=MA_RAMP_IN_RESULT)) {
+		
+		/* input */
+		switch(ma->rampin_spec) {
+		case MA_RAMP_IN_ENERGY:
+			fac = t;
+			break;
+		case MA_RAMP_IN_SHADER:
+			fac = is;
+			break;
+		case MA_RAMP_IN_NOR:
+			GPU_link(mat, "vec_math_dot", shi->view, shi->vn, &tmp, &fac);
+			break;
+		default:
+			GPU_link(mat, "set_value_zero", &fac);
+			break;
+		}
+		
+		/* colorband + blend */
+		do_colorband_blend(mat, ma->ramp_spec, fac, ma->rampfac_spec, ma->rampblend_spec, *spec, spec);
+	}
+}
+
+static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, Object *lampob, Lamp *la)
+{
+	Material *ma= shi->mat;
+	GPUMaterial *mat= shi->gpumat;
 	GPUNodeLink *lv, *dist, *visifac, *is, *inp, *i, *vn, *view;
-	GPUNodeLink *outcol, *specfac, *result, *t;
-	float energy, lampcol[3], zero[3] = {0.0f, 0.0f, 0.0f};
+	GPUNodeLink *outcol, *specfac, *t;
+	float energy, lampcol[3];
 	float *lampvec, *lampco;
 
 	if((la->mode & LA_ONLYSHADOW) && !(ma->mode & MA_SHADOW))
@@ -337,8 +474,7 @@
 	lampco= lampob->obmat[3];
 
 	vn= shi->vn;
-	GPU_link(mat, "shade_view", &view);
-	GPU_link(mat, "setrgb", GPU_uniform(zero), &result);
+	view= shi->view;
 
 	visifac= lamp_get_visibility(mat, lampob, la, &lv, &dist);
 
@@ -393,15 +529,16 @@
 		GPU_link(mat, "shade_tangent_v_spec", GPU_attribute(CD_TANGENT, ""), &vn);*/
 	
 	if(!(la->mode & LA_NO_DIFF)) {
-		GPU_link(mat, "shade_add_to_diffuse", i, GPU_uniform(lampcol), shi->rgb, &outcol);
-		GPU_link(mat, "shade_add", result, outcol, &result);
+		GPUNodeLink *rgb;
+		GPU_link(mat, "shade_mul_value", i, GPU_uniform(lampcol), &rgb);
+		add_to_diffuse(mat, ma, shi, is, rgb, &shr->diff);
 	}
 
 	if(!(la->mode & LA_NO_SPEC) && !(la->mode & LA_ONLYSHADOW)) {
 		if(la->type == LA_HEMI) {
-			GPU_link(mat, "shade_hemi_spec", vn, lv, view, GPU_uniform(&ma->spec), shi->har, &t);
-			GPU_link(mat, "shade_add_spec", t, GPU_uniform(lampcol), shi->specrgb, visifac, &outcol);
-			GPU_link(mat, "shade_add", result, outcol, &result);
+			GPU_link(mat, "shade_hemi_spec", vn, lv, view, GPU_uniform(&ma->spec), shi->har, visifac, &t);
+			GPU_link(mat, "shade_add_spec", t, GPU_uniform(lampcol), shi->specrgb, &outcol);
+			GPU_link(mat, "shade_add", shr->spec, outcol, &shr->spec);
 		}
 		else {
 			if(ma->spec_shader==MA_SPEC_PHONG)
@@ -420,24 +557,21 @@
 
 			GPU_link(mat, "shade_spec_t", shi->spec, visifac, specfac, &t);
 
-			/*if(ma->mode & MA_RAMP_SPEC) {
-				float spec[3];
-				do_specular_ramp(shi, specfac, t, spec);
-				shr->spec[0]+= t*(lacol[0] * spec[0]);
-				shr->spec[1]+= t*(lacol[1] * spec[1]);
-				shr->spec[2]+= t*(lacol[2] * spec[2]);
+			if(ma->mode & MA_RAMP_SPEC) {
+				GPUNodeLink *spec;

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list