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

Reply via email to