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