diff --git a/include/SFML/Graphics/Matrix3.hpp b/include/SFML/Graphics/Matrix3.hpp index 2b8db6ea2..cfc4e6d10 100644 --- a/include/SFML/Graphics/Matrix3.hpp +++ b/include/SFML/Graphics/Matrix3.hpp @@ -72,10 +72,12 @@ public : //////////////////////////////////////////////////////////// /// Build a matrix from a projection /// - /// \param Rectangle : Rectangle defining the region to project + /// \param Center : Center of the view + /// \param Size : Size of the view + /// \param Rotation : Angle of rotation of the view rectangle, in degrees /// //////////////////////////////////////////////////////////// - void SetFromProjection(const FloatRect& Rectangle); + void SetFromProjection(const Vector2f& Center, const Vector2f& Size, float Rotation); //////////////////////////////////////////////////////////// /// Transform a point by the matrix diff --git a/include/SFML/Graphics/Matrix3.inl b/include/SFML/Graphics/Matrix3.inl index 4f1734bab..5e1849626 100644 --- a/include/SFML/Graphics/Matrix3.inl +++ b/include/SFML/Graphics/Matrix3.inl @@ -76,19 +76,26 @@ inline void Matrix3::SetFromTransformations(const Vector2f& Center, const Vector //////////////////////////////////////////////////////////// /// Build a matrix from a projection //////////////////////////////////////////////////////////// -inline void Matrix3::SetFromProjection(const FloatRect& Rectangle) +inline void Matrix3::SetFromProjection(const Vector2f& Center, const Vector2f& Size, float Rotation) { + // Rotation components + float Angle = Rotation * 3.141592654f / 180.f; + float Cos = static_cast(cos(Angle)); + float Sin = static_cast(sin(Angle)); + float Tx = -Center.x * Cos - Center.y * Sin + Center.x; + float Ty = Center.x * Sin - Center.y * Cos + Center.y; + // Projection components - float A = 2.f / Rectangle.GetSize().x; - float B = -2.f / Rectangle.GetSize().y; - float C = -(Rectangle.Left + Rectangle.Right) / Rectangle.GetSize().x; - float D = (Rectangle.Bottom + Rectangle.Top) / Rectangle.GetSize().y; + float A = 2.f / Size.x; + float B = -2.f / Size.y; + float C = -A * Center.x; + float D = -B * Center.y; // Rebuild the projection matrix - myData[0] = A; myData[4] = 0.f; myData[8] = 0.f; myData[12] = C; - myData[1] = 0.f; myData[5] = B; myData[9] = 0.f; myData[13] = D; - myData[2] = 0.f; myData[6] = 0.f; myData[10] = 1.f; myData[14] = 0.f; - myData[3] = 0.f; myData[7] = 0.f; myData[11] = 0.f; myData[15] = 1.f; + myData[0] = A * Cos; myData[4] = A * Sin; myData[8] = 0.f; myData[12] = A * Tx + C; + myData[1] = -B * Sin; myData[5] = B * Cos; myData[9] = 0.f; myData[13] = B * Ty + D; + myData[2] = 0.f; myData[6] = 0.f; myData[10] = 1.f; myData[14] = 0.f; + myData[3] = 0.f; myData[7] = 0.f; myData[11] = 0.f; myData[15] = 1.f; } diff --git a/include/SFML/Graphics/View.hpp b/include/SFML/Graphics/View.hpp index f0ae84af6..70195dd98 100644 --- a/include/SFML/Graphics/View.hpp +++ b/include/SFML/Graphics/View.hpp @@ -37,20 +37,33 @@ namespace sf { //////////////////////////////////////////////////////////// -/// This class defines a view (position, size, etc.); -/// you can consider it as a 2D camera +/// This class defines a 2D view. A view is like a camera, +/// which defines what part of the scene is shown and +/// where it is shown. +/// A sf::View is defined by the following components: +/// its source rectangle in the scene, an optional rotation +/// to apply to the source rectangle, and the destination +/// rectangle where it will be displayed, in the render target +/// that it is attached to. //////////////////////////////////////////////////////////// class SFML_API View { public : //////////////////////////////////////////////////////////// - /// Construct the view from a rectangle - /// - /// \param ViewRect : Rectangle defining the position and size of the view (1000x1000 by default) + /// Default constructor + /// Constructs a default view of (0, 0, 1000, 1000) /// //////////////////////////////////////////////////////////// - explicit View(const FloatRect& ViewRect = FloatRect(0, 0, 1000, 1000)); + View(); + + //////////////////////////////////////////////////////////// + /// Construct the view from a rectangle + /// + /// \param Rectangle : Rectangle defining the view + /// + //////////////////////////////////////////////////////////// + explicit View(const FloatRect& Rectangle); //////////////////////////////////////////////////////////// /// Construct the view from its center and size @@ -62,24 +75,7 @@ public : View(const Vector2f& Center, const Vector2f& Size); //////////////////////////////////////////////////////////// - /// Set the rectangle defining the view by its center and size - /// - /// \param Center : Center of the view rectangle - /// \param Size : Size of the view rectangle - /// - //////////////////////////////////////////////////////////// - void SetRect(const Vector2f& Center, const Vector2f& Size); - - //////////////////////////////////////////////////////////// - /// Set the rectangle defining the view - /// - /// \param Rect : Rectangle defining the center and size of the view - /// - //////////////////////////////////////////////////////////// - void SetRect(const FloatRect& Rect); - - //////////////////////////////////////////////////////////// - /// Change the center of the view (take 2 values) + /// Change the center of the view /// /// \param X : X coordinate of the new center /// \param Y : Y coordinate of the new center @@ -88,7 +84,7 @@ public : void SetCenter(float X, float Y); //////////////////////////////////////////////////////////// - /// Change the center of the view (take a vector) + /// Change the center of the view /// /// \param Center : New center /// @@ -96,7 +92,7 @@ public : void SetCenter(const Vector2f& Center); //////////////////////////////////////////////////////////// - /// Change the size of the view (take 2 values) + /// Change the size of the view /// /// \param Width : New width /// \param Height : New height @@ -105,7 +101,7 @@ public : void SetSize(float Width, float Height); //////////////////////////////////////////////////////////// - /// Change the size of the view (take a vector) + /// Change the size of the view /// /// \param HalfSize : New half-size /// @@ -113,13 +109,21 @@ public : void SetSize(const Vector2f& Size); //////////////////////////////////////////////////////////// - /// Get the rectangle defining the view, - /// which is the combined center and size. + /// Set the angle of rotation of the view /// - /// \return View rectangle + /// \param Angle : New angle, in degrees /// //////////////////////////////////////////////////////////// - FloatRect GetRect() const; + void SetRotation(float Angle); + + //////////////////////////////////////////////////////////// + /// Reset the view to the given rectangle. + /// Note: this function resets the rotation angle to 0. + /// + /// \param Rectangle : Rectangle defining the view + /// + //////////////////////////////////////////////////////////// + void Reset(const FloatRect& Rectangle); //////////////////////////////////////////////////////////// /// Get the center of the view @@ -138,7 +142,7 @@ public : const Vector2f& GetSize() const; //////////////////////////////////////////////////////////// - /// Move the view (take 2 values) + /// Move the view /// /// \param OffsetX : Offset to move the view, on X axis /// \param OffsetY : Offset to move the view, on Y axis @@ -147,17 +151,25 @@ public : void Move(float OffsetX, float OffsetY); //////////////////////////////////////////////////////////// - /// Move the view (take a vector) + /// Move the view /// /// \param Offset : Offset to move the view /// //////////////////////////////////////////////////////////// void Move(const Vector2f& Offset); + //////////////////////////////////////////////////////////// + /// Rotate the view + /// + /// \param Angle : Angle to rotate, in degrees + /// + //////////////////////////////////////////////////////////// + void Rotate(float Angle); + //////////////////////////////////////////////////////////// /// Resize the view rectangle to simulate a zoom / unzoom effect /// - /// \param Factor : Zoom factor to apply, relative to the current zoom + /// \param Factor : Zoom factor to apply, relative to the current size /// //////////////////////////////////////////////////////////// void Zoom(float Factor); @@ -183,8 +195,9 @@ private : //////////////////////////////////////////////////////////// // Member data //////////////////////////////////////////////////////////// - sf::Vector2f myCenter; ///< Center of the view - sf::Vector2f mySize; ///< Size of the view + Vector2f myCenter; ///< Center of the view, in scene coordinates + Vector2f mySize; ///< Size of the view, in scene coordinates + float myRotation; ///< Angle of rotation of the view rectangle, in degrees mutable Matrix3 myMatrix; ///< Precomputed projection matrix corresponding to the view mutable Matrix3 myInverseMatrix; ///< Precomputed inverse projection matrix corresponding to the view mutable bool myNeedUpdate; ///< Internal state telling if the matrix needs to be updated diff --git a/samples/qt/Main.cpp b/samples/qt/Main.cpp index fd5789433..e8c597623 100644 --- a/samples/qt/Main.cpp +++ b/samples/qt/Main.cpp @@ -60,7 +60,7 @@ private : // Adjust the size of the default view when the widget is resized if (Event.Type == sf::Event::Resized) { - GetDefaultView().SetRect(sf::FloatRect(0, 0, Event.Size.Width, Event.Size.Height)); + GetDefaultView().Reset(sf::FloatRect(0, 0, Event.Size.Width, Event.Size.Height)); } } diff --git a/src/SFML/Graphics/PostFX.cpp b/src/SFML/Graphics/PostFX.cpp index 793ba879e..c9902d1bd 100644 --- a/src/SFML/Graphics/PostFX.cpp +++ b/src/SFML/Graphics/PostFX.cpp @@ -303,13 +303,16 @@ void PostFX::Render(RenderTarget& Target) const IntRect FrameBufferRect(0, 0, myFrameBuffer.GetWidth(), myFrameBuffer.GetHeight()); FloatRect TexCoords = myFrameBuffer.GetTexCoords(FrameBufferRect); + // Set the projection matrix to the identity so that the screen coordinates are in the range [-1, 1] + GLCheck(glMatrixMode(GL_PROJECTION)); + GLCheck(glLoadIdentity()); + // Render a fullscreen quad using the effect on our framebuffer - FloatRect Screen = Target.GetView().GetRect(); glBegin(GL_QUADS); - glTexCoord2f(TexCoords.Left, TexCoords.Top); glVertex2f(Screen.Left, Screen.Top); - glTexCoord2f(TexCoords.Right, TexCoords.Top); glVertex2f(Screen.Right, Screen.Top); - glTexCoord2f(TexCoords.Right, TexCoords.Bottom); glVertex2f(Screen.Right, Screen.Bottom); - glTexCoord2f(TexCoords.Left, TexCoords.Bottom); glVertex2f(Screen.Left, Screen.Bottom); + glTexCoord2f(TexCoords.Left, TexCoords.Top); glVertex2f(-1, 1); + glTexCoord2f(TexCoords.Right, TexCoords.Top); glVertex2f( 1, 1); + glTexCoord2f(TexCoords.Right, TexCoords.Bottom); glVertex2f( 1, -1); + glTexCoord2f(TexCoords.Left, TexCoords.Bottom); glVertex2f(-1, -1); glEnd(); // Disable program diff --git a/src/SFML/Graphics/RenderTarget.cpp b/src/SFML/Graphics/RenderTarget.cpp index 8393c24bf..9c2bda3c7 100644 --- a/src/SFML/Graphics/RenderTarget.cpp +++ b/src/SFML/Graphics/RenderTarget.cpp @@ -175,7 +175,7 @@ void RenderTarget::Initialize() SetRenderStates(); // Setup the default view - myDefaultView.SetRect(FloatRect(0, 0, static_cast(GetWidth()), static_cast(GetHeight()))); + myDefaultView.Reset(FloatRect(0, 0, static_cast(GetWidth()), static_cast(GetHeight()))); SetView(myDefaultView); Activate(false); diff --git a/src/SFML/Graphics/View.cpp b/src/SFML/Graphics/View.cpp index 9143b2829..7f8198859 100644 --- a/src/SFML/Graphics/View.cpp +++ b/src/SFML/Graphics/View.cpp @@ -30,12 +30,32 @@ namespace sf { +//////////////////////////////////////////////////////////// +/// Default constructor +/// Constructs a default view of (0, 0, 1000, 1000) +//////////////////////////////////////////////////////////// +View::View() : +myCenter (), +mySize (), +myRotation (0), +myNeedUpdate (true), +myNeedInvUpdate(true) +{ + Reset(FloatRect(0, 0, 1000, 1000)); +} + + //////////////////////////////////////////////////////////// /// Construct the view from a rectangle //////////////////////////////////////////////////////////// -View::View(const FloatRect& Rect) +View::View(const FloatRect& Rectangle) : +myCenter (), +mySize (), +myRotation (0), +myNeedUpdate (true), +myNeedInvUpdate(true) { - SetRect(Rect); + Reset(Rectangle); } @@ -45,36 +65,15 @@ View::View(const FloatRect& Rect) View::View(const Vector2f& Center, const Vector2f& Size) : myCenter (Center), mySize (Size), +myRotation (0), myNeedUpdate (true), myNeedInvUpdate(true) { } - //////////////////////////////////////////////////////////// -/// Set the rectangle defining the view by its center and size -//////////////////////////////////////////////////////////// -void View::SetRect(const Vector2f& Center, const Vector2f& Size) -{ - myCenter = Center; - mySize = Size; - myNeedUpdate = true; - myNeedInvUpdate = true; -} - - -//////////////////////////////////////////////////////////// -/// Set the rectangle defining the view -//////////////////////////////////////////////////////////// -void View::SetRect(const FloatRect& Rect) -{ - SetRect(Rect.GetCenter(), Rect.GetSize()); -} - - -//////////////////////////////////////////////////////////// -/// Change the center of the view (take 2 values) +/// Change the center of the view //////////////////////////////////////////////////////////// void View::SetCenter(float X, float Y) { @@ -86,7 +85,7 @@ void View::SetCenter(float X, float Y) //////////////////////////////////////////////////////////// -/// Change the center of the view (take a vector) +/// Change the center of the view //////////////////////////////////////////////////////////// void View::SetCenter(const Vector2f& Center) { @@ -95,7 +94,7 @@ void View::SetCenter(const Vector2f& Center) //////////////////////////////////////////////////////////// -/// Change the size of the view (take 2 values) +/// Change the size of the view //////////////////////////////////////////////////////////// void View::SetSize(float Width, float Height) { @@ -107,7 +106,7 @@ void View::SetSize(float Width, float Height) //////////////////////////////////////////////////////////// -/// Change the size of the view (take a vector) +/// Change the size of the view //////////////////////////////////////////////////////////// void View::SetSize(const Vector2f& Size) { @@ -116,15 +115,25 @@ void View::SetSize(const Vector2f& Size) //////////////////////////////////////////////////////////// -/// Get the rectangle defining the view, -/// which is the combined center and size. +/// Set the angle of rotation of the view //////////////////////////////////////////////////////////// -FloatRect View::GetRect() const +void View::SetRotation(float Angle) { - return FloatRect(myCenter.x - mySize.x / 2, - myCenter.y - mySize.y / 2, - myCenter.x + mySize.x / 2, - myCenter.y + mySize.y / 2); + myRotation = Angle; + myNeedUpdate = true; + myNeedInvUpdate = true; +} + + +//////////////////////////////////////////////////////////// +/// Reset the view to the given rectangle +//////////////////////////////////////////////////////////// +void View::Reset(const FloatRect& Rectangle) +{ + myCenter = Rectangle.GetCenter(); + mySize = Rectangle.GetSize(); + myNeedUpdate = true; + myNeedInvUpdate = true; } @@ -147,7 +156,7 @@ const Vector2f& View::GetSize() const //////////////////////////////////////////////////////////// -/// Move the view (take 2 values) +/// Move the view //////////////////////////////////////////////////////////// void View::Move(float OffsetX, float OffsetY) { @@ -159,7 +168,7 @@ void View::Move(float OffsetX, float OffsetY) //////////////////////////////////////////////////////////// -/// Move the view (take a vector) +/// Move the view //////////////////////////////////////////////////////////// void View::Move(const Vector2f& Offset) { @@ -167,17 +176,26 @@ void View::Move(const Vector2f& Offset) } +//////////////////////////////////////////////////////////// +/// Rotate the view +//////////////////////////////////////////////////////////// +void View::Rotate(float Angle) +{ + myRotation += Angle; + myNeedUpdate = true; + myNeedInvUpdate = true; +} + + //////////////////////////////////////////////////////////// /// Resize the view rectangle to simulate a zoom / unzoom effect //////////////////////////////////////////////////////////// void View::Zoom(float Factor) { - if (Factor != 0) - { - mySize /= Factor; - myNeedUpdate = true; - myNeedInvUpdate = true; - } + mySize.x *= Factor; + mySize.y *= Factor; + myNeedUpdate = true; + myNeedInvUpdate = true; } @@ -189,7 +207,7 @@ const Matrix3& View::GetMatrix() const // Recompute the matrix if needed if (myNeedUpdate) { - myMatrix.SetFromProjection(GetRect()); + myMatrix.SetFromProjection(myCenter, mySize, myRotation); myNeedUpdate = false; }