diff options
Diffstat (limited to 'source/blender/render/intern/source/initrender.c')
-rw-r--r-- | source/blender/render/intern/source/initrender.c | 1329 |
1 files changed, 1329 insertions, 0 deletions
diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c new file mode 100644 index 00000000000..67fddc271e6 --- /dev/null +++ b/source/blender/render/intern/source/initrender.c @@ -0,0 +1,1329 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + + +/* Global includes */ + +#include <math.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +#ifdef WIN32 +#include "BLI_winstuff.h" +#endif + +#include "MEM_guardedalloc.h" + +#include "PIL_time.h" + +#include "BLI_arithb.h" +#include "BLI_blenlib.h" +#include "BLI_rand.h" + +#include "MTC_matrixops.h" + +#include "DNA_image_types.h" +#include "DNA_camera_types.h" +#include "DNA_lamp_types.h" +#include "DNA_scene_types.h" +#include "DNA_object_types.h" + +#include "BKE_utildefines.h" +#include "BKE_global.h" +#include "BKE_material.h" +#include "BKE_object.h" +#include "BKE_image.h" +#include "BKE_ipo.h" +#include "BKE_key.h" +#include "BKE_ika.h" +#include "BKE_action.h" +#include "BKE_writeavi.h" +#include "BKE_scene.h" + +#include "BIF_toolbox.h" +#include "BIF_writeavicodec.h" +#include "BIF_writemovie.h" /* start_movie(), append_movie(), end_movie() */ + +#include "BSE_drawview.h" +#include "BSE_sequence.h" + +/* this module */ +#include "render.h" +#include "render_intern.h" + +#include "RE_callbacks.h" +#include "zbuf.h" +#include "rendercore.h" /* part handler for the old renderer, shading functions */ +#include "renderPreAndPost.h" +#include "outerRenderLoop.h" +#include "renderHelp.h" +#include "jitter.h" + +/* Own includes */ +#include "initrender.h" + +/* Some crud :/ */ +#define ELEM3(a, b, c, d) ( ELEM(a, b, c) || (a)==(d) ) + + +/* uit render.c */ +extern float fmask[256], centLut[16]; +extern unsigned short *mask1[9], *mask2[9], /* *igamtab1, */ *igamtab2/*, *gamtab */; +extern char cmask[256], *centmask; + +Material defmaterial; +short pa; /* pa is globaal part ivm print */ +short allparts[65][4]; +int qscount; + +/* ********************* *********************** */ + + +void init_def_material(void) +{ + Material *ma; + + ma= &defmaterial; + + init_material(&defmaterial); + + init_render_material(ma); +} + +void RE_init_render_data(void) +{ + memset(&R, 0, sizeof(RE_Render)); + memset(&O, 0, sizeof(Osa)); + O.dxwin[0]= 1.0; + O.dywin[1]= 1.0; + + R.blove= (VertRen **)MEM_callocN(sizeof(void *)*(MAXVERT>>8),"Blove"); + R.blovl= (VlakRen **)MEM_callocN(sizeof(void *)*(MAXVLAK>>8),"Blovl"); + R.bloha= (HaloRen **)MEM_callocN(sizeof(void *)*(MAXVERT>>8),"Bloha"); + R.la= (LampRen **)MEM_mallocN(MAXLAMP*sizeof(void *),"renderlamparray"); + + init_def_material(); +} + +void RE_free_render_data() +{ + MEM_freeN(R.blove); + R.blove= 0; + MEM_freeN(R.blovl); + R.blovl= 0; + MEM_freeN(R.bloha); + R.bloha= 0; + MEM_freeN(R.la); + R.la= 0; + if(R.rectot) MEM_freeN(R.rectot); + if(R.rectz) MEM_freeN(R.rectz); + if(R.rectspare) MEM_freeN(R.rectspare); + R.rectot= 0; + R.rectz= 0; + R.rectspare= 0; + + end_render_material(&defmaterial); +} + +/* ****************** GAMMA, MASKERS en LUTS **************** */ + +float calc_weight(float *weight, int i, int j) +{ + float x, y, dist, totw= 0.0; + int a; + + for(a=0; a<R.osa; a++) { + x= jit[a][0]-0.5+ i; + y= jit[a][1]-0.5+ j; + dist= sqrt(x*x+y*y); + + weight[a]= 0.0; + + if(R.r.mode & R_GAUSS) { + if(dist<1.5) { + x = dist*1.5; + weight[a]= (1.0/exp(x*x) - 1.0/exp(1.5*1.5*1.5*1.5)); + } + } + else { + if(i==0 && j==0) weight[a]= 1.0; + } + + totw+= weight[a]; + + } + return totw; +} + +void RE_init_filt_mask(void) +{ + static int firsttime=1; + static float lastgamma= 0.0; + float gamma, igamma; + float weight[32], totw, val, *fpx1, *fpx2, *fpy1, *fpy2; + int i, j, a; + unsigned short *m1, *m2, shweight[32]; + + if(firsttime) { + for(a=0; a<9;a++) { + mask1[a]= MEM_mallocN(256*sizeof(short), "initfilt"); + mask2[a]= MEM_mallocN(256*sizeof(short), "initfilt"); + } + for(a=0; a<256; a++) { + cmask[a]= 0; + if(a & 1) cmask[a]++; + if(a & 2) cmask[a]++; + if(a & 4) cmask[a]++; + if(a & 8) cmask[a]++; + if(a & 16) cmask[a]++; + if(a & 32) cmask[a]++; + if(a & 64) cmask[a]++; + if(a & 128) cmask[a]++; + } + centmask= MEM_mallocN(65536, "Initfilt3"); + for(a=0; a<16; a++) { + centLut[a]= -0.45+((float)a)/16.0; + } + + gamtab= MEM_mallocN(65536*sizeof(short), "initGaus2"); + igamtab1= MEM_mallocN(256*sizeof(short), "initGaus2"); + igamtab2= MEM_mallocN(65536*sizeof(short), "initGaus2"); + + } + + if(R.r.alphamode==R_ALPHAKEY) gamma= 1.0; /* ??? */ + + if(R.r.mode & R_GAMMA) gamma= 2.0; + else gamma= 1.0; + igamma= 1.0/gamma; + + if(gamma!= lastgamma) { + lastgamma= gamma; + + /* gamtab: in short, uit short */ + for(a=0; a<65536; a++) { + val= a; + val/= 65535.0; + + if(gamma==2.0) val= sqrt(val); + else if(gamma!=1.0) val= pow(val, igamma); + + gamtab[a]= (65535.99*val); + } + /* inv gamtab1 : in byte, uit short */ + for(a=1; a<=256; a++) { + if(gamma==2.0) igamtab1[a-1]= a*a-1; + else if(gamma==1.0) igamtab1[a-1]= 256*a-1; + else { + val= a/256.0; + igamtab1[a-1]= (65535.0*pow(val, gamma)) -1 ; + } + } + + /* inv gamtab2 : in short, uit short */ + for(a=0; a<65536; a++) { + val= a; + val/= 65535.0; + if(gamma==2.0) val= val*val; + else val= pow(val, gamma); + + igamtab2[a]= 65535.0*val; + } + } + + if(firsttime) { + firsttime= 0; + return; + } + + val= 1.0/((float)R.osa); + for(a=0; a<256; a++) { + fmask[a]= ((float)cmask[a])*val; + } + + for(a=0; a<9;a++) { + memset(mask1[a], 0, 256*2); + memset(mask2[a], 0, 256*2); + } + + /* bereken totw */ + totw= 0.0; + for(j= -1; j<2; j++) { + for(i= -1; i<2; i++) { + totw+= calc_weight(weight, i, j); + } + } + + for(j= -1; j<2; j++) { + for(i= -1; i<2; i++) { + /* bereken ahv jit met ofset de gewichten */ + + memset(weight, 0, 32*2); + calc_weight(weight, i, j); + + for(a=0; a<16; a++) shweight[a]= weight[a]*(65535.0/totw); + + m1= mask1[ 3*(j+1)+i+1 ]; + m2= mask2[ 3*(j+1)+i+1 ]; + + for(a=0; a<256; a++) { + if(a & 1) { + m1[a]+= shweight[0]; + m2[a]+= shweight[8]; + } + if(a & 2) { + m1[a]+= shweight[1]; + m2[a]+= shweight[9]; + } + if(a & 4) { + m1[a]+= shweight[2]; + m2[a]+= shweight[10]; + } + if(a & 8) { + m1[a]+= shweight[3]; + m2[a]+= shweight[11]; + } + if(a & 16) { + m1[a]+= shweight[4]; + m2[a]+= shweight[12]; + } + if(a & 32) { + m1[a]+= shweight[5]; + m2[a]+= shweight[13]; + } + if(a & 64) { + m1[a]+= shweight[6]; + m2[a]+= shweight[14]; + } + if(a & 128) { + m1[a]+= shweight[7]; + m2[a]+= shweight[15]; + } + } + } + } + + /* centmask: de juiste subpixel ofset per masker */ + + fpx1= MEM_mallocN(256*sizeof(float), "initgauss4"); + fpx2= MEM_mallocN(256*sizeof(float), "initgauss4"); + fpy1= MEM_mallocN(256*sizeof(float), "initgauss4"); + fpy2= MEM_mallocN(256*sizeof(float), "initgauss4"); + for(a=0; a<256; a++) { + fpx1[a]= fpx2[a]= 0.0; + fpy1[a]= fpy2[a]= 0.0; + if(a & 1) { + fpx1[a]+= jit[0][0]; + fpy1[a]+= jit[0][1]; + fpx2[a]+= jit[8][0]; + fpy2[a]+= jit[8][1]; + } + if(a & 2) { + fpx1[a]+= jit[1][0]; + fpy1[a]+= jit[1][1]; + fpx2[a]+= jit[9][0]; + fpy2[a]+= jit[9][1]; + } + if(a & 4) { + fpx1[a]+= jit[2][0]; + fpy1[a]+= jit[2][1]; + fpx2[a]+= jit[10][0]; + fpy2[a]+= jit[10][1]; + } + if(a & 8) { + fpx1[a]+= jit[3][0]; + fpy1[a]+= jit[3][1]; + fpx2[a]+= jit[11][0]; + fpy2[a]+= jit[11][1]; + } + if(a & 16) { + fpx1[a]+= jit[4][0]; + fpy1[a]+= jit[4][1]; + fpx2[a]+= jit[12][0]; + fpy2[a]+= jit[12][1]; + } + if(a & 32) { + fpx1[a]+= jit[5][0]; + fpy1[a]+= jit[5][1]; + fpx2[a]+= jit[13][0]; + fpy2[a]+= jit[13][1]; + } + if(a & 64) { + fpx1[a]+= jit[6][0]; + fpy1[a]+= jit[6][1]; + fpx2[a]+= jit[14][0]; + fpy2[a]+= jit[14][1]; + } + if(a & 128) { + fpx1[a]+= jit[7][0]; + fpy1[a]+= jit[7][1]; + fpx2[a]+= jit[15][0]; + fpy2[a]+= jit[15][1]; + } + } + + for(a= (1<<R.osa)-1; a>0; a--) { + val= count_mask(a); + i= (15.9*(fpy1[a & 255]+fpy2[a>>8])/val); + i<<=4; + i+= (15.9*(fpx1[a & 255]+fpx2[a>>8])/val); + centmask[a]= i; + } + + MEM_freeN(fpx1); + MEM_freeN(fpx2); + MEM_freeN(fpy1); + MEM_freeN(fpy2); + +} + +void RE_free_filt_mask() +{ + int a; + + for(a=0; a<9; a++) { + MEM_freeN(mask1[a]); + MEM_freeN(mask2[a]); + } + MEM_freeN(gamtab); + MEM_freeN(igamtab1); + MEM_freeN(igamtab2); + + MEM_freeN(centmask); +} + +/* add stuff */ + + +void defaultlamp() +{ + LampRen *lar; + + lar= (LampRen *)MEM_callocN(sizeof(LampRen),"lampren"); + R.la[R.totlamp++]=lar; + + lar->type= LA_SUN; + lar->vec[0]= -R.viewmat[2][0]; + lar->vec[1]= -R.viewmat[2][1]; + lar->vec[2]= -R.viewmat[2][2]; + Normalise(lar->vec); + lar->r= 1.0; + lar->g= 1.0; + lar->b= 1.0; + lar->lay= 65535; +} + + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +void RE_make_existing_file(char *name) +{ + char di[FILE_MAXDIR], fi[FILE_MAXFILE]; + + strcpy(di, name); + BLI_splitdirstring(di, fi); + + /* exist testen */ + if (BLI_exists(di) == 0) { + BLI_recurdir_fileops(di); + } +} + + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +extern float holoofs; /* render.c */ +void RE_setwindowclip(int mode, int jmode) +{ + /* jmode>=0: alleen jitter doen, anders berekenen */ + /* mode==1 zet persmat en grvec */ + Camera *cam=0; + float lens, fac, minx, miny, maxx, maxy; + float xd, yd, afmx, afmy; + + if(G.scene->camera==0) return; + + afmx= R.afmx; + afmy= R.afmy; + + if(mode) { + + if(G.scene->camera->type==OB_LAMP) { + /* fac= cos( PI*((float)(256- la->spsi))/512.0 ); */ + + /* phi= acos(fac); */ + /* lens= 16.0*fac/sin(phi); */ + lens= 35.0; + R.near= 0.1; + R.far= 1000.0; + } + else if(G.scene->camera->type==OB_CAMERA) { + cam= G.scene->camera->data; + + lens= cam->lens; + R.near= cam->clipsta; + R.far= cam->clipend; + } + else { + lens= 16.0; + } + + if( (R.r.xasp*afmx) >= (R.r.yasp*afmy) ) { + R.viewfac= (afmx*lens)/16.0; + } + else { + R.viewfac= R.ycor*(afmy*lens)/16.0; + } + if(R.r.mode & R_ORTHO) { + R.near*= 100.0; /* R.far niet doen */ + R.viewfac*= 100.0; + } + + R.pixsize= R.near/R.viewfac; + + } + + /* I think these offsets are wrong. They do not coincide with shadow */ + /* calculations, btw. */ + minx= R.xstart+.5; + miny= R.ycor*(R.ystart+.5); + maxx= R.xend+.4999; + maxy= R.ycor*(R.yend+.4999); + /* My guess: (or rather, what should be) */ +/* minx= R.xstart - 0.5; */ +/* miny= R.ycor * (R.ystart - 0.5); */ + /* Since the SCS-s map directly to the pixel center coordinates, we need */ + /* to stretch the clip area a bit, not just shift it. However, this gives*/ + /* nasty problems for parts... */ + + if(R.flag & R_SEC_FIELD) { + if(R.r.mode & R_ODDFIELD) { + miny-= .5*R.ycor; + maxy-= .5*R.ycor; + } + else { + miny+= .5*R.ycor; + maxy+= .5*R.ycor; + } + } + + xd= yd= 0.0; + if(jmode!= -1) { + xd= jit[jmode % R.osa][0]; + yd= R.ycor*jit[jmode % R.osa][1]; + + } + + if(G.special1 & G_HOLO) { + if(G.scene->camera->type==OB_CAMERA) { + cam= G.scene->camera->data; + if(cam->flag & CAM_HOLO2) { + + if(cam->netend==0.0) cam->netend= (G.scene->r.efra); + + fac= ((G.scene->r.cfra)-1.0)/(cam->netend)-0.5; + fac*= (R.rectx); + fac*= cam->hololen1; + + holoofs= -fac; + minx-= fac; + maxx-= fac; + } + } + } + + minx= R.pixsize*(minx+xd); + maxx= R.pixsize*(maxx+xd); + miny= R.pixsize*(miny+yd); + maxy= R.pixsize*(maxy+yd); + + if(R.r.mode & R_ORTHO) { + /* hier de near & far vermenigvuldigen is voldoende! */ + + i_window(minx, maxx, miny, maxy, R.near, 100.0*R.far, R.winmat); + } + else i_window(minx, maxx, miny, maxy, R.near, R.far, R.winmat); + +} + + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +void initparts() +{ + short nr, xd, yd, xpart, ypart, xparts, yparts; + short a, xminb, xmaxb, yminb, ymaxb; + + if(R.r.mode & R_BORDER) { + xminb= R.r.border.xmin*R.rectx; + xmaxb= R.r.border.xmax*R.rectx; + + yminb= R.r.border.ymin*R.recty; + ymaxb= R.r.border.ymax*R.recty; + + if(xminb<0) xminb= 0; + if(xmaxb>R.rectx) xmaxb= R.rectx; + if(yminb<0) yminb= 0; + if(ymaxb>R.recty) ymaxb= R.recty; + } + else { + xminb=yminb= 0; + xmaxb= R.rectx; + ymaxb= R.recty; + } + + xparts= R.r.xparts; /* voor border */ + yparts= R.r.yparts; + + for(nr=0;nr<xparts*yparts;nr++) + allparts[nr][0]= -1; /* array leegmaken */ + + xpart= R.rectx/xparts; + ypart= R.recty/yparts; + + /* als border: testen of aantal parts minder kan */ + if(R.r.mode & R_BORDER) { + a= (xmaxb-xminb-1)/xpart+1; /* zoveel parts in border */ + if(a<xparts) xparts= a; + a= (ymaxb-yminb-1)/ypart+1; /* zoveel parts in border */ + if(a<yparts) yparts= a; + + xpart= (xmaxb-xminb)/xparts; + ypart= (ymaxb-yminb)/yparts; + } + + for(nr=0; nr<xparts*yparts; nr++) { + + if(R.r.mode & R_PANORAMA) { + allparts[nr][0]= 0; + allparts[nr][1]= 0; + allparts[nr][2]= R.rectx; + allparts[nr][3]= R.recty; + } + else { + xd= (nr % xparts); + yd= (nr-xd)/xparts; + + allparts[nr][0]= xminb+ xd*xpart; + allparts[nr][1]= yminb+ yd*ypart; + if(xd<R.r.xparts-1) allparts[nr][2]= allparts[nr][0]+xpart; + else allparts[nr][2]= xmaxb; + if(yd<R.r.yparts-1) allparts[nr][3]= allparts[nr][1]+ypart; + else allparts[nr][3]= ymaxb; + + if(allparts[nr][2]-allparts[nr][0]<=0) allparts[nr][0]= -1; + if(allparts[nr][3]-allparts[nr][1]<=0) allparts[nr][0]= -1; + } + } +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +short setpart(short nr) /* return 0 als geen goede part */ +{ + + if(allparts[nr][0]== -1) return 0; + + R.xstart= allparts[nr][0]-R.afmx; + R.ystart= allparts[nr][1]-R.afmy; + R.xend= allparts[nr][2]-R.afmx; + R.yend= allparts[nr][3]-R.afmy; + R.rectx= R.xend-R.xstart; + R.recty= R.yend-R.ystart; + + return 1; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +void addparttorect(short nr, Part *part) +{ + unsigned int *rt, *rp; + short y, heigth, len; + + /* de juiste offset in rectot */ + + rt= R.rectot+ (allparts[nr][1]*R.rectx+ allparts[nr][0]); + rp= part->rect; + len= (allparts[nr][2]-allparts[nr][0]); + heigth= (allparts[nr][3]-allparts[nr][1]); + + for(y=0;y<heigth;y++) { + memcpy(rt, rp, 4*len); + rt+=R.rectx; + rp+= len; + } +} + + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + + +void RE_holoview() +{ + Camera *cam; + float dist, fac, fy, fz; + + if(G.scene==0 || G.scene->camera==0) return; + + if(G.scene->camera->type==OB_CAMERA) { + cam= G.scene->camera->data; + if(cam->flag & (CAM_HOLO1|CAM_HOLO2)) { + fy= G.scene->camera->loc[1]; + fz= G.scene->camera->loc[2]; + dist= cam->hololen*sqrt( fy*fy+ fz*fz ); + + fac= ((G.scene->r.cfra)-(G.scene->r.sfra))/((float)((G.scene->r.efra)-(G.scene->r.sfra))); + + G.scene->camera->loc[0]= -dist+ 2*fac*dist; + } + } +} + +void add_to_blurbuf(int blur) +{ + static unsigned int *blurrect= 0; + int tot, gamval; + short facr, facb; + char *rtr, *rtb; + + if(blur<0) { + if(blurrect) { + if(R.rectot) MEM_freeN(R.rectot); + R.rectot= blurrect; + blurrect= 0; + } + } + else if(blur==R.osa-1) { + /* eerste keer */ + blurrect= MEM_mallocN(R.rectx*R.recty*sizeof(int), "rectblur"); + if(R.rectot) memcpy(blurrect, R.rectot, R.rectx*R.recty*4); + } + else if(blurrect) { + /* accumuleren */ + + facr= 256/(R.osa-blur); + facb= 256-facr; + + if(R.rectot) { + rtr= (char *)R.rectot; + rtb= (char *)blurrect; + tot= R.rectx*R.recty; + while(tot--) { + if( *((unsigned int *)rtb) != *((unsigned int *)rtr) ) { + + if(R.r.mode & R_GAMMA) { + gamval= (facr* igamtab2[ rtr[0]<<8 ] + facb* igamtab2[ rtb[0]<<8 ])>>8; + rtb[0]= gamtab[ gamval ]>>8; + gamval= (facr* igamtab2[ rtr[1]<<8 ] + facb* igamtab2[ rtb[1]<<8 ])>>8; + rtb[1]= gamtab[ gamval ]>>8; + gamval= (facr* igamtab2[ rtr[2]<<8 ] + facb* igamtab2[ rtb[2]<<8 ])>>8; + rtb[2]= gamtab[ gamval ]>>8; + gamval= (facr* igamtab2[ rtr[3]<<8 ] + facb* igamtab2[ rtb[3]<<8 ])>>8; + rtb[3]= gamtab[ gamval ]>>8; + } + else { + rtb[0]= (facr*rtr[0] + facb*rtb[0])>>8; + rtb[1]= (facr*rtr[1] + facb*rtb[1])>>8; + rtb[2]= (facr*rtr[2] + facb*rtb[2])>>8; + rtb[3]= (facr*rtr[3] + facb*rtb[3])>>8; + } + } + rtr+= 4; + rtb+= 4; + } + } + if(blur==0) { + /* laatste keer */ + if(R.rectot) MEM_freeN(R.rectot); + R.rectot= blurrect; + blurrect= 0; + } + } +} + + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +void render() { + /* not too neat... should improve... */ + if(R.r.mode & R_UNIFIED) { + unifiedRenderingLoop(); + } else { + oldRenderLoop(); + } +} + + +void oldRenderLoop(void) /* hierbinnen de PART en FIELD lussen */ +{ + Part *part; + unsigned int *rt, *rt1, *rt2; + int len, y; + short blur, a,fields,fi,parts; /* pa is globaal ivm print */ + unsigned int *border_buf= NULL; + unsigned int border_x= 0; + unsigned int border_y= 0; + + if((R.r.mode & R_BORDER) && !(R.r.mode & R_MOVIECROP)) { + border_buf= R.rectot; + border_x= R.rectx; + border_y= R.recty; + R.rectot= 0; + } + + + if (R.rectz) MEM_freeN(R.rectz); + R.rectz = 0; + + /* FIELDLUS */ + fields= 1; + parts= R.r.xparts*R.r.yparts; + + if(R.r.mode & R_FIELDS) { + fields= 2; + R.rectf1= R.rectf2= 0; /* fieldrecten */ + R.r.ysch/= 2; + R.afmy/= 2; + R.r.yasp*= 2; + R.ycor= ( (float)R.r.yasp)/( (float)R.r.xasp); + + } + + + for(fi=0; fi<fields; fi++) { + + /* INIT */ + BLI_srand( 2*(G.scene->r.cfra)+fi); + + + R.vlaknr= -1; + R.flag|= R_RENDERING; + if(fi==1) R.flag |= R_SEC_FIELD; + + + /* MOTIONBLUR lus */ + if(R.r.mode & R_MBLUR) blur= R.osa; + else blur= 1; + + + while(blur--) { + + /* WINDOW */ + R.rectx= R.r.xsch; + R.recty= R.r.ysch; + R.xstart= -R.afmx; + R.ystart= -R.afmy; + R.xend= R.xstart+R.rectx-1; + R.yend= R.ystart+R.recty-1; + + + if(R.r.mode & R_MBLUR) set_mblur_offs(R.osa-blur); + + initparts(); /* altijd doen ivm border */ + setpart(0); + + RE_local_init_render_display(); + RE_local_clear_render_display(R.win); + RE_local_timecursor((G.scene->r.cfra)); + + prepareScene(); + + /* PARTS */ + R.parts.first= R.parts.last= 0; + for(pa=0; pa<parts; pa++) { + + if(RE_local_test_break()) break; + + if(pa) { /* want pa==0 is al gedaan */ + if(setpart(pa)==0) break; + } + + if(R.r.mode & R_MBLUR) RE_setwindowclip(0, blur); + else RE_setwindowclip(0,-1); + + if(R.r.mode & R_PANORAMA) setPanoRot(pa); + + /* HOMOGENE COORDINATEN EN ZBUF EN CLIP OPT (per part) */ + /* There may be some interference with z-coordinate */ + /* calculation here? */ + + doClipping(RE_projectverto); + if(RE_local_test_break()) break; + + + /* ZBUFFER & SHADE: zbuffer stores int distances, int face indices */ + R.rectot= (unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot"); + R.rectz = (unsigned int *)MEM_mallocN(sizeof(int)*R.rectx*R.recty, "rectz"); + + if(R.r.mode & R_MBLUR) RE_local_printrenderinfo(0.0, R.osa - blur); + else RE_local_printrenderinfo(0.0, -1); + + /* choose render pipeline type, and whether or not to use the */ + /* delta accumulation buffer. 3 choices. */ + if(R.r.mode & R_OSA) zbufshadeDA(); + else zbufshade(); + + if(RE_local_test_break()) break; + + /* uitzondering */ + if( (R.r.mode & R_BORDER) && (R.r.mode & R_MOVIECROP)); + else { + /* PART OF BORDER AFHANDELEN */ + if(parts>1 || (R.r.mode & R_BORDER)) { + + part= MEM_callocN(sizeof(Part), "part"); + BLI_addtail(&R.parts, part); + part->rect= R.rectot; + R.rectot= 0; + + if (R.rectz) { + MEM_freeN(R.rectz); + R.rectz= 0; + } + } + } + } + + /* PARTS SAMENVOEGEN OF BORDER INVOEGEN */ + + /* uitzondering: crop */ + if( (R.r.mode & R_BORDER) && (R.r.mode & R_MOVIECROP)) ; + else { + R.rectx= R.r.xsch; + R.recty= R.r.ysch; + + if(R.r.mode & R_PANORAMA) R.rectx*= R.r.xparts; + + if(parts>1 || (R.r.mode & R_BORDER)) { + if(R.rectot) MEM_freeN(R.rectot); + if(R.r.mode & R_BORDER) { + if(border_x<R.rectx || border_y<R.recty || border_buf==NULL) + R.rectot= (unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot"); + else + R.rectot= border_buf; + } + else R.rectot=(unsigned int *)MEM_mallocN(sizeof(int)*R.rectx*R.recty, "rectot"); + + part= R.parts.first; + for(pa=0; pa<parts; pa++) { + if(allparts[pa][0]== -1) break; + if(part==0) break; + + if(R.r.mode & R_PANORAMA) { + if(pa) { + allparts[pa][0] += pa*R.r.xsch; + allparts[pa][2] += pa*R.r.xsch; + } + } + addparttorect(pa, part); + + part= part->next; + } + + part= R.parts.first; + while(part) { + MEM_freeN(part->rect); + part= part->next; + } + BLI_freelistN(&R.parts); + } + } + + if( (R.flag & R_HALO)) { + add_halo_flare(); + } + + if(R.r.mode & R_MBLUR) { + add_to_blurbuf(blur); + } + + /* EINDE (blurlus) */ + finalizeScene(); + + if(RE_local_test_break()) break; + } + + /* definitief vrijgeven */ + add_to_blurbuf(-1); + + /* FIELD AFHANDELEN */ + if(R.r.mode & R_FIELDS) { + if(R.flag & R_SEC_FIELD) R.rectf2= R.rectot; + else R.rectf1= R.rectot; + R.rectot= 0; + } + + if(RE_local_test_break()) break; + } + + /* FIELDS SAMENVOEGEN */ + if(R.r.mode & R_FIELDS) { + R.r.ysch*= 2; + R.afmy*= 2; + R.recty*= 2; + R.r.yasp/=2; + + if(R.rectot) MEM_freeN(R.rectot); /* komt voor bij afbreek */ + R.rectot=(unsigned int *)MEM_mallocN(sizeof(int)*R.rectx*R.recty, "rectot"); + + if(RE_local_test_break()==0) { + rt= R.rectot; + + if(R.r.mode & R_ODDFIELD) { + rt2= R.rectf1; + rt1= R.rectf2; + } + else { + rt1= R.rectf1; + rt2= R.rectf2; + } + + len= 4*R.rectx; + + for(a=0; a<R.recty; a+=2) { + memcpy(rt, rt1, len); + rt+= R.rectx; + rt1+= R.rectx; + memcpy(rt, rt2, len); + rt+= R.rectx; + rt2+= R.rectx; + } + } + } + + /* R.rectx= R.r.xsch; */ + /* if(R.r.mode & R_PANORAMA) R.rectx*= R.r.xparts; */ + /* R.recty= R.r.ysch; */ + + /* als border: wel de skybuf doen */ + if(R.r.mode & R_BORDER) { + if( (R.r.mode & R_MOVIECROP)==0) { + if(R.r.bufflag & 1) { + R.xstart= -R.afmx; + R.ystart= -R.afmy; + rt= R.rectot; + for(y=0; y<R.recty; y++, rt+= R.rectx) scanlinesky((char *)rt, y); + } + } + } + + set_mblur_offs(0); + + /* VRIJGEVEN */ + + /* zbuf test */ + + /* don't free R.rectz, only when its size is not the same as R.rectot */ + + if (R.rectz && parts == 1 && (R.r.mode & R_FIELDS) == 0); + else { + if(R.rectz) MEM_freeN(R.rectz); + R.rectz= 0; + } + + if(R.rectf1) MEM_freeN(R.rectf1); + R.rectf1= 0; + if(R.rectf2) MEM_freeN(R.rectf2); + R.rectf2= 0; +} + + + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +extern unsigned short usegamtab; +void RE_initrender(struct View3D *ogl_render_view3d) +{ + double start_time; + Image *bima; + char name[256]; + + /* scenedata naar R */ + R.r= G.scene->r; + R.r.postigamma= 1.0/R.r.postgamma; + + /* voor zekerheid: bij voortijdige return */ + R.rectx= R.r.xsch; + R.recty= R.r.ysch; + + /* MAG ER WEL WORDEN GERENDERD */ + + /* verboden combinatie */ + if((R.r.mode & R_BORDER) && (R.r.mode & R_PANORAMA)) { + error("No border allowed for Panorama"); + G.afbreek= 1; + return; + } + + + if(R.r.xparts*R.r.yparts>64) { + error("No more than 64 parts"); + G.afbreek= 1; + return; + } + + if(R.r.yparts>1 && (R.r.mode & R_PANORAMA)) { + error("No Y-Parts allowed for Panorama"); + G.afbreek= 1; + return; + } + + + /* BACKBUF TESTEN */ + /* If an image is specified for use as backdrop, that image is loaded */ + /* here. */ + if((R.r.bufflag & 1) && (G.scene->r.scemode & R_OGL)==0) { + if(R.r.alphamode == R_ADDSKY) { + strcpy(name, R.r.backbuf); + BLI_convertstringcode(name, G.sce, G.scene->r.cfra); + + if(R.backbuf) { + R.backbuf->id.us--; + bima= R.backbuf; + } + else bima= 0; + + R.backbuf= add_image(name); + + if(bima && bima->id.us<1) { + free_image_buffers(bima); + } + if(R.backbuf==0) { + error("No backbuf there!"); + G.afbreek= 1; + return; + } + } + } + + + usegamtab= 0; /* zie hieronder */ + + if(R.r.mode & (R_OSA|R_MBLUR)) { + R.osa= R.r.osa; + if(R.osa>16) R.osa= 16; + + init_render_jit(R.osa); + RE_init_filt_mask(); + + /* wordt af en toe tijdelijk op nul gezet, o.a. in transp zbuf */ + if(R.r.mode & R_GAMMA) { + if((R.r.mode & R_OSA)) usegamtab= 1; + } + } + else R.osa= 0; + + /* WINDOW */ + R.r.xsch= (R.r.size*R.r.xsch)/100; + R.r.ysch= (R.r.size*R.r.ysch)/100; + + R.afmx= R.r.xsch/2; + R.afmy= R.r.ysch/2; + + /* when rendered without camera object */ + /* it has to done here because of envmaps */ + R.near= 0.1; + R.far= 1000.0; + + + if(R.afmx<1 || R.afmy<1) { + error("Image too small"); + return; + } + R.ycor= ( (float)R.r.yasp)/( (float)R.r.xasp); + + start_time= PIL_check_seconds_timer(); + + if(R.r.scemode & R_DOSEQ) { + R.rectx= R.r.xsch; + R.recty= R.r.ysch; + + if(R.rectot) MEM_freeN(R.rectot); + R.rectot= (unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot"); + + RE_local_timecursor((G.scene->r.cfra)); + + if(RE_local_test_break()==0) do_render_seq(); + + /* displayen */ + if(R.rectot) RE_local_render_display(0, R.recty-1, + R.rectx, R.recty, + R.rectot); + } + else if(R.r.scemode & R_OGL) { + R.rectx= R.r.xsch; + R.recty= R.r.ysch; + + if(R.rectot) MEM_freeN(R.rectot); + R.rectot= (unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot"); + + RE_local_init_render_display(); + drawview3d_render(ogl_render_view3d); + } + else { + if(G.scene->camera==0) { + G.scene->camera= scene_find_camera(G.scene); + } + + if(G.scene->camera==0) { + error("No camera"); + G.afbreek=1; + return; + } + else { + + if(G.scene->camera->type==OB_CAMERA) { + Camera *cam= G.scene->camera->data; + if(cam->type==CAM_ORTHO) R.r.mode |= R_ORTHO; + } + + render(); /* keert terug met complete rect xsch-ysch */ + } + } + + /* nog eens displayen: fields/seq/parts/pano etc */ + if(R.rectot) { + RE_local_init_render_display(); + RE_local_render_display(0, R.recty-1, + R.rectx, R.recty, + R.rectot); + } + else RE_local_clear_render_display(R.win); + + RE_local_printrenderinfo((PIL_check_seconds_timer() - start_time), -1); + + /* variabelen weer goed */ + R.osatex= 0; + R.vlr= 0; /* bij cubemap */ + R.flag= 0; +} + +void RE_animrender(struct View3D *ogl_render_view3d) +{ + int cfrao; + char name[256]; + + if(G.scene==0) return; + + /* scenedata naar R: (voor backbuf, R.rectx enz) */ + R.r= G.scene->r; + + /* START ANIMLUS overal wordt NIET de cfra uit R.r gebruikt: ivm rest blender */ + cfrao= (G.scene->r.cfra); + + if(G.scene->r.scemode & R_OGL) R.r.mode &= ~R_PANORAMA; + + // these calculations apply for + // all movie formats + R.rectx= (R.r.size*R.r.xsch)/100; + R.recty= (R.r.size*R.r.ysch)/100; + if(R.r.mode & R_PANORAMA) { + R.rectx*= R.r.xparts; + R.recty*= R.r.yparts; + } + + if (0) { +#ifdef __sgi + } else if (R.r.imtype==R_MOVIE) { + start_movie(); +#endif +#ifdef _WIN32 + } else if (R.r.imtype == R_AVICODEC) { + start_avi_codec(); +#endif + } else if ELEM4(R.r.imtype, R_AVIRAW, R_AVIJPEG, R_MOVIE, R_AVICODEC) { + if ELEM(R.r.imtype, R_MOVIE, R_AVICODEC) { + printf("Selected movie format not supported on this platform,\nusing RAW AVI instead\n"); + } + start_avi(); + } + + for((G.scene->r.cfra)=(G.scene->r.sfra); (G.scene->r.cfra)<=(G.scene->r.efra); (G.scene->r.cfra)++) { + double starttime= PIL_check_seconds_timer(); + + R.flag= R_ANIMRENDER; + + RE_initrender(ogl_render_view3d); + + /* SCHRIJF PLAATJE */ + if(RE_local_test_break()==0) { + + if (0) { +#ifdef __sgi + } else if (R.r.imtype == R_MOVIE) { + append_movie((G.scene->r.cfra)); +#endif +#ifdef _WIN32 + } else if (R.r.imtype == R_AVICODEC) { + append_avi_codec((G.scene->r.cfra)); +#endif + } else if ELEM4(R.r.imtype, R_AVIRAW, R_AVIJPEG, R_MOVIE, R_AVICODEC) { + append_avi((G.scene->r.cfra)); + } else { + makepicstring(name, (G.scene->r.cfra)); + schrijfplaatje(name); + if(RE_local_test_break()==0) printf("Saved: %s", name); + } + + timestr(PIL_check_seconds_timer()-starttime, name); + printf(" Time: %s\n", name); + fflush(stdout); /* nodig voor renderd !! */ + } + + if(G.afbreek==1) break; + + } + + (G.scene->r.cfra)= cfrao; + + /* restoren tijd */ + if(R.r.mode & (R_FIELDS|R_MBLUR)) { + do_all_ipos(); + do_all_keys(); + do_all_actions(); + do_all_ikas(); + } + + if (0) { +#ifdef __sgi + } else if (R.r.imtype==R_MOVIE) { + end_movie(); +#endif +#ifdef _WIN32 + } else if (R.r.imtype == R_AVICODEC) { + end_avi_codec(); +#endif + } else if ELEM4(R.r.imtype, R_AVIRAW, R_AVIJPEG, R_MOVIE, R_AVICODEC) { + end_avi(); + } +} + +/* *************************************************** */ +/* ******************* Screendumps ******************** */ +/* moved to the windowControl thing */ |