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