511 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			511 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| ////////////////////////////////////////////////////////////
 | |
| //
 | |
| // SFML - Simple and Fast Multimedia Library
 | |
| // Copyright (C) 2007-2018 Laurent Gomila (laurent@sfml-dev.org)
 | |
| //
 | |
| // This software is provided 'as-is', without any express or implied warranty.
 | |
| // In no event will the authors be held liable for any damages arising from the use of this software.
 | |
| //
 | |
| // Permission is granted to anyone to use this software for any purpose,
 | |
| // including commercial applications, and to alter it and redistribute it freely,
 | |
| // subject to the following restrictions:
 | |
| //
 | |
| // 1. The origin of this software must not be misrepresented;
 | |
| //    you must not claim that you wrote the original software.
 | |
| //    If you use this software in a product, an acknowledgment
 | |
| //    in the product documentation would be appreciated but is not required.
 | |
| //
 | |
| // 2. Altered source versions must be plainly marked as such,
 | |
| //    and must not be misrepresented as being the original software.
 | |
| //
 | |
| // 3. This notice may not be removed or altered from any source distribution.
 | |
| //
 | |
| ////////////////////////////////////////////////////////////
 | |
| 
 | |
| #ifndef SFML_RENDERTARGET_HPP
 | |
| #define SFML_RENDERTARGET_HPP
 | |
| 
 | |
| ////////////////////////////////////////////////////////////
 | |
| // Headers
 | |
| ////////////////////////////////////////////////////////////
 | |
| #include <SFML/Graphics/Export.hpp>
 | |
| #include <SFML/Graphics/Color.hpp>
 | |
| #include <SFML/Graphics/Rect.hpp>
 | |
| #include <SFML/Graphics/View.hpp>
 | |
| #include <SFML/Graphics/Transform.hpp>
 | |
| #include <SFML/Graphics/BlendMode.hpp>
 | |
| #include <SFML/Graphics/RenderStates.hpp>
 | |
| #include <SFML/Graphics/PrimitiveType.hpp>
 | |
| #include <SFML/Graphics/Vertex.hpp>
 | |
| #include <SFML/System/NonCopyable.hpp>
 | |
| 
 | |
| 
 | |
| namespace sf
 | |
