diff options
author | Lukas Tönne <lukas.toenne@gmail.com> | 2018-08-12 14:52:49 +0300 |
---|---|---|
committer | Lukas Tönne <lukas.toenne@gmail.com> | 2018-08-12 14:52:49 +0300 |
commit | dc2d841b7c50565302af2986d62ddbd29c332acd (patch) | |
tree | 324f234e56fde77fb80dfdef0c7c21f01968f71b /source/blender/editors/render | |
parent | 27b28e437d974ebbafa234205941c07aa0ab546c (diff) | |
parent | 4b6fa4d897a0bb3252b16383492b526d2cef3920 (diff) |
Merge branch 'blender2.8' into hair_guideshair_guides
Diffstat (limited to 'source/blender/editors/render')
-rw-r--r-- | source/blender/editors/render/render_opengl.c | 98 | ||||
-rw-r--r-- | source/blender/editors/render/render_preview.c | 221 | ||||
-rw-r--r-- | source/blender/editors/render/render_shading.c | 8 | ||||
-rw-r--r-- | source/blender/editors/render/render_update.c | 2 |
4 files changed, 165 insertions, 164 deletions
diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index b5c1ffc64dd..ed7950f3993 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -326,10 +326,10 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R GPU_clear(GPU_COLOR_BIT | GPU_DEPTH_BIT); wmOrtho2(0, sizex, 0, sizey); - gpuTranslate2f(sizex / 2, sizey / 2); + GPU_matrix_translate_2f(sizex / 2, sizey / 2); G.f |= G_RENDER_OGL; - ED_gpencil_draw_ex(scene, gpd, sizex, sizey, scene->r.cfra, SPACE_SEQ); + ED_gpencil_draw_ex(rv3d, scene, gpd, sizex, sizey, scene->r.cfra, SPACE_SEQ); G.f &= ~G_RENDER_OGL; gp_rect = MEM_mallocN(sizex * sizey * sizeof(unsigned char) * 4, "offscreen rect"); @@ -355,7 +355,7 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R if (view_context) { ibuf_view = ED_view3d_draw_offscreen_imbuf( - depsgraph, scene, v3d->drawtype, + depsgraph, scene, v3d->shading.type, v3d, ar, sizex, sizey, IB_rectfloat, draw_flags, alpha_mode, oglrender->ofs_samples, viewname, oglrender->ofs, err_out); @@ -417,7 +417,7 @@ static void screen_opengl_render_write(OGLRender *oglrender) else printf("OpenGL Render failed to write '%s'\n", name); } -static void addAlphaOverFloat(float dest[4], const float source[4]) +static void UNUSED_FUNCTION(addAlphaOverFloat)(float dest[4], const float source[4]) { /* d = s + (1-alpha_s)d*/ float mul; @@ -431,91 +431,6 @@ static void addAlphaOverFloat(float dest[4], const float source[4]) } -/* add renderlayer and renderpass for each grease pencil layer for using in composition */ -static void add_gpencil_renderpass(const bContext *C, OGLRender *oglrender, RenderResult *rr, RenderView *rv) -{ - bGPdata *gpd = oglrender->scene->gpd; - Scene *scene = oglrender->scene; - - /* sanity checks */ - if (gpd == NULL) { - return; - } - if (scene == NULL) { - return; - } - if (BLI_listbase_is_empty(&gpd->layers)) { - return; - } - if (oglrender->v3d != NULL && (oglrender->v3d->flag2 & V3D_SHOW_GPENCIL) == 0) { - return; - } - - /* save old alpha mode */ - short oldalphamode = scene->r.alphamode; - /* set alpha transparent for gp */ - scene->r.alphamode = R_ALPHAPREMUL; - - /* saves layer status */ - short *oldsts = MEM_mallocN(BLI_listbase_count(&gpd->layers) * sizeof(short), "temp_gplayers_flag"); - int i = 0; - for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { - oldsts[i] = gpl->flag; - ++i; - } - /* loop all layers to create separate render */ - for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { - /* dont draw layer if hidden */ - if (gpl->flag & GP_LAYER_HIDE) - continue; - /* hide all layer except current */ - for (bGPDlayer *gph = gpd->layers.first; gph; gph = gph->next) { - if (gpl != gph) { - gph->flag |= GP_LAYER_HIDE; - } - } - - /* render this gp layer */ - screen_opengl_render_doit(C, oglrender, rr); - - /* add RendePass composite */ - RenderPass *rp = RE_create_gp_pass(rr, gpl->info, rv->name); - - /* copy image data from rectf */ - // XXX: Needs conversion. - unsigned char *src = (unsigned char *)RE_RenderViewGetById(rr, oglrender->view_id)->rect32; - if (src != NULL) { - float *dest = rp->rect; - - int x, y, rectx, recty; - rectx = rr->rectx; - recty = rr->recty; - for (y = 0; y < recty; y++) { - for (x = 0; x < rectx; x++) { - unsigned char *pixSrc = src + 4 * (rectx * y + x); - if (pixSrc[3] > 0) { - float *pixDest = dest + 4 * (rectx * y + x); - float float_src[4]; - srgb_to_linearrgb_uchar4(float_src, pixSrc); - addAlphaOverFloat(pixDest, float_src); - } - } - } - } - /* back layer status */ - i = 0; - for (bGPDlayer *gph = gpd->layers.first; gph; gph = gph->next) { - gph->flag = oldsts[i]; - ++i; - } - } - /* free memory */ - MEM_freeN(oldsts); - - /* back default alpha mode */ - scene->r.alphamode = oldalphamode; -} - static void screen_opengl_render_apply(const bContext *C, OGLRender *oglrender) { RenderResult *rr; @@ -550,11 +465,6 @@ static void screen_opengl_render_apply(const bContext *C, OGLRender *oglrender) BLI_assert(view_id < oglrender->views_len); RE_SetActiveRenderView(oglrender->re, rv->name); oglrender->view_id = view_id; - /* add grease pencil passes. For sequencer, the render does not include renderpasses - * TODO: The sequencer render of grease pencil should be rethought */ - if (!oglrender->is_sequencer) { - add_gpencil_renderpass(C, oglrender, rr, rv); - } /* render composite */ screen_opengl_render_doit(C, oglrender, rr); } diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 04632838cf3..8bb60b19dcf 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -158,7 +158,7 @@ typedef struct ShaderPreview { Scene *scene; Depsgraph *depsgraph; - ID *id; + ID *id, *id_copy; ID *parent; MTex *slot; @@ -173,6 +173,7 @@ typedef struct ShaderPreview { int sizex, sizey; unsigned int *pr_rect; int pr_method; + bool own_id_copy; Main *bmain; Main *pr_main; @@ -189,7 +190,7 @@ typedef struct IconPreview { Scene *scene; Depsgraph *depsgraph; void *owner; - ID *id; + ID *id, *id_copy; ListBase sizes; } IconPreview; @@ -197,6 +198,7 @@ typedef struct IconPreview { static Main *G_pr_main = NULL; static Main *G_pr_main_cycles = NULL; +static Main *G_pr_main_grease_pencil = NULL; #ifndef WITH_HEADLESS static Main *load_main_from_memory(const void *blend, int blend_size) @@ -226,6 +228,7 @@ void ED_preview_ensure_dbase(void) if (!base_initialized) { G_pr_main = load_main_from_memory(datatoc_preview_blend, datatoc_preview_blend_size); G_pr_main_cycles = load_main_from_memory(datatoc_preview_cycles_blend, datatoc_preview_cycles_blend_size); + G_pr_main_grease_pencil = load_main_from_memory(datatoc_preview_grease_pencil_blend, datatoc_preview_grease_pencil_blend_size); base_initialized = true; } #endif @@ -234,7 +237,13 @@ void ED_preview_ensure_dbase(void) static bool check_engine_supports_textures(Scene *scene) { RenderEngineType *type = RE_engines_find(scene->r.engine); - return type->flag & RE_USE_TEXTURE_PREVIEW; + return (type->flag & RE_USE_TEXTURE_PREVIEW) != 0; +} + +static bool check_engine_supports_preview(Scene *scene) +{ + RenderEngineType *type = RE_engines_find(scene->r.engine); + return (type->flag & RE_USE_PREVIEW) != 0; } void ED_preview_free_dbase(void) @@ -244,6 +253,9 @@ void ED_preview_free_dbase(void) if (G_pr_main_cycles) BKE_main_free(G_pr_main_cycles); + + if (G_pr_main_grease_pencil) + BKE_main_free(G_pr_main_grease_pencil); } static Scene *preview_get_scene(Main *pr_main) @@ -312,6 +324,38 @@ static World *preview_get_localized_world(ShaderPreview *sp, World *world) return sp->worldcopy; } +static ID *duplicate_ids(ID *id, Depsgraph *depsgraph) +{ + if (id == NULL) { + /* Non-ID preview render. */ + return NULL; + } + + ID *id_eval = id; + + if (depsgraph) { + id_eval = DEG_get_evaluated_id(depsgraph, id); + } + + switch (GS(id->name)) { + case ID_MA: + return (ID *)BKE_material_localize((Material *)id_eval); + case ID_TE: + return (ID *)BKE_texture_localize((Tex *)id_eval); + case ID_LA: + return (ID *)BKE_lamp_localize((Lamp *)id_eval); + case ID_WO: + return (ID *)BKE_world_localize((World *)id_eval); + case ID_IM: + case ID_BR: + case ID_SCR: + return NULL; + default: + BLI_assert(!"ID type preview not supported."); + return NULL; + } +} + /* 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) @@ -373,8 +417,9 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty if (origmat) { /* work on a copy */ - mat = BKE_material_localize(origmat); - sp->matcopy = mat; + BLI_assert(sp->id_copy != NULL); + mat = sp->matcopy = (Material *)sp->id_copy; + sp->id_copy = NULL; BLI_addtail(&pr_main->mat, mat); /* use current scene world to light sphere */ @@ -400,13 +445,13 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty 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); + /* WATCH: Accessing origmat is not safe! */ BKE_node_preview_init_tree(origmat->nodetree, sp->sizex, sp->sizey, true); } } } else { sce->r.mode &= ~(R_OSA); - } for (Base *base = view_layer->object_bases.first; base; base = base->next) { @@ -432,16 +477,18 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty Tex *tex = NULL, *origtex = (Tex *)id; if (origtex) { - tex = BKE_texture_localize(origtex); - sp->texcopy = tex; + BLI_assert(sp->id_copy != NULL); + tex = sp->texcopy = (Tex *)sp->id_copy; + sp->id_copy = NULL; BLI_addtail(&pr_main->tex, tex); } set_preview_collection(sce, view_layer, MA_TEXTURE); if (tex && tex->nodetree && sp->pr_method == PR_NODE_RENDER) { /* two previews, they get copied by wmJob */ - BKE_node_preview_init_tree(origtex->nodetree, sp->sizex, sp->sizey, true); BKE_node_preview_init_tree(tex->nodetree, sp->sizex, sp->sizey, true); + /* WATCH: Accessing origtex is not safe! */ + BKE_node_preview_init_tree(origtex->nodetree, sp->sizex, sp->sizey, true); } } else if (id_type == ID_LA) { @@ -449,8 +496,9 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty /* work on a copy */ if (origla) { - la = BKE_lamp_localize(origla); - sp->lampcopy = la; + BLI_assert(sp->id_copy != NULL); + la = sp->lampcopy = (Lamp *)sp->id_copy; + sp->id_copy = NULL; BLI_addtail(&pr_main->lamp, la); } @@ -473,16 +521,18 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty if (la && la->nodetree && sp->pr_method == PR_NODE_RENDER) { /* two previews, they get copied by wmJob */ - BKE_node_preview_init_tree(origla->nodetree, sp->sizex, sp->sizey, true); BKE_node_preview_init_tree(la->nodetree, sp->sizex, sp->sizey, true); + /* WATCH: Accessing origla is not safe! */ + BKE_node_preview_init_tree(origla->nodetree, sp->sizex, sp->sizey, true); } } else if (id_type == ID_WO) { World *wrld = NULL, *origwrld = (World *)id; if (origwrld) { - wrld = BKE_world_localize(origwrld); - sp->worldcopy = wrld; + BLI_assert(sp->id_copy != NULL); + wrld = sp->worldcopy = (World *)sp->id_copy; + sp->id_copy = NULL; BLI_addtail(&pr_main->world, wrld); } @@ -492,6 +542,7 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty if (wrld && wrld->nodetree && sp->pr_method == PR_NODE_RENDER) { /* two previews, they get copied by wmJob */ BKE_node_preview_init_tree(wrld->nodetree, sp->sizex, sp->sizey, true); + /* WATCH: Accessing origwrld is not safe! */ BKE_node_preview_init_tree(origwrld->nodetree, sp->sizex, sp->sizey, true); } } @@ -685,7 +736,11 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs char name[32]; int sizex; Main *pr_main = sp->pr_main; - ID *id_eval = DEG_get_evaluated_id(sp->depsgraph, id); + ID *id_eval = id; + + if (sp->depsgraph) { + id_eval = DEG_get_evaluated_id(sp->depsgraph, id); + } /* in case of split preview, use border render */ if (split) { @@ -704,6 +759,7 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs sce->r.size = 100; } + /* get the stuff from the builtin preview dbase */ sce = preview_prepare_scene(sp->bmain, sp->scene, id_eval, idtype, sp); if (sce == NULL) return; @@ -795,70 +851,51 @@ static void shader_preview_free(void *customdata) Main *pr_main = sp->pr_main; if (sp->matcopy) { - struct IDProperty *properties; - - /* node previews */ - shader_preview_updatejob(sp); - - /* get rid of copied material */ + sp->id_copy = (ID *)sp->matcopy; BLI_remlink(&pr_main->mat, sp->matcopy); - - BKE_material_free(sp->matcopy); - - properties = IDP_GetProperties((ID *)sp->matcopy, false); - if (properties) { - IDP_FreeProperty(properties); - MEM_freeN(properties); - } - MEM_freeN(sp->matcopy); } if (sp->texcopy) { - struct IDProperty *properties; - /* node previews */ - shader_preview_updatejob(sp); - - /* get rid of copied texture */ + sp->id_copy = (ID *)sp->texcopy; BLI_remlink(&pr_main->tex, sp->texcopy); - BKE_texture_free(sp->texcopy); - - properties = IDP_GetProperties((ID *)sp->texcopy, false); - if (properties) { - IDP_FreeProperty(properties); - MEM_freeN(properties); - } - MEM_freeN(sp->texcopy); } if (sp->worldcopy) { - struct IDProperty *properties; - /* node previews */ - shader_preview_updatejob(sp); - - /* get rid of copied world */ + sp->id_copy = (ID *)sp->worldcopy; BLI_remlink(&pr_main->world, sp->worldcopy); - BKE_world_free(sp->worldcopy); - - properties = IDP_GetProperties((ID *)sp->worldcopy, false); - if (properties) { - IDP_FreeProperty(properties); - MEM_freeN(properties); - } - MEM_freeN(sp->worldcopy); } if (sp->lampcopy) { - struct IDProperty *properties; + sp->id_copy = (ID *)sp->lampcopy; + BLI_remlink(&pr_main->lamp, sp->lampcopy); + } + if (sp->id_copy) { /* node previews */ shader_preview_updatejob(sp); - - /* get rid of copied lamp */ - BLI_remlink(&pr_main->lamp, sp->lampcopy); - BKE_lamp_free(sp->lampcopy); - - properties = IDP_GetProperties((ID *)sp->lampcopy, false); + } + if (sp->id_copy && sp->own_id_copy) { + struct IDProperty *properties; + /* get rid of copied ID */ + properties = IDP_GetProperties(sp->id_copy, false); if (properties) { IDP_FreeProperty(properties); MEM_freeN(properties); } - MEM_freeN(sp->lampcopy); + switch (GS(sp->id_copy->name)) { + case ID_MA: + BKE_material_free((Material *)sp->id_copy); + break; + case ID_TE: + BKE_texture_free((Tex *)sp->id_copy); + break; + case ID_LA: + BKE_lamp_free((Lamp *)sp->id_copy); + break; + case ID_WO: + BKE_world_free((World *)sp->id_copy); + break; + default: + BLI_assert(!"ID type preview not supported."); + break; + } + MEM_freeN(sp->id_copy); } MEM_freeN(sp); @@ -1062,6 +1099,10 @@ static void icon_preview_startjob_all_sizes(void *customdata, short *stop, short continue; } + if (!check_engine_supports_preview(ip->scene)) { + continue; + } + ShaderPreview *sp = MEM_callocN(sizeof(ShaderPreview), "Icon ShaderPreview"); const bool is_render = !(prv->tag & PRV_TAG_DEFFERED); @@ -1074,7 +1115,10 @@ static void icon_preview_startjob_all_sizes(void *customdata, short *stop, short sp->pr_method = is_render ? PR_ICON_RENDER : PR_ICON_DEFERRED; sp->pr_rect = cur_size->rect; sp->id = ip->id; + sp->id_copy = ip->id_copy; sp->bmain = ip->bmain; + sp->own_id_copy = false; + Material *ma = NULL; if (is_render) { BLI_assert(ip->id); @@ -1082,10 +1126,22 @@ static void icon_preview_startjob_all_sizes(void *customdata, short *stop, short * so don't even think of using cycle's bmain for * texture icons */ - if (GS(ip->id->name) != ID_TE) - sp->pr_main = G_pr_main_cycles; - else + if (GS(ip->id->name) != ID_TE) { + /* grease pencil use its own preview file */ + if (GS(ip->id->name) == ID_MA) { + ma = (Material *)ip->id; + } + + if ((ma == NULL) || (ma->gp_style == NULL)) { + sp->pr_main = G_pr_main_cycles; + } + else { + sp->pr_main = G_pr_main_grease_pencil; + } + } + else { sp->pr_main = G_pr_main; + } } common_preview_startjob(sp, stop, do_update, progress); @@ -1133,6 +1189,15 @@ static void icon_preview_free(void *customdata) { IconPreview *ip = (IconPreview *)customdata; + if (ip->id_copy) { + /* Feels a bit hacky just to reuse shader_preview_free() */ + ShaderPreview *sp = MEM_callocN(sizeof(ShaderPreview), "Icon ShaderPreview"); + sp->id_copy = ip->id_copy; + sp->own_id_copy = true; + shader_preview_free(sp); + ip->id_copy = NULL; + } + BLI_freelistN(&ip->sizes); MEM_freeN(ip); } @@ -1149,6 +1214,7 @@ void ED_preview_icon_render(Main *bmain, Scene *scene, ID *id, unsigned int *rec ip.scene = scene; ip.owner = BKE_previewimg_id_ensure(id); ip.id = id; + ip.id_copy = duplicate_ids(id, NULL); icon_preview_add_size(&ip, rect, sizex, sizey); @@ -1183,6 +1249,7 @@ void ED_preview_icon_job(const bContext *C, void *owner, ID *id, unsigned int *r ip->depsgraph = CTX_data_depsgraph(C); ip->owner = owner; ip->id = id; + ip->id_copy = duplicate_ids(id, ip->depsgraph); icon_preview_add_size(ip, rect, sizex, sizey); @@ -1212,6 +1279,10 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, M /* Use workspace render only for buttons Window, since the other previews are related to the datablock. */ + if (!check_engine_supports_preview(scene)) { + return; + } + /* Only texture node preview is supported with Cycles. */ if (method == PR_NODE_RENDER && id_type != ID_TE) { return; @@ -1231,14 +1302,28 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, M sp->sizey = sizey; sp->pr_method = method; sp->id = id; + sp->id_copy = duplicate_ids(id, sp->depsgraph); + sp->own_id_copy = true; sp->parent = parent; sp->slot = slot; sp->bmain = CTX_data_main(C); + Material *ma = NULL; /* hardcoded preview .blend for Eevee + Cycles, this should be solved * once with custom preview .blend path for external engines */ if ((method != PR_NODE_RENDER) && id_type != ID_TE) { - sp->pr_main = G_pr_main_cycles; + /* grease pencil use its own preview file */ + if (GS(id->name) == ID_MA) { + ma = (Material *)id; + } + + if ((ma == NULL) || (ma->gp_style == NULL)) { + sp->pr_main = G_pr_main_cycles; + } + else { + sp->pr_main = G_pr_main_grease_pencil; + } + } else { sp->pr_main = G_pr_main; diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c index 8077079a9b5..2dd4f328d06 100644 --- a/source/blender/editors/render/render_shading.c +++ b/source/blender/editors/render/render_shading.c @@ -469,6 +469,7 @@ static int new_material_exec(bContext *C, wmOperator *UNUSED(op)) { Material *ma = CTX_data_pointer_get_type(C, "material", &RNA_Material).data; Main *bmain = CTX_data_main(C); + Object *ob = CTX_data_active_object(C); PointerRNA ptr, idptr; PropertyRNA *prop; @@ -477,7 +478,12 @@ static int new_material_exec(bContext *C, wmOperator *UNUSED(op)) ma = BKE_material_copy(bmain, ma); } else { - ma = BKE_material_add(bmain, DATA_("Material")); + if ((!ob) || (ob->type != OB_GPENCIL)) { + ma = BKE_material_add(bmain, DATA_("Material")); + } + else { + ma = BKE_material_add_gpencil(bmain, DATA_("Material")); + } ED_node_shader_default(C, &ma->id); ma->use_nodes = true; } diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c index e473b98b4a1..09d89e3b90f 100644 --- a/source/blender/editors/render/render_update.c +++ b/source/blender/editors/render/render_update.c @@ -144,7 +144,7 @@ void ED_render_scene_update(const DEGEditorUpdateContext *update_ctx, int update } else { RenderEngineType *engine_type = - ED_view3d_engine_type(scene, v3d->drawtype); + ED_view3d_engine_type(scene, v3d->shading.type); if (updated) { DRW_notify_view_update( (&(DRWUpdateContext){ |