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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/BKE_object.h1
-rw-r--r--source/blender/blenkernel/intern/action.c10
-rw-r--r--source/blender/blenkernel/intern/ipo.c8
-rw-r--r--source/blender/blenkernel/intern/node_composite.c3
-rw-r--r--source/blender/blenkernel/intern/object.c18
-rw-r--r--source/blender/makesdna/DNA_scene_types.h2
-rw-r--r--source/blender/render/extern/include/RE_pipeline.h2
-rw-r--r--source/blender/render/intern/include/render_types.h1
-rw-r--r--source/blender/render/intern/source/initrender.c24
-rw-r--r--source/blender/render/intern/source/pipeline.c382
-rw-r--r--source/blender/src/buttons_scene.c3
-rw-r--r--source/blender/src/writeimage.c6
12 files changed, 338 insertions, 122 deletions
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index 0ed4119ac59..37398ca3fcb 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -74,6 +74,7 @@ struct Object *copy_object(struct Object *ob);
void expand_local_object(struct Object *ob);
void make_local_object(struct Object *ob);
void set_mblur_offs(float blur);
+void set_field_offs(float field);
void disable_speed_curve(int val);
float bsystem_time(struct Object *ob, struct Object *par, float cfra, float ofs);
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index f64cc16702f..84656414ea9 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -752,15 +752,11 @@ float get_action_frame_inv(Object *ob, float cframe)
static float nla_time(float cfra, float unit)
{
extern float bluroffs; // bad construct, borrowed from object.c for now
+ extern float fieldoffs;
- /* 2nd field */
-// if(R.flag & R_SEC_FIELD) {
-// if(R.r.mode & R_FIELDSTILL); else cfra+= 0.5f*unit;
-// }
+ /* motion blur & fields */
+ cfra+= unit*(bluroffs+fieldoffs);
- /* motion blur */
- cfra+= unit*bluroffs;
-
/* global time */
cfra*= G.scene->r.framelen;
diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c
index 27bf9c1744f..fae4777d543 100644
--- a/source/blender/blenkernel/intern/ipo.c
+++ b/source/blender/blenkernel/intern/ipo.c
@@ -183,14 +183,12 @@ int fluidsim_ar[FLUIDSIM_TOTIPO]= {
float frame_to_float(int cfra) /* see also bsystem_time in object.c */
{
- extern float bluroffs; /* object.c */
+ extern float bluroffs; /* bad stuff borrowed from object.c */
+ extern float fieldoffs;
float ctime;
ctime= (float)cfra;
-// if(R.flag & R_SEC_FIELD) {
-// if((R.r.mode & R_FIELDSTILL)==0) ctime+= 0.5;
-// }
- ctime+= bluroffs;
+ ctime+= bluroffs+fieldoffs;
ctime*= G.scene->r.framelen;
return ctime;
diff --git a/source/blender/blenkernel/intern/node_composite.c b/source/blender/blenkernel/intern/node_composite.c
index cba083a2bfa..854cb47e4f6 100644
--- a/source/blender/blenkernel/intern/node_composite.c
+++ b/source/blender/blenkernel/intern/node_composite.c
@@ -938,6 +938,9 @@ static void node_composit_exec_rresult(void *data, bNode *node, bNodeStack **in,
stackbuf->rect= rl->rectf;
}
+ stackbuf->xof= rr->xof;
+ stackbuf->yof= rr->yof;
+
/* put on stack */
out[RRES_OUT_IMAGE]->data= stackbuf;
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 898bb0d3b4f..8d1ff0683de 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -997,15 +997,20 @@ void make_local_object(Object *ob)
/* there is also a timing calculation in drawobject() */
-float bluroffs= 0.0;
+float bluroffs= 0.0f, fieldoffs= 0.0f;
int no_speed_curve= 0;
-/* ugly call from render */
+/* ugly calls from render */
void set_mblur_offs(float blur)
{
bluroffs= blur;
}
-
+
+void set_field_offs(float field)
+{
+ fieldoffs= field;
+}
+
void disable_speed_curve(int val)
{
no_speed_curve= val;
@@ -1016,12 +1021,7 @@ float bsystem_time(Object *ob, Object *par, float cfra, float ofs)
{
/* returns float ( see frame_to_float in ipo.c) */
- /* 2nd field */
-// if(R.flag & R_SEC_FIELD) {
-// if(R.r.mode & R_FIELDSTILL); else cfra+= .5;
-// }
-
- cfra+= bluroffs;
+ cfra+= bluroffs+fieldoffs;
/* global time */
cfra*= G.scene->r.framelen;
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 9d8feb2583b..93270b6ea5e 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -414,7 +414,7 @@ typedef struct Scene {
#define R_RADIO 0x0100
#define R_BORDER 0x0200
#define R_PANORAMA 0x0400
- /* was moviecrop 0x0800 */
+#define R_CROP 0x0800
#define R_COSMO 0x1000
#define R_ODDFIELD 0x2000
#define R_MBLUR 0x4000
diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h
index 785d496dade..f0087ef6cce 100644
--- a/source/blender/render/extern/include/RE_pipeline.h
+++ b/source/blender/render/extern/include/RE_pipeline.h
@@ -93,6 +93,8 @@ typedef struct RenderResult {
/* coordinates within final image (after cropping) */
rcti tilerect;
+ /* offset to apply to get a border render in full image */
+ int xof, yof;
/* the main buffers */
ListBase layers;
diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h
index 0e405af8298..00e69438cb6 100644
--- a/source/blender/render/intern/include/render_types.h
+++ b/source/blender/render/intern/include/render_types.h
@@ -347,7 +347,6 @@ typedef struct LampRen
#define R_HALO 2
#define R_SEC_FIELD 4
#define R_LAMPHALO 8
-#define R_FILEBUFFER 16
/* vlakren->flag (vlak = face in dutch) char!!! */
#define R_SMOOTH 1
diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c
index 520378a9d86..8f858e062de 100644
--- a/source/blender/render/intern/source/initrender.c
+++ b/source/blender/render/intern/source/initrender.c
@@ -464,6 +464,8 @@ void RE_SetCamera(Render *re, Object *camera)
/* question mark */
re->ycor= ( (float)re->r.yasp)/( (float)re->r.xasp);
+ if(re->r.mode & R_FIELDS)
+ re->ycor *= 2.0f;
if(camera->type==OB_CAMERA) {
cam= camera->data;
@@ -603,17 +605,19 @@ void initparts(Render *re)
xparts= re->r.xparts;
yparts= re->r.yparts;
- /* mininum part size */
- if(re->r.mode & R_PANORAMA) {
- if(re->rectx/xparts < 8)
- xparts= 1 + re->rectx/8;
+ /* mininum part size, but for exr tile saving it was checked already */
+ if(!(re->r.scemode & R_EXR_TILE_FILE)) {
+ if(re->r.mode & R_PANORAMA) {
+ if(re->rectx/xparts < 8)
+ xparts= 1 + re->rectx/8;
+ }
+ else
+ if(re->rectx/xparts < 64)
+ xparts= 1 + re->rectx/64;
+
+ if(re->recty/yparts < 64)
+ yparts= 1 + re->recty/64;
}
- else
- if(re->rectx/xparts < 64)
- xparts= 1 + re->rectx/64;
-
- if(re->recty/yparts < 64)
- yparts= 1 + re->recty/64;
/* part size */
partx= re->rectx/xparts;
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index 58d3dd8414c..69140534a74 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -40,6 +40,7 @@
#include "BKE_global.h"
#include "BKE_image.h"
#include "BKE_node.h"
+#include "BKE_object.h"
#include "BKE_scene.h"
#include "BKE_writeavi.h" /* <------ should be replaced once with generic movie module */
@@ -286,8 +287,6 @@ static void render_unique_exr_name(Render *re, char *str)
else
BLI_make_file_string("/", str, U.tempdir, name);
- printf("exr file %s\n", str);
-
}
static void render_layer_add_pass(RenderResult *rr, RenderLayer *rl, int channels, int passtype)
@@ -342,11 +341,12 @@ RenderLayer *RE_GetRenderLayer(RenderResult *rr, const char *name)
return NULL;
}
+#define RR_USEMEM 0
/* called by main render as well for parts */
/* will read info from Render *re to define layers */
/* called in threads */
/* re->winx,winy is coordinate space of entire image, partrct the part within */
-static RenderResult *new_render_result(Render *re, rcti *partrct, int crop)
+static RenderResult *new_render_result(Render *re, rcti *partrct, int crop, int savebuffers)
{
RenderResult *rr;
RenderLayer *rl;
@@ -371,8 +371,7 @@ static RenderResult *new_render_result(Render *re, rcti *partrct, int crop)
rr->tilerect.ymin= partrct->ymin - re->disprect.ymin;
rr->tilerect.ymax= partrct->ymax - re->disprect.ymax;
- /* this flag needs cleared immediate after result was made */
- if(re->flag & R_FILEBUFFER) {
+ if(savebuffers) {
rr->exrhandle= IMB_exr_get_handle();
}
@@ -434,16 +433,20 @@ static RenderResult *new_render_result(Render *re, rcti *partrct, int crop)
re->r.actlay= 0;
}
+ /* border render; calculate offset for use in compositor. compo is centralized coords */
+ rr->xof= re->disprect.xmin + (re->disprect.xmax - re->disprect.xmin)/2 - re->winx/2;
+ rr->yof= re->disprect.ymin + (re->disprect.ymax - re->disprect.ymin)/2 - re->winy/2;
+
return rr;
}
-static int render_result_needs_vector(Render *re)
+static int render_scene_needs_vector(Render *re)
{
if(re->r.scemode & R_DOCOMP) {
- RenderLayer *rl;
+ SceneRenderLayer *srl;
- for(rl= re->result->layers.first; rl; rl= rl->next)
- if(rl->passflag & SCE_PASS_VECTOR)
+ for(srl= re->scene->r.layers.first; srl; srl= srl->next)
+ if(srl->passflag & SCE_PASS_VECTOR)
return 1;
}
return 0;
@@ -541,7 +544,6 @@ static void save_render_result_tile(Render *re, RenderPart *pa)
party= rrpart->tilerect.ymin + rrpart->crop;
partx= rrpart->tilerect.xmin + rrpart->crop;
-
IMB_exrtile_write_channels(re->result->exrhandle, partx, party);
BLI_unlock_thread(LOCK_CUSTOM1);
@@ -557,7 +559,7 @@ static void read_render_result(Render *re)
char str[FILE_MAXDIR+FILE_MAXFILE];
free_render_result(re->result);
- re->result= new_render_result(re, &re->disprect, 0);
+ re->result= new_render_result(re, &re->disprect, 0, RR_USEMEM);
render_unique_exr_name(re, str);
if(IMB_exr_begin_read(exrhandle, str, &rectx, &recty)==0) {
@@ -762,7 +764,7 @@ void RE_InitState(Render *re, RenderData *rd, int winx, int winy, rcti *disprect
re->recty= disprect->ymax-disprect->ymin;
}
else {
- re->disprect.xmin= re->disprect.xmax= 0;
+ re->disprect.xmin= re->disprect.ymin= 0;
re->disprect.xmax= winx;
re->disprect.ymax= winy;
re->rectx= winx;
@@ -784,8 +786,11 @@ void RE_InitState(Render *re, RenderData *rd, int winx, int winy, rcti *disprect
/* always call, checks for gamma, gamma tables and jitter too */
make_sample_tables(re);
+ /* make empty render result, so display callbacks can initialize */
free_render_result(re->result);
- re->result= new_render_result(re, &re->disprect, 0);
+ re->result= MEM_callocN(sizeof(RenderResult), "new render result");
+ re->result->rectx= re->rectx;
+ re->result->recty= re->recty;
}
}
@@ -797,7 +802,7 @@ void RE_SetDispRect (struct Render *re, rcti *disprect)
/* initialize render result */
free_render_result(re->result);
- re->result= new_render_result(re, &re->disprect, 0);
+ re->result= new_render_result(re, &re->disprect, 0, RR_USEMEM);
}
void RE_SetWindow(Render *re, rctf *viewplane, float clipsta, float clipend)
@@ -885,7 +890,7 @@ static void *do_part_thread(void *pa_v)
/* need to return nicely all parts on esc */
if(R.test_break()==0) {
- pa->result= new_render_result(&R, &pa->disprect, pa->crop);
+ pa->result= new_render_result(&R, &pa->disprect, pa->crop, RR_USEMEM);
if(R.osa)
zbufshadeDA_tile(pa);
@@ -904,13 +909,17 @@ static void *do_part_thread(void *pa_v)
return NULL;
}
-/* returns with render result filled, not threaded */
+/* returns with render result filled, not threaded, used for preview now only */
static void render_tile_processor(Render *re, int firsttile)
{
RenderPart *pa;
if(re->test_break())
return;
+
+ /* first step; the entire render result, no exr saving here */
+ free_render_result(re->result);
+ re->result= new_render_result(re, &re->disprect, 0, RR_USEMEM);
re->i.lastframetime= PIL_check_seconds_timer()- re->i.starttime;
re->stats_draw(&re->i);
@@ -1068,10 +1077,14 @@ static void threaded_tile_processor(Render *re)
{
ListBase threads;
RenderPart *pa, *nextpa;
- RenderResult *rr= re->result;
+ RenderResult *rr;
rctf viewplane= re->viewplane;
int maxthreads, rendering=1, counter= 1, drawtimer=0, hasdrawn, minx=0;
+ /* first step; the entire render result, or prepare exr buffer saving */
+ free_render_result(re->result);
+ rr= re->result= new_render_result(re, &re->disprect, 0, re->r.scemode & R_EXR_TILE_FILE);
+
if(rr==NULL)
return;
if(re->test_break())
@@ -1082,6 +1095,8 @@ static void threaded_tile_processor(Render *re)
if(rr->exrhandle) {
char str[FILE_MAXDIR+FILE_MAXFILE];
render_unique_exr_name(re, str);
+ printf("write exr tmp file, %dx%d, %s\n", rr->rectx, rr->recty, str);
+
IMB_exrtile_begin_write(rr->exrhandle, str, rr->rectx, rr->recty, rr->rectx/re->xparts, rr->recty/re->yparts);
}
@@ -1191,13 +1206,13 @@ void RE_TileProcessor(Render *re, int firsttile)
/* ************ This part uses API, for rendering Blender scenes ********** */
-void render_one_frame(Render *re)
+static void do_render_3d(Render *re)
{
// re->cfra= cfra; /* <- unused! */
/* make render verts/faces/halos/lamps */
- if(render_result_needs_vector(re))
+ if(render_scene_needs_vector(re))
RE_Database_FromScene_Vectors(re, re->scene);
else
RE_Database_FromScene(re, re->scene, 1);
@@ -1208,19 +1223,221 @@ void render_one_frame(Render *re)
RE_Database_Free(re);
}
-#if 0
-/* accumulates osa frames */
-static void do_render_blurred(Render *re, float frame)
+/* called by blur loop, accumulate renderlayers */
+static void addblur_rect(RenderResult *rr, float *rectf, float *rectf1, float blurfac, int channels)
+{
+ float mfac= 1.0f - blurfac;
+ int a, b, stride= channels*rr->rectx;
+ int len= stride*sizeof(float);
+
+ for(a=0; a<rr->recty; a++) {
+ if(blurfac==1.0f) {
+ memcpy(rectf, rectf1, len);
+ }
+ else {
+ float *rf= rectf, *rf1= rectf1;
+
+ for( b= rr->rectx*channels; b>0; b--, rf++, rf1++) {
+ rf[0]= mfac*rf[0] + blurfac*rf1[0];
+ }
+ }
+ rectf+= stride;
+ rectf1+= stride;
+ }
+}
+
+/* called by blur loop, accumulate renderlayers */
+static void merge_renderresult_blur(RenderResult *rr, RenderResult *brr, float blurfac)
+{
+ RenderLayer *rl, *rl1;
+ RenderPass *rpass, *rpass1;
+
+ rl1= brr->layers.first;
+ for(rl= rr->layers.first; rl && rl1; rl= rl->next, rl1= rl1->next) {
+
+ /* combined */
+ if(rl->rectf && rl1->rectf)
+ addblur_rect(rr, rl->rectf, rl1->rectf, blurfac, 4);
+
+ /* passes are allocated in sync */
+ rpass1= rl1->passes.first;
+ for(rpass= rl->passes.first; rpass && rpass1; rpass= rpass->next, rpass1= rpass1->next) {
+ addblur_rect(rr, rpass->rect, rpass1->rect, blurfac, rpass->channels);
+ }
+ }
+}
+
+/* main blur loop, can be called by fields too */
+static void do_render_blur_3d(Render *re)
{
+ RenderResult *rres;
+ float blurfac;
+ int blur= re->r.osa;
+
+ /* create accumulation render result */
+ rres= new_render_result(re, &re->disprect, 0, RR_USEMEM);
+
+ /* do the blur steps */
+ while(blur--) {
+ set_mblur_offs( re->r.blurfac*((float)(re->r.osa-blur))/(float)re->r.osa );
+
+ do_render_3d(re);
+
+ blurfac= 1.0f/(float)(re->r.osa-blur);
+
+ merge_renderresult_blur(rres, re->result, blurfac);
+ if(re->test_break()) break;
+ }
+ /* swap results */
+ free_render_result(re->result);
+ re->result= rres;
+
+ set_mblur_offs(0.0f);
+
+ /* weak... the display callback wants an active renderlayer pointer... */
+ re->result->renlay= render_get_active_layer(re, re->result);
+ re->display_draw(re->result, NULL);
+}
+
+
+/* function assumes rectf1 and rectf2 to be half size of rectf */
+static void interleave_rect(RenderResult *rr, float *rectf, float *rectf1, float *rectf2, int channels)
+{
+ int a, stride= channels*rr->rectx;
+ int len= stride*sizeof(float);
+
+ for(a=0; a<rr->recty; a+=2) {
+ memcpy(rectf, rectf1, len);
+ rectf+= stride;
+ rectf1+= stride;
+ memcpy(rectf, rectf2, len);
+ rectf+= stride;
+ rectf2+= stride;
+ }
}
+/* merge render results of 2 fields */
+static void merge_renderresult_fields(RenderResult *rr, RenderResult *rr1, RenderResult *rr2)
+{
+ RenderLayer *rl, *rl1, *rl2;
+ RenderPass *rpass, *rpass1, *rpass2;
+
+ rl1= rr1->layers.first;
+ rl2= rr2->layers.first;
+ for(rl= rr->layers.first; rl && rl1 && rl2; rl= rl->next, rl1= rl1->next, rl2= rl2->next) {
+
+ /* combined */
+ if(rl->rectf && rl1->rectf && rl2->rectf)
+ interleave_rect(rr, rl->rectf, rl1->rectf, rl2->rectf, 4);
+
+ /* passes are allocated in sync */
+ rpass1= rl1->passes.first;
+ rpass2= rl2->passes.first;
+ for(rpass= rl->passes.first; rpass && rpass1 && rpass2; rpass= rpass->next, rpass1= rpass1->next, rpass2= rpass2->next) {
+ interleave_rect(rr, rpass->rect, rpass1->rect, rpass2->rect, rpass->channels);
+ }
+ }
+}
+
+
/* interleaves 2 frames */
-static void do_render_fields(Render *re)
+static void do_render_fields_3d(Render *re)
+{
+ RenderResult *rr1, *rr2= NULL;
+
+ /* no render result was created, we can safely halve render y */
+ re->winy /= 2;
+ re->recty /= 2;
+ re->disprect.ymin /= 2;
+ re->disprect.ymax /= 2;
+
+ /* first field, we have to call camera routine for correct aspect and subpixel offset */
+ RE_SetCamera(re, re->scene->camera);
+ if(re->r.mode & R_MBLUR)
+ do_render_blur_3d(re);
+ else
+ do_render_3d(re);
+ rr1= re->result;
+ re->result= NULL;
+
+ /* second field */
+ if(!re->test_break()) {
+ re->flag |= R_SEC_FIELD;
+ if((re->r.mode & R_FIELDSTILL)==0)
+ set_field_offs(0.5f);
+ RE_SetCamera(re, re->scene->camera);
+ if(re->r.mode & R_MBLUR)
+ do_render_blur_3d(re);
+ else
+ do_render_3d(re);
+ re->flag &= ~R_SEC_FIELD;
+ set_field_offs(0.0f);
+
+ rr2= re->result;
+ }
+
+ /* allocate original height new buffers */
+ re->winy *= 2;
+ re->recty *= 2;
+ re->disprect.ymin *= 2;
+ re->disprect.ymax *= 2;
+ re->result= new_render_result(re, &re->disprect, 0, RR_USEMEM);
+
+ if(rr2) {
+ if(re->r.mode & R_ODDFIELD)
+ merge_renderresult_fields(re->result, rr2, rr1);
+ else
+ merge_renderresult_fields(re->result, rr1, rr2);
+
+ free_render_result(rr2);
+ }
+ free_render_result(rr1);
+
+ /* weak... the display callback wants an active renderlayer pointer... */
+ re->result->renlay= render_get_active_layer(re, re->result);
+ re->display_draw(re->result, NULL);
+}
+
+/* main render routine, no compositing */
+static void do_render_fields_blur_3d(Render *re)
{
+ if(re->r.mode & R_FIELDS)
+ do_render_fields_3d(re);
+ else if(re->r.mode & R_MBLUR)
+ do_render_blur_3d(re);
+ else
+ do_render_3d(re);
+ /* when border render, check if we have to insert it in black */
+ if(re->result) {
+ if(re->r.mode & R_BORDER) {
+ if((re->r.mode & R_CROP)==0) {
+ RenderResult *rres;
+
+ /* sub-rect for merge call later on */
+ re->result->tilerect= re->disprect;
+
+ /* this copying sequence could become function? */
+ re->disprect.xmin= re->disprect.ymin= 0;
+ re->disprect.xmax= re->winx;
+ re->disprect.ymax= re->winy;
+ re->rectx= re->winx;
+ re->recty= re->winy;
+
+ rres= new_render_result(re, &re->disprect, 0, RR_USEMEM);
+
+ merge_render_result(rres, re->result);
+ free_render_result(re->result);
+ re->result= rres;
+
+ re->display_init(re->result);
+ re->display_draw(re->result, NULL);
+ }
+ }
+ }
}
-#endif
+
/* within context of current Render *re, render another scene.
it uses current render image size and disprect, but doesn't execute composite
@@ -1230,13 +1447,9 @@ static void render_scene(Render *re, Scene *sce, int cfra)
Render *resc= RE_NewRender(sce->id.name);
sce->r.cfra= cfra;
-
- if(re->scene->r.scemode & R_EXR_TILE_FILE)
- resc->flag |= R_FILEBUFFER;
-
- /* makes render result etc */
+
+ /* initial setup */
RE_InitState(resc, &sce->r, re->winx, re->winy, &re->disprect);
- resc->flag &= ~R_FILEBUFFER;
/* this to enable this scene to create speed vectors */
resc->r.scemode |= R_DOCOMP;
@@ -1256,13 +1469,7 @@ static void render_scene(Render *re, Scene *sce, int cfra)
resc->test_break= re->test_break;
resc->stats_draw= re->stats_draw;
- if(resc->r.mode & R_FIELDS)
- printf("No field render yet...\n"); //do_render_fields(resc);
- else if(resc->r.mode & R_MBLUR)
- printf("No mblur render yet...\n"); //do_render_blurred(resc, resc->r.cfra);
- //else
- render_one_frame(resc);
-
+ do_render_fields_blur_3d(resc);
}
static void ntree_render_scenes(Render *re)
@@ -1304,7 +1511,7 @@ static void ntree_render_scenes(Render *re)
}
/* helper call to detect if theres a composite with render-result node */
-int composite_needs_render(Scene *sce)
+static int composite_needs_render(Scene *sce)
{
bNodeTree *ntree= sce->nodetree;
bNode *node;
@@ -1329,60 +1536,49 @@ static void render_composit_stats(char *str)
R.i.infostr= NULL;
}
-static void do_render_final(Render *re)
+/* returns fully composited render-result on given time step (in RenderData) */
+static void do_render_composite_fields_blur_3d(Render *re)
{
+ bNodeTree *ntree= re->scene->nodetree;
+
/* we set start time here, for main Blender loops */
re->i.starttime= PIL_check_seconds_timer();
- if(re->r.scemode & R_DOSEQ) {
- if(!re->test_break())
- do_render_seq(re->result, re->r.cfra);
- }
- else {
- bNodeTree *ntree= re->scene->nodetree;
+ if(composite_needs_render(re->scene)) {
+ /* save memory... free all cached images */
+ ntreeFreeCache(ntree);
- if(composite_needs_render(re->scene)) {
- /* save memory... free all cached images */
- ntreeFreeCache(ntree);
-
- /* now use renderdata and camera to set viewplane */
- RE_SetCamera(re, re->scene->camera);
-
- if(re->r.mode & R_FIELDS)
- printf("No field render yet...\n"); //do_render_fields(resc);
- else if(re->r.mode & R_MBLUR)
- printf("No mblur render yet...\n"); //do_render_blurred(resc, resc->r.cfra);
- //else
- render_one_frame(re);
- }
+ /* now use renderdata and camera to set viewplane */
+ RE_SetCamera(re, re->scene->camera);
- /* swap render result */
- if(re->r.scemode & R_SINGLE_LAYER)
- pop_render_result(re);
+ do_render_fields_blur_3d(re);
+ }
+
+ /* swap render result */
+ if(re->r.scemode & R_SINGLE_LAYER)
+ pop_render_result(re);
+
+ if(!re->test_break() && ntree) {
+ ntreeCompositTagRender(ntree);
+ ntreeCompositTagAnimated(ntree);
- if(!re->test_break() && ntree) {
- ntreeCompositTagRender(ntree);
- ntreeCompositTagAnimated(ntree);
+ if(re->r.scemode & R_DOCOMP) {
+ /* checks if there are render-result nodes that need scene */
+ if((re->r.scemode & R_SINGLE_LAYER)==0)
+ ntree_render_scenes(re);
- if(re->r.scemode & R_DOCOMP) {
- /* checks if there are render-result nodes that need scene */
- if((re->r.scemode & R_SINGLE_LAYER)==0)
- ntree_render_scenes(re);
+ if(!re->test_break()) {
+ ntree->stats_draw= render_composit_stats;
+ ntree->test_break= re->test_break;
+ /* in case it was never initialized */
+ R.stats_draw= re->stats_draw;
- if(!re->test_break()) {
- ntree->stats_draw= render_composit_stats;
- ntree->test_break= re->test_break;
- /* in case it was never initialized */
- R.stats_draw= re->stats_draw;
-
- ntreeCompositExecTree(ntree, &re->r, G.background==0);
- ntree->stats_draw= NULL;
- ntree->test_break= NULL;
- }
+ ntreeCompositExecTree(ntree, &re->r, G.background==0);
+ ntree->stats_draw= NULL;
+ ntree->test_break= NULL;
}
}
}
-
re->i.lastframetime= PIL_check_seconds_timer()- re->i.starttime;
re->stats_draw(&re->i);
@@ -1390,6 +1586,17 @@ static void do_render_final(Render *re)
re->display_draw(re->result, NULL);
}
+/* main loop: doing sequence + fields + blur + 3d render + compositing */
+static void do_render_all_options(Render *re)
+{
+ if(re->r.scemode & R_DOSEQ) {
+ if(!re->test_break())
+ do_render_seq(re->result, re->r.cfra);
+ }
+ else {
+ do_render_composite_fields_blur_3d(re);
+ }
+}
static int is_rendering_allowed(Render *re)
{
@@ -1460,7 +1667,7 @@ static int render_initialize_from_scene(Render *re, Scene *scene)
winx= (scene->r.size*scene->r.xsch)/100;
winy= (scene->r.size*scene->r.ysch)/100;
- /* only in movie case we render smaller part */
+ /* we always render smaller part, inserting it in larger image is compositor bizz, it uses disprect for it */
if(scene->r.mode & R_BORDER) {
disprect.xmin= scene->r.border.xmin*winx;
disprect.xmax= scene->r.border.xmax*winx;
@@ -1476,19 +1683,22 @@ static int render_initialize_from_scene(Render *re, Scene *scene)
if(scene->r.scemode & R_EXR_TILE_FILE) {
int partx= winx/scene->r.xparts, party= winy/scene->r.yparts;
+
/* stupid exr tiles dont like different sizes */
if(winx != partx*scene->r.xparts || winy != party*scene->r.yparts) {
re->error("Sorry... exr tile saving only allowed with equally sized parts");
return 0;
}
- re->flag |= R_FILEBUFFER;
+ if((scene->r.mode & R_FIELDS) && (party & 1)) {
+ re->error("Sorry... exr tile saving only allowed with equally sized parts");
+ return 0;
+ }
}
if(scene->r.scemode & R_SINGLE_LAYER)
push_render_result(re);
RE_InitState(re, &scene->r, winx, winy, &disprect);
- re->flag &= ~R_FILEBUFFER;
re->scene= scene;
if(!is_rendering_allowed(re))
@@ -1510,7 +1720,7 @@ void RE_BlenderFrame(Render *re, Scene *scene, int frame)
scene->r.cfra= frame;
if(render_initialize_from_scene(re, scene)) {
- do_render_final(re);
+ do_render_all_options(re);
}
/* UGLY WARNING */
@@ -1604,7 +1814,7 @@ void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra)
scene->r.cfra = nf;
re->r.cfra= scene->r.cfra; /* weak.... */
- do_render_final(re);
+ do_render_all_options(re);
if(re->test_break() == 0) {
do_write_image_or_movie(re, scene, mh);
@@ -1616,7 +1826,7 @@ void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra)
scene->r.cfra<=efra; scene->r.cfra++) {
re->r.cfra= scene->r.cfra; /* weak.... */
- do_render_final(re);
+ do_render_all_options(re);
if(re->test_break() == 0) {
do_write_image_or_movie(re, scene, mh);
diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c
index b482b831d03..d659307457c 100644
--- a/source/blender/src/buttons_scene.c
+++ b/source/blender/src/buttons_scene.c
@@ -1506,7 +1506,8 @@ static void render_panel_format(void)
uiDefButBitI(block, TOG, R_COSMO, 0,"Cosmo", 1059,32,60,20, &G.scene->r.mode, 0, 0, 0, 0, "Attempt to save SGI movies using Cosmo hardware");
#endif
- uiDefButS(block, MENU,B_FILETYPEMENU,imagetype_pup(), 892,yofs,225,20, &G.scene->r.imtype, 0, 0, 0, 0, "Images are saved in this file format");
+ uiDefButS(block, MENU,B_FILETYPEMENU,imagetype_pup(), 892,yofs,174,20, &G.scene->r.imtype, 0, 0, 0, 0, "Images are saved in this file format");
+ uiDefButBitI(block, TOG, R_CROP, B_DIFF, "Crop", 1068,yofs,51,20, &G.scene->r.mode, 0, 0, 0, 0, "When Border render, the resulting image gets cropped");
yofs -= 22;
diff --git a/source/blender/src/writeimage.c b/source/blender/src/writeimage.c
index fc44dc3835f..5dd5dc23805 100644
--- a/source/blender/src/writeimage.c
+++ b/source/blender/src/writeimage.c
@@ -218,9 +218,11 @@ void save_image_filesel_str(char *str)
/* calls fileselect if zbuf is set we are rendering the zbuffer */
void BIF_save_rendered_image_fs(int zbuf)
{
- RenderResult *rr= RE_GetResult(RE_GetRender(G.scene->id.name));
+ RenderResult rres;
- if(!rr) {
+ RE_GetResultImage(RE_GetRender(G.scene->id.name), &rres);
+
+ if(!rres.rectf) {
error("No image rendered");
} else {
char dir[FILE_MAXDIR * 2], str[FILE_MAXFILE * 2];