Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/render/render_preview.c')
-rw-r--r--source/blender/editors/render/render_preview.c170
1 files changed, 134 insertions, 36 deletions
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index 9656a57e2b7..2e3091268a9 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,50 +421,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 = 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)
- 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(view_layer, MA_FLAT);
}
else {
- sce->lay = 1 << MA_SPHERE_A;
+ set_preview_layer(view_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(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);
@@ -413,7 +487,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);
@@ -427,7 +501,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 +514,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]) {
@@ -481,21 +555,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(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);
+ }
- 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;
@@ -517,7 +593,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) {
@@ -527,6 +603,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(pr_main->eval_ctx, depsgraph, pr_main, sce, view_layer);
+
return sce;
}
@@ -593,7 +675,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);
@@ -775,7 +859,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;
@@ -1022,6 +1106,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);
@@ -1096,6 +1186,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;
@@ -1180,6 +1271,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;
@@ -1213,6 +1305,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;
@@ -1240,8 +1333,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) {
@@ -1264,6 +1361,7 @@ 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
* once with custom preview .blend path for external engines */