Skip to main content

euv_engine/renderer/
struct.rs

1use super::*;
2
3/// A 2D camera that defines the viewport into the game world.
4#[derive(Clone, Copy, Data, Debug, New, PartialEq, PartialOrd)]
5pub struct Camera2D {
6    /// The world-space position of the camera center.
7    #[get(type(copy))]
8    pub(crate) position: Vector2D,
9    /// The zoom factor (1.0 = no zoom, 2.0 = 2x magnification).
10    #[get(type(copy))]
11    pub(crate) zoom: f64,
12    /// The rotation angle in radians.
13    #[get(type(copy))]
14    pub(crate) rotation: f64,
15    /// The viewport width in screen pixels.
16    #[get(type(copy))]
17    pub(crate) viewport_width: f64,
18    /// The viewport height in screen pixels.
19    #[get(type(copy))]
20    pub(crate) viewport_height: f64,
21}
22
23/// A 3D camera that defines the viewport into a 3D world using perspective
24/// or orthographic projection.
25#[derive(Clone, Copy, Data, Debug, New, PartialEq, PartialOrd)]
26pub struct Camera3D {
27    /// The world-space position of the camera (eye).
28    #[get(type(copy))]
29    pub(crate) position: Vector3D,
30    /// The point the camera is looking at (target).
31    #[get(type(copy))]
32    pub(crate) target: Vector3D,
33    /// The up direction for the camera.
34    #[get(type(copy))]
35    #[new(skip)]
36    pub(crate) up: Vector3D,
37    /// The vertical field of view in radians.
38    #[get(type(copy))]
39    #[new(skip)]
40    pub(crate) fov: f64,
41    /// The near clipping plane distance.
42    #[get(type(copy))]
43    #[new(skip)]
44    pub(crate) near: f64,
45    /// The far clipping plane distance.
46    #[get(type(copy))]
47    #[new(skip)]
48    pub(crate) far: f64,
49    /// The viewport width in pixels.
50    #[get(type(copy))]
51    pub(crate) viewport_width: f64,
52    /// The viewport height in pixels.
53    #[get(type(copy))]
54    pub(crate) viewport_height: f64,
55}
56
57/// A wrapper around `CanvasRenderingContext2d` providing convenience
58/// drawing methods and camera management for the game engine.
59#[derive(Clone, Data, New)]
60pub struct CanvasRenderer {
61    /// The underlying canvas 2D rendering context.
62    pub(crate) context: CanvasRenderingContext2d,
63    /// The active camera controlling the viewport.
64    #[get(type(copy))]
65    pub(crate) camera: Camera2D,
66    /// The active rendering quality preset.
67    ///
68    /// Controls `imageSmoothingEnabled`, `imageSmoothingQuality`, and
69    /// `textRendering` on the underlying context. Defaults to `Medium`.
70    #[get(type(copy))]
71    pub(crate) quality: RenderQuality,
72}
73
74/// A linear gradient defined by two endpoints and a list of color stops.
75///
76/// Used to create smooth color transitions along a straight line
77/// for fill or stroke operations on the canvas.
78#[derive(Clone, Data, Debug, New, PartialEq)]
79pub struct LinearGradient {
80    /// The starting point of the gradient in world space.
81    #[get(type(copy))]
82    pub(crate) start: Vector2D,
83    /// The ending point of the gradient in world space.
84    #[get(type(copy))]
85    pub(crate) end: Vector2D,
86    /// The ordered list of color stops, each containing a position (0.0 to 1.0) and a CSS color string.
87    pub(crate) stops: Vec<(f64, String)>,
88}
89
90/// A radial gradient defined by inner and outer circles and a list of color stops.
91///
92/// Used to create smooth color transitions radiating outward from a center point
93/// for fill or stroke operations on the canvas.
94#[derive(Clone, Data, Debug, New, PartialEq)]
95pub struct RadialGradient {
96    /// The center of the inner circle of the gradient.
97    #[get(type(copy))]
98    pub(crate) inner_center: Vector2D,
99    /// The radius of the inner circle.
100    #[get(type(copy))]
101    pub(crate) inner_radius: f64,
102    /// The center of the outer circle of the gradient.
103    #[get(type(copy))]
104    pub(crate) outer_center: Vector2D,
105    /// The radius of the outer circle.
106    #[get(type(copy))]
107    pub(crate) outer_radius: f64,
108    /// The ordered list of color stops, each containing a position (0.0 to 1.0) and a CSS color string.
109    pub(crate) stops: Vec<(f64, String)>,
110}
111
112/// Shadow rendering configuration for drop shadow effects on canvas primitives.
113///
114/// When applied, all subsequent fill, stroke, and draw operations will cast
115/// a shadow with the specified color, blur radius, and offset.
116#[derive(Clone, Data, Debug, New, PartialEq, PartialOrd)]
117pub struct ShadowConfig {
118    /// The CSS color string of the shadow (e.g., `"rgba(0,0,0,0.5)"`).
119    #[get(type(clone))]
120    pub(crate) color: String,
121    /// The blur radius of the shadow in pixels.
122    #[get(type(copy))]
123    pub(crate) blur: f64,
124    /// The horizontal offset of the shadow in pixels.
125    #[get(type(copy))]
126    pub(crate) offset_x: f64,
127    /// The vertical offset of the shadow in pixels.
128    #[get(type(copy))]
129    pub(crate) offset_y: f64,
130}
131
132/// Represents the rendering priority layer for draw call ordering.
133///
134/// Higher z-index values are drawn on top of lower values,
135/// enabling correct visual layering of game objects.
136#[derive(Clone, Copy, Data, Debug, Default, Eq, Hash, New, Ord, PartialEq, PartialOrd)]
137pub struct RenderLayer {
138    /// The z-index determining draw order. Higher values draw later (on top).
139    #[get(type(copy))]
140    pub(crate) z_index: i32,
141    /// Whether objects in this layer should be rendered.
142    #[get(type(copy))]
143    pub(crate) visible: bool,
144}
145
146/// An ordered buffer of deferred draw commands recorded during a frame.
147///
148/// Scenes and components push `DrawCommand`s into the list during `on_render`
149/// instead of drawing immediately. The engine then replays the whole list once
150/// per frame via `CanvasRenderer::replay`, which batches consecutive same-style
151/// shapes into a single path and skips redundant canvas state changes. The
152/// backing `Vec` is reused across frames via `clear()` to avoid reallocation.
153#[derive(Clone, Data, Debug, Default, New)]
154pub struct DrawList {
155    /// The recorded draw commands for the current frame.
156    #[get(pub(crate))]
157    #[get_mut(pub(crate))]
158    #[set(pub(crate))]
159    pub(crate) commands: Vec<DrawCommand>,
160}
161
162/// A supersampling anti-aliasing (SSAA) canvas wrapper that renders at a higher
163/// resolution on an offscreen canvas and downscales to the display canvas for
164/// smoother polygon edges in software-rendered 3D scenes.
165///
166/// The offscreen context is scaled by `scale_factor` so that all drawing
167/// code can use logical pixel coordinates without modification. After
168/// rendering, call `present()` to draw the high-resolution buffer onto the
169/// visible canvas with high-quality image smoothing.
170#[derive(Clone, Data, New)]
171pub struct SsaaCanvas {
172    /// The display canvas element visible to the user.
173    pub(crate) display_canvas: HtmlCanvasElement,
174    /// The 2D rendering context of the display canvas used for final presentation.
175    pub(crate) display_context: CanvasRenderingContext2d,
176    /// The offscreen canvas used for high-resolution rendering.
177    pub(crate) offscreen_canvas: HtmlCanvasElement,
178    /// The 2D rendering context of the offscreen canvas, pre-scaled by `scale_factor`.
179    pub(crate) offscreen_context: CanvasRenderingContext2d,
180    /// The supersampling scale factor (e.g., 2.0 means 4x SSAA).
181    #[get(type(copy))]
182    pub(crate) scale_factor: f64,
183    /// The rendering quality preset for the downscaling present step.
184    ///
185    /// Controls the smoothing strategy when the offscreen buffer is
186    /// downscaled onto the display canvas. Defaults to `Medium`.
187    #[new(skip)]
188    #[get(type(copy))]
189    pub(crate) quality: RenderQuality,
190    /// The logical display width in CSS pixels.
191    #[get(type(copy))]
192    pub(crate) width: f64,
193    /// The logical display height in CSS pixels.
194    #[get(type(copy))]
195    pub(crate) height: f64,
196}
197
198/// A WebGPU rendering backend wrapping the GPU device, queue, and canvas context
199/// for GPU-accelerated rendering on the web.
200///
201/// Created asynchronously via `WebGpuRenderer::init` because adapter and
202/// device acquisition returns JavaScript Promises that must be awaited.
203/// Once initialized, the renderer provides methods to create GPU resources
204/// (buffers, shader modules, command encoders) and execute render passes.
205///
206/// WebGPU types are stored as `JsValue` to avoid feature-gated import issues
207/// with `web_sys`. Method calls are performed via `Reflect` and `JsCast`.
208#[derive(Clone, Data)]
209pub struct WebGpuRenderer {
210    /// The WebGPU device (`GpuDevice`) used to create GPU resources.
211    pub(crate) device: JsValue,
212    /// The device's command queue (`GpuQueue`) for submitting command buffers.
213    pub(crate) queue: JsValue,
214    /// The WebGPU canvas rendering context (`GpuCanvasContext`).
215    pub(crate) context: JsValue,
216    /// The HTML canvas element backing the WebGPU context.
217    pub(crate) canvas: HtmlCanvasElement,
218    /// The texture format string used by the canvas's swap chain (e.g., `"bgra8unorm"`).
219    #[get(type(clone))]
220    pub(crate) format: String,
221    /// The physical pixel width of the canvas backing store.
222    #[get(type(copy))]
223    pub(crate) width: u32,
224    /// The physical pixel height of the canvas backing store.
225    #[get(type(copy))]
226    pub(crate) height: u32,
227    /// Whether MSAA anti-aliasing is enabled for render pipelines.
228    ///
229    /// When `true`, the renderer allocates a multisampled intermediate texture
230    /// (`sampleCount: 4`) and resolves into the swap chain each frame; when
231    /// `false`, render passes attach directly to the swap chain view at
232    /// `sampleCount: 1`.
233    #[get(type(copy))]
234    pub(crate) antialias: bool,
235    /// The multisampled color texture used when `antialias` is `true`.
236    ///
237    /// `None` when MSAA is disabled. Rebuilt on every resize because the
238    /// `width`/`height` are immutable for a given `GpuTexture`.
239    #[get(type(clone))]
240    pub(crate) multisample_texture: Option<JsValue>,
241    /// The default `GpuTextureView` into `multisample_texture`.
242    ///
243    /// Cached at texture-create time so `begin_render_pass` does not have to
244    /// recreate the view each frame. `None` when MSAA is disabled.
245    #[get(type(clone))]
246    pub(crate) multisample_view: Option<JsValue>,
247}