Added automatic batching to improve performances

Moved the ConvertCoords function from RenderWindow to RenderTarget

git-svn-id: https://sfml.svn.sourceforge.net/svnroot/sfml/branches/sfml2@1221 4e206d99-4929-0410-ac5d-dfc041789085
This commit is contained in:
LaurentGom 2009-09-24 07:50:08 +00:00
parent 1852614e16
commit 565172fc75
51 changed files with 2835 additions and 865 deletions

View file

@ -25,6 +25,7 @@
#ifndef SFML_CONFIG_HPP
#define SFML_CONFIG_HPP
////////////////////////////////////////////////////////////
// Identify the operating system
////////////////////////////////////////////////////////////
@ -62,6 +63,23 @@
#endif
////////////////////////////////////////////////////////////
// Identify the endianess
////////////////////////////////////////////////////////////
#if defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || (defined(__MIPS__) && defined(__MISPEB__)) || \
defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) || defined(__sparc__) || defined(__hppa__)
// Big endian
#define SFML_ENDIAN_BIG
#else
// Little endian
#define SFML_ENDIAN_LITTLE
#endif
////////////////////////////////////////////////////////////
// Define a portable debug macro
////////////////////////////////////////////////////////////

View file

@ -36,6 +36,7 @@
#include <SFML/Graphics/Image.hpp>
#include <SFML/Graphics/PostFX.hpp>
#include <SFML/Graphics/RenderImage.hpp>
#include <SFML/Graphics/RenderQueue.hpp>
#include <SFML/Graphics/RenderWindow.hpp>
#include <SFML/Graphics/Shape.hpp>
#include <SFML/Graphics/Sprite.hpp>

View file

@ -35,6 +35,7 @@
namespace sf
{
class RenderQueue;
class RenderTarget;
////////////////////////////////////////////////////////////
@ -325,20 +326,22 @@ private :
friend class RenderTarget;
////////////////////////////////////////////////////////////
/// Draw the object into the specified window
/// Draw the object into the specified render target
///
/// \param target : Target into which render the object
/// \param queue : Render queue to add the rendering commands to
///
////////////////////////////////////////////////////////////
void Draw(RenderTarget& target) const;
void Draw(RenderTarget& target, RenderQueue& queue) const;
////////////////////////////////////////////////////////////
/// Render the specific geometry of the object
///
/// \param target : Target into which render the object
/// \param queue : Render queue to add the rendering commands to
///
////////////////////////////////////////////////////////////
virtual void Render(RenderTarget& target) const = 0;
virtual void Render(RenderTarget& target, RenderQueue& queue) const = 0;
////////////////////////////////////////////////////////////
// Member data

View file

@ -303,16 +303,6 @@ private :
////////////////////////////////////////////////////////////
void EnsureArrayUpdate();
////////////////////////////////////////////////////////////
/// Notify the image that an external source has modified
/// its content.
/// For internal use only (see RenderImage class).
///
/// \param source : RenderImage that will update the image
///
////////////////////////////////////////////////////////////
void ExternalUpdate(RenderImage& source);
////////////////////////////////////////////////////////////
/// Reset the image attributes
///
@ -337,7 +327,6 @@ private :
std::vector<Color> myPixels; ///< Pixels of the image
bool myNeedTextureUpdate; ///< Status of synchronization between pixels in central memory and the internal texture un video memory
bool myNeedArrayUpdate; ///< Status of synchronization between pixels in central memory and the internal texture un video memory
RenderImage* myUpdateSource; ///< If not null, the image will use it as a source to update its texture
bool myPixelsFlipped; ///< To work around the inconsistency in Y orientation
};

View file

@ -153,7 +153,7 @@ protected :
/// /see Drawable::Render
///
////////////////////////////////////////////////////////////
virtual void Render(RenderTarget& target) const;
virtual void Render(RenderTarget& target, RenderQueue& queue) const;
private :

View file