| {
 | |
| class Drawable;
 | |
| class VertexBuffer;
 | |
| 
 | |
| ////////////////////////////////////////////////////////////
 | |
| /// \brief Base class for all render targets (window, texture, ...)
 | |
| ///
 | |
| ////////////////////////////////////////////////////////////
 | |
| class SFML_GRAPHICS_API RenderTarget : NonCopyable
 | |
| {
 | |
| public:
 | |
| 
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     /// \brief Destructor
 | |
|     ///
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     virtual ~RenderTarget();
 | |
| 
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     /// \brief Clear the entire target with a single color
 | |
|     ///
 | |
|     /// This function is usually called once every frame,
 | |
|     /// to clear the previous contents of the target.
 | |
|     ///
 | |
|     /// \param color Fill color to use to clear the render target
 | |
|     ///
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     void clear(const Color& color = Color(0, 0, 0, 255));
 | |
| 
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     /// \brief Change the current active view
 | |
|     ///
 | |
|     /// The view is like a 2D camera, it controls which part of
 | |
|     /// the 2D scene is visible, and how it is viewed in the
 | |
|     /// render target.
 | |
|     /// The new view will affect everything that is drawn, until
 | |
|     /// another view is set.
 | |
|     /// The render target keeps its own copy of the view object,
 | |
|     /// so it is not necessary to keep the original one alive
 | |
|     /// after calling this function.
 | |
|     /// To restore the original view of the target, you can pass
 | |
|     /// the result of getDefaultView() to this function.
 | |
|     ///
 | |
|     /// \param view New view to use
 | |
|     ///
 | |
|     /// \see getView, getDefaultView
 | |
|     ///
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     void setView(const View& view);
 | |
| 
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     /// \brief Get the view currently in use in the render target
 | |
|     ///
 | |
|     /// \return The view object that is currently used
 | |
|     ///
 | |
|     /// \see setView, getDefaultView
 | |
|     ///
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     const View& getView() const;
 | |
| 
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     /// \brief Get the default view of the render target
 | |
|     ///
 | |
|     /// The default view has the initial size of the render target,
 | |
|     /// and never changes after the target has been created.
 | |
|     ///
 | |
|     /// \return The default view of the render target
 | |
|     ///
 | |
|     /// \see setView, getView
 | |
|     ///
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     const View& getDefaultView() const;
 | |
| 
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     /// \brief Get the viewport of a view, applied to this render target
 | |
|     ///
 | |
|     /// The viewport is defined in the view as a ratio, this function
 | |
|     /// simply applies this ratio to the current dimensions of the
 | |
|     /// render target to calculate the pixels rectangle that the viewport
 | |
|     /// actually covers in the target.
 | |
|     ///
 | |
|     /// \param view The view for which we want to compute the viewport
 | |
|     ///
 | |
|     /// \return Viewport rectangle, expressed in pixels
 | |
|     ///
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     IntRect getViewport(const View& view) const;
 | |
| 
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     /// \brief Convert a point from target coordinates to world
 | |
|     ///        coordinates, using the current view
 | |
|     ///
 | |
|     /// This function is an overload of the mapPixelToCoords
 | |
|     /// function that implicitly uses the current view.
 | |
|     /// It is equivalent to:
 | |
|     /// \code
 | |
|     /// target.mapPixelToCoords(point, target.getView());
 | |
|     /// \endcode
 | |
|     ///
 | |
|     /// \param point Pixel to convert
 | |
|     ///
 | |
|     /// \return The converted point, in "world" coordinates
 | |
|     ///
 | |
|     /// \see mapCoordsToPixel
 | |
|     ///
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     Vector2f mapPixelToCoords(const Vector2i& point) const;
 | |
| 
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     /// \brief Convert a point from target coordinates to world coordinates
 | |
|     ///
 | |
|     /// This function finds the 2D position that matches the
 | |
|     /// given pixel of the render target. In other words, it does
 | |
|     /// the inverse of what the graphics card does, to find the
 | |
|     /// initial position of a rendered pixel.
 | |
|     ///
 | |
|     /// Initially, both coordinate systems (world units and target pixels)
 | |
|     /// match perfectly. But if you define a custom view or resize your
 | |
|     /// render target, this assertion is not true anymore, i.e. a point
 | |
|     /// located at (10, 50) in your render target may map to the point
 | |
|     /// (150, 75) in your 2D world -- if the view is translated by (140, 25).
 | |
|     ///
 | |
|     /// For render-windows, this function is typically used to find
 | |
|     /// which point (or object) is located below the mouse cursor.
 | |
|     ///
 | |
|     /// This version uses a custom view for calculations, see the other
 | |
|     /// overload of the function if you want to use the current view of the
 | |
|     /// render target.
 | |
|     ///
 | |
|     /// \param point Pixel to convert
 | |
|     /// \param view The view to use for converting the point
 | |
|     ///
 | |
|     /// \return The converted point, in "world" units
 | |
|     ///
 | |
|     /// \see mapCoordsToPixel
 | |
|     ///
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     Vector2f mapPixelToCoords(const Vector2i& point, const View& view) const;
 | |
| 
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     /// \brief Convert a point from world coordinates to target
 | |
|     ///        coordinates, using the current view
 | |
|     ///
 | |
|     /// This function is an overload of the mapCoordsToPixel
 | |
|     /// function that implicitly uses the current view.
 | |
|     /// It is equivalent to:
 | |
|     /// \code
 | |
|     /// target.mapCoordsToPixel(point, target.getView());
 | |
|     /// \endcode
 | |
|     ///
 | |
|     /// \param point Point to convert
 | |
|     ///
 | |
|     /// \return The converted point, in target coordinates (pixels)
 | |
|     ///
 | |
|     /// \see mapPixelToCoords
 | |
|     ///
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     Vector2i mapCoordsToPixel(const Vector2f& point) const;
 | |
| 
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     /// \brief Convert a point from world coordinates to target coordinates
 | |
|     ///
 | |
|     /// This function finds the pixel of the render target that matches
 | |
|     /// the given 2D point. In other words, it goes through the same process
 | |
|     /// as the graphics card, to compute the final position of a rendered point.
 | |
|     ///
 | |
|     /// Initially, both coordinate systems (world units and target pixels)
 | |
|     /// match perfectly. But if you define a custom view or resize your
 | |
|     /// render target, this assertion is not true anymore, i.e. a point
 | |
|     /// located at (150, 75) in your 2D world may map to the pixel
 | |
|     /// (10, 50) of your render target -- if the view is translated by (140, 25).
 | |
|     ///
 | |
|     /// This version uses a custom view for calculations, see the other
 | |
|     /// overload of the function if you want to use the current view of the
 | |
|     /// render target.
 | |
|     ///
 | |
|     /// \param point Point to convert
 | |
|     /// \param view The view to use for converting the point
 | |
|     ///
 | |
|     /// \return The converted point, in target coordinates (pixels)
 | |
|     ///
 | |
|     /// \see mapPixelToCoords
 | |
|     ///
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     Vector2i mapCoordsToPixel(const Vector2f& point, const View& view) const;
 | |
| 
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     /// \brief Draw a drawable object to the render target
 | |
|     ///
 | |
|     /// \param drawable Object to draw
 | |
|     /// \param states   Render states to use for drawing
 | |
|     ///
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     void draw(const Drawable& drawable, const RenderStates& states = RenderStates::Default);
 | |
| 
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     /// \brief Draw primitives defined by an array of vertices
 | |
|     ///
 | |
|     /// \param vertices    Pointer to the vertices
 | |
|     /// \param vertexCount Number of vertices in the array
 | |
|     /// \param type        Type of primitives to draw
 | |
|     /// \param states      Render states to use for drawing
 | |
|     ///
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     void draw(const Vertex* vertices, std::size_t vertexCount,
 | |
|               PrimitiveType type, const RenderStates& states = RenderStates::Default);
 | |
| 
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     /// \brief Draw primitives defined by a vertex buffer
 | |
|     ///
 | |
|     /// \param vertexBuffer Vertex buffer
 | |
|     /// \param states       Render states to use for drawing
 | |
|     ///
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     void draw(const VertexBuffer& vertexBuffer, const RenderStates& states = RenderStates::Default);
 | |
| 
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     /// \brief Draw primitives defined by a vertex buffer
 | |
|     ///
 | |
|     /// \param vertexBuffer Vertex buffer
 | |
|     /// \param firstVertex  Index of the first vertex to render
 | |
|     /// \param vertexCount  Number of vertices to render
 | |
|     /// \param states       Render states to use for drawing
 | |
|     ///
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     void draw(const VertexBuffer& vertexBuffer, std::size_t firstVertex, std::size_t vertexCount, const RenderStates& states = RenderStates::Default);
 | |
| 
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     /// \brief Return the size of the rendering region of the target
 | |
|     ///
 | |
|     /// \return Size in pixels
 | |
|     ///
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     virtual Vector2u getSize() const = 0;
 | |
| 
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     /// \brief Activate or deactivate the render target for rendering
 | |
|     ///
 | |
|     /// This function makes the render target's context current for
 | |
|     /// future OpenGL rendering operations (so you shouldn't care
 | |
|     /// about it if you're not doing direct OpenGL stuff).
 | |
|     /// A render target's context is active only on the current thread,
 | |
|     /// if you want to make it active on another thread you have
 | |
|     /// to deactivate it on the previous thread first if it was active.
 | |
|     /// Only one context can be current in a thread, so if you
 | |
|     /// want to draw OpenGL geometry to another render target
 | |
|     /// don't forget to activate it again. Activating a render
 | |
|     /// target will automatically deactivate the previously active
 | |
|     /// context (if any).
 | |
|     ///
 | |
|     /// \param active True to activate, false to deactivate
 | |
|     ///
 | |
|     /// \return True if operation was successful, false otherwise
 | |
|     ///
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     virtual bool setActive(bool active = true);
 | |
| 
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     /// \brief Save the current OpenGL render states and matrices
 | |
|     ///
 | |
|     /// This function can be used when you mix SFML drawing
 | |
|     /// and direct OpenGL rendering. Combined with popGLStates,
 | |
|     /// it ensures that:
 | |
|     /// \li SFML's internal states are not messed up by your OpenGL code
 | |
|     /// \li your OpenGL states are not modified by a call to a SFML function
 | |
|     ///
 | |
|     /// More specifically, it must be used around code that
 | |
|     /// calls Draw functions. Example:
 | |
|     /// \code
 | |
|     /// // OpenGL code here...
 | |
|     /// window.pushGLStates();
 | |
|     /// window.draw(...);
 | |
|     /// window.draw(...);
 | |
|     /// window.popGLStates();
 | |
|     /// // OpenGL code here...
 | |
|     /// \endcode
 | |
|     ///
 | |
|     /// Note that this function is quite expensive: it saves all the
 | |
|     /// possible OpenGL states and matrices, even the ones you
 | |
|     /// don't care about. Therefore it should be used wisely.
 | |
|     /// It is provided for convenience, but the best results will
 | |
|     /// be achieved if you handle OpenGL states yourself (because
 | |
|     /// you know which states have really changed, and need to be
 | |
|     /// saved and restored). Take a look at the resetGLStates
 | |
|     /// function if you do so.
 | |
|     ///
 | |
|     /// \see popGLStates
 | |
|     ///
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     void pushGLStates();
 | |
| 
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     /// \brief Restore the previously saved OpenGL render states and matrices
 | |
|     ///
 | |
|     /// See the description of pushGLStates to get a detailed
 | |
|     /// description of these functions.
 | |
|     ///
 | |
|     /// \see pushGLStates
 | |
|     ///
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     void popGLStates();
 | |
| 
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     /// \brief Reset the internal OpenGL states so that the target is ready for drawing
 | |
|     ///
 | |
|     /// This function can be used when you mix SFML drawing
 | |
|     /// and direct OpenGL rendering, if you choose not to use
 | |
|     /// pushGLStates/popGLStates. It makes sure that all OpenGL
 | |
|     /// states needed by SFML are set, so that subsequent draw()
 | |
|     /// calls will work as expected.
 | |
|     ///
 | |
|     /// Example:
 | |
|     /// \code
 | |
|     /// // OpenGL code here...
 | |
|     /// glPushAttrib(...);
 | |
|     /// window.resetGLStates();
 | |
|     /// window.draw(...);
 | |
|     /// window.draw(...);
 | |
|     /// glPopAttrib(...);
 | |
|     /// // OpenGL code here...
 | |
|     /// \endcode
 | |
|     ///
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     void resetGLStates();
 | |
| 
 | |
| protected:
 | |
| 
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     /// \brief Default constructor
 | |
|     ///
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     RenderTarget();
 | |
| 
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     /// \brief Performs the common initialization step after creation
 | |
|     ///
 | |
|     /// The derived classes must call this function after the
 | |
|     /// target is created and ready for drawing.
 | |
|     ///
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     void initialize();
 | |
| 
 | |
| private:
 | |
| 
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     /// \brief Apply the current view
 | |
|     ///
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     void applyCurrentView();
 | |
| 
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     /// \brief Apply a new blending mode
 | |
|     ///
 | |
|     /// \param mode Blending mode to apply
 | |
|     ///
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     void applyBlendMode(const BlendMode& mode);
 | |
| 
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     /// \brief Apply a new transform
 | |
|     ///
 | |
|     /// \param transform Transform to apply
 | |
|     ///
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     void applyTransform(const Transform& transform);
 | |
| 
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     /// \brief Apply a new texture
 | |
|     ///
 | |
|     /// \param texture Texture to apply
 | |
|     ///
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     void applyTexture(const Texture* texture);
 | |
| 
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     /// \brief Apply a new shader
 | |
|     ///
 | |
|     /// \param shader Shader to apply
 | |
|     ///
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     void applyShader(const Shader* shader);
 | |
| 
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     /// \brief Setup environment for drawing
 | |
|     ///
 | |
|     /// \param useVertexCache Are we going to use the vertex cache?
 | |
|     /// \param states         Render states to use for drawing
 | |
|     ///
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     void setupDraw(bool useVertexCache, const RenderStates& states);
 | |
| 
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     /// \brief Draw the primitives
 | |
|     ///
 | |
|     /// \param type        Type of primitives to draw
 | |
|     /// \param firstVertex Index of the first vertex to use when drawing
 | |
|     /// \param vertexCount Number of vertices to use when drawing
 | |
|     ///
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     void drawPrimitives(PrimitiveType type, std::size_t firstVertex, std::size_t vertexCount);
 | |
| 
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     /// \brief Clean up environment after drawing
 | |
|     ///
 | |
|     /// \param states Render states used for drawing
 | |
|     ///
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     void cleanupDraw(const RenderStates& states);
 | |
| 
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     /// \brief Render states cache
 | |
|     ///
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     struct StatesCache
 | |
|     {
 | |
|         enum {VertexCacheSize = 4};
 | |
| 
 | |
|         bool      enable;         ///< Is the cache enabled?
 | |
|         bool      glStatesSet;    ///< Are our internal GL states set yet?
 | |
|         bool      viewChanged;    ///< Has the current view changed since last draw?
 | |
|         BlendMode lastBlendMode;  ///< Cached blending mode
 | |
|         Uint64    lastTextureId;  ///< Cached texture
 | |
|         bool      texCoordsArrayEnabled; ///< Is GL_TEXTURE_COORD_ARRAY client state enabled?
 | |
|         bool      useVertexCache; ///< Did we previously use the vertex cache?
 | |
|         Vertex    vertexCache[VertexCacheSize]; ///< Pre-transformed vertices cache
 | |
|     };
 | |
| 
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     // Member data
 | |
|     ////////////////////////////////////////////////////////////
 | |
|     View        m_defaultView; ///< Default view
 | |
|     View        m_view;        ///< Current view
 | |
|     StatesCache m_cache;       ///< Render states cache
 | |
|     Uint64      m_id;          ///< Unique number that identifies the RenderTarget
 | |
| };
 | |
| 
 | |
| } // namespace sf
 | |
