#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
void scene_update_for_newframe(struct Scene *sce, unsigned int lay);
+void scene_add_render_layer(struct Scene *sce);
+
#endif
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;
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;
}
}
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);
/* 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;
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;
}
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, "" }
};
{
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);
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;
/* 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;
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);
}
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);
}
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, "" }
};
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);
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... */
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);
}
}
{
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 */ "",
}
}
+/* custom1 = mix type */
static bNodeType cmp_node_mix_rgb= {
/* type code */ CMP_NODE_MIX_RGB,
/* name */ "Mix",
}
}
+/* custom1 = filter type */
static bNodeType cmp_node_filter= {
/* type code */ CMP_NODE_FILTER,
/* name */ "Filter",
};
+/* **************** 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[]= {
{ -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;
-
-
- 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;
+ float *gausstab, sum, val;
+ int i, n;
- /* 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;
-
- src -= 4*m;
- }
+ dest = work->rect + pix*(y * img->x);
- for (x = 0; x <= (img->x - n); x++) {
- gval = rval= bval= aval= 0.0f;
- v = gausstab;
+ for (x = 0; x < imgx ; x++) {
+ int minr= x-rad<0?-x:-rad;
+ int maxr= x+rad>imgx?imgx-x:rad;
- for (i = 0; i < n; i++) {
- val = *v++;
+ src= srcd + pix*(x+minr);
+
+ 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;
+ rad = ceil(blury);
+ if(rad>imgy/2)
+ rad= imgy/2;
+ else if(rad<1)
+ rad= 1;
+
+ gausstab= make_gausstab(rad);
+ gausstabcent= gausstab+rad;
- /* ugly : */
- if ((img->x <= n) || (img->y <= n)) {
- printf("gauss filter too large/n");
- return;
+ 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;
+ }
}
- gausstab = (float *) MEM_mallocN(n * sizeof(float), "gauss");
+ 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;
- sum = 0.0f;
- v = gausstab;
- for (x = -r; x <= r; x++) {
- val = exp(-4*(float ) (x*x)/ (float) (r*r));
- sum += val;
- *v++ = val;
- }
+ wbuf= alloc_compbuf(imgx, imgy, CB_VAL, 1);
+ memset(wbuf->rect, sizeof(float)*imgx*imgy, 0);
- i = n;
- v = gausstab;
- while (i--) {
- *v++ /= sum;
- }
+ /* horizontal */
+ radx = ceil(blurx);
+ if(radx>imgx/2)
+ radx= imgx/2;
+ else if(radx<1)
+ radx= 1;
- step = img->x;
- bigstep = (n - 1) * step;
- for (x = 0; x < step ; x++) {
- dest = new->rect + 4*x;
- src = work->rect + 4*x;
+ /* 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);
- 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;
+ /* 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];
}
- 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;
+ 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];
+ }
+ }
}
- 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;
+ }
+
+ 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;
}
- dest[0] = rval / sum;
- dest[1] = gval / sum;
- dest[2] = bval / sum;
- dest[3] = aval / sum;
- dest += 4* step;
- src -= 4 * (m - 1) * step;
}
}
+
+ free_compbuf(blurbuf);
+
+ x= MAX2(radx, rady);
+ for(i= 0; i<x; i++)
+ MEM_freeN(maintabs[i]);
+ MEM_freeN(maintabs);
+
+}
- free_compbuf(work);
- MEM_freeN(gausstab);
+
+
+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",
&cmp_node_rresult,
&cmp_node_alphaover,
&cmp_node_blur,
+ &cmp_node_map_value,
NULL
};
}
}
+/* copy_scene moved to src/header_info.c... should be back */
+
/* do not free scene itself */
void free_scene(Scene *sce)
{
}
BLI_freelistN(&sce->markers);
+ BLI_freelistN(&sce->r.layers);
if(sce->toolsettings){
MEM_freeN(sce->toolsettings);
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;
}
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;
+}
+
}
link_list(fd, &(sce->markers));
+ link_list(fd, &(sce->r.layers));
sce->nodetree= newdataadr(fd, sce->nodetree);
if(sce->nodetree)
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);
}
}
MetaStack *ms;
Strip *strip;
TimeMarker *marker;
-
+ SceneRenderLayer *srl;
+
sce= scebase->first;
while(sce) {
/* write LibData */
}
/* 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);
#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
#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;
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;
/* 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. */
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 */
/* 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];
#define ZBUF_H
struct RenderPart;
+struct RenderLayer;
struct LampRen;
struct VlakRen;
struct ListBase;
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 */
/* 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;
if(res->rect32)
MEM_freeN(res->rect32);
+ if(res->rectz)
+ MEM_freeN(res->rectz);
if(res->rectf)
MEM_freeN(res->rectf);
{
RenderResult *rr;
RenderLayer *rl;
+ SceneRenderLayer *srl;
int rectx, recty;
rectx= partrct->xmax - partrct->xmin;
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 */
-
- 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;
+ for(rl= rr->layers.first, rlp= rrpart->layers.first; rl && rlp; rl= rl->next, rlp= rlp->next) {
- // 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;
+ }
+ }
}
}
}
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;
+ }
}
}
}
-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;
}
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 {
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)
/* 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);
+ for(rl= pa->result->layers.first; rl; rl= rl->next) {
+
+ /* initialize pixelstructs */
+ addpsmain(&psmlist);
+ pa->rectdaps= RE_callocN(sizeof(long)*pa->rectx*pa->recty+4, "zbufDArectd");
- 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);
- }
+ 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);
- /* 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);
+
+ /* 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);
}
/* 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");
-
- zbuffer_solid(pa);
+ pa->rectp= RE_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp");
+ pa->rectz= RE_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz");
- 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;
}
}
-void zbuffer_solid(RenderPart *pa)
+void zbuffer_solid(RenderPart *pa, unsigned int lay, short layflag)
{
ZSpan zspan;
VlakRen *vlr= NULL;
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;
* 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;
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 */
#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;
}
/* fill the Apixbuf */
- zbuffer_abuf(pa, APixbuf, &apsmbase);
+ zbuffer_abuf(pa, APixbuf, &apsmbase, lay, layflag);
/* render tile */
ap= APixbuf;
}
+/* *************** */
+
+/* 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 */
#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"
#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"
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);
}
}
}
#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();
#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)
{
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) {
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)
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;
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;
}
/* 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? */
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);
}
}
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++;
+ }
+ }
+ }
}
}
}
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;
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");
/* 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;
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;
scen->toolsettings= MEM_dupallocN(sce->toolsettings);
duplicatelist(&(scen->markers), &(sce->markers));
+ duplicatelist(&(scen->r.layers), &(sce->r.layers));
scen->nodetree= ntreeCopyTree(sce->nodetree, 0);
/* 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);
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);
-
- 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);
-
- 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);
+ 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 {
+ RenderResult rres;
- 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)
}
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 ------------- */
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 */