diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2022-10-13 00:31:03 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2022-10-13 00:40:37 +0300 |
commit | 2abc4d053860559f0fe803d265f459b2b05ae7a3 (patch) | |
tree | 691c02dda18962db8a55c8e033f5bc5627e2fe04 | |
parent | c4ecfce6bb01ed31200f675719cc0baf10c6a4a2 (diff) |
Overlay-Next: Port Metaball overlayoverlay-next
6 files changed, 248 insertions, 8 deletions
diff --git a/source/blender/draw/engines/overlay/overlay_background.hh b/source/blender/draw/engines/overlay/overlay_background.hh index 37ab59abb9b..6ec212c108c 100644 --- a/source/blender/draw/engines/overlay/overlay_background.hh +++ b/source/blender/draw/engines/overlay/overlay_background.hh @@ -74,7 +74,6 @@ class Background { } bg_ps_.init(); - bg_ps_.clear_color(float4()); bg_ps_.state_set(pass_state); bg_ps_.shader_set(OVERLAY_shader_background()); bg_ps_.bind_ubo("globalsBlock", &res.globals_buf); @@ -95,9 +94,7 @@ class Background { void draw(Resources &res, Manager &manager) { - if (DRW_state_is_fbo()) { - GPU_framebuffer_bind(res.overlay_color_only_fb); - } + GPU_framebuffer_bind(res.overlay_color_only_fb); manager.submit(bg_ps_); } }; diff --git a/source/blender/draw/engines/overlay/overlay_instance.cc b/source/blender/draw/engines/overlay/overlay_instance.cc index a6ab60ec22f..417fcd45d4a 100644 --- a/source/blender/draw/engines/overlay/overlay_instance.cc +++ b/source/blender/draw/engines/overlay/overlay_instance.cc @@ -12,6 +12,7 @@ namespace blender::draw::overlay { void Instance::init() { resources.depth_tx.wrap(DRW_viewport_texture_list_get()->depth); + resources.depth_in_front_tx.wrap(DRW_viewport_texture_list_get()->depth_in_front); resources.color_overlay_tx.wrap(DRW_viewport_texture_list_get()->color_overlay); resources.color_render_tx.wrap(DRW_viewport_texture_list_get()->color); @@ -19,6 +20,7 @@ void Instance::init() const DRWContextState *ctx = DRW_context_state_get(); state.depsgraph = ctx->depsgraph; + state.view_layer = ctx->view_layer; state.scene = ctx->scene; state.v3d = ctx->v3d; state.rv3d = ctx->rv3d; @@ -64,16 +66,54 @@ void Instance::begin_sync() View view("OverlayView", view_legacy); background.begin_sync(resources, state); + metaballs.begin_sync(); grid.begin_sync(resources, state, view); } void Instance::object_sync(ObjectRef &ob_ref) { - UNUSED_VARS(ob_ref); + const bool in_edit_mode = object_is_edit_mode(ob_ref.object); + + if (in_edit_mode && !state.hide_overlays) { + switch (ob_ref.object->type) { + case OB_MESH: + break; + case OB_ARMATURE: + break; + case OB_CURVES_LEGACY: + break; + case OB_SURF: + break; + case OB_LATTICE: + break; + case OB_MBALL: + metaballs.edit_object_sync(ob_ref, resources); + break; + case OB_FONT: + break; + case OB_CURVES: + break; + } + } + + if (!state.hide_overlays) { + switch (ob_ref.object->type) { + case OB_ARMATURE: + break; + case OB_MBALL: + if (!in_edit_mode) { + metaballs.object_sync(ob_ref, resources, state); + } + break; + case OB_GPENCIL: + break; + } + } } void Instance::end_sync() { + metaballs.end_sync(resources, state); } void Instance::draw(Manager &manager) @@ -84,18 +124,32 @@ void Instance::draw(Manager &manager) return; } + int2 render_size = int2(resources.depth_tx.size()); + const DRWView *view_legacy = DRW_view_default_get(); View view("OverlayView", view_legacy); - resources.line_tx.acquire(int2(resources.depth_tx.size()), GPU_RGBA8); + resources.line_tx.acquire(render_size, GPU_RGBA8); - resources.overlay_color_only_fb.ensure(GPU_ATTACHMENT_NONE, - GPU_ATTACHMENT_TEXTURE(resources.color_overlay_tx)); resources.overlay_fb.ensure(GPU_ATTACHMENT_TEXTURE(resources.depth_tx), GPU_ATTACHMENT_TEXTURE(resources.color_overlay_tx)); resources.overlay_line_fb.ensure(GPU_ATTACHMENT_TEXTURE(resources.depth_tx), GPU_ATTACHMENT_TEXTURE(resources.color_overlay_tx), GPU_ATTACHMENT_TEXTURE(resources.line_tx)); + resources.overlay_color_only_fb.ensure(GPU_ATTACHMENT_NONE, + GPU_ATTACHMENT_TEXTURE(resources.color_overlay_tx)); + + /* TODO(fclem): Remove mandatory allocation. */ + if (!resources.depth_in_front_tx.is_valid()) { + resources.depth_in_front_alloc_tx.acquire(render_size, GPU_DEPTH_COMPONENT24); + resources.depth_in_front_tx.wrap(resources.depth_in_front_alloc_tx); + } + + resources.overlay_in_front_fb.ensure(GPU_ATTACHMENT_TEXTURE(resources.depth_in_front_tx), + GPU_ATTACHMENT_TEXTURE(resources.color_overlay_tx)); + resources.overlay_line_in_front_fb.ensure(GPU_ATTACHMENT_TEXTURE(resources.depth_in_front_tx), + GPU_ATTACHMENT_TEXTURE(resources.color_overlay_tx), + GPU_ATTACHMENT_TEXTURE(resources.line_tx)); GPU_framebuffer_bind(resources.overlay_color_only_fb); @@ -103,11 +157,17 @@ void Instance::draw(Manager &manager) GPU_framebuffer_clear_color(resources.overlay_color_only_fb, clear_color); background.draw(resources, manager); + + metaballs.draw(resources, manager, view); + grid.draw(resources, manager, view); + metaballs.draw_in_front(resources, manager, view); + // anti_aliasing.draw(resources, manager, view); resources.line_tx.release(); + resources.depth_in_front_alloc_tx.release(); } } // namespace blender::draw::overlay diff --git a/source/blender/draw/engines/overlay/overlay_instance.hh b/source/blender/draw/engines/overlay/overlay_instance.hh index 09029963c9a..1fb199e4e6e 100644 --- a/source/blender/draw/engines/overlay/overlay_instance.hh +++ b/source/blender/draw/engines/overlay/overlay_instance.hh @@ -10,6 +10,7 @@ #include "overlay_background.hh" #include "overlay_grid.hh" +#include "overlay_metaball.hh" namespace blender::draw::overlay { @@ -58,6 +59,7 @@ class Instance { /** Overlay types. */ Background background; + Metaballs metaballs; Grid grid; ~Instance() @@ -70,6 +72,37 @@ class Instance { void object_sync(ObjectRef &ob_ref); void end_sync(); void draw(Manager &manager); + + private: + bool object_is_edit_mode(const Object *ob) + { + if (DRW_object_is_in_edit_mode(ob)) { + /* Also check for context mode as the object mode is not 100% reliable. (see T72490) */ + switch (ob->type) { + case OB_MESH: + return state.ctx_mode == CTX_MODE_EDIT_MESH; + case OB_ARMATURE: + return state.ctx_mode == CTX_MODE_EDIT_ARMATURE; + case OB_CURVES_LEGACY: + return state.ctx_mode == CTX_MODE_EDIT_CURVE; + case OB_SURF: + return state.ctx_mode == CTX_MODE_EDIT_SURFACE; + case OB_LATTICE: + return state.ctx_mode == CTX_MODE_EDIT_LATTICE; + case OB_MBALL: + return state.ctx_mode == CTX_MODE_EDIT_METABALL; + case OB_FONT: + return state.ctx_mode == CTX_MODE_EDIT_TEXT; + case OB_CURVES: + return state.ctx_mode == CTX_MODE_EDIT_CURVES; + case OB_POINTCLOUD: + case OB_VOLUME: + /* No edit mode yet. */ + return false; + } + } + return false; + } }; } // namespace blender::draw::overlay diff --git a/source/blender/draw/engines/overlay/overlay_metaball.hh b/source/blender/draw/engines/overlay/overlay_metaball.hh new file mode 100644 index 00000000000..0bffac49180 --- /dev/null +++ b/source/blender/draw/engines/overlay/overlay_metaball.hh @@ -0,0 +1,132 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup overlay + */ + +#pragma once + +#include "DEG_depsgraph_query.h" +#include "DNA_camera_types.h" +#include "DNA_space_types.h" +#include "ED_view3d.h" +#include "UI_resources.h" + +#include "draw_cache.h" +#include "draw_pass.hh" +#include "overlay_private.hh" +#include "overlay_shader_shared.h" + +namespace blender::draw::overlay { + +class Metaballs { + + private: + PassSimple metaball_ps_ = {"MetaBalls"}; + PassSimple metaball_in_front_ps_ = {"MetaBalls_In_front"}; + + ArmatureSphereBuf data_buf_ = {"metaball_data_buf"}; + ArmatureSphereBuf data_in_front_buf_ = {"metaball_data_buf"}; + + public: + void begin_sync() + { + data_buf_.clear(); + data_in_front_buf_.clear(); + } + + void metaball_instance_data_set(BoneInstanceData *data, + Object *ob, + const float *pos, + const float radius, + const float color[4]) + { + /* Bone point radius is 0.05. Compensate for that. */ + mul_v3_v3fl(data->mat[0], ob->obmat[0], radius / 0.05f); + mul_v3_v3fl(data->mat[1], ob->obmat[1], radius / 0.05f); + mul_v3_v3fl(data->mat[2], ob->obmat[2], radius / 0.05f); + mul_v3_m4v3(data->mat[3], ob->obmat, pos); + /* WATCH: Reminder, alpha is wire-size. */ + OVERLAY_bone_instance_data_set_color(data, color); + } + + void edit_object_sync(const ObjectRef &ob_ref, const Resources &res) + { + ArmatureSphereBuf &data_buf = (ob_ref.object->dtx & OB_DRAW_IN_FRONT) != 0 ? + data_in_front_buf_ : + data_buf_; + MetaBall *mb = static_cast<MetaBall *>(ob_ref.object->data); + + const float *color; + const float *col_radius = res.theme_settings.color_mball_radius; + const float *col_radius_select = res.theme_settings.color_mball_radius_select; + const float *col_stiffness = res.theme_settings.color_mball_stiffness; + const float *col_stiffness_select = res.theme_settings.color_mball_stiffness_select; + + LISTBASE_FOREACH (MetaElem *, ml, mb->editelems) { + const bool is_selected = (ml->flag & SELECT) != 0; + const bool is_scale_radius = (ml->flag & MB_SCALE_RAD) != 0; + float stiffness_radius = ml->rad * atanf(ml->s) / float(M_PI_2); + BoneInstanceData instdata; + + color = (is_selected && is_scale_radius) ? col_radius_select : col_radius; + metaball_instance_data_set(&instdata, ob_ref.object, &ml->x, ml->rad, color); + data_buf.append(*reinterpret_cast<float4x4 *>(&instdata)); + + color = (is_selected && !is_scale_radius) ? col_stiffness_select : col_stiffness; + metaball_instance_data_set(&instdata, ob_ref.object, &ml->x, stiffness_radius, color); + data_buf.append(*reinterpret_cast<float4x4 *>(&instdata)); + } + } + + void object_sync(const ObjectRef &ob_ref, const Resources &res, const State &state) + { + ArmatureSphereBuf &data_buf = (ob_ref.object->dtx & OB_DRAW_IN_FRONT) != 0 ? + data_in_front_buf_ : + data_buf_; + MetaBall *mb = static_cast<MetaBall *>(ob_ref.object->data); + + float *color; + /* TODO(fclem): Remove DRW global usage. */ + UNUSED_VARS(res); + DRW_object_wire_theme_get(ob_ref.object, state.view_layer, &color); + + LISTBASE_FOREACH (MetaElem *, ml, &mb->elems) { + /* Draw radius only. */ + BoneInstanceData instdata; + metaball_instance_data_set(&instdata, ob_ref.object, &ml->x, ml->rad, color); + data_buf.append(*reinterpret_cast<float4x4 *>(&instdata)); + } + } + + void end_sync(Resources &res, const State &state) + { + auto init_pass = [&](PassSimple &pass, ArmatureSphereBuf &data_buf) { + data_buf.push_update(); + + pass.init(); + pass.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | + state.clipping_state); + pass.shader_set(OVERLAY_shader_armature_sphere(true)); + pass.bind_ubo("globalsBlock", &res.globals_buf); + pass.bind_ssbo("data_buf", &data_buf); + pass.draw(DRW_cache_bone_point_wire_outline_get(), data_buf.size()); + }; + init_pass(metaball_ps_, data_buf_); + init_pass(metaball_in_front_ps_, data_in_front_buf_); + } + + void draw(Resources &res, Manager &manager, View &view) + { + GPU_framebuffer_bind(res.overlay_line_fb); + manager.submit(metaball_ps_, view); + } + + void draw_in_front(Resources &res, Manager &manager, View &view) + { + GPU_framebuffer_bind(res.overlay_line_in_front_fb); + manager.submit(metaball_in_front_ps_, view); + } +}; + +} // 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 ed905991572..990946a11a5 100644 --- a/source/blender/draw/engines/overlay/overlay_private.hh +++ b/source/blender/draw/engines/overlay/overlay_private.hh @@ -33,6 +33,7 @@ class Instance; struct State { Depsgraph *depsgraph; + ViewLayer *view_layer; Scene *scene; View3D *v3d; RegionView3D *rv3d; @@ -53,9 +54,11 @@ struct State { }; using blender::draw::Framebuffer; +using blender::draw::StorageVectorBuffer; using blender::draw::Texture; using blender::draw::TextureFromPool; using blender::draw::TextureRef; +using ArmatureSphereBuf = StorageVectorBuffer<float4x4>; struct Resources { Framebuffer overlay_fb = {"overlay_fb"}; @@ -65,6 +68,7 @@ struct Resources { Framebuffer overlay_line_in_front_fb = {"overlay_line_in_front_fb"}; TextureFromPool line_tx = {"line_tx"}; + TextureFromPool depth_in_front_alloc_tx = {"overlay_depth_in_front_tx"}; /** TODO(fclem): Copy of G_data.block that should become theme colors only and managed by the * engine. */ @@ -72,6 +76,7 @@ struct Resources { /* References, not owned. */ GPUUniformBuf *globals_buf; TextureRef depth_tx; + TextureRef depth_in_front_tx; TextureRef color_overlay_tx; TextureRef color_render_tx; }; diff --git a/source/blender/draw/engines/overlay/overlay_shader.cc b/source/blender/draw/engines/overlay/overlay_shader.cc index b7e5e8c56b7..98e082aac84 100644 --- a/source/blender/draw/engines/overlay/overlay_shader.cc +++ b/source/blender/draw/engines/overlay/overlay_shader.cc @@ -11,6 +11,8 @@ #include "UI_resources.h" +#include "gpu_shader_create_info.hh" + #include "overlay_private.hh" typedef struct OVERLAY_Shaders { @@ -182,6 +184,17 @@ GPUShader *OVERLAY_shader_armature_sphere(bool use_outline) const DRWContextState *draw_ctx = DRW_context_state_get(); OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (use_outline && !sh_data->armature_sphere_outline) { + using namespace blender::gpu::shader; + ShaderCreateInfo &info = const_cast<ShaderCreateInfo &>( + *reinterpret_cast<const ShaderCreateInfo *>( + GPU_shader_create_info_get("overlay_armature_sphere_outline"))); + + if (U.experimental.enable_overlay_next) { + info.storage_buf(0, Qualifier::READ, "mat4", "data_buf[]"); + info.define("inst_obmat", "data_buf[gl_InstanceID]"); + info.vertex_inputs_.pop_last(); + } + sh_data->armature_sphere_outline = GPU_shader_create_from_info_name( draw_ctx->sh_cfg ? "overlay_armature_sphere_outline_clipped" : "overlay_armature_sphere_outline"); |