diff options
Diffstat (limited to 'source/blender/editors/render/render_preview.c')
-rw-r--r-- | source/blender/editors/render/render_preview.c | 148 |
1 files changed, 117 insertions, 31 deletions
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 35d772afae7..a9a469b4e46 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(). */ @@ -269,20 +275,75 @@ 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(SceneLayer *scene_layer, char pr_type) +{ + LayerCollection *lc; + const char *collection_name = preview_layer_name(pr_type); + for (lc = scene_layer->layer_collections.first; lc; lc = lc->next) { + if (STREQ(lc->scene_collection->name, collection_name)) { + lc->flag = COLLECTION_VISIBLE; + } + else { + lc->flag = 0; + } + } +} + +static World *preview_get_localized_world(ShaderPreview *sp, World *world) +{ + if (world == NULL) { + return NULL; + } + if (sp->worldcopy != NULL) { + return sp->worldcopy; + } + sp->worldcopy = localize_world(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) { - + SceneLayer *scene_layer = BKE_scene_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 */ @@ -357,50 +418,60 @@ 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 = scene_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 = scene_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) - sce->world = scene->world; + if (mat->pr_type == MA_SPHERE_A) { + sce->world = preview_get_localized_world(sp, scene->world); + } } if (sp->pr_method == PR_ICON_RENDER) { if (mat->material_type == MA_TYPE_HALO) { - sce->lay = 1 << MA_FLAT; + set_preview_layer(scene_layer, MA_FLAT); } else { - sce->lay = 1 << MA_SPHERE_A; + set_preview_layer(scene_layer, MA_SPHERE_A); /* same as above, use current scene world to light sphere */ if (BKE_scene_use_new_shading_nodes(scene)) - sce->world = scene->world; + sce->world = preview_get_localized_world(sp, scene->world); } } else { - sce->lay = 1 << mat->pr_type; + set_preview_layer(scene_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); @@ -413,7 +484,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 = scene_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); @@ -427,7 +498,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; } } } @@ -440,9 +511,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(scene_layer, MA_TEXTURE); - for (base = sce->base.first; base; base = base->next) { + for (Base *base = scene_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]) { @@ -481,21 +552,23 @@ 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(scene_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(scene_layer, MA_LAMP); } } + else { + set_preview_layer(scene_layer, MA_LAMP); + } - for (base = sce->base.first; base; base = base->next) { + for (Base *base = scene_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; @@ -517,7 +590,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(scene_layer, MA_SKY); sce->world = wrld; if (wrld && wrld->nodetree && sp->pr_method == PR_NODE_RENDER) { @@ -527,6 +600,11 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty } } + /* TODO(sergey): Use proper flag for tagging here. */ + DEG_id_tag_update(&sce->id, 0); + DEG_relations_tag_update(pr_main); + BKE_scene_update_tagged(pr_main->eval_ctx, pr_main, sce); + return sce; } @@ -593,7 +671,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); @@ -1022,6 +1102,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); |