| 
 | |
| 
 | |
| #endif // SFML_RENDERTARGET_HPP
 | |
| 
 | |
| 
 | |
| ////////////////////////////////////////////////////////////
 | |
| /// \class sf::RenderTarget
 | |
| /// \ingroup graphics
 | |
| ///
 | |
| /// sf::RenderTarget defines the common behavior of all the
 | |
| /// 2D render targets usable in the graphics module. It makes
 | |
| /// it possible to draw 2D entities like sprites, shapes, text
 | |
| /// without using any OpenGL command directly.
 | |
| ///
 | |
| /// A sf::RenderTarget is also able to use views (sf::View),
 | |
| /// which are a kind of 2D cameras. With views you can globally
 | |
| /// scroll, rotate or zoom everything that is drawn,
 | |
| /// without having to transform every single entity. See the
 | |
| /// documentation of sf::View for more details and sample pieces of
 | |
| /// code about this class.
 | |
| ///
 | |
| /// On top of that, render targets are still able to render direct
 | |
| /// OpenGL stuff. It is even possible to mix together OpenGL calls
 | |
| /// and regular SFML drawing commands. When doing so, make sure that
 | |
| /// OpenGL states are not messed up by calling the
 | |
| /// pushGLStates/popGLStates functions.
 | |
| ///
 | |
| /// \see sf::RenderWindow, sf::RenderTexture, sf::View
 | |
| ///
 | |
| ////////////////////////////////////////////////////////////
 |