[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