Unravel Engine C++ Reference
Loading...
Searching...
No Matches
gizmos_renderer.cpp
Go to the documentation of this file.
1#include "gizmos_renderer.h"
2#include <editor/events.h>
3
5
6#include <engine/events.h>
9
11
12#include "gizmos/gizmos.h"
13
15
25
26namespace unravel
27{
28
29void gizmos_renderer::draw_grid(uint32_t pass_id, const camera& cam, const editing_manager::grid& grid)
30{
31 grid_program_->begin();
32
33 float grid_height = 0.0f;
34 math::vec4 u_params(grid_height, cam.get_near_clip(), cam.get_far_clip(), grid.opacity);
35 grid_program_->set_uniform("u_params", u_params);
36
37 auto topology = gfx::clip_quad(1.0f);
38 auto state = topology | BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A | BGFX_STATE_BLEND_ALPHA;
39
40 if(grid.depth_aware)
41 {
42 state |= BGFX_STATE_DEPTH_TEST_LEQUAL | BGFX_STATE_WRITE_Z;
43 }
44
45 gfx::set_state(state);
46 gfx::submit(pass_id, grid_program_->native_handle());
47 gfx::set_state(BGFX_STATE_DEFAULT);
48
49 grid_program_->end();
50}
51
52void gizmos_renderer::on_frame_render(rtti::context& ctx, scene& scn, entt::handle camera_entity)
53{
54 if(!camera_entity)
55 return;
56
57 auto& em = ctx.get_cached<editing_manager>();
58 auto& camera_comp = camera_entity.get<camera_component>();
59 const auto& rview = camera_comp.get_render_view();
60 const auto& camera = camera_comp.get_camera();
61 const auto& view = camera.get_view();
62 const auto& proj = camera.get_projection();
63 const auto& obuffer = rview.fbo_get("OBUFFER_DEPTH");
64 auto size = obuffer->get_size();
65
66 bool selection_mask_drawn = false;
67 {
68 // Pass 1: Selection mask
69 resize_selection_mask_rt(size.width, size.height);
70 selection_mask_drawn = draw_selection_mask_pass(ctx, camera, selection_mask_);
71 }
72
73 {
74 // Pass 2: Gizmos
75 gfx::render_pass pass("gizmos_pass");
76 pass.bind(obuffer.get());
77 pass.set_view_proj(view, proj);
78
79 gfx::dd_raii dd(pass.id);
80
82
83 draw_selection_gizmos(ctx, camera, dd);
84
85 if(selection_mask_drawn)
86 {
87 draw_outline_pass(selection_mask_, obuffer, dd);
88 }
89
90 draw_icon_gizmos(ctx, scn, camera, dd);
91
92 if(em.show_grid)
93 {
94 draw_grid(pass.id, camera, em.grid_data);
95 }
96 }
97
98}
99
101{
102 auto& am = ctx.get_cached<asset_manager>();
103
104 {
105 auto vs = am.get_asset<gfx::shader>("editor:/data/shaders/vs_wf_wireframe.sc");
106 auto fs = am.get_asset<gfx::shader>("editor:/data/shaders/fs_wf_wireframe.sc");
107 wireframe_program_ = std::make_unique<gpu_program>(vs, fs);
108 }
109
110 {
111 auto vs = am.get_asset<gfx::shader>("editor:/data/shaders/vs_grid.sc");
112 auto fs = am.get_asset<gfx::shader>("editor:/data/shaders/fs_grid.sc");
113 grid_program_ = std::make_unique<gpu_program>(vs, fs);
114 }
115
116 {
117 auto vs = am.get_asset<gfx::shader>("editor:/data/shaders/vs_outline_mask.sc");
118 auto fs = am.get_asset<gfx::shader>("editor:/data/shaders/fs_outline_mask.sc");
119 outline_mask_program_.program = std::make_unique<gpu_program>(vs, fs);
120 outline_mask_program_.cache_uniforms();
121 }
122
123 {
124 auto vs = am.get_asset<gfx::shader>("editor:/data/shaders/vs_outline_mask_skinned.sc");
125 auto fs = am.get_asset<gfx::shader>("editor:/data/shaders/fs_outline_mask.sc");
126 outline_mask_program_skinned_.program = std::make_unique<gpu_program>(vs, fs);
127 outline_mask_program_skinned_.cache_uniforms();
128 }
129
130 {
131 auto vs = am.get_asset<gfx::shader>("editor:/data/shaders/vs_clip_quad.sc");
132 auto fs = am.get_asset<gfx::shader>("editor:/data/shaders/fs_outline_detect.sc");
133 outline_program_.program = std::make_unique<gpu_program>(vs, fs);
134 outline_program_.cache_uniforms();
135 }
136
137 return true;
138}
139
140void gizmos_renderer::draw_selection_gizmos(rtti::context& ctx, const camera& camera, gfx::dd_raii& dd)
141{
142 auto& em = ctx.get_cached<editing_manager>();
143
144 for(auto& s : em.get_selections())
145 {
146 draw_gizmo_var(ctx, s, camera, dd);
147 }
148}
149
150auto gizmos_renderer::draw_selection_mask_pass(rtti::context& ctx,
151 const camera& camera,
152 const gfx::frame_buffer::ptr& selection_mask) -> bool
153{
154 auto& em = ctx.get_cached<editing_manager>();
155 const auto& view = camera.get_view();
156 const auto& proj = camera.get_projection();
157
158 gfx::render_pass pass("selection_mask_pass");
159 pass.bind(selection_mask.get());
160 pass.set_view_proj(view, proj);
161
162 gfx::set_view_clear(pass.id,
163 BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH,
164 0x00000000, // clear R8 to zero
165 1.0f,
166 0);
167
168 bool any_drawn = false;
169 for(auto& obj : em.get_selections())
170 {
171 if(obj.type() == entt::resolve<entt::handle>())
172 {
173 auto e = obj.cast<entt::handle>();
174 if(!e.valid())
175 {
176 continue;
177 }
178 auto transform_comp = e.try_get<transform_component>();
179
180 if(!transform_comp)
181 {
182 continue;
183 }
184 const auto& world_transform = transform_comp->get_transform_global();
185
186 if(auto model_comp = e.try_get<model_component>())
187 {
188 auto& model = model_comp->get_model();
189 if(!model.is_valid())
190 {
191 continue;
192 }
193
194 auto lod = model.get_lod(0);
195 if(!lod)
196 {
197 continue;
198 }
199
200 const auto& mesh = lod.get();
201 const auto& bounds = mesh->get_bounds();
202
203 // Test the bounding box of the mesh
204 if(!camera.test_obb(bounds, world_transform))
205 continue;
206
207 const auto& submesh_transforms = model_comp->get_submesh_transforms();
208 const auto& bone_transforms = model_comp->get_bone_transforms();
209 const auto& skinning_transforms = model_comp->get_skinning_transforms();
210
211 model::submit_callbacks callbacks;
212 callbacks.setup_begin = [&](const model::submit_callbacks::params& submit_params)
213 {
214 auto& prog =
215 submit_params.skinned ? outline_mask_program_skinned_.program : outline_mask_program_.program;
216 prog->begin();
217 };
218 callbacks.setup_params_per_instance = [&](const model::submit_callbacks::params& submit_params)
219 {
220 auto& prog =
221 submit_params.skinned ? outline_mask_program_skinned_.program : outline_mask_program_.program;
222 };
223 callbacks.setup_params_per_submesh =
224 [&](const model::submit_callbacks::params& submit_params, const material& mat)
225 {
226 auto& prog =
227 submit_params.skinned ? outline_mask_program_skinned_.program : outline_mask_program_.program;
228 gfx::submit(pass.id, prog->native_handle(), 0, submit_params.preserve_state);
229 };
230 callbacks.setup_end = [&](const model::submit_callbacks::params& submit_params)
231 {
232 auto& prog =
233 submit_params.skinned ? outline_mask_program_skinned_.program : outline_mask_program_.program;
234 prog->end();
235 };
236
237 model.submit(world_transform, submesh_transforms, bone_transforms, skinning_transforms, 0, callbacks);
238
239 any_drawn = true;
240 }
241 }
242 }
243
244 return any_drawn;
245}
246
247void gizmos_renderer::draw_outline_pass(const gfx::frame_buffer::ptr& selection_mask,
248 const gfx::frame_buffer::ptr& obuffer,
249 gfx::dd_raii& dd)
250{
251 auto size = obuffer->get_size();
252
253 outline_program_.program->begin();
254
255 // Bind the selection mask (R8) to sampler slot 0
256 gfx::set_texture(outline_program_.s_tex, 0, selection_mask);
257
258 float thickness = 3.0f;
259 // Compute inverse‐pixel dims:
260 float data[4] = {1.0f / float(size.width), 1.0f / float(size.height), thickness, 0.0f};
261 gfx::set_uniform(outline_program_.u_data, data);
262
263 // Outline color uniform:
264 float outline_color[4] = {1.0f, 0.5f, 0.2f, 1.0f};
265 gfx::set_uniform(outline_program_.u_outline_color, outline_color);
266
267 // Draw a full‐screen quad
268 auto topology = gfx::clip_quad(0.0f);
269
270 // Alpha-blend the outline over existing scene
271 gfx::set_state(topology | BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A | BGFX_STATE_BLEND_ALPHA);
272
273 gfx::submit(dd.view, outline_program_.program->native_handle());
274
275 outline_program_.program->end();
276}
277
278void gizmos_renderer::draw_icon_gizmos(rtti::context& ctx, scene& scn, const camera& camera, gfx::dd_raii& dd)
279{
280 auto& em = ctx.get_cached<editing_manager>();
281
282 if(!em.show_icon_gizmos)
283 return;
284
285 hpp::for_each_type<camera_component, light_component, reflection_probe_component, audio_source_component>(
286 [&](auto tag)
287 {
288 using type_t = typename std::decay_t<decltype(tag)>::type;
289
290 scn.registry->view<type_t>().each(
291 [&](auto e, auto&& comp)
292 {
293 auto entity = scn.create_handle(e);
294 entt::meta_any s = entity;
295 draw_gizmo_billboard_var(ctx, s, camera, dd);
296 });
297 });
298}
299
301{
302 outline_mask_program_ = {};
303 outline_mask_program_skinned_ = {};
304 outline_program_ = {};
305 wireframe_program_.reset();
306 grid_program_.reset();
307 return true;
308}
309} // namespace unravel
manifold_type type
Manages assets, including loading, unloading, and storage.
Class that contains core camera data, used for rendering and other purposes.
Class representing a camera. Contains functionality for manipulating and updating a camera....
Definition camera.h:35
auto test_obb(const math::bbox &bounds, const math::transform &t) const -> bool
Tests if the specified OBB is within the frustum.
Definition camera.cpp:444
auto get_projection() const -> const math::transform &
Retrieves the current projection matrix.
Definition camera.cpp:203
auto get_view() const -> const math::transform &
Retrieves the current view matrix.
Definition camera.cpp:276
auto init(rtti::context &ctx) -> bool
void on_frame_render(rtti::context &ctx, scene &scn, entt::handle camera_entity)
auto deinit(rtti::context &ctx) -> bool
std::string tag
Definition hub.cpp:26
Definition cache.hpp:11
void submit(view_id _id, program_handle _handle, int32_t _depth, bool _preserveState)
Definition graphics.cpp:899
void set_view_clear(view_id _id, uint16_t _flags, uint32_t _rgba, float _depth, uint8_t _stencil)
Definition graphics.cpp:712
void set_state(uint64_t _state, uint32_t _rgba)
Definition graphics.cpp:763
bgfx::Topology topology
Definition graphics.h:36
void set_uniform(uniform_handle _handle, const void *_value, uint16_t _num)
Definition graphics.cpp:803
auto clip_quad(float depth, float width, float height) -> uint64_t
void set_texture(uint8_t _stage, uniform_handle _sampler, texture_handle _handle, uint32_t _flags)
Definition graphics.cpp:889
void draw_gizmo_var(rtti::context &ctx, entt::meta_any &var, const camera &cam, gfx::dd_raii &dd)
Definition gizmos.cpp:39
void draw_gizmo_billboard_var(rtti::context &ctx, entt::meta_any &var, const camera &cam, gfx::dd_raii &dd)
Definition gizmos.cpp:50
entt::entity entity
view_id view
Definition debugdraw.h:16
void set_view_proj(const float *v, const float *p)
gfx::view_id id
Definition render_pass.h:98
void bind(const frame_buffer *fb=nullptr) const
auto get_cached() -> T &
Definition context.hpp:49
T width
Definition basetypes.hpp:55
T height
Definition basetypes.hpp:56
static void draw_system_gizmos(rtti::context &ctx, const camera &cam, gfx::dd_raii &dd)
Represents a scene in the ACE framework, managing entities and their relationships.
Definition scene.h:21