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