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