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