Small fixes;
[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 #include "IMB_imbuf_types.h"
86 #include "IMB_imbuf.h"
87
88 #ifdef WITH_QUICKTIME
89 #include "quicktime_export.h"
90 #endif
91
92 #include "SDL_thread.h"
93
94 /* this module */
95 #include "render.h"
96
97 #include "RE_callbacks.h"
98 #include "zbuf.h"
99 #include "rendercore.h" /* part handler for the old renderer, shading functions */
100 #include "pixelshading.h"
101 #include "renderPreAndPost.h"
102 #include "vanillaRenderPipe.h"
103 #include "renderHelp.h"
104 #include "jitter.h"
105 #include "gammaCorrectionTables.h"
106
107 /* Own includes */
108 #include "initrender.h"
109
110 /* yafray: include for yafray export/render */
111 #include "YafRay_Api.h"
112
113
114 float centLut[16], *fmask1[9], *fmask2[9];
115 unsigned short *gamtab, *igamtab2, *igamtab1;
116 char cmask[256], *centmask;
117
118 Material defmaterial;
119
120 /* ****************** GAMMA, MASKS and LUTS **************** */
121
122 static float calc_weight(float *weight, int i, int j)
123 {
124         float x, y, dist, totw= 0.0, fac;
125         int a;
126
127         fac= R.r.gauss*R.r.gauss;
128         fac*= fac;
129
130         for(a=0; a<R.osa; a++) {
131                 x= jit[a][0] + i;
132                 y= jit[a][1] + j;
133                 dist= sqrt(x*x+y*y);
134
135                 weight[a]= 0.0;
136
137                 /* gaussian weighting */
138                 if(R.r.mode & R_GAUSS) {
139                         if(dist<R.r.gauss) {
140                                 x = dist*R.r.gauss;
141                                 weight[a]= (1.0/exp(x*x) - 1.0/exp(fac));
142                         }
143                 }
144                 else {
145                         if(i==0 && j==0) weight[a]= 1.0;
146                 }
147
148                 totw+= weight[a];
149
150         }
151         return totw;
152 }
153
154 static void init_filt_mask(void)
155 {
156         static int firsttime=1;
157         static int lastosa=0;
158         static int lastgauss=0;
159         static float lastgamma= 0.0;
160         float gamma, igamma, flweight[32], fmask[256];
161         float weight[32], totw, val, *fpx1, *fpx2, *fpy1, *fpy2, *m3, *m4;
162         int i, j, a;
163
164         if(firsttime) {
165                 firsttime= 0;
166                 
167                 for(a=0; a<9;a++) {
168                         fmask1[a]= MEM_mallocN(256*sizeof(float), "initfilt");
169                         fmask2[a]= MEM_mallocN(256*sizeof(float), "initfilt");
170                 }
171                 for(a=0; a<256; a++) {
172                         cmask[a]= 0;
173                         if(a &   1) cmask[a]++;
174                         if(a &   2) cmask[a]++;
175                         if(a &   4) cmask[a]++;
176                         if(a &   8) cmask[a]++;
177                         if(a &  16) cmask[a]++;
178                         if(a &  32) cmask[a]++;
179                         if(a &  64) cmask[a]++;
180                         if(a & 128) cmask[a]++;
181                 }
182                 centmask= MEM_mallocN(65536, "Initfilt3");
183                 for(a=0; a<16; a++) {
184                         centLut[a]= -0.45+((float)a)/16.0;
185                 }
186
187                 gamtab= MEM_mallocN(65536*sizeof(short), "initGaus2");
188                 igamtab1= MEM_mallocN(256*sizeof(short), "initGaus2");
189                 igamtab2= MEM_mallocN(65536*sizeof(short), "initGaus2");
190                 
191                 return; // this case is called on startup
192         }
193
194         if(R.r.alphamode==R_ALPHAKEY) gamma= 1.0;       /* gamma correction of alpha is nasty */
195
196         if(R.r.mode & R_GAMMA) gamma= 2.0;
197         else gamma= 1.0;
198         igamma= 1.0/gamma;
199
200         if(gamma!= lastgamma) {
201                 lastgamma= gamma;
202
203                 /* gamtab: in short, out short */
204                 for(a=0; a<65536; a++) {
205                         val= a;
206                         val/= 65535.0;
207
208                         if(gamma==2.0) val= sqrt(val);
209                         else if(gamma!=1.0) val= pow(val, igamma);
210
211                         gamtab[a]= (65535.99*val);
212                 }
213                 /* inverse gamtab1 : in byte, out short */
214                 for(a=1; a<=256; a++) {
215                         if(gamma==2.0) igamtab1[a-1]= a*a-1;
216                         else if(gamma==1.0) igamtab1[a-1]= 256*a-1;
217                         else {
218                                 val= a/256.0;
219                                 igamtab1[a-1]= (65535.0*pow(val, gamma)) -1 ;
220                         }
221                 }
222
223                 /* inverse gamtab2 : in short, out short */
224                 for(a=0; a<65536; a++) {
225                         val= a;
226                         val/= 65535.0;
227                         if(gamma==2.0) val= val*val;
228                         else val= pow(val, gamma);
229
230                         igamtab2[a]= 65535.0*val;
231                 }
232         }
233
234         if(R.osa && (lastosa!=R.osa || lastgauss != (R.r.mode & R_GAUSS)) ) {
235                 lastosa= R.osa;
236                 lastgauss= R.r.mode & R_GAUSS;
237                         
238                 val= 1.0/((float)R.osa);
239                 for(a=0; a<256; a++) {
240                         fmask[a]= ((float)cmask[a])*val;
241                 }
242
243                 for(a=0; a<9;a++) {
244                         memset(fmask1[a], 0, 256*sizeof(float));
245                         memset(fmask2[a], 0, 256*sizeof(float));
246                 }
247
248                 /* calculate totw */
249                 totw= 0.0;
250                 for(j= -1; j<2; j++) {
251                         for(i= -1; i<2; i++) {
252                                 totw+= calc_weight(weight, i, j);
253                         }
254                 }
255
256                 for(j= -1; j<2; j++) {
257                         for(i= -1; i<2; i++) {
258                                 /* calculate using jit, with offset the weights */
259
260                                 memset(weight, 0, sizeof(weight));
261                                 calc_weight(weight, i, j);
262
263                                 for(a=0; a<16; a++) flweight[a]= weight[a]*(1.0/totw);
264
265                                 m3= fmask1[ 3*(j+1)+i+1 ];
266                                 m4= fmask2[ 3*(j+1)+i+1 ];
267
268                                 for(a=0; a<256; a++) {
269                                         if(a &   1) {
270                                                 m3[a]+= flweight[0];
271                                                 m4[a]+= flweight[8];
272                                         }
273                                         if(a &   2) {
274                                                 m3[a]+= flweight[1];
275                                                 m4[a]+= flweight[9];
276                                         }
277                                         if(a &   4) {
278                                                 m3[a]+= flweight[2];
279                                                 m4[a]+= flweight[10];
280                                         }
281                                         if(a &   8) {
282                                                 m3[a]+= flweight[3];
283                                                 m4[a]+= flweight[11];
284                                         }
285                                         if(a &  16) {
286                                                 m3[a]+= flweight[4];
287                                                 m4[a]+= flweight[12];
288                                         }
289                                         if(a &  32) {
290                                                 m3[a]+= flweight[5];
291                                                 m4[a]+= flweight[13];
292                                         }
293                                         if(a &  64) {
294                                                 m3[a]+= flweight[6];
295                                                 m4[a]+= flweight[14];
296                                         }
297                                         if(a & 128) {
298                                                 m3[a]+= flweight[7];
299                                                 m4[a]+= flweight[15];
300                                         }
301                                 }
302                         }
303                 }
304
305                 /* centmask: the correct subpixel offset per mask */
306
307                 fpx1= MEM_mallocN(256*sizeof(float), "initgauss4");
308                 fpx2= MEM_mallocN(256*sizeof(float), "initgauss4");
309                 fpy1= MEM_mallocN(256*sizeof(float), "initgauss4");
310                 fpy2= MEM_mallocN(256*sizeof(float), "initgauss4");
311                 for(a=0; a<256; a++) {
312                         fpx1[a]= fpx2[a]= 0.0;
313                         fpy1[a]= fpy2[a]= 0.0;
314                         if(a & 1) {
315                                 fpx1[a]+= jit[0][0];
316                                 fpy1[a]+= jit[0][1];
317                                 fpx2[a]+= jit[8][0];
318                                 fpy2[a]+= jit[8][1];
319                         }
320                         if(a & 2) {
321                                 fpx1[a]+= jit[1][0];
322                                 fpy1[a]+= jit[1][1];
323                                 fpx2[a]+= jit[9][0];
324                                 fpy2[a]+= jit[9][1];
325                         }
326                         if(a & 4) {
327                                 fpx1[a]+= jit[2][0];
328                                 fpy1[a]+= jit[2][1];
329                                 fpx2[a]+= jit[10][0];
330                                 fpy2[a]+= jit[10][1];
331                         }
332                         if(a & 8) {
333                                 fpx1[a]+= jit[3][0];
334                                 fpy1[a]+= jit[3][1];
335                                 fpx2[a]+= jit[11][0];
336                                 fpy2[a]+= jit[11][1];
337                         }
338                         if(a & 16) {
339                                 fpx1[a]+= jit[4][0];
340                                 fpy1[a]+= jit[4][1];
341                                 fpx2[a]+= jit[12][0];
342                                 fpy2[a]+= jit[12][1];
343                         }
344                         if(a & 32) {
345                                 fpx1[a]+= jit[5][0];
346                                 fpy1[a]+= jit[5][1];
347                                 fpx2[a]+= jit[13][0];
348                                 fpy2[a]+= jit[13][1];
349                         }
350                         if(a & 64) {
351                                 fpx1[a]+= jit[6][0];
352                                 fpy1[a]+= jit[6][1];
353                                 fpx2[a]+= jit[14][0];
354                                 fpy2[a]+= jit[14][1];
355                         }
356                         if(a & 128) {
357                                 fpx1[a]+= jit[7][0];
358                                 fpy1[a]+= jit[7][1];
359                                 fpx2[a]+= jit[15][0];
360                                 fpy2[a]+= jit[15][1];
361                         }
362                 }
363
364                 for(a= (1<<R.osa)-1; a>0; a--) {
365                         val= count_mask(a);
366                         i= 8+(15.9*(fpy1[a & 255]+fpy2[a>>8])/val);
367                         CLAMP(i, 0, 15);
368                         j= 8+(15.9*(fpx1[a & 255]+fpx2[a>>8])/val);
369                         CLAMP(j, 0, 15);
370                         i= j + (i<<4);
371                         centmask[a]= i;
372                 }
373
374                 MEM_freeN(fpx1);
375                 MEM_freeN(fpx2);
376                 MEM_freeN(fpy1);
377                 MEM_freeN(fpy2);
378         }
379 }
380
381 static void free_filt_mask()
382 {
383         int a;
384
385         for(a=0; a<9; a++) {
386                 MEM_freeN(fmask1[a]);
387                 MEM_freeN(fmask2[a]);
388         }
389         MEM_freeN(gamtab);
390         MEM_freeN(igamtab1);
391         MEM_freeN(igamtab2);
392
393         MEM_freeN(centmask);
394 }
395
396 /* unused */
397
398 #if 0
399 void defaultlamp()
400 {
401         LampRen *lar;
402
403         lar= (LampRen *)MEM_callocN(sizeof(LampRen),"lampren");
404         R.la[R.totlamp++]=lar;
405
406         lar->type= LA_SUN;
407         lar->vec[0]= -R.viewmat[2][0];
408         lar->vec[1]= -R.viewmat[2][1];
409         lar->vec[2]= -R.viewmat[2][2];
410         Normalise(lar->vec);
411         lar->r= 1.0;
412         lar->g= 1.0;
413         lar->b= 1.0;
414         lar->lay= 65535;
415 }
416 #endif
417
418
419
420 /* ********************* init calls *********************** */
421
422
423 static void init_def_material(void)
424 {
425         Material *ma;
426         
427         ma= &defmaterial;
428         
429         init_material(&defmaterial);
430         
431         init_render_material(ma);
432 }
433
434 void RE_init_render_data(void)
435 {
436         memset(&R, 0, sizeof(RE_Render));
437         
438         R.blove= (VertRen **)MEM_callocN(sizeof(void *)*(TABLEINITSIZE),"Blove");
439         R.blovl= (VlakRen **)MEM_callocN(sizeof(void *)*(TABLEINITSIZE),"Blovl");
440         R.bloha= (HaloRen **)MEM_callocN(sizeof(void *)*(TABLEINITSIZE),"Bloha");
441         R.la= (LampRen **)MEM_mallocN(LAMPINITSIZE*sizeof(void *),"renderlamparray");
442         
443         init_def_material();
444         init_filt_mask();
445 }
446
447 void RE_free_render_data()
448 {
449         MEM_freeN(R.blove);
450         R.blove= NULL;
451         MEM_freeN(R.blovl);
452         R.blovl= NULL;
453         MEM_freeN(R.bloha);
454         R.bloha= NULL;
455         MEM_freeN(R.la);
456         R.la= NULL;
457         if(R.rectot) MEM_freeN(R.rectot);
458         if(R.rectftot) MEM_freeN(R.rectftot);
459         if(R.rectz) MEM_freeN(R.rectz);
460         if(R.rectspare) MEM_freeN(R.rectspare);
461         R.rectot= NULL;
462         R.rectftot= NULL;
463         R.rectz= NULL;
464         R.rectspare= NULL;
465         
466         end_render_material(&defmaterial);
467         free_filt_mask();
468 }
469
470 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
471
472 void RE_make_existing_file(char *name)
473 {
474         char di[FILE_MAXDIR], fi[FILE_MAXFILE];
475
476         strcpy(di, name);
477         BLI_splitdirstring(di, fi);
478
479         /* test exist */
480         if (BLI_exists(di) == 0) {
481                 BLI_recurdir_fileops(di);
482         }
483 }
484
485
486 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
487
488 void RE_setwindowclip(int mode, int jmode)
489 {
490         extern float bluroffsx, bluroffsy;      // rendercore.c... hackish (ton)
491         Camera *cam=0;
492         float lens, minx, miny, maxx, maxy;
493         float xd, yd, afmx, afmy;
494
495         if(G.scene->camera==0) return;
496
497         afmx= R.afmx;
498         afmy= R.afmy;
499
500         if(mode) {
501
502                 if(G.scene->camera->type==OB_LAMP) {
503                         /* fac= cos( PI*((float)(256- la->spsi))/512.0 ); */
504
505                         /* phi= acos(fac); */
506                         /* lens= 16.0*fac/sin(phi); */
507                         lens= 35.0;
508                         R.near= 0.1;
509                         R.far= 1000.0;
510                 }
511                 else if(G.scene->camera->type==OB_CAMERA) {
512                         cam= G.scene->camera->data;
513
514                         lens= cam->lens;
515                         R.near= cam->clipsta;
516                         R.far= cam->clipend;
517                 }
518                 else {
519                         lens= 16.0;
520                 }
521
522                 if( (R.r.xasp*afmx) >= (R.r.yasp*afmy) ) {
523                         R.viewfac= (afmx*lens)/16.0;
524                 }
525                 else {
526                         R.viewfac= R.ycor*(afmy*lens)/16.0;
527                 }
528                 if(R.r.mode & R_ORTHO) {
529                         R.near*= 100.0; 
530                         R.viewfac*= 100.0;
531                 }
532
533                 R.pixsize= R.near/R.viewfac;
534
535         }
536
537         /* revision / simplification of subpixel offsets:
538            - the matrix will go without offset from start (e.g. -100) to end (e.g. +99).
539            - filling in with zbuffer will set offset of 0.5. to make sure clipped faces fill in too
540            - in shadepixel() again that 0.5 offset is corrected
541         */
542         minx= R.xstart; 
543         miny= R.ycor*(R.ystart); 
544         maxx= R.xend; 
545         maxy= R.ycor*(R.yend); 
546            
547         if(R.flag & R_SEC_FIELD) {
548                 if(R.r.mode & R_ODDFIELD) {
549                         miny-= .5*R.ycor;
550                         maxy-= .5*R.ycor;
551                 }
552                 else {
553                         miny+= .5*R.ycor;
554                         maxy+= .5*R.ycor;
555                 }
556         }
557
558         xd= yd= 0.0;
559         if(jmode!= -1) {
560                 bluroffsx= xd= jit[jmode % R.osa][0];
561                 bluroffsy= yd= R.ycor*jit[jmode % R.osa][1];
562         }
563         else bluroffsx=bluroffsy= 0.0;
564
565         minx= R.pixsize*(minx+xd);
566         maxx= R.pixsize*(maxx+xd);
567         miny= R.pixsize*(miny+yd);
568         maxy= R.pixsize*(maxy+yd);
569
570         if(R.r.mode & R_ORTHO) {
571                 i_window(minx, maxx, miny, maxy, R.near, 100.0*R.far, R.winmat);
572         }
573         else i_window(minx, maxx, miny, maxy, R.near, R.far, R.winmat);
574
575 }
576
577
578 /* ~~~~~~~~~~~~~~~~ PARTS ~~~~~~~~~~~~~~~~~~~~~~ */
579
580 /** 
581 * Part as in part-rendering. An image rendered in parts is rendered
582 * to a list of parts, with x,y size, and a pointer to the render
583 * output stored per part. Internal!
584 */
585 typedef struct Part
586 {
587         struct Part *next, *prev;
588         unsigned int *rect;             // color 4x8 bits
589         float *rectf;                   // color 4x32 bits
590         unsigned int *rectz;    // zbuffer
591
592         short minx, miny, maxx, maxy, x, y;
593 } Part;
594
595 static void freeparts(void)
596 {
597         Part *part= R.parts.first;
598         while(part) {
599                 if(part->rect) MEM_freeN(part->rect);
600                 if(part->rectz) MEM_freeN(part->rectz);
601                 if(part->rectf) MEM_freeN(part->rectf);
602                 part= part->next;
603         }
604         BLI_freelistN(&R.parts);
605 }
606
607 static void initparts(void)
608 {
609         Part *pa;
610         short nr, xd, yd, xpart, ypart, xparts, yparts;
611         short a, xminb, xmaxb, yminb, ymaxb;
612
613         freeparts();
614         
615         if(R.r.mode & R_BORDER) {
616                 xminb= R.r.border.xmin*R.rectx;
617                 xmaxb= R.r.border.xmax*R.rectx;
618
619                 yminb= R.r.border.ymin*R.recty;
620                 ymaxb= R.r.border.ymax*R.recty;
621
622                 if(xminb<0) xminb= 0;
623                 if(xmaxb>R.rectx) xmaxb= R.rectx;
624                 if(yminb<0) yminb= 0;
625                 if(ymaxb>R.recty) ymaxb= R.recty;
626         }
627         else {
628                 xminb=yminb= 0;
629                 xmaxb= R.rectx;
630                 ymaxb= R.recty;
631         }
632
633         xparts= R.r.xparts;     /* for border */
634         yparts= R.r.yparts;
635
636         xpart= R.rectx/xparts;
637         ypart= R.recty/yparts;
638
639         /* if border: test if amount of parts can be fewer */
640         if(R.r.mode & R_BORDER) {
641                 a= (xmaxb-xminb-1)/xpart+1; /* amount of parts in border */
642                 if(a<xparts) xparts= a;
643                 a= (ymaxb-yminb-1)/ypart+1; /* amount of parts in border */
644                 if(a<yparts) yparts= a;
645
646                 xpart= (xmaxb-xminb)/xparts;
647                 ypart= (ymaxb-yminb)/yparts;
648         }
649         
650         for(nr=0; nr<xparts*yparts; nr++) {
651                 pa= MEM_callocN(sizeof(Part), "new part");
652                 
653                 if(R.r.mode & R_PANORAMA) {
654                         pa->minx= pa->miny= 0;
655                         pa->maxx= pa->x= R.rectx;
656                         pa->maxy= pa->y= R.recty;
657                 }
658                 else {
659                         xd= (nr % xparts);
660                         yd= (nr-xd)/xparts;
661
662                         pa->minx= xminb+ xd*xpart;
663                         pa->miny= yminb+ yd*ypart;
664                         if(xd<R.r.xparts-1) pa->maxx= pa->minx+xpart;
665                         else pa->maxx= xmaxb;
666                         if(yd<R.r.yparts-1) pa->maxy= pa->miny+ypart;
667                         else pa->maxy= ymaxb;
668
669                         pa->x= pa->maxx-pa->minx;
670                         pa->y= pa->maxy-pa->miny;
671                 }
672                 
673                 if(pa->x>0 && pa->y>0) {
674                         /* Gauss needs 1 pixel extra to work */
675                         if(xparts*yparts>1 && (R.r.mode & R_GAUSS)) {
676                                 pa->minx-= 1;
677                                 pa->miny-= 1;
678                                 pa->maxx+= 1;
679                                 pa->maxy+= 1;
680                                 pa->x+= 2;
681                                 pa->y+= 2;
682                         }
683                         BLI_addtail(&R.parts, pa);
684                 }
685                 else MEM_freeN(pa);
686         }
687         
688 }
689
690 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
691 static void setpart(Part *pa)
692 {
693
694         R.xstart= pa->minx-R.afmx;
695         R.ystart= pa->miny-R.afmy;
696         R.xend= pa->maxx-R.afmx;
697         R.yend= pa->maxy-R.afmy;
698         R.rectx= pa->x;
699         R.recty= pa->y;
700 }
701
702 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
703 static void addparttorect(Part *pa)
704 {
705         float *rf, *rfp;
706         unsigned int *rt, *rtp, *rz, *rzp;
707         int y, heigth, len, copylen;
708
709         /* calc the right offset in rects, zbuffer cannot exist... */
710
711         rtp= pa->rect;
712         rzp= pa->rectz;
713         rfp= pa->rectf;
714         
715         copylen=len= pa->x;
716         heigth= pa->y;
717         
718         if(R.r.mode & R_GAUSS) {
719                 
720                 rtp+= 1+len;
721                 if(rzp) rzp+= 1+len;
722                 if(rfp) rfp+= 4*(1+len);
723                 
724                 copylen= len-2;
725                 heigth -= 2;
726                 rt= R.rectot+ (pa->miny + 1)*R.rectx+ (pa->minx+1);
727                 rz= R.rectz+ (pa->miny + 1)*R.rectx+ (pa->minx+1);
728                 rf= R.rectftot+ 4*( (pa->miny + 1)*R.rectx + (pa->minx+1) );
729         }
730         else {
731                 rt= R.rectot+ pa->miny*R.rectx+ pa->minx;
732                 rz= R.rectz+ pa->miny*R.rectx+ pa->minx;
733                 rf= R.rectftot+ 4*(pa->miny*R.rectx+ pa->minx);
734         }
735
736         for(y=0; y<heigth; y++) {
737                 memcpy(rt, rtp, 4*copylen);
738                 rt+= R.rectx;
739                 rtp+= len;
740                 
741                 if(rzp) {
742                         memcpy(rz, rzp, 4*copylen);
743                         rz+= R.rectx;
744                         rzp+= len;
745                 }
746                 if(rfp) {
747                         memcpy(rf, rfp, 16*copylen);
748                         rf+= 4*R.rectx;
749                         rfp+= 4*len;
750                 }
751         }
752 }
753
754
755 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
756
757  
758 static void add_to_blurbuf(int blur)
759 {
760         static unsigned int *blurrect= 0;
761         int tot, gamval;
762         short facr, facb;
763         char *rtr, *rtb;
764
765         if(blur<0) {
766                 if(blurrect) {
767                         if(R.rectot) MEM_freeN(R.rectot);
768                         R.rectot= blurrect;
769                         blurrect= 0;
770                 }
771         }
772         else if(blur==R.osa-1) {
773                 /* first time */
774                 blurrect= MEM_mallocN(R.rectx*R.recty*sizeof(int), "rectblur");
775                 if(R.rectot) memcpy(blurrect, R.rectot, R.rectx*R.recty*4);
776         }
777         else if(blurrect) {
778                 /* accumulate */
779
780                 facr= 256/(R.osa-blur);
781                 facb= 256-facr;
782
783                 if(R.rectot) {
784                         rtr= (char *)R.rectot;
785                         rtb= (char *)blurrect;
786                         tot= R.rectx*R.recty;
787                         while(tot--) {
788                                 if( *((unsigned int *)rtb) != *((unsigned int *)rtr) ) {
789
790                                         if(R.r.mode & R_GAMMA) {
791                                                 gamval= (facr* igamtab2[ rtr[0]<<8 ] + facb* igamtab2[ rtb[0]<<8 ])>>8;
792                                                 rtb[0]= gamtab[ gamval ]>>8;
793                                                 gamval= (facr* igamtab2[ rtr[1]<<8 ] + facb* igamtab2[ rtb[1]<<8 ])>>8;
794                                                 rtb[1]= gamtab[ gamval ]>>8;
795                                                 gamval= (facr* igamtab2[ rtr[2]<<8 ] + facb* igamtab2[ rtb[2]<<8 ])>>8;
796                                                 rtb[2]= gamtab[ gamval ]>>8;
797                                                 gamval= (facr* igamtab2[ rtr[3]<<8 ] + facb* igamtab2[ rtb[3]<<8 ])>>8;
798                                                 rtb[3]= gamtab[ gamval ]>>8;
799                                         }
800                                         else {
801                                                 rtb[0]= (facr*rtr[0] + facb*rtb[0])>>8;
802                                                 rtb[1]= (facr*rtr[1] + facb*rtb[1])>>8;
803                                                 rtb[2]= (facr*rtr[2] + facb*rtb[2])>>8;
804                                                 rtb[3]= (facr*rtr[3] + facb*rtb[3])>>8;
805                                         }
806                                 }
807                                 rtr+= 4;
808                                 rtb+= 4;
809                         }
810                 }
811                 if(blur==0) {
812                         /* last time */
813                         if(R.rectot) MEM_freeN(R.rectot);
814                         R.rectot= blurrect;
815                         blurrect= 0;
816                 }
817         }
818 }
819
820
821 /* yafray: main yafray render/export call */
822 void yafrayRender()
823 {
824         R.flag |= R_RENDERING;  /* !!! */
825
826         /* all allocs moved here, out of export code */
827         /* display rgba buf */
828         if (R.rectot) MEM_freeN(R.rectot);
829         R.rectot = MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot");
830         /* zbuf */
831         if (R.rectz) MEM_freeN(R.rectz);
832         R.rectz = (unsigned int *)MEM_mallocN(sizeof(int)*R.rectx*R.recty, "rectz");
833         /* float rgba buf */
834         if (R.rectftot) MEM_freeN(R.rectftot);
835         if (R.r.mode & R_FBUF) R.rectftot= MEM_callocN(4*sizeof(float)*R.rectx*R.recty, "rectftot");
836
837         // switch must be done before prepareScene()
838         if (!R.r.YFexportxml)
839                 YAF_switchFile();
840         else
841                 YAF_switchPlugin();
842
843         printf("Starting scene conversion.\n");
844         prepareScene();
845         printf("Scene conversion done.\n");
846
847         YAF_exportScene();
848         finalizeScene();
849
850         // show postpro effects if floatbuffer used (plugin only)
851         if (R.r.YFexportxml) {
852                 if ((R.r.mode & R_FBUF) && R.rectftot)
853                         RE_floatbuffer_to_output();
854         }
855 }
856
857
858 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
859
860 // exported to other files, belongs in include... later
861 SDL_mutex *render_abuf_lock=NULL, *load_ibuf_lock=NULL;
862
863
864 static void renderloop_setblending(void)
865 {
866         
867         /* this value should only be set here. do_gamma is for gammablended adding of subpixels */
868         do_gamma= 0;
869         if(R.r.mode & R_GAMMA) {
870                 if((R.r.mode & R_OSA)) do_gamma= 1;
871         }
872         
873         /* always call, it does gamma tables used by alphaunder, but call after R.osa and jit was set */
874         init_filt_mask();
875         
876         switch (R.r.alphamode) {
877                 case R_ALPHAKEY:        
878                         setSkyBlendingMode(RE_ALPHA_KEY);
879                         break;
880                 case R_ALPHAPREMUL:     
881                         setSkyBlendingMode(RE_ALPHA_PREMUL);
882                         break;
883                 default:
884                         setSkyBlendingMode(RE_ALPHA_SKY);               
885         }
886         
887         /* SHould use slider when the gamma button is pressed. */
888         if (do_gamma) {         
889                 makeGammaTables(2.0);
890         } else {
891                 makeGammaTables(1.0);
892         }
893         
894 }
895
896 static void mainRenderLoop(void)  /* here the PART and FIELD loops */
897 {
898         Part *pa;
899         int blur, fields, fi, totparts, nr;
900
901         /* create mutexes for threaded render */
902         render_abuf_lock = SDL_CreateMutex();
903         load_ibuf_lock = SDL_CreateMutex();
904
905         if(R.rectz) MEM_freeN(R.rectz);
906         R.rectz = NULL;
907         if(R.rectftot) MEM_freeN(R.rectftot);
908         R.rectftot = NULL;
909         
910         /* FIELD LOOP */
911         totparts= R.r.xparts*R.r.yparts;
912         fields= 1;
913
914         if(R.r.mode & R_FIELDS) {
915                 fields= 2;
916                 R.rectf1= R.rectf2= NULL;       /* field rects */
917                 R.r.ysch/= 2;
918                 R.afmy/= 2;
919                 R.r.yasp*= 2;
920                 R.ycor= ( (float)R.r.yasp)/( (float)R.r.xasp);
921
922         }
923         
924         for(fi=0; fi<fields; fi++) {
925
926                 /* INIT */
927                 BLI_srand( 2*(G.scene->r.cfra)+fi);
928                         
929                 R.flag|= R_RENDERING;
930                 if(fi==1) R.flag |= R_SEC_FIELD;
931         
932                 /* MOTIONBLUR loop */
933                 if(R.r.mode & R_MBLUR) blur= R.osa;
934                 else blur= 1;
935                 while(blur--) {
936
937                         /* WINDOW */
938                         R.rectx= R.r.xsch;
939                         R.recty= R.r.ysch;
940                         R.xstart= -R.afmx;
941                         R.ystart= -R.afmy;
942                         R.xend= R.xstart+R.rectx-1;
943                         R.yend= R.ystart+R.recty-1;
944
945
946                         if(R.r.mode & R_MBLUR) set_mblur_offs(R.osa-blur);
947
948                         initparts(); /* always do, because of border */
949                         setpart(R.parts.first);
950
951                         RE_local_init_render_display();
952                         RE_local_clear_render_display(R.win);
953                         RE_local_timecursor((G.scene->r.cfra));
954
955                         prepareScene();
956
957                         /* PARTS LOOP */
958                         nr= 0;
959                         for(pa= R.parts.first; pa; pa= pa->next, nr++) {
960
961                                 if(RE_local_test_break()) break;
962
963                                 setpart(pa);
964
965                                 if(R.r.mode & R_MBLUR) RE_setwindowclip(0, blur);
966                                 else RE_setwindowclip(0,-1);
967
968                                 if(R.r.mode & R_PANORAMA) setPanoRot(nr);
969
970                                 /* HOMOGENIC COORDINATES AND ZBUF AND CLIP OPTIMISATION (per part) */
971                                 /* There may be some interference with z-coordinate    */
972                                 /* calculation here?                                   */
973
974                                 doClipping(RE_projectverto);
975                                 if(RE_local_test_break()) break;
976                                 
977                                 /* rectot is for result and integer face indices */
978                                 if(R.rectot) MEM_freeN(R.rectot);
979                                 R.rectot= MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot");
980                                 
981                                 if(R.rectftot) MEM_freeN(R.rectftot);
982                                 if(R.r.mode & R_FBUF) R.rectftot= MEM_callocN(4*sizeof(float)*R.rectx*R.recty, "rectftot");
983                                 
984                                 if(R.r.mode & R_MBLUR) {
985                                         RE_local_printrenderinfo(0.0, R.osa - blur);
986                                         if(G.background && blur<R.osa) printf("\n"); // newline for percentage print
987                                 }
988                                 else RE_local_printrenderinfo(0.0, -1);
989
990                                 if(R.r.mode & R_UNIFIED) {
991                                         zBufShadeAdvanced();
992                                 }
993                                 else {
994                                         R.rectz =  (unsigned int *)MEM_mallocN(sizeof(int)*R.rectx*R.recty, "rectz");
995
996                                         if(R.r.mode & R_OSA) zbufshadeDA();
997                                         else zbufshade();
998                                 }
999                                 
1000                                 /* exception */
1001                                 if( (R.r.mode & R_BORDER) && (R.r.mode & R_MOVIECROP));
1002                                 else {
1003                                         /* HANDLE PART OR BORDER */
1004                                         if(totparts>1 || (R.r.mode & R_BORDER)) {
1005
1006                                                 pa->rect= R.rectot;
1007                                                 R.rectot= NULL;
1008                                                 pa->rectf= R.rectftot;
1009                                                 R.rectftot= NULL;
1010                                                 pa->rectz= R.rectz;
1011                                                 R.rectz= NULL;
1012                                         }
1013                                 }
1014
1015                                 if(RE_local_test_break()) break;
1016                         }
1017
1018                         /* JOIN PARTS OR INSERT BORDER */
1019
1020                         /* exception: crop */
1021                         if( (R.r.mode & R_BORDER) && (R.r.mode & R_MOVIECROP)) ;
1022                         else {
1023                                 R.rectx= R.r.xsch;
1024                                 R.recty= R.r.ysch;
1025
1026                                 if(R.r.mode & R_PANORAMA) R.rectx*= R.r.xparts;
1027
1028                                 if(totparts>1 || (R.r.mode & R_BORDER)) {
1029                                         int a;
1030                                         
1031                                         if(R.rectot) MEM_freeN(R.rectot);
1032                                         if(R.rectftot) MEM_freeN(R.rectftot);
1033                                         if(R.rectz) MEM_freeN(R.rectz);
1034                                         
1035                                         R.rectot= MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot");
1036                                         R.rectz= MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectz");
1037                                         if(R.r.mode & R_FBUF) R.rectftot= MEM_callocN(4*sizeof(float)*R.rectx*R.recty, "rectftot");
1038                                         else R.rectftot= NULL;
1039                                         
1040                                         for(a=0, pa= R.parts.first; pa; pa= pa->next, a++) {
1041                                                 
1042                                                 if(R.r.mode & R_PANORAMA) {             // pano is fake parts...
1043                                                         pa->minx += a*R.r.xsch;
1044                                                         pa->maxx += a*R.r.xsch;
1045                                                 }
1046                                                 addparttorect(pa);
1047                                         }
1048                                 }
1049                         }
1050                         
1051                         freeparts();
1052                         
1053                         if( (R.flag & R_HALO)) {
1054                                 if(RE_local_test_break()==0) add_halo_flare();
1055                         }
1056
1057                         if(R.r.mode & R_MBLUR) {
1058                                 add_to_blurbuf(blur);
1059                         }
1060
1061                         /* END (blur loop) */
1062                         finalizeScene();
1063
1064                         if(RE_local_test_break()) break;
1065                 }
1066
1067                 /* definite free */
1068                 add_to_blurbuf(-1);
1069
1070                 /* HANDLE FIELD */
1071                 if(R.r.mode & R_FIELDS) {
1072                         if(R.flag & R_SEC_FIELD) R.rectf2= R.rectot;
1073                         else R.rectf1= R.rectot;
1074                         R.rectot= NULL;
1075                 }
1076
1077                 if(RE_local_test_break()) break;
1078         }
1079
1080         /* JOIN FIELDS */
1081         if(R.r.mode & R_FIELDS) {
1082                 R.r.ysch*= 2;
1083                 R.afmy*= 2;
1084                 R.recty*= 2;
1085                 R.r.yasp/=2;
1086
1087                 if(R.rectot) MEM_freeN(R.rectot);       /* happens when a render has been stopped */
1088                 R.rectot=(unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot");
1089                 
1090                 if(RE_local_test_break()==0) {
1091                         unsigned int *rt, *rt1, *rt2;
1092                         int len, a;
1093                         
1094                         rt= R.rectot;
1095
1096                         if(R.r.mode & R_ODDFIELD) {
1097                                 rt2= R.rectf1;
1098                                 rt1= R.rectf2;
1099                         }
1100                         else {
1101                                 rt1= R.rectf1;
1102                                 rt2= R.rectf2;
1103                         }
1104
1105                         len= 4*R.rectx;
1106
1107                         for(a=0; a<R.recty; a+=2) {
1108                                 memcpy(rt, rt1, len);
1109                                 rt+= R.rectx;
1110                                 rt1+= R.rectx;
1111                                 memcpy(rt, rt2, len);
1112                                 rt+= R.rectx;
1113                                 rt2+= R.rectx;
1114                         }
1115                 }
1116                 
1117                 if(R.rectf1) MEM_freeN(R.rectf1);
1118                 R.rectf1= NULL;
1119                 if(R.rectf2) MEM_freeN(R.rectf2);
1120                 R.rectf2= NULL;
1121                 /* fbuf and zbuf free, image size differs now */
1122                 if(R.rectftot) MEM_freeN(R.rectftot);
1123                 R.rectftot= NULL;
1124                 if(R.rectz) MEM_freeN(R.rectz);
1125                 R.rectz= NULL;
1126                 
1127         }
1128
1129         /* if border: still do skybuf */
1130         if(R.r.mode & R_BORDER) {
1131                 if( (R.r.mode & R_MOVIECROP)==0) {
1132                         if(R.r.bufflag & 1) {
1133                                 unsigned int *rt;
1134                                 int x, y;
1135                                 
1136                                 R.xstart= -R.afmx;
1137                                 R.ystart= -R.afmy;
1138                                 rt= R.rectot;
1139                                 for(y=0; y<R.recty; y++) {
1140                                         for(x=0; x<R.rectx; x++, rt++) {
1141                                                 if(*rt==0) fillBackgroundImageChar((char *)rt, x, y);
1142                                         }
1143                                 }
1144                         }
1145                 }
1146         }
1147
1148         set_mblur_offs(0);
1149
1150         /* mutexes free */
1151         SDL_DestroyMutex(load_ibuf_lock);
1152         SDL_DestroyMutex(render_abuf_lock);
1153         load_ibuf_lock= NULL;
1154         render_abuf_lock= NULL;
1155 }
1156
1157 void render() {
1158         /* yafray: render, see above */
1159         if (R.r.renderer==R_YAFRAY)
1160                 yafrayRender();
1161         else
1162                 mainRenderLoop();
1163 }
1164
1165
1166 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
1167
1168 void RE_initrender(struct View3D *ogl_render_view3d)
1169 {
1170         double start_time;
1171         Image *bima;
1172         char name[256];
1173         
1174         /* scene data to R */
1175         R.r= G.scene->r;
1176         R.r.postigamma= 1.0/R.r.postgamma;
1177         
1178         /* WINDOW size (sch='scherm' dutch for screen...) */
1179         R.r.xsch= (R.r.size*R.r.xsch)/100;
1180         R.r.ysch= (R.r.size*R.r.ysch)/100;
1181         
1182         R.afmx= R.r.xsch/2;
1183         R.afmy= R.r.ysch/2;
1184         
1185         /* to be sure: when a premature return (rectx can differ from xsch) */
1186         R.rectx= R.r.xsch;
1187         R.recty= R.r.ysch;
1188         
1189         /* IS RENDERING ALLOWED? */
1190         
1191         /* forbidden combination */
1192         if((R.r.mode & R_BORDER) && (R.r.mode & R_PANORAMA)) {
1193                 error("No border supported for Panorama");
1194                 G.afbreek= 1;
1195                 return;
1196         }
1197         
1198         if(R.r.xparts*R.r.yparts>=2 && (R.r.mode & R_MOVIECROP) && (R.r.mode & R_BORDER)) {
1199                 error("Combination of border, crop and parts not allowed");
1200                 G.afbreek= 1;
1201                 return;
1202         }
1203         
1204         if(R.r.xparts*R.r.yparts>64) {
1205                 error("No more than 64 parts supported");
1206                 G.afbreek= 1;
1207                 return;
1208         }
1209         
1210         if(R.r.yparts>1 && (R.r.mode & R_PANORAMA)) {
1211                 error("No Y-Parts supported for Panorama");
1212                 G.afbreek= 1;
1213                 return;
1214         }
1215         
1216         
1217         /* TEST BACKBUF */
1218         /* If an image is specified for use as backdrop, that image is loaded    */
1219         /* here.                                                                 */
1220         if((R.r.bufflag & 1) && (G.scene->r.scemode & R_OGL)==0) {
1221                 if(R.r.alphamode == R_ADDSKY) {
1222                         strcpy(name, R.r.backbuf);
1223                         BLI_convertstringcode(name, G.sce, G.scene->r.cfra);
1224                         
1225                         if(R.backbuf) {
1226                                 R.backbuf->id.us--;
1227                                 bima= R.backbuf;
1228                         }
1229                         else bima= NULL;
1230                         
1231                         R.backbuf= add_image(name);
1232                         
1233                         if(bima && bima->id.us<1) {
1234                                 free_image_buffers(bima);
1235                         }
1236
1237                         if(R.backbuf && R.backbuf->ibuf==NULL) {
1238                                 R.backbuf->ibuf= IMB_loadiffname(R.backbuf->name, IB_rect);
1239                                 if(R.backbuf->ibuf==NULL) R.backbuf->ok= 0;
1240                                 else R.backbuf->ok= 1;
1241                         }
1242                         if(R.backbuf==NULL || R.backbuf->ok==0) {
1243                                 // error() doesnt work with render window open
1244                                 //error("No backbuf there!");
1245                                 printf("Error: No backbuf %s\n", name);
1246                         }
1247                 }
1248         }
1249         
1250         if(R.r.mode & (R_OSA|R_MBLUR)) {
1251                 R.osa= R.r.osa;
1252                 if(R.osa>16) R.osa= 16;
1253                 
1254                 init_render_jit(R.osa);
1255                 
1256         }
1257         else R.osa= 0;
1258         
1259         renderloop_setblending();       // alpha, sky, gamma
1260         
1261         /* when rendered without camera object */
1262         /* it has to done here because of envmaps */
1263         R.near= 0.1;
1264         R.far= 1000.0;
1265         
1266         
1267         if(R.afmx<1 || R.afmy<1) {
1268                 error("Image too small");
1269                 return;
1270         }
1271         R.ycor= ( (float)R.r.yasp)/( (float)R.r.xasp);
1272         
1273         start_time= PIL_check_seconds_timer();
1274         
1275         if(R.r.scemode & R_DOSEQ) {
1276                 R.rectx= R.r.xsch;
1277                 R.recty= R.r.ysch;
1278                 if(R.r.mode & R_PANORAMA) {
1279                         R.rectx*= R.r.xparts;
1280                 }
1281                 
1282                 if(R.rectot) MEM_freeN(R.rectot);
1283                 R.rectot= (unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot");
1284                 
1285                 if(R.rectftot) MEM_freeN(R.rectftot);
1286                 R.rectftot= NULL;
1287                 
1288                 RE_local_timecursor((G.scene->r.cfra));
1289                 
1290                 if(RE_local_test_break()==0) do_render_seq();
1291                 
1292                 /* display */
1293                 if(R.rectot) RE_local_render_display(0, R.recty-1, R.rectx, R.recty,R.rectot);
1294         }
1295         else if(R.r.scemode & R_OGL) {
1296                 R.rectx= R.r.xsch;
1297                 R.recty= R.r.ysch;
1298                 
1299                 if(R.rectot) MEM_freeN(R.rectot);
1300                 R.rectot= (unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot");
1301                 
1302                 if(R.rectftot) MEM_freeN(R.rectftot);
1303                 R.rectftot= NULL;
1304                 
1305                 RE_local_init_render_display();
1306                 drawview3d_render(ogl_render_view3d);
1307         }
1308         else {
1309                 if(G.scene->camera==0) {
1310                         G.scene->camera= scene_find_camera(G.scene);
1311                 }
1312                 
1313                 if(G.scene->camera==0) {
1314                         error("No camera");
1315                         /* needed because R.rectx and R.recty can be unmatching R.rectot */
1316                         
1317                         if(R.rectot) MEM_freeN(R.rectot);
1318                         R.rectot= NULL;
1319                         if(R.rectftot) MEM_freeN(R.rectftot);
1320                         R.rectftot= NULL;
1321                         
1322                         G.afbreek=1;
1323                         return;
1324                 }
1325                 else {
1326                         
1327                         if(G.scene->camera->type==OB_CAMERA) {
1328                                 Camera *cam= G.scene->camera->data;
1329                                 if(cam->type==CAM_ORTHO) R.r.mode |= R_ORTHO;
1330                         }
1331                         
1332                         render(); /* returns with complete rect xsch-ysch */
1333                 }
1334         }
1335         
1336         /* display again: fields/seq/parts/pano etc */
1337         if(R.rectot) {
1338                 RE_local_init_render_display();
1339                 RE_local_render_display(0, R.recty-1, R.rectx, R.recty, R.rectot);
1340         }
1341         else RE_local_clear_render_display(R.win);
1342         
1343         if ((G.scene->r.scemode & R_OGL)==0) /* header gets scrabled if renderwindow holds OGL context */       
1344                 RE_local_printrenderinfo((PIL_check_seconds_timer() - start_time), -1);
1345         
1346         
1347         /* these flags remain on, until reset in caller to render (renderwin.c) */
1348         R.flag &= (R_RENDERING|R_ANIMRENDER|R_REDRAW_PRV);
1349 }
1350
1351 void RE_animrender(struct View3D *ogl_render_view3d)
1352 {
1353         int cfrao;
1354         char name[256];
1355
1356         if(G.scene==0) return;
1357
1358         /* scenedata to R: (for backbuf, R.rectx etc) */
1359         R.r= G.scene->r;
1360
1361         /* START ANIMLOOP, everywhere NOT the cfra from R.r is gebruikt: because of rest blender */
1362         cfrao= (G.scene->r.cfra);
1363
1364         if(G.scene->r.scemode & R_OGL) R.r.mode &= ~R_PANORAMA;
1365         
1366         // these calculations apply for all movie formats
1367         R.rectx= (R.r.size*R.r.xsch)/100;
1368         R.recty= (R.r.size*R.r.ysch)/100;
1369         if(R.r.mode & R_PANORAMA) {
1370                 R.rectx*= R.r.xparts;
1371                 R.recty*= R.r.yparts;
1372         }
1373         if(R.r.mode & R_MOVIECROP) {
1374                 initparts();
1375                 setpart(R.parts.first);         // this will adjust r.rectx
1376         }
1377
1378         if (0) {
1379 #ifdef __sgi
1380         } else if (R.r.imtype==R_MOVIE) {
1381                 start_movie();
1382 #endif
1383 #if defined(_WIN32) && !defined(FREE_WINDOWS)
1384         } else if (R.r.imtype == R_AVICODEC) {
1385                 start_avi_codec();
1386 #endif
1387 #if WITH_QUICKTIME
1388         } else if (R.r.imtype == R_QUICKTIME) {
1389                 start_qt();
1390 #endif
1391         } else if ELEM4(R.r.imtype, R_AVIRAW, R_AVIJPEG, R_MOVIE, R_AVICODEC) {
1392                 if ELEM(R.r.imtype, R_MOVIE, R_AVICODEC) {
1393                         printf("Selected movie format not supported on this platform,\nusing RAW AVI instead\n");
1394                 }
1395                 start_avi();
1396         }
1397
1398         for((G.scene->r.cfra)=(G.scene->r.sfra); (G.scene->r.cfra)<=(G.scene->r.efra); (G.scene->r.cfra)++) {
1399                 double starttime= PIL_check_seconds_timer();
1400
1401                 R.flag |= R_ANIMRENDER; // unused now (ton)
1402
1403                 RE_initrender(ogl_render_view3d);
1404                 
1405                 /* WRITE IMAGE */
1406                 if(RE_local_test_break()==0) {
1407
1408                         if (0) {
1409 #ifdef __sgi
1410                         } else if (R.r.imtype == R_MOVIE) {
1411                                 append_movie((G.scene->r.cfra));
1412 #endif
1413 #if defined(_WIN32) && !defined(FREE_WINDOWS)
1414                         } else if (R.r.imtype == R_AVICODEC) {
1415                                 append_avi_codec((G.scene->r.cfra));
1416 #endif
1417 #ifdef WITH_QUICKTIME
1418                         } else if (R.r.imtype == R_QUICKTIME) {
1419                                 append_qt((G.scene->r.cfra));
1420 #endif
1421                         } else if ELEM4(R.r.imtype, R_AVIRAW, R_AVIJPEG, R_MOVIE, R_AVICODEC) {
1422                                 append_avi((G.scene->r.cfra));
1423                         } else {
1424                                 makepicstring(name, (G.scene->r.cfra));
1425                                 schrijfplaatje(name);
1426                                 if(RE_local_test_break()==0) printf("Saved: %s", name);
1427                         }
1428
1429                         timestr(PIL_check_seconds_timer()-starttime, name);
1430                         printf(" Time: %s\n", name);
1431                         fflush(stdout); /* needed for renderd !! */
1432                 }
1433
1434                 if(G.afbreek==1) break;
1435
1436         }
1437
1438         G.scene->r.cfra= cfrao;
1439
1440         /* restore time */
1441         if(R.r.mode & (R_FIELDS|R_MBLUR)) {
1442                 do_all_ipos();
1443                 do_all_keys();
1444                 do_all_actions();
1445                 do_all_ikas();
1446         }
1447
1448         if (0) {
1449 #ifdef __sgi    
1450         } else if (R.r.imtype==R_MOVIE) {
1451                 end_movie();
1452 #endif
1453 #if defined(_WIN32) && !defined(FREE_WINDOWS)
1454         } else if (R.r.imtype == R_AVICODEC) {
1455                 end_avi_codec();
1456 #endif
1457 #ifdef WITH_QUICKTIME
1458         } else if (R.r.imtype == R_QUICKTIME) {
1459                 end_qt();
1460 #endif
1461         } else if ELEM4(R.r.imtype, R_AVIRAW, R_AVIJPEG, R_MOVIE, R_AVICODEC) {
1462                 end_avi();
1463         }
1464 }
1465
1466 /* *************************************************** */
1467 /* ******************* Screendumps ******************** */
1468 /* moved to the windowControl thing */