Overlay-Next: Initial implementation #107045
|
@ -595,6 +595,7 @@ set(GLSL_SRC
|
|||
|
||||
engines/select/shaders/select_id_vert.glsl
|
||||
engines/select/shaders/select_id_frag.glsl
|
||||
engines/select/shaders/select_lib.glsl
|
||||
|
||||
engines/basic/shaders/basic_conservative_depth_geom.glsl
|
||||
engines/basic/shaders/basic_depth_vert.glsl
|
||||
|
|
|
@ -97,6 +97,7 @@ template<typename SelectEngineT> class Empties {
|
|||
state.clipping_state);
|
||||
pass.shader_set(res.shaders.extra_shape);
|
||||
pass.bind_ubo("globalsBlock", &res.globals_buf);
|
||||
res.select_bind(pass);
|
||||
|
||||
call_bufs.plain_axes_buf.end_sync(pass, shapes.plain_axes);
|
||||
call_bufs.single_arrow_buf.end_sync(pass, shapes.single_arrow);
|
||||
|
|
|
@ -70,6 +70,8 @@ template<typename T> void Instance<T>::begin_sync()
|
|||
const DRWView *view_legacy = DRW_view_default_get();
|
||||
View view("OverlayView", view_legacy);
|
||||
|
||||
resources.begin_sync();
|
||||
|
||||
background.begin_sync(resources, state);
|
||||
prepass.begin_sync(resources, state);
|
||||
empties.begin_sync();
|
||||
|
@ -136,6 +138,8 @@ template<typename T> void Instance<T>::object_sync(ObjectRef &ob_ref, Manager &m
|
|||
|
||||
template<typename T> void Instance<T>::end_sync()
|
||||
{
|
||||
resources.end_sync();
|
||||
|
||||
metaballs.end_sync(resources, shapes, state);
|
||||
empties.end_sync(resources, shapes, state);
|
||||
}
|
||||
|
@ -197,6 +201,8 @@ template<typename T> void Instance<T>::draw(Manager &manager)
|
|||
|
||||
resources.line_tx.release();
|
||||
resources.depth_in_front_alloc_tx.release();
|
||||
|
||||
resources.read_result();
|
||||
}
|
||||
|
||||
/* Instantiation. */
|
||||
|
|
|
@ -90,6 +90,7 @@ template<typename SelectEngineT> class Metaballs {
|
|||
state.clipping_state);
|
||||
pass.shader_set(res.shaders.armature_sphere_outline);
|
||||
pass.bind_ubo("globalsBlock", &res.globals_buf);
|
||||
res.select_bind(pass);
|
||||
|
||||
call_buf.end_sync(pass, shapes.metaball_wire_circle);
|
||||
};
|
||||
|
|
|
@ -30,6 +30,7 @@ template<typename SelectEngineT> class Prepass {
|
|||
pass.init();
|
||||
pass.state_set(DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | state.clipping_state);
|
||||
pass.shader_set(res.shaders.depth_mesh);
|
||||
res.select_bind(pass);
|
||||
};
|
||||
init_pass(prepass_ps_);
|
||||
init_pass(prepass_in_front_ps_);
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "GPU_shader.h"
|
||||
|
||||
#include "gpu_shader_create_info.hh"
|
||||
|
@ -51,7 +49,7 @@ template<typename SelectEngineT, bool ClippingEnabled = false> class ShaderModul
|
|||
};
|
||||
|
||||
/**
|
||||
* Special class for every shader that needs to have clipped and selection variations.
|
||||
* Special class for any shader that needs to have clipped and selection variations.
|
||||
*/
|
||||
class ShaderGeometry : public Shader {
|
||||
public:
|
||||
|
@ -83,7 +81,7 @@ template<typename SelectEngineT, bool ClippingEnabled = false> class ShaderModul
|
|||
GPU_shader_create_info_get(create_info_name));
|
||||
|
||||
patch(info);
|
||||
info.define(SelectEngineT::shader_define);
|
||||
SelectEngineT::SelectShader::patch(info);
|
||||
|
||||
this->shader_ = GPU_shader_create_from_info(
|
||||
reinterpret_cast<const GPUShaderCreateInfo *>(&info));
|
||||
|
@ -125,6 +123,8 @@ template<typename SelectEngineT, bool ClippingEnabled = false> class ShaderModul
|
|||
Shader background_fill = {"overlay_background"};
|
||||
Shader background_clip_bound = {"overlay_clipbound"};
|
||||
|
||||
/** Module */
|
||||
|
||||
/** Only to be used by Instance constructor. */
|
||||
static ShaderModule &module_get()
|
||||
{
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#pragma BLENDER_REQUIRE(select_lib.glsl)
|
||||
|
||||
void main()
|
||||
{
|
||||
/* No color output, only depth (line below is implicit). */
|
||||
// gl_FragDepth = gl_FragCoord.z;
|
||||
|
||||
/* This is optimized to noop in the non select case. */
|
||||
select_id_output(select_id);
|
||||
}
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
|
||||
#pragma BLENDER_REQUIRE(common_view_clipping_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(select_lib.glsl)
|
||||
|
||||
void main()
|
||||
{
|
||||
GPU_INTEL_VERTEX_SHADER_WORKAROUND
|
||||
|
||||
select_id_set(in_select_buf[resource_id]);
|
||||
|
||||
vec3 world_pos = point_object_to_world(pos);
|
||||
gl_Position = point_world_to_ndc(world_pos);
|
||||
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
|
||||
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(select_lib.glsl)
|
||||
|
||||
void main()
|
||||
{
|
||||
fragColor = finalColor;
|
||||
lineOutput = pack_line_data(gl_FragCoord.xy, edgeStart, edgePos);
|
||||
|
||||
select_id_output(select_id);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
#pragma BLENDER_REQUIRE(common_view_clipping_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(select_lib.glsl)
|
||||
|
||||
#define lamp_area_size inst_data.xy
|
||||
#define lamp_clip_sta inst_data.z
|
||||
|
@ -41,6 +42,8 @@
|
|||
|
||||
void main()
|
||||
{
|
||||
select_id_set(in_select_buf[gl_InstanceID]);
|
||||
|
||||
/* Extract data packed inside the unused mat4 members. */
|
||||
vec4 inst_data = vec4(inst_obmat[0][3], inst_obmat[1][3], inst_obmat[2][3], inst_obmat[3][3]);
|
||||
float inst_color_data = color.a;
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup draw_engine
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define SELECT_ID_IN 5
|
||||
#define SELECT_ID_OUT 6
|
|
@ -11,13 +11,17 @@
|
|||
|
||||
#include "draw_manager.hh"
|
||||
|
||||
#include "gpu_shader_create_info.hh"
|
||||
|
||||
namespace blender::draw::select {
|
||||
|
||||
struct EngineEmpty {
|
||||
/* Add type safety to selection ID. Only the select engine should provide them. */
|
||||
struct ID {};
|
||||
|
||||
static constexpr const char *shader_define = "NO_SELECT";
|
||||
struct SelectShader {
|
||||
static void patch(gpu::shader::ShaderCreateInfo &){};
|
||||
};
|
||||
|
||||
struct SelectBuf {
|
||||
void select_clear(){};
|
||||
|
@ -30,6 +34,16 @@ struct EngineEmpty {
|
|||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
void begin_sync(){};
|
||||
|
||||
void select_bind(PassSimple &){};
|
||||
|
||||
void select_bind(PassMain &){};
|
||||
|
||||
void end_sync(){};
|
||||
|
||||
void read_result(){};
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -148,7 +148,7 @@ static void select_cache_init(void *vedata)
|
|||
}
|
||||
else {
|
||||
pd->shgrp_face_unif = DRW_shgroup_create(sh->select_id_uniform, psl->select_id_face_pass);
|
||||
DRW_shgroup_uniform_int_copy(pd->shgrp_face_unif, "id", 0);
|
||||
DRW_shgroup_uniform_int_copy(pd->shgrp_face_unif, "select_id", 0);
|
||||
}
|
||||
|
||||
if (e_data.context.select_mode & SCE_SELECT_EDGE) {
|
||||
|
|
|
@ -11,18 +11,39 @@
|
|||
#pragma once
|
||||
|
||||
#include "DRW_gpu_wrapper.hh"
|
||||
|
||||
#include "draw_manager.hh"
|
||||
#include "draw_pass.hh"
|
||||
|
||||
#include "gpu_shader_create_info.hh"
|
||||
|
||||
#include "select_defines.h"
|
||||
|
||||
namespace blender::draw::select {
|
||||
|
||||
struct EngineObject {
|
||||
/* Add type safety to selection ID. Only the select engine should provide them. */
|
||||
struct ID {
|
||||
uint32_t value;
|
||||
|
||||
friend constexpr bool operator==(ID a, ID b)
|
||||
{
|
||||
return a.value == b.value;
|
||||
}
|
||||
|
||||
uint64_t hash() const
|
||||
{
|
||||
return BLI_ghashutil_uinthash(value);
|
||||
}
|
||||
};
|
||||
|
||||
static constexpr const char *shader_define = "SELECT_OBJECT";
|
||||
struct SelectShader {
|
||||
static void patch(gpu::shader::ShaderCreateInfo &info)
|
||||
{
|
||||
info.define("SELECT_UNORDERED");
|
||||
info.additional_info("select_id_patch");
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a dedicated selection id buffer to a pass.
|
||||
|
@ -44,23 +65,85 @@ struct EngineObject {
|
|||
void select_bind(PassSimple &pass)
|
||||
{
|
||||
select_buf.push_update();
|
||||
pass.bind_ssbo("select_buf", &select_buf);
|
||||
pass.bind_ssbo(SELECT_ID_IN, &select_buf);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate selection IDs from objects and keep record of the mapping between them.
|
||||
* The id's are contiguous so that we can create a destination buffer.
|
||||
*/
|
||||
struct SelectMap {
|
||||
uint next_id = 0;
|
||||
Map<uint, ObjectRef> map;
|
||||
/** Mapping between internal IDs and `object->runtime.select_id`. */
|
||||
Vector<uint> select_id_map;
|
||||
#ifdef DEBUG
|
||||
/** Debug map containing a copy of the object name. */
|
||||
Vector<std::string> map_names;
|
||||
#endif
|
||||
/** Stores the result of the whole selection drawing. Content depends on selection mode. */
|
||||
StorageArrayBuffer<uint> select_output_buf = {"select_output_buf"};
|
||||
/** Dummy buffer. Might be better to remove, but simplify the shader create info patching. */
|
||||
StorageArrayBuffer<uint, 4, true> dummy_select_buf = {"dummy_select_buf"};
|
||||
|
||||
/* TODO(fclem): The sub_object_id id should eventually become some enum or take a sub-object
|
||||
* reference directly. */
|
||||
[[nodiscard]] const ID select_id(const ObjectRef &, uint sub_object_id = 0)
|
||||
* reference directly. This would isolate the selection logic to this class. */
|
||||
[[nodiscard]] const ID select_id(const ObjectRef &ob_ref, uint sub_object_id = 0)
|
||||
{
|
||||
/* TODO Insert Ref into the map. */
|
||||
return {sub_object_id | next_id++};
|
||||
uint object_id = ob_ref.object->runtime.select_id;
|
||||
uint id = select_id_map.append_and_get_index(object_id | sub_object_id);
|
||||
#ifdef DEBUG
|
||||
map_names.append(ob_ref.object->id.name);
|
||||
#endif
|
||||
return {id};
|
||||
}
|
||||
|
||||
void begin_sync()
|
||||
{
|
||||
select_id_map.clear();
|
||||
/* Index 0 is the invalid selection ID. */
|
||||
select_id_map.append(uint(-1));
|
||||
#ifdef DEBUG
|
||||
map_names.clear();
|
||||
map_names.append("Invalid Index");
|
||||
#endif
|
||||
}
|
||||
|
||||
void select_bind(PassSimple &pass)
|
||||
{
|
||||
pass.bind_ssbo(SELECT_ID_OUT, &select_output_buf);
|
||||
}
|
||||
|
||||
void select_bind(PassMain &pass)
|
||||
{
|
||||
/* IMPORTANT: This binds a dummy buffer `in_select_buf` but it is not supposed to be used. */
|
||||
pass.bind_ssbo(SELECT_ID_IN, &dummy_select_buf);
|
||||
pass.bind_ssbo(SELECT_ID_OUT, &select_output_buf);
|
||||
}
|
||||
|
||||
void end_sync()
|
||||
{
|
||||
select_output_buf.resize(ceil_to_multiple_u(select_id_map.size(), 4));
|
||||
select_output_buf.push_update();
|
||||
select_output_buf.clear_to_zero();
|
||||
}
|
||||
|
||||
void read_result()
|
||||
{
|
||||
/* TODO right barrier. */
|
||||
GPU_finish();
|
||||
select_output_buf.read();
|
||||
|
||||
#ifdef DEBUG
|
||||
for (auto i : IndexRange(select_output_buf.size())) {
|
||||
uint32_t word = select_output_buf[i];
|
||||
for (auto bit : IndexRange(32)) {
|
||||
if ((word & 1) != 0) {
|
||||
std::cout << map_names[i * 32 + bit] << std::endl;
|
||||
}
|
||||
word >>= 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "gpu_shader_create_info.hh"
|
||||
#include "select_defines.h"
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Select ID for Edit Mesh Selection
|
||||
* \{ */
|
||||
|
||||
GPU_SHADER_INTERFACE_INFO(select_id_iface, "").flat(Type::INT, "id");
|
||||
GPU_SHADER_INTERFACE_INFO(select_id_iface, "").flat(Type::INT, "select_id");
|
||||
|
||||
GPU_SHADER_CREATE_INFO(select_id_flat)
|
||||
.push_constant(Type::FLOAT, "sizeVertex")
|
||||
|
@ -23,7 +24,7 @@ GPU_SHADER_CREATE_INFO(select_id_flat)
|
|||
GPU_SHADER_CREATE_INFO(select_id_uniform)
|
||||
.define("UNIFORM_ID")
|
||||
.push_constant(Type::FLOAT, "sizeVertex")
|
||||
.push_constant(Type::INT, "id")
|
||||
.push_constant(Type::INT, "select_id")
|
||||
.vertex_in(0, Type::VEC3, "pos")
|
||||
.fragment_out(0, Type::UINT, "fragColor")
|
||||
.vertex_source("select_id_vert.glsl")
|
||||
|
@ -40,4 +41,13 @@ GPU_SHADER_CREATE_INFO(select_id_uniform_clipped)
|
|||
.additional_info("select_id_uniform")
|
||||
.additional_info("drw_clipped")
|
||||
.do_static_compilation(true);
|
||||
|
||||
/* Used to patch overlay shaders. */
|
||||
GPU_SHADER_CREATE_INFO(select_id_patch)
|
||||
.vertex_out(select_id_iface)
|
||||
/* Select IDs for instanced draw-calls not using #PassMain. */
|
||||
.storage_buf(SELECT_ID_IN, Qualifier::READ, "int", "in_select_buf[]")
|
||||
/* Stores the result of the whole selection drawing. Content depends on selection mode. */
|
||||
.storage_buf(SELECT_ID_OUT, Qualifier::READ_WRITE, "uint", "out_select_buf[]");
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
void main()
|
||||
{
|
||||
fragColor = floatBitsToUint(intBitsToFloat(id));
|
||||
fragColor = floatBitsToUint(intBitsToFloat(select_id));
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
void main()
|
||||
{
|
||||
#ifndef UNIFORM_ID
|
||||
id = offset + index;
|
||||
select_id = offset + index;
|
||||
#endif
|
||||
|
||||
vec3 world_pos = point_object_to_world(pos);
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
|
||||
#if !(defined(SELECT_UNORDERED) || defined(SELECT_DEPTH_PICKING))
|
||||
/* Avoid requesting the select_id when not in selection mode. */
|
||||
# define select_id_set(select_id)
|
||||
# define select_id_output(select_id)
|
||||
|
||||
#elif defined(GPU_VERTEX_SHADER)
|
||||
|
||||
void select_id_set(int id)
|
||||
{
|
||||
/* Declared in the create info. */
|
||||
select_id = id;
|
||||
}
|
||||
|
||||
#elif defined(GPU_FRAGMENT_SHADER)
|
||||
|
||||
void select_id_output(int id)
|
||||
{
|
||||
# if defined(SELECT_UNORDERED)
|
||||
/* Used by rectangle selection.
|
||||
* Set the bit of the select id in the bitmap. */
|
||||
atomicOr(out_select_buf[id / 32u], 1u << (uint(id) % 32u));
|
||||
|
||||
# elif defined(SELECT_DEPTH_PICKING)
|
||||
/* Used by mouse-clicking selection.
|
||||
* Stores the nearest depth for this select id. */
|
||||
atomicMin(out_select_buf[id], floatBitsToUint(gl_FragCoord.z));
|
||||
|
||||
# else
|
||||
# error
|
||||
# endif
|
||||
}
|
||||
|
||||
#endif
|
|
@ -29,6 +29,7 @@ set(INC
|
|||
# For *_info.hh includes.
|
||||
../compositor/realtime_compositor
|
||||
../draw/engines/eevee_next
|
||||
../draw/engines/select
|
||||
../draw/engines/workbench
|
||||
../draw/intern
|
||||
|
||||
|
|
Loading…
Reference in New Issue