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