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