Overlay-Next: Initial implementation #107045
|
@ -19,12 +19,14 @@
|
||||||
|
|
||||||
namespace blender::draw::overlay {
|
namespace blender::draw::overlay {
|
||||||
|
|
||||||
class Background {
|
template<typename SelectEngineT> class Background {
|
||||||
|
using ResourcesT = Resources<SelectEngineT>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PassSimple bg_ps_ = {"Background"};
|
PassSimple bg_ps_ = {"Background"};
|
||||||
|
|
||||||
public:
|
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;
|
DRWState pass_state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_BACKGROUND;
|
||||||
float4 color_override(0.0f, 0.0f, 0.0f, 0.0f);
|
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);
|
GPU_framebuffer_bind(res.overlay_color_only_fb);
|
||||||
manager.submit(bg_ps_);
|
manager.submit(bg_ps_);
|
||||||
|
|
|
@ -15,14 +15,15 @@
|
||||||
|
|
||||||
namespace blender::draw::overlay {
|
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:
|
private:
|
||||||
PassSimple empty_ps_ = {"Empties"};
|
PassSimple empty_ps_ = {"Empties"};
|
||||||
PassSimple empty_in_front_ps_ = {"Empties_In_front"};
|
PassSimple empty_in_front_ps_ = {"Empties_In_front"};
|
||||||
|
|
||||||
using EmptyInstanceBuf = StorageVectorBuffer<ExtraInstanceData>;
|
|
||||||
|
|
||||||
struct CallBuffers {
|
struct CallBuffers {
|
||||||
EmptyInstanceBuf plain_axes_buf = {"plain_axes_buf"};
|
EmptyInstanceBuf plain_axes_buf = {"plain_axes_buf"};
|
||||||
EmptyInstanceBuf single_arrow_buf = {"single_arrow_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)];
|
CallBuffers &call_bufs = call_buffers_[int((ob_ref.object->dtx & OB_DRAW_IN_FRONT) != 0)];
|
||||||
|
|
||||||
|
@ -57,36 +58,39 @@ class Empties {
|
||||||
ExtraInstanceData data(
|
ExtraInstanceData data(
|
||||||
float4x4(ob_ref.object->object_to_world), color, ob_ref.object->empty_drawsize);
|
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) {
|
switch (ob_ref.object->empty_drawtype) {
|
||||||
case OB_PLAINAXES:
|
case OB_PLAINAXES:
|
||||||
call_bufs.plain_axes_buf.append(data);
|
call_bufs.plain_axes_buf.append(data, select_id);
|
||||||
break;
|
break;
|
||||||
case OB_SINGLE_ARROW:
|
case OB_SINGLE_ARROW:
|
||||||
call_bufs.single_arrow_buf.append(data);
|
call_bufs.single_arrow_buf.append(data, select_id);
|
||||||
break;
|
break;
|
||||||
case OB_CUBE:
|
case OB_CUBE:
|
||||||
call_bufs.cube_buf.append(data);
|
call_bufs.cube_buf.append(data, select_id);
|
||||||
break;
|
break;
|
||||||
case OB_CIRCLE:
|
case OB_CIRCLE:
|
||||||
call_bufs.circle_buf.append(data);
|
call_bufs.circle_buf.append(data, select_id);
|
||||||
break;
|
break;
|
||||||
case OB_EMPTY_SPHERE:
|
case OB_EMPTY_SPHERE:
|
||||||
call_bufs.sphere_buf.append(data);
|
call_bufs.sphere_buf.append(data, select_id);
|
||||||
break;
|
break;
|
||||||
case OB_EMPTY_CONE:
|
case OB_EMPTY_CONE:
|
||||||
call_bufs.cone_buf.append(data);
|
call_bufs.cone_buf.append(data, select_id);
|
||||||
break;
|
break;
|
||||||
case OB_ARROWS:
|
case OB_ARROWS:
|
||||||
call_bufs.arrows_buf.append(data);
|
call_bufs.arrows_buf.append(data, select_id);
|
||||||
break;
|
break;
|
||||||
case OB_EMPTY_IMAGE:
|
case OB_EMPTY_IMAGE:
|
||||||
/* This only show the frame. See OVERLAY_image_empty_cache_populate() for the 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;
|
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) {
|
auto init_pass = [&](PassSimple &pass, CallBuffers &call_bufs) {
|
||||||
pass.init();
|
pass.init();
|
||||||
|
@ -95,49 +99,26 @@ class Empties {
|
||||||
pass.shader_set(OVERLAY_shader_extra(false));
|
pass.shader_set(OVERLAY_shader_extra(false));
|
||||||
pass.bind_ubo("globalsBlock", &res.globals_buf);
|
pass.bind_ubo("globalsBlock", &res.globals_buf);
|
||||||
|
|
||||||
call_bufs.plain_axes_buf.push_update();
|
call_bufs.plain_axes_buf.end_sync(pass, shapes.plain_axes);
|
||||||
pass.bind_ssbo("data_buf", &call_bufs.plain_axes_buf);
|
call_bufs.single_arrow_buf.end_sync(pass, shapes.single_arrow);
|
||||||
pass.draw(shapes.plain_axes, call_bufs.plain_axes_buf.size());
|
call_bufs.cube_buf.end_sync(pass, shapes.cube);
|
||||||
|
call_bufs.circle_buf.end_sync(pass, shapes.circle);
|
||||||
call_bufs.single_arrow_buf.push_update();
|
call_bufs.sphere_buf.end_sync(pass, shapes.empty_sphere);
|
||||||
pass.bind_ssbo("data_buf", &call_bufs.single_arrow_buf);
|
call_bufs.cone_buf.end_sync(pass, shapes.empty_cone);
|
||||||
pass.draw(shapes.single_arrow, call_bufs.single_arrow_buf.size());
|
call_bufs.arrows_buf.end_sync(pass, shapes.arrows);
|
||||||
|
call_bufs.image_buf.end_sync(pass, shapes.quad_wire);
|
||||||
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());
|
|
||||||
};
|
};
|
||||||
init_pass(empty_ps_, call_buffers_[0]);
|
init_pass(empty_ps_, call_buffers_[0]);
|
||||||
init_pass(empty_in_front_ps_, call_buffers_[1]);
|
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);
|
GPU_framebuffer_bind(res.overlay_line_fb);
|
||||||
manager.submit(empty_ps_, view);
|
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);
|
GPU_framebuffer_bind(res.overlay_line_in_front_fb);
|
||||||
manager.submit(empty_in_front_ps_, view);
|
manager.submit(empty_in_front_ps_, view);
|
||||||
|
|
|
@ -30,6 +30,10 @@
|
||||||
#include "overlay_engine.h"
|
#include "overlay_engine.h"
|
||||||
#include "overlay_private.hh"
|
#include "overlay_private.hh"
|
||||||
|
|
||||||
|
using namespace blender::draw;
|
||||||
|
|
||||||
|
using Instance = blender::draw::overlay::Instance<>;
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/** \name Engine Callbacks
|
/** \name Engine Callbacks
|
||||||
* \{ */
|
* \{ */
|
||||||
|
@ -51,7 +55,7 @@ static void OVERLAY_engine_init(void *vedata)
|
||||||
|
|
||||||
/* Allocate instance. */
|
/* Allocate instance. */
|
||||||
if (data->instance == nullptr) {
|
if (data->instance == nullptr) {
|
||||||
data->instance = new blender::draw::overlay::Instance();
|
data->instance = new Instance();
|
||||||
}
|
}
|
||||||
|
|
||||||
OVERLAY_PrivateData *pd = stl->pd;
|
OVERLAY_PrivateData *pd = stl->pd;
|
||||||
|
@ -737,7 +741,7 @@ static void OVERLAY_engine_free()
|
||||||
|
|
||||||
static void OVERLAY_instance_free(void *instance_)
|
static void OVERLAY_instance_free(void *instance_)
|
||||||
{
|
{
|
||||||
blender::draw::overlay::Instance *instance = (blender::draw::overlay::Instance *)instance_;
|
auto *instance = (Instance *)instance_;
|
||||||
if (instance != nullptr) {
|
if (instance != nullptr) {
|
||||||
delete instance;
|
delete instance;
|
||||||
}
|
}
|
||||||
|
@ -748,8 +752,6 @@ static void OVERLAY_instance_free(void *instance_)
|
||||||
/** \name Engine Instance
|
/** \name Engine Instance
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
using namespace blender::draw;
|
|
||||||
|
|
||||||
static void OVERLAY_next_engine_init(void *vedata)
|
static void OVERLAY_next_engine_init(void *vedata)
|
||||||
{
|
{
|
||||||
if (!GPU_shader_storage_buffer_objects_support()) {
|
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);
|
OVERLAY_Data *ved = reinterpret_cast<OVERLAY_Data *>(vedata);
|
||||||
|
|
||||||
if (ved->instance == nullptr) {
|
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)
|
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()) {
|
if (!GPU_shader_storage_buffer_objects_support()) {
|
||||||
return;
|
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)
|
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_object = DRW_object_get_dupli(object);
|
||||||
ref.dupli_parent = DRW_object_get_dupli_parent(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)
|
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()) {
|
if (!GPU_shader_storage_buffer_objects_support()) {
|
||||||
return;
|
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)
|
static void OVERLAY_next_draw_scene(void *vedata)
|
||||||
|
@ -800,7 +803,8 @@ static void OVERLAY_next_draw_scene(void *vedata)
|
||||||
return;
|
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_instance.hh"
|
||||||
#include "overlay_private.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, "")
|
BLI_STATIC_ASSERT(SI_GRID_STEPS_LEN == OVERLAY_GRID_STEPS_LEN, "")
|
||||||
|
|
||||||
void OVERLAY_grid_init(OVERLAY_Data *vedata)
|
void OVERLAY_grid_init(OVERLAY_Data *vedata)
|
||||||
|
@ -226,10 +230,11 @@ void OVERLAY_grid_cache_init(OVERLAY_Data *ved)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ved->instance->grid_ubo == nullptr) {
|
GPUUniformBuf *&grid_ubo = reinterpret_cast<Instance *>(ved->instance)->grid_ubo;
|
||||||
ved->instance->grid_ubo = GPU_uniformbuf_create(sizeof(OVERLAY_GridData));
|
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;
|
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA;
|
||||||
DRW_PASS_CREATE(psl->grid_ps, state);
|
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 */
|
/* Create 3 quads to render ordered transparency Z axis */
|
||||||
grp = DRW_shgroup_create(sh, psl->grid_ps);
|
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_block(grp, "globalsBlock", G_draw.block_ubo);
|
||||||
DRW_shgroup_uniform_texture_ref(grp, "depth_tx", &dtxl->depth);
|
DRW_shgroup_uniform_texture_ref(grp, "depth_tx", &dtxl->depth);
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,9 @@
|
||||||
|
|
||||||
namespace blender::draw::overlay {
|
namespace blender::draw::overlay {
|
||||||
|
|
||||||
class Grid {
|
template<typename SelectEngineT> class Grid {
|
||||||
|
using ResourcesT = Resources<SelectEngineT>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
UniformBuffer<OVERLAY_GridData> data_;
|
UniformBuffer<OVERLAY_GridData> data_;
|
||||||
|
|
||||||
|
@ -164,7 +166,7 @@ class Grid {
|
||||||
data_.push_update();
|
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);
|
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_) {
|
if (!enabled_) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
namespace blender::draw::overlay {
|
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_tx.wrap(DRW_viewport_texture_list_get()->depth);
|
||||||
resources.depth_in_front_tx.wrap(DRW_viewport_texture_list_get()->depth_in_front);
|
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;
|
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();
|
const DRWView *view_legacy = DRW_view_default_get();
|
||||||
View view("OverlayView", view_legacy);
|
View view("OverlayView", view_legacy);
|
||||||
|
@ -76,7 +76,7 @@ void Instance::begin_sync()
|
||||||
grid.begin_sync(resources, state, view);
|
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);
|
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);
|
metaballs.end_sync(resources, state);
|
||||||
empties.end_sync(resources, shapes, 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.
|
/* WORKAROUND: This is to prevent crashes when using depth picking or selection.
|
||||||
* The selection engine should handle theses cases instead. */
|
* The selection engine should handle theses cases instead. */
|
||||||
|
@ -182,4 +182,11 @@ void Instance::draw(Manager &manager)
|
||||||
resources.depth_in_front_alloc_tx.release();
|
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
|
} // namespace blender::draw::overlay
|
||||||
|
|
|
@ -14,6 +14,9 @@
|
||||||
#include "overlay_metaball.hh"
|
#include "overlay_metaball.hh"
|
||||||
#include "overlay_shape.hh"
|
#include "overlay_shape.hh"
|
||||||
|
|
||||||
|
#include "../select/select_empty.hh"
|
||||||
|
#include "../select/select_object.hh"
|
||||||
|
|
||||||
namespace blender::draw::overlay {
|
namespace blender::draw::overlay {
|
||||||
|
|
||||||
class ShaderCache {
|
class ShaderCache {
|
||||||
|
@ -22,32 +25,12 @@ class ShaderCache {
|
||||||
int clipping_enabled = 0;
|
int clipping_enabled = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SceneResources {
|
template<
|
||||||
ShaderCache shaders;
|
/* Selection engine reuse most of the Overlay engine by creating selection IDs for each
|
||||||
|
* selectable component and using a special shaders for drawing.
|
||||||
// UniformBuffer<ThemeColorData> theme_colors;
|
* Making the select engine templated makes it easier to phase out any overhead of the
|
||||||
// Texture color_ramp = {"color_ramp"};
|
* selection for the regular non-selection case.*/
|
||||||
|
typename SelectEngineT = select::EngineEmpty>
|
||||||
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 {
|
class Instance {
|
||||||
public:
|
public:
|
||||||
ShaderCache shaders;
|
ShaderCache shaders;
|
||||||
|
@ -57,14 +40,14 @@ class Instance {
|
||||||
GPUUniformBuf *grid_ubo = nullptr;
|
GPUUniformBuf *grid_ubo = nullptr;
|
||||||
|
|
||||||
/** Global types. */
|
/** Global types. */
|
||||||
Resources resources;
|
Resources<SelectEngineT> resources;
|
||||||
State state;
|
State state;
|
||||||
|
|
||||||
/** Overlay types. */
|
/** Overlay types. */
|
||||||
Background background;
|
Background<SelectEngineT> background;
|
||||||
Metaballs metaballs;
|
Metaballs<SelectEngineT> metaballs;
|
||||||
Empties empties;
|
Empties<SelectEngineT> empties;
|
||||||
Grid grid;
|
Grid<SelectEngineT> grid;
|
||||||
|
|
||||||
~Instance()
|
~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
|
} // namespace blender::draw::overlay
|
||||||
|
|
|
@ -19,7 +19,8 @@
|
||||||
|
|
||||||
namespace blender::draw::overlay {
|
namespace blender::draw::overlay {
|
||||||
|
|
||||||
class Metaballs {
|
template<typename SelectEngineT> class Metaballs {
|
||||||
|
using ResourcesT = Resources<SelectEngineT>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PassSimple metaball_ps_ = {"MetaBalls"};
|
PassSimple metaball_ps_ = {"MetaBalls"};
|
||||||
|
@ -50,7 +51,7 @@ class Metaballs {
|
||||||
OVERLAY_bone_instance_data_set_color(data, color);
|
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 ?
|
ArmatureSphereBuf &data_buf = (ob_ref.object->dtx & OB_DRAW_IN_FRONT) != 0 ?
|
||||||
data_in_front_buf_ :
|
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 ?
|
ArmatureSphereBuf &data_buf = (ob_ref.object->dtx & OB_DRAW_IN_FRONT) != 0 ?
|
||||||
data_in_front_buf_ :
|
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) {
|
auto init_pass = [&](PassSimple &pass, ArmatureSphereBuf &data_buf) {
|
||||||
data_buf.push_update();
|
data_buf.push_update();
|
||||||
|
@ -113,13 +114,13 @@ class Metaballs {
|
||||||
init_pass(metaball_in_front_ps_, data_in_front_buf_);
|
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);
|
GPU_framebuffer_bind(res.overlay_line_fb);
|
||||||
manager.submit(metaball_ps_, view);
|
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);
|
GPU_framebuffer_bind(res.overlay_line_in_front_fb);
|
||||||
manager.submit(metaball_in_front_ps_, view);
|
manager.submit(metaball_in_front_ps_, view);
|
||||||
|
|
|
@ -18,10 +18,6 @@
|
||||||
|
|
||||||
#include "overlay_shader_shared.h"
|
#include "overlay_shader_shared.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
# define USE_GEOM_SHADER_WORKAROUND 1
|
# define USE_GEOM_SHADER_WORKAROUND 1
|
||||||
#else
|
#else
|
||||||
|
@ -35,7 +31,7 @@ extern "C" {
|
||||||
struct ImBuf;
|
struct ImBuf;
|
||||||
|
|
||||||
namespace blender::draw::overlay {
|
namespace blender::draw::overlay {
|
||||||
class Instance;
|
template<typename SelectEngineT> class Instance;
|
||||||
|
|
||||||
struct State {
|
struct State {
|
||||||
Depsgraph *depsgraph;
|
Depsgraph *depsgraph;
|
||||||
|
@ -68,7 +64,7 @@ using blender::draw::TextureFromPool;
|
||||||
using blender::draw::TextureRef;
|
using blender::draw::TextureRef;
|
||||||
using ArmatureSphereBuf = StorageVectorBuffer<float4x4>;
|
using ArmatureSphereBuf = StorageVectorBuffer<float4x4>;
|
||||||
|
|
||||||
struct Resources {
|
template<typename SelectEngineT> struct Resources : public SelectEngineT::SelectMap {
|
||||||
Framebuffer overlay_fb = {"overlay_fb"};
|
Framebuffer overlay_fb = {"overlay_fb"};
|
||||||
Framebuffer overlay_in_front_fb = {"overlay_in_front_fb"};
|
Framebuffer overlay_in_front_fb = {"overlay_in_front_fb"};
|
||||||
Framebuffer overlay_color_only_fb = {"overlay_color_only_fb"};
|
Framebuffer overlay_color_only_fb = {"overlay_color_only_fb"};
|
||||||
|
@ -578,7 +574,7 @@ typedef struct OVERLAY_Data {
|
||||||
OVERLAY_PassList *psl;
|
OVERLAY_PassList *psl;
|
||||||
OVERLAY_StorageList *stl;
|
OVERLAY_StorageList *stl;
|
||||||
|
|
||||||
blender::draw::overlay::Instance *instance;
|
void *instance;
|
||||||
} OVERLAY_Data;
|
} OVERLAY_Data;
|
||||||
|
|
||||||
typedef struct OVERLAY_DupliData {
|
typedef struct OVERLAY_DupliData {
|
||||||
|
@ -927,7 +923,3 @@ GPUShader *OVERLAY_shader_xray_fade(void);
|
||||||
OVERLAY_InstanceFormats *OVERLAY_shader_instance_formats_get(void);
|
OVERLAY_InstanceFormats *OVERLAY_shader_instance_formats_get(void);
|
||||||
|
|
||||||
void OVERLAY_shader_free(void);
|
void OVERLAY_shader_free(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -192,7 +192,6 @@ struct ThemeColorData {
|
||||||
};
|
};
|
||||||
BLI_STATIC_ASSERT_ALIGN(ThemeColorData, 16)
|
BLI_STATIC_ASSERT_ALIGN(ThemeColorData, 16)
|
||||||
|
|
||||||
/* TODO Move to overlay engine. */
|
|
||||||
struct ExtraInstanceData {
|
struct ExtraInstanceData {
|
||||||
float4 color_;
|
float4 color_;
|
||||||
float4x4 object_to_world_;
|
float4x4 object_to_world_;
|
||||||
|
|
|
@ -12,6 +12,41 @@
|
||||||
|
|
||||||
namespace blender::draw::overlay {
|
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.
|
* Contains all overlay generic geometry batches.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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
|
|
@ -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