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