Gamedev Framework (gf)  0.4.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 "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 Tell if the scissor test is enabled
101  *
102  * @return True if the scissor test is enabled
103  */
104  bool getScissorTest();
105 
106  /**
107  * @brief Enable or disable the scissor test
108  *
109  * @param scissor True to enable, false to disable the test
110  */
111  void setScissorTest(bool scissor = true);
112 
113  /**
114  * @brief Get the current scissor box
115  *
116  * @return The current scissor box
117  */
118  RectI getScissoBox();
119 
120  /**
121  * @brief Define the scissor box
122  *
123  * @param box The scissor box
124  */
125  void setScissorBox(const RectI& box);
126 
127  /**
128  * @brief Clear the entire target with a single color
129  *
130  * This function is usually called once every frame,
131  * to clear the previous contents of the target.
132  *
133  * @param color Fill color to use to clear the render target
134  */
135  void clear(const Color4f& color);
136 
137  /**
138  * @brief Clear the entire target
139  *
140  * This function is usually called once every frame,
141  * to clear the previous contents of the target.
142  *
143  * The color used to clear the target is the last color passed
144  * to the other version of clear().
145  */
146  void clear();
147 
148  /**
149  * @brief Get the range for aliased line width
150  *
151  * @return A range for the line width
152  * @sa setLineWidth(), getLineWidth()
153  */
154  RangeF getAliasedLineWidthRange() const;
155 
156  /**
157  * @brief Get the line width
158  *
159  * @return The current line width
160  * @sa setLineWidth(), getAliasedLineWidthRange()
161  */
162  float getLineWidth() const;
163 
164  /**
165  * @brief Draw primitives defined by an array of vertices
166  *
167  * @param vertices Pointer to the vertices
168  * @param count Number of vertices in the array
169  * @param type Type of primitives to draw
170  * @param states Render states to use for drawing
171  */
172  void draw(const Vertex *vertices, std::size_t count, PrimitiveType type, const RenderStates& states = RenderStates());
173 
174  /**
175  * @brief Draw primitives defined by an array of vertices and their indices
176  *
177  * @param vertices Pointer to the vertices
178  * @param indices Pointer to the indices
179  * @param count Number of indices in the array
180  * @param type Type of primitives to draw
181  * @param states Render states to use for drawing
182  */
183  void draw(const Vertex *vertices, const uint16_t *indices, std::size_t count, PrimitiveType type, const RenderStates& states = RenderStates());
184 
185  /**
186  * @brief Draw primitives defined by an array of vertices
187  *
188  * @param vertices Pointer to the vertices
189  * @param first Array of starting indices
190  * @param count Array of number of vertices
191  * @param primcount Number of elements in `first` and `count`
192  * @param type Type of primitives to draw
193  * @param states Render states to use for drawing
194  */
195  void draw(const Vertex *vertices, int *first, const std::size_t *count, std::size_t primcount, PrimitiveType type, const RenderStates& states = RenderStates());
196 
197  /**
198  * @brief Draw primitives defined by an array of vertices and their indices
199  *
200  * @param vertices Pointer to the vertices
201  * @param indices Array of pointers to the indices
202  * @param count Array of number of indices
203  * @param primcount Number of elements in `indices` and `count`
204  * @param type Type of primitives to draw
205  * @param states Render states to use for drawing
206  */
207  void draw(const Vertex *vertices, const uint16_t **indices, const std::size_t *count, std::size_t primcount, PrimitiveType type, const RenderStates& states = RenderStates());
208 
209  /**
210  * @brief Draw a vertex buffer to the render target
211  *
212  * @param buffer A vertex buffer containing a geometry
213  * @param states Render states to use for drawing
214  */
215  void draw(const VertexBuffer& buffer, const RenderStates& states = RenderStates());
216 
217  /**
218  * @brief Draw a drawable object to the render target
219  *
220  * @param drawable Object to draw
221  * @param states Render states to use for drawing
222  */
223  void draw(Drawable& drawable, const RenderStates& states = RenderStates());
224 
225  /** @} */
226 
227  /**
228  * @name View management
229  * @{
230  */
231 
232  /**
233  * @brief Change the current active view
234  *
235  * The view is like a 2D camera, it controls which part of
236  * the 2D scene is visible, and how it is viewed in the
237  * render target.
238  *
239  * The new view will affect everything that is drawn, until
240  * another view is set.
241  *
242  * The render target keeps its own copy of the view object,
243  * so it is not necessary to keep the original one alive
244  * after calling this function.
245  *
246  * To restore the original view of the target, you can pass
247  * the result of getDefaultView() to this function.
248  *
249  * @param view New view to use
250  *
251  * @sa getView(), getDefaultView()
252  */
253  void setView(const View& view) {
254  m_view = view;
255  }
256 
257  /**
258  * @brief Get the view currently in use in the render target
259  *
260  * @return The view object that is currently used
261  *
262  * @sa setView(), getDefaultView()
263  */
264  const View& getView() const {
265  return m_view;
266  }
267 
268  /**
269  * @brief Get the viewport of a view, applied to this render target
270  *
271  * The viewport is defined in the view as a ratio, this function
272  * simply applies this ratio to the current dimensions of the
273  * render target to calculate the pixels rectangle that the viewport
274  * actually covers in the target.
275  *
276  * @param view The view for which we want to compute the viewport
277  *
278  * @return Viewport rectangle, expressed in pixels
279  */
280  RectI getViewport(const View& view) const;
281 
282  /**
283  * @brief Convert a point from target coordinates to world coordinates
284  *
285  * This function finds the 2D position that matches the
286  * given pixel of the render target. In other words, it does
287  * the inverse of what the graphics card does, to find the
288  * initial position of a rendered pixel.
289  *
290  * Initially, both coordinate systems (world units and target pixels)
291  * match perfectly. But if you define a custom view or resize your
292  * render target, this assertion is not true anymore, i.e. a point
293  * located at @f$(10, 50)@f$ in your render target may map to the point
294  * @f$(150, 75)@f$ in your 2D world -- if the view is translated by
295  * @f$(140, 25)@f$.
296  *
297  * For windows, this function is typically used to find
298  * which point (or object) is located below the mouse cursor.
299  *
300  * This version uses a custom view for calculations, see the other
301  * overload of the function if you want to use the current view of the
302  * render target.
303  *
304  * @param point Pixel to convert
305  * @param view The view to use for converting the point
306  *
307  * @return The converted point, in world coordinates
308  *
309  * @sa mapCoordsToPixel()
310  */
311  Vector2f mapPixelToCoords(Vector2i point, const View& view) const;
312 
313  /**
314  * @brief Convert a point from target coordinates to world
315  * coordinates, using the current view
316  *
317  * This function is an overload of the mapPixelToCoords()
318  * function that implicitly uses the current view.
319  *
320  * It is equivalent to:
321  *
322  * ~~~{.cc}
323  * target.mapPixelToCoords(point, target.getView());
324  * ~~~
325  *
326  * @param point Pixel to convert
327  *
328  * @return The converted point, in world coordinates
329  *
330  * @sa mapCoordsToPixel()
331  */
332  Vector2f mapPixelToCoords(Vector2i point) const;
333 
334  /**
335  * @brief Convert a point from world coordinates to target coordinates
336  *
337  * This function finds the pixel of the render target that matches
338  * the given 2D point. In other words, it goes through the same process
339  * as the graphics card, to compute the final position of a rendered point.
340  *
341  * Initially, both coordinate systems (world units and target pixels)
342  * match perfectly. But if you define a custom view or resize your
343  * render target, this assertion is not true anymore, i.e. a point
344  * located at @f$(150, 75)@f$ in your 2D world may map to the pixel
345  * @f$(10, 50)@f$ of your render target -- if the view is translated by
346  * @f$(140, 25)@f$.
347  *
348  * This version uses a custom view for calculations, see the other
349  * overload of the function if you want to use the current view of the
350  * render target.
351  *
352  * @param point Point to convert
353  * @param view The view to use for converting the point
354  *
355  * @return The converted point, in target coordinates (pixels)
356  *
357  * @sa mapPixelToCoords()
358  */
359  Vector2i mapCoordsToPixel(Vector2f point, const View& view) const;
360 
361  /**
362  * @brief Convert a point from world coordinates to target
363  * coordinates, using the current view
364  *
365  * This function is an overload of the mapCoordsToPixel
366  * function that implicitly uses the current view.
367  *
368  * It is equivalent to:
369  *
370  * ~~~{.cc}
371  * target.mapCoordsToPixel(point, target.getView());
372  * ~~~
373  *
374  * @param point Point to convert
375  *
376  * @return The converted point, in target coordinates (pixels)
377  *
378  * @sa mapPixelToCoords()
379  */
380  Vector2i mapCoordsToPixel(Vector2f point) const;
381 
382  /** @} */
383 
384  protected:
385  /**
386  * @brief Performs the common initialization step after creation
387  *
388  * The derived classes must call this function after the
389  * target is created and ready for drawing.
390  */
391  void initialize();
392 
393 
394  /**
395  * @brief Capture the given framebuffer
396  *
397  * @param name The name of the framebuffer
398  */
399  Image captureFramebuffer(unsigned name) const;
400 
401  private:
402  void initializeViews();
403  void initializeShader();
404  void initializeTexture();
405 
406  struct Locations {
407  int positionLoc;
408  int colorLoc;
409  int texCoordsLoc;
410  };
411 
412  void drawStart(const Vertex *vertices, const RenderStates& states, Locations& locations);
413  void drawFinish(const Locations& locations);
414 
415  private:
416  View m_view;
417  Shader m_defaultShader;
418  Shader m_defaultAlphaShader;
419  Texture m_defaultTexture;
420  };
421 
422 #ifndef DOXYGEN_SHOULD_SKIP_THIS
423 }
424 #endif
425 }
426 
427 #endif // GF_RENDER_TARGET_H
void clear()
Clear the entire target.
2D camera that defines what region is shown on screen
Definition: View.h:92
void setScissorBox(const RectI &box)
Define the scissor box.
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:264
Define the states used for drawing to a RenderTarget.
Definition: RenderStates.h:82
Image captureFramebuffer(unsigned name) const
Capture the given framebuffer.
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.
Definition: RenderTarget.h:253
A texture for colored images.
Definition: Texture.h:339
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.
The namespace for gf classes.
Definition: Action.h:34
void setScissorTest(bool scissor=true)
Enable or disable the scissor test.
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 getScissoBox()
Get the current scissor box.
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.
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
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.
bool getScissorTest()
Tell if the scissor test is enabled.
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.