From 3f567535da163df7e77fe9438cc80fb8b2c67b87 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 3 May 2017 02:50:29 +1000 Subject: Draw Manager: OpenGL render support Works for clay-engine but doesn't draw objects with eevee. --- source/blender/draw/DRW_engine.h | 5 +++ source/blender/draw/intern/draw_manager.c | 36 ++++++++++++++++++++++ .../editors/space_view3d/view3d_draw_legacy.c | 13 +++++++- source/blender/gpu/GPU_framebuffer.h | 4 +++ source/blender/gpu/GPU_viewport.h | 3 ++ source/blender/gpu/intern/gpu_framebuffer.c | 9 ++++++ source/blender/gpu/intern/gpu_viewport.c | 18 +++++++++++ 7 files changed, 87 insertions(+), 1 deletion(-) (limited to 'source/blender') diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h index 6b3aee73229..8811309bcc1 100644 --- a/source/blender/draw/DRW_engine.h +++ b/source/blender/draw/DRW_engine.h @@ -41,6 +41,7 @@ struct ViewContext; struct ViewportEngineData; struct View3D; struct rcti; +struct GPUOffScreen; #include "BLI_sys_types.h" /* for bool */ @@ -67,6 +68,10 @@ void DRW_draw_view(const struct bContext *C); void DRW_draw_render_loop( struct Depsgraph *graph, struct View3D *v3d, struct ARegion *ar); +void DRW_draw_render_loop_offscreen( + struct Depsgraph *graph, + struct View3D *v3d, struct ARegion *ar, + struct GPUOffScreen *ofs); void DRW_draw_select_loop( struct Depsgraph *graph, struct View3D *v3d, struct ARegion *ar, diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index f116ecbc8b4..07182ef2774 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -2188,6 +2188,11 @@ void DRW_draw_view(const bContext *C) DRW_draw_render_loop(graph, v3d, ar); } +/** + * Used for both regular drawing and off-screen drawing. + * + * \param ofs: When not NULL, use this data to create the viewport. + */ void DRW_draw_render_loop( struct Depsgraph *graph, View3D *v3d, ARegion *ar) @@ -2273,6 +2278,37 @@ void DRW_draw_render_loop( memset(&DST, 0x0, sizeof(DST)); } +void DRW_draw_render_loop_offscreen( + struct Depsgraph *graph, + View3D *v3d, ARegion *ar, GPUOffScreen *ofs) +{ + RegionView3D *rv3d = ar->regiondata; + + /* backup */ + void *backup_viewport = rv3d->viewport; + { + /* backup (_never_ use rv3d->viewport) */ + rv3d->viewport = GPU_viewport_create_from_offscreen(ofs); + } + + DST.draw_ctx.evil_C = NULL; + + DRW_draw_render_loop(graph, v3d, ar); + + /* restore */ + { + /* don't free data owned by 'ofs' */ + GPU_viewport_clear_from_offscreen(rv3d->viewport); + GPU_viewport_free(rv3d->viewport); + MEM_freeN(rv3d->viewport); + + rv3d->viewport = backup_viewport; + } + + /* we need to re-bind (annoying!) */ + GPU_offscreen_bind(ofs, false); +} + /** * object mode select-loop, see: ED_view3d_draw_select_loop (legacy drawing). */ diff --git a/source/blender/editors/space_view3d/view3d_draw_legacy.c b/source/blender/editors/space_view3d/view3d_draw_legacy.c index 60b9cbb3b1c..66876efd3e9 100644 --- a/source/blender/editors/space_view3d/view3d_draw_legacy.c +++ b/source/blender/editors/space_view3d/view3d_draw_legacy.c @@ -107,6 +107,10 @@ #include "GPU_select.h" #include "GPU_matrix.h" +#include "RE_engine.h" + +#include "DRW_engine.h" + #include "view3d_intern.h" /* own include */ /* prototypes */ @@ -1811,7 +1815,14 @@ void ED_view3d_draw_offscreen( } /* main drawing call */ - view3d_draw_objects(NULL, scene, v3d, ar, NULL, do_bgpic, true, do_compositing ? fx : NULL); + RenderEngineType *type = RE_engines_find(scene->r.engine); + if (IS_VIEWPORT_LEGACY(v3d) && ((type->flag & RE_USE_LEGACY_PIPELINE) != 0)) { + view3d_draw_objects(NULL, scene, v3d, ar, NULL, do_bgpic, true, do_compositing ? fx : NULL); + } + else { + /* XXX, should take depsgraph as arg */ + DRW_draw_render_loop_offscreen(scene->depsgraph, v3d, ar, ofs); + } /* post process */ if (do_compositing) { diff --git a/source/blender/gpu/GPU_framebuffer.h b/source/blender/gpu/GPU_framebuffer.h index 349e11ceb44..92f5d8a3796 100644 --- a/source/blender/gpu/GPU_framebuffer.h +++ b/source/blender/gpu/GPU_framebuffer.h @@ -84,6 +84,10 @@ int GPU_offscreen_width(const GPUOffScreen *ofs); int GPU_offscreen_height(const GPUOffScreen *ofs); int GPU_offscreen_color_texture(const GPUOffScreen *ofs); +void GPU_offscreen_viewport_data_get( + GPUOffScreen *ofs, + GPUFrameBuffer **r_fb, struct GPUTexture **r_color, struct GPUTexture **r_depth); + #ifdef __cplusplus } #endif diff --git a/source/blender/gpu/GPU_viewport.h b/source/blender/gpu/GPU_viewport.h index 93bf96a5830..2585fcae24c 100644 --- a/source/blender/gpu/GPU_viewport.h +++ b/source/blender/gpu/GPU_viewport.h @@ -88,6 +88,9 @@ void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect); void GPU_viewport_unbind(GPUViewport *viewport); void GPU_viewport_free(GPUViewport *viewport); +GPUViewport *GPU_viewport_create_from_offscreen(struct GPUOffScreen *ofs); +void GPU_viewport_clear_from_offscreen(GPUViewport *viewport); + void *GPU_viewport_engine_data_create(GPUViewport *viewport, void *engine_type); void *GPU_viewport_engine_data_get(GPUViewport *viewport, void *engine_type); void *GPU_viewport_framebuffer_list_get(GPUViewport *viewport); diff --git a/source/blender/gpu/intern/gpu_framebuffer.c b/source/blender/gpu/intern/gpu_framebuffer.c index 52e9a6aec3a..09e80eeac9e 100644 --- a/source/blender/gpu/intern/gpu_framebuffer.c +++ b/source/blender/gpu/intern/gpu_framebuffer.c @@ -682,3 +682,12 @@ int GPU_offscreen_color_texture(const GPUOffScreen *ofs) return GPU_texture_opengl_bindcode(ofs->color); } +/* only to be used by viewport code! */ +void GPU_offscreen_viewport_data_get( + GPUOffScreen *ofs, + GPUFrameBuffer **r_fb, GPUTexture **r_color, GPUTexture **r_depth) +{ + *r_fb = ofs->fb; + *r_color = ofs->color; + *r_depth = ofs->depth; +} \ No newline at end of file diff --git a/source/blender/gpu/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c index 94c2b022e86..98c3613e1e2 100644 --- a/source/blender/gpu/intern/gpu_viewport.c +++ b/source/blender/gpu/intern/gpu_viewport.c @@ -83,6 +83,24 @@ GPUViewport *GPU_viewport_create(void) return viewport; } +GPUViewport *GPU_viewport_create_from_offscreen(struct GPUOffScreen *ofs) +{ + GPUViewport *viewport = GPU_viewport_create(); + GPU_offscreen_viewport_data_get(ofs, &viewport->fbl->default_fb, &viewport->txl->color, &viewport->txl->depth); + viewport->size[0] = GPU_offscreen_width(ofs); + viewport->size[1] = GPU_offscreen_height(ofs); + return viewport; +} +/** + * Clear vars assigned from offscreen, so we don't free data owned by `GPUOffScreen`. + */ +void GPU_viewport_clear_from_offscreen(GPUViewport *viewport) +{ + viewport->fbl->default_fb = NULL; + viewport->txl->color = NULL; + viewport->txl->depth = NULL; +} + void *GPU_viewport_engine_data_create(GPUViewport *viewport, void *engine_type) { LinkData *ld = MEM_callocN(sizeof(LinkData), "LinkData"); -- cgit v1.2.3