From ba074d167033fa0e44d6fdfe8ed31862db0695ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cle=CC=81ment=20Foucault?= Date: Sun, 24 Nov 2024 22:24:21 +0100 Subject: [PATCH] Overlay-Next: Move grid view specific data sync to draw function This avoid sync function to be view agnostic (follow the design principle). --- .../draw/engines/overlay/overlay_next_base.hh | 3 +- .../draw/engines/overlay/overlay_next_grid.hh | 138 ++++++++++-------- .../engines/overlay/overlay_next_instance.cc | 2 +- .../engines/overlay/overlay_next_instance.hh | 2 +- 4 files changed, 83 insertions(+), 62 deletions(-) diff --git a/source/blender/draw/engines/overlay/overlay_next_base.hh b/source/blender/draw/engines/overlay/overlay_next_base.hh index 9e4dd48cd6d..7d9173c8c96 100644 --- a/source/blender/draw/engines/overlay/overlay_next_base.hh +++ b/source/blender/draw/engines/overlay/overlay_next_base.hh @@ -52,8 +52,7 @@ struct Overlay { * * This method must be implemented. */ - /* TODO(fclem): Make it pure virtual. */ - virtual void begin_sync(Resources & /*res*/, const State & /*state*/){}; + virtual void begin_sync(Resources & /*res*/, const State & /*state*/) = 0; /** * Fills passes or buffers for each object. diff --git a/source/blender/draw/engines/overlay/overlay_next_grid.hh b/source/blender/draw/engines/overlay/overlay_next_grid.hh index bf84102ff36..c54d9dca459 100644 --- a/source/blender/draw/engines/overlay/overlay_next_grid.hh +++ b/source/blender/draw/engines/overlay/overlay_next_grid.hh @@ -33,24 +33,33 @@ class Grid : Overlay { PassSimple grid_ps_ = {"grid_ps_"}; + bool show_axis_z_ = false; + bool is_xr_ = false; + bool is_space_image_ = false; + /* Copy of v3d->dist. */ + float v3d_clip_end_ = 0.0f; + float3 grid_axes_ = float3(0.0f); float3 zplane_axes_ = float3(0.0f); - OVERLAY_GridBits grid_flag_ = OVERLAY_GridBits(0); - OVERLAY_GridBits zneg_flag_ = OVERLAY_GridBits(0); - OVERLAY_GridBits zpos_flag_ = OVERLAY_GridBits(0); + int grid_flag_ = int(0); + int zneg_flag_ = int(0); + int zpos_flag_ = int(0); + + const ShapeCache &shapes_; public: - /* TODO(fclem): Remove dependency on view. */ - void begin_sync(Resources &res, ShapeCache &shapes, const State &state, const View &view) + Grid(const ShapeCache &shapes) : shapes_(shapes){}; + + void begin_sync(Resources &res, const State &state) final { - enabled_ = init(state, view); + is_space_image_ = state.is_space_image(); + + enabled_ = init(state); if (!enabled_) { grid_ps_.init(); return; } - data_.push_update(); - GPUTexture **depth_tx = state.xray_enabled ? &res.xray_depth_tx : &res.depth_tx; GPUTexture **depth_infront_tx = &res.depth_target_in_front_tx; @@ -66,7 +75,7 @@ class Grid : Overlay { sub.push_constant("ucolor", color_back); sub.push_constant("tile_scale", float3(data_.size)); sub.bind_texture("depthBuffer", depth_tx); - sub.draw(shapes.quad_solid.get()); + sub.draw(shapes_.quad_solid.get()); } { auto &sub = grid_ps_.sub("grid"); @@ -75,19 +84,19 @@ class Grid : Overlay { sub.bind_texture("depth_tx", depth_tx, GPUSamplerState::default_sampler()); sub.bind_texture("depth_infront_tx", depth_infront_tx, GPUSamplerState::default_sampler()); if (zneg_flag_ & SHOW_AXIS_Z) { - sub.push_constant("grid_flag", zneg_flag_); - sub.push_constant("plane_axes", zplane_axes_); - sub.draw(shapes.grid.get()); + sub.push_constant("grid_flag", &zneg_flag_); + sub.push_constant("plane_axes", &zplane_axes_); + sub.draw(shapes_.grid.get()); } if (grid_flag_) { - sub.push_constant("grid_flag", grid_flag_); - sub.push_constant("plane_axes", grid_axes_); - sub.draw(shapes.grid.get()); + sub.push_constant("grid_flag", &grid_flag_); + sub.push_constant("plane_axes", &grid_axes_); + sub.draw(shapes_.grid.get()); } if (zpos_flag_ & SHOW_AXIS_Z) { - sub.push_constant("grid_flag", zpos_flag_); - sub.push_constant("plane_axes", zplane_axes_); - sub.draw(shapes.grid.get()); + sub.push_constant("grid_flag", &zpos_flag_); + sub.push_constant("plane_axes", &zplane_axes_); + sub.draw(shapes_.grid.get()); } } if (state.is_space_image()) { @@ -107,7 +116,7 @@ class Grid : Overlay { } tile_pos_buf_.push_update(); sub.bind_ssbo("tile_pos_buf", &tile_pos_buf_); - sub.draw(shapes.quad_wire.get(), tile_pos_buf_.size()); + sub.draw(shapes_.quad_wire.get(), tile_pos_buf_.size()); } } @@ -117,18 +126,22 @@ class Grid : Overlay { return; } + sync_view(view); + data_.push_update(); + GPU_framebuffer_bind(framebuffer); manager.submit(grid_ps_, view); } private: - bool init(const State &state, const View &view) + bool init(const State &state) { data_.line_size = max_ff(0.0f, U.pixelsize - 1.0f) * 0.5f; /* Default, nothing is drawn. */ - grid_flag_ = zneg_flag_ = zpos_flag_ = OVERLAY_GridBits(0); + grid_flag_ = zneg_flag_ = zpos_flag_ = 0; + show_axis_z_ = false; - return (state.is_space_image()) ? init_2d(state) : init_3d(state, view); + return (state.is_space_image()) ? init_2d(state) : init_3d(state); } void copy_steps_to_data(Span grid_steps_x, Span grid_steps_y) @@ -188,7 +201,7 @@ class Grid : Overlay { return true; } - bool init_3d(const State &state, const View &view) + bool init_3d(const State &state) { const View3D *v3d = state.v3d; const RegionView3D *rv3d = state.rv3d; @@ -209,7 +222,7 @@ class Grid : Overlay { 0.001f, 0.01f, 0.1f, 1.0f, 10.0f, 100.0f, 1000.0f, 10000.0f}; /* If perspective view or non-axis aligned view. */ - if (view.is_persp() || rv3d->view == RV3D_VIEW_USER) { + if (rv3d->is_persp || rv3d->view == RV3D_VIEW_USER) { if (show_axis_x) { grid_flag_ |= PLANE_XY | SHOW_AXIS_X; } @@ -239,12 +252,43 @@ class Grid : Overlay { /* Z axis if needed */ if (((rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO)) && show_axis_z) { zpos_flag_ = SHOW_AXIS_Z; + } + else { + zneg_flag_ = zpos_flag_ = CLIP_ZNEG | CLIP_ZPOS; + } - float3 zvec = -float3(view.viewinv()[2]); - float3 campos = float3(view.viewinv()[3]); + if (rv3d->persp == RV3D_CAMOB && v3d->camera && v3d->camera->type == OB_CAMERA) { + Object *camera_object = DEG_get_evaluated_object(state.depsgraph, v3d->camera); + v3d_clip_end_ = ((Camera *)(camera_object->data))->clip_end; + grid_flag_ |= GRID_CAMERA; + zneg_flag_ |= GRID_CAMERA; + zpos_flag_ |= GRID_CAMERA; + } + else { + v3d_clip_end_ = v3d->clip_end; + } + + ED_view3d_grid_steps(state.scene, v3d, rv3d, grid_steps.data()); + + is_xr_ = (v3d->flag & (V3D_XR_SESSION_SURFACE | V3D_XR_SESSION_MIRROR)) != 0; + + copy_steps_to_data(grid_steps, grid_steps); + return true; + } + + /* Update data that depends on the view. */ + void sync_view(const View &view) + { + if (is_space_image_) { + return; + } + + if (zpos_flag_ & SHOW_AXIS_Z) { + float3 backward = -view.forward(); + float3 position = view.location(); /* z axis : chose the most facing plane */ - if (fabsf(zvec[0]) < fabsf(zvec[1])) { + if (fabsf(backward.x) < fabsf(backward.y)) { zpos_flag_ |= PLANE_XZ; } else { @@ -254,7 +298,7 @@ class Grid : Overlay { /* Perspective: If camera is below floor plane, we switch clipping. * Orthographic: If eye vector is looking up, we switch clipping. */ - if ((view.is_persp() && (campos[2] > 0.0f)) || (!view.is_persp() && (zvec[2] < 0.0f))) { + if ((view.is_persp() && (position.z > 0.0f)) || (!view.is_persp() && (backward.z < 0.0f))) { zpos_flag_ |= CLIP_ZPOS; zneg_flag_ |= CLIP_ZNEG; } @@ -263,39 +307,19 @@ class Grid : Overlay { zneg_flag_ |= CLIP_ZPOS; } - zplane_axes_[0] = float((zpos_flag_ & (PLANE_XZ | PLANE_XY)) != 0); - zplane_axes_[1] = float((zpos_flag_ & (PLANE_YZ | PLANE_XY)) != 0); - zplane_axes_[2] = float((zpos_flag_ & (PLANE_YZ | PLANE_XZ)) != 0); - } - else { - zneg_flag_ = zpos_flag_ = CLIP_ZNEG | CLIP_ZPOS; + zplane_axes_.x = float((zpos_flag_ & (PLANE_XZ | PLANE_XY)) != 0); + zplane_axes_.y = float((zpos_flag_ & (PLANE_YZ | PLANE_XY)) != 0); + zplane_axes_.z = float((zpos_flag_ & (PLANE_YZ | PLANE_XZ)) != 0); } - float dist; - if (rv3d->persp == RV3D_CAMOB && v3d->camera && v3d->camera->type == OB_CAMERA) { - Object *camera_object = DEG_get_evaluated_object(state.depsgraph, v3d->camera); - dist = ((Camera *)(camera_object->data))->clip_end; - grid_flag_ |= GRID_CAMERA; - zneg_flag_ |= GRID_CAMERA; - zpos_flag_ |= GRID_CAMERA; - } - else { - dist = v3d->clip_end; + data_.size = float4(v3d_clip_end_); + if (!view.is_persp()) { + data_.size /= min_ff(fabsf(view.winmat()[0][0]), fabsf(view.winmat()[1][1])); } - if (view.is_persp()) { - data_.size = float4(dist); - } - else { - float viewdist = 1.0f / min_ff(fabsf(view.winmat()[0][0]), fabsf(view.winmat()[1][1])); - data_.size = float4(viewdist * dist); - } + data_.distance = v3d_clip_end_ / 2.0f; - data_.distance = dist / 2.0f; - - ED_view3d_grid_steps(state.scene, v3d, rv3d, grid_steps.data()); - - if ((v3d->flag & (V3D_XR_SESSION_SURFACE | V3D_XR_SESSION_MIRROR)) != 0) { + if (is_xr_) { /* The calculations for the grid parameters assume that the view matrix has no scale * component, which may not be correct if the user is "shrunk" or "enlarged" by zooming in or * out. Therefore, we need to compensate the values here. */ @@ -303,8 +327,6 @@ class Grid : Overlay { float viewinvscale = len_v3(view.viewinv()[0]); data_.distance *= viewinvscale; } - copy_steps_to_data(grid_steps, grid_steps); - return true; } }; diff --git a/source/blender/draw/engines/overlay/overlay_next_instance.cc b/source/blender/draw/engines/overlay/overlay_next_instance.cc index b2fa00b8fbc..a9a42d0ed18 100644 --- a/source/blender/draw/engines/overlay/overlay_next_instance.cc +++ b/source/blender/draw/engines/overlay/overlay_next_instance.cc @@ -159,7 +159,7 @@ void Instance::begin_sync() begin_sync_layer(regular); begin_sync_layer(infront); - grid.begin_sync(resources, shapes, state, view); + grid.begin_sync(resources, state); anti_aliasing.begin_sync(resources, state); xray_fade.begin_sync(resources, state); diff --git a/source/blender/draw/engines/overlay/overlay_next_instance.hh b/source/blender/draw/engines/overlay/overlay_next_instance.hh index 68d08e71a98..90e8277e44b 100644 --- a/source/blender/draw/engines/overlay/overlay_next_instance.hh +++ b/source/blender/draw/engines/overlay/overlay_next_instance.hh @@ -110,7 +110,7 @@ class Instance { Wireframe wireframe; } regular{selection_type_, shapes}, infront{selection_type_, shapes}; - Grid grid; + Grid grid = {shapes}; AntiAliasing anti_aliasing; XrayFade xray_fade;