7a449bb23ddd9d7cee3135bf76052c86677205f8
[blender.git] / source / blender / gpu / intern / gpu_material.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. 
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2006 Blender Foundation.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): Brecht Van Lommel.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 #include <math.h>
31 #include <string.h>
32
33 #include "GL/glew.h"
34
35 #include "MEM_guardedalloc.h"
36
37 #include "DNA_lamp_types.h"
38 #include "DNA_material_types.h"
39 #include "DNA_object_types.h"
40 #include "DNA_scene_types.h"
41 #include "DNA_world_types.h"
42
43 #include "BLI_math.h"
44 #include "BLI_blenlib.h"
45 #include "BLI_utildefines.h"
46
47 #include "BKE_anim.h"
48 #include "BKE_colortools.h"
49 #include "BKE_DerivedMesh.h"
50 #include "BKE_global.h"
51 #include "BKE_main.h"
52 #include "BKE_node.h"
53 #include "BKE_scene.h"
54 #include "BKE_texture.h"
55
56
57 #include "GPU_extensions.h"
58 #include "GPU_material.h"
59
60 #include "gpu_codegen.h"
61
62 #include <string.h>
63
64 /* Structs */
65
66 typedef enum DynMatProperty {
67         DYN_LAMP_CO = 1,
68         DYN_LAMP_VEC = 2,
69         DYN_LAMP_IMAT = 4,
70         DYN_LAMP_PERSMAT = 8,
71 } DynMatProperty;
72
73 struct GPUMaterial {
74         Scene *scene;
75         Material *ma;
76
77         /* for creating the material */
78         ListBase nodes;
79         GPUNodeLink *outlink;
80
81         /* for binding the material */
82         GPUPass *pass;
83         GPUVertexAttribs attribs;
84         int bound;
85         int builtins;
86         int alpha, obcolalpha;
87         int dynproperty;
88
89         /* for passing uniforms */
90         int viewmatloc, invviewmatloc;
91         int obmatloc, invobmatloc;
92         int obcolloc;
93
94         ListBase lamps;
95 };
96
97 struct GPULamp {
98         Scene *scene;
99         Object *ob;
100         Object *par;
101         Lamp *la;
102
103         int type, mode, lay, hide;
104
105         float dynenergy, dyncol[3];
106         float energy, col[3];
107
108         float co[3], vec[3];
109         float dynco[3], dynvec[3];
110         float obmat[4][4];
111         float imat[4][4];
112         float dynimat[4][4];
113
114         float spotsi, spotbl, k;
115         float dist, att1, att2;
116
117         float bias, d, clipend;
118         int size;
119
120         int falloff_type;
121         struct CurveMapping *curfalloff;
122
123         float winmat[4][4];
124         float viewmat[4][4];
125         float persmat[4][4];
126         float dynpersmat[4][4];
127
128         GPUFrameBuffer *fb;
129         GPUTexture *tex;
130
131         ListBase materials;
132 };
133
134 /* Functions */
135
136 static GPUMaterial *GPU_material_construct_begin(Material *ma)
137 {
138         GPUMaterial *material = MEM_callocN(sizeof(GPUMaterial), "GPUMaterial");
139
140         material->ma= ma;
141
142         return material;
143 }
144
145 static void gpu_material_set_attrib_id(GPUMaterial *material)
146 {
147         GPUVertexAttribs *attribs;
148         GPUShader *shader;
149         GPUPass *pass;
150         char name[32];
151         int a, b;
152
153         attribs= &material->attribs;
154         pass= material->pass;
155         if(!pass) {
156                 attribs->totlayer = 0;
157                 return;
158         }
159         
160         shader= GPU_pass_shader(pass);
161         if(!shader) {
162                 attribs->totlayer = 0;
163                 return;
164         }
165
166         /* convert from attribute number to the actual id assigned by opengl,
167          * in case the attrib does not get a valid index back, it was probably
168          * removed by the glsl compiler by dead code elimination */
169
170         for(a=0, b=0; a<attribs->totlayer; a++) {
171                 sprintf(name, "att%d", attribs->layer[a].glindex);
172                 attribs->layer[a].glindex = GPU_shader_get_attribute(shader, name);
173
174                 if(attribs->layer[a].glindex >= 0) {
175                         attribs->layer[b] = attribs->layer[a];
176                         b++;
177                 }
178         }
179
180         attribs->totlayer = b;
181 }
182
183 static int GPU_material_construct_end(GPUMaterial *material)
184 {
185         if (material->outlink) {
186                 GPUNodeLink *outlink;
187                 GPUShader *shader;
188
189                 outlink = material->outlink;
190                 material->pass = GPU_generate_pass(&material->nodes, outlink,
191                         &material->attribs, &material->builtins, material->ma->id.name);
192
193                 if(!material->pass)
194                         return 0;
195
196                 gpu_material_set_attrib_id(material);
197                 
198                 shader = GPU_pass_shader(material->pass);
199
200                 if(material->builtins & GPU_VIEW_MATRIX)
201                         material->viewmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_VIEW_MATRIX));
202                 if(material->builtins & GPU_INVERSE_VIEW_MATRIX)
203                         material->invviewmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_INVERSE_VIEW_MATRIX));
204                 if(material->builtins & GPU_OBJECT_MATRIX)
205                         material->obmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_OBJECT_MATRIX));
206                 if(material->builtins & GPU_INVERSE_OBJECT_MATRIX)
207                         material->invobmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_INVERSE_OBJECT_MATRIX));
208                 if(material->builtins & GPU_OBCOLOR)
209                         material->obcolloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_OBCOLOR));
210
211                 return 1;
212         }
213
214         return 0;
215 }
216
217 void GPU_material_free(Material *ma)
218 {
219         LinkData *link;
220         LinkData *nlink, *mlink, *next;
221
222         for(link=ma->gpumaterial.first; link; link=link->next) {
223                 GPUMaterial *material = link->data;
224
225                 if(material->pass)
226                         GPU_pass_free(material->pass);
227
228                 for(nlink=material->lamps.first; nlink; nlink=nlink->next) {
229                         GPULamp *lamp = nlink->data;
230
231                         for(mlink=lamp->materials.first; mlink; mlink=next) {
232                                 next = mlink->next;
233                                 if(mlink->data == ma)
234                                         BLI_freelinkN(&lamp->materials, mlink);
235                         }
236                 }
237
238                 BLI_freelistN(&material->lamps);
239
240                 MEM_freeN(material);
241         }
242
243         BLI_freelistN(&ma->gpumaterial);
244 }
245
246 void GPU_material_bind(GPUMaterial *material, int oblay, int viewlay, double time, int mipmap)
247 {
248         if(material->pass) {
249                 LinkData *nlink;
250                 GPULamp *lamp;
251
252                 /* handle layer lamps */
253                 for(nlink=material->lamps.first; nlink; nlink=nlink->next) {
254                         lamp= nlink->data;
255
256                         if(!lamp->hide && (lamp->lay & viewlay) && (!(lamp->mode & LA_LAYER) || (lamp->lay & oblay))) {
257                                 lamp->dynenergy = lamp->energy;
258                                 VECCOPY(lamp->dyncol, lamp->col);
259                         }
260                         else {
261                                 lamp->dynenergy = 0.0f;
262                                 lamp->dyncol[0]= lamp->dyncol[1]= lamp->dyncol[2] = 0.0f;
263                         }
264                 }
265
266                 GPU_pass_bind(material->pass, time, mipmap);
267                 material->bound = 1;
268         }
269 }
270
271 void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[][4], float viewmat[][4], float viewinv[][4], float obcol[4])
272 {
273         if(material->pass) {
274                 GPUShader *shader = GPU_pass_shader(material->pass);
275                 LinkData *nlink;
276                 GPULamp *lamp;
277                 float invmat[4][4], col[4];
278
279                 /* handle builtins */
280                 if(material->builtins & GPU_VIEW_MATRIX) {
281                         GPU_shader_uniform_vector(shader, material->viewmatloc, 16, 1, (float*)viewmat);
282                 }
283                 if(material->builtins & GPU_INVERSE_VIEW_MATRIX) {
284                         GPU_shader_uniform_vector(shader, material->invviewmatloc, 16, 1, (float*)viewinv);
285                 }
286                 if(material->builtins & GPU_OBJECT_MATRIX) {
287                         GPU_shader_uniform_vector(shader, material->obmatloc, 16, 1, (float*)obmat);
288                 }
289                 if(material->builtins & GPU_INVERSE_OBJECT_MATRIX) {
290                         invert_m4_m4(invmat, obmat);
291                         GPU_shader_uniform_vector(shader, material->invobmatloc, 16, 1, (float*)invmat);
292                 }
293                 if(material->builtins & GPU_OBCOLOR) {
294                         QUATCOPY(col, obcol);
295                         CLAMP(col[3], 0.0f, 1.0f);
296                         GPU_shader_uniform_vector(shader, material->obcolloc, 4, 1, col);
297                 }
298
299                 /* update lamps */
300                 for(nlink=material->lamps.first; nlink; nlink=nlink->next) {
301                         lamp= nlink->data;
302
303                         if(material->dynproperty & DYN_LAMP_VEC) {
304                                 VECCOPY(lamp->dynvec, lamp->vec);
305                                 normalize_v3(lamp->dynvec);
306                                 negate_v3(lamp->dynvec);
307                                 mul_mat3_m4_v3(viewmat, lamp->dynvec);
308                         }
309
310                         if(material->dynproperty & DYN_LAMP_CO) {
311                                 VECCOPY(lamp->dynco, lamp->co);
312                                 mul_m4_v3(viewmat, lamp->dynco);
313                         }
314
315                         if(material->dynproperty & DYN_LAMP_IMAT)
316                                 mul_m4_m4m4(lamp->dynimat, viewinv, lamp->imat);
317                         if(material->dynproperty & DYN_LAMP_PERSMAT)
318                                 mul_m4_m4m4(lamp->dynpersmat, viewinv, lamp->persmat);
319                 }
320
321                 GPU_pass_update_uniforms(material->pass);
322         }
323 }
324
325 void GPU_material_unbind(GPUMaterial *material)
326 {
327         if (material->pass) {
328                 material->bound = 0;
329                 GPU_pass_unbind(material->pass);
330         }
331 }
332
333 int GPU_material_bound(GPUMaterial *material)
334 {
335         return material->bound;
336 }
337
338 void GPU_material_vertex_attributes(GPUMaterial *material, GPUVertexAttribs *attribs)
339 {
340         *attribs = material->attribs;
341 }
342
343 void GPU_material_output_link(GPUMaterial *material, GPUNodeLink *link)
344 {
345         if(!material->outlink)
346                 material->outlink= link;
347 }
348
349 void GPU_material_enable_alpha(GPUMaterial *material)
350 {
351         material->alpha= 1;
352 }
353
354 GPUBlendMode GPU_material_blend_mode(GPUMaterial *material, float obcol[3])
355 {
356         if(material->alpha || (material->obcolalpha && obcol[3] < 1.0f))
357                 return GPU_BLEND_ALPHA;
358         else
359                 return GPU_BLEND_SOLID;
360 }
361
362 void gpu_material_add_node(GPUMaterial *material, GPUNode *node)
363 {
364         BLI_addtail(&material->nodes, node);
365 }
366
367 /* Code generation */
368
369 static GPUNodeLink *lamp_get_visibility(GPUMaterial *mat, GPULamp *lamp, GPUNodeLink **lv, GPUNodeLink **dist)
370 {
371         GPUNodeLink *visifac, *inpr;
372
373         /* from get_lamp_visibility */
374         if(lamp->type==LA_SUN || lamp->type==LA_HEMI) {
375                 mat->dynproperty |= DYN_LAMP_VEC;
376                 GPU_link(mat, "lamp_visibility_sun_hemi", GPU_dynamic_uniform(lamp->dynvec), lv, dist, &visifac);
377                 return visifac;
378         }
379         else {
380                 mat->dynproperty |= DYN_LAMP_CO;
381                 GPU_link(mat, "lamp_visibility_other", GPU_builtin(GPU_VIEW_POSITION), GPU_dynamic_uniform(lamp->dynco), lv, dist, &visifac);
382
383                 if(lamp->type==LA_AREA)
384                         return visifac;
385
386                 switch(lamp->falloff_type)
387                 {
388                         case LA_FALLOFF_CONSTANT:
389                                 break;
390                         case LA_FALLOFF_INVLINEAR:
391                                 GPU_link(mat, "lamp_falloff_invlinear", GPU_uniform(&lamp->dist), *dist, &visifac);
392                                 break;
393                         case LA_FALLOFF_INVSQUARE:
394                                 GPU_link(mat, "lamp_falloff_invsquare", GPU_uniform(&lamp->dist), *dist, &visifac);
395                                 break;
396                         case LA_FALLOFF_SLIDERS:
397                                 GPU_link(mat, "lamp_falloff_sliders", GPU_uniform(&lamp->dist), GPU_uniform(&lamp->att1), GPU_uniform(&lamp->att2), *dist, &visifac);
398                                 break;
399                         case LA_FALLOFF_CURVE:
400                                 {
401                                         float *array;
402                                         int size;
403
404                                         curvemapping_table_RGBA(lamp->curfalloff, &array, &size);
405                                         GPU_link(mat, "lamp_falloff_curve", GPU_uniform(&lamp->dist), GPU_texture(size, array), *dist, &visifac);
406                                 }
407                                 break;
408                 }
409
410                 if(lamp->mode & LA_SPHERE)
411                         GPU_link(mat, "lamp_visibility_sphere", GPU_uniform(&lamp->dist), *dist, visifac, &visifac);
412
413                 if(lamp->type == LA_SPOT) {
414                         if(lamp->mode & LA_SQUARE) {
415                                 mat->dynproperty |= DYN_LAMP_VEC|DYN_LAMP_IMAT;
416                                 GPU_link(mat, "lamp_visibility_spot_square", GPU_dynamic_uniform(lamp->dynvec), GPU_dynamic_uniform((float*)lamp->dynimat), *lv, &inpr);
417                         }
418                         else {
419                                 mat->dynproperty |= DYN_LAMP_VEC;
420                                 GPU_link(mat, "lamp_visibility_spot_circle", GPU_dynamic_uniform(lamp->dynvec), *lv, &inpr);
421                         }
422                         
423                         GPU_link(mat, "lamp_visibility_spot", GPU_uniform(&lamp->spotsi), GPU_uniform(&lamp->spotbl), inpr, visifac, &visifac);
424                 }
425
426                 GPU_link(mat, "lamp_visibility_clamp", visifac, &visifac);
427
428                 return visifac;
429         }
430 }
431
432 #if 0
433 static void area_lamp_vectors(LampRen *lar)
434 {
435         float xsize= 0.5*lar->area_size, ysize= 0.5*lar->area_sizey, multifac;
436
437         /* make it smaller, so area light can be multisampled */
438         multifac= 1.0f/sqrt((float)lar->ray_totsamp);
439         xsize *= multifac;
440         ysize *= multifac;
441
442         /* corner vectors */
443         lar->area[0][0]= lar->co[0] - xsize*lar->mat[0][0] - ysize*lar->mat[1][0];
444         lar->area[0][1]= lar->co[1] - xsize*lar->mat[0][1] - ysize*lar->mat[1][1];
445         lar->area[0][2]= lar->co[2] - xsize*lar->mat[0][2] - ysize*lar->mat[1][2];
446
447         /* corner vectors */
448         lar->area[1][0]= lar->co[0] - xsize*lar->mat[0][0] + ysize*lar->mat[1][0];
449         lar->area[1][1]= lar->co[1] - xsize*lar->mat[0][1] + ysize*lar->mat[1][1];
450         lar->area[1][2]= lar->co[2] - xsize*lar->mat[0][2] + ysize*lar->mat[1][2];
451
452         /* corner vectors */
453         lar->area[2][0]= lar->co[0] + xsize*lar->mat[0][0] + ysize*lar->mat[1][0];
454         lar->area[2][1]= lar->co[1] + xsize*lar->mat[0][1] + ysize*lar->mat[1][1];
455         lar->area[2][2]= lar->co[2] + xsize*lar->mat[0][2] + ysize*lar->mat[1][2];
456
457         /* corner vectors */
458         lar->area[3][0]= lar->co[0] + xsize*lar->mat[0][0] - ysize*lar->mat[1][0];
459         lar->area[3][1]= lar->co[1] + xsize*lar->mat[0][1] - ysize*lar->mat[1][1];
460         lar->area[3][2]= lar->co[2] + xsize*lar->mat[0][2] - ysize*lar->mat[1][2];
461         /* only for correction button size, matrix size works on energy */
462         lar->areasize= lar->dist*lar->dist/(4.0*xsize*ysize);
463 }
464 #endif
465
466 static void ramp_blend(GPUMaterial *mat, GPUNodeLink *fac, GPUNodeLink *col1, GPUNodeLink *col2, int type, GPUNodeLink **outcol)
467 {
468         static const char *names[] = {"mix_blend", "mix_add", "mix_mult", "mix_sub",
469                 "mix_screen", "mix_div", "mix_diff", "mix_dark", "mix_light",
470                 "mix_overlay", "mix_dodge", "mix_burn", "mix_hue", "mix_sat",
471                 "mix_val", "mix_color", "mix_soft", "mix_linear"};
472
473         GPU_link(mat, names[type], fac, col1, col2, outcol);
474 }
475
476 static void do_colorband_blend(GPUMaterial *mat, ColorBand *coba, GPUNodeLink *fac, float rampfac, int type, GPUNodeLink *incol, GPUNodeLink **outcol)
477 {
478         GPUNodeLink *tmp, *alpha, *col;
479         float *array;
480         int size;
481
482         /* do colorband */
483         colorband_table_RGBA(coba, &array, &size);
484         GPU_link(mat, "valtorgb", fac, GPU_texture(size, array), &col, &tmp);
485
486         /* use alpha in fac */
487         GPU_link(mat, "mtex_alpha_from_col", col, &alpha);
488         GPU_link(mat, "math_multiply", alpha, GPU_uniform(&rampfac), &fac);
489
490         /* blending method */
491         ramp_blend(mat, fac, incol, col, type, outcol);
492 }
493
494 static void ramp_diffuse_result(GPUShadeInput *shi, GPUNodeLink **diff)
495 {
496         Material *ma= shi->mat;
497         GPUMaterial *mat= shi->gpumat;
498         GPUNodeLink *fac;
499
500         if(!(mat->scene->gm.flag & GAME_GLSL_NO_RAMPS)) {
501                 if(ma->ramp_col) {
502                         if(ma->rampin_col==MA_RAMP_IN_RESULT) {
503                                 GPU_link(mat, "ramp_rgbtobw", *diff, &fac);
504                                 
505                                 /* colorband + blend */
506                                 do_colorband_blend(mat, ma->ramp_col, fac, ma->rampfac_col, ma->rampblend_col, *diff, diff);
507                         }
508                 }
509         }
510 }
511
512 static void add_to_diffuse(GPUMaterial *mat, Material *ma, GPUShadeInput *shi, GPUNodeLink *is, GPUNodeLink *rgb, GPUNodeLink **diff)
513 {
514         GPUNodeLink *fac, *tmp, *addcol;
515         
516         if(!(mat->scene->gm.flag & GAME_GLSL_NO_RAMPS) &&
517            ma->ramp_col && (ma->mode & MA_RAMP_COL)) {
518                 /* MA_RAMP_IN_RESULT is exceptional */
519                 if(ma->rampin_col==MA_RAMP_IN_RESULT) {
520                         addcol = shi->rgb;
521                 }
522                 else {
523                         /* input */
524                         switch(ma->rampin_col) {
525                         case MA_RAMP_IN_ENERGY:
526                                 GPU_link(mat, "ramp_rgbtobw", rgb, &fac);
527                                 break;
528                         case MA_RAMP_IN_SHADER:
529                                 fac= is;
530                                 break;
531                         case MA_RAMP_IN_NOR:
532                                 GPU_link(mat, "vec_math_dot", shi->view, shi->vn, &tmp, &fac);
533                                 break;
534                         default:
535                                 GPU_link(mat, "set_value_zero", &fac);
536                                 break;
537                         }
538
539                         /* colorband + blend */
540                         do_colorband_blend(mat, ma->ramp_col, fac, ma->rampfac_col, ma->rampblend_col, shi->rgb, &addcol);
541                 }
542         }
543         else
544                 addcol = shi->rgb;
545
546         /* output to */
547         GPU_link(mat, "shade_madd", *diff, rgb, addcol, diff);
548 }
549
550 static void ramp_spec_result(GPUShadeInput *shi, GPUNodeLink **spec)
551 {
552         Material *ma= shi->mat;
553         GPUMaterial *mat= shi->gpumat;
554         GPUNodeLink *fac;
555
556         if(!(mat->scene->gm.flag & GAME_GLSL_NO_RAMPS) &&
557            ma->ramp_spec && ma->rampin_spec==MA_RAMP_IN_RESULT) {
558                 GPU_link(mat, "ramp_rgbtobw", *spec, &fac);
559                 
560                 /* colorband + blend */
561                 do_colorband_blend(mat, ma->ramp_spec, fac, ma->rampfac_spec, ma->rampblend_spec, *spec, spec);
562         }
563 }
564
565 static void do_specular_ramp(GPUShadeInput *shi, GPUNodeLink *is, GPUNodeLink *t, GPUNodeLink **spec)
566 {
567         Material *ma= shi->mat;
568         GPUMaterial *mat= shi->gpumat;
569         GPUNodeLink *fac, *tmp;
570
571         *spec = shi->specrgb;
572
573         /* MA_RAMP_IN_RESULT is exception */
574         if(ma->ramp_spec && (ma->rampin_spec!=MA_RAMP_IN_RESULT)) {
575                 
576                 /* input */
577                 switch(ma->rampin_spec) {
578                 case MA_RAMP_IN_ENERGY:
579                         fac = t;
580                         break;
581                 case MA_RAMP_IN_SHADER:
582                         fac = is;
583                         break;
584                 case MA_RAMP_IN_NOR:
585                         GPU_link(mat, "vec_math_dot", shi->view, shi->vn, &tmp, &fac);
586                         break;
587                 default:
588                         GPU_link(mat, "set_value_zero", &fac);
589                         break;
590                 }
591                 
592                 /* colorband + blend */
593                 do_colorband_blend(mat, ma->ramp_spec, fac, ma->rampfac_spec, ma->rampblend_spec, *spec, spec);
594         }
595 }
596
597 void add_user_list(ListBase *list, void *data)
598 {
599         LinkData *link = MEM_callocN(sizeof(LinkData), "GPULinkData");
600         link->data = data;
601         BLI_addtail(list, link);
602 }
603
604 static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *lamp)
605 {
606         Material *ma= shi->mat;
607         GPUMaterial *mat= shi->gpumat;
608         GPUNodeLink *lv, *dist, *visifac, *is, *inp, *i, *vn, *view;
609         GPUNodeLink *outcol, *specfac, *t, *shadfac= NULL;
610         float one = 1.0f;
611
612         if((lamp->mode & LA_ONLYSHADOW) && !(ma->mode & MA_SHADOW))
613                 return;
614         
615         vn= shi->vn;
616         view= shi->view;
617
618         visifac= lamp_get_visibility(mat, lamp, &lv, &dist);
619
620         /*if(ma->mode & MA_TANGENT_V)
621                 GPU_link(mat, "shade_tangent_v", lv, GPU_attribute(CD_TANGENT, ""), &vn);*/
622         
623         GPU_link(mat, "shade_inp", vn, lv, &inp);
624
625         if(lamp->mode & LA_NO_DIFF) {
626                 GPU_link(mat, "shade_is_no_diffuse", &is);
627         }
628         else if(lamp->type == LA_HEMI) {
629                 GPU_link(mat, "shade_is_hemi", inp, &is);
630         }
631         else {
632                 if(lamp->type == LA_AREA) {
633                         float area[4][4]= {{0.0f}}, areasize= 0.0f;
634
635                         mat->dynproperty |= DYN_LAMP_VEC|DYN_LAMP_CO;
636                         GPU_link(mat, "shade_inp_area", GPU_builtin(GPU_VIEW_POSITION), GPU_dynamic_uniform(lamp->dynco), GPU_dynamic_uniform(lamp->dynvec), vn, GPU_uniform((float*)area),
637                                 GPU_uniform(&areasize), GPU_uniform(&lamp->k), &inp);
638                 }
639
640                 is= inp; /* Lambert */
641
642                 if(!(mat->scene->gm.flag & GAME_GLSL_NO_SHADERS)) {
643                         if(ma->diff_shader==MA_DIFF_ORENNAYAR)
644                                 GPU_link(mat, "shade_diffuse_oren_nayer", inp, vn, lv, view, GPU_uniform(&ma->roughness), &is);
645                         else if(ma->diff_shader==MA_DIFF_TOON)
646                                 GPU_link(mat, "shade_diffuse_toon", vn, lv, view, GPU_uniform(&ma->param[0]), GPU_uniform(&ma->param[1]), &is);
647                         else if(ma->diff_shader==MA_DIFF_MINNAERT)
648                                 GPU_link(mat, "shade_diffuse_minnaert", inp, vn, view, GPU_uniform(&ma->darkness), &is);
649                         else if(ma->diff_shader==MA_DIFF_FRESNEL)
650                                 GPU_link(mat, "shade_diffuse_fresnel", vn, lv, view, GPU_uniform(&ma->param[0]), GPU_uniform(&ma->param[1]), &is);
651                 }
652         }
653
654         if(!(mat->scene->gm.flag & GAME_GLSL_NO_SHADERS))
655                 if(ma->shade_flag & MA_CUBIC)
656                         GPU_link(mat, "shade_cubic", is, &is);
657         
658         i = is;
659         GPU_link(mat, "shade_visifac", i, visifac, shi->refl, &i);
660
661         vn = shi->vn;
662         /*if(ma->mode & MA_TANGENT_VN)
663                 GPU_link(mat, "shade_tangent_v_spec", GPU_attribute(CD_TANGENT, ""), &vn);*/
664
665         /* this replaces if(i > 0.0) conditional until that is supported */
666         // done in shade_visifac now, GPU_link(mat, "mtex_value_clamp_positive", i, &i);
667
668         if((ma->mode & MA_SHADOW) && GPU_lamp_has_shadow_buffer(lamp)) {
669                 if(!(mat->scene->gm.flag & GAME_GLSL_NO_SHADOWS)) {
670                         mat->dynproperty |= DYN_LAMP_PERSMAT;
671
672                         GPU_link(mat, "test_shadowbuf",
673                                 GPU_builtin(GPU_VIEW_POSITION),
674                                 GPU_dynamic_texture(lamp->tex),
675                                 GPU_dynamic_uniform((float*)lamp->dynpersmat),
676                                 GPU_uniform(&lamp->bias), inp, &shadfac);
677                         
678                         if(lamp->mode & LA_ONLYSHADOW) {
679                                 GPU_link(mat, "shade_only_shadow", i, shadfac,
680                                         GPU_dynamic_uniform(&lamp->dynenergy), &shadfac);
681                                 
682                                 if(!(lamp->mode & LA_NO_DIFF))
683                                         GPU_link(mat, "shade_only_shadow_diffuse", shadfac, shi->rgb,
684                                                 shr->diff, &shr->diff);
685
686                                 if(!(lamp->mode & LA_NO_SPEC))
687                                         GPU_link(mat, "shade_only_shadow_specular", shadfac, shi->specrgb,
688                                                 shr->spec, &shr->spec);
689                                 
690                                 add_user_list(&mat->lamps, lamp);
691                                 add_user_list(&lamp->materials, shi->gpumat->ma);
692                                 return;
693                         }
694                         
695                         GPU_link(mat, "math_multiply", i, shadfac, &i);
696                 }
697         }
698         else if((mat->scene->gm.flag & GAME_GLSL_NO_SHADOWS) && (lamp->mode & LA_ONLYSHADOW)) {
699                 add_user_list(&mat->lamps, lamp);
700                 add_user_list(&lamp->materials, shi->gpumat->ma);
701                 return;
702         }
703         else
704                 GPU_link(mat, "set_value", GPU_uniform(&one), &shadfac);
705
706         if(GPU_link_changed(shi->refl) || ma->ref != 0.0f) {
707                 if(!(lamp->mode & LA_NO_DIFF)) {
708                         GPUNodeLink *rgb;
709                         GPU_link(mat, "shade_mul_value", i, GPU_dynamic_uniform(lamp->dyncol), &rgb);
710                         add_to_diffuse(mat, ma, shi, is, rgb, &shr->diff);
711                 }
712         }
713
714         if(mat->scene->gm.flag & GAME_GLSL_NO_SHADERS);
715         else if(!(lamp->mode & LA_NO_SPEC) && !(lamp->mode & LA_ONLYSHADOW) &&
716            (GPU_link_changed(shi->spec) || ma->spec != 0.0f)) {
717                 if(lamp->type == LA_HEMI) {
718                         GPU_link(mat, "shade_hemi_spec", vn, lv, view, GPU_uniform(&ma->spec), shi->har, visifac, &t);
719                         GPU_link(mat, "shade_add_spec", t, GPU_dynamic_uniform(lamp->dyncol), shi->specrgb, &outcol);
720                         GPU_link(mat, "shade_add", shr->spec, outcol, &shr->spec);
721                 }
722                 else {
723                         if(ma->spec_shader==MA_SPEC_PHONG)
724                                 GPU_link(mat, "shade_phong_spec", vn, lv, view, shi->har, &specfac);
725                         else if(ma->spec_shader==MA_SPEC_COOKTORR)
726                                 GPU_link(mat, "shade_cooktorr_spec", vn, lv, view, shi->har, &specfac);
727                         else if(ma->spec_shader==MA_SPEC_BLINN)
728                                 GPU_link(mat, "shade_blinn_spec", vn, lv, view, GPU_uniform(&ma->refrac), shi->har, &specfac);
729                         else if(ma->spec_shader==MA_SPEC_WARDISO)
730                                 GPU_link(mat, "shade_wardiso_spec", vn, lv, view, GPU_uniform(&ma->rms), &specfac);
731                         else
732                                 GPU_link(mat, "shade_toon_spec", vn, lv, view, GPU_uniform(&ma->param[2]), GPU_uniform(&ma->param[3]), &specfac);
733
734                         if(lamp->type==LA_AREA)
735                                 GPU_link(mat, "shade_spec_area_inp", specfac, inp, &specfac);
736
737                         GPU_link(mat, "shade_spec_t", shadfac, shi->spec, visifac, specfac, &t);
738
739                         if(ma->mode & MA_RAMP_SPEC) {
740                                 GPUNodeLink *spec;
741                                 do_specular_ramp(shi, specfac, t, &spec);
742                                 GPU_link(mat, "shade_add_spec", t, GPU_dynamic_uniform(lamp->dyncol), spec, &outcol);
743                                 GPU_link(mat, "shade_add", shr->spec, outcol, &shr->spec);
744                         }
745                         else {
746                                 GPU_link(mat, "shade_add_spec", t, GPU_dynamic_uniform(lamp->dyncol), shi->specrgb, &outcol);
747                                 GPU_link(mat, "shade_add", shr->spec, outcol, &shr->spec);
748                         }
749                 }
750         }
751
752         add_user_list(&mat->lamps, lamp);
753         add_user_list(&lamp->materials, shi->gpumat->ma);
754 }
755
756 static void material_lights(GPUShadeInput *shi, GPUShadeResult *shr)
757 {
758         Base *base;
759         Object *ob;
760         Scene *sce_iter;
761         GPULamp *lamp;
762         
763         for(SETLOOPER(shi->gpumat->scene, sce_iter, base)) {
764                 ob= base->object;
765
766                 if(ob->type==OB_LAMP) {
767                         lamp = GPU_lamp_from_blender(shi->gpumat->scene, ob, NULL);
768                         if(lamp)
769                                 shade_one_light(shi, shr, lamp);
770                 }
771
772                 if (ob->transflag & OB_DUPLI) {
773                         DupliObject *dob;
774                         ListBase *lb = object_duplilist(shi->gpumat->scene, ob);
775                         
776                         for(dob=lb->first; dob; dob=dob->next) {
777                                 Object *ob = dob->ob;
778                                 
779                                 if(ob->type==OB_LAMP) {
780                                         copy_m4_m4(ob->obmat, dob->mat);
781
782                                         lamp = GPU_lamp_from_blender(shi->gpumat->scene, ob, base->object);
783                                         if(lamp)
784                                                 shade_one_light(shi, shr, lamp);
785                                 }
786                         }
787                         
788                         free_object_duplilist(lb);
789                 }
790         }
791 }
792
793 static void texture_rgb_blend(GPUMaterial *mat, GPUNodeLink *tex, GPUNodeLink *out, GPUNodeLink *fact, GPUNodeLink *facg, int blendtype, GPUNodeLink **in)
794 {
795         switch(blendtype) {
796         case MTEX_BLEND:
797                 GPU_link(mat, "mtex_rgb_blend", out, tex, fact, facg, in);
798                 break;
799         case MTEX_MUL:
800                 GPU_link(mat, "mtex_rgb_mul", out, tex, fact, facg, in);
801                 break;
802         case MTEX_SCREEN:
803                 GPU_link(mat, "mtex_rgb_screen", out, tex, fact, facg, in);
804                 break;
805         case MTEX_OVERLAY:
806                 GPU_link(mat, "mtex_rgb_overlay", out, tex, fact, facg, in);
807                 break;
808         case MTEX_SUB:
809                 GPU_link(mat, "mtex_rgb_sub", out, tex, fact, facg, in);
810                 break;
811         case MTEX_ADD:
812                 GPU_link(mat, "mtex_rgb_add", out, tex, fact, facg, in);
813                 break;
814         case MTEX_DIV:
815                 GPU_link(mat, "mtex_rgb_div", out, tex, fact, facg, in);
816                 break;
817         case MTEX_DIFF:
818                 GPU_link(mat, "mtex_rgb_diff", out, tex, fact, facg, in);
819                 break;
820         case MTEX_DARK:
821                 GPU_link(mat, "mtex_rgb_dark", out, tex, fact, facg, in);
822                 break;
823         case MTEX_LIGHT:
824                 GPU_link(mat, "mtex_rgb_light", out, tex, fact, facg, in);
825                 break;
826         case MTEX_BLEND_HUE:
827                 GPU_link(mat, "mtex_rgb_hue", out, tex, fact, facg, in);
828                 break;
829         case MTEX_BLEND_SAT:
830                 GPU_link(mat, "mtex_rgb_sat", out, tex, fact, facg, in);
831                 break;
832         case MTEX_BLEND_VAL:
833                 GPU_link(mat, "mtex_rgb_val", out, tex, fact, facg, in);
834                 break;
835         case MTEX_BLEND_COLOR:
836                 GPU_link(mat, "mtex_rgb_color", out, tex, fact, facg, in);
837                 break;
838         default:
839                 GPU_link(mat, "set_rgb_zero", &in);
840                 break;
841         }
842 }
843
844 static void texture_value_blend(GPUMaterial *mat, GPUNodeLink *tex, GPUNodeLink *out, GPUNodeLink *fact, GPUNodeLink *facg, int blendtype, GPUNodeLink **in)
845 {
846         switch(blendtype) {
847         case MTEX_BLEND:
848                 GPU_link(mat, "mtex_value_blend", out, tex, fact, facg, in);
849                 break;
850         case MTEX_MUL:
851                 GPU_link(mat, "mtex_value_mul", out, tex, fact, facg, in);
852                 break;
853         case MTEX_SCREEN:
854                 GPU_link(mat, "mtex_value_screen", out, tex, fact, facg, in);
855                 break;
856         case MTEX_SUB:
857                 GPU_link(mat, "mtex_value_sub", out, tex, fact, facg, in);
858                 break;
859         case MTEX_ADD:
860                 GPU_link(mat, "mtex_value_add", out, tex, fact, facg, in);
861                 break;
862         case MTEX_DIV:
863                 GPU_link(mat, "mtex_value_div", out, tex, fact, facg, in);
864                 break;
865         case MTEX_DIFF:
866                 GPU_link(mat, "mtex_value_diff", out, tex, fact, facg, in);
867                 break;
868         case MTEX_DARK:
869                 GPU_link(mat, "mtex_value_dark", out, tex, fact, facg, in);
870                 break;
871         case MTEX_LIGHT:
872                 GPU_link(mat, "mtex_value_light", out, tex, fact, facg, in);
873                 break;
874         default:
875                 GPU_link(mat, "set_value_zero", &in);
876                 break;
877         }
878 }
879
880 static void do_material_tex(GPUShadeInput *shi)
881 {
882         Material *ma= shi->mat;
883         GPUMaterial *mat= shi->gpumat;
884         MTex *mtex;
885         Tex *tex;
886         GPUNodeLink *texco, *tin, *trgb, *tnor, *tcol, *stencil, *tnorfac;
887         GPUNodeLink *texco_norm, *texco_orco, *texco_object, *texco_tangent;
888         GPUNodeLink *texco_global, *texco_uv = NULL;
889         GPUNodeLink *newnor, *orn;
890         char *lastuvname = NULL;
891         float one = 1.0f, norfac, ofs[3];
892         int tex_nr, rgbnor, talpha;
893
894         GPU_link(mat, "set_value", GPU_uniform(&one), &stencil);
895
896         GPU_link(mat, "texco_norm", GPU_builtin(GPU_VIEW_NORMAL), &texco_norm);
897         GPU_link(mat, "texco_orco", GPU_attribute(CD_ORCO, ""), &texco_orco);
898         GPU_link(mat, "texco_object", GPU_builtin(GPU_INVERSE_VIEW_MATRIX),
899                 GPU_builtin(GPU_INVERSE_OBJECT_MATRIX),
900                 GPU_builtin(GPU_VIEW_POSITION), &texco_object);
901         GPU_link(mat, "texco_tangent", GPU_attribute(CD_TANGENT, ""), &texco_tangent);
902         GPU_link(mat, "texco_global", GPU_builtin(GPU_INVERSE_VIEW_MATRIX),
903                 GPU_builtin(GPU_VIEW_POSITION), &texco_global);
904
905         orn= texco_norm;
906
907         /* go over texture slots */
908         for(tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) {
909                 /* separate tex switching */
910                 if(ma->septex & (1<<tex_nr)) continue;
911                 
912                 if(ma->mtex[tex_nr]) {
913                         mtex= ma->mtex[tex_nr];
914                         
915                         tex= mtex->tex;
916                         if(tex==0) continue;
917
918                         /* which coords */
919                         if(mtex->texco==TEXCO_ORCO)
920                                 texco= texco_orco;
921                         else if(mtex->texco==TEXCO_OBJECT)
922                                 texco= texco_object;
923                         else if(mtex->texco==TEXCO_NORM)
924                                 texco= orn;
925                         else if(mtex->texco==TEXCO_TANGENT)
926                                 texco= texco_object;
927                         else if(mtex->texco==TEXCO_GLOB)
928                                 texco= texco_global;
929                         else if(mtex->texco==TEXCO_REFL)
930                                 texco= shi->ref;
931                         else if(mtex->texco==TEXCO_UV) {
932                                 if(1) { //!(texco_uv && strcmp(mtex->uvname, lastuvname) == 0)) {
933                                         GPU_link(mat, "texco_uv", GPU_attribute(CD_MTFACE, mtex->uvname), &texco_uv);
934                                         lastuvname = mtex->uvname;
935                                 }
936                                 texco= texco_uv;
937                         }
938                         else
939                                 continue;
940
941                         /* in case of uv, this would just undo a multiplication in texco_uv */
942                         if(mtex->texco != TEXCO_UV)
943                                 GPU_link(mat, "mtex_2d_mapping", texco, &texco);
944
945                         if(mtex->size[0] != 1.0f || mtex->size[1] != 1.0f || mtex->size[2] != 1.0f)
946                                 GPU_link(mat, "mtex_mapping_size", texco, GPU_uniform(mtex->size), &texco);
947
948                         ofs[0] = mtex->ofs[0] + 0.5f - 0.5f*mtex->size[0];
949                         ofs[1] = mtex->ofs[1] + 0.5f - 0.5f*mtex->size[1];
950                         ofs[2] = 0.0f;
951                         if(ofs[0] != 0.0f || ofs[1] != 0.0f || ofs[2] != 0.0f)
952                                 GPU_link(mat, "mtex_mapping_ofs", texco, GPU_uniform(ofs), &texco);
953
954                         talpha = 0;
955                         rgbnor = 0;
956
957                         if(tex && tex->type == TEX_IMAGE && tex->ima) {
958                                 GPU_link(mat, "mtex_image", texco, GPU_image(tex->ima, &tex->iuser), &tin, &trgb);
959                                 rgbnor= TEX_RGB;
960
961                                 if(tex->imaflag & TEX_USEALPHA)
962                                         talpha= 1;
963                         }
964                         else continue;
965
966                         /* texture output */
967                         if((rgbnor & TEX_RGB) && (mtex->texflag & MTEX_RGBTOINT)) {
968                                 GPU_link(mat, "mtex_rgbtoint", trgb, &tin);
969                                 rgbnor -= TEX_RGB;
970                         }
971
972                         if(mtex->texflag & MTEX_NEGATIVE) {
973                                 if(rgbnor & TEX_RGB)
974                                         GPU_link(mat, "mtex_rgb_invert", trgb, &trgb);
975                                 else
976                                         GPU_link(mat, "mtex_value_invert", tin, &tin);
977                         }
978
979                         if(mtex->texflag & MTEX_STENCIL) {
980                                 if(rgbnor & TEX_RGB)
981                                         GPU_link(mat, "mtex_rgb_stencil", stencil, trgb, &stencil, &trgb);
982                                 else
983                                         GPU_link(mat, "mtex_value_stencil", stencil, tin, &stencil, &tin);
984                         }
985
986                         /* mapping */
987                         if(mtex->mapto & (MAP_COL+MAP_COLSPEC)) {
988                                 /* stencil maps on the texture control slider, not texture intensity value */
989                                 if((rgbnor & TEX_RGB)==0) {
990                                         GPU_link(mat, "set_rgb", GPU_uniform(&mtex->r), &tcol);
991                                 }
992                                 else {
993                                         GPU_link(mat, "set_rgba", trgb, &tcol);
994
995                                         if(mtex->mapto & MAP_ALPHA)
996                                                 GPU_link(mat, "set_value", stencil, &tin);
997                                         else if(talpha)
998                                                 GPU_link(mat, "mtex_alpha_from_col", trgb, &tin);
999                                         else
1000                                                 GPU_link(mat, "set_value_one", &tin);
1001                                 }
1002
1003                                 if(tex->type==TEX_IMAGE)
1004                                         if(mat->scene->r.color_mgt_flag & R_COLOR_MANAGEMENT)
1005                                                 GPU_link(mat, "srgb_to_linearrgb", tcol, &tcol);
1006                                 
1007                                 if(mtex->mapto & MAP_COL) {
1008                                         GPUNodeLink *colfac;
1009
1010                                         if(mtex->colfac == 1.0f) colfac = stencil;
1011                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->colfac), stencil, &colfac);
1012
1013                                         texture_rgb_blend(mat, tcol, shi->rgb, tin, colfac, mtex->blendtype, &shi->rgb);
1014                                 }
1015                                 
1016                                 if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && (mtex->mapto & MAP_COLSPEC)) {
1017                                         GPUNodeLink *colspecfac;
1018
1019                                         if(mtex->colspecfac == 1.0f) colspecfac = stencil;
1020                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->colspecfac), stencil, &colspecfac);
1021
1022                                         texture_rgb_blend(mat, tcol, shi->specrgb, tin, colspecfac, mtex->blendtype, &shi->specrgb);
1023                                 }
1024                         }
1025
1026                         if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && (mtex->mapto & MAP_NORM)) {
1027                                 if(tex->type==TEX_IMAGE) {
1028                                         if(tex->imaflag & TEX_NORMALMAP) {
1029                                                 /* normalmap image */
1030                                                 GPU_link(mat, "mtex_normal", texco, GPU_image(tex->ima, &tex->iuser), &tnor );
1031                                                 
1032                                                 if(mtex->norfac < 0.0f)
1033                                                         GPU_link(mat, "mtex_negate_texnormal", tnor, &tnor);
1034
1035                                                 if(mtex->normapspace == MTEX_NSPACE_TANGENT)
1036                                                         GPU_link(mat, "mtex_nspace_tangent", GPU_attribute(CD_TANGENT, ""), shi->vn, tnor, &newnor);
1037                                                 else
1038                                                         newnor = tnor;
1039                                                 
1040                                                 norfac = MIN2(fabsf(mtex->norfac), 1.0);
1041                                         } else if( mtex->texflag & (MTEX_3TAP_BUMP|MTEX_5TAP_BUMP)) {
1042                                                 /* ntap bumpmap image */
1043                                                 float hScale = 0.1f; // compatibility adjustment factor for all bumpspace types
1044                                                 float fScaleTex = 130.0f; // factor for scaling texspace bumps
1045                                                 
1046                                                 GPUNodeLink *surf_pos = GPU_builtin(GPU_VIEW_POSITION);
1047                                                 GPUNodeLink *vR1, *vR2, *fDet;
1048                                                 GPUNodeLink *dBs, *dBt, *vN;
1049                                                 
1050                                                 if( mtex->texflag & MTEX_BUMP_OBJECTSPACE )
1051                                                         GPU_link( mat, "mtex_bump_init_objspace",
1052                                                                           surf_pos, shi->vn, 
1053                                                                   GPU_builtin(GPU_VIEW_MATRIX), GPU_builtin(GPU_INVERSE_VIEW_MATRIX), GPU_builtin(GPU_OBJECT_MATRIX),  GPU_builtin(GPU_INVERSE_OBJECT_MATRIX), 
1054                                                                           &vR1, &vR2, &fDet, &vN );
1055                                                 else
1056                                                         GPU_link( mat, "mtex_bump_init_viewspace",
1057                                                                           surf_pos, shi->vn,
1058                                                                           &vR1, &vR2, &fDet, &vN );
1059                                                 
1060                                                 if( mtex->texflag & MTEX_3TAP_BUMP )
1061                                                         GPU_link( mat, "mtex_bump_tap3", 
1062                                                                   texco, GPU_image(tex->ima, &tex->iuser), GPU_uniform(&hScale),
1063                                                                   &dBs, &dBt );
1064                                                 else
1065                                                         GPU_link( mat, "mtex_bump_tap5", 
1066                                                                   texco, GPU_image(tex->ima, &tex->iuser), GPU_uniform(&hScale),
1067                                                                   &dBs, &dBt );
1068                                                 
1069                                                 if( mtex->texflag & MTEX_BUMP_TEXTURESPACE )
1070                                                         GPU_link( mat, "mtex_bump_apply_texspace",
1071                                                                   fDet, dBs, dBt, vR1, vR2, vN, GPU_image(tex->ima, &tex->iuser), texco, GPU_uniform(&fScaleTex),
1072                                                                   &tnor );
1073                                                 else if( mtex->texflag & MTEX_BUMP_OBJECTSPACE )
1074                                                         GPU_link( mat, "mtex_bump_apply_objspace",
1075                                                                   fDet, dBs, dBt, vR1, vR2, vN, GPU_builtin(GPU_INVERSE_VIEW_MATRIX), GPU_builtin(GPU_INVERSE_OBJECT_MATRIX), 
1076                                                                   &tnor, &vR1, &vR2, &vN );
1077                                                 else
1078                                                         GPU_link( mat, "mtex_bump_apply_viewspace",
1079                                                                   fDet, dBs, dBt, vR1, vR2, vN,
1080                                                                   &tnor );
1081                                                 
1082                                                 newnor = tnor;
1083                                                 norfac = mtex->norfac;
1084                                         } else {
1085                                                 /* original or compatible bump - don't have shaders */
1086                                                 newnor = shi->vn;
1087                                                 norfac = mtex->norfac;
1088                                         }
1089                                         
1090                                         if(norfac == 1.0f && !GPU_link_changed(stencil)) {
1091                                                 shi->vn = newnor;
1092                                         }
1093                                         else {
1094                                                 tnorfac = GPU_uniform(&norfac);
1095
1096                                                 if(GPU_link_changed(stencil))
1097                                                         GPU_link(mat, "math_multiply", tnorfac, stencil, &tnorfac);
1098
1099                                                 GPU_link(mat, "mtex_blend_normal", tnorfac, shi->vn, newnor, &shi->vn);
1100                                         }
1101                                 }
1102                                 
1103                                 GPU_link(mat, "vec_math_negate", shi->vn, &orn);
1104                                 GPU_link(mat, "texco_refl", shi->vn, shi->view, &shi->ref);
1105                         }
1106
1107                         if((mtex->mapto & MAP_VARS)) {
1108                                 if(rgbnor & TEX_RGB) {
1109                                         if(talpha)
1110                                                 GPU_link(mat, "mtex_alpha_from_col", trgb, &tin);
1111                                         else
1112                                                 GPU_link(mat, "mtex_rgbtoint", trgb, &tin);
1113                                 }
1114
1115                                 if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_REF) {
1116                                         GPUNodeLink *difffac;
1117
1118                                         if(mtex->difffac == 1.0f) difffac = stencil;
1119                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->difffac), stencil, &difffac);
1120
1121                                         texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->refl, tin, difffac, mtex->blendtype, &shi->refl);
1122                                         GPU_link(mat, "mtex_value_clamp_positive", shi->refl, &shi->refl);
1123                                 }
1124                                 if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_SPEC) {
1125                                         GPUNodeLink *specfac;
1126
1127                                         if(mtex->specfac == 1.0f) specfac = stencil;
1128                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->specfac), stencil, &specfac);
1129
1130                                         texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->spec, tin, specfac, mtex->blendtype, &shi->spec);
1131                                         GPU_link(mat, "mtex_value_clamp_positive", shi->spec, &shi->spec);
1132                                 }
1133                                 if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_EMIT) {
1134                                         GPUNodeLink *emitfac;
1135
1136                                         if(mtex->emitfac == 1.0f) emitfac = stencil;
1137                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->emitfac), stencil, &emitfac);
1138
1139                                         texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->emit, tin, emitfac, mtex->blendtype, &shi->emit);
1140                                         GPU_link(mat, "mtex_value_clamp_positive", shi->emit, &shi->emit);
1141                                 }
1142                                 if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_HAR) {
1143                                         GPUNodeLink *hardfac;
1144
1145                                         if(mtex->hardfac == 1.0f) hardfac = stencil;
1146                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->hardfac), stencil, &hardfac);
1147
1148                                         GPU_link(mat, "mtex_har_divide", shi->har, &shi->har);
1149                                         texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->har, tin, hardfac, mtex->blendtype, &shi->har);
1150                                         GPU_link(mat, "mtex_har_multiply_clamp", shi->har, &shi->har);
1151                                 }
1152                                 if(mtex->mapto & MAP_ALPHA) {
1153                                         GPUNodeLink *alphafac;
1154
1155                                         if(mtex->alphafac == 1.0f) alphafac = stencil;
1156                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->alphafac), stencil, &alphafac);
1157
1158                                         texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->alpha, tin, alphafac, mtex->blendtype, &shi->alpha);
1159                                         GPU_link(mat, "mtex_value_clamp", shi->alpha, &shi->alpha);
1160                                 }
1161                                 if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_AMB) {
1162                                         GPUNodeLink *ambfac;
1163
1164                                         if(mtex->ambfac == 1.0f) ambfac = stencil;
1165                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->ambfac), stencil, &ambfac);
1166
1167                                         texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->amb, tin, ambfac, mtex->blendtype, &shi->amb);
1168                                         GPU_link(mat, "mtex_value_clamp", shi->amb, &shi->amb);
1169                                 }
1170                         }
1171                 }
1172         }
1173 }
1174
1175 void GPU_shadeinput_set(GPUMaterial *mat, Material *ma, GPUShadeInput *shi)
1176 {
1177         float hard = ma->har;
1178
1179         memset(shi, 0, sizeof(*shi));
1180
1181         shi->gpumat = mat;
1182         shi->mat = ma;
1183
1184         GPU_link(mat, "set_rgb", GPU_uniform(&ma->r), &shi->rgb);
1185         GPU_link(mat, "set_rgb", GPU_uniform(&ma->specr), &shi->specrgb);
1186         GPU_link(mat, "shade_norm", GPU_builtin(GPU_VIEW_NORMAL), &shi->vn);
1187         GPU_link(mat, "set_value", GPU_uniform(&ma->alpha), &shi->alpha);
1188         GPU_link(mat, "set_value", GPU_uniform(&ma->ref), &shi->refl);
1189         GPU_link(mat, "set_value", GPU_uniform(&ma->spec), &shi->spec);
1190         GPU_link(mat, "set_value", GPU_uniform(&ma->emit), &shi->emit);
1191         GPU_link(mat, "set_value", GPU_uniform(&hard), &shi->har);
1192         GPU_link(mat, "set_value", GPU_uniform(&ma->amb), &shi->amb);
1193         GPU_link(mat, "shade_view", GPU_builtin(GPU_VIEW_POSITION), &shi->view);
1194         GPU_link(mat, "vcol_attribute", GPU_attribute(CD_MCOL, ""), &shi->vcol);
1195         GPU_link(mat, "texco_refl", shi->vn, shi->view, &shi->ref);
1196 }
1197
1198 void GPU_shaderesult_set(GPUShadeInput *shi, GPUShadeResult *shr)
1199 {
1200         GPUMaterial *mat= shi->gpumat;
1201         GPUNodeLink *emit, *ulinfac, *ulogfac, *mistfac;
1202         Material *ma= shi->mat;
1203         World *world= mat->scene->world;
1204         float linfac, logfac, misttype;
1205
1206         memset(shr, 0, sizeof(*shr));
1207
1208         if(ma->mode & MA_VERTEXCOLP)
1209                 shi->rgb = shi->vcol;
1210
1211         do_material_tex(shi);
1212
1213         if((ma->mode & MA_TRANSP) && (ma->mode & MA_ZTRANSP))
1214                 GPU_material_enable_alpha(mat);
1215
1216         if((mat->scene->gm.flag & GAME_GLSL_NO_LIGHTS) || (ma->mode & MA_SHLESS)) {
1217                 shr->combined = shi->rgb;
1218                 shr->alpha = shi->alpha;
1219                 GPU_link(mat, "set_rgb", shi->rgb, &shr->diff);
1220                 GPU_link(mat, "set_rgb_zero", &shr->spec);
1221         }
1222         else {
1223                 if(GPU_link_changed(shi->emit) || ma->emit != 0.0f) {
1224                         if((ma->mode & (MA_VERTEXCOL|MA_VERTEXCOLP))== MA_VERTEXCOL) {
1225                                 GPU_link(mat, "shade_add", shi->emit, shi->vcol, &emit);
1226                                 GPU_link(mat, "shade_mul", emit, shi->rgb, &shr->diff);
1227                         }
1228                         else
1229                                 GPU_link(mat, "shade_mul_value", shi->emit, shi->rgb, &shr->diff);
1230                 }
1231                 else
1232                         GPU_link(mat, "set_rgb_zero", &shr->diff);
1233
1234                 GPU_link(mat, "set_rgb_zero", &shr->spec);
1235
1236                 material_lights(shi, shr);
1237
1238                 shr->combined = shr->diff;
1239                 shr->alpha = shi->alpha;
1240
1241                 if(world) {
1242                         /* exposure correction */
1243                         if(world->exp!=0.0f || world->range!=1.0f) {
1244                                 linfac= 1.0 + pow((2.0*world->exp + 0.5), -10);
1245                                 logfac= log((linfac-1.0)/linfac)/world->range;
1246
1247                                 GPU_link(mat, "set_value", GPU_uniform(&linfac), &ulinfac);
1248                                 GPU_link(mat, "set_value", GPU_uniform(&logfac), &ulogfac);
1249
1250                                 GPU_link(mat, "shade_exposure_correct", shr->combined,
1251                                         ulinfac, ulogfac, &shr->combined);
1252                                 GPU_link(mat, "shade_exposure_correct", shr->spec,
1253                                         ulinfac, ulogfac, &shr->spec);
1254                         }
1255
1256                         /* ambient color */
1257                         if(world->ambr!=0.0f || world->ambg!=0.0f || world->ambb!=0.0f) {
1258                                 if(GPU_link_changed(shi->amb) || ma->amb != 0.0f)
1259                                         GPU_link(mat, "shade_maddf", shr->combined, GPU_uniform(&ma->amb),
1260                                                 GPU_uniform(&world->ambr), &shr->combined);
1261                         }
1262                 }
1263
1264                 if(ma->mode & MA_RAMP_COL) ramp_diffuse_result(shi, &shr->combined);
1265                 if(ma->mode & MA_RAMP_SPEC) ramp_spec_result(shi, &shr->spec);
1266
1267                 if(GPU_link_changed(shi->spec) || ma->spec != 0.0f)
1268                         GPU_link(mat, "shade_add", shr->combined, shr->spec, &shr->combined);
1269         }
1270
1271         GPU_link(mat, "mtex_alpha_to_col", shr->combined, shr->alpha, &shr->combined);
1272
1273         if(ma->shade_flag & MA_OBCOLOR)
1274                 GPU_link(mat, "shade_obcolor", shr->combined, GPU_builtin(GPU_OBCOLOR), &shr->combined);
1275
1276         if(world && (world->mode & WO_MIST) && !(ma->mode & MA_NOMIST)) {
1277                 misttype = world->mistype;
1278
1279                 GPU_link(mat, "shade_mist_factor", GPU_builtin(GPU_VIEW_POSITION),
1280                         GPU_uniform(&world->miststa), GPU_uniform(&world->mistdist),
1281                         GPU_uniform(&misttype), GPU_uniform(&world->misi), &mistfac);
1282
1283                 GPU_link(mat, "mix_blend", mistfac, shr->combined,
1284                         GPU_uniform(&world->horr), &shr->combined);
1285         }
1286
1287         if(!((ma->mode & MA_TRANSP) && (ma->mode & MA_ZTRANSP))) {
1288                 if(world && (GPU_link_changed(shr->alpha) || ma->alpha != 1.0f))
1289                         GPU_link(mat, "shade_world_mix", GPU_uniform(&world->horr),
1290                                 shr->combined, &shr->combined);
1291
1292                 GPU_link(mat, "shade_alpha_opaque", shr->combined, &shr->combined);
1293         }
1294
1295         if(ma->shade_flag & MA_OBCOLOR) {
1296                 mat->obcolalpha = 1;
1297                 GPU_link(mat, "shade_alpha_obcolor", shr->combined, GPU_builtin(GPU_OBCOLOR), &shr->combined);
1298         }
1299
1300         if(mat->scene->r.color_mgt_flag & R_COLOR_MANAGEMENT)
1301                 GPU_link(mat, "linearrgb_to_srgb", shr->combined, &shr->combined);
1302 }
1303
1304 GPUNodeLink *GPU_blender_material(GPUMaterial *mat, Material *ma)
1305 {
1306         GPUShadeInput shi;
1307         GPUShadeResult shr;
1308
1309         GPU_shadeinput_set(mat, ma, &shi);
1310         GPU_shaderesult_set(&shi, &shr);
1311
1312         return shr.combined;
1313 }
1314
1315 GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma)
1316 {
1317         GPUMaterial *mat;
1318         GPUNodeLink *outlink;
1319         LinkData *link;
1320
1321         for(link=ma->gpumaterial.first; link; link=link->next)
1322                 if(((GPUMaterial*)link->data)->scene == scene)
1323                         return link->data;
1324
1325         mat = GPU_material_construct_begin(ma);
1326         mat->scene = scene;
1327
1328         if(!(scene->gm.flag & GAME_GLSL_NO_NODES) && ma->nodetree && ma->use_nodes) {
1329                 ntreeGPUMaterialNodes(ma->nodetree, mat);
1330         }
1331         else {
1332                 outlink = GPU_blender_material(mat, ma);
1333                 GPU_material_output_link(mat, outlink);
1334         }
1335
1336         /*if(!GPU_material_construct_end(mat)) {
1337                 GPU_material_free(mat);
1338                 mat= NULL;
1339                 return 0;
1340         }*/
1341
1342         GPU_material_construct_end(mat);
1343
1344         link = MEM_callocN(sizeof(LinkData), "GPUMaterialLink");
1345         link->data = mat;
1346         BLI_addtail(&ma->gpumaterial, link);
1347
1348         return mat;
1349 }
1350
1351 void GPU_materials_free(void)
1352 {
1353         Object *ob;
1354         Material *ma;
1355         extern Material defmaterial;
1356
1357         for(ma=G.main->mat.first; ma; ma=ma->id.next)
1358                 GPU_material_free(ma);
1359
1360         GPU_material_free(&defmaterial);
1361
1362         for(ob=G.main->object.first; ob; ob=ob->id.next)
1363                 GPU_lamp_free(ob);
1364 }
1365
1366 /* Lamps and shadow buffers */
1367
1368 void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[][4])
1369 {
1370         float mat[4][4];
1371
1372         lamp->lay = lay;
1373         lamp->hide = hide;
1374
1375         copy_m4_m4(mat, obmat);
1376         normalize_m4(mat);
1377
1378         VECCOPY(lamp->vec, mat[2]);
1379         VECCOPY(lamp->co, mat[3]);
1380         copy_m4_m4(lamp->obmat, mat);
1381         invert_m4_m4(lamp->imat, mat);
1382 }
1383
1384 void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float energy)
1385 {
1386         lamp->energy = energy;
1387         if(lamp->mode & LA_NEG) lamp->energy= -lamp->energy;
1388
1389         lamp->col[0]= r* lamp->energy;
1390         lamp->col[1]= g* lamp->energy;
1391         lamp->col[2]= b* lamp->energy;
1392 }
1393
1394 static void gpu_lamp_from_blender(Scene *scene, Object *ob, Object *par, Lamp *la, GPULamp *lamp)
1395 {
1396         float temp, angle, pixsize, wsize;
1397
1398         lamp->scene = scene;
1399         lamp->ob = ob;
1400         lamp->par = par;
1401         lamp->la = la;
1402
1403         /* add_render_lamp */
1404         lamp->mode = la->mode;
1405         lamp->type = la->type;
1406
1407         lamp->energy = la->energy;
1408         if(lamp->mode & LA_NEG) lamp->energy= -lamp->energy;
1409
1410         lamp->col[0]= la->r*lamp->energy;
1411         lamp->col[1]= la->g*lamp->energy;
1412         lamp->col[2]= la->b*lamp->energy;
1413
1414         GPU_lamp_update(lamp, ob->lay, (ob->restrictflag & OB_RESTRICT_RENDER), ob->obmat);
1415
1416         lamp->spotsi= la->spotsize;
1417         if(lamp->mode & LA_HALO)
1418                 if(lamp->spotsi > 170.0)
1419                         lamp->spotsi = 170.0;
1420         lamp->spotsi= cos(M_PI*lamp->spotsi/360.0);
1421         lamp->spotbl= (1.0 - lamp->spotsi)*la->spotblend;
1422         lamp->k= la->k;
1423
1424         lamp->dist= la->dist;
1425         lamp->falloff_type= la->falloff_type;
1426         lamp->att1= la->att1;
1427         lamp->att2= la->att2;
1428         lamp->curfalloff= la->curfalloff;
1429
1430         /* initshadowbuf */
1431         lamp->bias = 0.02f*la->bias;
1432         lamp->size = la->bufsize;
1433         lamp->d= la->clipsta;
1434         lamp->clipend= la->clipend;
1435
1436         /* arbitrary correction for the fact we do no soft transition */
1437         lamp->bias *= 0.25f;
1438
1439         /* makeshadowbuf */
1440         angle= saacos(lamp->spotsi);
1441         temp= 0.5f*lamp->size*cos(angle)/sin(angle);
1442         pixsize= (lamp->d)/temp;
1443         wsize= pixsize*0.5f*lamp->size;
1444                 
1445         perspective_m4( lamp->winmat,-wsize, wsize, -wsize, wsize, lamp->d, lamp->clipend);
1446 }
1447
1448 static void gpu_lamp_shadow_free(GPULamp *lamp)
1449 {
1450         if(lamp->tex) {
1451                 GPU_texture_free(lamp->tex);
1452                 lamp->tex= NULL;
1453         }
1454         if(lamp->fb) {
1455                 GPU_framebuffer_free(lamp->fb);
1456                 lamp->fb= NULL;
1457         }
1458 }
1459
1460 GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par)
1461 {
1462         Lamp *la;
1463         GPULamp *lamp;
1464         LinkData *link;
1465
1466         for(link=ob->gpulamp.first; link; link=link->next) {
1467                 lamp = (GPULamp*)link->data;
1468
1469                 if(lamp->par == par && lamp->scene == scene)
1470                         return link->data;
1471         }
1472
1473         lamp = MEM_callocN(sizeof(GPULamp), "GPULamp");
1474
1475         link = MEM_callocN(sizeof(LinkData), "GPULampLink");
1476         link->data = lamp;
1477         BLI_addtail(&ob->gpulamp, link);
1478
1479         la = ob->data;
1480         gpu_lamp_from_blender(scene, ob, par, la, lamp);
1481
1482         if(la->type==LA_SPOT && (la->mode & LA_SHAD_BUF)) {
1483                 /* opengl */
1484                 lamp->fb = GPU_framebuffer_create();
1485                 if(!lamp->fb) {
1486                         gpu_lamp_shadow_free(lamp);
1487                         return lamp;
1488                 }
1489
1490                 lamp->tex = GPU_texture_create_depth(lamp->size, lamp->size);
1491                 if(!lamp->tex) {
1492                         gpu_lamp_shadow_free(lamp);
1493                         return lamp;
1494                 }
1495
1496                 if(!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex)) {
1497                         gpu_lamp_shadow_free(lamp);
1498                         return lamp;
1499                 }
1500
1501                 GPU_framebuffer_restore();
1502         }
1503
1504         return lamp;
1505 }
1506
1507 void GPU_lamp_free(Object *ob)
1508 {
1509         GPULamp *lamp;
1510         LinkData *link;
1511         LinkData *nlink;
1512         Material *ma;
1513
1514         for(link=ob->gpulamp.first; link; link=link->next) {
1515                 lamp = link->data;
1516
1517                 while(lamp->materials.first) {
1518                         nlink = lamp->materials.first;
1519                         ma = nlink->data;
1520                         BLI_freelinkN(&lamp->materials, nlink);
1521
1522                         if(ma->gpumaterial.first)
1523                                 GPU_material_free(ma);
1524                 }
1525
1526                 gpu_lamp_shadow_free(lamp);
1527
1528                 MEM_freeN(lamp);
1529         }
1530
1531         BLI_freelistN(&ob->gpulamp);
1532 }
1533
1534 int GPU_lamp_has_shadow_buffer(GPULamp *lamp)
1535 {
1536         return (!(lamp->scene->gm.flag & GAME_GLSL_NO_SHADOWS) &&
1537                         !(lamp->scene->gm.flag & GAME_GLSL_NO_LIGHTS) &&
1538                         lamp->tex && lamp->fb);
1539 }
1540
1541 void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[][4], int *winsize, float winmat[][4])
1542 {
1543         float rangemat[4][4], persmat[4][4];
1544
1545         /* initshadowbuf */
1546         invert_m4_m4(lamp->viewmat, lamp->obmat);
1547         normalize_v3(lamp->viewmat[0]);
1548         normalize_v3(lamp->viewmat[1]);
1549         normalize_v3(lamp->viewmat[2]);
1550
1551         /* makeshadowbuf */
1552         mul_m4_m4m4(persmat, lamp->viewmat, lamp->winmat);
1553
1554         /* opengl depth buffer is range 0.0..1.0 instead of -1.0..1.0 in blender */
1555         unit_m4(rangemat);
1556         rangemat[0][0] = 0.5f;
1557         rangemat[1][1] = 0.5f;
1558         rangemat[2][2] = 0.5f;
1559         rangemat[3][0] = 0.5f;
1560         rangemat[3][1] = 0.5f;
1561         rangemat[3][2] = 0.5f;
1562
1563         mul_m4_m4m4(lamp->persmat, persmat, rangemat);
1564
1565         /* opengl */
1566         glDisable(GL_SCISSOR_TEST);
1567         GPU_framebuffer_texture_bind(lamp->fb, lamp->tex);
1568
1569         /* set matrices */
1570         copy_m4_m4(viewmat, lamp->viewmat);
1571         copy_m4_m4(winmat, lamp->winmat);
1572         *winsize = lamp->size;
1573 }
1574
1575 void GPU_lamp_shadow_buffer_unbind(GPULamp *lamp)
1576 {
1577         GPU_framebuffer_texture_unbind(lamp->fb, lamp->tex);
1578         GPU_framebuffer_restore();
1579         glEnable(GL_SCISSOR_TEST);
1580 }
1581
1582 int GPU_lamp_shadow_layer(GPULamp *lamp)
1583 {
1584         if(lamp->fb && lamp->tex && (lamp->mode & (LA_LAYER|LA_LAYER_SHADOW)))
1585                 return lamp->lay;
1586         else
1587                 return -1;
1588 }
1589