Fix for bug #8073: texture nodes connected to a viewer could crash.

Also fixed a bug where procedural buffers did not convert correctly
to different buffer types (e.g. value -> rgba would give red).
This commit is contained in:
Brecht Van Lommel
2008-04-07 15:21:25 +00:00
parent 77639a5cde
commit 6dec5db1e6
3 changed files with 123 additions and 11 deletions

View File

@@ -42,12 +42,12 @@ static bNodeSocketType cmp_node_texture_out[]= {
};
/* called without rect allocated */
static void texture_procedural(CompBuf *cbuf, float *col, float xco, float yco)
static void texture_procedural(CompBuf *cbuf, float *out, float xco, float yco)
{
bNode *node= cbuf->node;
TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
float vec[3], *size, nor[3]={0.0f, 0.0f, 0.0f};
int retval, type= cbuf->type;
float vec[3], *size, nor[3]={0.0f, 0.0f, 0.0f}, col[4];
int retval, type= cbuf->procedural_type;
size= cbuf->procedural_size;
@@ -79,6 +79,8 @@ static void texture_procedural(CompBuf *cbuf, float *col, float xco, float yco)
else {
VECCOPY(col, nor);
}
typecheck_compbuf_color(out, col, cbuf->type, cbuf->procedural_type);
}
/* texture node outputs get a small rect, to make sure all other nodes accept it */
@@ -107,6 +109,7 @@ static void node_composit_exec_texture(void *data, bNode *node, bNodeStack **in,
prevbuf->node= node;
VECCOPY(prevbuf->procedural_offset, in[0]->vec);
VECCOPY(prevbuf->procedural_size, in[1]->vec);
prevbuf->procedural_type= CB_RGBA;
composit1_pixel_processor(node, prevbuf, prevbuf, out[0]->vec, do_copy_rgba, CB_RGBA);
generate_preview(node, prevbuf);
free_compbuf(prevbuf);
@@ -118,6 +121,7 @@ static void node_composit_exec_texture(void *data, bNode *node, bNodeStack **in,
stackbuf->node= node;
VECCOPY(stackbuf->procedural_offset, in[0]->vec);
VECCOPY(stackbuf->procedural_size, in[1]->vec);
stackbuf->procedural_type= CB_VAL;
out[0]->data= stackbuf;
}
@@ -128,6 +132,7 @@ static void node_composit_exec_texture(void *data, bNode *node, bNodeStack **in,
stackbuf->node= node;
VECCOPY(stackbuf->procedural_offset, in[0]->vec);
VECCOPY(stackbuf->procedural_size, in[1]->vec);
stackbuf->procedural_type= CB_RGBA;
out[1]->data= stackbuf;
}

View File

@@ -225,17 +225,100 @@ CompBuf *scalefast_compbuf(CompBuf *inbuf, int newx, int newy)
return outbuf;
}
void typecheck_compbuf_color(float *out, float *in, int outtype, int intype)
{
if(intype == outtype) {
memcpy(out, in, sizeof(float)*outtype);
}
else if(outtype==CB_VAL) {
if(intype==CB_VEC2) {
*out= 0.5f*(in[0]+in[1]);
}
else if(intype==CB_VEC3) {
*out= 0.333333f*(in[0]+in[1]+in[2]);
}
else if(intype==CB_RGBA) {
*out= in[0]*0.35f + in[1]*0.45f + in[2]*0.2f;
}
}
else if(outtype==CB_VEC2) {
if(intype==CB_VAL) {
out[0]= in[0];
out[1]= in[0];
}
else if(intype==CB_VEC3) {
out[0]= in[0];
out[1]= in[1];
}
else if(intype==CB_RGBA) {
out[0]= in[0];
out[1]= in[1];
}
}
else if(outtype==CB_VEC3) {
if(intype==CB_VAL) {
out[0]= in[0];
out[1]= in[0];
out[2]= in[0];
}
else if(intype==CB_VEC2) {
out[0]= in[0];
out[1]= in[1];
out[2]= 0.0f;
}
else if(intype==CB_RGBA) {
out[0]= in[0];
out[1]= in[1];
out[2]= in[2];
}
}
else if(outtype==CB_RGBA) {
if(intype==CB_VAL) {
out[0]= in[0];
out[1]= in[0];
out[2]= in[0];
out[3]= 1.0f;
}
else if(intype==CB_VEC2) {
out[0]= in[0];
out[1]= in[1];
out[2]= 0.0f;
out[3]= 1.0f;
}
else if(intype==CB_VEC3) {
out[0]= in[0];
out[1]= in[1];
out[2]= in[2];
out[3]= 1.0f;
}
}
}
CompBuf *typecheck_compbuf(CompBuf *inbuf, int type)
{
if(inbuf && inbuf->type!=type && inbuf->rect_procedural==NULL) {
CompBuf *outbuf= alloc_compbuf(inbuf->x, inbuf->y, type, 1);
float *inrf= inbuf->rect;
float *outrf= outbuf->rect;
int x= inbuf->x*inbuf->y;
if(inbuf && inbuf->type!=type) {
CompBuf *outbuf;
float *inrf, *outrf;
int x;
outbuf= alloc_compbuf(inbuf->x, inbuf->y, type, 1);
/* warning note: xof and yof are applied in pixelprocessor, but should be copied otherwise? */
outbuf->xof= inbuf->xof;
outbuf->yof= inbuf->yof;
if(inbuf->rect_procedural) {
outbuf->rect_procedural= inbuf->rect_procedural;
VECCOPY(outbuf->procedural_size, inbuf->procedural_size);
VECCOPY(outbuf->procedural_offset, inbuf->procedural_offset);
outbuf->procedural_type= inbuf->procedural_type;
outbuf->node= inbuf->node;
return outbuf;
}
inrf= inbuf->rect;
outrf= outbuf->rect;
x= inbuf->x*inbuf->y;
if(type==CB_VAL) {
if(inbuf->type==CB_VEC2) {
@@ -502,6 +585,25 @@ CompBuf *valbuf_from_rgbabuf(CompBuf *cbuf, int channel)
return valbuf;
}
static CompBuf *generate_procedural_preview(CompBuf *cbuf, int newx, int newy)
{
CompBuf *outbuf;
float *outfp;
int xrad, yrad, x, y;
outbuf= alloc_compbuf(newx, newy, CB_RGBA, 1);
outfp= outbuf->rect;
xrad= outbuf->xrad;
yrad= outbuf->yrad;
for(y= -yrad; y<-yrad+outbuf->y; y++)
for(x= -xrad; x<-xrad+outbuf->x; x++, outfp+=outbuf->type)
cbuf->rect_procedural(cbuf, outfp, (float)x/(float)xrad, (float)y/(float)yrad);
return outbuf;
}
void generate_preview(bNode *node, CompBuf *stackbuf)
{
bNodePreview *preview= node->preview;
@@ -509,7 +611,7 @@ void generate_preview(bNode *node, CompBuf *stackbuf)
if(preview && stackbuf) {
CompBuf *cbuf, *stackbuf_use;
if(stackbuf->rect==NULL) return;
if(stackbuf->rect==NULL && stackbuf->rect_procedural==NULL) return;
stackbuf_use= typecheck_compbuf(stackbuf, CB_RGBA);
@@ -522,7 +624,10 @@ void generate_preview(bNode *node, CompBuf *stackbuf)
preview->xsize= (140*stackbuf->x)/stackbuf->y;
}
cbuf= scalefast_compbuf(stackbuf_use, preview->xsize, preview->ysize);
if(stackbuf_use->rect_procedural)
cbuf= generate_procedural_preview(stackbuf_use, preview->xsize, preview->ysize);
else
cbuf= scalefast_compbuf(stackbuf_use, preview->xsize, preview->ysize);
/* this ensures free-compbuf does the right stuff */
SWAP(float *, cbuf->rect, node->preview->rect);

View File

@@ -108,6 +108,7 @@ typedef struct CompBuf {
void (*rect_procedural)(struct CompBuf *, float *, float, float);
float procedural_size[3], procedural_offset[3];
int procedural_type;
bNode *node; /* only in use for procedural bufs */
struct CompBuf *next, *prev; /* for pass-on, works nicer than reference counting */
@@ -138,6 +139,7 @@ void node_compo_pass_on(struct bNode *node, struct bNodeStack **nsin, struct bNo
CompBuf *get_cropped_compbuf(rcti *drect, float *rectf, int rectx, int recty, int type);
CompBuf *scalefast_compbuf(CompBuf *inbuf, int newx, int newy);
CompBuf *typecheck_compbuf(CompBuf *inbuf, int type);
void typecheck_compbuf_color(float *out, float *in, int outtype, int intype);
float *compbuf_get_pixel(CompBuf *cbuf, float *rectf, int x, int y, int xrad, int yrad);
/* **************************************************** */