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
|
|
///
|
|
////////////////////////////////////////////////////////////
|