Orange; more render & compo stuff!

-> Rendering in RenderLayers

It's important to distinguish a 'render layer' from a 'pass'. The first is
control over the main pipeline itself, to indicate what geometry is being
is rendered. The 'pass' (not in this commit!) is related to internal
shading code, like shadow/spec/AO/normals/etc.

Options for RenderLayers now are:
- Indicate which 3d 'view layers' have to be included (so you can render
  front and back separately)
- "Solid", all solid faces, includes sky at the moment too
- "ZTransp", all transparent faces
- "Halo", the halos
- "Strand", the particle strands (not coded yet...)

Currently only 2 'passes' are exported for render, which is the "Combined"
buffer and the "Z. The latter now works, and can be turned on/off.

Note that all layers are still fully kept in memory now, saving the tiles
and layers to disk (in exr) is also todo.

-> New Blur options

The existing Blur Node (compositor) now has an optional input image. This
has to be a 'value buffer', which can be a Zbuffer, or any mask you can
think of. The input values have to be in the 0-1 range, so another new
node was added too "Map Value".
The value input can also be used to tweak blur size with the (todo)
Time Node.

Temporal screenies:
http://www.blender.org/bf/rt.jpg
http://www.blender.org/bf/rt1.jpg
http://www.blender.org/bf/rt2.jpg

BTW: The compositor is very slow still, it recalulates all nodes on each
change still. Persistant memory and dependency checks is coming!
This commit is contained in:
Ton Roosendaal 2006-01-26 22:18:46 +00:00
parent 1ae7fb0c99
commit 4a52c6ac6f
22 changed files with 1163 additions and 420 deletions

View File

