1////////////////////////////////////////////////////////////
2//
3// SFML - Simple and Fast Multimedia Library
4// Copyright (C) 2007-2020 Laurent Gomila (laurent@sfml-dev.org)
5//
6// This software is provided 'as-is', without any express or implied warranty.
7// In no event will the authors be held liable for any damages 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 freely,
11// subject to the following restrictions:
12//
13// 1. The origin of this software must not be misrepresented;
14// you must not claim that you wrote the original software.
15// If you use this software in a product, an acknowledgment
16// in the product documentation would be appreciated but is not required.
17//
18// 2. Altered source versions must be plainly marked as such,
19// and must not be misrepresented as being the original software.
20//
21// 3. This notice may not be removed or altered from any source distribution.
22//
23////////////////////////////////////////////////////////////
24
25#ifndef SFML_RENDERTARGET_HPP
26#define SFML_RENDERTARGET_HPP
27
28////////////////////////////////////////////////////////////
29// Headers
30////////////////////////////////////////////////////////////
31#include <SFML/Graphics/Export.hpp>
32#include <SFML/Graphics/Color.hpp>
33#include <SFML/Graphics/Rect.hpp>
34#include <SFML/Graphics/View.hpp>
35#include <SFML/Graphics/Transform.hpp>
36#include <SFML/Graphics/BlendMode.hpp>
37#include <SFML/Graphics/RenderStates.hpp>
38#include <SFML/Graphics/PrimitiveType.hpp>
39#include <SFML/Graphics/Vertex.hpp>
40#include <SFML/System/NonCopyable.hpp>
41
42
43namespace sf
44{
45class Drawable;
46class VertexBuffer;
47
48////////////////////////////////////////////////////////////
49/// \brief Base class for all render targets (window, texture, ...)
50///
51////////////////////////////////////////////////////////////
52class SFML_GRAPHICS_API RenderTarget : NonCopyable
53{
54public:
55
56 ////////////////////////////////////////////////////////////
57 /// \brief Destructor
58 ///
59 ////////////////////////////////////////////////////////////
60 virtual ~RenderTarget();
61
62 ////////////////////////////////////////////////////////////
63 /// \brief Clear the entire target with a single color
64 ///
65 /// This function is usually called once every frame,
66 /// to clear the previous contents of the target.
67 ///
68 /// \param color Fill color to use to clear the render target
69 ///
70 ////////////////////////////////////////////////////////////
71 void clear(const Color& color = Color(0, 0, 0, 255));
72
73 ////////////////////////////////////////////////////////////
74 /// \brief Change the current active view
75 ///
76 /// The view is like a 2D camera, it controls which part of
77 /// the 2D scene is visible, and how it is viewed in the
78 /// render target.
79 /// The new view will affect everything that is drawn, until
80 /// another view is set.
81 /// The render target keeps its own copy of the view object,
82 /// so it is not necessary to keep the original one alive
83 /// after calling this function.
84 /// To restore the original view of the target, you can pass
85 /// the result of getDefaultView() to this function.
86 ///
87 /// \param view New view to use
88 ///
89 /// \see getView, getDefaultView
90 ///
91 ////////////////////////////////////////////////////////////
92 void setView(const View& view);
93
94 ////////////////////////////////////////////////////////////
95 /// \brief Get the view currently in use in the render target
96 ///
97 /// \return The view object that is currently used
98 ///
99 /// \see setView, getDefaultView
100 ///
101 ////////////////////////////////////////////////////////////
102 const View& getView() const;
103
104 ////////////////////////////////////////////////////////////
105 /// \brief Get the default view of the render target
106 ///
107 /// The default view has the initial size of the render target,
108 /// and never changes after the target has been created.
109 ///
110 /// \return The default view of the render target
111 ///
112 /// \see setView, getView
113 ///
114 ////////////////////////////////////////////////////////////
115 const View& getDefaultView() const;
116
117 ////////////////////////////////////////////////////////////
118 /// \brief Get the viewport of a view, applied to this render target
119 ///
120 /// The viewport is defined in the view as a ratio, this function
121 /// simply applies this ratio to the current dimensions of the
122 /// render target to calculate the pixels rectangle that the viewport
123 /// actually covers in the target.
124 ///
125 /// \param view The view for which we want to compute the viewport
126 ///
127 /// \return Viewport rectangle, expressed in pixels
128 ///
129 ////////////////////////////////////////////////////////////
130 IntRect getViewport(const View& view) const;
131
132 ////////////////////////////////////////////////////////////
133 /// \brief Convert a point from target coordinates to world
134 /// coordinates, using the current view
135 ///
136 /// This function is an overload of the mapPixelToCoords
137 /// function that implicitly uses the current view.
138 /// It is equivalent to:
139 /// \code
140 /// target.mapPixelToCoords(point, target.getView());
141 /// \endcode
142 ///
143 /// \param point Pixel to convert
144 ///
145 /// \return The converted point, in "world" coordinates
146 ///
147 /// \see mapCoordsToPixel
148 ///
149 ////////////////////////////////////////////////////////////
150 Vector2f mapPixelToCoords(const Vector2i& point) const;
151
152 ////////////////////////////////////////////////////////////
153 /// \brief Convert a point from target coordinates to world coordinates
154 ///
155 /// This function finds the 2D position that matches the
156 /// given pixel of the render target. In other words, it does
157 /// the inverse of what the graphics card does, to find the
158 /// initial position of a rendered pixel.
159 ///
160 /// Initially, both coordinate systems (world units and target pixels)
161 /// match perfectly. But if you define a custom view or resize your
162 /// render target, this assertion is not true anymore, i.e. a point
163 /// located at (10, 50) in your render target may map to the point
164 /// (150, 75) in your 2D world -- if the view is translated by (140, 25).
165 ///
166 /// For render-windows, this function is typically used to find
167 /// which point (or object) is located below the mouse cursor.
168 ///
169 /// This version uses a custom view for calculations, see the other
170 /// overload of the function if you want to use the current view of the
171 /// render target.
172 ///
173 /// \param point Pixel to convert
174 /// \param view The view to use for converting the point
175 ///
176 /// \return The converted point, in "world" units
177 ///
178 /// \see mapCoordsToPixel
179 ///
180 ////////////////////////////////////////////////////////////
181 Vector2f mapPixelToCoords(const Vector2i& point, const View& view) const;
182
183 ////////////////////////////////////////////////////////////
184 /// \brief Convert a point from world coordinates to target
185 /// coordinates, using the current view
186 ///
187 /// This function is an overload of the mapCoordsToPixel
188 /// function that implicitly uses the current view.
189 /// It is equivalent to:
190 /// \code
191 /// target.mapCoordsToPixel(point, target.getView());
192 /// \endcode
193 ///
194 /// \param point Point to convert
195 ///
196 /// \return The converted point, in target coordinates (pixels)
197 ///
198 /// \see mapPixelToCoords
199 ///
200 ////////////////////////////////////////////////////////////
201 Vector2i mapCoordsToPixel(const Vector2f& point) const;
202
203 ////////////////////////////////////////////////////////////
204 /// \brief Convert a point from world coordinates to target coordinates
205 ///
206 /// This function finds the pixel of the render target that matches
207 /// the given 2D point. In other words, it goes through the same process
208 /// as the graphics card, to compute the final position of a rendered point.
209 ///
210 /// Initially, both coordinate systems (world units and target pixels)
211 /// match perfectly. But if you define a custom view or resize your
212 /// render target, this assertion is not true anymore, i.e. a point
213 /// located at (150, 75) in your 2D world may map to the pixel
214 /// (10, 50) of your render target -- if the view is translated by (140, 25).
215 ///
216 /// This version uses a custom view for calculations, see the other
217 /// overload of the function if you want to use the current view of the
218 /// render target.
219 ///
220 /// \param point Point to convert
221 /// \param view The view to use for converting the point
222 ///
223 /// \return The converted point, in target coordinates (pixels)
224 ///
225 /// \see mapPixelToCoords
226 ///
227 ////////////////////////////////////////////////////////////
228 Vector2i mapCoordsToPixel(const Vector2f& point, const View& view) const;
229
230 ////////////////////////////////////////////////////////////
231 /// \brief Draw a drawable object to the render target
232 ///
233 /// \param drawable Object to draw
234 /// \param states Render states to use for drawing
235 ///
236 ////////////////////////////////////////////////////////////
237 void draw(const Drawable& drawable, const RenderStates& states = RenderStates::Default);
238
239 ////////////////////////////////////////////////////////////
240 /// \brief Draw primitives defined by an array of vertices
241 ///
242 /// \param vertices Pointer to the vertices
243 /// \param vertexCount Number of vertices in the array
244 /// \param type Type of primitives to draw
245 /// \param states Render states to use for drawing
246 ///
247 ////////////////////////////////////////////////////////////
248 void draw(const Vertex* vertices, std::size_t vertexCount,
249 PrimitiveType type, const RenderStates& states = RenderStates::Default);
250
251 ////////////////////////////////////////////////////////////
252 /// \brief Draw primitives defined by a vertex buffer
253 ///
254 /// \param vertexBuffer Vertex buffer
255 /// \param states Render states to use for drawing
256 ///
257 ////////////////////////////////////////////////////////////
258 void draw(const VertexBuffer& vertexBuffer, const RenderStates& states = RenderStates::Default);
259
260 ////////////////////////////////////////////////////////////
261 /// \brief Draw primitives defined by a vertex buffer
262 ///
263 /// \param vertexBuffer Vertex buffer
264 /// \param firstVertex Index of the first vertex to render
265 /// \param vertexCount Number of vertices to render
266 /// \param states Render states to use for drawing
267 ///
268 ////////////////////////////////////////////////////////////
269 void draw(const VertexBuffer& vertexBuffer, std::size_t firstVertex, std::size_t vertexCount, const RenderStates& states = RenderStates::Default);
270
271 ////////////////////////////////////////////////////////////
272 /// \brief Return the size of the rendering region of the target
273 ///
274 /// \return Size in pixels
275 ///
276 ////////////////////////////////////////////////////////////
277 virtual Vector2u getSize() const = 0;
278
279 ////////////////////////////////////////////////////////////
280 /// \brief Activate or deactivate the render target for rendering
281 ///
282 /// This function makes the render target's context current for
283 /// future OpenGL rendering operations (so you shouldn't care
284 /// about it if you're not doing direct OpenGL stuff).
285 /// A render target's context is active only on the current thread,
286 /// if you want to make it active on another thread you have
287 /// to deactivate it on the previous thread first if it was active.
288 /// Only one context can be current in a thread, so if you
289 /// want to draw OpenGL geometry to another render target
290 /// don't forget to activate it again. Activating a render
291 /// target will automatically deactivate the previously active
292 /// context (if any).
293 ///
294 /// \param active True to activate, false to deactivate
295 ///
296 /// \return True if operation was successful, false otherwise
297 ///
298 ////////////////////////////////////////////////////////////
299 virtual bool setActive(bool active = true);
300
301 ////////////////////////////////////////////////////////////
302 /// \brief Save the current OpenGL render states and matrices
303 ///
304 /// This function can be used when you mix SFML drawing
305 /// and direct OpenGL rendering. Combined with popGLStates,
306 /// it ensures that:
307 /// \li SFML's internal states are not messed up by your OpenGL code
308 /// \li your OpenGL states are not modified by a call to a SFML function
309 ///
310 /// More specifically, it must be used around code that
311 /// calls Draw functions. Example:
312 /// \code
313 /// // OpenGL code here...
314 /// window.pushGLStates();
315 /// window.draw(...);
316 /// window.draw(...);
317 /// window.popGLStates();
318 /// // OpenGL code here...
319 /// \endcode
320 ///
321 /// Note that this function is quite expensive: it saves all the
322 /// possible OpenGL states and matrices, even the ones you
323 /// don't care about. Therefore it should be used wisely.
324 /// It is provided for convenience, but the best results will
325 /// be achieved if you handle OpenGL states yourself (because
326 /// you know which states have really changed, and need to be
327 /// saved and restored). Take a look at the resetGLStates
328 /// function if you do so.
329 ///
330 /// \see popGLStates
331 ///
332 ////////////////////////////////////////////////////////////
333 void pushGLStates();
334
335 ////////////////////////////////////////////////////////////
336 /// \brief Restore the previously saved OpenGL render states and matrices
337 ///
338 /// See the description of pushGLStates to get a detailed
339 /// description of these functions.
340 ///
341 /// \see pushGLStates
342 ///
343 ////////////////////////////////////////////////////////////
344 void popGLStates();
345
346 ////////////////////////////////////////////////////////////
347 /// \brief Reset the internal OpenGL states so that the target is ready for drawing
348 ///
349 /// This function can be used when you mix SFML drawing
350 /// and direct OpenGL rendering, if you choose not to use
351 /// pushGLStates/popGLStates. It makes sure that all OpenGL
352 /// states needed by SFML are set, so that subsequent draw()
353 /// calls will work as expected.
354 ///
355 /// Example:
356 /// \code
357 /// // OpenGL code here...
358 /// glPushAttrib(...);
359 /// window.resetGLStates();
360 /// window.draw(...);
361 /// window.draw(...);
362 /// glPopAttrib(...);
363 /// // OpenGL code here...
364 /// \endcode
365 ///
366 ////////////////////////////////////////////////////////////
367 void resetGLStates();
368
369protected:
370
371 ////////////////////////////////////////////////////////////
372 /// \brief Default constructor
373 ///
374 ////////////////////////////////////////////////////////////
375 RenderTarget();
376
377 ////////////////////////////////////////////////////////////
378 /// \brief Performs the common initialization step after creation
379 ///
380 /// The derived classes must call this function after the
381 /// target is created and ready for drawing.
382 ///
383 ////////////////////////////////////////////////////////////
384 void initialize();
385
386private:
387
388 ////////////////////////////////////////////////////////////
389 /// \brief Apply the current view
390 ///
391 ////////////////////////////////////////////////////////////
392 void applyCurrentView();
393
394 ////////////////////////////////////////////////////////////
395 /// \brief Apply a new blending mode
396 ///
397 /// \param mode Blending mode to apply
398 ///
399 ////////////////////////////////////////////////////////////
400 void applyBlendMode(const BlendMode& mode);
401
402 ////////////////////////////////////////////////////////////
403 /// \brief Apply a new transform
404 ///
405 /// \param transform Transform to apply
406 ///
407 ////////////////////////////////////////////////////////////
408 void applyTransform(const Transform& transform);
409
410 ////////////////////////////////////////////////////////////
411 /// \brief Apply a new texture
412 ///
413 /// \param texture Texture to apply
414 ///
415 ////////////////////////////////////////////////////////////
416 void applyTexture(const Texture* texture);
417
418 ////////////////////////////////////////////////////////////
419 /// \brief Apply a new shader
420 ///
421 /// \param shader Shader to apply
422 ///
423 ////////////////////////////////////////////////////////////
424 void applyShader(const Shader* shader);
425
426 ////////////////////////////////////////////////////////////
427 /// \brief Setup environment for drawing
428 ///
429 /// \param useVertexCache Are we going to use the vertex cache?
430 /// \param states Render states to use for drawing
431 ///
432 ////////////////////////////////////////////////////////////
433 void setupDraw(bool useVertexCache, const RenderStates& states);
434
435 ////////////////////////////////////////////////////////////
436 /// \brief Draw the primitives
437 ///
438 /// \param type Type of primitives to draw
439 /// \param firstVertex Index of the first vertex to use when drawing
440 /// \param vertexCount Number of vertices to use when drawing
441 ///
442 ////////////////////////////////////////////////////////////
443 void drawPrimitives(PrimitiveType type, std::size_t firstVertex, std::size_t vertexCount);
444
445 ////////////////////////////////////////////////////////////
446 /// \brief Clean up environment after drawing
447 ///
448 /// \param states Render states used for drawing
449 ///
450 ////////////////////////////////////////////////////////////
451 void cleanupDraw(const RenderStates& states);
452
453 ////////////////////////////////////////////////////////////
454 /// \brief Render states cache
455 ///
456 ////////////////////////////////////////////////////////////
457 struct StatesCache
458 {
459 enum {VertexCacheSize = 4};
460
461 bool enable; //!< Is the cache enabled?
462 bool glStatesSet; //!< Are our internal GL states set yet?
463 bool viewChanged; //!< Has the current view changed since last draw?
464 BlendMode lastBlendMode; //!< Cached blending mode
465 Uint64 lastTextureId; //!< Cached texture
466 bool texCoordsArrayEnabled; //!< Is GL_TEXTURE_COORD_ARRAY client state enabled?
467 bool useVertexCache; //!< Did we previously use the vertex cache?
468 Vertex vertexCache[VertexCacheSize]; //!< Pre-transformed vertices cache
469 };
470
471 ////////////////////////////////////////////////////////////
472 // Member data
473 ////////////////////////////////////////////////////////////
474 View m_defaultView; //!< Default view
475 View m_view; //!< Current view
476 StatesCache m_cache; //!< Render states cache
477 Uint64 m_id; //!< Unique number that identifies the RenderTarget
478};
479
480} // namespace sf
481
482
483#endif // SFML_RENDERTARGET_HPP
484
485
486////////////////////////////////////////////////////////////
487/// \class sf::RenderTarget
488/// \ingroup graphics
489///
490/// sf::RenderTarget defines the common behavior of all the
491/// 2D render targets usable in the graphics module. It makes
492/// it possible to draw 2D entities like sprites, shapes, text
493/// without using any OpenGL command directly.
494///
495/// A sf::RenderTarget is also able to use views (sf::View),
496/// which are a kind of 2D cameras. With views you can globally
497/// scroll, rotate or zoom everything that is drawn,
498/// without having to transform every single entity. See the
499/// documentation of sf::View for more details and sample pieces of
500/// code about this class.
501///
502/// On top of that, render targets are still able to render direct
503/// OpenGL stuff. It is even possible to mix together OpenGL calls
504/// and regular SFML drawing commands. When doing so, make sure that
505/// OpenGL states are not messed up by calling the
506/// pushGLStates/popGLStates functions.
507///
508/// \see sf::RenderWindow, sf::RenderTexture, sf::View
509///
510////////////////////////////////////////////////////////////
511