@ -65,7 +65,7 @@ public :
///
/// \param width : Width of the render image
/// \param height : Height of the render image
/// \param depthBuffer : Do you want a depth buffer attached? (false by default)
/// \param depthBuffer : Do you want this render image to have a depth buffer?
///
/// \return True if creation has been successful
///
@ -83,6 +83,12 @@ public :
////////////////////////////////////////////////////////////
bool SetActive(bool active = true);
////////////////////////////////////////////////////////////
/// Update the contents of the target image
///
////////////////////////////////////////////////////////////
void Display();
////////////////////////////////////////////////////////////
/// Get the width of the rendering region of the image
///
@ -117,26 +123,12 @@ public :
private :
friend class Image;
////////////////////////////////////////////////////////////
/// /see RenderTarget::Activate
///
////////////////////////////////////////////////////////////
virtual bool Activate(bool active);
////////////////////////////////////////////////////////////
/// Update the pixels of the target image.
/// This function is called automatically by the image when it
/// needs to update its pixels, and is only meant for internal use.
///
/// \param target : Target image to update
///
/// \return True if the new pixels are flipped vertically
///
////////////////////////////////////////////////////////////
bool UpdateImage(Image& target);
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////

View file

@ -0,0 +1,381 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// 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_RENDERQUEUE_HPP
#define SFML_RENDERQUEUE_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Config.hpp>
#include <SFML/System/NonCopyable.hpp>
#include <SFML/Graphics/Drawable.hpp>
#include <SFML/Graphics/Image.hpp>
#include <SFML/Graphics/Matrix3.hpp>
#include <SFML/Graphics/Rect.hpp>
#include <vector>
namespace sf
{
namespace priv
{
class Batch;
class GeometryRenderer;
}
////////////////////////////////////////////////////////////
/// \brief Implements a queue of rendering commands
///
////////////////////////////////////////////////////////////
class RenderQueue : NonCopyable
{
public :
////////////////////////////////////////////////////////////
/// \brief Default constructor
///
////////////////////////////////////////////////////////////
RenderQueue();
////////////////////////////////////////////////////////////
/// \brief Destructor
///
////////////////////////////////////////////////////////////
~RenderQueue();
////////////////////////////////////////////////////////////
/// \brief Save the current render states
///
/// \see PopStates
///
////////////////////////////////////////////////////////////
void PushStates();
////////////////////////////////////////////////////////////
/// \brief Restore the previously saved render states
///
/// \see PushStates
///
////////////////////////////////////////////////////////////
void PopStates();
////////////////////////////////////////////////////////////
/// \brief Set a new model-view matrix
///
/// Note: any call to this function after a call to BeginBatch
/// will be ignored, and delayed until BeginBatch is called again.
///
/// \param matrix New model-view matrix
///
/// \see ApplyModelView
///
////////////////////////////////////////////////////////////
void SetModelView(const Matrix3& matrix);
////////////////////////////////////////////////////////////
/// \brief Combine a new model-view matrix with the current one
///
/// Note: any call to this function after a call to BeginBatch
/// will be ignored, and delayed until BeginBatch is called again.
///
/// \param matrix Model-view matrix to combine
///
/// \see SetModelView
///
////////////////////////////////////////////////////////////
void ApplyModelView(const Matrix3& matrix);
////////////////////////////////////////////////////////////
/// \brief Set a new projection matrix
///
/// Note: any call to this function after a call to BeginBatch
/// will be ignored, and delayed until BeginBatch is called again.
///
/// \param matrix New projection matrix
///
/// \see ApplyProjection
///
////////////////////////////////////////////////////////////
void SetProjection(const Matrix3& matrix);
////////////////////////////////////////////////////////////
/// \brief Combine a new projection matrix with the current one
///
/// Note: any call to this function after a call to BeginBatch
/// will be ignored, and delayed until BeginBatch is called again.
///
/// \param matrix Model-view matrix to combine
///
/// \see SetProjection
///
////////////////////////////////////////////////////////////
void ApplyProjection(const Matrix3& matrix);
////////////////////////////////////////////////////////////
/// \brief Set the current global color
///
/// This color will be modulated with each vertex's color.
/// Note: any call to this function after a call to BeginBatch
/// will be ignored, and delayed until BeginBatch is called again.
///
/// \param color New global color
///
/// \see ApplyColor
///
////////////////////////////////////////////////////////////
void SetColor(const Color& color);
////////////////////////////////////////////////////////////
/// \brief Modulate the current global color with a new one
///
/// This color will be modulated with each vertex's color.
/// Note: any call to this function after a call to BeginBatch
/// will be ignored, and delayed until BeginBatch is called again.
///
/// \param color Color to modulate
///
/// \see SetColor
///
////////////////////////////////////////////////////////////
void ApplyColor(const Color& color);
////////////////////////////////////////////////////////////
/// \brief Set the current viewport
///
/// Note: any call to this function after a call to BeginBatch
/// will be ignored, and delayed until BeginBatch is called again.
///
/// \param viewport New viewport to apply
///
////////////////////////////////////////////////////////////
void SetViewport(const IntRect& viewport);
////////////////////////////////////////////////////////////
/// \brief Set the current alpha-blending mode
///
/// Note: any call to this function after a call to BeginBatch
/// will be ignored, and delayed until BeginBatch is called again.
///
/// \param mode New blending mode
///
////////////////////////////////////////////////////////////
void SetBlendMode(Blend::Mode mode);
////////////////////////////////////////////////////////////
/// \brief Set the current texture
///
/// Note: any call to this function after a call to BeginBatch
/// will be ignored, and delayed until BeginBatch is called again.
///
/// \param texture New texture
///
////////////////////////////////////////////////////////////
void SetTexture(const Image* texture);
////////////////////////////////////////////////////////////
/// \brief Begin a new geometry batch
///
/// This function starts storing geometry and associates it
/// to the current render states (viewport, color, blending, transform).
/// Note: There's no EndBatch, a batch ends as soon as BeginBatch
/// is called again.
///
////////////////////////////////////////////////////////////
void BeginBatch();
////////////////////////////////////////////////////////////
/// \brief Add a new vertex (position only)
///
/// This function adds a new vertex to the current batch.
/// This is equivalent to calling AddVertex(x, y, 0, 0, Color::White).
///
/// \param x X coordinate of the vertex
/// \param y Y coordinate of the vertex
///
////////////////////////////////////////////////////////////
void AddVertex(float x, float y);
////////////////////////////////////////////////////////////
/// \brief Add a new vertex (position + texture coordinates)
///
/// This function adds a new vertex to the current batch.
/// This is equivalent to calling AddVertex(x, y, u, v, Color::White).
///
/// \param x X coordinate of the vertex
/// \param y Y coordinate of the vertex
/// \param u X texture coordinate of the vertex
/// \param v Y texture coordinate of the vertex
///
////////////////////////////////////////////////////////////
void AddVertex(float x, float y, float u, float v);
////////////////////////////////////////////////////////////
/// \brief Add a new vertex (position + color)
///
/// This function adds a new vertex to the current batch.
/// This is equivalent to calling AddVertex(x, y, 0, 0, color).
///
/// \param x X coordinate of the vertex
/// \param y Y coordinate of the vertex
/// \param color Color of the vertex
///
////////////////////////////////////////////////////////////
void AddVertex(float x, float y, const Color& color);
////////////////////////////////////////////////////////////
/// \brief Add a new vertex (position + texture coordinates + color)
///
/// This function adds a new vertex to the current batch.
///
/// \param x X coordinate of the vertex
/// \param y Y coordinate of the vertex
/// \param u X texture coordinate of the vertex
/// \param v Y texture coordinate of the vertex
/// \param color Color of the vertex
///
////////////////////////////////////////////////////////////
void AddVertex(float x, float y, float u, float v, const Color& color);
////////////////////////////////////////////////////////////
/// \brief Add a new triangle to be rendered
///
/// This function adds a new triangle, using indices of previously
/// added vertices. Note that the index base is set to 0
/// everytime a new batch is started (BeginBatch).
///
/// Example:
/// \begincode
/// queue.BeginBatch();
/// queue.AddVertex(...);
/// queue.AddVertex(...);
/// queue.AddVertex(...);
/// queue.AddTriangle(0, 1, 2);
/// \endcode
///
/// \param index0 Index of the first vertex of the triangle
/// \param index1 Index of the second vertex of the triangle
/// \param index2 Index of the third vertex of the triangle
///
////////////////////////////////////////////////////////////
void AddTriangle(unsigned int index0, unsigned int index1, unsigned int index2);
////////////////////////////////////////////////////////////
/// \brief Render the content of the whole queue
///
/// After everything has been rendered, the render queue is
/// automatically cleared.
///
/// \see Clear
///
////////////////////////////////////////////////////////////
void Render();
////////////////////////////////////////////////////////////
/// \brief Clear the whole queue without rendering it
///
////////////////////////////////////////////////////////////
void Clear();
private :
////////////////////////////////////////////////////////////
// Structure holding the render states that can be stacked
////////////////////////////////////////////////////////////
struct RenderStates
{
RenderStates() : color(255, 255, 255, 255) {}
Matrix3 modelView; ///< Model-view matrix
Matrix3 projection; ///< Projection matrix
Color color; ///< Vertex color
};
////////////////////////////////////////////////////////////
// Types
////////////////////////////////////////////////////////////
typedef std::vector<priv::Batch> BatchArray;
typedef std::vector<float> VertexArray;
typedef std::vector<unsigned int> IndexArray;
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
RenderStates myStatesStack[16]; ///< Stack of render states
RenderStates* myCurrentStates; ///< Current set of render states
Matrix3 myCurrentTransform; ///< Current combined projection-model-view matrix
const Image* myCurrentTexture; ///< Current texture
Blend::Mode myCurrentBlendMode; ///< Current blending mode
IntRect myCurrentViewport; ///< Current target viewport
Vector2f myCurrentViewportSize; ///< Size of the current viewport (for vertex calculations)
unsigned int myBaseIndex; ///< Base vertex index for the current batch
priv::GeometryRenderer* myRenderer; ///< Optimized geometry renderer
priv::Batch* myCurrentBatch; ///< Current geometry block
BatchArray myBatches; ///< Blocks of geometry to render
VertexArray myVertices; ///< Geometry to be rendered
IndexArray myIndices; ///< Indices defining the triangles to be rendered
std::size_t myCurrentVertexCount; ///< Current number of vertices in the vertex array
std::size_t myCurrentIndexCount; ///< Current number of indices in the index array
};
} // namespace sf
#endif // SFML_RENDERQUEUE_HPP
////////////////////////////////////////////////////////////
/// \class sf::RenderQueue
///
/// The RenderQueue class allows to delay the actual rendering
/// by storing the sequence of render states and geometry.
///
/// Delaying rendering is crucial in order to implement batching
/// (grouping all the geometry using the same states, and sending
/// it to the graphics card with only one call), which allow
/// huge improvements in performances.
///
/// Usage example:
/// \begincode
/// void MyDrawable::Render(sf::RenderTarget& target)
/// {
/// RenderQueue& queue = target.GetRenderQueue();
///
/// queue.SetTexture(myImage);
/// queue.BeginBatch();
/// {
/// queue.AddVertex(...);
/// queue.AddVertex(...);
/// queue.AddVertex(...);
///
/// queue.AddTriangle(0, 1, 2);
/// }
/// }
/// \endcode
///
/// Note that this class is meant for internal use only
/// (it is used by render targets), unless you want to
/// inherit from sf::Drawable.
///
////////////////////////////////////////////////////////////

