diff options
author | Ton Roosendaal <ton@blender.org> | 2006-12-07 17:17:38 +0300 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2006-12-07 17:17:38 +0300 |
commit | 17231f83f37be4890c4067caa72d4957207975b0 (patch) | |
tree | 298c6ca2cbb01b6c546162b070498c6b7f123450 /source | |
parent | 80d1d88ef6dbcae8bfba2bbc7429310bac127652 (diff) |
Work on RenderLayer and Pass control:
Full log:
http://www.blender3d.org/cms/Render_Passes.829.0.html
In short:
- Passes now have option to be excluded from "Combined".
- RenderLayers allow to override Light (Lamp groups) or Material.
- RenderLayers and Passes are in Outliner now, (ab)using Matt's nice
'restriction collumns'. :)
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/intern/node_shaders.c | 4 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 23 | ||||
-rw-r--r-- | source/blender/include/BIF_interface.h | 2 | ||||
-rw-r--r-- | source/blender/include/BIF_outliner.h | 6 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_scene_types.h | 15 | ||||
-rw-r--r-- | source/blender/render/extern/include/RE_pipeline.h | 5 | ||||
-rw-r--r-- | source/blender/render/extern/include/RE_shader_ext.h | 9 | ||||
-rw-r--r-- | source/blender/render/intern/source/convertblender.c | 49 | ||||
-rw-r--r-- | source/blender/render/intern/source/pipeline.c | 19 | ||||
-rw-r--r-- | source/blender/render/intern/source/ray.c | 60 | ||||
-rw-r--r-- | source/blender/render/intern/source/rendercore.c | 4 | ||||
-rw-r--r-- | source/blender/render/intern/source/shadeinput.c | 15 | ||||
-rw-r--r-- | source/blender/render/intern/source/shadeoutput.c | 144 | ||||
-rw-r--r-- | source/blender/src/buttons_scene.c | 73 | ||||
-rw-r--r-- | source/blender/src/buttons_shading.c | 4 | ||||
-rw-r--r-- | source/blender/src/interface.c | 32 | ||||
-rw-r--r-- | source/blender/src/interface_draw.c | 21 | ||||
-rw-r--r-- | source/blender/src/outliner.c | 202 |
18 files changed, 466 insertions, 221 deletions
diff --git a/source/blender/blenkernel/intern/node_shaders.c b/source/blender/blenkernel/intern/node_shaders.c index 49c3c4eff59..cf6a23c4611 100644 --- a/source/blender/blenkernel/intern/node_shaders.c +++ b/source/blender/blenkernel/intern/node_shaders.c @@ -1034,10 +1034,6 @@ void ntreeShaderExecTree(bNodeTree *ntree, ShadeInput *shi, ShadeResult *shr) ntreeExecTree(ntree, &scd, shi->thread); /* threads */ /* better not allow negative for now */ - if(shr->spec[0]<0.0f) shr->spec[0]= 0.0f; - if(shr->spec[1]<0.0f) shr->spec[1]= 0.0f; - if(shr->spec[2]<0.0f) shr->spec[2]= 0.0f; - if(shr->combined[0]<0.0f) shr->combined[0]= 0.0f; if(shr->combined[1]<0.0f) shr->combined[1]= 0.0f; if(shr->combined[2]<0.0f) shr->combined[2]= 0.0f; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 6d41ffcdcd3..27394e3d0ea 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -2993,6 +2993,7 @@ static void lib_link_scene(FileData *fd, Main *main) Base *base, *next; Editing *ed; Sequence *seq; + SceneRenderLayer *srl; int a; sce= main->scene.first; @@ -3016,8 +3017,7 @@ static void lib_link_scene(FileData *fd, Main *main) mtex->tex= newlibadr_us(fd, sce->id.lib, mtex->tex); } - base= sce->base.first; - while(base) { + for(base= sce->base.first; base; base= next) { next= base->next; /* base->object= newlibadr_us(fd, sce->id.lib, base->object); */ @@ -3032,7 +3032,6 @@ static void lib_link_scene(FileData *fd, Main *main) if(base==sce->basact) sce->basact= 0; MEM_freeN(base); } - base= next; } ed= sce->ed; @@ -3057,7 +3056,12 @@ static void lib_link_scene(FileData *fd, Main *main) if(sce->nodetree) lib_link_ntree(fd, &sce->id, sce->nodetree); - + + for(srl= sce->r.layers.first; srl; srl= srl->next) { + srl->mat_override= newlibadr_us(fd, sce->id.lib, srl->mat_override); + srl->light_override= newlibadr_us(fd, sce->id.lib, srl->light_override); + } + sce->id.flag -= LIB_NEEDLINK; } @@ -6830,17 +6834,22 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob) static void expand_scene(FileData *fd, Main *mainvar, Scene *sce) { Base *base; + SceneRenderLayer *srl; - base= sce->base.first; - while(base) { + for(base= sce->base.first; base; base= base->next) { expand_doit(fd, mainvar, base->object); - base= base->next; } expand_doit(fd, mainvar, sce->camera); expand_doit(fd, mainvar, sce->world); if(sce->nodetree) expand_nodetree(fd, mainvar, sce->nodetree); + + for(srl= sce->r.layers.first; srl; srl= srl->next) { + expand_doit(fd, mainvar, srl->mat_override); + expand_doit(fd, mainvar, srl->light_override); + } + } static void expand_camera(FileData *fd, Main *mainvar, Camera *ca) diff --git a/source/blender/include/BIF_interface.h b/source/blender/include/BIF_interface.h index 0e944857409..9b7078d0476 100644 --- a/source/blender/include/BIF_interface.h +++ b/source/blender/include/BIF_interface.h @@ -164,7 +164,7 @@ struct ScrArea; #define BUT_NORMAL (31<<9) #define BUT_CURVE (32<<9) #define BUT_TOGDUAL (33<<9) - +#define ICONTOGN (34<<9) #define BUTTYPE (63<<9) diff --git a/source/blender/include/BIF_outliner.h b/source/blender/include/BIF_outliner.h index dc71d02970c..34ed7950421 100644 --- a/source/blender/include/BIF_outliner.h +++ b/source/blender/include/BIF_outliner.h @@ -72,6 +72,12 @@ typedef struct TreeElement { #define TSE_VERSE_GEOM_NODE 17 /*#endif*/ #define TSE_PROXY 18 +#define TSE_R_LAYER_BASE 19 +#define TSE_R_LAYER 20 +#define TSE_R_PASS 21 +#define TSE_LINKED_MAT 22 + /* NOTE, is used for light group */ +#define TSE_LINKED_LAMP 23 /* outliner search flags */ #define OL_FIND 0 diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 0102479eec3..f57e853cecd 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -115,10 +115,14 @@ typedef struct SceneRenderLayer { struct SceneRenderLayer *next, *prev; char name[32]; - struct Scene *scene; /* unused still */ + + struct Material *mat_override; + struct Group *light_override; + unsigned int lay; /* scene->lay itself has priority over this */ - short layflag; - short passflag; + int layflag; + int passflag; /* pass_xor has to be after passflag */ + int pass_xor; } SceneRenderLayer; /* srl->layflag */ @@ -128,8 +132,11 @@ typedef struct SceneRenderLayer { #define SCE_LAY_EDGE 8 #define SCE_LAY_SKY 16 #define SCE_LAY_STRAND 32 + /* flags between 32 and 0x8000 are set to 1 already, for future options */ #define SCE_LAY_ALL_Z 0x8000 +#define SCE_LAY_XOR 0x10000 +#define SCE_LAY_DISABLE 0x20000 /* srl->passflag */ #define SCE_PASS_COMBINED 1 @@ -144,6 +151,8 @@ typedef struct SceneRenderLayer { #define SCE_PASS_VECTOR 512 #define SCE_PASS_REFRACT 1024 #define SCE_PASS_INDEXOB 2048 +#define SCE_PASS_RADIO 4096 + /* note, passflag is treestore element 'nr' in outliner, short still... */ typedef struct RenderData { struct AviCodecData *avicodecdata; diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h index 0a07dd4cdac..22b623816ab 100644 --- a/source/blender/render/extern/include/RE_pipeline.h +++ b/source/blender/render/extern/include/RE_pipeline.h @@ -70,7 +70,10 @@ typedef struct RenderLayer { /* copy of RenderData */ char name[RE_MAXNAME]; unsigned int lay; - int layflag, passflag; + int layflag, passflag, pass_xor; + + struct Material *mat_override; + struct Group *light_override; float *rectf; /* 4 float, standard rgba buffer */ float *acolrect; /* 4 float, optional transparent buffer, needs storage for display updates */ diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h index efe19a6b6ec..18fabc91036 100644 --- a/source/blender/render/extern/include/RE_shader_ext.h +++ b/source/blender/render/extern/include/RE_shader_ext.h @@ -48,14 +48,14 @@ typedef struct ShadeResult float combined[4]; float col[4]; float alpha; - float diff[3]; /* includes ramps, shadow, etc */ - float diff_raw[3]; /* pure diffuse, no shadow no ramps */ + float diff[3]; /* no ramps, shadow, etc */ float spec[3]; float shad[3]; float ao[3]; float refl[3]; float refr[3]; float nor[3]; + float rad[3]; float winspeed[4]; } ShadeResult; @@ -139,8 +139,9 @@ typedef struct ShadeInput short do_preview; /* for nodes, in previewrender */ short thread, sample; /* sample: ShadeSample array index */ unsigned int lay; - int layflag, passflag; - + int layflag, passflag, combinedflag; + struct Group *light_override; + struct Material *mat_override; } ShadeInput; diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 6268971bb79..0fba6916c36 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -3115,31 +3115,48 @@ static void check_non_flat_quads(Render *re) } } -static void set_material_lightgroups(Render *re) +static void add_lightgroup(Render *re, Group *group) { GroupObject *go, *gol; - Material *ma; /* it's a bit too many loops in loops... but will survive */ - for(ma= G.main->mat.first; ma; ma=ma->id.next) { - if(ma->group) { - for(go= ma->group->gobject.first; go; go= go->next) { - go->lampren= NULL; - if(go->ob && go->ob->type==OB_LAMP) { - for(gol= re->lights.first; gol; gol= gol->next) { - if(gol->ob==go->ob) { - go->lampren= gol->lampren; - break; - } - } - if(go->lampren==NULL) - go->lampren= add_render_lamp(re, go->ob); + for(go= group->gobject.first; go; go= go->next) { + go->lampren= NULL; + if(go->ob && go->ob->type==OB_LAMP) { + for(gol= re->lights.first; gol; gol= gol->next) { + if(gol->ob==go->ob) { + go->lampren= gol->lampren; + break; } } + if(go->lampren==NULL) + go->lampren= add_render_lamp(re, go->ob); } } } +static void set_material_lightgroups(Render *re) +{ + Material *ma; + + /* it's a bit too many loops in loops... but will survive */ + /* hola! materials not in use...? */ + for(ma= G.main->mat.first; ma; ma=ma->id.next) { + if(ma->group) + add_lightgroup(re, ma->group); + } +} + +static void set_renderlayer_lightgroups(Render *re, Scene *sce) +{ + SceneRenderLayer *srl; + + for(srl= sce->r.layers.first; srl; srl= srl->next) { + if(srl->light_override) + add_lightgroup(re, srl->light_override); + } +} + void init_render_world(Render *re) { int a; @@ -3367,6 +3384,8 @@ void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view) sort_halos(re); set_material_lightgroups(re); + for(sce= re->scene; sce; sce= sce->set) + set_renderlayer_lightgroups(re, sce); slurph_opt= 1; diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index a4fd1168d22..ad33e0e2a4b 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -411,6 +411,8 @@ static RenderResult *new_render_result(Render *re, rcti *partrct, int crop, int if((re->r.scemode & R_SINGLE_LAYER) && nr!=re->r.actlay) continue; + if(srl->layflag & SCE_LAY_DISABLE) + continue; rl= MEM_callocN(sizeof(RenderLayer), "new render layer"); BLI_addtail(&rr->layers, rl); @@ -419,6 +421,9 @@ static RenderResult *new_render_result(Render *re, rcti *partrct, int crop, int rl->lay= srl->lay; rl->layflag= srl->layflag; rl->passflag= srl->passflag; + rl->pass_xor= srl->pass_xor; + rl->light_override= srl->light_override; + rl->mat_override= srl->mat_override; if(rr->exrhandle) { IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.R"); @@ -484,8 +489,9 @@ static int render_scene_needs_vector(Render *re) SceneRenderLayer *srl; for(srl= re->scene->r.layers.first; srl; srl= srl->next) - if(srl->passflag & SCE_PASS_VECTOR) - return 1; + if(!(srl->layflag & SCE_LAY_DISABLE)) + if(srl->passflag & SCE_PASS_VECTOR) + return 1; } return 0; } @@ -1788,6 +1794,7 @@ static void do_render_all_options(Render *re) static int is_rendering_allowed(Render *re) { + SceneRenderLayer *srl; /* forbidden combinations */ if(re->r.mode & R_PANORAMA) { @@ -1856,6 +1863,14 @@ static int is_rendering_allowed(Render *re) return 0; } } + /* layer flag tests */ + for(srl= re->scene->r.layers.first; srl; srl= srl->next) + if(!(srl->layflag & SCE_LAY_DISABLE)) + break; + if(srl==NULL) { + re->error("All RenderLayers are disabled"); + return 0; + } return 1; } diff --git a/source/blender/render/intern/source/ray.c b/source/blender/render/intern/source/ray.c index 71c116e0c9b..554fba9cf38 100644 --- a/source/blender/render/intern/source/ray.c +++ b/source/blender/render/intern/source/ray.c @@ -1601,13 +1601,16 @@ static void traceray(ShadeInput *origshi, short depth, float *start, float *vec, shi.mask= origshi->mask; shi.osatex= origshi->osatex; - shi.depth= 1; // only now to indicate tracing + shi.depth= 1; /* only used to indicate tracing */ shi.thread= origshi->thread; shi.xs= origshi->xs; shi.ys= origshi->ys; shi.lay= origshi->lay; - shi.passflag= origshi->passflag; + shi.passflag= SCE_PASS_COMBINED; /* result of tracing needs no pass info */ + shi.combinedflag= 0xFFFFFF; /* ray trace does all options */ shi.do_preview= 0; + shi.light_override= origshi->light_override; + shi.mat_override= origshi->mat_override; memset(&shr, 0, sizeof(ShadeResult)); @@ -1838,12 +1841,9 @@ void ray_trace(ShadeInput *shi, ShadeResult *shr) do_mir= ((shi->mat->mode & MA_RAYMIRROR) && shi->ray_mirror!=0.0f); vlr= shi->vlr; - /* raytrace likes to separate the spec color */ - VECSUB(shr->diff, shr->combined, shr->spec); - if(do_tra) { float refract[3]; - float olddiff[3]; + float combined[3]; tracol[3]= shr->alpha; @@ -1856,15 +1856,18 @@ void ray_trace(ShadeInput *shi, ShadeResult *shr) fb= 1.0f+ shi->mat->filter*(shi->b-1.0f); /* for refract pass */ - VECCOPY(olddiff, shr->diff); + VECCOPY(combined, shr->combined); - shr->diff[0]= f*shr->diff[0] + fr*tracol[0]; - shr->diff[1]= f*shr->diff[1] + fr*tracol[1]; - shr->diff[2]= f*shr->diff[2] + fr*tracol[2]; + combined[0]= f*combined[0] + fr*tracol[0]; + combined[1]= f*combined[1] + fr*tracol[1]; + combined[2]= f*combined[2] + fr*tracol[2]; if(shi->passflag & SCE_PASS_REFRACT) - VECSUB(shr->refr, shr->diff, olddiff); - + VECSUB(shr->refr, combined, shr->combined); + + if(shi->combinedflag & SCE_PASS_REFRACT) + VECCOPY(shr->combined, combined); + shr->alpha= tracol[3]; } @@ -1872,6 +1875,11 @@ void ray_trace(ShadeInput *shi, ShadeResult *shr) i= shi->ray_mirror*fresnel_fac(shi->view, shi->vn, shi->mat->fresnel_mir_i, shi->mat->fresnel_mir); if(i!=0.0f) { + float diff[3]; + + /* raytrace mirror likes to separate the spec color */ + VECSUB(diff, shr->combined, shr->spec); + fr= i*shi->mirr; fg= i*shi->mirg; fb= i*shi->mirb; @@ -1885,23 +1893,27 @@ void ray_trace(ShadeInput *shi, ShadeResult *shr) if(shi->passflag & SCE_PASS_REFLECT) { /* mirror pass is not blocked out with spec */ - shr->refl[0]= fr*mircol[0] - fr*shr->diff[0]; - shr->refl[1]= fg*mircol[1] - fg*shr->diff[1]; - shr->refl[2]= fb*mircol[2] - fb*shr->diff[2]; + shr->refl[0]= fr*mircol[0] - fr*diff[0]; + shr->refl[1]= fg*mircol[1] - fg*diff[1]; + shr->refl[2]= fb*mircol[2] - fb*diff[2]; } - f= fr*(1.0f-shr->spec[0]); f1= 1.0f-i; - shr->diff[0]= f*mircol[0] + f1*shr->diff[0]; - f= fg*(1.0f-shr->spec[1]); f1= 1.0f-i; - shr->diff[1]= f*mircol[1] + f1*shr->diff[1]; + if(shi->combinedflag & SCE_PASS_REFLECT) { + + f= fr*(1.0f-shr->spec[0]); f1= 1.0f-i; + diff[0]= f*mircol[0] + f1*diff[0]; + + f= fg*(1.0f-shr->spec[1]); f1= 1.0f-i; + diff[1]= f*mircol[1] + f1*diff[1]; + + f= fb*(1.0f-shr->spec[2]); f1= 1.0f-i; + diff[2]= f*mircol[2] + f1*diff[2]; - f= fb*(1.0f-shr->spec[2]); f1= 1.0f-i; - shr->diff[2]= f*mircol[2] + f1*shr->diff[2]; + /* put back together */ + VECADD(shr->combined, diff, shr->spec); + } } } - - /* put back together */ - VECADD(shr->combined, shr->diff, shr->spec); } /* color 'shadfac' passes through 'col' with alpha and filter */ diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index 019113959ef..20718941aad 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -378,7 +378,7 @@ static void add_filt_passes(RenderLayer *rl, int curmask, int rectx, int offset, pixsize= 4; break; case SCE_PASS_DIFFUSE: - col= shr->diff_raw; + col= shr->diff; break; case SCE_PASS_SPEC: col= shr->spec; @@ -442,7 +442,7 @@ static void add_passes(RenderLayer *rl, int offset, ShadeInput *shi, ShadeResult pixsize= 4; break; case SCE_PASS_DIFFUSE: - col= shr->diff_raw; + col= shr->diff; break; case SCE_PASS_SPEC: col= shr->spec; diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c index a5b4a60861f..a15e0d031e8 100644 --- a/source/blender/render/intern/source/shadeinput.c +++ b/source/blender/render/intern/source/shadeinput.c @@ -108,7 +108,7 @@ void shade_material_loop(ShadeInput *shi, ShadeResult *shr) if(shi->passflag & SCE_PASS_SPEC) VECADDISFAC(shr->spec, shr_t.spec, fac); if(shi->passflag & SCE_PASS_DIFFUSE) - VECADDISFAC(shr->diff_raw, shr_t.diff_raw, fac); + VECADDISFAC(shr->diff, shr_t.diff, fac); if(shi->passflag & SCE_PASS_SHADOW) VECADDISFAC(shr->shad, shr_t.shad, fac); @@ -221,7 +221,9 @@ void shade_input_set_triangle_i(ShadeInput *shi, VlakRen *vlr, short i1, short i shi->i2= i2; shi->i3= i3; - shi->mat= vlr->mat; + /* note, shi->mat is set in node shaders */ + shi->mat= shi->mat_override?shi->mat_override:vlr->mat; + shi->osatex= (shi->mat->texco & TEXCO_OSA); shi->mode= shi->mat->mode_l; /* or-ed result for all nodes */ @@ -832,7 +834,7 @@ void shade_input_set_shade_texco(ShadeInput *shi) /* ****************** ShadeSample ************************************** */ - +/* initialize per part, not per pixel! */ static void shade_input_initialize(ShadeInput *shi, RenderPart *pa, RenderLayer *rl, int sample) { @@ -844,10 +846,14 @@ static void shade_input_initialize(ShadeInput *shi, RenderPart *pa, RenderLayer shi->lay= rl->lay; shi->layflag= rl->layflag; shi->passflag= rl->passflag; + shi->combinedflag= ~rl->pass_xor; + shi->mat_override= rl->mat_override; + shi->light_override= rl->light_override; /* note shi.depth==0 means first hit, not raytracing */ } +/* initialize per part, not per pixel! */ void shade_sample_initialize(ShadeSample *ssamp, RenderPart *pa, RenderLayer *rl) { int a, tot; @@ -886,6 +892,9 @@ void shade_samples_do_shadow(ShadeSample *ssamp) if(!(shi->mode & MA_SHADOW) || (shi->mode & MA_SHLESS)) continue; + if(!( (shi->combinedflag | shi->passflag) & SCE_PASS_SHADOW)) + continue; + visifac= lamp_get_visibility(lar, shi->co, lv, &lampdist); if(visifac==0.0f) continue; diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c index 1d3bcd4eac3..dd2cad02dc0 100644 --- a/source/blender/render/intern/source/shadeoutput.c +++ b/source/blender/render/intern/source/shadeoutput.c @@ -54,6 +54,16 @@ extern struct Render R; /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +static ListBase *get_lights(ShadeInput *shi) +{ + + if(shi->light_override) + return &shi->light_override->gobject; + else if(shi->mat->group) + return &shi->mat->group->gobject; + else + return &R.lights; +} #if 0 static void fogcolor(float *colf, float *rco, float *view) @@ -323,13 +333,14 @@ static void spothalo(struct LampRen *lar, ShadeInput *shi, float *intens) void renderspothalo(ShadeInput *shi, float *col, float alpha) { + ListBase *lights= get_lights(shi); GroupObject *go; LampRen *lar; float i; if(alpha==0.0f) return; - - for(go=R.lights.first; go; go= go->next) { + + for(go=lights->first; go; go= go->next) { lar= go->lampren; if(lar->type==LA_SPOT && (lar->mode & LA_HALO) && lar->haint>0) { @@ -1099,7 +1110,7 @@ float lamp_get_visibility(LampRen *lar, float *co, float *lv, float *dist) } } -/* function returns diff, spec and raw diff */ +/* function returns raw diff, spec and full shadowed diff in the 'shad' pass */ static void shade_one_light(LampRen *lar, ShadeInput *shi, ShadeResult *shr, int passflag) { Material *ma= shi->mat; @@ -1226,15 +1237,12 @@ static void shade_one_light(LampRen *lar, ShadeInput *shi, ShadeResult *shr, int if(lar->mode & LA_ONLYSHADOW) { shadfac[3]= i*lar->energy*(1.0f-shadfac[3]); - shr->diff[0] -= shadfac[3]*shi->r; - shr->diff[1] -= shadfac[3]*shi->g; - shr->diff[2] -= shadfac[3]*shi->b; + shr->shad[0] -= shadfac[3]*shi->r; + shr->shad[1] -= shadfac[3]*shi->g; + shr->shad[2] -= shadfac[3]*shi->b; return; } - if(!(passflag & (SCE_PASS_DIFFUSE|SCE_PASS_SHADOW))) - if(shadfac[3]==0.0f) return; - i*= shadfac[3]; } } @@ -1244,15 +1252,19 @@ static void shade_one_light(LampRen *lar, ShadeInput *shi, ShadeResult *shr, int if(!(lar->mode & LA_NO_DIFF)) { if(i>0.0f) { if(ma->mode & MA_SHADOW_TRA) - add_to_diffuse(shr->diff, shi, is, i*shadfac[0]*lacol[0], i*shadfac[1]*lacol[1], i*shadfac[2]*lacol[2]); + add_to_diffuse(shr->shad, shi, is, i*shadfac[0]*lacol[0], i*shadfac[1]*lacol[1], i*shadfac[2]*lacol[2]); else - add_to_diffuse(shr->diff, shi, is, i*lacol[0], i*lacol[1], i*lacol[2]); + add_to_diffuse(shr->shad, shi, is, i*lacol[0], i*lacol[1], i*lacol[2]); } - if(i_noshad>0.0f && (passflag & (SCE_PASS_DIFFUSE|SCE_PASS_SHADOW))) { - if(ma->mode & MA_SHADOW_TRA) - add_to_diffuse(shr->diff_raw, shi, is, i_noshad*shadfac[0]*lacol[0], i_noshad*shadfac[1]*lacol[1], i_noshad*shadfac[2]*lacol[2]); + if(i_noshad>0.0f) { + if(passflag & (SCE_PASS_DIFFUSE|SCE_PASS_SHADOW)) { + if(ma->mode & MA_SHADOW_TRA) + add_to_diffuse(shr->diff, shi, is, i_noshad*shadfac[0]*lacol[0], i_noshad*shadfac[1]*lacol[1], i_noshad*shadfac[2]*lacol[2]); + else + add_to_diffuse(shr->diff, shi, is, i_noshad*lacol[0], i_noshad*lacol[1], i_noshad*lacol[2]); + } else - add_to_diffuse(shr->diff_raw, shi, is, i_noshad*lacol[0], i_noshad*lacol[1], i_noshad*lacol[2]); + VECCOPY(shr->diff, shr->shad); } } @@ -1323,7 +1335,7 @@ static void shade_lamp_loop_only_shadow(ShadeInput *shi, ShadeResult *shr) { if(R.r.mode & R_SHADOW) { - ListBase *lights; + ListBase *lights= get_lights(shi); LampRen *lar; GroupObject *go; float inpr, lv[3]; @@ -1332,13 +1344,7 @@ static void shade_lamp_loop_only_shadow(ShadeInput *shi, ShadeResult *shr) vn= shi->vn; view= shi->view; - - /* lights */ - if(shi->mat->group) - lights= &shi->mat->group->gobject; - else - lights= &R.lights; - + accum= ir= 0.0f; for(go=lights->first; go; go= go->next) { @@ -1391,6 +1397,13 @@ static void shade_lamp_loop_only_shadow(ShadeInput *shi, ShadeResult *shr) } } +static void wrld_exposure_correct(float *diff) +{ + diff[0]= R.wrld.linfac*(1.0f-exp( diff[0]*R.wrld.logfac) ); + diff[1]= R.wrld.linfac*(1.0f-exp( diff[1]*R.wrld.logfac) ); + diff[2]= R.wrld.linfac*(1.0f-exp( diff[2]*R.wrld.logfac) ); +} + void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) { Material *ma= shi->mat; @@ -1456,15 +1469,9 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) /* lighting pass */ if(passflag & (SCE_PASS_COMBINED|SCE_PASS_DIFFUSE|SCE_PASS_SPEC|SCE_PASS_SHADOW)) { GroupObject *go; - ListBase *lights; + ListBase *lights= get_lights(shi); LampRen *lar; - /* lights */ - if(ma->group) - lights= &ma->group->gobject; - else - lights= &R.lights; - for(go=lights->first; go; go= go->next) { lar= go->lampren; if(lar==NULL) continue; @@ -1476,31 +1483,31 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) if(lar->mode & LA_LAYER) if((lar->lay & vlr->lay)==0) continue; if((lar->lay & shi->lay)==0) continue; - /* accumulates in shr->diff and shr->spec and shr->diff_raw (diffuse without shadow!) */ + /* accumulates in shr->diff and shr->spec and shr->shad (diffuse with shadow!) */ shade_one_light(lar, shi, shr, passflag); } + if(shi->combinedflag & SCE_PASS_SHADOW) + VECCOPY(shr->combined, shr->shad) /* note, no ';' ! */ + else + VECCOPY(shr->combined, shr->diff); + /* calculate shadow pass, we use a multiplication mask */ if(passflag & SCE_PASS_SHADOW) { - if(shr->diff_raw[0]!=0.0f) shr->shad[0]= shr->diff[0]/shr->diff_raw[0]; - if(shr->diff_raw[1]!=0.0f) shr->shad[1]= shr->diff[1]/shr->diff_raw[1]; - if(shr->diff_raw[2]!=0.0f) shr->shad[2]= shr->diff[2]/shr->diff_raw[2]; + if(shr->diff[0]!=0.0f) shr->shad[0]= shr->shad[0]/shr->diff[0]; + if(shr->diff[1]!=0.0f) shr->shad[1]= shr->shad[1]/shr->diff[1]; + if(shr->diff[2]!=0.0f) shr->shad[2]= shr->shad[2]/shr->diff[2]; } /* exposure correction */ if(R.wrld.exp!=0.0f || R.wrld.range!=1.0f) { - shr->diff[0]= R.wrld.linfac*(1.0f-exp( shr->diff[0]*R.wrld.logfac) ); - shr->diff[1]= R.wrld.linfac*(1.0f-exp( shr->diff[1]*R.wrld.logfac) ); - shr->diff[2]= R.wrld.linfac*(1.0f-exp( shr->diff[2]*R.wrld.logfac) ); - - shr->spec[0]= R.wrld.linfac*(1.0f-exp( shr->spec[0]*R.wrld.logfac) ); - shr->spec[1]= R.wrld.linfac*(1.0f-exp( shr->spec[1]*R.wrld.logfac) ); - shr->spec[2]= R.wrld.linfac*(1.0f-exp( shr->spec[2]*R.wrld.logfac) ); + wrld_exposure_correct(shr->diff); + wrld_exposure_correct(shr->spec); } } /* alpha in end, spec can influence it */ - if(passflag & (SCE_PASS_COMBINED|SCE_PASS_RGBA)) { + if(passflag & (SCE_PASS_COMBINED)) { if(ma->fresnel_tra!=0.0f) shi->alpha*= fresnel_fac(shi->view, shi->vn, ma->fresnel_tra_i, ma->fresnel_tra); @@ -1516,44 +1523,47 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) } shr->alpha= shi->alpha; - /* now stuff everything in shr->diff: ambient, AO, radio, ramps, exposure */ - shr->diff[0]+= shi->ambr + shi->r*shi->amb*shi->rad[0]; - shr->diff[1]+= shi->ambg + shi->g*shi->amb*shi->rad[1]; - shr->diff[2]+= shi->ambb + shi->b*shi->amb*shi->rad[2]; + /* from now stuff everything in shr->combined: ambient, AO, radio, ramps, exposure */ + shr->combined[0]+= shi->ambr + shi->r*shi->amb*shi->rad[0]; + shr->combined[1]+= shi->ambg + shi->g*shi->amb*shi->rad[1]; + shr->combined[2]+= shi->ambb + shi->b*shi->amb*shi->rad[2]; + /* add AO in combined? */ if(R.wrld.mode & WO_AMB_OCC) { - float aodiff[3]; - ambient_occlusion_to_diffuse(shi, aodiff); - - shr->diff[0] += shi->r*aodiff[0]; - shr->diff[1] += shi->g*aodiff[1]; - shr->diff[2] += shi->b*aodiff[2]; + if(shi->combinedflag & SCE_PASS_AO) { + float aodiff[3]; + ambient_occlusion_to_diffuse(shi, aodiff); + + shr->combined[0] += shi->r*aodiff[0]; + shr->combined[1] += shi->g*aodiff[1]; + shr->combined[2] += shi->b*aodiff[2]; + } } - if(ma->mode & MA_RAMP_COL) ramp_diffuse_result(shr->diff, shi); + if(ma->mode & MA_RAMP_COL) ramp_diffuse_result(shr->combined, shi); if(ma->mode & MA_RAMP_SPEC) ramp_spec_result(shr->spec, shr->spec+1, shr->spec+2, shi); /* refcol is for envmap only */ if(shi->refcol[0]!=0.0f) { - float olddiff[3]; + float result[3]; - VECCOPY(olddiff, shr->diff); - - shr->diff[0]= shi->mirr*shi->refcol[1] + (1.0f - shi->mirr*shi->refcol[0])*shr->diff[0]; - shr->diff[1]= shi->mirg*shi->refcol[2] + (1.0f - shi->mirg*shi->refcol[0])*shr->diff[1]; - shr->diff[2]= shi->mirb*shi->refcol[3] + (1.0f - shi->mirb*shi->refcol[0])*shr->diff[2]; + result[0]= shi->mirr*shi->refcol[1] + (1.0f - shi->mirr*shi->refcol[0])*shr->combined[0]; + result[1]= shi->mirg*shi->refcol[2] + (1.0f - shi->mirg*shi->refcol[0])*shr->combined[1]; + result[2]= shi->mirb*shi->refcol[3] + (1.0f - shi->mirb*shi->refcol[0])*shr->combined[2]; if(passflag & SCE_PASS_REFLECT) - VECSUB(shr->refl, shr->diff, olddiff); + VECSUB(shr->refl, result, shr->combined); + + if(shi->combinedflag & SCE_PASS_REFLECT) + VECCOPY(shr->combined, result); + } + + /* and add spec */ + if(shi->combinedflag & SCE_PASS_SPEC) + VECADD(shr->combined, shr->combined, shr->spec); - /* XXX SOLVE */ - if(passflag & SCE_PASS_COMBINED) { - shr->combined[0]= shr->diff[0]+ shr->spec[0]; - shr->combined[1]= shr->diff[1]+ shr->spec[1]; - shr->combined[2]= shr->diff[2]+ shr->spec[2]; - shr->combined[3]= shr->alpha; - } + shr->combined[3]= shr->alpha; } diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c index e66c674993f..fd7e357df2c 100644 --- a/source/blender/src/buttons_scene.c +++ b/source/blender/src/buttons_scene.c @@ -834,9 +834,10 @@ void do_render_panels(unsigned short event) case B_SET_PASS: if(G.scene->nodetree) { ntreeCompositForceHidden(G.scene->nodetree); - allqueue(REDRAWBUTSSCENE, 0); allqueue(REDRAWNODE, 0); } + allqueue(REDRAWBUTSSCENE, 0); + allqueue(REDRAWOOPS, 0); } } @@ -1167,7 +1168,7 @@ static void render_panel_output(void) if(G.scene->set) { uiSetButLock(1, NULL); - uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 0, "", 31, 120, 100, 20, &(G.scene->set), "Name of the Set"); + uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, B_NOP, "", 31, 120, 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"); } @@ -1273,7 +1274,7 @@ static void render_panel_render(void) uiDefButS(block, MENU, B_DIFF,str, 565,34,60,20, &G.scene->r.filtertype, 0, 0, 0, 0, "Set sampling filter for antialiasing"); uiDefButF(block, NUM,B_DIFF,"", 627,34,60,20,&G.scene->r.gauss,0.5, 1.5, 10, 2, "Sets the filter size"); - uiDefButBitI(block, TOG, R_BORDER, REDRAWVIEWCAM, "Border", 565,13,60,20, &G.scene->r.mode, 0, 0, 0, 0, "Render a small cut-out of the image"); + uiDefButBitI(block, TOG, R_BORDER, REDRAWVIEWCAM, "Border", 565,13,122,20, &G.scene->r.mode, 0, 0, 0, 0, "Render a small cut-out of the image"); uiBlockEndAlign(block); } @@ -1732,6 +1733,7 @@ static void rename_scene_layer_func(void *srl_v, void *unused_v) } } allqueue(REDRAWBUTSSCENE, 0); + allqueue(REDRAWOOPS, 0); allqueue(REDRAWNODE, 0); } @@ -1745,7 +1747,10 @@ static char *scene_layer_menu(void) strcpy(str, "ADD NEW %x32767"); a= strlen(str); for(nr=0, srl= G.scene->r.layers.first; srl; srl= srl->next, nr++) { - a+= sprintf(str+a, "|%s %%x%d", srl->name, nr); + if(srl->layflag & SCE_LAY_DISABLE) + a+= sprintf(str+a, "|%s %%i%d %%x%d", srl->name, ICON_BLANK1, nr); + else + a+= sprintf(str+a, "|%s %%i%d %%x%d", srl->name, ICON_CHECKBOX_HLT, nr); } return str; @@ -1798,53 +1803,55 @@ static void render_panel_layers(void) /* first, as reminder, the scene layers */ uiDefBut(block, LABEL, 0, "Scene:", 10,170,100,20, NULL, 0, 0, 0, 0, ""); + draw_3d_layer_buttons(block, &G.scene->lay, 130, 170, 35, 30); - draw_3d_layer_buttons(block, &G.scene->lay, 130, 170, 35, 30); - - /* layer menu, name, delete button */ + /* layer disable, menu, name, delete button */ uiBlockBeginAlign(block); + uiDefIconButBitI(block, ICONTOGN, SCE_LAY_DISABLE, B_REDR, ICON_CHECKBOX_HLT-1, 10, 145, 20, 20, &srl->layflag, 0.0, 0.0, 0, 0, "Disable or enable this RenderLayer"); strp= scene_layer_menu(); - uiDefButS(block, MENU, B_ADD_RENDERLAYER, strp, 10,130,23,20, &(G.scene->r.actlay), 0, 0, 0, 0, "Choose Active Render Layer"); + uiDefButS(block, MENU, B_ADD_RENDERLAYER, strp, 30,145,23,20, &(G.scene->r.actlay), 0, 0, 0, 0, "Choose Active Render Layer"); MEM_freeN(strp); - bt= uiDefBut(block, TEX, REDRAWNODE, "", 33,130,192,20, srl->name, 0.0, 31.0, 0, 0, ""); + bt= uiDefBut(block, TEX, REDRAWNODE, "", 53,145,172,20, srl->name, 0.0, 31.0, 0, 0, ""); uiButSetFunc(bt, rename_scene_layer_func, srl, NULL); - uiDefButBitS(block, TOG, R_SINGLE_LAYER, B_NOP, "Single", 230,130,60,20, &G.scene->r.scemode, 0, 0, 0, 0, "Only render this layer"); - bt=uiDefIconBut(block, BUT, B_NOP, ICON_X, 285, 130, 25, 20, 0, 0, 0, 0, 0, "Deletes current Render Layer"); + uiDefButBitS(block, TOG, R_SINGLE_LAYER, B_NOP, "Single", 230,145,60,20, &G.scene->r.scemode, 0, 0, 0, 0, "Only render this layer"); + bt=uiDefIconBut(block, BUT, B_NOP, ICON_X, 285, 145, 25, 20, 0, 0, 0, 0, 0, "Deletes current Render Layer"); uiButSetFunc(bt, delete_scene_layer_func, srl, (void *)(long)G.scene->r.actlay); uiBlockEndAlign(block); /* RenderLayer visible-layers */ - uiDefBut(block, LABEL, 0, "Layer:", 10,95,100,20, NULL, 0, 0, 0, 0, ""); - draw_3d_layer_buttons(block, &srl->lay, 130, 95, 35, 30); + uiDefBut(block, LABEL, 0, "Layer:", 10,110,100,20, NULL, 0, 0, 0, 0, ""); + draw_3d_layer_buttons(block, &srl->lay, 130,110, 35, 30); uiBlockBeginAlign(block); - uiDefButBitS(block, TOG, SCE_LAY_ALL_Z, B_NOP,"AllZ", 10, 70, 40, 20, &srl->layflag, 0, 0, 0, 0, "Fill in Z values for all not-rendered faces, for masking"); + uiDefButBitI(block, TOG, SCE_LAY_ALL_Z, B_NOP,"AllZ", 10, 85, 40, 20, &srl->layflag, 0, 0, 0, 0, "Fill in Z values for all not-rendered faces, for masking"); uiBlockBeginAlign(block); - uiDefButBitS(block, TOG, SCE_LAY_SOLID, B_NOP,"Solid", 50, 70, 60, 20, &srl->layflag, 0, 0, 0, 0, "Render Solid faces in this Layer"); - uiDefButBitS(block, TOG, SCE_LAY_HALO, B_NOP,"Halo", 110, 70, 55, 20, &srl->layflag, 0, 0, 0, 0, "Render Halos in this Layer (on top of Solid)"); - uiDefButBitS(block, TOG, SCE_LAY_ZTRA, B_NOP,"Ztra", 165, 70, 55, 20, &srl->layflag, 0, 0, 0, 0, "Render Z-Transparent faces in this Layer (On top of Solid and Halos)"); - uiDefButBitS(block, TOG, SCE_LAY_SKY, B_NOP,"Sky", 220, 70, 40, 20, &srl->layflag, 0, 0, 0, 0, "Render Sky or backbuffer in this Layer"); - uiDefButBitS(block, TOG, SCE_LAY_EDGE, B_NOP,"Edge", 260, 70, 50, 20, &srl->layflag, 0, 0, 0, 0, "Render Edge-enhance in this Layer (only works for Solid faces)"); + uiDefButBitI(block, TOG, SCE_LAY_SOLID, B_NOP,"Solid", 50, 85, 60, 20, &srl->layflag, 0, 0, 0, 0, "Render Solid faces in this Layer"); + uiDefButBitI(block, TOG, SCE_LAY_HALO, B_NOP,"Halo", 110, 85, 55, 20, &srl->layflag, 0, 0, 0, 0, "Render Halos in this Layer (on top of Solid)"); + uiDefButBitI(block, TOG, SCE_LAY_ZTRA, B_NOP,"Ztra", 165, 85, 55, 20, &srl->layflag, 0, 0, 0, 0, "Render Z-Transparent faces in this Layer (On top of Solid and Halos)"); + uiDefButBitI(block, TOG, SCE_LAY_SKY, B_NOP,"Sky", 220, 85, 40, 20, &srl->layflag, 0, 0, 0, 0, "Render Sky or backbuffer in this Layer"); + uiDefButBitI(block, TOG, SCE_LAY_EDGE, B_NOP,"Edge", 260, 85, 50, 20, &srl->layflag, 0, 0, 0, 0, "Render Edge-enhance in this Layer (only works for Solid faces)"); + + uiDefIDPoinBut(block, test_grouppoin_but, ID_GR, B_SET_PASS, "Light:", 10, 65, 150, 20, &(srl->light_override), "Name of Group to use as Lamps instead"); + uiDefIDPoinBut(block, test_matpoin_but, ID_MA, B_SET_PASS, "Mat:", 160, 65, 150, 20, &(srl->mat_override), "Name of Material to use as Lamps instead"); uiBlockEndAlign(block); - uiDefBut(block, LABEL, 0, "Passes:", 10,30,50,20, NULL, 0, 0, 0, 0, ""); - uiBlockBeginAlign(block); - uiDefButBitS(block, TOG, SCE_PASS_COMBINED, B_NOP,"Combined", 60, 30, 85, 20, &srl->passflag, 0, 0, 0, 0, "Deliver full combined RGBA buffer"); - uiDefButBitS(block, TOG, SCE_PASS_Z, B_SET_PASS,"Z", 145, 30, 25, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Z values pass"); - uiDefButBitS(block, TOG, SCE_PASS_VECTOR, B_SET_PASS,"Vec", 170, 30, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Speed Vector pass"); - uiDefButBitS(block, TOG, SCE_PASS_NORMAL, B_SET_PASS,"Nor", 210, 30, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Normal pass"); - uiDefButBitS(block, TOG, SCE_PASS_INDEXOB, B_SET_PASS,"IndexOb",250, 30, 60, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Object Index pass"); + uiDefBut(block, LABEL, 0, "Pass:", 10,30,45,20, NULL, 0, 0, 0, 0, ""); + uiDefButBitI(block, TOG, SCE_PASS_COMBINED, B_SET_PASS,"Combined", 55, 30, 90, 20, &srl->passflag, 0, 0, 0, 0, "Deliver full combined RGBA buffer"); + uiDefButBitI(block, TOG, SCE_PASS_Z, B_SET_PASS,"Z", 145, 30, 25, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Z values pass"); + uiDefButBitI(block, TOG, SCE_PASS_VECTOR, B_SET_PASS,"Vec", 170, 30, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Speed Vector pass"); + uiDefButBitI(block, TOG, SCE_PASS_NORMAL, B_SET_PASS,"Nor", 210, 30, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Normal pass"); + uiDefButBitI(block, TOG, SCE_PASS_INDEXOB, B_SET_PASS,"IndexOb",250, 30, 60, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Object Index pass"); - uiDefButBitS(block, TOG, SCE_PASS_RGBA, B_SET_PASS,"Col", 10, 10, 45, 20, &srl->passflag, 0, 0, 0, 0, "Deliver shade-less Color pass"); - uiDefButBitS(block, TOG, SCE_PASS_DIFFUSE, B_SET_PASS,"Diff", 55, 10, 45, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Diffuse pass"); - uiDefButBitS(block, TOG, SCE_PASS_SPEC, B_SET_PASS,"Spec", 100, 10, 45, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Specular pass"); - uiDefButBitS(block, TOG, SCE_PASS_SHADOW, B_SET_PASS,"Shad", 145, 10, 45, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Shadow pass"); - uiDefButBitS(block, TOG, SCE_PASS_AO, B_SET_PASS,"AO", 185, 10, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver AO pass"); - uiDefButBitS(block, TOG, SCE_PASS_REFLECT, B_SET_PASS,"Refl", 225, 10, 45, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Raytraced Reflection pass"); - uiDefButBitS(block, TOG, SCE_PASS_REFRACT, B_SET_PASS,"Refr", 270, 10, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Raytraced Refraction pass"); + uiDefButBitI(block, TOG, SCE_PASS_RGBA, B_SET_PASS,"Col", 10, 10, 45, 20, &srl->passflag, 0, 0, 0, 0, "Deliver shade-less Color pass"); + uiDefButBitI(block, TOG, SCE_PASS_DIFFUSE, B_SET_PASS,"Diff", 55, 10, 45, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Diffuse pass"); + uiDefButBitI(block, BUT_TOGDUAL, SCE_PASS_SPEC, B_SET_PASS,"Spec", 100, 10, 45, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Specular pass"); + uiDefButBitI(block, BUT_TOGDUAL, SCE_PASS_SHADOW, B_SET_PASS,"Shad", 145, 10, 45, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Shadow pass"); + uiDefButBitI(block, BUT_TOGDUAL, SCE_PASS_AO, B_SET_PASS,"AO", 185, 10, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver AO pass"); + uiDefButBitI(block, BUT_TOGDUAL, SCE_PASS_REFLECT, B_SET_PASS,"Refl", 225, 10, 45, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Raytraced Reflection pass"); + uiDefButBitI(block, BUT_TOGDUAL, SCE_PASS_REFRACT, B_SET_PASS,"Refr", 270, 10, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Raytraced Refraction pass"); } diff --git a/source/blender/src/buttons_shading.c b/source/blender/src/buttons_shading.c index d9837e7eaa9..3392f074a09 100644 --- a/source/blender/src/buttons_shading.c +++ b/source/blender/src/buttons_shading.c @@ -2821,9 +2821,7 @@ static void material_panel_texture(Material *ma) for(a= 0; a<MAX_MTEX; a++) { mtex= ma->mtex[a]; if(mtex && mtex->tex) { - if(ma->septex & (1<<a)) - uiDefButBitS(block, TOG, 1<<a, B_MATPRV, " ", -20, 180-18*a, 28, 20, &ma->septex, 0.0, 0.0, 0, 0, "Click to disable or enable this texture channel"); - else uiDefIconButBitS(block, TOG, 1<<a, B_MATPRV, ICON_CHECKBOX_HLT, -20, 180-18*a, 28, 20, &ma->septex, 0.0, 0.0, 0, 0, "Click to disable or enable this texture channel"); + uiDefIconButBitS(block, ICONTOGN, 1<<a, B_MATPRV, ICON_CHECKBOX_HLT-1, -20, 180-18*a, 28, 20, &ma->septex, 0.0, 0.0, 0, 0, "Click to disable or enable this texture channel"); } } uiBlockBeginAlign(block); diff --git a/source/blender/src/interface.c b/source/blender/src/interface.c index 73efa6bc5e1..13b72739d0d 100644 --- a/source/blender/src/interface.c +++ b/source/blender/src/interface.c @@ -1412,7 +1412,7 @@ static void ui_is_but_sel(uiBut *but) value= ui_get_but_val(but); - if( but->type==TOGN ) true= 0; + if( but->type==TOGN || but->type==ICONTOGN) true= 0; if( but->bit ) { lvalue= (int)value; @@ -1434,6 +1434,7 @@ static void ui_is_but_sel(uiBut *but) case ICONTOG: if(value!=but->min) push= 1; break; + case ICONTOGN: case TOGN: if(value==0.0) push= 1; break; @@ -1556,28 +1557,29 @@ static int ui_do_but_TOG(uiBlock *block, uiBut *but, int qual) } ui_set_but_val(but, (double)lvalue); - if(but->type==ICONTOG) ui_check_but(but); + if(but->type==ICONTOG || but->type==ICONTOGN) ui_check_but(but); // no frontbuffer draw for this one - if((but->flag & UI_NO_HILITE)==0) ui_draw_but(but); + if(but->type==BUT_TOGDUAL); + else if((but->flag & UI_NO_HILITE)==0) ui_draw_but(but); } else { if(value==0.0) push= 1; else push= 0; - if(but->type==TOGN) push= !push; + if(but->type==TOGN || but->type==ICONTOGN) push= !push; ui_set_but_val(but, (double)push); - if(but->type==ICONTOG) ui_check_but(but); + if(but->type==ICONTOG || but->type==ICONTOGN) ui_check_but(but); // no frontbuffer draw for this one if((but->flag & UI_NO_HILITE)==0) ui_draw_but(but); } /* end local hack... */ - if(but->type==BUT_TOGDUAL && qual) { + if(but->type==BUT_TOGDUAL && qual==LR_CTRLKEY) { if(but->pointype==SHO) but->poin -= 2; else if(but->pointype==INT) - but->poin -= 2; + but->poin -= 4; } /* no while loop...this button is used for viewmove */ @@ -3843,7 +3845,8 @@ static int ui_do_button(uiBlock *block, uiBut *but, uiEvent *uevent) case TOG: case TOGR: - case ICONTOG: + case ICONTOG: + case ICONTOGN: case TOGN: case BUT_TOGDUAL: if(uevent->val) { @@ -5353,6 +5356,7 @@ void ui_check_but(uiBut *but) break; case ICONTOG: + case ICONTOGN: if(but->flag & UI_SELECT) but->iconadd= 1; else but->iconadd= 0; break; @@ -5446,7 +5450,13 @@ void ui_check_but(uiBut *but) strcat(but->drawstr, key_event_to_string((short) ui_get_but_val(but))); } break; - + case BUT_TOGDUAL: + /* trying to get the dual-icon to left of text... not very nice */ + if(but->str[0]) { + strcpy(but->drawstr, " "); + strcpy(but->drawstr+2, but->str); + } + break; default: strcpy(but->drawstr, but->str); @@ -5812,6 +5822,10 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, char *str, short if ELEM8(but->type, HSVSLI , NUMSLI, MENU, TEX, LABEL, IDPOIN, BLOCK, BUTM) { but->flag |= UI_TEXT_LEFT; } + + if(but->type==BUT_TOGDUAL) { + but->flag |= UI_ICON_LEFT; + } if(but->type==ROUNDBOX) but->flag |= UI_NO_HILITE; diff --git a/source/blender/src/interface_draw.c b/source/blender/src/interface_draw.c index de95b1264b4..653b596e5ec 100644 --- a/source/blender/src/interface_draw.c +++ b/source/blender/src/interface_draw.c @@ -160,10 +160,9 @@ void uiEmboss(float x1, float y1, float x2, float y2, int sel) /* icons have been standardized... and this call draws in untransformed coordinates */ #define ICON_HEIGHT 16.0f -static void ui_draw_icon(uiBut *but, BIFIconID icon) +static void ui_draw_icon(uiBut *but, BIFIconID icon, int blend) { float xs=0, ys=0, aspect, height; - int blend= 0; /* this icon doesn't need draw... */ if(icon==ICON_BLANK1) return; @@ -184,7 +183,10 @@ static void ui_draw_icon(uiBut *but, BIFIconID icon) height= ICON_HEIGHT; if(but->flag & UI_ICON_LEFT) { - if (but->type==BUTM) { + if (but->type==BUT_TOGDUAL && but->drawstr[0]) { + xs= but->x1-1.0; + } + else if (but->type==BUTM ) { xs= but->x1+1.0; } else if ((but->type==ICONROW) || (but->type==ICONTEXTROW)) { @@ -1455,7 +1457,7 @@ static void ui_draw_text_icon(uiBut *but) /* check for button text label */ if (but->type == ICONTEXTROW) { - ui_draw_icon(but, (BIFIconID) (but->icon+but->iconadd)); + ui_draw_icon(but, (BIFIconID) (but->icon+but->iconadd), 0); } else { @@ -1514,9 +1516,8 @@ static void ui_draw_text_icon(uiBut *but) dualset= BTST( *(((short *)but->poin)+1), but->bitnr); else if(but->pointype==INT) dualset= BTST( *(((int *)but->poin)+1), but->bitnr); - if(dualset) { - ui_draw_icon(but, ICON_DOT); - } + + ui_draw_icon(but, ICON_DOT, dualset?0:-100); } if(but->drawstr[0]!=0) { @@ -1531,7 +1532,7 @@ static void ui_draw_text_icon(uiBut *but) and offset the text label to accomodate it */ if ( (but->flag & UI_HAS_ICON) && (but->flag & UI_ICON_LEFT) ) { - ui_draw_icon(but, but->icon); + ui_draw_icon(but, but->icon, 0); if(but->flag & UI_TEXT_LEFT) x= but->x1 + but->aspect*BIF_icon_get_width(but->icon)+5.0; else x= (but->x1+but->x2-but->strwidth+1)/2.0; @@ -1591,7 +1592,7 @@ static void ui_draw_text_icon(uiBut *but) } /* if there's no text label, then check to see if there's an icon only and draw it */ else if( but->flag & UI_HAS_ICON ) { - ui_draw_icon(but, (BIFIconID) (but->icon+but->iconadd)); + ui_draw_icon(but, (BIFIconID) (but->icon+but->iconadd), 0); } } } @@ -2368,7 +2369,7 @@ void ui_draw_but(uiBut *but) case LINK: case INLINK: - ui_draw_icon(but, but->icon); + ui_draw_icon(but, but->icon, 0); break; case ROUNDBOX: diff --git a/source/blender/src/outliner.c b/source/blender/src/outliner.c index 2a026234ed3..c0b83eed71f 100644 --- a/source/blender/src/outliner.c +++ b/source/blender/src/outliner.c @@ -362,6 +362,7 @@ static void outliner_sort(SpaceOops *soops, ListBase *lb) if(totelem>1) { struct treesort *tear= MEM_mallocN(totelem*sizeof(struct treesort), "tree sort array"); struct treesort *tp=tear; + int skip= 0; for(te= lb->first; te; te= te->next, tp++) { tselem= TREESTORE(te); @@ -371,8 +372,12 @@ static void outliner_sort(SpaceOops *soops, ListBase *lb) if(tselem->type && tselem->type!=TSE_DEFGROUP) tp->idcode= 0; // dont sort this tp->id= tselem->id; } + /* keep beginning of list */ + for(tp= tear, skip=0; skip<totelem; skip++, tp++) + if(tp->idcode) break; - qsort(tear, totelem, sizeof(struct treesort), treesort_alpha); + if(skip<totelem) + qsort(tear+skip, totelem-skip, sizeof(struct treesort), treesort_alpha); lb->first=lb->last= NULL; tp= tear; @@ -389,9 +394,86 @@ static void outliner_sort(SpaceOops *soops, ListBase *lb) } } -/* Prototype, see function below */ -static void outliner_add_bone(SpaceOops *soops, ListBase *lb, - ID *id, Bone *curBone, TreeElement *parent, int *a); +/* Prototype, see functions below */ +static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *idv, + TreeElement *parent, short type, short index); + + +static void outliner_add_passes(SpaceOops *soops, TreeElement *tenla, ID *id, SceneRenderLayer *srl) +{ + TreeStoreElem *tselem= TREESTORE(tenla); + TreeElement *te; + + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, SCE_PASS_COMBINED); + te->name= "Combined"; + te->directdata= &srl->passflag; + + /* save cpu cycles, but we add the first to invoke an open/close triangle */ + if(tselem->flag & TSE_CLOSED) + return; + + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, SCE_PASS_Z); + te->name= "Z"; + te->directdata= &srl->passflag; + + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, SCE_PASS_VECTOR); + te->name= "Vector"; + te->directdata= &srl->passflag; + + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, SCE_PASS_NORMAL); + te->name= "Normal"; + te->directdata= &srl->passflag; + + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, SCE_PASS_INDEXOB); + te->name= "Index Object"; + te->directdata= &srl->passflag; + + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, SCE_PASS_RGBA); + te->name= "Color"; + te->directdata= &srl->passflag; + + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, SCE_PASS_DIFFUSE); + te->name= "Diffuse"; + te->directdata= &srl->passflag; + + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, SCE_PASS_SPEC); + te->name= "Specular"; + te->directdata= &srl->passflag; + + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, SCE_PASS_SHADOW); + te->name= "Shadow"; + te->directdata= &srl->passflag; + + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, SCE_PASS_AO); + te->name= "AO"; + te->directdata= &srl->passflag; + + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, SCE_PASS_REFRACT); + te->name= "Reflection"; + te->directdata= &srl->passflag; + + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, SCE_PASS_REFLECT); + te->name= "Refraction"; + te->directdata= &srl->passflag; + +} + + +/* special handling of hierarchical non-lib data */ +static void outliner_add_bone(SpaceOops *soops, ListBase *lb, ID *id, Bone *curBone, + TreeElement *parent, int *a) +{ + TreeElement *te= outliner_add_element(soops, lb, id, parent, TSE_BONE, *a); + + (*a)++; + te->name= curBone->name; + te->directdata= curBone; + + for(curBone= curBone->childbase.first; curBone; curBone=curBone->next) { + outliner_add_bone(soops, &te->subtree, id, curBone, te, a); + } +} + static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *idv, TreeElement *parent, short type, short index) @@ -428,9 +510,28 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i case ID_SCE: { Scene *sce= (Scene *)id; + SceneRenderLayer *srl; + TreeElement *tenla= outliner_add_element(soops, &te->subtree, sce, te, TSE_R_LAYER_BASE, 0); + int a; + + tenla->name= "RenderLayers"; + for(a=0, srl= sce->r.layers.first; srl; srl= srl->next, a++) { + TreeElement *tenlay= outliner_add_element(soops, &tenla->subtree, sce, te, TSE_R_LAYER, a); + tenlay->name= srl->name; + tenlay->directdata= &srl->passflag; + + if(srl->light_override) + outliner_add_element(soops, &tenlay->subtree, srl->light_override, tenlay, TSE_LINKED_LAMP, 0); + if(srl->mat_override) + outliner_add_element(soops, &tenlay->subtree, srl->mat_override, tenlay, TSE_LINKED_MAT, 0); + + outliner_add_passes(soops, tenlay, &sce->id, srl); + } + outliner_add_element(soops, &te->subtree, sce->world, te, 0, 0); + if(sce->scriptlink.scripts) { - TreeElement *tenla= outliner_add_element(soops, &te->subtree, sce, te, TSE_SCRIPT_BASE, 0); + tenla= outliner_add_element(soops, &te->subtree, sce, te, TSE_SCRIPT_BASE, 0); int a= 0; tenla->name= "Scripts"; for (a=0; a<sce->scriptlink.totscript; a++) { @@ -781,22 +882,6 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i return te; } - -/* special handling of hierarchical non-lib data */ -static void outliner_add_bone(SpaceOops *soops, ListBase *lb, ID *id, Bone *curBone, - TreeElement *parent, int *a) -{ - TreeElement *te= outliner_add_element(soops, lb, id, parent, TSE_BONE, *a); - - (*a)++; - te->name= curBone->name; - te->directdata= curBone; - - for(curBone= curBone->childbase.first; curBone; curBone=curBone->next) { - outliner_add_bone(soops, &te->subtree, id, curBone, te, a); - } -} - static void outliner_make_hierarchy(SpaceOops *soops, ListBase *lb) { TreeElement *te, *ten, *tep; @@ -1777,7 +1862,7 @@ static int do_outliner_mouse_event(SpaceOops *soops, TreeElement *te, short even if(event==LEFTMOUSE) { if (G.qual & LR_CTRLKEY) { - if(ELEM5(tselem->type, TSE_NLA, TSE_DEFGROUP_BASE, TSE_CONSTRAINT_BASE, TSE_MODIFIER_BASE, TSE_SCRIPT_BASE)) + if(ELEM8(tselem->type, TSE_NLA, TSE_DEFGROUP_BASE, TSE_CONSTRAINT_BASE, TSE_MODIFIER_BASE, TSE_SCRIPT_BASE, TSE_POSE_BASE, TSE_R_LAYER_BASE, TSE_R_PASS)) error("Cannot edit builtin name"); else if(tselem->id->lib) error("Cannot edit Library Data"); @@ -1902,11 +1987,13 @@ static TreeElement *outliner_find_id(SpaceOops *soops, ListBase *lb, ID *id) for(te= lb->first; te; te= te->next) { tselem= TREESTORE(te); - if(tselem->id==id) return te; - /* only deeper on scene or object */ - if( te->idcode==ID_OB || te->idcode==ID_SCE) { - tes= outliner_find_id(soops, &te->subtree, id); - if(tes) return tes; + if(tselem->type==0) { + if(tselem->id==id) return te; + /* only deeper on scene or object */ + if( te->idcode==ID_OB || te->idcode==ID_SCE) { + tes= outliner_find_id(soops, &te->subtree, id); + if(tes) return tes; + } } } return NULL; @@ -2686,6 +2773,15 @@ static void tselem_draw_icon(float x, float y, TreeStoreElem *tselem, TreeElemen BIF_icon_draw(x, y, ICON_WPAINT_DEHLT); break; case TSE_PROXY: BIF_icon_draw(x, y, ICON_GHOST); break; + case TSE_R_LAYER_BASE: + BIF_icon_draw(x, y, ICON_RESTRICT_RENDER_OFF); break; + case TSE_R_LAYER: + BIF_icon_draw(x, y, ICON_IMAGE_DEHLT); break; + case TSE_LINKED_LAMP: + BIF_icon_draw(x, y, ICON_LAMP_DEHLT); break; + case TSE_LINKED_MAT: + BIF_icon_draw(x, y, ICON_MATERIAL_DEHLT); break; + #ifdef WITH_VERSE case ID_VS: case ID_MS: @@ -2783,7 +2879,9 @@ static void outliner_draw_iconrow(SpaceOops *soops, ListBase *lb, int level, int (*offsx) += OL_X; } - outliner_draw_iconrow(soops, &te->subtree, level+1, offsx, ys); + /* this tree element always has same amount of branches, so dont draw */ + if(tselem->type!=TSE_R_LAYER) + outliner_draw_iconrow(soops, &te->subtree, level+1, offsx, ys); } } @@ -2895,7 +2993,7 @@ static void outliner_draw_tree_element(SpaceOops *soops, TreeElement *te, int st } /* open/close icon, only when sublevels, except for scene */ - if(te->subtree.first || te->idcode==ID_SCE) { + if(te->subtree.first || (te->idcode==ID_SCE && tselem->type==0)) { int icon_x; if((tselem->type==0 && ELEM(te->idcode, ID_OB, ID_SCE)) || ELEM4(te->idcode,ID_VN,ID_VS, ID_MS, ID_SS)) icon_x = startx; @@ -2961,7 +3059,7 @@ static void outliner_draw_tree_element(SpaceOops *soops, TreeElement *te, int st offsx+= OL_X + BIF_GetStringWidth(G.font, server_buf, 0); } #endif - else { + else if(tselem->type!=TSE_R_LAYER) { /* this tree element always has same amount of branches, so dont draw */ int tempx= startx+offsx; // divider BIF_ThemeColorShade(TH_BACK, -40); @@ -2969,7 +3067,9 @@ static void outliner_draw_tree_element(SpaceOops *soops, TreeElement *te, int st glEnable(GL_BLEND); glPixelTransferf(GL_ALPHA_SCALE, 0.5); + outliner_draw_iconrow(soops, &te->subtree, 0, &tempx, *starty+2); + glPixelTransferf(GL_ALPHA_SCALE, 1.0); glDisable(GL_BLEND); } @@ -3178,6 +3278,12 @@ static void restrictbutton_rend_cb(void *poin, void *poin2) allqueue(REDRAWVIEW3D, 0); } +static void restrictbutton_r_lay_cb(void *poin, void *poin2) +{ + allqueue(REDRAWOOPS, 0); + allqueue(REDRAWBUTSSCENE, 0); +} + static void namebutton_cb(void *tep, void *oldnamep) { SpaceOops *soops= curarea->spacedata.first; @@ -3251,7 +3357,10 @@ static void namebutton_cb(void *tep, void *oldnamep) allqueue(REDRAWVIEW3D, 1); allqueue(REDRAWBUTSEDIT, 0); break; - + case TSE_R_LAYER: + allqueue(REDRAWOOPS, 0); + allqueue(REDRAWBUTSSCENE, 0); + break; } } } @@ -3292,8 +3401,9 @@ static void outliner_buttons(uiBlock *block, SpaceOops *soops, ListBase *lb) } if (!(soops->flag & SO_HIDE_RESTRICTCOLS)) { + + /* objects have toggle-able restriction flags */ if(tselem->type==0 && te->idcode==ID_OB) { - /* only objects have toggle-able flags */ ob = (Object *)tselem->id; uiBlockSetEmboss(block, UI_EMBOSSN); @@ -3313,7 +3423,33 @@ static void outliner_buttons(uiBlock *block, SpaceOops *soops, ListBase *lb) uiButSetFlag(bt, UI_NO_HILITE); uiBlockSetEmboss(block, UI_EMBOSS); - + } + /* scene render layers and passes have toggle-able flags too! */ + else if(tselem->type==TSE_R_LAYER) { + uiBlockSetEmboss(block, UI_EMBOSSN); + + bt= uiDefIconButBitI(block, ICONTOGN, SCE_LAY_DISABLE, REDRAWBUTSSCENE, ICON_CHECKBOX_HLT-1, + (int)soops->v2d.mask.xmax-(OL_TOG_RESTRICT_VIEWX+SCROLLB), te->ys, 17, OL_H-1, te->directdata, 0, 0, 0, 0, "Render this RenderLayer"); + uiButSetFunc(bt, restrictbutton_r_lay_cb, NULL, NULL); + + uiBlockSetEmboss(block, UI_EMBOSS); + } + else if(tselem->type==TSE_R_PASS) { + int *layflag= te->directdata; + uiBlockSetEmboss(block, UI_EMBOSSN); + + /* NOTE: tselem->nr is short! */ + bt= uiDefIconButBitI(block, ICONTOG, tselem->nr, REDRAWBUTSSCENE, ICON_CHECKBOX_HLT-1, + (int)soops->v2d.mask.xmax-(OL_TOG_RESTRICT_VIEWX+SCROLLB), te->ys, 17, OL_H-1, layflag, 0, 0, 0, 0, "Render this Pass"); + uiButSetFunc(bt, restrictbutton_r_lay_cb, NULL, NULL); + + layflag++; /* is lay_xor */ + if(ELEM6(tselem->nr, SCE_PASS_SPEC, SCE_PASS_SHADOW, SCE_PASS_AO, SCE_PASS_REFLECT, SCE_PASS_REFRACT, SCE_PASS_RADIO)) + bt= uiDefIconButBitI(block, TOG, tselem->nr, REDRAWBUTSSCENE, (*layflag & tselem->nr)?ICON_DOT:ICON_BLANK1, + (int)soops->v2d.mask.xmax-(OL_TOG_RESTRICT_SELECTX+SCROLLB), te->ys, 17, OL_H-1, layflag, 0, 0, 0, 0, "Exclude this Pass from Combined"); + uiButSetFunc(bt, restrictbutton_r_lay_cb, NULL, NULL); + + uiBlockSetEmboss(block, UI_EMBOSS); } } |