ark_module/types/
render.rs

1//! 🌈 Render module
2//!
3//! TODO: Add overviewdescription how they work and how to use it
4//!
5//! Also see the Developer Guide section about [render modules](https://ark.embark.dev/guide/api/render.html)
6
7pub use ark_api_ffi::entrypoints::render::RenderDrawFlags;
8pub use ark_api_ffi::entrypoints::render::RenderDrawInfo;
9pub use ark_api_ffi::entrypoints::render::RenderFrameInfo;
10
11/// Render module creation & update trait
12pub trait RenderModule {
13    /// Creation of a new module
14    ///
15    /// This is called once on startup of the module
16    fn new() -> Self;
17
18    /// Implement the rendering for an entity here.
19    ///
20    /// `cache_id` is unique per entity, and can be used internally to cache entity-specific data.
21    /// It is unrelated to the `instance_id` you can specify in the render API, although you might
22    /// find it useful to use the `cache_id` to come up with suitably unique and stable `instance_id`s.
23    ///
24    /// `static_data` is the data array you specified when creating the Shape.
25    /// `dynamic_data` is empty by default but can be set at any time on the Render component of the Entity.
26    fn draw(
27        &mut self,
28        common_info: &RenderFrameInfo,
29        object_to_world: macaw::Mat4,
30        static_data: &[u8],
31        dynamic_data: &[u8],
32        cache_id: u64,
33    );
34
35    /// Gets called when you can safely delete all cached information related to a specific `cache_id`.
36    fn removed(&mut self, cache_id: u64);
37}
38
39/// Implement a render module
40#[macro_export]
41macro_rules! impl_render_module {
42    ($module: ty) => {
43        use $crate::render::RenderModule as _;
44
45        static mut MODULE: Option<$module> = None;
46
47        #[no_mangle]
48        pub fn ark_initialize() {
49            $crate::init();
50            // SAFETY: Sound to access static as we do not use threads in Wasm and this is guaranteed to be called first in the module
51            unsafe {
52                MODULE = Some(<$module as $crate::render::RenderModule>::new());
53            }
54        }
55
56        #[no_mangle]
57        pub unsafe fn ark_render_frame(
58            frame_info_ptr: *const $crate::render::RenderFrameInfo,
59            draw_info_ptr: *const $crate::render::RenderDrawInfo,
60            draw_info_len: u32,
61        ) {
62            // SAFETY: Sound to access static as we do not use threads in Wasm and this is guaranteed to be initialized on startup with `ark_initialize` first
63            unsafe {
64                let module = MODULE.as_mut().unwrap();
65                let slice = std::slice::from_raw_parts::<$crate::render::RenderDrawInfo>(
66                    draw_info_ptr,
67                    draw_info_len as usize,
68                );
69                for entry in slice {
70                    let static_data_slice = std::slice::from_raw_parts::<u8>(
71                        entry.static_data_ptr as *const u8,
72                        entry.static_data_len as usize,
73                    );
74                    let dynamic_data_slice = std::slice::from_raw_parts::<u8>(
75                        entry.dynamic_data_ptr as *const u8,
76                        entry.dynamic_data_len as usize,
77                    );
78                    if entry
79                        .flags
80                        .contains($crate::render::RenderDrawFlags::REMOVED)
81                    {
82                        // Instance was removed
83                        <$module as $crate::render::RenderModule>::removed(module, entry.cache_id);
84                    } else {
85                        <$module as $crate::render::RenderModule>::draw(
86                            module,
87                            frame_info_ptr.as_ref().unwrap(),
88                            macaw::Mat4::from_cols_array(&entry.object_to_world),
89                            static_data_slice,
90                            dynamic_data_slice,
91                            entry.cache_id,
92                        );
93                    }
94                }
95            }
96        }
97    };
98}