diff options
Diffstat (limited to 'source/blender/editors/preview')
-rw-r--r-- | source/blender/editors/preview/previewrender.c | 145 |
1 files changed, 102 insertions, 43 deletions
diff --git a/source/blender/editors/preview/previewrender.c b/source/blender/editors/preview/previewrender.c index 28b9c6b1833..624952b48f5 100644 --- a/source/blender/editors/preview/previewrender.c +++ b/source/blender/editors/preview/previewrender.c @@ -112,6 +112,7 @@ typedef struct ShaderPreview { Scene *scene; ID *id; + ID *parent; int sizex, sizey; int *pr_rect; @@ -273,11 +274,10 @@ static Object *find_object(ListBase *lb, const char *name) /* call this with a pointer to initialize preview scene */ /* call this with NULL to restore assigned ID pointers in preview scene */ -static Scene *preview_prepare_scene(Scene *scene, int id_type, ShaderPreview *sp) +static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPreview *sp) { Scene *sce; Base *base; - ID *id= sp?sp->id:NULL; if(pr_main==NULL) return NULL; @@ -410,38 +410,74 @@ static Scene *preview_prepare_scene(Scene *scene, int id_type, ShaderPreview *sp /* new UI convention: draw is in pixel space already. */ /* uses ROUNDBOX button in block to get the rect */ -void ED_preview_draw(const bContext *C, void *idp, rcti *rect) +static int ed_preview_draw_rect(ScrArea *sa, Scene *sce, ID *id, int split, int first, rcti *rect, rcti *newrect) +{ + RenderResult rres; + char name[32]; + int gamma_correct=0; + int offx=0, newx= rect->xmax-rect->xmin, newy= rect->ymax-rect->ymin; + + if (id && GS(id->name) != ID_TE) { + /* exception: don't color manage texture previews - show the raw values */ + if (sce) gamma_correct = sce->r.color_mgt_flag & R_COLOR_MANAGEMENT; + } + + if(!split || first) sprintf(name, "Preview %p", sa); + else sprintf(name, "SecondPreview %p", sa); + + if(split) { + if(first) { + offx= 0; + newx= newx/2; + } + else { + offx= newx/2; + newx= newx - newx/2; + } + } + + RE_GetResultImage(RE_GetRender(name), &rres); + + if(rres.rectf) { + + if(ABS(rres.rectx-newx)<2 && ABS(rres.recty-newy)<2) { + newrect->xmax= MAX2(newrect->xmax, rect->xmin + rres.rectx + offx); + newrect->ymax= MAX2(newrect->ymax, rect->ymin + rres.recty); + + glPushMatrix(); + glTranslatef(offx, 0, 0); + glaDrawPixelsSafe_to32(rect->xmin, rect->ymin, rres.rectx, rres.recty, rres.rectx, rres.rectf, gamma_correct); + glPopMatrix(); + return 1; + } + } + + return 0; +} + +void ED_preview_draw(const bContext *C, void *idp, void *parentp, rcti *rect) { if(idp) { ScrArea *sa= CTX_wm_area(C); Scene *sce = CTX_data_scene(C); ID *id = (ID *)idp; + ID *parent= (ID *)parentp; SpaceButs *sbuts= sa->spacedata.first; - RenderResult rres; + rcti newrect; + int ok; int newx= rect->xmax-rect->xmin, newy= rect->ymax-rect->ymin; - int ok= 0; - char name[32]; - int gamma_correct=0; - - if (id && GS(id->name) != ID_TE) { - /* exception: don't color manage texture previews - show the raw values */ - if (sce) gamma_correct = sce->r.color_mgt_flag & R_COLOR_MANAGEMENT; - } - - sprintf(name, "Preview %p", sa); - RE_GetResultImage(RE_GetRender(name), &rres); - if(rres.rectf) { - - if( ABS(rres.rectx-newx)<2 && ABS(rres.recty-newy)<2 ) { - /* correct size, then black outline matches */ - rect->xmax= rect->xmin + rres.rectx; - rect->ymax= rect->ymin + rres.recty; - - glaDrawPixelsSafe_to32(rect->xmin, rect->ymin, rres.rectx, rres.recty, rres.rectx, rres.rectf, gamma_correct); - ok= 1; - } - } + newrect.xmin= rect->xmin; + newrect.xmax= rect->xmin; + newrect.ymin= rect->ymin; + newrect.ymax= rect->ymin; + + ok= ed_preview_draw_rect(sa, sce, id, (parent != NULL), 1, rect, &newrect); + if(parent) + ok &= ed_preview_draw_rect(sa, sce, parent, 1, 0, rect, &newrect); + + if(ok) + *rect= newrect; /* check for spacetype... */ if(sbuts->spacetype==SPACE_BUTS && sbuts->preview) { @@ -450,7 +486,7 @@ void ED_preview_draw(const bContext *C, void *idp, rcti *rect) } if(ok==0) { - ED_preview_shader_job(C, sa, idp, newx, newy); + ED_preview_shader_job(C, sa, id, parent, newx, newy); } } } @@ -791,23 +827,20 @@ static void shader_preview_updatejob(void *spv) } -/* runs inside thread for material, in foreground for icons */ -static void shader_preview_startjob(void *customdata, short *stop, short *do_update) +static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int first) { - ShaderPreview *sp= customdata; Render *re; Scene *sce; float oldlens; - char name [32]; + char name[32]; + int sizex; - sp->stop= stop; - sp->do_update= do_update; - /* get the stuff from the builtin preview dbase */ - sce= preview_prepare_scene(sp->scene, GS(sp->id->name), sp); + sce= preview_prepare_scene(sp->scene, id, GS(id->name), sp); // XXX sizex if(sce==NULL) return; - sprintf(name, "Preview %p", sp->owner); + if(!split || first) sprintf(name, "Preview %p", sp->owner); + else sprintf(name, "SecondPreview %p", sp->owner); re= RE_GetRender(name); /* full refreshed render from first tile */ @@ -825,8 +858,15 @@ static void shader_preview_startjob(void *customdata, short *stop, short *do_upd sce->r.scemode |= R_NO_IMAGE_LOAD; } + /* in case of split preview, use border render */ + if(split) { + if(first) sizex= sp->sizex/2; + else sizex= sp->sizex - sp->sizex/2; + } + else sizex= sp->sizex; + /* allocates or re-uses render result */ - RE_InitState(re, NULL, &sce->r, sp->sizex, sp->sizey, NULL); + RE_InitState(re, NULL, &sce->r, sizex, sp->sizey, NULL); /* callbacs are cleared on GetRender() */ if(sp->pr_method==PR_DO_RENDER) { @@ -835,8 +875,8 @@ static void shader_preview_startjob(void *customdata, short *stop, short *do_upd } /* lens adjust */ oldlens= ((Camera *)sce->camera->data)->lens; - if(sp->sizex > sp->sizey) - ((Camera *)sce->camera->data)->lens *= (float)sp->sizey/(float)sp->sizex; + if(sizex > sp->sizey) + ((Camera *)sce->camera->data)->lens *= (float)sp->sizey/(float)sizex; /* entire cycle for render engine */ RE_SetCamera(re, sce->camera); @@ -845,7 +885,6 @@ static void shader_preview_startjob(void *customdata, short *stop, short *do_upd RE_Database_Free(re); ((Camera *)sce->camera->data)->lens= oldlens; - *do_update= 1; /* handle results */ if(sp->pr_method==PR_ICON_RENDER) { @@ -860,8 +899,25 @@ static void shader_preview_startjob(void *customdata, short *stop, short *do_upd } /* unassign the pointers, reset vars */ - preview_prepare_scene(sp->scene, GS(sp->id->name), NULL); + preview_prepare_scene(sp->scene, NULL, GS(id->name), NULL); +} +/* runs inside thread for material, in foreground for icons */ +static void shader_preview_startjob(void *customdata, short *stop, short *do_update) +{ + ShaderPreview *sp= customdata; + + sp->stop= stop; + sp->do_update= do_update; + + if(sp->parent) { + shader_preview_render(sp, sp->parent, 1, 1); + shader_preview_render(sp, sp->id, 1, 0); + } + else + shader_preview_render(sp, sp->id, 0, 0); + + *do_update= 1; } static void shader_preview_free(void *customdata) @@ -871,7 +927,7 @@ static void shader_preview_free(void *customdata) MEM_freeN(sp); } -void ED_preview_shader_job(const bContext *C, void *owner, ID *id, int sizex, int sizey) +void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, int sizex, int sizey) { wmJob *steve; ShaderPreview *sp; @@ -890,6 +946,7 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, int sizex, in sp->sizey= sizey; sp->pr_method= PR_DO_RENDER; sp->id = id; + sp->parent= parent; /* setup job */ WM_jobs_customdata(steve, sp, shader_preview_free); @@ -905,8 +962,10 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, int sizex, in /* rect should be allocated, sizex/sizy pixels, 32 bits */ void ED_preview_iconrender(Scene *scene, ID *id, int *rect, int sizex, int sizey) { - ShaderPreview *sp= MEM_callocN(sizeof(ShaderPreview), "ShaderPreview"); + ShaderPreview *sp; short stop=0, do_update=0; + + sp= MEM_callocN(sizeof(ShaderPreview), "ShaderPreview"); /* customdata for preview thread */ sp->scene= scene; |