Gamedev Framework (gf)  0.1.0
A C++11 framework for 2D games
RenderTarget.h
1 /*
2  * Gamedev Framework (gf)
3  * Copyright (C) 2016 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_RENDER_TARGET_H
25 #define GF_RENDER_TARGET_H
26 
27 #include <cstdint>
28 
29 #include "Image.h"
30 #include "Matrix.h"
31 #include "Portability.h"
32 #include "PrimitiveType.h"
33 #include "Range.h"
34 #include "RenderStates.h"
35 #include "Shader.h"
36 #include "View.h"
37 
38 namespace gf {
39 #ifndef DOXYGEN_SHOULD_SKIP_THIS
40 inline namespace v1 {
41 #endif
42 
43  class Drawable;
44  class VertexBuffer;
45  struct Vertex;
46 
47  /**
48  * @ingroup graphics
49  * @brief Base class for all render targets (window, texture, ...)
50  *
51  * gf::RenderTarget defines the common behavior of all the
52  * 2D render targets usable in the graphics module. It makes
53  * it possible to draw 2D entities like sprites, shapes, text
54  * without using any OpenGL command directly.
55  *
56  * A gf::RenderTarget is also able to use views (gf::View),
57  * which are a kind of 2D cameras. With views you can globally
58  * scroll, rotate or zoom everything that is drawn,
59  * without having to transform every single entity. See the
60  * documentation of gf::View for more details and sample pieces of
61  * code about this class.
62  *
63  * @sa gf::RenderWindow, gf::RenderTexture, gf::View
64  */
66  public:
67  /**
68  * @brief Default constructor
69  */
70  RenderTarget() = default;
71 
72  /**
73  * @brief Destructor
74  */
75  virtual ~RenderTarget();
76 
77  /**
78  * @brief Deleted copy constructor
79  */
80  RenderTarget(const RenderTarget&) = delete;
81 
82  /**
83  * @brief Deleted copy assignment
84  */
85  RenderTarget& operator=(const RenderTarget&) = delete;
86 
87  /**
88  * @brief Return the size of the rendering region of the target
89  *
90  * @return Size in pixels
91  */
92  virtual Vector2u getSize() const = 0;
93 
94  /**
95  * @name Drawing commands
96  * @{
97  */
98 
99  /**
100  * @brief Clear the entire target with a single color
101  *
102  * This function is usually called once every frame,
103  * to clear the previous contents of the target.
104  *
105  * @param color Fill color to use to clear the render target
106  */
107  void clear(const Color4f& color);
108 
109  /**
110  * @brief Clear the entire target
111  *
112  * This function is usually called once every frame,
113  * to clear the previous contents of the target.
114  *
115  * The color used to clear the target is the last color passed
116  * to the other version of clear().
117  */
118  void clear();
119 
120  /**
121  * @brief Get the range for aliased line width
122  *
123  * @return A range for the line width
124  * @sa setLineWidth(), getLineWidth()
125  */
127 
128  /**
129  * @brief Get the line width
130  *
131  * @return The current line width
132  * @sa setLineWidth(), getAliasedLineWidthRange()
133  */
134  float getLineWidth() const;
135 
136  /**
137  * @brief Draw primitives defined by an array of vertices
138  *
139  * @param vertices Pointer to the vertices
140  * @param count Number of vertices in the array
141  * @param type Type of primitives to draw
142  * @param states Render states to use for drawing
143  */
144  void draw(const Vertex *vertices, std::size_t count, PrimitiveType type, const RenderStates& states = RenderStates());
145 
146  /**
147  * @brief Draw primitives defined by an array of vertices and their indices
148  *
149  * @param vertices Pointer to the vertices
150  * @param indices Pointer to the indices
151  * @param count Number of indices in the array
152  * @param type Type of primitives to draw
153  * @param states Render states to use for drawing
154  */
155  void draw(const Vertex *vertices, const uint16_t *indices, std::size_t count, PrimitiveType type, const RenderStates& states = RenderStates());
156 
157  /**
158  * @brief Draw primitives defined by an array of vertices
159  *
160  * @param vertices Pointer to the vertices
161  * @param first Array of starting indices
162  * @param count Array of number of vertices
163  * @param primcount Number of elements in `first` and `count`
164  * @param type Type of primitives to draw
165  * @param states Render states to use for drawing
166  */
167  void draw(const Vertex *vertices, int *first, const std::size_t *count, std::size_t primcount, PrimitiveType type, const RenderStates& states = RenderStates());
168 
169  /**
170  * @brief Draw primitives defined by an array of vertices and their indices
171  *
172  * @param vertices Pointer to the vertices
173  * @param indices Array of pointers to the indices
174  * @param count Array of number of indices
175  * @param primcount Number of elements in `indices` and `count`
176  * @param type Type of primitives to draw
177  * @param states Render states to use for drawing
178  */
179  void draw(const Vertex *vertices, const uint16_t **indices, const std::size_t *count, std::size_t primcount, PrimitiveType type, const RenderStates& states = RenderStates());
180 
181  /**
182  * @brief Draw a vertex buffer to the render target
183  *
184  * @param buffer A vertex buffer containing a geometry
185  * @param states Render states to use for drawing
186  */
187  void draw(const VertexBuffer& buffer, const RenderStates& states = RenderStates());
188 
189  /**
190  * @brief Draw a drawable object to the render target
191  *
192  * @param drawable Object to draw
193  * @param states Render states to use for drawing
194  */
195  void draw(Drawable& drawable, const RenderStates& states = RenderStates());
196 
197  /** @} */
198 
199  /**
200  * @name View management
201  * @{
202  */
203 
204  /**
205  * @brief Change the current active view
206  *
207  * The view is like a 2D camera, it controls which part of
208  * the 2D scene is visible, and how it is viewed in the
209  * render target.
210  *
211  * The new view will affect everything that is drawn, until
212  * another view is set.
213  *
214  * The render target keeps its own copy of the view object,
215  * so it is not necessary to keep the original one alive
216  * after calling this function.
217  *
218  * To restore the original view of the target, you can pass
219  * the result of getDefaultView() to this function.
220  *
221  * @param view New view to use
222  *
223  * @sa getView(), getDefaultView()
224  */
225  void setView(const View& view) {
226  m_view = view;
227  }
228 
229  /**
230  * @brief Get the view currently in use in the render target
231  *
232  * @return The view object that is currently used
233  *
234  * @sa setView(), getDefaultView()
235  */
236  const View& getView() const {
237  return m_view;
238  }
239 
240  /**
241  * @brief Get the default view of the render target
242  *
243  * The default view has the initial size of the render target,
244  * and never changes after the target has been created.
245  *
246  * @return The default view of the render target
247  *
248  * @sa setView(), getView()
249  */
250  const View& getDefaultView() const {
251  return m_defaultView;
252  }
253 
254  /**
255  * @brief Get the viewport of a view, applied to this render target
256  *
257  * The viewport is defined in the view as a ratio, this function
258  * simply applies this ratio to the current dimensions of the
259  * render target to calculate the pixels rectangle that the viewport
260  * actually covers in the target.
261  *
262  * @param view The view for which we want to compute the viewport
263  *
264  * @return Viewport rectangle, expressed in pixels
265  */
266  RectI getViewport(const View& view) const;
267 
268  /**
269  * @brief Convert a point from target coordinates to world coordinates
270  *
271  * This function finds the 2D position that matches the
272  * given pixel of the render target. In other words, it does
273  * the inverse of what the graphics card does, to find the
274  * initial position of a rendered pixel.
275  *
276  * Initially, both coordinate systems (world units and target pixels)
277  * match perfectly. But if you define a custom view or resize your
278  * render target, this assertion is not true anymore, i.e. a point
279  * located at @f$(10, 50)@f$ in your render target may map to the point
280  * @f$(150, 75)@f$ in your 2D world -- if the view is translated by
281  * @f$(140, 25)@f$.
282  *
283  * For windows, this function is typically used to find
284  * which point (or object) is located below the mouse cursor.
285  *
286  * This version uses a custom view for calculations, see the other
287  * overload of the function if you want to use the current view of the
288  * render target.
289  *
290  * @param point Pixel to convert
291  * @param view The view to use for converting the point
292  *
293  * @return The converted point, in world coordinates
294  *
295  * @sa mapCoordsToPixel()
296  */
297  Vector2f mapPixelToCoords(Vector2i point, const View& view) const;
298 
299  /**
300  * @brief Convert a point from target coordinates to world
301  * coordinates, using the current view
302  *
303  * This function is an overload of the mapPixelToCoords()
304  * function that implicitly uses the current view.
305  *
306  * It is equivalent to:
307  *
308  * ~~~{.cc}
309  * target.mapPixelToCoords(point, target.getView());
310  * ~~~
311  *
312  * @param point Pixel to convert
313  *
314  * @return The converted point, in world coordinates
315  *
316  * @sa mapCoordsToPixel()
317  */
318  Vector2f mapPixelToCoords(Vector2i point) const;
319 
320  /**
321  * @brief Convert a point from world coordinates to target coordinates
322  *
323  * This function finds the pixel of the render target that matches
324  * the given 2D point. In other words, it goes through the same process
325  * as the graphics card, to compute the final position of a rendered point.
326  *
327  * Initially, both coordinate systems (world units and target pixels)
328  * match perfectly. But if you define a custom view or resize your
329  * render target, this assertion is not true anymore, i.e. a point
330  * located at @f$(150, 75)@f$ in your 2D world may map to the pixel
331  * @f$(10, 50)@f$ of your render target -- if the view is translated by
332  * @f$(140, 25)@f$.
333  *
334  * This version uses a custom view for calculations, see the other
335  * overload of the function if you want to use the current view of the
336  * render target.
337  *
338  * @param point Point to convert
339  * @param view The view to use for converting the point
340  *
341  * @return The converted point, in target coordinates (pixels)
342  *
343  * @sa mapPixelToCoords()
344  */
345  Vector2i mapCoordsToPixel(Vector2f point, const View& view) const;
346 
347  /**
348  * @brief Convert a point from world coordinates to target
349  * coordinates, using the current view
350  *
351  * This function is an overload of the mapCoordsToPixel
352  * function that implicitly uses the current view.
353  *
354  * It is equivalent to:
355  *
356  * ~~~{.cc}
357  * target.mapCoordsToPixel(point, target.getView());
358  * ~~~
359  *
360  * @param point Point to convert
361  *
362  * @return The converted point, in target coordinates (pixels)
363  *
364  * @sa mapPixelToCoords()
365  */
366  Vector2i mapCoordsToPixel(Vector2f point) const;
367 
368  /** @} */
369 
370  protected:
371  /**
372  * @brief Performs the common initialization step after creation
373  *
374  * The derived classes must call this function after the
375  * target is created and ready for drawing.
376  */
377  void initialize();
378 
379 
380  /**
381  * @brief Capture the given framebuffer
382  *
383  * @param name The name of the framebuffer
384  */
385  Image captureFramebuffer(unsigned name) const;
386 
387  private:
388  void initializeViews();
389  void initializeShader();
390  void initializeTexture();
391 
392  struct Locations {
393  int positionLoc;
394  int colorLoc;
395  int texCoordsLoc;
396  };
397 
398  void drawStart(const Vertex *vertices, const RenderStates& states, Locations& locations);
399  void drawFinish(const Locations& locations);
400 
401  private:
402  View m_view;
403  View m_defaultView;
404  Shader m_defaultShader;
405  Shader m_defaultAlphaShader;
406  Texture m_defaultTexture;
407 
408  };
409 
410 #ifndef DOXYGEN_SHOULD_SKIP_THIS
411 }
412 #endif
413 }
414 
415 #endif // GF_RENDER_TARGET_H
void clear()
Clear the entire target.
Vector< unsigned, 2 > Vector2u
A unsigned vector with 2 components.
Definition: Vector.h:795
2D camera that defines what region is shown on screen
Definition: View.h:92
Vector< float, 2 > Vector2f
A float vector with 2 components.
Definition: Vector.h:741
Base class for all render targets (window, texture, ...)
Definition: RenderTarget.h:65
const View & getView() const
Get the view currently in use in the render target.
Definition: RenderTarget.h:236
Define the states used for drawing to a RenderTarget.
Definition: RenderStates.h:81
Image captureFramebuffer(unsigned name) const
Capture the given framebuffer.
Vector< int, 2 > Vector2i
A int vector with 2 components.
Definition: Vector.h:777
A point associated with a color and a texture coordinate.
Definition: Vertex.h:75
RenderTarget()=default
Default constructor.
PrimitiveType
Kind of primitives to render.
Definition: PrimitiveType.h:43
Range< float > RangeF
A float range.
Definition: Range.h:169
Data in the graphics memory.
Definition: VertexBuffer.h:70
virtual ~RenderTarget()
Destructor.
void draw(Drawable &drawable, const RenderStates &states=RenderStates())
Draw a drawable object to the render target.
Rect< int > RectI
A int rectangle.
Definition: Rect.h:312
Abstract base class for objects that can be drawn to a render window.
Definition: Drawable.h:79
void clear(const Color4f &color)
Clear the entire target with a single color.
virtual Vector2u getSize() const =0
Return the size of the rendering region of the target.
An OpenGL vertex and/or fragment shader.
Definition: Shader.h:119
void draw(const VertexBuffer &buffer, const RenderStates &states=RenderStates())
Draw a vertex buffer to the render target.
void draw(const Vertex *vertices, const uint16_t *indices, std::size_t count, PrimitiveType type, const RenderStates &states=RenderStates())
Draw primitives defined by an array of vertices and their indices.
void setView(const View &view)
Change the current active view.
Definition: RenderTarget.h:225
A texture for colored images.
Definition: Texture.h:317
void initialize()
Performs the common initialization step after creation.
Vector2i mapCoordsToPixel(Vector2f point) const
Convert a point from world coordinates to target coordinates, using the current view.
Class for loading, manipulating and saving images.
Definition: Image.h:92
RenderTarget(const RenderTarget &)=delete
Deleted copy constructor.
Definition: Action.h:34
Vector2f mapPixelToCoords(Vector2i point, const View &view) const
Convert a point from target coordinates to world coordinates.
Vector2i mapCoordsToPixel(Vector2f point, const View &view) const
Convert a point from world coordinates to target coordinates.
RectI getViewport(const View &view) const
Get the viewport of a view, applied to this render target.
RangeF getAliasedLineWidthRange() const
Get the range for aliased line width.
Vector< float, 4 > Color4f
A float color vector with 4 components.
Definition: Vector.h:855
Vector2f mapPixelToCoords(Vector2i point) const
Convert a point from target coordinates to world coordinates, using the current view.
#define GF_API
Definition: Portability.h:35
const View & getDefaultView() const
Get the default view of the render target.
Definition: RenderTarget.h:250
void draw(const Vertex *vertices, const uint16_t **indices, const std::size_t *count, std::size_t primcount, PrimitiveType type, const RenderStates &states=RenderStates())
Draw primitives defined by an array of vertices and their indices.
void draw(const Vertex *vertices, int *first, const std::size_t *count, std::size_t primcount, PrimitiveType type, const RenderStates &states=RenderStates())
Draw primitives defined by an array of vertices.
void draw(const Vertex *vertices, std::size_t count, PrimitiveType type, const RenderStates &states=RenderStates())
Draw primitives defined by an array of vertices.
float getLineWidth() const
Get the line width.
RenderTarget & operator=(const RenderTarget &)=delete
Deleted copy assignment.