New export through plugin scheme for yafray. It is working on linux and mac os x
[blender.git] / source / blender / render / intern / source / initrender.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  */
32
33
34 /* Global includes */
35
36 #include <math.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <stdio.h>
40
41 #ifdef HAVE_CONFIG_H
42 #include <config.h>
43 #endif
44
45 #ifdef WIN32
46 #include "BLI_winstuff.h"
47 #endif
48
49 #include "blendef.h"
50 #include "MEM_guardedalloc.h"
51
52 #include "PIL_time.h"
53
54 #include "BLI_arithb.h"
55 #include "BLI_blenlib.h"
56 #include "BLI_rand.h"
57
58 #include "MTC_matrixops.h"
59
60 #include "DNA_image_types.h"
61 #include "DNA_camera_types.h"
62 #include "DNA_lamp_types.h"
63 #include "DNA_scene_types.h"
64 #include "DNA_object_types.h"
65
66 #include "BKE_utildefines.h"
67 #include "BKE_global.h"
68 #include "BKE_material.h"
69 #include "BKE_object.h"
70 #include "BKE_image.h"
71 #include "BKE_ipo.h"
72 #include "BKE_key.h"
73 #include "BKE_ika.h"
74 #include "BKE_action.h"
75 #include "BKE_writeavi.h"
76 #include "BKE_scene.h"
77
78 #include "BIF_toolbox.h"
79 #include "BIF_writeavicodec.h"
80 #include "BIF_writemovie.h"             /* start_movie(), append_movie(), end_movie() */
81
82 #include "BSE_drawview.h"
83 #include "BSE_sequence.h"
84
85 #ifdef WITH_QUICKTIME
86 #include "quicktime_export.h"
87 #endif
88
89 /* this module */
90 #include "render.h"
91 #include "render_intern.h"
92
93 #include "RE_callbacks.h"
94 #include "zbuf.h"
95 #include "rendercore.h" /* part handler for the old renderer, shading functions */
96 #include "renderPreAndPost.h"
97 #include "vanillaRenderPipe.h"
98 #include "renderHelp.h"
99 #include "jitter.h"
100
101 /* Own includes */
102 #include "initrender.h"
103
104 /* yafray: include for yafray export/render */
105 #include "YafRay_Api.h"
106
107 /* Some crud :/ */
108 #define ELEM3(a, b, c, d)       ( ELEM(a, b, c) || (a)==(d) )
109
110
111 /* from render.c */
112 extern float fmask[256], centLut[16];
113 extern unsigned short *mask1[9], *mask2[9], /*  *igamtab1, */ *igamtab2/*,  *gamtab */;
114 extern char cmask[256], *centmask;
115
116 Material defmaterial;
117 short pa; /* pa is global part, for print */
118 short allparts[65][4];
119 int qscount;
120
121 /* ********************* *********************** */
122
123
124 void init_def_material(void)
125 {
126         Material *ma;
127
128         ma= &defmaterial;
129         
130         init_material(&defmaterial);
131
132         init_render_material(ma);
133 }
134
135 void RE_init_render_data(void)
136 {
137         memset(&R, 0, sizeof(RE_Render));
138         memset(&O, 0, sizeof(Osa));
139         O.dxwin[0]= 1.0;
140         O.dywin[1]= 1.0;
141         
142         R.blove= (VertRen **)MEM_callocN(sizeof(void *)*(TABLEINITSIZE),"Blove");
143         R.blovl= (VlakRen **)MEM_callocN(sizeof(void *)*(TABLEINITSIZE),"Blovl");
144         R.bloha= (HaloRen **)MEM_callocN(sizeof(void *)*(TABLEINITSIZE),"Bloha");
145         R.la= (LampRen **)MEM_mallocN(LAMPINITSIZE*sizeof(void *),"renderlamparray");
146
147         init_def_material();
148 }
149
150 void RE_free_render_data()
151 {
152         MEM_freeN(R.blove);
153         R.blove= 0;
154         MEM_freeN(R.blovl);
155         R.blovl= 0;
156         MEM_freeN(R.bloha);
157         R.bloha= 0;
158         MEM_freeN(R.la);
159         R.la= 0;
160         if(R.rectot) MEM_freeN(R.rectot);
161         if(R.rectz) MEM_freeN(R.rectz);
162         if(R.rectspare) MEM_freeN(R.rectspare);
163         R.rectot= 0;
164         R.rectz= 0;
165         R.rectspare= 0;
166
167         end_render_material(&defmaterial);
168 }
169
170 /* ****************** GAMMA, MASKS and LUTS **************** */
171
172 float  calc_weight(float *weight, int i, int j)
173 {
174         float x, y, dist, totw= 0.0, fac;
175         int a;
176
177         fac= R.r.gauss*R.r.gauss;
178         fac*= fac;
179
180         for(a=0; a<R.osa; a++) {
181                 x= jit[a][0] + i;
182                 y= jit[a][1] + j;
183                 dist= sqrt(x*x+y*y);
184
185                 weight[a]= 0.0;
186
187                 /* gaussian weighting has been cancelled */
188                 if(R.r.mode & R_GAUSS) {
189                         if(dist<R.r.gauss) {
190                                 x = dist*R.r.gauss;
191                                 weight[a]= (1.0/exp(x*x) - 1.0/exp(fac));
192                         }
193                 }
194                 else {
195                         if(i==0 && j==0) weight[a]= 1.0;
196                 }
197
198                 totw+= weight[a];
199
200         }
201         return totw;
202 }
203
204 void RE_init_filt_mask(void)
205 {
206         static int firsttime=1;
207         static float lastgamma= 0.0;
208         float gamma, igamma;
209         float weight[32], totw, val, *fpx1, *fpx2, *fpy1, *fpy2;
210         int i, j, a;
211         unsigned short *m1, *m2, shweight[32];
212
213         if(firsttime) {
214                 for(a=0; a<9;a++) {
215                         mask1[a]= MEM_mallocN(256*sizeof(short), "initfilt");
216                         mask2[a]= MEM_mallocN(256*sizeof(short), "initfilt");
217                 }
218                 for(a=0; a<256; a++) {
219                         cmask[a]= 0;
220                         if(a &   1) cmask[a]++;
221                         if(a &   2) cmask[a]++;
222                         if(a &   4) cmask[a]++;
223                         if(a &   8) cmask[a]++;
224                         if(a &  16) cmask[a]++;
225                         if(a &  32) cmask[a]++;
226                         if(a &  64) cmask[a]++;
227                         if(a & 128) cmask[a]++;
228                 }
229                 centmask= MEM_mallocN(65536, "Initfilt3");
230                 for(a=0; a<16; a++) {
231                         centLut[a]= -0.45+((float)a)/16.0;
232                 }
233
234                 gamtab= MEM_mallocN(65536*sizeof(short), "initGaus2");
235                 igamtab1= MEM_mallocN(256*sizeof(short), "initGaus2");
236                 igamtab2= MEM_mallocN(65536*sizeof(short), "initGaus2");
237
238         }
239
240         if(R.r.alphamode==R_ALPHAKEY) gamma= 1.0;       /* gamma correction of alpha is nasty */
241
242         if(R.r.mode & R_GAMMA) gamma= 2.0;
243         else gamma= 1.0;
244         igamma= 1.0/gamma;
245
246         if(gamma!= lastgamma) {
247                 lastgamma= gamma;
248
249                 /* gamtab: in short, out short */
250                 for(a=0; a<65536; a++) {
251                         val= a;
252                         val/= 65535.0;
253
254                         if(gamma==2.0) val= sqrt(val);
255                         else if(gamma!=1.0) val= pow(val, igamma);
256
257                         gamtab[a]= (65535.99*val);
258                 }
259                 /* inverse gamtab1 : in byte, out short */
260                 for(a=1; a<=256; a++) {
261                         if(gamma==2.0) igamtab1[a-1]= a*a-1;
262                         else if(gamma==1.0) igamtab1[a-1]= 256*a-1;
263                         else {
264                                 val= a/256.0;
265                                 igamtab1[a-1]= (65535.0*pow(val, gamma)) -1 ;
266                         }
267                 }
268
269                 /* inverse gamtab2 : in short, out short */
270                 for(a=0; a<65536; a++) {
271                         val= a;
272                         val/= 65535.0;
273                         if(gamma==2.0) val= val*val;
274                         else val= pow(val, gamma);
275
276                         igamtab2[a]= 65535.0*val;
277                 }
278         }
279
280         if(firsttime) {
281                 firsttime= 0;
282                 return;
283         }
284
285         val= 1.0/((float)R.osa);
286         for(a=0; a<256; a++) {
287                 fmask[a]= ((float)cmask[a])*val;
288         }
289
290         for(a=0; a<9;a++) {
291                 memset(mask1[a], 0, 256*2);
292                 memset(mask2[a], 0, 256*2);
293         }
294
295         /* calculate totw */
296         totw= 0.0;
297         for(j= -1; j<2; j++) {
298                 for(i= -1; i<2; i++) {
299                         totw+= calc_weight(weight, i, j);
300                 }
301         }
302
303         for(j= -1; j<2; j++) {
304                 for(i= -1; i<2; i++) {
305                         /* calculate using jit, with offset the weights */
306
307                         memset(weight, 0, 32*2);
308                         calc_weight(weight, i, j);
309
310                         for(a=0; a<16; a++) shweight[a]= weight[a]*(65535.0/totw);
311
312                         m1= mask1[ 3*(j+1)+i+1 ];
313                         m2= mask2[ 3*(j+1)+i+1 ];
314
315                         for(a=0; a<256; a++) {
316                                 if(a &   1) {
317                                         m1[a]+= shweight[0];
318                                         m2[a]+= shweight[8];
319                                 }
320                                 if(a &   2) {
321                                         m1[a]+= shweight[1];
322                                         m2[a]+= shweight[9];
323                                 }
324                                 if(a &   4) {
325                                         m1[a]+= shweight[2];
326                                         m2[a]+= shweight[10];
327                                 }
328                                 if(a &   8) {
329                                         m1[a]+= shweight[3];
330                                         m2[a]+= shweight[11];
331                                 }
332                                 if(a &  16) {
333                                         m1[a]+= shweight[4];
334                                         m2[a]+= shweight[12];
335                                 }
336                                 if(a &  32) {
337                                         m1[a]+= shweight[5];
338                                         m2[a]+= shweight[13];
339                                 }
340                                 if(a &  64) {
341                                         m1[a]+= shweight[6];
342                                         m2[a]+= shweight[14];
343                                 }
344                                 if(a & 128) {
345                                         m1[a]+= shweight[7];
346                                         m2[a]+= shweight[15];
347                                 }
348                         }
349                 }
350         }
351
352         /* centmask: the correct subpixel offset per mask */
353
354         fpx1= MEM_mallocN(256*sizeof(float), "initgauss4");
355         fpx2= MEM_mallocN(256*sizeof(float), "initgauss4");
356         fpy1= MEM_mallocN(256*sizeof(float), "initgauss4");
357         fpy2= MEM_mallocN(256*sizeof(float), "initgauss4");
358         for(a=0; a<256; a++) {
359                 fpx1[a]= fpx2[a]= 0.0;
360                 fpy1[a]= fpy2[a]= 0.0;
361                 if(a & 1) {
362                         fpx1[a]+= jit[0][0];
363                         fpy1[a]+= jit[0][1];
364                         fpx2[a]+= jit[8][0];
365                         fpy2[a]+= jit[8][1];
366                 }
367                 if(a & 2) {
368                         fpx1[a]+= jit[1][0];
369                         fpy1[a]+= jit[1][1];
370                         fpx2[a]+= jit[9][0];
371                         fpy2[a]+= jit[9][1];
372                 }
373                 if(a & 4) {
374                         fpx1[a]+= jit[2][0];
375                         fpy1[a]+= jit[2][1];
376                         fpx2[a]+= jit[10][0];
377                         fpy2[a]+= jit[10][1];
378                 }
379                 if(a & 8) {
380                         fpx1[a]+= jit[3][0];
381                         fpy1[a]+= jit[3][1];
382                         fpx2[a]+= jit[11][0];
383                         fpy2[a]+= jit[11][1];
384                 }
385                 if(a & 16) {
386                         fpx1[a]+= jit[4][0];
387                         fpy1[a]+= jit[4][1];
388                         fpx2[a]+= jit[12][0];
389                         fpy2[a]+= jit[12][1];
390                 }
391                 if(a & 32) {
392                         fpx1[a]+= jit[5][0];
393                         fpy1[a]+= jit[5][1];
394                         fpx2[a]+= jit[13][0];
395                         fpy2[a]+= jit[13][1];
396                 }
397                 if(a & 64) {
398                         fpx1[a]+= jit[6][0];
399                         fpy1[a]+= jit[6][1];
400                         fpx2[a]+= jit[14][0];
401                         fpy2[a]+= jit[14][1];
402                 }
403                 if(a & 128) {
404                         fpx1[a]+= jit[7][0];
405                         fpy1[a]+= jit[7][1];
406                         fpx2[a]+= jit[15][0];
407                         fpy2[a]+= jit[15][1];
408                 }
409         }
410
411         for(a= (1<<R.osa)-1; a>0; a--) {
412                 val= count_mask(a);
413                 i= 8+(15.9*(fpy1[a & 255]+fpy2[a>>8])/val);
414                 CLAMP(i, 0, 15);
415                 j= 8+(15.9*(fpx1[a & 255]+fpx2[a>>8])/val);
416                 CLAMP(j, 0, 15);
417                 i= j + (i<<4);
418                 centmask[a]= i;
419         }
420
421         MEM_freeN(fpx1);
422         MEM_freeN(fpx2);
423         MEM_freeN(fpy1);
424         MEM_freeN(fpy2);
425
426 }
427
428 void RE_free_filt_mask()
429 {
430         int a;
431
432         for(a=0; a<9; a++) {
433                 MEM_freeN(mask1[a]);
434                 MEM_freeN(mask2[a]);
435         }
436         MEM_freeN(gamtab);
437         MEM_freeN(igamtab1);
438         MEM_freeN(igamtab2);
439
440         MEM_freeN(centmask);
441 }
442
443 /* add stuff */
444
445
446 void defaultlamp()
447 {
448         LampRen *lar;
449
450         lar= (LampRen *)MEM_callocN(sizeof(LampRen),"lampren");
451         R.la[R.totlamp++]=lar;
452
453         lar->type= LA_SUN;
454         lar->vec[0]= -R.viewmat[2][0];
455         lar->vec[1]= -R.viewmat[2][1];
456         lar->vec[2]= -R.viewmat[2][2];
457         Normalise(lar->vec);
458         lar->r= 1.0;
459         lar->g= 1.0;
460         lar->b= 1.0;
461         lar->lay= 65535;
462 }
463
464
465 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
466
467 void RE_make_existing_file(char *name)
468 {
469         char di[FILE_MAXDIR], fi[FILE_MAXFILE];
470
471         strcpy(di, name);
472         BLI_splitdirstring(di, fi);
473
474         /* test exist */
475         if (BLI_exists(di) == 0) {
476                 BLI_recurdir_fileops(di);
477         }
478 }
479
480
481 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
482
483 void RE_setwindowclip(int mode, int jmode)
484 {
485         extern float bluroffsx, bluroffsy;      // rendercore.c... hackish (ton)
486         Camera *cam=0;
487         float lens, minx, miny, maxx, maxy;
488         float xd, yd, afmx, afmy;
489
490         if(G.scene->camera==0) return;
491
492         afmx= R.afmx;
493         afmy= R.afmy;
494
495         if(mode) {
496
497                 if(G.scene->camera->type==OB_LAMP) {
498                         /* fac= cos( PI*((float)(256- la->spsi))/512.0 ); */
499
500                         /* phi= acos(fac); */
501                         /* lens= 16.0*fac/sin(phi); */
502                         lens= 35.0;
503                         R.near= 0.1;
504                         R.far= 1000.0;
505                 }
506                 else if(G.scene->camera->type==OB_CAMERA) {
507                         cam= G.scene->camera->data;
508
509                         lens= cam->lens;
510                         R.near= cam->clipsta;
511                         R.far= cam->clipend;
512                 }
513                 else {
514                         lens= 16.0;
515                 }
516
517                 if( (R.r.xasp*afmx) >= (R.r.yasp*afmy) ) {
518                         R.viewfac= (afmx*lens)/16.0;
519                 }
520                 else {
521                         R.viewfac= R.ycor*(afmy*lens)/16.0;
522                 }
523                 if(R.r.mode & R_ORTHO) {
524                         R.near*= 100.0; 
525                         R.viewfac*= 100.0;
526                 }
527
528                 R.pixsize= R.near/R.viewfac;
529
530         }
531
532         /* revision / simplification of subpixel offsets:
533            - the matrix will go without offset from start (e.g. -100) to end (e.g. +99).
534            - filling in with zbuffer will set offset of 0.5. to make sure clipped faces fill in too
535            - in shadepixel() again that 0.5 offset is corrected
536         */
537         minx= R.xstart; 
538         miny= R.ycor*(R.ystart); 
539         maxx= R.xend; 
540         maxy= R.ycor*(R.yend); 
541            
542         if(R.flag & R_SEC_FIELD) {
543                 if(R.r.mode & R_ODDFIELD) {
544                         miny-= .5*R.ycor;
545                         maxy-= .5*R.ycor;
546                 }
547                 else {
548                         miny+= .5*R.ycor;
549                         maxy+= .5*R.ycor;
550                 }
551         }
552
553         xd= yd= 0.0;
554         if(jmode!= -1) {
555                 bluroffsx= xd= jit[jmode % R.osa][0];
556                 bluroffsy= yd= R.ycor*jit[jmode % R.osa][1];
557         }
558         else bluroffsx=bluroffsy= 0.0;
559
560         minx= R.pixsize*(minx+xd);
561         maxx= R.pixsize*(maxx+xd);
562         miny= R.pixsize*(miny+yd);
563         maxy= R.pixsize*(maxy+yd);
564
565         if(R.r.mode & R_ORTHO) {
566                 i_window(minx, maxx, miny, maxy, R.near, 100.0*R.far, R.winmat);
567         }
568         else i_window(minx, maxx, miny, maxy, R.near, R.far, R.winmat);
569
570 }
571
572
573 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
574 void initparts()
575 {
576         short nr, xd, yd, xpart, ypart, xparts, yparts;
577         short a, xminb, xmaxb, yminb, ymaxb;
578
579         if(R.r.mode & R_BORDER) {
580                 xminb= R.r.border.xmin*R.rectx;
581                 xmaxb= R.r.border.xmax*R.rectx;
582
583                 yminb= R.r.border.ymin*R.recty;
584                 ymaxb= R.r.border.ymax*R.recty;
585
586                 if(xminb<0) xminb= 0;
587                 if(xmaxb>R.rectx) xmaxb= R.rectx;
588                 if(yminb<0) yminb= 0;
589                 if(ymaxb>R.recty) ymaxb= R.recty;
590         }
591         else {
592                 xminb=yminb= 0;
593                 xmaxb= R.rectx;
594                 ymaxb= R.recty;
595         }
596
597         xparts= R.r.xparts;     /* for border */
598         yparts= R.r.yparts;
599
600         for(nr=0;nr<xparts*yparts;nr++)
601                 allparts[nr][0]= -1;    /* clear array */
602
603         xpart= R.rectx/xparts;
604         ypart= R.recty/yparts;
605
606         /* if border: test if amount of parts can be fewer */
607         if(R.r.mode & R_BORDER) {
608                 a= (xmaxb-xminb-1)/xpart+1; /* amount of parts in border */
609                 if(a<xparts) xparts= a;
610                 a= (ymaxb-yminb-1)/ypart+1; /* amount of parts in border */
611                 if(a<yparts) yparts= a;
612
613                 xpart= (xmaxb-xminb)/xparts;
614                 ypart= (ymaxb-yminb)/yparts;
615         }
616
617         for(nr=0; nr<xparts*yparts; nr++) {
618
619                 if(R.r.mode & R_PANORAMA) {
620                         allparts[nr][0]= 0;
621                         allparts[nr][1]= 0;
622                         allparts[nr][2]= R.rectx;
623                         allparts[nr][3]= R.recty;
624                 }
625                 else {
626                         xd= (nr % xparts);
627                         yd= (nr-xd)/xparts;
628
629                         allparts[nr][0]= xminb+ xd*xpart;
630                         allparts[nr][1]= yminb+ yd*ypart;
631                         if(xd<R.r.xparts-1) allparts[nr][2]= allparts[nr][0]+xpart;
632                         else allparts[nr][2]= xmaxb;
633                         if(yd<R.r.yparts-1) allparts[nr][3]= allparts[nr][1]+ypart;
634                         else allparts[nr][3]= ymaxb;
635
636                         if(allparts[nr][2]-allparts[nr][0]<=0) allparts[nr][0]= -1;
637                         if(allparts[nr][3]-allparts[nr][1]<=0) allparts[nr][0]= -1;
638                 }
639         }
640 }
641
642 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
643 short setpart(short nr) /* return 0 if incorrect part */
644 {
645
646         if(allparts[nr][0]== -1) return 0;
647
648         R.xstart= allparts[nr][0]-R.afmx;
649         R.ystart= allparts[nr][1]-R.afmy;
650         R.xend= allparts[nr][2]-R.afmx;
651         R.yend= allparts[nr][3]-R.afmy;
652         R.rectx= R.xend-R.xstart;
653         R.recty= R.yend-R.ystart;
654
655         return 1;
656 }
657
658 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
659 void addparttorect(short nr, Part *part)
660 {
661         unsigned int *rt, *rp;
662         short y, heigth, len;
663
664         /* the right offset in rectot */
665
666         rt= R.rectot+ (allparts[nr][1]*R.rectx+ allparts[nr][0]);
667         rp= part->rect;
668         len= (allparts[nr][2]-allparts[nr][0]);
669         heigth= (allparts[nr][3]-allparts[nr][1]);
670
671         for(y=0;y<heigth;y++) {
672                 memcpy(rt, rp, 4*len);
673                 rt+=R.rectx;
674                 rp+= len;
675         }
676 }
677
678
679 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
680
681  
682 void add_to_blurbuf(int blur)
683 {
684         static unsigned int *blurrect= 0;
685         int tot, gamval;
686         short facr, facb;
687         char *rtr, *rtb;
688
689         if(blur<0) {
690                 if(blurrect) {
691                         if(R.rectot) MEM_freeN(R.rectot);
692                         R.rectot= blurrect;
693                         blurrect= 0;
694                 }
695         }
696         else if(blur==R.osa-1) {
697                 /* first time */
698                 blurrect= MEM_mallocN(R.rectx*R.recty*sizeof(int), "rectblur");
699                 if(R.rectot) memcpy(blurrect, R.rectot, R.rectx*R.recty*4);
700         }
701         else if(blurrect) {
702                 /* accumulate */
703
704                 facr= 256/(R.osa-blur);
705                 facb= 256-facr;
706
707                 if(R.rectot) {
708                         rtr= (char *)R.rectot;
709                         rtb= (char *)blurrect;
710                         tot= R.rectx*R.recty;
711                         while(tot--) {
712                                 if( *((unsigned int *)rtb) != *((unsigned int *)rtr) ) {
713
714                                         if(R.r.mode & R_GAMMA) {
715                                                 gamval= (facr* igamtab2[ rtr[0]<<8 ] + facb* igamtab2[ rtb[0]<<8 ])>>8;
716                                                 rtb[0]= gamtab[ gamval ]>>8;
717                                                 gamval= (facr* igamtab2[ rtr[1]<<8 ] + facb* igamtab2[ rtb[1]<<8 ])>>8;
718                                                 rtb[1]= gamtab[ gamval ]>>8;
719                                                 gamval= (facr* igamtab2[ rtr[2]<<8 ] + facb* igamtab2[ rtb[2]<<8 ])>>8;
720                                                 rtb[2]= gamtab[ gamval ]>>8;
721                                                 gamval= (facr* igamtab2[ rtr[3]<<8 ] + facb* igamtab2[ rtb[3]<<8 ])>>8;
722                                                 rtb[3]= gamtab[ gamval ]>>8;
723                                         }
724                                         else {
725                                                 rtb[0]= (facr*rtr[0] + facb*rtb[0])>>8;
726                                                 rtb[1]= (facr*rtr[1] + facb*rtb[1])>>8;
727                                                 rtb[2]= (facr*rtr[2] + facb*rtb[2])>>8;
728                                                 rtb[3]= (facr*rtr[3] + facb*rtb[3])>>8;
729                                         }
730                                 }
731                                 rtr+= 4;
732                                 rtb+= 4;
733                         }
734                 }
735                 if(blur==0) {
736                         /* last time */
737                         if(R.rectot) MEM_freeN(R.rectot);
738                         R.rectot= blurrect;
739                         blurrect= 0;
740                 }
741         }
742 }
743
744
745 /* yafray: main yafray render/export call */
746 void yafrayRender()
747 {
748         R.flag |= R_RENDERING;  /* !!! */
749         printf("Starting scene conversion.\n");
750         prepareScene();
751         printf("Scene conversion done.\n");
752         if(!R.r.YFexportxml)
753                 YAF_switchFile();
754         else
755                 YAF_switchPlugin();
756         YAF_exportScene();
757         finalizeScene();
758 }
759
760
761 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
762 void render() {
763         /* yafray: render, see above */
764         if (R.r.renderer==R_YAFRAY)
765                 yafrayRender();
766         else {
767                 /* not too neat... should improve... */
768                 //if(R.r.mode & R_UNIFIED) {
769                 //      unifiedRenderingLoop();
770                 //} else {
771                         oldRenderLoop();
772                 //}
773         }
774 }
775
776
777 void oldRenderLoop(void)  /* here the PART and FIELD loops */
778 {
779         Part *part;
780         unsigned int *rt, *rt1, *rt2;
781         int len, y;
782         short blur, a,fields,fi,parts;  /* pa is a global because of print */
783
784         if (R.rectz) MEM_freeN(R.rectz);
785         R.rectz = 0;
786
787         /* FIELD LOOP */
788         fields= 1;
789         parts= R.r.xparts*R.r.yparts;
790
791         if(R.r.mode & R_FIELDS) {
792                 fields= 2;
793                 R.rectf1= R.rectf2= 0;  /* field rects */
794                 R.r.ysch/= 2;
795                 R.afmy/= 2;
796                 R.r.yasp*= 2;
797                 R.ycor= ( (float)R.r.yasp)/( (float)R.r.xasp);
798
799         }
800
801         
802         for(fi=0; fi<fields; fi++) {
803
804                 /* INIT */
805                 BLI_srand( 2*(G.scene->r.cfra)+fi);
806                         
807                 R.flag|= R_RENDERING;
808                 if(fi==1) R.flag |= R_SEC_FIELD;
809         
810                 /* MOTIONBLUR loop */
811                 if(R.r.mode & R_MBLUR) blur= R.osa;
812                 else blur= 1;
813                 while(blur--) {
814
815                         /* WINDOW */
816                         R.rectx= R.r.xsch;
817                         R.recty= R.r.ysch;
818                         R.xstart= -R.afmx;
819                         R.ystart= -R.afmy;
820                         R.xend= R.xstart+R.rectx-1;
821                         R.yend= R.ystart+R.recty-1;
822
823
824                         if(R.r.mode & R_MBLUR) set_mblur_offs(R.osa-blur);
825
826                         initparts(); /* always do, because of border */
827                         setpart(0);
828
829                         RE_local_init_render_display();
830                         RE_local_clear_render_display(R.win);
831                         RE_local_timecursor((G.scene->r.cfra));
832
833                         prepareScene();
834
835                         /* PARTS */
836                         R.parts.first= R.parts.last= 0;
837                         for(pa=0; pa<parts; pa++) {
838
839                                 if(RE_local_test_break()) break;
840
841                                 if(pa) {        /* because case pa==0 has been done */
842                                         if(setpart(pa)==0) break;
843                                 }
844
845                                 if(R.r.mode & R_MBLUR) RE_setwindowclip(0, blur);
846                                 else RE_setwindowclip(0,-1);
847
848                                 if(R.r.mode & R_PANORAMA) setPanoRot(pa);
849
850                                 /* HOMOGENIC COORDINATES AND ZBUF AND CLIP OPTIMISATION (per part) */
851                                 /* There may be some interference with z-coordinate    */
852                                 /* calculation here?                                   */
853
854                                 doClipping(RE_projectverto);
855                                 if(RE_local_test_break()) break;
856
857
858                                 /* rectot is for result and integer face indices */
859                                 R.rectot= (unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot");
860                                 
861                                 if(R.r.mode & R_MBLUR) {
862                                         RE_local_printrenderinfo(0.0, R.osa - blur);
863                                         if(G.background && blur<R.osa) printf("\n"); // newline for percentage print
864                                 }
865                                 else RE_local_printrenderinfo(0.0, -1);
866
867                                 if(R.r.mode & R_UNIFIED) {
868                                         zBufShadeAdvanced();
869                                 }
870                                 else {
871                                         R.rectz =  (unsigned int *)MEM_mallocN(sizeof(int)*R.rectx*R.recty, "rectz");
872
873                                         if(R.r.mode & R_OSA) zbufshadeDA();
874                                         else zbufshade();
875                                 }
876                                 
877                                 if(RE_local_test_break()) break;
878
879                                 /* exception */
880                                 if( (R.r.mode & R_BORDER) && (R.r.mode & R_MOVIECROP));
881                                 else {
882                                         /* HANDLE PART OR BORDER */
883                                         if(parts>1 || (R.r.mode & R_BORDER)) {
884
885                                                 part= MEM_callocN(sizeof(Part), "part");
886                                                 BLI_addtail(&R.parts, part);
887                                                 part->rect= R.rectot;
888                                                 R.rectot= NULL;
889
890                                                 if (R.rectz) {
891                                                         MEM_freeN(R.rectz);
892                                                         R.rectz= NULL;
893                                                 }
894                                         }
895                                 }
896                         }
897
898                         /* JOIN PARTS OR INSERT BORDER */
899
900                         /* exception: crop */
901                         if( (R.r.mode & R_BORDER) && (R.r.mode & R_MOVIECROP)) ;
902                         else {
903                                 R.rectx= R.r.xsch;
904                                 R.recty= R.r.ysch;
905
906                                 if(R.r.mode & R_PANORAMA) R.rectx*= R.r.xparts;
907
908                                 if(parts>1 || (R.r.mode & R_BORDER)) {
909                                         if(R.rectot) MEM_freeN(R.rectot);
910                                         
911                                         R.rectot=(unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot");
912                                         
913                                         part= R.parts.first;
914                                         for(pa=0; pa<parts; pa++) {
915                                                 if(allparts[pa][0]== -1) break;
916                                                 if(part==0) break;
917                                                 
918                                                 if(R.r.mode & R_PANORAMA) {
919                                                         if(pa) {
920                                                                 allparts[pa][0] += pa*R.r.xsch;
921                                                                 allparts[pa][2] += pa*R.r.xsch;
922                                                         }
923                                                 }
924                                                 addparttorect(pa, part);
925                                                 
926                                                 part= part->next;
927                                         }
928                                         
929                                         part= R.parts.first;
930                                         while(part) {
931                                                 MEM_freeN(part->rect);
932                                                 part= part->next;
933                                         }
934                                         BLI_freelistN(&R.parts);
935                                 }
936                         }
937
938                         if( (R.flag & R_HALO)) {
939                                 if(RE_local_test_break()==0) add_halo_flare();
940                         }
941
942                         if(R.r.mode & R_MBLUR) {
943                                 add_to_blurbuf(blur);
944                         }
945
946                         /* END (blur loop) */
947                         finalizeScene();
948
949                         if(RE_local_test_break()) break;
950                 }
951
952                 /* definite free */
953                 add_to_blurbuf(-1);
954
955                 /* HANDLE FIELD */
956                 if(R.r.mode & R_FIELDS) {
957                         if(R.flag & R_SEC_FIELD) R.rectf2= R.rectot;
958                         else R.rectf1= R.rectot;
959                         R.rectot= 0;
960                 }
961
962                 if(RE_local_test_break()) break;
963         }
964
965         /* JOIN FIELDS */
966         if(R.r.mode & R_FIELDS) {
967                 R.r.ysch*= 2;
968                 R.afmy*= 2;
969                 R.recty*= 2;
970                 R.r.yasp/=2;
971
972                 if(R.rectot) MEM_freeN(R.rectot);       /* happens when a render has been stopped */
973                 R.rectot=(unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot");
974
975                 if(RE_local_test_break()==0) {
976                         rt= R.rectot;
977
978                         if(R.r.mode & R_ODDFIELD) {
979                                 rt2= R.rectf1;
980                                 rt1= R.rectf2;
981                         }
982                         else {
983                                 rt1= R.rectf1;
984                                 rt2= R.rectf2;
985                         }
986
987                         len= 4*R.rectx;
988
989                         for(a=0; a<R.recty; a+=2) {
990                                 memcpy(rt, rt1, len);
991                                 rt+= R.rectx;
992                                 rt1+= R.rectx;
993                                 memcpy(rt, rt2, len);
994                                 rt+= R.rectx;
995                                 rt2+= R.rectx;
996                         }
997                 }
998         }
999
1000         /* R.rectx= R.r.xsch; */
1001         /* if(R.r.mode & R_PANORAMA) R.rectx*= R.r.xparts; */
1002         /* R.recty= R.r.ysch; */
1003
1004         /* if border: still do skybuf */
1005         if(R.r.mode & R_BORDER) {
1006                 if( (R.r.mode & R_MOVIECROP)==0) {
1007                         if(R.r.bufflag & 1) {
1008                                 R.xstart= -R.afmx;
1009                                 R.ystart= -R.afmy;
1010                                 rt= R.rectot;
1011                                 for(y=0; y<R.recty; y++, rt+= R.rectx) scanlinesky((char *)rt, y);
1012                         }
1013                 }
1014         }
1015
1016         set_mblur_offs(0);
1017
1018         /* FREE */
1019
1020         /* zbuf test */
1021
1022         /* don't free R.rectz, only when its size is not the same as R.rectot */
1023
1024         if (R.rectz && parts == 1 && (R.r.mode & R_FIELDS) == 0);
1025         else {
1026                 if(R.rectz) MEM_freeN(R.rectz);
1027                 R.rectz= 0;
1028         }
1029
1030         if(R.rectf1) MEM_freeN(R.rectf1);
1031         R.rectf1= 0;
1032         if(R.rectf2) MEM_freeN(R.rectf2);
1033         R.rectf2= 0;
1034 }
1035
1036
1037
1038 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
1039 extern unsigned short usegamtab;
1040 void RE_initrender(struct View3D *ogl_render_view3d)
1041 {
1042         double start_time;
1043         Image *bima;
1044         char name[256];
1045         
1046         /* scene data to R */
1047         R.r= G.scene->r;
1048         R.r.postigamma= 1.0/R.r.postgamma;
1049         
1050         /* WINDOW size (sch='scherm' dutch for screen...) */
1051         R.r.xsch= (R.r.size*R.r.xsch)/100;
1052         R.r.ysch= (R.r.size*R.r.ysch)/100;
1053
1054         R.afmx= R.r.xsch/2;
1055         R.afmy= R.r.ysch/2;
1056
1057         /* to be sure: when a premature return (rectx can differ from xsch) */
1058         R.rectx= R.r.xsch;
1059         R.recty= R.r.ysch;
1060
1061         /* IS RENDERING ALLOWED? */
1062
1063         /* forbidden combination */
1064         if((R.r.mode & R_BORDER) && (R.r.mode & R_PANORAMA)) {
1065                 error("No border allowed for Panorama");
1066                 G.afbreek= 1;
1067                 return;
1068         }
1069
1070         
1071         if(R.r.xparts*R.r.yparts>64) {
1072                 error("No more than 64 parts");
1073                 G.afbreek= 1;
1074                 return;
1075         }
1076
1077         if(R.r.yparts>1 && (R.r.mode & R_PANORAMA)) {
1078                 error("No Y-Parts allowed for Panorama");
1079                 G.afbreek= 1;
1080                 return;
1081         }
1082
1083
1084         /* TEST BACKBUF */
1085         /* If an image is specified for use as backdrop, that image is loaded    */
1086         /* here.                                                                 */
1087         if((R.r.bufflag & 1) && (G.scene->r.scemode & R_OGL)==0) {
1088                 if(R.r.alphamode == R_ADDSKY) {
1089                         strcpy(name, R.r.backbuf);
1090                         BLI_convertstringcode(name, G.sce, G.scene->r.cfra);
1091
1092                         if(R.backbuf) {
1093                                 R.backbuf->id.us--;
1094                                 bima= R.backbuf;
1095                         }
1096                         else bima= 0;
1097
1098                         R.backbuf= add_image(name);
1099
1100                         if(bima && bima->id.us<1) {
1101                                 free_image_buffers(bima);
1102                         }
1103                         if(R.backbuf==0) {
1104                                 // error() doesnt work with render window open
1105                                 //error("No backbuf there!");
1106                                 printf("Error: No backbuf %s\n", name);
1107                                 G.afbreek= 1;
1108                                 return;
1109                         }
1110                 }
1111         }
1112
1113
1114         usegamtab= 0; /* see also further */
1115
1116         if(R.r.mode & (R_OSA|R_MBLUR)) {
1117                 R.osa= R.r.osa;
1118                 if(R.osa>16) R.osa= 16;
1119
1120                 init_render_jit(R.osa);
1121                 RE_init_filt_mask();
1122
1123                 /* this value sometimes is reset temporally, for example in transp zbuf */
1124                 if(R.r.mode & R_GAMMA) {
1125                         if((R.r.mode & R_OSA)) usegamtab= 1;
1126                 }
1127         }
1128         else R.osa= 0;
1129
1130         /* when rendered without camera object */
1131         /* it has to done here because of envmaps */
1132         R.near= 0.1;
1133         R.far= 1000.0;
1134
1135
1136         if(R.afmx<1 || R.afmy<1) {
1137                 error("Image too small");
1138                 return;
1139         }
1140         R.ycor= ( (float)R.r.yasp)/( (float)R.r.xasp);
1141
1142         start_time= PIL_check_seconds_timer();
1143
1144         if(R.r.scemode & R_DOSEQ) {
1145                 R.rectx= R.r.xsch;
1146                 R.recty= R.r.ysch;
1147
1148                 if(R.rectot) MEM_freeN(R.rectot);
1149                 R.rectot= (unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot");
1150
1151                 RE_local_timecursor((G.scene->r.cfra));
1152
1153                 if(RE_local_test_break()==0) do_render_seq();
1154
1155                 /* display */
1156                 if(R.rectot) RE_local_render_display(0, R.recty-1,
1157                                                                                          R.rectx, R.recty,
1158                                                                                          R.rectot);
1159         }
1160         else if(R.r.scemode & R_OGL) {
1161                 R.rectx= R.r.xsch;
1162                 R.recty= R.r.ysch;
1163
1164                 if(R.rectot) MEM_freeN(R.rectot);
1165                 R.rectot= (unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot");
1166
1167                 RE_local_init_render_display();
1168                 drawview3d_render(ogl_render_view3d);
1169         }
1170         else {
1171                 if(G.scene->camera==0) {
1172                         G.scene->camera= scene_find_camera(G.scene);
1173                 }
1174
1175                 if(G.scene->camera==0) {
1176                         error("No camera");
1177                         G.afbreek=1;
1178                         return;
1179                 }
1180                 else {
1181
1182                         if(G.scene->camera->type==OB_CAMERA) {
1183                                 Camera *cam= G.scene->camera->data;
1184                                 if(cam->type==CAM_ORTHO) R.r.mode |= R_ORTHO;
1185                         }
1186
1187                         render(); /* returns with complete rect xsch-ysch */
1188                 }
1189         }
1190
1191         /* display again: fields/seq/parts/pano etc */
1192         if(R.rectot) {
1193                 RE_local_init_render_display();
1194                 RE_local_render_display(0, R.recty-1,
1195                                                                 R.rectx, R.recty,
1196                                                                 R.rectot);
1197         }
1198         else RE_local_clear_render_display(R.win);
1199
1200         RE_local_printrenderinfo((PIL_check_seconds_timer() - start_time), -1);
1201         
1202         /* restore variables */
1203         //R.osatex= 0;
1204         //R.vlr= 0;     
1205         ///* at cubemap */
1206         R.flag= 0;
1207 }
1208
1209 void RE_animrender(struct View3D *ogl_render_view3d)
1210 {
1211         int cfrao;
1212         char name[256];
1213
1214         if(G.scene==0) return;
1215
1216         /* scenedata to R: (for backbuf, R.rectx etc) */
1217         R.r= G.scene->r;
1218
1219         /* START ANIMLOOP, everywhere NOT the cfra from R.r is gebruikt: because of rest blender */
1220         cfrao= (G.scene->r.cfra);
1221
1222         if(G.scene->r.scemode & R_OGL) R.r.mode &= ~R_PANORAMA;
1223         
1224         // these calculations apply for
1225         // all movie formats
1226         R.rectx= (R.r.size*R.r.xsch)/100;
1227         R.recty= (R.r.size*R.r.ysch)/100;
1228         if(R.r.mode & R_PANORAMA) {
1229                 R.rectx*= R.r.xparts;
1230                 R.recty*= R.r.yparts;
1231         }
1232
1233         if (0) {
1234 #ifdef __sgi
1235         } else if (R.r.imtype==R_MOVIE) {
1236                 start_movie();
1237 #endif
1238 #if defined(_WIN32) && !defined(FREE_WINDOWS)
1239         } else if (R.r.imtype == R_AVICODEC) {
1240                 start_avi_codec();
1241 #endif
1242 #if WITH_QUICKTIME
1243         } else if (R.r.imtype == R_QUICKTIME) {
1244                 start_qt();
1245 #endif
1246         } else if ELEM4(R.r.imtype, R_AVIRAW, R_AVIJPEG, R_MOVIE, R_AVICODEC) {
1247                 if ELEM(R.r.imtype, R_MOVIE, R_AVICODEC) {
1248                         printf("Selected movie format not supported on this platform,\nusing RAW AVI instead\n");
1249                 }
1250                 start_avi();
1251         }
1252
1253         for((G.scene->r.cfra)=(G.scene->r.sfra); (G.scene->r.cfra)<=(G.scene->r.efra); (G.scene->r.cfra)++) {
1254                 double starttime= PIL_check_seconds_timer();
1255
1256                 R.flag= R_ANIMRENDER;
1257
1258                 RE_initrender(ogl_render_view3d);
1259                 
1260                 /* WRITE IMAGE */
1261                 if(RE_local_test_break()==0) {
1262
1263                         if (0) {
1264 #ifdef __sgi
1265                         } else if (R.r.imtype == R_MOVIE) {
1266                                 append_movie((G.scene->r.cfra));
1267 #endif
1268 #if defined(_WIN32) && !defined(FREE_WINDOWS)
1269                         } else if (R.r.imtype == R_AVICODEC) {
1270                                 append_avi_codec((G.scene->r.cfra));
1271 #endif
1272 #ifdef WITH_QUICKTIME
1273                         } else if (R.r.imtype == R_QUICKTIME) {
1274                                 append_qt((G.scene->r.cfra));
1275 #endif
1276                         } else if ELEM4(R.r.imtype, R_AVIRAW, R_AVIJPEG, R_MOVIE, R_AVICODEC) {
1277                                 append_avi((G.scene->r.cfra));
1278                         } else {
1279                                 makepicstring(name, (G.scene->r.cfra));
1280                                 schrijfplaatje(name);
1281                                 if(RE_local_test_break()==0) printf("Saved: %s", name);
1282                         }
1283
1284                         timestr(PIL_check_seconds_timer()-starttime, name);
1285                         printf(" Time: %s\n", name);
1286                         fflush(stdout); /* needed for renderd !! */
1287                 }
1288
1289                 if(G.afbreek==1) break;
1290
1291         }
1292
1293         (G.scene->r.cfra)= cfrao;
1294
1295         /* restore time */
1296         if(R.r.mode & (R_FIELDS|R_MBLUR)) {
1297                 do_all_ipos();
1298                 do_all_keys();
1299                 do_all_actions();
1300                 do_all_ikas();
1301         }
1302
1303         if (0) {
1304 #ifdef __sgi    
1305         } else if (R.r.imtype==R_MOVIE) {
1306                 end_movie();
1307 #endif
1308 #if defined(_WIN32) && !defined(FREE_WINDOWS)
1309         } else if (R.r.imtype == R_AVICODEC) {
1310                 end_avi_codec();
1311 #endif
1312 #ifdef WITH_QUICKTIME
1313         } else if (R.r.imtype == R_QUICKTIME) {
1314                 end_qt();
1315 #endif
1316         } else if ELEM4(R.r.imtype, R_AVIRAW, R_AVIJPEG, R_MOVIE, R_AVICODEC) {
1317                 end_avi();
1318         }
1319 }
1320
1321 /* *************************************************** */
1322 /* ******************* Screendumps ******************** */
1323 /* moved to the windowControl thing */