2002-10-12 11:37:38 +00:00
|
|
|
/**
|
|
|
|
|
* $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>
|
|
|
|
|
|
2002-11-25 12:02:15 +00:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
|
#include <config.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
#ifdef WIN32
|
|
|
|
|
#include "BLI_winstuff.h"
|
|
|
|
|
#endif
|
|
|
|
|
|
2003-05-20 17:09:55 +00:00
|
|
|
#include "blendef.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
#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"
|
|
|
|
|
|
2003-04-28 11:17:21 +00:00
|
|
|
#ifdef WITH_QUICKTIME
|
2003-04-28 02:15:46 +00:00
|
|
|
#include "quicktime_export.h"
|
2003-04-28 11:17:21 +00:00
|
|
|
#endif
|
2003-04-28 02:15:46 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
/* 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"
|
2004-05-15 18:07:09 +00:00
|
|
|
#include "vanillaRenderPipe.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "renderHelp.h"
|
|
|
|
|
#include "jitter.h"
|
|
|
|
|
|
|
|
|
|
/* Own includes */
|
|
|
|
|
#include "initrender.h"
|
|
|
|
|
|
2004-01-04 22:10:36 +00:00
|
|
|
/* yafray: include for yafray export/render */
|
2004-01-05 14:53:56 +00:00
|
|
|
#include "YafRay_Api.h"
|
2004-01-04 22:10:36 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
/* Some crud :/ */
|
2004-01-04 22:10:36 +00:00
|
|
|
#define ELEM3(a, b, c, d) ( ELEM(a, b, c) || (a)==(d) )
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
|
|
2003-04-27 14:05:41 +00:00
|
|
|
/* from render.c */
|
2002-10-12 11:37:38 +00:00
|
|
|
extern float fmask[256], centLut[16];
|
|
|
|
|
extern unsigned short *mask1[9], *mask2[9], /* *igamtab1, */ *igamtab2/*, *gamtab */;
|
|
|
|
|
extern char cmask[256], *centmask;
|
|
|
|
|
|
|
|
|
|
Material defmaterial;
|
2003-04-27 14:05:41 +00:00
|
|
|
short pa; /* pa is global part, for print */
|
2002-10-12 11:37:38 +00:00
|
|
|
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;
|
|
|
|
|
|
Dynamic Face/Vert/Halo/Lamp tables:
User Info:
Hard coded limits on the total number of face, verts, halos, and lamps
is gone. Blender now allocates the tables for these on an as needed
basis. As long as your system can come up with the memory, you won't
run out. As a bonus, it also uses slightly less memory on smaller scenes.
Coder info:
This has been in tuhopuu for a while, but I don't know how hard it
has been tested. Since it now allocates only an initial 1024 tables
(of 256 verts/faces/halos each), it seems like it has been put through
it's paces. Lamps are allocated one at a time, and I start with 256.
I rendered 2.5M Faces/Verts/Halos. 4444 lamps. None the less, I left
a few printf's in the realocation to hunt bugs. I'll take them out
just before the release freeze.
Also, be on the lookout for other "sanity checks" that assume
a limited number of the above items. I think I got them all, but
you never know.
2003-10-19 21:47:03 +00:00
|
|
|
R.blove= (VertRen **)MEM_callocN(sizeof(void *)*(TABLEINITSIZE),"Blove");
|
|
|
|
|
R.blovl= (VlakRen **)MEM_callocN(sizeof(void *)*(TABLEINITSIZE),"Blovl");
|
|
|
|
|
R.bloha= (HaloRen **)MEM_callocN(sizeof(void *)*(TABLEINITSIZE),"Bloha");
|
|
|
|
|
R.la= (LampRen **)MEM_mallocN(LAMPINITSIZE*sizeof(void *),"renderlamparray");
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2003-04-27 14:05:41 +00:00
|
|
|
/* ****************** GAMMA, MASKS and LUTS **************** */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
|
float calc_weight(float *weight, int i, int j)
|
|
|
|
|
{
|
2003-12-22 22:27:51 +00:00
|
|
|
float x, y, dist, totw= 0.0, fac;
|
2002-10-12 11:37:38 +00:00
|
|
|
int a;
|
|
|
|
|
|
2003-12-22 22:27:51 +00:00
|
|
|
fac= R.r.gauss*R.r.gauss;
|
|
|
|
|
fac*= fac;
|
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
for(a=0; a<R.osa; a++) {
|
2004-05-15 18:07:09 +00:00
|
|
|
x= jit[a][0] + i;
|
|
|
|
|
y= jit[a][1] + j;
|
2002-10-12 11:37:38 +00:00
|
|
|
dist= sqrt(x*x+y*y);
|
|
|
|
|
|
|
|
|
|
weight[a]= 0.0;
|
|
|
|
|
|
So, for the platform managers to check:
- the link order for Blender has changed, the libradiosity.a has to be moved after the librender.a (obviously for a new dependency!). Check blender/source/Makefile
- there's a new file: blender/source/radiosity/intern/source/radrender.c
Here's what the new code does:
Using the core routines of the Radiosity tool, each renderface with 'emit material' and each renderface with 'radio material flag' set will be used to itterate to a global illumination solution. Per face with high energy (emit) little images are rendered (hemicubes) which makes up lookup tables to 'shoot' its energy to other faces.
In the end this energy - color - then is directly added to the pixel colors while rendering, Gouraud shaded.
Since it's done with renderfaces, it works for all primitives in Blender.
What is doesn't do yet:
- take into account textured color of faces. Currently it uses the material RGB color for filtering distributed energy.
- do some smart pre-subdividing. I don't know yet if this is useful... Right now it means that you'll have to balance the models yourself, to deliver small faces where you want a high accuracy for shadowing.
- unified render (is at my todo list)
User notes:
- per Material you want to have included in radiosity render: set the 'radio' flag. For newly added Materials it is ON by default now.
- the Ambient slider in Material controls the amount of radiosity color.
- for enabling radiosity rendering, set the F10 "Radio" button.
- the Radiosity buttons now only show the relevant radiosity rendering options. Pressing "collect meshes" will show all buttons again.
- for meshes, the faces who use Radio material always call the 'autosmooth' routine, this to make sure sharp angles (like corners in a room) do not have shared vertices. For some smooth models (like the raptor example) you might increase the standard smoothing angle from 30 to 45 degree.
Technical notes:
- I had to expand the renderface and rendervertices for it... shame on me! Faces have one pointer extra, render vertices four floats...
- The size of the hemicubes is now based at the boundbox of the entire scene (0.002 of it). This should be more reliable... to be done
- I fixed a bug in radiosity render, where sometimes backfaces where lit
In general:
I'd like everyone to play a bit with this system. It's not easy to get good results with it. A simple "hit and go" isn't there... maybe some good suggestions?
2003-08-31 20:33:46 +00:00
|
|
|
/* gaussian weighting has been cancelled */
|
2003-12-22 22:27:51 +00:00
|
|
|
if(R.r.mode & R_GAUSS) {
|
|
|
|
|
if(dist<R.r.gauss) {
|
|
|
|
|
x = dist*R.r.gauss;
|
|
|
|
|
weight[a]= (1.0/exp(x*x) - 1.0/exp(fac));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
2002-10-12 11:37:38 +00:00
|
|
|
if(i==0 && j==0) weight[a]= 1.0;
|
2003-12-22 22:27:51 +00:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
|
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");
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2003-04-27 14:05:41 +00:00
|
|
|
if(R.r.alphamode==R_ALPHAKEY) gamma= 1.0; /* gamma correction of alpha is nasty */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
|
if(R.r.mode & R_GAMMA) gamma= 2.0;
|
|
|
|
|
else gamma= 1.0;
|
|
|
|
|
igamma= 1.0/gamma;
|
|
|
|
|
|
|
|
|
|
if(gamma!= lastgamma) {
|
|
|
|
|
lastgamma= gamma;
|
|
|
|
|
|
2003-04-27 14:05:41 +00:00
|
|
|
/* gamtab: in short, out short */
|
2002-10-12 11:37:38 +00:00
|
|
|
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);
|
|
|
|
|
}
|
2003-04-27 14:05:41 +00:00
|
|
|
/* inverse gamtab1 : in byte, out short */
|
2002-10-12 11:37:38 +00:00
|
|
|
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 ;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2003-04-27 14:05:41 +00:00
|
|
|
/* inverse gamtab2 : in short, out short */
|
2002-10-12 11:37:38 +00:00
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2003-04-27 14:05:41 +00:00
|
|
|
/* calculate totw */
|
2002-10-12 11:37:38 +00:00
|
|
|
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++) {
|
2003-04-27 14:05:41 +00:00
|
|
|
/* calculate using jit, with offset the weights */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
|
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];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2003-04-27 14:05:41 +00:00
|
|
|
/* centmask: the correct subpixel offset per mask */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
|
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);
|
2004-05-15 18:07:09 +00:00
|
|
|
i= 8+(15.9*(fpy1[a & 255]+fpy2[a>>8])/val);
|
|
|
|
|
CLAMP(i, 0, 15);
|
|
|
|
|
j= 8+(15.9*(fpx1[a & 255]+fpx2[a>>8])/val);
|
|
|
|
|
CLAMP(j, 0, 15);
|
|
|
|
|
i= j + (i<<4);
|
2002-10-12 11:37:38 +00:00
|
|
|
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);
|
|
|
|
|
|
2003-04-27 14:05:41 +00:00
|
|
|
/* test exist */
|
2002-10-12 11:37:38 +00:00
|
|
|
if (BLI_exists(di) == 0) {
|
|
|
|
|
BLI_recurdir_fileops(di);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
|
|
|
|
|
|
|
|
|
void RE_setwindowclip(int mode, int jmode)
|
|
|
|
|
{
|
2004-04-06 11:21:44 +00:00
|
|
|
extern float bluroffsx, bluroffsy; // rendercore.c... hackish (ton)
|
2002-10-12 11:37:38 +00:00
|
|
|
Camera *cam=0;
|
Phew, a lot of work, and no new features...
Main target was to make the inner rendering loop using no globals anymore.
This is essential for proper usage while raytracing, it caused a lot of
hacks in the raycode as well, which even didn't work correctly for all
situations (textures especially).
Done this by creating a new local struct RenderInput, which replaces usage
of the global struct Render R. The latter now only is used to denote
image size, viewmatrix, and the like.
Making the inner render loops using no globals caused 1000s of vars to
be changed... but the result definitely is much nicer code, which enables
making 'real' shaders in a next stage.
It also enabled me to remove the hacks from ray.c
Then i went to the task of removing redundant code. Especially the calculus
of texture coords took place (identical) in three locations.
Most obvious is the change in the unified render part, which is much less
code now; it uses the same rendering routines as normal render now.
(Note; not for halos yet!)
I also removed 6 files called 'shadowbuffer' something. This was experimen-
tal stuff from NaN days. And again saved a lot of double used code.
Finally I went over the blenkernel and blender/src calls to render stuff.
Here the same local data is used now, resulting in less dependency.
I also moved render-texture to the render module, this was still in Kernel.
(new file: texture.c)
So! After this commit I will check on the autofiles, to try to fix that.
MSVC people have to do it themselves.
This commit will need quite some testing help, but I'm around!
2003-12-21 21:52:51 +00:00
|
|
|
float lens, minx, miny, maxx, maxy;
|
2002-10-12 11:37:38 +00:00
|
|
|
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) {
|
2003-04-27 14:05:41 +00:00
|
|
|
R.near*= 100.0;
|
2002-10-12 11:37:38 +00:00
|
|
|
R.viewfac*= 100.0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
R.pixsize= R.near/R.viewfac;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2004-05-15 18:07:09 +00:00
|
|
|
/* revision / simplification of subpixel offsets:
|
|
|
|
|
- the matrix will go without offset from start (e.g. -100) to end (e.g. +99).
|
|
|
|
|
- filling in with zbuffer will set offset of 0.5. to make sure clipped faces fill in too
|
|
|
|
|
- in shadepixel() again that 0.5 offset is corrected
|
|
|
|
|
*/
|
|
|
|
|
minx= R.xstart;
|
|
|
|
|
miny= R.ycor*(R.ystart);
|
|
|
|
|
maxx= R.xend;
|
|
|
|
|
maxy= R.ycor*(R.yend);
|
2004-04-06 11:21:44 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
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) {
|
2004-04-06 11:21:44 +00:00
|
|
|
bluroffsx= xd= jit[jmode % R.osa][0];
|
|
|
|
|
bluroffsy= yd= R.ycor*jit[jmode % R.osa][1];
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2004-04-06 11:21:44 +00:00
|
|
|
else bluroffsx=bluroffsy= 0.0;
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
|
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) {
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2003-04-27 14:05:41 +00:00
|
|
|
xparts= R.r.xparts; /* for border */
|
2002-10-12 11:37:38 +00:00
|
|
|
yparts= R.r.yparts;
|
|
|
|
|
|
|
|
|
|
for(nr=0;nr<xparts*yparts;nr++)
|
2003-04-27 14:05:41 +00:00
|
|
|
allparts[nr][0]= -1; /* clear array */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
|
xpart= R.rectx/xparts;
|
|
|
|
|
ypart= R.recty/yparts;
|
|
|
|
|
|
2003-04-27 14:05:41 +00:00
|
|
|
/* if border: test if amount of parts can be fewer */
|
2002-10-12 11:37:38 +00:00
|
|
|
if(R.r.mode & R_BORDER) {
|
2003-04-27 14:05:41 +00:00
|
|
|
a= (xmaxb-xminb-1)/xpart+1; /* amount of parts in border */
|
2002-10-12 11:37:38 +00:00
|
|
|
if(a<xparts) xparts= a;
|
2003-04-27 14:05:41 +00:00
|
|
|
a= (ymaxb-yminb-1)/ypart+1; /* amount of parts in border */
|
2002-10-12 11:37:38 +00:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
2003-04-27 14:05:41 +00:00
|
|
|
short setpart(short nr) /* return 0 if incorrect part */
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
2003-04-27 14:05:41 +00:00
|
|
|
/* the right offset in rectot */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
|
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 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) {
|
2003-04-27 14:05:41 +00:00
|
|
|
/* first time */
|
2002-10-12 11:37:38 +00:00
|
|
|
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) {
|
2003-04-27 14:05:41 +00:00
|
|
|
/* accumulate */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
|
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) {
|
2003-04-27 14:05:41 +00:00
|
|
|
/* last time */
|
2002-10-12 11:37:38 +00:00
|
|
|
if(R.rectot) MEM_freeN(R.rectot);
|
|
|
|
|
R.rectot= blurrect;
|
|
|
|
|
blurrect= 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2004-01-04 22:10:36 +00:00
|
|
|
/* yafray: main yafray render/export call */
|
|
|
|
|
void yafrayRender()
|
|
|
|
|
{
|
|
|
|
|
R.flag |= R_RENDERING; /* !!! */
|
2004-11-18 05:22:18 +00:00
|
|
|
|
|
|
|
|
if (R.rectz) MEM_freeN(R.rectz);
|
|
|
|
|
R.rectz = 0;
|
|
|
|
|
|
2004-07-12 03:20:31 +00:00
|
|
|
// switch must be done before prepareScene()
|
|
|
|
|
if (!R.r.YFexportxml)
|
2004-06-16 18:44:12 +00:00
|
|
|
YAF_switchFile();
|
|
|
|
|
else
|
|
|
|
|
YAF_switchPlugin();
|
2004-11-18 05:22:18 +00:00
|
|
|
|
2004-07-12 03:20:31 +00:00
|
|
|
printf("Starting scene conversion.\n");
|
|
|
|
|
prepareScene();
|
|
|
|
|
printf("Scene conversion done.\n");
|
2004-11-18 05:22:18 +00:00
|
|
|
|
2004-01-04 22:10:36 +00:00
|
|
|
YAF_exportScene();
|
|
|
|
|
finalizeScene();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
|
|
|
|
void render() {
|
2004-01-04 22:10:36 +00:00
|
|
|
/* yafray: render, see above */
|
2004-01-27 05:46:12 +00:00
|
|
|
if (R.r.renderer==R_YAFRAY)
|
2004-01-04 22:10:36 +00:00
|
|
|
yafrayRender();
|
2004-11-18 05:22:18 +00:00
|
|
|
else
|
2004-10-28 21:21:24 +00:00
|
|
|
oldRenderLoop();
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2003-04-27 14:05:41 +00:00
|
|
|
void oldRenderLoop(void) /* here the PART and FIELD loops */
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
|
|
|
|
Part *part;
|
|
|
|
|
unsigned int *rt, *rt1, *rt2;
|
|
|
|
|
int len, y;
|
2003-04-27 14:05:41 +00:00
|
|
|
short blur, a,fields,fi,parts; /* pa is a global because of print */
|
2004-01-04 22:10:36 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if (R.rectz) MEM_freeN(R.rectz);
|
|
|
|
|
R.rectz = 0;
|
|
|
|
|
|
2003-04-27 14:05:41 +00:00
|
|
|
/* FIELD LOOP */
|
2002-10-12 11:37:38 +00:00
|
|
|
fields= 1;
|
|
|
|
|
parts= R.r.xparts*R.r.yparts;
|
|
|
|
|
|
|
|
|
|
if(R.r.mode & R_FIELDS) {
|
|
|
|
|
fields= 2;
|
2003-04-27 14:05:41 +00:00
|
|
|
R.rectf1= R.rectf2= 0; /* field rects */
|
2002-10-12 11:37:38 +00:00
|
|
|
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);
|
Phew, a lot of work, and no new features...
Main target was to make the inner rendering loop using no globals anymore.
This is essential for proper usage while raytracing, it caused a lot of
hacks in the raycode as well, which even didn't work correctly for all
situations (textures especially).
Done this by creating a new local struct RenderInput, which replaces usage
of the global struct Render R. The latter now only is used to denote
image size, viewmatrix, and the like.
Making the inner render loops using no globals caused 1000s of vars to
be changed... but the result definitely is much nicer code, which enables
making 'real' shaders in a next stage.
It also enabled me to remove the hacks from ray.c
Then i went to the task of removing redundant code. Especially the calculus
of texture coords took place (identical) in three locations.
Most obvious is the change in the unified render part, which is much less
code now; it uses the same rendering routines as normal render now.
(Note; not for halos yet!)
I also removed 6 files called 'shadowbuffer' something. This was experimen-
tal stuff from NaN days. And again saved a lot of double used code.
Finally I went over the blenkernel and blender/src calls to render stuff.
Here the same local data is used now, resulting in less dependency.
I also moved render-texture to the render module, this was still in Kernel.
(new file: texture.c)
So! After this commit I will check on the autofiles, to try to fix that.
MSVC people have to do it themselves.
This commit will need quite some testing help, but I'm around!
2003-12-21 21:52:51 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
R.flag|= R_RENDERING;
|
|
|
|
|
if(fi==1) R.flag |= R_SEC_FIELD;
|
|
|
|
|
|
2003-04-27 14:05:41 +00:00
|
|
|
/* MOTIONBLUR loop */
|
2002-10-12 11:37:38 +00:00
|
|
|
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;
|
|
|
|
|
|
2004-01-04 22:10:36 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if(R.r.mode & R_MBLUR) set_mblur_offs(R.osa-blur);
|
|
|
|
|
|
2003-04-27 14:05:41 +00:00
|
|
|
initparts(); /* always do, because of border */
|
2002-10-12 11:37:38 +00:00
|
|
|
setpart(0);
|
2004-01-04 22:10:36 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
RE_local_init_render_display();
|
|
|
|
|
RE_local_clear_render_display(R.win);
|
|
|
|
|
RE_local_timecursor((G.scene->r.cfra));
|
|
|
|
|
|
|
|
|
|
prepareScene();
|
2004-01-04 22:10:36 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
/* PARTS */
|
|
|
|
|
R.parts.first= R.parts.last= 0;
|
|
|
|
|
for(pa=0; pa<parts; pa++) {
|
2004-01-04 22:10:36 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if(RE_local_test_break()) break;
|
2004-01-04 22:10:36 +00:00
|
|
|
|
2003-04-27 14:05:41 +00:00
|
|
|
if(pa) { /* because case pa==0 has been done */
|
2002-10-12 11:37:38 +00:00
|
|
|
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);
|
|
|
|
|
|
2003-04-27 14:05:41 +00:00
|
|
|
/* HOMOGENIC COORDINATES AND ZBUF AND CLIP OPTIMISATION (per part) */
|
2002-10-12 11:37:38 +00:00
|
|
|
/* There may be some interference with z-coordinate */
|
|
|
|
|
/* calculation here? */
|
|
|
|
|
|
|
|
|
|
doClipping(RE_projectverto);
|
|
|
|
|
if(RE_local_test_break()) break;
|
|
|
|
|
|
2004-01-04 22:10:36 +00:00
|
|
|
|
2004-05-15 18:07:09 +00:00
|
|
|
/* rectot is for result and integer face indices */
|
2002-10-12 11:37:38 +00:00
|
|
|
R.rectot= (unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot");
|
2004-05-15 18:07:09 +00:00
|
|
|
|
2004-04-24 12:02:39 +00:00
|
|
|
if(R.r.mode & R_MBLUR) {
|
|
|
|
|
RE_local_printrenderinfo(0.0, R.osa - blur);
|
|
|
|
|
if(G.background && blur<R.osa) printf("\n"); // newline for percentage print
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
else RE_local_printrenderinfo(0.0, -1);
|
2004-01-04 22:10:36 +00:00
|
|
|
|
2004-05-15 18:07:09 +00:00
|
|
|
if(R.r.mode & R_UNIFIED) {
|
|
|
|
|
zBufShadeAdvanced();
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
R.rectz = (unsigned int *)MEM_mallocN(sizeof(int)*R.rectx*R.recty, "rectz");
|
2004-01-04 22:10:36 +00:00
|
|
|
|
2004-05-15 18:07:09 +00:00
|
|
|
if(R.r.mode & R_OSA) zbufshadeDA();
|
|
|
|
|
else zbufshade();
|
|
|
|
|
}
|
|
|
|
|
|
2003-04-27 14:05:41 +00:00
|
|
|
/* exception */
|
2002-10-12 11:37:38 +00:00
|
|
|
if( (R.r.mode & R_BORDER) && (R.r.mode & R_MOVIECROP));
|
|
|
|
|
else {
|
2003-04-27 14:05:41 +00:00
|
|
|
/* HANDLE PART OR BORDER */
|
2002-10-12 11:37:38 +00:00
|
|
|
if(parts>1 || (R.r.mode & R_BORDER)) {
|
2004-01-04 22:10:36 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
part= MEM_callocN(sizeof(Part), "part");
|
|
|
|
|
BLI_addtail(&R.parts, part);
|
|
|
|
|
part->rect= R.rectot;
|
2003-11-08 12:50:40 +00:00
|
|
|
R.rectot= NULL;
|
2004-01-04 22:10:36 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if (R.rectz) {
|
|
|
|
|
MEM_freeN(R.rectz);
|
2003-11-08 12:50:40 +00:00
|
|
|
R.rectz= NULL;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2004-10-28 21:21:24 +00:00
|
|
|
|
|
|
|
|
if(RE_local_test_break()) break;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2003-04-27 14:05:41 +00:00
|
|
|
/* JOIN PARTS OR INSERT BORDER */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2003-04-27 14:05:41 +00:00
|
|
|
/* exception: crop */
|
2002-10-12 11:37:38 +00:00
|
|
|
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);
|
2003-11-08 12:50:40 +00:00
|
|
|
|
|
|
|
|
R.rectot=(unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot");
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
|
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)) {
|
2003-09-24 21:21:29 +00:00
|
|
|
if(RE_local_test_break()==0) add_halo_flare();
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(R.r.mode & R_MBLUR) {
|
|
|
|
|
add_to_blurbuf(blur);
|
|
|
|
|
}
|
|
|
|
|
|
2003-04-27 14:05:41 +00:00
|
|
|
/* END (blur loop) */
|
2002-10-12 11:37:38 +00:00
|
|
|
finalizeScene();
|
|
|
|
|
|
|
|
|
|
if(RE_local_test_break()) break;
|
|
|
|
|
}
|
|
|
|
|
|
2003-04-27 14:05:41 +00:00
|
|
|
/* definite free */
|
2002-10-12 11:37:38 +00:00
|
|
|
add_to_blurbuf(-1);
|
|
|
|
|
|
2003-04-27 14:05:41 +00:00
|
|
|
/* HANDLE FIELD */
|
2002-10-12 11:37:38 +00:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2003-04-27 14:05:41 +00:00
|
|
|
/* JOIN FIELDS */
|
2002-10-12 11:37:38 +00:00
|
|
|
if(R.r.mode & R_FIELDS) {
|
|
|
|
|
R.r.ysch*= 2;
|
|
|
|
|
R.afmy*= 2;
|
|
|
|
|
R.recty*= 2;
|
|
|
|
|
R.r.yasp/=2;
|
|
|
|
|
|
2003-04-27 14:05:41 +00:00
|
|
|
if(R.rectot) MEM_freeN(R.rectot); /* happens when a render has been stopped */
|
2003-11-08 12:50:40 +00:00
|
|
|
R.rectot=(unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot");
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
|
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; */
|
|
|
|
|
|
2003-04-27 14:05:41 +00:00
|
|
|
/* if border: still do skybuf */
|
2002-10-12 11:37:38 +00:00
|
|
|
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);
|
|
|
|
|
|
2003-04-27 14:05:41 +00:00
|
|
|
/* FREE */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
|
/* 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];
|
|
|
|
|
|
2003-04-27 14:05:41 +00:00
|
|
|
/* scene data to R */
|
2002-10-12 11:37:38 +00:00
|
|
|
R.r= G.scene->r;
|
|
|
|
|
R.r.postigamma= 1.0/R.r.postgamma;
|
|
|
|
|
|
2003-11-08 12:50:40 +00:00
|
|
|
/* WINDOW size (sch='scherm' dutch for screen...) */
|
|
|
|
|
R.r.xsch= (R.r.size*R.r.xsch)/100;
|
|
|
|
|
R.r.ysch= (R.r.size*R.r.ysch)/100;
|
2004-11-13 00:24:39 +00:00
|
|
|
|
2003-11-08 12:50:40 +00:00
|
|
|
R.afmx= R.r.xsch/2;
|
|
|
|
|
R.afmy= R.r.ysch/2;
|
2004-11-13 00:24:39 +00:00
|
|
|
|
2003-11-08 12:50:40 +00:00
|
|
|
/* to be sure: when a premature return (rectx can differ from xsch) */
|
2002-10-12 11:37:38 +00:00
|
|
|
R.rectx= R.r.xsch;
|
|
|
|
|
R.recty= R.r.ysch;
|
2004-11-13 00:24:39 +00:00
|
|
|
|
2003-04-27 14:05:41 +00:00
|
|
|
/* IS RENDERING ALLOWED? */
|
2004-11-13 00:24:39 +00:00
|
|
|
|
2003-04-27 14:05:41 +00:00
|
|
|
/* forbidden combination */
|
2002-10-12 11:37:38 +00:00
|
|
|
if((R.r.mode & R_BORDER) && (R.r.mode & R_PANORAMA)) {
|
|
|
|
|
error("No border allowed for Panorama");
|
|
|
|
|
G.afbreek= 1;
|
|
|
|
|
return;
|
|
|
|
|
}
|
2004-11-13 00:24:39 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
|
if(R.r.xparts*R.r.yparts>64) {
|
|
|
|
|
error("No more than 64 parts");
|
|
|
|
|
G.afbreek= 1;
|
|
|
|
|
return;
|
|
|
|
|
}
|
2004-11-13 00:24:39 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if(R.r.yparts>1 && (R.r.mode & R_PANORAMA)) {
|
|
|
|
|
error("No Y-Parts allowed for Panorama");
|
|
|
|
|
G.afbreek= 1;
|
|
|
|
|
return;
|
|
|
|
|
}
|
2004-11-13 00:24:39 +00:00
|
|
|
|
|
|
|
|
|
2003-04-27 14:05:41 +00:00
|
|
|
/* TEST BACKBUF */
|
2002-10-12 11:37:38 +00:00
|
|
|
/* 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);
|
2004-11-13 00:24:39 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if(R.backbuf) {
|
|
|
|
|
R.backbuf->id.us--;
|
|
|
|
|
bima= R.backbuf;
|
|
|
|
|
}
|
|
|
|
|
else bima= 0;
|
2004-11-13 00:24:39 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
R.backbuf= add_image(name);
|
2004-11-13 00:24:39 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if(bima && bima->id.us<1) {
|
|
|
|
|
free_image_buffers(bima);
|
|
|
|
|
}
|
|
|
|
|
if(R.backbuf==0) {
|
2004-01-30 18:07:26 +00:00
|
|
|
// error() doesnt work with render window open
|
|
|
|
|
//error("No backbuf there!");
|
|
|
|
|
printf("Error: No backbuf %s\n", name);
|
2002-10-12 11:37:38 +00:00
|
|
|
G.afbreek= 1;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2004-11-13 00:24:39 +00:00
|
|
|
|
|
|
|
|
|
2003-04-27 14:05:41 +00:00
|
|
|
usegamtab= 0; /* see also further */
|
2004-11-13 00:24:39 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if(R.r.mode & (R_OSA|R_MBLUR)) {
|
|
|
|
|
R.osa= R.r.osa;
|
|
|
|
|
if(R.osa>16) R.osa= 16;
|
2004-11-13 00:24:39 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
init_render_jit(R.osa);
|
|
|
|
|
RE_init_filt_mask();
|
2004-11-13 00:24:39 +00:00
|
|
|
|
2003-04-27 14:05:41 +00:00
|
|
|
/* this value sometimes is reset temporally, for example in transp zbuf */
|
2002-10-12 11:37:38 +00:00
|
|
|
if(R.r.mode & R_GAMMA) {
|
|
|
|
|
if((R.r.mode & R_OSA)) usegamtab= 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else R.osa= 0;
|
2004-11-13 00:24:39 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
/* when rendered without camera object */
|
|
|
|
|
/* it has to done here because of envmaps */
|
|
|
|
|
R.near= 0.1;
|
|
|
|
|
R.far= 1000.0;
|
2004-11-13 00:24:39 +00:00
|
|
|
|
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if(R.afmx<1 || R.afmy<1) {
|
|
|
|
|
error("Image too small");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
R.ycor= ( (float)R.r.yasp)/( (float)R.r.xasp);
|
2004-11-13 00:24:39 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
start_time= PIL_check_seconds_timer();
|
2004-11-13 00:24:39 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if(R.r.scemode & R_DOSEQ) {
|
|
|
|
|
R.rectx= R.r.xsch;
|
|
|
|
|
R.recty= R.r.ysch;
|
2004-11-13 00:24:39 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if(R.rectot) MEM_freeN(R.rectot);
|
|
|
|
|
R.rectot= (unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot");
|
2004-11-13 00:24:39 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
RE_local_timecursor((G.scene->r.cfra));
|
2004-11-13 00:24:39 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if(RE_local_test_break()==0) do_render_seq();
|
2004-11-13 00:24:39 +00:00
|
|
|
|
2003-04-27 14:05:41 +00:00
|
|
|
/* display */
|
2002-10-12 11:37:38 +00:00
|
|
|
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;
|
2004-11-13 00:24:39 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if(R.rectot) MEM_freeN(R.rectot);
|
|
|
|
|
R.rectot= (unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot");
|
2004-11-13 00:24:39 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
RE_local_init_render_display();
|
|
|
|
|
drawview3d_render(ogl_render_view3d);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if(G.scene->camera==0) {
|
|
|
|
|
G.scene->camera= scene_find_camera(G.scene);
|
|
|
|
|
}
|
2004-11-13 00:24:39 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if(G.scene->camera==0) {
|
|
|
|
|
error("No camera");
|
2004-11-27 18:47:51 +00:00
|
|
|
/* needed because R.rectx and R.recty can be unmatching R.rectot */
|
|
|
|
|
if(R.rectot) freeN(R.rectot);
|
|
|
|
|
R.rectot= NULL;
|
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
G.afbreek=1;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
else {
|
2004-11-13 00:24:39 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if(G.scene->camera->type==OB_CAMERA) {
|
|
|
|
|
Camera *cam= G.scene->camera->data;
|
|
|
|
|
if(cam->type==CAM_ORTHO) R.r.mode |= R_ORTHO;
|
|
|
|
|
}
|
2004-11-13 00:24:39 +00:00
|
|
|
|
2003-04-27 14:05:41 +00:00
|
|
|
render(); /* returns with complete rect xsch-ysch */
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
}
|
2004-11-13 00:24:39 +00:00
|
|
|
|
2003-04-27 14:05:41 +00:00
|
|
|
/* display again: fields/seq/parts/pano etc */
|
2004-01-04 22:10:36 +00:00
|
|
|
if(R.rectot) {
|
2002-10-12 11:37:38 +00:00
|
|
|
RE_local_init_render_display();
|
|
|
|
|
RE_local_render_display(0, R.recty-1,
|
2004-11-13 00:24:39 +00:00
|
|
|
R.rectx, R.recty,
|
|
|
|
|
R.rectot);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
else RE_local_clear_render_display(R.win);
|
2004-11-13 00:24:39 +00:00
|
|
|
|
|
|
|
|
if ((G.scene->r.scemode & R_OGL)==0) /* header gets scrabled if renderwindow holds OGL context */
|
|
|
|
|
RE_local_printrenderinfo((PIL_check_seconds_timer() - start_time), -1);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2004-01-04 22:10:36 +00:00
|
|
|
/* restore variables */
|
|
|
|
|
//R.osatex= 0;
|
|
|
|
|
//R.vlr= 0;
|
|
|
|
|
///* at cubemap */
|
2002-10-12 11:37:38 +00:00
|
|
|
R.flag= 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RE_animrender(struct View3D *ogl_render_view3d)
|
|
|
|
|
{
|
|
|
|
|
int cfrao;
|
|
|
|
|
char name[256];
|
|
|
|
|
|
|
|
|
|
if(G.scene==0) return;
|
|
|
|
|
|
2003-04-27 14:05:41 +00:00
|
|
|
/* scenedata to R: (for backbuf, R.rectx etc) */
|
2002-10-12 11:37:38 +00:00
|
|
|
R.r= G.scene->r;
|
|
|
|
|
|
2003-04-27 14:05:41 +00:00
|
|
|
/* START ANIMLOOP, everywhere NOT the cfra from R.r is gebruikt: because of rest blender */
|
2002-10-12 11:37:38 +00:00
|
|
|
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
|
2003-05-24 20:04:37 +00:00
|
|
|
#if defined(_WIN32) && !defined(FREE_WINDOWS)
|
2002-10-12 11:37:38 +00:00
|
|
|
} else if (R.r.imtype == R_AVICODEC) {
|
|
|
|
|
start_avi_codec();
|
2003-04-28 02:15:46 +00:00
|
|
|
#endif
|
|
|
|
|
#if WITH_QUICKTIME
|
|
|
|
|
} else if (R.r.imtype == R_QUICKTIME) {
|
|
|
|
|
start_qt();
|
2002-10-12 11:37:38 +00:00
|
|
|
#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);
|
|
|
|
|
|
2003-04-27 14:05:41 +00:00
|
|
|
/* WRITE IMAGE */
|
2002-10-12 11:37:38 +00:00
|
|
|
if(RE_local_test_break()==0) {
|
|
|
|
|
|
|
|
|
|
if (0) {
|
|
|
|
|
#ifdef __sgi
|
|
|
|
|
} else if (R.r.imtype == R_MOVIE) {
|
|
|
|
|
append_movie((G.scene->r.cfra));
|
|
|
|
|
#endif
|
2003-05-24 20:04:37 +00:00
|
|
|
#if defined(_WIN32) && !defined(FREE_WINDOWS)
|
2002-10-12 11:37:38 +00:00
|
|
|
} else if (R.r.imtype == R_AVICODEC) {
|
|
|
|
|
append_avi_codec((G.scene->r.cfra));
|
2003-04-28 02:15:46 +00:00
|
|
|
#endif
|
|
|
|
|
#ifdef WITH_QUICKTIME
|
|
|
|
|
} else if (R.r.imtype == R_QUICKTIME) {
|
|
|
|
|
append_qt((G.scene->r.cfra));
|
2002-10-12 11:37:38 +00:00
|
|
|
#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);
|
2003-04-27 14:05:41 +00:00
|
|
|
fflush(stdout); /* needed for renderd !! */
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(G.afbreek==1) break;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
(G.scene->r.cfra)= cfrao;
|
|
|
|
|
|
2003-04-27 14:05:41 +00:00
|
|
|
/* restore time */
|
2002-10-12 11:37:38 +00:00
|
|
|
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
|
2003-05-24 20:04:37 +00:00
|
|
|
#if defined(_WIN32) && !defined(FREE_WINDOWS)
|
2002-10-12 11:37:38 +00:00
|
|
|
} else if (R.r.imtype == R_AVICODEC) {
|
|
|
|
|
end_avi_codec();
|
2003-04-28 02:15:46 +00:00
|
|
|
#endif
|
|
|
|
|
#ifdef WITH_QUICKTIME
|
|
|
|
|
} else if (R.r.imtype == R_QUICKTIME) {
|
|
|
|
|
end_qt();
|
2002-10-12 11:37:38 +00:00
|
|
|
#endif
|
|
|
|
|
} else if ELEM4(R.r.imtype, R_AVIRAW, R_AVIJPEG, R_MOVIE, R_AVICODEC) {
|
|
|
|
|
end_avi();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* *************************************************** */
|
|
|
|
|
/* ******************* Screendumps ******************** */
|
|
|
|
|
/* moved to the windowControl thing */
|