This repository has been archived on 2023-10-09. You can view files and clone it, but cannot push or open issues or pull requests.
Files
blender-archive/source/blender/render/intern/source/initrender.c
Kent Mein d0e346d544 updated .c files to include:
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

Just need to finish cpp files now :)

Kent
--
mein@cs.umn.edu
2002-11-25 12:02:15 +00:00

1334 lines
28 KiB
C

/**
* $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 HAVE_CONFIG_H
#include <config.h>
#endif
#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 */