doxygen: prevent GPL license block from being parsed as doxygen comment.
[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 #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 static 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_iter = dob->ob;
780
781                                 if(ob_iter->type==OB_LAMP) {
782                                         copy_m4_m4(ob_iter->obmat, dob->mat);
783
784                                         lamp = GPU_lamp_from_blender(shi->gpumat->scene, ob_iter, ob);
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;
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         int iFirstTimeNMap=1;
898
899         GPU_link(mat, "set_value", GPU_uniform(&one), &stencil);
900
901         GPU_link(mat, "texco_norm", GPU_builtin(GPU_VIEW_NORMAL), &texco_norm);
902         GPU_link(mat, "texco_orco", GPU_attribute(CD_ORCO, ""), &texco_orco);
903         GPU_link(mat, "texco_object", GPU_builtin(GPU_INVERSE_VIEW_MATRIX),
904                 GPU_builtin(GPU_INVERSE_OBJECT_MATRIX),
905                 GPU_builtin(GPU_VIEW_POSITION), &texco_object);
906         //GPU_link(mat, "texco_tangent", GPU_attribute(CD_TANGENT, ""), &texco_tangent);
907         GPU_link(mat, "texco_global", GPU_builtin(GPU_INVERSE_VIEW_MATRIX),
908                 GPU_builtin(GPU_VIEW_POSITION), &texco_global);
909
910         orn= texco_norm;
911
912         /* go over texture slots */
913         for(tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) {
914                 /* separate tex switching */
915                 if(ma->septex & (1<<tex_nr)) continue;
916                 
917                 if(ma->mtex[tex_nr]) {
918                         mtex= ma->mtex[tex_nr];
919                         
920                         tex= mtex->tex;
921                         if(tex==0) continue;
922
923                         /* which coords */
924                         if(mtex->texco==TEXCO_ORCO)
925                                 texco= texco_orco;
926                         else if(mtex->texco==TEXCO_OBJECT)
927                                 texco= texco_object;
928                         else if(mtex->texco==TEXCO_NORM)
929                                 texco= orn;
930                         else if(mtex->texco==TEXCO_TANGENT)
931                                 texco= texco_object;
932                         else if(mtex->texco==TEXCO_GLOB)
933                                 texco= texco_global;
934                         else if(mtex->texco==TEXCO_REFL)
935                                 texco= shi->ref;
936                         else if(mtex->texco==TEXCO_UV) {
937                                 if(1) { //!(texco_uv && strcmp(mtex->uvname, lastuvname) == 0)) {
938                                         GPU_link(mat, "texco_uv", GPU_attribute(CD_MTFACE, mtex->uvname), &texco_uv);
939                                         lastuvname = mtex->uvname;
940                                 }
941                                 texco= texco_uv;
942                         }
943                         else
944                                 continue;
945
946                         /* in case of uv, this would just undo a multiplication in texco_uv */
947                         if(mtex->texco != TEXCO_UV)
948                                 GPU_link(mat, "mtex_2d_mapping", texco, &texco);
949
950                         if(mtex->size[0] != 1.0f || mtex->size[1] != 1.0f || mtex->size[2] != 1.0f)
951                                 GPU_link(mat, "mtex_mapping_size", texco, GPU_uniform(mtex->size), &texco);
952
953                         ofs[0] = mtex->ofs[0] + 0.5f - 0.5f*mtex->size[0];
954                         ofs[1] = mtex->ofs[1] + 0.5f - 0.5f*mtex->size[1];
955                         ofs[2] = 0.0f;
956                         if(ofs[0] != 0.0f || ofs[1] != 0.0f || ofs[2] != 0.0f)
957                                 GPU_link(mat, "mtex_mapping_ofs", texco, GPU_uniform(ofs), &texco);
958
959                         talpha = 0;
960                         rgbnor = 0;
961
962                         if(tex && tex->type == TEX_IMAGE && tex->ima) {
963                                 GPU_link(mat, "mtex_image", texco, GPU_image(tex->ima, &tex->iuser), &tin, &trgb);
964                                 rgbnor= TEX_RGB;
965
966                                 if(tex->imaflag & TEX_USEALPHA)
967                                         talpha= 1;
968                         }
969                         else continue;
970
971                         /* texture output */
972                         if((rgbnor & TEX_RGB) && (mtex->texflag & MTEX_RGBTOINT)) {
973                                 GPU_link(mat, "mtex_rgbtoint", trgb, &tin);
974                                 rgbnor -= TEX_RGB;
975                         }
976
977                         if(mtex->texflag & MTEX_NEGATIVE) {
978                                 if(rgbnor & TEX_RGB)
979                                         GPU_link(mat, "mtex_rgb_invert", trgb, &trgb);
980                                 else
981                                         GPU_link(mat, "mtex_value_invert", tin, &tin);
982                         }
983
984                         if(mtex->texflag & MTEX_STENCIL) {
985                                 if(rgbnor & TEX_RGB)
986                                         GPU_link(mat, "mtex_rgb_stencil", stencil, trgb, &stencil, &trgb);
987                                 else
988                                         GPU_link(mat, "mtex_value_stencil", stencil, tin, &stencil, &tin);
989                         }
990
991                         /* mapping */
992                         if(mtex->mapto & (MAP_COL+MAP_COLSPEC)) {
993                                 /* stencil maps on the texture control slider, not texture intensity value */
994                                 if((rgbnor & TEX_RGB)==0) {
995                                         GPU_link(mat, "set_rgb", GPU_uniform(&mtex->r), &tcol);
996                                 }
997                                 else {
998                                         GPU_link(mat, "set_rgba", trgb, &tcol);
999
1000                                         if(mtex->mapto & MAP_ALPHA)
1001                                                 GPU_link(mat, "set_value", stencil, &tin);
1002                                         else if(talpha)
1003                                                 GPU_link(mat, "mtex_alpha_from_col", trgb, &tin);
1004                                         else
1005                                                 GPU_link(mat, "set_value_one", &tin);
1006                                 }
1007
1008                                 if(tex->type==TEX_IMAGE)
1009                                         if(mat->scene->r.color_mgt_flag & R_COLOR_MANAGEMENT)
1010                                                 GPU_link(mat, "srgb_to_linearrgb", tcol, &tcol);
1011                                 
1012                                 if(mtex->mapto & MAP_COL) {
1013                                         GPUNodeLink *colfac;
1014
1015                                         if(mtex->colfac == 1.0f) colfac = stencil;
1016                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->colfac), stencil, &colfac);
1017
1018                                         texture_rgb_blend(mat, tcol, shi->rgb, tin, colfac, mtex->blendtype, &shi->rgb);
1019                                 }
1020                                 
1021                                 if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && (mtex->mapto & MAP_COLSPEC)) {
1022                                         GPUNodeLink *colspecfac;
1023
1024                                         if(mtex->colspecfac == 1.0f) colspecfac = stencil;
1025                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->colspecfac), stencil, &colspecfac);
1026
1027                                         texture_rgb_blend(mat, tcol, shi->specrgb, tin, colspecfac, mtex->blendtype, &shi->specrgb);
1028                                 }
1029                         }
1030
1031                         if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && (mtex->mapto & MAP_NORM)) {
1032                                 if(tex->type==TEX_IMAGE) {
1033                                         if(tex->imaflag & TEX_NORMALMAP) {
1034                                                 /* normalmap image */
1035                                                 GPU_link(mat, "mtex_normal", texco, GPU_image(tex->ima, &tex->iuser), &tnor );
1036                                                 
1037                                                 if(mtex->norfac < 0.0f)
1038                                                         GPU_link(mat, "mtex_negate_texnormal", tnor, &tnor);
1039
1040                                                 if(mtex->normapspace == MTEX_NSPACE_TANGENT)
1041                                                 {
1042                                                         if(iFirstTimeNMap!=0)
1043                                                         {
1044                                                                 // use unnormalized normal (this is how we bake it - closer to gamedev)
1045                                                                 GPUNodeLink *vNegNorm;
1046                                                                 GPU_link(mat, "vec_math_negate", GPU_builtin(GPU_VIEW_NORMAL), &vNegNorm);
1047                                                                 GPU_link(mat, "mtex_nspace_tangent", GPU_attribute(CD_TANGENT, ""), vNegNorm, tnor, &newnor);
1048                                                                 iFirstTimeNMap = 0;
1049                                                         }
1050                                                         else    // otherwise use accumulated perturbations
1051                                                         {
1052                                                                 GPU_link(mat, "mtex_nspace_tangent", GPU_attribute(CD_TANGENT, ""), shi->vn, tnor, &newnor);
1053                                                         }
1054                                                 }
1055                                                 else
1056                                                         newnor = tnor;
1057                                                 
1058                                                 norfac = MIN2(fabsf(mtex->norfac), 1.0);
1059                                                 
1060                                                 if(norfac == 1.0f && !GPU_link_changed(stencil)) {
1061                                                         shi->vn = newnor;
1062                                                 }
1063                                                 else {
1064                                                         tnorfac = GPU_uniform(&norfac);
1065         
1066                                                         if(GPU_link_changed(stencil))
1067                                                                 GPU_link(mat, "math_multiply", tnorfac, stencil, &tnorfac);
1068         
1069                                                         GPU_link(mat, "mtex_blend_normal", tnorfac, shi->vn, newnor, &shi->vn);
1070                                                 }
1071                                                 
1072                                         } else if( mtex->texflag & (MTEX_3TAP_BUMP|MTEX_5TAP_BUMP)) {
1073                                                 /* ntap bumpmap image */
1074                                                 int iBumpSpace;
1075                                                 float hScale = 0.1f; // compatibility adjustment factor for all bumpspace types
1076                                                 float hScaleTex = 13.0f; // factor for scaling texspace bumps
1077                                                 
1078                                                 GPUNodeLink *surf_pos = GPU_builtin(GPU_VIEW_POSITION);
1079                                                 GPUNodeLink *vR1, *vR2;
1080                                                 GPUNodeLink *dBs, *dBt, *fDet;
1081                                                 
1082                                                 if( mtex->texflag & MTEX_BUMP_TEXTURESPACE )
1083                                                         hScale = hScaleTex;
1084                                                 norfac = hScale * mtex->norfac;
1085                                                 tnorfac = GPU_uniform(&norfac);
1086                                                 
1087                                                 if(GPU_link_changed(stencil))
1088                                                         GPU_link(mat, "math_multiply", tnorfac, stencil, &tnorfac);
1089                                                 
1090                                                 if( !init_done ) {
1091                                                         // copy shi->vn to vNorg and vNacc, set magnitude to 1
1092                                                         GPU_link(mat, "mtex_bump_normals_init", shi->vn, &vNorg, &vNacc, &fPrevMagnitude);
1093                                                         iBumpSpacePrev = 0;
1094                                                         init_done = 1;
1095                                                 }
1096                                                 
1097                                                 // find current bump space
1098                                                 if( mtex->texflag & MTEX_BUMP_OBJECTSPACE )
1099                                                         iBumpSpace = 1;
1100                                                 else if( mtex->texflag & MTEX_BUMP_TEXTURESPACE )
1101                                                         iBumpSpace = 2;
1102                                                 else
1103                                                         iBumpSpace = 4; // ViewSpace
1104                                                 
1105                                                 // re-initialize if bump space changed
1106                                                 if( iBumpSpacePrev != iBumpSpace ) {
1107                                                         
1108                                                         if( mtex->texflag & MTEX_BUMP_OBJECTSPACE ) 
1109                                                                 GPU_link( mat, "mtex_bump_init_objspace",
1110                                                                                   surf_pos, vNorg, 
1111                                                                           GPU_builtin(GPU_VIEW_MATRIX), GPU_builtin(GPU_INVERSE_VIEW_MATRIX), GPU_builtin(GPU_OBJECT_MATRIX),  GPU_builtin(GPU_INVERSE_OBJECT_MATRIX), 
1112                                                                           fPrevMagnitude, vNacc,
1113                                                                                   &fPrevMagnitude, &vNacc, 
1114                                                                           &vR1, &vR2, &fDet );
1115                                                                 
1116                                                         else if( mtex->texflag & MTEX_BUMP_TEXTURESPACE )
1117                                                                 GPU_link( mat, "mtex_bump_init_texturespace",
1118                                                                                   surf_pos, vNorg, 
1119                                                                           fPrevMagnitude, vNacc,
1120                                                                                   &fPrevMagnitude, &vNacc, 
1121                                                                           &vR1, &vR2, &fDet );
1122                                                                 
1123                                                         else
1124                                                                 GPU_link( mat, "mtex_bump_init_viewspace",
1125                                                                                   surf_pos, vNorg, 
1126                                                                           fPrevMagnitude, vNacc,
1127                                                                                   &fPrevMagnitude, &vNacc, 
1128                                                                           &vR1, &vR2, &fDet );
1129                                                         
1130                                                         iBumpSpacePrev = iBumpSpace;
1131                                                 }
1132                                                 
1133                                                 
1134                                                 if( mtex->texflag & MTEX_3TAP_BUMP )
1135                                                         GPU_link( mat, "mtex_bump_tap3", 
1136                                                                   texco, GPU_image(tex->ima, &tex->iuser), tnorfac,
1137                                                                   &dBs, &dBt );
1138                                                 else
1139                                                         GPU_link( mat, "mtex_bump_tap5", 
1140                                                                   texco, GPU_image(tex->ima, &tex->iuser), tnorfac,
1141                                                                   &dBs, &dBt );
1142                                                 
1143                                                 
1144                                                 if( mtex->texflag & MTEX_BUMP_TEXTURESPACE ) {
1145                                                         float ima_x= 512.0f, ima_y= 512.f;              // prevent calling textureSize, glsl 1.3 only
1146                                                         ImBuf *ibuf= BKE_image_get_ibuf(tex->ima, &tex->iuser);
1147                                                         if(ibuf) {
1148                                                                 ima_x= ibuf->x;
1149                                                                 ima_y= ibuf->y;
1150                                                         }
1151                                                         
1152                                                         GPU_link( mat, "mtex_bump_apply_texspace",
1153                                                                   fDet, dBs, dBt, vR1, vR2, 
1154                                                                   GPU_image(tex->ima, &tex->iuser), texco, GPU_uniform(&ima_x), GPU_uniform(&ima_y), vNacc,
1155                                                                   &vNacc, &shi->vn );
1156                                                 } else
1157                                                         GPU_link( mat, "mtex_bump_apply",
1158                                                                   fDet, dBs, dBt, vR1, vR2, vNacc,
1159                                                                   &vNacc, &shi->vn );
1160                                                 
1161                                         }
1162                                 }
1163                                 
1164                                 GPU_link(mat, "vec_math_negate", shi->vn, &orn);
1165                                 GPU_link(mat, "texco_refl", shi->vn, shi->view, &shi->ref);
1166                         }
1167
1168                         if((mtex->mapto & MAP_VARS)) {
1169                                 if(rgbnor & TEX_RGB) {
1170                                         if(talpha)
1171                                                 GPU_link(mat, "mtex_alpha_from_col", trgb, &tin);
1172                                         else
1173                                                 GPU_link(mat, "mtex_rgbtoint", trgb, &tin);
1174                                 }
1175
1176                                 if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_REF) {
1177                                         GPUNodeLink *difffac;
1178
1179                                         if(mtex->difffac == 1.0f) difffac = stencil;
1180                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->difffac), stencil, &difffac);
1181
1182                                         texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->refl, tin, difffac, mtex->blendtype, &shi->refl);
1183                                         GPU_link(mat, "mtex_value_clamp_positive", shi->refl, &shi->refl);
1184                                 }
1185                                 if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_SPEC) {
1186                                         GPUNodeLink *specfac;
1187
1188                                         if(mtex->specfac == 1.0f) specfac = stencil;
1189                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->specfac), stencil, &specfac);
1190
1191                                         texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->spec, tin, specfac, mtex->blendtype, &shi->spec);
1192                                         GPU_link(mat, "mtex_value_clamp_positive", shi->spec, &shi->spec);
1193                                 }
1194                                 if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_EMIT) {
1195                                         GPUNodeLink *emitfac;
1196
1197                                         if(mtex->emitfac == 1.0f) emitfac = stencil;
1198                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->emitfac), stencil, &emitfac);
1199
1200                                         texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->emit, tin, emitfac, mtex->blendtype, &shi->emit);
1201                                         GPU_link(mat, "mtex_value_clamp_positive", shi->emit, &shi->emit);
1202                                 }
1203                                 if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_HAR) {
1204                                         GPUNodeLink *hardfac;
1205
1206                                         if(mtex->hardfac == 1.0f) hardfac = stencil;
1207                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->hardfac), stencil, &hardfac);
1208
1209                                         GPU_link(mat, "mtex_har_divide", shi->har, &shi->har);
1210                                         texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->har, tin, hardfac, mtex->blendtype, &shi->har);
1211                                         GPU_link(mat, "mtex_har_multiply_clamp", shi->har, &shi->har);
1212                                 }
1213                                 if(mtex->mapto & MAP_ALPHA) {
1214                                         GPUNodeLink *alphafac;
1215
1216                                         if(mtex->alphafac == 1.0f) alphafac = stencil;
1217                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->alphafac), stencil, &alphafac);
1218
1219                                         texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->alpha, tin, alphafac, mtex->blendtype, &shi->alpha);
1220                                         GPU_link(mat, "mtex_value_clamp", shi->alpha, &shi->alpha);
1221                                 }
1222                                 if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_AMB) {
1223                                         GPUNodeLink *ambfac;
1224
1225                                         if(mtex->ambfac == 1.0f) ambfac = stencil;
1226                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->ambfac), stencil, &ambfac);
1227
1228                                         texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->amb, tin, ambfac, mtex->blendtype, &shi->amb);
1229                                         GPU_link(mat, "mtex_value_clamp", shi->amb, &shi->amb);
1230                                 }
1231                         }
1232                 }
1233         }
1234 }
1235
1236 void GPU_shadeinput_set(GPUMaterial *mat, Material *ma, GPUShadeInput *shi)
1237 {
1238         float hard = ma->har;
1239
1240         memset(shi, 0, sizeof(*shi));
1241
1242         shi->gpumat = mat;
1243         shi->mat = ma;
1244
1245         GPU_link(mat, "set_rgb", GPU_uniform(&ma->r), &shi->rgb);
1246         GPU_link(mat, "set_rgb", GPU_uniform(&ma->specr), &shi->specrgb);
1247         GPU_link(mat, "shade_norm", GPU_builtin(GPU_VIEW_NORMAL), &shi->vn);
1248         GPU_link(mat, "set_value", GPU_uniform(&ma->alpha), &shi->alpha);
1249         GPU_link(mat, "set_value", GPU_uniform(&ma->ref), &shi->refl);
1250         GPU_link(mat, "set_value", GPU_uniform(&ma->spec), &shi->spec);
1251         GPU_link(mat, "set_value", GPU_uniform(&ma->emit), &shi->emit);
1252         GPU_link(mat, "set_value", GPU_uniform(&hard), &shi->har);
1253         GPU_link(mat, "set_value", GPU_uniform(&ma->amb), &shi->amb);
1254         GPU_link(mat, "shade_view", GPU_builtin(GPU_VIEW_POSITION), &shi->view);
1255         GPU_link(mat, "vcol_attribute", GPU_attribute(CD_MCOL, ""), &shi->vcol);
1256         GPU_link(mat, "texco_refl", shi->vn, shi->view, &shi->ref);
1257 }
1258
1259 void GPU_shaderesult_set(GPUShadeInput *shi, GPUShadeResult *shr)
1260 {
1261         GPUMaterial *mat= shi->gpumat;
1262         GPUNodeLink *emit, *ulinfac, *ulogfac, *mistfac;
1263         Material *ma= shi->mat;
1264         World *world= mat->scene->world;
1265         float linfac, logfac, misttype;
1266
1267         memset(shr, 0, sizeof(*shr));
1268
1269         if(ma->mode & MA_VERTEXCOLP)
1270                 shi->rgb = shi->vcol;
1271
1272         do_material_tex(shi);
1273
1274         if((ma->mode & MA_TRANSP) && (ma->mode & MA_ZTRANSP))
1275                 GPU_material_enable_alpha(mat);
1276
1277         if((mat->scene->gm.flag & GAME_GLSL_NO_LIGHTS) || (ma->mode & MA_SHLESS)) {
1278                 shr->combined = shi->rgb;
1279                 shr->alpha = shi->alpha;
1280                 GPU_link(mat, "set_rgb", shi->rgb, &shr->diff);
1281                 GPU_link(mat, "set_rgb_zero", &shr->spec);
1282         }
1283         else {
1284                 if(GPU_link_changed(shi->emit) || ma->emit != 0.0f) {
1285                         if((ma->mode & (MA_VERTEXCOL|MA_VERTEXCOLP))== MA_VERTEXCOL) {
1286                                 GPU_link(mat, "shade_add", shi->emit, shi->vcol, &emit);
1287                                 GPU_link(mat, "shade_mul", emit, shi->rgb, &shr->diff);
1288                         }
1289                         else
1290                                 GPU_link(mat, "shade_mul_value", shi->emit, shi->rgb, &shr->diff);
1291                 }
1292                 else
1293                         GPU_link(mat, "set_rgb_zero", &shr->diff);
1294
1295                 GPU_link(mat, "set_rgb_zero", &shr->spec);
1296
1297                 material_lights(shi, shr);
1298
1299                 shr->combined = shr->diff;
1300                 shr->alpha = shi->alpha;
1301
1302                 if(world) {
1303                         /* exposure correction */
1304                         if(world->exp!=0.0f || world->range!=1.0f) {
1305                                 linfac= 1.0 + pow((2.0*world->exp + 0.5), -10);
1306                                 logfac= log((linfac-1.0)/linfac)/world->range;
1307
1308                                 GPU_link(mat, "set_value", GPU_uniform(&linfac), &ulinfac);
1309                                 GPU_link(mat, "set_value", GPU_uniform(&logfac), &ulogfac);
1310
1311                                 GPU_link(mat, "shade_exposure_correct", shr->combined,
1312                                         ulinfac, ulogfac, &shr->combined);
1313                                 GPU_link(mat, "shade_exposure_correct", shr->spec,
1314                                         ulinfac, ulogfac, &shr->spec);
1315                         }
1316
1317                         /* ambient color */
1318                         if(world->ambr!=0.0f || world->ambg!=0.0f || world->ambb!=0.0f) {
1319                                 if(GPU_link_changed(shi->amb) || ma->amb != 0.0f)
1320                                         GPU_link(mat, "shade_maddf", shr->combined, GPU_uniform(&ma->amb),
1321                                                 GPU_uniform(&world->ambr), &shr->combined);
1322                         }
1323                 }
1324
1325                 if(ma->mode & MA_RAMP_COL) ramp_diffuse_result(shi, &shr->combined);
1326                 if(ma->mode & MA_RAMP_SPEC) ramp_spec_result(shi, &shr->spec);
1327
1328                 if(GPU_link_changed(shi->spec) || ma->spec != 0.0f)
1329                         GPU_link(mat, "shade_add", shr->combined, shr->spec, &shr->combined);
1330         }
1331
1332         GPU_link(mat, "mtex_alpha_to_col", shr->combined, shr->alpha, &shr->combined);
1333
1334         if(ma->shade_flag & MA_OBCOLOR)
1335                 GPU_link(mat, "shade_obcolor", shr->combined, GPU_builtin(GPU_OBCOLOR), &shr->combined);
1336
1337         if(world && (world->mode & WO_MIST) && !(ma->mode & MA_NOMIST)) {
1338                 misttype = world->mistype;
1339
1340                 GPU_link(mat, "shade_mist_factor", GPU_builtin(GPU_VIEW_POSITION),
1341                         GPU_uniform(&world->miststa), GPU_uniform(&world->mistdist),
1342                         GPU_uniform(&misttype), GPU_uniform(&world->misi), &mistfac);
1343
1344                 GPU_link(mat, "mix_blend", mistfac, shr->combined,
1345                         GPU_uniform(&world->horr), &shr->combined);
1346         }
1347
1348         if(!((ma->mode & MA_TRANSP) && (ma->mode & MA_ZTRANSP))) {
1349                 if(world && (GPU_link_changed(shr->alpha) || ma->alpha != 1.0f))
1350                         GPU_link(mat, "shade_world_mix", GPU_uniform(&world->horr),
1351                                 shr->combined, &shr->combined);
1352
1353                 GPU_link(mat, "shade_alpha_opaque", shr->combined, &shr->combined);
1354         }
1355
1356         if(ma->shade_flag & MA_OBCOLOR) {
1357                 mat->obcolalpha = 1;
1358                 GPU_link(mat, "shade_alpha_obcolor", shr->combined, GPU_builtin(GPU_OBCOLOR), &shr->combined);
1359         }
1360
1361         if(mat->scene->r.color_mgt_flag & R_COLOR_MANAGEMENT)
1362                 GPU_link(mat, "linearrgb_to_srgb", shr->combined, &shr->combined);
1363 }
1364
1365 static GPUNodeLink *GPU_blender_material(GPUMaterial *mat, Material *ma)
1366 {
1367         GPUShadeInput shi;
1368         GPUShadeResult shr;
1369
1370         GPU_shadeinput_set(mat, ma, &shi);
1371         GPU_shaderesult_set(&shi, &shr);
1372
1373         return shr.combined;
1374 }
1375
1376 GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma)
1377 {
1378         GPUMaterial *mat;
1379         GPUNodeLink *outlink;
1380         LinkData *link;
1381
1382         for(link=ma->gpumaterial.first; link; link=link->next)
1383                 if(((GPUMaterial*)link->data)->scene == scene)
1384                         return link->data;
1385
1386         mat = GPU_material_construct_begin(ma);
1387         mat->scene = scene;
1388
1389         if(!(scene->gm.flag & GAME_GLSL_NO_NODES) && ma->nodetree && ma->use_nodes) {
1390                 ntreeGPUMaterialNodes(ma->nodetree, mat);
1391         }
1392         else {
1393                 outlink = GPU_blender_material(mat, ma);
1394                 GPU_material_output_link(mat, outlink);
1395         }
1396
1397         /*if(!GPU_material_construct_end(mat)) {
1398                 GPU_material_free(mat);
1399                 mat= NULL;
1400                 return 0;
1401         }*/
1402
1403         GPU_material_construct_end(mat);
1404
1405         link = MEM_callocN(sizeof(LinkData), "GPUMaterialLink");
1406         link->data = mat;
1407         BLI_addtail(&ma->gpumaterial, link);
1408
1409         return mat;
1410 }
1411
1412 void GPU_materials_free(void)
1413 {
1414         Object *ob;
1415         Material *ma;
1416         extern Material defmaterial;
1417
1418         for(ma=G.main->mat.first; ma; ma=ma->id.next)
1419                 GPU_material_free(ma);
1420
1421         GPU_material_free(&defmaterial);
1422
1423         for(ob=G.main->object.first; ob; ob=ob->id.next)
1424                 GPU_lamp_free(ob);
1425 }
1426
1427 /* Lamps and shadow buffers */
1428
1429 void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[][4])
1430 {
1431         float mat[4][4];
1432
1433         lamp->lay = lay;
1434         lamp->hide = hide;
1435
1436         copy_m4_m4(mat, obmat);
1437         normalize_m4(mat);
1438
1439         VECCOPY(lamp->vec, mat[2]);
1440         VECCOPY(lamp->co, mat[3]);
1441         copy_m4_m4(lamp->obmat, mat);
1442         invert_m4_m4(lamp->imat, mat);
1443 }
1444
1445 void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float energy)
1446 {
1447         lamp->energy = energy;
1448         if(lamp->mode & LA_NEG) lamp->energy= -lamp->energy;
1449
1450         lamp->col[0]= r* lamp->energy;
1451         lamp->col[1]= g* lamp->energy;
1452         lamp->col[2]= b* lamp->energy;
1453 }
1454
1455 static void gpu_lamp_from_blender(Scene *scene, Object *ob, Object *par, Lamp *la, GPULamp *lamp)
1456 {
1457         float temp, angle, pixsize, wsize;
1458
1459         lamp->scene = scene;
1460         lamp->ob = ob;
1461         lamp->par = par;
1462         lamp->la = la;
1463
1464         /* add_render_lamp */
1465         lamp->mode = la->mode;
1466         lamp->type = la->type;
1467
1468         lamp->energy = la->energy;
1469         if(lamp->mode & LA_NEG) lamp->energy= -lamp->energy;
1470
1471         lamp->col[0]= la->r*lamp->energy;
1472         lamp->col[1]= la->g*lamp->energy;
1473         lamp->col[2]= la->b*lamp->energy;
1474
1475         GPU_lamp_update(lamp, ob->lay, (ob->restrictflag & OB_RESTRICT_RENDER), ob->obmat);
1476
1477         lamp->spotsi= la->spotsize;
1478         if(lamp->mode & LA_HALO)
1479                 if(lamp->spotsi > 170.0)
1480                         lamp->spotsi = 170.0;
1481         lamp->spotsi= cos(M_PI*lamp->spotsi/360.0);
1482         lamp->spotbl= (1.0 - lamp->spotsi)*la->spotblend;
1483         lamp->k= la->k;
1484
1485         lamp->dist= la->dist;
1486         lamp->falloff_type= la->falloff_type;
1487         lamp->att1= la->att1;
1488         lamp->att2= la->att2;
1489         lamp->curfalloff= la->curfalloff;
1490
1491         /* initshadowbuf */
1492         lamp->bias = 0.02f*la->bias;
1493         lamp->size = la->bufsize;
1494         lamp->d= la->clipsta;
1495         lamp->clipend= la->clipend;
1496
1497         /* arbitrary correction for the fact we do no soft transition */
1498         lamp->bias *= 0.25f;
1499
1500         /* makeshadowbuf */
1501         angle= saacos(lamp->spotsi);
1502         temp= 0.5f*lamp->size*cos(angle)/sin(angle);
1503         pixsize= (lamp->d)/temp;
1504         wsize= pixsize*0.5f*lamp->size;
1505                 
1506         perspective_m4( lamp->winmat,-wsize, wsize, -wsize, wsize, lamp->d, lamp->clipend);
1507 }
1508
1509 static void gpu_lamp_shadow_free(GPULamp *lamp)
1510 {
1511         if(lamp->tex) {
1512                 GPU_texture_free(lamp->tex);
1513                 lamp->tex= NULL;
1514         }
1515         if(lamp->fb) {
1516                 GPU_framebuffer_free(lamp->fb);
1517                 lamp->fb= NULL;
1518         }
1519 }
1520
1521 GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par)
1522 {
1523         Lamp *la;
1524         GPULamp *lamp;
1525         LinkData *link;
1526
1527         for(link=ob->gpulamp.first; link; link=link->next) {
1528                 lamp = (GPULamp*)link->data;
1529
1530                 if(lamp->par == par && lamp->scene == scene)
1531                         return link->data;
1532         }
1533
1534         lamp = MEM_callocN(sizeof(GPULamp), "GPULamp");
1535
1536         link = MEM_callocN(sizeof(LinkData), "GPULampLink");
1537         link->data = lamp;
1538         BLI_addtail(&ob->gpulamp, link);
1539
1540         la = ob->data;
1541         gpu_lamp_from_blender(scene, ob, par, la, lamp);
1542
1543         if(la->type==LA_SPOT && (la->mode & LA_SHAD_BUF)) {
1544                 /* opengl */
1545                 lamp->fb = GPU_framebuffer_create();
1546                 if(!lamp->fb) {
1547                         gpu_lamp_shadow_free(lamp);
1548                         return lamp;
1549                 }
1550
1551                 lamp->tex = GPU_texture_create_depth(lamp->size, lamp->size);
1552                 if(!lamp->tex) {
1553                         gpu_lamp_shadow_free(lamp);
1554                         return lamp;
1555                 }
1556
1557                 if(!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex)) {
1558                         gpu_lamp_shadow_free(lamp);
1559                         return lamp;
1560                 }
1561
1562                 GPU_framebuffer_restore();
1563         }
1564
1565         return lamp;
1566 }
1567
1568 void GPU_lamp_free(Object *ob)
1569 {
1570         GPULamp *lamp;
1571         LinkData *link;
1572         LinkData *nlink;
1573         Material *ma;
1574
1575         for(link=ob->gpulamp.first; link; link=link->next) {
1576                 lamp = link->data;
1577
1578                 while(lamp->materials.first) {
1579                         nlink = lamp->materials.first;
1580                         ma = nlink->data;
1581                         BLI_freelinkN(&lamp->materials, nlink);
1582
1583                         if(ma->gpumaterial.first)
1584                                 GPU_material_free(ma);
1585                 }
1586
1587                 gpu_lamp_shadow_free(lamp);
1588
1589                 MEM_freeN(lamp);
1590         }
1591
1592         BLI_freelistN(&ob->gpulamp);
1593 }
1594
1595 int GPU_lamp_has_shadow_buffer(GPULamp *lamp)
1596 {
1597         return (!(lamp->scene->gm.flag & GAME_GLSL_NO_SHADOWS) &&
1598                         !(lamp->scene->gm.flag & GAME_GLSL_NO_LIGHTS) &&
1599                         lamp->tex && lamp->fb);
1600 }
1601
1602 void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[][4], int *winsize, float winmat[][4])
1603 {
1604         float rangemat[4][4], persmat[4][4];
1605
1606         /* initshadowbuf */
1607         invert_m4_m4(lamp->viewmat, lamp->obmat);
1608         normalize_v3(lamp->viewmat[0]);
1609         normalize_v3(lamp->viewmat[1]);
1610         normalize_v3(lamp->viewmat[2]);
1611
1612         /* makeshadowbuf */
1613         mul_m4_m4m4(persmat, lamp->viewmat, lamp->winmat);
1614
1615         /* opengl depth buffer is range 0.0..1.0 instead of -1.0..1.0 in blender */
1616         unit_m4(rangemat);
1617         rangemat[0][0] = 0.5f;
1618         rangemat[1][1] = 0.5f;
1619         rangemat[2][2] = 0.5f;
1620         rangemat[3][0] = 0.5f;
1621         rangemat[3][1] = 0.5f;
1622         rangemat[3][2] = 0.5f;
1623
1624         mul_m4_m4m4(lamp->persmat, persmat, rangemat);
1625
1626         /* opengl */
1627         glDisable(GL_SCISSOR_TEST);
1628         GPU_framebuffer_texture_bind(lamp->fb, lamp->tex);
1629
1630         /* set matrices */
1631         copy_m4_m4(viewmat, lamp->viewmat);
1632         copy_m4_m4(winmat, lamp->winmat);
1633         *winsize = lamp->size;
1634 }
1635
1636 void GPU_lamp_shadow_buffer_unbind(GPULamp *lamp)
1637 {
1638         GPU_framebuffer_texture_unbind(lamp->fb, lamp->tex);
1639         GPU_framebuffer_restore();
1640         glEnable(GL_SCISSOR_TEST);
1641 }
1642
1643 int GPU_lamp_shadow_layer(GPULamp *lamp)
1644 {
1645         if(lamp->fb && lamp->tex && (lamp->mode & (LA_LAYER|LA_LAYER_SHADOW)))
1646                 return lamp->lay;
1647         else
1648                 return -1;
1649 }
1650