55from typing import TYPE_CHECKING
66
77from pyglet .math import Mat4 , Vec2 , Vec3
8- from pyglet .window .key import F
98from typing_extensions import Self
109
1110from arcade .camera .data_types import DEFAULT_FAR , DEFAULT_NEAR_ORTHO
12- from arcade .types import LBWH , Point , Rect
11+ from arcade .types import Point
1312from arcade .window_commands import get_window
1413
1514if TYPE_CHECKING :
@@ -24,24 +23,20 @@ class DefaultProjector:
2423 here to act as the default camera used internally by Arcade. There should be
2524 no instance where a developer would want to use this class.
2625
27- The default viewport tries it's best to allow
28- simple usecases with no need to use a camera.
29-
30- It does this by defaulting to the size of the active
31- framebuffer. If the user sets the framebuffer's viewport
32- without a camera then the default camera will match it
33- until the framebuffer is changed again.
26+ The job of the default projector is to ensure that when no other Projector
27+ (Camera2D, OthrographicProjector, PerspectiveProjector, etc) is in use the
28+ projection and view matrices are correct such at (0.0, 0.0) is in the bottom
29+ left corner of the viewport and that one pixel equals one 'unit'.
3430
3531 Args:
3632 context: The window context to bind the camera to. Defaults to the currently active context.
3733 """
3834
3935 def __init__ (self , * , context : ArcadeContext | None = None ):
4036 self ._ctx : ArcadeContext = context or get_window ().ctx
41- self ._viewport : Rect | None = None
42- self ._scissor : Rect | None = None
37+ self ._viewport : tuple [ int , int , int , int ] | None = None
38+ self ._scissor : tuple [ int , int , int , int ] | None = None
4339 self ._matrix : Mat4 | None = None
44- self ._updating : bool = False
4540
4641 def update_viewport (self ):
4742 """
@@ -54,27 +49,25 @@ def update_viewport(self):
5449
5550 # If another camera is active then the viewport was probably set
5651 # by camera.use()
57- if self ._ctx .current_camera != self or self . _updating :
52+ if self ._ctx .current_camera != self :
5853 return
59- self ._updating = True
6054
6155 if (
6256 self ._ctx .viewport [2 ] != self ._ctx .fbo .width
6357 or self ._ctx .viewport [3 ] != self ._ctx .fbo .height
6458 ):
65- self .viewport = LBWH ( * self ._ctx .viewport )
59+ self .viewport = self ._ctx .viewport
6660 else :
6761 self .viewport = None
6862
6963 self .use ()
70- self ._updating = False
7164
7265 @property
73- def viewport (self ) -> Rect | None :
66+ def viewport (self ) -> tuple [ int , int , int , int ] | None :
7467 return self ._viewport
7568
7669 @viewport .setter
77- def viewport (self , viewport : Rect | None ) -> None :
70+ def viewport (self , viewport : tuple [ int , int , int , int ] | None ) -> None :
7871 if viewport == self ._viewport :
7972 return
8073 self ._viewport = viewport
@@ -87,11 +80,11 @@ def viewport(self):
8780 self .viewport = None
8881
8982 @property
90- def scissor (self ) -> Rect | None :
83+ def scissor (self ) -> tuple [ int , int , int , int ] | None :
9184 return self ._scissor
9285
9386 @scissor .setter
94- def scissor (self , scissor : Rect | None ) -> None :
87+ def scissor (self , scissor : tuple [ int , int , int , int ] | None ) -> None :
9588 self ._scissor = scissor
9689
9790 @scissor .deleter
@@ -101,18 +94,18 @@ def scissor(self) -> None:
10194 @property
10295 def width (self ) -> int :
10396 if self ._viewport is not None :
104- return int (self ._viewport . width )
97+ return int (self ._viewport [ 2 ] )
10598 return self ._ctx .fbo .width
10699
107100 @property
108101 def height (self ) -> int :
109102 if self ._viewport is not None :
110- return int (self ._viewport . height )
103+ return int (self ._viewport [ 3 ] )
111104 return self ._ctx .fbo .height
112105
113106 def get_current_viewport (self ) -> tuple [int , int , int , int ]:
114107 if self ._viewport is not None :
115- return self ._viewport . lbwh_int
108+ return self ._viewport
116109 return (0 , 0 , self ._ctx .fbo .width , self ._ctx .fbo .height )
117110
118111 def use (self ) -> None :
@@ -124,8 +117,8 @@ def use(self) -> None:
124117
125118 self ._ctx .current_camera = self
126119 if self ._ctx .viewport != viewport :
127- self ._ctx .viewport = viewport
128- self ._ctx .scissor = None if self ._scissor is None else self ._scissor . lbwh_int
120+ self ._ctx .active_framebuffer . viewport = viewport
121+ self ._ctx .scissor = None if self ._scissor is None else self ._scissor
129122
130123 self ._ctx .view_matrix = Mat4 ()
131124 if self ._matrix is None :
@@ -141,14 +134,20 @@ def activate(self) -> Generator[Self, None, None]:
141134
142135 usable with the 'with' block. e.g. 'with ViewportProjector.activate() as cam: ...'
143136 """
144- previous = self ._ctx .current_camera
137+ previous_projector = self ._ctx .current_camera
138+ previous_view = self ._ctx .view_matrix
139+ previous_projection = self ._ctx .projection_matrix
140+ previous_scissor = self ._ctx .scissor
145141 previous_viewport = self ._ctx .viewport
146142 try :
147143 self .use ()
148144 yield self
149145 finally :
150146 self ._ctx .viewport = previous_viewport
151- previous .use ()
147+ self ._ctx .scissor = previous_scissor
148+ self ._ctx .projection_matrix = previous_projection
149+ self ._ctx .view_matrix = previous_view
150+ self ._ctx .current_camera = previous_projector
152151
153152 def project (self , world_coordinate : Point ) -> Vec2 :
154153 """
0 commit comments