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