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