Skip to main content

dear_imgui_rs/render/draw_data/
core.rs

1use super::DrawListIterator;
2use crate::internal::{RawCast, RawWrapper};
3use crate::sys;
4use std::slice;
5
6/// All draw data to render a Dear ImGui frame.
7#[repr(C)]
8pub struct DrawData {
9    /// Only valid after render() is called and before the next new frame() is called.
10    pub(super) valid: bool,
11    /// Number of DrawList to render.
12    pub(super) cmd_lists_count: i32,
13    /// For convenience, sum of all draw list index buffer sizes.
14    pub(super) total_idx_count: i32,
15    /// For convenience, sum of all draw list vertex buffer sizes.
16    pub(super) total_vtx_count: i32,
17    // Array of DrawList.
18    pub(super) cmd_lists: crate::internal::ImVector<*mut sys::ImDrawList>,
19    /// Upper-left position of the viewport to render.
20    ///
21    /// (= upper-left corner of the orthogonal projection matrix to use)
22    pub display_pos: [f32; 2],
23    /// Size of the viewport to render.
24    ///
25    /// (= display_pos + display_size == lower-right corner of the orthogonal matrix to use)
26    pub display_size: [f32; 2],
27    /// Amount of pixels for each unit of display_size.
28    ///
29    /// Based on io.display_frame_buffer_scale. Typically [1.0, 1.0] on normal displays, and
30    /// [2.0, 2.0] on Retina displays, but fractional values are also possible.
31    pub framebuffer_scale: [f32; 2],
32
33    /// Viewport carrying the DrawData instance, might be of use to the renderer (generally not).
34    pub(super) owner_viewport: *mut sys::ImGuiViewport,
35    /// Texture data (internal use)
36    pub(super) textures: *mut crate::internal::ImVector<*mut sys::ImTextureData>,
37}
38
39// Keep this struct layout-compatible with the sys bindings (`ImDrawData`).
40const _: [(); std::mem::size_of::<sys::ImDrawData>()] = [(); std::mem::size_of::<DrawData>()];
41const _: [(); std::mem::align_of::<sys::ImDrawData>()] = [(); std::mem::align_of::<DrawData>()];
42
43unsafe impl RawCast<sys::ImDrawData> for DrawData {}
44
45pub(super) fn total_count_from_i32(caller: &str, raw: i32) -> usize {
46    usize::try_from(raw).unwrap_or_else(|_| panic!("{caller} returned a negative count"))
47}
48
49impl RawWrapper for DrawData {
50    type Raw = sys::ImDrawData;
51
52    unsafe fn raw(&self) -> &Self::Raw {
53        unsafe { <Self as RawCast<Self::Raw>>::raw(self) }
54    }
55
56    unsafe fn raw_mut(&mut self) -> &mut Self::Raw {
57        unsafe { <Self as RawCast<Self::Raw>>::raw_mut(self) }
58    }
59}
60
61impl DrawData {
62    /// Check if the draw data is valid
63    ///
64    /// Draw data is only valid after `Context::render()` is called and before
65    /// the next `Context::new_frame()` is called.
66    #[inline]
67    pub fn valid(&self) -> bool {
68        self.valid
69    }
70
71    /// Returns an iterator over the draw lists included in the draw data.
72    #[inline]
73    pub fn draw_lists(&self) -> DrawListIterator<'_> {
74        unsafe { DrawListIterator::new(self.cmd_lists().iter()) }
75    }
76    /// Returns the number of draw lists included in the draw data.
77    #[inline]
78    pub fn draw_lists_count(&self) -> usize {
79        unsafe { self.cmd_lists().len() }
80    }
81
82    /// Returns the total number of index-buffer elements across all draw lists.
83    #[inline]
84    pub fn total_idx_count(&self) -> usize {
85        total_count_from_i32("DrawData::total_idx_count()", self.total_idx_count)
86    }
87
88    /// Returns the total number of vertex-buffer elements across all draw lists.
89    #[inline]
90    pub fn total_vtx_count(&self) -> usize {
91        total_count_from_i32("DrawData::total_vtx_count()", self.total_vtx_count)
92    }
93
94    /// Get the display position as an array
95    #[inline]
96    pub fn display_pos(&self) -> [f32; 2] {
97        self.display_pos
98    }
99
100    /// Get the display size as an array
101    #[inline]
102    pub fn display_size(&self) -> [f32; 2] {
103        self.display_size
104    }
105
106    /// Get the framebuffer scale as an array
107    #[inline]
108    pub fn framebuffer_scale(&self) -> [f32; 2] {
109        self.framebuffer_scale
110    }
111
112    /// Raw owner viewport pointer for this draw data.
113    ///
114    /// This is primarily useful for integrations that snapshot multiple Dear ImGui platform
115    /// viewports. The pointer belongs to the current ImGui context and must not be stored beyond
116    /// the draw data lifetime.
117    #[inline]
118    pub fn owner_viewport(&self) -> *mut sys::ImGuiViewport {
119        self.owner_viewport
120    }
121
122    #[inline]
123    pub(crate) unsafe fn cmd_lists(&self) -> &[*mut sys::ImDrawList] {
124        unsafe {
125            if self.cmd_lists_count <= 0 || self.cmd_lists.data.is_null() {
126                return &[];
127            }
128            let len = match usize::try_from(self.cmd_lists_count) {
129                Ok(len) => len,
130                Err(_) => return &[],
131            };
132            slice::from_raw_parts(self.cmd_lists.data, len)
133        }
134    }
135
136    /// Converts all buffers from indexed to non-indexed, in case you cannot render indexed buffers
137    ///
138    /// **This is slow and most likely a waste of resources. Always prefer indexed rendering!**
139    #[doc(alias = "DeIndexAllBuffers")]
140    pub fn deindex_all_buffers(&mut self) {
141        unsafe {
142            sys::ImDrawData_DeIndexAllBuffers(RawWrapper::raw_mut(self));
143        }
144    }
145
146    /// Scales the clip rect of each draw command
147    ///
148    /// Can be used if your final output buffer is at a different scale than Dear ImGui expects,
149    /// or if there is a difference between your window resolution and framebuffer resolution.
150    #[doc(alias = "ScaleClipRects")]
151    pub fn scale_clip_rects(&mut self, fb_scale: [f32; 2]) {
152        unsafe {
153            let scale = sys::ImVec2 {
154                x: fb_scale[0],
155                y: fb_scale[1],
156            };
157            sys::ImDrawData_ScaleClipRects(RawWrapper::raw_mut(self), scale);
158        }
159    }
160}