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