diff options
23 files changed, 129 insertions, 12 deletions
diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h index 0cfa1fe7d6a..c4946e2a4b8 100644 --- a/source/blender/draw/DRW_engine.h +++ b/source/blender/draw/DRW_engine.h @@ -46,6 +46,7 @@ struct View3D; struct rcti; struct GPUOffScreen; struct GPUViewport; +struct RenderEngine; struct RenderEngineType; struct WorkSpace; @@ -67,6 +68,7 @@ typedef struct DefaultTextureList { void DRW_engines_register(void); void DRW_engines_free(void); +bool DRW_engine_render_support(struct DrawEngineType *draw_engine_type); void DRW_engine_register(struct DrawEngineType *draw_engine_type); void DRW_engine_viewport_data_size_get( const void *engine_type, diff --git a/source/blender/draw/engines/basic/basic_engine.c b/source/blender/draw/engines/basic/basic_engine.c index 10dfe7b5996..31a431e3001 100644 --- a/source/blender/draw/engines/basic/basic_engine.c +++ b/source/blender/draw/engines/basic/basic_engine.c @@ -264,6 +264,7 @@ DrawEngineType draw_engine_basic_type = { &basic_draw_scene, NULL, NULL, + NULL, }; /* Note: currently unused, we may want to register so we can see this when debugging the view. */ diff --git a/source/blender/draw/engines/clay/clay_engine.c b/source/blender/draw/engines/clay/clay_engine.c index a9a919f7ac2..d2bf164efdc 100644 --- a/source/blender/draw/engines/clay/clay_engine.c +++ b/source/blender/draw/engines/clay/clay_engine.c @@ -949,6 +949,7 @@ DrawEngineType draw_engine_clay_type = { &clay_draw_scene, NULL, NULL, + NULL, }; RenderEngineType DRW_engine_viewport_clay_type = { diff --git a/source/blender/draw/engines/external/external_engine.c b/source/blender/draw/engines/external/external_engine.c index 851d0ef9eb7..ec0141953fe 100644 --- a/source/blender/draw/engines/external/external_engine.c +++ b/source/blender/draw/engines/external/external_engine.c @@ -218,6 +218,7 @@ DrawEngineType draw_engine_external_type = { &external_draw_scene, NULL, NULL, + NULL, }; /* Note: currently unused, we should not register unless we want to see this when debugging the view. */ diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h index f5943f2130b..a9ab2d2cf0e 100644 --- a/source/blender/draw/intern/DRW_render.h +++ b/source/blender/draw/intern/DRW_render.h @@ -139,6 +139,8 @@ typedef struct DrawEngineType { void (*view_update)(void *vedata); void (*id_update)(void *vedata, struct ID *id); + + void (*render_to_image)(void *vedata, struct RenderEngine *engine, struct Depsgraph *graph); } DrawEngineType; #ifndef __DRW_ENGINE_H__ @@ -386,6 +388,11 @@ struct DefaultTextureList *DRW_viewport_texture_list_get(void); void DRW_viewport_request_redraw(void); +void DRW_render_to_image(struct RenderEngine *re, struct Depsgraph *depsgraph); +void DRW_render_object_iter( + void *vedata, struct RenderEngine *engine, struct Depsgraph *graph, + void (*callback)(void *vedata, struct Object *ob, struct RenderEngine *engine, struct Depsgraph *graph)); + /* ViewLayers */ void *DRW_view_layer_engine_data_get(DrawEngineType *engine_type); void **DRW_view_layer_engine_data_ensure(DrawEngineType *engine_type, void (*callback)(void *storage)); diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 70b246047a9..a882c89ff88 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -2365,7 +2365,9 @@ void DRW_framebuffer_init( } } - GPU_framebuffer_bind(DST.default_framebuffer); + if (DST.default_framebuffer != NULL) { + GPU_framebuffer_bind(DST.default_framebuffer); + } } } @@ -2626,14 +2628,17 @@ static void drw_viewport_var_init(void) DST.default_framebuffer = NULL; DST.vmempool = NULL; } - /* Refresh DST.screenvecs */ - copy_v3_v3(DST.screenvecs[0], rv3d->viewinv[0]); - copy_v3_v3(DST.screenvecs[1], rv3d->viewinv[1]); - normalize_v3(DST.screenvecs[0]); - normalize_v3(DST.screenvecs[1]); - /* Refresh DST.pixelsize */ - DST.pixsize = rv3d->pixsize; + if (rv3d != NULL) { + /* Refresh DST.screenvecs */ + copy_v3_v3(DST.screenvecs[0], rv3d->viewinv[0]); + copy_v3_v3(DST.screenvecs[1], rv3d->viewinv[1]); + normalize_v3(DST.screenvecs[0]); + normalize_v3(DST.screenvecs[1]); + + /* Refresh DST.pixelsize */ + DST.pixsize = rv3d->pixsize; + } /* Reset facing */ DST.frontface = GL_CCW; @@ -2664,6 +2669,7 @@ void DRW_viewport_matrix_get(float mat[4][4], DRWViewportMatrixType type) copy_m4_m4(mat, viewport_matrix_override.mat[type]); } else { + BLI_assert(rv3d != NULL); /* Can't use this in render mode. */ switch (type) { case DRW_MAT_PERS: copy_m4_m4(mat, rv3d->persmat); @@ -2704,6 +2710,7 @@ void DRW_viewport_matrix_override_unset(DRWViewportMatrixType type) bool DRW_viewport_is_persp_get(void) { RegionView3D *rv3d = DST.draw_ctx.rv3d; + BLI_assert(rv3d); return rv3d->is_persp; } @@ -3422,9 +3429,7 @@ void DRW_draw_render_loop_ex( /* Init engines */ drw_engines_init(); - /* TODO : tag to refresh by the dependency graph */ - /* ideally only refresh when objects are added/removed */ - /* or render properties / materials change */ + /* Cache filling */ { PROFILE_START(stime); drw_engines_cache_init(); @@ -3569,6 +3574,70 @@ void DRW_draw_render_loop_offscreen( GPU_offscreen_bind(ofs, false); } +void DRW_render_to_image(RenderEngine *re, struct Depsgraph *depsgraph) +{ + Scene *scene = DEG_get_evaluated_scene(depsgraph); + ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph); + RenderEngineType *engine_type = re->type; + DrawEngineType *draw_engine_type = engine_type->draw_engine; + RenderData *r = &scene->r; + + /* Reset before using it. */ + memset(&DST, 0x0, sizeof(DST)); + DST.options.is_image_render = true; + + DST.draw_ctx = (DRWContextState){ + NULL, NULL, NULL, scene, view_layer, OBACT(view_layer), engine_type, depsgraph, NULL + }; + + DST.viewport = GPU_viewport_create(); + const int size[2] = {(r->size * r->xsch) / 100, (r->size * r->ysch) / 100}; + GPU_viewport_size_set(DST.viewport, size); + + drw_viewport_var_init(); + + ViewportEngineData *data = DRW_viewport_engine_data_ensure(draw_engine_type); + + /* set default viewport */ + gpuPushAttrib(GPU_ENABLE_BIT | GPU_VIEWPORT_BIT); + glDisable(GL_SCISSOR_TEST); + glViewport(0, 0, size[0], size[1]); + + engine_type->draw_engine->render_to_image(data, re, depsgraph); + + /* TODO grease pencil */ + + GPU_viewport_free(DST.viewport); + MEM_freeN(DST.viewport); + + DRW_state_reset(); + /* FIXME GL_DEPTH_TEST is enabled by default but it seems + * to trigger some bad behaviour / artifacts if it's turned + * on at this point. */ + glDisable(GL_DEPTH_TEST); + + /* Restore Drawing area. */ + gpuPopAttrib(); + glEnable(GL_SCISSOR_TEST); + GPU_framebuffer_restore(); + +#ifdef DEBUG + /* Avoid accidental reuse. */ + memset(&DST, 0xFF, sizeof(DST)); +#endif +} + +void DRW_render_object_iter( + void *vedata, RenderEngine *engine, struct Depsgraph *depsgraph, + void (*callback)(void *vedata, Object *ob, RenderEngine *engine, struct Depsgraph *depsgraph)) +{ + DEG_OBJECT_ITER_FOR_RENDER_ENGINE(depsgraph, ob, DRW_iterator_mode_get()) + { + callback(vedata, ob, engine, depsgraph); + } + DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END +} + /** * object mode select-loop, see: ED_view3d_draw_select_loop (legacy drawing). */ @@ -3796,7 +3865,7 @@ void DRW_state_dfdy_factors_get(float dfdyfac[2]) */ bool DRW_state_is_fbo(void) { - return (DST.default_framebuffer != NULL); + return ((DST.default_framebuffer != NULL) || DST.options.is_image_render); } /** @@ -3894,6 +3963,11 @@ const DRWContextState *DRW_context_state_get(void) /** \name Init/Exit (DRW_engines) * \{ */ +bool DRW_engine_render_support(DrawEngineType *draw_engine_type) +{ + return draw_engine_type->render_to_image; +} + void DRW_engine_register(DrawEngineType *draw_engine_type) { BLI_addtail(&DRW_engines, draw_engine_type); diff --git a/source/blender/draw/modes/edit_armature_mode.c b/source/blender/draw/modes/edit_armature_mode.c index 4deb4f86692..3c0c33b1daa 100644 --- a/source/blender/draw/modes/edit_armature_mode.c +++ b/source/blender/draw/modes/edit_armature_mode.c @@ -154,4 +154,5 @@ DrawEngineType draw_engine_edit_armature_type = { NULL, &EDIT_ARMATURE_draw_scene, NULL, + NULL, }; diff --git a/source/blender/draw/modes/edit_curve_mode.c b/source/blender/draw/modes/edit_curve_mode.c index ec12f7570c2..54a1bd79572 100644 --- a/source/blender/draw/modes/edit_curve_mode.c +++ b/source/blender/draw/modes/edit_curve_mode.c @@ -347,4 +347,5 @@ DrawEngineType draw_engine_edit_curve_type = { NULL, /* draw_background but not needed by mode engines */ &EDIT_CURVE_draw_scene, NULL, + NULL, }; diff --git a/source/blender/draw/modes/edit_lattice_mode.c b/source/blender/draw/modes/edit_lattice_mode.c index ff4c557326e..e676677ff97 100644 --- a/source/blender/draw/modes/edit_lattice_mode.c +++ b/source/blender/draw/modes/edit_lattice_mode.c @@ -294,4 +294,5 @@ DrawEngineType draw_engine_edit_lattice_type = { NULL, /* draw_background but not needed by mode engines */ &EDIT_LATTICE_draw_scene, NULL, + NULL, }; diff --git a/source/blender/draw/modes/edit_mesh_mode.c b/source/blender/draw/modes/edit_mesh_mode.c index 1a8c03e3933..29ba658f79d 100644 --- a/source/blender/draw/modes/edit_mesh_mode.c +++ b/source/blender/draw/modes/edit_mesh_mode.c @@ -610,4 +610,5 @@ DrawEngineType draw_engine_edit_mesh_type = { NULL, &EDIT_MESH_draw_scene, NULL, + NULL, }; diff --git a/source/blender/draw/modes/edit_metaball_mode.c b/source/blender/draw/modes/edit_metaball_mode.c index a83f5ae33bc..78ceaf8b6f1 100644 --- a/source/blender/draw/modes/edit_metaball_mode.c +++ b/source/blender/draw/modes/edit_metaball_mode.c @@ -248,4 +248,5 @@ DrawEngineType draw_engine_edit_metaball_type = { NULL, /* draw_background but not needed by mode engines */ &EDIT_METABALL_draw_scene, NULL, + NULL, }; diff --git a/source/blender/draw/modes/edit_surface_mode.c b/source/blender/draw/modes/edit_surface_mode.c index 4e60c4abff5..8f0371925db 100644 --- a/source/blender/draw/modes/edit_surface_mode.c +++ b/source/blender/draw/modes/edit_surface_mode.c @@ -266,4 +266,5 @@ DrawEngineType draw_engine_edit_surface_type = { NULL, /* draw_background but not needed by mode engines */ &EDIT_SURFACE_draw_scene, NULL, + NULL, }; diff --git a/source/blender/draw/modes/edit_text_mode.c b/source/blender/draw/modes/edit_text_mode.c index b375bad84b5..60f28d89f4b 100644 --- a/source/blender/draw/modes/edit_text_mode.c +++ b/source/blender/draw/modes/edit_text_mode.c @@ -309,4 +309,5 @@ DrawEngineType draw_engine_edit_text_type = { NULL, /* draw_background but not needed by mode engines */ &EDIT_TEXT_draw_scene, NULL, + NULL, }; diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c index 4aa0d4141e4..f27f41c3d2a 100644 --- a/source/blender/draw/modes/object_mode.c +++ b/source/blender/draw/modes/object_mode.c @@ -2044,4 +2044,5 @@ DrawEngineType draw_engine_object_type = { NULL, &OBJECT_draw_scene, NULL, + NULL, }; diff --git a/source/blender/draw/modes/paint_texture_mode.c b/source/blender/draw/modes/paint_texture_mode.c index b49da0cba2f..2a5eabd08fa 100644 --- a/source/blender/draw/modes/paint_texture_mode.c +++ b/source/blender/draw/modes/paint_texture_mode.c @@ -414,4 +414,5 @@ DrawEngineType draw_engine_paint_texture_type = { NULL, /* draw_background but not needed by mode engines */ &PAINT_TEXTURE_draw_scene, NULL, + NULL, }; diff --git a/source/blender/draw/modes/paint_vertex_mode.c b/source/blender/draw/modes/paint_vertex_mode.c index e430fca5742..835fefdee26 100644 --- a/source/blender/draw/modes/paint_vertex_mode.c +++ b/source/blender/draw/modes/paint_vertex_mode.c @@ -213,4 +213,5 @@ DrawEngineType draw_engine_paint_vertex_type = { NULL, &PAINT_VERTEX_draw_scene, NULL, + NULL, }; diff --git a/source/blender/draw/modes/paint_weight_mode.c b/source/blender/draw/modes/paint_weight_mode.c index e139b4af97f..3cc2ad63ed4 100644 --- a/source/blender/draw/modes/paint_weight_mode.c +++ b/source/blender/draw/modes/paint_weight_mode.c @@ -251,4 +251,5 @@ DrawEngineType draw_engine_paint_weight_type = { NULL, &PAINT_WEIGHT_draw_scene, NULL, + NULL, }; diff --git a/source/blender/draw/modes/particle_mode.c b/source/blender/draw/modes/particle_mode.c index 6a3e53a72c2..0d0758971d5 100644 --- a/source/blender/draw/modes/particle_mode.c +++ b/source/blender/draw/modes/particle_mode.c @@ -261,4 +261,5 @@ DrawEngineType draw_engine_particle_type = { NULL, /* draw_background but not needed by mode engines */ &PARTICLE_draw_scene, NULL, + NULL, }; diff --git a/source/blender/draw/modes/pose_mode.c b/source/blender/draw/modes/pose_mode.c index 1c2acd56085..560773f2d05 100644 --- a/source/blender/draw/modes/pose_mode.c +++ b/source/blender/draw/modes/pose_mode.c @@ -195,4 +195,5 @@ DrawEngineType draw_engine_pose_type = { NULL, &POSE_draw_scene, NULL, + NULL, }; diff --git a/source/blender/draw/modes/sculpt_mode.c b/source/blender/draw/modes/sculpt_mode.c index d9f1f5ebe91..d8c5bae522b 100644 --- a/source/blender/draw/modes/sculpt_mode.c +++ b/source/blender/draw/modes/sculpt_mode.c @@ -302,4 +302,5 @@ DrawEngineType draw_engine_sculpt_type = { NULL, /* draw_background but not needed by mode engines */ &SCULPT_draw_scene, NULL, + NULL, }; diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index 80bdeaa8069..233365ec926 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -844,6 +844,7 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even Main *mainp; ViewLayer *view_layer = NULL; Scene *scene = CTX_data_scene(C); + RenderEngineType *re_type = RE_engines_find(scene->view_render.engine_id); Render *re; wmJob *wm_job; RenderJob *rj; @@ -856,6 +857,13 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even struct Object *camera_override = v3d ? V3D_CAMERA_LOCAL(v3d) : NULL; const char *name; ScrArea *sa; + + /* XXX FIXME If engine is an OpenGL engine do not run modal. + * This is a problem for animation rendering since you cannot abort them. + * This also does not open an image editor space. */ + if (RE_engine_is_opengl(re_type)) { + return screen_render_exec(C, op); + } /* only one render job at a time */ if (WM_jobs_test(CTX_wm_manager(C), scene, WM_JOB_TYPE_RENDER)) diff --git a/source/blender/render/extern/include/RE_engine.h b/source/blender/render/extern/include/RE_engine.h index 60ffd8f42e4..f789ab702fe 100644 --- a/source/blender/render/extern/include/RE_engine.h +++ b/source/blender/render/extern/include/RE_engine.h @@ -183,6 +183,8 @@ void RE_engines_init(void); void RE_engines_exit(void); void RE_engines_register(struct Main *bmain, RenderEngineType *render_type); +bool RE_engine_is_opengl(RenderEngineType *render_type); + RenderEngineType *RE_engines_find(const char *idname); rcti* RE_engine_get_current_tiles(struct Render *re, int *r_total_tiles, bool *r_needs_free); diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c index 68077d4d93b..2714e8b7685 100644 --- a/source/blender/render/intern/source/external_engine.c +++ b/source/blender/render/intern/source/external_engine.c @@ -155,6 +155,13 @@ bool RE_engine_is_external(Render *re) return (re->engine && re->engine->type && re->engine->type->render_to_image); } +bool RE_engine_is_opengl(RenderEngineType *render_type) +{ + /* TODO refine? Can we have ogl render engine without ogl render pipeline? */ + return (render_type->draw_engine != NULL) && + DRW_engine_render_support(render_type->draw_engine); +} + /* Create, Free */ RenderEngine *RE_engine_create(RenderEngineType *type) |