Overlay-Next: Initial implementation #107045
@ -19,12 +19,14 @@
|
||||
|
||||
namespace blender::draw::overlay {
|
||||
|
||||
class Background {
|
||||
template<typename SelectEngineT> class Background {
|
||||
using ResourcesT = Resources<SelectEngineT>;
|
||||
|
||||
private:
|
||||
PassSimple bg_ps_ = {"Background"};
|
||||
|
||||
public:
|
||||
void begin_sync(Resources &res, const State &state)
|
||||
void begin_sync(ResourcesT &res, const State &state)
|
||||
{
|
||||
DRWState pass_state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_BACKGROUND;
|
||||
float4 color_override(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
@ -92,7 +94,7 @@ class Background {
|
||||
}
|
||||
}
|
||||
|
||||
void draw(Resources &res, Manager &manager)
|
||||
void draw(ResourcesT &res, Manager &manager)
|
||||
{
|
||||
GPU_framebuffer_bind(res.overlay_color_only_fb);
|
||||
manager.submit(bg_ps_);
|
||||
|
@ -15,14 +15,15 @@
|
||||
|
||||
namespace blender::draw::overlay {
|
||||
|
||||
class Empties {
|
||||
template<typename SelectEngineT> class Empties {
|
||||
using SelectID = typename SelectEngineT::ID;
|
||||
using ResourcesT = Resources<SelectEngineT>;
|
||||
using EmptyInstanceBuf = ShapeInstanceBuf<SelectEngineT, ExtraInstanceData>;
|
||||
|
||||
private:
|
||||
PassSimple empty_ps_ = {"Empties"};
|
||||
PassSimple empty_in_front_ps_ = {"Empties_In_front"};
|
||||
|
||||
using EmptyInstanceBuf = StorageVectorBuffer<ExtraInstanceData>;
|
||||
|
||||
struct CallBuffers {
|
||||
EmptyInstanceBuf plain_axes_buf = {"plain_axes_buf"};
|
||||
EmptyInstanceBuf single_arrow_buf = {"single_arrow_buf"};
|
||||
@ -49,7 +50,7 @@ class Empties {
|
||||
}
|
||||
}
|
||||
|
||||
void object_sync(const ObjectRef &ob_ref, const Resources &res, const State &state)
|
||||
void object_sync(const ObjectRef &ob_ref, ResourcesT &res, const State &state)
|
||||
{
|
||||
CallBuffers &call_bufs = call_buffers_[int((ob_ref.object->dtx & OB_DRAW_IN_FRONT) != 0)];
|
||||
|
||||
@ -57,36 +58,39 @@ class Empties {
|
||||
ExtraInstanceData data(
|
||||
float4x4(ob_ref.object->object_to_world), color, ob_ref.object->empty_drawsize);
|
||||
|
||||
/* TODO(fclem): Get selection ID from the selection engine. */
|
||||
const SelectID select_id = res.select_id(ob_ref);
|
||||
|
||||
switch (ob_ref.object->empty_drawtype) {
|
||||
case OB_PLAINAXES:
|
||||
call_bufs.plain_axes_buf.append(data);
|
||||
call_bufs.plain_axes_buf.append(data, select_id);
|
||||
break;
|
||||
case OB_SINGLE_ARROW:
|
||||
call_bufs.single_arrow_buf.append(data);
|
||||
call_bufs.single_arrow_buf.append(data, select_id);
|
||||
break;
|
||||
case OB_CUBE:
|
||||
call_bufs.cube_buf.append(data);
|
||||
call_bufs.cube_buf.append(data, select_id);
|
||||
break;
|
||||
case OB_CIRCLE:
|
||||
call_bufs.circle_buf.append(data);
|
||||
call_bufs.circle_buf.append(data, select_id);
|
||||
break;
|
||||
case OB_EMPTY_SPHERE:
|
||||
call_bufs.sphere_buf.append(data);
|
||||
call_bufs.sphere_buf.append(data, select_id);
|
||||
break;
|
||||
case OB_EMPTY_CONE:
|
||||
call_bufs.cone_buf.append(data);
|
||||
call_bufs.cone_buf.append(data, select_id);
|
||||
break;
|
||||
case OB_ARROWS:
|
||||
call_bufs.arrows_buf.append(data);
|
||||
call_bufs.arrows_buf.append(data, select_id);
|
||||
break;
|
||||
case OB_EMPTY_IMAGE:
|
||||
/* This only show the frame. See OVERLAY_image_empty_cache_populate() for the image. */
|
||||
call_bufs.image_buf.append(data);
|
||||
call_bufs.image_buf.append(data, select_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void end_sync(Resources &res, ShapeCache &shapes, const State &state)
|
||||
void end_sync(ResourcesT &res, ShapeCache &shapes, const State &state)
|
||||
{
|
||||
auto init_pass = [&](PassSimple &pass, CallBuffers &call_bufs) {
|
||||
pass.init();
|
||||
@ -95,49 +99,26 @@ class Empties {
|
||||
pass.shader_set(OVERLAY_shader_extra(false));
|
||||
pass.bind_ubo("globalsBlock", &res.globals_buf);
|
||||
|
||||
call_bufs.plain_axes_buf.push_update();
|
||||
pass.bind_ssbo("data_buf", &call_bufs.plain_axes_buf);
|
||||
pass.draw(shapes.plain_axes, call_bufs.plain_axes_buf.size());
|
||||
|
||||
call_bufs.single_arrow_buf.push_update();
|
||||
pass.bind_ssbo("data_buf", &call_bufs.single_arrow_buf);
|
||||
pass.draw(shapes.single_arrow, call_bufs.single_arrow_buf.size());
|
||||
|
||||
call_bufs.cube_buf.push_update();
|
||||
pass.bind_ssbo("data_buf", &call_bufs.cube_buf);
|
||||
pass.draw(shapes.cube, call_bufs.cube_buf.size());
|
||||
|
||||
call_bufs.circle_buf.push_update();
|
||||
pass.bind_ssbo("data_buf", &call_bufs.circle_buf);
|
||||
pass.draw(shapes.circle, call_bufs.circle_buf.size());
|
||||
|
||||
call_bufs.sphere_buf.push_update();
|
||||
pass.bind_ssbo("data_buf", &call_bufs.sphere_buf);
|
||||
pass.draw(shapes.empty_sphere, call_bufs.sphere_buf.size());
|
||||
|
||||
call_bufs.cone_buf.push_update();
|
||||
pass.bind_ssbo("data_buf", &call_bufs.cone_buf);
|
||||
pass.draw(shapes.empty_cone, call_bufs.cone_buf.size());
|
||||
|
||||
call_bufs.arrows_buf.push_update();
|
||||
pass.bind_ssbo("data_buf", &call_bufs.arrows_buf);
|
||||
pass.draw(shapes.arrows, call_bufs.arrows_buf.size());
|
||||
|
||||
call_bufs.image_buf.push_update();
|
||||
pass.bind_ssbo("data_buf", &call_bufs.image_buf);
|
||||
pass.draw(shapes.quad_wire, call_bufs.image_buf.size());
|
||||
call_bufs.plain_axes_buf.end_sync(pass, shapes.plain_axes);
|
||||
call_bufs.single_arrow_buf.end_sync(pass, shapes.single_arrow);
|
||||
call_bufs.cube_buf.end_sync(pass, shapes.cube);
|
||||
call_bufs.circle_buf.end_sync(pass, shapes.circle);
|
||||
call_bufs.sphere_buf.end_sync(pass, shapes.empty_sphere);
|
||||
call_bufs.cone_buf.end_sync(pass, shapes.empty_cone);
|
||||
call_bufs.arrows_buf.end_sync(pass, shapes.arrows);
|
||||
call_bufs.image_buf.end_sync(pass, shapes.quad_wire);
|
||||
};
|
||||
init_pass(empty_ps_, call_buffers_[0]);
|
||||
init_pass(empty_in_front_ps_, call_buffers_[1]);
|
||||
}
|
||||
|
||||
void draw(Resources &res, Manager &manager, View &view)
|
||||
void draw(ResourcesT &res, Manager &manager, View &view)
|
||||
{
|
||||
GPU_framebuffer_bind(res.overlay_line_fb);
|
||||
manager.submit(empty_ps_, view);
|
||||
}
|
||||
|
||||
void draw_in_front(Resources &res, Manager &manager, View &view)
|
||||
void draw_in_front(ResourcesT &res, Manager &manager, View &view)
|
||||
{
|
||||
GPU_framebuffer_bind(res.overlay_line_in_front_fb);
|
||||
manager.submit(empty_in_front_ps_, view);
|
||||
|
@ -30,6 +30,10 @@
|
||||
#include "overlay_engine.h"
|
||||
#include "overlay_private.hh"
|
||||
|
||||
using namespace blender::draw;
|
||||
|
||||
using Instance = blender::draw::overlay::Instance<>;
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Engine Callbacks
|
||||
* \{ */
|
||||
@ -51,7 +55,7 @@ static void OVERLAY_engine_init(void *vedata)
|
||||
|
||||
/* Allocate instance. */
|
||||
if (data->instance == nullptr) {
|
||||
data->instance = new blender::draw::overlay::Instance();
|
||||
data->instance = new Instance();
|
||||
}
|
||||
|
||||
OVERLAY_PrivateData *pd = stl->pd;
|
||||
@ -737,7 +741,7 @@ static void OVERLAY_engine_free()
|
||||
|
||||
static void OVERLAY_instance_free(void *instance_)
|
||||
{
|
||||
blender::draw::overlay::Instance *instance = (blender::draw::overlay::Instance *)instance_;
|
||||
auto *instance = (Instance *)instance_;
|
||||
if (instance != nullptr) {
|
||||
delete instance;
|
||||
}
|
||||
@ -748,8 +752,6 @@ static void OVERLAY_instance_free(void *instance_)
|
||||
/** \name Engine Instance
|
||||
* \{ */
|
||||
|
||||
using namespace blender::draw;
|
||||
|
||||
static void OVERLAY_next_engine_init(void *vedata)
|
||||
{
|
||||
if (!GPU_shader_storage_buffer_objects_support()) {
|
||||
@ -759,10 +761,10 @@ static void OVERLAY_next_engine_init(void *vedata)
|
||||
OVERLAY_Data *ved = reinterpret_cast<OVERLAY_Data *>(vedata);
|
||||
|
||||
if (ved->instance == nullptr) {
|
||||
ved->instance = new overlay::Instance();
|
||||
ved->instance = new Instance();
|
||||
}
|
||||
|
||||
ved->instance->init();
|
||||
reinterpret_cast<Instance *>(ved->instance)->init();
|
||||
}
|
||||
|
||||
static void OVERLAY_next_cache_init(void *vedata)
|
||||
@ -770,7 +772,7 @@ static void OVERLAY_next_cache_init(void *vedata)
|
||||
if (!GPU_shader_storage_buffer_objects_support()) {
|
||||
return;
|
||||
}
|
||||
reinterpret_cast<OVERLAY_Data *>(vedata)->instance->begin_sync();
|
||||
reinterpret_cast<Instance *>(reinterpret_cast<OVERLAY_Data *>(vedata)->instance)->begin_sync();
|
||||
}
|
||||
|
||||
static void OVERLAY_next_cache_populate(void *vedata, Object *object)
|
||||
@ -783,7 +785,8 @@ static void OVERLAY_next_cache_populate(void *vedata, 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);
|
||||
reinterpret_cast<Instance *>(reinterpret_cast<OVERLAY_Data *>(vedata)->instance)
|
||||
->object_sync(ref);
|
||||
}
|
||||
|
||||
static void OVERLAY_next_cache_finish(void *vedata)
|
||||
@ -791,7 +794,7 @@ static void OVERLAY_next_cache_finish(void *vedata)
|
||||
if (!GPU_shader_storage_buffer_objects_support()) {
|
||||
return;
|
||||
}
|
||||
reinterpret_cast<OVERLAY_Data *>(vedata)->instance->end_sync();
|
||||
reinterpret_cast<Instance *>(reinterpret_cast<OVERLAY_Data *>(vedata)->instance)->end_sync();
|
||||
}
|
||||
|
||||
static void OVERLAY_next_draw_scene(void *vedata)
|
||||
@ -800,7 +803,8 @@ static void OVERLAY_next_draw_scene(void *vedata)
|
||||
return;
|
||||
}
|
||||
|
||||
reinterpret_cast<OVERLAY_Data *>(vedata)->instance->draw(*DRW_manager_get());
|
||||
reinterpret_cast<Instance *>(reinterpret_cast<OVERLAY_Data *>(vedata)->instance)
|
||||
->draw(*DRW_manager_get());
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
@ -20,6 +20,10 @@
|
||||
#include "overlay_instance.hh"
|
||||
#include "overlay_private.hh"
|
||||
|
||||
using namespace blender::draw;
|
||||
|
||||
using Instance = blender::draw::overlay::Instance<>;
|
||||
|
||||
BLI_STATIC_ASSERT(SI_GRID_STEPS_LEN == OVERLAY_GRID_STEPS_LEN, "")
|
||||
|
||||
void OVERLAY_grid_init(OVERLAY_Data *vedata)
|
||||
@ -226,10 +230,11 @@ void OVERLAY_grid_cache_init(OVERLAY_Data *ved)
|
||||
return;
|
||||
}
|
||||
|
||||
if (ved->instance->grid_ubo == nullptr) {
|
||||
ved->instance->grid_ubo = GPU_uniformbuf_create(sizeof(OVERLAY_GridData));
|
||||
GPUUniformBuf *&grid_ubo = reinterpret_cast<Instance *>(ved->instance)->grid_ubo;
|
||||
if (grid_ubo == nullptr) {
|
||||
grid_ubo = GPU_uniformbuf_create(sizeof(OVERLAY_GridData));
|
||||
}
|
||||
GPU_uniformbuf_update(ved->instance->grid_ubo, &pd->grid_data);
|
||||
GPU_uniformbuf_update(grid_ubo, &pd->grid_data);
|
||||
|
||||
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA;
|
||||
DRW_PASS_CREATE(psl->grid_ps, state);
|
||||
@ -259,7 +264,7 @@ void OVERLAY_grid_cache_init(OVERLAY_Data *ved)
|
||||
|
||||
/* Create 3 quads to render ordered transparency Z axis */
|
||||
grp = DRW_shgroup_create(sh, psl->grid_ps);
|
||||
DRW_shgroup_uniform_block(grp, "grid_buf", ved->instance->grid_ubo);
|
||||
DRW_shgroup_uniform_block(grp, "grid_buf", grid_ubo);
|
||||
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
|
||||
DRW_shgroup_uniform_texture_ref(grp, "depth_tx", &dtxl->depth);
|
||||
|
||||
|
@ -18,7 +18,9 @@
|
||||
|
||||
namespace blender::draw::overlay {
|
||||
|
||||
class Grid {
|
||||
template<typename SelectEngineT> class Grid {
|
||||
using ResourcesT = Resources<SelectEngineT>;
|
||||
|
||||
private:
|
||||
UniformBuffer<OVERLAY_GridData> data_;
|
||||
|
||||
@ -164,7 +166,7 @@ class Grid {
|
||||
data_.push_update();
|
||||
}
|
||||
|
||||
void begin_sync(Resources &res, const State &state, const View &view)
|
||||
void begin_sync(ResourcesT &res, const State &state, const View &view)
|
||||
{
|
||||
this->update_ubo(state, view);
|
||||
|
||||
@ -195,7 +197,7 @@ class Grid {
|
||||
}
|
||||
}
|
||||
|
||||
void draw(Resources &res, Manager &manager, View &view)
|
||||
void draw(ResourcesT &res, Manager &manager, View &view)
|
||||
{
|
||||
if (!enabled_) {
|
||||
return;
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
namespace blender::draw::overlay {
|
||||
|
||||
void Instance::init()
|
||||
template<typename T> void Instance<T>::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);
|
||||
@ -65,7 +65,7 @@ void Instance::init()
|
||||
resources.theme_settings = G_draw.block;
|
||||
}
|
||||
|
||||
void Instance::begin_sync()
|
||||
template<typename T> void Instance<T>::begin_sync()
|
||||
{
|
||||
const DRWView *view_legacy = DRW_view_default_get();
|
||||
View view("OverlayView", view_legacy);
|
||||
@ -76,7 +76,7 @@ void Instance::begin_sync()
|
||||
grid.begin_sync(resources, state, view);
|
||||
}
|
||||
|
||||
void Instance::object_sync(ObjectRef &ob_ref)
|
||||
template<typename T> void Instance<T>::object_sync(ObjectRef &ob_ref)
|
||||
{
|
||||
const bool in_edit_mode = object_is_edit_mode(ob_ref.object);
|
||||
|
||||
@ -120,13 +120,13 @@ void Instance::object_sync(ObjectRef &ob_ref)
|
||||
}
|
||||
}
|
||||
|
||||
void Instance::end_sync()
|
||||
template<typename T> void Instance<T>::end_sync()
|
||||
{
|
||||
metaballs.end_sync(resources, state);
|
||||
empties.end_sync(resources, shapes, state);
|
||||
}
|
||||
|
||||
void Instance::draw(Manager &manager)
|
||||
template<typename T> void Instance<T>::draw(Manager &manager)
|
||||
{
|
||||
/* WORKAROUND: This is to prevent crashes when using depth picking or selection.
|
||||
* The selection engine should handle theses cases instead. */
|
||||
@ -182,4 +182,11 @@ void Instance::draw(Manager &manager)
|
||||
resources.depth_in_front_alloc_tx.release();
|
||||
}
|
||||
|
||||
/* Instantiation. */
|
||||
template void Instance<>::init();
|
||||
template void Instance<>::begin_sync();
|
||||
template void Instance<>::object_sync(ObjectRef &ob_ref);
|
||||
template void Instance<>::end_sync();
|
||||
template void Instance<>::draw(Manager &manager);
|
||||
|
||||
} // namespace blender::draw::overlay
|
||||
|
@ -14,6 +14,9 @@
|
||||
#include "overlay_metaball.hh"
|
||||
#include "overlay_shape.hh"
|
||||
|
||||
#include "../select/select_empty.hh"
|
||||
#include "../select/select_object.hh"
|
||||
|
||||
namespace blender::draw::overlay {
|
||||
|
||||
class ShaderCache {
|
||||
@ -22,32 +25,12 @@ class ShaderCache {
|
||||
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();
|
||||
// }
|
||||
}
|
||||
};
|
||||
|
||||
template<
|
||||
/* Selection engine reuse most of the Overlay engine by creating selection IDs for each
|
||||
* selectable component and using a special shaders for drawing.
|
||||
* Making the select engine templated makes it easier to phase out any overhead of the
|
||||
* selection for the regular non-selection case.*/
|
||||
typename SelectEngineT = select::EngineEmpty>
|
||||
class Instance {
|
||||
public:
|
||||
ShaderCache shaders;
|
||||
@ -57,14 +40,14 @@ class Instance {
|
||||
GPUUniformBuf *grid_ubo = nullptr;
|
||||
|
||||
/** Global types. */
|
||||
Resources resources;
|
||||
Resources<SelectEngineT> resources;
|
||||
State state;
|
||||
|
||||
/** Overlay types. */
|
||||
Background background;
|
||||
Metaballs metaballs;
|
||||
Empties empties;
|
||||
Grid grid;
|
||||
Background<SelectEngineT> background;
|
||||
Metaballs<SelectEngineT> metaballs;
|
||||
Empties<SelectEngineT> empties;
|
||||
Grid<SelectEngineT> grid;
|
||||
|
||||
~Instance()
|
||||
{
|
||||
@ -109,4 +92,11 @@ 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<>::end_sync();
|
||||
extern template void Instance<>::draw(Manager &manager);
|
||||
|
||||
} // namespace blender::draw::overlay
|
||||
|
@ -19,7 +19,8 @@
|
||||
|
||||
namespace blender::draw::overlay {
|
||||
|
||||
class Metaballs {
|
||||
template<typename SelectEngineT> class Metaballs {
|
||||
using ResourcesT = Resources<SelectEngineT>;
|
||||
|
||||
private:
|
||||
PassSimple metaball_ps_ = {"MetaBalls"};
|
||||
@ -50,7 +51,7 @@ class Metaballs {
|
||||
OVERLAY_bone_instance_data_set_color(data, color);
|
||||
}
|
||||
|
||||
void edit_object_sync(const ObjectRef &ob_ref, const Resources &res)
|
||||
void edit_object_sync(const ObjectRef &ob_ref, const ResourcesT &res)
|
||||
{
|
||||
ArmatureSphereBuf &data_buf = (ob_ref.object->dtx & OB_DRAW_IN_FRONT) != 0 ?
|
||||
data_in_front_buf_ :
|
||||
@ -79,7 +80,7 @@ class Metaballs {
|
||||
}
|
||||
}
|
||||
|
||||
void object_sync(const ObjectRef &ob_ref, const Resources &res, const State &state)
|
||||
void object_sync(const ObjectRef &ob_ref, const ResourcesT &res, const State &state)
|
||||
{
|
||||
ArmatureSphereBuf &data_buf = (ob_ref.object->dtx & OB_DRAW_IN_FRONT) != 0 ?
|
||||
data_in_front_buf_ :
|
||||
@ -96,7 +97,7 @@ class Metaballs {
|
||||
}
|
||||
}
|
||||
|
||||
void end_sync(Resources &res, const State &state)
|
||||
void end_sync(ResourcesT &res, const State &state)
|
||||
{
|
||||
auto init_pass = [&](PassSimple &pass, ArmatureSphereBuf &data_buf) {
|
||||
data_buf.push_update();
|
||||
@ -113,13 +114,13 @@ class Metaballs {
|
||||
init_pass(metaball_in_front_ps_, data_in_front_buf_);
|
||||
}
|
||||
|
||||
void draw(Resources &res, Manager &manager, View &view)
|
||||
void draw(ResourcesT &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)
|
||||
void draw_in_front(ResourcesT &res, Manager &manager, View &view)
|
||||
{
|
||||
GPU_framebuffer_bind(res.overlay_line_in_front_fb);
|
||||
manager.submit(metaball_in_front_ps_, view);
|
||||
|
@ -18,10 +18,6 @@
|
||||
|
||||
#include "overlay_shader_shared.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
# define USE_GEOM_SHADER_WORKAROUND 1
|
||||
#else
|
||||
@ -35,7 +31,7 @@ extern "C" {
|
||||
struct ImBuf;
|
||||
|
||||
namespace blender::draw::overlay {
|
||||
class Instance;
|
||||
template<typename SelectEngineT> class Instance;
|
||||
|
||||
struct State {
|
||||
Depsgraph *depsgraph;
|
||||
@ -68,7 +64,7 @@ using blender::draw::TextureFromPool;
|
||||
using blender::draw::TextureRef;
|
||||
using ArmatureSphereBuf = StorageVectorBuffer<float4x4>;
|
||||
|
||||
struct Resources {
|
||||
template<typename SelectEngineT> struct Resources : public SelectEngineT::SelectMap {
|
||||
Framebuffer overlay_fb = {"overlay_fb"};
|
||||
Framebuffer overlay_in_front_fb = {"overlay_in_front_fb"};
|
||||
Framebuffer overlay_color_only_fb = {"overlay_color_only_fb"};
|
||||
@ -578,7 +574,7 @@ typedef struct OVERLAY_Data {
|
||||
OVERLAY_PassList *psl;
|
||||
OVERLAY_StorageList *stl;
|
||||
|
||||
blender::draw::overlay::Instance *instance;
|
||||
void *instance;
|
||||
} OVERLAY_Data;
|
||||
|
||||
typedef struct OVERLAY_DupliData {
|
||||
@ -927,7 +923,3 @@ GPUShader *OVERLAY_shader_xray_fade(void);
|
||||
OVERLAY_InstanceFormats *OVERLAY_shader_instance_formats_get(void);
|
||||
|
||||
void OVERLAY_shader_free(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -192,7 +192,6 @@ struct ThemeColorData {
|
||||
};
|
||||
BLI_STATIC_ASSERT_ALIGN(ThemeColorData, 16)
|
||||
|
||||
/* TODO Move to overlay engine. */
|
||||
struct ExtraInstanceData {
|
||||
float4 color_;
|
||||
float4x4 object_to_world_;
|
||||
|
@ -12,6 +12,41 @@
|
||||
|
||||
namespace blender::draw::overlay {
|
||||
|
||||
/**
|
||||
* Buffer containing instances of a certain shape.
|
||||
*/
|
||||
template<typename SelectEngineT, typename InstanceDataT>
|
||||
struct ShapeInstanceBuf : private SelectEngineT::SelectBuf {
|
||||
using SelectID = typename SelectEngineT::ID;
|
||||
|
||||
StorageVectorBuffer<InstanceDataT> data_buf;
|
||||
|
||||
ShapeInstanceBuf(const char *name = nullptr) : data_buf(name){};
|
||||
|
||||
void clear()
|
||||
{
|
||||
this->select_clear();
|
||||
data_buf.clear();
|
||||
}
|
||||
|
||||
void append(const InstanceDataT &data, SelectID select_id)
|
||||
{
|
||||
this->select_append(select_id);
|
||||
data_buf.append(data);
|
||||
}
|
||||
|
||||
void end_sync(PassSimple &pass, GPUBatch *shape)
|
||||
{
|
||||
if (data_buf.size() == 0) {
|
||||
return;
|
||||
}
|
||||
this->select_bind(pass);
|
||||
data_buf.push_update();
|
||||
pass.bind_ssbo("data_buf", &data_buf);
|
||||
pass.draw(shape, data_buf.size());
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Contains all overlay generic geometry batches.
|
||||
*/
|
||||
|
34
source/blender/draw/engines/select/select_empty.hh
Normal file
34
source/blender/draw/engines/select/select_empty.hh
Normal file
@ -0,0 +1,34 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2023 Blender Foundation. */
|
||||
|
||||
/** \file
|
||||
* \ingroup draw_engine
|
||||
*
|
||||
* Dummy implementation of the select engine types to avoid any overhead.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "draw_manager.hh"
|
||||
|
||||
namespace blender::draw::select {
|
||||
|
||||
struct EngineEmpty {
|
||||
/* Add type safety to selection ID. Only the select engine should provide them. */
|
||||
struct ID {};
|
||||
|
||||
struct SelectBuf {
|
||||
void select_clear(){};
|
||||
void select_append(ID){};
|
||||
void select_bind(PassSimple &){};
|
||||
};
|
||||
|
||||
struct SelectMap {
|
||||
[[nodiscard]] constexpr ID select_id(const ObjectRef &)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace blender::draw::select
|
63
source/blender/draw/engines/select/select_object.hh
Normal file
63
source/blender/draw/engines/select/select_object.hh
Normal file
@ -0,0 +1,63 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2023 Blender Foundation. */
|
||||
|
||||
/** \file
|
||||
* \ingroup draw_engine
|
||||
*
|
||||
* This is an implementation of the Select engine specialized for selecting object.
|
||||
* Should plug seamlessly inside the overlay engine logic.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "DRW_gpu_wrapper.hh"
|
||||
#include "draw_manager.hh"
|
||||
|
||||
namespace blender::draw::select {
|
||||
|
||||
struct EngineObject {
|
||||
/* Add type safety to selection ID. Only the select engine should provide them. */
|
||||
struct ID {
|
||||
uint32_t value;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a dedicated selection id buffer to a pass.
|
||||
* Use this when not using a #PassMain which can pass the select ID via CustomID.
|
||||
*/
|
||||
struct SelectBuf {
|
||||
StorageVectorBuffer<uint32_t> select_buf = {"select_buf"};
|
||||
|
||||
void select_clear()
|
||||
{
|
||||
select_buf.clear();
|
||||
}
|
||||
|
||||
void select_append(ID select_id)
|
||||
{
|
||||
select_buf.append(select_id.value);
|
||||
}
|
||||
|
||||
void select_bind(PassSimple &pass)
|
||||
{
|
||||
select_buf.push_update();
|
||||
pass.bind_ssbo("select_buf", &select_buf);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate selection IDs from objects and keep record of the mapping between them.
|
||||
*/
|
||||
struct SelectMap {
|
||||
uint next_id = 0;
|
||||
Map<uint, ObjectRef> map;
|
||||
|
||||
[[nodiscard]] const ID select_id(const ObjectRef &)
|
||||
{
|
||||
/* TODO Insert Ref into the map. */
|
||||
return {next_id++};
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace blender::draw::select
|
Loading…
Reference in New Issue
Block a user