New rendering option: FSA!
This completes the pipeline make-over, as started in 2006. With this option, during rendering, each sample for every layer and pass is being saved on disk (looks like non-antialiased images). Then the composite and color correction happens, then a clip to 0-1 range, and only in end all samples get combined - using sampling filters such as gauss/mitch/catmul. This results in artefact-free antialiased images. Even Z-combine or ID masks now work perfect for it! This is an unfinished commit btw; Brecht will finish this for strands. Also Halo doesnt work yet. To activate FSA: press "Save Buffers" and the new button next to it. :)
This commit is contained in:
parent
b9842ec247
commit
703f248ab4
|
@ -589,8 +589,9 @@ typedef struct Scene {
|
|||
#define R_EXR_TILE_FILE 0x0400
|
||||
#define R_COMP_FREE 0x0800
|
||||
#define R_NO_IMAGE_LOAD 0x1000
|
||||
#define R_NO_TEX 0x2000
|
||||
#define R_NO_TEX 0x2000
|
||||
#define R_STAMP_INFO 0x4000
|
||||
#define R_FULL_SAMPLE 0x8000
|
||||
|
||||
/* r->stamp */
|
||||
#define R_STAMP_TIME 0x0001
|
||||
|
|
|
@ -376,8 +376,10 @@ static void defocus_blur(bNode *node, CompBuf *new, CompBuf *img, CompBuf *zbuf,
|
|||
// some sort of visual feedback would be nice, or at least this text in the renderwin header
|
||||
// but for now just print some info in the console every 8 scanlines.
|
||||
if (((y & 7)==0) || (y==(img->y-1))) {
|
||||
printf("\rdefocus: Processing Line %d of %d ... ", y+1, img->y);
|
||||
fflush(stdout);
|
||||
if(G.background==0) {
|
||||
printf("\rdefocus: Processing Line %d of %d ... ", y+1, img->y);
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
// esc set by main calling process
|
||||
if(node->exec & NODE_BREAK)
|
||||
|
|
|
@ -63,8 +63,25 @@ static void do_idmask(CompBuf *stackbuf, CompBuf *cbuf, float idnr)
|
|||
MEM_freeN(abuf);
|
||||
}
|
||||
|
||||
/* full sample version */
|
||||
static void do_idmask_fsa(CompBuf *stackbuf, CompBuf *cbuf, float idnr)
|
||||
{
|
||||
float *rect, *rs;
|
||||
int x;
|
||||
|
||||
rect= cbuf->rect;
|
||||
rs= stackbuf->rect;
|
||||
for(x= cbuf->x*cbuf->y - 1; x>=0; x--)
|
||||
if(rect[x]==idnr)
|
||||
rs[x]= 1.0f;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void node_composit_exec_idmask(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
|
||||
{
|
||||
RenderData *rd= data;
|
||||
|
||||
if(out[0]->hasoutput==0)
|
||||
return;
|
||||
|
||||
|
@ -77,7 +94,10 @@ static void node_composit_exec_idmask(void *data, bNode *node, bNodeStack **in,
|
|||
|
||||
stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); /* allocs */;
|
||||
|
||||
do_idmask(stackbuf, cbuf, (float)node->custom1);
|
||||
if(rd->scemode & R_FULL_SAMPLE)
|
||||
do_idmask_fsa(stackbuf, cbuf, (float)node->custom1);
|
||||
else
|
||||
do_idmask(stackbuf, cbuf, (float)node->custom1);
|
||||
|
||||
out[0]->data= stackbuf;
|
||||
}
|
||||
|
|
|
@ -45,6 +45,16 @@ static bNodeSocketType cmp_node_zcombine_out[]= {
|
|||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
static void do_zcombine(bNode *node, float *out, float *src1, float *z1, float *src2, float *z2)
|
||||
{
|
||||
if(*z1 <= *z2) {
|
||||
QUATCOPY(out, src1);
|
||||
}
|
||||
else {
|
||||
QUATCOPY(out, src2);
|
||||
}
|
||||
}
|
||||
|
||||
static void do_zcombine_mask(bNode *node, float *out, float *z1, float *z2)
|
||||
{
|
||||
if(*z1 > *z2) {
|
||||
|
@ -67,6 +77,8 @@ static void do_zcombine_add(bNode *node, float *out, float *col1, float *col2, f
|
|||
|
||||
static void node_composit_exec_zcombine(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
|
||||
{
|
||||
RenderData *rd= data;
|
||||
|
||||
/* stack order in: col z col z */
|
||||
/* stack order out: col z */
|
||||
if(out[0]->hasoutput==0)
|
||||
|
@ -76,6 +88,16 @@ static void node_composit_exec_zcombine(void *data, bNode *node, bNodeStack **in
|
|||
if(in[0]->data==NULL) {
|
||||
return;
|
||||
}
|
||||
else if(rd->scemode & R_FULL_SAMPLE) {
|
||||
/* make output size of first input image */
|
||||
CompBuf *cbuf= in[0]->data;
|
||||
CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); // allocs
|
||||
|
||||
composit4_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, in[2]->data, in[2]->vec,
|
||||
in[3]->data, in[3]->vec, do_zcombine, CB_RGBA, CB_VAL, CB_RGBA, CB_VAL);
|
||||
|
||||
out[0]->data= stackbuf;
|
||||
}
|
||||
else {
|
||||
/* make output size of first input image */
|
||||
CompBuf *cbuf= in[0]->data;
|
||||
|
|
|
@ -88,10 +88,11 @@ typedef struct RenderLayer {
|
|||
} RenderLayer;
|
||||
|
||||
typedef struct RenderResult {
|
||||
struct RenderResult *next, *prev;
|
||||
|
||||
/* target image size */
|
||||
int rectx, recty;
|
||||
short crop, pad;
|
||||
short crop, sample_nr;
|
||||
|
||||
/* optional, 32 bits version of picture, used for ogl render and image curves */
|
||||
int *rect32;
|
||||
|
@ -113,7 +114,6 @@ typedef struct RenderResult {
|
|||
volatile RenderLayer *renlay;
|
||||
|
||||
/* optional saved endresult on disk */
|
||||
char exrfile[FILE_MAXDIR];
|
||||
void *exrhandle;
|
||||
|
||||
/* for render results in Image, verify validity for sequences */
|
||||
|
@ -121,6 +121,7 @@ typedef struct RenderResult {
|
|||
|
||||
} RenderResult;
|
||||
|
||||
|
||||
typedef struct RenderStats {
|
||||
int totface, totvert, totstrand, tothalo, totlamp, totpart;
|
||||
short curfield, curblur, curpart, partsdone, convertdone;
|
||||
|
|
|
@ -157,6 +157,7 @@ typedef struct ShadeInput
|
|||
|
||||
int xs, ys; /* pixel to be rendered */
|
||||
int mask; /* subsample mask */
|
||||
|
||||
int samplenr; /* sample counter, to detect if we should do shadow again */
|
||||
int depth; /* 1 or larger on raytrace shading */
|
||||
|
||||
|
@ -169,6 +170,7 @@ typedef struct ShadeInput
|
|||
/* from initialize, part or renderlayer */
|
||||
short do_preview; /* for nodes, in previewrender */
|
||||
short thread, sample; /* sample: ShadeSample array index */
|
||||
|
||||
unsigned int lay;
|
||||
int layflag, passflag, combinedflag;
|
||||
struct Group *light_override;
|
||||
|
|
|
@ -79,8 +79,8 @@ typedef struct RenderPart
|
|||
{
|
||||
struct RenderPart *next, *prev;
|
||||
|
||||
/* result of part rendering */
|
||||
RenderResult *result;
|
||||
RenderResult *result; /* result of part rendering */
|
||||
ListBase fullresult; /* optional full sample buffers */
|
||||
|
||||
int *recto; /* object table for objects */
|
||||
int *rectp; /* polygon index table */
|
||||
|
@ -113,6 +113,8 @@ struct Render
|
|||
RenderResult *result;
|
||||
/* if render with single-layer option, other rendered layers are stored here */
|
||||
RenderResult *pushedresult;
|
||||
/* a list of RenderResults, for fullsample */
|
||||
ListBase fullresult;
|
||||
|
||||
/* window size, display rect, viewplane */
|
||||
int winx, winy;
|
||||
|
|
|
@ -93,6 +93,9 @@ void zbufshade_sss_tile(struct RenderPart *pa);
|
|||
|
||||
void addps(struct ListBase *lb, long *rd, int obi, int facenr, int z, unsigned short mask);
|
||||
|
||||
int get_sample_layers(struct RenderPart *pa, struct RenderLayer *rl, struct RenderLayer **rlpp);
|
||||
|
||||
|
||||
/* -------- ray.c ------- */
|
||||
|
||||
extern void freeraytree(Render *re);
|
||||
|
|
|
@ -40,7 +40,9 @@ struct ObjectInstanceRen obi;
|
|||
|
||||
/* needed to calculate shadow and AO for an entire pixel */
|
||||
typedef struct ShadeSample {
|
||||
int tot; /* amount of shi in use, can be 1 for not FULL_OSA */
|
||||
int tot; /* amount of shi in use, can be 1 for not FULL_OSA */
|
||||
|
||||
RenderLayer *rlpp[RE_MAX_OSA]; /* fast lookup from sample to renderlayer (fullsample buf) */
|
||||
|
||||
/* could be malloced once */
|
||||
ShadeInput shi[RE_MAX_OSA];
|
||||
|
|
|
@ -3704,7 +3704,7 @@ static void set_phong_threshold(ObjectRen *obr)
|
|||
}
|
||||
|
||||
/* per face check if all samples should be taken.
|
||||
if raytrace, do always for raytraced material, or when material full_osa set */
|
||||
if raytrace or multisample, do always for raytraced material, or when material full_osa set */
|
||||
static void set_fullsample_flag(Render *re, ObjectRen *obr)
|
||||
{
|
||||
VlakRen *vlr;
|
||||
|
@ -3718,7 +3718,8 @@ static void set_fullsample_flag(Render *re, ObjectRen *obr)
|
|||
for(a=obr->totvlak-1; a>=0; a--) {
|
||||
vlr= RE_findOrAddVlak(obr, a);
|
||||
|
||||
if(vlr->mat->mode & MA_FULL_OSA) vlr->flag |= R_FULL_OSA;
|
||||
if(vlr->mat->mode & MA_FULL_OSA)
|
||||
vlr->flag |= R_FULL_OSA;
|
||||
else if(trace) {
|
||||
if(vlr->mat->mode & MA_SHLESS);
|
||||
else if(vlr->mat->mode & (MA_RAYTRANSP|MA_RAYMIRROR))
|
||||
|
|
|
@ -78,6 +78,7 @@
|
|||
#include "envmap.h"
|
||||
#include "initrender.h"
|
||||
#include "shadbuf.h"
|
||||
#include "pixelblending.h"
|
||||
#include "zbuf.h"
|
||||
|
||||
|
||||
|
@ -195,6 +196,22 @@ void RE_FreeRenderResult(RenderResult *res)
|
|||
MEM_freeN(res);
|
||||
}
|
||||
|
||||
/* version that's compatible with fullsample buffers */
|
||||
static void free_render_result(ListBase *lb, RenderResult *rr)
|
||||
{
|
||||
RenderResult *rrnext;
|
||||
|
||||
for(; rr; rr= rrnext) {
|
||||
rrnext= rr->next;
|
||||
|
||||
if(lb && lb->first)
|
||||
BLI_remlink(lb, rr);
|
||||
|
||||
RE_FreeRenderResult(rr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* all layers except the active one get temporally pushed away */
|
||||
static void push_render_result(Render *re)
|
||||
{
|
||||
|
@ -391,13 +408,18 @@ static int passtype_from_name(char *str)
|
|||
|
||||
|
||||
|
||||
static void render_unique_exr_name(Render *re, char *str)
|
||||
static void render_unique_exr_name(Render *re, char *str, int sample)
|
||||
{
|
||||
char di[FILE_MAX], name[FILE_MAXFILE], fi[FILE_MAXFILE];
|
||||
|
||||
BLI_strncpy(di, G.sce, FILE_MAX);
|
||||
BLI_splitdirstring(di, fi);
|
||||
sprintf(name, "%s_%s.exr", fi, re->scene->id.name+2);
|
||||
|
||||
if(sample==0)
|
||||
sprintf(name, "%s_%s.exr", fi, re->scene->id.name+2);
|
||||
else
|
||||
sprintf(name, "%s_%s%d.exr", fi, re->scene->id.name+2, sample);
|
||||
|
||||
if(G.background)
|
||||
BLI_make_file_string("/", str, "/tmp/", name);
|
||||
else
|
||||
|
@ -421,17 +443,22 @@ static void render_layer_add_pass(RenderResult *rr, RenderLayer *rl, int channel
|
|||
IMB_exr_add_channel(rr->exrhandle, rl->name, get_pass_name(passtype, a), 0, 0, NULL);
|
||||
}
|
||||
else {
|
||||
float *rect;
|
||||
int x;
|
||||
|
||||
rpass->rect= MEM_mapallocN(sizeof(float)*rectsize, typestr);
|
||||
|
||||
if(passtype==SCE_PASS_VECTOR) {
|
||||
float *rect;
|
||||
int x;
|
||||
|
||||
/* initialize to max speed */
|
||||
rect= rpass->rect= MEM_mapallocN(sizeof(float)*rectsize, typestr);
|
||||
rect= rpass->rect;
|
||||
for(x= rectsize-1; x>=0; x--)
|
||||
rect[x]= PASS_VECTOR_MAX;
|
||||
}
|
||||
else
|
||||
rpass->rect= MEM_mapallocN(sizeof(float)*rectsize, typestr);
|
||||
else if(passtype==SCE_PASS_Z) {
|
||||
rect= rpass->rect;
|
||||
for(x= rectsize-1; x>=0; x--)
|
||||
rect[x]= 10e10;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -655,9 +682,8 @@ static void merge_render_result(RenderResult *rr, RenderResult *rrpart)
|
|||
}
|
||||
|
||||
|
||||
static void save_render_result_tile(Render *re, RenderPart *pa)
|
||||
static void save_render_result_tile(RenderResult *rr, RenderResult *rrpart)
|
||||
{
|
||||
RenderResult *rrpart= pa->result;
|
||||
RenderLayer *rlp;
|
||||
RenderPass *rpassp;
|
||||
int offs, partx, party;
|
||||
|
@ -677,23 +703,23 @@ static void save_render_result_tile(Render *re, RenderPart *pa)
|
|||
if(rlp->rectf) {
|
||||
int a, xstride= 4;
|
||||
for(a=0; a<xstride; a++)
|
||||
IMB_exr_set_channel(re->result->exrhandle, rlp->name, get_pass_name(SCE_PASS_COMBINED, a),
|
||||
xstride, xstride*pa->rectx, rlp->rectf+a + xstride*offs);
|
||||
IMB_exr_set_channel(rr->exrhandle, rlp->name, get_pass_name(SCE_PASS_COMBINED, a),
|
||||
xstride, xstride*rrpart->rectx, rlp->rectf+a + xstride*offs);
|
||||
}
|
||||
|
||||
/* passes are allocated in sync */
|
||||
for(rpassp= rlp->passes.first; rpassp; rpassp= rpassp->next) {
|
||||
int a, xstride= rpassp->channels;
|
||||
for(a=0; a<xstride; a++)
|
||||
IMB_exr_set_channel(re->result->exrhandle, rlp->name, get_pass_name(rpassp->passtype, a),
|
||||
xstride, xstride*pa->rectx, rpassp->rect+a + xstride*offs);
|
||||
IMB_exr_set_channel(rr->exrhandle, rlp->name, get_pass_name(rpassp->passtype, a),
|
||||
xstride, xstride*rrpart->rectx, rpassp->rect+a + xstride*offs);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
party= rrpart->tilerect.ymin + rrpart->crop;
|
||||
partx= rrpart->tilerect.xmin + rrpart->crop;
|
||||
IMB_exrtile_write_channels(re->result->exrhandle, partx, party);
|
||||
IMB_exrtile_write_channels(rr->exrhandle, partx, party);
|
||||
|
||||
BLI_unlock_thread(LOCK_IMAGE);
|
||||
|
||||
|
@ -702,14 +728,17 @@ static void save_render_result_tile(Render *re, RenderPart *pa)
|
|||
static void save_empty_result_tiles(Render *re)
|
||||
{
|
||||
RenderPart *pa;
|
||||
RenderResult *rr;
|
||||
|
||||
IMB_exrtile_clear_channels(re->result->exrhandle);
|
||||
for(rr= re->result; rr; rr= rr->next) {
|
||||
IMB_exrtile_clear_channels(rr->exrhandle);
|
||||
|
||||
for(pa= re->parts.first; pa; pa= pa->next) {
|
||||
if(pa->ready==0) {
|
||||
int party= pa->disprect.ymin - re->disprect.ymin + pa->crop;
|
||||
int partx= pa->disprect.xmin - re->disprect.xmin + pa->crop;
|
||||
IMB_exrtile_write_channels(re->result->exrhandle, partx, party);
|
||||
for(pa= re->parts.first; pa; pa= pa->next) {
|
||||
if(pa->ready==0) {
|
||||
int party= pa->disprect.ymin - re->disprect.ymin + pa->crop;
|
||||
int partx= pa->disprect.xmin - re->disprect.xmin + pa->crop;
|
||||
IMB_exrtile_write_channels(rr->exrhandle, partx, party);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -836,7 +865,7 @@ static void renderresult_add_names(RenderResult *rr)
|
|||
|
||||
|
||||
/* only for temp buffer files, makes exact copy of render result */
|
||||
static void read_render_result(Render *re)
|
||||
static void read_render_result(Render *re, int sample)
|
||||
{
|
||||
RenderLayer *rl;
|
||||
RenderPass *rpass;
|
||||
|
@ -847,13 +876,15 @@ static void read_render_result(Render *re)
|
|||
RE_FreeRenderResult(re->result);
|
||||
re->result= new_render_result(re, &re->disprect, 0, RR_USEMEM);
|
||||
|
||||
render_unique_exr_name(re, str);
|
||||
render_unique_exr_name(re, str, sample);
|
||||
if(IMB_exr_begin_read(exrhandle, str, &rectx, &recty)==0) {
|
||||
IMB_exr_close(exrhandle);
|
||||
printf("cannot read: %s\n", str);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("read exr tmp file: %s\n", str);
|
||||
|
||||
if(rectx!=re->result->rectx || recty!=re->result->recty) {
|
||||
printf("error in reading render result\n");
|
||||
}
|
||||
|
@ -1060,7 +1091,7 @@ void RE_InitState(Render *re, RenderData *rd, int winx, int winy, rcti *disprect
|
|||
}
|
||||
|
||||
if(re->rectx < 2 || re->recty < 2 || (BKE_imtype_is_movie(rd->imtype) &&
|
||||
(re->rectx < 16 || re->recty < 16) )) {
|
||||
(re->rectx < 16 || re->recty < 16) )) {
|
||||
re->error("Image too small");
|
||||
re->ok= 0;
|
||||
}
|
||||
|
@ -1089,6 +1120,7 @@ void RE_InitState(Render *re, RenderData *rd, int winx, int winy, rcti *disprect
|
|||
}
|
||||
}
|
||||
|
||||
/* part of external api, not called for regular render pipeline */
|
||||
void RE_SetDispRect (struct Render *re, rcti *disprect)
|
||||
{
|
||||
re->disprect= *disprect;
|
||||
|
@ -1189,13 +1221,36 @@ static int render_display_draw_enabled(Render *re)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* allocate osa new results for samples */
|
||||
static RenderResult *new_full_sample_buffers(Render *re, ListBase *lb, rcti *partrct, int crop)
|
||||
{
|
||||
int a;
|
||||
|
||||
if(re->osa==0)
|
||||
return new_render_result(re, partrct, crop, RR_USEMEM);
|
||||
|
||||
for(a=0; a<re->osa; a++) {
|
||||
RenderResult *rr= new_render_result(re, partrct, crop, RR_USEMEM);
|
||||
BLI_addtail(lb, rr);
|
||||
rr->sample_nr= a;
|
||||
}
|
||||
|
||||
return lb->first;
|
||||
}
|
||||
|
||||
|
||||
/* the main thread call, renders an entire part */
|
||||
static void *do_part_thread(void *pa_v)
|
||||
{
|
||||
RenderPart *pa= 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, RR_USEMEM);
|
||||
|
||||
if(R.r.scemode & R_FULL_SAMPLE)
|
||||
pa->result= new_full_sample_buffers(&R, &pa->fullresult, &pa->disprect, pa->crop);
|
||||
else
|
||||
pa->result= new_render_result(&R, &pa->disprect, pa->crop, RR_USEMEM);
|
||||
|
||||
if(R.sss_points)
|
||||
zbufshade_sss_tile(pa);
|
||||
|
@ -1205,8 +1260,13 @@ static void *do_part_thread(void *pa_v)
|
|||
zbufshade_tile(pa);
|
||||
|
||||
/* merge too on break! */
|
||||
if(R.result->exrhandle)
|
||||
save_render_result_tile(&R, pa);
|
||||
if(R.result->exrhandle) {
|
||||
RenderResult *rr, *rrpart;
|
||||
|
||||
for(rr= R.result, rrpart= pa->result; rr && rrpart; rr= rr->next, rrpart= rrpart->next)
|
||||
save_render_result_tile(rr, rrpart);
|
||||
|
||||
}
|
||||
else if(render_display_draw_enabled(&R))
|
||||
merge_render_result(R.result, pa->result);
|
||||
}
|
||||
|
@ -1380,33 +1440,52 @@ static void print_part_stats(Render *re, RenderPart *pa)
|
|||
re->i.infostr= NULL;
|
||||
}
|
||||
|
||||
/* make osa new results for samples */
|
||||
static RenderResult *new_full_sample_buffers_exr(Render *re)
|
||||
{
|
||||
int a;
|
||||
|
||||
for(a=0; a<re->osa; a++) {
|
||||
RenderResult *rr= new_render_result(re, &re->disprect, 0, 1);
|
||||
BLI_addtail(&re->fullresult, rr);
|
||||
rr->sample_nr= a;
|
||||
}
|
||||
|
||||
return re->fullresult.first;
|
||||
}
|
||||
|
||||
static void threaded_tile_processor(Render *re)
|
||||
{
|
||||
ListBase threads;
|
||||
RenderPart *pa, *nextpa;
|
||||
RenderResult *rr;
|
||||
rctf viewplane= re->viewplane;
|
||||
int rendering=1, counter= 1, drawtimer=0, hasdrawn, minx=0;
|
||||
|
||||
/* first step; the entire render result, or prepare exr buffer saving */
|
||||
/* first step; free the entire render result, make new, and/or prepare exr buffer saving */
|
||||
RE_FreeRenderResult(re->result);
|
||||
rr= re->result= new_render_result(re, &re->disprect, 0, re->r.scemode & R_EXR_TILE_FILE);
|
||||
|
||||
if(rr==NULL)
|
||||
if(re->r.scemode & R_FULL_SAMPLE)
|
||||
re->result= new_full_sample_buffers_exr(re);
|
||||
else
|
||||
re->result= new_render_result(re, &re->disprect, 0, re->r.scemode & R_EXR_TILE_FILE);
|
||||
|
||||
if(re->result==NULL)
|
||||
return;
|
||||
|
||||
/* warning; no return here without closing exr file */
|
||||
// if(re->re->test_break())
|
||||
// return;
|
||||
|
||||
initparts(re);
|
||||
|
||||
if(rr->exrhandle) {
|
||||
if(re->result->exrhandle) {
|
||||
RenderResult *rr;
|
||||
char str[FILE_MAX];
|
||||
|
||||
render_unique_exr_name(re, str);
|
||||
for(rr= re->result; rr; rr= rr->next) {
|
||||
render_unique_exr_name(re, str, rr->sample_nr);
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
BLI_init_threads(&threads, do_part_thread, re->r.threads);
|
||||
|
@ -1461,7 +1540,7 @@ static void threaded_tile_processor(Render *re)
|
|||
re->display_draw(pa->result, NULL);
|
||||
print_part_stats(re, pa);
|
||||
|
||||
RE_FreeRenderResult(pa->result);
|
||||
free_render_result(&pa->fullresult, pa->result);
|
||||
pa->result= NULL;
|
||||
re->i.partsdone++;
|
||||
hasdrawn= 1;
|
||||
|
@ -1485,11 +1564,20 @@ static void threaded_tile_processor(Render *re)
|
|||
|
||||
}
|
||||
|
||||
if(rr->exrhandle) {
|
||||
if(re->result->exrhandle) {
|
||||
RenderResult *rr;
|
||||
|
||||
save_empty_result_tiles(re);
|
||||
IMB_exr_close(rr->exrhandle);
|
||||
rr->exrhandle= NULL;
|
||||
read_render_result(re);
|
||||
|
||||
for(rr= re->result; rr; rr= rr->next) {
|
||||
IMB_exr_close(rr->exrhandle);
|
||||
rr->exrhandle= NULL;
|
||||
}
|
||||
|
||||
free_render_result(&re->fullresult, re->result);
|
||||
re->result= NULL;
|
||||
|
||||
read_render_result(re, 0);
|
||||
}
|
||||
|
||||
/* unset threadsafety */
|
||||
|
@ -1822,11 +1910,18 @@ static void do_render_fields_blur_3d(Render *re)
|
|||
static void render_scene(Render *re, Scene *sce, int cfra)
|
||||
{
|
||||
Render *resc= RE_NewRender(sce->id.name);
|
||||
int winx= re->winx, winy= re->winy;
|
||||
|
||||
sce->r.cfra= cfra;
|
||||
|
||||
/* exception: scene uses own size (unfinished code) */
|
||||
if(0) {
|
||||
winx= (sce->r.size*sce->r.xsch)/100;
|
||||
winy= (sce->r.size*sce->r.ysch)/100;
|
||||
}
|
||||
|
||||
/* initial setup */
|
||||
RE_InitState(resc, &sce->r, re->winx, re->winy, &re->disprect);
|
||||
RE_InitState(resc, &sce->r, winx, winy, &re->disprect);
|
||||
|
||||
/* this to enable this scene to create speed vectors */
|
||||
resc->r.scemode |= R_DOCOMP;
|
||||
|
@ -1837,6 +1932,10 @@ static void render_scene(Render *re, Scene *sce, int cfra)
|
|||
/* ensure scene has depsgraph, base flags etc OK. Warning... also sets G.scene */
|
||||
set_scene_bg(sce);
|
||||
|
||||
/* fullsample wants uniform osa levels */
|
||||
if(resc->r.scemode & R_FULL_SAMPLE)
|
||||
resc->r.osa= resc->osa= re->osa;
|
||||
|
||||
/* copy callbacks */
|
||||
resc->display_draw= re->display_draw;
|
||||
resc->test_break= re->test_break;
|
||||
|
@ -1909,6 +2008,72 @@ static void render_composit_stats(char *str)
|
|||
R.i.infostr= NULL;
|
||||
}
|
||||
|
||||
/* reads all buffers, calls optional composite, merges in first result->rectf */
|
||||
static void do_merge_fullsample(Render *re, bNodeTree *ntree)
|
||||
{
|
||||
float *rectf;
|
||||
int sample;
|
||||
|
||||
/* we accumulate in here */
|
||||
rectf= MEM_mapallocN(re->rectx*re->recty*sizeof(float)*4, "fullsample rgba");
|
||||
|
||||
for(sample=0; sample<re->osa; sample++) {
|
||||
RenderResult rres;
|
||||
int x, y, mask;
|
||||
|
||||
/* set all involved renders on the samplebuffers (first was done by render itself) */
|
||||
if(sample) {
|
||||
Render *re1;
|
||||
for(re1= RenderList.first; re1; re1= re1->next) {
|
||||
if(re1->r.scemode & R_FULL_SAMPLE)
|
||||
read_render_result(re1, sample);
|
||||
}
|
||||
}
|
||||
|
||||
/* composite */
|
||||
if(ntree) {
|
||||
ntreeCompositTagRender(re->scene);
|
||||
ntreeCompositTagAnimated(ntree);
|
||||
|
||||
ntreeCompositExecTree(ntree, &re->r, G.background==0);
|
||||
}
|
||||
|
||||
/* ensure we get either composited result or the active layer */
|
||||
RE_GetResultImage(re, &rres);
|
||||
|
||||
/* accumulate with filter, and clip */
|
||||
mask= (1<<sample);
|
||||
for(y=1; y<re->recty-1; y++) {
|
||||
float *rf= rectf + 4*y*re->rectx + 4;
|
||||
float *col= rres.rectf + 4*y*re->rectx + 4;
|
||||
|
||||
for(x=1; x<re->rectx-1; x++, rf+=4, col+=4) {
|
||||
if(col[0]<0.0f) col[0]=0.0f; else if(col[0] > 1.0f) col[0]= 1.0f;
|
||||
if(col[1]<0.0f) col[1]=0.0f; else if(col[1] > 1.0f) col[1]= 1.0f;
|
||||
if(col[2]<0.0f) col[2]=0.0f; else if(col[2] > 1.0f) col[2]= 1.0f;
|
||||
|
||||
add_filt_fmask(mask, col, rf, re->rectx);
|
||||
}
|
||||
}
|
||||
|
||||
/* show stuff */
|
||||
if(sample!=re->osa-1) {
|
||||
/* 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);
|
||||
}
|
||||
|
||||
if(re->test_break())
|
||||
break;
|
||||
}
|
||||
|
||||
if(re->result->rectf)
|
||||
MEM_freeN(re->result->rectf);
|
||||
re->result->rectf= rectf;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* returns fully composited render-result on given time step (in RenderData) */
|
||||
static void do_render_composite_fields_blur_3d(Render *re)
|
||||
{
|
||||
|
@ -1928,9 +2093,12 @@ static void do_render_composite_fields_blur_3d(Render *re)
|
|||
if(re->r.scemode & R_SINGLE_LAYER)
|
||||
pop_render_result(re);
|
||||
|
||||
if(!re->test_break() && ntree) {
|
||||
ntreeCompositTagRender(re->scene);
|
||||
ntreeCompositTagAnimated(ntree);
|
||||
if(!re->test_break()) {
|
||||
|
||||
if(ntree) {
|
||||
ntreeCompositTagRender(re->scene);
|
||||
ntreeCompositTagAnimated(ntree);
|
||||
}
|
||||
|
||||
if(re->r.scemode & R_DOCOMP) {
|
||||
/* checks if there are render-result nodes that need scene */
|
||||
|
@ -1943,11 +2111,19 @@ static void do_render_composite_fields_blur_3d(Render *re)
|
|||
/* in case it was never initialized */
|
||||
R.stats_draw= re->stats_draw;
|
||||
|
||||
ntreeCompositExecTree(ntree, &re->r, G.background==0);
|
||||
if(re->r.scemode & R_FULL_SAMPLE)
|
||||
do_merge_fullsample(re, ntree);
|
||||
else
|
||||
ntreeCompositExecTree(ntree, &re->r, G.background==0);
|
||||
|
||||
ntree->stats_draw= NULL;
|
||||
ntree->test_break= NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
if(re->r.scemode & R_FULL_SAMPLE)
|
||||
do_merge_fullsample(re, NULL);
|
||||
|
||||
}
|
||||
|
||||
/* weak... the display callback wants an active renderlayer pointer... */
|
||||
|
@ -2101,14 +2277,20 @@ static int is_rendering_allowed(Render *re)
|
|||
if(re->r.scemode & R_EXR_TILE_FILE) {
|
||||
char str[FILE_MAX];
|
||||
|
||||
render_unique_exr_name(re, str);
|
||||
render_unique_exr_name(re, str, 0);
|
||||
|
||||
if (BLI_is_writable(str)==0) {
|
||||
re->error("Can not save render buffers, check the temp default path");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* no osa + fullsample won't work... */
|
||||
if(re->osa==0)
|
||||
re->r.scemode &= ~R_FULL_SAMPLE;
|
||||
|
||||
}
|
||||
else
|
||||
re->r.scemode &= ~R_FULL_SAMPLE; /* clear to be sure */
|
||||
|
||||
if(re->r.scemode & R_DOCOMP) {
|
||||
if(re->scene->use_nodes) {
|
||||
|
@ -2394,7 +2576,7 @@ void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra)
|
|||
|
||||
/* note; repeated win/disprect calc... solve that nicer, also in compo */
|
||||
|
||||
/* only temp file! */
|
||||
/* only the temp file! */
|
||||
void RE_ReadRenderResult(Scene *scene, Scene *scenode)
|
||||
{
|
||||
Render *re;
|
||||
|
@ -2426,7 +2608,7 @@ void RE_ReadRenderResult(Scene *scene, Scene *scenode)
|
|||
RE_InitState(re, &scene->r, winx, winy, &disprect);
|
||||
re->scene= scene;
|
||||
|
||||
read_render_result(re);
|
||||
read_render_result(re, 0);
|
||||
}
|
||||
|
||||
void RE_set_max_threads(int threads)
|
||||
|
|
|
@ -91,15 +91,6 @@ void addAlphaOverFloat(float *dest, float *source)
|
|||
void addAlphaUnderFloat(float *dest, float *source)
|
||||
{
|
||||
float mul;
|
||||
|
||||
if( (-RE_EMPTY_COLOR_FLOAT < dest[3])
|
||||
&& (dest[3] < RE_EMPTY_COLOR_FLOAT) ) {
|
||||
dest[0] = source[0];
|
||||
dest[1] = source[1];
|
||||
dest[2] = source[2];
|
||||
dest[3] = source[3];
|
||||
return;
|
||||
}
|
||||
|
||||
mul= 1.0 - dest[3];
|
||||
|
||||
|
|
|
@ -348,12 +348,19 @@ static void lamphalo_tile(RenderPart *pa, RenderLayer *rl)
|
|||
static void add_filt_passes(RenderLayer *rl, int curmask, int rectx, int offset, ShadeInput *shi, ShadeResult *shr)
|
||||
{
|
||||
RenderPass *rpass;
|
||||
|
||||
/* combined rgb */
|
||||
add_filt_fmask(curmask, shr->combined, rl->rectf + 4*offset, rectx);
|
||||
|
||||
for(rpass= rl->passes.first; rpass; rpass= rpass->next) {
|
||||
float *fp, *col= NULL;
|
||||
int pixsize= 3;
|
||||
|
||||
switch(rpass->passtype) {
|
||||
case SCE_PASS_Z:
|
||||
fp= rpass->rect + offset;
|
||||
*fp= -shi->co[2];
|
||||
break;
|
||||
case SCE_PASS_RGBA:
|
||||
col= shr->col;
|
||||
pixsize= 4;
|
||||
|
@ -432,12 +439,20 @@ static void add_filt_passes(RenderLayer *rl, int curmask, int rectx, int offset,
|
|||
static void add_passes(RenderLayer *rl, int offset, ShadeInput *shi, ShadeResult *shr)
|
||||
{
|
||||
RenderPass *rpass;
|
||||
float *fp;
|
||||
|
||||
fp= rl->rectf + 4*offset;
|
||||
QUATCOPY(fp, shr->combined);
|
||||
|
||||
for(rpass= rl->passes.first; rpass; rpass= rpass->next) {
|
||||
float *fp, *col= NULL, uvcol[3];
|
||||
float *col= NULL, uvcol[3];
|
||||
int a, pixsize= 3;
|
||||
|
||||
switch(rpass->passtype) {
|
||||
case SCE_PASS_Z:
|
||||
fp= rpass->rect + offset;
|
||||
*fp= -shi->co[2];
|
||||
break;
|
||||
case SCE_PASS_RGBA:
|
||||
col= shr->col;
|
||||
pixsize= 4;
|
||||
|
@ -497,26 +512,60 @@ static void add_passes(RenderLayer *rl, int offset, ShadeInput *shi, ShadeResult
|
|||
}
|
||||
}
|
||||
|
||||
/* only do sky, is default in the solid layer (shade_tile) btw */
|
||||
static void sky_tile(RenderPart *pa, float *pass)
|
||||
int get_sample_layers(RenderPart *pa, RenderLayer *rl, RenderLayer **rlpp)
|
||||
{
|
||||
float col[4];
|
||||
int x, y;
|
||||
|
||||
if(pa->fullresult.first) {
|
||||
int sample, nr= BLI_findindex(&pa->result->layers, rl);
|
||||
|
||||
for(sample=0; sample<R.osa; sample++) {
|
||||
RenderResult *rr= BLI_findlink(&pa->fullresult, sample);
|
||||
|
||||
rlpp[sample]= BLI_findlink(&rr->layers, nr);
|
||||
}
|
||||
return R.osa;
|
||||
}
|
||||
else {
|
||||
rlpp[0]= rl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* only do sky, is default in the solid layer (shade_tile) btw */
|
||||
static void sky_tile(RenderPart *pa, RenderLayer *rl)
|
||||
{
|
||||
RenderLayer *rlpp[RE_MAX_OSA];
|
||||
int x, y, od=0, totsample;
|
||||
|
||||
if(R.r.alphamode!=R_ADDSKY)
|
||||
return;
|
||||
|
||||
totsample= get_sample_layers(pa, rl, rlpp);
|
||||
|
||||
for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++) {
|
||||
for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, pass+=4) {
|
||||
if(pass[3]<1.0f) {
|
||||
if(pass[3]==0.0f)
|
||||
shadeSkyPixel(pass, x, y);
|
||||
else {
|
||||
shadeSkyPixel(col, x, y);
|
||||
addAlphaOverFloat(col, pass);
|
||||
QUATCOPY(pass, col);
|
||||
for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, od+=4) {
|
||||
float col[4];
|
||||
int sample, done= 0;
|
||||
|
||||
for(sample= 0; sample<totsample; sample++) {
|
||||
float *pass= rlpp[sample]->rectf + od;
|
||||
|
||||
if(pass[3]<1.0f) {
|
||||
|
||||
if(done==0) {
|
||||
shadeSkyPixel(col, x, y);
|
||||
done= 1;
|
||||
}
|
||||
|
||||
if(pass[3]==0.0f) {
|
||||
QUATCOPY(pass, col);
|
||||
}
|
||||
else {
|
||||
addAlphaUnderFloat(pass, col);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(y&1)
|
||||
|
@ -528,10 +577,9 @@ static void shadeDA_tile(RenderPart *pa, RenderLayer *rl)
|
|||
{
|
||||
RenderResult *rr= pa->result;
|
||||
ShadeSample ssamp;
|
||||
float *fcol, *rf, *rectf= rl->rectf;
|
||||
long *rd, *rectdaps= pa->rectdaps;
|
||||
int samp;
|
||||
int x, y, seed, crop=0, offs=0, od, addpassflag;
|
||||
int x, y, seed, crop=0, offs=0, od;
|
||||
|
||||
if(R.test_break()) return;
|
||||
|
||||
|
@ -544,7 +592,6 @@ static void shadeDA_tile(RenderPart *pa, RenderLayer *rl)
|
|||
|
||||
/* general shader info, passes */
|
||||
shade_sample_initialize(&ssamp, pa, rl);
|
||||
addpassflag= rl->passflag & ~(SCE_PASS_Z|SCE_PASS_COMBINED);
|
||||
|
||||
/* occlusion caching */
|
||||
if(R.occlusiontree)
|
||||
|
@ -553,7 +600,6 @@ static void shadeDA_tile(RenderPart *pa, RenderLayer *rl)
|
|||
/* filtered render, for now we assume only 1 filter size */
|
||||
if(pa->crop) {
|
||||
crop= 1;
|
||||
rectf+= 4*(pa->rectx + 1);
|
||||
rectdaps+= pa->rectx + 1;
|
||||
offs= pa->rectx + 1;
|
||||
}
|
||||
|
@ -564,28 +610,35 @@ static void shadeDA_tile(RenderPart *pa, RenderLayer *rl)
|
|||
rr->renlay= rl;
|
||||
|
||||
for(y=pa->disprect.ymin+crop; y<pa->disprect.ymax-crop; y++, rr->renrect.ymax++) {
|
||||
rf= rectf;
|
||||
rd= rectdaps;
|
||||
od= offs;
|
||||
|
||||
for(x=pa->disprect.xmin+crop; x<pa->disprect.xmax-crop; x++, rd++, rf+=4, od++) {
|
||||
for(x=pa->disprect.xmin+crop; x<pa->disprect.xmax-crop; x++, rd++, od++) {
|
||||
BLI_thread_srandom(pa->thread, seed++);
|
||||
|
||||
if(*rd) {
|
||||
if(shade_samples(&ssamp, (PixStr *)(*rd), x, y)) {
|
||||
for(samp=0; samp<ssamp.tot; samp++) {
|
||||
|
||||
fcol= ssamp.shr[samp].combined;
|
||||
add_filt_fmask(ssamp.shi[samp].mask, fcol, rf, pa->rectx);
|
||||
|
||||
if(addpassflag)
|
||||
|
||||
/* multisample buffers or filtered mask filling? */
|
||||
if(pa->fullresult.first) {
|
||||
int a;
|
||||
for(samp=0; samp<ssamp.tot; samp++) {
|
||||
int smask= ssamp.shi[samp].mask;
|
||||
for(a=0; a<R.osa; a++) {
|
||||
int mask= 1<<a;
|
||||
if(smask & mask)
|
||||
add_passes(ssamp.rlpp[a], od, &ssamp.shi[samp], &ssamp.shr[samp]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for(samp=0; samp<ssamp.tot; samp++)
|
||||
add_filt_passes(rl, ssamp.shi[samp].mask, pa->rectx, od, &ssamp.shi[samp], &ssamp.shr[samp]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rectf+= 4*pa->rectx;
|
||||
rectdaps+= pa->rectx;
|
||||
offs+= pa->rectx;
|
||||
|
||||
|
@ -918,97 +971,104 @@ void zbufshadeDA_tile(RenderPart *pa)
|
|||
/* transp layer */
|
||||
if(R.flag & R_ZTRA) {
|
||||
if(rl->layflag & SCE_LAY_ZTRA) {
|
||||
unsigned short *ztramask, *solidmask= NULL; /* 16 bits, MAX_OSA */
|
||||
|
||||
/* allocate, but not free here, for asynchronous display of this rect in main thread */
|
||||
rl->acolrect= MEM_callocN(4*sizeof(float)*pa->rectx*pa->recty, "alpha layer");
|
||||
|
||||
/* swap for live updates, and it is used in zbuf.c!!! */
|
||||
SWAP(float *, rl->acolrect, rl->rectf);
|
||||
ztramask= zbuffer_transp_shade(pa, rl, rl->rectf, &psmlist);
|
||||
SWAP(float *, rl->acolrect, rl->rectf);
|
||||
|
||||
/* zbuffer transp only returns ztramask if there's solid rendered */
|
||||
if(ztramask)
|
||||
solidmask= make_solid_mask(pa);
|
||||
|
||||
if(ztramask && solidmask) {
|
||||
unsigned short *sps= solidmask, *spz= ztramask;
|
||||
unsigned short fullmask= (1<<R.osa)-1;
|
||||
float *fcol= rl->rectf; float *acol= rl->acolrect;
|
||||
int x;
|
||||
|
||||
for(x=pa->rectx*pa->recty; x>0; x--, acol+=4, fcol+=4, sps++, spz++) {
|
||||
if(*sps == fullmask)
|
||||
addAlphaOverFloat(fcol, acol);
|
||||
else
|
||||
addAlphaOverFloatMask(fcol, acol, *sps, *spz);
|
||||
}
|
||||
}
|
||||
else {
|
||||
float *fcol= rl->rectf; float *acol= rl->acolrect;
|
||||
int x;
|
||||
for(x=pa->rectx*pa->recty; x>0; x--, acol+=4, fcol+=4) {
|
||||
addAlphaOverFloat(fcol, acol);
|
||||
}
|
||||
if(pa->fullresult.first) {
|
||||
zbuffer_transp_shade(pa, rl, rl->rectf, &psmlist);
|
||||
}
|
||||
else {
|
||||
unsigned short *ztramask, *solidmask= NULL; /* 16 bits, MAX_OSA */
|
||||
|
||||
/* allocate, but not free here, for asynchronous display of this rect in main thread */
|
||||
rl->acolrect= MEM_callocN(4*sizeof(float)*pa->rectx*pa->recty, "alpha layer");
|
||||
|
||||
/* swap for live updates, and it is used in zbuf.c!!! */
|
||||
SWAP(float *, rl->acolrect, rl->rectf);
|
||||
ztramask= zbuffer_transp_shade(pa, rl, rl->rectf, &psmlist);
|
||||
SWAP(float *, rl->acolrect, rl->rectf);
|
||||
|
||||
/* zbuffer transp only returns ztramask if there's solid rendered */
|
||||
if(ztramask)
|
||||
solidmask= make_solid_mask(pa);
|
||||
|
||||
if(ztramask && solidmask) {
|
||||
unsigned short *sps= solidmask, *spz= ztramask;
|
||||
unsigned short fullmask= (1<<R.osa)-1;
|
||||
float *fcol= rl->rectf; float *acol= rl->acolrect;
|
||||
int x;
|
||||
|
||||
for(x=pa->rectx*pa->recty; x>0; x--, acol+=4, fcol+=4, sps++, spz++) {
|
||||
if(*sps == fullmask)
|
||||
addAlphaOverFloat(fcol, acol);
|
||||
else
|
||||
addAlphaOverFloatMask(fcol, acol, *sps, *spz);
|
||||
}
|
||||
}
|
||||
else {
|
||||
float *fcol= rl->rectf; float *acol= rl->acolrect;
|
||||
int x;
|
||||
for(x=pa->rectx*pa->recty; x>0; x--, acol+=4, fcol+=4) {
|
||||
addAlphaOverFloat(fcol, acol);
|
||||
}
|
||||
}
|
||||
if(solidmask) MEM_freeN(solidmask);
|
||||
if(ztramask) MEM_freeN(ztramask);
|
||||
}
|
||||
if(solidmask) MEM_freeN(solidmask);
|
||||
if(ztramask) MEM_freeN(ztramask);
|
||||
}
|
||||
}
|
||||
|
||||
/* strand rendering */
|
||||
if((rl->layflag & SCE_LAY_STRAND) && R.totstrand) {
|
||||
float *fcol, *scol;
|
||||
unsigned short *strandmask, *solidmask= NULL; /* 16 bits, MAX_OSA */
|
||||
int x;
|
||||
|
||||
/* allocate, but not free here, for asynchronous display of this rect in main thread */
|
||||
rl->scolrect= MEM_callocN(4*sizeof(float)*pa->rectx*pa->recty, "strand layer");
|
||||
|
||||
/* swap for live updates, and it is used in zbuf.c!!! */
|
||||
SWAP(float*, rl->scolrect, rl->rectf);
|
||||
strandmask= zbuffer_strands_shade(&R, pa, rl, rl->rectf);
|
||||
SWAP(float*, rl->scolrect, rl->rectf);
|
||||
|
||||
/* zbuffer strands only returns strandmask if there's solid rendered */
|
||||
if(strandmask)
|
||||
solidmask= make_solid_mask(pa);
|
||||
|
||||
if(strandmask && solidmask) {
|
||||
unsigned short *sps= solidmask, *spz= strandmask;
|
||||
unsigned short fullmask= (1<<R.osa)-1;
|
||||
|
||||
fcol= rl->rectf; scol= rl->scolrect;
|
||||
for(x=pa->rectx*pa->recty; x>0; x--, scol+=4, fcol+=4, sps++, spz++) {
|
||||
if(*sps == fullmask)
|
||||
addAlphaOverFloat(fcol, scol);
|
||||
else
|
||||
addAlphaOverFloatMask(fcol, scol, *sps, *spz);
|
||||
}
|
||||
if(pa->fullresult.first) {
|
||||
zbuffer_strands_shade(&R, pa, rl, rl->rectf);
|
||||
}
|
||||
else {
|
||||
fcol= rl->rectf; scol= rl->scolrect;
|
||||
for(x=pa->rectx*pa->recty; x>0; x--, scol+=4, fcol+=4)
|
||||
addAlphaOverFloat(fcol, scol);
|
||||
}
|
||||
float *fcol, *scol;
|
||||
unsigned short *strandmask, *solidmask= NULL; /* 16 bits, MAX_OSA */
|
||||
int x;
|
||||
|
||||
/* allocate, but not free here, for asynchronous display of this rect in main thread */
|
||||
rl->scolrect= MEM_callocN(4*sizeof(float)*pa->rectx*pa->recty, "strand layer");
|
||||
|
||||
if(solidmask) MEM_freeN(solidmask);
|
||||
if(strandmask) MEM_freeN(strandmask);
|
||||
/* swap for live updates, and it is used in zbuf.c!!! */
|
||||
SWAP(float*, rl->scolrect, rl->rectf);
|
||||
strandmask= zbuffer_strands_shade(&R, pa, rl, rl->rectf);
|
||||
SWAP(float*, rl->scolrect, rl->rectf);
|
||||
|
||||
/* zbuffer strands only returns strandmask if there's solid rendered */
|
||||
if(strandmask)
|
||||
solidmask= make_solid_mask(pa);
|
||||
|
||||
if(strandmask && solidmask) {
|
||||
unsigned short *sps= solidmask, *spz= strandmask;
|
||||
unsigned short fullmask= (1<<R.osa)-1;
|
||||
|
||||
fcol= rl->rectf; scol= rl->scolrect;
|
||||
for(x=pa->rectx*pa->recty; x>0; x--, scol+=4, fcol+=4, sps++, spz++) {
|
||||
if(*sps == fullmask)
|
||||
addAlphaOverFloat(fcol, scol);
|
||||
else
|
||||
addAlphaOverFloatMask(fcol, scol, *sps, *spz);
|
||||
}
|
||||
}
|
||||
else {
|
||||
fcol= rl->rectf; scol= rl->scolrect;
|
||||
for(x=pa->rectx*pa->recty; x>0; x--, scol+=4, fcol+=4)
|
||||
addAlphaOverFloat(fcol, scol);
|
||||
}
|
||||
|
||||
if(solidmask) MEM_freeN(solidmask);
|
||||
if(strandmask) MEM_freeN(strandmask);
|
||||
}
|
||||
}
|
||||
|
||||
/* sky before edge */
|
||||
if(rl->layflag & SCE_LAY_SKY)
|
||||
sky_tile(pa, rl->rectf);
|
||||
sky_tile(pa, rl);
|
||||
|
||||
/* extra layers */
|
||||
if(rl->layflag & SCE_LAY_EDGE)
|
||||
if(R.r.mode & R_EDGE)
|
||||
edge_enhance_add(pa, rl->rectf, edgerect);
|
||||
|
||||
if(rl->passflag & SCE_PASS_Z)
|
||||
convert_zbuf_to_distbuf(pa, rl);
|
||||
|
||||
if(rl->passflag & SCE_PASS_VECTOR)
|
||||
reset_sky_speed(pa, rl);
|
||||
|
||||
|
@ -1046,7 +1106,6 @@ void zbufshade_tile(RenderPart *pa)
|
|||
RenderLayer *rl;
|
||||
PixStr ps;
|
||||
float *edgerect= NULL;
|
||||
int addpassflag;
|
||||
|
||||
/* fake pixel struct, to comply to osa render */
|
||||
ps.next= NULL;
|
||||
|
@ -1061,7 +1120,6 @@ void zbufshade_tile(RenderPart *pa)
|
|||
|
||||
/* general shader info, passes */
|
||||
shade_sample_initialize(&ssamp, pa, rl);
|
||||
addpassflag= rl->passflag & ~(SCE_PASS_Z|SCE_PASS_COMBINED);
|
||||
|
||||
zbuffer_solid(pa, rl, NULL, NULL);
|
||||
|
||||
|
@ -1104,11 +1162,8 @@ void zbufshade_tile(RenderPart *pa)
|
|||
ps.facenr= *rp;
|
||||
ps.z= *rz;
|
||||
if(shade_samples(&ssamp, &ps, x, y)) {
|
||||
QUATCOPY(fcol, ssamp.shr[0].combined);
|
||||
|
||||
/* passes */
|
||||
if(addpassflag)
|
||||
add_passes(rl, offs, ssamp.shi, ssamp.shr);
|
||||
/* combined and passes */
|
||||
add_passes(rl, offs, ssamp.shi, ssamp.shr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1177,7 +1232,7 @@ void zbufshade_tile(RenderPart *pa)
|
|||
|
||||
/* sky before edge */
|
||||
if(rl->layflag & SCE_LAY_SKY)
|
||||
sky_tile(pa, rl->rectf);
|
||||
sky_tile(pa, rl);
|
||||
|
||||
if(!R.test_break()) {
|
||||
if(rl->layflag & SCE_LAY_EDGE)
|
||||
|
@ -1185,9 +1240,6 @@ void zbufshade_tile(RenderPart *pa)
|
|||
edge_enhance_add(pa, rl->rectf, edgerect);
|
||||
}
|
||||
|
||||
if(rl->passflag & SCE_PASS_Z)
|
||||
convert_zbuf_to_distbuf(pa, rl);
|
||||
|
||||
if(rl->passflag & SCE_PASS_VECTOR)
|
||||
reset_sky_speed(pa, rl);
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include "MTC_matrixops.h"
|
||||
#include "BLI_arithb.h"
|
||||
#include "BLI_blenlib.h"
|
||||
|
||||
#include "DNA_curve_types.h"
|
||||
#include "DNA_group_types.h"
|
||||
|
@ -1214,8 +1215,9 @@ void shade_input_initialize(ShadeInput *shi, RenderPart *pa, RenderLayer *rl, in
|
|||
shi->combinedflag= ~rl->pass_xor;
|
||||
shi->mat_override= rl->mat_override;
|
||||
shi->light_override= rl->light_override;
|
||||
|
||||
// shi->rl= rl;
|
||||
/* note shi.depth==0 means first hit, not raytracing */
|
||||
|
||||
}
|
||||
|
||||
/* initialize per part, not per pixel! */
|
||||
|
@ -1230,6 +1232,8 @@ void shade_sample_initialize(ShadeSample *ssamp, RenderPart *pa, RenderLayer *rl
|
|||
memset(&ssamp->shr[a], 0, sizeof(ShadeResult));
|
||||
}
|
||||
|
||||
get_sample_layers(pa, rl, ssamp->rlpp);
|
||||
|
||||
ssamp->samplenr= 0; /* counter, detect shadow-reuse for shaders */
|
||||
}
|
||||
|
||||
|
@ -1279,7 +1283,8 @@ void shade_samples_fill_with_ps(ShadeSample *ssamp, PixStr *ps, int x, int y)
|
|||
shade_input_copy_triangle(shi, shi-1);
|
||||
|
||||
shi->mask= (1<<samp);
|
||||
shi->samplenr= ssamp->samplenr++;
|
||||
// shi->rl= ssamp->rlpp[samp];
|
||||
shi->samplenr= ssamp->samplenr++; /* this counter is not being reset per pixel */
|
||||
shade_input_set_viewco(shi, xs, ys, (float)ps->z);
|
||||
shade_input_set_uv(shi);
|
||||
shade_input_set_normals(shi);
|
||||
|
|
|
@ -913,12 +913,16 @@ static void zbuffer_strands_filter(Render *re, RenderPart *pa, RenderLayer *rl,
|
|||
{
|
||||
RenderResult *rr= pa->result;
|
||||
ShadeResult *shr, *shrrect= spart->result;
|
||||
RenderLayer *rl_pp[RE_MAX_OSA];
|
||||
float *passrect= pass, alpha, sampalpha;
|
||||
long *rdrect;
|
||||
int osa, x, y, a, crop= 0, offs=0, od;
|
||||
|
||||
osa= (re->osa? re->osa: 1);
|
||||
sampalpha= 1.0f/osa;
|
||||
|
||||
/* only used for multisample buffers */
|
||||
get_sample_layers(pa, rl, rl_pp);
|
||||
|
||||
/* filtered render, for now we assume only 1 filter size */
|
||||
if(pa->crop) {
|
||||
|
@ -933,7 +937,7 @@ static void zbuffer_strands_filter(Render *re, RenderPart *pa, RenderLayer *rl,
|
|||
/* zero alpha pixels get speed vector max again */
|
||||
if(spart->addpassflag & SCE_PASS_VECTOR)
|
||||
if(rl->layflag & SCE_LAY_SOLID)
|
||||
reset_sky_speedvectors(pa, rl, rl->scolrect);
|
||||
reset_sky_speedvectors(pa, rl, rl->scolrect?rl->scolrect:rl->rectf); /* scolrect==NULL for multisample */
|
||||
|
||||
/* init scanline updates */
|
||||
rr->renrect.ymin= 0;
|
||||
|
@ -954,26 +958,44 @@ static void zbuffer_strands_filter(Render *re, RenderPart *pa, RenderLayer *rl,
|
|||
else {
|
||||
alpha= 0.0f;
|
||||
|
||||
if(re->osa == 0) {
|
||||
addAlphaUnderFloat(pass, shr->combined);
|
||||
if(pa->fullresult.first) {
|
||||
for(a=0; a<re->osa; a++) {
|
||||
alpha= shr[a].combined[3];
|
||||
if(alpha!=0.0f) {
|
||||
RenderLayer *rl= rl_pp[a];
|
||||
|
||||
addAlphaOverFloat(rl->rectf + 4*od, shr[a].combined);
|
||||
|
||||
add_transp_passes(rl, od, shr, alpha);
|
||||
if(spart->addpassflag & SCE_PASS_VECTOR)
|
||||
add_transp_speed(rl, od, shr[a].winspeed, alpha, rdrect);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
/* note; cannot use pass[3] for alpha due to filtermask */
|
||||
for(a=0; a<re->osa; a++) {
|
||||
add_filt_fmask(1<<a, shr[a].combined, pass, rr->rectx);
|
||||
alpha += shr[a].combined[3];
|
||||
|
||||
if(re->osa == 0) {
|
||||
addAlphaUnderFloat(pass, shr->combined);
|
||||
}
|
||||
else {
|
||||
/* note; cannot use pass[3] for alpha due to filtermask */
|
||||
for(a=0; a<re->osa; a++) {
|
||||
add_filt_fmask(1<<a, shr[a].combined, pass, rr->rectx);
|
||||
alpha += shr[a].combined[3];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(spart->addpassflag) {
|
||||
alpha *= sampalpha;
|
||||
if(spart->addpassflag) {
|
||||
alpha *= sampalpha;
|
||||
|
||||
/* merge all in one, and then add */
|
||||
merge_transp_passes(rl, shr);
|
||||
add_transp_passes(rl, od, shr, alpha);
|
||||
/* merge all in one, and then add */
|
||||
merge_transp_passes(rl, shr);
|
||||
add_transp_passes(rl, od, shr, alpha);
|
||||
|
||||
if(spart->addpassflag & SCE_PASS_VECTOR)
|
||||
add_transp_speed(rl, od, shr->winspeed, alpha, rdrect);
|
||||
if(spart->addpassflag & SCE_PASS_VECTOR)
|
||||
add_transp_speed(rl, od, shr->winspeed, alpha, rdrect);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1203,7 +1225,7 @@ unsigned short *zbuffer_strands_shade(Render *re, RenderPart *pa, RenderLayer *r
|
|||
|
||||
zbuf_free_span(&zspan);
|
||||
|
||||
if(!(re->osa && (rl->layflag & SCE_LAY_SOLID))) {
|
||||
if( !(re->osa && (rl->layflag & SCE_LAY_SOLID)) || (pa->fullresult.first)) {
|
||||
MEM_freeN(spart.mask);
|
||||
spart.mask= NULL;
|
||||
}
|
||||
|
|
|
@ -3793,7 +3793,7 @@ void reset_sky_speedvectors(RenderPart *pa, RenderLayer *rl, float *rectf)
|
|||
|
||||
#define MAX_ZROW 2000
|
||||
|
||||
/* main render call to fill in pass the full transparent layer */
|
||||
/* main render call to do the z-transparent layer */
|
||||
/* returns a mask, only if a) transp rendered and b) solid was rendered */
|
||||
unsigned short *zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pass, ListBase *psmlist)
|
||||
{
|
||||
|
@ -3851,13 +3851,13 @@ unsigned short *zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pas
|
|||
ISB_create(pa, APixbuf);
|
||||
|
||||
/* masks, to have correct alpha combine */
|
||||
if(R.osa && (rl->layflag & SCE_LAY_SOLID))
|
||||
if(R.osa && (rl->layflag & SCE_LAY_SOLID) && pa->fullresult.first==NULL)
|
||||
ztramask= MEM_callocN(pa->rectx*pa->recty*sizeof(short), "ztramask");
|
||||
|
||||
/* zero alpha pixels get speed vector max again */
|
||||
if(addpassflag & SCE_PASS_VECTOR)
|
||||
if(rl->layflag & SCE_LAY_SOLID)
|
||||
reset_sky_speedvectors(pa, rl, rl->acolrect);
|
||||
reset_sky_speedvectors(pa, rl, rl->acolrect?rl->acolrect:rl->rectf); /* if acolrect is set we use it */
|
||||
|
||||
/* filtered render, for now we assume only 1 filter size */
|
||||
if(pa->crop) {
|
||||
|
@ -3967,21 +3967,39 @@ unsigned short *zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pas
|
|||
}
|
||||
}
|
||||
|
||||
/* note; cannot use pass[3] for alpha due to filtermask */
|
||||
for(a=0; a<R.osa; a++) {
|
||||
add_filt_fmask(1<<a, samp_shr[a].combined, pass, rr->rectx);
|
||||
alpha+= samp_shr[a].combined[3];
|
||||
/* multisample buffers or filtered mask filling? */
|
||||
if(pa->fullresult.first) {
|
||||
for(a=0; a<R.osa; a++) {
|
||||
alpha= samp_shr[a].combined[3];
|
||||
if(alpha!=0.0f) {
|
||||
RenderLayer *rl= ssamp.rlpp[a];
|
||||
|
||||
addAlphaOverFloat(rl->rectf + 4*od, samp_shr[a].combined);
|
||||
|
||||
add_transp_passes(rl, od, samp_shr, alpha);
|
||||
if(addpassflag & SCE_PASS_VECTOR)
|
||||
add_transp_speed(rl, od, samp_shr[a].winspeed, alpha, rdrect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(addpassflag) {
|
||||
alpha*= sampalpha;
|
||||
else {
|
||||
|
||||
/* note; cannot use pass[3] for alpha due to filtermask */
|
||||
for(a=0; a<R.osa; a++) {
|
||||
add_filt_fmask(1<<a, samp_shr[a].combined, pass, rr->rectx);
|
||||
alpha+= samp_shr[a].combined[3];
|
||||
}
|
||||
|
||||
/* merge all in one, and then add */
|
||||
merge_transp_passes(rl, samp_shr);
|
||||
add_transp_passes(rl, od, samp_shr, alpha);
|
||||
if(addpassflag) {
|
||||
alpha*= sampalpha;
|
||||
|
||||
/* merge all in one, and then add */
|
||||
merge_transp_passes(rl, samp_shr);
|
||||
add_transp_passes(rl, od, samp_shr, alpha);
|
||||
|
||||
if(addpassflag & SCE_PASS_VECTOR)
|
||||
add_transp_speed(rl, od, samp_shr[0].winspeed, alpha, rdrect);
|
||||
if(addpassflag & SCE_PASS_VECTOR)
|
||||
add_transp_speed(rl, od, samp_shr[0].winspeed, alpha, rdrect);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1837,28 +1837,27 @@ static void render_panel_output(void)
|
|||
uiBlockEndAlign(block);
|
||||
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButBitI(block, TOG, R_TOUCH, B_NOP, "Touch", 10, 142, 50, 20, &G.scene->r.mode, 0.0, 0.0, 0, 0, "Create an empty file before rendering each frame, remove if cancelled (and empty)");
|
||||
uiDefButBitI(block, TOG, R_TOUCH, B_NOP, "Touch", 10, 142, 50, 20, &G.scene->r.mode, 0.0, 0.0, 0, 0, "Create an empty file before rendering each frame, remove if cancelled (and empty)");
|
||||
uiDefButBitI(block, TOG, R_NO_OVERWRITE, B_NOP, "No Overwrite", 60, 142, 90, 20, &G.scene->r.mode, 0.0, 0.0, 0, 0, "Skip rendering frames when the file exists (image output only)");
|
||||
uiBlockEndAlign(block);
|
||||
uiDefButBitS(block, TOG, R_BACKBUF, B_NOP,"Backbuf", 160, 142, 80, 20, &G.scene->r.bufflag, 0, 0, 0, 0, "Enable/Disable use of Backbuf image");
|
||||
|
||||
/* SET BUTTON */
|
||||
uiBlockBeginAlign(block);
|
||||
id= (ID *)G.scene->set;
|
||||
IDnames_to_pupstring(&strp, NULL, NULL, &(G.main->scene), id, &(G.buts->menunr));
|
||||
if(strp[0])
|
||||
uiDefButS(block, MENU, B_SETBROWSE, strp, 10, 114, 20, 20, &(G.buts->menunr), 0, 0, 0, 0, "Scene to link as a Set");
|
||||
uiDefButS(block, MENU, B_SETBROWSE, strp, 10, 114, 20, 20, &(G.buts->menunr), 0, 0, 0, 0, "Scene to link as a Set");
|
||||
MEM_freeN(strp);
|
||||
|
||||
if(G.scene->set) {
|
||||
uiSetButLock(1, NULL);
|
||||
uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, B_NOP, "", 31, 120, 100, 20, &(G.scene->set), "Name of the Set");
|
||||
uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, B_NOP, "", 31, 114, 100, 20, &(G.scene->set), "Name of the Set");
|
||||
uiClearButLock();
|
||||
uiDefIconBut(block, BUT, B_CLEARSET, ICON_X, 132, 120, 20, 20, 0, 0, 0, 0, 0, "Remove Set link");
|
||||
uiDefIconBut(block, BUT, B_CLEARSET, ICON_X, 132, 114, 20, 20, 0, 0, 0, 0, 0, "Remove Set link");
|
||||
}
|
||||
uiBlockEndAlign(block);
|
||||
|
||||
uiBlockSetCol(block, TH_BUT_SETTING1);
|
||||
uiDefButBitS(block, TOG, R_BACKBUF, B_NOP,"Backbuf", 10, 89, 80, 20, &G.scene->r.bufflag, 0, 0, 0, 0, "Enable/Disable use of Backbuf image");
|
||||
uiDefButS(block, NUM, B_NOP, "Threads:", 10, 63, 100, 20, &G.scene->r.threads, 1, BLENDER_MAX_THREADS, 0, 0, "Amount of threads for render (takes advantage of multi-core and multi-processor computers)");
|
||||
uiBlockSetCol(block, TH_AUTO);
|
||||
|
||||
|
@ -1866,9 +1865,12 @@ static void render_panel_output(void)
|
|||
for(b=2; b>=0; b--)
|
||||
for(a=0; a<3; a++)
|
||||
uiDefButBitS(block, TOG, 1<<(3*b+a), 800,"", (short)(10+18*a),(short)(10+14*b),16,12, &G.winpos, 0, 0, 0, 0, "Render window placement on screen");
|
||||
uiBlockEndAlign(block);
|
||||
|
||||
uiDefButBitS(block, TOG, R_EXR_TILE_FILE, B_NOP, "Save Buffers", 72, 31, 120, 19, &G.scene->r.scemode, 0.0, 0.0, 0, 0, "Save the tiles for all RenderLayers and used SceneNodes to files, to save memory");
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButBitS(block, TOG, R_EXR_TILE_FILE, B_REDR, "Save Buffers", 72, 31, 120, 19, &G.scene->r.scemode, 0.0, 0.0, 0, 0, "Save the tiles for all RenderLayers and used SceneNodes to files, to save memory");
|
||||
if(G.scene->r.scemode & R_EXR_TILE_FILE)
|
||||
uiDefButBitS(block, TOG, R_FULL_SAMPLE, B_REDR, "FullSample", 192, 31, 118, 19, &G.scene->r.scemode, 0.0, 0.0, 0, 0, "Saves for every OSA sample the entire RenderLayer results");
|
||||
uiBlockEndAlign(block);
|
||||
|
||||
uiDefButS(block, MENU, B_REDR, "Render Display %t|Render Window %x1|Image Editor %x0|Full Screen %x2",
|
||||
72, 10, 120, 19, &G.displaymode, 0.0, (float)R_DISPLAYWIN, 0, 0, "Sets render output display");
|
||||
|
@ -1876,12 +1878,12 @@ static void render_panel_output(void)
|
|||
uiDefButBitS(block, TOG, R_EXTENSION, B_NOP, "Extensions", 205, 10, 105, 19, &G.scene->r.scemode, 0.0, 0.0, 0, 0, "Adds filetype extensions to the filename when rendering animations");
|
||||
|
||||
/* Dither control */
|
||||
uiDefButF(block, NUM,B_DIFF, "Dither:", 205,31,105,19, &G.scene->r.dither_intensity, 0.0, 2.0, 0, 0, "The amount of dithering noise present in the output image (0.0 = no dithering)");
|
||||
uiDefButF(block, NUM,B_DIFF, "Dither:", 10,89,100,19, &G.scene->r.dither_intensity, 0.0, 2.0, 0, 0, "The amount of dithering noise present in the output image (0.0 = no dithering)");
|
||||
|
||||
/* Toon shading buttons */
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButBitI(block, TOG, R_EDGE, B_NOP,"Edge", 100, 89, 70, 20, &G.scene->r.mode, 0, 0, 0, 0, "Enable Toon Edge-enhance");
|
||||
uiDefBlockBut(block, edge_render_menu, NULL, "Edge Settings", 170, 89, 140, 20, "Display Edge settings");
|
||||
uiDefButBitI(block, TOG, R_EDGE, B_NOP,"Edge", 115, 89, 60, 20, &G.scene->r.mode, 0, 0, 0, 0, "Enable Toon Edge-enhance");
|
||||
uiDefBlockBut(block, edge_render_menu, NULL, "Edge Settings", 175, 89, 135, 20, "Display Edge settings");
|
||||
uiBlockEndAlign(block);
|
||||
|
||||
uiBlockBeginAlign(block);
|
||||
|
@ -1957,7 +1959,10 @@ static void render_panel_render(void)
|
|||
#endif /* disable yafray */
|
||||
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButBitI(block, TOG, R_OSA, B_DIFF, "OSA", 369,109,122,20,&G.scene->r.mode, 0, 0, 0, 0, "Enables Oversampling (Anti-aliasing)");
|
||||
if((G.scene->r.scemode & R_FULL_SAMPLE) && (G.scene->r.scemode & R_EXR_TILE_FILE))
|
||||
uiDefButBitI(block, TOG, R_OSA, B_DIFF, "FSA", 369,109,122,20,&G.scene->r.mode, 0, 0, 0, 0, "Saves all samples, then composites, and then merges (for best Anti-aliasing)");
|
||||
else
|
||||
uiDefButBitI(block, TOG, R_OSA, B_DIFF, "OSA", 369,109,122,20,&G.scene->r.mode, 0, 0, 0, 0, "Enables Oversampling (Anti-aliasing)");
|
||||
uiDefButS(block, ROW,B_DIFF,"5", 369,88,29,20,&G.scene->r.osa,2.0,5.0, 0, 0, "Render 5 samples per pixel for smooth edges (Fast)");
|
||||
uiDefButS(block, ROW,B_DIFF,"8", 400,88,29,20,&G.scene->r.osa,2.0,8.0, 0, 0, "Render 8 samples per pixel for smooth edges (Recommended)");
|
||||
uiDefButS(block, ROW,B_DIFF,"11", 431,88,29,20,&G.scene->r.osa,2.0,11.0, 0, 0, "Render 11 samples per pixel for smooth edges (High Quality)");
|
||||
|
|
|
@ -1175,13 +1175,13 @@ void uiblock_image_panel(uiBlock *block, Image **ima_pp, ImageUser *iuser,
|
|||
|
||||
/* fields */
|
||||
uiBlockBeginAlign(block);
|
||||
but= uiDefButBitS(block, TOG, IMA_FIELDS, imagechanged, "Fields", 10, 90, 65, 20, &ima->flag, 0, 0, 0, 0, "Click to enable use of fields in Image");
|
||||
but= uiDefButBitS(block, TOG, IMA_FIELDS, imagechanged, "Fields", 10, 70, 65, 20, &ima->flag, 0, 0, 0, 0, "Click to enable use of fields in Image");
|
||||
uiButSetFunc(but, image_field_test, ima, iuser);
|
||||
uiDefButBitS(block, TOG, IMA_STD_FIELD, B_NOP, "Odd", 75, 90, 45, 20, &ima->flag, 0, 0, 0, 0, "Standard Field Toggle");
|
||||
uiDefButBitS(block, TOG, IMA_STD_FIELD, B_NOP, "Odd", 75, 70, 45, 20, &ima->flag, 0, 0, 0, 0, "Standard Field Toggle");
|
||||
|
||||
uiBlockSetFunc(block, image_reload_cb, ima, iuser);
|
||||
uiDefButBitS(block, TOG, IMA_ANTIALI, B_NOP, "Anti", 10, 70, 45, 20, &ima->flag, 0, 0, 0, 0, "Toggles Image anti-aliasing, only works with solid colors");
|
||||
uiDefButBitS(block, TOG, IMA_DO_PREMUL, imagechanged, "Premul", 55, 70, 65, 20, &ima->flag, 0, 0, 0, 0, "Toggles premultiplying alpha");
|
||||
uiDefButBitS(block, TOG, IMA_ANTIALI, B_NOP, "Anti", 10, 50, 45, 20, &ima->flag, 0, 0, 0, 0, "Toggles Image anti-aliasing, only works with solid colors");
|
||||
uiDefButBitS(block, TOG, IMA_DO_PREMUL, imagechanged, "Premul", 55, 50, 65, 20, &ima->flag, 0, 0, 0, 0, "Toggles premultiplying alpha");
|
||||
uiBlockEndAlign(block);
|
||||
|
||||
if( ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) {
|
||||
|
@ -1189,21 +1189,21 @@ void uiblock_image_panel(uiBlock *block, Image **ima_pp, ImageUser *iuser,
|
|||
|
||||
uiBlockBeginAlign(block);
|
||||
uiBlockSetFunc(block, image_user_change, iuser, NULL);
|
||||
uiDefButBitS(block, TOG, IMA_ANIM_ALWAYS, B_NOP, "Auto Refresh", 120, 90, 190, 20, &iuser->flag, 0, 0, 0, 0, "Always refresh Image on frame changes");
|
||||
uiDefButBitS(block, TOG, IMA_ANIM_ALWAYS, B_NOP, "Auto Refresh", 120, 70, 190, 20, &iuser->flag, 0, 0, 0, 0, "Always refresh Image on frame changes");
|
||||
|
||||
if(ima->anim) {
|
||||
uiDefButI(block, NUM, imagechanged, str, 120, 70,170, 20, &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Sets the number of images of a movie to use");
|
||||
but= uiDefBut(block, BUT, redraw, "<", 290, 70, 20, 20, 0, 0, 0, 0, 0, "Copies number of frames in movie file to Frames: button");
|
||||
uiDefButI(block, NUM, imagechanged, str, 120, 50,170, 20, &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Sets the number of images of a movie to use");
|
||||
but= uiDefBut(block, BUT, redraw, "<", 290, 50, 20, 20, 0, 0, 0, 0, 0, "Copies number of frames in movie file to Frames: button");
|
||||
uiButSetFunc(but, set_frames_cb, ima, iuser);
|
||||
}
|
||||
else
|
||||
uiDefButI(block, NUM, imagechanged, str, 120, 70,190, 20, &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Sets the number of images of a movie to use");
|
||||
uiDefButI(block, NUM, imagechanged, str, 120, 50,190, 20, &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Sets the number of images of a movie to use");
|
||||
|
||||
uiDefButI(block, NUM, imagechanged, "Offs:", 120,50,100,20, &iuser->offset, -MAXFRAMEF, MAXFRAMEF, 0, 0, "Offsets the number of the frame to use in the animation");
|
||||
uiDefButS(block, NUM, imagechanged, "Fie/Ima:", 220,50,90,20, &iuser->fie_ima, 1.0, 200.0, 0, 0, "The number of fields per rendered frame (2 fields is 1 image)");
|
||||
uiDefButI(block, NUM, imagechanged, "Offs:", 120,30,100,20, &iuser->offset, -MAXFRAMEF, MAXFRAMEF, 0, 0, "Offsets the number of the frame to use in the animation");
|
||||
uiDefButS(block, NUM, imagechanged, "Fie/Ima:", 220,30,90,20, &iuser->fie_ima, 1.0, 200.0, 0, 0, "The number of fields per rendered frame (2 fields is 1 image)");
|
||||
|
||||
uiDefButI(block, NUM, imagechanged, "StartFr:", 120,30,100,20, &iuser->sfra, 1.0, MAXFRAMEF, 0, 0, "Sets the global starting frame of the movie");
|
||||
uiDefButS(block, TOG, imagechanged, "Cyclic", 220,30,90,20, &iuser->cycl, 0.0, 1.0, 0, 0, "Cycle the images in the movie");
|
||||
uiDefButI(block, NUM, imagechanged, "StartFr:", 120,10,100,20, &iuser->sfra, 1.0, MAXFRAMEF, 0, 0, "Sets the global starting frame of the movie");
|
||||
uiDefButS(block, TOG, imagechanged, "Cyclic", 220,10,90,20, &iuser->cycl, 0.0, 1.0, 0, 0, "Cycle the images in the movie");
|
||||
|
||||
uiBlockSetFunc(block, NULL, iuser, NULL);
|
||||
}
|
||||
|
@ -1211,9 +1211,9 @@ void uiblock_image_panel(uiBlock *block, Image **ima_pp, ImageUser *iuser,
|
|||
|
||||
uiBlockBeginAlign(block);
|
||||
uiBlockSetFunc(block, image_generated_change_cb, ima, iuser);
|
||||
uiDefButS(block, NUM, imagechanged, "SizeX:", 120,90,100,20, &ima->gen_x, 1.0, 5000.0, 0, 0, "Image size x");
|
||||
uiDefButS(block, NUM, imagechanged, "SizeY:", 220,90,90,20, &ima->gen_y, 1.0, 5000.0, 0, 0, "Image size y");
|
||||
uiDefButS(block, TOG, imagechanged, "UV Test grid",120,70,190,20, &ima->gen_type, 0.0, 1.0, 0, 0, "");
|
||||
uiDefButS(block, NUM, imagechanged, "SizeX:", 120,70,100,20, &ima->gen_x, 1.0, 5000.0, 0, 0, "Image size x");
|
||||
uiDefButS(block, NUM, imagechanged, "SizeY:", 220,70,90,20, &ima->gen_y, 1.0, 5000.0, 0, 0, "Image size y");
|
||||
uiDefButS(block, TOG, imagechanged, "UV Test grid",120,50,190,20, &ima->gen_type, 0.0, 1.0, 0, 0, "");
|
||||
uiBlockSetFunc(block, NULL, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue