summaryrefslogtreecommitdiff
path: root/src/SFML/Graphics/RenderWindow.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/SFML/Graphics/RenderWindow.cpp')
-rwxr-xr-xsrc/SFML/Graphics/RenderWindow.cpp212
1 files changed, 109 insertions, 103 deletions
diff --git a/src/SFML/Graphics/RenderWindow.cpp b/src/SFML/Graphics/RenderWindow.cpp
index 1e2d1a9..dc43bb0 100755
--- a/src/SFML/Graphics/RenderWindow.cpp
+++ b/src/SFML/Graphics/RenderWindow.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2008 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.
@@ -27,9 +27,8 @@
////////////////////////////////////////////////////////////
#include <SFML/Graphics/RenderWindow.hpp>
#include <SFML/Graphics/Drawable.hpp>
-#include <SFML/Graphics/GraphicsDevice.hpp>
#include <SFML/Graphics/Image.hpp>
-#include <SFML/Graphics/OpenGL.hpp>
+#include <SFML/Graphics/Renderer.hpp>
#include <iostream>
@@ -40,7 +39,9 @@ namespace sf
////////////////////////////////////////////////////////////
RenderWindow::RenderWindow() :
myBackgroundColor(Color(0, 0, 0, 255)),
-myOptimizeStates (false)
+myCurrentView (&myDefaultView),
+myPreserveStates (false),
+myIsDrawing (false)
{
}
@@ -49,22 +50,26 @@ myOptimizeStates (false)
////////////////////////////////////////////////////////////
/// Construct the window
////////////////////////////////////////////////////////////
-RenderWindow::RenderWindow(VideoMode Mode, const std::string& Title, unsigned long WindowStyle, int AntialiasingLevel) :
+RenderWindow::RenderWindow(VideoMode Mode, const std::string& Title, unsigned long WindowStyle, const WindowSettings& Params) :
myBackgroundColor(Color(0, 0, 0, 255)),
-myOptimizeStates (false)
+myCurrentView (&myDefaultView),
+myPreserveStates (false),
+myIsDrawing (false)
{
- Create(Mode, Title, WindowStyle, AntialiasingLevel);
+ Create(Mode, Title, WindowStyle, Params);
}
////////////////////////////////////////////////////////////
/// Construct the window from an existing control
////////////////////////////////////////////////////////////
-RenderWindow::RenderWindow(WindowHandle Handle, int AntialiasingLevel) :
+RenderWindow::RenderWindow(WindowHandle Handle, const WindowSettings& Params) :
myBackgroundColor(Color(0, 0, 0, 255)),
-myOptimizeStates (false)
+myCurrentView (&myDefaultView),
+myPreserveStates (false),
+myIsDrawing (false)
{
- Create(Handle, AntialiasingLevel);
+ Create(Handle, Params);
}
@@ -82,33 +87,47 @@ RenderWindow::~RenderWindow()
////////////////////////////////////////////////////////////
void RenderWindow::Draw(const Drawable& Object) const
{
- // Set our window as the current target for rendering
- if (SetCurrent())
+ // Check whether we are called from the outside or from a previous call to Draw
+ if (!myIsDrawing)
{
- // Save the current render states and set the SFML ones
- if (!myOptimizeStates)
+ myIsDrawing = true;
+
+ // Set our window as the current target for rendering
+ if (SetActive())
{
- static const GLbitfield States = GL_COLOR_BUFFER_BIT | GL_CURRENT_BIT | GL_ENABLE_BIT |
- GL_TEXTURE_BIT | GL_TRANSFORM_BIT | GL_VIEWPORT_BIT;
- GLCheck(glPushAttrib(States));
- SetRenderStates();
+ // Save the current render states and set the SFML ones
+ if (myPreserveStates)
+ {
+ GLCheck(glMatrixMode(GL_MODELVIEW)); GLCheck(glPushMatrix());
+ GLCheck(glMatrixMode(GL_PROJECTION)); GLCheck(glPushMatrix());
+ GLCheck(glPushAttrib(GL_COLOR_BUFFER_BIT | GL_CURRENT_BIT | GL_ENABLE_BIT |
+ GL_TEXTURE_BIT | GL_TRANSFORM_BIT | GL_VIEWPORT_BIT));
+ SetRenderStates();
+ }
+
+ // Set the window viewport and transform matrices
+ GLCheck(glViewport(0, 0, GetWidth(), GetHeight()));
+ GLCheck(glMatrixMode(GL_PROJECTION)); GLCheck(glLoadMatrixf(myCurrentView->GetMatrix().Get4x4Elements()));
+ GLCheck(glMatrixMode(GL_MODELVIEW)); GLCheck(glLoadIdentity());
+
+ // Let the object draw itself
+ Object.Draw(*this);
+
+ // Restore render states
+ if (myPreserveStates)
+ {
+ GLCheck(glMatrixMode(GL_PROJECTION)); GLCheck(glPopMatrix());
+ GLCheck(glMatrixMode(GL_MODELVIEW)); GLCheck(glPopMatrix());
+ GLCheck(glPopAttrib());
+ }
}
- // Set the projection matrix corresponding to the current view
- GLCheck(glMatrixMode(GL_PROJECTION));
- GLCheck(glPushMatrix());
- GLCheck(glLoadMatrixf(myCurrentProjection));
-
- // Let the object draw itself
+ myIsDrawing = false;
+ }
+ else
+ {
+ // We are already called from a previous Draw : we don't need to set the states again, just draw the object
Object.Draw(*this);
-
- // Restore the previous projection matrix
- GLCheck(glMatrixMode(GL_PROJECTION));
- GLCheck(glPopMatrix());
-
- // Restore render states
- if (!myOptimizeStates)
- GLCheck(glPopAttrib());
}
}
@@ -123,14 +142,20 @@ Image RenderWindow::Capture() const
const unsigned int Height = GetHeight();
// Set our window as the current target for rendering
- if (SetCurrent())
+ if (SetActive())
{
// Get pixels from the backbuffer
- std::vector<Uint8> Pixels(Width * Height);
- glReadPixels(0, 0, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, &Pixels[0]);
+ std::vector<Uint8> Pixels(Width * Height * 4);
+ Uint8* PixelsPtr = &Pixels[0];
+ GLCheck(glReadPixels(0, 0, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, PixelsPtr));
+
+ // Flip the pixels
+ unsigned int Pitch = Width * 4;
+ for (unsigned int y = 0; y < Height / 2; ++y)
+ std::swap_ranges(PixelsPtr + y * Pitch, PixelsPtr + (y + 1) * Pitch, PixelsPtr + (Height - y - 1) * Pitch);
- // Create an image from it and return it
- return Image(Width, Height, &Pixels[0]);
+ // Create an image from the pixel buffer and return it
+ return Image(Width, Height, PixelsPtr);
}
else
{
@@ -151,54 +176,59 @@ void RenderWindow::SetBackgroundColor(const Color& Col)
////////////////////////////////////////////////////////////
/// Change the current active view
////////////////////////////////////////////////////////////
-void RenderWindow::SetView(const View* NewView)
+void RenderWindow::SetView(const View& NewView)
{
- // Set our window as the current target for rendering
- if (SetCurrent())
- {
- // If a null pointer is passed, switch to default view
- if (NewView == NULL)
- NewView = &myDefaultView;
-
- // Compute the view rectangle coordinates
- float X = NewView->Rect.Left + NewView->Rect.GetWidth() / 2;
- float Y = NewView->Rect.Top + NewView->Rect.GetHeight() / 2;
- float HalfWidth = NewView->Rect.GetWidth() / (2 * NewView->Zoom);
- float HalfHeight = NewView->Rect.GetHeight() / (2 * NewView->Zoom);
-
- // Store the view rectangle for optimization purpose
- myCurrentRect.Left = std::min(X - HalfWidth, X + HalfWidth);
- myCurrentRect.Top = std::min(Y - HalfHeight, Y + HalfHeight);
- myCurrentRect.Right = std::max(X - HalfWidth, X + HalfWidth);
- myCurrentRect.Bottom = std::max(Y - HalfHeight, Y + HalfHeight);
-
- // Update the projection matrix according to the new view, and save it
- GLCheck(glMatrixMode(GL_PROJECTION));
- GLCheck(glPushMatrix());
- GLCheck(glLoadIdentity());
- GLCheck(glOrtho(X - HalfWidth, X + HalfWidth, Y + HalfHeight, Y - HalfHeight, -1, 1));
- GLCheck(glGetFloatv(GL_PROJECTION_MATRIX, myCurrentProjection));
- GLCheck(glPopMatrix());
- }
+ myCurrentView = &NewView;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Get the current view
+////////////////////////////////////////////////////////////
+const View& RenderWindow::GetView() const
+{
+ return *myCurrentView;
}
////////////////////////////////////////////////////////////
-/// Get current view rectangle
+/// Get the default view of the window for read / write
////////////////////////////////////////////////////////////
-const FloatRect& RenderWindow::GetViewRect() const
+View& RenderWindow::GetDefaultView()
{
- return myCurrentRect;
+ return myDefaultView;
}
////////////////////////////////////////////////////////////
-/// Tell SFML to optimize its calls to the graphics driver,
-/// in case the user is not doing custom OpenGL calls
+/// Convert a point in window coordinates into view coordinates
////////////////////////////////////////////////////////////
-void RenderWindow::OptimizeForNonOpenGL(bool Optimize)
+sf::Vector2f RenderWindow::ConvertCoords(unsigned int WindowX, unsigned int WindowY, const View* TargetView) const
{
- myOptimizeStates = Optimize;
+ // Use the current view if none has been passed
+ if (!TargetView)
+ TargetView = myCurrentView;
+
+ float Left = TargetView->GetCenter().x - TargetView->GetHalfSize().x;
+ float Top = TargetView->GetCenter().y - TargetView->GetHalfSize().y;
+ float Right = TargetView->GetCenter().x + TargetView->GetHalfSize().x;
+ float Bottom = TargetView->GetCenter().y + TargetView->GetHalfSize().y;
+
+ return sf::Vector2f(Left + WindowX * (Right - Left) / GetWidth(),
+ Top + WindowY * (Bottom - Top) / GetHeight());
+}
+
+////////////////////////////////////////////////////////////
+/// 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
+////////////////////////////////////////////////////////////
+void RenderWindow::PreserveOpenGLStates(bool Preserve)
+{
+ myPreserveStates = Preserve;
}
@@ -207,13 +237,12 @@ void RenderWindow::OptimizeForNonOpenGL(bool Optimize)
////////////////////////////////////////////////////////////
void RenderWindow::OnCreate()
{
- // Set default OpenGL states
+ // Set the default rendering states
SetRenderStates();
// Setup the default view
- myDefaultView.Rect = FloatRect(0, 0, static_cast<float>(GetWidth()), static_cast<float>(GetHeight()));
- myDefaultView.Zoom = 1.f;
- SetView(NULL);
+ myDefaultView.SetFromRect(FloatRect(0, 0, static_cast<float>(GetWidth()), static_cast<float>(GetHeight())));
+ SetView(myDefaultView);
}
@@ -222,31 +251,12 @@ void RenderWindow::OnCreate()
////////////////////////////////////////////////////////////
void RenderWindow::OnDisplay()
{
- // Find which buffers we must clear
- GLbitfield ClearBits = GL_COLOR_BUFFER_BIT;
- if (GetDepthBits() > 0) ClearBits |= GL_DEPTH_BUFFER_BIT;
- if (GetStencilBits() > 0) ClearBits |= GL_STENCIL_BUFFER_BIT;
-
- // Clear the color/depth/stencil buffers for next frame
+ // Clear the frame buffer with the background color, for next frame
GLCheck(glClearColor(myBackgroundColor.r / 255.f,
myBackgroundColor.g / 255.f,
myBackgroundColor.b / 255.f,
myBackgroundColor.a / 255.f));
- GLCheck(glClear(ClearBits));
-}
-
-
-////////////////////////////////////////////////////////////
-/// Called after an event has been received
-////////////////////////////////////////////////////////////
-void RenderWindow::OnEventReceived(const Event& EventReceived)
-{
- // Adjust the viewport when the window is resized
- if (EventReceived.Type == Event::Resized)
- {
- if (SetCurrent())
- GLCheck(glViewport(0, 0, EventReceived.Size.Width, EventReceived.Size.Height));
- }
+ GLCheck(glClear(GL_COLOR_BUFFER_BIT));
}
@@ -255,13 +265,9 @@ void RenderWindow::OnEventReceived(const Event& EventReceived)
////////////////////////////////////////////////////////////
void RenderWindow::SetRenderStates() const
{
- GLCheck(glAlphaFunc(GL_GREATER, 0));
- GLCheck(glDisable(GL_LIGHTING));
+ GLCheck(glDisable(GL_ALPHA_TEST));
GLCheck(glDisable(GL_DEPTH_TEST));
- GLCheck(glDisable(GL_CULL_FACE));
- GLCheck(glShadeModel(GL_SMOOTH));
- GLCheck(glClearDepth(1.f));
- GLCheck(glClearStencil(0));
+ GLCheck(glDisable(GL_LIGHTING));
}
} // namespace sf