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