use BLI_strncpy and BLI_snprintf when the size of the string is known.
[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                 BLI_snprintf(name, sizeof(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                                 mult_m4_m4m4(lamp->dynimat, lamp->imat, viewinv);
325                         if(material->dynproperty & DYN_LAMP_PERSMAT)
326                                 mult_m4_m4m4(lamp->dynpersmat, lamp->persmat, viewinv);
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
976                         if(tex && tex->type == TEX_IMAGE && tex->ima) {
977                                 GPU_link(mat, "mtex_image", texco, GPU_image(tex->ima, &tex->iuser), &tin, &trgb);
978                                 rgbnor= TEX_RGB;
979
980                                 if(tex->imaflag & TEX_USEALPHA)
981                                         talpha= 1;
982                         }
983                         else continue;
984
985                         /* texture output */
986                         if((rgbnor & TEX_RGB) && (mtex->texflag & MTEX_RGBTOINT)) {
987                                 GPU_link(mat, "mtex_rgbtoint", trgb, &tin);
988                                 rgbnor -= TEX_RGB;
989                         }
990
991                         if(mtex->texflag & MTEX_NEGATIVE) {
992                                 if(rgbnor & TEX_RGB)
993                                         GPU_link(mat, "mtex_rgb_invert", trgb, &trgb);
994                                 else
995                                         GPU_link(mat, "mtex_value_invert", tin, &tin);
996                         }
997
998                         if(mtex->texflag & MTEX_STENCIL) {
999                                 if(rgbnor & TEX_RGB)
1000                                         GPU_link(mat, "mtex_rgb_stencil", stencil, trgb, &stencil, &trgb);
1001                                 else
1002                                         GPU_link(mat, "mtex_value_stencil", stencil, tin, &stencil, &tin);
1003                         }
1004
1005                         /* mapping */
1006                         if(mtex->mapto & (MAP_COL+MAP_COLSPEC)) {
1007                                 /* stencil maps on the texture control slider, not texture intensity value */
1008                                 if((rgbnor & TEX_RGB)==0) {
1009                                         GPU_link(mat, "set_rgb", GPU_uniform(&mtex->r), &tcol);
1010                                 }
1011                                 else {
1012                                         GPU_link(mat, "set_rgba", trgb, &tcol);
1013
1014                                         if(mtex->mapto & MAP_ALPHA)
1015                                                 GPU_link(mat, "set_value", stencil, &tin);
1016                                         else if(talpha)
1017                                                 GPU_link(mat, "mtex_alpha_from_col", trgb, &tin);
1018                                         else
1019                                                 GPU_link(mat, "set_value_one", &tin);
1020                                 }
1021
1022                                 if(tex->type==TEX_IMAGE)
1023                                         if(gpu_do_color_management(mat))
1024                                                 GPU_link(mat, "srgb_to_linearrgb", tcol, &tcol);
1025                                 
1026                                 if(mtex->mapto & MAP_COL) {
1027                                         GPUNodeLink *colfac;
1028
1029                                         if(mtex->colfac == 1.0f) colfac = stencil;
1030                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->colfac), stencil, &colfac);
1031
1032                                         texture_rgb_blend(mat, tcol, shi->rgb, tin, colfac, mtex->blendtype, &shi->rgb);
1033                                 }
1034                                 
1035                                 if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && (mtex->mapto & MAP_COLSPEC)) {
1036                                         GPUNodeLink *colspecfac;
1037
1038                                         if(mtex->colspecfac == 1.0f) colspecfac = stencil;
1039                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->colspecfac), stencil, &colspecfac);
1040
1041                                         texture_rgb_blend(mat, tcol, shi->specrgb, tin, colspecfac, mtex->blendtype, &shi->specrgb);
1042                                 }
1043                         }
1044
1045                         if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && (mtex->mapto & MAP_NORM)) {
1046                                 if(tex->type==TEX_IMAGE) {
1047                                         found_deriv_map = tex->imaflag & TEX_DERIVATIVEMAP;
1048
1049                                         if(tex->imaflag & TEX_NORMALMAP) {
1050                                                 /* normalmap image */
1051                                                 GPU_link(mat, "mtex_normal", texco, GPU_image(tex->ima, &tex->iuser), &tnor );
1052                                                 
1053                                                 if(mtex->norfac < 0.0f)
1054                                                         GPU_link(mat, "mtex_negate_texnormal", tnor, &tnor);
1055
1056                                                 if(mtex->normapspace == MTEX_NSPACE_TANGENT)
1057                                                 {
1058                                                         if(iFirstTimeNMap!=0)
1059                                                         {
1060                                                                 // use unnormalized normal (this is how we bake it - closer to gamedev)
1061                                                                 GPUNodeLink *vNegNorm;
1062                                                                 GPU_link(mat, "vec_math_negate", GPU_builtin(GPU_VIEW_NORMAL), &vNegNorm);
1063                                                                 GPU_link(mat, "mtex_nspace_tangent", GPU_attribute(CD_TANGENT, ""), vNegNorm, tnor, &newnor);
1064                                                                 iFirstTimeNMap = 0;
1065                                                         }
1066                                                         else    // otherwise use accumulated perturbations
1067                                                         {
1068                                                                 GPU_link(mat, "mtex_nspace_tangent", GPU_attribute(CD_TANGENT, ""), shi->vn, tnor, &newnor);
1069                                                         }
1070                                                 }
1071                                                 else
1072                                                         newnor = tnor;
1073                                                 
1074                                                 norfac = MIN2(fabsf(mtex->norfac), 1.0f);
1075                                                 
1076                                                 if(norfac == 1.0f && !GPU_link_changed(stencil)) {
1077                                                         shi->vn = newnor;
1078                                                 }
1079                                                 else {
1080                                                         tnorfac = GPU_uniform(&norfac);
1081         
1082                                                         if(GPU_link_changed(stencil))
1083                                                                 GPU_link(mat, "math_multiply", tnorfac, stencil, &tnorfac);
1084         
1085                                                         GPU_link(mat, "mtex_blend_normal", tnorfac, shi->vn, newnor, &shi->vn);
1086                                                 }
1087                                                 
1088                                         } else if( (mtex->texflag & (MTEX_3TAP_BUMP|MTEX_5TAP_BUMP|MTEX_BICUBIC_BUMP)) || found_deriv_map) {
1089                                                 /* ntap bumpmap image */
1090                                                 int iBumpSpace;
1091                                                 float ima_x, ima_y;
1092                                                 float hScale; 
1093
1094                                                 float imag_tspace_dimension_x = 1024.0f;                // only used for texture space variant
1095                                                 float aspect = 1.0f;
1096                                                 
1097                                                 GPUNodeLink *surf_pos = GPU_builtin(GPU_VIEW_POSITION);
1098                                                 GPUNodeLink *vR1, *vR2;
1099                                                 GPUNodeLink *dBs, *dBt, *fDet;
1100
1101                                                 hScale = 0.1;           // compatibility adjustment factor for all bumpspace types
1102                                                 if( mtex->texflag & MTEX_BUMP_TEXTURESPACE )
1103                                                         hScale = 13.0f;         // factor for scaling texspace bumps
1104                                                 else if(found_deriv_map!=0)
1105                                                         hScale = 1.0f;
1106
1107                                                 // resolve texture resolution
1108                                                 if( (mtex->texflag & MTEX_BUMP_TEXTURESPACE) || found_deriv_map ) {
1109                                                         ImBuf *ibuf= BKE_image_get_ibuf(tex->ima, &tex->iuser);
1110                                                         ima_x= 512.0f; ima_y= 512.f;            // prevent calling textureSize, glsl 1.3 only
1111                                                         if(ibuf) {
1112                                                                 ima_x= ibuf->x;
1113                                                                 ima_y= ibuf->y;
1114                                                                 aspect = ((float) ima_y) / ima_x;
1115                                                         }
1116                                                 }
1117
1118                                                 // The negate on norfac is done because the
1119                                                 // normal in the renderer points inward which corresponds
1120                                                 // to inverting the bump map. Should this ever change
1121                                                 // this negate must be removed.
1122                                                 norfac = -hScale * mtex->norfac;
1123                                                 if(found_deriv_map)
1124                                                 {
1125                                                         float fVirtDim = sqrtf(fabsf(ima_x*mtex->size[0]*ima_y*mtex->size[1]));
1126                                                         norfac /= MAX2(fVirtDim, FLT_EPSILON);
1127                                                 }
1128
1129                                                 tnorfac = GPU_uniform(&norfac);
1130
1131                                                 if(found_deriv_map)
1132                                                         GPU_link(mat, "math_multiply", tnorfac, GPU_builtin(GPU_AUTO_BUMPSCALE), &tnorfac);
1133                                                 
1134                                                 if(GPU_link_changed(stencil))
1135                                                         GPU_link(mat, "math_multiply", tnorfac, stencil, &tnorfac);
1136                                                 
1137                                                 if( !init_done ) {
1138                                                         // copy shi->vn to vNorg and vNacc, set magnitude to 1
1139                                                         GPU_link(mat, "mtex_bump_normals_init", shi->vn, &vNorg, &vNacc, &fPrevMagnitude);
1140                                                         iBumpSpacePrev = 0;
1141                                                         init_done = 1;
1142                                                 }
1143                                                 
1144                                                 // find current bump space
1145                                                 if( mtex->texflag & MTEX_BUMP_OBJECTSPACE )
1146                                                         iBumpSpace = 1;
1147                                                 else if( mtex->texflag & MTEX_BUMP_TEXTURESPACE )
1148                                                         iBumpSpace = 2;
1149                                                 else
1150                                                         iBumpSpace = 4; // ViewSpace
1151                                                 
1152                                                 // re-initialize if bump space changed
1153                                                 if( iBumpSpacePrev != iBumpSpace ) {
1154                                                         
1155                                                         if( mtex->texflag & MTEX_BUMP_OBJECTSPACE ) 
1156                                                                 GPU_link( mat, "mtex_bump_init_objspace",
1157                                                                                   surf_pos, vNorg, 
1158                                                                           GPU_builtin(GPU_VIEW_MATRIX), GPU_builtin(GPU_INVERSE_VIEW_MATRIX), GPU_builtin(GPU_OBJECT_MATRIX),  GPU_builtin(GPU_INVERSE_OBJECT_MATRIX), 
1159                                                                           fPrevMagnitude, vNacc,
1160                                                                                   &fPrevMagnitude, &vNacc, 
1161                                                                           &vR1, &vR2, &fDet );
1162                                                                 
1163                                                         else if( mtex->texflag & MTEX_BUMP_TEXTURESPACE )
1164                                                                 GPU_link( mat, "mtex_bump_init_texturespace",
1165                                                                                   surf_pos, vNorg, 
1166                                                                           fPrevMagnitude, vNacc,
1167                                                                                   &fPrevMagnitude, &vNacc, 
1168                                                                           &vR1, &vR2, &fDet );
1169                                                                 
1170                                                         else
1171                                                                 GPU_link( mat, "mtex_bump_init_viewspace",
1172                                                                                   surf_pos, vNorg, 
1173                                                                           fPrevMagnitude, vNacc,
1174                                                                                   &fPrevMagnitude, &vNacc, 
1175                                                                           &vR1, &vR2, &fDet );
1176                                                         
1177                                                         iBumpSpacePrev = iBumpSpace;
1178                                                 }
1179                                                 
1180                                                 
1181                                                 if(found_deriv_map) {
1182                                                         GPU_link( mat, "mtex_bump_deriv", 
1183                                                                   texco, GPU_image(tex->ima, &tex->iuser), GPU_uniform(&ima_x), GPU_uniform(&ima_y), tnorfac,
1184                                                                   &dBs, &dBt );
1185                                                 }
1186                                                 else if( mtex->texflag & MTEX_3TAP_BUMP )
1187                                                         GPU_link( mat, "mtex_bump_tap3", 
1188                                                                   texco, GPU_image(tex->ima, &tex->iuser), tnorfac,
1189                                                                   &dBs, &dBt );
1190                                                 else if( mtex->texflag & MTEX_5TAP_BUMP )
1191                                                         GPU_link( mat, "mtex_bump_tap5",
1192                                                                   texco, GPU_image(tex->ima, &tex->iuser), tnorfac,
1193                                                                   &dBs, &dBt );
1194                                                 else if( mtex->texflag & MTEX_BICUBIC_BUMP ){
1195                                                         if(GPU_bicubic_bump_support()){
1196                                                                 GPU_link( mat, "mtex_bump_bicubic",
1197                                                                                 texco, GPU_image(tex->ima, &tex->iuser), tnorfac,
1198                                                                                 &dBs, &dBt );
1199                                                         }else{
1200                                                                 GPU_link( mat, "mtex_bump_tap5",
1201                                                                                 texco, GPU_image(tex->ima, &tex->iuser), tnorfac,
1202                                                                                 &dBs, &dBt );
1203                                                         }
1204                                                 }
1205                                                 
1206                                                 
1207                                                 if( mtex->texflag & MTEX_BUMP_TEXTURESPACE ) {
1208                                                         float imag_tspace_dimension_y = aspect*imag_tspace_dimension_x;
1209                                                         GPU_link( mat, "mtex_bump_apply_texspace",
1210                                                                   fDet, dBs, dBt, vR1, vR2, 
1211                                                                   GPU_image(tex->ima, &tex->iuser), texco,
1212                                                                           GPU_uniform(&imag_tspace_dimension_x), GPU_uniform(&imag_tspace_dimension_y), vNacc,
1213                                                                   &vNacc, &shi->vn );
1214                                                 } else
1215                                                         GPU_link( mat, "mtex_bump_apply",
1216                                                                   fDet, dBs, dBt, vR1, vR2, vNacc,
1217                                                                   &vNacc, &shi->vn );
1218                                                 
1219                                         }
1220                                 }
1221                                 
1222                                 GPU_link(mat, "vec_math_negate", shi->vn, &orn);
1223                         }
1224
1225                         if((mtex->mapto & MAP_VARS)) {
1226                                 if(rgbnor & TEX_RGB) {
1227                                         if(talpha)
1228                                                 GPU_link(mat, "mtex_alpha_from_col", trgb, &tin);
1229                                         else
1230                                                 GPU_link(mat, "mtex_rgbtoint", trgb, &tin);
1231                                 }
1232
1233                                 if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_REF) {
1234                                         GPUNodeLink *difffac;
1235
1236                                         if(mtex->difffac == 1.0f) difffac = stencil;
1237                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->difffac), stencil, &difffac);
1238
1239                                         texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->refl, tin, difffac, mtex->blendtype, &shi->refl);
1240                                         GPU_link(mat, "mtex_value_clamp_positive", shi->refl, &shi->refl);
1241                                 }
1242                                 if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_SPEC) {
1243                                         GPUNodeLink *specfac;
1244
1245                                         if(mtex->specfac == 1.0f) specfac = stencil;
1246                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->specfac), stencil, &specfac);
1247
1248                                         texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->spec, tin, specfac, mtex->blendtype, &shi->spec);
1249                                         GPU_link(mat, "mtex_value_clamp_positive", shi->spec, &shi->spec);
1250                                 }
1251                                 if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_EMIT) {
1252                                         GPUNodeLink *emitfac;
1253
1254                                         if(mtex->emitfac == 1.0f) emitfac = stencil;
1255                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->emitfac), stencil, &emitfac);
1256
1257                                         texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->emit, tin, emitfac, mtex->blendtype, &shi->emit);
1258                                         GPU_link(mat, "mtex_value_clamp_positive", shi->emit, &shi->emit);
1259                                 }
1260                                 if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_HAR) {
1261                                         GPUNodeLink *hardfac;
1262
1263                                         if(mtex->hardfac == 1.0f) hardfac = stencil;
1264                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->hardfac), stencil, &hardfac);
1265
1266                                         GPU_link(mat, "mtex_har_divide", shi->har, &shi->har);
1267                                         texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->har, tin, hardfac, mtex->blendtype, &shi->har);
1268                                         GPU_link(mat, "mtex_har_multiply_clamp", shi->har, &shi->har);
1269                                 }
1270                                 if(mtex->mapto & MAP_ALPHA) {
1271                                         GPUNodeLink *alphafac;
1272
1273                                         if(mtex->alphafac == 1.0f) alphafac = stencil;
1274                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->alphafac), stencil, &alphafac);
1275
1276                                         texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->alpha, tin, alphafac, mtex->blendtype, &shi->alpha);
1277                                         GPU_link(mat, "mtex_value_clamp", shi->alpha, &shi->alpha);
1278                                 }
1279                                 if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_AMB) {
1280                                         GPUNodeLink *ambfac;
1281
1282                                         if(mtex->ambfac == 1.0f) ambfac = stencil;
1283                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->ambfac), stencil, &ambfac);
1284
1285                                         texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->amb, tin, ambfac, mtex->blendtype, &shi->amb);
1286                                         GPU_link(mat, "mtex_value_clamp", shi->amb, &shi->amb);
1287                                 }
1288                         }
1289                 }
1290         }
1291 }
1292
1293 void GPU_shadeinput_set(GPUMaterial *mat, Material *ma, GPUShadeInput *shi)
1294 {
1295         float hard = ma->har;
1296
1297         memset(shi, 0, sizeof(*shi));
1298
1299         shi->gpumat = mat;
1300         shi->mat = ma;
1301
1302         GPU_link(mat, "set_rgb", GPU_uniform(&ma->r), &shi->rgb);
1303         GPU_link(mat, "set_rgb", GPU_uniform(&ma->specr), &shi->specrgb);
1304         GPU_link(mat, "shade_norm", GPU_builtin(GPU_VIEW_NORMAL), &shi->vn);
1305         GPU_link(mat, "set_value", GPU_uniform(&ma->alpha), &shi->alpha);
1306         GPU_link(mat, "set_value", GPU_uniform(&ma->ref), &shi->refl);
1307         GPU_link(mat, "set_value", GPU_uniform(&ma->spec), &shi->spec);
1308         GPU_link(mat, "set_value", GPU_uniform(&ma->emit), &shi->emit);
1309         GPU_link(mat, "set_value", GPU_uniform(&hard), &shi->har);
1310         GPU_link(mat, "set_value", GPU_uniform(&ma->amb), &shi->amb);
1311         GPU_link(mat, "shade_view", GPU_builtin(GPU_VIEW_POSITION), &shi->view);
1312         GPU_link(mat, "vcol_attribute", GPU_attribute(CD_MCOL, ""), &shi->vcol);
1313         if(gpu_do_color_management(mat))
1314                 GPU_link(mat, "srgb_to_linearrgb", shi->vcol, &shi->vcol);
1315         GPU_link(mat, "texco_refl", shi->vn, shi->view, &shi->ref);
1316 }
1317
1318 void GPU_shaderesult_set(GPUShadeInput *shi, GPUShadeResult *shr)
1319 {
1320         GPUMaterial *mat= shi->gpumat;
1321         GPUNodeLink *emit, *ulinfac, *ulogfac, *mistfac;
1322         Material *ma= shi->mat;
1323         World *world= mat->scene->world;
1324         float linfac, logfac, misttype;
1325
1326         memset(shr, 0, sizeof(*shr));
1327
1328         if(ma->mode & MA_VERTEXCOLP)
1329                 shi->rgb = shi->vcol;
1330
1331         do_material_tex(shi);
1332
1333         if((ma->mode & MA_TRANSP) && (ma->mode & MA_ZTRANSP))
1334                 GPU_material_enable_alpha(mat);
1335
1336         if((mat->scene->gm.flag & GAME_GLSL_NO_LIGHTS) || (ma->mode & MA_SHLESS)) {
1337                 shr->combined = shi->rgb;
1338                 shr->alpha = shi->alpha;
1339                 GPU_link(mat, "set_rgb", shi->rgb, &shr->diff);
1340                 GPU_link(mat, "set_rgb_zero", &shr->spec);
1341         }
1342         else {
1343                 if(GPU_link_changed(shi->emit) || ma->emit != 0.0f) {
1344                         if((ma->mode & (MA_VERTEXCOL|MA_VERTEXCOLP))== MA_VERTEXCOL) {
1345                                 GPU_link(mat, "shade_add", shi->emit, shi->vcol, &emit);
1346                                 GPU_link(mat, "shade_mul", emit, shi->rgb, &shr->diff);
1347                         }
1348                         else
1349                                 GPU_link(mat, "shade_mul_value", shi->emit, shi->rgb, &shr->diff);
1350                 }
1351                 else
1352                         GPU_link(mat, "set_rgb_zero", &shr->diff);
1353
1354                 GPU_link(mat, "set_rgb_zero", &shr->spec);
1355
1356                 material_lights(shi, shr);
1357
1358                 shr->combined = shr->diff;
1359                 shr->alpha = shi->alpha;
1360
1361                 if(world) {
1362                         /* exposure correction */
1363                         if(world->exp!=0.0f || world->range!=1.0f) {
1364                                 linfac= 1.0f + powf((2.0f*world->exp + 0.5f), -10);
1365                                 logfac= logf((linfac-1.0f)/linfac)/world->range;
1366
1367                                 GPU_link(mat, "set_value", GPU_uniform(&linfac), &ulinfac);
1368                                 GPU_link(mat, "set_value", GPU_uniform(&logfac), &ulogfac);
1369
1370                                 GPU_link(mat, "shade_exposure_correct", shr->combined,
1371                                         ulinfac, ulogfac, &shr->combined);
1372                                 GPU_link(mat, "shade_exposure_correct", shr->spec,
1373                                         ulinfac, ulogfac, &shr->spec);
1374                         }
1375
1376                         /* ambient color */
1377                         if(world->ambr!=0.0f || world->ambg!=0.0f || world->ambb!=0.0f) {
1378                                 if(GPU_link_changed(shi->amb) || ma->amb != 0.0f)
1379                                         GPU_link(mat, "shade_maddf", shr->combined, GPU_uniform(&ma->amb),
1380                                                 GPU_uniform(&world->ambr), &shr->combined);
1381                         }
1382                 }
1383
1384                 if(ma->mode & MA_RAMP_COL) ramp_diffuse_result(shi, &shr->combined);
1385                 if(ma->mode & MA_RAMP_SPEC) ramp_spec_result(shi, &shr->spec);
1386
1387                 if(GPU_link_changed(shi->spec) || ma->spec != 0.0f)
1388                         GPU_link(mat, "shade_add", shr->combined, shr->spec, &shr->combined);
1389         }
1390
1391         GPU_link(mat, "mtex_alpha_to_col", shr->combined, shr->alpha, &shr->combined);
1392
1393         if(ma->shade_flag & MA_OBCOLOR)
1394                 GPU_link(mat, "shade_obcolor", shr->combined, GPU_builtin(GPU_OBCOLOR), &shr->combined);
1395
1396         if(world && (world->mode & WO_MIST) && !(ma->mode & MA_NOMIST)) {
1397                 misttype = world->mistype;
1398
1399                 GPU_link(mat, "shade_mist_factor", GPU_builtin(GPU_VIEW_POSITION),
1400                         GPU_uniform(&world->miststa), GPU_uniform(&world->mistdist),
1401                         GPU_uniform(&misttype), GPU_uniform(&world->misi), &mistfac);
1402
1403                 GPU_link(mat, "mix_blend", mistfac, shr->combined,
1404                         GPU_uniform(&world->horr), &shr->combined);
1405         }
1406
1407         if(!((ma->mode & MA_TRANSP) && (ma->mode & MA_ZTRANSP))) {
1408                 if(world && (GPU_link_changed(shr->alpha) || ma->alpha != 1.0f))
1409                         GPU_link(mat, "shade_world_mix", GPU_uniform(&world->horr),
1410                                 shr->combined, &shr->combined);
1411
1412                 GPU_link(mat, "shade_alpha_opaque", shr->combined, &shr->combined);
1413         }
1414
1415         if(ma->shade_flag & MA_OBCOLOR) {
1416                 mat->obcolalpha = 1;
1417                 GPU_link(mat, "shade_alpha_obcolor", shr->combined, GPU_builtin(GPU_OBCOLOR), &shr->combined);
1418         }
1419 }
1420
1421 static GPUNodeLink *GPU_blender_material(GPUMaterial *mat, Material *ma)
1422 {
1423         GPUShadeInput shi;
1424         GPUShadeResult shr;
1425
1426         GPU_shadeinput_set(mat, ma, &shi);
1427         GPU_shaderesult_set(&shi, &shr);
1428
1429         return shr.combined;
1430 }
1431
1432 GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma)
1433 {
1434         GPUMaterial *mat;
1435         GPUNodeLink *outlink;
1436         LinkData *link;
1437
1438         for(link=ma->gpumaterial.first; link; link=link->next)
1439                 if(((GPUMaterial*)link->data)->scene == scene)
1440                         return link->data;
1441
1442         /* allocate material */
1443         mat = GPU_material_construct_begin(ma);
1444         mat->scene = scene;
1445
1446         if(!(scene->gm.flag & GAME_GLSL_NO_NODES) && ma->nodetree && ma->use_nodes) {
1447                 /* create nodes */
1448                 ntreeGPUMaterialNodes(ma->nodetree, mat);
1449         }
1450         else {
1451                 /* create material */
1452                 outlink = GPU_blender_material(mat, ma);
1453                 GPU_material_output_link(mat, outlink);
1454         }
1455
1456         if(!scene_use_new_shading_nodes(scene)) {
1457                 if(gpu_do_color_management(mat))
1458                         if(mat->outlink)
1459                                 GPU_link(mat, "linearrgb_to_srgb", mat->outlink, &mat->outlink);
1460         }
1461
1462
1463         GPU_material_construct_end(mat);
1464
1465         /* note that even if building the shader fails in some way, we still keep
1466            it to avoid trying to compile again and again, and simple do not use
1467            the actual shader on drawing */
1468
1469         link = MEM_callocN(sizeof(LinkData), "GPUMaterialLink");
1470         link->data = mat;
1471         BLI_addtail(&ma->gpumaterial, link);
1472
1473         return mat;
1474 }
1475
1476 void GPU_materials_free(void)
1477 {
1478         Object *ob;
1479         Material *ma;
1480         extern Material defmaterial;
1481
1482         for(ma=G.main->mat.first; ma; ma=ma->id.next)
1483                 GPU_material_free(ma);
1484
1485         GPU_material_free(&defmaterial);
1486
1487         for(ob=G.main->object.first; ob; ob=ob->id.next)
1488                 GPU_lamp_free(ob);
1489 }
1490
1491 /* Lamps and shadow buffers */
1492
1493 void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[][4])
1494 {
1495         float mat[4][4];
1496
1497         lamp->lay = lay;
1498         lamp->hide = hide;
1499
1500         copy_m4_m4(mat, obmat);
1501         normalize_m4(mat);
1502
1503         copy_v3_v3(lamp->vec, mat[2]);
1504         copy_v3_v3(lamp->co, mat[3]);
1505         copy_m4_m4(lamp->obmat, mat);
1506         invert_m4_m4(lamp->imat, mat);
1507 }
1508
1509 void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float energy)
1510 {
1511         lamp->energy = energy;
1512         if(lamp->mode & LA_NEG) lamp->energy= -lamp->energy;
1513
1514         lamp->col[0]= r* lamp->energy;
1515         lamp->col[1]= g* lamp->energy;
1516         lamp->col[2]= b* lamp->energy;
1517 }
1518
1519 static void gpu_lamp_from_blender(Scene *scene, Object *ob, Object *par, Lamp *la, GPULamp *lamp)
1520 {
1521         float temp, angle, pixsize, wsize;
1522
1523         lamp->scene = scene;
1524         lamp->ob = ob;
1525         lamp->par = par;
1526         lamp->la = la;
1527
1528         /* add_render_lamp */
1529         lamp->mode = la->mode;
1530         lamp->type = la->type;
1531
1532         lamp->energy = la->energy;
1533         if(lamp->mode & LA_NEG) lamp->energy= -lamp->energy;
1534
1535         lamp->col[0]= la->r*lamp->energy;
1536         lamp->col[1]= la->g*lamp->energy;
1537         lamp->col[2]= la->b*lamp->energy;
1538
1539         GPU_lamp_update(lamp, ob->lay, (ob->restrictflag & OB_RESTRICT_RENDER), ob->obmat);
1540
1541         lamp->spotsi= la->spotsize;
1542         if(lamp->mode & LA_HALO)
1543                 if(lamp->spotsi > 170.0f)
1544                         lamp->spotsi = 170.0f;
1545         lamp->spotsi= cosf((float)M_PI*lamp->spotsi/360.0f);
1546         lamp->spotbl= (1.0f - lamp->spotsi)*la->spotblend;
1547         lamp->k= la->k;
1548
1549         lamp->dist= la->dist;
1550         lamp->falloff_type= la->falloff_type;
1551         lamp->att1= la->att1;
1552         lamp->att2= la->att2;
1553         lamp->curfalloff= la->curfalloff;
1554
1555         /* initshadowbuf */
1556         lamp->bias = 0.02f*la->bias;
1557         lamp->size = la->bufsize;
1558         lamp->d= la->clipsta;
1559         lamp->clipend= la->clipend;
1560
1561         /* arbitrary correction for the fact we do no soft transition */
1562         lamp->bias *= 0.25f;
1563
1564         /* makeshadowbuf */
1565         angle= saacos(lamp->spotsi);
1566         temp= 0.5f*lamp->size*cosf(angle)/sinf(angle);
1567         pixsize= (lamp->d)/temp;
1568         wsize= pixsize*0.5f*lamp->size;
1569                 
1570         perspective_m4( lamp->winmat,-wsize, wsize, -wsize, wsize, lamp->d, lamp->clipend);
1571 }
1572
1573 static void gpu_lamp_shadow_free(GPULamp *lamp)
1574 {
1575         if(lamp->tex) {
1576                 GPU_texture_free(lamp->tex);
1577                 lamp->tex= NULL;
1578         }
1579         if(lamp->fb) {
1580                 GPU_framebuffer_free(lamp->fb);
1581                 lamp->fb= NULL;
1582         }
1583 }
1584
1585 GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par)
1586 {
1587         Lamp *la;
1588         GPULamp *lamp;
1589         LinkData *link;
1590
1591         for(link=ob->gpulamp.first; link; link=link->next) {
1592                 lamp = (GPULamp*)link->data;
1593
1594                 if(lamp->par == par && lamp->scene == scene)
1595                         return link->data;
1596         }
1597
1598         lamp = MEM_callocN(sizeof(GPULamp), "GPULamp");
1599
1600         link = MEM_callocN(sizeof(LinkData), "GPULampLink");
1601         link->data = lamp;
1602         BLI_addtail(&ob->gpulamp, link);
1603
1604         la = ob->data;
1605         gpu_lamp_from_blender(scene, ob, par, la, lamp);
1606
1607         if(la->type==LA_SPOT && (la->mode & LA_SHAD_BUF)) {
1608                 /* opengl */
1609                 lamp->fb = GPU_framebuffer_create();
1610                 if(!lamp->fb) {
1611                         gpu_lamp_shadow_free(lamp);
1612                         return lamp;
1613                 }
1614
1615                 lamp->tex = GPU_texture_create_depth(lamp->size, lamp->size, NULL);
1616                 if(!lamp->tex) {
1617                         gpu_lamp_shadow_free(lamp);
1618                         return lamp;
1619                 }
1620
1621                 if(!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex, NULL)) {
1622                         gpu_lamp_shadow_free(lamp);
1623                         return lamp;
1624                 }
1625
1626                 GPU_framebuffer_restore();
1627         }
1628
1629         return lamp;
1630 }
1631
1632 void GPU_lamp_free(Object *ob)
1633 {
1634         GPULamp *lamp;
1635         LinkData *link;
1636         LinkData *nlink;
1637         Material *ma;
1638
1639         for(link=ob->gpulamp.first; link; link=link->next) {
1640                 lamp = link->data;
1641
1642                 while(lamp->materials.first) {
1643                         nlink = lamp->materials.first;
1644                         ma = nlink->data;
1645                         BLI_freelinkN(&lamp->materials, nlink);
1646
1647                         if(ma->gpumaterial.first)
1648                                 GPU_material_free(ma);
1649                 }
1650
1651                 gpu_lamp_shadow_free(lamp);
1652
1653                 MEM_freeN(lamp);
1654         }
1655
1656         BLI_freelistN(&ob->gpulamp);
1657 }
1658
1659 int GPU_lamp_has_shadow_buffer(GPULamp *lamp)
1660 {
1661         return (!(lamp->scene->gm.flag & GAME_GLSL_NO_SHADOWS) &&
1662                         !(lamp->scene->gm.flag & GAME_GLSL_NO_LIGHTS) &&
1663                         lamp->tex && lamp->fb);
1664 }
1665
1666 void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[][4], int *winsize, float winmat[][4])
1667 {
1668         float rangemat[4][4], persmat[4][4];
1669
1670         /* initshadowbuf */
1671         invert_m4_m4(lamp->viewmat, lamp->obmat);
1672         normalize_v3(lamp->viewmat[0]);
1673         normalize_v3(lamp->viewmat[1]);
1674         normalize_v3(lamp->viewmat[2]);
1675
1676         /* makeshadowbuf */
1677         mult_m4_m4m4(persmat, lamp->winmat, lamp->viewmat);
1678
1679         /* opengl depth buffer is range 0.0..1.0 instead of -1.0..1.0 in blender */
1680         unit_m4(rangemat);
1681         rangemat[0][0] = 0.5f;
1682         rangemat[1][1] = 0.5f;
1683         rangemat[2][2] = 0.5f;
1684         rangemat[3][0] = 0.5f;
1685         rangemat[3][1] = 0.5f;
1686         rangemat[3][2] = 0.5f;
1687
1688         mult_m4_m4m4(lamp->persmat, rangemat, persmat);
1689
1690         /* opengl */
1691         glDisable(GL_SCISSOR_TEST);
1692         GPU_framebuffer_texture_bind(lamp->fb, lamp->tex,
1693                 GPU_texture_opengl_width(lamp->tex), GPU_texture_opengl_height(lamp->tex));
1694
1695         /* set matrices */
1696         copy_m4_m4(viewmat, lamp->viewmat);
1697         copy_m4_m4(winmat, lamp->winmat);
1698         *winsize = lamp->size;
1699 }
1700
1701 void GPU_lamp_shadow_buffer_unbind(GPULamp *lamp)
1702 {
1703         GPU_framebuffer_texture_unbind(lamp->fb, lamp->tex);
1704         GPU_framebuffer_restore();
1705         glEnable(GL_SCISSOR_TEST);
1706 }
1707
1708 int GPU_lamp_shadow_layer(GPULamp *lamp)
1709 {
1710         if(lamp->fb && lamp->tex && (lamp->mode & (LA_LAYER|LA_LAYER_SHADOW)))
1711                 return lamp->lay;
1712         else
1713                 return -1;
1714 }
1715
1716 /* export the GLSL shader */
1717
1718 GPUShaderExport *GPU_shader_export(struct Scene *scene, struct Material *ma)
1719 {
1720         static struct {
1721                 GPUBuiltin gputype;
1722                 GPUDynamicType dynamictype;
1723                 GPUDataType datatype;
1724         } builtins[] = { 
1725                 { GPU_VIEW_MATRIX, GPU_DYNAMIC_OBJECT_VIEWMAT, GPU_DATA_16F },
1726                 { GPU_INVERSE_VIEW_MATRIX, GPU_DYNAMIC_OBJECT_VIEWIMAT, GPU_DATA_16F },
1727                 { GPU_OBJECT_MATRIX, GPU_DYNAMIC_OBJECT_MAT, GPU_DATA_16F },
1728                 { GPU_INVERSE_OBJECT_MATRIX, GPU_DYNAMIC_OBJECT_IMAT, GPU_DATA_16F },
1729                 { GPU_OBCOLOR, GPU_DYNAMIC_OBJECT_COLOR, GPU_DATA_4F },
1730                 { GPU_AUTO_BUMPSCALE, GPU_DYNAMIC_OBJECT_AUTOBUMPSCALE, GPU_DATA_1F },
1731                 { 0 }
1732         };
1733
1734         GPUShaderExport *shader = NULL;
1735         GPUPass *pass;
1736         GPUInput *input;
1737         GPUMaterial *mat;
1738         GPUInputUniform *uniform;
1739         GPUInputAttribute *attribute;
1740         GLint lastbindcode;
1741         int i, liblen, fraglen;
1742
1743         if(!GPU_glsl_support())
1744                 return NULL;
1745
1746         mat = GPU_material_from_blender(scene, ma);
1747         pass = (mat)? mat->pass: NULL;
1748
1749         if(pass && pass->fragmentcode && pass->vertexcode) {
1750                 shader = MEM_callocN(sizeof(GPUShaderExport), "GPUShaderExport");
1751
1752                 for(input = pass->inputs.first; input; input = input->next) {
1753                         uniform = MEM_callocN(sizeof(GPUInputUniform), "GPUInputUniform");
1754
1755                         if(input->ima) {
1756                                 /* image sampler uniform */
1757                                 uniform->type = GPU_DYNAMIC_SAMPLER_2DIMAGE;
1758                                 uniform->datatype = GPU_DATA_1I;
1759                                 uniform->image = input->ima;
1760                                 uniform->texnumber = input->texid;
1761                                 BLI_strncpy(uniform->varname, input->shadername, sizeof(uniform->varname));
1762                         }
1763                         else if(input->tex) {
1764                                 /* generated buffer */
1765                                 uniform->texnumber = input->texid;
1766                                 uniform->datatype = GPU_DATA_1I;
1767                                 BLI_strncpy(uniform->varname, input->shadername, sizeof(uniform->varname));
1768
1769                                 switch(input->textype) {
1770                                 case GPU_SHADOW2D:
1771                                         uniform->type = GPU_DYNAMIC_SAMPLER_2DSHADOW;
1772                                         uniform->lamp = input->dynamicdata;
1773                                         break;
1774                                 case GPU_TEX2D:
1775                                         if(GPU_texture_opengl_bindcode(input->tex)) {
1776                                                 uniform->type = GPU_DYNAMIC_SAMPLER_2DBUFFER;
1777                                                 glGetIntegerv(GL_TEXTURE_BINDING_2D, &lastbindcode);
1778                                                 glBindTexture(GL_TEXTURE_2D, GPU_texture_opengl_bindcode(input->tex));
1779                                                 uniform->texsize = GPU_texture_opengl_width(input->tex) * GPU_texture_opengl_height(input->tex);
1780                                                 uniform->texpixels = MEM_mallocN(uniform->texsize*4, "RGBApixels");
1781                                                 glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, uniform->texpixels); 
1782                                                 glBindTexture(GL_TEXTURE_2D, lastbindcode);
1783                                         }
1784                                         break;
1785                                 }
1786                         }
1787                         else {
1788                                 uniform->type = input->dynamictype;
1789                                 BLI_strncpy(uniform->varname, input->shadername, sizeof(uniform->varname));
1790                                 switch(input->type) {
1791                                 case 1:
1792                                         uniform->datatype = GPU_DATA_1F;
1793                                         break;
1794                                 case 2:
1795                                         uniform->datatype = GPU_DATA_2F;
1796                                         break;
1797                                 case 3:
1798                                         uniform->datatype = GPU_DATA_3F;
1799                                         break;
1800                                 case 4:
1801                                         uniform->datatype = GPU_DATA_4F;
1802                                         break;
1803                                 case 9:
1804                                         uniform->datatype = GPU_DATA_9F;
1805                                         break;
1806                                 case 16:
1807                                         uniform->datatype = GPU_DATA_16F;
1808                                         break;
1809                                 }
1810
1811                                 if(uniform->type >= GPU_DYNAMIC_LAMP_FIRST && uniform->type <= GPU_DYNAMIC_LAMP_LAST)
1812                                         uniform->lamp = input->dynamicdata;
1813                         }
1814
1815                         if(uniform->type != GPU_DYNAMIC_NONE)
1816                                 BLI_addtail(&shader->uniforms, uniform);
1817                         else
1818                                 MEM_freeN(uniform);
1819                 }
1820
1821                 /* process builtin uniform */
1822                 for(i=0; builtins[i].gputype; i++) {
1823                         if(mat->builtins & builtins[i].gputype) {
1824                                 uniform = MEM_callocN(sizeof(GPUInputUniform), "GPUInputUniform");
1825                                 uniform->type = builtins[i].dynamictype;
1826                                 uniform->datatype = builtins[i].datatype;
1827                                 BLI_strncpy(uniform->varname, GPU_builtin_name(builtins[i].gputype), sizeof(uniform->varname));
1828                                 BLI_addtail(&shader->uniforms, uniform);
1829                         }
1830                 }
1831
1832                 // now link fragement shader with library shader
1833                 // TBD: remove the function that are not used in the main function
1834                 liblen = (pass->libcode) ? strlen(pass->libcode) : 0;
1835                 fraglen = strlen(pass->fragmentcode);
1836                 shader->fragment = (char *)MEM_mallocN(liblen+fraglen+1, "GPUFragShader");
1837                 if(pass->libcode)
1838                         memcpy(shader->fragment, pass->libcode, liblen);
1839                 memcpy(&shader->fragment[liblen], pass->fragmentcode, fraglen);
1840                 shader->fragment[liblen+fraglen] = 0;
1841
1842                 // export the attribute
1843                 for(i=0; i<mat->attribs.totlayer; i++) {
1844                         attribute = MEM_callocN(sizeof(GPUInputAttribute), "GPUInputAttribute");
1845                         attribute->type = mat->attribs.layer[i].type;
1846                         attribute->number = mat->attribs.layer[i].glindex;
1847                         BLI_snprintf(attribute->varname, sizeof(attribute->varname), "att%d", mat->attribs.layer[i].attribid);
1848
1849                         switch(attribute->type) {
1850                         case CD_TANGENT:
1851                                 attribute->datatype = GPU_DATA_4F;
1852                                 break;
1853                         case CD_MTFACE:
1854                                 attribute->datatype = GPU_DATA_2F;
1855                                 attribute->name = mat->attribs.layer[i].name;
1856                                 break;
1857                         case CD_MCOL:
1858                                 attribute->datatype = GPU_DATA_4UB;
1859                                 attribute->name = mat->attribs.layer[i].name;
1860                                 break;
1861                         case CD_ORCO:
1862                                 attribute->datatype = GPU_DATA_3F;
1863                                 break;
1864                         }
1865
1866                         if(attribute->datatype != GPU_DATA_NONE)
1867                                 BLI_addtail(&shader->attributes, attribute);
1868                         else
1869                                 MEM_freeN(attribute);
1870                 }
1871
1872                 // export the vertex shader
1873                 shader->vertex = BLI_strdup(pass->vertexcode);
1874         }
1875
1876         return shader;
1877 }
1878
1879 void GPU_free_shader_export(GPUShaderExport *shader)
1880 {
1881         GPUInputUniform *uniform;
1882
1883         if(shader == NULL)
1884                 return;
1885
1886         for(uniform = shader->uniforms.first; uniform; uniform=uniform->next)
1887                 if(uniform->texpixels)
1888                         MEM_freeN(uniform->texpixels);
1889
1890         BLI_freelistN(&shader->uniforms);
1891         BLI_freelistN(&shader->attributes);
1892
1893         if(shader->vertex)
1894                 MEM_freeN(shader->vertex);
1895         if(shader->fragment)
1896                 MEM_freeN(shader->fragment);
1897
1898         MEM_freeN(shader);
1899 }
1900