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. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org http://lists.blender.org/mailman/listinfo/bf-blender-cvs