Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorTon Roosendaal <ton@blender.org>2006-02-01 00:49:05 +0300
committerTon Roosendaal <ton@blender.org>2006-02-01 00:49:05 +0300
commit5e3170fafd0a64d562c5c9e94af42136e8e98af6 (patch)
treeec721bb3fbeeb9c30dd377b8098f744146ddc18c /source
parent397ee6768dca9e4696c608c7731f050ce4440802 (diff)
Three features;
- Live scanline updates while rendering Using a timer system, each second now the tiles that are being processed are checked if they could use display. To make this work pretty, I had to use the threaded 'tile processor' for a single thread too, but that's now proven to be stable. Also note that these updates draw per layer, including ztransp progress separately from solid render. - Recode of ztransp OSA Until now (since blender 1.0) the ztransp part was fully rendered and added on top of the solid part with alpha-over. This adding was done before the solid part applied sub-pixel sample filtering, causing the ztransp layer to be always too blurry. Now the ztransp layer uses same sub=pixel filter, resulting in the same AA level (and filter results) as the solid part. Quite noticable with hair renders. - Vector buffer support & preliminary vector-blur Node Using the "Render Layer" panel "Vector" pass button, the motion vectors per pixel are calculated and stored. Accessible via the Compositor. The vector-blur node is horrible btw! It just uses the length of the vector to apply a filter like with current (z)blur. I'm committing it anyway, I'll experiment with it further, and who knows some surprise code shows up!
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_node.h1
-rw-r--r--source/blender/blenkernel/intern/material.c2
-rw-r--r--source/blender/blenkernel/intern/node_composite.c123
-rw-r--r--source/blender/blenloader/intern/readfile.c1
-rw-r--r--source/blender/makesdna/DNA_material_types.h1
-rw-r--r--source/blender/makesdna/DNA_scene_types.h3
-rw-r--r--source/blender/render/extern/include/RE_pipeline.h10
-rw-r--r--source/blender/render/extern/include/RE_shader_ext.h6
-rw-r--r--source/blender/render/intern/include/rendercore.h3
-rw-r--r--source/blender/render/intern/include/renderdatabase.h17
-rw-r--r--source/blender/render/intern/source/convertblender.c495
-rw-r--r--source/blender/render/intern/source/pipeline.c141
-rw-r--r--source/blender/render/intern/source/pixelblending.c95
-rw-r--r--source/blender/render/intern/source/ray.c2
-rw-r--r--source/blender/render/intern/source/rendercore.c236
-rw-r--r--source/blender/render/intern/source/renderdatabase.c68
-rw-r--r--source/blender/render/intern/source/zbuf.c162
-rw-r--r--source/blender/src/editnode.c2
-rw-r--r--source/blender/src/renderwin.c27
19 files changed, 912 insertions, 483 deletions
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index d6ebdbef083..353389fde38 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -200,6 +200,7 @@ void set_node_shader_lamp_loop(void (*lamp_loop_func)(struct ShadeInput *, str
#define CMP_NODE_FILTER 212
#define CMP_NODE_MAP_VALUE 213
#define CMP_NODE_TIME 214
+#define CMP_NODE_VECBLUR 215
#define CMP_NODE_IMAGE 220
#define CMP_NODE_R_RESULT 221
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index b95c401808d..adeac4e6dc3 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -584,7 +584,7 @@ static void do_init_render_material(Material *ma, int osa, float *amb)
}
if(ma->texco & (TEXCO_ORCO|TEXCO_REFL|TEXCO_NORM|TEXCO_STRAND|TEXCO_STRESS)) needuv= 1;
- else if(ma->texco & (TEXCO_GLOB|TEXCO_UV|TEXCO_OBJECT)) needuv= 1;
+ else if(ma->texco & (TEXCO_GLOB|TEXCO_UV|TEXCO_OBJECT|TEXCO_SPEED)) needuv= 1;
else if(ma->texco & (TEXCO_LAVECTOR|TEXCO_VIEW|TEXCO_STICKY)) needuv= 1;
}
}
diff --git a/source/blender/blenkernel/intern/node_composite.c b/source/blender/blenkernel/intern/node_composite.c
index e7bfcd722b9..89fe2da98cd 100644
--- a/source/blender/blenkernel/intern/node_composite.c
+++ b/source/blender/blenkernel/intern/node_composite.c
@@ -70,6 +70,8 @@ typedef struct CompBuf {
/* defines also used for pixel size */
#define CB_RGBA 4
+#define CB_VEC3 3
+#define CB_VEC2 2
#define CB_VAL 1
static CompBuf *alloc_compbuf(int sizex, int sizey, int type, int alloc)
@@ -82,6 +84,10 @@ static CompBuf *alloc_compbuf(int sizex, int sizey, int type, int alloc)
if(alloc) {
if(cbuf->type==CB_RGBA)
cbuf->rect= MEM_mallocT(4*sizeof(float)*sizex*sizey, "compbuf RGBA rect");
+ else if(cbuf->type==CB_VEC3)
+ cbuf->rect= MEM_mallocT(4*sizeof(float)*sizex*sizey, "compbuf Vector3 rect");
+ else if(cbuf->type==CB_VEC2)
+ cbuf->rect= MEM_mallocT(4*sizeof(float)*sizex*sizey, "compbuf Vector2 rect");
else
cbuf->rect= MEM_mallocT(sizeof(float)*sizex*sizey, "compbuf Fac rect");
cbuf->malloc= 1;
@@ -735,6 +741,7 @@ static bNodeSocketType cmp_node_rresult_out[]= {
{ SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
{ SOCK_VALUE, 0, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{ SOCK_VALUE, 0, "Z", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_VECTOR, 0, "Vec", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{ -1, 0, "" }
};
@@ -761,6 +768,11 @@ static void node_composit_exec_rresult(void *data, bNode *node, bNodeStack **in,
zbuf->rect= rl->rectz;
out[2]->data= zbuf;
}
+ if(out[3]->hasoutput && rl->rectvec) {
+ CompBuf *vecbuf= alloc_compbuf(rr->rectx, rr->recty, CB_VEC2, 0);
+ vecbuf->rect= rl->rectvec;
+ out[3]->data= vecbuf;
+ }
generate_preview(node, stackbuf);
}
@@ -1080,34 +1092,33 @@ static void do_filter3(CompBuf *out, CompBuf *in, float *filter, float fac)
float *row1, *row2, *row3;
float *fp, mfac= 1.0f-fac;
int rowlen, x, y, c;
+ int pixlen= in->type;
rowlen= in->x;
- if(in->type==CB_RGBA) {
+ for(y=2; y<in->y; y++) {
+ /* setup rows */
+ row1= in->rect + pixlen*(y-2)*rowlen;
+ row2= row1 + pixlen*rowlen;
+ row3= row2 + pixlen*rowlen;
- for(y=2; y<in->y; y++) {
- /* setup rows */
- row1= in->rect + 4*(y-2)*rowlen;
- row2= row1 + 4*rowlen;
- row3= row2 + 4*rowlen;
-
- fp= out->rect + 4*(y-1)*rowlen;
- QUATCOPY(fp, row2);
- fp+= 4;
-
- for(x=2; x<rowlen; x++) {
- for(c=0; c<4; c++) {
- fp[0]= mfac*row2[4] + fac*(filter[0]*row1[0] + filter[1]*row1[4] + filter[2]*row1[8] + filter[3]*row2[0] + filter[4]*row2[4] + filter[5]*row2[8] + filter[6]*row3[0] + filter[7]*row3[4] + filter[8]*row3[8]);
- fp++; row1++; row2++; row3++;
- }
+ fp= out->rect + pixlen*(y-1)*rowlen;
+ QUATCOPY(fp, row2);
+ fp+= pixlen;
+
+ for(x=2; x<rowlen; x++) {
+ for(c=0; c<pixlen; c++) {
+ fp[0]= mfac*row2[4] + fac*(filter[0]*row1[0] + filter[1]*row1[4] + filter[2]*row1[8] + filter[3]*row2[0] + filter[4]*row2[4] + filter[5]*row2[8] + filter[6]*row3[0] + filter[7]*row3[4] + filter[8]*row3[8]);
+ fp++; row1++; row2++; row3++;
}
}
- }
+ }
}
+static float soft[9]= {1/16.0f, 2/16.0f, 1/16.0f, 2/16.0f, 4/16.0f, 2/16.0f, 1/16.0f, 2/16.0f, 1/16.0f};
+
static void node_composit_exec_filter(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
{
- float soft[9]= {1/16.0f, 2/16.0f, 1/16.0f, 2/16.0f, 4/16.0f, 2/16.0f, 1/16.0f, 2/16.0f, 1/16.0f};
float sharp[9]= {-1,-1,-1,-1,9,-1,-1,-1,-1};
float laplace[9]= {1/8.0f, -1/8.0f, 1/8.0f, -1/8.0f, 1.0f, -1/8.0f, 1/8.0f, -1/8.0f, 1/8.0f};
float sobel[9]= {1,2,1,0,0,0,-1,-2,-1};
@@ -1821,6 +1832,81 @@ static bNodeType cmp_node_blur= {
};
+/* **************** VECTOR BLUR ******************** */
+static bNodeSocketType cmp_node_vecblur_in[]= {
+ { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
+ { SOCK_VECTOR, 1, "Vec", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+static bNodeSocketType cmp_node_vecblur_out[]= {
+ { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+
+static void fill_rct_in_image(rcti poly, float *rect, int xsize, int ysize, float *col)
+{
+ float *dest;
+ int x, y;
+
+ for(y=poly.ymin; y<poly.ymax; y++) {
+ for(x=poly.xmin; x<poly.xmax; x++) {
+ dest= rect + 4*(xsize*y + x);
+ QUATCOPY(dest, col);
+ }
+ }
+
+}
+
+
+static void node_composit_exec_vecblur(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+ CompBuf *new, *img= in[0]->data, *vecbuf= in[1]->data, *wbuf;
+ float *vect, *dest;
+ int x, y;
+
+ if(img==NULL || vecbuf==NULL || out[0]->hasoutput==0)
+ return;
+ if(vecbuf->x!=img->x || vecbuf->y!=img->y) {
+ printf("cannot do different sized vecbuf yet\n");
+ return;
+ }
+ if(vecbuf->type!=CB_VEC2) {
+ printf("input should be vecbuf\n");
+ return;
+ }
+
+ /* make weights version of vectors */
+ wbuf= alloc_compbuf(img->x, img->y, CB_VAL, 1); // allocs
+ dest= wbuf->rect;
+ vect= vecbuf->rect;
+ for(y=0; y<img->y; y++) {
+ for(x=0; x<img->x; x++, dest++, vect+=2) {
+ *dest= 0.02f*sqrt(vect[0]*vect[0] + vect[1]*vect[1]);
+ if(*dest>1.0f) *dest= 1.0f;
+ }
+ }
+
+ /* make output size of input image */
+ new= alloc_compbuf(img->x, img->y, CB_RGBA, 1); // allocs
+
+ blur_with_reference(new, img, wbuf, 100.0f, 100.0f);
+
+ free_compbuf(wbuf);
+ out[0]->data= new;
+}
+
+static bNodeType cmp_node_vecblur= {
+ /* type code */ CMP_NODE_VECBLUR,
+ /* name */ "Vector Blur",
+ /* width+range */ 120, 80, 200,
+ /* class+opts */ NODE_CLASS_OPERATOR, NODE_OPTIONS,
+ /* input sock */ cmp_node_vecblur_in,
+ /* output sock */ cmp_node_vecblur_out,
+ /* storage */ "",
+ /* execfunc */ node_composit_exec_vecblur
+
+};
+
/* ****************** types array for all shaders ****************** */
@@ -1842,6 +1928,7 @@ bNodeType *node_all_composit[]= {
&cmp_node_rresult,
&cmp_node_alphaover,
&cmp_node_blur,
+ &cmp_node_vecblur,
&cmp_node_map_value,
NULL
};
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index df36fafcab1..6342578115e 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -4910,7 +4910,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
bScreen *sc;
while(sce) {
- sce->r.mode &= ~R_ZBLUR; // disabled for release
if(sce->r.postsat==0.0) sce->r.postsat= 1.0f;
diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h
index 04cd1c29a71..b9b4eaa0c29 100644
--- a/source/blender/makesdna/DNA_material_types.h
+++ b/source/blender/makesdna/DNA_material_types.h
@@ -216,6 +216,7 @@ typedef struct Material {
/* still stored in vertex->accum, 1 D */
#define TEXCO_STRAND 8192
#define TEXCO_STRESS 16384
+#define TEXCO_SPEED 32768
/* mapto */
#define MAP_COL 1
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 01776a2e981..a59e6e06427 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -387,9 +387,10 @@ typedef struct Scene {
#define R_RAYTRACE 0x10000
/* R_GAUSS is obsolete, but used to retrieve setting from old files */
#define R_GAUSS 0x20000
+ /* fbuf obsolete... */
#define R_FBUF 0x40000
#define R_THREADS 0x80000
-#define R_ZBLUR 0x100000
+#define R_SPEED 0x100000
/* filtertype */
#define R_FILTER_BOX 0
diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h
index d34fc968e77..a9b75184e36 100644
--- a/source/blender/render/extern/include/RE_pipeline.h
+++ b/source/blender/render/extern/include/RE_pipeline.h
@@ -65,8 +65,9 @@ typedef struct RenderLayer {
unsigned int lay;
int layflag, passflag;
- float *rectf; /* standard rgba buffer */
- float *rectz; /* standard camera coordinate zbuffer */
+ float *rectf; /* 4 float, standard rgba buffer */
+ float *rectz; /* 1 float, standard camera coordinate zbuffer */
+ float *rectvec; /* 2 float, screen aligned speed vectors */
ListBase passes;
@@ -90,7 +91,10 @@ typedef struct RenderResult {
/* the main buffers */
ListBase layers;
- int actlay; /* copy of renderdata..., so display callbacks can find out */
+
+ /* allowing live updates: */
+ rcti renrect;
+ RenderLayer *renlay;
/* optional saved endresult on disk */
char exrfile[FILE_MAXDIR];
diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h
index 3524523f9bc..b8bd46d784e 100644
--- a/source/blender/render/extern/include/RE_shader_ext.h
+++ b/source/blender/render/extern/include/RE_shader_ext.h
@@ -45,9 +45,12 @@ typedef struct TexResult {
/* localized shade result data */
typedef struct ShadeResult
{
+ float combined[4];
float diff[3];
float spec[3];
float alpha;
+ float nor[3];
+ float winspeed[2];
} ShadeResult;
@@ -76,7 +79,8 @@ typedef struct ShadeInput
/* texture coordinates */
float lo[3], gl[3], uv[3], ref[3], orn[3], winco[3], sticky[3], vcol[3], rad[3];
- float vn[3], vno[3], facenor[3], view[3], refcol[4], displace[3], strand, tang[3], stress;
+ float vn[3], vno[3], facenor[3], view[3], refcol[4], displace[3];
+ float strand, tang[3], stress, winspeed[3];
/* dx/dy OSA coordinates */
float dxco[3], dyco[3];
diff --git a/source/blender/render/intern/include/rendercore.h b/source/blender/render/intern/include/rendercore.h
index cfdf34c205b..793480458c6 100644
--- a/source/blender/render/intern/include/rendercore.h
+++ b/source/blender/render/intern/include/rendercore.h
@@ -45,6 +45,7 @@
struct HaloRen;
struct ShadeInput;
+struct ShadeResult;
/* ------------------------------------------------------------------------- */
@@ -84,7 +85,7 @@ void shade_material_loop(struct ShadeInput *shi, struct ShadeResult *shr);
void zbufshade(void);
void zbufshadeDA(void); /* Delta Accum Pixel Struct */
-void *shadepixel(RenderPart *pa, float x, float y, int z, int facenr, int mask, float *col, float *rco);
+void *shadepixel(RenderPart *pa, float x, float y, int z, int facenr, int mask, struct ShadeResult *shr, float *rco);
int count_mask(unsigned short mask);
diff --git a/source/blender/render/intern/include/renderdatabase.h b/source/blender/render/intern/include/renderdatabase.h
index 6996bca7a5c..a820800fae1 100644
--- a/source/blender/render/intern/include/renderdatabase.h
+++ b/source/blender/render/intern/include/renderdatabase.h
@@ -36,8 +36,21 @@ struct HaloRen;
struct Material;
struct Render;
+/* render allocates totvert/256 of these nodes, for lookup and quick alloc */
+typedef struct VertTableNode {
+ struct VertRen *vert;
+ float *rad;
+ float *sticky;
+ float *strand;
+ float *tangent;
+ float *stress;
+ float *winspeed;
+} VertTableNode;
+
/* renderdatabase.c */
void free_renderdata_tables(struct Render *re);
+void free_renderdata_vertnodes(struct VertTableNode *vertnodes);
+
void set_normalflags(Render *re);
void project_renderdata(struct Render *re, void (*projectfunc)(float *, float mat[][4], float *), int do_pano, int part);
@@ -54,6 +67,7 @@ float *RE_vertren_get_stress(struct Render *re, struct VertRen *ver, int verify)
float *RE_vertren_get_rad(struct Render *re, struct VertRen *ver, int verify);
float *RE_vertren_get_strand(struct Render *re, struct VertRen *ver, int verify);
float *RE_vertren_get_tangent(struct Render *re, struct VertRen *ver, int verify);
+float *RE_vertren_get_winspeed(struct Render *re, struct VertRen *ver, int verify);
/* haloren->type: flags */
#define HA_ONLYSKY 1
@@ -61,8 +75,9 @@ float *RE_vertren_get_tangent(struct Render *re, struct VertRen *ver, int verify
#define HA_XALPHA 4
#define HA_FLARECIRC 8
-
+/* convertblender.c */
void init_render_world(Render *re);
+void RE_Database_FromScene_Vectors(Render *re, struct Scene *sce);
#endif /* RENDERDATABASE_H */
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index 9fbc071f0aa..beac431ce9d 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -708,6 +708,8 @@ static Material *give_render_material(Render *re, Object *ob, int nr)
if(ma->mode & MA_ZTRA)
re->flag |= R_ZTRA;
+ if(re->r.mode & R_SPEED) ma->texco |= NEED_UV;
+
return ma;
}
@@ -1404,7 +1406,7 @@ static void use_mesh_edge_lookup(Render *re, Mesh *me, DispListMesh *dlm, MEdge
}
}
-static void init_render_mesh(Render *re, Object *ob)
+static void init_render_mesh(Render *re, Object *ob, int only_verts)
{
Mesh *me;
MVert *mvert = NULL;
@@ -1493,190 +1495,196 @@ static void init_render_mesh(Render *re, Object *ob)
ms++;
}
}
- /* still to do for keys: the correct local texture coordinate */
-
- /* faces in order of color blocks */
- vertofs= re->totvert - totvert;
- for(a1=0; (a1<ob->totcol || (a1==0 && ob->totcol==0)); a1++) {
-
- ma= give_render_material(re, ob, a1+1);
-
- /* test for 100% transparant */
- ok= 1;
- if(ma->alpha==0.0 && ma->spectra==0.0) {
- ok= 0;
- /* texture on transparency? */
- for(a=0; a<MAX_MTEX; a++) {
- if(ma->mtex[a] && ma->mtex[a]->tex) {
- if(ma->mtex[a]->mapto & MAP_ALPHA) ok= 1;
- }
- }
- }
+
+ if(!only_verts) {
- /* if wire material, and we got edges, don't do the faces */
- if(ma->mode & MA_WIRE) {
- end= dlm?dlm->totedge:me->totedge;
- if(end) ok= 0;
- }
+ /* still to do for keys: the correct local texture coordinate */
- if(ok) {
- TFace *tface= NULL;
+ /* faces in order of color blocks */
+ vertofs= re->totvert - totvert;
+ for(a1=0; (a1<ob->totcol || (a1==0 && ob->totcol==0)); a1++) {
- /* radio faces need autosmooth, to separate shared vertices in corners */
- if(re->r.mode & R_RADIO)
- if(ma->mode & MA_RADIO)
- do_autosmooth= 1;
+ ma= give_render_material(re, ob, a1+1);
- end= dlm?dlm->totface:me->totface;
- if (dlm) {
- mface= dlm->mface;
- if (dlm->tface) {
- tface= dlm->tface;
- vertcol= NULL;
- } else if (dlm->mcol) {
- vertcol= (unsigned int *)dlm->mcol;
- } else {
- vertcol= NULL;
- }
- } else {
- mface= me->mface;
- if (me->tface) {
- tface= me->tface;
- vertcol= NULL;
- } else if (me->mcol) {
- vertcol= (unsigned int *)me->mcol;
- } else {
- vertcol= NULL;
+ /* test for 100% transparant */
+ ok= 1;
+ if(ma->alpha==0.0 && ma->spectra==0.0) {
+ ok= 0;
+ /* texture on transparency? */
+ for(a=0; a<MAX_MTEX; a++) {
+ if(ma->mtex[a] && ma->mtex[a]->tex) {
+ if(ma->mtex[a]->mapto & MAP_ALPHA) ok= 1;
+ }
}
}
+
+ /* if wire material, and we got edges, don't do the faces */
+ if(ma->mode & MA_WIRE) {
+ end= dlm?dlm->totedge:me->totedge;
+ if(end) ok= 0;
+ }
- for(a=0; a<end; a++) {
- int v1, v2, v3, v4, flag;
-
- if( mface->mat_nr==a1 ) {
- float len;
-
- v1= mface->v1;
- v2= mface->v2;
- v3= mface->v3;
- v4= mface->v4;
- flag= mface->flag & ME_SMOOTH;
-
- vlr= RE_findOrAddVlak(re, re->totvlak++);
- vlr->ob= ob;
- vlr->v1= RE_findOrAddVert(re, vertofs+v1);
- vlr->v2= RE_findOrAddVert(re, vertofs+v2);
- vlr->v3= RE_findOrAddVert(re, vertofs+v3);
- if(v4) vlr->v4= RE_findOrAddVert(re, vertofs+v4);
- else vlr->v4= 0;
-
- /* render normals are inverted in render */
- if(vlr->v4) len= CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co,
- vlr->v1->co, vlr->n);
- else len= CalcNormFloat(vlr->v3->co, vlr->v2->co, vlr->v1->co,
- vlr->n);
+ if(ok) {
+ TFace *tface= NULL;
- vlr->mat= ma;
- vlr->flag= flag;
- if((me->flag & ME_NOPUNOFLIP) ) {
- vlr->flag |= R_NOPUNOFLIP;
+ /* radio faces need autosmooth, to separate shared vertices in corners */
+ if(re->r.mode & R_RADIO)
+ if(ma->mode & MA_RADIO)
+ do_autosmooth= 1;
+
+ end= dlm?dlm->totface:me->totface;
+ if (dlm) {
+ mface= dlm->mface;
+ if (dlm->tface) {
+ tface= dlm->tface;
+ vertcol= NULL;
+ } else if (dlm->mcol) {
+ vertcol= (unsigned int *)dlm->mcol;
+ } else {
+ vertcol= NULL;
}
- vlr->ec= 0; /* mesh edges rendered separately */
- vlr->lay= ob->lay;
+ } else {
+ mface= me->mface;
+ if (me->tface) {
+ tface= me->tface;
+ vertcol= NULL;
+ } else if (me->mcol) {
+ vertcol= (unsigned int *)me->mcol;
+ } else {
+ vertcol= NULL;
+ }
+ }
- if(len==0) re->totvlak--;
- else {
- if(dlm) {
- if(tface) {
- vlr->tface= BLI_memarena_alloc(re->memArena, sizeof(TFace));
- vlr->vcol= vlr->tface->col;
- memcpy(vlr->tface, tface, sizeof(TFace));
- }
- else if (vertcol) {
- vlr->vcol= BLI_memarena_alloc(re->memArena, sizeof(int)*4);
- memcpy(vlr->vcol, vertcol+4*a, sizeof(int)*4);
- }
- } else {
- if(tface) {
- vlr->vcol= tface->col;
- vlr->tface= tface;
- }
- else if (vertcol) {
- vlr->vcol= vertcol+4*a;
+ for(a=0; a<end; a++) {
+ int v1, v2, v3, v4, flag;
+
+ if( mface->mat_nr==a1 ) {
+ float len;
+
+ v1= mface->v1;
+ v2= mface->v2;
+ v3= mface->v3;
+ v4= mface->v4;
+ flag= mface->flag & ME_SMOOTH;
+
+ vlr= RE_findOrAddVlak(re, re->totvlak++);
+ vlr->ob= ob;
+ vlr->v1= RE_findOrAddVert(re, vertofs+v1);
+ vlr->v2= RE_findOrAddVert(re, vertofs+v2);
+ vlr->v3= RE_findOrAddVert(re, vertofs+v3);
+ if(v4) vlr->v4= RE_findOrAddVert(re, vertofs+v4);
+ else vlr->v4= 0;
+
+ /* render normals are inverted in render */
+ if(vlr->v4) len= CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co,
+ vlr->v1->co, vlr->n);
+ else len= CalcNormFloat(vlr->v3->co, vlr->v2->co, vlr->v1->co,
+ vlr->n);
+
+ vlr->mat= ma;
+ vlr->flag= flag;
+ if((me->flag & ME_NOPUNOFLIP) ) {
+ vlr->flag |= R_NOPUNOFLIP;
+ }
+ vlr->ec= 0; /* mesh edges rendered separately */
+ vlr->lay= ob->lay;
+
+ if(len==0) re->totvlak--;
+ else {
+ if(dlm) {
+ if(tface) {
+ vlr->tface= BLI_memarena_alloc(re->memArena, sizeof(TFace));
+ vlr->vcol= vlr->tface->col;
+ memcpy(vlr->tface, tface, sizeof(TFace));
+ }
+ else if (vertcol) {
+ vlr->vcol= BLI_memarena_alloc(re->memArena, sizeof(int)*4);
+ memcpy(vlr->vcol, vertcol+4*a, sizeof(int)*4);
+ }
+ } else {
+ if(tface) {
+ vlr->vcol= tface->col;
+ vlr->tface= tface;
+ }
+ else if (vertcol) {
+ vlr->vcol= vertcol+4*a;
+ }
}
}
}
- }
- mface++;
- if(tface) tface++;
+ mface++;
+ if(tface) tface++;
+ }
}
}
- }
-
- /* exception... we do edges for wire mode. potential conflict when faces exist... */
- end= dlm?dlm->totedge:me->totedge;
- mvert= dlm?dlm->mvert:me->mvert;
- ma= give_render_material(re, ob, 1);
- if(end && (ma->mode & MA_WIRE)) {
- MEdge *medge;
- struct edgesort *edgetable;
- int totedge;
-
- medge= dlm?dlm->medge:me->medge;
- /* we want edges to have UV and vcol too... */
- edgetable= make_mesh_edge_lookup(me, dlm, &totedge);
-
- for(a1=0; a1<end; a1++, medge++) {
- if (medge->flag&ME_EDGERENDER) {
- MVert *v0 = &mvert[medge->v1];
- MVert *v1 = &mvert[medge->v2];
+ /* exception... we do edges for wire mode. potential conflict when faces exist... */
+ end= dlm?dlm->totedge:me->totedge;
+ mvert= dlm?dlm->mvert:me->mvert;
+ ma= give_render_material(re, ob, 1);
+ if(end && (ma->mode & MA_WIRE)) {
+ MEdge *medge;
+ struct edgesort *edgetable;
+ int totedge;
+
+ medge= dlm?dlm->medge:me->medge;
+
+ /* we want edges to have UV and vcol too... */
+ edgetable= make_mesh_edge_lookup(me, dlm, &totedge);
+
+ for(a1=0; a1<end; a1++, medge++) {
+ if (medge->flag&ME_EDGERENDER) {
+ MVert *v0 = &mvert[medge->v1];
+ MVert *v1 = &mvert[medge->v2];
- vlr= RE_findOrAddVlak(re, re->totvlak++);
- vlr->ob= ob;
- vlr->v1= RE_findOrAddVert(re, vertofs+medge->v1);
- vlr->v2= RE_findOrAddVert(re, vertofs+medge->v2);
- vlr->v3= vlr->v2;
- vlr->v4= NULL;
-
- if(edgetable) {
- use_mesh_edge_lookup(re, me, dlm, medge, vlr, edgetable, totedge);
+ vlr= RE_findOrAddVlak(re, re->totvlak++);
+ vlr->ob= ob;
+ vlr->v1= RE_findOrAddVert(re, vertofs+medge->v1);
+ vlr->v2= RE_findOrAddVert(re, vertofs+medge->v2);
+ vlr->v3= vlr->v2;
+ vlr->v4= NULL;
+
+ if(edgetable) {
+ use_mesh_edge_lookup(re, me, dlm, medge, vlr, edgetable, totedge);
+ }
+
+ xn= (v0->no[0]+v1->no[0]);
+ yn= (v0->no[1]+v1->no[1]);
+ zn= (v0->no[2]+v1->no[2]);
+ /* transpose ! */
+ vlr->n[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
+ vlr->n[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
+ vlr->n[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
+ Normalise(vlr->n);
+
+ vlr->mat= ma;
+ vlr->flag= 0;
+ vlr->ec= ME_V1V2;
+ vlr->lay= ob->lay;
}
-
- xn= (v0->no[0]+v1->no[0]);
- yn= (v0->no[1]+v1->no[1]);
- zn= (v0->no[2]+v1->no[2]);
- /* transpose ! */
- vlr->n[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
- vlr->n[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
- vlr->n[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
- Normalise(vlr->n);
-
- vlr->mat= ma;
- vlr->flag= 0;
- vlr->ec= ME_V1V2;
- vlr->lay= ob->lay;
}
+ if(edgetable)
+ MEM_freeN(edgetable);
}
- if(edgetable)
- MEM_freeN(edgetable);
}
}
- if (test_for_displace(re, ob ) ) {
- calc_vertexnormals(re, totverto, totvlako, 0);
- do_displacement(re, ob, totvlako, re->totvlak-totvlako, totverto, re->totvert-totverto);
- }
+ if(!only_verts) {
+ if (test_for_displace(re, ob ) ) {
+ calc_vertexnormals(re, totverto, totvlako, 0);
+ do_displacement(re, ob, totvlako, re->totvlak-totvlako, totverto, re->totvert-totverto);
+ }
- if(do_autosmooth || (me->flag & ME_AUTOSMOOTH)) {
- autosmooth(re, totverto, totvlako, me->smoothresh);
- }
+ if(do_autosmooth || (me->flag & ME_AUTOSMOOTH)) {
+ autosmooth(re, totverto, totvlako, me->smoothresh);
+ }
- calc_vertexnormals(re, totverto, totvlako, need_tangent);
+ calc_vertexnormals(re, totverto, totvlako, need_tangent);
- if(need_stress)
- calc_edge_stress(re, me, totverto, totvlako);
+ if(need_stress)
+ calc_edge_stress(re, me, totverto, totvlako);
+ }
if(dlm) displistmesh_free(dlm);
if(dm_needsfree) dm->release(dm);
@@ -2422,7 +2430,7 @@ static void set_phong_threshold(Render *re, Object *ob, int startface, int numfa
}
}
-static void init_render_object(Render *re, Object *ob)
+static void init_render_object(Render *re, Object *ob, int only_verts)
{
float mat[4][4];
int startface, startvert;
@@ -2439,7 +2447,7 @@ static void init_render_object(Render *re, Object *ob)
else if(ob->type==OB_SURF)
init_render_surf(re, ob);
else if(ob->type==OB_MESH)
- init_render_mesh(re, ob);
+ init_render_mesh(re, ob, only_verts);
else if(ob->type==OB_MBALL)
init_render_mball(re, ob);
else {
@@ -2735,8 +2743,8 @@ void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view)
Base *base;
Object *ob;
Scene *sce;
- unsigned int lay;
float mat[4][4];
+ unsigned int lay;
re->scene= scene;
@@ -2799,7 +2807,7 @@ void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view)
if (re->r.renderer==R_YAFRAY) {
if ((ob->type!=OB_MBALL) && ((ob->transflag & OB_DUPLIFRAMES)!=0)) {
printf("Object %s has OB_DUPLIFRAMES set, adding to renderlist\n", ob->id.name);
- init_render_object(re, ob);
+ init_render_object(re, ob, 0);
}
}
/* before make duplis, update particle for current frame */
@@ -2811,7 +2819,7 @@ void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view)
}
if(ob->type==OB_MBALL) {
- init_render_object(re, ob);
+ init_render_object(re, ob, 0);
}
else {
DupliObject *dob;
@@ -2833,7 +2841,7 @@ void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view)
printf("Adding dupli matrix for object %s\n", obd->id.name);
YAF_addDupliMtx(obd);
}
- else init_render_object(re, obd);
+ else init_render_object(re, obd, 0);
}
Mat4CpyMat4(obd->obmat, dob->omat);
}
@@ -2853,14 +2861,14 @@ void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view)
(ob->parent->type!=OB_LATTICE) && YAF_objectKnownData(ob))
printf("From parent: Added dupli matrix for linked data object %s\n", ob->id.name);
else
- init_render_object(re, ob);
+ init_render_object(re, ob, 0);
}
else if ((ob->type!=OB_EMPTY) && (ob->type!=OB_LAMP) && (ob->type!=OB_ARMATURE) && YAF_objectKnownData(ob))
printf("Added dupli matrix for linked data object %s\n", ob->id.name);
else
- init_render_object(re, ob);
+ init_render_object(re, ob, 0);
}
- else init_render_object(re, ob);
+ else init_render_object(re, ob, 0);
}
}
@@ -2895,6 +2903,7 @@ void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view)
if(lar->shb) {
makeshadowbuf(re, lar);
}
+ re->stats_draw(&re->i);
}
/* yafray: 'direct' radiosity, environment maps and octree init not needed for yafray render */
@@ -2924,6 +2933,158 @@ void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view)
}
+static void database_fromscene_vectors(Render *re, Scene *scene)
+{
+ extern int slurph_opt; /* key.c */
+ Base *base;
+ Object *ob;
+ Scene *sce;
+ float mat[4][4];
+ unsigned int lay;
+
+ re->scene= scene;
+
+ /* XXX add test if dbase was filled already? */
+
+ re->memArena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE);
+ re->totvlak=re->totvert=re->totlamp=re->tothalo= 0;
+ re->lights.first= re->lights.last= NULL;
+
+ slurph_opt= 0;
+
+ /* in localview, lamps are using normal layers, objects only local bits */
+ if(re->scene->lay & 0xFF000000) lay= re->scene->lay & 0xFF000000;
+ else lay= re->scene->lay;
+
+ /* applies changes fully, still using G.scene for timing... */
+ G.scene->r.cfra--;
+ scene_update_for_newframe(re->scene, lay);
+ G.scene->r.cfra++;
+
+ /* if no camera, viewmat should have been set! */
+ if(re->scene->camera) {
+ Mat4Ortho(re->scene->camera->obmat);
+ Mat4Invert(mat, re->scene->camera->obmat);
+ RE_SetView(re, mat);
+ }
+
+ for(SETLOOPER(re->scene, base)) {
+ ob= base->object;
+ /* imat objects has to be done here, since displace can have texture using Object map-input */
+ MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
+ MTC_Mat4Invert(ob->imat, mat);
+ /* each object should only be rendered once */
+ ob->flag &= ~OB_DONE;
+ }
+
+ /* MAKE RENDER DATA */
+
+ for(SETLOOPER(re->scene, base)) {
+ ob= base->object;
+
+ /* OB_DONE means the object itself got duplicated, so was already converted */
+ if(ob->flag & OB_DONE);
+ else if( (base->lay & lay) || (ob->type==OB_LAMP && (base->lay & re->scene->lay)) ) {
+ if(ob->transflag & OB_DUPLI) {
+
+ /* before make duplis, update particle for current frame */
+ if(ob->transflag & OB_DUPLIVERTS) {
+ PartEff *paf= give_parteff(ob);
+ if(paf) {
+ if(paf->flag & PAF_ANIMATED) build_particle_system(ob);
+ }
+ }
+
+ if(ob->type==OB_MBALL) {
+ init_render_object(re, ob, 1);
+ }
+ else {
+ DupliObject *dob;
+ ListBase *lb= object_duplilist(sce, ob);
+
+ for(dob= lb->first; dob; dob= dob->next) {
+ Object *obd= dob->ob;
+ Mat4CpyMat4(obd->obmat, dob->mat);
+
+ if(obd->type!=OB_MBALL) {
+ init_render_object(re, obd, 1);
+ }
+ Mat4CpyMat4(obd->obmat, dob->omat);
+ }
+ BLI_freelistN(lb);
+ }
+ }
+ else {
+ init_render_object(re, ob, 1);
+ }
+
+ }
+ }
+
+ project_renderdata(re, projectverto, re->r.mode & R_PANORAMA, 0);
+}
+
+void RE_Database_FromScene_Vectors(Render *re, Scene *sce)
+{
+ struct VertTableNode *vertnodes;
+ int vertnodeslen= 0;
+ printf("creating speed vectors \n");
+ re->r.mode |= R_SPEED;
+
+ /* creates entire dbase */
+ database_fromscene_vectors(re, sce);
+
+ /* copy away vertex info */
+ vertnodes= re->vertnodes;
+ vertnodeslen= re->vertnodeslen;
+ re->vertnodes= NULL;
+ re->vertnodeslen= 0;
+
+ /* free dbase and make the real one */
+ RE_Database_Free(re);
+
+ RE_Database_FromScene(re, sce, 1);
+
+ if(re->vertnodeslen!=vertnodeslen) {
+ printf("ERROR: vertex tables different in size %d %d\n", re->vertnodeslen, vertnodeslen);
+ }
+ else {
+ VertRen *ver= NULL, *oldver= NULL;
+ float *speed, div, zco[2], oldzco[2];
+ float zmulx= re->winx/2, zmuly= re->winy/2;
+ int a;
+
+ for(a=0; a< re->totvert;a++) {
+ if((a & 255)==0) {
+ ver= re->vertnodes[a>>8].vert;
+ oldver= vertnodes[a>>8].vert;
+ }
+ else {
+ ver++;
+ oldver++;
+ }
+
+ /* now map both hocos to screenspace */
+ div= 1.0f/ver->ho[3];
+ zco[0]= zmulx*(1.0+ver->ho[0]*div);
+ zco[1]= zmuly*(1.0+ver->ho[1]*div);
+
+ div= 1.0f/oldver->ho[3];
+ oldzco[0]= zmulx*(1.0+oldver->ho[0]*div);
+ oldzco[1]= zmuly*(1.0+oldver->ho[1]*div);
+
+ speed= RE_vertren_get_winspeed(re, ver, 1);
+ speed[0]= oldzco[0] - zco[0];
+ speed[1]= oldzco[1] - zco[1];
+ //printf("speed %d %f %f\n", a, speed[0], speed[1]);
+ }
+ }
+
+ free_renderdata_vertnodes(vertnodes);
+
+}
+
+
/* exported call to recalculate hoco for vertices, when winmat changed */
void RE_DataBase_ApplyWindow(Render *re)
{
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index 375cb5f3a0c..e4268735e8a 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -150,6 +150,7 @@ static void free_render_result(RenderResult *res)
RenderLayer *rl= res->layers.first;
if(rl->rectf) RE_freeN(rl->rectf);
if(rl->rectz) RE_freeN(rl->rectz);
+ if(rl->rectvec) RE_freeN(rl->rectvec);
BLI_remlink(&res->layers, rl);
RE_freeN(rl);
}
@@ -193,9 +194,6 @@ static RenderResult *new_render_result(Render *re, rcti *partrct, int crop)
rr->tilerect.ymin= partrct->ymin - re->disprect.ymin;
rr->tilerect.ymax= partrct->ymax - re->disprect.ymax;
- /* copy, so display callbacks can find out too */
- rr->actlay= re->r.actlay;
-
/* check renderdata for amount of layers */
for(srl= re->r.layers.first; srl; srl= srl->next) {
rl= RE_callocN(sizeof(RenderLayer), "new render layer");
@@ -209,6 +207,8 @@ static RenderResult *new_render_result(Render *re, rcti *partrct, int crop)
rl->rectf= RE_callocN(rectx*recty*sizeof(float)*4, "layer float rgba");
if(srl->passflag & SCE_PASS_Z)
rl->rectz= RE_callocN(rectx*recty*sizeof(float), "layer float Z");
+ if(srl->passflag & SCE_PASS_VECTOR)
+ rl->rectvec= RE_callocN(rectx*recty*sizeof(float)*2, "layer float Vector");
}
/* previewrender and envmap don't do layers, so we make a default one */
@@ -229,6 +229,47 @@ static RenderResult *new_render_result(Render *re, rcti *partrct, int crop)
return rr;
}
+static int render_result_needs_vector(RenderResult *rr)
+{
+ RenderLayer *rl;
+
+ for(rl= rr->layers.first; rl; rl= rl->next)
+ if(rl->passflag & SCE_PASS_VECTOR)
+ return 1;
+ return 0;
+}
+
+static void do_merge_tile(RenderResult *rr, RenderResult *rrpart, float *target, float *tile, int pixsize)
+{
+ int y, ofs, copylen, tilex, tiley;
+
+ copylen= tilex= rrpart->rectx;
+ tiley= rrpart->recty;
+
+ if(rrpart->crop) { /* filters add pixel extra */
+ tile+= pixsize*(rrpart->crop + rrpart->crop*tilex);
+
+ copylen= tilex - 2*rrpart->crop;
+ tiley -= 2*rrpart->crop;
+
+ ofs= (rrpart->tilerect.ymin + rrpart->crop)*rr->rectx + (rrpart->tilerect.xmin+rrpart->crop);
+ target+= pixsize*ofs;
+ }
+ else {
+ ofs= (rrpart->tilerect.ymin*rr->rectx + rrpart->tilerect.xmin);
+ target+= pixsize*ofs;
+ }
+
+ copylen *= sizeof(float)*pixsize;
+ tilex *= pixsize;
+ ofs= pixsize*rr->rectx;
+
+ for(y=0; y<tiley; y++) {
+ memcpy(target, tile, copylen);
+ target+= ofs;
+ tile+= tilex;
+ }
+}
/* used when rendering to a full buffer, or when reading the exr part-layer-pass file */
/* no test happens here if it fits... we also assume layers are in sync */
@@ -236,53 +277,18 @@ static RenderResult *new_render_result(Render *re, rcti *partrct, int crop)
static void merge_render_result(RenderResult *rr, RenderResult *rrpart)
{
RenderLayer *rl, *rlp;
- float *rf, *rfp;
- float *rz, *rzp;
- int y, height, len, copylen;
for(rl= rr->layers.first, rlp= rrpart->layers.first; rl && rlp; rl= rl->next, rlp= rlp->next) {
- /* first combined and z pass */
- if(rl->rectf && rlp->rectf) {
- int ofs;
-
- rzp= rlp->rectz;
- rfp= rlp->rectf;
-
- copylen=len= rrpart->rectx;
- height= rrpart->recty;
-
- if(rrpart->crop) { /* filters add pixel extra */
-
- if(rzp) rzp+= rrpart->crop + rrpart->crop*len;
- if(rfp) rfp+= 4*(rrpart->crop + rrpart->crop*len);
-
- copylen= len-2*rrpart->crop;
- height -= 2*rrpart->crop;
-
- ofs= (rrpart->tilerect.ymin + rrpart->crop)*rr->rectx + (rrpart->tilerect.xmin+rrpart->crop);
- rz= rl->rectz+ ofs;
- rf= rl->rectf+ 4*ofs;
- }
- else {
- ofs= (rrpart->tilerect.ymin*rr->rectx + rrpart->tilerect.xmin);
- rz= rl->rectz+ ofs;
- rf= rl->rectf+ 4*ofs;
- }
-
- for(y=0; y<height; y++) {
- if(rzp) {
- memcpy(rz, rzp, 4*copylen);
- rz+= rr->rectx;
- rzp+= len;
- }
- if(rfp) {
- memcpy(rf, rfp, 16*copylen);
- rf+= 4*rr->rectx;
- rfp+= 4*len;
- }
- }
- }
+ /* combined */
+ if(rl->rectf && rlp->rectf)
+ do_merge_tile(rr, rrpart, rl->rectf, rlp->rectf, 4);
+ /* z */
+ if(rl->rectz && rlp->rectz)
+ do_merge_tile(rr, rrpart, rl->rectz, rlp->rectz, 1);
+ /* vector */
+ if(rl->rectvec && rlp->rectvec)
+ do_merge_tile(rr, rrpart, rl->rectvec, rlp->rectvec, 2);
}
}
@@ -313,7 +319,7 @@ RenderResult *RE_GetResult(Render *re)
/* fill provided result struct with what's currently active or done */
void RE_GetResultImage(Render *re, RenderResult *rr)
{
- memset(rr, sizeof(RenderResult), 0);
+ memset(rr, 0, sizeof(RenderResult));
if(re && re->result) {
RenderLayer *rl;
@@ -359,7 +365,7 @@ void RE_ResultGet32(Render *re, unsigned int *rect)
}
else
/* else fill with black */
- memset(rect, sizeof(int)*re->rectx*re->recty, 0);
+ memset(rect, 0, sizeof(int)*re->rectx*re->recty);
}
@@ -573,9 +579,9 @@ static int do_part_thread(void *pa_v)
zbufshadeDA_tile(pa);
else
zbufshade_tile(pa);
-
- if(!R.test_break())
- merge_render_result(R.result, pa->result);
+
+ /* merge too on break! */
+ merge_render_result(R.result, pa->result);
}
pa->ready= 1;
@@ -661,13 +667,16 @@ static void threaded_tile_processor(Render *re)
{
ListBase threads;
RenderPart *pa;
- int maxthreads=2, rendering=1, counter= 1;
+ int maxthreads, rendering=1, counter= 1, hasdrawn, drawtimer=0;
if(re->result==NULL)
return;
if(re->test_break())
return;
+ if(re->r.mode & R_THREADS) maxthreads= 2;
+ else maxthreads= 1;
+
initparts(re);
BLI_init_threads(&threads, do_part_thread, maxthreads);
@@ -687,10 +696,13 @@ static void threaded_tile_processor(Render *re)
BLI_insert_thread(&threads, pa);
}
}
- else
+ else {
PIL_sleep_ms(50);
+ drawtimer++;
+ }
/* check for ready ones to display, and if we need to continue */
+ hasdrawn= 0;
rendering= 0;
for(pa= re->parts.first; pa; pa= pa->next) {
if(pa->ready) {
@@ -700,11 +712,21 @@ static void threaded_tile_processor(Render *re)
free_render_result(pa->result);
pa->result= NULL;
re->i.partsdone++;
+ hasdrawn= 1;
+ }
+ }
+ else {
+ rendering= 1;
+ if(pa->nr && pa->result && drawtimer>20) {
+ re->display_draw(pa->result, &pa->result->renrect);
+ hasdrawn= 1;
}
}
- else rendering= 1;
}
+ if(hasdrawn)
+ drawtimer= 0;
+
/* on break, wait for all slots to get freed */
if(re->test_break() && BLI_available_threads(&threads)==maxthreads)
rendering= 0;
@@ -719,7 +741,7 @@ static void threaded_tile_processor(Render *re)
void RE_TileProcessor(Render *re)
{
- if(re->r.mode & R_THREADS)
+ if(1)
threaded_tile_processor(re);
else
render_tile_processor(re);
@@ -734,8 +756,11 @@ void render_one_frame(Render *re)
// re->cfra= cfra; /* <- unused! */
/* make render verts/faces/halos/lamps */
- RE_Database_FromScene(re, re->scene, 1);
-
+ if(render_result_needs_vector(re->result))
+ RE_Database_FromScene_Vectors(re, re->scene);
+ else
+ RE_Database_FromScene(re, re->scene, 1);
+
RE_TileProcessor(re);
/* free all render verts etc */
diff --git a/source/blender/render/intern/source/pixelblending.c b/source/blender/render/intern/source/pixelblending.c
index 860aeed29d7..ece9970e885 100644
--- a/source/blender/render/intern/source/pixelblending.c
+++ b/source/blender/render/intern/source/pixelblending.c
@@ -74,22 +74,14 @@ extern struct Render R;
void addAlphaOverFloat(float *dest, float *source)
{
/* d = s + (1-alpha_s)d*/
- float c;
float mul;
mul= 1.0 - source[3];
- c= (mul*dest[0]) + source[0];
- dest[0]= c;
-
- c= (mul*dest[1]) + source[1];
- dest[1]= c;
-
- c= (mul*dest[2]) + source[2];
- dest[2]= c;
-
- c= (mul*dest[3]) + source[3];
- dest[3]= c;
+ dest[0]= (mul*dest[0]) + source[0];
+ dest[1]= (mul*dest[1]) + source[1];
+ dest[2]= (mul*dest[2]) + source[2];
+ dest[3]= (mul*dest[3]) + source[3];
}
@@ -98,7 +90,6 @@ void addAlphaOverFloat(float *dest, float *source)
void addAlphaUnderFloat(float *dest, float *source)
{
- float c;
float mul;
if( (-RE_EMPTY_COLOUR_FLOAT < dest[3])
@@ -112,18 +103,10 @@ void addAlphaUnderFloat(float *dest, float *source)
mul= 1.0 - dest[3];
- c= (mul*source[0]) + dest[0];
- dest[0]= c;
-
- c= (mul*source[1]) + dest[1];
- dest[1]= c;
-
- c= (mul*source[2]) + dest[2];
- dest[2]= c;
-
- c= (mul*source[3]) + dest[3];
- dest[3]= c;
-
+ dest[0]+= (mul*source[0]);
+ dest[1]+= (mul*source[1]);
+ dest[2]+= (mul*source[2]);
+ dest[3]+= (mul*source[3]);
}
@@ -229,6 +212,68 @@ void add_filt_fmask(unsigned int mask, float *col, float *rowbuf, int row_w)
}
}
+/* filtered adding to scanlines */
+void add_filt_fmask_alphaunder(unsigned int mask, float *col, float *rowbuf, int row_w)
+{
+ /* calc the value of mask */
+ float **fmask1= R.samples->fmask1, **fmask2=R.samples->fmask2;
+ float *rb1, *rb2, *rb3;
+ float val, r, g, b, al, acol[4];
+ unsigned int a, maskand, maskshift;
+ int j;
+
+ r= col[0];
+ g= col[1];
+ b= col[2];
+ al= col[3];
+
+ rb2= rowbuf-4;
+ rb3= rb2-4*row_w;
+ rb1= rb2+4*row_w;
+
+ maskand= (mask & 255);
+ maskshift= (mask >>8);
+
+ for(j=2; j>=0; j--) {
+
+ a= j;
+
+ val= *(fmask1[a] +maskand) + *(fmask2[a] +maskshift);
+ if(val!=0.0) {
+ acol[0]= val*r;
+ acol[1]= val*g;
+ acol[2]= val*b;
+ acol[3]= val*al;
+ addAlphaUnderFloat(rb1, acol);
+ }
+ a+=3;
+
+ val= *(fmask1[a] +maskand) + *(fmask2[a] +maskshift);
+ if(val!=0.0) {
+ acol[0]= val*r;
+ acol[1]= val*g;
+ acol[2]= val*b;
+ acol[3]= val*al;
+ addAlphaUnderFloat(rb2, acol);
+ }
+ a+=3;
+
+ val= *(fmask1[a] +maskand) + *(fmask2[a] +maskshift);
+ if(val!=0.0) {
+ acol[0]= val*r;
+ acol[1]= val*g;
+ acol[2]= val*b;
+ acol[3]= val*al;
+ addAlphaUnderFloat(rb3, acol);
+ }
+
+ rb1+= 4;
+ rb2+= 4;
+ rb3+= 4;
+ }
+}
+
+
/* ------------------------------------------------------------------------- */
void addalphaAddFloat(float *dest, float *source)
{
diff --git a/source/blender/render/intern/source/ray.c b/source/blender/render/intern/source/ray.c
index 19ec1dd546d..d5d0a951604 100644
--- a/source/blender/render/intern/source/ray.c
+++ b/source/blender/render/intern/source/ray.c
@@ -628,6 +628,8 @@ void makeoctree(Render *re)
}
MEM_freeN(ocface);
+ re->stats_draw(&re->i);
+
}
/* ************ raytracer **************** */
diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c
index 87c1330d5ef..ba45953eefc 100644
--- a/source/blender/render/intern/source/rendercore.c
+++ b/source/blender/render/intern/source/rendercore.c
@@ -27,6 +27,7 @@
*/
/* system includes */
+#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
@@ -1854,7 +1855,20 @@ void shade_input_set_coords(ShadeInput *shi, float u, float v, int i1, int i2, i
if(mode & MA_TANGENT_V)
shi->tang[0]= shi->tang[1]= shi->tang[2]= 0.0f;
}
-
+
+ if(R.r.mode & R_SPEED) {
+ float *s1, *s2, *s3;
+
+ s1= RE_vertren_get_winspeed(&R, v1, 0);
+ s2= RE_vertren_get_winspeed(&R, v2, 0);
+ s3= RE_vertren_get_winspeed(&R, v3, 0);
+ if(s1 && s2 && s3) {
+ shi->winspeed[0]= (l*s3[0] - u*s1[0] - v*s2[0]);
+ shi->winspeed[1]= (l*s3[1] - u*s1[1] - v*s2[1]);
+ shi->winspeed[2]= 0.0f;
+ }
+ }
+
/* texture coordinates. shi->dxuv shi->dyuv have been set */
if(texco & NEED_UV) {
if(texco & TEXCO_ORCO) {
@@ -2111,9 +2125,8 @@ void shade_material_loop(ShadeInput *shi, ShadeResult *shr)
/* note, facenr declared volatile due to over-eager -O2 optimizations
* on cygwin (particularly -frerun-cse-after-loop)
*/
-void *shadepixel(RenderPart *pa, float x, float y, int z, volatile int facenr, int mask, float *col, float *rco)
+void *shadepixel(RenderPart *pa, float x, float y, int z, volatile int facenr, int mask, ShadeResult *shr, float *rco)
{
- ShadeResult shr;
ShadeInput shi;
VlakRen *vlr=NULL;
@@ -2131,8 +2144,8 @@ void *shadepixel(RenderPart *pa, float x, float y, int z, volatile int facenr, i
shi.depth= 0; // means first hit, not raytracing
if(facenr==0) { /* sky */
- col[0]= 0.0; col[1]= 0.0; col[2]= 0.0; col[3]= 0.0;
- VECCOPY(rco, col);
+ memset(shr, 0, sizeof(ShadeResult));
+ rco[0]= rco[1]= rco[2]= 0.0f;
}
else if( (facenr & 0x7FFFFF) <= R.totvlak) {
VertRen *v1;
@@ -2327,34 +2340,38 @@ void *shadepixel(RenderPart *pa, float x, float y, int z, volatile int facenr, i
VECCOPY(shi.vno, shi.vn);
if(shi.mat->nodetree && shi.mat->use_nodes) {
- ntreeShaderExecTree(shi.mat->nodetree, &shi, &shr);
+ ntreeShaderExecTree(shi.mat->nodetree, &shi, shr);
}
else {
/* copy all relevant material vars, note, keep this synced with render_types.h */
memcpy(&shi.r, &shi.mat->r, 23*sizeof(float));
shi.har= shi.mat->har;
- shade_material_loop(&shi, &shr);
+ shade_material_loop(&shi, shr);
}
/* after shading and composit layers */
- if(shr.spec[0]<0.0f) shr.spec[0]= 0.0f;
- if(shr.spec[1]<0.0f) shr.spec[1]= 0.0f;
- if(shr.spec[2]<0.0f) shr.spec[2]= 0.0f;
+ if(shr->spec[0]<0.0f) shr->spec[0]= 0.0f;
+ if(shr->spec[1]<0.0f) shr->spec[1]= 0.0f;
+ if(shr->spec[2]<0.0f) shr->spec[2]= 0.0f;
- if(shr.diff[0]<0.0f) shr.diff[0]= 0.0f;
- if(shr.diff[1]<0.0f) shr.diff[1]= 0.0f;
- if(shr.diff[2]<0.0f) shr.diff[2]= 0.0f;
+ if(shr->diff[0]<0.0f) shr->diff[0]= 0.0f;
+ if(shr->diff[1]<0.0f) shr->diff[1]= 0.0f;
+ if(shr->diff[2]<0.0f) shr->diff[2]= 0.0f;
- VECADD(col, shr.diff, shr.spec);
+ VECADD(shr->combined, shr->diff, shr->spec);
+
+ /* additional passes */
+ shr->winspeed[0]= shi.winspeed[0]; shr->winspeed[1]= shi.winspeed[1];
+ VECCOPY(shr->nor, shi.vn);
/* NOTE: this is not correct here, sky from raytrace gets corrected... */
/* exposure correction */
if(R.wrld.exp!=0.0 || R.wrld.range!=1.0) {
if((shi.mat->mode & MA_SHLESS)==0) {
- col[0]= R.wrld.linfac*(1.0-exp( col[0]*R.wrld.logfac) );
- col[1]= R.wrld.linfac*(1.0-exp( col[1]*R.wrld.logfac) );
- col[2]= R.wrld.linfac*(1.0-exp( col[2]*R.wrld.logfac) );
+ shr->combined[0]= R.wrld.linfac*(1.0-exp( shr->combined[0]*R.wrld.logfac) );
+ shr->combined[1]= R.wrld.linfac*(1.0-exp( shr->combined[1]*R.wrld.logfac) );
+ shr->combined[2]= R.wrld.linfac*(1.0-exp( shr->combined[2]*R.wrld.logfac) );
}
}
@@ -2367,26 +2384,20 @@ void *shadepixel(RenderPart *pa, float x, float y, int z, volatile int facenr, i
}
else alpha= 1.0;
- if(shr.alpha!=1.0 || alpha!=1.0) {
+ if(shr->alpha!=1.0 || alpha!=1.0) {
if(shi.mat->mode & MA_RAYTRANSP) {
fac= alpha;
- if(R.r.mode & R_UNIFIED)
- /* unified alpha overs everything... */
- col[3]= 1.0f;
- else {
- /* sky was applied allready for ray transp, only do mist */
- col[3]= shr.alpha;
- }
+ shr->combined[3]= shr->alpha;
}
else {
- fac= alpha*(shr.alpha);
- col[3]= fac;
+ fac= alpha*(shr->alpha);
+ shr->combined[3]= fac;
}
- col[0]*= fac;
- col[1]*= fac;
- col[2]*= fac;
+ shr->combined[0]*= fac;
+ shr->combined[1]*= fac;
+ shr->combined[2]*= fac;
}
- else col[3]= 1.0;
+ else shr->combined[3]= 1.0;
}
if(R.flag & R_LAMPHALO) {
@@ -2403,29 +2414,30 @@ void *shadepixel(RenderPart *pa, float x, float y, int z, volatile int facenr, i
calc_view_vector(shi.view, x, y);
shi.co[2]= 0.0;
- renderspothalo(&shi, col, 1.0);
+ renderspothalo(&shi, shr->combined, 1.0);
}
else
- renderspothalo(&shi, col, col[3]);
+ renderspothalo(&shi, shr->combined, shr->combined[3]);
}
return vlr;
}
-static void shadepixel_sky(RenderPart *pa, float x, float y, int z, int facenr, int mask, float *colf)
+static void shadepixel_sky(RenderPart *pa, float x, float y, int z, int facenr, int mask, ShadeResult *shr)
{
VlakRen *vlr;
float collector[4], rco[3];
- vlr= shadepixel(pa, x, y, z, facenr, mask, colf, rco);
- if(colf[3] != 1.0) {
+ vlr= shadepixel(pa, x, y, z, facenr, mask, shr, rco);
+ if(shr->combined[3] != 1.0) {
+
/* bail out when raytrace transparency (sky included already) */
if(vlr && (R.r.mode & R_RAYTRACE))
if(vlr->mat->mode & MA_RAYTRANSP) return;
renderSkyPixelFloat(collector, x, y, vlr?rco:NULL);
- addAlphaOverFloat(collector, colf);
- QUATCOPY(colf, collector);
+ addAlphaOverFloat(collector, shr->combined);
+ QUATCOPY(shr->combined, collector);
}
}
@@ -2503,14 +2515,16 @@ static void edge_enhance_add(RenderPart *pa, float *rectf, float *arect)
/* ********************* MAINLOOPS ******************** */
-static void shadeDA_tile(RenderPart *pa, float *rectf, float *recta)
+static void shadeDA_tile(RenderPart *pa, RenderLayer *rl)
{
+ RenderResult *rr= pa->result;
+ ShadeResult shr;
PixStr *ps;
float xs, ys;
- float fcol[4], *rf, *grf, *acol= NULL;
+ float *fcol= shr.combined, *rf, *rectf= rl->rectf;
long *rd, *rectdaps= pa->rectdaps;
int zbuf, samp, curmask, face, mask, fullmask;
- int b, x, y, full_osa, seed, crop=0;
+ int b, x, y, full_osa, seed, crop=0, offs=0, od;
if(R.test_break()) return;
@@ -2519,23 +2533,24 @@ static void shadeDA_tile(RenderPart *pa, float *rectf, float *recta)
fullmask= (1<<R.osa)-1;
- /* might need it for gamma, in end of this function */
- grf= rectf;
-
/* filtered render, for now we assume only 1 filter size */
if(pa->crop) {
crop= 1;
rectf+= 4*(pa->rectx + 1);
rectdaps+= pa->rectx + 1;
- if(recta) recta+= 4*(pa->rectx + 1);
+ offs= pa->rectx + 1;
}
- for(y=pa->disprect.ymin+crop; y<pa->disprect.ymax-crop; y++) {
+ /* scanline updates have to be 2 lines behind */
+ rr->renrect.ymin= 0;
+ rr->renrect.ymax= -2*crop;
+
+ for(y=pa->disprect.ymin+crop; y<pa->disprect.ymax-crop; y++, rr->renrect.ymax++) {
rf= rectf;
rd= rectdaps;
- if(recta) acol= recta;
-
- for(x=pa->disprect.xmin+crop; x<pa->disprect.xmax-crop; x++, rd++, rf+=4) {
+ od= offs;
+
+ for(x=pa->disprect.xmin+crop; x<pa->disprect.xmax-crop; x++, rd++, rf+=4, od++) {
BLI_thread_srandom(pa->thread, seed+x);
ps= (PixStr *)(*rd);
@@ -2567,9 +2582,8 @@ static void shadeDA_tile(RenderPart *pa, float *rectf, float *recta)
if(curmask & (1<<samp)) {
xs= (float)x + R.jit[samp][0];
ys= (float)y + R.jit[samp][1];
- shadepixel_sky(pa, xs, ys, zbuf, face, (1<<samp), fcol);
+ shadepixel_sky(pa, xs, ys, zbuf, face, (1<<samp), &shr);
- if(acol && acol[3]!=0.0) addAlphaOverFloat(fcol, acol);
if(R.do_gamma) {
fcol[0]= gammaCorrect(fcol[0]);
fcol[1]= gammaCorrect(fcol[1]);
@@ -2579,14 +2593,12 @@ static void shadeDA_tile(RenderPart *pa, float *rectf, float *recta)
}
}
}
- else {
+ else if(curmask) {
b= R.samples->centmask[curmask];
xs= (float)x+R.samples->centLut[b & 15];
ys= (float)y+R.samples->centLut[b>>4];
- shadepixel_sky(pa, xs, ys, zbuf, face, curmask, fcol);
-
- if(acol && acol[3]!=0.0) addAlphaOverFloat(fcol, acol);
-
+ shadepixel_sky(pa, xs, ys, zbuf, face, curmask, &shr);
+
if(R.do_gamma) {
fcol[0]= gammaCorrect(fcol[0]);
fcol[1]= gammaCorrect(fcol[1]);
@@ -2600,22 +2612,29 @@ static void shadeDA_tile(RenderPart *pa, float *rectf, float *recta)
if(ps==NULL) break;
else ps= ps->next;
}
- if(acol) acol+=4;
+
+ /* passes */
+ if(rl->passflag & SCE_PASS_VECTOR) {
+ float *fp= rl->rectvec+2*od;
+ fp[0]= shr.winspeed[0];
+ fp[1]= shr.winspeed[1];
+ }
}
rectf+= 4*pa->rectx;
rectdaps+= pa->rectx;
- if(recta) recta+= 4*pa->rectx;
+ offs+= pa->rectx;
seed+= pa->rectx;
if(y&1) if(R.test_break()) break;
}
if(R.do_gamma) {
- for(y= pa->rectx*pa->recty; y>0; y--, grf+=4) {
- grf[0] = invGammaCorrect(grf[0]);
- grf[1] = invGammaCorrect(grf[1]);
- grf[2] = invGammaCorrect(grf[2]);
+ rectf= rl->rectf;
+ for(y= pa->rectx*pa->recty; y>0; y--, rectf+=4) {
+ rectf[0] = invGammaCorrect(rectf[0]);
+ rectf[1] = invGammaCorrect(rectf[1]);
+ rectf[2] = invGammaCorrect(rectf[2]);
}
}
@@ -2706,9 +2725,10 @@ static void make_pixelstructs(RenderPart *pa, ListBase *lb)
/* supposed to be fully threadable! */
void zbufshadeDA_tile(RenderPart *pa)
{
+ RenderResult *rr= pa->result;
RenderLayer *rl;
ListBase psmlist= {NULL, NULL};
- float *acolrect= NULL, *edgerect= NULL;
+ float *edgerect= NULL;
set_part_zbuf_clipflag(pa);
@@ -2718,7 +2738,9 @@ void zbufshadeDA_tile(RenderPart *pa)
pa->rectz= RE_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz");
if(R.r.mode & R_EDGE) edgerect= RE_callocN(sizeof(float)*pa->rectx*pa->recty, "rectedge");
- for(rl= pa->result->layers.first; rl; rl= rl->next) {
+ for(rl= rr->layers.first; rl; rl= rl->next) {
+ /* indication for scanline updates */
+ rr->renlay= rl;
/* initialize pixelstructs */
addpsmain(&psmlist);
@@ -2737,20 +2759,28 @@ void zbufshadeDA_tile(RenderPart *pa)
fillrect(pa->rectz, pa->rectx, pa->recty, 0x7FFFFFFF);
- /* we do transp layer first, so its get added with filter in main buffer... still incorrect though */
+ /* shades solid */
+ if(rl->layflag & SCE_LAY_SOLID)
+ shadeDA_tile(pa, rl);
+
+ /* transp layer */
if(R.flag & R_ZTRA) {
if(rl->layflag & SCE_LAY_ZTRA) {
- acolrect= RE_callocN(4*sizeof(float)*pa->rectx*pa->recty, "alpha layer");
- zbuffer_transp_shade(pa, acolrect, rl->lay, rl->layflag);
+ float *acolrect= RE_callocN(4*sizeof(float)*pa->rectx*pa->recty, "alpha layer");
+ float *fcol= rl->rectf, *acol= acolrect;
+ int x;
+
+ /* swap for live updates */
+ SWAP(float *, acolrect, rl->rectf);
+ zbuffer_transp_shade(pa, rl->rectf, rl->lay, rl->layflag);
+ SWAP(float *, acolrect, rl->rectf);
+
+ for(x=pa->rectx*pa->recty; x>0; x--, acol+=4, fcol+=4) {
+ addAlphaOverFloat(fcol, acol);
+ }
+ RE_freeN(acolrect);
}
}
-
- /* shades solid and adds transparent layer */
- if(rl->layflag & SCE_LAY_SOLID)
- shadeDA_tile(pa, rl->rectf, acolrect);
- else if(acolrect) {
- SWAP(float *, acolrect, rl->rectf);
- }
/* extra layers */
if(R.r.mode & R_EDGE)
@@ -2763,10 +2793,6 @@ void zbufshadeDA_tile(RenderPart *pa)
convert_zbuf_to_distbuf(pa, rl);
/* free stuff within loop! */
- if(acolrect) {
- RE_freeN(acolrect);
- acolrect= NULL;
- }
RE_freeN(pa->rectdaps); pa->rectdaps= NULL;
freeps(&psmlist);
}
@@ -2786,35 +2812,67 @@ void zbufshadeDA_tile(RenderPart *pa)
/* supposed to be fully threadable! */
void zbufshade_tile(RenderPart *pa)
{
+ ShadeResult shr;
+ RenderResult *rr= pa->result;
RenderLayer *rl;
-
+
set_part_zbuf_clipflag(pa);
/* zbuffer code clears/inits rects */
pa->rectp= RE_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp");
pa->rectz= RE_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz");
- for(rl= pa->result->layers.first; rl; rl= rl->next) {
+ for(rl= rr->layers.first; rl; rl= rl->next) {
+ /* indication for scanline updates */
+ rr->renlay= rl;
+
zbuffer_solid(pa, rl->lay, rl->layflag);
if(!R.test_break()) {
if(rl->layflag & SCE_LAY_SOLID) {
float *fcol= rl->rectf;
- int x, y, *rp= pa->rectp, *rz= pa->rectz;
-
- for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++) {
- for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, rz++, rp++, fcol+=4) {
- shadepixel_sky(pa, (float)x, (float)y, *rz, *rp, 0, fcol);
+ int x, y, *rp= pa->rectp, *rz= pa->rectz, offs=0;
+
+ /* init scanline updates */
+ rr->renrect.ymin=rr->renrect.ymax= 0;
+
+ for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++, rr->renrect.ymax++) {
+ for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, rz++, rp++, fcol+=4, offs++) {
+ shadepixel_sky(pa, (float)x, (float)y, *rz, *rp, 0, &shr);
+ QUATCOPY(fcol, shr.combined);
+
+ /* passes */
+ if(*rp && (rl->passflag & SCE_PASS_VECTOR)) {
+ float *fp= rl->rectvec+2*(offs);
+ fp[0]= shr.winspeed[0];
+ fp[1]= shr.winspeed[1];
+ }
}
- if(y&1) if(R.test_break()) break;
+ if(y&1)
+ if(R.test_break()) break;
}
}
}
- if(!R.test_break())
- if(R.flag & R_ZTRA)
- if(rl->layflag & SCE_LAY_ZTRA)
+ if(!R.test_break()) {
+ if(R.flag & R_ZTRA) {
+ if(rl->layflag & SCE_LAY_ZTRA) {
+ float *acolrect= RE_callocN(4*sizeof(float)*pa->rectx*pa->recty, "alpha layer");
+ float *fcol= rl->rectf, *acol= acolrect;
+ int x;
+
+ /* swap for live updates */
+ SWAP(float *, acolrect, rl->rectf);
zbuffer_transp_shade(pa, rl->rectf, rl->lay, rl->layflag);
+ SWAP(float *, acolrect, rl->rectf);
+
+ for(x=pa->rectx*pa->recty; x>0; x--, acol+=4, fcol+=4) {
+ addAlphaOverFloat(fcol, acol);
+ }
+ RE_freeN(acolrect);
+ }
+ }
+ }
if(!R.test_break()) {
if(R.r.mode & R_EDGE) {
diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c
index 098d4491060..d43a2bea8b8 100644
--- a/source/blender/render/intern/source/renderdatabase.c
+++ b/source/blender/render/intern/source/renderdatabase.c
@@ -91,16 +91,7 @@
#define RE_STRAND_ELEMS 1
#define RE_TANGENT_ELEMS 3
#define RE_STRESS_ELEMS 1
-
-/* render allocates totvert/256 of these nodes, for lookup and quick alloc */
-typedef struct VertTableNode {
- struct VertRen *vert;
- float *rad;
- float *sticky;
- float *strand;
- float *tangent;
- float *stress;
-} VertTableNode;
+#define RE_WINSPEED_ELEMS 2
float *RE_vertren_get_sticky(Render *re, VertRen *ver, int verify)
{
@@ -179,6 +170,21 @@ float *RE_vertren_get_tangent(Render *re, VertRen *ver, int verify)
return tangent + (ver->index & 255)*RE_TANGENT_ELEMS;
}
+/* needs malloc */
+float *RE_vertren_get_winspeed(Render *re, VertRen *ver, int verify)
+{
+ float *winspeed;
+ int nr= ver->index>>8;
+
+ winspeed= re->vertnodes[nr].winspeed;
+ if(winspeed==NULL) {
+ if(verify)
+ winspeed= re->vertnodes[nr].winspeed= MEM_mallocN(256*RE_WINSPEED_ELEMS*sizeof(float), "winspeed table");
+ else
+ return NULL;
+ }
+ return winspeed + (ver->index & 255)*RE_WINSPEED_ELEMS;
+}
VertRen *RE_findOrAddVert(Render *re, int nr)
{
@@ -218,6 +224,31 @@ VertRen *RE_findOrAddVert(Render *re, int nr)
return v;
}
+void free_renderdata_vertnodes(VertTableNode *vertnodes)
+{
+ int a;
+
+ for(a=0; vertnodes[a].vert; a++) {
+ MEM_freeN(vertnodes[a].vert);
+
+ if(vertnodes[a].rad)
+ MEM_freeN(vertnodes[a].rad);
+ if(vertnodes[a].sticky)
+ MEM_freeN(vertnodes[a].sticky);
+ if(vertnodes[a].strand)
+ MEM_freeN(vertnodes[a].strand);
+ if(vertnodes[a].tangent)
+ MEM_freeN(vertnodes[a].tangent);
+ if(vertnodes[a].stress)
+ MEM_freeN(vertnodes[a].stress);
+ if(vertnodes[a].winspeed)
+ MEM_freeN(vertnodes[a].winspeed);
+ }
+
+ MEM_freeN(vertnodes);
+
+}
+
void free_renderdata_tables(Render *re)
{
int a=0;
@@ -241,22 +272,7 @@ void free_renderdata_tables(Render *re)
}
if(re->vertnodes) {
- for(a=0; re->vertnodes[a].vert; a++) {
- MEM_freeN(re->vertnodes[a].vert);
-
- if(re->vertnodes[a].rad)
- MEM_freeN(re->vertnodes[a].rad);
- if(re->vertnodes[a].sticky)
- MEM_freeN(re->vertnodes[a].sticky);
- if(re->vertnodes[a].strand)
- MEM_freeN(re->vertnodes[a].strand);
- if(re->vertnodes[a].tangent)
- MEM_freeN(re->vertnodes[a].tangent);
- if(re->vertnodes[a].stress)
- MEM_freeN(re->vertnodes[a].stress);
- }
-
- MEM_freeN(re->vertnodes);
+ free_renderdata_vertnodes(re->vertnodes);
re->vertnodes= NULL;
re->vertnodeslen= 0;
}
diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c
index 7fac9f59944..4830db352d7 100644
--- a/source/blender/render/intern/source/zbuf.c
+++ b/source/blender/render/intern/source/zbuf.c
@@ -56,6 +56,7 @@
#include "RE_render_ext.h"
/* local includes */
+#include "gammaCorrectionTables.h"
#include "render_types.h"
#include "renderpipeline.h"
#include "renderdatabase.h"
@@ -1879,7 +1880,7 @@ static void copyto_abufz(RenderPart *pa, int *arectz, int sample)
long *rd;
/* now, in OSA the pixstructs contain all faces filled in */
- if(R.r.mode & R_OSA) fillrect(arectz, pa->rectx, pa->recty, 0x7FFFFFFF);
+ if(R.osa) fillrect(arectz, pa->rectx, pa->recty, 0x7FFFFFFF);
else {
memcpy(arectz, pa->rectz, 4*pa->rectx*pa->recty);
return;
@@ -1952,7 +1953,7 @@ static void zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, u
copyto_abufz(pa, zspan.arectz, zsample); /* init zbuffer */
zspan.mask= 1<<zsample;
- if(R.r.mode & R_OSA) {
+ if(R.osa) {
zspan.zofsx= -pa->disprect.xmin-R.jit[zsample][0];
zspan.zofsy= -pa->disprect.ymin-R.jit[zsample][1];
}
@@ -2010,7 +2011,7 @@ static void zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, u
}
}
- if((R.r.mode & R_OSA)==0) break;
+ if(R.osa==0) break;
if(R.test_break()) break;
}
@@ -2033,13 +2034,14 @@ static int vergzvlak(const void *a1, const void *a2)
*/
static void shadetrapixel(RenderPart *pa, float x, float y, int z, int facenr, int mask, float *fcol)
{
+ ShadeResult shr;
float rco[3];
if( (facenr & 0x7FFFFF) > R.totvlak) {
printf("error in shadetrapixel nr: %d\n", (facenr & 0x7FFFFF));
return;
}
- if(R.r.mode & R_OSA) {
+ if(R.osa) {
VlakRen *vlr= RE_findOrAddVlak(&R, (facenr-1) & 0x7FFFFF);
float accumcol[4]={0,0,0,0}, tot=0.0;
int a;
@@ -2047,11 +2049,11 @@ static void shadetrapixel(RenderPart *pa, float x, float y, int z, int facenr, i
if(vlr->flag & R_FULL_OSA) {
for(a=0; a<R.osa; a++) {
if(mask & (1<<a)) {
- shadepixel(pa, x+R.jit[a][0], y+R.jit[a][1], z, facenr, 1<<a, fcol, rco);
- accumcol[0]+= fcol[0];
- accumcol[1]+= fcol[1];
- accumcol[2]+= fcol[2];
- accumcol[3]+= fcol[3];
+ shadepixel(pa, x+R.jit[a][0], y+R.jit[a][1], z, facenr, 1<<a, &shr, rco);
+ accumcol[0]+= shr.combined[0];
+ accumcol[1]+= shr.combined[1];
+ accumcol[2]+= shr.combined[2];
+ accumcol[3]+= shr.combined[3];
tot+= 1.0;
}
}
@@ -2065,11 +2067,14 @@ static void shadetrapixel(RenderPart *pa, float x, float y, int z, int facenr, i
int b= R.samples->centmask[mask];
x= x+R.samples->centLut[b & 15];
y= y+R.samples->centLut[b>>4];
- shadepixel(pa, x, y, z, facenr, mask, fcol, rco);
-
+ shadepixel(pa, x, y, z, facenr, mask, &shr, rco);
+ QUATCOPY(fcol, shr.combined);
}
}
- else shadepixel(pa, x, y, z, facenr, mask, fcol, rco);
+ else {
+ shadepixel(pa, x, y, z, facenr, mask, &shr, rco);
+ QUATCOPY(fcol, shr.combined);
+ }
}
static int addtosampcol(float *sampcol, float *fcol, int mask)
@@ -2089,14 +2094,15 @@ static int addtosampcol(float *sampcol, float *fcol, int mask)
void zbuffer_transp_shade(RenderPart *pa, float *pass, unsigned int lay, short layflag)
{
+ RenderResult *rr= pa->result;
APixstr *APixbuf; /* Zbuffer: linked list of face samples */
- APixstr *ap, *apn;
+ APixstr *ap, *aprect, *apn;
ListBase apsmbase={NULL, NULL};
- float col[4], fcol[4], tempcol[4], sampcol[16*4], *scol, accumcol[4];
- float fac, alpha[32];
- int x, y, a, zrow[MAX_ZROW][3], totface, nr;
+ float fcol[4], sampcol[16*4];
+ float fac, alpha[32], *passrect= pass;
+ int x, y, crop=0, a, zrow[MAX_ZROW][3], totface;
int sval;
-
+
/* looks nicer for calling code */
if(R.test_break())
return;
@@ -2110,7 +2116,7 @@ void zbuffer_transp_shade(RenderPart *pa, float *pass, unsigned int lay, short l
}
/* alpha LUT */
- if(R.r.mode & R_OSA ) {
+ if(R.osa) {
fac= (1.0/(float)R.osa);
for(a=0; a<=R.osa; a++) {
alpha[a]= (float)a*fac;
@@ -2119,12 +2125,26 @@ void zbuffer_transp_shade(RenderPart *pa, float *pass, unsigned int lay, short l
/* fill the Apixbuf */
zbuffer_abuf(pa, APixbuf, &apsmbase, lay, layflag);
+ aprect= APixbuf;
- /* render tile */
- ap= APixbuf;
+ /* filtered render, for now we assume only 1 filter size */
+ if(pa->crop) {
+ crop= 1;
+ passrect+= 4*(pa->rectx + 1);
+ aprect+= pa->rectx + 1;
+ }
- for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++) {
- for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, ap++, pass+=4) {
+ /* init scanline updates */
+ rr->renrect.ymin= 0;
+ rr->renrect.ymax= -pa->crop;
+
+ /* render the tile */
+
+ for(y=pa->disprect.ymin+crop; y<pa->disprect.ymax-crop; y++, rr->renrect.ymax++) {
+ pass= passrect;
+ ap= aprect;
+
+ for(x=pa->disprect.xmin+crop; x<pa->disprect.xmax-crop; x++, ap++, pass+=4) {
if(ap->p[0]) {
/* sort in z */
@@ -2148,23 +2168,14 @@ void zbuffer_transp_shade(RenderPart *pa, float *pass, unsigned int lay, short l
shadetrapixel(pa, (float)x, (float)y, zrow[0][0], zrow[0][1], zrow[0][2], fcol);
- nr= count_mask(zrow[0][2]);
- if( (R.r.mode & R_OSA) && nr<R.osa) {
- fac= alpha[ nr ];
- col[0]= (fcol[0]*fac);
- col[1]= (fcol[1]*fac);
- col[2]= (fcol[2]*fac);
- col[3]= (fcol[3]*fac);
+ if(R.osa) {
+ add_filt_fmask(zrow[0][2], fcol, pass, rr->rectx);
}
else {
- col[0]= fcol[0];
- col[1]= fcol[1];
- col[2]= fcol[2];
- col[3]= fcol[3];
+ QUATCOPY(pass, fcol);
}
}
else {
- col[0]= col[1]= col[2]= col[3]= 0.0f;
if(totface==2) {
if(zrow[0][0] < zrow[1][0]) {
@@ -2178,62 +2189,43 @@ void zbuffer_transp_shade(RenderPart *pa, float *pass, unsigned int lay, short l
qsort(zrow, totface, sizeof(int)*3, vergzvlak);
}
- /* join when pixels are adjacent */
-
- while(totface>0) {
- totface--;
-
- shadetrapixel(pa, (float)x, (float)y, zrow[totface][0], zrow[totface][1], zrow[totface][2], fcol);
-
- a= count_mask(zrow[totface][2]);
- if( (R.r.mode & R_OSA ) && a<R.osa) {
- if(totface>0) {
- memset(sampcol, 0, 4*sizeof(float)*R.osa);
- sval= addtosampcol(sampcol, fcol, zrow[totface][2]);
-
- /* sval==0: alpha completely full */
- while( (sval != 0) && (totface>0) ) {
- a= count_mask(zrow[totface-1][2]);
- if(a==R.osa) break;
- totface--;
-
- shadetrapixel(pa, (float)x, (float)y, zrow[totface][0], zrow[totface][1], zrow[totface][2], fcol);
- sval= addtosampcol(sampcol, fcol, zrow[totface][2]);
- }
-
- scol= sampcol;
- accumcol[0]= scol[0]; accumcol[1]= scol[1];
- accumcol[2]= scol[2]; accumcol[3]= scol[3];
- scol+= 4;
- for(a=1; a<R.osa; a++, scol+=4) {
- accumcol[0]+= scol[0]; accumcol[1]+= scol[1];
- accumcol[2]+= scol[2]; accumcol[3]+= scol[3];
- }
- tempcol[0]= accumcol[0]/R.osa;
- tempcol[1]= accumcol[1]/R.osa;
- tempcol[2]= accumcol[2]/R.osa;
- tempcol[3]= accumcol[3]/R.osa;
-
- addAlphaUnderFloat(col, tempcol);
-
- }
- else {
- fac= alpha[a];
- fcol[0]= (fcol[0]*fac);
- fcol[1]= (fcol[1]*fac);
- fcol[2]= (fcol[2]*fac);
- fcol[3]= (fcol[3]*fac);
- addAlphaUnderFloat(col, fcol);
- }
- }
- else addAlphaUnderFloat(col, fcol); /* no osa or full pixel with same face? */
+ if(R.osa==0) {
+ while(totface>0) {
+ totface--;
+
+ shadetrapixel(pa, (float)x, (float)y, zrow[totface][0], zrow[totface][1], zrow[totface][2], fcol);
+ addAlphaUnderFloat(pass, fcol);
+
+ if(pass[3]>=0.999) break;
+ }
+ }
+ else {
+ /* for each mask-sample we alpha-under colors. then in end it's added using filter */
+ memset(sampcol, 0, 4*sizeof(float)*R.osa);
+
+ while(totface>0) {
+ totface--;
+
+ shadetrapixel(pa, (float)x, (float)y, zrow[totface][0], zrow[totface][1], zrow[totface][2], fcol);
+ sval= addtosampcol(sampcol, fcol, zrow[totface][2]);
+
+ if(sval==0) break;
+ }
- if(col[3]>=0.999) break;
+ for(a=0; a<R.osa; a++)
+ add_filt_fmask(1<<a, sampcol+4*a, pass, rr->rectx);
}
}
- if(col[3]!=0.0) addAlphaOverFloat(pass, col);
+ //if(R.osa && R.do_gamma) {
+ // pass[0]= invGammaCorrect(pass[0]);
+ // pass[1]= invGammaCorrect(pass[1]);
+ // pass[2]= invGammaCorrect(pass[2]);
+ //}
}
}
+
+ aprect+= pa->rectx;
+ passrect+= 4*pa->rectx;
}
RE_freeN(APixbuf);
diff --git a/source/blender/src/editnode.c b/source/blender/src/editnode.c
index 84354859067..c192d801b65 100644
--- a/source/blender/src/editnode.c
+++ b/source/blender/src/editnode.c
@@ -1178,7 +1178,7 @@ static void node_add_menu(SpaceNode *snode)
}
else if(snode->treetype==NTREE_COMPOSIT) {
/* compo menu, still hardcoded defines... solve */
- event= pupmenu("Add Node%t|Render Result %x221|Composite %x222|Viewer%x201|Image %x220|RGB Curves%x209|AlphaOver %x210|Blur %x211|Filter %x212|Value %x203|Color %x202|Mix %x204|ColorRamp %x205|Color to BW %x206|Map Value %x213|Normal %x207");
+ event= pupmenu("Add Node%t|Render Result %x221|Composite %x222|Viewer%x201|Image %x220|RGB Curves%x209|AlphaOver %x210|Blur %x211|Vector Blur %x215|Filter %x212|Value %x203|Color %x202|Mix %x204|ColorRamp %x205|Color to BW %x206|Map Value %x213|Normal %x207");
if(event<1) return;
}
else return;
diff --git a/source/blender/src/renderwin.c b/source/blender/src/renderwin.c
index 579dc8b892a..8b2c0093b3e 100644
--- a/source/blender/src/renderwin.c
+++ b/source/blender/src/renderwin.c
@@ -721,10 +721,23 @@ static void renderwin_clear_display_cb(RenderResult *rr)
*/
/* can get as well the full picture, as the parts while rendering */
-static void renderwin_progress(RenderWin *rw, RenderResult *rr, rcti *unused)
+static void renderwin_progress(RenderWin *rw, RenderResult *rr, rcti *renrect)
{
rcti win_rct;
float *rectf, fullrect[2][2];
+ int ymin, ymax;
+
+ /* if renrect argument, we only display scanlines */
+ if(renrect) {
+ ymin= renrect->ymin;
+ ymax= renrect->ymax-ymin;
+ if(ymax<2) return;
+ renrect->ymin= renrect->ymax;
+ }
+ else {
+ ymin= 0;
+ ymax= rr->recty-2*rr->crop;
+ }
/* renderwindow cruft */
win_rct.xmin= win_rct.ymin= 0;
@@ -736,9 +749,13 @@ static void renderwin_progress(RenderWin *rw, RenderResult *rr, rcti *unused)
if(rr->rectf)
rectf= rr->rectf;
else {
- RenderLayer *rl= BLI_findlink(&rr->layers, rr->actlay);
+ RenderLayer *rl= rr->renlay;
+ if(rl==NULL) return;
rectf= rl->rectf;
- }
+ }
+ /* if scanline updates... */
+ rectf+= 4*rr->rectx*ymin;
+
/* when rendering more pixels than needed, we crop away cruft */
if(rr->crop)
rectf+= 4*(rr->crop*rr->rectx + rr->crop);
@@ -746,14 +763,14 @@ static void renderwin_progress(RenderWin *rw, RenderResult *rr, rcti *unused)
/* tilerect defines drawing offset from (0,0) */
/* however, tilerect (xmin, ymin) is first pixel */
fullrect[0][0] += (rr->tilerect.xmin+rr->crop)*rw->zoom;
- fullrect[0][1] += (rr->tilerect.ymin+rr->crop)*rw->zoom;
+ fullrect[0][1] += (rr->tilerect.ymin+rr->crop + ymin)*rw->zoom;
glEnable(GL_SCISSOR_TEST);
glaDefine2DArea(&win_rct);
glDrawBuffer(GL_FRONT);
glPixelZoom(rw->zoom, rw->zoom);
- glaDrawPixelsSafe(fullrect[0][0], fullrect[0][1], rr->rectx-2*rr->crop, rr->recty-2*rr->crop, rr->rectx,
+ glaDrawPixelsSafe(fullrect[0][0], fullrect[0][1], rr->rectx-2*rr->crop, ymax, rr->rectx,
GL_RGBA, GL_FLOAT, rectf);
glPixelZoom(1.0, 1.0);
glFlush();