@ -194,6 +194,8 @@ void set_node_shader_lamp_loop(void (*lamp_loop_func)(struct ShadeInput *, str
#define CMP_NODE_ALPHAOVER 210
#define CMP_NODE_BLUR 211
#define CMP_NODE_FILTER 212
#define CMP_NODE_MAP_VALUE 213
#define CMP_NODE_TIME 214
#define CMP_NODE_IMAGE 220
#define CMP_NODE_R_RESULT 221

View File

@ -75,5 +75,7 @@ void scene_select_base(struct Scene *sce, struct Base *selbase);
void scene_update_for_newframe(struct Scene *sce, unsigned int lay);
void scene_add_render_layer(struct Scene *sce);
#endif

View File

@ -754,6 +754,8 @@ bNode *nodeAddNodeType(bNodeTree *ntree, int type, bNodeTree *ngroup)
node->storage= curvemapping_add(3, -1.0f, -1.0f, 1.0f, 1.0f);
else if(type==CMP_NODE_CURVE_RGB)
node->storage= curvemapping_add(4, 0.0f, 0.0f, 1.0f, 1.0f);
else if(type==CMP_NODE_MAP_VALUE)
node->storage= add_mapping();
}
return node;
@ -1188,14 +1190,16 @@ void ntreeSolveOrder(bNodeTree *ntree)
for(tnode= ntree->nodes.first; tnode; tnode= tnode->next) {
if(tnode->typeinfo->nclass==NODE_CLASS_OUTPUT) {
if(tnode->type==node->type) {
if(output==0)
tnode->flag |= NODE_DO_OUTPUT;
else
tnode->flag &= ~NODE_DO_OUTPUT;
output= 1;
if(tnode->flag & NODE_DO_OUTPUT) {
if(output>1)
tnode->flag &= ~NODE_DO_OUTPUT;
output++;
}
}
}
}
if(output==0)
node->flag |= NODE_DO_OUTPUT;
}
}
@ -1210,14 +1214,6 @@ void ntreeSolveOrder(bNodeTree *ntree)
static void nodeInitPreview(bNode *node, int xsize, int ysize)
{
/* sanity checks & initialize */
if(node->preview && node->preview->rect) {
if(node->preview->xsize!=xsize && node->preview->ysize!=ysize) {
MEM_freeN(node->preview->rect);
node->preview->rect= NULL;
}
}
if(node->preview==NULL) {
node->preview= MEM_callocN(sizeof(bNodePreview), "node preview");
printf("added preview %s\n", node->name);
@ -1226,7 +1222,15 @@ static void nodeInitPreview(bNode *node, int xsize, int ysize)
/* node previews can get added with variable size this way */
if(xsize==0 || ysize==0)
return;
/* sanity checks & initialize */
if(node->preview && node->preview->rect) {
if(node->preview->xsize!=xsize && node->preview->ysize!=ysize) {
MEM_freeN(node->preview->rect);
node->preview->rect= NULL;
}
}
if(node->preview->rect==NULL) {
node->preview->rect= MEM_callocN(4*xsize + xsize*ysize*sizeof(float)*4, "node preview rect");
node->preview->xsize= xsize;

View File

@ -216,7 +216,7 @@ static void composit2_pixel_processor(bNode *node, CompBuf *out, CompBuf *src_bu
facx= fac_buf->x;
facy= fac_buf->y;
fac_stride= facx;
fac_pix= src_buf->type;
fac_pix= fac_buf->type;
fac_data= fac_buf->rect;
}
@ -408,6 +408,7 @@ static void generate_preview(bNode *node, CompBuf *stackbuf)
static bNodeSocketType cmp_node_viewer_in[]= {
{ SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
{ SOCK_VALUE, 1, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{ SOCK_VALUE, 1, "Z", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{ -1, 0, "" }
};
@ -415,6 +416,10 @@ static void do_copy_rgba(bNode *node, float *out, float *in)
{
QUATCOPY(out, in);
}
static void do_copy_value(bNode *node, float *out, float *in)
{
out[0]= in[0];
}
static void do_copy_a_rgba(bNode *node, float *out, float *in, float *fac)
{
VECCOPY(out, in);
@ -424,7 +429,7 @@ static void do_copy_a_rgba(bNode *node, float *out, float *in, float *fac)
static void node_composit_exec_viewer(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
{
/* image assigned to output */
/* stack order input sockets: col, alpha */
/* stack order input sockets: col, alpha, z */
if(node->id && (node->flag & NODE_DO_OUTPUT)) { /* only one works on out */
Image *ima= (Image *)node->id;
@ -434,7 +439,7 @@ static void node_composit_exec_viewer(void *data, bNode *node, bNodeStack **in,
/* scene size? */
if(1) {
RenderData *rd= data;
/* re-create output, derive size from scene */
rectx= (rd->size*rd->xsch)/100;
recty= (rd->size*rd->ysch)/100;
@ -451,6 +456,14 @@ static void node_composit_exec_viewer(void *data, bNode *node, bNodeStack **in,
else
composit2_pixel_processor(node, cbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, do_copy_a_rgba);
if(in[2]->data) {
CompBuf *zbuf= alloc_compbuf(rectx, recty, CB_VAL, 0);
addzbuffloatImBuf(ima->ibuf);
zbuf->rect= ima->ibuf->zbuf_float;
composit1_pixel_processor(node, zbuf, in[2]->data, in[2]->vec, do_copy_value);
free_compbuf(zbuf);
}
generate_preview(node, cbuf);
free_compbuf(cbuf);
}
@ -465,8 +478,8 @@ static void node_composit_exec_viewer(void *data, bNode *node, bNodeStack **in,
cbuf->rect= NULL;
}
}
else if(in[0]->data)
} /* lets make only previews when not done yet, so activating doesnt update */
else if(in[0]->data && node->preview && node->preview->rect==NULL)
generate_preview(node, in[0]->data);
}
@ -486,6 +499,7 @@ static bNodeType cmp_node_viewer= {
static bNodeSocketType cmp_node_composite_in[]= {
{ SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
{ SOCK_VALUE, 1, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{ SOCK_VALUE, 1, "Z", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{ -1, 0, "" }
};
@ -493,14 +507,14 @@ static bNodeSocketType cmp_node_composite_in[]= {
static void node_composit_exec_composite(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
{
/* image assigned to output */
/* stack order input sockets: col, alpha */
/* stack order input sockets: col, alpha, z */
if(node->flag & NODE_DO_OUTPUT) { /* only one works on out */
RenderData *rd= data;
if(rd->scemode & R_DOCOMP) {
RenderResult *rr= RE_GetResult(RE_GetRender("Render"));
if(rr) {
CompBuf *outbuf;
CompBuf *outbuf, *zbuf=NULL;
if(rr->rectf)
MEM_freeN(rr->rectf);
@ -511,6 +525,15 @@ static void node_composit_exec_composite(void *data, bNode *node, bNodeStack **i
else
composit2_pixel_processor(node, outbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, do_copy_a_rgba);
if(in[2]->data) {
if(rr->rectz)
MEM_freeN(rr->rectz);
zbuf= alloc_compbuf(rr->rectx, rr->recty, CB_VAL, 1);
composit1_pixel_processor(node, zbuf, in[2]->data, in[2]->vec, do_copy_value);
rr->rectz= zbuf->rect;
zbuf->malloc= 0;
free_compbuf(zbuf);
}
generate_preview(node, outbuf);
/* we give outbuf to rr... */
@ -675,6 +698,12 @@ static void node_composit_exec_image(void *data, bNode *node, bNodeStack **in, b
if(out[1]->hasoutput)
out[1]->data= alphabuf_from_rgbabuf(stackbuf);
if(out[2]->hasoutput && ima->ibuf->zbuf_float) {
CompBuf *zbuf= alloc_compbuf(ima->ibuf->x, ima->ibuf->y, CB_VAL, 0);
zbuf->rect= ima->ibuf->zbuf_float;
out[2]->data= zbuf;
}
generate_preview(node, stackbuf);
}
}
@ -705,28 +734,36 @@ static void node_composit_exec_rresult(void *data, bNode *node, bNodeStack **in,
{
RenderResult *rr= RE_GetResult(RE_GetRender("Render"));
if(rr) {
RenderLayer *rl= rr->layers.first;
CompBuf *stackbuf;
/* we put render rect on stack, cbuf knows rect is from other ibuf when freed! */
stackbuf= alloc_compbuf(rr->rectx, rr->recty, CB_RGBA, 0);
stackbuf->rect= rl->rectf;
/* put on stack */
out[0]->data= stackbuf;
if(out[1]->hasoutput)
out[1]->data= alphabuf_from_rgbabuf(stackbuf);
generate_preview(node, stackbuf);
RenderLayer *rl= BLI_findlink(&rr->layers, node->custom1);
if(rl) {
CompBuf *stackbuf;
/* we put render rect on stack, cbuf knows rect is from other ibuf when freed! */
stackbuf= alloc_compbuf(rr->rectx, rr->recty, CB_RGBA, 0);
stackbuf->rect= rl->rectf;
/* put on stack */
out[0]->data= stackbuf;
if(out[1]->hasoutput)
out[1]->data= alphabuf_from_rgbabuf(stackbuf);
if(out[2]->hasoutput && rl->rectz) {
CompBuf *zbuf= alloc_compbuf(rr->rectx, rr->recty, CB_VAL, 0);
zbuf->rect= rl->rectz;
out[2]->data= zbuf;
}
generate_preview(node, stackbuf);
}
}
}
/* custom1 = render layer in use */
static bNodeType cmp_node_rresult= {
/* type code */ CMP_NODE_R_RESULT,
/* name */ "Render Result",
/* width+range */ 120, 80, 300,
/* class+opts */ NODE_CLASS_GENERATOR, NODE_PREVIEW,
/* class+opts */ NODE_CLASS_GENERATOR, NODE_PREVIEW|NODE_OPTIONS,
/* input sock */ NULL,
/* output sock */ cmp_node_rresult_out,
/* storage */ "",
@ -951,6 +988,7 @@ static void node_composit_exec_mix_rgb(void *data, bNode *node, bNodeStack **in,
}
}
/* custom1 = mix type */
static bNodeType cmp_node_mix_rgb= {
/* type code */ CMP_NODE_MIX_RGB,
/* name */ "Mix",
@ -1082,6 +1120,7 @@ static void node_composit_exec_filter(void *data, bNode *node, bNodeStack **in,
}
}
/* custom1 = filter type */
static bNodeType cmp_node_filter= {
/* type code */ CMP_NODE_FILTER,
/* name */ "Filter",
@ -1255,9 +1294,65 @@ static bNodeType cmp_node_alphaover= {
};
/* **************** MAP VALUE ******************** */
static bNodeSocketType cmp_node_map_value_in[]= {
{ SOCK_VALUE, 1, "Value", 1.0f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
{ -1, 0, "" }
};
static bNodeSocketType cmp_node_map_value_out[]= {
{ SOCK_VALUE, 0, "Value", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
{ -1, 0, "" }
};
static void do_map_value(bNode *node, float *out, float *src)
{
TexMapping *texmap= node->storage;
out[0]= (src[0] + texmap->loc[0])*texmap->size[0];
if(texmap->flag & TEXMAP_CLIP_MIN)
if(out[0]<texmap->min[0])
out[0]= texmap->min[0];
if(texmap->flag & TEXMAP_CLIP_MAX)
if(out[0]>texmap->max[0])
out[0]= texmap->max[0];
}
static void node_composit_exec_map_value(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
{
/* stack order in: col col */
/* stack order out: col */
/* input no image? then only value operation */
if(in[0]->data==NULL) {
do_map_value(node, out[0]->vec, in[0]->vec);
}
else {
/* make output size of input image */
CompBuf *cbuf= in[0]->data;
CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); // allocs
composit1_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, do_map_value);
out[0]->data= stackbuf;
}
}
static bNodeType cmp_node_map_value= {
/* type code */ CMP_NODE_MAP_VALUE,
/* name */ "Map Value",
/* width+range */ 100, 60, 150,
/* class+opts */ NODE_CLASS_OPERATOR, NODE_OPTIONS,
/* input sock */ cmp_node_map_value_in,
/* output sock */ cmp_node_map_value_out,
/* storage */ "TexMapping",
/* execfunc */ node_composit_exec_map_value
};
/* **************** GAUSS BLUR ******************** */
static bNodeSocketType cmp_node_blur_in[]= {
{ SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
{ SOCK_VALUE, 1, "Size", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{ -1, 0, "" }
};
static bNodeSocketType cmp_node_blur_out[]= {
@ -1265,224 +1360,424 @@ static bNodeSocketType cmp_node_blur_out[]= {
{ -1, 0, "" }
};
static void node_composit_exec_blur(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
static float *make_gausstab(int rad)
{
CompBuf *new, *work, *img= in[0]->data;
register float sum, val;
float rval, gval, bval, aval;
float *gausstab, *v;
int r, n, m;
int x, y;
int i;
int step, bigstep;
float *src, *dest;
float *gausstab, sum, val;
int i, n;
if(img==NULL || out[0]->hasoutput==0)
return;
/* make output size of input image */
new= alloc_compbuf(img->x, img->y, CB_RGBA, 1); // allocs
out[0]->data= new;
/* prepare for gauss tab */
r = (1.5 * node->custom1 + 1.5);
n = 2 * r + 1;
/* ugly : */
if ((img->x <= n) || (img->y <= n)) {
printf("gauss filter too large/n");
return;
}
n = 2 * rad + 1;
gausstab = (float *) MEM_mallocN(n * sizeof(float), "gauss");
sum = 0.0f;
v = gausstab;
for (x = -r; x <= r; x++) {
val = exp(-4*(float ) (x*x)/ (float) (r*r));
for (i = -rad; i <= rad; i++) {
val = exp(-4.0*((float)i*i) / (float) (rad*rad));
sum += val;
*v++ = val;
gausstab[i+rad] = val;
}
i = n;
v = gausstab;
while (i--) {
*v++ /= sum;
sum= 1.0f/sum;
for(i=0; i<n; i++)
gausstab[i]*= sum;
return gausstab;
}
static float *make_bloomtab(int rad)
{
float *bloomtab, val;
int i, n;
n = 2 * rad + 1;
bloomtab = (float *) MEM_mallocN(n * sizeof(float), "bloom");
for (i = -rad; i <= rad; i++) {
val = pow(1.0 - fabs((float)i)/((float)rad), 4.0);
bloomtab[i+rad] = val;
}
return bloomtab;
}
static void blur_single_image(CompBuf *new, CompBuf *img, float blurx, float blury)
{
CompBuf *work;
register float sum, val;
float rval, gval, bval, aval;
float *gausstab, *gausstabcent;
int rad, imgx= img->x, imgy= img->y;
int x, y, pix= img->type;
int i, bigstep;
float *src, *dest;
/* helper image */
work= alloc_compbuf(img->x, img->y, CB_RGBA, 1); // allocs
work= alloc_compbuf(imgx, imgy, img->type, 1); // allocs
/* horizontal */
step = (n - 1);
rad = ceil(blurx);
if(rad>imgx/2)
rad= imgx/2;
else if(rad<1)
rad= 1;
gausstab= make_gausstab(rad);
gausstabcent= gausstab+rad;
for (y = 0; y < img->y; y++) {
src = img->rect + 4*(y * img->x);
dest = work->rect + 4*(y * img->x);
for (y = 0; y < imgy; y++) {
float *srcd= img->rect + pix*(y*img->x);
for (x = r; x > 0 ; x--) {
m = n - x;
gval = rval= bval= aval= 0.0f;
sum = 0.0;
v = gausstab + x;
for (i = 0; i < m; i++) {
val = *v++;
sum += val;
rval += val * (*src++);
gval += val * (*src++);
bval += val * (*src++);
aval += val * (*src++);
}
*dest++ = rval / sum;
*dest++ = gval / sum;
*dest++ = bval / sum;
*dest++ = aval / sum;
dest = work->rect + pix*(y * img->x);
for (x = 0; x < imgx ; x++) {
int minr= x-rad<0?-x:-rad;
int maxr= x+rad>imgx?imgx-x:rad;
src -= 4*m;
}
for (x = 0; x <= (img->x - n); x++) {
gval = rval= bval= aval= 0.0f;
v = gausstab;
src= srcd + pix*(x+minr);
for (i = 0; i < n; i++) {
val = *v++;
sum= gval = rval= bval= aval= 0.0f;
for (i= minr; i < maxr; i++) {
val= gausstabcent[i];
sum+= val;
rval += val * (*src++);
gval += val * (*src++);
bval += val * (*src++);
aval += val * (*src++);
if(pix==4) {
gval += val * (*src++);
bval += val * (*src++);
aval += val * (*src++);
}
}
*dest++ = rval;
*dest++ = gval;
*dest++ = bval;
*dest++ = aval;
src -= 4*step;
}
for (x = 1; x <= r ; x++) {
m = n - x;
gval = rval= bval= aval= 0.0f;
sum = 0.0;
v = gausstab;
for (i = 0; i < m; i++) {
val = *v++;
sum += val;
rval += val * (*src++);
gval += val * (*src++);
bval += val * (*src++);
aval += val * (*src++);
sum= 1.0f/sum;
*dest++ = rval*sum;
if(pix==4) {
*dest++ = gval*sum;
*dest++ = bval*sum;
*dest++ = aval*sum;
}
*dest++ = rval / sum;
*dest++ = gval / sum;
*dest++ = bval / sum;
*dest++ = aval / sum;
src -= 4*(m - 1);
}
}
/* vertical */
MEM_freeN(gausstab);
/* prepare for gauss tab */
r = (1.5 * node->custom2 + 1.5);
n = 2 * r + 1;
/* ugly : */
if ((img->x <= n) || (img->y <= n)) {
printf("gauss filter too large/n");
return;
}
gausstab = (float *) MEM_mallocN(n * sizeof(float), "gauss");
sum = 0.0f;
v = gausstab;
for (x = -r; x <= r; x++) {
val = exp(-4*(float ) (x*x)/ (float) (r*r));
sum += val;
*v++ = val;
}
i = n;
v = gausstab;
while (i--) {
*v++ /= sum;
}
step = img->x;
bigstep = (n - 1) * step;
for (x = 0; x < step ; x++) {
dest = new->rect + 4*x;
src = work->rect + 4*x;
for (y = r; y > 0; y--) {
m = n - y;
gval = rval= bval= aval= 0.0f;
sum = 0.0;
v = gausstab + y;
for (i = 0; i < m; i++) {
val = *v++;
sum += val;
rval += val * src[0];
gval += val * src[1];
bval += val * src[2];
aval += val * src[3];
src += 4 * step;
}
dest[0] = rval / sum;
dest[1] = gval / sum;
dest[2] = bval / sum;
dest[3] = aval / sum;
src -= 4 * m * step;
dest+= 4 * step;
}
for (y = 0; y <= (img->y - n); y++) {
gval = rval= bval= aval= 0.0f;
v = gausstab;
for (i = 0; i < n; i++) {
val = *v++;
rval += val * src[0];
gval += val * src[1];
bval += val * src[2];
aval += val * src[3];
src += 4 * step;
}
dest[0] = rval;
dest[1] = gval;
dest[2] = bval;
dest[3] = aval;
dest += 4 * step;
src -= 4 * bigstep;
}
for (y = 1; y <= r ; y++) {
m = n - y;
gval = rval= bval= aval= 0.0f;
sum = 0.0;
v = gausstab;
for (i = 0; i < m; i++) {
val = *v++;
sum += val;
rval += val * src[0];
gval += val * src[1];
bval += val * src[2];
aval += val * src[3];
src += 4 * step;
}
dest[0] = rval / sum;
dest[1] = gval / sum;
dest[2] = bval / sum;
dest[3] = aval / sum;
dest += 4* step;
src -= 4 * (m - 1) * step;
}
}
rad = ceil(blury);
if(rad>imgy/2)
rad= imgy/2;
else if(rad<1)
rad= 1;
gausstab= make_gausstab(rad);
gausstabcent= gausstab+rad;
bigstep = pix*imgx;
for (x = 0; x < imgx; x++) {
float *srcd= work->rect + pix*x;
dest = new->rect + pix*x;
for (y = 0; y < imgy ; y++) {
int minr= y-rad<0?-y:-rad;
int maxr= y+rad>imgy?imgy-y:rad;
src= srcd + bigstep*(y+minr);
sum= gval = rval= bval= aval= 0.0f;
for (i= minr; i < maxr; i++) {
val= gausstabcent[i];
sum+= val;
rval += val * src[0];
if(pix==4) {
gval += val * src[1];
bval += val * src[2];
aval += val * src[3];
}
src += bigstep;
}
sum= 1.0f/sum;
dest[0] = rval*sum;
if(pix==4) {
dest[1] = gval*sum;
dest[2] = bval*sum;
dest[3] = aval*sum;
}
dest+= bigstep;
}
}
free_compbuf(work);
MEM_freeN(gausstab);
}
/* reference has to be mapped 0-1, and equal in size */
static void bloom_with_reference(CompBuf *new, CompBuf *img, CompBuf *ref, float blurx, float blury)
{
CompBuf *wbuf;
register float val;
float radxf, radyf;
float **maintabs;
float *gausstabx, *gausstabcenty;
float *gausstaby, *gausstabcentx;
int radx, rady, imgx= img->x, imgy= img->y;
int x, y;
int i, j;
float *src, *dest, *wb;
wbuf= alloc_compbuf(imgx, imgy, CB_VAL, 1);
memset(wbuf->rect, sizeof(float)*imgx*imgy, 0);
/* horizontal */
radx = ceil(blurx);
if(radx>imgx/2)
radx= imgx/2;
else if(radx<1)
radx= 1;
/* vertical */
rady = ceil(blury);
if(rady>imgy/2)
rady= imgy/2;
else if(rady<1)
rady= 1;
x= MAX2(radx, rady);
maintabs= MEM_mallocN(x*sizeof(void *), "gauss array");
for(i= 0; i<x; i++)
maintabs[i]= make_bloomtab(i+1);
/* vars to store before we go */
// refd= ref->rect;
src= img->rect;
memset(new->rect, 4*imgx*imgy, 0);
radxf= (float)radx;
radyf= (float)rady;
for (y = 0; y < imgy; y++) {
for (x = 0; x < imgx ; x++, src+=4) {//, refd++) {
// int refradx= (int)(refd[0]*radxf);
// int refrady= (int)(refd[0]*radyf);
int refradx= (int)(radxf*0.3f*src[3]*(src[0]+src[1]+src[2]));
int refrady= (int)(radyf*0.3f*src[3]*(src[0]+src[1]+src[2]));
if(refradx>radx) refradx= radx;
else if(refradx<1) refradx= 1;
if(refrady>rady) refrady= rady;
else if(refrady<1) refrady= 1;
if(refradx==1 && refrady==1) {
wb= wbuf->rect + ( y*imgx + x);
dest= new->rect + 4*( y*imgx + x);
wb[0]+= 1.0f;
dest[0] += src[0];
dest[1] += src[1];
dest[2] += src[2];
dest[3] += src[3];
}
else {
int minxr= x-refradx<0?-x:-refradx;
int maxxr= x+refradx>imgx?imgx-x:refradx;
int minyr= y-refrady<0?-y:-refrady;
int maxyr= y+refrady>imgy?imgy-y:refrady;
float *destd= new->rect + 4*( (y + minyr)*imgx + x + minxr);
float *wbufd= wbuf->rect + ( (y + minyr)*imgx + x + minxr);
gausstabx= maintabs[refradx-1];
gausstabcentx= gausstabx+refradx;
gausstaby= maintabs[refrady-1];
gausstabcenty= gausstaby+refrady;
for (i= minyr; i < maxyr; i++, destd+= 4*imgx, wbufd+= imgx) {
dest= destd;
wb= wbufd;
for (j= minxr; j < maxxr; j++, dest+=4, wb++) {
val= gausstabcenty[i]*gausstabcentx[j];
wb[0]+= val;
dest[0] += val * src[0];
dest[1] += val * src[1];
dest[2] += val * src[2];
dest[3] += val * src[3];
}
}
}
}
}
x= imgx*imgy;
dest= new->rect;
wb= wbuf->rect;
while(x--) {
val= 1.0f/wb[0];
dest[0]*= val;
dest[1]*= val;
dest[2]*= val;
dest[3]*= val;
wb++;
dest+= 4;
}
free_compbuf(wbuf);
x= MAX2(radx, rady);
for(i= 0; i<x; i++)
MEM_freeN(maintabs[i]);
MEM_freeN(maintabs);
}
/* reference has to be mapped 0-1, and equal in size */
static void blur_with_reference(CompBuf *new, CompBuf *img, CompBuf *ref, float blurx, float blury)
{
CompBuf *blurbuf;
register float sum, val;
float rval, gval, bval, aval, radxf, radyf;
float **maintabs;
float *gausstabx, *gausstabcenty;
float *gausstaby, *gausstabcentx;
int radx, rady, imgx= img->x, imgy= img->y;
int x, y;
int i, j;
float *src, *dest, *refd, *blurd;
/* trick is; we blur the reference image... but only works with clipped values*/
blurbuf= alloc_compbuf(imgx, imgy, CB_VAL, 1);
blurd= blurbuf->rect;
refd= ref->rect;
for(x= imgx*imgy; x>0; x--, refd++, blurd++) {
if(refd[0]<0.0f) blurd[0]= 0.0f;
else if(refd[0]>1.0f) blurd[0]= 1.0f;
else blurd[0]= refd[0];
}
blur_single_image(blurbuf, blurbuf, blurx, blury);
/* horizontal */
radx = ceil(blurx);
if(radx>imgx/2)
radx= imgx/2;
else if(radx<1)
radx= 1;
/* vertical */
rady = ceil(blury);
if(rady>imgy/2)
rady= imgy/2;
else if(rady<1)
rady= 1;
x= MAX2(radx, rady);
maintabs= MEM_mallocN(x*sizeof(void *), "gauss array");
for(i= 0; i<x; i++)
maintabs[i]= make_gausstab(i+1);
refd= blurbuf->rect;
dest= new->rect;
radxf= (float)radx;
radyf= (float)rady;
for (y = 0; y < imgy; y++) {
for (x = 0; x < imgx ; x++, dest+=4, refd++) {
int refradx= (int)(refd[0]*radxf);
int refrady= (int)(refd[0]*radyf);
if(refradx>radx) refradx= radx;
else if(refradx<1) refradx= 1;
if(refrady>rady) refrady= rady;
else if(refrady<1) refrady= 1;
if(refradx==1 && refrady==1) {
src= img->rect + 4*( y*imgx + x);
QUATCOPY(dest, src);
}
else {
int minxr= x-refradx<0?-x:-refradx;
int maxxr= x+refradx>imgx?imgx-x:refradx;
int minyr= y-refrady<0?-y:-refrady;
int maxyr= y+refrady>imgy?imgy-y:refrady;
float *srcd= img->rect + 4*( (y + minyr)*imgx + x + minxr);
gausstabx= maintabs[refradx-1];
gausstabcentx= gausstabx+refradx;
gausstaby= maintabs[refrady-1];
gausstabcenty= gausstaby+refrady;
sum= gval = rval= bval= aval= 0.0f;
for (i= minyr; i < maxyr; i++, srcd+= 4*imgx) {
src= srcd;
for (j= minxr; j < maxxr; j++, src+=4) {
val= gausstabcenty[i]*gausstabcentx[j];
sum+= val;
rval += val * src[0];
gval += val * src[1];
bval += val * src[2];
aval += val * src[3];
}
}
sum= 1.0f/sum;
dest[0] = rval*sum;
dest[1] = gval*sum;
dest[2] = bval*sum;
dest[3] = aval*sum;
}
}
}
free_compbuf(blurbuf);
x= MAX2(radx, rady);
for(i= 0; i<x; i++)
MEM_freeN(maintabs[i]);
MEM_freeN(maintabs);
}
static void node_composit_exec_blur(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
{
CompBuf *new, *img= in[0]->data;
if(img==NULL || out[0]->hasoutput==0)
return;
/* if fac input, we do it different */
if(in[1]->data) {
/* test fitness if reference */
/* make output size of input image */
new= alloc_compbuf(img->x, img->y, CB_RGBA, 1); // allocs
blur_with_reference(new, img, in[1]->data, (float)node->custom1, (float)node->custom2);
out[0]->data= new;
}
else {
if(in[1]->vec[0]==0.0f) {
/* pass on image */
new= alloc_compbuf(img->x, img->y, img->type, 0);
new->rect= img->rect;
}
else {
/* make output size of input image */
new= alloc_compbuf(img->x, img->y, img->type, 1); // allocs
if(1)
blur_single_image(new, img, in[1]->vec[0]*(float)node->custom1, in[1]->vec[0]*(float)node->custom2);
else /* bloom experimental... */
bloom_with_reference(new, img, NULL, in[1]->vec[0]*(float)node->custom1, in[1]->vec[0]*(float)node->custom2);
}
out[0]->data= new;
}
}
/* custom1 custom2 = blur filter size */
static bNodeType cmp_node_blur= {
/* type code */ CMP_NODE_BLUR,
/* name */ "Blur",
@ -1516,6 +1811,7 @@ bNodeType *node_all_composit[]= {
&cmp_node_rresult,
&cmp_node_alphaover,
&cmp_node_blur,
&cmp_node_map_value,
NULL
};

View File

@ -114,6 +114,8 @@ void free_qtcodecdata(QuicktimeCodecData *qcd)
}
}
/* copy_scene moved to src/header_info.c... should be back */
/* do not free scene itself */
void free_scene(Scene *sce)
{
@ -144,6 +146,7 @@ void free_scene(Scene *sce)
}
BLI_freelistN(&sce->markers);
BLI_freelistN(&sce->r.layers);
if(sce->toolsettings){
MEM_freeN(sce->toolsettings);
@ -224,6 +227,8 @@ Scene *add_scene(char *name)
BLI_init_rctf(&sce->r.safety, 0.1f, 0.9f, 0.1f, 0.9f);
sce->r.osa= 8;
scene_add_render_layer(sce);
return sce;
}
@ -479,3 +484,19 @@ void scene_update_for_newframe(Scene *sce, unsigned int lay)
setcount++;
}
}
/* return default layer, also used to patch old files */
void scene_add_render_layer(Scene *sce)
{
SceneRenderLayer *srl;
int tot= 1 + BLI_countlist(&sce->r.layers);
srl= MEM_callocN(sizeof(SceneRenderLayer), "new render layer");
sprintf(srl->name, "%d RenderLayer", tot);
BLI_addtail(&sce->r.layers, srl);
srl->lay= (1<<20) -1;
srl->layflag= 0x7FFF; /* solid ztra halo strand */
srl->passflag= SCE_PASS_COMBINED|SCE_PASS_Z;
}

View File

@ -2807,6 +2807,7 @@ static void direct_link_scene(FileData *fd, Scene *sce)
}
link_list(fd, &(sce->markers));
link_list(fd, &(sce->r.layers));
sce->nodetree= newdataadr(fd, sce->nodetree);
if(sce->nodetree)
@ -5259,6 +5260,9 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
for(sce= main->scene.first; sce; sce= sce->id.next) {
if(sce->r.xparts<2) sce->r.xparts= 4;
if(sce->r.yparts<2) sce->r.yparts= 4;
/* adds default layer */
if(sce->r.layers.first==NULL)
scene_add_render_layer(sce);
}
}

View File

@ -1137,7 +1137,8 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
MetaStack *ms;
Strip *strip;
TimeMarker *marker;
SceneRenderLayer *srl;
sce= scebase->first;
while(sce) {
/* write LibData */
@ -1213,11 +1214,11 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
}
/* writing dynamic list of TimeMarkers to the blend file */
marker= sce->markers.first;
while(marker){
for(marker= sce->markers.first; marker; marker= marker->next)
writestruct(wd, DATA, "TimeMarker", 1, marker);
marker= marker->next;
}
for(srl= sce->r.layers.first; srl; srl= srl->next)
writestruct(wd, DATA, "SceneRenderLayer", 1, srl);
if(sce->nodetree) {
writestruct(wd, DATA, "bNodeTree", 1, sce->nodetree);

View File

@ -319,8 +319,9 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la
#define B_SWITCHRENDER 1641
#define B_FBUF_REDO 1642
#define B_SET_EDGE 1643
#define B_SET_ZBLUR 1644
#define B_SET_EDGE 1643
#define B_SET_ZBLUR 1644
#define B_ADD_RENDERLAYER 1645
/* *********************** */
#define B_ARMATUREBUTS 1800

View File

@ -30,10 +30,11 @@
#ifndef DNA_NODE_TYPES_H
#define DNA_NODE_TYPES_H
#include "DNA_ID.h"
#include "DNA_vec_types.h"
#include "DNA_listBase.h"
struct ID;
struct SpaceNode;
struct bNodeLink;
struct bNodeType;

View File

@ -94,6 +94,34 @@ typedef struct AudioData {
short pad[3];
} AudioData;
typedef struct SceneRenderLayer {
struct SceneRenderLayer *next, *prev;
char name[32];
struct Scene *scene; /* unused still */
unsigned int lay; /* scene->lay itself has priority over this */
short layflag;
short passflag;
} SceneRenderLayer;
/* srl->layflag */
#define SCE_LAY_SOLID 1
#define SCE_LAY_ZTRA 2
#define SCE_LAY_HALO 4
#define SCE_LAY_STRAND 8
/* srl->passflag */
#define SCE_PASS_COMBINED 1
#define SCE_PASS_Z 2
#define SCE_PASS_RGBA 4
#define SCE_PASS_DIFFUSE 8
#define SCE_PASS_SPEC 16
#define SCE_PASS_SHADOW 32
#define SCE_PASS_AO 64
#define SCE_PASS_MIRROR 128
#define SCE_PASS_NORMAL 256
#define SCE_PASS_VECTOR 512
typedef struct RenderData {
struct AviCodecData *avicodecdata;
struct QuicktimeCodecData *qtcodecdata;
@ -209,6 +237,11 @@ typedef struct RenderData {
/* safety and border rect */
rctf safety, border;
/* information on different layers to be rendered */
ListBase layers;
short actlay, pad;
int pad2;
/**
* The gamma for the normal rendering. Used when doing
* oversampling, to correctly blend subpixels to pixels. */

View File

@ -60,8 +60,10 @@ typedef struct Render Render;
typedef struct RenderLayer {
struct RenderLayer *next, *prev;
char name[RE_MAXNAME];
int flag, type;
/* copy of RenderData */
char name[RE_MAXNAME];
unsigned int lay;
int layflag, passflag;
float *rectf; /* standard rgba buffer */
float *rectz; /* standard camera coordinate zbuffer */
@ -88,6 +90,7 @@ typedef struct RenderResult {
/* the main buffers */
ListBase layers;
int actlay; /* copy of renderdata..., so display callbacks can find out */
/* optional saved endresult on disk */
char exrfile[FILE_MAXDIR];

View File

@ -31,6 +31,7 @@
#define ZBUF_H
struct RenderPart;
struct RenderLayer;
struct LampRen;
struct VlakRen;
struct ListBase;
@ -47,8 +48,9 @@ int testclip(float *v);
void set_part_zbuf_clipflag(struct RenderPart *pa);
void zbuffer_shadow(struct Render *re, struct LampRen *lar, int *rectz, int size);
void zbuffer_solid(struct RenderPart *pa);
void zbuffer_transp_shade(struct RenderPart *pa, float *pass);
void zbuffer_solid(struct RenderPart *pa, unsigned int layer, short layflag);
void zbuffer_transp_shade(struct RenderPart *pa, float *pass, unsigned int layer, short layflag);
void convert_zbuf_to_distbuf(struct RenderPart *pa, struct RenderLayer *rl);
typedef struct APixstr {
unsigned short mask[4]; /* jitter mask */

View File

@ -126,8 +126,9 @@ static Render *envmap_render_copy(Render *re, EnvMap *env)
/* set up renderdata */
envre->r= re->r;
envre->r.mode &= ~(R_BORDER | R_PANORAMA | R_ORTHO | R_MBLUR);
envre->r.layers.first= envre->r.layers.last= NULL;
envre->r.filtertype= 0;
envre->r.xparts= envre->r.yparts= 1;
envre->r.xparts= envre->r.yparts= 2;
envre->r.bufflag= 0;
envre->r.size= 100;
envre->r.yasp= envre->r.xasp= 1;

View File

@ -154,6 +154,8 @@ static void free_render_result(RenderResult *res)
if(res->rect32)
MEM_freeN(res->rect32);
if(res->rectz)
MEM_freeN(res->rectz);
if(res->rectf)
MEM_freeN(res->rectf);
@ -168,6 +170,7 @@ static RenderResult *new_render_result(Render *re, rcti *partrct, int crop)
{
RenderResult *rr;
RenderLayer *rl;
SceneRenderLayer *srl;
int rectx, recty;
rectx= partrct->xmax - partrct->xmin;
@ -188,64 +191,89 @@ 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;
/* check renderdata for amount of layers */
/* for now just one */
rl= RE_callocN(sizeof(RenderLayer), "new render layer");
BLI_addtail(&rr->layers, rl);
/* copy, so display callbacks can find out too */
rr->actlay= re->r.actlay;
rl->rectf= RE_callocN(rectx*recty*sizeof(float)*4, "layer float rgba");
rl->rectz= RE_callocN(rectx*recty*sizeof(float), "layer float Z");
/* check renderdata for amount of layers */
for(srl= re->r.layers.first; srl; srl= srl->next) {
rl= RE_callocN(sizeof(RenderLayer), "new render layer");
BLI_addtail(&rr->layers, rl);
strcpy(rl->name, srl->name);
rl->lay= srl->lay;
rl->layflag= srl->layflag;
rl->passflag= srl->passflag;
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");
}
/* previewrender and envmap don't do layers, so we make a default one */
if(rr->layers.first==NULL) {
rl= RE_callocN(sizeof(RenderLayer), "new render layer");
BLI_addtail(&rr->layers, rl);
rl->rectf= RE_callocN(rectx*recty*sizeof(float)*4, "layer float rgba");
rl->rectz= RE_callocN(rectx*recty*sizeof(float), "layer float Z");
}
return rr;
}
/* used when rendering to a full buffer, or when reading the exr part-layer-pass file */
/* no test happens here if it fits... */
/* no test happens here if it fits... we also assume layers are in sync */
/* is used within threads */
static void merge_render_result(RenderResult *rr, RenderResult *rrpart)
{
RenderLayer *rl= rr->layers.first;
RenderLayer *rlp= rrpart->layers.first;
RenderLayer *rl, *rlp;
float *rf, *rfp;
int *rz=NULL, *rzp;
float *rz, *rzp;
int y, height, len, copylen;
if(rlp->rectf==NULL) return;
if(rl->rectf==NULL) return;
rzp= NULL; //rlp->rectz;
rfp= rlp->rectf;
copylen=len= rrpart->rectx;
height= rrpart->recty;
if(rrpart->crop) { /* filters add pixel extra */
for(rl= rr->layers.first, rlp= rrpart->layers.first; rl && rlp; rl= rl->next, rlp= rlp->next) {
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;
// rz= re->rectz+ (pa->miny + rrpart->crop)*rr->rectx+ (pa->minx+rrpart->crop);
rf= rl->rectf+ ( (rrpart->tilerect.ymin + rrpart->crop)*rr->rectx + (rrpart->tilerect.xmin+rrpart->crop) )*4;
}
else {
// rz= re->rectz + (pa->disprect.ymin*rr->rectx + pa->disprect.xmin);
rf= rl->rectf+ (rrpart->tilerect.ymin*rr->rectx + rrpart->tilerect.xmin)*4;
}
/* 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;
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;
}
}
}
}
}
@ -278,22 +306,25 @@ RenderResult *RE_GetResult(Render *re)
void RE_GetResultImage(Render *re, RenderResult *rr)
{
memset(rr, sizeof(RenderResult), 0);
if(re && re->result) {
RenderLayer *rl;
rr->rectx= re->result->rectx;
rr->recty= re->result->recty;
rr->rectf= re->result->rectf;
rr->rectz= re->result->rectz;
rr->rect32= re->result->rect32;
/* will become 'active' call */
rl= re->result->layers.first;
if(rr->rectf==NULL)
rr->rectf= rl->rectf;
if(rr->rectz==NULL)
rr->rectz= rl->rectz;
/* active layer */
rl= BLI_findlink(&re->result->layers, re->r.actlay);
if(rl) {
if(rr->rectf==NULL)
rr->rectf= rl->rectf;
if(rr->rectz==NULL)
rr->rectz= rl->rectz;
}
}
}

View File

@ -471,7 +471,7 @@ static void halo_pixelstruct(HaloRen *har, float *rb, float dist, float xn, floa
}
static void halo_tile(RenderPart *pa, float *pass)
static void halo_tile(RenderPart *pa, float *pass, unsigned int lay)
{
HaloRen *har = NULL;
rcti disprect= pa->disprect;
@ -488,8 +488,9 @@ static void halo_tile(RenderPart *pa, float *pass)
}
else har++;
/* clip halo with y */
if(disprect.ymin > har->maxy);
/* layer test, clip halo with y */
if((har->lay & lay)==0);
else if(disprect.ymin > har->maxy);
else if(disprect.ymax < har->miny);
else {
@ -2646,6 +2647,7 @@ static void freeps(ListBase *lb)
RE_freeN(psm->ps);
RE_freeN(psm);
}
lb->first= lb->last= NULL;
}
static void addps(ListBase *lb, long *rd, int facenr, int z, unsigned short mask)
@ -2704,53 +2706,77 @@ static void make_pixelstructs(RenderPart *pa, ListBase *lb)
/* supposed to be fully threadable! */
void zbufshadeDA_tile(RenderPart *pa)
{
RenderLayer *rl= pa->result->layers.first;
RenderLayer *rl;
ListBase psmlist= {NULL, NULL};
float *acolrect= NULL, *edgerect= NULL;
set_part_zbuf_clipflag(pa);
/* allocate the necessary buffers */
pa->rectdaps= RE_callocN(sizeof(long)*pa->rectx*pa->recty+4, "zbufDArectd");
/* zbuffer inits these rects */
pa->rectp= RE_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp");
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");
/* initialize pixelstructs */
addpsmain(&psmlist);
for(pa->sample=0; pa->sample<R.osa; pa->sample++) {
zbuffer_solid(pa);
make_pixelstructs(pa, &psmlist);
if(R.r.mode & R_EDGE) edge_enhance_calc(pa, edgerect);
if(R.test_break()) break;
}
/* we do transp layer first, so its get added with filter in main buffer... still incorrect though */
if(R.flag & R_ZTRA) {
acolrect= RE_callocN(4*sizeof(float)*pa->rectx*pa->recty, "alpha layer");
zbuffer_transp_shade(pa, acolrect);
}
for(rl= pa->result->layers.first; rl; rl= rl->next) {
/* shades solid and adds transparent layer */
shadeDA_tile(pa, rl->rectf, acolrect);
/* extra layers */
if(R.r.mode & R_EDGE)
edge_enhance_add(pa, rl->rectf, edgerect);
if(R.flag & R_HALO)
halo_tile(pa, rl->rectf);
/* initialize pixelstructs */
addpsmain(&psmlist);
pa->rectdaps= RE_callocN(sizeof(long)*pa->rectx*pa->recty+4, "zbufDArectd");
if(rl->layflag & SCE_LAY_SOLID) {
for(pa->sample=0; pa->sample<R.osa; pa->sample++) {
zbuffer_solid(pa, rl->lay, rl->layflag);
make_pixelstructs(pa, &psmlist);
if(R.r.mode & R_EDGE) edge_enhance_calc(pa, edgerect);
if(R.test_break()) break;
}
}
else /* need to clear rectz for next passes */
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 */
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);
}
}
/* 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)
edge_enhance_add(pa, rl->rectf, edgerect);
if(R.flag & R_HALO)
if(rl->layflag & SCE_LAY_HALO)
halo_tile(pa, rl->rectf, rl->lay);
if(rl->passflag & SCE_PASS_Z)
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);
}
/* free all */
RE_freeN(pa->rectp); pa->rectp= NULL;
RE_freeN(pa->rectz); pa->rectz= NULL;
RE_freeN(pa->rectdaps); pa->rectdaps= NULL;
if(acolrect) RE_freeN(acolrect);
if(edgerect) RE_freeN(edgerect);
freeps(&psmlist);
}
@ -2760,43 +2786,53 @@ void zbufshadeDA_tile(RenderPart *pa)
/* supposed to be fully threadable! */
void zbufshade_tile(RenderPart *pa)
{
RenderLayer *rl= pa->result->layers.first;
float *fcol;
int x, y, *rp, *rz;
RenderLayer *rl;
set_part_zbuf_clipflag(pa);
/* zbuffer code clears/inits rects */
rp= pa->rectp= RE_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp");
rz= pa->rectz= RE_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz");
pa->rectp= RE_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp");
pa->rectz= RE_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz");
zbuffer_solid(pa);
if(!R.test_break()) {
fcol= rl->rectf;
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);
for(rl= pa->result->layers.first; rl; rl= rl->next) {
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);
}
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)
zbuffer_transp_shade(pa, rl->rectf);
if(!R.test_break()) {
if(R.r.mode & R_EDGE) {
fillrect(pa->rectp, pa->rectx, pa->recty, 0);
edge_enhance_calc(pa, (float *)pa->rectp);
edge_enhance_add(pa, rl->rectf, (float *)pa->rectp);
if(!R.test_break())
if(R.flag & R_ZTRA)
if(rl->layflag & SCE_LAY_ZTRA)
zbuffer_transp_shade(pa, rl->rectf, rl->lay, rl->layflag);
if(!R.test_break()) {
if(R.r.mode & R_EDGE) {
fillrect(pa->rectp, pa->rectx, pa->recty, 0);
edge_enhance_calc(pa, (float *)pa->rectp);
edge_enhance_add(pa, rl->rectf, (float *)pa->rectp);
}
}
if(!R.test_break())
if(R.flag & R_HALO)
if(rl->layflag & SCE_LAY_HALO)
halo_tile(pa, rl->rectf, rl->lay);
if(rl->passflag & SCE_PASS_Z)
convert_zbuf_to_distbuf(pa, rl);
}
if(!R.test_break())
if(R.flag & R_HALO)
halo_tile(pa, rl->rectf);
RE_freeN(pa->rectp); pa->rectp= NULL;
RE_freeN(pa->rectz); pa->rectz= NULL;

View File

@ -1592,7 +1592,7 @@ void set_part_zbuf_clipflag(RenderPart *pa)
}
}
void zbuffer_solid(RenderPart *pa)
void zbuffer_solid(RenderPart *pa, unsigned int lay, short layflag)
{
ZSpan zspan;
VlakRen *vlr= NULL;
@ -1633,7 +1633,7 @@ void zbuffer_solid(RenderPart *pa)
if((v & 255)==0) vlr= R.blovl[v>>8];
else vlr++;
if(vlr->flag & R_VISIBLE) {
if((vlr->flag & R_VISIBLE) && (vlr->lay & lay)) {
if(vlr->mat!=ma) {
ma= vlr->mat;
transp= ma->mode & MA_ZTRA;
@ -1906,7 +1906,7 @@ static void copyto_abufz(RenderPart *pa, int *arectz, int sample)
* Do accumulation z buffering.
*/
static void zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase)
static void zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, unsigned int lay, short layflag)
{
ZSpan zspan;
Material *ma=0;
@ -1952,7 +1952,7 @@ static void zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase)
ma= vlr->mat;
if(ma->mode & (MA_ZTRA)) {
if(vlr->flag & R_VISIBLE) {
if((vlr->flag & R_VISIBLE) && (vlr->lay & lay)) {
unsigned short partclip;
/* partclipping doesn't need viewplane clipping */
@ -2075,7 +2075,7 @@ static int addtosampcol(float *sampcol, float *fcol, int mask)
#define MAX_ZROW 1000
/* main render call to fill in pass the full transparent layer */
void zbuffer_transp_shade(RenderPart *pa, float *pass)
void zbuffer_transp_shade(RenderPart *pa, float *pass, unsigned int lay, short layflag)
{
APixstr *APixbuf; /* Zbuffer: linked list of face samples */
APixstr *ap, *apn;
@ -2106,7 +2106,7 @@ void zbuffer_transp_shade(RenderPart *pa, float *pass)
}
/* fill the Apixbuf */
zbuffer_abuf(pa, APixbuf, &apsmbase);
zbuffer_abuf(pa, APixbuf, &apsmbase, lay, layflag);
/* render tile */
ap= APixbuf;
@ -2229,6 +2229,39 @@ void zbuffer_transp_shade(RenderPart *pa, float *pass)
}
/* *************** */
/* uses part zbuffer values to convert into distances from camera in renderlayer */
void convert_zbuf_to_distbuf(RenderPart *pa, RenderLayer *rl)
{
float *rectzf, zco;
int a, *rectz, ortho= R.r.mode & R_ORTHO;
if(pa->rectz==NULL) return;
if(rl->rectz==NULL) {
printf("called convert zbuf wrong...\n");
return;
}
rectzf= rl->rectz;
rectz= pa->rectz;
for(a=pa->rectx*pa->recty; a>0; a--, rectz++, rectzf++) {
if(*rectz==0x7FFFFFFF)
*rectzf= 10e10;
else {
/* inverse of zbuf calc: zbuf = MAXZ*hoco_z/hoco_w */
/* or: (R.winmat[3][2] - zco*R.winmat[3][3])/(R.winmat[2][2] - R.winmat[2][3]*zco); */
/* if ortho [2][3] is zero, else [3][3] is zero */
zco= ((float)*rectz)/2147483647.0f;
if(ortho)
*rectzf= (R.winmat[3][2] - zco*R.winmat[3][3])/(R.winmat[2][2]);
else
*rectzf= (R.winmat[3][2])/(R.winmat[2][2] - R.winmat[2][3]*zco);
}
}
}
/* end of zbuf.c */

View File

@ -36,6 +36,7 @@
#include <string.h>
#include "MEM_guardedalloc.h"
#include "DNA_node_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
#include "DNA_scene_types.h"
@ -45,7 +46,9 @@
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_node.h"
#include "BKE_library.h"
#include "BKE_scene.h"
#include "BKE_sound.h"
#include "BKE_packedFile.h"
#include "BKE_utildefines.h"
@ -816,6 +819,13 @@ void do_render_panels(unsigned short event)
G.scene->r.mode &= ~R_EDGE;
allqueue(REDRAWBUTSSCENE, 0);
break;
case B_ADD_RENDERLAYER:
if(G.scene->r.actlay==32767) {
scene_add_render_layer(G.scene);
G.scene->r.actlay= BLI_countlist(&G.scene->r.layers) - 1;
}
allqueue(REDRAWBUTSSCENE, 0);
allqueue(REDRAWNODE, 0);
}
}
@ -1475,12 +1485,152 @@ static void render_panel_sfx(void)
}
#endif
static void layer_copy_func(void *lay_v, void *lay_p)
{
unsigned int *lay= lay_p;
int laybit= (int)lay_v;
if(G.qual & LR_SHIFTKEY) {
if(*lay==0) *lay= 1<<laybit;
}
else
*lay= 1<<laybit;
copy_view3d_lock(REDRAW);
allqueue(REDRAWBUTSSCENE, 0);
}
static void delete_scene_layer_func(void *srl_v, void *unused1)
{
if(BLI_countlist(&G.scene->r.layers)>1) {
BLI_remlink(&G.scene->r.layers, srl_v);
MEM_freeN(srl_v);
G.scene->r.actlay= 0;
allqueue(REDRAWBUTSSCENE, 0);
allqueue(REDRAWNODE, 0);
}
}
static void rename_scene_layer_func(void *srl_v, void *unused_v)
{
if(G.scene->nodetree) {
SceneRenderLayer *srl= srl_v;
bNode *node;
for(node= G.scene->nodetree->nodes.first; node; node= node->next) {
if(node->type==CMP_NODE_R_RESULT) {
if(node->custom1==G.scene->r.actlay)
BLI_strncpy(node->name, srl->name, NODE_MAXSTR);
}
}
}
allqueue(REDRAWNODE, 0);
}
static char *scene_layer_menu(void)
{
SceneRenderLayer *srl;
int len= 32 + 32*BLI_countlist(&G.scene->r.layers);
short a, nr;
char *str= MEM_callocN(len, "menu layers");
strcpy(str, "ADD NEW %x32767");
a= strlen(str);
for(nr=0, srl= G.scene->r.layers.first; srl; srl= srl->next, nr++) {
a+= sprintf(str+a, "|%s %%x%d", srl->name, nr);
}
return str;
}
static void draw_3d_layer_buttons(uiBlock *block, unsigned int *poin, short xco, short yco, short dx, short dy, int event)
{
uiBut *bt;
long a;
uiBlockBeginAlign(block);
for(a=0; a<5; a++) {
bt= uiDefButBitI(block, TOG, 1<<a, B_NOP, "", (short)(xco+a*(dx/2)), yco+dy/2, (short)(dx/2), (short)(dy/2), poin, 0, 0, 0, 0, "");
uiButSetFunc(bt, layer_copy_func, (void *)a, poin);
}
for(a=0; a<5; a++) {
bt=uiDefButBitI(block, TOG, 1<<(a+10), B_NOP, "", (short)(xco+a*(dx/2)), yco, (short)(dx/2), (short)(dy/2), poin, 0, 0, 0, 0, "");
uiButSetFunc(bt, layer_copy_func, (void *)(a+10), poin);
}
xco+= 7;
uiBlockBeginAlign(block);
for(a=5; a<10; a++) {
bt=uiDefButBitI(block, TOG, 1<<a, B_NOP, "", (short)(xco+a*(dx/2)), yco+dy/2, (short)(dx/2), (short)(dy/2), poin, 0, 0, 0, 0, "");
uiButSetFunc(bt, layer_copy_func, (void *)a, poin);
}
for(a=5; a<10; a++) {
bt=uiDefButBitI(block, TOG, 1<<(a+10), B_NOP, "", (short)(xco+a*(dx/2)), yco, (short)(dx/2), (short)(dy/2), poin, 0, 0, 0, 0, "");
uiButSetFunc(bt, layer_copy_func, (void *)(a+10), poin);
}
uiBlockEndAlign(block);
}
static void render_panel_layers(void)
{
uiBlock *block;
uiBut *bt;
SceneRenderLayer *srl= BLI_findlink(&G.scene->r.layers, G.scene->r.actlay);
char *strp;
block= uiNewBlock(&curarea->uiblocks, "render_panel_layers", UI_EMBOSS, UI_HELV, curarea->win);
uiNewPanelTabbed("Output", "Render");
if(uiNewPanel(curarea, block, "Render Layers", "Render", 320, 0, 318, 204)==0) return;
/* first, as reminder, the scene layers */
uiDefBut(block, LABEL, 0, "Scene:", 10,170,100,20, NULL, 0, 0, 0, 0, "");
draw_3d_layer_buttons(block, &G.scene->lay, 130, 170, 35, 30, B_LAY);
/* layer menu, name, delete button */
uiBlockBeginAlign(block);
strp= scene_layer_menu();
uiDefButS(block, MENU, B_ADD_RENDERLAYER, strp, 10,130,23,20, &(G.scene->r.actlay), 0, 0, 0, 0, "Choose Active Render Layer");
MEM_freeN(strp);
bt= uiDefBut(block, TEX, REDRAWNODE, "", 33,130,252,20, srl->name, 0.0, 31.0, 0, 0, "");
uiButSetFunc(bt, rename_scene_layer_func, srl, NULL);
bt=uiDefIconBut(block, BUT, B_NOP, ICON_X, 285, 130, 25, 20, 0, 0, 0, 0, 0, "Deletes current Render Layer");
uiButSetFunc(bt, delete_scene_layer_func, srl, NULL);
uiBlockEndAlign(block);
/* RenderLayer visible-layers */
uiDefBut(block, LABEL, 0, "Layer:", 10,95,100,20, NULL, 0, 0, 0, 0, "");
draw_3d_layer_buttons(block, &srl->lay, 130, 95, 35, 30, B_NOP);
uiBlockBeginAlign(block);
uiDefButBitS(block, TOG, SCE_LAY_SOLID, B_NOP,"Solid", 10, 70, 75, 20, &srl->layflag, 0, 0, 0, 0, "Render Solid faces in this Layer");
uiDefButBitS(block, TOG, SCE_LAY_ZTRA, B_NOP,"Ztra", 85, 70, 75, 20, &srl->layflag, 0, 0, 0, 0, "Render Z-Transparent faces in this Layer");
uiDefButBitS(block, TOG, SCE_LAY_HALO, B_NOP,"Halo", 160, 70, 75, 20, &srl->layflag, 0, 0, 0, 0, "Render Halos in this Layer");
uiDefButBitS(block, TOG, SCE_LAY_STRAND, B_NOP,"Strand", 235, 70, 75, 20, &srl->layflag, 0, 0, 0, 0, "Render Particle Strands in this Layer");
uiBlockEndAlign(block);
uiDefBut(block, LABEL, 0, "Passes:", 10,30,150,20, NULL, 0, 0, 0, 0, "");
uiBlockBeginAlign(block);
uiDefButBitS(block, TOG, SCE_PASS_COMBINED, B_NOP,"Combined", 130, 30, 155, 20, &srl->passflag, 0, 0, 0, 0, "Deliver full combined RGBA buffer");
uiDefButBitS(block, TOG, SCE_PASS_Z, B_NOP,"Z", 285, 30, 25, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Z values pass");
uiDefButBitS(block, TOG, SCE_PASS_DIFFUSE, B_NOP,"Diff",10, 10, 45, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Diffuse pass");
uiDefButBitS(block, TOG, SCE_PASS_SPEC, B_NOP,"Spec", 55, 10, 45, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Diffuse pass");
uiDefButBitS(block, TOG, SCE_PASS_SHADOW, B_NOP,"Shad", 100, 10, 45, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Diffuse pass");
uiDefButBitS(block, TOG, SCE_PASS_AO, B_NOP,"AO", 145, 10, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Diffuse pass");
uiDefButBitS(block, TOG, SCE_PASS_MIRROR, B_NOP,"Mirr", 185, 10, 45, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Diffuse pass");
uiDefButBitS(block, TOG, SCE_PASS_NORMAL, B_NOP,"Nor", 230, 10, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Diffuse pass");
uiDefButBitS(block, TOG, SCE_PASS_VECTOR, B_NOP,"Vec", 270, 10, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Diffuse pass");
}
void render_panels()
{
render_panel_output();
// render_panel_sfx();
render_panel_layers();
render_panel_render();
render_panel_anim();
render_panel_format();

View File

@ -73,12 +73,16 @@
#include "BMF_Api.h"
#include "MEM_guardedalloc.h"
#include "RE_pipeline.h"
#include "blendef.h"
#include "butspace.h"
#include "interface.h" /* urm... for rasterpos_safe, roundbox */
#include "mydevice.h"
#include "MEM_guardedalloc.h"
static void snode_drawstring(SpaceNode *snode, char *str, int okwidth)
{
@ -659,6 +663,39 @@ static int node_composit_buts_image(uiBlock *block, bNodeTree *ntree, bNode *nod
return 19;
}
static char *scene_layer_menu(void)
{
SceneRenderLayer *srl;
int len= 32 + 32*BLI_countlist(&G.scene->r.layers);
short a, nr;
char *str= MEM_callocN(len, "menu layers");
strcpy(str, "Active Layer %t");
a= strlen(str);
for(nr=0, srl= G.scene->r.layers.first; srl; srl= srl->next, nr++) {
a+= sprintf(str+a, "|%s %%x%d", srl->name, nr);
}
return str;
}
static int node_composit_buts_renderresult(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
{
if(block) {
uiBut *bt;
char *strp;
strp= scene_layer_menu();
bt= uiDefButS(block, MENU, B_NODE_EXEC, strp,
butr->xmin, butr->ymin, (butr->xmax-butr->xmin), 19,
&node->custom1, 0, 0, 0, 0, "Choose Render Layer");
uiButSetFunc(bt, node_but_title_cb, node, bt);
MEM_freeN(strp);
}
return 19;
}
static int node_composit_buts_blur(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
{
if(block) {
@ -689,6 +726,29 @@ static int node_composit_buts_filter(uiBlock *block, bNodeTree *ntree, bNode *no
return 20;
}
static int node_composit_buts_map_value(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
{
if(block) {
TexMapping *texmap= node->storage;
short xstart= (short)butr->xmin;
short dy= (short)(butr->ymax-19.0f);
short dx= (short)(butr->xmax-butr->xmin)/2;
uiBlockBeginAlign(block);
uiDefButF(block, NUM, B_NODE_EXEC, "Offs:", xstart, dy, 2*dx, 19, texmap->loc, -1000.0f, 1000.0f, 10, 2, "");
dy-= 19;
uiDefButF(block, NUM, B_NODE_EXEC, "Size:", xstart, dy, 2*dx, 19, texmap->size, -1000.0f, 1000.0f, 10, 3, "");
dy-= 23;
uiBlockBeginAlign(block);
uiDefButBitI(block, TOG, TEXMAP_CLIP_MIN, B_NODE_EXEC, "Min", xstart, dy, dx, 19, &texmap->flag, 0.0f, 0.0f, 0, 0, "");
uiDefButF(block, NUM, B_NODE_EXEC, "", xstart+dx, dy, dx, 19, texmap->min, -1000.0f, 1000.0f, 10, 2, "");
dy-= 19;
uiDefButBitI(block, TOG, TEXMAP_CLIP_MIN, B_NODE_EXEC, "Max", xstart, dy, dx, 19, &texmap->flag, 0.0f, 0.0f, 0, 0, "");
uiDefButF(block, NUM, B_NODE_EXEC, "", xstart+dx, dy, dx, 19, texmap->min, -1000.0f, 1000.0f, 10, 2, "");
}
return 80;
}
/* only once called */
static void node_composit_set_butfunc(bNodeType *ntype)
@ -700,6 +760,9 @@ static void node_composit_set_butfunc(bNodeType *ntype)
case CMP_NODE_IMAGE:
ntype->butfunc= node_composit_buts_image;
break;
case CMP_NODE_R_RESULT:
ntype->butfunc= node_composit_buts_renderresult;
break;
case CMP_NODE_NORMAL:
ntype->butfunc= node_buts_normal;
break;
@ -727,6 +790,9 @@ static void node_composit_set_butfunc(bNodeType *ntype)
case CMP_NODE_FILTER:
ntype->butfunc= node_composit_buts_filter;
break;
case CMP_NODE_MAP_VALUE:
ntype->butfunc= node_composit_buts_map_value;
break;
default:
ntype->butfunc= NULL;
}
@ -986,15 +1052,27 @@ static void node_update(bNode *node)
/* preview rect? */
if(node->flag & NODE_PREVIEW) {
float aspect= 1.0f;
if(node->preview && node->preview->xsize && node->preview->ysize)
aspect= (float)node->preview->ysize/(float)node->preview->xsize;
dy-= NODE_DYS/2;
node->prvr.ymax= dy;
node->prvr.ymin= dy - aspect*(node->width-NODE_DY);
dy= node->prvr.ymin - NODE_DYS/2;
/* only recalculate size when there's a preview actually, otherwise we use stored result */
if(node->preview && node->preview->rect) {
float aspect= 1.0f;
if(node->preview && node->preview->xsize && node->preview->ysize)
aspect= (float)node->preview->ysize/(float)node->preview->xsize;
dy-= NODE_DYS/2;
node->prvr.ymax= dy;
node->prvr.ymin= dy - aspect*(node->width-NODE_DY);
dy= node->prvr.ymin - NODE_DYS/2;
}
else {
float oldh= node->prvr.ymax - node->prvr.ymin;
if(oldh==0.0f)
oldh= node->width-NODE_DY;
dy-= NODE_DYS/2;
node->prvr.ymax= dy;
node->prvr.ymin= dy - oldh;
dy= node->prvr.ymin - NODE_DYS/2;
}
}
/* buttons rect? */

View File

@ -203,10 +203,6 @@ static void composit_node_event(SpaceNode *snode, short event)
strcpy(name, ((Image *)node->id)->name);
else strcpy(name, U.textudir);
/* node->block pointers are stored, but filesel frees it, so we need to clear them */
for(node= snode->edittree->nodes.first; node; node= node->next)
node->block= NULL;
activate_fileselect(FILE_SPECIAL, "SELECT IMAGE", name, load_node_image);
}
}
@ -338,6 +334,34 @@ static void node_set_active(SpaceNode *snode, bNode *node)
allqueue(REDRAWBUTSSHADING, 1);
}
else if(snode->treetype==NTREE_COMPOSIT) {
/* make active viewer, currently only 1 supported... */
if(node->type==CMP_NODE_VIEWER) {
bNode *tnode;
int was_output= node->flag & NODE_DO_OUTPUT;
for(tnode= snode->edittree->nodes.first; tnode; tnode= tnode->next)
if(tnode->type==CMP_NODE_VIEWER)
tnode->flag &= ~NODE_DO_OUTPUT;
node->flag |= NODE_DO_OUTPUT;
if(was_output==0) snode_handle_recalc(snode);
/* add node doesnt link this yet... */
if(node->id==NULL) {
node->id= find_id("IM", "Compositor");
if(node->id==NULL) {
Image *ima= alloc_libblock(&G.main->image, ID_IM, "Compositor");
strcpy(ima->name, "Compositor");
ima->ok= 1;
ima->xrep= ima->yrep= 1;
node->id= &ima->id;
}
else
node->id->us++;
}
}
}
}
}
@ -1134,7 +1158,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|Normal %x207");
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");
if(event<1) return;
}
else return;
@ -1480,6 +1504,19 @@ void node_make_group(SpaceNode *snode)
return;
}
/* for time being... is too complex to handle */
if(snode->treetype==NTREE_COMPOSIT) {
for(gnode=snode->nodetree->nodes.first; gnode; gnode= gnode->next) {
if(gnode->flag & SELECT)
if(gnode->type==CMP_NODE_R_RESULT)
break;
}
if(gnode) {
error("Can not add RenderResult in a Group");
return;
}
}
gnode= nodeMakeGroupFromSelected(snode->nodetree);
if(gnode==NULL) {
error("Can not make Group");
@ -1496,7 +1533,7 @@ void node_make_group(SpaceNode *snode)
/* special version to prevent overlapping buttons, has a bit of hack... */
/* yes, check for example composit_node_event(), file window use... */
int node_uiDoBlocks(SpaceNode *snode, ListBase *lb, short event)
static int node_uiDoBlocks(SpaceNode *snode, ListBase *lb, short event)
{
bNode *node;
rctf rect;
@ -1507,6 +1544,11 @@ int node_uiDoBlocks(SpaceNode *snode, ListBase *lb, short event)
getmouseco_areawin(mval);
areamouseco_to_ipoco(G.v2d, mval, &rect.xmin, &rect.ymin);
/* this happens after filesel usage... */
if(lb->first==NULL) {
return UI_NOTHING;
}
rect.xmin -= 2.0f;
rect.ymin -= 2.0f;

View File

@ -316,6 +316,7 @@ Scene *copy_scene(Scene *sce, int level)
scen->toolsettings= MEM_dupallocN(sce->toolsettings);
duplicatelist(&(scen->markers), &(sce->markers));
duplicatelist(&(scen->r.layers), &(sce->r.layers));
scen->nodetree= ntreeCopyTree(sce->nodetree, 0);

View File

@ -650,6 +650,7 @@ void BIF_view3d_previewrender(ScrArea *sa)
/* no osa, blur, seq, for preview render */
rdata= G.scene->r;
rdata.mode &= ~(R_OSA|R_MBLUR|R_DOSEQ);
rdata.layers.first= rdata.layers.last= NULL;
RE_InitState(re, &rdata, sa->winx, sa->winy, &ri->disprect);

View File

@ -287,46 +287,46 @@ static void renderwin_draw_render_info(RenderWin *rw)
static void renderwin_draw(RenderWin *rw, int just_clear)
{
RenderResult rres;
float fullrect[2][2];
int set_back_mainwindow;
rcti rect;
/* since renderwin uses callbacks (controlled by ghost) it can
mess up active window output with redraw events after a render.
this is patchy, still WIP */
set_back_mainwindow = (winlay_get_active_window() != rw->win);
window_make_active(rw->win);
RE_GetResultImage(RE_GetRender("Render"), &rres);
rect.xmin= rect.ymin= 0;
window_get_size(rw->win, &rect.xmax, &rect.ymax);
rect.ymax-= RW_HEADERY;
renderwin_get_fullrect(rw, fullrect);
/* do this first, so window ends with correct scissor */
renderwin_draw_render_info(rw);
glEnable(GL_SCISSOR_TEST);
glaDefine2DArea(&rect);
glClearColor(.1875, .1875, .1875, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
if(rres.rectf) {
float fullrect[2][2];
int set_back_mainwindow;
rcti rect;
/* since renderwin uses callbacks (controlled by ghost) it can
mess up active window output with redraw events after a render.
this is patchy, still WIP */
set_back_mainwindow = (winlay_get_active_window() != rw->win);
window_make_active(rw->win);
if (just_clear) {
glColor3ub(0, 0, 0);
glRectfv(fullrect[0], fullrect[1]);
} else {
RenderResult rres;
rect.xmin= rect.ymin= 0;
window_get_size(rw->win, &rect.xmax, &rect.ymax);
rect.ymax-= RW_HEADERY;
renderwin_get_fullrect(rw, fullrect);
/* do this first, so window ends with correct scissor */
renderwin_draw_render_info(rw);
glEnable(GL_SCISSOR_TEST);
glaDefine2DArea(&rect);
glClearColor(.1875, .1875, .1875, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
if (just_clear) {
glColor3ub(0, 0, 0);
glRectfv(fullrect[0], fullrect[1]);
} else {
RE_GetResultImage(RE_GetRender("Render"), &rres);
if(rres.rectf) {
glPixelZoom(rw->zoom, rw->zoom);
if(rw->flags & RW_FLAGS_ALPHA) {
/* swap bytes, so alpha is most significant one, then just draw it as luminance int */
// glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
// glaDrawPixelsSafe(fullrect[0][0], fullrect[0][1], rr->rectx, rr->recty, GL_LUMINANCE, GL_UNSIGNED_INT, R.rectot);
// glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
// glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
// glaDrawPixelsSafe(fullrect[0][0], fullrect[0][1], rr->rectx, rr->recty, GL_LUMINANCE, GL_UNSIGNED_INT, R.rectot);
// glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
}
else {
if(rres.rect32)
@ -336,25 +336,25 @@ static void renderwin_draw(RenderWin *rw, int just_clear)
}
glPixelZoom(1.0, 1.0);
}
/* info text is overlayed on bottom */
if (rw->info_text) {
float w;
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
w=186.0*strlen(rw->info_text)/30;
glColor4f(.5,.5,.5,.25);
glRectf(0.0,0.0,w,30.0);
glDisable(GL_BLEND);
glColor3ub(255, 255, 255);
glRasterPos2i(10, 10);
BMF_DrawString(G.font, rw->info_text);
}
window_swap_buffers(rw->win);
if (set_back_mainwindow) mainwindow_make_active();
}
/* info text is overlayed on bottom */
if (rw->info_text) {
float w;
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
w=186.0*strlen(rw->info_text)/30;
glColor4f(.5,.5,.5,.25);
glRectf(0.0,0.0,w,30.0);
glDisable(GL_BLEND);
glColor3ub(255, 255, 255);
glRasterPos2i(10, 10);
BMF_DrawString(G.font, rw->info_text);
}
window_swap_buffers(rw->win);
if (set_back_mainwindow) mainwindow_make_active();
}
/* ------ interactivity calls for RenderWin ------------- */
@ -736,7 +736,7 @@ static void renderwin_progress(RenderWin *rw, RenderResult *rr, rcti *unused)
if(rr->rectf)
rectf= rr->rectf;
else {
RenderLayer *rl= rr->layers.first;
RenderLayer *rl= BLI_findlink(&rr->layers, rr->actlay);
rectf= rl->rectf;
}
/* when rendering more pixels than needed, we crop away cruft */