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