4 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
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
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.
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.
23 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24 * All rights reserved.
26 * The Original Code is: all of this file.
28 * Contributor(s): none yet.
30 * ***** END GPL/BL DUAL LICENSE BLOCK *****
46 #include "BLI_winstuff.h"
50 #include "MEM_guardedalloc.h"
54 #include "BLI_arithb.h"
55 #include "BLI_blenlib.h"
58 #include "MTC_matrixops.h"
60 #include "DNA_image_types.h"
61 #include "DNA_camera_types.h"
62 #include "DNA_lamp_types.h"
63 #include "DNA_scene_types.h"
64 #include "DNA_object_types.h"
66 #include "BKE_utildefines.h"
67 #include "BKE_global.h"
68 #include "BKE_material.h"
69 #include "BKE_object.h"
70 #include "BKE_image.h"
74 #include "BKE_action.h"
75 #include "BKE_writeavi.h"
76 #include "BKE_scene.h"
78 #include "BIF_toolbox.h"
79 #include "BIF_writeavicodec.h"
80 #include "BIF_writemovie.h" /* start_movie(), append_movie(), end_movie() */
82 #include "BSE_drawview.h"
83 #include "BSE_sequence.h"
86 #include "quicktime_export.h"
91 #include "render_intern.h"
93 #include "RE_callbacks.h"
95 #include "rendercore.h" /* part handler for the old renderer, shading functions */
96 #include "renderPreAndPost.h"
97 #include "outerRenderLoop.h"
98 #include "renderHelp.h"
102 #include "initrender.h"
105 #define ELEM3(a, b, c, d) ( ELEM(a, b, c) || (a)==(d) )
109 extern float fmask[256], centLut[16];
110 extern unsigned short *mask1[9], *mask2[9], /* *igamtab1, */ *igamtab2/*, *gamtab */;
111 extern char cmask[256], *centmask;
113 Material defmaterial;
114 short pa; /* pa is global part, for print */
115 short allparts[65][4];
118 /* ********************* *********************** */
121 void init_def_material(void)
127 init_material(&defmaterial);
129 init_render_material(ma);
132 void RE_init_render_data(void)
134 memset(&R, 0, sizeof(RE_Render));
135 memset(&O, 0, sizeof(Osa));
139 R.blove= (VertRen **)MEM_callocN(sizeof(void *)*(MAXVERT>>8),"Blove");
140 R.blovl= (VlakRen **)MEM_callocN(sizeof(void *)*(MAXVLAK>>8),"Blovl");
141 R.bloha= (HaloRen **)MEM_callocN(sizeof(void *)*(MAXVERT>>8),"Bloha");
142 R.la= (LampRen **)MEM_mallocN(MAXLAMP*sizeof(void *),"renderlamparray");
147 void RE_free_render_data()
157 if(R.rectot) MEM_freeN(R.rectot);
158 if(R.rectz) MEM_freeN(R.rectz);
159 if(R.rectspare) MEM_freeN(R.rectspare);
164 end_render_material(&defmaterial);
167 /* ****************** GAMMA, MASKS and LUTS **************** */
169 float calc_weight(float *weight, int i, int j)
171 float x, y, dist, totw= 0.0;
174 for(a=0; a<R.osa; a++) {
181 if(R.r.mode & R_GAUSS) {
184 weight[a]= (1.0/exp(x*x) - 1.0/exp(1.5*1.5*1.5*1.5));
188 if(i==0 && j==0) weight[a]= 1.0;
197 void RE_init_filt_mask(void)
199 static int firsttime=1;
200 static float lastgamma= 0.0;
202 float weight[32], totw, val, *fpx1, *fpx2, *fpy1, *fpy2;
204 unsigned short *m1, *m2, shweight[32];
208 mask1[a]= MEM_mallocN(256*sizeof(short), "initfilt");
209 mask2[a]= MEM_mallocN(256*sizeof(short), "initfilt");
211 for(a=0; a<256; a++) {
213 if(a & 1) cmask[a]++;
214 if(a & 2) cmask[a]++;
215 if(a & 4) cmask[a]++;
216 if(a & 8) cmask[a]++;
217 if(a & 16) cmask[a]++;
218 if(a & 32) cmask[a]++;
219 if(a & 64) cmask[a]++;
220 if(a & 128) cmask[a]++;
222 centmask= MEM_mallocN(65536, "Initfilt3");
223 for(a=0; a<16; a++) {
224 centLut[a]= -0.45+((float)a)/16.0;
227 gamtab= MEM_mallocN(65536*sizeof(short), "initGaus2");
228 igamtab1= MEM_mallocN(256*sizeof(short), "initGaus2");
229 igamtab2= MEM_mallocN(65536*sizeof(short), "initGaus2");
233 if(R.r.alphamode==R_ALPHAKEY) gamma= 1.0; /* gamma correction of alpha is nasty */
235 if(R.r.mode & R_GAMMA) gamma= 2.0;
239 if(gamma!= lastgamma) {
242 /* gamtab: in short, out short */
243 for(a=0; a<65536; a++) {
247 if(gamma==2.0) val= sqrt(val);
248 else if(gamma!=1.0) val= pow(val, igamma);
250 gamtab[a]= (65535.99*val);
252 /* inverse gamtab1 : in byte, out short */
253 for(a=1; a<=256; a++) {
254 if(gamma==2.0) igamtab1[a-1]= a*a-1;
255 else if(gamma==1.0) igamtab1[a-1]= 256*a-1;
258 igamtab1[a-1]= (65535.0*pow(val, gamma)) -1 ;
262 /* inverse gamtab2 : in short, out short */
263 for(a=0; a<65536; a++) {
266 if(gamma==2.0) val= val*val;
267 else val= pow(val, gamma);
269 igamtab2[a]= 65535.0*val;
278 val= 1.0/((float)R.osa);
279 for(a=0; a<256; a++) {
280 fmask[a]= ((float)cmask[a])*val;
284 memset(mask1[a], 0, 256*2);
285 memset(mask2[a], 0, 256*2);
290 for(j= -1; j<2; j++) {
291 for(i= -1; i<2; i++) {
292 totw+= calc_weight(weight, i, j);
296 for(j= -1; j<2; j++) {
297 for(i= -1; i<2; i++) {
298 /* calculate using jit, with offset the weights */
300 memset(weight, 0, 32*2);
301 calc_weight(weight, i, j);
303 for(a=0; a<16; a++) shweight[a]= weight[a]*(65535.0/totw);
305 m1= mask1[ 3*(j+1)+i+1 ];
306 m2= mask2[ 3*(j+1)+i+1 ];
308 for(a=0; a<256; a++) {
319 m2[a]+= shweight[10];
323 m2[a]+= shweight[11];
327 m2[a]+= shweight[12];
331 m2[a]+= shweight[13];
335 m2[a]+= shweight[14];
339 m2[a]+= shweight[15];
345 /* centmask: the correct subpixel offset per mask */
347 fpx1= MEM_mallocN(256*sizeof(float), "initgauss4");
348 fpx2= MEM_mallocN(256*sizeof(float), "initgauss4");
349 fpy1= MEM_mallocN(256*sizeof(float), "initgauss4");
350 fpy2= MEM_mallocN(256*sizeof(float), "initgauss4");
351 for(a=0; a<256; a++) {
352 fpx1[a]= fpx2[a]= 0.0;
353 fpy1[a]= fpy2[a]= 0.0;
369 fpx2[a]+= jit[10][0];
370 fpy2[a]+= jit[10][1];
375 fpx2[a]+= jit[11][0];
376 fpy2[a]+= jit[11][1];
381 fpx2[a]+= jit[12][0];
382 fpy2[a]+= jit[12][1];
387 fpx2[a]+= jit[13][0];
388 fpy2[a]+= jit[13][1];
393 fpx2[a]+= jit[14][0];
394 fpy2[a]+= jit[14][1];
399 fpx2[a]+= jit[15][0];
400 fpy2[a]+= jit[15][1];
404 for(a= (1<<R.osa)-1; a>0; a--) {
406 i= (15.9*(fpy1[a & 255]+fpy2[a>>8])/val);
408 i+= (15.9*(fpx1[a & 255]+fpx2[a>>8])/val);
419 void RE_free_filt_mask()
441 lar= (LampRen *)MEM_callocN(sizeof(LampRen),"lampren");
442 R.la[R.totlamp++]=lar;
445 lar->vec[0]= -R.viewmat[2][0];
446 lar->vec[1]= -R.viewmat[2][1];
447 lar->vec[2]= -R.viewmat[2][2];
456 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
458 void RE_make_existing_file(char *name)
460 char di[FILE_MAXDIR], fi[FILE_MAXFILE];
463 BLI_splitdirstring(di, fi);
466 if (BLI_exists(di) == 0) {
467 BLI_recurdir_fileops(di);
472 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
474 /* code for holographic hack, used in the neogeo days. SHould be removed (ton) */
476 extern float holoofs; /* render.c */
477 void RE_setwindowclip(int mode, int jmode)
480 float lens, fac, minx, miny, maxx, maxy;
481 float xd, yd, afmx, afmy;
483 if(G.scene->camera==0) return;
490 if(G.scene->camera->type==OB_LAMP) {
491 /* fac= cos( PI*((float)(256- la->spsi))/512.0 ); */
493 /* phi= acos(fac); */
494 /* lens= 16.0*fac/sin(phi); */
499 else if(G.scene->camera->type==OB_CAMERA) {
500 cam= G.scene->camera->data;
503 R.near= cam->clipsta;
510 if( (R.r.xasp*afmx) >= (R.r.yasp*afmy) ) {
511 R.viewfac= (afmx*lens)/16.0;
514 R.viewfac= R.ycor*(afmy*lens)/16.0;
516 if(R.r.mode & R_ORTHO) {
521 R.pixsize= R.near/R.viewfac;
525 /* I think these offsets are wrong. They do not coincide with shadow */
526 /* calculations, btw. */
528 miny= R.ycor*(R.ystart+.5);
530 maxy= R.ycor*(R.yend+.4999);
531 /* My guess: (or rather, what should be) */
532 /* minx= R.xstart - 0.5; */
533 /* miny= R.ycor * (R.ystart - 0.5); */
534 /* Since the SCS-s map directly to the pixel center coordinates, we need */
535 /* to stretch the clip area a bit, not just shift it. However, this gives*/
536 /* nasty problems for parts... */
538 if(R.flag & R_SEC_FIELD) {
539 if(R.r.mode & R_ODDFIELD) {
551 xd= jit[jmode % R.osa][0];
552 yd= R.ycor*jit[jmode % R.osa][1];
556 if(G.special1 & G_HOLO) {
557 if(G.scene->camera->type==OB_CAMERA) {
558 cam= G.scene->camera->data;
559 if(cam->flag & CAM_HOLO2) {
561 if(cam->netend==0.0) cam->netend= (G.scene->r.efra);
563 fac= ((G.scene->r.cfra)-1.0)/(cam->netend)-0.5;
574 minx= R.pixsize*(minx+xd);
575 maxx= R.pixsize*(maxx+xd);
576 miny= R.pixsize*(miny+yd);
577 maxy= R.pixsize*(maxy+yd);
579 if(R.r.mode & R_ORTHO) {
580 i_window(minx, maxx, miny, maxy, R.near, 100.0*R.far, R.winmat);
582 else i_window(minx, maxx, miny, maxy, R.near, R.far, R.winmat);
587 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
590 short nr, xd, yd, xpart, ypart, xparts, yparts;
591 short a, xminb, xmaxb, yminb, ymaxb;
593 if(R.r.mode & R_BORDER) {
594 xminb= R.r.border.xmin*R.rectx;
595 xmaxb= R.r.border.xmax*R.rectx;
597 yminb= R.r.border.ymin*R.recty;
598 ymaxb= R.r.border.ymax*R.recty;
600 if(xminb<0) xminb= 0;
601 if(xmaxb>R.rectx) xmaxb= R.rectx;
602 if(yminb<0) yminb= 0;
603 if(ymaxb>R.recty) ymaxb= R.recty;
611 xparts= R.r.xparts; /* for border */
614 for(nr=0;nr<xparts*yparts;nr++)
615 allparts[nr][0]= -1; /* clear array */
617 xpart= R.rectx/xparts;
618 ypart= R.recty/yparts;
620 /* if border: test if amount of parts can be fewer */
621 if(R.r.mode & R_BORDER) {
622 a= (xmaxb-xminb-1)/xpart+1; /* amount of parts in border */
623 if(a<xparts) xparts= a;
624 a= (ymaxb-yminb-1)/ypart+1; /* amount of parts in border */
625 if(a<yparts) yparts= a;
627 xpart= (xmaxb-xminb)/xparts;
628 ypart= (ymaxb-yminb)/yparts;
631 for(nr=0; nr<xparts*yparts; nr++) {
633 if(R.r.mode & R_PANORAMA) {
636 allparts[nr][2]= R.rectx;
637 allparts[nr][3]= R.recty;
643 allparts[nr][0]= xminb+ xd*xpart;
644 allparts[nr][1]= yminb+ yd*ypart;
645 if(xd<R.r.xparts-1) allparts[nr][2]= allparts[nr][0]+xpart;
646 else allparts[nr][2]= xmaxb;
647 if(yd<R.r.yparts-1) allparts[nr][3]= allparts[nr][1]+ypart;
648 else allparts[nr][3]= ymaxb;
650 if(allparts[nr][2]-allparts[nr][0]<=0) allparts[nr][0]= -1;
651 if(allparts[nr][3]-allparts[nr][1]<=0) allparts[nr][0]= -1;
656 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
657 short setpart(short nr) /* return 0 if incorrect part */
660 if(allparts[nr][0]== -1) return 0;
662 R.xstart= allparts[nr][0]-R.afmx;
663 R.ystart= allparts[nr][1]-R.afmy;
664 R.xend= allparts[nr][2]-R.afmx;
665 R.yend= allparts[nr][3]-R.afmy;
666 R.rectx= R.xend-R.xstart;
667 R.recty= R.yend-R.ystart;
672 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
673 void addparttorect(short nr, Part *part)
675 unsigned int *rt, *rp;
676 short y, heigth, len;
678 /* the right offset in rectot */
680 rt= R.rectot+ (allparts[nr][1]*R.rectx+ allparts[nr][0]);
682 len= (allparts[nr][2]-allparts[nr][0]);
683 heigth= (allparts[nr][3]-allparts[nr][1]);
685 for(y=0;y<heigth;y++) {
686 memcpy(rt, rp, 4*len);
693 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
699 float dist, fac, fy, fz;
701 if(G.scene==0 || G.scene->camera==0) return;
703 if(G.scene->camera->type==OB_CAMERA) {
704 cam= G.scene->camera->data;
705 if(cam->flag & (CAM_HOLO1|CAM_HOLO2)) {
706 fy= G.scene->camera->loc[1];
707 fz= G.scene->camera->loc[2];
708 dist= cam->hololen*sqrt( fy*fy+ fz*fz );
710 fac= ((G.scene->r.cfra)-(G.scene->r.sfra))/((float)((G.scene->r.efra)-(G.scene->r.sfra)));
712 G.scene->camera->loc[0]= -dist+ 2*fac*dist;
717 void add_to_blurbuf(int blur)
719 static unsigned int *blurrect= 0;
726 if(R.rectot) MEM_freeN(R.rectot);
731 else if(blur==R.osa-1) {
733 blurrect= MEM_mallocN(R.rectx*R.recty*sizeof(int), "rectblur");
734 if(R.rectot) memcpy(blurrect, R.rectot, R.rectx*R.recty*4);
739 facr= 256/(R.osa-blur);
743 rtr= (char *)R.rectot;
744 rtb= (char *)blurrect;
745 tot= R.rectx*R.recty;
747 if( *((unsigned int *)rtb) != *((unsigned int *)rtr) ) {
749 if(R.r.mode & R_GAMMA) {
750 gamval= (facr* igamtab2[ rtr[0]<<8 ] + facb* igamtab2[ rtb[0]<<8 ])>>8;
751 rtb[0]= gamtab[ gamval ]>>8;
752 gamval= (facr* igamtab2[ rtr[1]<<8 ] + facb* igamtab2[ rtb[1]<<8 ])>>8;
753 rtb[1]= gamtab[ gamval ]>>8;
754 gamval= (facr* igamtab2[ rtr[2]<<8 ] + facb* igamtab2[ rtb[2]<<8 ])>>8;
755 rtb[2]= gamtab[ gamval ]>>8;
756 gamval= (facr* igamtab2[ rtr[3]<<8 ] + facb* igamtab2[ rtb[3]<<8 ])>>8;
757 rtb[3]= gamtab[ gamval ]>>8;
760 rtb[0]= (facr*rtr[0] + facb*rtb[0])>>8;
761 rtb[1]= (facr*rtr[1] + facb*rtb[1])>>8;
762 rtb[2]= (facr*rtr[2] + facb*rtb[2])>>8;
763 rtb[3]= (facr*rtr[3] + facb*rtb[3])>>8;
772 if(R.rectot) MEM_freeN(R.rectot);
780 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
782 /* not too neat... should improve... */
783 if(R.r.mode & R_UNIFIED) {
784 unifiedRenderingLoop();
791 void oldRenderLoop(void) /* here the PART and FIELD loops */
794 unsigned int *rt, *rt1, *rt2;
796 short blur, a,fields,fi,parts; /* pa is a global because of print */
797 unsigned int *border_buf= NULL;
798 unsigned int border_x= 0;
799 unsigned int border_y= 0;
801 if((R.r.mode & R_BORDER) && !(R.r.mode & R_MOVIECROP)) {
802 border_buf= R.rectot;
809 if (R.rectz) MEM_freeN(R.rectz);
814 parts= R.r.xparts*R.r.yparts;
816 if(R.r.mode & R_FIELDS) {
818 R.rectf1= R.rectf2= 0; /* field rects */
822 R.ycor= ( (float)R.r.yasp)/( (float)R.r.xasp);
827 for(fi=0; fi<fields; fi++) {
830 BLI_srand( 2*(G.scene->r.cfra)+fi);
834 R.flag|= R_RENDERING;
835 if(fi==1) R.flag |= R_SEC_FIELD;
838 /* MOTIONBLUR loop */
839 if(R.r.mode & R_MBLUR) blur= R.osa;
850 R.xend= R.xstart+R.rectx-1;
851 R.yend= R.ystart+R.recty-1;
854 if(R.r.mode & R_MBLUR) set_mblur_offs(R.osa-blur);
856 initparts(); /* always do, because of border */
859 RE_local_init_render_display();
860 RE_local_clear_render_display(R.win);
861 RE_local_timecursor((G.scene->r.cfra));
866 R.parts.first= R.parts.last= 0;
867 for(pa=0; pa<parts; pa++) {
869 if(RE_local_test_break()) break;
871 if(pa) { /* because case pa==0 has been done */
872 if(setpart(pa)==0) break;
875 if(R.r.mode & R_MBLUR) RE_setwindowclip(0, blur);
876 else RE_setwindowclip(0,-1);
878 if(R.r.mode & R_PANORAMA) setPanoRot(pa);
880 /* HOMOGENIC COORDINATES AND ZBUF AND CLIP OPTIMISATION (per part) */
881 /* There may be some interference with z-coordinate */
882 /* calculation here? */
884 doClipping(RE_projectverto);
885 if(RE_local_test_break()) break;
888 /* ZBUFFER & SHADE: zbuffer stores integer distances, and integer face indices */
889 R.rectot= (unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot");
890 R.rectz = (unsigned int *)MEM_mallocN(sizeof(int)*R.rectx*R.recty, "rectz");
892 if(R.r.mode & R_MBLUR) RE_local_printrenderinfo(0.0, R.osa - blur);
893 else RE_local_printrenderinfo(0.0, -1);
895 /* choose render pipeline type, and whether or not to use the */
896 /* delta accumulation buffer. 3 choices. */
897 if(R.r.mode & R_OSA) zbufshadeDA();
900 if(RE_local_test_break()) break;
903 if( (R.r.mode & R_BORDER) && (R.r.mode & R_MOVIECROP));
905 /* HANDLE PART OR BORDER */
906 if(parts>1 || (R.r.mode & R_BORDER)) {
908 part= MEM_callocN(sizeof(Part), "part");
909 BLI_addtail(&R.parts, part);
910 part->rect= R.rectot;
921 /* JOIN PARTS OR INSERT BORDER */
923 /* exception: crop */
924 if( (R.r.mode & R_BORDER) && (R.r.mode & R_MOVIECROP)) ;
929 if(R.r.mode & R_PANORAMA) R.rectx*= R.r.xparts;
931 if(parts>1 || (R.r.mode & R_BORDER)) {
932 if(R.rectot) MEM_freeN(R.rectot);
933 if(R.r.mode & R_BORDER) {
934 if(border_x<R.rectx || border_y<R.recty || border_buf==NULL)
935 R.rectot= (unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot");
937 R.rectot= border_buf;
939 else R.rectot=(unsigned int *)MEM_mallocN(sizeof(int)*R.rectx*R.recty, "rectot");
942 for(pa=0; pa<parts; pa++) {
943 if(allparts[pa][0]== -1) break;
946 if(R.r.mode & R_PANORAMA) {
948 allparts[pa][0] += pa*R.r.xsch;
949 allparts[pa][2] += pa*R.r.xsch;
952 addparttorect(pa, part);
959 MEM_freeN(part->rect);
962 BLI_freelistN(&R.parts);
966 if( (R.flag & R_HALO)) {
970 if(R.r.mode & R_MBLUR) {
971 add_to_blurbuf(blur);
974 /* END (blur loop) */
977 if(RE_local_test_break()) break;
984 if(R.r.mode & R_FIELDS) {
985 if(R.flag & R_SEC_FIELD) R.rectf2= R.rectot;
986 else R.rectf1= R.rectot;
990 if(RE_local_test_break()) break;
994 if(R.r.mode & R_FIELDS) {
1000 if(R.rectot) MEM_freeN(R.rectot); /* happens when a render has been stopped */
1001 R.rectot=(unsigned int *)MEM_mallocN(sizeof(int)*R.rectx*R.recty, "rectot");
1003 if(RE_local_test_break()==0) {
1006 if(R.r.mode & R_ODDFIELD) {
1017 for(a=0; a<R.recty; a+=2) {
1018 memcpy(rt, rt1, len);
1021 memcpy(rt, rt2, len);
1028 /* R.rectx= R.r.xsch; */
1029 /* if(R.r.mode & R_PANORAMA) R.rectx*= R.r.xparts; */
1030 /* R.recty= R.r.ysch; */
1032 /* if border: still do skybuf */
1033 if(R.r.mode & R_BORDER) {
1034 if( (R.r.mode & R_MOVIECROP)==0) {
1035 if(R.r.bufflag & 1) {
1039 for(y=0; y<R.recty; y++, rt+= R.rectx) scanlinesky((char *)rt, y);
1050 /* don't free R.rectz, only when its size is not the same as R.rectot */
1052 if (R.rectz && parts == 1 && (R.r.mode & R_FIELDS) == 0);
1054 if(R.rectz) MEM_freeN(R.rectz);
1058 if(R.rectf1) MEM_freeN(R.rectf1);
1060 if(R.rectf2) MEM_freeN(R.rectf2);
1066 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
1067 extern unsigned short usegamtab;
1068 void RE_initrender(struct View3D *ogl_render_view3d)
1074 /* scene data to R */
1076 R.r.postigamma= 1.0/R.r.postgamma;
1078 /* to be sure: when a premature return */
1082 /* IS RENDERING ALLOWED? */
1084 /* forbidden combination */
1085 if((R.r.mode & R_BORDER) && (R.r.mode & R_PANORAMA)) {
1086 error("No border allowed for Panorama");
1092 if(R.r.xparts*R.r.yparts>64) {
1093 error("No more than 64 parts");
1098 if(R.r.yparts>1 && (R.r.mode & R_PANORAMA)) {
1099 error("No Y-Parts allowed for Panorama");
1106 /* If an image is specified for use as backdrop, that image is loaded */
1108 if((R.r.bufflag & 1) && (G.scene->r.scemode & R_OGL)==0) {
1109 if(R.r.alphamode == R_ADDSKY) {
1110 strcpy(name, R.r.backbuf);
1111 BLI_convertstringcode(name, G.sce, G.scene->r.cfra);
1119 R.backbuf= add_image(name);
1121 if(bima && bima->id.us<1) {
1122 free_image_buffers(bima);
1125 error("No backbuf there!");
1133 usegamtab= 0; /* see also further */
1135 if(R.r.mode & (R_OSA|R_MBLUR)) {
1137 if(R.osa>16) R.osa= 16;
1139 init_render_jit(R.osa);
1140 RE_init_filt_mask();
1142 /* this value sometimes is reset temporally, for example in transp zbuf */
1143 if(R.r.mode & R_GAMMA) {
1144 if((R.r.mode & R_OSA)) usegamtab= 1;
1150 R.r.xsch= (R.r.size*R.r.xsch)/100;
1151 R.r.ysch= (R.r.size*R.r.ysch)/100;
1156 /* when rendered without camera object */
1157 /* it has to done here because of envmaps */
1162 if(R.afmx<1 || R.afmy<1) {
1163 error("Image too small");
1166 R.ycor= ( (float)R.r.yasp)/( (float)R.r.xasp);
1168 start_time= PIL_check_seconds_timer();
1170 if(R.r.scemode & R_DOSEQ) {
1174 if(R.rectot) MEM_freeN(R.rectot);
1175 R.rectot= (unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot");
1177 RE_local_timecursor((G.scene->r.cfra));
1179 if(RE_local_test_break()==0) do_render_seq();
1182 if(R.rectot) RE_local_render_display(0, R.recty-1,
1186 else if(R.r.scemode & R_OGL) {
1190 if(R.rectot) MEM_freeN(R.rectot);
1191 R.rectot= (unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot");
1193 RE_local_init_render_display();
1194 drawview3d_render(ogl_render_view3d);
1197 if(G.scene->camera==0) {
1198 G.scene->camera= scene_find_camera(G.scene);
1201 if(G.scene->camera==0) {
1208 if(G.scene->camera->type==OB_CAMERA) {
1209 Camera *cam= G.scene->camera->data;
1210 if(cam->type==CAM_ORTHO) R.r.mode |= R_ORTHO;
1213 render(); /* returns with complete rect xsch-ysch */
1217 /* display again: fields/seq/parts/pano etc */
1219 RE_local_init_render_display();
1220 RE_local_render_display(0, R.recty-1,
1224 else RE_local_clear_render_display(R.win);
1226 RE_local_printrenderinfo((PIL_check_seconds_timer() - start_time), -1);
1228 /* restore variables */
1230 R.vlr= 0; /* at cubemap */
1234 void RE_animrender(struct View3D *ogl_render_view3d)
1239 if(G.scene==0) return;
1241 /* scenedata to R: (for backbuf, R.rectx etc) */
1244 /* START ANIMLOOP, everywhere NOT the cfra from R.r is gebruikt: because of rest blender */
1245 cfrao= (G.scene->r.cfra);
1247 if(G.scene->r.scemode & R_OGL) R.r.mode &= ~R_PANORAMA;
1249 // these calculations apply for
1250 // all movie formats
1251 R.rectx= (R.r.size*R.r.xsch)/100;
1252 R.recty= (R.r.size*R.r.ysch)/100;
1253 if(R.r.mode & R_PANORAMA) {
1254 R.rectx*= R.r.xparts;
1255 R.recty*= R.r.yparts;
1260 } else if (R.r.imtype==R_MOVIE) {
1263 #if defined(_WIN32) && !defined(FREE_WINDOWS)
1264 } else if (R.r.imtype == R_AVICODEC) {
1268 } else if (R.r.imtype == R_QUICKTIME) {
1271 } else if ELEM4(R.r.imtype, R_AVIRAW, R_AVIJPEG, R_MOVIE, R_AVICODEC) {
1272 if ELEM(R.r.imtype, R_MOVIE, R_AVICODEC) {
1273 printf("Selected movie format not supported on this platform,\nusing RAW AVI instead\n");
1278 for((G.scene->r.cfra)=(G.scene->r.sfra); (G.scene->r.cfra)<=(G.scene->r.efra); (G.scene->r.cfra)++) {
1279 double starttime= PIL_check_seconds_timer();
1281 R.flag= R_ANIMRENDER;
1283 RE_initrender(ogl_render_view3d);
1286 if(RE_local_test_break()==0) {
1290 } else if (R.r.imtype == R_MOVIE) {
1291 append_movie((G.scene->r.cfra));
1293 #if defined(_WIN32) && !defined(FREE_WINDOWS)
1294 } else if (R.r.imtype == R_AVICODEC) {
1295 append_avi_codec((G.scene->r.cfra));
1297 #ifdef WITH_QUICKTIME
1298 } else if (R.r.imtype == R_QUICKTIME) {
1299 append_qt((G.scene->r.cfra));
1301 } else if ELEM4(R.r.imtype, R_AVIRAW, R_AVIJPEG, R_MOVIE, R_AVICODEC) {
1302 append_avi((G.scene->r.cfra));
1304 makepicstring(name, (G.scene->r.cfra));
1305 schrijfplaatje(name);
1306 if(RE_local_test_break()==0) printf("Saved: %s", name);
1309 timestr(PIL_check_seconds_timer()-starttime, name);
1310 printf(" Time: %s\n", name);
1311 fflush(stdout); /* needed for renderd !! */
1314 if(G.afbreek==1) break;
1318 (G.scene->r.cfra)= cfrao;
1321 if(R.r.mode & (R_FIELDS|R_MBLUR)) {
1330 } else if (R.r.imtype==R_MOVIE) {
1333 #if defined(_WIN32) && !defined(FREE_WINDOWS)
1334 } else if (R.r.imtype == R_AVICODEC) {
1337 #ifdef WITH_QUICKTIME
1338 } else if (R.r.imtype == R_QUICKTIME) {
1341 } else if ELEM4(R.r.imtype, R_AVIRAW, R_AVIJPEG, R_MOVIE, R_AVICODEC) {
1346 /* *************************************************** */
1347 /* ******************* Screendumps ******************** */
1348 /* moved to the windowControl thing */