From fb095afe4d27c83a72cad0829fe0ab0546b9e8ea Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 12 Apr 2014 15:34:59 +1000 Subject: View3D: refactor ED_view3d_draw_offscreen and view3d_main_area_draw_objects de-duplicate object drawing code between offscreen buffer and regular view3d. Also skip drawing grease pencil and setting pixelspace when drawing from lamps. --- source/blender/editors/space_view3d/view3d_draw.c | 437 +++++++++++----------- 1 file changed, 210 insertions(+), 227 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 2552be9b83b..d22dca4ad88 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -1062,7 +1062,7 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d) rctf viewborder; Camera *ca = NULL; - RegionView3D *rv3d = (RegionView3D *)ar->regiondata; + RegionView3D *rv3d = ar->regiondata; if (v3d->camera == NULL) return; @@ -1892,7 +1892,7 @@ static void view3d_draw_transp(Scene *scene, ARegion *ar, View3D *v3d) } /* clears zbuffer and draws it over */ -static void view3d_draw_xray(Scene *scene, ARegion *ar, View3D *v3d, int clear) +static void view3d_draw_xray(Scene *scene, ARegion *ar, View3D *v3d, const bool clear) { View3DAfter *v3da, *next; @@ -1911,7 +1911,7 @@ static void view3d_draw_xray(Scene *scene, ARegion *ar, View3D *v3d, int clear) /* clears zbuffer and draws it over */ -static void view3d_draw_xraytransp(Scene *scene, ARegion *ar, View3D *v3d, int clear) +static void view3d_draw_xraytransp(Scene *scene, ARegion *ar, View3D *v3d, const bool clear) { View3DAfter *v3da, *next; @@ -2554,6 +2554,171 @@ void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float view } } + + +/** + * Shared by #ED_view3d_draw_offscreen and #view3d_main_area_draw_objects + * + * \note \a C and \a grid_unit will be NULL when \a draw_offscreen is set. + * \note Drawing lamps and opengl render uses this, so dont do grease pencil or view widgets here. + */ +static void view3d_draw_objects( + const bContext *C, + Scene *scene, View3D *v3d, ARegion *ar, + const char **grid_unit, + const bool do_bgpic, const bool draw_offscreen) +{ + RegionView3D *rv3d = ar->regiondata; + Base *base; + const bool do_camera_frame = !draw_offscreen; + + if (!draw_offscreen) { + ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW); + } + + if (rv3d->rflag & RV3D_CLIPPING) + view3d_draw_clipping(rv3d); + + /* set zbuffer after we draw clipping region */ + if (v3d->drawtype > OB_WIRE) { + v3d->zbuf = true; + glEnable(GL_DEPTH_TEST); + } + else { + v3d->zbuf = false; + } + + if (!draw_offscreen) { + /* needs to be done always, gridview is adjusted in drawgrid() now, but only for ortho views. */ + rv3d->gridview = v3d->grid; + if (scene->unit.system) { + rv3d->gridview /= scene->unit.scale_length; + } + + if ((rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO)) { + if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { + drawfloor(scene, v3d, grid_unit); + } + } + else { + if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { + ED_region_pixelspace(ar); + drawgrid(&scene->unit, ar, v3d, grid_unit); + /* XXX make function? replaces persp(1) */ + glMatrixMode(GL_PROJECTION); + glLoadMatrixf(rv3d->winmat); + glMatrixMode(GL_MODELVIEW); + glLoadMatrixf(rv3d->viewmat); + } + } + } + + /* important to do before clipping */ + if (do_bgpic) { + view3d_draw_bgpic_test(scene, ar, v3d, false, do_camera_frame); + } + + if (rv3d->rflag & RV3D_CLIPPING) { + ED_view3d_clipping_set(rv3d); + } + + /* draw set first */ + if (scene->set) { + Scene *sce_iter; + for (SETLOOPER(scene->set, sce_iter, base)) { + if (v3d->lay & base->lay) { + UI_ThemeColorBlend(TH_WIRE, TH_BACK, 0.6f); + draw_object(scene, ar, v3d, base, DRAW_CONSTCOLOR | DRAW_SCENESET); + + if (base->object->transflag & OB_DUPLI) { + draw_dupli_objects_color(scene, ar, v3d, base, TH_WIRE); + } + } + } + + /* Transp and X-ray afterdraw stuff for sets is done later */ + } + + + if (draw_offscreen) { + for (base = scene->base.first; base; base = base->next) { + if (v3d->lay & base->lay) { + /* dupli drawing */ + if (base->object->transflag & OB_DUPLI) + draw_dupli_objects(scene, ar, v3d, base); + + draw_object(scene, ar, v3d, base, 0); + } + } + } + else { + unsigned int lay_used = 0; + + /* then draw not selected and the duplis, but skip editmode object */ + for (base = scene->base.first; base; base = base->next) { + lay_used |= base->lay & ((1 << 20) - 1); + + if (v3d->lay & base->lay) { + + /* dupli drawing */ + if (base->object->transflag & OB_DUPLI) { + draw_dupli_objects(scene, ar, v3d, base); + } + if ((base->flag & SELECT) == 0) { + if (base->object != scene->obedit) + draw_object(scene, ar, v3d, base, 0); + } + } + } + + v3d->lay_used = lay_used; + + /* draw selected and editmode */ + for (base = scene->base.first; base; base = base->next) { + if (v3d->lay & base->lay) { + if (base->object == scene->obedit || (base->flag & SELECT)) { + draw_object(scene, ar, v3d, base, 0); + } + } + } + } + + /* must be before xray draw which clears the depth buffer */ + if (v3d->flag2 & V3D_SHOW_GPENCIL) { + /* must be before xray draw which clears the depth buffer */ + if (v3d->zbuf) glDisable(GL_DEPTH_TEST); + draw_gpencil_view3d(scene, v3d, ar, true); + if (v3d->zbuf) glEnable(GL_DEPTH_TEST); + } + + /* transp and X-ray afterdraw stuff */ + if (v3d->afterdraw_transp.first) view3d_draw_transp(scene, ar, v3d); + if (v3d->afterdraw_xray.first) view3d_draw_xray(scene, ar, v3d, true); + if (v3d->afterdraw_xraytransp.first) view3d_draw_xraytransp(scene, ar, v3d, true); + + if (!draw_offscreen) { + ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW); + } + + if (rv3d->rflag & RV3D_CLIPPING) + ED_view3d_clipping_disable(); + + /* important to do after clipping */ + if (do_bgpic) { + view3d_draw_bgpic_test(scene, ar, v3d, true, do_camera_frame); + } + + if (!draw_offscreen) { + BIF_draw_manipulator(C); + } + + /* cleanup */ + if (v3d->zbuf) { + v3d->zbuf = false; + glDisable(GL_DEPTH_TEST); + } +} + static void view3d_main_area_setup_view(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4]) { RegionView3D *rv3d = ar->regiondata; @@ -2578,10 +2743,9 @@ void ED_view3d_draw_offscreen_init(Scene *scene, View3D *v3d) * stuff like shadow buffers */ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, int winx, int winy, - float viewmat[4][4], float winmat[4][4], bool do_bgpic, bool do_sky) + float viewmat[4][4], float winmat[4][4], + bool do_bgpic, bool do_sky) { - RegionView3D *rv3d = ar->regiondata; - Base *base; int bwinx, bwiny; rcti brect; @@ -2591,7 +2755,7 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, int winx, bwinx = ar->winx; bwiny = ar->winy; brect = ar->winrct; - + ar->winx = winx; ar->winy = winy; ar->winrct.xmin = 0; @@ -2601,13 +2765,15 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, int winx, /* set theme */ UI_SetTheme(SPACE_VIEW3D, RGN_TYPE_WINDOW); - + /* set flags */ G.f |= G_RENDER_OGL; - /* free images which can have changed on frame-change - * warning! can be slow so only free animated images - campbell */ - GPU_free_images_anim(); + if ((v3d->flag2 & V3D_RENDER_SHADOW) == 0) { + /* free images which can have changed on frame-change + * warning! can be slow so only free animated images - campbell */ + GPU_free_images_anim(); + } /* clear opengl buffers */ if (do_sky) { @@ -2622,91 +2788,28 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, int winx, glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + /* setup view matrices */ view3d_main_area_setup_view(scene, v3d, ar, viewmat, winmat); - if (rv3d->rflag & RV3D_CLIPPING) - view3d_draw_clipping(rv3d); - /* set zbuffer */ - if (v3d->drawtype > OB_WIRE) { - v3d->zbuf = true; - glEnable(GL_DEPTH_TEST); - } - else - v3d->zbuf = false; + /* main drawing call */ + view3d_draw_objects(NULL, scene, v3d, ar, NULL, do_bgpic, true); - /* important to do before clipping */ - if (do_bgpic) { - view3d_draw_bgpic_test(scene, ar, v3d, false, false); - } + if ((v3d->flag2 & V3D_RENDER_SHADOW) == 0) { + /* draw grease-pencil stuff */ + ED_region_pixelspace(ar); - if (rv3d->rflag & RV3D_CLIPPING) - ED_view3d_clipping_set(rv3d); - /* draw set first */ - if (scene->set) { - Scene *sce_iter; - for (SETLOOPER(scene->set, sce_iter, base)) { - if (v3d->lay & base->lay) { - UI_ThemeColorBlend(TH_WIRE, TH_BACK, 0.6f); - draw_object(scene, ar, v3d, base, DRAW_CONSTCOLOR | DRAW_SCENESET); - - if (base->object->transflag & OB_DUPLI) - draw_dupli_objects_color(scene, ar, v3d, base, TH_WIRE); - } - } - } - - /* then draw not selected and the duplis, but skip editmode object */ - for (base = scene->base.first; base; base = base->next) { - if (v3d->lay & base->lay) { - /* dupli drawing */ - if (base->object->transflag & OB_DUPLI) - draw_dupli_objects(scene, ar, v3d, base); - - draw_object(scene, ar, v3d, base, 0); + if (v3d->flag2 & V3D_SHOW_GPENCIL) { + /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */ + draw_gpencil_view3d(scene, v3d, ar, false); } - } - - /* must be before xray draw which clears the depth buffer */ - if (v3d->flag2 & V3D_SHOW_GPENCIL) { - if (v3d->zbuf) glDisable(GL_DEPTH_TEST); - draw_gpencil_view3d(scene, v3d, ar, true); - if (v3d->zbuf) glEnable(GL_DEPTH_TEST); - } - - /* transp and X-ray afterdraw stuff */ - if (v3d->afterdraw_transp.first) view3d_draw_transp(scene, ar, v3d); - if (v3d->afterdraw_xray.first) view3d_draw_xray(scene, ar, v3d, 1); /* clears zbuffer if it is used! */ - if (v3d->afterdraw_xraytransp.first) view3d_draw_xraytransp(scene, ar, v3d, 1); - - if (rv3d->rflag & RV3D_CLIPPING) - ED_view3d_clipping_disable(); - - /* important to do after clipping */ - if (do_bgpic) { - view3d_draw_bgpic_test(scene, ar, v3d, true, false); - } - - /* cleanup */ - if (v3d->zbuf) { - v3d->zbuf = false; - glDisable(GL_DEPTH_TEST); - } - - /* draw grease-pencil stuff */ - ED_region_pixelspace(ar); - - if (v3d->flag2 & V3D_SHOW_GPENCIL) { - /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */ - draw_gpencil_view3d(scene, v3d, ar, false); + /* freeing the images again here could be done after the operator runs, leaving for now */ + GPU_free_images_anim(); } - /* freeing the images again here could be done after the operator runs, leaving for now */ - GPU_free_images_anim(); - /* restore size */ ar->winx = bwinx; ar->winy = bwiny; @@ -2896,8 +2999,6 @@ void ED_scene_draw_fps(Scene *scene, rcti *rect) #endif } -static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const char **grid_unit); - static bool view3d_main_area_do_render_draw(Scene *scene) { RenderEngineType *type = RE_engines_find(scene->r.engine); @@ -2946,11 +3047,11 @@ bool ED_view3d_calc_render_border(Scene *scene, View3D *v3d, ARegion *ar, rcti * return true; } -static bool view3d_main_area_draw_engine(const bContext *C, ARegion *ar, bool clip_border, rcti *border_rect) +static bool view3d_main_area_draw_engine(const bContext *C, Scene *scene, + ARegion *ar, View3D *v3d, + bool clip_border, const rcti *border_rect) { - Scene *scene = CTX_data_scene(C); - View3D *v3d = CTX_wm_view3d(C); - RegionView3D *rv3d = CTX_wm_region_view3d(C); + RegionView3D *rv3d = ar->regiondata; RenderEngineType *type; GLint scissor[4]; @@ -3228,14 +3329,11 @@ static void update_lods(Scene *scene, float camera_pos[3]) #endif -/* warning: this function has duplicate drawing in ED_view3d_draw_offscreen() */ -static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const char **grid_unit) +static void view3d_main_area_draw_objects(const bContext *C, Scene *scene, View3D *v3d, + ARegion *ar, const char **grid_unit) { - Scene *scene = CTX_data_scene(C); - View3D *v3d = CTX_wm_view3d(C); - RegionView3D *rv3d = CTX_wm_region_view3d(C); - Base *base; - unsigned int lay_used; + RegionView3D *rv3d = ar->regiondata; + unsigned int lay_used = v3d->lay_used; /* shadow buffers, before we setup matrices */ if (draw_glsl_material(scene, NULL, v3d, v3d->drawtype)) @@ -3263,88 +3361,17 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const /* clear the background */ view3d_main_area_clear(scene, v3d, ar); - ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW); - - if (rv3d->rflag & RV3D_CLIPPING) - view3d_draw_clipping(rv3d); - - /* set zbuffer after we draw clipping region */ - if (v3d->drawtype > OB_WIRE) { - v3d->zbuf = true; - glEnable(GL_DEPTH_TEST); - } - else - v3d->zbuf = false; - /* enables anti-aliasing for 3D view drawing */ if (U.ogl_multisamples != USER_MULTISAMPLE_NONE) { glEnable(GL_MULTISAMPLE_ARB); } - /* needs to be done always, gridview is adjusted in drawgrid() now, but only for ortho views. */ - rv3d->gridview = v3d->grid; - if (scene->unit.system) { - rv3d->gridview /= scene->unit.scale_length; - } - - if ((rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO)) { - if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { - drawfloor(scene, v3d, grid_unit); - } - } - else { - if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { - ED_region_pixelspace(ar); - drawgrid(&scene->unit, ar, v3d, grid_unit); - /* XXX make function? replaces persp(1) */ - glMatrixMode(GL_PROJECTION); - glLoadMatrixf(rv3d->winmat); - glMatrixMode(GL_MODELVIEW); - glLoadMatrixf(rv3d->viewmat); - } - } - - view3d_draw_bgpic_test(scene, ar, v3d, false, true); + /* main drawing call */ + view3d_draw_objects(C, scene, v3d, ar, grid_unit, true, false); - if (rv3d->rflag & RV3D_CLIPPING) - ED_view3d_clipping_set(rv3d); - - /* draw set first */ - if (scene->set) { - Scene *sce_iter; - for (SETLOOPER(scene->set, sce_iter, base)) { - - if (v3d->lay & base->lay) { - - UI_ThemeColorBlend(TH_WIRE, TH_BACK, 0.6f); - draw_object(scene, ar, v3d, base, DRAW_CONSTCOLOR | DRAW_SCENESET); - - if (base->object->transflag & OB_DUPLI) { - draw_dupli_objects_color(scene, ar, v3d, base, TH_WIRE); - } - } - } - - /* Transp and X-ray afterdraw stuff for sets is done later */ - } - - lay_used = 0; - - /* then draw not selected and the duplis, but skip editmode object */ - for (base = scene->base.first; base; base = base->next) { - lay_used |= base->lay & ((1 << 20) - 1); - - if (v3d->lay & base->lay) { - - /* dupli drawing */ - if (base->object->transflag & OB_DUPLI) { - draw_dupli_objects(scene, ar, v3d, base); - } - if ((base->flag & SELECT) == 0) { - if (base->object != scene->obedit) - draw_object(scene, ar, v3d, base, 0); - } - } + /* Disable back anti-aliasing */ + if (U.ogl_multisamples != USER_MULTISAMPLE_NONE) { + glDisable(GL_MULTISAMPLE_ARB); } if (v3d->lay_used != lay_used) { /* happens when loading old files or loading with UI load */ @@ -3352,51 +3379,6 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const ScrArea *sa = CTX_wm_area(C); ARegion *ar_header = BKE_area_find_region_type(sa, RGN_TYPE_HEADER); ED_region_tag_redraw(ar_header); /* can be NULL */ - v3d->lay_used = lay_used; - } - - /* draw selected and editmode */ - for (base = scene->base.first; base; base = base->next) { - if (v3d->lay & base->lay) { - if (base->object == scene->obedit || (base->flag & SELECT)) { - draw_object(scene, ar, v3d, base, 0); - } - } - } - -// REEB_draw(); - - if (v3d->flag2 & V3D_SHOW_GPENCIL) { - /* must be before xray draw which clears the depth buffer */ - if (v3d->zbuf) glDisable(GL_DEPTH_TEST); - draw_gpencil_view3d(scene, v3d, ar, true); - if (v3d->zbuf) glEnable(GL_DEPTH_TEST); - } - - /* Transp and X-ray afterdraw stuff */ - if (v3d->afterdraw_transp.first) view3d_draw_transp(scene, ar, v3d); - if (v3d->afterdraw_xray.first) view3d_draw_xray(scene, ar, v3d, 1); /* clears zbuffer if it is used! */ - if (v3d->afterdraw_xraytransp.first) view3d_draw_xraytransp(scene, ar, v3d, 1); - - ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW); - - if (rv3d->rflag & RV3D_CLIPPING) - ED_view3d_clipping_disable(); - - /* important to do after clipping */ - view3d_draw_bgpic_test(scene, ar, v3d, true, true); - - BIF_draw_manipulator(C); - - /* Disable back anti-aliasing */ - if (U.ogl_multisamples != USER_MULTISAMPLE_NONE) { - glDisable(GL_MULTISAMPLE_ARB); - } - - - if (v3d->zbuf) { - v3d->zbuf = false; - glDisable(GL_DEPTH_TEST); } if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { @@ -3409,12 +3391,11 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const } -static void view3d_main_area_draw_info(const bContext *C, ARegion *ar, const char *grid_unit, bool render_border) +static void view3d_main_area_draw_info(const bContext *C, Scene *scene, + ARegion *ar, View3D *v3d, + const char *grid_unit, bool render_border) { - wmWindowManager *wm = CTX_wm_manager(C); - Scene *scene = CTX_data_scene(C); - View3D *v3d = CTX_wm_view3d(C); - RegionView3D *rv3d = CTX_wm_region_view3d(C); + RegionView3D *rv3d = ar->regiondata; rcti rect; /* local coordinate visible rect inside region, to accomodate overlapping ui */ @@ -3461,6 +3442,8 @@ static void view3d_main_area_draw_info(const bContext *C, ARegion *ar, const cha } if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { + wmWindowManager *wm = CTX_wm_manager(C); + if ((U.uiflag & USER_SHOW_FPS) && ED_screen_animation_playing(wm)) { ED_scene_draw_fps(scene, &rect); } @@ -3498,7 +3481,7 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar) /* draw viewport using opengl */ if (v3d->drawtype != OB_RENDER || !view3d_main_area_do_render_draw(scene) || clip_border) { - view3d_main_area_draw_objects(C, ar, &grid_unit); + view3d_main_area_draw_objects(C, scene, v3d, ar, &grid_unit); #ifdef DEBUG_DRAW bl_debug_draw(); #endif @@ -3507,9 +3490,9 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar) /* draw viewport using external renderer */ if (v3d->drawtype == OB_RENDER) - view3d_main_area_draw_engine(C, ar, clip_border, &border_rect); + view3d_main_area_draw_engine(C, scene, ar, v3d, clip_border, &border_rect); - view3d_main_area_draw_info(C, ar, grid_unit, render_border); + view3d_main_area_draw_info(C, scene, ar, v3d, grid_unit, render_border); v3d->flag |= V3D_INVALID_BACKBUF; } -- cgit v1.2.3