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