gl_utils/render/
viewport.rs1use math_utils as math;
4use glium;
5
6use crate::{Camera2d, Camera3d};
7use crate::render::params;
8
9#[derive(Debug)]
12pub struct Viewport {
13 rect : glium::Rect,
18 camera2d : Option <Camera2d>,
19 camera3d : Option <Camera3d>
20}
21
22pub struct Builder {
23 rect : glium::Rect,
24 camera_2d : bool,
26 camera_3d : bool,
28 orthographic_3d : Option <f32>,
30 pose_3d : Option <math::Pose3 <f32>>,
31 position_2d : Option <math::Point2 <f32>>,
32 zoom_2d : Option <f32>
33}
34
35impl Viewport {
36 pub fn new (rect : glium::Rect) -> Self {
68 assert!(rect.width <= u16::MAX as u32);
69 assert!(rect.height <= u16::MAX as u32);
70 Viewport {
71 rect,
72 camera2d: Some (Camera2d::new (rect.width as u16, rect.height as u16)),
73 camera3d: Some (Camera3d::new (rect.width as u16, rect.height as u16))
74 }
75 }
76
77 pub fn with_pose_3d (
79 rect : glium::Rect,
80 pose : math::Pose3 <f32>
81 ) -> Self {
82 assert!(rect.width <= u16::MAX as u32);
83 assert!(rect.height <= u16::MAX as u32);
84 Viewport {
85 rect,
86 camera2d: Some (Camera2d::new (rect.width as u16, rect.height as u16)),
87 camera3d: Some (Camera3d::with_pose (
88 rect.width as u16, rect.height as u16,
89 pose
90 ))
91 }
92 }
93
94 pub fn rect (&self) -> &glium::Rect {
95 &self.rect
96 }
97 pub fn camera2d (&self) -> Option <&Camera2d> {
98 self.camera2d.as_ref()
99 }
100 pub fn camera3d (&self) -> Option <&Camera3d> {
101 self.camera3d.as_ref()
102 }
103
104 pub fn set_rect (&mut self, rect : glium::Rect) {
144 assert!(rect.width <= u16::MAX as u32);
145 assert!(rect.height <= u16::MAX as u32);
146 self.rect = rect;
147 self.camera2d.as_mut().map (|camera2d|
148 camera2d.set_viewport_dimensions (rect.width as u16, rect.height as u16));
149 self.camera3d.as_mut().map (|camera3d|
150 camera3d.set_viewport_dimensions (rect.width as u16, rect.height as u16));
151 }
152
153 pub fn camera2d_set_position (&mut self, position : math::Point2 <f32>) {
154 self.camera2d.as_mut().unwrap().set_position (position)
155 }
156 pub fn camera2d_set_zoom (&mut self, zoom : f32) {
157 self.camera2d.as_mut().unwrap().set_zoom (zoom)
158 }
159 pub fn camera2d_move_local (&mut self, dx : f32, dy : f32) {
160 self.camera2d.as_mut().unwrap().move_local (dx, dy)
161 }
162 pub fn camera2d_move_origin_to_bottom_left (&mut self) {
163 self.camera2d.as_mut().unwrap().move_origin_to_bottom_left()
164 }
165 pub fn camera3d_set_position (&mut self, position : math::Point3 <f32>) {
166 self.camera3d.as_mut().unwrap().set_position (position)
167 }
168 pub fn camera3d_set_orientation (&mut self,
169 orientation : math::Rotation3 <f32>
170 ) {
171 self.camera3d.as_mut().unwrap().set_orientation (orientation)
172 }
173 pub fn camera3d_look_at (&mut self, target : math::Point3 <f32>) {
174 self.camera3d.as_mut().unwrap().look_at (target)
175 }
176 pub fn camera3d_move_local_xy (&mut self, dx : f32, dy : f32, dz : f32) {
177 self.camera3d.as_mut().unwrap().move_local_xy (dx, dy, dz)
178 }
179 pub fn camera3d_rotate (&mut self,
180 dyaw : math::Rad <f32>, dpitch : math::Rad <f32>, droll : math::Rad <f32>
181 ) {
182 self.camera3d.as_mut().unwrap().rotate (dyaw, dpitch, droll)
183 }
184 pub fn camera3d_scale_fovy_or_zoom (&mut self, zoom : f32) {
185 self.camera3d.as_mut().unwrap().scale_fovy_or_zoom (zoom)
186 }
187 #[allow(mismatched_lifetime_syntaxes)]
190 pub fn draw_parameters (&self) -> glium::DrawParameters {
191 glium::DrawParameters {
192 viewport: Some (self.rect),
193 .. Default::default()
194 }
195 }
196
197 #[allow(mismatched_lifetime_syntaxes)]
200 pub fn draw_parameters_blend_invert (&self) -> glium::DrawParameters {
201 glium::DrawParameters {
202 blend: params::BLEND_FUNC_INVERT_COLOR,
206 .. self.draw_parameters()
207 }
208 }
209}
210
211impl Builder {
212 #[inline]
213 pub fn new (rect : glium::Rect) -> Self {
214 Builder {
215 rect,
216 camera_2d: true,
217 camera_3d: true,
218 orthographic_3d: None,
219 pose_3d: None,
220 position_2d: None,
221 zoom_2d: None
222 }
223 }
224 pub fn with_camera_2d (self, camera_2d : bool) -> Self {
225 Builder { camera_2d, .. self }
226 }
227 pub fn with_camera_3d (self, camera_3d : bool) -> Self {
228 Builder { camera_3d, .. self }
229 }
230 pub fn with_zoom_2d (self, zoom : f32) -> Self {
231 Builder { zoom_2d: Some (zoom), .. self }
232 }
233 pub fn with_position_2d (self, position_2d : math::Point2 <f32>) -> Self {
234 Builder { position_2d: Some (position_2d), .. self }
235 }
236 pub fn orthographic_3d (self, zoom : f32) -> Self {
238 Builder { orthographic_3d: Some (zoom), .. self }
239 }
240 pub fn with_pose_3d (self, pose_3d : math::Pose3 <f32>) -> Self {
241 Builder { pose_3d: Some (pose_3d), .. self }
242 }
243 #[inline]
244 pub fn build (self) -> Viewport {
245 let mut viewport = if let Some (pose_3d) = self.pose_3d {
246 Viewport::with_pose_3d (self.rect, pose_3d)
247 } else {
248 Viewport::new (self.rect)
249 };
250 if self.camera_2d {
251 if let Some (position) = self.position_2d {
252 viewport.camera2d.as_mut().unwrap().set_position (position);
253 }
254 if let Some (zoom) = self.zoom_2d {
255 viewport.camera2d.as_mut().unwrap().set_zoom (zoom);
256 }
257 } else {
258 let _ = viewport.camera2d.take();
259 }
260 if self.camera_3d {
261 if let Some (zoom) = self.orthographic_3d {
262 viewport.camera3d.as_mut().unwrap().to_orthographic (zoom);
263 }
264 } else {
265 let _ = viewport.camera3d.take();
266 }
267 viewport
268 }
269}
270
271#[cfg(test)]
272mod tests {
273 use super::*;
274 use glium;
275
276 #[test]
277 fn viewport_matrices() {
278 let viewport = Viewport::new (
279 glium::Rect { left: 0, bottom: 0, width: 1600, height: 900 }
280 );
281 let (transform_view_matrix, projection_ortho_matrix) =
282 viewport.camera2d().unwrap().view_ortho_mats();
283 println!("transform view matrix:\n{:#?}", transform_view_matrix);
284 println!("projection ortho matrix:\n{:#?}", projection_ortho_matrix);
285 }
286}