BGE: Bringing over the dynamic lamp properties fixes from Cucumber (thanks to Daniel...
[blender.git] / source / blender / gpu / intern / gpu_material.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version. 
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2006 Blender Foundation.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): Brecht Van Lommel.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/gpu/intern/gpu_material.c
29  *  \ingroup gpu
30  */
31
32
33 #include <math.h>
34 #include <string.h>
35
36 #include "GL/glew.h"
37
38 #include "MEM_guardedalloc.h"
39
40 #include "DNA_lamp_types.h"
41 #include "DNA_material_types.h"
42 #include "DNA_object_types.h"
43 #include "DNA_scene_types.h"
44 #include "DNA_world_types.h"
45
46 #include "BLI_math.h"
47 #include "BLI_blenlib.h"
48 #include "BLI_utildefines.h"
49
50 #include "BKE_anim.h"
51 #include "BKE_colortools.h"
52 #include "BKE_DerivedMesh.h"
53 #include "BKE_global.h"
54 #include "BKE_image.h"
55 #include "BKE_main.h"
56 #include "BKE_node.h"
57 #include "BKE_scene.h"
58 #include "BKE_texture.h"
59
60 #include "IMB_imbuf_types.h"
61
62 #include "GPU_extensions.h"
63 #include "GPU_material.h"
64
65 #include "gpu_codegen.h"
66
67 #include <string.h>
68
69 /* Structs */
70
71 typedef enum DynMatProperty {
72         DYN_LAMP_CO = 1,
73         DYN_LAMP_VEC = 2,
74         DYN_LAMP_IMAT = 4,
75         DYN_LAMP_PERSMAT = 8,
76 } DynMatProperty;
77
78 struct GPUMaterial {
79         Scene *scene;
80         Material *ma;
81
82         /* for creating the material */
83         ListBase nodes;
84         GPUNodeLink *outlink;
85
86         /* for binding the material */
87         GPUPass *pass;
88         GPUVertexAttribs attribs;
89         int bound;
90         int builtins;
91         int alpha, obcolalpha;
92         int dynproperty;
93
94         /* for passing uniforms */
95         int viewmatloc, invviewmatloc;
96         int obmatloc, invobmatloc;
97         int obcolloc, obautobumpscaleloc;
98
99         ListBase lamps;
100 };
101
102 struct GPULamp {
103         Scene *scene;
104         Object *ob;
105         Object *par;
106         Lamp *la;
107
108         int type, mode, lay, hide;
109
110         float dynenergy, dyncol[3];
111         float energy, col[3];
112
113         float co[3], vec[3];
114         float dynco[3], dynvec[3];
115         float obmat[4][4];
116         float imat[4][4];
117         float dynimat[4][4];
118
119         float spotsi, spotbl, k;
120         float dyndist, dynatt1, dynatt2;
121         float dist, att1, att2;
122         float shadow_color[3];
123
124         float bias, d, clipend;
125         int size;
126
127         int falloff_type;
128         struct CurveMapping *curfalloff;
129
130         float winmat[4][4];
131         float viewmat[4][4];
132         float persmat[4][4];
133         float dynpersmat[4][4];
134
135         GPUFrameBuffer *fb;
136         GPUFrameBuffer *blurfb;
137         GPUTexture *tex;
138         GPUTexture *depthtex;
139         GPUTexture *blurtex;
140
141         ListBase materials;
142 };
143
144 /* Forward declaration so shade_light_textures() can use this, while still keeping the code somewhat organized */
145 static void texture_rgb_blend(GPUMaterial *mat, GPUNodeLink *tex, GPUNodeLink *out, GPUNodeLink *fact, GPUNodeLink *facg, int blendtype, GPUNodeLink **in);
146
147 /* Functions */
148
149 static GPUMaterial *GPU_material_construct_begin(Material *ma)
150 {
151         GPUMaterial *material = MEM_callocN(sizeof(GPUMaterial), "GPUMaterial");
152
153         material->ma= ma;
154
155         return material;
156 }
157
158 static void gpu_material_set_attrib_id(GPUMaterial *material)
159 {
160         GPUVertexAttribs *attribs;
161         GPUShader *shader;
162         GPUPass *pass;
163         char name[32];
164         int a, b;
165
166         attribs= &material->attribs;
167         pass= material->pass;
168         if (!pass) {
169                 attribs->totlayer = 0;
170                 return;
171         }
172         
173         shader= GPU_pass_shader(pass);
174         if (!shader) {
175                 attribs->totlayer = 0;
176                 return;
177         }
178
179         /* convert from attribute number to the actual id assigned by opengl,
180          * in case the attrib does not get a valid index back, it was probably
181          * removed by the glsl compiler by dead code elimination */
182
183         for (a=0, b=0; a<attribs->totlayer; a++) {
184                 BLI_snprintf(name, sizeof(name), "att%d", attribs->layer[a].attribid);
185                 attribs->layer[a].glindex = GPU_shader_get_attribute(shader, name);
186
187                 if (attribs->layer[a].glindex >= 0) {
188                         attribs->layer[b] = attribs->layer[a];
189                         b++;
190                 }
191         }
192
193         attribs->totlayer = b;
194 }
195
196 static int GPU_material_construct_end(GPUMaterial *material)
197 {
198         if (material->outlink) {
199                 GPUNodeLink *outlink;
200                 GPUShader *shader;
201
202                 outlink = material->outlink;
203                 material->pass = GPU_generate_pass(&material->nodes, outlink,
204                         &material->attribs, &material->builtins, material->ma->id.name);
205
206                 if (!material->pass)
207                         return 0;
208
209                 gpu_material_set_attrib_id(material);
210                 
211                 shader = GPU_pass_shader(material->pass);
212
213                 if (material->builtins & GPU_VIEW_MATRIX)
214                         material->viewmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_VIEW_MATRIX));
215                 if (material->builtins & GPU_INVERSE_VIEW_MATRIX)
216                         material->invviewmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_INVERSE_VIEW_MATRIX));
217                 if (material->builtins & GPU_OBJECT_MATRIX)
218                         material->obmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_OBJECT_MATRIX));
219                 if (material->builtins & GPU_INVERSE_OBJECT_MATRIX)
220                         material->invobmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_INVERSE_OBJECT_MATRIX));
221                 if (material->builtins & GPU_OBCOLOR)
222                         material->obcolloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_OBCOLOR));
223                 if (material->builtins & GPU_AUTO_BUMPSCALE)
224                         material->obautobumpscaleloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_AUTO_BUMPSCALE));
225                 return 1;
226         }
227
228         return 0;
229 }
230
231 void GPU_material_free(Material *ma)
232 {
233         LinkData *link;
234         LinkData *nlink, *mlink, *next;
235
236         for (link=ma->gpumaterial.first; link; link=link->next) {
237                 GPUMaterial *material = link->data;
238
239                 if (material->pass)
240                         GPU_pass_free(material->pass);
241
242                 for (nlink=material->lamps.first; nlink; nlink=nlink->next) {
243                         GPULamp *lamp = nlink->data;
244
245                         for (mlink=lamp->materials.first; mlink; mlink=next) {
246                                 next = mlink->next;
247                                 if (mlink->data == ma)
248                                         BLI_freelinkN(&lamp->materials, mlink);
249                         }
250                 }
251
252                 BLI_freelistN(&material->lamps);
253
254                 MEM_freeN(material);
255         }
256
257         BLI_freelistN(&ma->gpumaterial);
258 }
259
260 void GPU_material_bind(GPUMaterial *material, int oblay, int viewlay, double time, int mipmap)
261 {
262         if (material->pass) {
263                 LinkData *nlink;
264                 GPULamp *lamp;
265
266                 /* handle layer lamps */
267                 for (nlink=material->lamps.first; nlink; nlink=nlink->next) {
268                         lamp= nlink->data;
269
270                         if (!lamp->hide && (lamp->lay & viewlay) && (!(lamp->mode & LA_LAYER) || (lamp->lay & oblay))) {
271                                 lamp->dynenergy = lamp->energy;
272                                 copy_v3_v3(lamp->dyncol, lamp->col);
273                         }
274                         else {
275                                 lamp->dynenergy = 0.0f;
276                                 lamp->dyncol[0]= lamp->dyncol[1]= lamp->dyncol[2] = 0.0f;
277                         }
278                 }
279
280                 GPU_pass_bind(material->pass, time, mipmap);
281                 material->bound = 1;
282         }
283 }
284
285 void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[][4], float viewmat[][4], float viewinv[][4], float obcol[4], float autobumpscale)
286 {
287         if (material->pass) {
288                 GPUShader *shader = GPU_pass_shader(material->pass);
289                 LinkData *nlink;
290                 GPULamp *lamp;
291                 float invmat[4][4], col[4];
292
293                 /* handle builtins */
294                 if (material->builtins & GPU_VIEW_MATRIX) {
295                         GPU_shader_uniform_vector(shader, material->viewmatloc, 16, 1, (float*)viewmat);
296                 }
297                 if (material->builtins & GPU_INVERSE_VIEW_MATRIX) {
298                         GPU_shader_uniform_vector(shader, material->invviewmatloc, 16, 1, (float*)viewinv);
299                 }
300                 if (material->builtins & GPU_OBJECT_MATRIX) {
301                         GPU_shader_uniform_vector(shader, material->obmatloc, 16, 1, (float*)obmat);
302                 }
303                 if (material->builtins & GPU_INVERSE_OBJECT_MATRIX) {
304                         invert_m4_m4(invmat, obmat);
305                         GPU_shader_uniform_vector(shader, material->invobmatloc, 16, 1, (float*)invmat);
306                 }
307                 if (material->builtins & GPU_OBCOLOR) {
308                         copy_v4_v4(col, obcol);
309                         CLAMP(col[3], 0.0f, 1.0f);
310                         GPU_shader_uniform_vector(shader, material->obcolloc, 4, 1, col);
311                 }
312                 if (material->builtins & GPU_AUTO_BUMPSCALE) {
313                         GPU_shader_uniform_vector(shader, material->obautobumpscaleloc, 1, 1, &autobumpscale);
314                 }
315                 /* update lamps */
316                 for (nlink=material->lamps.first; nlink; nlink=nlink->next) {
317                         lamp= nlink->data;
318
319                         if (material->dynproperty & DYN_LAMP_VEC) {
320                                 copy_v3_v3(lamp->dynvec, lamp->vec);
321                                 normalize_v3(lamp->dynvec);
322                                 negate_v3(lamp->dynvec);
323                                 mul_mat3_m4_v3(viewmat, lamp->dynvec);
324                         }
325
326                         if (material->dynproperty & DYN_LAMP_CO) {
327                                 copy_v3_v3(lamp->dynco, lamp->co);
328                                 mul_m4_v3(viewmat, lamp->dynco);
329                         }
330
331                         if (material->dynproperty & DYN_LAMP_IMAT) {
332                                 mult_m4_m4m4(lamp->dynimat, lamp->imat, viewinv);
333                         }
334
335                         if (material->dynproperty & DYN_LAMP_PERSMAT) {
336                                 if (!GPU_lamp_has_shadow_buffer(lamp)) /* The lamp matrices are already updated if we're using shadow buffers */
337                                         GPU_lamp_update_buffer_mats(lamp);
338                                 mult_m4_m4m4(lamp->dynpersmat, lamp->persmat, viewinv);
339                         }
340                 }
341
342                 GPU_pass_update_uniforms(material->pass);
343         }
344 }
345
346 void GPU_material_unbind(GPUMaterial *material)
347 {
348         if (material->pass) {
349                 material->bound = 0;
350                 GPU_pass_unbind(material->pass);
351         }
352 }
353
354 int GPU_material_bound(GPUMaterial *material)
355 {
356         return material->bound;
357 }
358
359 void GPU_material_vertex_attributes(GPUMaterial *material, GPUVertexAttribs *attribs)
360 {
361         *attribs = material->attribs;
362 }
363
364 void GPU_material_output_link(GPUMaterial *material, GPUNodeLink *link)
365 {
366         if (!material->outlink)
367                 material->outlink= link;
368 }
369
370 void GPU_material_enable_alpha(GPUMaterial *material)
371 {
372         material->alpha= 1;
373 }
374
375 GPUBlendMode GPU_material_alpha_blend(GPUMaterial *material, float obcol[4])
376 {
377         if (material->alpha || (material->obcolalpha && obcol[3] < 1.0f))
378                 return GPU_BLEND_ALPHA;
379         else
380                 return GPU_BLEND_SOLID;
381 }
382
383 void gpu_material_add_node(GPUMaterial *material, GPUNode *node)
384 {
385         BLI_addtail(&material->nodes, node);
386 }
387
388 /* Code generation */
389
390 static int gpu_do_color_management(GPUMaterial *mat)
391 {
392         return ((mat->scene->r.color_mgt_flag & R_COLOR_MANAGEMENT) &&
393            !((mat->scene->gm.flag & GAME_GLSL_NO_COLOR_MANAGEMENT)));
394 }
395
396 static GPUNodeLink *lamp_get_visibility(GPUMaterial *mat, GPULamp *lamp, GPUNodeLink **lv, GPUNodeLink **dist)
397 {
398         GPUNodeLink *visifac, *inpr;
399
400         /* from get_lamp_visibility */
401         if (lamp->type==LA_SUN || lamp->type==LA_HEMI) {
402                 mat->dynproperty |= DYN_LAMP_VEC;
403                 GPU_link(mat, "lamp_visibility_sun_hemi", GPU_dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob), lv, dist, &visifac);
404                 return visifac;
405         }
406         else {
407                 mat->dynproperty |= DYN_LAMP_CO;
408                 GPU_link(mat, "lamp_visibility_other", GPU_builtin(GPU_VIEW_POSITION), GPU_dynamic_uniform(lamp->dynco, GPU_DYNAMIC_LAMP_DYNCO, lamp->ob), lv, dist, &visifac);
409
410                 if (lamp->type==LA_AREA)
411                         return visifac;
412
413                 switch (lamp->falloff_type) {
414                         case LA_FALLOFF_CONSTANT:
415                                 break;
416                         case LA_FALLOFF_INVLINEAR:
417                                 GPU_link(mat, "lamp_falloff_invlinear", GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob), *dist, &visifac);
418                                 break;
419                         case LA_FALLOFF_INVSQUARE:
420                                 GPU_link(mat, "lamp_falloff_invsquare", GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob), *dist, &visifac);
421                                 break;
422                         case LA_FALLOFF_SLIDERS:
423                                 GPU_link(mat, "lamp_falloff_sliders", GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob), GPU_dynamic_uniform(&lamp->att1, GPU_DYNAMIC_LAMP_ATT1, lamp->ob), GPU_dynamic_uniform(&lamp->att2, GPU_DYNAMIC_LAMP_ATT2, lamp->ob), *dist, &visifac);
424                                 break;
425                         case LA_FALLOFF_CURVE:
426                                 {
427                                         float *array;
428                                         int size;
429
430                                         curvemapping_table_RGBA(lamp->curfalloff, &array, &size);
431                                         GPU_link(mat, "lamp_falloff_curve", GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob), GPU_texture(size, array), *dist, &visifac);
432                                 }
433                                 break;
434                 }
435
436                 if (lamp->mode & LA_SPHERE)
437                         GPU_link(mat, "lamp_visibility_sphere", GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob), *dist, visifac, &visifac);
438
439                 if (lamp->type == LA_SPOT) {
440                         if (lamp->mode & LA_SQUARE) {
441                                 mat->dynproperty |= DYN_LAMP_VEC|DYN_LAMP_IMAT;
442                                 GPU_link(mat, "lamp_visibility_spot_square", GPU_dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob), GPU_dynamic_uniform((float*)lamp->dynimat, GPU_DYNAMIC_LAMP_DYNIMAT, lamp->ob), *lv, &inpr);
443                         }
444                         else {
445                                 mat->dynproperty |= DYN_LAMP_VEC;
446                                 GPU_link(mat, "lamp_visibility_spot_circle", GPU_dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob), *lv, &inpr);
447                         }
448                         
449                         GPU_link(mat, "lamp_visibility_spot", GPU_dynamic_uniform(&lamp->spotsi, GPU_DYNAMIC_LAMP_SPOTSIZE, lamp->ob), GPU_dynamic_uniform(&lamp->spotbl, GPU_DYNAMIC_LAMP_SPOTSIZE, lamp->ob), inpr, visifac, &visifac);
450                 }
451
452                 GPU_link(mat, "lamp_visibility_clamp", visifac, &visifac);
453
454                 return visifac;
455         }
456 }
457
458 #if 0
459 static void area_lamp_vectors(LampRen *lar)
460 {
461         float xsize= 0.5*lar->area_size, ysize= 0.5*lar->area_sizey, multifac;
462
463         /* make it smaller, so area light can be multisampled */
464         multifac= 1.0f/sqrt((float)lar->ray_totsamp);
465         xsize *= multifac;
466         ysize *= multifac;
467
468         /* corner vectors */
469         lar->area[0][0]= lar->co[0] - xsize*lar->mat[0][0] - ysize*lar->mat[1][0];
470         lar->area[0][1]= lar->co[1] - xsize*lar->mat[0][1] - ysize*lar->mat[1][1];
471         lar->area[0][2]= lar->co[2] - xsize*lar->mat[0][2] - ysize*lar->mat[1][2];
472
473         /* corner vectors */
474         lar->area[1][0]= lar->co[0] - xsize*lar->mat[0][0] + ysize*lar->mat[1][0];
475         lar->area[1][1]= lar->co[1] - xsize*lar->mat[0][1] + ysize*lar->mat[1][1];
476         lar->area[1][2]= lar->co[2] - xsize*lar->mat[0][2] + ysize*lar->mat[1][2];
477
478         /* corner vectors */
479         lar->area[2][0]= lar->co[0] + xsize*lar->mat[0][0] + ysize*lar->mat[1][0];
480         lar->area[2][1]= lar->co[1] + xsize*lar->mat[0][1] + ysize*lar->mat[1][1];
481         lar->area[2][2]= lar->co[2] + xsize*lar->mat[0][2] + ysize*lar->mat[1][2];
482
483         /* corner vectors */
484         lar->area[3][0]= lar->co[0] + xsize*lar->mat[0][0] - ysize*lar->mat[1][0];
485         lar->area[3][1]= lar->co[1] + xsize*lar->mat[0][1] - ysize*lar->mat[1][1];
486         lar->area[3][2]= lar->co[2] + xsize*lar->mat[0][2] - ysize*lar->mat[1][2];
487         /* only for correction button size, matrix size works on energy */
488         lar->areasize= lar->dist*lar->dist/(4.0*xsize*ysize);
489 }
490 #endif
491
492 static void ramp_blend(GPUMaterial *mat, GPUNodeLink *fac, GPUNodeLink *col1, GPUNodeLink *col2, int type, GPUNodeLink **outcol)
493 {
494         static const char *names[] = {"mix_blend", "mix_add", "mix_mult", "mix_sub",
495                 "mix_screen", "mix_div", "mix_diff", "mix_dark", "mix_light",
496                 "mix_overlay", "mix_dodge", "mix_burn", "mix_hue", "mix_sat",
497                 "mix_val", "mix_color", "mix_soft", "mix_linear"};
498
499         GPU_link(mat, names[type], fac, col1, col2, outcol);
500 }
501
502 static void do_colorband_blend(GPUMaterial *mat, ColorBand *coba, GPUNodeLink *fac, float rampfac, int type, GPUNodeLink *incol, GPUNodeLink **outcol)
503 {
504         GPUNodeLink *tmp, *alpha, *col;
505         float *array;
506         int size;
507
508         /* do colorband */
509         colorband_table_RGBA(coba, &array, &size);
510         GPU_link(mat, "valtorgb", fac, GPU_texture(size, array), &col, &tmp);
511
512         /* use alpha in fac */
513         GPU_link(mat, "mtex_alpha_from_col", col, &alpha);
514         GPU_link(mat, "math_multiply", alpha, GPU_uniform(&rampfac), &fac);
515
516         /* blending method */
517         ramp_blend(mat, fac, incol, col, type, outcol);
518 }
519
520 static void ramp_diffuse_result(GPUShadeInput *shi, GPUNodeLink **diff)
521 {
522         Material *ma= shi->mat;
523         GPUMaterial *mat= shi->gpumat;
524         GPUNodeLink *fac;
525
526         if (!(mat->scene->gm.flag & GAME_GLSL_NO_RAMPS)) {
527                 if (ma->ramp_col) {
528                         if (ma->rampin_col==MA_RAMP_IN_RESULT) {
529                                 GPU_link(mat, "ramp_rgbtobw", *diff, &fac);
530                                 
531                                 /* colorband + blend */
532                                 do_colorband_blend(mat, ma->ramp_col, fac, ma->rampfac_col, ma->rampblend_col, *diff, diff);
533                         }
534                 }
535         }
536 }
537
538 static void add_to_diffuse(GPUMaterial *mat, Material *ma, GPUShadeInput *shi, GPUNodeLink *is, GPUNodeLink *rgb, GPUNodeLink **diff)
539 {
540         GPUNodeLink *fac, *tmp, *addcol;
541         
542         if (!(mat->scene->gm.flag & GAME_GLSL_NO_RAMPS) &&
543             ma->ramp_col && (ma->mode & MA_RAMP_COL))
544         {
545                 /* MA_RAMP_IN_RESULT is exceptional */
546                 if (ma->rampin_col==MA_RAMP_IN_RESULT) {
547                         addcol = shi->rgb;
548                 }
549                 else {
550                         /* input */
551                         switch (ma->rampin_col) {
552                         case MA_RAMP_IN_ENERGY:
553                                 GPU_link(mat, "ramp_rgbtobw", rgb, &fac);
554                                 break;
555                         case MA_RAMP_IN_SHADER:
556                                 fac= is;
557                                 break;
558                         case MA_RAMP_IN_NOR:
559                                 GPU_link(mat, "vec_math_dot", shi->view, shi->vn, &tmp, &fac);
560                                 break;
561                         default:
562                                 GPU_link(mat, "set_value_zero", &fac);
563                                 break;
564                         }
565
566                         /* colorband + blend */
567                         do_colorband_blend(mat, ma->ramp_col, fac, ma->rampfac_col, ma->rampblend_col, shi->rgb, &addcol);
568                 }
569         }
570         else
571                 addcol = shi->rgb;
572
573         /* output to */
574         GPU_link(mat, "shade_madd_clamped", *diff, rgb, addcol, diff);
575 }
576
577 static void ramp_spec_result(GPUShadeInput *shi, GPUNodeLink **spec)
578 {
579         Material *ma= shi->mat;
580         GPUMaterial *mat= shi->gpumat;
581         GPUNodeLink *fac;
582
583         if (!(mat->scene->gm.flag & GAME_GLSL_NO_RAMPS) &&
584             ma->ramp_spec && ma->rampin_spec==MA_RAMP_IN_RESULT)
585         {
586                 GPU_link(mat, "ramp_rgbtobw", *spec, &fac);
587                 
588                 /* colorband + blend */
589                 do_colorband_blend(mat, ma->ramp_spec, fac, ma->rampfac_spec, ma->rampblend_spec, *spec, spec);
590         }
591 }
592
593 static void do_specular_ramp(GPUShadeInput *shi, GPUNodeLink *is, GPUNodeLink *t, GPUNodeLink **spec)
594 {
595         Material *ma= shi->mat;
596         GPUMaterial *mat= shi->gpumat;
597         GPUNodeLink *fac, *tmp;
598
599         *spec = shi->specrgb;
600
601         /* MA_RAMP_IN_RESULT is exception */
602         if (ma->ramp_spec && (ma->rampin_spec!=MA_RAMP_IN_RESULT)) {
603                 
604                 /* input */
605                 switch (ma->rampin_spec) {
606                 case MA_RAMP_IN_ENERGY:
607                         fac = t;
608                         break;
609                 case MA_RAMP_IN_SHADER:
610                         fac = is;
611                         break;
612                 case MA_RAMP_IN_NOR:
613                         GPU_link(mat, "vec_math_dot", shi->view, shi->vn, &tmp, &fac);
614                         break;
615                 default:
616                         GPU_link(mat, "set_value_zero", &fac);
617                         break;
618                 }
619                 
620                 /* colorband + blend */
621                 do_colorband_blend(mat, ma->ramp_spec, fac, ma->rampfac_spec, ma->rampblend_spec, *spec, spec);
622         }
623 }
624
625 static void add_user_list(ListBase *list, void *data)
626 {
627         LinkData *link = MEM_callocN(sizeof(LinkData), "GPULinkData");
628         link->data = data;
629         BLI_addtail(list, link);
630 }
631
632 static void shade_light_textures(GPUMaterial *mat, GPULamp *lamp, GPUNodeLink **rgb)
633 {
634         GPUNodeLink *tex_rgb;
635         MTex *mtex = NULL;
636         int i;
637         float one = 1.f;
638
639         for (i=0; i<MAX_MTEX; ++i) {
640                 mtex = lamp->la->mtex[i];
641
642                 if (mtex && mtex->tex->type & TEX_IMAGE && mtex->tex->ima) {
643                         mat->dynproperty |= DYN_LAMP_PERSMAT;
644
645                         GPU_link(mat, "shade_light_texture",
646                                 GPU_builtin(GPU_VIEW_POSITION),
647                                 GPU_image(mtex->tex->ima, &mtex->tex->iuser),
648                                 GPU_dynamic_uniform((float*)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob),
649                                 &tex_rgb);
650                         texture_rgb_blend(mat, tex_rgb, *rgb, GPU_uniform(&one), GPU_uniform(&mtex->colfac), mtex->blendtype, rgb); 
651                 }
652         }
653 }
654
655 static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *lamp)
656 {
657         Material *ma= shi->mat;
658         GPUMaterial *mat= shi->gpumat;
659         GPUNodeLink *lv, *dist, *visifac, *is, *inp, *i, *vn, *view;
660         GPUNodeLink *outcol, *specfac, *t, *shadfac= NULL, *lcol;
661         float one = 1.0f;
662
663         if ((lamp->mode & LA_ONLYSHADOW) && !(ma->mode & MA_SHADOW))
664                 return;
665         
666         vn= shi->vn;
667         view= shi->view;
668
669         visifac= lamp_get_visibility(mat, lamp, &lv, &dist);
670
671         /*if (ma->mode & MA_TANGENT_V)
672                 GPU_link(mat, "shade_tangent_v", lv, GPU_attribute(CD_TANGENT, ""), &vn);*/
673         
674         GPU_link(mat, "shade_inp", vn, lv, &inp);
675
676         if (lamp->mode & LA_NO_DIFF) {
677                 GPU_link(mat, "shade_is_no_diffuse", &is);
678         }
679         else if (lamp->type == LA_HEMI) {
680                 GPU_link(mat, "shade_is_hemi", inp, &is);
681         }
682         else {
683                 if (lamp->type == LA_AREA) {
684                         float area[4][4]= {{0.0f}}, areasize= 0.0f;
685
686                         mat->dynproperty |= DYN_LAMP_VEC|DYN_LAMP_CO;
687                         GPU_link(mat, "shade_inp_area", GPU_builtin(GPU_VIEW_POSITION), GPU_dynamic_uniform(lamp->dynco, GPU_DYNAMIC_LAMP_DYNCO, lamp->ob), GPU_dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob), vn, GPU_uniform((float*)area),
688                                 GPU_uniform(&areasize), GPU_uniform(&lamp->k), &inp);
689                 }
690
691                 is= inp; /* Lambert */
692
693                 if (!(mat->scene->gm.flag & GAME_GLSL_NO_SHADERS)) {
694                         if (ma->diff_shader==MA_DIFF_ORENNAYAR)
695                                 GPU_link(mat, "shade_diffuse_oren_nayer", inp, vn, lv, view, GPU_uniform(&ma->roughness), &is);
696                         else if (ma->diff_shader==MA_DIFF_TOON)
697                                 GPU_link(mat, "shade_diffuse_toon", vn, lv, view, GPU_uniform(&ma->param[0]), GPU_uniform(&ma->param[1]), &is);
698                         else if (ma->diff_shader==MA_DIFF_MINNAERT)
699                                 GPU_link(mat, "shade_diffuse_minnaert", inp, vn, view, GPU_uniform(&ma->darkness), &is);
700                         else if (ma->diff_shader==MA_DIFF_FRESNEL)
701                                 GPU_link(mat, "shade_diffuse_fresnel", vn, lv, view, GPU_uniform(&ma->param[0]), GPU_uniform(&ma->param[1]), &is);
702                 }
703         }
704
705         if (!(mat->scene->gm.flag & GAME_GLSL_NO_SHADERS))
706                 if (ma->shade_flag & MA_CUBIC)
707                         GPU_link(mat, "shade_cubic", is, &is);
708         
709         i = is;
710         GPU_link(mat, "shade_visifac", i, visifac, shi->refl, &i);
711         
712         GPU_link(mat, "set_value", GPU_dynamic_uniform(lamp->dyncol, GPU_DYNAMIC_LAMP_DYNCOL, lamp->ob), &lcol);
713         shade_light_textures(mat, lamp, &lcol);
714
715 #if 0
716         if (ma->mode & MA_TANGENT_VN)
717                 GPU_link(mat, "shade_tangent_v_spec", GPU_attribute(CD_TANGENT, ""), &vn);
718 #endif
719
720         /* this replaces if (i > 0.0) conditional until that is supported */
721         // done in shade_visifac now, GPU_link(mat, "mtex_value_clamp_positive", i, &i);
722
723         if ((ma->mode & MA_SHADOW) && GPU_lamp_has_shadow_buffer(lamp)) {
724                 if (!(mat->scene->gm.flag & GAME_GLSL_NO_SHADOWS)) {
725                         mat->dynproperty |= DYN_LAMP_PERSMAT;
726                         
727                         if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) {
728                                 GPU_link(mat, "test_shadowbuf_vsm",
729                                         GPU_builtin(GPU_VIEW_POSITION),
730                                         GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob),
731                                         GPU_dynamic_uniform((float*)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob),
732                                         GPU_uniform(&lamp->bias), GPU_uniform(&lamp->la->bleedbias), inp, &shadfac);
733                         }
734                         else {
735                                 GPU_link(mat, "test_shadowbuf",
736                                         GPU_builtin(GPU_VIEW_POSITION),
737                                         GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob),
738                                         GPU_dynamic_uniform((float*)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob),
739                                         GPU_uniform(&lamp->bias), inp, &shadfac);
740                         }
741                         
742                         if (lamp->mode & LA_ONLYSHADOW) {
743                                 GPU_link(mat, "shade_only_shadow", i, shadfac,
744                                         GPU_dynamic_uniform(&lamp->dynenergy, GPU_DYNAMIC_LAMP_DYNENERGY, lamp->ob), &shadfac);
745                                 
746                                 if (!(lamp->mode & LA_NO_DIFF)) {
747                                         GPU_link(mat, "mix_mult", shadfac, shr->diff,
748                                                 GPU_uniform(lamp->shadow_color), &shr->diff);
749                                 }
750
751                                 if (!(lamp->mode & LA_NO_SPEC))
752                                         GPU_link(mat, "shade_only_shadow_specular", shadfac, shi->specrgb,
753                                                 shr->spec, &shr->spec);
754                                 
755                                 add_user_list(&mat->lamps, lamp);
756                                 add_user_list(&lamp->materials, shi->gpumat->ma);
757                                 return;
758                         }
759                 }
760         }
761         else if ((mat->scene->gm.flag & GAME_GLSL_NO_SHADOWS) && (lamp->mode & LA_ONLYSHADOW)) {
762                 add_user_list(&mat->lamps, lamp);
763                 add_user_list(&lamp->materials, shi->gpumat->ma);
764                 return;
765         }
766         else
767                 GPU_link(mat, "set_value", GPU_uniform(&one), &shadfac);
768
769         if (GPU_link_changed(shi->refl) || ma->ref != 0.0f) {
770                 if (!(lamp->mode & LA_NO_DIFF)) {
771                         GPUNodeLink *rgb;
772                         GPU_link(mat, "shade_mul_value", i, lcol, &rgb);
773                         GPU_link(mat, "mtex_value_invert", shadfac, &shadfac);
774                         GPU_link(mat, "mix_mult",  shadfac, rgb, GPU_uniform(lamp->shadow_color), &rgb);
775                         GPU_link(mat, "mtex_value_invert", shadfac, &shadfac);
776                         add_to_diffuse(mat, ma, shi, is, rgb, &shr->diff);
777                 }
778         }
779
780         if (mat->scene->gm.flag & GAME_GLSL_NO_SHADERS);
781         else if (!(lamp->mode & LA_NO_SPEC) && !(lamp->mode & LA_ONLYSHADOW) &&
782                  (GPU_link_changed(shi->spec) || ma->spec != 0.0f))
783         {
784                 if (lamp->type == LA_HEMI) {
785                         GPU_link(mat, "shade_hemi_spec", vn, lv, view, GPU_uniform(&ma->spec), shi->har, visifac, &t);
786                         GPU_link(mat, "shade_add_spec", t, lcol, shi->specrgb, &outcol);
787                         GPU_link(mat, "shade_add_clamped", shr->spec, outcol, &shr->spec);
788                 }
789                 else {
790                         if (ma->spec_shader==MA_SPEC_PHONG)
791                                 GPU_link(mat, "shade_phong_spec", vn, lv, view, shi->har, &specfac);
792                         else if (ma->spec_shader==MA_SPEC_COOKTORR)
793                                 GPU_link(mat, "shade_cooktorr_spec", vn, lv, view, shi->har, &specfac);
794                         else if (ma->spec_shader==MA_SPEC_BLINN)
795                                 GPU_link(mat, "shade_blinn_spec", vn, lv, view, GPU_uniform(&ma->refrac), shi->har, &specfac);
796                         else if (ma->spec_shader==MA_SPEC_WARDISO)
797                                 GPU_link(mat, "shade_wardiso_spec", vn, lv, view, GPU_uniform(&ma->rms), &specfac);
798                         else
799                                 GPU_link(mat, "shade_toon_spec", vn, lv, view, GPU_uniform(&ma->param[2]), GPU_uniform(&ma->param[3]), &specfac);
800
801                         if (lamp->type==LA_AREA)
802                                 GPU_link(mat, "shade_spec_area_inp", specfac, inp, &specfac);
803
804                         GPU_link(mat, "shade_spec_t", shadfac, shi->spec, visifac, specfac, &t); 
805
806                         if (ma->mode & MA_RAMP_SPEC) {
807                                 GPUNodeLink *spec;
808                                 do_specular_ramp(shi, specfac, t, &spec);
809                                 GPU_link(mat, "shade_add_spec", t, lcol, spec, &outcol);
810                                 GPU_link(mat, "shade_add_clamped", shr->spec, outcol, &shr->spec);
811                         }
812                         else {
813                                 GPU_link(mat, "shade_add_spec", t, lcol, shi->specrgb, &outcol);
814                                 GPU_link(mat, "shade_add_clamped", shr->spec, outcol, &shr->spec);
815                         }
816                 }
817         }
818
819         add_user_list(&mat->lamps, lamp);
820         add_user_list(&lamp->materials, shi->gpumat->ma);
821 }
822
823 static void material_lights(GPUShadeInput *shi, GPUShadeResult *shr)
824 {
825         Base *base;
826         Object *ob;
827         Scene *sce_iter;
828         GPULamp *lamp;
829         
830         for (SETLOOPER(shi->gpumat->scene, sce_iter, base)) {
831                 ob= base->object;
832
833                 if (ob->type==OB_LAMP) {
834                         lamp = GPU_lamp_from_blender(shi->gpumat->scene, ob, NULL);
835                         if (lamp)
836                                 shade_one_light(shi, shr, lamp);
837                 }
838
839                 if (ob->transflag & OB_DUPLI) {
840                         DupliObject *dob;
841                         ListBase *lb = object_duplilist(shi->gpumat->scene, ob);
842                         
843                         for (dob=lb->first; dob; dob=dob->next) {
844                                 Object *ob_iter = dob->ob;
845
846                                 if (ob_iter->type==OB_LAMP) {
847                                         copy_m4_m4(ob_iter->obmat, dob->mat);
848
849                                         lamp = GPU_lamp_from_blender(shi->gpumat->scene, ob_iter, ob);
850                                         if (lamp)
851                                                 shade_one_light(shi, shr, lamp);
852                                 }
853                         }
854                         
855                         free_object_duplilist(lb);
856                 }
857         }
858 }
859
860 static void texture_rgb_blend(GPUMaterial *mat, GPUNodeLink *tex, GPUNodeLink *out, GPUNodeLink *fact, GPUNodeLink *facg, int blendtype, GPUNodeLink **in)
861 {
862         switch (blendtype) {
863         case MTEX_BLEND:
864                 GPU_link(mat, "mtex_rgb_blend", out, tex, fact, facg, in);
865                 break;
866         case MTEX_MUL:
867                 GPU_link(mat, "mtex_rgb_mul", out, tex, fact, facg, in);
868                 break;
869         case MTEX_SCREEN:
870                 GPU_link(mat, "mtex_rgb_screen", out, tex, fact, facg, in);
871                 break;
872         case MTEX_OVERLAY:
873                 GPU_link(mat, "mtex_rgb_overlay", out, tex, fact, facg, in);
874                 break;
875         case MTEX_SUB:
876                 GPU_link(mat, "mtex_rgb_sub", out, tex, fact, facg, in);
877                 break;
878         case MTEX_ADD:
879                 GPU_link(mat, "mtex_rgb_add", out, tex, fact, facg, in);
880                 break;
881         case MTEX_DIV:
882                 GPU_link(mat, "mtex_rgb_div", out, tex, fact, facg, in);
883                 break;
884         case MTEX_DIFF:
885                 GPU_link(mat, "mtex_rgb_diff", out, tex, fact, facg, in);
886                 break;
887         case MTEX_DARK:
888                 GPU_link(mat, "mtex_rgb_dark", out, tex, fact, facg, in);
889                 break;
890         case MTEX_LIGHT:
891                 GPU_link(mat, "mtex_rgb_light", out, tex, fact, facg, in);
892                 break;
893         case MTEX_BLEND_HUE:
894                 GPU_link(mat, "mtex_rgb_hue", out, tex, fact, facg, in);
895                 break;
896         case MTEX_BLEND_SAT:
897                 GPU_link(mat, "mtex_rgb_sat", out, tex, fact, facg, in);
898                 break;
899         case MTEX_BLEND_VAL:
900                 GPU_link(mat, "mtex_rgb_val", out, tex, fact, facg, in);
901                 break;
902         case MTEX_BLEND_COLOR:
903                 GPU_link(mat, "mtex_rgb_color", out, tex, fact, facg, in);
904                 break;
905         default:
906                 GPU_link(mat, "set_rgb_zero", &in);
907                 break;
908         }
909 }
910
911 static void texture_value_blend(GPUMaterial *mat, GPUNodeLink *tex, GPUNodeLink *out, GPUNodeLink *fact, GPUNodeLink *facg, int blendtype, GPUNodeLink **in)
912 {
913         switch (blendtype) {
914         case MTEX_BLEND:
915                 GPU_link(mat, "mtex_value_blend", out, tex, fact, facg, in);
916                 break;
917         case MTEX_MUL:
918                 GPU_link(mat, "mtex_value_mul", out, tex, fact, facg, in);
919                 break;
920         case MTEX_SCREEN:
921                 GPU_link(mat, "mtex_value_screen", out, tex, fact, facg, in);
922                 break;
923         case MTEX_SUB:
924                 GPU_link(mat, "mtex_value_sub", out, tex, fact, facg, in);
925                 break;
926         case MTEX_ADD:
927                 GPU_link(mat, "mtex_value_add", out, tex, fact, facg, in);
928                 break;
929         case MTEX_DIV:
930                 GPU_link(mat, "mtex_value_div", out, tex, fact, facg, in);
931                 break;
932         case MTEX_DIFF:
933                 GPU_link(mat, "mtex_value_diff", out, tex, fact, facg, in);
934                 break;
935         case MTEX_DARK:
936                 GPU_link(mat, "mtex_value_dark", out, tex, fact, facg, in);
937                 break;
938         case MTEX_LIGHT:
939                 GPU_link(mat, "mtex_value_light", out, tex, fact, facg, in);
940                 break;
941         default:
942                 GPU_link(mat, "set_value_zero", &in);
943                 break;
944         }
945 }
946
947 static void do_material_tex(GPUShadeInput *shi)
948 {
949         Material *ma= shi->mat;
950         GPUMaterial *mat= shi->gpumat;
951         MTex *mtex;
952         Tex *tex;
953         GPUNodeLink *texco, *tin, *trgb, *tnor, *tcol, *stencil, *tnorfac;
954         GPUNodeLink *texco_norm, *texco_orco, *texco_object;
955         GPUNodeLink *texco_global, *texco_uv = NULL;
956         GPUNodeLink *newnor, *orn;
957         /*char *lastuvname = NULL;*/ /*UNUSED*/
958         float one = 1.0f, norfac, ofs[3];
959         int tex_nr, rgbnor, talpha;
960         int init_done = FALSE, iBumpSpacePrev = 0; /* Not necessary, quiting gcc warning. */
961         GPUNodeLink *vNorg, *vNacc, *fPrevMagnitude;
962         int iFirstTimeNMap=1;
963         int found_deriv_map = 0;
964
965         GPU_link(mat, "set_value", GPU_uniform(&one), &stencil);
966
967         GPU_link(mat, "texco_norm", GPU_builtin(GPU_VIEW_NORMAL), &texco_norm);
968         GPU_link(mat, "texco_orco", GPU_attribute(CD_ORCO, ""), &texco_orco);
969         GPU_link(mat, "texco_object", GPU_builtin(GPU_INVERSE_VIEW_MATRIX),
970                 GPU_builtin(GPU_INVERSE_OBJECT_MATRIX),
971                 GPU_builtin(GPU_VIEW_POSITION), &texco_object);
972         //GPU_link(mat, "texco_tangent", GPU_attribute(CD_TANGENT, ""), &texco_tangent);
973         GPU_link(mat, "texco_global", GPU_builtin(GPU_INVERSE_VIEW_MATRIX),
974                 GPU_builtin(GPU_VIEW_POSITION), &texco_global);
975
976         orn= texco_norm;
977
978         /* go over texture slots */
979         for (tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) {
980                 /* separate tex switching */
981                 if (ma->septex & (1<<tex_nr)) continue;
982                 
983                 if (ma->mtex[tex_nr]) {
984                         mtex= ma->mtex[tex_nr];
985                         
986                         tex= mtex->tex;
987                         if (tex == NULL) continue;
988
989                         /* which coords */
990                         if (mtex->texco==TEXCO_ORCO)
991                                 texco= texco_orco;
992                         else if (mtex->texco==TEXCO_OBJECT)
993                                 texco= texco_object;
994                         else if (mtex->texco==TEXCO_NORM)
995                                 texco= orn;
996                         else if (mtex->texco==TEXCO_TANGENT)
997                                 texco= texco_object;
998                         else if (mtex->texco==TEXCO_GLOB)
999                                 texco= texco_global;
1000                         else if (mtex->texco==TEXCO_REFL) {
1001                                 GPU_link(mat, "texco_refl", shi->vn, shi->view, &shi->ref);
1002                                 texco= shi->ref;
1003                         }
1004                         else if (mtex->texco==TEXCO_UV) {
1005                                 if (1) { //!(texco_uv && strcmp(mtex->uvname, lastuvname) == 0)) {
1006                                         GPU_link(mat, "texco_uv", GPU_attribute(CD_MTFACE, mtex->uvname), &texco_uv);
1007                                         /*lastuvname = mtex->uvname;*/ /*UNUSED*/
1008                                 }
1009                                 texco= texco_uv;
1010                         }
1011                         else
1012                                 continue;
1013
1014                         /* in case of uv, this would just undo a multiplication in texco_uv */
1015                         if (mtex->texco != TEXCO_UV)
1016                                 GPU_link(mat, "mtex_2d_mapping", texco, &texco);
1017
1018                         if (mtex->size[0] != 1.0f || mtex->size[1] != 1.0f || mtex->size[2] != 1.0f)
1019                                 GPU_link(mat, "mtex_mapping_size", texco, GPU_uniform(mtex->size), &texco);
1020
1021                         ofs[0] = mtex->ofs[0] + 0.5f - 0.5f*mtex->size[0];
1022                         ofs[1] = mtex->ofs[1] + 0.5f - 0.5f*mtex->size[1];
1023                         ofs[2] = 0.0f;
1024                         if (ofs[0] != 0.0f || ofs[1] != 0.0f || ofs[2] != 0.0f)
1025                                 GPU_link(mat, "mtex_mapping_ofs", texco, GPU_uniform(ofs), &texco);
1026
1027                         talpha = 0;
1028
1029                         if (tex && tex->type == TEX_IMAGE && tex->ima) {
1030                                 GPU_link(mat, "mtex_image", texco, GPU_image(tex->ima, &tex->iuser), &tin, &trgb);
1031                                 rgbnor= TEX_RGB;
1032
1033                                 if (tex->imaflag & TEX_USEALPHA)
1034                                         talpha= 1;
1035                         }
1036                         else {
1037                                 continue;
1038                         }
1039
1040                         /* texture output */
1041                         if ((rgbnor & TEX_RGB) && (mtex->texflag & MTEX_RGBTOINT)) {
1042                                 GPU_link(mat, "mtex_rgbtoint", trgb, &tin);
1043                                 rgbnor -= TEX_RGB;
1044                         }
1045
1046                         if (mtex->texflag & MTEX_NEGATIVE) {
1047                                 if (rgbnor & TEX_RGB)
1048                                         GPU_link(mat, "mtex_rgb_invert", trgb, &trgb);
1049                                 else
1050                                         GPU_link(mat, "mtex_value_invert", tin, &tin);
1051                         }
1052
1053                         if (mtex->texflag & MTEX_STENCIL) {
1054                                 if (rgbnor & TEX_RGB)
1055                                         GPU_link(mat, "mtex_rgb_stencil", stencil, trgb, &stencil, &trgb);
1056                                 else
1057                                         GPU_link(mat, "mtex_value_stencil", stencil, tin, &stencil, &tin);
1058                         }
1059
1060                         /* mapping */
1061                         if (mtex->mapto & (MAP_COL+MAP_COLSPEC)) {
1062                                 /* stencil maps on the texture control slider, not texture intensity value */
1063                                 if ((rgbnor & TEX_RGB)==0) {
1064                                         GPU_link(mat, "set_rgb", GPU_uniform(&mtex->r), &tcol);
1065                                 }
1066                                 else {
1067                                         GPU_link(mat, "set_rgba", trgb, &tcol);
1068
1069                                         if (mtex->mapto & MAP_ALPHA)
1070                                                 GPU_link(mat, "set_value", stencil, &tin);
1071                                         else if (talpha)
1072                                                 GPU_link(mat, "mtex_alpha_from_col", trgb, &tin);
1073                                         else
1074                                                 GPU_link(mat, "set_value_one", &tin);
1075                                 }
1076
1077                                 if (tex->type==TEX_IMAGE)
1078                                         if (gpu_do_color_management(mat))
1079                                                 GPU_link(mat, "srgb_to_linearrgb", tcol, &tcol);
1080                                 
1081                                 if (mtex->mapto & MAP_COL) {
1082                                         GPUNodeLink *colfac;
1083
1084                                         if (mtex->colfac == 1.0f) colfac = stencil;
1085                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->colfac), stencil, &colfac);
1086
1087                                         texture_rgb_blend(mat, tcol, shi->rgb, tin, colfac, mtex->blendtype, &shi->rgb);
1088                                 }
1089                                 
1090                                 if (!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && (mtex->mapto & MAP_COLSPEC)) {
1091                                         GPUNodeLink *colspecfac;
1092
1093                                         if (mtex->colspecfac == 1.0f) colspecfac = stencil;
1094                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->colspecfac), stencil, &colspecfac);
1095
1096                                         texture_rgb_blend(mat, tcol, shi->specrgb, tin, colspecfac, mtex->blendtype, &shi->specrgb);
1097                                 }
1098                         }
1099
1100                         if (!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && (mtex->mapto & MAP_NORM)) {
1101                                 if (tex->type==TEX_IMAGE) {
1102                                         found_deriv_map = tex->imaflag & TEX_DERIVATIVEMAP;
1103
1104                                         if (tex->imaflag & TEX_NORMALMAP) {
1105                                                 /* normalmap image */
1106                                                 GPU_link(mat, "mtex_normal", texco, GPU_image(tex->ima, &tex->iuser), &tnor);
1107                                                 
1108                                                 if (mtex->norfac < 0.0f)
1109                                                         GPU_link(mat, "mtex_negate_texnormal", tnor, &tnor);
1110
1111                                                 if (mtex->normapspace == MTEX_NSPACE_TANGENT) {
1112                                                         if (iFirstTimeNMap != 0) {
1113                                                                 // use unnormalized normal (this is how we bake it - closer to gamedev)
1114                                                                 GPUNodeLink *vNegNorm;
1115                                                                 GPU_link(mat, "vec_math_negate", GPU_builtin(GPU_VIEW_NORMAL), &vNegNorm);
1116                                                                 GPU_link(mat, "mtex_nspace_tangent", GPU_attribute(CD_TANGENT, ""), vNegNorm, tnor, &newnor);
1117                                                                 iFirstTimeNMap = 0;
1118                                                         }
1119                                                         else { /* otherwise use accumulated perturbations */
1120                                                                 GPU_link(mat, "mtex_nspace_tangent", GPU_attribute(CD_TANGENT, ""), shi->vn, tnor, &newnor);
1121                                                         }
1122                                                 }
1123                                                 else {
1124                                                         newnor = tnor;
1125                                                 }
1126                                                 
1127                                                 norfac = minf(fabsf(mtex->norfac), 1.0f);
1128                                                 
1129                                                 if (norfac == 1.0f && !GPU_link_changed(stencil)) {
1130                                                         shi->vn = newnor;
1131                                                 }
1132                                                 else {
1133                                                         tnorfac = GPU_uniform(&norfac);
1134         
1135                                                         if (GPU_link_changed(stencil))
1136                                                                 GPU_link(mat, "math_multiply", tnorfac, stencil, &tnorfac);
1137         
1138                                                         GPU_link(mat, "mtex_blend_normal", tnorfac, shi->vn, newnor, &shi->vn);
1139                                                 }
1140                                                 
1141                                         }
1142                                         else if ( (mtex->texflag & (MTEX_3TAP_BUMP|MTEX_5TAP_BUMP|MTEX_BICUBIC_BUMP)) || found_deriv_map) {
1143                                                 /* ntap bumpmap image */
1144                                                 int iBumpSpace;
1145                                                 float ima_x, ima_y;
1146                                                 float hScale; 
1147
1148                                                 float imag_tspace_dimension_x = 1024.0f;                // only used for texture space variant
1149                                                 float aspect = 1.0f;
1150                                                 
1151                                                 GPUNodeLink *surf_pos = GPU_builtin(GPU_VIEW_POSITION);
1152                                                 GPUNodeLink *vR1, *vR2;
1153                                                 GPUNodeLink *dBs, *dBt, *fDet;
1154
1155                                                 hScale = 0.1;           // compatibility adjustment factor for all bumpspace types
1156                                                 if ( mtex->texflag & MTEX_BUMP_TEXTURESPACE )
1157                                                         hScale = 13.0f;         // factor for scaling texspace bumps
1158                                                 else if (found_deriv_map!=0)
1159                                                         hScale = 1.0f;
1160
1161                                                 // resolve texture resolution
1162                                                 if ( (mtex->texflag & MTEX_BUMP_TEXTURESPACE) || found_deriv_map ) {
1163                                                         ImBuf *ibuf= BKE_image_get_ibuf(tex->ima, &tex->iuser);
1164                                                         ima_x= 512.0f; ima_y= 512.f;            // prevent calling textureSize, glsl 1.3 only
1165                                                         if (ibuf) {
1166                                                                 ima_x= ibuf->x;
1167                                                                 ima_y= ibuf->y;
1168                                                                 aspect = ((float) ima_y) / ima_x;
1169                                                         }
1170                                                 }
1171
1172                                                 // The negate on norfac is done because the
1173                                                 // normal in the renderer points inward which corresponds
1174                                                 // to inverting the bump map. Should this ever change
1175                                                 // this negate must be removed.
1176                                                 norfac = -hScale * mtex->norfac;
1177                                                 if (found_deriv_map) {
1178                                                         float fVirtDim = sqrtf(fabsf(ima_x*mtex->size[0]*ima_y*mtex->size[1]));
1179                                                         norfac /= MAX2(fVirtDim, FLT_EPSILON);
1180                                                 }
1181
1182                                                 tnorfac = GPU_uniform(&norfac);
1183
1184                                                 if (found_deriv_map)
1185                                                         GPU_link(mat, "math_multiply", tnorfac, GPU_builtin(GPU_AUTO_BUMPSCALE), &tnorfac);
1186                                                 
1187                                                 if (GPU_link_changed(stencil))
1188                                                         GPU_link(mat, "math_multiply", tnorfac, stencil, &tnorfac);
1189                                                 
1190                                                 if ( !init_done ) {
1191                                                         // copy shi->vn to vNorg and vNacc, set magnitude to 1
1192                                                         GPU_link(mat, "mtex_bump_normals_init", shi->vn, &vNorg, &vNacc, &fPrevMagnitude);
1193                                                         iBumpSpacePrev = 0;
1194                                                         init_done = TRUE;
1195                                                 }
1196                                                 
1197                                                 // find current bump space
1198                                                 if ( mtex->texflag & MTEX_BUMP_OBJECTSPACE )
1199                                                         iBumpSpace = 1;
1200                                                 else if ( mtex->texflag & MTEX_BUMP_TEXTURESPACE )
1201                                                         iBumpSpace = 2;
1202                                                 else
1203                                                         iBumpSpace = 4; // ViewSpace
1204                                                 
1205                                                 // re-initialize if bump space changed
1206                                                 if ( iBumpSpacePrev != iBumpSpace ) {
1207                                                         
1208                                                         if ( mtex->texflag & MTEX_BUMP_OBJECTSPACE )
1209                                                                 GPU_link(mat, "mtex_bump_init_objspace",
1210                                                                          surf_pos, vNorg,
1211                                                                          GPU_builtin(GPU_VIEW_MATRIX), GPU_builtin(GPU_INVERSE_VIEW_MATRIX), GPU_builtin(GPU_OBJECT_MATRIX),  GPU_builtin(GPU_INVERSE_OBJECT_MATRIX),
1212                                                                          fPrevMagnitude, vNacc,
1213                                                                          &fPrevMagnitude, &vNacc,
1214                                                                          &vR1, &vR2, &fDet);
1215                                                                 
1216                                                         else if ( mtex->texflag & MTEX_BUMP_TEXTURESPACE )
1217                                                                 GPU_link(mat, "mtex_bump_init_texturespace",
1218                                                                          surf_pos, vNorg,
1219                                                                          fPrevMagnitude, vNacc,
1220                                                                          &fPrevMagnitude, &vNacc,
1221                                                                          &vR1, &vR2, &fDet);
1222                                                                 
1223                                                         else
1224                                                                 GPU_link(mat, "mtex_bump_init_viewspace",
1225                                                                          surf_pos, vNorg,
1226                                                                          fPrevMagnitude, vNacc,
1227                                                                          &fPrevMagnitude, &vNacc,
1228                                                                          &vR1, &vR2, &fDet);
1229                                                         
1230                                                         iBumpSpacePrev = iBumpSpace;
1231                                                 }
1232                                                 
1233                                                 
1234                                                 if (found_deriv_map) {
1235                                                         GPU_link(mat, "mtex_bump_deriv",
1236                                                                  texco, GPU_image(tex->ima, &tex->iuser), GPU_uniform(&ima_x), GPU_uniform(&ima_y), tnorfac,
1237                                                                  &dBs, &dBt );
1238                                                 }
1239                                                 else if ( mtex->texflag & MTEX_3TAP_BUMP)
1240                                                         GPU_link(mat, "mtex_bump_tap3",
1241                                                                  texco, GPU_image(tex->ima, &tex->iuser), tnorfac,
1242                                                                  &dBs, &dBt );
1243                                                 else if ( mtex->texflag & MTEX_5TAP_BUMP)
1244                                                         GPU_link(mat, "mtex_bump_tap5",
1245                                                                  texco, GPU_image(tex->ima, &tex->iuser), tnorfac,
1246                                                                  &dBs, &dBt );
1247                                                 else if ( mtex->texflag & MTEX_BICUBIC_BUMP ) {
1248                                                         if (GPU_bicubic_bump_support()) {
1249                                                                 GPU_link(mat, "mtex_bump_bicubic",
1250                                                                          texco, GPU_image(tex->ima, &tex->iuser), tnorfac,
1251                                                                          &dBs, &dBt);
1252                                                         }
1253                                                         else {
1254                                                                 GPU_link(mat, "mtex_bump_tap5",
1255                                                                          texco, GPU_image(tex->ima, &tex->iuser), tnorfac,
1256                                                                          &dBs, &dBt);
1257                                                         }
1258                                                 }
1259                                                 
1260                                                 
1261                                                 if ( mtex->texflag & MTEX_BUMP_TEXTURESPACE ) {
1262                                                         float imag_tspace_dimension_y = aspect*imag_tspace_dimension_x;
1263                                                         GPU_link(mat, "mtex_bump_apply_texspace",
1264                                                                  fDet, dBs, dBt, vR1, vR2,
1265                                                                  GPU_image(tex->ima, &tex->iuser), texco,
1266                                                                  GPU_uniform(&imag_tspace_dimension_x), GPU_uniform(&imag_tspace_dimension_y), vNacc,
1267                                                                  &vNacc, &shi->vn );
1268                                                 }
1269                                                 else
1270                                                         GPU_link(mat, "mtex_bump_apply",
1271                                                                  fDet, dBs, dBt, vR1, vR2, vNacc,
1272                                                                  &vNacc, &shi->vn );
1273                                                 
1274                                         }
1275                                 }
1276                                 
1277                                 GPU_link(mat, "vec_math_negate", shi->vn, &orn);
1278                         }
1279
1280                         if ((mtex->mapto & MAP_VARS)) {
1281                                 if (rgbnor & TEX_RGB) {
1282                                         if (talpha)
1283                                                 GPU_link(mat, "mtex_alpha_from_col", trgb, &tin);
1284                                         else
1285                                                 GPU_link(mat, "mtex_rgbtoint", trgb, &tin);
1286                                 }
1287
1288                                 if (!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_REF) {
1289                                         GPUNodeLink *difffac;
1290
1291                                         if (mtex->difffac == 1.0f) difffac = stencil;
1292                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->difffac), stencil, &difffac);
1293
1294                                         texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->refl, tin, difffac, mtex->blendtype, &shi->refl);
1295                                         GPU_link(mat, "mtex_value_clamp_positive", shi->refl, &shi->refl);
1296                                 }
1297                                 if (!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_SPEC) {
1298                                         GPUNodeLink *specfac;
1299
1300                                         if (mtex->specfac == 1.0f) specfac = stencil;
1301                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->specfac), stencil, &specfac);
1302
1303                                         texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->spec, tin, specfac, mtex->blendtype, &shi->spec);
1304                                         GPU_link(mat, "mtex_value_clamp_positive", shi->spec, &shi->spec);
1305                                 }
1306                                 if (!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_EMIT) {
1307                                         GPUNodeLink *emitfac;
1308
1309                                         if (mtex->emitfac == 1.0f) emitfac = stencil;
1310                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->emitfac), stencil, &emitfac);
1311
1312                                         texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->emit, tin, emitfac, mtex->blendtype, &shi->emit);
1313                                         GPU_link(mat, "mtex_value_clamp_positive", shi->emit, &shi->emit);
1314                                 }
1315                                 if (!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_HAR) {
1316                                         GPUNodeLink *hardfac;
1317
1318                                         if (mtex->hardfac == 1.0f) hardfac = stencil;
1319                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->hardfac), stencil, &hardfac);
1320
1321                                         GPU_link(mat, "mtex_har_divide", shi->har, &shi->har);
1322                                         texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->har, tin, hardfac, mtex->blendtype, &shi->har);
1323                                         GPU_link(mat, "mtex_har_multiply_clamp", shi->har, &shi->har);
1324                                 }
1325                                 if (mtex->mapto & MAP_ALPHA) {
1326                                         GPUNodeLink *alphafac;
1327
1328                                         if (mtex->alphafac == 1.0f) alphafac = stencil;
1329                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->alphafac), stencil, &alphafac);
1330
1331                                         texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->alpha, tin, alphafac, mtex->blendtype, &shi->alpha);
1332                                         GPU_link(mat, "mtex_value_clamp", shi->alpha, &shi->alpha);
1333                                 }
1334                                 if (!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_AMB) {
1335                                         GPUNodeLink *ambfac;
1336
1337                                         if (mtex->ambfac == 1.0f) ambfac = stencil;
1338                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->ambfac), stencil, &ambfac);
1339
1340                                         texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->amb, tin, ambfac, mtex->blendtype, &shi->amb);
1341                                         GPU_link(mat, "mtex_value_clamp", shi->amb, &shi->amb);
1342                                 }
1343                         }
1344                 }
1345         }
1346 }
1347
1348 void GPU_shadeinput_set(GPUMaterial *mat, Material *ma, GPUShadeInput *shi)
1349 {
1350         float hard = ma->har;
1351
1352         memset(shi, 0, sizeof(*shi));
1353
1354         shi->gpumat = mat;
1355         shi->mat = ma;
1356
1357         GPU_link(mat, "set_rgb", GPU_uniform(&ma->r), &shi->rgb);
1358         GPU_link(mat, "set_rgb", GPU_uniform(&ma->specr), &shi->specrgb);
1359         GPU_link(mat, "shade_norm", GPU_builtin(GPU_VIEW_NORMAL), &shi->vn);
1360         GPU_link(mat, "set_value", GPU_uniform(&ma->alpha), &shi->alpha);
1361         GPU_link(mat, "set_value", GPU_uniform(&ma->ref), &shi->refl);
1362         GPU_link(mat, "set_value", GPU_uniform(&ma->spec), &shi->spec);
1363         GPU_link(mat, "set_value", GPU_uniform(&ma->emit), &shi->emit);
1364         GPU_link(mat, "set_value", GPU_uniform(&hard), &shi->har);
1365         GPU_link(mat, "set_value", GPU_uniform(&ma->amb), &shi->amb);
1366         GPU_link(mat, "shade_view", GPU_builtin(GPU_VIEW_POSITION), &shi->view);
1367         GPU_link(mat, "vcol_attribute", GPU_attribute(CD_MCOL, ""), &shi->vcol);
1368         if (gpu_do_color_management(mat))
1369                 GPU_link(mat, "srgb_to_linearrgb", shi->vcol, &shi->vcol);
1370         GPU_link(mat, "texco_refl", shi->vn, shi->view, &shi->ref);
1371 }
1372
1373 void GPU_shaderesult_set(GPUShadeInput *shi, GPUShadeResult *shr)
1374 {
1375         GPUMaterial *mat= shi->gpumat;
1376         GPUNodeLink *emit, *ulinfac, *ulogfac, *mistfac;
1377         Material *ma= shi->mat;
1378         World *world= mat->scene->world;
1379         float linfac, logfac, misttype;
1380
1381         memset(shr, 0, sizeof(*shr));
1382
1383         if (ma->mode & MA_VERTEXCOLP)
1384                 shi->rgb = shi->vcol;
1385
1386         do_material_tex(shi);
1387
1388         if ((ma->mode & MA_TRANSP) && (ma->mode & MA_ZTRANSP))
1389                 GPU_material_enable_alpha(mat);
1390
1391         if ((mat->scene->gm.flag & GAME_GLSL_NO_LIGHTS) || (ma->mode & MA_SHLESS)) {
1392                 shr->combined = shi->rgb;
1393                 shr->alpha = shi->alpha;
1394                 GPU_link(mat, "set_rgb", shi->rgb, &shr->diff);
1395                 GPU_link(mat, "set_rgb_zero", &shr->spec);
1396         }
1397         else {
1398                 if (GPU_link_changed(shi->emit) || ma->emit != 0.0f) {
1399                         if ((ma->mode & (MA_VERTEXCOL|MA_VERTEXCOLP))== MA_VERTEXCOL) {
1400                                 GPU_link(mat, "shade_add", shi->emit, shi->vcol, &emit);
1401                                 GPU_link(mat, "shade_mul", emit, shi->rgb, &shr->diff);
1402                         }
1403                         else
1404                                 GPU_link(mat, "shade_mul_value", shi->emit, shi->rgb, &shr->diff);
1405                 }
1406                 else
1407                         GPU_link(mat, "set_rgb_zero", &shr->diff);
1408
1409                 GPU_link(mat, "set_rgb_zero", &shr->spec);
1410
1411                 material_lights(shi, shr);
1412
1413                 shr->combined = shr->diff;
1414                 shr->alpha = shi->alpha;
1415
1416                 if (world) {
1417                         /* exposure correction */
1418                         if (world->exp!=0.0f || world->range!=1.0f) {
1419                                 linfac= 1.0f + powf((2.0f*world->exp + 0.5f), -10);
1420                                 logfac= logf((linfac-1.0f)/linfac)/world->range;
1421
1422                                 GPU_link(mat, "set_value", GPU_uniform(&linfac), &ulinfac);
1423                                 GPU_link(mat, "set_value", GPU_uniform(&logfac), &ulogfac);
1424
1425                                 GPU_link(mat, "shade_exposure_correct", shr->combined,
1426                                         ulinfac, ulogfac, &shr->combined);
1427                                 GPU_link(mat, "shade_exposure_correct", shr->spec,
1428                                         ulinfac, ulogfac, &shr->spec);
1429                         }
1430
1431                         /* ambient color */
1432                         if (world->ambr!=0.0f || world->ambg!=0.0f || world->ambb!=0.0f) {
1433                                 if (GPU_link_changed(shi->amb) || ma->amb != 0.0f)
1434                                         GPU_link(mat, "shade_maddf", shr->combined, GPU_uniform(&ma->amb),
1435                                                 GPU_uniform(&world->ambr), &shr->combined);
1436                         }
1437                 }
1438
1439                 if (ma->mode & MA_RAMP_COL) ramp_diffuse_result(shi, &shr->combined);
1440                 if (ma->mode & MA_RAMP_SPEC) ramp_spec_result(shi, &shr->spec);
1441
1442                 if (GPU_link_changed(shi->spec) || ma->spec != 0.0f)
1443                         GPU_link(mat, "shade_add", shr->combined, shr->spec, &shr->combined);
1444         }
1445
1446         GPU_link(mat, "mtex_alpha_to_col", shr->combined, shr->alpha, &shr->combined);
1447
1448         if (ma->shade_flag & MA_OBCOLOR)
1449                 GPU_link(mat, "shade_obcolor", shr->combined, GPU_builtin(GPU_OBCOLOR), &shr->combined);
1450
1451         if (world && (world->mode & WO_MIST) && !(ma->mode & MA_NOMIST)) {
1452                 misttype = world->mistype;
1453
1454                 GPU_link(mat, "shade_mist_factor", GPU_builtin(GPU_VIEW_POSITION),
1455                         GPU_uniform(&world->miststa), GPU_uniform(&world->mistdist),
1456                         GPU_uniform(&misttype), GPU_uniform(&world->misi), &mistfac);
1457
1458                 GPU_link(mat, "mix_blend", mistfac, shr->combined,
1459                         GPU_uniform(&world->horr), &shr->combined);
1460         }
1461
1462         if (!((ma->mode & MA_TRANSP) && (ma->mode & MA_ZTRANSP))) {
1463                 if (world && (GPU_link_changed(shr->alpha) || ma->alpha != 1.0f))
1464                         GPU_link(mat, "shade_world_mix", GPU_uniform(&world->horr),
1465                                 shr->combined, &shr->combined);
1466
1467                 GPU_link(mat, "shade_alpha_opaque", shr->combined, &shr->combined);
1468         }
1469
1470         if (ma->shade_flag & MA_OBCOLOR) {
1471                 mat->obcolalpha = 1;
1472                 GPU_link(mat, "shade_alpha_obcolor", shr->combined, GPU_builtin(GPU_OBCOLOR), &shr->combined);
1473         }
1474 }
1475
1476 static GPUNodeLink *GPU_blender_material(GPUMaterial *mat, Material *ma)
1477 {
1478         GPUShadeInput shi;
1479         GPUShadeResult shr;
1480
1481         GPU_shadeinput_set(mat, ma, &shi);
1482         GPU_shaderesult_set(&shi, &shr);
1483
1484         return shr.combined;
1485 }
1486
1487 GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma)
1488 {
1489         GPUMaterial *mat;
1490         GPUNodeLink *outlink;
1491         LinkData *link;
1492
1493         for (link=ma->gpumaterial.first; link; link=link->next)
1494                 if (((GPUMaterial*)link->data)->scene == scene)
1495                         return link->data;
1496
1497         /* allocate material */
1498         mat = GPU_material_construct_begin(ma);
1499         mat->scene = scene;
1500
1501         if (!(scene->gm.flag & GAME_GLSL_NO_NODES) && ma->nodetree && ma->use_nodes) {
1502                 /* create nodes */
1503                 ntreeGPUMaterialNodes(ma->nodetree, mat);
1504         }
1505         else {
1506                 /* create material */
1507                 outlink = GPU_blender_material(mat, ma);
1508                 GPU_material_output_link(mat, outlink);
1509         }
1510
1511         if (!BKE_scene_use_new_shading_nodes(scene)) {
1512                 if (gpu_do_color_management(mat))
1513                         if (mat->outlink)
1514                                 GPU_link(mat, "linearrgb_to_srgb", mat->outlink, &mat->outlink);
1515         }
1516
1517
1518         GPU_material_construct_end(mat);
1519
1520         /* note that even if building the shader fails in some way, we still keep
1521          * it to avoid trying to compile again and again, and simple do not use
1522          * the actual shader on drawing */
1523
1524         link = MEM_callocN(sizeof(LinkData), "GPUMaterialLink");
1525         link->data = mat;
1526         BLI_addtail(&ma->gpumaterial, link);
1527
1528         return mat;
1529 }
1530
1531 void GPU_materials_free(void)
1532 {
1533         Object *ob;
1534         Material *ma;
1535         extern Material defmaterial;
1536
1537         for (ma=G.main->mat.first; ma; ma=ma->id.next)
1538                 GPU_material_free(ma);
1539
1540         GPU_material_free(&defmaterial);
1541
1542         for (ob=G.main->object.first; ob; ob=ob->id.next)
1543                 GPU_lamp_free(ob);
1544 }
1545
1546 /* Lamps and shadow buffers */
1547
1548 void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[][4])
1549 {
1550         float mat[4][4];
1551
1552         lamp->lay = lay;
1553         lamp->hide = hide;
1554
1555         copy_m4_m4(mat, obmat);
1556         normalize_m4(mat);
1557
1558         copy_v3_v3(lamp->vec, mat[2]);
1559         copy_v3_v3(lamp->co, mat[3]);
1560         copy_m4_m4(lamp->obmat, mat);
1561         invert_m4_m4(lamp->imat, mat);
1562 }
1563
1564 void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float energy)
1565 {
1566         lamp->energy = energy;
1567         if (lamp->mode & LA_NEG) lamp->energy= -lamp->energy;
1568
1569         lamp->col[0]= r* lamp->energy;
1570         lamp->col[1]= g* lamp->energy;
1571         lamp->col[2]= b* lamp->energy;
1572 }
1573
1574 void GPU_lamp_update_distance(GPULamp *lamp, float distance, float att1, float att2)
1575 {
1576         lamp->dist = distance;
1577         lamp->att1 = att1;
1578         lamp->att2 = att2;
1579 }
1580
1581 void GPU_lamp_update_spot(GPULamp *lamp, float spotsize, float spotblend)
1582 {
1583         lamp->spotsi= cos(M_PI*spotsize/360.0);
1584         lamp->spotbl= (1.0f - lamp->spotsi)*spotblend;
1585 }
1586
1587 static void gpu_lamp_from_blender(Scene *scene, Object *ob, Object *par, Lamp *la, GPULamp *lamp)
1588 {
1589         float temp, angle, pixsize, wsize;
1590
1591         lamp->scene = scene;
1592         lamp->ob = ob;
1593         lamp->par = par;
1594         lamp->la = la;
1595
1596         /* add_render_lamp */
1597         lamp->mode = la->mode;
1598         lamp->type = la->type;
1599
1600         lamp->energy = la->energy;
1601         if (lamp->mode & LA_NEG) lamp->energy= -lamp->energy;
1602
1603         lamp->col[0]= la->r*lamp->energy;
1604         lamp->col[1]= la->g*lamp->energy;
1605         lamp->col[2]= la->b*lamp->energy;
1606
1607         GPU_lamp_update(lamp, ob->lay, (ob->restrictflag & OB_RESTRICT_RENDER), ob->obmat);
1608
1609         lamp->spotsi= la->spotsize;
1610         if (lamp->mode & LA_HALO)
1611                 if (lamp->spotsi > 170.0f)
1612                         lamp->spotsi = 170.0f;
1613         lamp->spotsi= cosf((float)M_PI*lamp->spotsi/360.0f);
1614         lamp->spotbl= (1.0f - lamp->spotsi)*la->spotblend;
1615         lamp->k= la->k;
1616
1617         lamp->dist= la->dist;
1618         lamp->falloff_type= la->falloff_type;
1619         lamp->att1= la->att1;
1620         lamp->att2= la->att2;
1621         lamp->curfalloff= la->curfalloff;
1622
1623         /* initshadowbuf */
1624         lamp->bias = 0.02f*la->bias;
1625         lamp->size = la->bufsize;
1626         lamp->d= la->clipsta;
1627         lamp->clipend= la->clipend;
1628
1629         /* arbitrary correction for the fact we do no soft transition */
1630         lamp->bias *= 0.25f;
1631
1632         /* makeshadowbuf */
1633         if (lamp->type == LA_SUN) {
1634                 wsize = la->shadow_frustum_size;
1635                 orthographic_m4(lamp->winmat, -wsize, wsize, -wsize, wsize, lamp->d, lamp->clipend);
1636         }
1637         else {
1638                 angle= saacos(lamp->spotsi);
1639                 temp= 0.5f*lamp->size*cosf(angle)/sinf(angle);
1640                 pixsize= (lamp->d)/temp;
1641                 wsize= pixsize*0.5f*lamp->size;
1642                 perspective_m4(lamp->winmat, -wsize, wsize, -wsize, wsize, lamp->d, lamp->clipend);
1643         }
1644 }
1645
1646 static void gpu_lamp_shadow_free(GPULamp *lamp)
1647 {
1648         if (lamp->tex) {
1649                 GPU_texture_free(lamp->tex);
1650                 lamp->tex= NULL;
1651         }
1652         if (lamp->depthtex) {
1653                 GPU_texture_free(lamp->depthtex);
1654                 lamp->depthtex= NULL;
1655         }
1656         if (lamp->fb) {
1657                 GPU_framebuffer_free(lamp->fb);
1658                 lamp->fb= NULL;
1659         }
1660         if (lamp->blurtex) {
1661                 GPU_texture_free(lamp->blurtex);
1662                 lamp->blurtex= NULL;
1663         }
1664         if (lamp->blurfb) {
1665                 GPU_framebuffer_free(lamp->blurfb);
1666                 lamp->blurfb= NULL;
1667         }
1668 }
1669
1670 GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par)
1671 {
1672         Lamp *la;
1673         GPULamp *lamp;
1674         LinkData *link;
1675
1676         for (link=ob->gpulamp.first; link; link=link->next) {
1677                 lamp = (GPULamp*)link->data;
1678
1679                 if (lamp->par == par && lamp->scene == scene)
1680                         return link->data;
1681         }
1682
1683         lamp = MEM_callocN(sizeof(GPULamp), "GPULamp");
1684
1685         link = MEM_callocN(sizeof(LinkData), "GPULampLink");
1686         link->data = lamp;
1687         BLI_addtail(&ob->gpulamp, link);
1688
1689         la = ob->data;
1690         gpu_lamp_from_blender(scene, ob, par, la, lamp);
1691
1692         if ((la->type==LA_SPOT && (la->mode & LA_SHAD_BUF)) || (la->type==LA_SUN && (la->mode & LA_SHAD_RAY))) {
1693                 /* opengl */
1694                 lamp->fb = GPU_framebuffer_create();
1695                 if (!lamp->fb) {
1696                         gpu_lamp_shadow_free(lamp);
1697                         return lamp;
1698                 }
1699
1700                 if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) {
1701                         /* Shadow depth map */
1702                         lamp->depthtex = GPU_texture_create_depth(lamp->size, lamp->size, NULL);
1703                         if (!lamp->depthtex) {
1704                                 gpu_lamp_shadow_free(lamp);
1705                                 return lamp;
1706                         }
1707                 
1708                         if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->depthtex, NULL)) {
1709                                 gpu_lamp_shadow_free(lamp);
1710                                 return lamp;
1711                         }
1712
1713                         /* Shadow color map */
1714                         lamp->tex = GPU_texture_create_vsm_shadow_map(lamp->size, NULL);
1715                         if (!lamp->tex) {
1716                                 gpu_lamp_shadow_free(lamp);
1717                                 return lamp;
1718                         }
1719
1720                         if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex, NULL)) {
1721                                 gpu_lamp_shadow_free(lamp);
1722                                 return lamp;
1723                         }
1724
1725                         /* FBO and texture for blurring */
1726                         lamp->blurfb = GPU_framebuffer_create();
1727                         if (!lamp->blurfb) {
1728                                 gpu_lamp_shadow_free(lamp);
1729                                 return lamp;
1730                         }
1731
1732                         lamp->blurtex = GPU_texture_create_vsm_shadow_map(lamp->size*0.5, NULL);
1733                         if (!lamp->blurtex) {
1734                                 gpu_lamp_shadow_free(lamp);
1735                                 return lamp;
1736                         }
1737                 
1738                         if (!GPU_framebuffer_texture_attach(lamp->blurfb, lamp->blurtex, NULL)) {
1739                                 gpu_lamp_shadow_free(lamp);
1740                                 return lamp;
1741                         }
1742                 }
1743                 else {
1744                         lamp->tex = GPU_texture_create_depth(lamp->size, lamp->size, NULL);
1745                         if (!lamp->tex) {
1746                                 gpu_lamp_shadow_free(lamp);
1747                                 return lamp;
1748                         }
1749
1750                         if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex, NULL)) {
1751                                 gpu_lamp_shadow_free(lamp);
1752                                 return lamp;
1753                         }
1754                 }
1755
1756                 GPU_framebuffer_restore();
1757
1758                 lamp->shadow_color[0] = la->shdwr;
1759                 lamp->shadow_color[1] = la->shdwg;
1760                 lamp->shadow_color[2] = la->shdwb;
1761         }
1762         else {
1763                 lamp->shadow_color[0] = 1.0;
1764                 lamp->shadow_color[1] = 1.0;
1765                 lamp->shadow_color[2] = 1.0;
1766         }
1767
1768         return lamp;
1769 }
1770
1771 void GPU_lamp_free(Object *ob)
1772 {
1773         GPULamp *lamp;
1774         LinkData *link;
1775         LinkData *nlink;
1776         Material *ma;
1777
1778         for (link=ob->gpulamp.first; link; link=link->next) {
1779                 lamp = link->data;
1780
1781                 while (lamp->materials.first) {
1782                         nlink = lamp->materials.first;
1783                         ma = nlink->data;
1784                         BLI_freelinkN(&lamp->materials, nlink);
1785
1786                         if (ma->gpumaterial.first)
1787                                 GPU_material_free(ma);
1788                 }
1789
1790                 gpu_lamp_shadow_free(lamp);
1791
1792                 MEM_freeN(lamp);
1793         }
1794
1795         BLI_freelistN(&ob->gpulamp);
1796 }
1797
1798 int GPU_lamp_has_shadow_buffer(GPULamp *lamp)
1799 {
1800         return (!(lamp->scene->gm.flag & GAME_GLSL_NO_SHADOWS) &&
1801                         !(lamp->scene->gm.flag & GAME_GLSL_NO_LIGHTS) &&
1802                         lamp->tex && lamp->fb);
1803 }
1804
1805 void GPU_lamp_update_buffer_mats(GPULamp *lamp)
1806 {
1807         float rangemat[4][4], persmat[4][4];
1808
1809         /* initshadowbuf */
1810         invert_m4_m4(lamp->viewmat, lamp->obmat);
1811         normalize_v3(lamp->viewmat[0]);
1812         normalize_v3(lamp->viewmat[1]);
1813         normalize_v3(lamp->viewmat[2]);
1814
1815         /* makeshadowbuf */
1816         mult_m4_m4m4(persmat, lamp->winmat, lamp->viewmat);
1817
1818         /* opengl depth buffer is range 0.0..1.0 instead of -1.0..1.0 in blender */
1819         unit_m4(rangemat);
1820         rangemat[0][0] = 0.5f;
1821         rangemat[1][1] = 0.5f;
1822         rangemat[2][2] = 0.5f;
1823         rangemat[3][0] = 0.5f;
1824         rangemat[3][1] = 0.5f;
1825         rangemat[3][2] = 0.5f;
1826
1827         mult_m4_m4m4(lamp->persmat, rangemat, persmat);
1828 }
1829
1830 void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[][4], int *winsize, float winmat[][4])
1831 {
1832         GPU_lamp_update_buffer_mats(lamp);
1833
1834         /* opengl */
1835         glDisable(GL_SCISSOR_TEST);
1836         GPU_framebuffer_texture_bind(lamp->fb, lamp->tex,
1837                 GPU_texture_opengl_width(lamp->tex), GPU_texture_opengl_height(lamp->tex));
1838         if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE)
1839                 GPU_shader_bind(GPU_shader_get_builtin_shader(GPU_SHADER_VSM_STORE));
1840
1841         /* set matrices */
1842         copy_m4_m4(viewmat, lamp->viewmat);
1843         copy_m4_m4(winmat, lamp->winmat);
1844         *winsize = lamp->size;
1845 }
1846
1847 void GPU_lamp_shadow_buffer_unbind(GPULamp *lamp)
1848 {
1849         if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) {
1850                 GPU_shader_unbind(GPU_shader_get_builtin_shader(GPU_SHADER_VSM_STORE));
1851                 GPU_framebuffer_blur(lamp->fb, lamp->tex, lamp->blurfb, lamp->blurtex);
1852         }
1853
1854         GPU_framebuffer_texture_unbind(lamp->fb, lamp->tex);
1855         GPU_framebuffer_restore();
1856         glEnable(GL_SCISSOR_TEST);
1857 }
1858
1859 int GPU_lamp_shadow_layer(GPULamp *lamp)
1860 {
1861         if (lamp->fb && lamp->tex && (lamp->mode & (LA_LAYER|LA_LAYER_SHADOW)))
1862                 return lamp->lay;
1863         else
1864                 return -1;
1865 }
1866
1867 /* export the GLSL shader */
1868
1869 GPUShaderExport *GPU_shader_export(struct Scene *scene, struct Material *ma)
1870 {
1871         static struct {
1872                 GPUBuiltin gputype;
1873                 GPUDynamicType dynamictype;
1874                 GPUDataType datatype;
1875         } builtins[] = { 
1876                 { GPU_VIEW_MATRIX, GPU_DYNAMIC_OBJECT_VIEWMAT, GPU_DATA_16F },
1877                 { GPU_INVERSE_VIEW_MATRIX, GPU_DYNAMIC_OBJECT_VIEWIMAT, GPU_DATA_16F },
1878                 { GPU_OBJECT_MATRIX, GPU_DYNAMIC_OBJECT_MAT, GPU_DATA_16F },
1879                 { GPU_INVERSE_OBJECT_MATRIX, GPU_DYNAMIC_OBJECT_IMAT, GPU_DATA_16F },
1880                 { GPU_OBCOLOR, GPU_DYNAMIC_OBJECT_COLOR, GPU_DATA_4F },
1881                 { GPU_AUTO_BUMPSCALE, GPU_DYNAMIC_OBJECT_AUTOBUMPSCALE, GPU_DATA_1F },
1882                 { 0 }
1883         };
1884
1885         GPUShaderExport *shader = NULL;
1886         GPUPass *pass;
1887         GPUInput *input;
1888         GPUMaterial *mat;
1889         GPUInputUniform *uniform;
1890         GPUInputAttribute *attribute;
1891         GLint lastbindcode;
1892         int i, liblen, fraglen;
1893
1894         if (!GPU_glsl_support())
1895                 return NULL;
1896
1897         mat = GPU_material_from_blender(scene, ma);
1898         pass = (mat)? mat->pass: NULL;
1899
1900         if (pass && pass->fragmentcode && pass->vertexcode) {
1901                 shader = MEM_callocN(sizeof(GPUShaderExport), "GPUShaderExport");
1902
1903                 for (input = pass->inputs.first; input; input = input->next) {
1904                         uniform = MEM_callocN(sizeof(GPUInputUniform), "GPUInputUniform");
1905
1906                         if (input->ima) {
1907                                 /* image sampler uniform */
1908                                 uniform->type = GPU_DYNAMIC_SAMPLER_2DIMAGE;
1909                                 uniform->datatype = GPU_DATA_1I;
1910                                 uniform->image = input->ima;
1911                                 uniform->texnumber = input->texid;
1912                                 BLI_strncpy(uniform->varname, input->shadername, sizeof(uniform->varname));
1913                         }
1914                         else if (input->tex) {
1915                                 /* generated buffer */
1916                                 uniform->texnumber = input->texid;
1917                                 uniform->datatype = GPU_DATA_1I;
1918                                 BLI_strncpy(uniform->varname, input->shadername, sizeof(uniform->varname));
1919
1920                                 switch (input->textype) {
1921                                 case GPU_SHADOW2D:
1922                                         uniform->type = GPU_DYNAMIC_SAMPLER_2DSHADOW;
1923                                         uniform->lamp = input->dynamicdata;
1924                                         break;
1925                                 case GPU_TEX2D:
1926                                         if (GPU_texture_opengl_bindcode(input->tex)) {
1927                                                 uniform->type = GPU_DYNAMIC_SAMPLER_2DBUFFER;
1928                                                 glGetIntegerv(GL_TEXTURE_BINDING_2D, &lastbindcode);
1929                                                 glBindTexture(GL_TEXTURE_2D, GPU_texture_opengl_bindcode(input->tex));
1930                                                 uniform->texsize = GPU_texture_opengl_width(input->tex) * GPU_texture_opengl_height(input->tex);
1931                                                 uniform->texpixels = MEM_mallocN(uniform->texsize*4, "RGBApixels");
1932                                                 glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, uniform->texpixels); 
1933                                                 glBindTexture(GL_TEXTURE_2D, lastbindcode);
1934                                         }
1935                                         break;
1936                                 }
1937                         }
1938                         else {
1939                                 uniform->type = input->dynamictype;
1940                                 BLI_strncpy(uniform->varname, input->shadername, sizeof(uniform->varname));
1941                                 switch (input->type) {
1942                                 case 1:
1943                                         uniform->datatype = GPU_DATA_1F;
1944                                         break;
1945                                 case 2:
1946                                         uniform->datatype = GPU_DATA_2F;
1947                                         break;
1948                                 case 3:
1949                                         uniform->datatype = GPU_DATA_3F;
1950                                         break;
1951                                 case 4:
1952                                         uniform->datatype = GPU_DATA_4F;
1953                                         break;
1954                                 case 9:
1955                                         uniform->datatype = GPU_DATA_9F;
1956                                         break;
1957                                 case 16:
1958                                         uniform->datatype = GPU_DATA_16F;
1959                                         break;
1960                                 }
1961
1962                                 if (uniform->type >= GPU_DYNAMIC_LAMP_FIRST && uniform->type <= GPU_DYNAMIC_LAMP_LAST)
1963                                         uniform->lamp = input->dynamicdata;
1964                         }
1965
1966                         if (uniform->type != GPU_DYNAMIC_NONE)
1967                                 BLI_addtail(&shader->uniforms, uniform);
1968                         else
1969                                 MEM_freeN(uniform);
1970                 }
1971
1972                 /* process builtin uniform */
1973                 for (i=0; builtins[i].gputype; i++) {
1974                         if (mat->builtins & builtins[i].gputype) {
1975                                 uniform = MEM_callocN(sizeof(GPUInputUniform), "GPUInputUniform");
1976                                 uniform->type = builtins[i].dynamictype;
1977                                 uniform->datatype = builtins[i].datatype;
1978                                 BLI_strncpy(uniform->varname, GPU_builtin_name(builtins[i].gputype), sizeof(uniform->varname));
1979                                 BLI_addtail(&shader->uniforms, uniform);
1980                         }
1981                 }
1982
1983                 /* now link fragment shader with library shader */
1984                 /* TBD: remove the function that are not used in the main function */
1985                 liblen = (pass->libcode) ? strlen(pass->libcode) : 0;
1986                 fraglen = strlen(pass->fragmentcode);
1987                 shader->fragment = (char *)MEM_mallocN(liblen+fraglen+1, "GPUFragShader");
1988                 if (pass->libcode)
1989                         memcpy(shader->fragment, pass->libcode, liblen);
1990                 memcpy(&shader->fragment[liblen], pass->fragmentcode, fraglen);
1991                 shader->fragment[liblen+fraglen] = 0;
1992
1993                 // export the attribute
1994                 for (i=0; i<mat->attribs.totlayer; i++) {
1995                         attribute = MEM_callocN(sizeof(GPUInputAttribute), "GPUInputAttribute");
1996                         attribute->type = mat->attribs.layer[i].type;
1997                         attribute->number = mat->attribs.layer[i].glindex;
1998                         BLI_snprintf(attribute->varname, sizeof(attribute->varname), "att%d", mat->attribs.layer[i].attribid);
1999
2000                         switch (attribute->type) {
2001                         case CD_TANGENT:
2002                                 attribute->datatype = GPU_DATA_4F;
2003                                 break;
2004                         case CD_MTFACE:
2005                                 attribute->datatype = GPU_DATA_2F;
2006                                 attribute->name = mat->attribs.layer[i].name;
2007                                 break;
2008                         case CD_MCOL:
2009                                 attribute->datatype = GPU_DATA_4UB;
2010                                 attribute->name = mat->attribs.layer[i].name;
2011                                 break;
2012                         case CD_ORCO:
2013                                 attribute->datatype = GPU_DATA_3F;
2014                                 break;
2015                         }
2016
2017                         if (attribute->datatype != GPU_DATA_NONE)
2018                                 BLI_addtail(&shader->attributes, attribute);
2019                         else
2020                                 MEM_freeN(attribute);
2021                 }
2022
2023                 // export the vertex shader
2024                 shader->vertex = BLI_strdup(pass->vertexcode);
2025         }
2026
2027         return shader;
2028 }
2029
2030 void GPU_free_shader_export(GPUShaderExport *shader)
2031 {
2032         GPUInputUniform *uniform;
2033
2034         if (shader == NULL)
2035                 return;
2036
2037         for (uniform = shader->uniforms.first; uniform; uniform=uniform->next)
2038                 if (uniform->texpixels)
2039                         MEM_freeN(uniform->texpixels);
2040
2041         BLI_freelistN(&shader->uniforms);
2042         BLI_freelistN(&shader->attributes);
2043
2044         if (shader->vertex)
2045                 MEM_freeN(shader->vertex);
2046         if (shader->fragment)
2047                 MEM_freeN(shader->fragment);
2048
2049         MEM_freeN(shader);
2050 }
2051