View file

@ -29,8 +29,9 @@
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Graphics/Color.hpp>
#include <SFML/Graphics/View.hpp>
#include <SFML/Graphics/Rect.hpp>
#include <SFML/Graphics/RenderQueue.hpp>
#include <SFML/Graphics/View.hpp>
namespace sf
@ -66,6 +67,22 @@ public :
////////////////////////////////////////////////////////////
virtual void Draw(const Drawable& object);
////////////////////////////////////////////////////////////
/// Make sure that what has been drawn so far is rendered
///
/// Use this function if you use OpenGL rendering commands,
/// and you want to make sure that things will appear on top
/// of all the SFML objects that have been drawn so far.
/// This is needed because SFML doesn't use immediate rendering,
/// it first accumulates drawables into a queue and
/// trigger the actual rendering afterwards.
///
/// You don't need to call this function if you're not
/// dealing with OpenGL directly.
///
////////////////////////////////////////////////////////////
void Flush();
////////////////////////////////////////////////////////////
/// Get the width of the rendering region of the target
///
@ -107,17 +124,39 @@ public :
View& GetDefaultView();
////////////////////////////////////////////////////////////
/// Tell SFML to preserve external OpenGL states, at the expense of
/// more CPU charge. Use this function if you don't want SFML
/// to mess up your own OpenGL states (if any).
/// Don't enable state preservation if not needed, as it will allow
/// SFML to do internal optimizations and improve performances.
/// This parameter is false by default
/// Get the viewport of a view applied to this target
///
/// \param preserve : True to preserve OpenGL states, false to let SFML optimize
/// \param view Target view
///
/// \return Viewport rectangle, expressed in pixels in the current target
///
////////////////////////////////////////////////////////////
void PreserveOpenGLStates(bool preserve);
IntRect GetViewport(const View& view) const;
////////////////////////////////////////////////////////////
/// Convert a point in target coordinates into view coordinates
/// This version uses the current view of the window
///
/// \param x : X coordinate of the point to convert, relative to the target
/// \param y : Y coordinate of the point to convert, relative to the target
///
/// \return Converted point
///
////////////////////////////////////////////////////////////
sf::Vector2f ConvertCoords(unsigned int x, unsigned int y) const;
////////////////////////////////////////////////////////////
/// Convert a point in target coordinates into view coordinates
/// This version uses the given view
///
/// \param x : X coordinate of the point to convert, relative to the target
/// \param y : Y coordinate of the point to convert, relative to the target
/// \param view : Target view to convert the point to
///
/// \return Converted point
///
////////////////////////////////////////////////////////////
sf::Vector2f ConvertCoords(unsigned int x, unsigned int y, const View& view) const;
protected :
@ -145,19 +184,12 @@ private :
////////////////////////////////////////////////////////////
virtual bool Activate(bool active) = 0;
////////////////////////////////////////////////////////////
/// Set the OpenGL render states needed for the SFML rendering
///
////////////////////////////////////////////////////////////
void SetRenderStates();
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
View myDefaultView; ///< Default view
const View* myCurrentView; ///< Current active view
bool myPreserveStates; ///< Should we preserve external OpenGL states ?
bool myIsDrawing; ///< True when Draw is called from inside, to allow some renderstates optimizations
RenderQueue myRenderQueue; ///< Rendering queue storing render commands
View myDefaultView; ///< Default view
const View* myCurrentView; ///< Current active view
};
} // namespace sf

