diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2022-10-11 18:22:17 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2022-10-11 18:22:17 +0300 |
commit | 279774ad0b8fb20a9c5ea4cfabccd915e54472fe (patch) | |
tree | 7a4ec674e9066bee0aaafd419ba01cbea88cc5e5 | |
parent | 2538c3b1a2fed320fdf933b12612aab67f58dc9e (diff) |
Overlay-Next: First commit
9 files changed, 513 insertions, 10 deletions
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index d82ae4cd32c..9184cdbd810 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -192,6 +192,7 @@ set(SRC engines/overlay/overlay_gpencil.cc engines/overlay/overlay_grid.cc engines/overlay/overlay_image.cc + engines/overlay/overlay_instance.cc engines/overlay/overlay_lattice.cc engines/overlay/overlay_metaball.cc engines/overlay/overlay_mode_transfer.cc @@ -291,6 +292,7 @@ set(SRC engines/select/select_engine.h engines/select/select_private.h engines/overlay/overlay_engine.h + engines/overlay/overlay_instance.hh engines/overlay/overlay_private.hh ) diff --git a/source/blender/draw/engines/overlay/overlay_engine.cc b/source/blender/draw/engines/overlay/overlay_engine.cc index f1fdfe98fdc..184c1f3d45d 100644 --- a/source/blender/draw/engines/overlay/overlay_engine.cc +++ b/source/blender/draw/engines/overlay/overlay_engine.cc @@ -20,8 +20,13 @@ #include "BKE_object.h" #include "BKE_paint.h" +#include "GPU_capabilities.h" + #include "DNA_space_types.h" +#include "draw_manager.hh" +#include "overlay_instance.hh" + #include "overlay_engine.h" #include "overlay_private.hh" @@ -46,8 +51,7 @@ static void OVERLAY_engine_init(void *vedata) /* Allocate instance. */ if (data->instance == nullptr) { - data->instance = static_cast<OVERLAY_Instance *>( - MEM_callocN(sizeof(*data->instance), __func__)); + data->instance = new blender::draw::overlay::Instance(); } OVERLAY_PrivateData *pd = stl->pd; @@ -731,9 +735,70 @@ static void OVERLAY_engine_free() static void OVERLAY_instance_free(void *instance_) { - OVERLAY_Instance *instance = (OVERLAY_Instance *)instance_; - DRW_UBO_FREE_SAFE(instance->grid_ubo); - MEM_freeN(instance); + blender::draw::overlay::Instance *instance = (blender::draw::overlay::Instance *)instance_; + if (instance != nullptr) { + delete instance; + } +} +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Engine Instance + * \{ */ + +using namespace blender::draw; + +static void OVERLAY_next_engine_init(void *vedata) +{ + if (!GPU_shader_storage_buffer_objects_support()) { + return; + } + + OVERLAY_Data *ved = reinterpret_cast<OVERLAY_Data *>(vedata); + + if (ved->instance == nullptr) { + ved->instance = new overlay::Instance(); + } + + ved->instance->init(); +} + +static void OVERLAY_next_cache_init(void *vedata) +{ + if (!GPU_shader_storage_buffer_objects_support()) { + return; + } + reinterpret_cast<OVERLAY_Data *>(vedata)->instance->begin_sync(); +} + +static void OVERLAY_next_cache_populate(void *vedata, Object *object) +{ + if (!GPU_shader_storage_buffer_objects_support()) { + return; + } + ObjectRef ref; + ref.object = object; + ref.dupli_object = DRW_object_get_dupli(object); + ref.dupli_parent = DRW_object_get_dupli_parent(object); + + reinterpret_cast<OVERLAY_Data *>(vedata)->instance->object_sync(ref); +} + +static void OVERLAY_next_cache_finish(void *vedata) +{ + if (!GPU_shader_storage_buffer_objects_support()) { + return; + } + reinterpret_cast<OVERLAY_Data *>(vedata)->instance->end_sync(); +} + +static void OVERLAY_next_draw_scene(void *vedata) +{ + if (!GPU_shader_storage_buffer_objects_support()) { + return; + } + + reinterpret_cast<OVERLAY_Data *>(vedata)->instance->draw(*DRW_manager_get()); } /** \} */ @@ -762,6 +827,24 @@ DrawEngineType draw_engine_overlay_type = { nullptr, }; +DrawEngineType draw_engine_overlay_next_type = { + nullptr, + nullptr, + N_("Overlay"), + &overlay_data_size, + &OVERLAY_next_engine_init, + nullptr, + &OVERLAY_instance_free, + &OVERLAY_next_cache_init, + &OVERLAY_next_cache_populate, + &OVERLAY_next_cache_finish, + &OVERLAY_next_draw_scene, + nullptr, + nullptr, + nullptr, + nullptr, +}; + /** \} */ #undef SELECT_ENGINE diff --git a/source/blender/draw/engines/overlay/overlay_engine.h b/source/blender/draw/engines/overlay/overlay_engine.h index a33ea17dc1e..caf380c87af 100644 --- a/source/blender/draw/engines/overlay/overlay_engine.h +++ b/source/blender/draw/engines/overlay/overlay_engine.h @@ -12,6 +12,7 @@ extern "C" { #endif extern DrawEngineType draw_engine_overlay_type; +extern DrawEngineType draw_engine_overlay_next_type; #ifdef __cplusplus } diff --git a/source/blender/draw/engines/overlay/overlay_grid.cc b/source/blender/draw/engines/overlay/overlay_grid.cc index e31c40fff41..860f26fc18f 100644 --- a/source/blender/draw/engines/overlay/overlay_grid.cc +++ b/source/blender/draw/engines/overlay/overlay_grid.cc @@ -17,6 +17,7 @@ #include "UI_resources.h" +#include "overlay_instance.hh" #include "overlay_private.hh" BLI_STATIC_ASSERT(SI_GRID_STEPS_LEN == OVERLAY_GRID_STEPS_LEN, "") diff --git a/source/blender/draw/engines/overlay/overlay_grid.hh b/source/blender/draw/engines/overlay/overlay_grid.hh new file mode 100644 index 00000000000..76368f3c1d3 --- /dev/null +++ b/source/blender/draw/engines/overlay/overlay_grid.hh @@ -0,0 +1,198 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup overlay + */ + +#pragma once + +#include "DNA_space_types.h" +#include "ED_view3d.h" + +#include "draw_cache.h" +#include "draw_pass.hh" +#include "overlay_private.hh" +#include "overlay_shader_shared.h" + +namespace blender::draw::overlay { + +class Grid { + private: + UniformBuffer<OVERLAY_GridData> data_; + + bool enabled = false; + + PassSimple grid_ps_ = {"grid_ps_"}; + + float3 grid_axes = float3(0.0f); + float3 zplane_axes = float3(0.0f); + OVERLAY_GridBits grid_flag_; + OVERLAY_GridBits zneg_flag_; + OVERLAY_GridBits zpos_flag_; + + public: + void update_ubo() + { + float grid_steps[SI_GRID_STEPS_LEN] = { + 0.001f, 0.01f, 0.1f, 1.0f, 10.0f, 100.0f, 1000.0f, 10000.0f}; + float grid_steps_y[SI_GRID_STEPS_LEN] = {0.0f}; /* When zero, use value from grid_steps. */ + 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); + + /* SPACE_VIEW3D */ + Scene *scene = DRW_context_state_get()->scene; + View3D *v3d = DRW_context_state_get()->v3d; + RegionView3D *rv3d = DRW_context_state_get()->rv3d; + + const bool show_axis_x = true; //(pd->v3d_gridflag & V3D_SHOW_X) != 0; + const bool show_axis_y = true; //(pd->v3d_gridflag & V3D_SHOW_Y) != 0; + const bool show_axis_z = true; //(pd->v3d_gridflag & V3D_SHOW_Z) != 0; + const bool show_floor = true; //(pd->v3d_gridflag & V3D_SHOW_FLOOR) != 0; + const bool show_ortho_grid = true; //(pd->v3d_gridflag & V3D_SHOW_ORTHO_GRID) != 0; + + // if (pd->hide_overlays || !(pd->v3d_gridflag & (V3D_SHOW_X | V3D_SHOW_Y | V3D_SHOW_Z | + // V3D_SHOW_FLOOR | V3D_SHOW_ORTHO_GRID))) { + // return; + // } + + float viewinv[4][4], wininv[4][4]; + float viewmat[4][4], winmat[4][4]; + DRW_view_winmat_get(nullptr, winmat, false); + DRW_view_winmat_get(nullptr, wininv, true); + DRW_view_viewmat_get(nullptr, viewmat, false); + DRW_view_viewmat_get(nullptr, viewinv, true); + + /* If perspective view or non-axis aligned view. */ + if (winmat[3][3] == 0.0f || rv3d->view == RV3D_VIEW_USER) { + if (show_axis_x) { + grid_flag_ |= PLANE_XY | SHOW_AXIS_X; + } + if (show_axis_y) { + grid_flag_ |= PLANE_XY | SHOW_AXIS_Y; + } + if (show_floor) { + grid_flag_ |= PLANE_XY | SHOW_GRID; + } + } + else { + if (show_ortho_grid && ELEM(rv3d->view, RV3D_VIEW_RIGHT, RV3D_VIEW_LEFT)) { + grid_flag_ = PLANE_YZ | SHOW_AXIS_Y | SHOW_AXIS_Z | SHOW_GRID | GRID_BACK; + } + else if (show_ortho_grid && ELEM(rv3d->view, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM)) { + grid_flag_ = PLANE_XY | SHOW_AXIS_X | SHOW_AXIS_Y | SHOW_GRID | GRID_BACK; + } + else if (show_ortho_grid && ELEM(rv3d->view, RV3D_VIEW_FRONT, RV3D_VIEW_BACK)) { + grid_flag_ = PLANE_XZ | SHOW_AXIS_X | SHOW_AXIS_Z | SHOW_GRID | GRID_BACK; + } + } + + grid_axes[0] = float((grid_flag_ & (PLANE_XZ | PLANE_XY)) != 0); + grid_axes[1] = float((grid_flag_ & (PLANE_YZ | PLANE_XY)) != 0); + grid_axes[2] = float((grid_flag_ & (PLANE_YZ | PLANE_XZ)) != 0); + + /* Z axis if needed */ + if (((rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO)) && show_axis_z) { + zpos_flag_ = SHOW_AXIS_Z; + + float zvec[3], campos[3]; + negate_v3_v3(zvec, viewinv[2]); + copy_v3_v3(campos, viewinv[3]); + + /* z axis : chose the most facing plane */ + if (fabsf(zvec[0]) < fabsf(zvec[1])) { + zpos_flag_ |= PLANE_XZ; + } + else { + zpos_flag_ |= PLANE_YZ; + } + + zneg_flag_ = zpos_flag_; + + /* Perspective: If camera is below floor plane, we switch clipping. + * Orthographic: If eye vector is looking up, we switch clipping. */ + if (((winmat[3][3] == 0.0f) && (campos[2] > 0.0f)) || + ((winmat[3][3] != 0.0f) && (zvec[2] < 0.0f))) { + zpos_flag_ |= CLIP_ZPOS; + zneg_flag_ |= CLIP_ZNEG; + } + else { + zpos_flag_ |= CLIP_ZNEG; + 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; + } + + float dist; + // if (rv3d->persp == RV3D_CAMOB && v3d->camera && v3d->camera->type == OB_CAMERA) { + // Object *camera_object = DEG_get_evaluated_object(draw_ctx->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; + // } + + if (winmat[3][3] == 0.0f) { + copy_v3_fl(data_.size, dist); + } + else { + float viewdist = 1.0f / min_ff(fabsf(winmat[0][0]), fabsf(winmat[1][1])); + copy_v3_fl(data_.size, viewdist * dist); + } + + data_.distance = dist / 2.0f; + + ED_view3d_grid_steps(scene, v3d, rv3d, grid_steps); + + if ((v3d->flag & (V3D_XR_SESSION_SURFACE | V3D_XR_SESSION_MIRROR)) != 0) { + /* 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. */ + /* Assumption is uniform scaling (all column vectors are of same length). */ + float viewinvscale = len_v3(viewinv[0]); + data_.distance *= viewinvscale; + } + + /* Convert to UBO alignment. */ + for (int i = 0; i < SI_GRID_STEPS_LEN; i++) { + data_.steps[i][0] = grid_steps[i]; + data_.steps[i][1] = (grid_steps_y[i] != 0.0f) ? grid_steps_y[i] : grid_steps[i]; + } + + data_.push_update(); + } + + void begin_sync() + { + update_ubo(); + + grid_ps_.init(); + grid_ps_.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA); + + grid_ps_.shader_set(OVERLAY_shader_grid()); + grid_ps_.bind_ubo("grid_buf", &data_); + grid_ps_.bind_ubo("globalsBlock", &G_draw.block_ubo); + grid_ps_.bind_texture("depth_tx", &DRW_viewport_texture_list_get()->depth); + + grid_ps_.push_constant("grid_flag", grid_flag_); + grid_ps_.push_constant("plane_axes", grid_axes); + grid_ps_.clear_color(float4(0.0f, 0.0f, 0.0f, 0.0f)); + grid_ps_.draw(DRW_cache_grid_get()); + } + + void draw(Manager &manager, View &view) + { + manager.submit(grid_ps_, view); + } +}; + +} // namespace blender::draw::overlay diff --git a/source/blender/draw/engines/overlay/overlay_instance.cc b/source/blender/draw/engines/overlay/overlay_instance.cc new file mode 100644 index 00000000000..1d27c74e19a --- /dev/null +++ b/source/blender/draw/engines/overlay/overlay_instance.cc @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup overlay + */ + +#include "overlay_instance.hh" + +namespace blender::draw::overlay { + +void Instance::init() +{ + GPUTexture *viewport_depth_tx = DRW_viewport_texture_list_get()->depth; + GPUTexture *viewport_color_tx = DRW_viewport_texture_list_get()->color_overlay; + overlay_fb.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(viewport_color_tx)); +} + +void Instance::begin_sync() +{ + grid.begin_sync(); +} + +void Instance::object_sync(ObjectRef &ob_ref) +{ + UNUSED_VARS(ob_ref); +} + +void Instance::end_sync() +{ +} + +void Instance::draw(Manager &manager) +{ + const DRWView *view_old = DRW_view_default_get(); + View view("OverlayView", view_old); + + GPU_framebuffer_bind(overlay_fb); + grid.draw(manager, view); +} + +} // namespace blender::draw::overlay diff --git a/source/blender/draw/engines/overlay/overlay_instance.hh b/source/blender/draw/engines/overlay/overlay_instance.hh new file mode 100644 index 00000000000..85a73c71900 --- /dev/null +++ b/source/blender/draw/engines/overlay/overlay_instance.hh @@ -0,0 +1,70 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup overlay + */ + +#pragma once + +#include "draw_manager.hh" + +#include "overlay_grid.hh" + +namespace blender::draw::overlay { + +class ShaderCache { + Map<StringRefNull, std::array<GPUShader *, 2>> cache; + + int clipping_enabled = 0; +}; + +class SceneResources { + ShaderCache shaders; + + // UniformBuffer<ThemeColorData> theme_colors; + // Texture color_ramp = {"color_ramp"}; + + void weight_ramp_init() + { + /* Weight Painting color ramp texture */ + // bool user_weight_ramp = (U.flag & USER_CUSTOM_RANGE) != 0; + + // if (weight_ramp_custom != user_weight_ramp || + // (user_weight_ramp && memcmp(&weight_ramp_copy, &U.coba_weight, sizeof(ColorBand)) != 0)) + // { + // DRW_TEXTURE_FREE_SAFE(G_draw.weight_ramp); + // } + + // if (G_draw.weight_ramp == NULL) { + // weight_ramp_custom = user_weight_ramp; + // memcpy(&weight_ramp_copy, &U.coba_weight, sizeof(ColorBand)); + + // G_draw.weight_ramp = DRW_create_weight_colorramp_texture(); + // } + } +}; + +class Instance { + public: + ShaderCache shaders; + + /* WORKAROUND: Legacy. Move to grid pass. */ + GPUUniformBuf *grid_ubo = nullptr; + + Framebuffer overlay_fb = {"overlay_fb"}; + + Grid grid; + + ~Instance() + { + DRW_UBO_FREE_SAFE(grid_ubo); + } + + void init(); + void begin_sync(); + void object_sync(ObjectRef &ob_ref); + void end_sync(); + void draw(Manager &manager); +}; + +} // namespace blender::draw::overlay diff --git a/source/blender/draw/engines/overlay/overlay_private.hh b/source/blender/draw/engines/overlay/overlay_private.hh index b1118e084a6..9b433928321 100644 --- a/source/blender/draw/engines/overlay/overlay_private.hh +++ b/source/blender/draw/engines/overlay/overlay_private.hh @@ -27,6 +27,10 @@ extern "C" { /* Forward declarations */ struct ImBuf; +namespace blender::draw::overlay { +class Instance; +} + typedef struct OVERLAY_FramebufferList { struct GPUFrameBuffer *overlay_default_fb; struct GPUFrameBuffer *overlay_line_fb; @@ -428,10 +432,6 @@ typedef struct OVERLAY_StorageList { struct OVERLAY_PrivateData *pd; } OVERLAY_StorageList; -typedef struct OVERLAY_Instance { - GPUUniformBuf *grid_ubo; -} OVERLAY_Instance; - typedef struct OVERLAY_Data { void *engine_type; OVERLAY_FramebufferList *fbl; @@ -439,7 +439,7 @@ typedef struct OVERLAY_Data { OVERLAY_PassList *psl; OVERLAY_StorageList *stl; - OVERLAY_Instance *instance; + blender::draw::overlay::Instance *instance; } OVERLAY_Data; typedef struct OVERLAY_DupliData { diff --git a/source/blender/draw/engines/overlay/overlay_shader_shared.h b/source/blender/draw/engines/overlay/overlay_shader_shared.h index 739e5be6c2f..bb937d2c45a 100644 --- a/source/blender/draw/engines/overlay/overlay_shader_shared.h +++ b/source/blender/draw/engines/overlay/overlay_shader_shared.h @@ -1,6 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ #ifndef GPU_SHADER +# pragma once + # include "GPU_shader_shared_utils.h" # include "DNA_action_types.h" @@ -12,6 +14,7 @@ extern "C" { typedef enum OVERLAY_GridBits OVERLAY_GridBits; # endif typedef struct OVERLAY_GridData OVERLAY_GridData; +typedef struct ThemeColorData ThemeColorData; #endif /* TODO(fclem): Should eventually become OVERLAY_BackgroundType. @@ -84,6 +87,110 @@ BLI_STATIC_ASSERT(MOTIONPATH_VERT_SEL == (1 << 0), "Ensure value is sync"); BLI_STATIC_ASSERT(MOTIONPATH_VERT_KEY == (1 << 1), "Ensure value is sync"); #endif +struct ThemeColorData { + float4 color_wire; + float4 color_wire_edit; + float4 color_active; + float4 color_select; + float4 color_library_select; + float4 color_library; + float4 color_transform; + float4 color_light; + float4 color_speaker; + float4 color_camera; + float4 color_camera_path; + float4 color_empty; + float4 color_vertex; + float4 color_vertex_select; + float4 color_vertex_unreferenced; + float4 color_vertex_missing_data; + float4 color_edit_mesh_active; + float4 color_edge_select; + float4 color_edge_seam; + float4 color_edge_sharp; + float4 color_edge_crease; + float4 color_edge_bweight; + float4 color_edge_face_select; + float4 color_edge_freestyle; + float4 color_face; + float4 color_face_select; + float4 color_face_freestyle; + float4 color_gpencil_vertex; + float4 color_gpencil_vertex_select; + float4 color_normal; + float4 color_vnormal; + float4 color_lnormal; + float4 color_facedot; + float4 color_skinroot; + + float4 color_deselect; + float4 color_outline; + float4 color_light_no_alpha; + + float4 color_background; + float4 color_background_gradient; + float4 color_checker_primary; + float4 color_checker_secondary; + float4 color_clipping_border; + float4 color_edit_mesh_middle; + + float4 color_handle_free; + float4 color_handle_auto; + float4 color_handle_vect; + float4 color_handle_align; + float4 color_handle_autoclamp; + float4 color_handle_sel_free; + float4 color_handle_sel_auto; + float4 color_handle_sel_vect; + float4 color_handle_sel_align; + float4 color_handle_sel_autoclamp; + float4 color_nurb_uline; + float4 color_nurb_vline; + float4 color_nurb_sel_uline; + float4 color_nurb_sel_vline; + float4 color_active_spline; + + float4 color_bone_pose; + float4 color_bone_pose_active; + float4 color_bone_pose_active_unsel; + float4 color_bone_pose_constraint; + float4 color_bone_pose_ik; + float4 color_bone_pose_spline_ik; + float4 color_bone_pose_target; + float4 color_bone_solid; + float4 color_bone_locked; + float4 color_bone_active; + float4 color_bone_active_unsel; + float4 color_bone_select; + float4 color_bone_ik_line; + float4 color_bone_ik_line_no_target; + float4 color_bone_ik_line_spline; + + float4 color_text; + float4 color_text_hi; + + float4 color_bundle_solid; + + float4 color_mball_radius; + float4 color_mball_radius_select; + float4 color_mball_stiffness; + float4 color_mball_stiffness_select; + + float4 color_current_frame; + + float4 color_grid; + float4 color_grid_emphasis; + float4 color_grid_axis_x; + float4 color_grid_axis_y; + float4 color_grid_axis_z; + + float4 color_face_back; + float4 color_face_front; + + float4 color_uv_shadow; +}; +BLI_STATIC_ASSERT_ALIGN(ThemeColorData, 16) + #ifndef GPU_SHADER # ifdef __cplusplus } |