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