View file

@ -94,39 +94,6 @@ public :
////////////////////////////////////////////////////////////
virtual unsigned int GetHeight() const;
////////////////////////////////////////////////////////////
/// Save the content of the window to an image
///
/// \return Image instance containing the contents of the screen
///
////////////////////////////////////////////////////////////
Image Capture() const;
////////////////////////////////////////////////////////////
/// Convert a point in window coordinates into view coordinates
/// This version uses the current view of the window
///
/// \param x : X coordinate of the point to convert, relative to the window
/// \param y : Y coordinate of the point to convert, relative to the window
///
/// \return Converted point
///
////////////////////////////////////////////////////////////
sf::Vector2f ConvertCoords(unsigned int x, unsigned int y) const;
////////////////////////////////////////////////////////////
/// Convert a point in window coordinates into view coordinates
/// This version uses the given view
///
/// \param x : X coordinate of the point to convert, relative to the window
/// \param y : Y coordinate of the point to convert, relative to the window
/// \param view : Target view to convert the point to
///
/// \return Converted point
///
////////////////////////////////////////////////////////////
sf::Vector2f ConvertCoords(unsigned int x, unsigned int y, const View& view) const;
private :
////////////////////////////////////////////////////////////
@ -135,6 +102,12 @@ private :
////////////////////////////////////////////////////////////
virtual void OnCreate();
////////////////////////////////////////////////////////////
/// /see Window::OnDisplay
///
////////////////////////////////////////////////////////////
virtual void OnDisplay();
////////////////////////////////////////////////////////////
/// /see RenderTarget::Activate
///

View file

@ -259,7 +259,7 @@ protected :
/// /see Drawable::Render
///
////////////////////////////////////////////////////////////
virtual void Render(RenderTarget& target) const;
virtual void Render(RenderTarget& target, RenderQueue& queue) const;
private :

View file

@ -158,7 +158,7 @@ protected :
/// /see Drawable::Render
///
////////////////////////////////////////////////////////////
virtual void Render(RenderTarget& target) const;
virtual void Render(RenderTarget& target, RenderQueue& queue) const;
private :

View file

@ -164,7 +164,7 @@ protected :
/// /see Drawable::Render
///
////////////////////////////////////////////////////////////
virtual void Render(RenderTarget& target) const;
virtual void Render(RenderTarget& target, RenderQueue& queue) const;
private :

View file

@ -290,6 +290,12 @@ private :
////////////////////////////////////////////////////////////
virtual void OnCreate();
////////////////////////////////////////////////////////////
/// Called before the window has been displayed
///
////////////////////////////////////////////////////////////
virtual void OnDisplay();
////////////////////////////////////////////////////////////
/// /see WindowListener::OnEvent
///