Gamedev Framework (gf)  0.4.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 
37  /**
38  * @ingroup graphics
39  * @brief 2D camera that defines what region is shown on screen
40  *
41  * gf::View defines a camera in the 2D scene. This is a
42  * very powerful concept: you can scroll, rotate or zoom
43  * the entire scene without altering the way that your
44  * drawable objects are drawn.
45  *
46  * A view is composed of a source rectangle, which defines
47  * what part of the 2D scene is shown, and a target viewport,
48  * which defines where the contents of the source rectangle
49  * will be displayed on the render target (window or texture).
50  *
51  * The viewport allows to map the scene to a custom part
52  * of the render target, and can be used for split-screen
53  * or for displaying a minimap, for example. If the source
54  * rectangle has not the same size as the viewport, its
55  * contents will be stretched to fit in.
56  *
57  * To apply a view, you have to assign it to the render target.
58  * Then, every objects drawn in this render target will be
59  * affected by the view until you use another view.
60  *
61  * Usage example:
62  *
63  * ~~~{.cc}
64  * gf::RenderWindow renderer;
65  * gf::View view;
66  *
67  * // Initialize the view to a rectangle located at (100, 100) and
68  * // with a size of 400x200
69  * view.reset({ 100.0f, 100.0f, 400.0f, 200.0f });
70  *
71  * // Rotate it by 45 degrees
72  * view.rotate(gf::Pi / 4);
73  *
74  * // Set its target viewport to be half of the window
75  * view.setViewport({ 0.f, 0.f, 0.5f, 1.f });
76  *
77  * // Apply it
78  * renderer.setView(view);
79  *
80  * // Render stuff
81  * renderer.draw(someSprite);
82  *
83  * // Set the default view back
84  * renderer.setView(renderer.getDefaultView());
85  *
86  * // Render stuff not affected by the view
87  * renderer.draw(someOtherSprite);
88  * ~~~
89  *
90  * @sa gf::RenderTarget, gf::AdaptiveView
91  */
92  class GF_API View {
93  public:
94  /**
95  * @brief Default constructor
96  *
97  * This constructor creates a default view of @f$(0, 0, 1000, 1000)@f$.
98  */
99  View();
100 
101  /**
102  * @brief Construct the view from a rectangle
103  *
104  * @param rect Rectangle defining the zone to display
105  */
106  explicit View(const RectF& rect);
107 
108  /**
109  * @brief Construct the view from its center and size
110  *
111  * @param center Center of the zone to display
112  * @param size Size of the zone to display
113  */
114  View(Vector2f center, Vector2f size);
115 
116  /**
117  * @brief Destructor
118  */
119  virtual ~View();
120 
121  /**
122  * @brief Set the center of the view
123  *
124  * @param center New center
125  *
126  * @sa getCenter()
127  */
128  void setCenter(Vector2f center) {
129  m_center = center;
130  }
131 
132  /**
133  * @brief Get the center of the view
134  *
135  * @return Center of the view
136  *
137  * @sa setCenter()
138  */
139  Vector2f getCenter() const {
140  return m_center;
141  }
142 
143  /**
144  * @brief Set the size of the view
145  *
146  * @param size New size
147  *
148  * @sa getSize()
149  */
150  void setSize(Vector2f size) {
151  m_size = size;
152  onWorldResize(m_size);
153  }
154 
155  /**
156  * @brief Get the size of the view
157  *
158  * @return Size of the view
159  *
160  * @sa setSize()
161  */
162  Vector2f getSize() const {
163  return m_size;
164  }
165 
166  /**
167  * @brief Set the orientation of the view
168  *
169  * The default rotation of a view is 0 degree.
170  *
171  * @param rotation New angle, in radians
172  *
173  * @sa getRotation()
174  */
175  void setRotation(float rotation) {
176  m_rotation = rotation;
177  }
178 
179  /**
180  * @brief Get the current orientation of the view
181  *
182  * @return Rotation angle of the view, in radians
183  *
184  * @sa setRotation()
185  */
186  float getRotation() const {
187  return m_rotation;
188  }
189 
190  /**
191  * @brief Set the target viewport
192  *
193  * The viewport is the rectangle into which the contents of the
194  * view are displayed, expressed as a factor (between 0 and 1)
195  * of the size of the RenderTarget to which the view is applied.
196  *
197  * For example, a view which takes the left side of the target would
198  * be defined with:
199  *
200  * ~~~{.cc}
201  * view.setViewport({0.0f, 0.0f, 0.5f, 1.0f}).
202  * ~~~
203  *
204  * By default, a view has a viewport which covers the entire target.
205  *
206  * @param viewport New viewport rectangle
207  *
208  * @sa getViewport()
209  */
210  void setViewport(const RectF& viewport) {
211  m_viewport = viewport;
212  }
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 onWorldResize()
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 setWorldSize(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 worldSize The new size of the visible world
331  */
332  virtual void onWorldResize(Vector2f worldSize);
333 
334  private:
335  Vector2f m_center;
336  Vector2f m_size;
337  float m_rotation;
338  RectF m_viewport;
339  };
340 
341 
342  /**
343  * @ingroup graphics
344  * @brief Adaptative view
345  *
346  * An adaptative view is a view that adapts automatically to screen
347  * resolution change.
348  *
349  * There are several kinds of adaptative views, according to the policy
350  * that is adopted when the resolution changes. In the examples below,
351  * The screen is represented by the black rectangle and the world is
352  * the red square. If red dashed lines appears, it means that the world
353  * has been modified.
354  *
355  * | Class | Example |
356  * |-----------------|-----------------------------|
357  * | gf::StretchView | @image html stretchview.png |
358  * | gf::FitView | @image html fitview.png |
359  * | gf::FillView | @image html fillview.png |
360  * | gf::ExtendView | @image html extendview.png |
361  * | gf::ScreenView | @image html screenview.png |
362  *
363  * @sa gf::ViewContainer
364  */
365  class GF_API AdaptativeView : public View {
366  public:
367  /**
368  * @brief Default constructor
369  *
370  * This constructor creates a default view of @f$(0, 0, 1000, 1000)@f$.
371  */
373  : View()
374  {
375 
376  }
377 
378  /**
379  * @brief Construct the view from a rectangle
380  *
381  * @param rect Rectangle defining the zone to display
382  */
383  explicit AdaptativeView(const RectF& rect)
384  : View(rect)
385  {
386 
387  }
388 
389  /**
390  * @brief Construct the view from its center and size
391  *
392  * @param center Center of the zone to display
393  * @param size Size of the zone to display
394  */
395  AdaptativeView(Vector2f center, Vector2f size)
396  : View(center, size)
397  {
398 
399  }
400 
401  /**
402  * @brief Callback when the screen has just been resized
403  *
404  * @param screenSize The new size of the screen
405  */
406  virtual void onScreenResize(Vector2u screenSize) = 0;
407 
408  /**
409  * @brief Set the initial screen size
410  *
411  * @param screenSize The initial size of the screen
412  */
413  void setInitialScreenSize(Vector2u screenSize);
414 
415  };
416 
417 #ifndef DOXYGEN_SHOULD_SKIP_THIS
418 }
419 #endif
420 }
421 
422 #endif // GF_VIEW_H
float getRotation() const
Get the current orientation of the view.
Definition: View.h:186
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:92
AdaptativeView(const RectF &rect)
Construct the view from a rectangle.
Definition: View.h:383
virtual void onScreenResize(Vector2u screenSize)=0
Callback when the screen has just been resized.
View()
Default constructor.
Matrix3f getTransform() const
Get the projection transform of the view.
const RectF & getViewport() const
Get the target viewport rectangle of the view.
Definition: View.h:221
void zoom(float factor)
Resize the view rectangle relatively to its current size.
Vector2f getCenter() const
Get the center of the view.
Definition: View.h:139
void setViewport(const RectF &viewport)
Set the target viewport.
Definition: View.h:210
void rotate(float angle)
Rotate the view relatively to its current orientation.
Matrix3f getInverseTransform() const
Get the inverse projection transform of the view.
The namespace for gf classes.
Definition: Action.h:34
Vector2f getSize() const
Get the size of the view.
Definition: View.h:162
virtual void onWorldResize(Vector2f worldSize)
Callback when the world has just been resized.
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:150
View(const RectF &rect)
Construct the view from a rectangle.
AdaptativeView()
Default constructor.
Definition: View.h:372
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:365
void setRotation(float rotation)
Set the orientation of the view.
Definition: View.h:175
virtual ~View()
Destructor.
AdaptativeView(Vector2f center, Vector2f size)
Construct the view from its center and size.
Definition: View.h:395
void setWorldSize(Vector2f size)
Set the world size, without calling onWorldResize()
Definition: View.h:321
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:128