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