Overlay-Next: Initial implementation #107045

Closed
Clément Foucault wants to merge 28 commits from fclem/blender:overlay-next into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
6 changed files with 120 additions and 20 deletions
Showing only changes of commit 78ae27bab3 - Show all commits

View File

@ -786,7 +786,7 @@ static void OVERLAY_next_cache_populate(void *vedata, Object *object)
ref.dupli_parent = DRW_object_get_dupli_parent(object);
reinterpret_cast<Instance *>(reinterpret_cast<OVERLAY_Data *>(vedata)->instance)
->object_sync(ref);
->object_sync(ref, *DRW_manager_get());
}
static void OVERLAY_next_cache_finish(void *vedata)

View File

@ -71,14 +71,28 @@ template<typename T> void Instance<T>::begin_sync()
View view("OverlayView", view_legacy);
background.begin_sync(resources, state);
prepass.begin_sync(state);
empties.begin_sync();
metaballs.begin_sync();
grid.begin_sync(resources, state, view);
}
template<typename T> void Instance<T>::object_sync(ObjectRef &ob_ref)
template<typename T> void Instance<T>::object_sync(ObjectRef &ob_ref, Manager &manager)
{
const bool in_edit_mode = object_is_edit_mode(ob_ref.object);
const bool needs_prepass = true; /* TODO */
if (needs_prepass) {
switch (ob_ref.object->type) {
case OB_MESH:
case OB_SURF:
case OB_CURVES:
case OB_FONT:
case OB_CURVES_LEGACY:
prepass.object_sync(manager, ob_ref, resources);
break;
}
}
if (in_edit_mode && !state.hide_overlays) {
switch (ob_ref.object->type) {
@ -166,6 +180,9 @@ template<typename T> void Instance<T>::draw(Manager &manager)
float4 clear_color(0.0f);
GPU_framebuffer_clear_color(resources.overlay_color_only_fb, clear_color);
prepass.draw(resources, manager, view);
prepass.draw_in_front(resources, manager, view);
background.draw(resources, manager);
empties.draw(resources, manager, view);
@ -185,7 +202,7 @@ template<typename T> void Instance<T>::draw(Manager &manager)
/* Instantiation. */
template void Instance<>::init();
template void Instance<>::begin_sync();
template void Instance<>::object_sync(ObjectRef &ob_ref);
template void Instance<>::object_sync(ObjectRef &ob_ref, Manager &manager);
template void Instance<>::end_sync();
template void Instance<>::draw(Manager &manager);

View File

@ -12,6 +12,7 @@
#include "overlay_empty.hh"
#include "overlay_grid.hh"
#include "overlay_metaball.hh"
#include "overlay_prepass.hh"
#include "overlay_shape.hh"
#include "../select/select_empty.hh"
@ -45,6 +46,7 @@ class Instance {
/** Overlay types. */
Background<SelectEngineT> background;
Prepass<SelectEngineT> prepass;
Metaballs<SelectEngineT> metaballs;
Empties<SelectEngineT> empties;
Grid<SelectEngineT> grid;
@ -56,7 +58,7 @@ class Instance {
void init();
void begin_sync();
void object_sync(ObjectRef &ob_ref);
void object_sync(ObjectRef &ob_ref, Manager &manager);
void end_sync();
void draw(Manager &manager);
@ -95,7 +97,7 @@ class Instance {
/* Instantiation. */
extern template void Instance<>::init();
extern template void Instance<>::begin_sync();
extern template void Instance<>::object_sync(ObjectRef &ob_ref);
extern template void Instance<>::object_sync(ObjectRef &ob_ref, Manager &manager);
extern template void Instance<>::end_sync();
extern template void Instance<>::draw(Manager &manager);

View File

@ -28,21 +28,21 @@ template<typename SelectEngineT> class Metaballs {
PassSimple metaball_ps_ = {"MetaBalls"};
PassSimple metaball_in_front_ps_ = {"MetaBalls_In_front"};
SphereOutlineInstanceBuf data_buf_ = {"metaball_data_buf"};
SphereOutlineInstanceBuf data_in_front_buf_ = {"metaball_data_buf"};
SphereOutlineInstanceBuf circle_buf_ = {"metaball_data_buf"};
SphereOutlineInstanceBuf circle_in_front_buf_ = {"metaball_data_buf"};
public:
void begin_sync()
{
data_buf_.clear();
data_in_front_buf_.clear();
circle_buf_.clear();
circle_in_front_buf_.clear();
}
void edit_object_sync(const ObjectRef &ob_ref, ResourcesT &res)
{
SphereOutlineInstanceBuf &data_buf = (ob_ref.object->dtx & OB_DRAW_IN_FRONT) != 0 ?
data_in_front_buf_ :
data_buf_;
SphereOutlineInstanceBuf &circle_buf = (ob_ref.object->dtx & OB_DRAW_IN_FRONT) != 0 ?
circle_in_front_buf_ :
circle_buf_;
MetaBall *mb = static_cast<MetaBall *>(ob_ref.object->data);
const float *color;
@ -58,19 +58,19 @@ template<typename SelectEngineT> class Metaballs {
const SelectID radius_id = res.select_id(ob_ref, MBALLSEL_RADIUS);
color = (is_selected && is_scale_radius) ? col_radius_select : col_radius;
data_buf.append({ob_ref.object, &ml->x, ml->rad, color}, radius_id);
circle_buf.append({ob_ref.object, &ml->x, ml->rad, color}, radius_id);
const SelectID stiff_id = res.select_id(ob_ref, MBALLSEL_STIFF);
color = (is_selected && !is_scale_radius) ? col_stiffness_select : col_stiffness;
data_buf.append({ob_ref.object, &ml->x, stiffness_radius, color}, stiff_id);
circle_buf.append({ob_ref.object, &ml->x, stiffness_radius, color}, stiff_id);
}
}
void object_sync(const ObjectRef &ob_ref, ResourcesT &res, const State &state)
{
SphereOutlineInstanceBuf &data_buf = (ob_ref.object->dtx & OB_DRAW_IN_FRONT) != 0 ?
data_in_front_buf_ :
data_buf_;
SphereOutlineInstanceBuf &circle_buf = (ob_ref.object->dtx & OB_DRAW_IN_FRONT) != 0 ?
circle_in_front_buf_ :
circle_buf_;
MetaBall *mb = static_cast<MetaBall *>(ob_ref.object->data);
const float4 &color = res.object_wire_color(ob_ref, state);
@ -78,7 +78,7 @@ template<typename SelectEngineT> class Metaballs {
LISTBASE_FOREACH (MetaElem *, ml, &mb->elems) {
/* Draw radius only. */
data_buf.append({ob_ref.object, &ml->x, ml->rad, color}, select_id);
circle_buf.append({ob_ref.object, &ml->x, ml->rad, color}, select_id);
}
}
@ -93,8 +93,8 @@ template<typename SelectEngineT> class Metaballs {
call_buf.end_sync(pass, shapes.metaball_wire_circle);
};
init_pass(metaball_ps_, data_buf_);
init_pass(metaball_in_front_ps_, data_in_front_buf_);
init_pass(metaball_ps_, circle_buf_);
init_pass(metaball_in_front_ps_, circle_in_front_buf_);
}
void draw(ResourcesT &res, Manager &manager, View &view)

View File

@ -0,0 +1,71 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup overlay
*
* A depth pass that write surface depth when it is needed.
* It is also used for selecting non overlay-only objects.
*/
#pragma once
#include "draw_cache.h"
#include "overlay_private.hh"
namespace blender::draw::overlay {
template<typename SelectEngineT> class Prepass {
using SelectID = typename SelectEngineT::ID;
using ResourcesT = Resources<SelectEngineT>;
private:
PassMain prepass_ps_ = {"prepass"};
PassMain prepass_in_front_ps_ = {"prepass_in_front"};
public:
void begin_sync(const State &state)
{
auto init_pass = [&](PassMain &pass) {
pass.init();
pass.state_set(DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | state.clipping_state);
pass.shader_set(OVERLAY_shader_depth_only());
};
init_pass(prepass_ps_);
init_pass(prepass_in_front_ps_);
}
void object_sync(Manager &manager, const ObjectRef &ob_ref, ResourcesT & /*res*/)
{
PassMain &pass = (ob_ref.object->dtx & OB_DRAW_IN_FRONT) != 0 ? prepass_in_front_ps_ :
prepass_ps_;
/* TODO(fclem) This function should contain what `basic_cache_populate` contained. */
GPUBatch *geom = DRW_cache_object_surface_get(ob_ref.object);
if (geom) {
ResourceHandle res_handle = manager.resource_handle(ob_ref);
pass.draw(geom, res_handle);
/* TODO */
// const SelectID radius_id = res.select_id(ob_ref);
// pass.draw(geom, res_handle, radius_id.value);
}
}
void draw(ResourcesT &res, Manager &manager, View &view)
{
/* Should be fine to use the line buffer since the prepass only writes to the depth buffer. */
GPU_framebuffer_bind(res.overlay_line_fb);
manager.submit(prepass_ps_, view);
}
void draw_in_front(ResourcesT &res, Manager &manager, View &view)
{
/* Should be fine to use the line buffer since the prepass only writes to the depth buffer. */
GPU_framebuffer_bind(res.overlay_line_in_front_fb);
manager.submit(prepass_in_front_ps_, view);
}
};
} // namespace blender::draw::overlay

View File

@ -148,6 +148,16 @@ GPUShader *OVERLAY_shader_depth_only(void)
const DRWContextState *draw_ctx = DRW_context_state_get();
OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
if (!sh_data->depth_only) {
if (U.experimental.enable_overlay_next) {
using namespace blender::gpu::shader;
ShaderCreateInfo &info = const_cast<ShaderCreateInfo &>(
*reinterpret_cast<const ShaderCreateInfo *>(
GPU_shader_create_info_get("overlay_depth_only")));
info.additional_infos_.clear();
info.additional_info("draw_view", "draw_modelmat_new", "draw_resource_handle_new");
}
sh_data->depth_only = GPU_shader_create_from_info_name(
(draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_depth_only_clipped" :
"overlay_depth_only");