diff options
Diffstat (limited to 'source/blender/editors/render/render_preview.c')
-rw-r--r-- | source/blender/editors/render/render_preview.c | 167 |
1 files changed, 132 insertions, 35 deletions
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index e52dd7c65c8..4297d4fa316 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -69,6 +69,7 @@ #include "BKE_image.h" #include "BKE_icons.h" #include "BKE_lamp.h" +#include "BKE_layer.h" #include "BKE_library.h" #include "BKE_library_remap.h" #include "BKE_main.h" @@ -78,6 +79,9 @@ #include "BKE_texture.h" #include "BKE_world.h" +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_build.h" + #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" #include "IMB_thumbs.h" @@ -85,6 +89,7 @@ #include "BIF_gl.h" #include "BIF_glutil.h" +#include "GPU_shader.h" #include "RE_pipeline.h" #include "RE_engine.h" @@ -94,6 +99,7 @@ #include "ED_datafiles.h" #include "ED_render.h" +#include "ED_screen.h" #ifndef NDEBUG /* Used for database init assert(). */ @@ -167,6 +173,7 @@ typedef struct ShaderPreview { Main *bmain; Main *pr_main; + ViewRender *view_render; } ShaderPreview; typedef struct IconPreviewSize { @@ -181,6 +188,7 @@ typedef struct IconPreview { void *owner; ID *id; ListBase sizes; + ViewRender *view_render; } IconPreview; /* *************************** Preview for buttons *********************** */ @@ -223,7 +231,7 @@ void ED_preview_ensure_dbase(void) static bool check_engine_supports_textures(Scene *scene) { - RenderEngineType *type = RE_engines_find(scene->r.engine); + RenderEngineType *type = RE_engines_find(scene->view_render.engine_id); return type->flag & RE_USE_TEXTURE_PREVIEW; } @@ -269,20 +277,76 @@ static Scene *preview_get_scene(Main *pr_main) return pr_main->scene.first; } +static const char *preview_layer_name(const char pr_type) +{ + switch (pr_type) { + case MA_FLAT: + return "Flat"; + case MA_SPHERE: + return "Sphere"; + case MA_CUBE: + return "Cube"; + case MA_MONKEY: + return "Monkey"; + case MA_SPHERE_A: + return "World Sphere"; + case MA_TEXTURE: + return "Texture"; + case MA_LAMP: + return "Lamp"; + case MA_SKY: + return "Sky"; + case MA_HAIR: + return "Hair"; + case MA_ATMOS: + return "Atmosphere"; + default: + BLI_assert(!"Unknown preview type"); + return ""; + } +} + +static void set_preview_layer(ViewLayer *view_layer, char pr_type) +{ + LayerCollection *lc; + const char *collection_name = preview_layer_name(pr_type); + + for (lc = view_layer->layer_collections.first; lc; lc = lc->next) { + if (STREQ(lc->scene_collection->name, collection_name)) { + lc->flag = COLLECTION_VIEWPORT | COLLECTION_RENDER; + } + else { + lc->flag = COLLECTION_DISABLED; + } + } +} + +static World *preview_get_localized_world(ShaderPreview *sp, World *world) +{ + if (world == NULL) { + return NULL; + } + if (sp->worldcopy != NULL) { + return sp->worldcopy; + } + sp->worldcopy = BKE_world_localize(world); + BLI_addtail(&sp->pr_main->world, sp->worldcopy); + return sp->worldcopy; +} /* 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(Main *bmain, Scene *scene, ID *id, int id_type, ShaderPreview *sp) { Scene *sce; - Base *base; Main *pr_main = sp->pr_main; memcpy(pr_main->name, bmain->name, sizeof(pr_main->name)); sce = preview_get_scene(pr_main); if (sce) { - + ViewLayer *view_layer = BKE_view_layer_from_scene_get(sce); + /* this flag tells render to not execute depsgraph or ipos etc */ sce->r.scemode |= R_BUTS_PREVIEW; /* set world always back, is used now */ @@ -320,10 +384,10 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty * seems commonly used render engines does not support * such kind of rendering. */ - BLI_strncpy(sce->r.engine, RE_engine_id_BLENDER_RENDER, sizeof(sce->r.engine)); + BLI_strncpy(sce->view_render.engine_id, RE_engine_id_BLENDER_RENDER, sizeof(sce->view_render.engine_id)); } else { - BLI_strncpy(sce->r.engine, scene->r.engine, sizeof(sce->r.engine)); + BLI_strncpy(sce->view_render.engine_id, scene->view_render.engine_id, sizeof(sce->view_render.engine_id)); } if (id_type == ID_MA) { @@ -357,34 +421,43 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty /* this only works in a specific case where the preview.blend contains * an object starting with 'c' which has a material linked to it (not the obdata) * and that material has a fake shadow texture in the active texture slot */ - for (base = sce->base.first; base; base = base->next) { - if (base->object->id.name[2] == 'c') { - Material *shadmat = give_current_material(base->object, base->object->actcol); + for (Base *base = view_layer->object_bases.first; base; base = base->next) { + Object *ob = base->object; + if (ob->id.name[2] == 'c') { + Material *shadmat = give_current_material(ob, ob->actcol); if (shadmat) { - if (mat->mode2 & MA_CASTSHADOW) shadmat->septex = 0; - else shadmat->septex |= 1; + if (mat->mode2 & MA_CASTSHADOW) { + shadmat->septex = 0; + } + else { + shadmat->septex |= 1; + } } } } /* turn off bounce lights for volume, * doesn't make much visual difference and slows it down too */ - for (base = sce->base.first; base; base = base->next) { - if (base->object->type == OB_LAMP) { + for (Base *base = view_layer->object_bases.first; base; base = base->next) { + Object *ob = base->object; + if (ob->type == OB_LAMP) { /* if doesn't match 'Lamp.002' --> main key light */ - if (!STREQ(base->object->id.name + 2, "Lamp.002")) { - if (mat->material_type == MA_TYPE_VOLUME) - base->object->restrictflag |= OB_RESTRICT_RENDER; - else - base->object->restrictflag &= ~OB_RESTRICT_RENDER; + if (!STREQ(ob->id.name + 2, "Lamp.002")) { + if (mat->material_type == MA_TYPE_VOLUME) { + base->flag &= ~BASE_VISIBLED; + } + else { + base->flag |= BASE_VISIBLED; + } } } } } else { + /* use current scene world to light sphere */ if (mat->pr_type == MA_SPHERE_A && sp->pr_method == PR_BUTS_RENDER) { /* Use current scene world to light sphere. */ - sce->world = scene->world; + sce->world = preview_get_localized_world(sp, scene->world); } else if (sce->world) { /* Use a default world color. Using the current @@ -398,14 +471,15 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty if (sp->pr_method == PR_ICON_RENDER) { if (mat->material_type == MA_TYPE_HALO) { - sce->lay = 1 << MA_FLAT; + set_preview_layer(view_layer, MA_FLAT); } else { - sce->lay = 1 << MA_SPHERE_A; + set_preview_layer(view_layer, MA_SPHERE_A); } } else { - sce->lay = 1 << mat->pr_type; + set_preview_layer(view_layer, mat->pr_type); + if (mat->nodetree && sp->pr_method == PR_NODE_RENDER) { /* two previews, they get copied by wmJob */ BKE_node_preview_init_tree(mat->nodetree, sp->sizex, sp->sizey, true); @@ -418,7 +492,7 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty } - for (base = sce->base.first; base; base = base->next) { + for (Base *base = view_layer->object_bases.first; base; base = base->next) { if (base->object->id.name[2] == 'p') { /* copy over object color, in case material uses it */ copy_v4_v4(base->object->col, sp->col); @@ -432,7 +506,7 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty (*matar)[actcol] = mat; } else if (base->object->type == OB_LAMP) { - base->object->restrictflag &= ~OB_RESTRICT_RENDER; + base->flag |= BASE_VISIBLED; } } } @@ -445,9 +519,9 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty sp->texcopy = tex; BLI_addtail(&pr_main->tex, tex); } - sce->lay = 1 << MA_TEXTURE; + set_preview_layer(view_layer, MA_TEXTURE); - for (base = sce->base.first; base; base = base->next) { + for (Base *base = view_layer->object_bases.first; base; base = base->next) { if (base->object->id.name[2] == 't') { Material *mat = give_current_material(base->object, base->object->actcol); if (mat && mat->mtex[0]) { @@ -486,20 +560,21 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty BLI_addtail(&pr_main->lamp, la); } - sce->lay = 1 << MA_LAMP; - if (!BKE_scene_use_new_shading_nodes(scene)) { if (la && la->type == LA_SUN && (la->sun_effect_type & LA_SUN_EFFECT_SKY)) { - sce->lay = 1 << MA_ATMOS; - sce->world = scene->world; + set_preview_layer(view_layer, MA_ATMOS); + sce->world = preview_get_localized_world(sp, scene->world); sce->camera = (Object *)BLI_findstring(&pr_main->object, "CameraAtmo", offsetof(ID, name) + 2); } else { sce->world = NULL; sce->camera = (Object *)BLI_findstring(&pr_main->object, "Camera", offsetof(ID, name) + 2); + set_preview_layer(view_layer, MA_LAMP); } } else { + set_preview_layer(view_layer, MA_LAMP); + if (sce->world) { /* Only use lighting from the lamp. */ sce->world->use_nodes = false; @@ -509,7 +584,7 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty } } - for (base = sce->base.first; base; base = base->next) { + for (Base *base = view_layer->object_bases.first; base; base = base->next) { if (base->object->id.name[2] == 'p') { if (base->object->type == OB_LAMP) base->object->data = la; @@ -531,7 +606,7 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty BLI_addtail(&pr_main->world, wrld); } - sce->lay = 1 << MA_SKY; + set_preview_layer(view_layer, MA_SKY); sce->world = wrld; if (wrld && wrld->nodetree && sp->pr_method == PR_NODE_RENDER) { @@ -541,6 +616,12 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty } } + Depsgraph *depsgraph = BKE_scene_get_depsgraph(sce, view_layer, true); + /* TODO(sergey): Use proper flag for tagging here. */ + DEG_graph_id_tag_update(pr_main, depsgraph, &sce->id, 0); + DEG_relations_tag_update(pr_main); + BKE_scene_graph_update_tagged(depsgraph, pr_main); + return sce; } @@ -607,7 +688,9 @@ static bool ed_preview_draw_rect(ScrArea *sa, int split, int first, rcti *rect, if (re) RE_AcquiredResultGet32(re, &rres, (unsigned int *)rect_byte, 0); - glaDrawPixelsSafe(fx, fy, rres.rectx, rres.recty, rres.rectx, GL_RGBA, GL_UNSIGNED_BYTE, rect_byte); + IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR); + immDrawPixelsTex(&state, fx, fy, rres.rectx, rres.recty, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST, rect_byte, + 1.0f, 1.0f, NULL); MEM_freeN(rect_byte); @@ -789,7 +872,7 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs ((Camera *)sce->camera->data)->lens *= (float)sp->sizey / (float)sizex; /* entire cycle for render engine */ - RE_PreviewRender(re, pr_main, sce); + RE_PreviewRender(re, pr_main, sce, sp->view_render); ((Camera *)sce->camera->data)->lens = oldlens; @@ -1036,6 +1119,12 @@ static void icon_preview_startjob(void *customdata, short *stop, short *do_updat *do_update = true; } + else if (idtype == ID_SCR) { + bScreen *screen = (bScreen *)id; + + ED_screen_preview_render(screen, sp->sizex, sp->sizey, sp->pr_rect); + *do_update = true; + } else { /* re-use shader job */ shader_preview_startjob(customdata, stop, do_update); @@ -1110,6 +1199,7 @@ static void icon_preview_startjob_all_sizes(void *customdata, short *stop, short /* construct shader preview from image size and previewcustomdata */ sp->scene = ip->scene; + sp->view_render = ip->view_render; sp->owner = ip->owner; sp->sizex = cur_size->sizex; sp->sizey = cur_size->sizey; @@ -1194,6 +1284,7 @@ void ED_preview_icon_render(Main *bmain, Scene *scene, ID *id, unsigned int *rec ip.bmain = bmain; ip.scene = scene; + ip.view_render = &scene->view_render; ip.owner = BKE_previewimg_id_ensure(id); ip.id = id; @@ -1227,6 +1318,7 @@ void ED_preview_icon_job(const bContext *C, void *owner, ID *id, unsigned int *r /* customdata for preview thread */ ip->bmain = CTX_data_main(C); ip->scene = CTX_data_scene(C); + ip->view_render = &ip->scene->view_render; ip->owner = owner; ip->id = id; @@ -1254,8 +1346,12 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, M wmJob *wm_job; ShaderPreview *sp; Scene *scene = CTX_data_scene(C); + WorkSpace *workspace = CTX_wm_workspace(C); short id_type = GS(id->name); - bool use_new_shading = BKE_scene_use_new_shading_nodes(scene); + + /* Use workspace render only for buttons Window, since the other previews are related to the datablock. */ + ViewRender *view_render = (method == PR_BUTS_RENDER) ? BKE_viewrender_get(scene, workspace) : &scene->view_render; + bool use_new_shading = BKE_viewrender_use_new_shading_nodes(view_render); /* Only texture node preview is supported with Cycles. */ if (use_new_shading && method == PR_NODE_RENDER && id_type != ID_TE) { @@ -1278,8 +1374,9 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, M sp->parent = parent; sp->slot = slot; sp->bmain = CTX_data_main(C); + sp->view_render = view_render; - /* hardcoded preview .blend for cycles/internal, this should be solved + /* hardcoded preview .blend for Eevee + cycles/internal, this should be solved * once with custom preview .blend path for external engines */ if ((method != PR_NODE_RENDER) && id_type != ID_TE && use_new_shading) { sp->pr_main = G_pr_main_cycles; |