Orange: enabled compositing in render pipeline.
authorTon Roosendaal <ton@blender.org>
Tue, 24 Jan 2006 21:50:23 +0000 (21:50 +0000)
committerTon Roosendaal <ton@blender.org>
Tue, 24 Jan 2006 21:50:23 +0000 (21:50 +0000)
- New Node "Composite" is output node that puts composited result back
  in render pipeline.
- This then also displays in the render window while editing
- But, only with Scene buttons option "Do Compositor" set
- Then, just press F12 or render anims to see the magic!

For clarity, the former 'Output" node is renamed to "Viewer".

source/blender/blenkernel/BKE_node.h
source/blender/blenkernel/intern/node_composit.c
source/blender/makesdna/DNA_scene_types.h
source/blender/render/extern/include/RE_pipeline.h
source/blender/render/intern/source/pipeline.c
source/blender/src/buttons_scene.c
source/blender/src/editnode.c
source/blender/src/renderwin.c
source/blender/src/writeimage.c

index 3ecfbb8ef29921d849cf64631c429e6f33876ce5..23004b0ebeafa751f8e171c2dde034dc819d71e6 100644 (file)
@@ -182,10 +182,7 @@ void                       set_node_shader_lamp_loop(void (*lamp_loop_func)(struct ShadeInput *, str
 /* ************** COMPOSIT NODES *************** */
 
 /* note: types are needed to restore callbacks, don't change values */
-#define CMP_NODE_OUTPUT                        201
-#define CMP_NODE_OUTPUT_RENDER 202
-#define CMP_NODE_OUTPUT_FILE   203
-
+#define CMP_NODE_VIEWER                201
 #define CMP_NODE_RGB           202
 #define CMP_NODE_VALUE         203
 #define CMP_NODE_MIX_RGB       204
@@ -198,8 +195,10 @@ void                       set_node_shader_lamp_loop(void (*lamp_loop_func)(struct ShadeInput *, str
 #define CMP_NODE_BLUR          211
 #define CMP_NODE_FILTER                212
 
-#define CMP_NODE_IMAGE         220
-#define CMP_NODE_R_RESULT      221
+#define CMP_NODE_IMAGE                 220
+#define CMP_NODE_R_RESULT              221
+#define CMP_NODE_COMPOSITE             222
+#define CMP_NODE_OUTPUT_FILE   223
 
 
 /* filter types */
@@ -217,9 +216,10 @@ extern bNodeType *node_all_composit[];
 
 /* API */
 struct CompBuf;
-void ntreeCompositExecTree(struct bNodeTree *ntree);
+struct RenderData;
+void ntreeCompositExecTree(struct bNodeTree *ntree, struct RenderData *rd, int do_previews);
+int ntreeCompositNeedsRender(struct bNodeTree *ntree);
 void free_compbuf(struct CompBuf *cbuf); /* internal...*/
 
-
 #endif
 
index 4659b587e6103aac1c235fb510ac984c7ae7544e..8c2202f053d823bc14c74788a0b1a8bf545d3fc5 100644 (file)
@@ -404,8 +404,8 @@ static void generate_preview(bNode *node, CompBuf *stackbuf)
 
 /* Verification rule: If name changes, a saved socket and its links will be removed! Type changes are OK */
 
-/* **************** OUTPUT ******************** */
-static bNodeSocketType cmp_node_output_in[]= {
+/* **************** VIEWER ******************** */
+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},
        {       -1, 0, ""       }
@@ -421,7 +421,7 @@ static void do_copy_a_rgba(bNode *node, float *out, float *in, float *fac)
        out[3]= *fac;
 }
 
-static void node_composit_exec_output(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+static void node_composit_exec_viewer(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
 {
        /* image assigned to output */
        /* stack order input sockets: col, alpha */
@@ -433,9 +433,11 @@ static void node_composit_exec_output(void *data, bNode *node, bNodeStack **in,
                
                /* scene size? */
                if(1) {
+                       RenderData *rd= data;
+                       
                        /* re-create output, derive size from scene */
-                       rectx= (G.scene->r.size*G.scene->r.xsch)/100;
-                       recty= (G.scene->r.size*G.scene->r.ysch)/100;
+                       rectx= (rd->size*rd->xsch)/100;
+                       recty= (rd->size*rd->ysch)/100;
                        
                        if(ima->ibuf) IMB_freeImBuf(ima->ibuf);
                        ima->ibuf= IMB_allocImBuf(rectx, recty, 32, IB_rectfloat, 0); // do alloc
@@ -468,60 +470,71 @@ static void node_composit_exec_output(void *data, bNode *node, bNodeStack **in,
                generate_preview(node, in[0]->data);
 }
 
-static bNodeType cmp_node_output= {
-       /* type code   */       CMP_NODE_OUTPUT,
-       /* name        */       "Output",
+static bNodeType cmp_node_viewer= {
+       /* type code   */       CMP_NODE_VIEWER,
+       /* name        */       "Viewer",
        /* width+range */       80, 60, 200,
        /* class+opts  */       NODE_CLASS_OUTPUT, NODE_PREVIEW,
-       /* input sock  */       cmp_node_output_in,
+       /* input sock  */       cmp_node_viewer_in,
        /* output sock */       NULL,
        /* storage     */       "",
-       /* execfunc    */       node_composit_exec_output
+       /* execfunc    */       node_composit_exec_viewer
        
 };
 
-/* **************** OUTPUT RENDER ******************** */
-static bNodeSocketType cmp_node_output_render_in[]= {
+/* **************** COMPOSITE ******************** */
+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},
        {       -1, 0, ""       }
 };
 
-
-static void node_composit_exec_output_render(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+/* applies to render pipeline */
+static void node_composit_exec_composite(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
 {
        /* image assigned to output */
        /* stack order input sockets: col, alpha */
        
        if(node->flag & NODE_DO_OUTPUT) {       /* only one works on out */
-               RenderResult *rr= RE_GetResult(RE_GetRender("Render"));
-               if(rr) {
-                       RenderLayer *rl= rr->layers.first;
-                       CompBuf *outbuf= alloc_compbuf(rr->rectx, rr->recty, CB_RGBA, 0);       /* no alloc */
-                       
-                       outbuf->rect= rl->rectf;
-                       
-                       if(in[1]->data==NULL)
-                               composit1_pixel_processor(node, outbuf, in[0]->data, in[0]->vec, do_copy_rgba);
-                       else
-                               composit2_pixel_processor(node, outbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, do_copy_a_rgba);
-                       
-                       free_compbuf(outbuf);
+               RenderData *rd= data;
+               if(rd->scemode & R_DOCOMP) {
+                       RenderResult *rr= RE_GetResult(RE_GetRender("Render"));
+                       if(rr) {
+                               CompBuf *outbuf;
+                               
+                               if(rr->rectf) 
+                                       MEM_freeN(rr->rectf);
+                               outbuf= alloc_compbuf(rr->rectx, rr->recty, CB_RGBA, 1);
+                               
+                               if(in[1]->data==NULL)
+                                       composit1_pixel_processor(node, outbuf, in[0]->data, in[0]->vec, do_copy_rgba);
+                               else
+                                       composit2_pixel_processor(node, outbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, do_copy_a_rgba);
+                               
+                               generate_preview(node, outbuf);
+                               
+                               /* we give outbuf to rr... */
+                               rr->rectf= outbuf->rect;
+                               outbuf->malloc= 0;
+                               free_compbuf(outbuf);
+                               
+                               return;
+                       }
                }
        }
-       else if(in[0]->data)
+       if(in[0]->data)
                generate_preview(node, in[0]->data);
 }
 
-static bNodeType cmp_node_output_render= {
-       /* type code   */       CMP_NODE_OUTPUT_RENDER,
-       /* name        */       "Render Output",
+static bNodeType cmp_node_composite= {
+       /* type code   */       CMP_NODE_COMPOSITE,
+       /* name        */       "Composite",
        /* width+range */       80, 60, 200,
        /* class+opts  */       NODE_CLASS_OUTPUT, NODE_PREVIEW,
-       /* input sock  */       cmp_node_output_render_in,
+       /* input sock  */       cmp_node_composite_in,
        /* output sock */       NULL,
        /* storage     */       "",
-       /* execfunc    */       node_composit_exec_output_render
+       /* execfunc    */       node_composit_exec_composite
        
 };
 
@@ -575,7 +588,9 @@ static void node_composit_exec_image(void *data, bNode *node, bNodeStack **in, b
                /* test if image is OK */
                if(ima->ok==0) return;
                if(ima->ibuf==NULL) {
-                       load_image(ima, IB_rect, G.sce, G.scene->r.cfra);
+                       RenderData *rd= data;
+                       
+                       load_image(ima, IB_rect, G.sce, rd->cfra);      /* G.sce is current .blend path */
                        if(ima->ibuf==NULL) {
                                ima->ok= 0;
                                return;
@@ -1417,8 +1432,8 @@ static bNodeType cmp_node_blur= {
 
 bNodeType *node_all_composit[]= {
        &node_group_typeinfo,
-       &cmp_node_output,
-       &cmp_node_output_render,
+       &cmp_node_viewer,
+       &cmp_node_composite,
        &cmp_node_output_file,
        &cmp_node_value,
        &cmp_node_rgb,
@@ -1438,15 +1453,34 @@ bNodeType *node_all_composit[]= {
 
 /* ******************* execute and parse ************ */
 
-void ntreeCompositExecTree(bNodeTree *ntree)
+/* helper call to detect if theres a render-result node */
+int ntreeCompositNeedsRender(bNodeTree *ntree)
 {
+       bNode *node;
+       
+       if(ntree==NULL) return 1;
+       
+       for(node= ntree->nodes.first; node; node= node->next) {
+               if(node->type==CMP_NODE_R_RESULT)
+                       return 1;
+       }
+       return 0;
+}
+
+/* note; if called without preview, and previews exist, they get updated */
+/* render calls it without previews, works nicer for bg render */
+void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview)
+{
+       if(ntree==NULL) return;
+       
+       if(do_preview)
+               ntreeInitPreview(ntree, 0, 0);
        
-       ntreeInitPreview(ntree, 0, 0);
        ntreeBeginExecTree(ntree);
 
-       /* allocate composit data */
+       /* allocate composit data? */
        
-       ntreeExecTree(ntree, NULL, 0);  /* threads */
+       ntreeExecTree(ntree, rd, 0);    /* threads */
        
        ntreeEndExecTree(ntree);
 }
index 3f84b812cfb370370d9842d69c34de999253ff93..2f3452c5c757be864281d1f1fd03239de3f11a35 100644 (file)
@@ -379,6 +379,7 @@ typedef struct Scene {
 
 #define R_EXTENSION            0x0010
 #define R_NODE_PREVIEW 0x0020
+#define R_DOCOMP               0x0040
 
 /* alphamode */
 #define R_ADDSKY               0
index 14d21b699a3ac59912f08cedd46db98f9e44ab8e..b0a12d7f35789676993b12af3032b8cc447d4f99 100644 (file)
@@ -76,8 +76,12 @@ typedef struct RenderResult {
        int rectx, recty;
        short crop, pad;
        
-       /* optional, 32 bits version of (composited?) layers */
+       /* optional, 32 bits version of picture, used for ogl render and image curves */
        int *rect32;
+       /* if this exists, a copy of one of layers, or result of composited layers */
+       float *rectf;
+       /* if this exists, a copy of one of layers, or result of composited layers */
+       float *rectz;
        
        /* coordinates within final image (after cropping) */
        rcti tilerect;
@@ -112,6 +116,7 @@ void RE_FreeAllRender (void);
 
 /* get results and statistics */
 RenderResult *RE_GetResult(Render *re);
+void RE_GetResultImage(Render *re, RenderResult *rr);
 RenderStats *RE_GetStats(Render *re);
 void RE_ResultGet32(Render *re, unsigned int *rect);
 
index 67690fd69f6141d5f490f79c6f6a80d8cdbe0c67..e602f968beada2a30943ba49e08e5a083353e303 100644 (file)
@@ -37,6 +37,7 @@
 
 #include "BKE_global.h"
 #include "BKE_image.h"
+#include "BKE_node.h"
 #include "BKE_scene.h"
 #include "BKE_writeavi.h"      /* <------ should be replaced once with generic movie module */
 
@@ -153,6 +154,8 @@ static void free_render_result(RenderResult *res)
        
        if(res->rect32)
                MEM_freeN(res->rect32);
+       if(res->rectf)
+               MEM_freeN(res->rectf);
        
        RE_freeN(res);
 }
@@ -196,29 +199,6 @@ static RenderResult *new_render_result(Render *re, rcti *partrct, int crop)
        return rr;
 }
 
-#define FTOCHAR(val) val<=0.0f?0: (val>=1.0f?255: (char)(255.0f*val))
-/* caller is responsible for allocating rect in correct size! */
-void RE_ResultGet32(Render *re, unsigned int *rect)
-{
-       if(re->result) {
-               RenderLayer *rl= re->result->layers.first;
-               float *fp= rl->rectf;
-               if(fp) {
-                       int tot= re->rectx*re->recty;
-                       char *cp= (char *)rect;
-                       
-                       for(;tot>0; tot--, cp+=4, fp+=4) {
-                               cp[0] = FTOCHAR(fp[0]);
-                               cp[1] = FTOCHAR(fp[1]);
-                               cp[2] = FTOCHAR(fp[2]);
-                               cp[3] = FTOCHAR(fp[3]);
-                       }
-                       return;
-               }
-       }
-       /* else fill with black */
-       memset(rect, sizeof(int)*re->rectx*re->recty, 0);
-}
 
 /* used when rendering to a full buffer, or when reading the exr part-layer-pass file */
 /* no test happens here if it fits... */
@@ -286,6 +266,7 @@ Render *RE_GetRender(const char *name)
        return re;
 }
 
+/* if you want to know exactly what has been done */
 RenderResult *RE_GetResult(Render *re)
 {
        if(re)
@@ -293,6 +274,56 @@ RenderResult *RE_GetResult(Render *re)
        return NULL;
 }
 
+/* fill provided result struct with what's currently active or done */
+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;   
+       }
+}
+
+#define FTOCHAR(val) val<=0.0f?0: (val>=1.0f?255: (char)(255.0f*val))
+/* caller is responsible for allocating rect in correct size! */
+void RE_ResultGet32(Render *re, unsigned int *rect)
+{
+       RenderResult rres;
+       
+       RE_GetResultImage(re, &rres);
+       if(rres.rect32) 
+               memcpy(rect, rres.rect32, sizeof(int)*rres.rectx*rres.recty);
+       else if(rres.rectf) {
+               float *fp= rres.rectf;
+               int tot= rres.rectx*rres.recty;
+               char *cp= (char *)rect;
+               
+               for(;tot>0; tot--, cp+=4, fp+=4) {
+                       cp[0] = FTOCHAR(fp[0]);
+                       cp[1] = FTOCHAR(fp[1]);
+                       cp[2] = FTOCHAR(fp[2]);
+                       cp[3] = FTOCHAR(fp[3]);
+               }
+       }
+       else
+               /* else fill with black */
+               memset(rect, sizeof(int)*re->rectx*re->recty, 0);
+}
+
+
 RenderStats *RE_GetStats(Render *re)
 {
        return &re->i;
@@ -750,18 +781,26 @@ static void do_render_final(Render *re, Scene *scene)
                        do_render_seq(re->result);
        }
        else {
+               /* first check if theres nodetree with render result */
+               int do_render= ntreeCompositNeedsRender(scene->nodetree);
+               /* but.. do we use nodes? */
+               if(scene->use_nodes==NULL) do_render= 1;
                
                re->scene= scene;
                
-               /* now use renderdata and camera to set viewplane */
-               RE_SetCamera(re, re->scene->camera);
-               
-               if(re->r.mode & R_FIELDS)
-                       do_render_fields(re);
-               else if(re->r.mode & R_MBLUR)
-                       do_render_blurred(re, re->scene->r.cfra);
-               else
-                       render_one_frame(re);
+               if(do_render) {
+                       /* now use renderdata and camera to set viewplane */
+                       RE_SetCamera(re, re->scene->camera);
+                       
+                       if(re->r.mode & R_FIELDS)
+                               do_render_fields(re);
+                       else if(re->r.mode & R_MBLUR)
+                               do_render_blurred(re, re->scene->r.cfra);
+                       else
+                               render_one_frame(re);
+               }
+               if(re->r.scemode & R_DOCOMP)
+                       ntreeCompositExecTree(scene->nodetree, &re->r, 0);
        }
        
 
@@ -905,26 +944,27 @@ void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra)
                
                /* write image or movie */
                if(re->test_break()==0) {
-                       RenderResult *rr= re->result;
-                       RenderLayer *rl= rr->layers.first;
+                       RenderResult rres;
+                       
+                       RE_GetResultImage(re, &rres);
 
                        /* write movie or image */
                        if(BKE_imtype_is_movie(scene->r.imtype)) {
-                               if(rr->rect32==NULL) {
-                                       rr->rect32= MEM_mallocN(sizeof(int)*rr->rectx*rr->recty, "temp 32 bits rect");
+                               if(rres.rect32==NULL) {
+                                       rres.rect32= MEM_mallocN(sizeof(int)*rres.rectx*rres.recty, "temp 32 bits rect");
                                }
-                               RE_ResultGet32(re, rr->rect32);
-                               mh->append_movie(scene->r.cfra, rr->rect32, rr->rectx, rr->recty);
+                               RE_ResultGet32(re, rres.rect32);
+                               mh->append_movie(scene->r.cfra, rres.rect32, rres.rectx, rres.recty);
                                printf("Append frame %d", scene->r.cfra);
                        }
                        else {
-                               ImBuf *ibuf= IMB_allocImBuf(rr->rectx, rr->recty, scene->r.planes, 0, 0);
+                               ImBuf *ibuf= IMB_allocImBuf(rres.rectx, rres.recty, scene->r.planes, 0, 0);
                                int ok;
                                
                                BKE_makepicstring(name, (scene->r.cfra));
-                               ibuf->rect= rr->rect32;         /* if not exists, BKE_write_ibuf makes one */
-                               ibuf->rect_float= rl->rectf;
-                               ibuf->zbuf_float= rl->rectz;
+                               ibuf->rect= rres.rect32;                /* if not exists, BKE_write_ibuf makes one */
+                               ibuf->rect_float= rres.rectf;
+                               ibuf->zbuf_float= rres.rectz;
                                ok= BKE_write_ibuf(ibuf, name, scene->r.imtype, scene->r.subimtype, scene->r.quality);
                                IMB_freeImBuf(ibuf);    /* imbuf knows which rects are not part of ibuf */
 
index 6c76171dac4fcf6f27f51390cd4c944e90eccb00..83647424e3d2085f5e3c8d1cea0c779fe7e89392 100644 (file)
@@ -1212,8 +1212,8 @@ static void render_panel_anim(void)
 
        uiBlockSetCol(block, TH_BUT_SETTING1);
        uiBlockBeginAlign(block);
-       uiDefButBitS(block, TOG, R_DOSEQ, 0, "Do Sequence",692,114,192,20, &G.scene->r.scemode, 0, 0, 0, 0, "Enables sequence output rendering (Default: 3D rendering)");
-       uiDefButBitS(block, TOG, R_BG_RENDER, 0, "Render Daemon",692,90,192,20, &G.scene->r.scemode, 0, 0, 0, 0, "Let external network render current scene");
+       uiDefButBitS(block, TOG, R_DOSEQ, B_NOP, "Do Sequence",692,114,192,20, &G.scene->r.scemode, 0, 0, 0, 0, "Enables sequence output rendering (Default: 3D rendering)");
+       uiDefButBitS(block, TOG, R_DOCOMP, B_NOP, "Do Composit",692,90,192,20, &G.scene->r.scemode, 0, 0, 0, 0, "Uses compositing nodes for output rendering");
        uiBlockEndAlign(block);
 
        uiBlockSetCol(block, TH_AUTO);
index 114c3983712002deace8a277bb025880c7d4271f..fc0aed7728a091aac9fcd32519dcd3e98c0f39b3 100644 (file)
@@ -60,6 +60,7 @@
 #include "BIF_mywindow.h"
 #include "BIF_previewrender.h"
 #include "BIF_resources.h"
+#include "BIF_renderwin.h"
 #include "BIF_space.h"
 #include "BIF_screen.h"
 #include "BIF_toolbox.h"
@@ -139,9 +140,13 @@ static void snode_handle_recalc(SpaceNode *snode)
                BIF_preview_changed(ID_MA);      /* signals buttons windows and node editors */
        }
        else if(snode->treetype==NTREE_COMPOSIT) {
-               ntreeCompositExecTree(snode->nodetree);
+               ntreeCompositExecTree(snode->nodetree, &G.scene->r, 1); /* 1 is do_previews */
                allqueue(REDRAWNODE, 1);
                allqueue(REDRAWIMAGE, 1);
+               if(G.scene->r.scemode & R_DOCOMP) {
+                       BIF_redraw_render_rect();       /* seems to screwup display? */
+                       mywinset(curarea->win);
+               }
        }
 }
 
@@ -253,7 +258,7 @@ void node_composit_default(Scene *sce)
        
        sce->nodetree= ntreeAddTree(NTREE_COMPOSIT);
        
-       out= nodeAddNodeType(sce->nodetree, CMP_NODE_OUTPUT, NULL);
+       out= nodeAddNodeType(sce->nodetree, CMP_NODE_VIEWER, NULL);
        out->locx= 300.0f; out->locy= 300.0f;
        
        in= nodeAddNodeType(sce->nodetree, CMP_NODE_R_RESULT, NULL);
@@ -1129,7 +1134,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|Output%x201|Render Output%x202|Render Result %x221|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|Normal %x207");
                if(event<1) return;
        }
        else return;
index 97f1a6fbca2de0efae3d7d79105993b5ed0a29e3..493621269e64ec9d412b163ca05566f71f46fae2 100644 (file)
@@ -287,10 +287,11 @@ static void renderwin_draw_render_info(RenderWin *rw)
 
 static void renderwin_draw(RenderWin *rw, int just_clear)
 {
-       RenderResult *rr= RE_GetResult(RE_GetRender("Render"));
+       RenderResult rres;
+       
+       RE_GetResultImage(RE_GetRender("Render"), &rres);
 
-       if(rr) {
-               RenderLayer *rl= rr->layers.first;
+       if(rres.rectf) {
                float fullrect[2][2];
                int set_back_mainwindow;
                rcti rect;
@@ -328,10 +329,10 @@ static void renderwin_draw(RenderWin *rw, int just_clear)
 //                             glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
                        }
                        else {
-                               if(rr->rect32)
-                                       glaDrawPixelsSafe(fullrect[0][0], fullrect[0][1], rr->rectx, rr->recty, rr->rectx, GL_RGBA, GL_UNSIGNED_BYTE, rr->rect32);
-                               else if(rl->rectf)
-                                       glaDrawPixelsSafe(fullrect[0][0], fullrect[0][1], rr->rectx, rr->recty, rr->rectx, GL_RGBA, GL_FLOAT, rl->rectf);
+                               if(rres.rect32)
+                                       glaDrawPixelsSafe(fullrect[0][0], fullrect[0][1], rres.rectx, rres.recty, rres.rectx, GL_RGBA, GL_UNSIGNED_BYTE, rres.rect32);
+                               else if(rres.rectf)
+                                       glaDrawPixelsSafe(fullrect[0][0], fullrect[0][1], rres.rectx, rres.recty, rres.rectx, GL_RGBA, GL_FLOAT, rres.rectf);
                        }
                        glPixelZoom(1.0, 1.0);
                }
@@ -360,25 +361,26 @@ static void renderwin_draw(RenderWin *rw, int just_clear)
 
 static void renderwin_mouse_moved(RenderWin *rw)
 {
-       RenderResult *rr= RE_GetResult(RE_GetRender("Render"));
-       RenderLayer *rl= (rr?rr->layers.first:NULL);
+       RenderResult rres;
+       
+       RE_GetResultImage(RE_GetRender("Render"), &rres);
 
        if (rw->flags & RW_FLAGS_PIXEL_EXAMINING) {
                int imgco[2], ofs=0;
                char buf[128];
-//             char *pxl;
+               char *pxl;
 
-               if (rl && renderwin_win_to_image_co(rw, rw->lmouse, imgco)) {
-//                     pxl= (char*) &R.rectot[R.rectx*imgco[1] + imgco[0]];
-                       
-//                     ofs= sprintf(buf, "R: %d G: %d B: %d A: %d", pxl[0], pxl[1], pxl[2], pxl[3]);   
-                       
-                       if (rl->rectf) {
-                               float *pxlf= rl->rectf + 4*(rr->rectx*imgco[1] + imgco[0]);
+               if (renderwin_win_to_image_co(rw, rw->lmouse, imgco)) {
+                       if (rres.rect32) {
+                               pxl= (char*) &rres.rect32[rres.rectx*imgco[1] + imgco[0]];
+                               ofs= sprintf(buf, "R: %d G: %d B: %d A: %d", pxl[0], pxl[1], pxl[2], pxl[3]);   
+                       }
+                       if (rres.rectf) {
+                               float *pxlf= rres.rectf + 4*(rres.rectx*imgco[1] + imgco[0]);
                                ofs+= sprintf(buf+ofs, " | R: %.3f G: %.3f B: %.3f A: %.3f ", pxlf[0], pxlf[1], pxlf[2], pxlf[3]);
                        }
-                       if (rl->rectz) {
-                               float *pxlz= &rl->rectz[rr->rectx*imgco[1] + imgco[0]];                 
+                       if (rres.rectz) {
+                               float *pxlz= &rres.rectz[rres.rectx*imgco[1] + imgco[0]];                       
                                sprintf(buf+ofs, "| Z: %.3f", *pxlz );
                        }
 
@@ -395,8 +397,8 @@ static void renderwin_mouse_moved(RenderWin *rw)
        
                rw->zoomofs[0]= rw->pan_ofs_start[0] - delta_x/rw->zoom;
                rw->zoomofs[1]= rw->pan_ofs_start[1] - delta_y/rw->zoom;
-               rw->zoomofs[0]= CLAMPIS(rw->zoomofs[0], -rr->rectx/2, rr->rectx/2);
-               rw->zoomofs[1]= CLAMPIS(rw->zoomofs[1], -rr->recty/2, rr->recty/2);
+               rw->zoomofs[0]= CLAMPIS(rw->zoomofs[0], -rres.rectx/2, rres.rectx/2);
+               rw->zoomofs[1]= CLAMPIS(rw->zoomofs[1], -rres.recty/2, rres.recty/2);
 
                renderwin_queue_redraw(rw);
        } 
@@ -408,8 +410,8 @@ static void renderwin_mouse_moved(RenderWin *rw)
                h-= RW_HEADERY;
                renderwin_win_to_ndc(rw, rw->lmouse, ndc);
 
-               rw->zoomofs[0]= -0.5*ndc[0]*(w-rr->rectx*rw->zoom)/rw->zoom;
-               rw->zoomofs[1]= -0.5*ndc[1]*(h-rr->recty*rw->zoom)/rw->zoom;
+               rw->zoomofs[0]= -0.5*ndc[0]*(w-rres.rectx*rw->zoom)/rw->zoom;
+               rw->zoomofs[1]= -0.5*ndc[1]*(h-rres.recty*rw->zoom)/rw->zoom;
 
                renderwin_queue_redraw(rw);
        }
@@ -721,7 +723,6 @@ static void renderwin_clear_display_cb(RenderResult *rr)
 /* can get as well the full picture, as the parts while rendering */
 static void renderwin_progress(RenderWin *rw, RenderResult *rr, rcti *unused)
 {
-       RenderLayer *rl;
        rcti win_rct;
        float *rectf, fullrect[2][2];
        
@@ -731,10 +732,13 @@ static void renderwin_progress(RenderWin *rw, RenderResult *rr, rcti *unused)
        win_rct.ymax-= RW_HEADERY;
        renderwin_get_fullrect(rw, fullrect);
        
-       /* find current float rect for display */
-       rl= rr->layers.first;
-       rectf= rl->rectf;
-       
+       /* find current float rect for display, first case is after composit... still weak */
+       if(rr->rectf)
+               rectf= rr->rectf;
+       else {
+               RenderLayer *rl= rr->layers.first;
+               rectf= rl->rectf;
+       }       
        /* when rendering more pixels than needed, we crop away cruft */
        if(rr->crop)
                rectf+= 4*(rr->crop*rr->rectx + rr->crop);
@@ -1018,6 +1022,8 @@ void BIF_do_render(int anim)
        }
        else do_render(anim);
 
+       if(G.scene->use_nodes)
+               allqueue(REDRAWNODE, 1);
        if (slink_flag) G.f |= G_DOSCRIPTLINKS;
        if (G.f & G_DOSCRIPTLINKS) BPY_do_all_scripts(SCRIPT_POSTRENDER);
 }
index 1e89c8e8bba70331912f418a96ae5e84e924c141..808c10c4a175d51c73c92d86e028549d7a174c8c 100644 (file)
@@ -88,7 +88,7 @@ static void save_rendered_image_cb(char *name)
 {
        char str[FILE_MAXDIR+FILE_MAXFILE];
        
-       if(BLI_testextensie(str,".blend")) {
+       if(BLI_testextensie(name,".blend")) {
                error("Wrong filename");
                return;
        }
@@ -102,16 +102,17 @@ static void save_rendered_image_cb(char *name)
        BLI_convertstringcode(str, G.sce, G.scene->r.cfra);
        
        if(saveover(str)) {
-               RenderResult *rr= RE_GetResult(RE_GetRender("Render"));
-               RenderLayer *rl= rr->layers.first;
+               RenderResult rres;
                ImBuf *ibuf;
                
+               RE_GetResultImage(RE_GetRender("Render"), &rres);
+
                waitcursor(1); /* from screen.c */
 
-               ibuf= IMB_allocImBuf(rr->rectx, rr->recty, G.scene->r.planes, 0, 0);
-               ibuf->rect= rr->rect32;
-               ibuf->rect_float= rl->rectf;
-               ibuf->zbuf_float= rl->rectz;
+               ibuf= IMB_allocImBuf(rres.rectx, rres.recty, G.scene->r.planes, 0, 0);
+               ibuf->rect= rres.rect32;
+               ibuf->rect_float= rres.rectf;
+               ibuf->zbuf_float= rres.rectz;
                
                BKE_write_ibuf(ibuf, str, G.scene->r.imtype, G.scene->r.subimtype, G.scene->r.quality);
                IMB_freeImBuf(ibuf);    /* imbuf knows rects are not part of ibuf */