Overlay-Next: Initial implementation #107045
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
|
71
source/blender/draw/engines/overlay/overlay_prepass.hh
Normal file
71
source/blender/draw/engines/overlay/overlay_prepass.hh
Normal 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
|
@ -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");
|
||||
|
Loading…
Reference in New Issue
Block a user