cleanup: style/indentation
[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  * Manages materials, lights and textures.
32  */
33
34
35 #include <math.h>
36 #include <string.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 #include "BKE_group.h"
60
61 #include "IMB_imbuf_types.h"
62
63 #include "GPU_extensions.h"
64 #include "GPU_material.h"
65
66 #include "gpu_codegen.h"
67
68 #include <string.h>
69
70 /* Structs */
71
72 typedef enum DynMatProperty {
73         DYN_LAMP_CO = 1,
74         DYN_LAMP_VEC = 2,
75         DYN_LAMP_IMAT = 4,
76         DYN_LAMP_PERSMAT = 8,
77 } DynMatProperty;
78
79
80 struct GPUMaterial {
81         Scene *scene;
82         Material *ma;
83
84         /* material for mesh surface, worlds or something else.
85          * some code generation is done differently depending on the use case */
86         int type;
87         
88         /* for creating the material */
89         ListBase nodes;
90         GPUNodeLink *outlink;
91
92         /* for binding the material */
93         GPUPass *pass;
94         GPUVertexAttribs attribs;
95         int bound;
96         int builtins;
97         int alpha, obcolalpha;
98         int dynproperty;
99
100         /* for passing uniforms */
101         int viewmatloc, invviewmatloc;
102         int obmatloc, invobmatloc;
103         int obcolloc, obautobumpscaleloc;
104         int cameratexcofacloc;
105
106         ListBase lamps;
107 };
108
109 struct GPULamp {
110         Scene *scene;
111         Object *ob;
112         Object *par;
113         Lamp *la;
114
115         int type, mode, lay, hide;
116
117         float dynenergy, dyncol[3];
118         float energy, col[3];
119
120         float co[3], vec[3];
121         float dynco[3], dynvec[3];
122         float obmat[4][4];
123         float imat[4][4];
124         float dynimat[4][4];
125
126         float spotsi, spotbl, k;
127         float dyndist, dynatt1, dynatt2;
128         float dist, att1, att2;
129         float shadow_color[3];
130
131         float bias, d, clipend;
132         int size;
133
134         int falloff_type;
135         struct CurveMapping *curfalloff;
136
137         float winmat[4][4];
138         float viewmat[4][4];
139         float persmat[4][4];
140         float dynpersmat[4][4];
141
142         GPUFrameBuffer *fb;
143         GPUFrameBuffer *blurfb;
144         GPUTexture *tex;
145         GPUTexture *depthtex;
146         GPUTexture *blurtex;
147
148         ListBase materials;
149 };
150
151 /* Forward declaration so shade_light_textures() can use this, while still keeping the code somewhat organized */
152 static void texture_rgb_blend(GPUMaterial *mat, GPUNodeLink *tex, GPUNodeLink *out, GPUNodeLink *fact, GPUNodeLink *facg, int blendtype, GPUNodeLink **in);
153
154 /* Functions */
155
156 static GPUMaterial *GPU_material_construct_begin(Material *ma)
157 {
158         GPUMaterial *material = MEM_callocN(sizeof(GPUMaterial), "GPUMaterial");
159
160         material->ma= ma;
161
162         return material;
163 }
164
165 static void gpu_material_set_attrib_id(GPUMaterial *material)
166 {
167         GPUVertexAttribs *attribs;
168         GPUShader *shader;
169         GPUPass *pass;
170         char name[32];
171         int a, b;
172
173         attribs= &material->attribs;
174         pass= material->pass;
175         if (!pass) {
176                 attribs->totlayer = 0;
177                 return;
178         }
179         
180         shader= GPU_pass_shader(pass);
181         if (!shader) {
182                 attribs->totlayer = 0;
183                 return;
184         }
185
186         /* convert from attribute number to the actual id assigned by opengl,
187          * in case the attrib does not get a valid index back, it was probably
188          * removed by the glsl compiler by dead code elimination */
189
190         for (a=0, b=0; a<attribs->totlayer; a++) {
191                 BLI_snprintf(name, sizeof(name), "att%d", attribs->layer[a].attribid);
192                 attribs->layer[a].glindex = GPU_shader_get_attribute(shader, name);
193
194                 if (attribs->layer[a].glindex >= 0) {
195                         attribs->layer[b] = attribs->layer[a];
196                         b++;
197                 }
198         }
199
200         attribs->totlayer = b;
201 }
202
203 static int GPU_material_construct_end(GPUMaterial *material, const char *passname)
204 {
205         if (material->outlink) {
206                 GPUNodeLink *outlink;
207                 GPUShader *shader;
208
209                 outlink = material->outlink;
210                 material->pass = GPU_generate_pass(&material->nodes, outlink,
211                         &material->attribs, &material->builtins, material->type, passname);
212
213                 if (!material->pass)
214                         return 0;
215
216                 gpu_material_set_attrib_id(material);
217                 
218                 shader = GPU_pass_shader(material->pass);
219
220                 if (material->builtins & GPU_VIEW_MATRIX)
221                         material->viewmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_VIEW_MATRIX));
222                 if (material->builtins & GPU_INVERSE_VIEW_MATRIX)
223                         material->invviewmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_INVERSE_VIEW_MATRIX));
224                 if (material->builtins & GPU_OBJECT_MATRIX)
225                         material->obmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_OBJECT_MATRIX));
226                 if (material->builtins & GPU_INVERSE_OBJECT_MATRIX)
227                         material->invobmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_INVERSE_OBJECT_MATRIX));
228                 if (material->builtins & GPU_OBCOLOR)
229                         material->obcolloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_OBCOLOR));
230                 if (material->builtins & GPU_AUTO_BUMPSCALE)
231                         material->obautobumpscaleloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_AUTO_BUMPSCALE));
232                 if (material->builtins & GPU_CAMERA_TEXCO_FACTORS)
233                         material->cameratexcofacloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_CAMERA_TEXCO_FACTORS));
234                 return 1;
235         }
236
237         return 0;
238 }
239
240 void GPU_material_free(ListBase *gpumaterial)
241 {
242         LinkData *link;
243         LinkData *nlink, *mlink, *next;
244
245         for (link=gpumaterial->first; link; link=link->next) {
246                 GPUMaterial *material = link->data;
247
248                 if (material->pass)
249                         GPU_pass_free(material->pass);
250
251                 for (nlink=material->lamps.first; nlink; nlink=nlink->next) {
252                         GPULamp *lamp = nlink->data;
253
254                         if (material->ma) {
255                                 Material *ma = material->ma;
256                                 
257                                 for (mlink=lamp->materials.first; mlink; mlink=next) {
258                                         next = mlink->next;
259                                         if (mlink->data == ma)
260                                                 BLI_freelinkN(&lamp->materials, mlink);
261                                 }
262                         }
263                 }
264                 
265                 BLI_freelistN(&material->lamps);
266
267                 MEM_freeN(material);
268         }
269
270         BLI_freelistN(gpumaterial);
271 }
272
273 bool GPU_lamp_override_visible(GPULamp *lamp, SceneRenderLayer *srl, Material *ma)
274 {
275         if (srl && srl->light_override)
276                 return BKE_group_object_exists(srl->light_override, lamp->ob);
277         else if (ma && ma->group)
278                 return BKE_group_object_exists(ma->group, lamp->ob);
279         else
280                 return true;
281 }
282
283 void GPU_material_bind(GPUMaterial *material, int oblay, int viewlay, double time, int mipmap, float viewmat[4][4], float viewinv[4][4], float camerafactors[4], bool scenelock)
284 {
285         if (material->pass) {
286                 LinkData *nlink;
287                 GPULamp *lamp;
288                 GPUShader *shader = GPU_pass_shader(material->pass);
289                 SceneRenderLayer *srl = scenelock ? BLI_findlink(&material->scene->r.layers, material->scene->r.actlay) : NULL;
290
291                 if (srl)
292                         viewlay &= srl->lay;
293
294                 /* handle layer lamps */
295                 if (material->type == GPU_MATERIAL_TYPE_MESH) {
296                         for (nlink=material->lamps.first; nlink; nlink=nlink->next) {
297                                 lamp= nlink->data;
298                                 
299                                 if (!lamp->hide && (lamp->lay & viewlay) && (!(lamp->mode & LA_LAYER) || (lamp->lay & oblay))
300                                         && GPU_lamp_override_visible(lamp, srl, material->ma)) {
301                                         lamp->dynenergy = lamp->energy;
302                                         copy_v3_v3(lamp->dyncol, lamp->col);
303                                 }
304                                 else {
305                                         lamp->dynenergy = 0.0f;
306                                         lamp->dyncol[0]= lamp->dyncol[1]= lamp->dyncol[2] = 0.0f;
307                                 }
308                                 
309                                 if (material->dynproperty & DYN_LAMP_VEC) {
310                                         copy_v3_v3(lamp->dynvec, lamp->vec);
311                                         normalize_v3(lamp->dynvec);
312                                         negate_v3(lamp->dynvec);
313                                         mul_mat3_m4_v3(viewmat, lamp->dynvec);
314                                 }
315                                 
316                                 if (material->dynproperty & DYN_LAMP_CO) {
317                                         copy_v3_v3(lamp->dynco, lamp->co);
318                                         mul_m4_v3(viewmat, lamp->dynco);
319                                 }
320                                 
321                                 if (material->dynproperty & DYN_LAMP_IMAT) {
322                                         mul_m4_m4m4(lamp->dynimat, lamp->imat, viewinv);
323                                 }
324                                 
325                                 if (material->dynproperty & DYN_LAMP_PERSMAT) {
326                                         if (!GPU_lamp_has_shadow_buffer(lamp)) /* The lamp matrices are already updated if we're using shadow buffers */
327                                                 GPU_lamp_update_buffer_mats(lamp);
328                                         mul_m4_m4m4(lamp->dynpersmat, lamp->persmat, viewinv);
329                                 }
330                         }
331                 }
332                 
333                 /* note material must be bound before setting uniforms */
334                 GPU_pass_bind(material->pass, time, mipmap);
335
336                 /* handle per material built-ins */
337                 if (material->builtins & GPU_VIEW_MATRIX) {
338                         GPU_shader_uniform_vector(shader, material->viewmatloc, 16, 1, (float*)viewmat);
339                 }
340                 if (material->builtins & GPU_INVERSE_VIEW_MATRIX) {
341                         GPU_shader_uniform_vector(shader, material->invviewmatloc, 16, 1, (float*)viewinv);
342                 }
343                 if (material->builtins & GPU_CAMERA_TEXCO_FACTORS) {
344                         if (camerafactors) {
345                                 GPU_shader_uniform_vector(shader, material->cameratexcofacloc, 4, 1, (float*)camerafactors);
346                         }
347                         else {
348                                 /* use default, no scaling no offset */
349                                 float borders[4] = {1.0f, 1.0f, 0.0f, 0.0f};
350                                 GPU_shader_uniform_vector(shader, material->cameratexcofacloc, 4, 1, (float*)borders);
351                         }
352                 }
353
354                 GPU_pass_update_uniforms(material->pass);
355
356                 material->bound = 1;
357         }
358 }
359
360 void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[4][4], float obcol[4], float autobumpscale)
361 {
362         if (material->pass) {
363                 GPUShader *shader = GPU_pass_shader(material->pass);
364                 float invmat[4][4], col[4];
365
366                 /* handle per object builtins */
367                 if (material->builtins & GPU_OBJECT_MATRIX) {
368                         GPU_shader_uniform_vector(shader, material->obmatloc, 16, 1, (float*)obmat);
369                 }
370                 if (material->builtins & GPU_INVERSE_OBJECT_MATRIX) {
371                         invert_m4_m4(invmat, obmat);
372                         GPU_shader_uniform_vector(shader, material->invobmatloc, 16, 1, (float*)invmat);
373                 }
374                 if (material->builtins & GPU_OBCOLOR) {
375                         copy_v4_v4(col, obcol);
376                         CLAMP(col[3], 0.0f, 1.0f);
377                         GPU_shader_uniform_vector(shader, material->obcolloc, 4, 1, col);
378                 }
379                 if (material->builtins & GPU_AUTO_BUMPSCALE) {
380                         GPU_shader_uniform_vector(shader, material->obautobumpscaleloc, 1, 1, &autobumpscale);
381                 }
382         }
383 }
384
385 void GPU_material_unbind(GPUMaterial *material)
386 {
387         if (material->pass) {
388                 material->bound = 0;
389                 GPU_pass_unbind(material->pass);
390         }
391 }
392
393 int GPU_material_bound(GPUMaterial *material)
394 {
395         return material->bound;
396 }
397
398 Scene *GPU_material_scene(GPUMaterial *material)
399 {
400         return material->scene;
401 }
402
403 GPUMatType GPU_Material_get_type(GPUMaterial *material)
404 {
405         return material->type;
406 }
407
408
409 void GPU_material_vertex_attributes(GPUMaterial *material, GPUVertexAttribs *attribs)
410 {
411         *attribs = material->attribs;
412 }
413
414 void GPU_material_output_link(GPUMaterial *material, GPUNodeLink *link)
415 {
416         if (!material->outlink)
417                 material->outlink= link;
418 }
419
420 void GPU_material_enable_alpha(GPUMaterial *material)
421 {
422         material->alpha= 1;
423 }
424
425 GPUBlendMode GPU_material_alpha_blend(GPUMaterial *material, float obcol[4])
426 {
427         if (material->alpha || (material->obcolalpha && obcol[3] < 1.0f))
428                 return GPU_BLEND_ALPHA;
429         else
430                 return GPU_BLEND_SOLID;
431 }
432
433 void gpu_material_add_node(GPUMaterial *material, GPUNode *node)
434 {
435         BLI_addtail(&material->nodes, node);
436 }
437
438 /* Code generation */
439
440 bool GPU_material_do_color_management(GPUMaterial *mat)
441 {
442         if (!BKE_scene_check_color_management_enabled(mat->scene))
443                 return false;
444
445         return !((mat->scene->gm.flag & GAME_GLSL_NO_COLOR_MANAGEMENT));
446 }
447
448 bool GPU_material_use_new_shading_nodes(GPUMaterial *mat)
449 {
450         return BKE_scene_use_new_shading_nodes(mat->scene);
451 }
452
453 static GPUNodeLink *lamp_get_visibility(GPUMaterial *mat, GPULamp *lamp, GPUNodeLink **lv, GPUNodeLink **dist)
454 {
455         GPUNodeLink *visifac, *inpr;
456
457         /* from get_lamp_visibility */
458         if (lamp->type==LA_SUN || lamp->type==LA_HEMI) {
459                 mat->dynproperty |= DYN_LAMP_VEC;
460                 GPU_link(mat, "lamp_visibility_sun_hemi", GPU_dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob), lv, dist, &visifac);
461                 return visifac;
462         }
463         else {
464                 mat->dynproperty |= DYN_LAMP_CO;
465                 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);
466
467                 if (lamp->type==LA_AREA)
468                         return visifac;
469
470                 switch (lamp->falloff_type) {
471                         case LA_FALLOFF_CONSTANT:
472                                 break;
473                         case LA_FALLOFF_INVLINEAR:
474                                 GPU_link(mat, "lamp_falloff_invlinear", GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob), *dist, &visifac);
475                                 break;
476                         case LA_FALLOFF_INVSQUARE:
477                                 GPU_link(mat, "lamp_falloff_invsquare", GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob), *dist, &visifac);
478                                 break;
479                         case LA_FALLOFF_SLIDERS:
480                                 GPU_link(mat, "lamp_falloff_sliders", GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob), GPU_dynamic_uniform(&lamp->att1, GPU_DYNAMIC_LAMP_ATT1, lamp->ob), GPU_dynamic_uniform(&lamp->att2, GPU_DYNAMIC_LAMP_ATT2, lamp->ob), *dist, &visifac);
481                                 break;
482                         case LA_FALLOFF_CURVE:
483                                 {
484                                         float *array;
485                                         int size;
486
487                                         curvemapping_initialize(lamp->curfalloff);
488                                         curvemapping_table_RGBA(lamp->curfalloff, &array, &size);
489                                         GPU_link(mat, "lamp_falloff_curve", GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob), GPU_texture(size, array), *dist, &visifac);
490                                 }
491                                 break;
492                 }
493
494                 if (lamp->mode & LA_SPHERE)
495                         GPU_link(mat, "lamp_visibility_sphere", GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob), *dist, visifac, &visifac);
496
497                 if (lamp->type == LA_SPOT) {
498                         if (lamp->mode & LA_SQUARE) {
499                                 mat->dynproperty |= DYN_LAMP_VEC|DYN_LAMP_IMAT;
500                                 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);
501                         }
502                         else {
503                                 mat->dynproperty |= DYN_LAMP_VEC;
504                                 GPU_link(mat, "lamp_visibility_spot_circle", GPU_dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob), *lv, &inpr);
505                         }
506                         
507                         GPU_link(mat, "lamp_visibility_spot", GPU_dynamic_uniform(&lamp->spotsi, GPU_DYNAMIC_LAMP_SPOTSIZE, lamp->ob), GPU_dynamic_uniform(&lamp->spotbl, GPU_DYNAMIC_LAMP_SPOTSIZE, lamp->ob), inpr, visifac, &visifac);
508                 }
509
510                 GPU_link(mat, "lamp_visibility_clamp", visifac, &visifac);
511
512                 return visifac;
513         }
514 }
515
516 #if 0
517 static void area_lamp_vectors(LampRen *lar)
518 {
519         float xsize= 0.5*lar->area_size, ysize= 0.5*lar->area_sizey, multifac;
520
521         /* make it smaller, so area light can be multisampled */
522         multifac= 1.0f/sqrt((float)lar->ray_totsamp);
523         xsize *= multifac;
524         ysize *= multifac;
525
526         /* corner vectors */
527         lar->area[0][0]= lar->co[0] - xsize*lar->mat[0][0] - ysize*lar->mat[1][0];
528         lar->area[0][1]= lar->co[1] - xsize*lar->mat[0][1] - ysize*lar->mat[1][1];
529         lar->area[0][2]= lar->co[2] - xsize*lar->mat[0][2] - ysize*lar->mat[1][2];
530
531         /* corner vectors */
532         lar->area[1][0]= lar->co[0] - xsize*lar->mat[0][0] + ysize*lar->mat[1][0];
533         lar->area[1][1]= lar->co[1] - xsize*lar->mat[0][1] + ysize*lar->mat[1][1];
534         lar->area[1][2]= lar->co[2] - xsize*lar->mat[0][2] + ysize*lar->mat[1][2];
535
536         /* corner vectors */
537         lar->area[2][0]= lar->co[0] + xsize*lar->mat[0][0] + ysize*lar->mat[1][0];
538         lar->area[2][1]= lar->co[1] + xsize*lar->mat[0][1] + ysize*lar->mat[1][1];
539         lar->area[2][2]= lar->co[2] + xsize*lar->mat[0][2] + ysize*lar->mat[1][2];
540
541         /* corner vectors */
542         lar->area[3][0]= lar->co[0] + xsize*lar->mat[0][0] - ysize*lar->mat[1][0];
543         lar->area[3][1]= lar->co[1] + xsize*lar->mat[0][1] - ysize*lar->mat[1][1];
544         lar->area[3][2]= lar->co[2] + xsize*lar->mat[0][2] - ysize*lar->mat[1][2];
545         /* only for correction button size, matrix size works on energy */
546         lar->areasize= lar->dist*lar->dist/(4.0*xsize*ysize);
547 }
548 #endif
549
550 static void ramp_blend(GPUMaterial *mat, GPUNodeLink *fac, GPUNodeLink *col1, GPUNodeLink *col2, int type, GPUNodeLink **outcol)
551 {
552         static const char *names[] = {"mix_blend", "mix_add", "mix_mult", "mix_sub",
553                 "mix_screen", "mix_div", "mix_diff", "mix_dark", "mix_light",
554                 "mix_overlay", "mix_dodge", "mix_burn", "mix_hue", "mix_sat",
555                 "mix_val", "mix_color", "mix_soft", "mix_linear"};
556
557         GPU_link(mat, names[type], fac, col1, col2, outcol);
558 }
559
560 static void do_colorband_blend(GPUMaterial *mat, ColorBand *coba, GPUNodeLink *fac, float rampfac, int type, GPUNodeLink *incol, GPUNodeLink **outcol)
561 {
562         GPUNodeLink *tmp, *alpha, *col;
563         float *array;
564         int size;
565
566         /* do colorband */
567         colorband_table_RGBA(coba, &array, &size);
568         GPU_link(mat, "valtorgb", fac, GPU_texture(size, array), &col, &tmp);
569
570         /* use alpha in fac */
571         GPU_link(mat, "mtex_alpha_from_col", col, &alpha);
572         GPU_link(mat, "math_multiply", alpha, GPU_uniform(&rampfac), &fac);
573
574         /* blending method */
575         ramp_blend(mat, fac, incol, col, type, outcol);
576 }
577
578 static void ramp_diffuse_result(GPUShadeInput *shi, GPUNodeLink **diff)
579 {
580         Material *ma= shi->mat;
581         GPUMaterial *mat= shi->gpumat;
582         GPUNodeLink *fac;
583
584         if (!(mat->scene->gm.flag & GAME_GLSL_NO_RAMPS)) {
585                 if (ma->ramp_col) {
586                         if (ma->rampin_col==MA_RAMP_IN_RESULT) {
587                                 GPU_link(mat, "ramp_rgbtobw", *diff, &fac);
588                                 
589                                 /* colorband + blend */
590                                 do_colorband_blend(mat, ma->ramp_col, fac, ma->rampfac_col, ma->rampblend_col, *diff, diff);
591                         }
592                 }
593         }
594 }
595
596 static void add_to_diffuse(GPUMaterial *mat, Material *ma, GPUShadeInput *shi, GPUNodeLink *is, GPUNodeLink *rgb, GPUNodeLink **diff)
597 {
598         GPUNodeLink *fac, *tmp, *addcol;
599         
600         if (!(mat->scene->gm.flag & GAME_GLSL_NO_RAMPS) &&
601             ma->ramp_col && (ma->mode & MA_RAMP_COL))
602         {
603                 /* MA_RAMP_IN_RESULT is exceptional */
604                 if (ma->rampin_col==MA_RAMP_IN_RESULT) {
605                         addcol = shi->rgb;
606                 }
607                 else {
608                         /* input */
609                         switch (ma->rampin_col) {
610                         case MA_RAMP_IN_ENERGY:
611                                 GPU_link(mat, "ramp_rgbtobw", rgb, &fac);
612                                 break;
613                         case MA_RAMP_IN_SHADER:
614                                 fac= is;
615                                 break;
616                         case MA_RAMP_IN_NOR:
617                                 GPU_link(mat, "vec_math_dot", shi->view, shi->vn, &tmp, &fac);
618                                 break;
619                         default:
620                                 GPU_link(mat, "set_value_zero", &fac);
621                                 break;
622                         }
623
624                         /* colorband + blend */
625                         do_colorband_blend(mat, ma->ramp_col, fac, ma->rampfac_col, ma->rampblend_col, shi->rgb, &addcol);
626                 }
627         }
628         else
629                 addcol = shi->rgb;
630
631         /* output to */
632         GPU_link(mat, "shade_madd", *diff, rgb, addcol, diff);
633 }
634
635 static void ramp_spec_result(GPUShadeInput *shi, GPUNodeLink **spec)
636 {
637         Material *ma= shi->mat;
638         GPUMaterial *mat= shi->gpumat;
639         GPUNodeLink *fac;
640
641         if (!(mat->scene->gm.flag & GAME_GLSL_NO_RAMPS) &&
642             ma->ramp_spec && ma->rampin_spec==MA_RAMP_IN_RESULT)
643         {
644                 GPU_link(mat, "ramp_rgbtobw", *spec, &fac);
645                 
646                 /* colorband + blend */
647                 do_colorband_blend(mat, ma->ramp_spec, fac, ma->rampfac_spec, ma->rampblend_spec, *spec, spec);
648         }
649 }
650
651 static void do_specular_ramp(GPUShadeInput *shi, GPUNodeLink *is, GPUNodeLink *t, GPUNodeLink **spec)
652 {
653         Material *ma= shi->mat;
654         GPUMaterial *mat= shi->gpumat;
655         GPUNodeLink *fac, *tmp;
656
657         *spec = shi->specrgb;
658
659         /* MA_RAMP_IN_RESULT is exception */
660         if (ma->ramp_spec && (ma->rampin_spec!=MA_RAMP_IN_RESULT)) {
661                 
662                 /* input */
663                 switch (ma->rampin_spec) {
664                 case MA_RAMP_IN_ENERGY:
665                         fac = t;
666                         break;
667                 case MA_RAMP_IN_SHADER:
668                         fac = is;
669                         break;
670                 case MA_RAMP_IN_NOR:
671                         GPU_link(mat, "vec_math_dot", shi->view, shi->vn, &tmp, &fac);
672                         break;
673                 default:
674                         GPU_link(mat, "set_value_zero", &fac);
675                         break;
676                 }
677                 
678                 /* colorband + blend */
679                 do_colorband_blend(mat, ma->ramp_spec, fac, ma->rampfac_spec, ma->rampblend_spec, *spec, spec);
680         }
681 }
682
683 static void add_user_list(ListBase *list, void *data)
684 {
685         LinkData *link = MEM_callocN(sizeof(LinkData), "GPULinkData");
686         link->data = data;
687         BLI_addtail(list, link);
688 }
689
690 static void shade_light_textures(GPUMaterial *mat, GPULamp *lamp, GPUNodeLink **rgb)
691 {
692         GPUNodeLink *tex_rgb;
693         MTex *mtex = NULL;
694         int i;
695         float one = 1.f;
696
697         for (i=0; i<MAX_MTEX; ++i) {
698                 mtex = lamp->la->mtex[i];
699
700                 if (mtex && mtex->tex->type & TEX_IMAGE && mtex->tex->ima) {
701                         mat->dynproperty |= DYN_LAMP_PERSMAT;
702
703                         GPU_link(mat, "shade_light_texture",
704                                 GPU_builtin(GPU_VIEW_POSITION),
705                                 GPU_image(mtex->tex->ima, &mtex->tex->iuser, false),
706                                 GPU_dynamic_uniform((float*)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob),
707                                 &tex_rgb);
708                         texture_rgb_blend(mat, tex_rgb, *rgb, GPU_uniform(&one), GPU_uniform(&mtex->colfac), mtex->blendtype, rgb); 
709                 }
710         }
711 }
712
713 static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *lamp)
714 {
715         Material *ma= shi->mat;
716         GPUMaterial *mat= shi->gpumat;
717         GPUNodeLink *lv, *dist, *visifac, *is, *inp, *i, *vn, *view;
718         GPUNodeLink *outcol, *specfac, *t, *shadfac= NULL, *lcol;
719         float one = 1.0f;
720
721         if ((lamp->mode & LA_ONLYSHADOW) && !(ma->mode & MA_SHADOW))
722                 return;
723         
724         vn= shi->vn;
725         view= shi->view;
726
727         visifac= lamp_get_visibility(mat, lamp, &lv, &dist);
728
729         /*if (ma->mode & MA_TANGENT_V)
730                 GPU_link(mat, "shade_tangent_v", lv, GPU_attribute(CD_TANGENT, ""), &vn);*/
731         
732         GPU_link(mat, "shade_inp", vn, lv, &inp);
733
734         if (lamp->mode & LA_NO_DIFF) {
735                 GPU_link(mat, "shade_is_no_diffuse", &is);
736         }
737         else if (lamp->type == LA_HEMI) {
738                 GPU_link(mat, "shade_is_hemi", inp, &is);
739         }
740         else {
741                 if (lamp->type == LA_AREA) {
742                         float area[4][4]= {{0.0f}}, areasize= 0.0f;
743
744                         mat->dynproperty |= DYN_LAMP_VEC|DYN_LAMP_CO;
745                         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),
746                                 GPU_uniform(&areasize), GPU_uniform(&lamp->k), &inp);
747                 }
748
749                 is= inp; /* Lambert */
750
751                 if (!(mat->scene->gm.flag & GAME_GLSL_NO_SHADERS)) {
752                         if (ma->diff_shader==MA_DIFF_ORENNAYAR)
753                                 GPU_link(mat, "shade_diffuse_oren_nayer", inp, vn, lv, view, GPU_uniform(&ma->roughness), &is);
754                         else if (ma->diff_shader==MA_DIFF_TOON)
755                                 GPU_link(mat, "shade_diffuse_toon", vn, lv, view, GPU_uniform(&ma->param[0]), GPU_uniform(&ma->param[1]), &is);
756                         else if (ma->diff_shader==MA_DIFF_MINNAERT)
757                                 GPU_link(mat, "shade_diffuse_minnaert", inp, vn, view, GPU_uniform(&ma->darkness), &is);
758                         else if (ma->diff_shader==MA_DIFF_FRESNEL)
759                                 GPU_link(mat, "shade_diffuse_fresnel", vn, lv, view, GPU_uniform(&ma->param[0]), GPU_uniform(&ma->param[1]), &is);
760                 }
761         }
762
763         if (!(mat->scene->gm.flag & GAME_GLSL_NO_SHADERS))
764                 if (ma->shade_flag & MA_CUBIC)
765                         GPU_link(mat, "shade_cubic", is, &is);
766         
767         i = is;
768         GPU_link(mat, "shade_visifac", i, visifac, shi->refl, &i);
769         
770         GPU_link(mat, "set_rgb", GPU_dynamic_uniform(lamp->dyncol, GPU_DYNAMIC_LAMP_DYNCOL, lamp->ob), &lcol);
771         shade_light_textures(mat, lamp, &lcol);
772         GPU_link(mat, "shade_mul_value_v3", GPU_dynamic_uniform(&lamp->dynenergy, GPU_DYNAMIC_LAMP_DYNENERGY, lamp->ob), lcol, &lcol);  
773
774 #if 0
775         if (ma->mode & MA_TANGENT_VN)
776                 GPU_link(mat, "shade_tangent_v_spec", GPU_attribute(CD_TANGENT, ""), &vn);
777 #endif
778
779         /* this replaces if (i > 0.0) conditional until that is supported */
780         // done in shade_visifac now, GPU_link(mat, "mtex_value_clamp_positive", i, &i);
781
782         if ((ma->mode & MA_SHADOW) && GPU_lamp_has_shadow_buffer(lamp)) {
783                 if (!(mat->scene->gm.flag & GAME_GLSL_NO_SHADOWS)) {
784                         mat->dynproperty |= DYN_LAMP_PERSMAT;
785                         
786                         if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) {
787                                 GPU_link(mat, "test_shadowbuf_vsm",
788                                         GPU_builtin(GPU_VIEW_POSITION),
789                                         GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob),
790                                         GPU_dynamic_uniform((float*)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob),
791                                         GPU_uniform(&lamp->bias), GPU_uniform(&lamp->la->bleedbias), inp, &shadfac);
792                         }
793                         else {
794                                 GPU_link(mat, "test_shadowbuf",
795                                         GPU_builtin(GPU_VIEW_POSITION),
796                                         GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob),
797                                         GPU_dynamic_uniform((float*)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob),
798                                         GPU_uniform(&lamp->bias), inp, &shadfac);
799                         }
800                         
801                         if (lamp->mode & LA_ONLYSHADOW) {
802                                 GPUNodeLink *shadrgb;
803                                 GPU_link(mat, "shade_only_shadow", i, shadfac,
804                                         GPU_dynamic_uniform(&lamp->dynenergy, GPU_DYNAMIC_LAMP_DYNENERGY, lamp->ob),
805                                         GPU_uniform(lamp->shadow_color), &shadrgb);
806                                 
807                                 if (!(lamp->mode & LA_NO_DIFF)) {
808                                         GPU_link(mat, "shade_only_shadow_diffuse", shadrgb, shi->rgb,
809                                                 shr->diff, &shr->diff);
810                                 }
811
812                                 if (!(lamp->mode & LA_NO_SPEC))
813                                         GPU_link(mat, "shade_only_shadow_specular", shadrgb, shi->specrgb,
814                                                 shr->spec, &shr->spec);
815                                 
816                                 add_user_list(&mat->lamps, lamp);
817                                 add_user_list(&lamp->materials, shi->gpumat->ma);
818                                 return;
819                         }
820                 }
821         }
822         else if ((mat->scene->gm.flag & GAME_GLSL_NO_SHADOWS) && (lamp->mode & LA_ONLYSHADOW)) {
823                 add_user_list(&mat->lamps, lamp);
824                 add_user_list(&lamp->materials, shi->gpumat->ma);
825                 return;
826         }
827         else
828                 GPU_link(mat, "set_value", GPU_uniform(&one), &shadfac);
829
830         if (GPU_link_changed(shi->refl) || ma->ref != 0.0f) {
831                 if (!(lamp->mode & LA_NO_DIFF)) {
832                         GPUNodeLink *rgb;
833                         GPU_link(mat, "shade_mul_value", i, lcol, &rgb);
834                         GPU_link(mat, "mtex_value_invert", shadfac, &shadfac);
835                         GPU_link(mat, "mix_mult",  shadfac, rgb, GPU_uniform(lamp->shadow_color), &rgb);
836                         GPU_link(mat, "mtex_value_invert", shadfac, &shadfac);
837                         add_to_diffuse(mat, ma, shi, is, rgb, &shr->diff);
838                 }
839         }
840
841         if (mat->scene->gm.flag & GAME_GLSL_NO_SHADERS) {
842                 /* pass */
843         }
844         else if (!(lamp->mode & LA_NO_SPEC) && !(lamp->mode & LA_ONLYSHADOW) &&
845                  (GPU_link_changed(shi->spec) || ma->spec != 0.0f))
846         {
847                 if (lamp->type == LA_HEMI) {
848                         GPU_link(mat, "shade_hemi_spec", vn, lv, view, GPU_uniform(&ma->spec), shi->har, visifac, &t);
849                         GPU_link(mat, "shade_add_spec", t, lcol, shi->specrgb, &outcol);
850                         GPU_link(mat, "shade_add_clamped", shr->spec, outcol, &shr->spec);
851                 }
852                 else {
853                         if (ma->spec_shader==MA_SPEC_PHONG)
854                                 GPU_link(mat, "shade_phong_spec", vn, lv, view, shi->har, &specfac);
855                         else if (ma->spec_shader==MA_SPEC_COOKTORR)
856                                 GPU_link(mat, "shade_cooktorr_spec", vn, lv, view, shi->har, &specfac);
857                         else if (ma->spec_shader==MA_SPEC_BLINN)
858                                 GPU_link(mat, "shade_blinn_spec", vn, lv, view, GPU_uniform(&ma->refrac), shi->har, &specfac);
859                         else if (ma->spec_shader==MA_SPEC_WARDISO)
860                                 GPU_link(mat, "shade_wardiso_spec", vn, lv, view, GPU_uniform(&ma->rms), &specfac);
861                         else
862                                 GPU_link(mat, "shade_toon_spec", vn, lv, view, GPU_uniform(&ma->param[2]), GPU_uniform(&ma->param[3]), &specfac);
863
864                         if (lamp->type==LA_AREA)
865                                 GPU_link(mat, "shade_spec_area_inp", specfac, inp, &specfac);
866
867                         GPU_link(mat, "shade_spec_t", shadfac, shi->spec, visifac, specfac, &t); 
868
869                         if (ma->mode & MA_RAMP_SPEC) {
870                                 GPUNodeLink *spec;
871                                 do_specular_ramp(shi, specfac, t, &spec);
872                                 GPU_link(mat, "shade_add_spec", t, lcol, spec, &outcol);
873                                 GPU_link(mat, "shade_add_clamped", shr->spec, outcol, &shr->spec);
874                         }
875                         else {
876                                 GPU_link(mat, "shade_add_spec", t, lcol, shi->specrgb, &outcol);
877                                 GPU_link(mat, "shade_add_clamped", shr->spec, outcol, &shr->spec);
878                         }
879                 }
880         }
881
882         add_user_list(&mat->lamps, lamp);
883         add_user_list(&lamp->materials, shi->gpumat->ma);
884 }
885
886 static void material_lights(GPUShadeInput *shi, GPUShadeResult *shr)
887 {
888         Base *base;
889         Object *ob;
890         Scene *sce_iter;
891         GPULamp *lamp;
892         
893         for (SETLOOPER(shi->gpumat->scene, sce_iter, base)) {
894                 ob= base->object;
895
896                 if (ob->type==OB_LAMP) {
897                         lamp = GPU_lamp_from_blender(shi->gpumat->scene, ob, NULL);
898                         if (lamp)
899                                 shade_one_light(shi, shr, lamp);
900                 }
901
902                 if (ob->transflag & OB_DUPLI) {
903                         DupliObject *dob;
904                         ListBase *lb = object_duplilist(G.main->eval_ctx, shi->gpumat->scene, ob);
905                         
906                         for (dob=lb->first; dob; dob=dob->next) {
907                                 Object *ob_iter = dob->ob;
908
909                                 if (ob_iter->type==OB_LAMP) {
910                                         float omat[4][4];
911                                         copy_m4_m4(omat, ob_iter->obmat);
912                                         copy_m4_m4(ob_iter->obmat, dob->mat);
913
914                                         lamp = GPU_lamp_from_blender(shi->gpumat->scene, ob_iter, ob);
915                                         if (lamp)
916                                                 shade_one_light(shi, shr, lamp);
917
918                                         copy_m4_m4(ob_iter->obmat, omat);
919                                 }
920                         }
921                         
922                         free_object_duplilist(lb);
923                 }
924         }
925
926         /* prevent only shadow lamps from producing negative colors.*/
927         GPU_link(shi->gpumat, "shade_clamp_positive", shr->spec, &shr->spec);
928         GPU_link(shi->gpumat, "shade_clamp_positive", shr->diff, &shr->diff);
929 }
930
931 static void texture_rgb_blend(GPUMaterial *mat, GPUNodeLink *tex, GPUNodeLink *out, GPUNodeLink *fact, GPUNodeLink *facg, int blendtype, GPUNodeLink **in)
932 {
933         switch (blendtype) {
934         case MTEX_BLEND:
935                 GPU_link(mat, "mtex_rgb_blend", out, tex, fact, facg, in);
936                 break;
937         case MTEX_MUL:
938                 GPU_link(mat, "mtex_rgb_mul", out, tex, fact, facg, in);
939                 break;
940         case MTEX_SCREEN:
941                 GPU_link(mat, "mtex_rgb_screen", out, tex, fact, facg, in);
942                 break;
943         case MTEX_OVERLAY:
944                 GPU_link(mat, "mtex_rgb_overlay", out, tex, fact, facg, in);
945                 break;
946         case MTEX_SUB:
947                 GPU_link(mat, "mtex_rgb_sub", out, tex, fact, facg, in);
948                 break;
949         case MTEX_ADD:
950                 GPU_link(mat, "mtex_rgb_add", out, tex, fact, facg, in);
951                 break;
952         case MTEX_DIV:
953                 GPU_link(mat, "mtex_rgb_div", out, tex, fact, facg, in);
954                 break;
955         case MTEX_DIFF:
956                 GPU_link(mat, "mtex_rgb_diff", out, tex, fact, facg, in);
957                 break;
958         case MTEX_DARK:
959                 GPU_link(mat, "mtex_rgb_dark", out, tex, fact, facg, in);
960                 break;
961         case MTEX_LIGHT:
962                 GPU_link(mat, "mtex_rgb_light", out, tex, fact, facg, in);
963                 break;
964         case MTEX_BLEND_HUE:
965                 GPU_link(mat, "mtex_rgb_hue", out, tex, fact, facg, in);
966                 break;
967         case MTEX_BLEND_SAT:
968                 GPU_link(mat, "mtex_rgb_sat", out, tex, fact, facg, in);
969                 break;
970         case MTEX_BLEND_VAL:
971                 GPU_link(mat, "mtex_rgb_val", out, tex, fact, facg, in);
972                 break;
973         case MTEX_BLEND_COLOR:
974                 GPU_link(mat, "mtex_rgb_color", out, tex, fact, facg, in);
975                 break;
976         case MTEX_SOFT_LIGHT:
977                 GPU_link(mat, "mtex_rgb_soft", out, tex, fact, facg, in);
978                 break;
979         case MTEX_LIN_LIGHT:
980                 GPU_link(mat, "mtex_rgb_linear", out, tex, fact, facg, in);
981                 break;
982         default:
983                 GPU_link(mat, "set_rgb_zero", &in);
984                 break;
985         }
986 }
987
988 static void texture_value_blend(GPUMaterial *mat, GPUNodeLink *tex, GPUNodeLink *out, GPUNodeLink *fact, GPUNodeLink *facg, int blendtype, GPUNodeLink **in)
989 {
990         switch (blendtype) {
991         case MTEX_BLEND:
992                 GPU_link(mat, "mtex_value_blend", out, tex, fact, facg, in);
993                 break;
994         case MTEX_MUL:
995                 GPU_link(mat, "mtex_value_mul", out, tex, fact, facg, in);
996                 break;
997         case MTEX_SCREEN:
998                 GPU_link(mat, "mtex_value_screen", out, tex, fact, facg, in);
999                 break;
1000         case MTEX_SUB:
1001                 GPU_link(mat, "mtex_value_sub", out, tex, fact, facg, in);
1002                 break;
1003         case MTEX_ADD:
1004                 GPU_link(mat, "mtex_value_add", out, tex, fact, facg, in);
1005                 break;
1006         case MTEX_DIV:
1007                 GPU_link(mat, "mtex_value_div", out, tex, fact, facg, in);
1008                 break;
1009         case MTEX_DIFF:
1010                 GPU_link(mat, "mtex_value_diff", out, tex, fact, facg, in);
1011                 break;
1012         case MTEX_DARK:
1013                 GPU_link(mat, "mtex_value_dark", out, tex, fact, facg, in);
1014                 break;
1015         case MTEX_LIGHT:
1016                 GPU_link(mat, "mtex_value_light", out, tex, fact, facg, in);
1017                 break;
1018         default:
1019                 GPU_link(mat, "set_value_zero", &in);
1020                 break;
1021         }
1022 }
1023
1024 static void do_material_tex(GPUShadeInput *shi)
1025 {
1026         Material *ma= shi->mat;
1027         GPUMaterial *mat= shi->gpumat;
1028         MTex *mtex;
1029         Tex *tex;
1030         GPUNodeLink *texco, *tin, *trgb, *tnor, *tcol, *stencil, *tnorfac;
1031         GPUNodeLink *texco_norm, *texco_orco, *texco_object;
1032         GPUNodeLink *texco_global, *texco_uv = NULL;
1033         GPUNodeLink *newnor, *orn;
1034         /*char *lastuvname = NULL;*/ /*UNUSED*/
1035         float one = 1.0f, norfac, ofs[3];
1036         int tex_nr, rgbnor, talpha;
1037         bool init_done = false;
1038         int iBumpSpacePrev = 0; /* Not necessary, quiting gcc warning. */
1039         GPUNodeLink *vNorg, *vNacc, *fPrevMagnitude;
1040         int iFirstTimeNMap=1;
1041         int found_deriv_map = 0;
1042
1043         GPU_link(mat, "set_value", GPU_uniform(&one), &stencil);
1044
1045         GPU_link(mat, "texco_norm", GPU_builtin(GPU_VIEW_NORMAL), &texco_norm);
1046         GPU_link(mat, "texco_orco", GPU_attribute(CD_ORCO, ""), &texco_orco);
1047         GPU_link(mat, "texco_object", GPU_builtin(GPU_INVERSE_VIEW_MATRIX),
1048                 GPU_builtin(GPU_INVERSE_OBJECT_MATRIX),
1049                 GPU_builtin(GPU_VIEW_POSITION), &texco_object);
1050         //GPU_link(mat, "texco_tangent", GPU_attribute(CD_TANGENT, ""), &texco_tangent);
1051         GPU_link(mat, "texco_global", GPU_builtin(GPU_INVERSE_VIEW_MATRIX),
1052                 GPU_builtin(GPU_VIEW_POSITION), &texco_global);
1053
1054         orn= texco_norm;
1055
1056         /* go over texture slots */
1057         for (tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) {
1058                 /* separate tex switching */
1059                 if (ma->septex & (1<<tex_nr)) continue;
1060                 
1061                 if (ma->mtex[tex_nr]) {
1062                         mtex= ma->mtex[tex_nr];
1063                         
1064                         tex= mtex->tex;
1065                         if (tex == NULL) continue;
1066
1067                         /* which coords */
1068                         if (mtex->texco==TEXCO_ORCO)
1069                                 texco= texco_orco;
1070                         else if (mtex->texco==TEXCO_OBJECT)
1071                                 texco= texco_object;
1072                         else if (mtex->texco==TEXCO_NORM)
1073                                 texco= orn;
1074                         else if (mtex->texco==TEXCO_TANGENT)
1075                                 texco= texco_object;
1076                         else if (mtex->texco==TEXCO_GLOB)
1077                                 texco= texco_global;
1078                         else if (mtex->texco==TEXCO_REFL) {
1079                                 GPU_link(mat, "texco_refl", shi->vn, shi->view, &shi->ref);
1080                                 texco= shi->ref;
1081                         }
1082                         else if (mtex->texco==TEXCO_UV) {
1083                                 if (1) { //!(texco_uv && strcmp(mtex->uvname, lastuvname) == 0)) {
1084                                         GPU_link(mat, "texco_uv", GPU_attribute(CD_MTFACE, mtex->uvname), &texco_uv);
1085                                         /*lastuvname = mtex->uvname;*/ /*UNUSED*/
1086                                 }
1087                                 texco= texco_uv;
1088                         }
1089                         else
1090                                 continue;
1091
1092                         /* in case of uv, this would just undo a multiplication in texco_uv */
1093                         if (mtex->texco != TEXCO_UV)
1094                                 GPU_link(mat, "mtex_2d_mapping", texco, &texco);
1095
1096                         if (mtex->size[0] != 1.0f || mtex->size[1] != 1.0f || mtex->size[2] != 1.0f)
1097                                 GPU_link(mat, "mtex_mapping_size", texco, GPU_uniform(mtex->size), &texco);
1098
1099                         ofs[0] = mtex->ofs[0] + 0.5f - 0.5f*mtex->size[0];
1100                         ofs[1] = mtex->ofs[1] + 0.5f - 0.5f*mtex->size[1];
1101                         ofs[2] = 0.0f;
1102                         if (ofs[0] != 0.0f || ofs[1] != 0.0f || ofs[2] != 0.0f)
1103                                 GPU_link(mat, "mtex_mapping_ofs", texco, GPU_uniform(ofs), &texco);
1104
1105                         talpha = 0;
1106
1107                         if (tex && tex->type == TEX_IMAGE && tex->ima) {
1108                                 GPU_link(mat, "mtex_image", texco, GPU_image(tex->ima, &tex->iuser, false), &tin, &trgb);
1109                                 rgbnor= TEX_RGB;
1110
1111                                 talpha = ((tex->imaflag & TEX_USEALPHA) && tex->ima && (tex->ima->flag & IMA_IGNORE_ALPHA) == 0);
1112                         }
1113                         else {
1114                                 continue;
1115                         }
1116
1117                         /* texture output */
1118                         if ((rgbnor & TEX_RGB) && (mtex->texflag & MTEX_RGBTOINT)) {
1119                                 GPU_link(mat, "mtex_rgbtoint", trgb, &tin);
1120                                 rgbnor -= TEX_RGB;
1121                         }
1122
1123                         if (mtex->texflag & MTEX_NEGATIVE) {
1124                                 if (rgbnor & TEX_RGB)
1125                                         GPU_link(mat, "mtex_rgb_invert", trgb, &trgb);
1126                                 else
1127                                         GPU_link(mat, "mtex_value_invert", tin, &tin);
1128                         }
1129
1130                         if (mtex->texflag & MTEX_STENCIL) {
1131                                 if (rgbnor & TEX_RGB)
1132                                         GPU_link(mat, "mtex_rgb_stencil", stencil, trgb, &stencil, &trgb);
1133                                 else
1134                                         GPU_link(mat, "mtex_value_stencil", stencil, tin, &stencil, &tin);
1135                         }
1136
1137                         /* mapping */
1138                         if (mtex->mapto & (MAP_COL+MAP_COLSPEC)) {
1139                                 /* stencil maps on the texture control slider, not texture intensity value */
1140                                 if ((rgbnor & TEX_RGB)==0) {
1141                                         GPU_link(mat, "set_rgb", GPU_uniform(&mtex->r), &tcol);
1142                                 }
1143                                 else {
1144                                         GPU_link(mat, "set_rgba", trgb, &tcol);
1145
1146                                         if (mtex->mapto & MAP_ALPHA)
1147                                                 GPU_link(mat, "set_value", stencil, &tin);
1148                                         else if (talpha)
1149                                                 GPU_link(mat, "mtex_alpha_from_col", trgb, &tin);
1150                                         else
1151                                                 GPU_link(mat, "set_value_one", &tin);
1152                                 }
1153
1154                                 if (tex->type==TEX_IMAGE)
1155                                         if (GPU_material_do_color_management(mat))
1156                                                 GPU_link(mat, "srgb_to_linearrgb", tcol, &tcol);
1157                                 
1158                                 if (mtex->mapto & MAP_COL) {
1159                                         GPUNodeLink *colfac;
1160
1161                                         if (mtex->colfac == 1.0f) colfac = stencil;
1162                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->colfac), stencil, &colfac);
1163
1164                                         texture_rgb_blend(mat, tcol, shi->rgb, tin, colfac, mtex->blendtype, &shi->rgb);
1165                                 }
1166                                 
1167                                 if (!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && (mtex->mapto & MAP_COLSPEC)) {
1168                                         GPUNodeLink *colspecfac;
1169
1170                                         if (mtex->colspecfac == 1.0f) colspecfac = stencil;
1171                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->colspecfac), stencil, &colspecfac);
1172
1173                                         texture_rgb_blend(mat, tcol, shi->specrgb, tin, colspecfac, mtex->blendtype, &shi->specrgb);
1174                                 }
1175                         }
1176
1177                         if (!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && (mtex->mapto & MAP_NORM)) {
1178                                 if (tex->type==TEX_IMAGE) {
1179                                         found_deriv_map = tex->imaflag & TEX_DERIVATIVEMAP;
1180
1181                                         if (tex->imaflag & TEX_NORMALMAP) {
1182                                                 /* normalmap image */
1183                                                 GPU_link(mat, "mtex_normal", texco, GPU_image(tex->ima, &tex->iuser, true), &tnor);
1184                                                 
1185                                                 if (mtex->norfac < 0.0f)
1186                                                         GPU_link(mat, "mtex_negate_texnormal", tnor, &tnor);
1187
1188                                                 if (mtex->normapspace == MTEX_NSPACE_TANGENT) {
1189                                                         if (iFirstTimeNMap != 0) {
1190                                                                 // use unnormalized normal (this is how we bake it - closer to gamedev)
1191                                                                 GPUNodeLink *vNegNorm;
1192                                                                 GPU_link(mat, "vec_math_negate", GPU_builtin(GPU_VIEW_NORMAL), &vNegNorm);
1193                                                                 GPU_link(mat, "mtex_nspace_tangent", GPU_attribute(CD_TANGENT, ""), vNegNorm, tnor, &newnor);
1194                                                                 iFirstTimeNMap = 0;
1195                                                         }
1196                                                         else { /* otherwise use accumulated perturbations */
1197                                                                 GPU_link(mat, "mtex_nspace_tangent", GPU_attribute(CD_TANGENT, ""), shi->vn, tnor, &newnor);
1198                                                         }
1199                                                 }
1200                                                 else if (mtex->normapspace == MTEX_NSPACE_OBJECT) {
1201                                                         /* transform normal by object then view matrix */
1202                                                         GPU_link(mat, "mtex_nspace_object", tnor, &newnor);
1203                                                 }
1204                                                 else if (mtex->normapspace == MTEX_NSPACE_WORLD) {
1205                                                         /* transform normal by view matrix */
1206                                                         GPU_link(mat, "mtex_nspace_world", GPU_builtin(GPU_VIEW_MATRIX), tnor, &newnor);
1207                                                 }
1208                                                 else {
1209                                                         /* no transform, normal in camera space */
1210                                                         newnor = tnor;
1211                                                 }
1212                                                 
1213                                                 norfac = min_ff(fabsf(mtex->norfac), 1.0f);
1214                                                 
1215                                                 if (norfac == 1.0f && !GPU_link_changed(stencil)) {
1216                                                         shi->vn = newnor;
1217                                                 }
1218                                                 else {
1219                                                         tnorfac = GPU_uniform(&norfac);
1220         
1221                                                         if (GPU_link_changed(stencil))
1222                                                                 GPU_link(mat, "math_multiply", tnorfac, stencil, &tnorfac);
1223         
1224                                                         GPU_link(mat, "mtex_blend_normal", tnorfac, shi->vn, newnor, &shi->vn);
1225                                                 }
1226                                                 
1227                                         }
1228                                         else if ( (mtex->texflag & (MTEX_3TAP_BUMP|MTEX_5TAP_BUMP|MTEX_BICUBIC_BUMP)) || found_deriv_map) {
1229                                                 /* ntap bumpmap image */
1230                                                 int iBumpSpace;
1231                                                 float ima_x, ima_y;
1232                                                 float hScale; 
1233
1234                                                 float imag_tspace_dimension_x = 1024.0f;                // only used for texture space variant
1235                                                 float aspect = 1.0f;
1236                                                 
1237                                                 GPUNodeLink *surf_pos = GPU_builtin(GPU_VIEW_POSITION);
1238                                                 GPUNodeLink *vR1, *vR2;
1239                                                 GPUNodeLink *dBs, *dBt, *fDet;
1240
1241                                                 hScale = 0.1;           // compatibility adjustment factor for all bumpspace types
1242                                                 if ( mtex->texflag & MTEX_BUMP_TEXTURESPACE )
1243                                                         hScale = 13.0f;         // factor for scaling texspace bumps
1244                                                 else if (found_deriv_map!=0)
1245                                                         hScale = 1.0f;
1246
1247                                                 // resolve texture resolution
1248                                                 if ( (mtex->texflag & MTEX_BUMP_TEXTURESPACE) || found_deriv_map ) {
1249                                                         ImBuf *ibuf= BKE_image_acquire_ibuf(tex->ima, &tex->iuser, NULL);
1250                                                         ima_x= 512.0f; ima_y= 512.f;            // prevent calling textureSize, glsl 1.3 only
1251                                                         if (ibuf) {
1252                                                                 ima_x= ibuf->x;
1253                                                                 ima_y= ibuf->y;
1254                                                                 aspect = ((float) ima_y) / ima_x;
1255                                                         }
1256                                                         BKE_image_release_ibuf(tex->ima, ibuf, NULL);
1257                                                 }
1258
1259                                                 // The negate on norfac is done because the
1260                                                 // normal in the renderer points inward which corresponds
1261                                                 // to inverting the bump map. Should this ever change
1262                                                 // this negate must be removed.
1263                                                 norfac = -hScale * mtex->norfac;
1264                                                 if (found_deriv_map) {
1265                                                         float fVirtDim = sqrtf(fabsf(ima_x*mtex->size[0]*ima_y*mtex->size[1]));
1266                                                         norfac /= MAX2(fVirtDim, FLT_EPSILON);
1267                                                 }
1268
1269                                                 tnorfac = GPU_uniform(&norfac);
1270
1271                                                 if (found_deriv_map)
1272                                                         GPU_link(mat, "math_multiply", tnorfac, GPU_builtin(GPU_AUTO_BUMPSCALE), &tnorfac);
1273                                                 
1274                                                 if (GPU_link_changed(stencil))
1275                                                         GPU_link(mat, "math_multiply", tnorfac, stencil, &tnorfac);
1276                                                 
1277                                                 if ( !init_done ) {
1278                                                         // copy shi->vn to vNorg and vNacc, set magnitude to 1
1279                                                         GPU_link(mat, "mtex_bump_normals_init", shi->vn, &vNorg, &vNacc, &fPrevMagnitude);
1280                                                         iBumpSpacePrev = 0;
1281                                                         init_done = true;
1282                                                 }
1283                                                 
1284                                                 // find current bump space
1285                                                 if ( mtex->texflag & MTEX_BUMP_OBJECTSPACE )
1286                                                         iBumpSpace = 1;
1287                                                 else if ( mtex->texflag & MTEX_BUMP_TEXTURESPACE )
1288                                                         iBumpSpace = 2;
1289                                                 else
1290                                                         iBumpSpace = 4; // ViewSpace
1291                                                 
1292                                                 // re-initialize if bump space changed
1293                                                 if ( iBumpSpacePrev != iBumpSpace ) {
1294                                                         
1295                                                         if ( mtex->texflag & MTEX_BUMP_OBJECTSPACE )
1296                                                                 GPU_link(mat, "mtex_bump_init_objspace",
1297                                                                          surf_pos, vNorg,
1298                                                                          GPU_builtin(GPU_VIEW_MATRIX), GPU_builtin(GPU_INVERSE_VIEW_MATRIX), GPU_builtin(GPU_OBJECT_MATRIX),  GPU_builtin(GPU_INVERSE_OBJECT_MATRIX),
1299                                                                          fPrevMagnitude, vNacc,
1300                                                                          &fPrevMagnitude, &vNacc,
1301                                                                          &vR1, &vR2, &fDet);
1302                                                                 
1303                                                         else if ( mtex->texflag & MTEX_BUMP_TEXTURESPACE )
1304                                                                 GPU_link(mat, "mtex_bump_init_texturespace",
1305                                                                          surf_pos, vNorg,
1306                                                                          fPrevMagnitude, vNacc,
1307                                                                          &fPrevMagnitude, &vNacc,
1308                                                                          &vR1, &vR2, &fDet);
1309                                                                 
1310                                                         else
1311                                                                 GPU_link(mat, "mtex_bump_init_viewspace",
1312                                                                          surf_pos, vNorg,
1313                                                                          fPrevMagnitude, vNacc,
1314                                                                          &fPrevMagnitude, &vNacc,
1315                                                                          &vR1, &vR2, &fDet);
1316                                                         
1317                                                         iBumpSpacePrev = iBumpSpace;
1318                                                 }
1319                                                 
1320                                                 
1321                                                 if (found_deriv_map) {
1322                                                         GPU_link(mat, "mtex_bump_deriv",
1323                                                                  texco, GPU_image(tex->ima, &tex->iuser, true), GPU_uniform(&ima_x), GPU_uniform(&ima_y), tnorfac,
1324                                                                  &dBs, &dBt );
1325                                                 }
1326                                                 else if ( mtex->texflag & MTEX_3TAP_BUMP)
1327                                                         GPU_link(mat, "mtex_bump_tap3",
1328                                                                  texco, GPU_image(tex->ima, &tex->iuser, true), tnorfac,
1329                                                                  &dBs, &dBt );
1330                                                 else if ( mtex->texflag & MTEX_5TAP_BUMP)
1331                                                         GPU_link(mat, "mtex_bump_tap5",
1332                                                                  texco, GPU_image(tex->ima, &tex->iuser, true), tnorfac,
1333                                                                  &dBs, &dBt );
1334                                                 else if ( mtex->texflag & MTEX_BICUBIC_BUMP ) {
1335                                                         if (GPU_bicubic_bump_support()) {
1336                                                                 GPU_link(mat, "mtex_bump_bicubic",
1337                                                                          texco, GPU_image(tex->ima, &tex->iuser, true), tnorfac,
1338                                                                          &dBs, &dBt);
1339                                                         }
1340                                                         else {
1341                                                                 GPU_link(mat, "mtex_bump_tap5",
1342                                                                          texco, GPU_image(tex->ima, &tex->iuser, true), tnorfac,
1343                                                                          &dBs, &dBt);
1344                                                         }
1345                                                 }
1346                                                 
1347                                                 
1348                                                 if ( mtex->texflag & MTEX_BUMP_TEXTURESPACE ) {
1349                                                         float imag_tspace_dimension_y = aspect*imag_tspace_dimension_x;
1350                                                         GPU_link(mat, "mtex_bump_apply_texspace",
1351                                                                  fDet, dBs, dBt, vR1, vR2,
1352                                                                  GPU_image(tex->ima, &tex->iuser, true), texco,
1353                                                                  GPU_uniform(&imag_tspace_dimension_x), GPU_uniform(&imag_tspace_dimension_y), vNacc,
1354                                                                  &vNacc, &shi->vn );
1355                                                 }
1356                                                 else
1357                                                         GPU_link(mat, "mtex_bump_apply",
1358                                                                  fDet, dBs, dBt, vR1, vR2, vNacc,
1359                                                                  &vNacc, &shi->vn );
1360                                                 
1361                                         }
1362                                 }
1363                                 
1364                                 GPU_link(mat, "vec_math_negate", shi->vn, &orn);
1365                         }
1366
1367                         if ((mtex->mapto & MAP_VARS)) {
1368                                 if (rgbnor & TEX_RGB) {
1369                                         if (talpha)
1370                                                 GPU_link(mat, "mtex_alpha_from_col", trgb, &tin);
1371                                         else
1372                                                 GPU_link(mat, "mtex_rgbtoint", trgb, &tin);
1373                                 }
1374
1375                                 if (!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_REF) {
1376                                         GPUNodeLink *difffac;
1377
1378                                         if (mtex->difffac == 1.0f) difffac = stencil;
1379                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->difffac), stencil, &difffac);
1380
1381                                         texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->refl, tin, difffac, mtex->blendtype, &shi->refl);
1382                                         GPU_link(mat, "mtex_value_clamp_positive", shi->refl, &shi->refl);
1383                                 }
1384                                 if (!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_SPEC) {
1385                                         GPUNodeLink *specfac;
1386
1387                                         if (mtex->specfac == 1.0f) specfac = stencil;
1388                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->specfac), stencil, &specfac);
1389
1390                                         texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->spec, tin, specfac, mtex->blendtype, &shi->spec);
1391                                         GPU_link(mat, "mtex_value_clamp_positive", shi->spec, &shi->spec);
1392                                 }
1393                                 if (!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_EMIT) {
1394                                         GPUNodeLink *emitfac;
1395
1396                                         if (mtex->emitfac == 1.0f) emitfac = stencil;
1397                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->emitfac), stencil, &emitfac);
1398
1399                                         texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->emit, tin, emitfac, mtex->blendtype, &shi->emit);
1400                                         GPU_link(mat, "mtex_value_clamp_positive", shi->emit, &shi->emit);
1401                                 }
1402                                 if (!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_HAR) {
1403                                         GPUNodeLink *hardfac;
1404
1405                                         if (mtex->hardfac == 1.0f) hardfac = stencil;
1406                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->hardfac), stencil, &hardfac);
1407
1408                                         GPU_link(mat, "mtex_har_divide", shi->har, &shi->har);
1409                                         texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->har, tin, hardfac, mtex->blendtype, &shi->har);
1410                                         GPU_link(mat, "mtex_har_multiply_clamp", shi->har, &shi->har);
1411                                 }
1412                                 if (mtex->mapto & MAP_ALPHA) {
1413                                         GPUNodeLink *alphafac;
1414
1415                                         if (mtex->alphafac == 1.0f) alphafac = stencil;
1416                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->alphafac), stencil, &alphafac);
1417
1418                                         texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->alpha, tin, alphafac, mtex->blendtype, &shi->alpha);
1419                                         GPU_link(mat, "mtex_value_clamp", shi->alpha, &shi->alpha);
1420                                 }
1421                                 if (!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_AMB) {
1422                                         GPUNodeLink *ambfac;
1423
1424                                         if (mtex->ambfac == 1.0f) ambfac = stencil;
1425                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->ambfac), stencil, &ambfac);
1426
1427                                         texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->amb, tin, ambfac, mtex->blendtype, &shi->amb);
1428                                         GPU_link(mat, "mtex_value_clamp", shi->amb, &shi->amb);
1429                                 }
1430                         }
1431                 }
1432         }
1433 }
1434
1435 void GPU_shadeinput_set(GPUMaterial *mat, Material *ma, GPUShadeInput *shi)
1436 {
1437         float hard = ma->har;
1438         float one = 1.0f;
1439
1440         memset(shi, 0, sizeof(*shi));
1441
1442         shi->gpumat = mat;
1443         shi->mat = ma;
1444
1445         GPU_link(mat, "set_rgb", GPU_uniform(&ma->r), &shi->rgb);
1446         GPU_link(mat, "set_rgb", GPU_uniform(&ma->specr), &shi->specrgb);
1447         GPU_link(mat, "shade_norm", GPU_builtin(GPU_VIEW_NORMAL), &shi->vn);
1448
1449         if (mat->alpha)
1450                 GPU_link(mat, "set_value", GPU_uniform(&ma->alpha), &shi->alpha);
1451         else
1452                 GPU_link(mat, "set_value", GPU_uniform(&one), &shi->alpha);
1453
1454         GPU_link(mat, "set_value", GPU_uniform(&ma->ref), &shi->refl);
1455         GPU_link(mat, "set_value", GPU_uniform(&ma->spec), &shi->spec);
1456         GPU_link(mat, "set_value", GPU_uniform(&ma->emit), &shi->emit);
1457         GPU_link(mat, "set_value", GPU_uniform(&hard), &shi->har);
1458         GPU_link(mat, "set_value", GPU_uniform(&ma->amb), &shi->amb);
1459         GPU_link(mat, "set_value", GPU_uniform(&ma->spectra), &shi->spectra);
1460         GPU_link(mat, "shade_view", GPU_builtin(GPU_VIEW_POSITION), &shi->view);
1461         GPU_link(mat, "vcol_attribute", GPU_attribute(CD_MCOL, ""), &shi->vcol);
1462         if (GPU_material_do_color_management(mat))
1463                 GPU_link(mat, "srgb_to_linearrgb", shi->vcol, &shi->vcol);
1464         GPU_link(mat, "texco_refl", shi->vn, shi->view, &shi->ref);
1465 }
1466
1467 void GPU_shaderesult_set(GPUShadeInput *shi, GPUShadeResult *shr)
1468 {
1469         GPUMaterial *mat= shi->gpumat;
1470         GPUNodeLink *emit, *ulinfac, *ulogfac, *mistfac;
1471         Material *ma= shi->mat;
1472         World *world= mat->scene->world;
1473         float linfac, logfac, misttype;
1474
1475         memset(shr, 0, sizeof(*shr));
1476
1477         if (ma->mode & MA_VERTEXCOLP)
1478                 shi->rgb = shi->vcol;
1479
1480         do_material_tex(shi);
1481
1482         if ((mat->scene->gm.flag & GAME_GLSL_NO_LIGHTS) || (ma->mode & MA_SHLESS)) {
1483                 GPU_link(mat, "set_rgb", shi->rgb, &shr->diff);
1484                 GPU_link(mat, "set_rgb_zero", &shr->spec);
1485                 GPU_link(mat, "set_value", shi->alpha, &shr->alpha);
1486                 shr->combined = shr->diff;
1487         }
1488         else {
1489                 if (GPU_link_changed(shi->emit) || ma->emit != 0.0f) {
1490                         if ((ma->mode & (MA_VERTEXCOL|MA_VERTEXCOLP))== MA_VERTEXCOL) {
1491                                 GPU_link(mat, "shade_add", shi->emit, shi->vcol, &emit);
1492                                 GPU_link(mat, "shade_mul", emit, shi->rgb, &shr->diff);
1493                         }
1494                         else
1495                                 GPU_link(mat, "shade_mul_value", shi->emit, shi->rgb, &shr->diff);
1496                 }
1497                 else
1498                         GPU_link(mat, "set_rgb_zero", &shr->diff);
1499
1500                 GPU_link(mat, "set_rgb_zero", &shr->spec);
1501
1502                 material_lights(shi, shr);
1503
1504                 shr->combined = shr->diff;
1505
1506                 GPU_link(mat, "set_value", shi->alpha, &shr->alpha);
1507
1508                 if (world) {
1509                         /* exposure correction */
1510                         if (world->exp!=0.0f || world->range!=1.0f) {
1511                                 linfac= 1.0f + powf((2.0f*world->exp + 0.5f), -10);
1512                                 logfac= logf((linfac-1.0f)/linfac)/world->range;
1513
1514                                 GPU_link(mat, "set_value", GPU_uniform(&linfac), &ulinfac);
1515                                 GPU_link(mat, "set_value", GPU_uniform(&logfac), &ulogfac);
1516
1517                                 GPU_link(mat, "shade_exposure_correct", shr->combined,
1518                                         ulinfac, ulogfac, &shr->combined);
1519                                 GPU_link(mat, "shade_exposure_correct", shr->spec,
1520                                         ulinfac, ulogfac, &shr->spec);
1521                         }
1522
1523                         /* ambient color */
1524                         if (world->ambr!=0.0f || world->ambg!=0.0f || world->ambb!=0.0f) {
1525                                 if (GPU_link_changed(shi->amb) || ma->amb != 0.0f)
1526                                         GPU_link(mat, "shade_maddf", shr->combined, GPU_uniform(&ma->amb),
1527                                                 GPU_uniform(&world->ambr), &shr->combined);
1528                         }
1529                 }
1530
1531                 if (ma->mode & MA_TRANSP && (ma->mode & (MA_ZTRANSP|MA_RAYTRANSP))) {
1532                         if (GPU_link_changed(shi->spectra) || ma->spectra != 0.0f)
1533                                 GPU_link(mat, "alpha_spec_correction", shr->spec, shi->spectra,
1534                                         shi->alpha, &shr->alpha);
1535                 }
1536
1537                 if (ma->mode & MA_RAMP_COL) ramp_diffuse_result(shi, &shr->combined);
1538                 if (ma->mode & MA_RAMP_SPEC) ramp_spec_result(shi, &shr->spec);
1539
1540                 if (GPU_link_changed(shi->spec) || ma->spec != 0.0f)
1541                         GPU_link(mat, "shade_add", shr->combined, shr->spec, &shr->combined);
1542         }
1543
1544         GPU_link(mat, "mtex_alpha_to_col", shr->combined, shr->alpha, &shr->combined);
1545
1546         if (ma->shade_flag & MA_OBCOLOR)
1547                 GPU_link(mat, "shade_obcolor", shr->combined, GPU_builtin(GPU_OBCOLOR), &shr->combined);
1548
1549         if (world && (world->mode & WO_MIST) && !(ma->mode & MA_NOMIST)) {
1550                 misttype = world->mistype;
1551
1552                 GPU_link(mat, "shade_mist_factor", GPU_builtin(GPU_VIEW_POSITION),
1553                         GPU_uniform(&world->miststa), GPU_uniform(&world->mistdist),
1554                         GPU_uniform(&misttype), GPU_uniform(&world->misi), &mistfac);
1555
1556                 GPU_link(mat, "mix_blend", mistfac, shr->combined,
1557                         GPU_uniform(&world->horr), &shr->combined);
1558         }
1559
1560         if (!mat->alpha) {
1561                 if (world && (GPU_link_changed(shr->alpha) || ma->alpha != 1.0f))
1562                         GPU_link(mat, "shade_world_mix", GPU_uniform(&world->horr),
1563                                 shr->combined, &shr->combined);
1564
1565                 GPU_link(mat, "shade_alpha_opaque", shr->combined, &shr->combined);
1566         }
1567
1568         if (ma->shade_flag & MA_OBCOLOR) {
1569                 mat->obcolalpha = 1;
1570                 GPU_link(mat, "shade_alpha_obcolor", shr->combined, GPU_builtin(GPU_OBCOLOR), &shr->combined);
1571         }
1572 }
1573
1574 static GPUNodeLink *GPU_blender_material(GPUMaterial *mat, Material *ma)
1575 {
1576         GPUShadeInput shi;
1577         GPUShadeResult shr;
1578
1579         GPU_shadeinput_set(mat, ma, &shi);
1580         GPU_shaderesult_set(&shi, &shr);
1581
1582         return shr.combined;
1583 }
1584
1585 static GPUNodeLink *gpu_material_diffuse_bsdf(GPUMaterial *mat, Material *ma)
1586 {
1587         static float roughness = 0.0f;
1588         GPUNodeLink *outlink;
1589
1590         GPU_link(mat, "node_bsdf_diffuse", GPU_uniform(&ma->r), GPU_uniform(&roughness), GPU_builtin(GPU_VIEW_NORMAL), &outlink);
1591
1592         return outlink;
1593 }
1594
1595 static GPUNodeLink *gpu_material_preview_matcap(GPUMaterial *mat, Material *ma)
1596 {
1597         GPUNodeLink *outlink;
1598         
1599         /* some explanations here:
1600          * matcap normal holds the normal remapped to the 0.0 - 1.0 range. To take advantage of flat shading, we abuse
1601          * the built in secondary color of opengl. Color is just the regular color, which should include mask value too.
1602          * This also needs flat shading so we use the primary opengl color built-in */
1603         GPU_link(mat, "material_preview_matcap", GPU_uniform(&ma->r), GPU_image_preview(ma->preview), GPU_opengl_builtin(GPU_MATCAP_NORMAL), GPU_opengl_builtin(GPU_COLOR), &outlink);
1604         
1605         return outlink;
1606 }
1607
1608 /* new solid draw mode with glsl matcaps */
1609 GPUMaterial *GPU_material_matcap(Scene *scene, Material *ma)
1610 {
1611         GPUMaterial *mat;
1612         GPUNodeLink *outlink;
1613         LinkData *link;
1614         
1615         for (link=ma->gpumaterial.first; link; link=link->next)
1616                 if (((GPUMaterial*)link->data)->scene == scene)
1617                         return link->data;
1618         
1619         /* allocate material */
1620         mat = GPU_material_construct_begin(ma);
1621         mat->scene = scene;
1622         mat->type = GPU_MATERIAL_TYPE_MESH;
1623         
1624         if (ma->preview && ma->preview->rect[0]) {
1625                 outlink = gpu_material_preview_matcap(mat, ma);
1626         }
1627         else {
1628                 outlink = gpu_material_diffuse_bsdf(mat, ma);
1629         }
1630                 
1631         GPU_material_output_link(mat, outlink);
1632
1633         GPU_material_construct_end(mat, "matcap_pass");
1634         
1635         /* note that even if building the shader fails in some way, we still keep
1636          * it to avoid trying to compile again and again, and simple do not use
1637          * the actual shader on drawing */
1638         
1639         link = MEM_callocN(sizeof(LinkData), "GPUMaterialLink");
1640         link->data = mat;
1641         BLI_addtail(&ma->gpumaterial, link);
1642         
1643         return mat;
1644 }
1645
1646 GPUMaterial *GPU_material_world(struct Scene *scene, struct World *wo)
1647 {
1648         LinkData *link;
1649         GPUMaterial *mat;
1650
1651         for (link=wo->gpumaterial.first; link; link=link->next)
1652                 if (((GPUMaterial*)link->data)->scene == scene)
1653                         return link->data;
1654
1655         /* allocate material */
1656         mat = GPU_material_construct_begin(NULL);
1657         mat->scene = scene;
1658         mat->type = GPU_MATERIAL_TYPE_WORLD;
1659         
1660         /* create nodes */
1661         if (BKE_scene_use_new_shading_nodes(scene) && wo->nodetree && wo->use_nodes)
1662                 ntreeGPUMaterialNodes(wo->nodetree, mat, NODE_NEW_SHADING);
1663         else {
1664                 /* old fixed function world */
1665         }
1666
1667         if (GPU_material_do_color_management(mat))
1668                 if (mat->outlink)
1669                         GPU_link(mat, "linearrgb_to_srgb", mat->outlink, &mat->outlink);
1670
1671         GPU_material_construct_end(mat, wo->id.name);
1672         
1673         /* note that even if building the shader fails in some way, we still keep
1674          * it to avoid trying to compile again and again, and simple do not use
1675          * the actual shader on drawing */
1676
1677         link = MEM_callocN(sizeof(LinkData), "GPUMaterialLink");
1678         link->data = mat;
1679         BLI_addtail(&wo->gpumaterial, link);
1680
1681         return mat;
1682 }
1683
1684
1685 GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma)
1686 {
1687         GPUMaterial *mat;
1688         GPUNodeLink *outlink;
1689         LinkData *link;
1690
1691         for (link=ma->gpumaterial.first; link; link=link->next)
1692                 if (((GPUMaterial*)link->data)->scene == scene)
1693                         return link->data;
1694
1695         /* allocate material */
1696         mat = GPU_material_construct_begin(ma);
1697         mat->scene = scene;
1698         mat->type = GPU_MATERIAL_TYPE_MESH;
1699
1700         /* render pipeline option */
1701         if (ma->mode & MA_TRANSP)
1702                 GPU_material_enable_alpha(mat);
1703
1704         if (!(scene->gm.flag & GAME_GLSL_NO_NODES) && ma->nodetree && ma->use_nodes) {
1705                 /* create nodes */
1706                 if (BKE_scene_use_new_shading_nodes(scene))
1707                         ntreeGPUMaterialNodes(ma->nodetree, mat, NODE_NEW_SHADING);
1708                 else
1709                         ntreeGPUMaterialNodes(ma->nodetree, mat, NODE_OLD_SHADING);
1710         }
1711         else {
1712                 if (BKE_scene_use_new_shading_nodes(scene)) {
1713                         /* create simple diffuse material instead of nodes */
1714                         outlink = gpu_material_diffuse_bsdf(mat, ma);
1715                 }
1716                 else {
1717                         /* create blender material */
1718                         outlink = GPU_blender_material(mat, ma);
1719                 }
1720
1721                 GPU_material_output_link(mat, outlink);
1722         }
1723
1724         if (GPU_material_do_color_management(mat))
1725                 if (mat->outlink)
1726                         GPU_link(mat, "linearrgb_to_srgb", mat->outlink, &mat->outlink);
1727
1728         GPU_material_construct_end(mat, ma->id.name);
1729
1730         /* note that even if building the shader fails in some way, we still keep
1731          * it to avoid trying to compile again and again, and simple do not use
1732          * the actual shader on drawing */
1733
1734         link = MEM_callocN(sizeof(LinkData), "GPUMaterialLink");
1735         link->data = mat;
1736         BLI_addtail(&ma->gpumaterial, link);
1737
1738         return mat;
1739 }
1740
1741 void GPU_materials_free(void)
1742 {
1743         Object *ob;
1744         Material *ma;
1745         World *wo;
1746         extern Material defmaterial;
1747
1748         for (ma=G.main->mat.first; ma; ma=ma->id.next)
1749                 GPU_material_free(&ma->gpumaterial);
1750
1751         for (wo=G.main->world.first; wo; wo=wo->id.next)
1752                 GPU_material_free(&wo->gpumaterial);
1753         
1754         GPU_material_free(&defmaterial.gpumaterial);
1755
1756         for (ob=G.main->object.first; ob; ob=ob->id.next)
1757                 GPU_lamp_free(ob);
1758 }
1759
1760 /* Lamps and shadow buffers */
1761
1762 static void gpu_lamp_calc_winmat(GPULamp *lamp)
1763 {
1764         float temp, angle, pixsize, wsize;
1765
1766         if (lamp->type == LA_SUN) {
1767                 wsize = lamp->la->shadow_frustum_size;
1768                 orthographic_m4(lamp->winmat, -wsize, wsize, -wsize, wsize, lamp->d, lamp->clipend);
1769         }
1770         else {
1771                 angle = saacos(lamp->spotsi);
1772                 temp = 0.5f * lamp->size * cosf(angle) / sinf(angle);
1773                 pixsize = lamp->d / temp;
1774                 wsize = pixsize * 0.5f * lamp->size;
1775                 perspective_m4(lamp->winmat, -wsize, wsize, -wsize, wsize, lamp->d, lamp->clipend);
1776         }
1777 }
1778
1779 void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[4][4])
1780 {
1781         float mat[4][4];
1782
1783         lamp->lay = lay;
1784         lamp->hide = hide;
1785
1786         copy_m4_m4(mat, obmat);
1787         normalize_m4(mat);
1788
1789         copy_v3_v3(lamp->vec, mat[2]);
1790         copy_v3_v3(lamp->co, mat[3]);
1791         copy_m4_m4(lamp->obmat, mat);
1792         invert_m4_m4(lamp->imat, mat);
1793 }
1794
1795 void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float energy)
1796 {
1797         lamp->energy = energy;
1798         if (lamp->mode & LA_NEG) lamp->energy= -lamp->energy;
1799
1800         lamp->col[0]= r;
1801         lamp->col[1]= g;
1802         lamp->col[2]= b;
1803 }
1804
1805 void GPU_lamp_update_distance(GPULamp *lamp, float distance, float att1, float att2)
1806 {
1807         lamp->dist = distance;
1808         lamp->att1 = att1;
1809         lamp->att2 = att2;
1810 }
1811
1812 void GPU_lamp_update_spot(GPULamp *lamp, float spotsize, float spotblend)
1813 {
1814         lamp->spotsi = cosf(spotsize * 0.5f);
1815         lamp->spotbl = (1.0f - lamp->spotsi) * spotblend;
1816
1817         gpu_lamp_calc_winmat(lamp);
1818 }
1819
1820 static void gpu_lamp_from_blender(Scene *scene, Object *ob, Object *par, Lamp *la, GPULamp *lamp)
1821 {
1822         lamp->scene = scene;
1823         lamp->ob = ob;
1824         lamp->par = par;
1825         lamp->la = la;
1826
1827         /* add_render_lamp */
1828         lamp->mode = la->mode;
1829         lamp->type = la->type;
1830
1831         lamp->energy = la->energy;
1832         if (lamp->mode & LA_NEG) lamp->energy= -lamp->energy;
1833
1834         lamp->col[0]= la->r;
1835         lamp->col[1]= la->g;
1836         lamp->col[2]= la->b;
1837
1838         GPU_lamp_update(lamp, ob->lay, (ob->restrictflag & OB_RESTRICT_RENDER), ob->obmat);
1839
1840         lamp->spotsi = la->spotsize;
1841         if (lamp->mode & LA_HALO)
1842                 if (lamp->spotsi > DEG2RADF(170.0f))
1843                         lamp->spotsi = DEG2RADF(170.0f);
1844         lamp->spotsi = cosf(lamp->spotsi * 0.5f);
1845         lamp->spotbl= (1.0f - lamp->spotsi)*la->spotblend;
1846         lamp->k= la->k;
1847
1848         lamp->dist= la->dist;
1849         lamp->falloff_type= la->falloff_type;
1850         lamp->att1= la->att1;
1851         lamp->att2= la->att2;
1852         lamp->curfalloff= la->curfalloff;
1853
1854         /* initshadowbuf */
1855         lamp->bias = 0.02f*la->bias;
1856         lamp->size = la->bufsize;
1857         lamp->d= la->clipsta;
1858         lamp->clipend= la->clipend;
1859
1860         /* arbitrary correction for the fact we do no soft transition */
1861         lamp->bias *= 0.25f;
1862
1863         /* makeshadowbuf */
1864         gpu_lamp_calc_winmat(lamp);
1865 }
1866
1867 static void gpu_lamp_shadow_free(GPULamp *lamp)
1868 {
1869         if (lamp->tex) {
1870                 GPU_texture_free(lamp->tex);
1871                 lamp->tex= NULL;
1872         }
1873         if (lamp->depthtex) {
1874                 GPU_texture_free(lamp->depthtex);
1875                 lamp->depthtex= NULL;
1876         }
1877         if (lamp->fb) {
1878                 GPU_framebuffer_free(lamp->fb);
1879                 lamp->fb= NULL;
1880         }
1881         if (lamp->blurtex) {
1882                 GPU_texture_free(lamp->blurtex);
1883                 lamp->blurtex= NULL;
1884         }
1885         if (lamp->blurfb) {
1886                 GPU_framebuffer_free(lamp->blurfb);
1887                 lamp->blurfb= NULL;
1888         }
1889 }
1890
1891 GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par)
1892 {
1893         Lamp *la;
1894         GPULamp *lamp;
1895         LinkData *link;
1896
1897         for (link=ob->gpulamp.first; link; link=link->next) {
1898                 lamp = (GPULamp*)link->data;
1899
1900                 if (lamp->par == par && lamp->scene == scene)
1901                         return link->data;
1902         }
1903
1904         lamp = MEM_callocN(sizeof(GPULamp), "GPULamp");
1905
1906         link = MEM_callocN(sizeof(LinkData), "GPULampLink");
1907         link->data = lamp;
1908         BLI_addtail(&ob->gpulamp, link);
1909
1910         la = ob->data;
1911         gpu_lamp_from_blender(scene, ob, par, la, lamp);
1912
1913         if ((la->type==LA_SPOT && (la->mode & (LA_SHAD_BUF | LA_SHAD_RAY))) || (la->type==LA_SUN && (la->mode & LA_SHAD_RAY))) {
1914                 /* opengl */
1915                 lamp->fb = GPU_framebuffer_create();
1916                 if (!lamp->fb) {
1917                         gpu_lamp_shadow_free(lamp);
1918                         return lamp;
1919                 }
1920
1921                 if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) {
1922                         /* Shadow depth map */
1923                         lamp->depthtex = GPU_texture_create_depth(lamp->size, lamp->size, NULL);
1924                         if (!lamp->depthtex) {
1925                                 gpu_lamp_shadow_free(lamp);
1926                                 return lamp;
1927                         }
1928                 
1929                         if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->depthtex, 0, NULL)) {
1930                                 gpu_lamp_shadow_free(lamp);
1931                                 return lamp;
1932                         }
1933
1934                         /* Shadow color map */
1935                         lamp->tex = GPU_texture_create_vsm_shadow_map(lamp->size, NULL);
1936                         if (!lamp->tex) {
1937                                 gpu_lamp_shadow_free(lamp);
1938                                 return lamp;
1939                         }
1940
1941                         if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex, 0, NULL)) {
1942                                 gpu_lamp_shadow_free(lamp);
1943                                 return lamp;
1944                         }
1945
1946                         if (!GPU_framebuffer_check_valid(lamp->fb, NULL)) {
1947                                 gpu_lamp_shadow_free(lamp);
1948                                 return lamp;                            
1949                         }
1950                         
1951                         /* FBO and texture for blurring */
1952                         lamp->blurfb = GPU_framebuffer_create();
1953                         if (!lamp->blurfb) {
1954                                 gpu_lamp_shadow_free(lamp);
1955                                 return lamp;
1956                         }
1957
1958                         lamp->blurtex = GPU_texture_create_vsm_shadow_map(lamp->size*0.5, NULL);
1959                         if (!lamp->blurtex) {
1960                                 gpu_lamp_shadow_free(lamp);
1961                                 return lamp;
1962                         }
1963                 
1964                         if (!GPU_framebuffer_texture_attach(lamp->blurfb, lamp->blurtex, 0, NULL)) {
1965                                 gpu_lamp_shadow_free(lamp);
1966                                 return lamp;
1967                         }
1968                         
1969                         /* we need to properly bind to test for completeness */
1970                         GPU_texture_bind_as_framebuffer(lamp->blurtex);
1971                         
1972                         if (!GPU_framebuffer_check_valid(lamp->blurfb, NULL)) {
1973                                 gpu_lamp_shadow_free(lamp);
1974                                 return lamp;
1975                         }
1976                         
1977                         GPU_framebuffer_texture_unbind(lamp->blurfb, lamp->blurtex);
1978                 }
1979                 else {
1980                         lamp->tex = GPU_texture_create_depth(lamp->size, lamp->size, NULL);
1981                         if (!lamp->tex) {
1982                                 gpu_lamp_shadow_free(lamp);
1983                                 return lamp;
1984                         }
1985
1986                         if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex, 0, NULL)) {
1987                                 gpu_lamp_shadow_free(lamp);
1988                                 return lamp;
1989                         }
1990                         
1991                         if (!GPU_framebuffer_check_valid(lamp->fb, NULL)) {
1992                                 gpu_lamp_shadow_free(lamp);
1993                                 return lamp;                            
1994                         }                                               
1995                 }
1996
1997                 GPU_framebuffer_restore();
1998
1999                 lamp->shadow_color[0] = la->shdwr;
2000                 lamp->shadow_color[1] = la->shdwg;
2001                 lamp->shadow_color[2] = la->shdwb;
2002         }
2003         else {
2004                 lamp->shadow_color[0] = 1.0;
2005                 lamp->shadow_color[1] = 1.0;
2006                 lamp->shadow_color[2] = 1.0;
2007         }
2008
2009         return lamp;
2010 }
2011
2012 void GPU_lamp_free(Object *ob)
2013 {
2014         GPULamp *lamp;
2015         LinkData *link;
2016         LinkData *nlink;
2017         Material *ma;
2018
2019         for (link=ob->gpulamp.first; link; link=link->next) {
2020                 lamp = link->data;
2021
2022                 while (lamp->materials.first) {
2023                         nlink = lamp->materials.first;
2024                         ma = nlink->data;
2025                         BLI_freelinkN(&lamp->materials, nlink);
2026
2027                         if (ma->gpumaterial.first)
2028                                 GPU_material_free(&ma->gpumaterial);
2029                 }
2030
2031                 gpu_lamp_shadow_free(lamp);
2032
2033                 MEM_freeN(lamp);
2034         }
2035
2036         BLI_freelistN(&ob->gpulamp);
2037 }
2038
2039 bool GPU_lamp_has_shadow_buffer(GPULamp *lamp)
2040 {
2041         return (!(lamp->scene->gm.flag & GAME_GLSL_NO_SHADOWS) &&
2042                 !(lamp->scene->gm.flag & GAME_GLSL_NO_LIGHTS) &&
2043                 lamp->tex && lamp->fb);
2044 }
2045
2046 void GPU_lamp_update_buffer_mats(GPULamp *lamp)
2047 {
2048         float rangemat[4][4], persmat[4][4];
2049
2050         /* initshadowbuf */
2051         invert_m4_m4(lamp->viewmat, lamp->obmat);
2052         normalize_v3(lamp->viewmat[0]);
2053         normalize_v3(lamp->viewmat[1]);
2054         normalize_v3(lamp->viewmat[2]);
2055
2056         /* makeshadowbuf */
2057         mul_m4_m4m4(persmat, lamp->winmat, lamp->viewmat);
2058
2059         /* opengl depth buffer is range 0.0..1.0 instead of -1.0..1.0 in blender */
2060         unit_m4(rangemat);
2061         rangemat[0][0] = 0.5f;
2062         rangemat[1][1] = 0.5f;
2063         rangemat[2][2] = 0.5f;
2064         rangemat[3][0] = 0.5f;
2065         rangemat[3][1] = 0.5f;
2066         rangemat[3][2] = 0.5f;
2067
2068         mul_m4_m4m4(lamp->persmat, rangemat, persmat);
2069 }
2070
2071 void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[4][4], int *winsize, float winmat[4][4])
2072 {
2073         GPU_lamp_update_buffer_mats(lamp);
2074
2075         /* opengl */
2076         glDisable(GL_SCISSOR_TEST);
2077         GPU_texture_bind_as_framebuffer(lamp->tex);
2078         if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE)
2079                 GPU_shader_bind(GPU_shader_get_builtin_shader(GPU_SHADER_VSM_STORE));
2080
2081         /* set matrices */
2082         copy_m4_m4(viewmat, lamp->viewmat);
2083         copy_m4_m4(winmat, lamp->winmat);
2084         *winsize = lamp->size;
2085 }
2086
2087 void GPU_lamp_shadow_buffer_unbind(GPULamp *lamp)
2088 {
2089         if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) {
2090                 GPU_shader_unbind();
2091                 GPU_framebuffer_blur(lamp->fb, lamp->tex, lamp->blurfb, lamp->blurtex);
2092         }
2093
2094         GPU_framebuffer_texture_unbind(lamp->fb, lamp->tex);
2095         GPU_framebuffer_restore();
2096         glEnable(GL_SCISSOR_TEST);
2097 }
2098
2099 int GPU_lamp_shadow_buffer_type(GPULamp *lamp)
2100 {
2101         return lamp->la->shadowmap_type;
2102 }
2103
2104 int GPU_lamp_shadow_layer(GPULamp *lamp)
2105 {
2106         if (lamp->fb && lamp->tex && (lamp->mode & (LA_LAYER|LA_LAYER_SHADOW)))
2107                 return lamp->lay;
2108         else
2109                 return -1;
2110 }
2111
2112 GPUNodeLink *GPU_lamp_get_data(GPUMaterial *mat, GPULamp *lamp, GPUNodeLink **col, GPUNodeLink **lv, GPUNodeLink **dist, GPUNodeLink **shadow, GPUNodeLink **energy)
2113 {
2114         GPUNodeLink *visifac;
2115
2116         *col = GPU_dynamic_uniform(lamp->dyncol, GPU_DYNAMIC_LAMP_DYNCOL, lamp->ob);
2117         *energy = GPU_dynamic_uniform(&lamp->dynenergy, GPU_DYNAMIC_LAMP_DYNENERGY, lamp->ob);
2118         visifac = lamp_get_visibility(mat, lamp, lv, dist);
2119
2120         shade_light_textures(mat, lamp, col);
2121
2122         if (GPU_lamp_has_shadow_buffer(lamp)) {
2123                 GPUNodeLink *vn, *inp;
2124
2125                 GPU_link(mat, "shade_norm", GPU_builtin(GPU_VIEW_NORMAL), &vn);
2126                 GPU_link(mat, "shade_inp", vn, *lv, &inp);
2127                 mat->dynproperty |= DYN_LAMP_PERSMAT;
2128
2129                 if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) {
2130                         GPU_link(mat, "shadows_only_vsm",
2131                                  GPU_builtin(GPU_VIEW_POSITION),
2132                                  GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob),
2133                                  GPU_dynamic_uniform((float*)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob),
2134                                  GPU_uniform(&lamp->bias), GPU_uniform(&lamp->la->bleedbias),
2135                                  GPU_uniform(lamp->shadow_color), inp, shadow);
2136                 }
2137                 else {
2138                         GPU_link(mat, "shadows_only",
2139                                  GPU_builtin(GPU_VIEW_POSITION),
2140                                  GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob),
2141                                  GPU_dynamic_uniform((float*)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob),
2142                                  GPU_uniform(&lamp->bias), GPU_uniform(lamp->shadow_color), inp, shadow);
2143                 }
2144         }
2145         else {
2146                 GPU_link(mat, "set_rgb_one", shadow);
2147         }
2148
2149         /* ensure shadow buffer and lamp textures will be updated */
2150         add_user_list(&mat->lamps, lamp);
2151         add_user_list(&lamp->materials, mat->ma);
2152
2153         return visifac;
2154 }
2155
2156 /* export the GLSL shader */
2157
2158 GPUShaderExport *GPU_shader_export(struct Scene *scene, struct Material *ma)
2159 {
2160         static struct {
2161                 GPUBuiltin gputype;
2162                 GPUDynamicType dynamictype;
2163                 GPUDataType datatype;
2164         } builtins[] = {
2165                 { GPU_VIEW_MATRIX, GPU_DYNAMIC_OBJECT_VIEWMAT, GPU_DATA_16F },
2166                 { GPU_INVERSE_VIEW_MATRIX, GPU_DYNAMIC_OBJECT_VIEWIMAT, GPU_DATA_16F },
2167                 { GPU_OBJECT_MATRIX, GPU_DYNAMIC_OBJECT_MAT, GPU_DATA_16F },
2168                 { GPU_INVERSE_OBJECT_MATRIX, GPU_DYNAMIC_OBJECT_IMAT, GPU_DATA_16F },
2169                 { GPU_OBCOLOR, GPU_DYNAMIC_OBJECT_COLOR, GPU_DATA_4F },
2170                 { GPU_AUTO_BUMPSCALE, GPU_DYNAMIC_OBJECT_AUTOBUMPSCALE, GPU_DATA_1F },
2171                 { 0 }
2172         };
2173
2174         GPUShaderExport *shader = NULL;
2175         GPUPass *pass;
2176         GPUInput *input;
2177         GPUMaterial *mat;
2178         GPUInputUniform *uniform;
2179         GPUInputAttribute *attribute;
2180         GLint lastbindcode;
2181         int i, liblen, fraglen;
2182
2183         if (!GPU_glsl_support())
2184                 return NULL;
2185
2186         mat = GPU_material_from_blender(scene, ma);
2187         pass = (mat)? mat->pass: NULL;
2188
2189         if (pass && pass->fragmentcode && pass->vertexcode) {
2190                 shader = MEM_callocN(sizeof(GPUShaderExport), "GPUShaderExport");
2191
2192                 for (input = pass->inputs.first; input; input = input->next) {
2193                         uniform = MEM_callocN(sizeof(GPUInputUniform), "GPUInputUniform");
2194
2195                         if (input->ima) {
2196                                 /* image sampler uniform */
2197                                 uniform->type = GPU_DYNAMIC_SAMPLER_2DIMAGE;
2198                                 uniform->datatype = GPU_DATA_1I;
2199                                 uniform->image = input->ima;
2200                                 uniform->texnumber = input->texid;
2201                                 BLI_strncpy(uniform->varname, input->shadername, sizeof(uniform->varname));
2202                         }
2203                         else if (input->tex) {
2204                                 /* generated buffer */
2205                                 uniform->texnumber = input->texid;
2206                                 uniform->datatype = GPU_DATA_1I;
2207                                 BLI_strncpy(uniform->varname, input->shadername, sizeof(uniform->varname));
2208
2209                                 switch (input->textype) {
2210                                 case GPU_SHADOW2D:
2211                                         uniform->type = GPU_DYNAMIC_SAMPLER_2DSHADOW;
2212                                         uniform->lamp = input->dynamicdata;
2213                                         break;
2214                                 case GPU_TEX2D:
2215                                         if (GPU_texture_opengl_bindcode(input->tex)) {
2216                                                 uniform->type = GPU_DYNAMIC_SAMPLER_2DBUFFER;
2217                                                 glGetIntegerv(GL_TEXTURE_BINDING_2D, &lastbindcode);
2218                                                 glBindTexture(GL_TEXTURE_2D, GPU_texture_opengl_bindcode(input->tex));
2219                                                 uniform->texsize = GPU_texture_opengl_width(input->tex) * GPU_texture_opengl_height(input->tex);
2220                                                 uniform->texpixels = MEM_mallocN(uniform->texsize*4, "RGBApixels");
2221                                                 glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, uniform->texpixels); 
2222                                                 glBindTexture(GL_TEXTURE_2D, lastbindcode);
2223                                         }
2224                                         break;
2225
2226                                 case GPU_NONE:
2227                                 case GPU_FLOAT:
2228                                 case GPU_VEC2:
2229                                 case GPU_VEC3:
2230                                 case GPU_VEC4:
2231                                 case GPU_MAT3:
2232                                 case GPU_MAT4:
2233                                 case GPU_ATTRIB:
2234                                         break;
2235                                 }
2236                         }
2237                         else {
2238                                 uniform->type = input->dynamictype;
2239                                 BLI_strncpy(uniform->varname, input->shadername, sizeof(uniform->varname));
2240                                 switch (input->type) {
2241                                 case GPU_FLOAT:
2242                                         uniform->datatype = GPU_DATA_1F;
2243                                         break;
2244                                 case GPU_VEC2:
2245                                         uniform->datatype = GPU_DATA_2F;
2246                                         break;
2247                                 case GPU_VEC3:
2248                                         uniform->datatype = GPU_DATA_3F;
2249                                         break;
2250                                 case GPU_VEC4:
2251                                         uniform->datatype = GPU_DATA_4F;
2252                                         break;
2253                                 case GPU_MAT3:
2254                                         uniform->datatype = GPU_DATA_9F;
2255                                         break;
2256                                 case GPU_MAT4:
2257                                         uniform->datatype = GPU_DATA_16F;
2258                                         break;
2259
2260                                 case GPU_NONE:
2261                                 case GPU_TEX2D:
2262                                 case GPU_SHADOW2D:
2263                                 case GPU_ATTRIB:
2264                                         break;
2265                                 }
2266
2267                                 if (uniform->type >= GPU_DYNAMIC_LAMP_FIRST && uniform->type <= GPU_DYNAMIC_LAMP_LAST)
2268                                         uniform->lamp = input->dynamicdata;
2269                         }
2270
2271                         if (uniform->type != GPU_DYNAMIC_NONE)
2272                                 BLI_addtail(&shader->uniforms, uniform);
2273                         else
2274                                 MEM_freeN(uniform);
2275                 }
2276
2277                 /* process builtin uniform */
2278                 for (i=0; builtins[i].gputype; i++) {
2279                         if (mat->builtins & builtins[i].gputype) {
2280                                 uniform = MEM_callocN(sizeof(GPUInputUniform), "GPUInputUniform");
2281                                 uniform->type = builtins[i].dynamictype;
2282                                 uniform->datatype = builtins[i].datatype;
2283                                 BLI_strncpy(uniform->varname, GPU_builtin_name(builtins[i].gputype), sizeof(uniform->varname));
2284                                 BLI_addtail(&shader->uniforms, uniform);
2285                         }
2286                 }
2287
2288                 /* now link fragment shader with library shader */
2289                 /* TBD: remove the function that are not used in the main function */
2290                 liblen = (pass->libcode) ? strlen(pass->libcode) : 0;
2291                 fraglen = strlen(pass->fragmentcode);
2292                 shader->fragment = (char *)MEM_mallocN(liblen+fraglen+1, "GPUFragShader");
2293                 if (pass->libcode)
2294                         memcpy(shader->fragment, pass->libcode, liblen);
2295                 memcpy(&shader->fragment[liblen], pass->fragmentcode, fraglen);
2296                 shader->fragment[liblen+fraglen] = 0;
2297
2298                 // export the attribute
2299                 for (i=0; i<mat->attribs.totlayer; i++) {
2300                         attribute = MEM_callocN(sizeof(GPUInputAttribute), "GPUInputAttribute");
2301                         attribute->type = mat->attribs.layer[i].type;
2302                         attribute->number = mat->attribs.layer[i].glindex;
2303                         BLI_snprintf(attribute->varname, sizeof(attribute->varname), "att%d", mat->attribs.layer[i].attribid);
2304
2305                         switch (attribute->type) {
2306                         case CD_TANGENT:
2307                                 attribute->datatype = GPU_DATA_4F;
2308                                 break;
2309                         case CD_MTFACE:
2310                                 attribute->datatype = GPU_DATA_2F;
2311                                 attribute->name = mat->attribs.layer[i].name;
2312                                 break;
2313                         case CD_MCOL:
2314                                 attribute->datatype = GPU_DATA_4UB;
2315                                 attribute->name = mat->attribs.layer[i].name;
2316                                 break;
2317                         case CD_ORCO:
2318                                 attribute->datatype = GPU_DATA_3F;
2319                                 break;
2320                         }
2321
2322                         if (attribute->datatype != GPU_DATA_NONE)
2323                                 BLI_addtail(&shader->attributes, attribute);
2324                         else
2325                                 MEM_freeN(attribute);
2326                 }
2327
2328                 // export the vertex shader
2329                 shader->vertex = BLI_strdup(pass->vertexcode);
2330         }
2331
2332         return shader;
2333 }
2334
2335 void GPU_free_shader_export(GPUShaderExport *shader)
2336 {
2337         GPUInputUniform *uniform;
2338
2339         if (shader == NULL)
2340                 return;
2341
2342         for (uniform = shader->uniforms.first; uniform; uniform=uniform->next)
2343                 if (uniform->texpixels)
2344                         MEM_freeN(uniform->texpixels);
2345
2346         BLI_freelistN(&shader->uniforms);
2347         BLI_freelistN(&shader->attributes);
2348
2349         if (shader->vertex)
2350                 MEM_freeN(shader->vertex);
2351         if (shader->fragment)
2352                 MEM_freeN(shader->fragment);
2353
2354         MEM_freeN(shader);
2355 }
2356