8b8da348ae1c03116a05272e57fa26bf070d4c80
[blender.git] / source / blender / render / intern / source / texture.c
1 /* texture.c
2  *
3  *
4  * $Id$
5  *
6  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version. The Blender
12  * Foundation also sells licenses for use in proprietary software under
13  * the Blender License.  See http://www.blender.org/BL/ for information
14  * about this.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  *
25  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
26  * All rights reserved.
27  *
28  * The Original Code is: all of this file.
29  *
30  * Contributor(s): none yet.
31  *
32  * ***** END GPL/BL DUAL LICENSE BLOCK *****
33  */
34
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <math.h>
39
40 #ifdef HAVE_CONFIG_H
41 #include <config.h>
42 #endif
43
44 #ifdef WIN32
45 #include "BLI_winstuff.h"
46 #endif
47
48 #include "MTC_matrixops.h"
49
50 #include "BLI_blenlib.h"
51 #include "BLI_arithb.h"
52 #include "BLI_rand.h"
53
54 #include "DNA_texture_types.h"
55 #include "DNA_object_types.h"
56 #include "DNA_lamp_types.h"
57 #include "DNA_mesh_types.h"
58 #include "DNA_material_types.h"
59 #include "DNA_image_types.h"
60
61 #include "IMB_imbuf_types.h"
62 #include "IMB_imbuf.h"
63
64 #include "BKE_osa_types.h"
65 #include "BKE_plugin_types.h"
66 #include "BKE_utildefines.h"
67
68 #include "BKE_global.h"
69 #include "BKE_main.h"
70
71 #include "BKE_library.h"
72 #include "BKE_image.h"
73 #include "BKE_texture.h"
74 #include "BKE_key.h"
75 #include "BKE_ipo.h"
76
77 #include "render.h"
78 #include "rendercore.h"
79 #include "envmap.h"
80
81 /* These vars form the texture channel */
82 float Tin, Tr, Tg, Tb, Ta, Txtra;
83 extern int Talpha;
84
85
86 /* ------------------------------------------------------------------------- */
87
88 void init_render_texture(Tex *tex)
89 {
90         Image *ima;
91         int imanr;
92         unsigned short numlen;
93         char name[FILE_MAXDIR+FILE_MAXFILE], head[FILE_MAXDIR+FILE_MAXFILE], tail[FILE_MAXDIR+FILE_MAXFILE];
94
95         /* is also used as signal */
96         tex->nor= NULL;
97
98         /* imap test */
99         if(tex->frames && tex->ima && tex->ima->name) { /* frames */
100                 strcpy(name, tex->ima->name);
101                 
102                 imanr= calcimanr(G.scene->r.cfra, tex);
103                 
104                 if(tex->imaflag & TEX_ANIM5) {
105                         if(tex->ima->lastframe != imanr) {
106                                 if(tex->ima->ibuf) IMB_freeImBuf(tex->ima->ibuf);
107                                 tex->ima->ibuf= 0;
108                                 tex->ima->lastframe= imanr;
109                         }
110                 }
111                 else {
112                                 /* for patch field-ima rendering */
113                         tex->ima->lastframe= imanr;
114                         
115                         BLI_stringdec(name, head, tail, &numlen);
116                         BLI_stringenc(name, head, tail, numlen, imanr);
117         
118                         ima= add_image(name);
119
120                         if(ima) {
121                                 ima->flag |= IMA_FROMANIM;
122                                 
123                                 if(tex->ima) tex->ima->id.us--;
124                                 tex->ima= ima;
125                                 
126                                 ima->ok= 1;
127                         }
128                 }
129         }
130         if(tex->imaflag & (TEX_ANTIALI+TEX_ANTISCALE)) {
131                 if(tex->ima && tex->ima->lastquality<R.osa) {
132                         if(tex->ima->ibuf) IMB_freeImBuf(tex->ima->ibuf);
133                         tex->ima->ibuf= 0;
134                 }
135         }
136         
137         if(tex->type==TEX_PLUGIN) {
138                 if(tex->plugin && tex->plugin->doit) {
139                                 if(tex->plugin->cfra) {
140                                         *(tex->plugin->cfra)= frame_to_float(G.scene->r.cfra); 
141                                 }
142                 }
143         }
144         else if(tex->type==TEX_ENVMAP) {
145                 /* just in case */
146                 tex->imaflag= TEX_INTERPOL | TEX_MIPMAP;
147                 tex->extend= TEX_CLIP;
148                 
149                 if(tex->env) {
150                         if(R.flag & R_RENDERING) {
151                                 if(tex->env->stype==ENV_ANIM) RE_free_envmapdata(tex->env);
152                         }
153                 }
154         }
155 }
156
157 /* ------------------------------------------------------------------------- */
158
159 void init_render_textures()
160 {
161         Tex *tex;
162         
163         tex= G.main->tex.first;
164         while(tex) {
165                 if(tex->id.us) init_render_texture(tex);
166                 tex= tex->id.next;
167         }
168         
169         free_unused_animimages();
170 }
171
172 /* ------------------------------------------------------------------------- */
173
174 void end_render_texture(Tex *tex)
175 {
176
177
178 }
179
180 /* ------------------------------------------------------------------------- */
181
182 void end_render_textures()
183 {
184         Tex *tex;
185
186         tex= G.main->tex.first;
187         while(tex) {
188                 if(tex->id.us) end_render_texture(tex);
189                 tex= tex->id.next;
190         }
191
192 }
193
194 /* ------------------------------------------------------------------------- */
195
196 static int blend(Tex *tex, float *texvec)
197 {
198         float x, y, t;
199
200         if(tex->flag & TEX_FLIPBLEND) {
201                 x= texvec[1];
202                 y= texvec[0];
203         }
204         else {
205                 x= texvec[0];
206                 y= texvec[1];
207         }
208
209         if(tex->stype==0) {     /* lin */
210                 Tin= (1.0+x)/2.0;
211         }
212         else if(tex->stype==1) {        /* quad */
213                 Tin= (1.0+x)/2.0;
214                 if(Tin<0.0) Tin= 0.0;
215                 else Tin*= Tin;
216         }
217         else if(tex->stype==2) {        /* ease */
218                 Tin= (1.0+x)/2.0;
219                 if(Tin<=.0) Tin= 0.0;
220                 else if(Tin>=1.0) Tin= 1.0;
221                 else {
222                         t= Tin*Tin;
223                         Tin= (3.0*t-2.0*t*Tin);
224                 }
225         }
226         else if(tex->stype==3) { /* diag */
227                 Tin= (2.0+x+y)/4.0;
228         }
229         else {  /* sphere */
230                 Tin= 1.0-sqrt(x*x+      y*y+texvec[2]*texvec[2]);
231                 if(Tin<0.0) Tin= 0.0;
232                 if(tex->stype==5) Tin*= Tin;  /* halo */
233         }
234
235         BRICON;
236
237         return 0;
238 }
239
240 /* ------------------------------------------------------------------------- */
241 /* ************************************************************************* */
242 /* clouds, wood & marble updated to do proper bumpmapping */
243 /* 0.025 seems reasonable value for offset */
244 #define B_OFFS 0.025
245
246 /* newnoise: all noisebased types now have different noisebases to choose from */
247
248 static int clouds(Tex *tex, float *texvec)
249 {
250         int rv=0;       /* return value, int:0, col:1, nor:2, everything:3 */
251         Tin = BLI_gTurbulence(tex->noisesize, texvec[0], texvec[1], texvec[2], tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
252
253         if (tex->nor!=NULL) {
254                 // calculate bumpnormal
255                 tex->nor[0] = Tin - BLI_gTurbulence(tex->noisesize, texvec[0] + B_OFFS, texvec[1], texvec[2], tex->noisedepth,  (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
256                 tex->nor[1] = Tin - BLI_gTurbulence(tex->noisesize, texvec[0], texvec[1] + B_OFFS, texvec[2], tex->noisedepth,  (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
257                 tex->nor[2] = Tin - BLI_gTurbulence(tex->noisesize, texvec[0], texvec[1], texvec[2] + B_OFFS, tex->noisedepth,  (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
258                 rv += 2;
259         }
260
261         if (tex->stype==1) {
262                 // in this case, int. value should really be computed from color,
263                 // and bumpnormal from that, would be too slow, looks ok as is
264                 Tr = Tin;
265                 Tg = BLI_gTurbulence(tex->noisesize, texvec[1], texvec[0], texvec[2], tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
266                 Tb = BLI_gTurbulence(tex->noisesize, texvec[1], texvec[2], texvec[0], tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
267                 BRICONRGB;
268                 Ta = 1.0;
269                 return (rv+1);
270         }
271
272         BRICON;
273
274         return rv;
275
276 }
277
278 /* computes basic wood intensity value at x,y,z */
279 static float wood_int(Tex *tex, float x, float y, float z)
280 {
281         float wi=0;
282
283         if (tex->stype==0)
284                 wi = 0.5 + 0.5*sin((x + y + z)*10.0);
285         else if (tex->stype==1)
286                 wi = 0.5 + 0.5*sin(sqrt(x*x + y*y + z*z)*20.0);
287         else if (tex->stype==2) {
288                 wi = BLI_gNoise(tex->noisesize, x, y, z, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
289                 wi = 0.5 + 0.5*sin(tex->turbul*wi + (x + y + z)*10.0);
290         }
291         else if (tex->stype==3) {
292                 wi = BLI_gNoise(tex->noisesize, x, y, z, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
293                 wi = 0.5 + 0.5*sin(tex->turbul*wi + (sqrt(x*x + y*y + z*z))*20.0);
294         }
295
296         return wi;
297 }
298
299 static int wood(Tex *tex, float *texvec)
300 {
301         int rv=0;       /* return value, int:0, col:1, nor:2, everything:3 */
302
303         Tin = wood_int(tex, texvec[0], texvec[1], texvec[2]);
304         if (tex->nor!=NULL) {
305                 /* calculate bumpnormal */
306                 tex->nor[0] = Tin - wood_int(tex, texvec[0] + B_OFFS, texvec[1], texvec[2]);
307                 tex->nor[1] = Tin - wood_int(tex, texvec[0], texvec[1] + B_OFFS, texvec[2]);
308                 tex->nor[2] = Tin - wood_int(tex, texvec[0], texvec[1], texvec[2] + B_OFFS);
309                 rv += 2;
310         }
311
312         BRICON;
313
314         return rv;
315 }
316
317 /* computes basic marble intensity at x,y,z */
318 static float marble_int(Tex *tex, float x, float y, float z)
319 {
320         float n, mi;
321
322         n = 5.0 * (x + y + z);
323
324         mi = 0.5 + 0.5 * sin(n + tex->turbul * BLI_gTurbulence(tex->noisesize, x, y, z, tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT),  tex->noisebasis));
325         if (tex->stype>=1) {
326                 mi = sqrt(mi);
327                 if (tex->stype==2) mi = sqrt(mi);
328         }
329
330         return mi;
331 }
332
333 static int marble(Tex *tex, float *texvec)
334 {
335         int rv=0;       /* return value, int:0, col:1, nor:2, everything:3 */
336
337         Tin = marble_int(tex, texvec[0], texvec[1], texvec[2]);
338
339         if (tex->nor!=NULL) {
340                 /* calculate bumpnormal */
341                 tex->nor[0] = Tin - marble_int(tex, texvec[0] + B_OFFS, texvec[1], texvec[2]);
342                 tex->nor[1] = Tin - marble_int(tex, texvec[0], texvec[1] + B_OFFS, texvec[2]);
343                 tex->nor[2] = Tin - marble_int(tex, texvec[0], texvec[1], texvec[2] + B_OFFS);
344                 rv += 2;
345         }
346
347         BRICON;
348
349         return rv;
350 }
351
352 /* ------------------------------------------------------------------------- */
353
354 static int magic(Tex *tex, float *texvec)
355 {
356         float x, y, z, turb=1.0;
357         int n;
358
359         n= tex->noisedepth;
360         turb= tex->turbul/5.0;
361
362         x=  sin( ( texvec[0]+texvec[1]+texvec[2])*5.0 );
363         y=  cos( (-texvec[0]+texvec[1]-texvec[2])*5.0 );
364         z= -cos( (-texvec[0]-texvec[1]+texvec[2])*5.0 );
365         if(n>0) {
366                 x*= turb;
367                 y*= turb;
368                 z*= turb;
369                 y= -cos(x-y+z);
370                 y*= turb;
371                 if(n>1) {
372                         x= cos(x-y-z);
373                         x*= turb;
374                         if(n>2) {
375                                 z= sin(-x-y-z);
376                                 z*= turb;
377                                 if(n>3) {
378                                         x= -cos(-x+y-z);
379                                         x*= turb;
380                                         if(n>4) {
381                                                 y= -sin(-x+y+z);
382                                                 y*= turb;
383                                                 if(n>5) {
384                                                         y= -cos(-x+y+z);
385                                                         y*= turb;
386                                                         if(n>6) {
387                                                                 x= cos(x+y+z);
388                                                                 x*= turb;
389                                                                 if(n>7) {
390                                                                         z= sin(x+y-z);
391                                                                         z*= turb;
392                                                                         if(n>8) {
393                                                                                 x= -cos(-x-y+z);
394                                                                                 x*= turb;
395                                                                                 if(n>9) {
396                                                                                         y= -sin(x-y+z);
397                                                                                         y*= turb;
398                                                                                 }
399                                                                         }
400                                                                 }
401                                                         }
402                                                 }
403                                         }
404                                 }
405                         }
406                 }
407         }
408
409         if(turb!=0.0) {
410                 turb*= 2.0;
411                 x/= turb; 
412                 y/= turb; 
413                 z/= turb;
414         }
415         Tr= 0.5-x;
416         Tg= 0.5-y;
417         Tb= 0.5-z;
418
419         BRICONRGB;
420         Ta= 1.0;
421         
422         return 1;
423 }
424
425 /* ------------------------------------------------------------------------- */
426
427 /* newnoise: stucci also modified to use different noisebasis */
428 static int stucci(Tex *tex, float *texvec)
429 {
430         float b2, vec[3], ofs;
431
432         if(tex->nor == NULL) return 0;
433
434         ofs= tex->turbul/200.0;
435
436         b2= BLI_gNoise(tex->noisesize, texvec[0], texvec[1], texvec[2], (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
437         if(tex->stype) ofs*=(b2*b2);
438         vec[0] = b2 - BLI_gNoise(tex->noisesize, texvec[0]+ofs, texvec[1], texvec[2], (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
439         vec[1] = b2 - BLI_gNoise(tex->noisesize, texvec[0], texvec[1]+ofs, texvec[2], (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);        
440         vec[2] = b2 - BLI_gNoise(tex->noisesize, texvec[0], texvec[1], texvec[2]+ofs, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
441
442         if(tex->stype==1) {
443                 tex->nor[0]= vec[0];
444                 tex->nor[1]= vec[1];
445                 tex->nor[2]= vec[2];
446         }
447         else {
448                 tex->nor[0]= -vec[0];
449                 tex->nor[1]= -vec[1];
450                 tex->nor[2]= -vec[2];
451         }
452
453         return 2;
454 }
455
456 /* ------------------------------------------------------------------------- */
457 /* newnoise: musgrave terrain noise types */
458
459 static float mg_mFractalOrfBmTex(Tex *tex, float *texvec)
460 {
461         int rv=0;       /* return value, int:0, col:1, nor:2, everything:3 */
462         float (*mgravefunc)(float, float, float, float, float, float, int);
463
464         if (tex->stype==TEX_MFRACTAL)
465                 mgravefunc = mg_MultiFractal;
466         else
467                 mgravefunc = mg_fBm;
468
469         Tin = mgravefunc(texvec[0], texvec[1], texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->noisebasis);
470
471         if (tex->nor!=NULL) {
472                 /* calculate bumpnormal */
473                 tex->nor[0] = Tin - mgravefunc(texvec[0] + B_OFFS, texvec[1], texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->noisebasis);
474                 tex->nor[1] = Tin - mgravefunc(texvec[0], texvec[1] + B_OFFS, texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->noisebasis);
475                 tex->nor[2] = Tin - mgravefunc(texvec[0], texvec[1], texvec[2] + B_OFFS, tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->noisebasis);
476                 rv += 2;
477         }
478
479         Tin *= tex->ns_outscale;
480
481         BRICON;
482
483         return rv;
484
485 }
486
487 static float mg_ridgedOrHybridMFTex(Tex *tex, float *texvec)
488 {
489         int rv=0;       /* return value, int:0, col:1, nor:2, everything:3 */
490         float (*mgravefunc)(float, float, float, float, float, float, float, float, int);
491
492         if (tex->stype==TEX_RIDGEDMF)
493                 mgravefunc = mg_RidgedMultiFractal;
494         else
495                 mgravefunc = mg_HybridMultiFractal;
496
497         Tin = mgravefunc(texvec[0], texvec[1], texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->mg_gain, tex->noisebasis);
498
499         if (tex->nor!=NULL) {
500                 /* calculate bumpnormal */
501                 tex->nor[0] = Tin - mgravefunc(texvec[0] + B_OFFS, texvec[1], texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->mg_gain, tex->noisebasis);
502                 tex->nor[1] = Tin - mgravefunc(texvec[0], texvec[1] + B_OFFS, texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->mg_gain, tex->noisebasis);
503                 tex->nor[2] = Tin - mgravefunc(texvec[0], texvec[1], texvec[2] + B_OFFS, tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->mg_gain, tex->noisebasis);
504                 rv += 2;
505         }
506
507         Tin *= tex->ns_outscale;
508
509         BRICON;
510
511         return rv;
512
513 }
514
515
516 static float mg_HTerrainTex(Tex *tex, float *texvec)
517 {
518         int rv=0;       /* return value, int:0, col:1, nor:2, everything:3 */
519
520         Tin = mg_HeteroTerrain(texvec[0], texvec[1], texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->noisebasis);
521
522         if (tex->nor!=NULL) {
523                 /* calculate bumpnormal */
524                 tex->nor[0] = Tin - mg_HeteroTerrain(texvec[0] + B_OFFS, texvec[1], texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->noisebasis);
525                 tex->nor[1] = Tin - mg_HeteroTerrain(texvec[0], texvec[1] + B_OFFS, texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->noisebasis);
526                 tex->nor[2] = Tin - mg_HeteroTerrain(texvec[0], texvec[1], texvec[2] + B_OFFS, tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->noisebasis);
527                 rv += 2;
528         }
529
530         Tin *= tex->ns_outscale;
531
532         BRICON;
533
534         return rv;
535
536 }
537
538
539 static float mg_distNoiseTex(Tex *tex, float *texvec)
540 {
541         int rv=0;       /* return value, int:0, col:1, nor:2, everything:3 */
542
543         Tin = mg_VLNoise(texvec[0], texvec[1], texvec[2], tex->dist_amount, tex->noisebasis, tex->noisebasis2);
544
545         if (tex->nor!=NULL) {
546                 /* calculate bumpnormal */
547                 tex->nor[0] = Tin - mg_VLNoise(texvec[0] + B_OFFS, texvec[1], texvec[2], tex->dist_amount, tex->noisebasis, tex->noisebasis2);
548                 tex->nor[1] = Tin - mg_VLNoise(texvec[0], texvec[1] + B_OFFS, texvec[2], tex->dist_amount, tex->noisebasis, tex->noisebasis2);
549                 tex->nor[2] = Tin - mg_VLNoise(texvec[0], texvec[1], texvec[2] + B_OFFS, tex->dist_amount, tex->noisebasis, tex->noisebasis2);
550                 rv += 2;
551         }
552
553         BRICON;
554
555
556         return rv;
557
558 }
559
560
561 /* ------------------------------------------------------------------------- */
562 /* newnoise: Voronoi texture type, probably the slowest, especially with minkovsky, bumpmapping, could be done another way */
563
564 static float voronoiTex(Tex *tex, float *texvec)
565 {
566         int rv=0;       /* return value, int:0, col:1, nor:2, everything:3 */
567         float da[4], pa[12];    /* distance and point coordinate arrays of 4 nearest neighbours */
568         float aw1 = fabs(tex->vn_w1);
569         float aw2 = fabs(tex->vn_w2);
570         float aw3 = fabs(tex->vn_w3);
571         float aw4 = fabs(tex->vn_w4);
572         float sc = (aw1 + aw2 + aw3 + aw4);
573         if (sc!=0.f) sc =  tex->ns_outscale/sc;
574
575         voronoi(texvec[0], texvec[1], texvec[2], da, pa, tex->vn_mexp, tex->vn_distm);
576         Tin = sc * fabs(tex->vn_w1*da[0] + tex->vn_w2*da[1] + tex->vn_w3*da[2] + tex->vn_w4*da[3]);
577
578         if (tex->vn_coltype) {
579                 float ca[3];    /* cell color */
580                 cellNoiseV(pa[0], pa[1], pa[2], ca);
581                 Tr = aw1*ca[0];
582                 Tg = aw1*ca[1];
583                 Tb = aw1*ca[2];
584                 cellNoiseV(pa[3], pa[4], pa[5], ca);
585                 Tr += aw2*ca[0];
586                 Tg += aw2*ca[1];
587                 Tb += aw2*ca[2];
588                 cellNoiseV(pa[6], pa[7], pa[8], ca);
589                 Tr += aw3*ca[0];
590                 Tg += aw3*ca[1];
591                 Tb += aw3*ca[2];
592                 cellNoiseV(pa[9], pa[10], pa[11], ca);
593                 Tr += aw4*ca[0];
594                 Tg += aw4*ca[1];
595                 Tb += aw4*ca[2];
596                 if (tex->vn_coltype>=2) {
597                         float t1 = (da[1]-da[0])*10;
598                         if (t1>1) t1=1;
599                         if (tex->vn_coltype==3) t1*=Tin; else t1*=sc;
600                         Tr *= t1;
601                         Tg *= t1;
602                         Tb *= t1;
603                 }
604                 else {
605                         Tr *= sc;
606                         Tg *= sc;
607                         Tb *= sc;
608                 }
609         }
610
611         if (tex->nor!=NULL) {
612                 /* calculate bumpnormal */
613                 voronoi(texvec[0] + B_OFFS, texvec[1], texvec[2], da, pa, tex->vn_mexp,  tex->vn_distm);
614                 tex->nor[0] = Tin - sc * fabs(tex->vn_w1*da[0] + tex->vn_w2*da[1] + tex->vn_w3*da[2] + tex->vn_w4*da[3]);
615                 voronoi(texvec[0], texvec[1] + B_OFFS, texvec[2], da, pa, tex->vn_mexp,  tex->vn_distm);
616                 tex->nor[1] = Tin - sc * fabs(tex->vn_w1*da[0] + tex->vn_w2*da[1] + tex->vn_w3*da[2] + tex->vn_w4*da[3]);
617                 voronoi(texvec[0], texvec[1], texvec[2] + B_OFFS, da, pa, tex->vn_mexp,  tex->vn_distm);
618                 tex->nor[2] = Tin - sc * fabs(tex->vn_w1*da[0] + tex->vn_w2*da[1] + tex->vn_w3*da[2] + tex->vn_w4*da[3]);
619                 rv += 2;
620         }
621
622         if (tex->vn_coltype) {
623                 BRICONRGB;
624                 Ta = 1.0;
625                 return (rv+1);
626         }
627         
628         BRICON;
629
630         return rv;
631
632 }
633
634
635 /* ------------------------------------------------------------------------- */
636
637 static int texnoise(Tex *tex)
638 {
639         float div=3.0;
640         int val, ran, loop;
641         
642         ran= BLI_rand();
643         val= (ran & 3);
644         
645         loop= tex->noisedepth;
646         while(loop--) {
647                 ran= (ran>>2);
648                 val*= (ran & 3);
649                 div*= 3.0;
650         }
651         
652         Tin= ((float)val)/div;;
653
654         BRICON;
655         return 0;
656 }
657
658 /* ------------------------------------------------------------------------- */
659
660 static int plugintex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex)
661 {
662         PluginTex *pit;
663         int rgbnor=0;
664
665         Tin= 0.0;
666
667         pit= tex->plugin;
668         if(pit && pit->doit) {
669                 if(tex->nor) {
670                         VECCOPY(pit->result+5, tex->nor);
671                 }
672                 if(osatex) rgbnor= ((TexDoit)pit->doit)(tex->stype, pit->data, texvec, dxt, dyt);
673                 else rgbnor= ((TexDoit)pit->doit)(tex->stype, pit->data, texvec, 0, 0);
674
675                 Tin= pit->result[0];
676
677                 if(rgbnor & TEX_NOR) {
678                         if(tex->nor) {
679                                 VECCOPY(tex->nor, pit->result+5);
680                         }
681                 }
682                 
683                 if(rgbnor & TEX_RGB) {
684                         Tr= pit->result[1];
685                         Tg= pit->result[2];
686                         Tb= pit->result[3];
687                         Ta= pit->result[4];
688
689                         BRICONRGB;
690                 }
691                 
692                 BRICON;
693         }
694
695         return rgbnor;
696 }
697
698 /* *************** PROJECTIONS ******************* */
699
700 void tubemap(float x, float y, float z, float *adr1, float *adr2)
701 {
702         float len;
703
704         *adr2 = (z + 1.0) / 2.0;
705
706         len= sqrt(x*x+y*y);
707         if(len>0) {
708                 *adr1 = (1.0 - (atan2(x/len,y/len) / M_PI)) / 2.0;
709         }
710 }
711
712 /* ------------------------------------------------------------------------- */
713
714 void spheremap(float x, float y, float z, float *adr1, float *adr2)
715 {
716         float len;
717
718         len= sqrt(x*x+y*y+z*z);
719         if(len>0.0) {
720                 
721                 if(x==0.0 && y==0.0) *adr1= 0.0;        /* othwise domain error */
722                 else *adr1 = (1.0 - atan2(x,y)/M_PI )/2.0;
723
724                 z/=len;
725                 *adr2 = 1.0- saacos(z)/M_PI;
726         }
727 }
728
729 /* ------------------------------------------------------------------------- */
730
731 static int cubemap_glob(MTex *mtex, VlakRen *vlr, float x, float y, float z, float *adr1, float *adr2)
732 {
733         float x1, y1, z1, nor[3];
734         int ret;
735         
736         if(vlr==NULL) {
737                 nor[0]= x; nor[1]= y; nor[2]= z;        // use local render coord
738         }
739         else {
740                 VECCOPY(nor, vlr->n);
741         }
742         MTC_Mat4Mul3Vecfl(R.viewinv, nor);
743
744         x1= fabs(nor[0]);
745         y1= fabs(nor[1]);
746         z1= fabs(nor[2]);
747         
748         if(z1>=x1 && z1>=y1) {
749                 *adr1 = (x + 1.0) / 2.0;
750                 *adr2 = (y + 1.0) / 2.0;
751                 ret= 0;
752         }
753         else if(y1>=x1 && y1>=z1) {
754                 *adr1 = (x + 1.0) / 2.0;
755                 *adr2 = (z + 1.0) / 2.0;
756                 ret= 1;
757         }
758         else {
759                 *adr1 = (y + 1.0) / 2.0;
760                 *adr2 = (z + 1.0) / 2.0;
761                 ret= 2;         
762         }
763         return ret;
764 }
765
766 /* ------------------------------------------------------------------------- */
767
768 static int cubemap(MTex *mtex, VlakRen *vlr, float x, float y, float z, float *adr1, float *adr2)
769 {
770         int proj[4], ret= 0;
771         
772         if(vlr) {
773                 int index;
774                 
775                 /* Mesh vertices have such flags, for others we calculate it once based on orco */
776                 if((vlr->puno & (ME_PROJXY|ME_PROJXZ|ME_PROJYZ))==0) {
777                         if(vlr->v1->orco) {
778                                 float nor[3];
779                                 CalcNormFloat(vlr->v1->orco, vlr->v2->orco, vlr->v3->orco, nor);
780                                 
781                                 if( fabs(nor[0])<fabs(nor[2]) && fabs(nor[1])<fabs(nor[2]) ) vlr->puno |= ME_PROJXY;
782                                 else if( fabs(nor[0])<fabs(nor[1]) && fabs(nor[2])<fabs(nor[1]) ) vlr->puno |= ME_PROJXZ;
783                                 else vlr->puno |= ME_PROJYZ;
784                         }
785                         else return cubemap_glob(mtex, vlr, x, y, z, adr1, adr2);
786                 }
787                 
788                 /* the mtex->proj{xyz} have type char. maybe this should be wider? */
789                 /* casting to int ensures that the index type is right.            */
790                 index = (int) mtex->projx;
791                 proj[index]= ME_PROJXY;
792
793                 index = (int) mtex->projy;
794                 proj[index]= ME_PROJXZ;
795
796                 index = (int) mtex->projz;
797                 proj[index]= ME_PROJYZ;
798                 
799                 if(vlr->puno & proj[1]) {
800                         *adr1 = (x + 1.0) / 2.0;
801                         *adr2 = (y + 1.0) / 2.0;        
802                 }
803                 else if(vlr->puno & proj[2]) {
804                         *adr1 = (x + 1.0) / 2.0;
805                         *adr2 = (z + 1.0) / 2.0;
806                         ret= 1;
807                 }
808                 else {
809                         *adr1 = (y + 1.0) / 2.0;
810                         *adr2 = (z + 1.0) / 2.0;
811                         ret= 2;
812                 }               
813         } 
814         else {
815                 return cubemap_glob(mtex, vlr, x, y, z, adr1, adr2);
816         }
817         
818         return ret;
819 }
820
821 /* ------------------------------------------------------------------------- */
822
823 static int cubemap_ob(MTex *mtex, VlakRen *vlr, float x, float y, float z, float *adr1, float *adr2)
824 {
825         float x1, y1, z1, nor[3];
826         int ret;
827         
828         if(vlr==NULL) return 0;
829         
830         VECCOPY(nor, vlr->n);
831         if(mtex->object) MTC_Mat4Mul3Vecfl(mtex->object->imat, nor);
832         
833         x1= fabs(nor[0]);
834         y1= fabs(nor[1]);
835         z1= fabs(nor[2]);
836         
837         if(z1>=x1 && z1>=y1) {
838                 *adr1 = (x + 1.0) / 2.0;
839                 *adr2 = (y + 1.0) / 2.0;
840                 ret= 0;
841         }
842         else if(y1>=x1 && y1>=z1) {
843                 *adr1 = (x + 1.0) / 2.0;
844                 *adr2 = (z + 1.0) / 2.0;
845                 ret= 1;
846         }
847         else {
848                 *adr1 = (y + 1.0) / 2.0;
849                 *adr2 = (z + 1.0) / 2.0;
850                 ret= 2;         
851         }
852         return ret;
853 }
854
855 /* ------------------------------------------------------------------------- */
856
857 static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, float *dxt, float *dyt)
858 {
859         Tex *tex;
860         float fx, fy, fac1, area[8];
861         int ok, proj, areaflag= 0, wrap;
862         
863         wrap= mtex->mapping;
864         tex= mtex->tex;
865
866         if(R.osa==0) {
867                 
868                 if(wrap==MTEX_FLAT) {
869                         fx = (t[0] + 1.0) / 2.0;
870                         fy = (t[1] + 1.0) / 2.0;
871                 }
872                 else if(wrap==MTEX_TUBE) tubemap(t[0], t[1], t[2], &fx, &fy);
873                 else if(wrap==MTEX_SPHERE) spheremap(t[0], t[1], t[2], &fx, &fy);
874                 else {
875                         if(mtex->texco==TEXCO_OBJECT) cubemap_ob(mtex, vlr, t[0], t[1], t[2], &fx, &fy);
876                         else if(mtex->texco==TEXCO_GLOB) cubemap_glob(mtex, vlr, t[0], t[1], t[2], &fx, &fy);
877                         else cubemap(mtex, vlr, t[0], t[1], t[2], &fx, &fy);
878                 }
879                 
880                 /* repeat */
881                 if(tex->extend==TEX_REPEAT) {
882                         if(tex->xrepeat>1) {
883                                 fx *= tex->xrepeat;
884                                 if(fx>1.0) fx -= (int)(fx);
885                                 else if(fx<0.0) fx+= 1-(int)(fx);
886                         }
887                         if(tex->yrepeat>1) {
888                                 fy *= tex->yrepeat;
889                                 if(fy>1.0) fy -= (int)(fy);
890                                 else if(fy<0.0) fy+= 1-(int)(fy);
891                         }
892                 }
893                 /* crop */
894                 if(tex->cropxmin!=0.0 || tex->cropxmax!=1.0) {
895                         fac1= tex->cropxmax - tex->cropxmin;
896                         fx= tex->cropxmin+ fx*fac1;
897                 }
898                 if(tex->cropymin!=0.0 || tex->cropymax!=1.0) {
899                         fac1= tex->cropymax - tex->cropymin;
900                         fy= tex->cropymin+ fy*fac1;
901                 }
902
903                 t[0]= fx;
904                 t[1]= fy;
905         }
906         else {
907                 
908                 if(wrap==MTEX_FLAT) {
909                         fx= (t[0] + 1.0) / 2.0;
910                         fy= (t[1] + 1.0) / 2.0;
911                         dxt[0]/= 2.0; 
912                         dxt[1]/= 2.0;
913                         dyt[0]/= 2.0; 
914                         dyt[1]/= 2.0;
915                 }
916                 else if ELEM(wrap, MTEX_TUBE, MTEX_SPHERE) {
917                         /* exception: the seam behind (y<0.0) */
918                         ok= 1;
919                         if(t[1]<=0.0) {
920                                 fx= t[0]+dxt[0];
921                                 fy= t[0]+dyt[0];
922                                 if(fx>=0.0 && fy>=0.0 && t[0]>=0.0);
923                                 else if(fx<=0.0 && fy<=0.0 && t[0]<=0.0);
924                                 else ok= 0;
925                         }
926                         if(ok) {
927                                 if(wrap==MTEX_TUBE) {
928                                         tubemap(t[0], t[1], t[2], area, area+1);
929                                         tubemap(t[0]+dxt[0], t[1]+dxt[1], t[2]+dxt[2], area+2, area+3);
930                                         tubemap(t[0]+dyt[0], t[1]+dyt[1], t[2]+dyt[2], area+4, area+5);
931                                 }
932                                 else { 
933                                         spheremap(t[0], t[1], t[2],area,area+1);
934                                         spheremap(t[0]+dxt[0], t[1]+dxt[1], t[2]+dxt[2], area+2, area+3);
935                                         spheremap(t[0]+dyt[0], t[1]+dyt[1], t[2]+dyt[2], area+4, area+5);
936                                 }
937                                 areaflag= 1;
938                         }
939                         else {
940                                 if(wrap==MTEX_TUBE) tubemap(t[0], t[1], t[2], &fx, &fy);
941                                 else spheremap(t[0], t[1], t[2], &fx, &fy);
942                                 dxt[0]/= 2.0; 
943                                 dxt[1]/= 2.0;
944                                 dyt[0]/= 2.0; 
945                                 dyt[1]/= 2.0;
946                         }
947                 }
948                 else {
949
950                         if(mtex->texco==TEXCO_OBJECT) proj = cubemap_ob(mtex, vlr, t[0], t[1], t[2], &fx, &fy);
951                         else if (mtex->texco==TEXCO_GLOB) proj = cubemap_glob(mtex, vlr, t[0], t[1], t[2], &fx, &fy);
952                         else proj = cubemap(mtex, vlr, t[0], t[1], t[2], &fx, &fy);
953
954                         if(proj==1) {
955                                 dxt[1]= dxt[2];
956                                 dyt[1]= dyt[2];
957                         }
958                         else if(proj==2) {
959                                 dxt[0]= dxt[1];
960                                 dyt[0]= dyt[1];
961                                 dxt[1]= dxt[2];
962                                 dyt[1]= dyt[2];
963                         }
964                         dxt[0]/= 2.0; 
965                         dxt[1]/= 2.0;
966                         dyt[0]/= 2.0; 
967                         dyt[1]/= 2.0;
968                 }
969                 
970                 /* if area, then reacalculate dxt[] and dyt[] */
971                 if(areaflag) {
972                         fx= area[0]; 
973                         fy= area[1];
974                         dxt[0]= area[2]-fx;
975                         dxt[1]= area[3]-fy;
976                         dyt[0]= area[4]-fx;
977                         dyt[1]= area[5]-fy;
978                 }
979                 
980                 /* repeat */
981                 if(tex->extend==TEX_REPEAT) {
982                         if(tex->xrepeat>1) {
983                                 fx *= tex->xrepeat;
984                                 dxt[0]*= tex->xrepeat;
985                                 dyt[0]*= tex->xrepeat;
986                                 if(fx>1.0) fx -= (int)(fx);
987                                 else if(fx<0.0) fx+= 1-(int)(fx);
988                         }
989                         if(tex->yrepeat>1) {
990                                 fy *= tex->yrepeat;
991                                 dxt[1]*= tex->yrepeat;
992                                 dyt[1]*= tex->yrepeat;
993                                 if(fy>1.0) fy -= (int)(fy);
994                                 else if(fy<0.0) fy+= 1-(int)(fy);
995                         }
996                 }
997                 /* crop */
998                 if(tex->cropxmin!=0.0 || tex->cropxmax!=1.0) {
999                         fac1= tex->cropxmax - tex->cropxmin;
1000                         fx= tex->cropxmin+ fx*fac1;
1001                         dxt[0]*= fac1;
1002                         dyt[0]*= fac1;
1003                 }
1004                 if(tex->cropymin!=0.0 || tex->cropymax!=1.0) {
1005                         fac1= tex->cropymax - tex->cropymin;
1006                         fy= tex->cropymin+ fy*fac1;
1007                         dxt[1]*= fac1;
1008                         dyt[1]*= fac1;
1009                 }
1010                 
1011                 t[0]= fx;
1012                 t[1]= fy;
1013
1014         }
1015 }
1016
1017
1018 /* ************************************** */
1019
1020 int multitex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex)
1021 {
1022         int retval=0; /* return value, int:0, col:1, nor:2, everything:3 */
1023
1024         Talpha= 0;      /* is set when image texture returns alpha (considered premul) */
1025         
1026         switch(tex->type) {
1027         
1028         case 0:
1029                 Tin= 0.0;
1030                 return 0;
1031         case TEX_CLOUDS:
1032                 retval= clouds(tex, texvec);
1033                 break;
1034         case TEX_WOOD:
1035                 retval= wood(tex, texvec); 
1036                 break;
1037         case TEX_MARBLE:
1038                 retval= marble(tex, texvec); 
1039                 break;
1040         case TEX_MAGIC:
1041                 retval= magic(tex, texvec); 
1042                 break;
1043         case TEX_BLEND:
1044                 retval= blend(tex, texvec);
1045                 break;
1046         case TEX_STUCCI:
1047                 Tin= 0.0;
1048                 retval= stucci(tex, texvec); 
1049                 break;
1050         case TEX_NOISE:
1051                 retval= texnoise(tex); 
1052                 break;
1053         case TEX_IMAGE:
1054                 if(osatex) retval= imagewraposa(tex, texvec, dxt, dyt); 
1055                 else retval= imagewrap(tex, texvec); 
1056                 break;
1057         case TEX_PLUGIN:
1058                 retval= plugintex(tex, texvec, dxt, dyt, osatex);
1059                 break;
1060         case TEX_ENVMAP:
1061                 retval= envmaptex(tex, texvec, dxt, dyt, osatex);
1062                 break;
1063         case TEX_MUSGRAVE:
1064                 /* newnoise: musgrave types */
1065                 
1066                 /* ton: added this, for Blender convention reason. scaling texvec here is so-so... */
1067                 VecMulf(texvec, 1.0/tex->noisesize);
1068                 
1069                 switch(tex->stype) {
1070                 case TEX_MFRACTAL:
1071                 case TEX_FBM:
1072                         retval= mg_mFractalOrfBmTex(tex, texvec);
1073                         break;
1074                 case TEX_RIDGEDMF:
1075                 case TEX_HYBRIDMF:
1076                         retval= mg_ridgedOrHybridMFTex(tex, texvec);
1077                         break;
1078                 case TEX_HTERRAIN:
1079                         retval= mg_HTerrainTex(tex, texvec);
1080                         break;
1081                 }
1082                 break;
1083         /* newnoise: voronoi type */
1084         case TEX_VORONOI:
1085                 /* ton: added this, for Blender convention reason. scaling texvec here is so-so... */
1086                 VecMulf(texvec, 1.0/tex->noisesize);
1087                 
1088                 retval= voronoiTex(tex, texvec);
1089                 break;
1090         case TEX_DISTNOISE:
1091                 /* ton: added this, for Blender convention reason. scaling texvec here is so-so... */
1092                 VecMulf(texvec, 1.0/tex->noisesize);
1093                 
1094                 retval= mg_distNoiseTex(tex, texvec);
1095                 break;
1096         }
1097
1098         if (tex->flag & TEX_COLORBAND) {
1099                 float col[4];
1100                 if (do_colorband(tex->coba, Tin, col)) {
1101                         retval |= 1;
1102                         Tr= col[0];
1103                         Tg= col[1];
1104                         Tb= col[2];
1105                         Ta= col[3];
1106                 }
1107         }
1108         return retval;
1109 }
1110
1111 /* ------------------------------------------------------------------------- */
1112
1113 /* alphatype */
1114 #define T_ALPHA_PREMUL  1
1115 #define T_ALPHA_TRANSP  2
1116
1117 /* in = destination, tex = texture, out = previous color */
1118 /* fact = texture strength, facg = button strength value */
1119 static void texture_rgb_blend(float *in, float *tex, float *out, float fact, float facg, int blendtype, int alphatype)
1120 {
1121         float facm, col;
1122         
1123         switch(blendtype) {
1124         case MTEX_BLEND:
1125                 if(alphatype & T_ALPHA_TRANSP) {
1126                         /* de-premul */
1127                         if(fact>0.0) fact= facg/fact;
1128                         facm= 1.0-facg;
1129                 }
1130                 else if(alphatype & T_ALPHA_PREMUL) {
1131                         facm= 1.0- fact*facg;
1132                         fact= facg;
1133                 }
1134                 else {
1135                         fact*= facg;
1136                         facm= 1.0-fact;
1137                 }
1138                 in[0]= (fact*tex[0] + facm*out[0]);
1139                 in[1]= (fact*tex[1] + facm*out[1]);
1140                 in[2]= (fact*tex[2] + facm*out[2]);
1141                 break;
1142
1143         case MTEX_MUL:
1144                 fact*= facg;
1145                 facm= 1.0-facg;
1146                 in[0]= (facm+fact*tex[0])*out[0];
1147                 in[1]= (facm+fact*tex[1])*out[1];
1148                 in[2]= (facm+fact*tex[2])*out[2];
1149                 break;
1150
1151         case MTEX_SCREEN:
1152                 fact*= facg;
1153                 facm= 1.0-facg;
1154                 in[0]= 1.0-(facm+fact*(1.0-tex[0]))*(1.0-out[0]);
1155                 in[1]= 1.0-(facm+fact*(1.0-tex[1]))*(1.0-out[1]);
1156                 in[2]= 1.0-(facm+fact*(1.0-tex[2]))*(1.0-out[2]);
1157                 break;
1158
1159         case MTEX_SUB:
1160                 fact= -fact;
1161         case MTEX_ADD:
1162                 fact*= facg;
1163                 in[0]= (fact*tex[0] + out[0]);
1164                 in[1]= (fact*tex[1] + out[1]);
1165                 in[2]= (fact*tex[2] + out[2]);
1166                 break;
1167
1168         case MTEX_DIV:
1169                 fact*= facg;
1170                 facm= 1.0-fact;
1171                 
1172                 if(tex[0]!=0.0)
1173                         in[0]= facm*out[0] + fact*out[0]/tex[0];
1174                 if(tex[1]!=0.0)
1175                         in[1]= facm*out[1] + fact*out[1]/tex[1];
1176                 if(tex[2]!=0.0)
1177                         in[2]= facm*out[2] + fact*out[2]/tex[2];
1178
1179                 break;
1180
1181         case MTEX_DIFF:
1182                 fact*= facg;
1183                 facm= 1.0-fact;
1184                 in[0]= facm*out[0] + fact*fabs(tex[0]-out[0]);
1185                 in[1]= facm*out[1] + fact*fabs(tex[1]-out[1]);
1186                 in[2]= facm*out[2] + fact*fabs(tex[2]-out[2]);
1187                 break;
1188
1189         case MTEX_DARK:
1190                 fact*= facg;
1191                 facm= 1.0-fact;
1192                 
1193                 col= fact*tex[0];
1194                 if(col < out[0]) in[0]= col; else in[0]= out[0];
1195                 col= fact*tex[1];
1196                 if(col < out[1]) in[1]= col; else in[1]= out[1];
1197                 col= fact*tex[2];
1198                 if(col < out[2]) in[2]= col; else in[2]= out[2];
1199                 break;
1200
1201         case MTEX_LIGHT:
1202                 fact*= facg;
1203                 facm= 1.0-fact;
1204                 
1205                 col= fact*tex[0];
1206                 if(col > out[0]) in[0]= col; else in[0]= out[0];
1207                 col= fact*tex[1];
1208                 if(col > out[1]) in[1]= col; else in[1]= out[1];
1209                 col= fact*tex[2];
1210                 if(col > out[2]) in[2]= col; else in[2]= out[2];
1211                 break;
1212         }
1213
1214
1215 }
1216
1217 static float texture_value_blend(float tex, float out, float fact, float facg, int blendtype, int flip)
1218 {
1219         float in=0.0, facm, col;
1220         
1221         fact*= facg;
1222         facm= 1.0-fact;
1223         if(flip) SWAP(float, fact, facm);
1224
1225         switch(blendtype) {
1226         case MTEX_BLEND:
1227                 in= fact*tex + facm*out;
1228                 break;
1229
1230         case MTEX_MUL:
1231                 facm= 1.0-facg;
1232                 in= (facm+fact*tex)*out;
1233                 break;
1234
1235         case MTEX_SCREEN:
1236                 facm= 1.0-facg;
1237                 in= 1.0-(facm+fact*(1.0-tex))*(1.0-out);
1238                 break;
1239
1240         case MTEX_SUB:
1241                 fact= -fact;
1242         case MTEX_ADD:
1243                 in= fact*tex + out;
1244                 break;
1245
1246         case MTEX_DIV:
1247                 if(tex!=0.0)
1248                         in= facm*out + fact*out/tex;
1249                 break;
1250
1251         case MTEX_DIFF:
1252                 in= facm*out + fact*fabs(tex-out);
1253                 break;
1254
1255         case MTEX_DARK:
1256                 col= fact*tex;
1257                 if(col < out) in= col; else in= out;
1258                 break;
1259
1260         case MTEX_LIGHT:
1261                 col= fact*tex;
1262                 if(col > out) in= col; else in= out;
1263                 break;
1264         }
1265         
1266         return in;
1267 }
1268
1269
1270 void do_material_tex(ShadeInput *shi)
1271 {
1272         Object *ob;
1273         Material *mat_col, *mat_colspec, *mat_colmir, *mat_ref, *mat_amb;
1274         Material *mat_spec, *mat_har, *mat_emit, *mat_alpha, *mat_ray_mirr, *mat_translu;
1275         MTex *mtex;
1276         Tex *tex;
1277         float *co = NULL, *dx = NULL, *dy = NULL;
1278         float fact, facm, factt, facmm, stencilTin=1.0;
1279         float texvec[3], dxt[3], dyt[3], tempvec[3], norvec[3], Tnor=1.0;
1280         int tex_nr, rgbnor= 0;
1281
1282         /* here: test flag if there's a tex (todo) */
1283         
1284         mat_col=mat_colspec=mat_colmir=mat_ref=mat_spec=mat_har=mat_emit=mat_alpha=mat_ray_mirr=mat_translu=mat_amb= shi->mat;
1285         
1286         for(tex_nr=0; tex_nr<8; tex_nr++) {
1287                 
1288                 /* separate tex switching */
1289                 if(shi->mat->septex & (1<<tex_nr)) continue;
1290                 
1291                 if(shi->mat->mtex[tex_nr]) {
1292                         mtex= shi->mat->mtex[tex_nr];
1293                         
1294                         tex= mtex->tex;
1295                         if(tex==0) continue;
1296                         
1297                         /* which coords */
1298                         if(mtex->texco==TEXCO_ORCO) {
1299                                 co= shi->lo; dx= O.dxlo; dy= O.dylo;
1300                         }
1301                         else if(mtex->texco==TEXCO_STICKY) {
1302                                 co= shi->sticky; dx= O.dxsticky; dy= O.dysticky;
1303                         }
1304                         else if(mtex->texco==TEXCO_OBJECT) {
1305                                 ob= mtex->object;
1306                                 if(ob) {
1307                                         co= tempvec;
1308                                         dx= dxt;
1309                                         dy= dyt;
1310                                         VECCOPY(tempvec, shi->co);
1311                                         MTC_Mat4MulVecfl(ob->imat, tempvec);
1312                                         if(shi->osatex) {
1313                                                 VECCOPY(dxt, O.dxco);
1314                                                 VECCOPY(dyt, O.dyco);
1315                                                 MTC_Mat4Mul3Vecfl(ob->imat, dxt);
1316                                                 MTC_Mat4Mul3Vecfl(ob->imat, dyt);
1317                                         }
1318                                 }
1319                                 else {
1320                                         /* if object doesn't exist, do not use orcos (not initialized) */
1321                                         co= shi->co;
1322                                         dx= O.dxco; dy= O.dyco;
1323                                 }
1324                         }
1325                         else if(mtex->texco==TEXCO_REFL) {
1326                                 co= shi->ref; dx= O.dxref; dy= O.dyref;
1327                         }
1328                         else if(mtex->texco==TEXCO_NORM) {
1329                                 co= shi->orn; dx= O.dxno; dy= O.dyno;
1330                         }
1331                         else if(mtex->texco==TEXCO_GLOB) {
1332                                 co= shi->gl; dx= O.dxco; dy= O.dyco;
1333                         }
1334                         else if(mtex->texco==TEXCO_UV) {
1335                                 co= shi->uv; dx= O.dxuv; dy= O.dyuv; 
1336                         }
1337                         else if(mtex->texco==TEXCO_WINDOW) {
1338                                 co= shi->winco; dx= O.dxwin; dy= O.dywin;
1339                         }
1340                         
1341                         /* de pointer defines if bumping happens */
1342                         if(mtex->mapto & (MAP_NORM|MAP_DISPLACE)) {
1343                                 tex->nor= norvec;
1344                                 norvec[0]= norvec[1]= norvec[2]= 0.0;
1345                         }
1346                         else tex->nor= NULL;
1347
1348                         if(tex->type==TEX_IMAGE) {
1349
1350                                 /* new: first swap coords, then map, then trans/scale */
1351
1352                                 /* placement */
1353                                 if(mtex->projx) texvec[0]= co[mtex->projx-1];
1354                                 else texvec[0]= 0.0;
1355                                 if(mtex->projy) texvec[1]= co[mtex->projy-1];
1356                                 else texvec[1]= 0.0;
1357                                 if(mtex->projz) texvec[2]= co[mtex->projz-1];
1358                                 else texvec[2]= 0.0;
1359
1360                                 if(shi->osatex) {
1361
1362                                         if(mtex->projx) {
1363                                                 dxt[0]= dx[mtex->projx-1];
1364                                                 dyt[0]= dy[mtex->projx-1];
1365                                         }
1366                                         else dxt[0]= 0.0;
1367                                         if(mtex->projy) {
1368                                                 dxt[1]= dx[mtex->projy-1];
1369                                                 dyt[1]= dy[mtex->projy-1];
1370                                         }
1371                                         else dxt[1]= 0.0;
1372                                         if(mtex->projx) {
1373                                                 dxt[2]= dx[mtex->projz-1];
1374                                                 dyt[2]= dy[mtex->projz-1];
1375                                         }
1376                                         else dxt[2]= 0.0;
1377                                 }
1378
1379                                 do_2d_mapping(mtex, texvec, shi->vlr, dxt, dyt);
1380
1381                                 /* translate and scale */
1382                                 texvec[0]= mtex->size[0]*(texvec[0]-0.5) +mtex->ofs[0]+0.5;
1383                                 texvec[1]= mtex->size[1]*(texvec[1]-0.5) +mtex->ofs[1]+0.5;
1384                                 if(shi->osatex) {
1385                                         dxt[0]= mtex->size[0]*dxt[0];
1386                                         dxt[1]= mtex->size[1]*dxt[1];
1387                                         dyt[0]= mtex->size[0]*dyt[0];
1388                                         dyt[1]= mtex->size[1]*dyt[1];
1389                                 }
1390                         }
1391                         else {
1392
1393                                 /* placement */
1394                                 if(mtex->projx) texvec[0]= mtex->size[0]*(co[mtex->projx-1]+mtex->ofs[0]);
1395                                 else texvec[0]= mtex->size[0]*(mtex->ofs[0]);
1396
1397                                 if(mtex->projy) texvec[1]= mtex->size[1]*(co[mtex->projy-1]+mtex->ofs[1]);
1398                                 else texvec[1]= mtex->size[1]*(mtex->ofs[1]);
1399
1400                                 if(mtex->projz) texvec[2]= mtex->size[2]*(co[mtex->projz-1]+mtex->ofs[2]);
1401                                 else texvec[2]= mtex->size[2]*(mtex->ofs[2]);
1402
1403                                 if(shi->osatex) {
1404                                         if(mtex->projx) {
1405                                                 dxt[0]= mtex->size[0]*dx[mtex->projx-1];
1406                                                 dyt[0]= mtex->size[0]*dy[mtex->projx-1];
1407                                         }
1408                                         else dxt[0]= 0.0;
1409                                         if(mtex->projy) {
1410                                                 dxt[1]= mtex->size[1]*dx[mtex->projy-1];
1411                                                 dyt[1]= mtex->size[1]*dy[mtex->projy-1];
1412                                         }
1413                                         else dxt[1]= 0.0;
1414                                         if(mtex->projx) {
1415                                                 dxt[2]= mtex->size[2]*dx[mtex->projz-1];
1416                                                 dyt[2]= mtex->size[2]*dy[mtex->projz-1];
1417                                         }
1418                                         else dxt[2]= 0.0;
1419                                 }
1420                         }
1421
1422                         rgbnor= multitex(tex, texvec, dxt, dyt, shi->osatex);
1423
1424                         /* texture output */
1425
1426                         if( (rgbnor & TEX_RGB) && (mtex->texflag & MTEX_RGBTOINT)) {
1427                                 Tin= (0.35*Tr+0.45*Tg+0.2*Tb);
1428                                 rgbnor-= 1;
1429                         }
1430                         if(mtex->texflag & MTEX_NEGATIVE) {
1431                                 if(rgbnor & TEX_RGB) {
1432                                         Tr= 1.0-Tr;
1433                                         Tg= 1.0-Tg;
1434                                         Tb= 1.0-Tb;
1435                                 }
1436                                 Tin= 1.0-Tin;
1437                         }
1438                         if(mtex->texflag & MTEX_STENCIL) {
1439                                 if(rgbnor & TEX_RGB) {
1440                                         fact= Ta;
1441                                         Ta*= stencilTin;
1442                                         stencilTin*= fact;
1443                                 }
1444                                 else {
1445                                         fact= Tin;
1446                                         Tin*= stencilTin;
1447                                         stencilTin*= fact;
1448                                 }
1449                         }
1450                         else {
1451                                 Ta*= stencilTin;
1452                                 Tnor*= stencilTin;
1453                                 Tin*= stencilTin;
1454                         }
1455
1456                         if(tex->nor && (rgbnor & TEX_NOR)==0) {
1457                                 /* make our own normal */
1458                                 if(rgbnor & TEX_RGB) {
1459                                         tex->nor[0]= Tr;
1460                                         tex->nor[1]= Tg;
1461                                         tex->nor[2]= Tb;
1462                                 }
1463                                 else {
1464                                         float co= 0.5*cos(Tin-0.5);
1465                                         float si= 0.5*sin(Tin-0.5);
1466                                         float f1, f2;
1467
1468                                         f1= shi->vn[0];
1469                                         f2= shi->vn[1];
1470                                         tex->nor[0]= f1*co+f2*si;
1471                                         tex->nor[1]= f2*co-f1*si;
1472                                         f1= shi->vn[1];
1473                                         f2= shi->vn[2];
1474                                         tex->nor[1]= f1*co+f2*si;
1475                                         tex->nor[2]= f2*co-f1*si;
1476                                 }
1477                         }
1478
1479
1480                         /* mapping */
1481                         if(mtex->mapto & (MAP_COL+MAP_COLSPEC+MAP_COLMIR)) {
1482                                 float tcol[3];
1483                                 int alphatype= 0;
1484                                 
1485                                 tcol[0]=Tr; tcol[1]=Tg; tcol[2]=Tb;
1486                                 
1487                                 if((rgbnor & TEX_RGB)==0) {
1488                                         tcol[0]= mtex->r;
1489                                         tcol[1]= mtex->g;
1490                                         tcol[2]= mtex->b;
1491                                 }
1492                                 else if(mtex->mapto & MAP_ALPHA) {
1493                                         alphatype= T_ALPHA_TRANSP;
1494                                 }
1495                                 else Tin= Ta;
1496                                 
1497                                 if(Talpha) {
1498                                         alphatype |= T_ALPHA_PREMUL;
1499                                 }
1500                                 if(mtex->mapto & MAP_COL) {
1501                                         texture_rgb_blend(&shi->matren->r, tcol, &mat_col->r, Tin, mtex->colfac, mtex->blendtype, alphatype);
1502                                         mat_col= shi->matren;
1503                                 }
1504                                 if(mtex->mapto & MAP_COLSPEC) {
1505                                         texture_rgb_blend(&shi->matren->specr, tcol, &mat_col->specr, Tin, mtex->colfac, mtex->blendtype, 0);
1506                                         mat_colspec= shi->matren;
1507                                 }
1508                                 if(mtex->mapto & MAP_COLMIR) {
1509                                         // exception for envmap only
1510                                         if(tex->type==TEX_ENVMAP && mtex->blendtype==MTEX_BLEND) {
1511                                                 fact= Tin*mtex->colfac;
1512                                                 facm= 1.0- fact;
1513                                                 shi->refcol[0]= fact + facm*shi->refcol[0];
1514                                                 shi->refcol[1]= fact*tcol[0] + facm*shi->refcol[1];
1515                                                 shi->refcol[2]= fact*tcol[1] + facm*shi->refcol[2];
1516                                                 shi->refcol[3]= fact*tcol[2] + facm*shi->refcol[3];
1517                                         }
1518                                         else {
1519                                                 texture_rgb_blend(&shi->matren->mirr, tcol, &mat_col->mirr, Tin, mtex->colfac, mtex->blendtype, 0);
1520                                         }
1521                                         mat_colmir= shi->matren;
1522                                 }
1523                         }
1524                         if( (mtex->mapto & MAP_NORM) ) {
1525                                 if(tex->nor) {
1526                                         
1527                                         if(mtex->maptoneg & MAP_NORM) tex->norfac= -mtex->norfac;
1528                                         else tex->norfac= mtex->norfac;
1529
1530                                         shi->vn[0]+= Tnor*tex->norfac*tex->nor[0];
1531                                         shi->vn[1]+= Tnor*tex->norfac*tex->nor[1];
1532                                         shi->vn[2]+= Tnor*tex->norfac*tex->nor[2];
1533                                         
1534                                         Normalise(shi->vn);
1535                                         
1536                                         /* this makes sure the bump is passed on to the next texture */
1537                                         shi->orn[0]= shi->vn[0];
1538                                         shi->orn[1]= shi->vn[1];
1539                                         shi->orn[2]= shi->vn[2];
1540                                         
1541                                         /* reflection vector */
1542                                         calc_R_ref(shi);
1543                                 }
1544                         }
1545
1546                         if( mtex->mapto & MAP_DISPLACE ) {
1547                                 /* Now that most textures offer both Nor and Intensity, allow  */
1548                                 /* both to work, and let user select with slider.   */
1549                                 if(tex->nor) {
1550                                         if(mtex->maptoneg & MAP_DISPLACE) tex->norfac= -mtex->norfac;
1551                                         else tex->norfac= mtex->norfac;
1552
1553                                         shi->displace[0]+= 0.2f*Tnor*tex->norfac*tex->nor[0];
1554                                         shi->displace[1]+= 0.2f*Tnor*tex->norfac*tex->nor[1];
1555                                         shi->displace[2]+= 0.2f*Tnor*tex->norfac*tex->nor[2];
1556                                 }
1557                                 
1558                                 if(rgbnor & TEX_RGB) {
1559                                         if(Talpha) Tin= Ta;
1560                                         else Tin= (0.35*Tr+0.45*Tg+0.2*Tb);
1561                                 }
1562
1563                                 if(mtex->maptoneg & MAP_DISPLACE) {
1564                                         factt= (0.5-Tin)*mtex->dispfac; facmm= 1.0-factt;
1565                                 }
1566                                 else {
1567                                         factt= (Tin-0.5)*mtex->dispfac; facmm= 1.0-factt;
1568                                 }
1569
1570                                 if(mtex->blendtype==MTEX_BLEND) {
1571                                         shi->displace[0]= factt*shi->vn[0] + facmm*shi->displace[0];
1572                                         shi->displace[1]= factt*shi->vn[1] + facmm*shi->displace[1];
1573                                         shi->displace[2]= factt*shi->vn[2] + facmm*shi->displace[2];
1574                                 }
1575                                 else if(mtex->blendtype==MTEX_MUL) {
1576                                         shi->displace[0]*= factt*shi->vn[0];
1577                                         shi->displace[1]*= factt*shi->vn[1];
1578                                         shi->displace[2]*= factt*shi->vn[2];
1579                                 }
1580                                 else { /* add or sub */
1581                                         if(mtex->blendtype==MTEX_SUB) factt= -factt;
1582                                         else factt= factt;
1583                                         shi->displace[0]+= factt*shi->vn[0];
1584                                         shi->displace[1]+= factt*shi->vn[1];
1585                                         shi->displace[2]+= factt*shi->vn[2];
1586                                 }
1587                         }
1588
1589                         if(mtex->mapto & MAP_VARS) {
1590                                 if(rgbnor & TEX_RGB) {
1591                                         if(Talpha) Tin= Ta;
1592                                         else Tin= (0.35*Tr+0.45*Tg+0.2*Tb);
1593                                 }
1594
1595                                 if(mtex->mapto & MAP_REF) {
1596                                         int flip= mtex->maptoneg & MAP_REF;
1597
1598                                         shi->matren->ref= texture_value_blend(mtex->def_var, mat_ref->ref, Tin, mtex->varfac, mtex->blendtype, flip);
1599
1600                                         if(shi->matren->ref<0.0) shi->matren->ref= 0.0;
1601                                         mat_ref= shi->matren;
1602                                 }
1603                                 if(mtex->mapto & MAP_SPEC) {
1604                                         int flip= mtex->maptoneg & MAP_SPEC;
1605                                         
1606                                         shi->matren->spec= texture_value_blend(mtex->def_var, mat_ref->spec, Tin, mtex->varfac, mtex->blendtype, flip);
1607
1608                                         if(shi->matren->spec<0.0) shi->matren->spec= 0.0;
1609                                         mat_spec= shi->matren;
1610                                 }
1611                                 if(mtex->mapto & MAP_EMIT) {
1612                                         int flip= mtex->maptoneg & MAP_EMIT;
1613
1614                                         shi->matren->emit= texture_value_blend(mtex->def_var, mat_ref->emit, Tin, mtex->varfac, mtex->blendtype, flip);
1615
1616                                         if(shi->matren->emit<0.0) shi->matren->emit= 0.0;
1617                                         mat_emit= shi->matren;
1618                                 }
1619                                 if(mtex->mapto & MAP_ALPHA) {
1620                                         int flip= mtex->maptoneg & MAP_ALPHA;
1621
1622                                         shi->matren->alpha= texture_value_blend(mtex->def_var, mat_ref->alpha, Tin, mtex->varfac, mtex->blendtype, flip);
1623                                                 
1624                                         if(shi->matren->alpha<0.0) shi->matren->alpha= 0.0;
1625                                         else if(shi->matren->alpha>1.0) shi->matren->alpha= 1.0;
1626                                         mat_alpha= shi->matren;
1627                                 }
1628                                 if(mtex->mapto & MAP_HAR) {
1629                                         int flip= mtex->maptoneg & MAP_HAR;
1630                                         float har;  // have to map to 0-1
1631                                         
1632                                         har= ((float)mat_ref->har)/128.0;
1633                                         har= 128.0*texture_value_blend(mtex->def_var, har, Tin, mtex->varfac, mtex->blendtype, flip);
1634                                         
1635                                         if(har<1.0) shi->matren->har= 1; 
1636                                         else if(har>511.0) shi->matren->har= 511;
1637                                         else shi->matren->har= (int)har;
1638                                         mat_har= shi->matren;
1639                                 }
1640                                 if(mtex->mapto & MAP_RAYMIRR) {
1641                                         int flip= mtex->maptoneg & MAP_RAYMIRR;
1642
1643                                         shi->matren->ray_mirror= texture_value_blend(mtex->def_var, mat_ref->ray_mirror, Tin, mtex->varfac, mtex->blendtype, flip);
1644
1645                                         if(shi->matren->ray_mirror<0.0) shi->matren->ray_mirror= 0.0;
1646                                         else if(shi->matren->ray_mirror>1.0) shi->matren->ray_mirror= 1.0;
1647                                         mat_ray_mirr= shi->matren;
1648                                 }
1649                                 if(mtex->mapto & MAP_TRANSLU) {
1650                                         int flip= mtex->maptoneg & MAP_TRANSLU;
1651
1652                                         shi->matren->translucency= texture_value_blend(mtex->def_var, mat_ref->translucency, Tin, mtex->varfac, mtex->blendtype, flip);
1653
1654                                         if(shi->matren->translucency<0.0) shi->matren->translucency= 0.0;
1655                                         else if(shi->matren->translucency>1.0) shi->matren->translucency= 1.0;
1656                                         mat_translu= shi->matren;
1657                                 }
1658                                 if(mtex->mapto & MAP_AMB) {
1659                                         int flip= mtex->maptoneg & MAP_AMB;
1660
1661                                         shi->matren->amb= texture_value_blend(mtex->def_var, mat_ref->amb, Tin, mtex->varfac, mtex->blendtype, flip);
1662
1663                                         if(shi->matren->amb<0.0) shi->matren->amb= 0.0;
1664                                         else if(shi->matren->amb>1.0) shi->matren->amb= 1.0;
1665                                         mat_amb= shi->matren;
1666                                 }
1667                         }
1668                 }
1669         }
1670 }
1671
1672 /* ------------------------------------------------------------------------- */
1673
1674 void do_halo_tex(HaloRen *har, float xn, float yn, float *colf)
1675 {
1676         MTex *mtex;
1677         float texvec[3], dxt[3], dyt[3], fact, facm, dx;
1678         int rgb, osatex;
1679         
1680         mtex= har->mat->mtex[0];
1681         if(mtex->tex==0) return;
1682         /* no normal mapping */
1683         mtex->tex->nor= NULL;
1684                 
1685         texvec[0]= xn/har->rad;
1686         texvec[1]= yn/har->rad;
1687         texvec[2]= 0.0;
1688         
1689         osatex= (har->mat->texco & TEXCO_OSA);
1690
1691         /* placement */
1692         if(mtex->projx) texvec[0]= mtex->size[0]*(texvec[mtex->projx-1]+mtex->ofs[0]);
1693         else texvec[0]= mtex->size[0]*(mtex->ofs[0]);
1694         
1695         if(mtex->projy) texvec[1]= mtex->size[1]*(texvec[mtex->projy-1]+mtex->ofs[1]);
1696         else texvec[1]= mtex->size[1]*(mtex->ofs[1]);
1697         
1698         if(mtex->projz) texvec[2]= mtex->size[2]*(texvec[mtex->projz-1]+mtex->ofs[2]);
1699         else texvec[2]= mtex->size[2]*(mtex->ofs[2]);
1700         
1701         if(osatex) {
1702         
1703                 dx= 1.0/har->rad;
1704         
1705                 if(mtex->projx) {
1706                         dxt[0]= mtex->size[0]*dx;
1707                         dyt[0]= mtex->size[0]*dx;
1708                 }
1709                 else dxt[0]= 0.0;
1710                 if(mtex->projy) {
1711                         dxt[1]= mtex->size[1]*dx;
1712                         dyt[1]= mtex->size[1]*dx;
1713                 }
1714                 else dxt[1]= 0.0;
1715                 if(mtex->projz) {
1716                         dxt[2]= 0.0;
1717                         dyt[2]= 0.0;
1718                 }
1719                 else dxt[2]= 0.0;
1720
1721         }
1722
1723         if(mtex->tex->type==TEX_IMAGE) do_2d_mapping(mtex, texvec, NULL, dxt, dyt);
1724         
1725         rgb= multitex(mtex->tex, texvec, dxt, dyt, osatex);
1726
1727         /* texture output */
1728         if(rgb && (mtex->texflag & MTEX_RGBTOINT)) {
1729                 Tin= (0.35*Tr+0.45*Tg+0.2*Tb);
1730                 rgb= 0;
1731         }
1732         if(mtex->texflag & MTEX_NEGATIVE) {
1733                 if(rgb) {
1734                         Tr= 1.0-Tr;
1735                         Tg= 1.0-Tg;
1736                         Tb= 1.0-Tb;
1737                 }
1738                 else Tin= 1.0-Tin;
1739         }
1740
1741         /* mapping */
1742         if(mtex->mapto & MAP_COL) {
1743                 
1744                 if(rgb==0) {
1745                         Tr= mtex->r;
1746                         Tg= mtex->g;
1747                         Tb= mtex->b;
1748                 }
1749                 else if(mtex->mapto & MAP_ALPHA) {
1750                         Tin= 1.0;
1751                 }
1752                 else Tin= Ta;
1753
1754                 fact= Tin*mtex->colfac;
1755                 facm= 1.0-fact;
1756                 
1757                 if(mtex->blendtype==MTEX_MUL) {
1758                         facm= 1.0-mtex->colfac;
1759                 }
1760                 else fact*= 256;
1761                 /* note: halo colors are still 0-255, should map that for new mixing functions... */
1762                 
1763                 if(mtex->blendtype==MTEX_SUB) fact= -fact;
1764
1765                 if(mtex->blendtype==MTEX_BLEND) {
1766                         colf[0]= (fact*Tr + facm*har->r);
1767                         colf[1]= (fact*Tg + facm*har->g);
1768                         colf[2]= (fact*Tb + facm*har->b);
1769                 }
1770                 else if(mtex->blendtype==MTEX_MUL) {
1771                         colf[0]= (facm+fact*Tr)*har->r;
1772                         colf[1]= (facm+fact*Tg)*har->g;
1773                         colf[2]= (facm+fact*Tb)*har->b;
1774                 }
1775                 else {
1776                         colf[0]= (fact*Tr + har->r);
1777                         colf[1]= (fact*Tg + har->g);
1778                         colf[2]= (fact*Tb + har->b);
1779                         
1780                         CLAMP(colf[0], 0.0, 1.0);
1781                         CLAMP(colf[1], 0.0, 1.0);
1782                         CLAMP(colf[2], 0.0, 1.0);
1783                 }
1784         }
1785         if(mtex->mapto & MAP_ALPHA) {
1786                 if(rgb) {
1787                         if(Talpha) Tin= Ta;
1788                         else Tin= (0.35*Tr+0.45*Tg+0.2*Tb);
1789                 }
1790                                 
1791                 colf[3]*= Tin;
1792         }
1793 }
1794
1795 /* ------------------------------------------------------------------------- */
1796
1797 void do_sky_tex(float *lo)
1798 {
1799         World *wrld_hor, *wrld_zen;
1800         MTex *mtex;
1801         float *co, fact, stencilTin=1.0;
1802         float tempvec[3], texvec[3], dxt[3], dyt[3];
1803         int tex_nr, rgb= 0, ok;
1804         
1805
1806         /* todo: add flag to test if there's a tex */
1807         
1808         wrld_hor= wrld_zen= G.scene->world;
1809
1810         /* The 6 here is the max amount of channels for a world */
1811         for(tex_nr=0; tex_nr<6; tex_nr++) {
1812                 if(R.wrld.mtex[tex_nr]) {
1813                         mtex= R.wrld.mtex[tex_nr];
1814                         
1815                         if(mtex->tex==0) continue;
1816                         /* if(mtex->mapto==0) continue; */
1817                         
1818                         /* which coords */
1819                         co= lo;
1820                         
1821                         /* dxt dyt just from 1 value */
1822                         dxt[0]= dxt[1]= dxt[2]= O.dxview;
1823                         dyt[0]= dyt[1]= dyt[2]= O.dyview;
1824                         
1825                         /* Grab the mapping settings for this texture */
1826                         switch(mtex->texco) {
1827                         case TEXCO_ANGMAP:
1828                                 
1829                                 fact= (1.0/M_PI)*acos(lo[2])/(sqrt(lo[0]*lo[0] + lo[1]*lo[1])); 
1830                                 tempvec[0]= lo[0]*fact;
1831                                 tempvec[1]= lo[1]*fact;
1832                                 tempvec[2]= 0.0;
1833                                 co= tempvec;
1834                                 break;
1835                         
1836                         case TEXCO_H_SPHEREMAP:
1837                         case TEXCO_H_TUBEMAP:
1838                                 if(R.wrld.skytype & WO_ZENUP) {
1839                                         if(mtex->texco==TEXCO_H_TUBEMAP) tubemap(lo[0], lo[2], lo[1], tempvec, tempvec+1);
1840                                         else spheremap(lo[0], lo[2], lo[1], tempvec, tempvec+1);
1841                                         /* tube/spheremap maps for outside view, not inside */
1842                                         tempvec[0]= 1.0-tempvec[0];
1843                                         /* only top half */
1844                                         tempvec[1]= 2.0*tempvec[1]-1.0;
1845                                         tempvec[2]= 0.0;
1846                                         /* and correction for do_2d_mapping */
1847                                         tempvec[0]= 2.0*tempvec[0]-1.0;
1848                                         tempvec[1]= 2.0*tempvec[1]-1.0;
1849                                         co= tempvec;
1850                                 }
1851                                 else {
1852                                         /* potentially dangerous... check with multitex! */
1853                                         R.wrld.horr= (wrld_hor->horr);
1854                                         R.wrld.horg= (wrld_hor->horg);
1855                                         R.wrld.horb= (wrld_hor->horb);
1856                                         R.wrld.zenr= (wrld_hor->zenr);
1857                                         R.wrld.zeng= (wrld_hor->zeng);
1858                                         R.wrld.zenb= (wrld_hor->zenb);
1859                                         continue;
1860                                 }
1861                                 break;
1862                         case TEXCO_OBJECT:
1863                                 if(mtex->object) {
1864                                         VECCOPY(tempvec, lo);
1865                                         MTC_Mat4MulVecfl(mtex->object->imat, tempvec);
1866                                         co= tempvec;
1867                                 }
1868                         }
1869                         
1870                         /* placement */                 
1871                         if(mtex->projx) texvec[0]= mtex->size[0]*(co[mtex->projx-1]+mtex->ofs[0]);
1872                         else texvec[0]= mtex->size[0]*(mtex->ofs[0]);
1873                         
1874                         if(mtex->projy) texvec[1]= mtex->size[1]*(co[mtex->projy-1]+mtex->ofs[1]);
1875                         else texvec[1]= mtex->size[1]*(mtex->ofs[1]);
1876                         
1877                         if(mtex->projz) texvec[2]= mtex->size[2]*(co[mtex->projz-1]+mtex->ofs[2]);
1878                         else texvec[2]= mtex->size[2]*(mtex->ofs[2]);
1879                         
1880                         /* texture */
1881                         if(mtex->tex->type==TEX_IMAGE) do_2d_mapping(mtex, texvec, NULL, dxt, dyt);
1882                 
1883                         rgb= multitex(mtex->tex, texvec, dxt, dyt, R.osa);
1884                         
1885                         /* texture output */
1886                         if(rgb && (mtex->texflag & MTEX_RGBTOINT)) {
1887                                 Tin= (0.35*Tr+0.45*Tg+0.2*Tb);
1888                                 rgb= 0;
1889                         }
1890                         if(mtex->texflag & MTEX_NEGATIVE) {
1891                                 if(rgb) {
1892                                         Tr= 1.0-Tr;
1893                                         Tg= 1.0-Tg;
1894                                         Tb= 1.0-Tb;
1895                                 }
1896                                 else Tin= 1.0-Tin;
1897                         }
1898                         if(mtex->texflag & MTEX_STENCIL) {
1899                                 if(rgb) {
1900                                         
1901                                 }
1902                                 else {
1903                                         fact= Tin;
1904                                         Tin*= stencilTin;
1905                                         stencilTin*= fact;
1906                                 }
1907                         }
1908                         else {
1909                                 if(rgb) ;
1910                                 else Tin*= stencilTin;
1911                         }
1912                         
1913                         /* colour mapping */
1914                         if(mtex->mapto & (WOMAP_HORIZ+WOMAP_ZENUP+WOMAP_ZENDOWN)) {
1915                                 float tcol[3];
1916                                 
1917                                 if(rgb==0) {
1918                                         Tr= mtex->r;
1919                                         Tg= mtex->g;
1920                                         Tb= mtex->b;
1921                                 }
1922                                 else Tin= 1.0;
1923                                 
1924                                 tcol[0]= Tr; tcol[1]= Tg; tcol[2]= Tb;
1925
1926                                 if(mtex->mapto & WOMAP_HORIZ) {
1927                                         texture_rgb_blend(&R.wrld.horr, tcol, &wrld_hor->horr, Tin, mtex->colfac, mtex->blendtype, 0);
1928                                         wrld_hor= &R.wrld;
1929                                 }
1930                                 if(mtex->mapto & (WOMAP_ZENUP+WOMAP_ZENDOWN)) {
1931                                         ok= 0;
1932                                         if(R.wrld.skytype & WO_SKYREAL) {
1933                                                 if((R.wrld.skytype & WO_ZENUP)) {
1934                                                         if(mtex->mapto & WOMAP_ZENUP) ok= 1;
1935                                                 }
1936                                                 else if(mtex->mapto & WOMAP_ZENDOWN) ok= 1;
1937                                         }
1938                                         else ok= 1;
1939                                         
1940                                         if(ok) {
1941                                                 texture_rgb_blend(&R.wrld.zenr, tcol, &wrld_hor->zenr, Tin, mtex->colfac, mtex->blendtype, 0);
1942                                                 wrld_zen= &R.wrld;
1943                                         }
1944                                         else {
1945                                                 /* otherwise zenRGB undefined */
1946                                                 R.wrld.zenr= wrld_zen->zenr;
1947                                                 R.wrld.zeng= wrld_zen->zeng;
1948                                                 R.wrld.zenb= wrld_zen->zenb;
1949                                         }
1950                                 }
1951                         }
1952                         if(mtex->mapto & WOMAP_BLEND) {
1953                                 if(rgb) Tin= (0.35*Tr+0.45*Tg+0.2*Tb);
1954                                 
1955                                 R.inprz= texture_value_blend(mtex->def_var, R.inprz, Tin, mtex->varfac, mtex->blendtype, 0);
1956                         }
1957                 }
1958         }
1959 }
1960
1961 /* ------------------------------------------------------------------------- */
1962 /* explicit lampren stuff should be factored out! or rather, the
1963    texturing stuff might need to go...*/
1964 void do_lamp_tex(LampRen *la, float *lavec, ShadeInput *shi)
1965 {
1966         Object *ob;
1967         LampRen *la_col;
1968         MTex *mtex;
1969         Tex *tex;
1970         float *co = NULL, *dx = NULL, *dy = NULL, fact, stencilTin=1.0;
1971         float texvec[3], dxt[3], dyt[3], tempvec[3];
1972         int tex_nr, rgb= 0;
1973         
1974         la_col= la->org;
1975         
1976         tex_nr= 0;
1977         
1978         for(; tex_nr<6; tex_nr++) {
1979                 
1980                 if(la->mtex[tex_nr]) {
1981                         mtex= la->mtex[tex_nr];
1982                         
1983                         tex= mtex->tex;
1984                         if(tex==0) continue;
1985                         tex->nor= NULL;
1986                         
1987                         /* which coords */
1988                         if(mtex->texco==TEXCO_OBJECT) {
1989                                 ob= mtex->object;
1990                                 if(ob) {
1991                                         co= tempvec;
1992                                         dx= dxt;
1993                                         dy= dyt;
1994                                         VECCOPY(tempvec, shi->co);
1995                                         MTC_Mat4MulVecfl(ob->imat, tempvec);
1996                                         if(shi->osatex) {
1997                                                 VECCOPY(dxt, O.dxco);
1998                                                 VECCOPY(dyt, O.dyco);
1999                                                 MTC_Mat4Mul3Vecfl(ob->imat, dxt);
2000                                                 MTC_Mat4Mul3Vecfl(ob->imat, dyt);
2001                                         }
2002                                 }
2003                                 else {
2004                                         co= shi->co;
2005                                         dx= O.dxco; dy= O.dyco;
2006                                 }
2007                         }
2008                         else if(mtex->texco==TEXCO_GLOB) {
2009                                 co= shi->gl; dx= O.dxco; dy= O.dyco;
2010                                 VECCOPY(shi->gl, shi->co);
2011                                 MTC_Mat4MulVecfl(R.viewinv, shi->gl);
2012                         }
2013                         else if(mtex->texco==TEXCO_VIEW) {
2014                                 
2015                                 VECCOPY(tempvec, lavec);
2016                                 MTC_Mat3MulVecfl(la->imat, tempvec);
2017                                 
2018                                 tempvec[0]*= la->spottexfac;
2019                                 tempvec[1]*= la->spottexfac;
2020                                 co= tempvec; 
2021                                 
2022                                 dx= dxt; dy= dyt;       
2023                                 if(shi->osatex) {
2024                                         VECCOPY(dxt, O.dxlv);
2025                                         VECCOPY(dyt, O.dylv);
2026                                         /* need some matrix conversion here? la->imat is a [3][3]  matrix!!! **/
2027                                         MTC_Mat3MulVecfl(la->imat, dxt);
2028                                         MTC_Mat3MulVecfl(la->imat, dyt);
2029                                         
2030                                         VecMulf(dxt, la->spottexfac);
2031                                         VecMulf(dyt, la->spottexfac);
2032                                 }
2033                         }
2034                         
2035                         
2036                         /* placement */
2037                         if(mtex->projx) texvec[0]= mtex->size[0]*(co[mtex->projx-1]+mtex->ofs[0]);
2038                         else texvec[0]= mtex->size[0]*(mtex->ofs[0]);
2039                         
2040                         if(mtex->projy) texvec[1]= mtex->size[1]*(co[mtex->projy-1]+mtex->ofs[1]);
2041                         else texvec[1]= mtex->size[1]*(mtex->ofs[1]);
2042                         
2043                         if(mtex->projz) texvec[2]= mtex->size[2]*(co[mtex->projz-1]+mtex->ofs[2]);
2044                         else texvec[2]= mtex->size[2]*(mtex->ofs[2]);
2045                         
2046                         if(shi->osatex) {
2047                                 if(mtex->projx) {
2048                                         dxt[0]= mtex->size[0]*dx[mtex->projx-1];
2049                                         dyt[0]= mtex->size[0]*dy[mtex->projx-1];
2050                                 }
2051                                 else dxt[0]= 0.0;
2052                                 if(mtex->projy) {
2053                                         dxt[1]= mtex->size[1]*dx[mtex->projy-1];
2054                                         dyt[1]= mtex->size[1]*dy[mtex->projy-1];
2055                                 }
2056                                 else dxt[1]= 0.0;
2057                                 if(mtex->projx) {
2058                                         dxt[2]= mtex->size[2]*dx[mtex->projz-1];
2059                                         dyt[2]= mtex->size[2]*dy[mtex->projz-1];
2060                                 }
2061                                 else dxt[2]= 0.0;
2062                         }
2063                         
2064                         /* texture */
2065                         if(tex->type==TEX_IMAGE) {
2066                                 do_2d_mapping(mtex, texvec, NULL, dxt, dyt);
2067                         }
2068                         
2069                         rgb= multitex(tex, texvec, dxt, dyt, shi->osatex);
2070
2071                         /* texture output */
2072                         if(rgb && (mtex->texflag & MTEX_RGBTOINT)) {
2073                                 Tin= (0.35*Tr+0.45*Tg+0.2*Tb);
2074                                 rgb= 0;
2075                         }
2076                         if(mtex->texflag & MTEX_NEGATIVE) {
2077                                 if(rgb) {
2078                                         Tr= 1.0-Tr;
2079                                         Tg= 1.0-Tg;
2080                                         Tb= 1.0-Tb;
2081                                 }
2082                                 else Tin= 1.0-Tin;
2083                         }
2084                         if(mtex->texflag & MTEX_STENCIL) {
2085                                 if(rgb) {
2086                                         fact= Ta;
2087                                         Ta*= stencilTin;
2088                                         stencilTin*= fact;
2089                                 }
2090                                 else {
2091                                         fact= Tin;
2092                                         Tin*= stencilTin;
2093                                         stencilTin*= fact;
2094                                 }
2095                         }
2096                         else {
2097                                 if(rgb) Ta*= stencilTin;
2098                                 else Tin*= stencilTin;
2099                         }
2100                         
2101                         /* mapping */
2102                         if(mtex->mapto & LAMAP_COL) {
2103                                 float col[3];
2104                                 
2105                                 if(rgb==0) {
2106                                         Tr= mtex->r;
2107                                         Tg= mtex->g;
2108                                         Tb= mtex->b;
2109                                 }
2110                                 else if(mtex->mapto & MAP_ALPHA) {
2111                                         Tin= stencilTin;
2112                                 }
2113                                 else Tin= Ta;
2114
2115                                 /* lamp colors were premultiplied with this */
2116                                 col[0]= Tr*la->energy;
2117                                 col[1]= Tg*la->energy;
2118                                 col[2]= Tb*la->energy;
2119                                 
2120                                 texture_rgb_blend(&la->r, col, &la_col->r, Tin, mtex->colfac, mtex->blendtype, 0);
2121
2122                                 la_col= la; /* makes sure first run uses la->org, then la */
2123                         }
2124                         
2125                 }
2126         }
2127 }
2128
2129 /* ------------------------------------------------------------------------- */
2130
2131 void externtex(MTex *mtex, float *vec)
2132 {
2133         Tex *tex;
2134         float dxt[3], dyt[3], texvec[3], dummy[3];
2135         int rgb;
2136         
2137         tex= mtex->tex;
2138         if(tex==0) return;
2139         
2140         /* placement */
2141         if(mtex->projx) texvec[0]= mtex->size[0]*(vec[mtex->projx-1]+mtex->ofs[0]);
2142         else texvec[0]= mtex->size[0]*(mtex->ofs[0]);
2143         
2144         if(mtex->projy) texvec[1]= mtex->size[1]*(vec[mtex->projy-1]+mtex->ofs[1]);
2145         else texvec[1]= mtex->size[1]*(mtex->ofs[1]);
2146         
2147         if(mtex->projz) texvec[2]= mtex->size[2]*(vec[mtex->projz-1]+mtex->ofs[2]);
2148         else texvec[2]= mtex->size[2]*(mtex->ofs[2]);
2149         
2150         /* texture */
2151         if(tex->type==TEX_IMAGE) {
2152                 do_2d_mapping(mtex, texvec, NULL, dxt, dyt);
2153                 
2154                 if(mtex->mapto & MAP_NORM) {
2155                         /* the pointer defines if there's bump */
2156                         tex->nor= dummy;
2157                         if(mtex->maptoneg & MAP_NORM) tex->norfac= -mtex->norfac;
2158                         else tex->norfac= mtex->norfac;
2159                 }
2160                 else tex->nor= NULL;
2161         }
2162         
2163         rgb= multitex(tex, texvec, dxt, dyt, 0);
2164         
2165         if(rgb) {
2166                 Tin= (0.35*Tr+0.45*Tg+0.2*Tb);
2167         }
2168         else {
2169                 Tr= mtex->r;
2170                 Tg= mtex->g;
2171                 Tb= mtex->b;
2172         }
2173 }
2174
2175 /* ------------------------------------------------------------------------- */
2176
2177 void externtexcol(MTex *mtex, float *orco, char *col)
2178 {
2179         int temp;
2180         float b1;
2181
2182         if(mtex->tex==0) return;
2183         
2184         externtex(mtex, orco);
2185
2186         b1= 1.0-Tin;
2187
2188         temp= 255*(Tin*Tr)+b1*col[0];
2189         if(temp>255) col[0]= 255; else col[0]= temp;
2190         temp= 255*(Tin*Tg)+b1*col[1];
2191         if(temp>255) col[1]= 255; else col[1]= temp;
2192         temp= 255*(Tin*Tb)+b1*col[2];
2193         if(temp>255) col[2]= 255; else col[2]= temp;
2194         
2195 }
2196
2197 /* ------------------------------------------------------------------------- */
2198
2199 void render_realtime_texture(ShadeInput *shi)
2200 {
2201         static Tex tex;
2202         static int firsttime= 1;
2203         float texvec[2], dx[2], dy[2];
2204         
2205         if(firsttime) {
2206                 default_tex(&tex);
2207                 tex.type= TEX_IMAGE;
2208                 firsttime= 0;
2209         }
2210         
2211         tex.ima = shi->vlr->tface->tpage;
2212         if(tex.ima) {
2213                 
2214                 texvec[0]= 0.5+0.5*shi->uv[0];
2215                 texvec[1]= 0.5+0.5*shi->uv[1];
2216                 if(shi->osatex) {
2217                         dx[0]= 0.5*O.dxuv[0];
2218                         dx[1]= 0.5*O.dxuv[1];
2219                         dy[0]= 0.5*O.dyuv[0];
2220                         dy[1]= 0.5*O.dyuv[1];
2221                 }
2222                 
2223                 if(shi->osatex) imagewraposa(&tex, texvec, dx, dy); 
2224                 else imagewrap(&tex, texvec); 
2225                 
2226                 shi->vcol[0]*= Tr;
2227                 shi->vcol[1]*= Tg;
2228                 shi->vcol[2]*= Tb;
2229         }
2230         
2231         
2232 }
2233
2234 /* eof */