Gamedev Framework (gf)  0.6.0
A C++11 framework for 2D games
View.h
1 /*
2  * Gamedev Framework (gf)
3  * Copyright (C) 2016-2017 Julien Bernard
4  *
5  * This software is provided 'as-is', without any express or implied
6  * warranty. In no event will the authors be held liable for any damages
7  * arising from the use of this software.
8  *
9  * Permission is granted to anyone to use this software for any purpose,
10  * including commercial applications, and to alter it and redistribute it
11  * freely, subject to the following restrictions:
12  *
13  * 1. The origin of this software must not be misrepresented; you must not
14  * claim that you wrote the original software. If you use this software
15  * in a product, an acknowledgment in the product documentation would be
16  * appreciated but is not required.
17  * 2. Altered source versions must be plainly marked as such, and must not be
18  * misrepresented as being the original software.
19  * 3. This notice may not be removed or altered from any source distribution.
20  *
21  * Part of this file comes from SFML, with the same license:
22  * Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
23  */
24 #ifndef GF_VIEW_H
25 #define GF_VIEW_H
26 
27 #include "Matrix.h"
28 #include "Portability.h"
29 #include "Rect.h"
30 #include "Vector.h"
31 
32 namespace gf {
33 #ifndef DOXYGEN_SHOULD_SKIP_THIS
34 inline namespace v1 {
35 #endif
36  struct Event;
37  class RenderTarget;
38 
39  /**
40  * @ingroup graphics
41  * @brief 2D camera that defines what region is shown on screen
42  *
43  * gf::View defines a camera in the 2D scene. This is a
44  * very powerful concept: you can scroll, rotate or zoom
45  * the entire scene without altering the way that your
46  * drawable objects are drawn.
47  *
48  * A view is composed of a source rectangle, which defines
49  * what part of the 2D scene is shown, and a target viewport,
50  * which defines where the contents of the source rectangle
51  * will be displayed on the render target (window or texture).
52  *
53  * The viewport allows to map the scene to a custom part
54  * of the render target, and can be used for split-screen
55  * or for displaying a minimap, for example. If the source
56  * rectangle has not the same size as the viewport, its
57  * contents will be stretched to fit in.
58  *
59  * To apply a view, you have to assign it to the render target.
60  * Then, every objects drawn in this render target will be
61  * affected by the view until you use another view.
62  *
63  * Usage example:
64  *
65  * ~~~{.cc}
66  * gf::RenderWindow renderer;
67  * gf::View view;
68  *
69  * // Initialize the view to a rectangle located at (100, 100) and
70  * // with a size of 400x200
71  * view.reset({ 100.0f, 100.0f, 400.0f, 200.0f });
72  *
73  * // Rotate it by 45 degrees
74  * view.rotate(gf::Pi / 4);
75  *
76  * // Set its target viewport to be half of the window
77  * view.setViewport({ 0.f, 0.f, 0.5f, 1.f });
78  *
79  * // Apply it
80  * renderer.setView(view);
81  *
82  * // Render stuff
83  * renderer.draw(someSprite);
84  *
85  * // Set the default view back
86  * renderer.setView(renderer.getDefaultView());
87  *
88  * // Render stuff not affected by the view
89  * renderer.draw(someOtherSprite);
90  * ~~~
91  *
92  * @sa gf::RenderTarget, gf::AdaptiveView
93  */
94  class GF_API View {
95  public:
96  /**
97  * @brief Default constructor
98  *
99  * This constructor creates a default view of @f$(0, 0, 1000, 1000)@f$.
100  */
101  View();
102 
103  /**
104  * @brief Construct the view from a rectangle
105  *
106  * @param rect Rectangle defining the zone to display
107  */
108  explicit View(const RectF& rect);
109 
110  /**
111  * @brief Construct the view from its center and size
112  *
113  * @param center Center of the zone to display
114  * @param size Size of the zone to display
115  */
116  View(Vector2f center, Vector2f size);
117 
118  /**
119  * @brief Destructor
120  */
121  virtual ~View();
122 
123  /**
124  * @brief Set the center of the view
125  *
126  * @param center New center
127  *
128  * @sa getCenter()
129  */
130  void setCenter(Vector2f center) {
131  m_center = center;
132  }
133 
134  /**
135  * @brief Get the center of the view
136  *
137  * @return Center of the view
138  *
139  * @sa setCenter()
140  */
141  Vector2f getCenter() const {
142  return m_center;
143  }
144 
145  /**
146  * @brief Set the size of the view
147  *
148  * @param size New size
149  *
150  * @sa getSize()
151  */
152  void setSize(Vector2f size) {
153  m_size = size;
154  onSizeChange(m_size);
155  }
156 
157  /**
158  * @brief Get the size of the view
159  *
160  * @return Size of the view
161  *
162  * @sa setSize()
163  */
164  Vector2f getSize() const {
165  return m_size;
166  }
167 
168  /**
169  * @brief Set the orientation of the view
170  *
171  * The default rotation of a view is 0 degree.
172  *
173  * @param rotation New angle, in radians
174  *
175  * @sa getRotation()
176  */
177  void setRotation(float rotation) {
178  m_rotation = rotation;
179  }
180 
181  /**
182  * @brief Get the current orientation of the view
183  *
184  * @return Rotation angle of the view, in radians
185  *
186  * @sa setRotation()
187  */
188  float getRotation() const {
189  return m_rotation;
190  }
191 
192  /**
193  * @brief Set the target viewport
194  *
195  * The viewport is the rectangle into which the contents of the
196  * view are displayed, expressed as a factor (between 0 and 1)
197  * of the size of the RenderTarget to which the view is applied.
198  *
199  * For example, a view which takes the left side of the target would
200  * be defined with:
201  *
202  * ~~~{.cc}
203  * view.setViewport({0.0f, 0.0f, 0.5f, 1.0f}).
204  * ~~~
205  *
206  * By default, a view has a viewport which covers the entire target.
207  *
208  * @param viewport New viewport rectangle
209  *
210  * @sa getViewport()
211  */
212  void setViewport(const RectF& viewport);
213 
214  /**
215  * @brief Get the target viewport rectangle of the view
216  *
217  * @return Viewport rectangle, expressed as a factor of the target size
218  *
219  * @sa setViewport()
220  */
221  const RectF& getViewport() const {
222  return m_viewport;
223  }
224 
225  /**
226  * @brief Reset the view to the given rectangle
227  *
228  * Note that this function resets the rotation angle to 0.
229  *
230  * @param rect Rectangle defining the zone to display
231  *
232  * @sa setCenter(), setSize(), setRotation()
233  */
234  void reset(const RectF& rect);
235 
236  /**
237  * @brief Move the view relatively to its current position
238  *
239  * @param offset Move offset
240  *
241  * @sa setCenter(), rotate(), zoom()
242  */
243  void move(Vector2f offset);
244 
245  /**
246  * @brief Rotate the view relatively to its current orientation
247  *
248  * @param angle Angle to rotate, in radians
249  *
250  * @sa setRotation(), move(), zoom()
251  */
252  void rotate(float angle);
253 
254  /**
255  * @brief Resize the view rectangle relatively to its current size
256  *
257  * Resizing the view simulates a zoom, as the zone displayed on
258  * screen grows or shrinks. `factor` is a multiplier:
259  *
260  * - @f$ = 1 @f$ keeps the size unchanged
261  * - @f$ > 1 @f$ makes the view bigger (objects appear smaller)
262  * - @f$ < 1 @f$ makes the view smaller (objects appear bigger)
263  *
264  * @param factor Zoom factor to apply
265  *
266  * @sa setSize(), move(), rotate()
267  */
268  void zoom(float factor);
269 
270  /**
271  * @brief Resize the view rectangle relatively to its current size and a fixed point
272  *
273  * Resizing the view simulates a zoom, as the zone displayed on
274  * screen grows or shrinks. `factor` is a multiplier:
275  *
276  * - @f$ = 1 @f$ keeps the size unchanged
277  * - @f$ > 1 @f$ makes the view bigger (objects appear smaller)
278  * - @f$ < 1 @f$ makes the view smaller (objects appear bigger)
279  *
280  * Additionally, a fixed point is used as the center of the zoom. It is the
281  * only point that stays at the same place in the view.
282  *
283  * @param factor Zoom factor to apply
284  * @param fixed The center of the zoom
285  *
286  * @sa setSize(), move(), rotate()
287  */
288  void zoom(float factor, Vector2f fixed);
289 
290  /**
291  * @brief Get the projection transform of the view
292  *
293  * This function is meant for internal use only.
294  *
295  * @return Projection transform defining the view
296  *
297  * @sa getInverseTransform()
298  */
299  Matrix3f getTransform() const;
300 
301  /**
302  * @brief Get the inverse projection transform of the view
303  *
304  * This function is meant for internal use only.
305  *
306  * @return Inverse of the projection transform defining the view
307  *
308  * @sa getTransform
309  */
310  Matrix3f getInverseTransform() const;
311 
312  protected:
313  /**
314  * @brief Set the world size, without calling onSizeChange()
315  *
316  * This function is meant for adaptative views so that they can
317  * adapt the world size without having a callback infinite loop.
318  *
319  * @param size The new world size
320  */
321  void setSizeNoCallback(Vector2f size) {
322  m_size = size;
323  }
324 
325  /**
326  * @brief Callback when the world has just been resized
327  *
328  * This callback is called when setSize() is called.
329  *
330  * @param size The new size of the visible world
331  */
332  virtual void onSizeChange(Vector2f size);
333 
334  /**
335  * @brief Set the viewport, without calling onViewportChange()
336  *
337  * This function is meant for adaptative views so that they can
338  * adapt the viewport without having a callback infinite loop.
339  *
340  * @param viewport The new viewport
341  */
342  void setViewportNoCallback(const RectF& viewport);
343 
344  /**
345  * @brief Callback when the viewport has just been changed
346  *
347  * @param viewport The new viewport
348  */
349  virtual void onViewportChange(const RectF& viewport);
350 
351  private:
352  Vector2f m_center;
353  Vector2f m_size;
354  float m_rotation;
355  RectF m_viewport;
356  };
357 
358 
359  /**
360  * @ingroup graphics
361  * @brief Adaptative view
362  *
363  * An adaptative view is a view that adapts automatically to screen
364  * resolution change.
365  *
366  * There are several kinds of adaptative views, according to the policy
367  * that is adopted when the resolution changes. In the examples below,
368  * The screen is represented by the black rectangle and the world is
369  * the red square. If red dashed lines appears, it means that the world
370  * has been modified.
371  *
372  * | Class | Example |
373  * |-----------------|-----------------------------|
374  * | gf::StretchView | @image html stretchview.png |
375  * | gf::FitView | @image html fitview.png |
376  * | gf::FillView | @image html fillview.png |
377  * | gf::ExtendView | @image html extendview.png |
378  * | gf::LockedView | @image html lockedview.png |
379  * | gf::ScreenView | @image html screenview.png |
380  *
381  * @sa gf::ViewContainer
382  */
383  class GF_API AdaptativeView : public View {
384  public:
385  /**
386  * @brief Default constructor
387  *
388  * This constructor creates a default view of @f$(0, 0, 1000, 1000)@f$.
389  */
391  : View()
392  {
393 
394  }
395 
396  /**
397  * @brief Construct the view from a rectangle
398  *
399  * @param rect Rectangle defining the zone to display
400  */
401  explicit AdaptativeView(const RectF& rect)
402  : View(rect)
403  {
404 
405  }
406 
407  /**
408  * @brief Construct the view from its center and size
409  *
410  * @param center Center of the zone to display
411  * @param size Size of the zone to display
412  */
413  AdaptativeView(Vector2f center, Vector2f size)
414  : View(center, size)
415  {
416 
417  }
418 
419  /**
420  * @brief Set the initial screen size
421  *
422  * @param screenSize The initial size of the screen
423  */
424  void setInitialScreenSize(Vector2u screenSize);
425 
426  /**
427  * @brief Callback when the screen has just been resized
428  *
429  * @param screenSize The new size of the screen
430  */
431  virtual void onScreenSizeChange(Vector2u screenSize) = 0;
432 
433  };
434 
435  /**
436  * @ingroup graphics
437  * @brief A view adaptor for zooming/moving with the mouse
438  */
440  public:
441  /**
442  * @brief Constructor
443  *
444  * @param target The rendering target
445  * @param view The original view to zoom/move
446  */
447  ZoomingViewAdaptor(const RenderTarget& target, View& view);
448 
449  /**
450  * @brief Update the original view thanks to the event
451  *
452  * @param event An event
453  */
454  void processEvent(const Event& event);
455 
456  private:
457  const RenderTarget& m_target;
458  View& m_view;
459  gf::Vector2i m_mousePosition;
460 
461  enum class State {
462  Stationary,
463  Moving,
464  };
465 
466  State m_state;
467  };
468 
469 #ifndef DOXYGEN_SHOULD_SKIP_THIS
470 }
471 #endif
472 }
473 
474 #endif // GF_VIEW_H
View(Vector2f center, Vector2f size)
Construct the view from its center and size.
2D camera that defines what region is shown on screen
Definition: View.h:94
A view adaptor for zooming/moving with the mouse.
Definition: View.h:439
AdaptativeView(const RectF &rect)
Construct the view from a rectangle.
Definition: View.h:401
float getRotation() const
Get the current orientation of the view.
Definition: View.h:188
Matrix3f getTransform() const
Get the projection transform of the view.
Base class for all render targets (window, texture, ...)
Definition: RenderTarget.h:66
View()
Default constructor.
void setViewportNoCallback(const RectF &viewport)
Set the viewport, without calling onViewportChange()
void processEvent(const Event &event)
Update the original view thanks to the event.
virtual void onScreenSizeChange(Vector2u screenSize)=0
Callback when the screen has just been resized.
virtual void onSizeChange(Vector2f size)
Callback when the world has just been resized.
ZoomingViewAdaptor(const RenderTarget &target, View &view)
Constructor.
void zoom(float factor)
Resize the view rectangle relatively to its current size.
void setViewport(const RectF &viewport)
Set the target viewport.
const RectF & getViewport() const
Get the target viewport rectangle of the view.
Definition: View.h:221
void rotate(float angle)
Rotate the view relatively to its current orientation.
The namespace for gf classes.
Definition: Action.h:34
virtual void onViewportChange(const RectF &viewport)
Callback when the viewport has just been changed.
void setSizeNoCallback(Vector2f size)
Set the world size, without calling onSizeChange()
Definition: View.h:321
Vector2f getCenter() const
Get the center of the view.
Definition: View.h:141
void move(Vector2f offset)
Move the view relatively to its current position.
void setSize(Vector2f size)
Set the size of the view.
Definition: View.h:152
Matrix3f getInverseTransform() const
Get the inverse projection transform of the view.
View(const RectF &rect)
Construct the view from a rectangle.
AdaptativeView()
Default constructor.
Definition: View.h:390
Vector2f getSize() const
Get the size of the view.
Definition: View.h:164
Defines a system event and its parameters.
Definition: Event.h:118
void zoom(float factor, Vector2f fixed)
Resize the view rectangle relatively to its current size and a fixed point.
#define GF_API
Definition: Portability.h:35
Adaptative view.
Definition: View.h:383
void setRotation(float rotation)
Set the orientation of the view.
Definition: View.h:177
virtual ~View()
Destructor.
AdaptativeView(Vector2f center, Vector2f size)
Construct the view from its center and size.
Definition: View.h:413
void setInitialScreenSize(Vector2u screenSize)
Set the initial screen size.
void reset(const RectF &rect)
Reset the view to the given rectangle.
void setCenter(Vector2f center)
Set the center of the view.
Definition: View.h:130