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

@ -179,7 +179,8 @@ EXPORTS
sfRenderImage_SetView sfRenderImage_SetView
sfRenderImage_GetView sfRenderImage_GetView
sfRenderImage_GetDefaultView sfRenderImage_GetDefaultView
sfRenderImage_PreserveOpenGLStates sfRenderImage_GetViewport
sfRenderImage_ConvertCoords
sfRenderImage_GetImage sfRenderImage_GetImage
sfRenderImage_CanUseRenderImage sfRenderImage_CanUseRenderImage
sfRenderWindow_Create sfRenderWindow_Create
@ -214,8 +215,8 @@ EXPORTS
sfRenderWindow_SetView sfRenderWindow_SetView
sfRenderWindow_GetView sfRenderWindow_GetView
sfRenderWindow_GetDefaultView sfRenderWindow_GetDefaultView
sfRenderWindow_GetViewport
sfRenderWindow_ConvertCoords sfRenderWindow_ConvertCoords
sfRenderWindow_PreserveOpenGLStates
sfView_Create sfView_Create
sfView_CreateFromRect sfView_CreateFromRect
sfView_Destroy sfView_Destroy

View File

@ -134,18 +134,28 @@ CSFML_API const sfView* sfRenderImage_GetView(sfRenderImage* renderImage);
CSFML_API sfView* sfRenderImage_GetDefaultView(sfRenderImage* renderImage); CSFML_API sfView* sfRenderImage_GetDefaultView(sfRenderImage* renderImage);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Tell SFML to preserve external OpenGL states, at the expense of /// Get the viewport of a view applied to this target
/// 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
/// ///
/// \param renderImage : Target renderimage /// \param renderImage : Renderimage object
/// \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
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
CSFML_API void sfRenderImage_PreserveOpenGLStates(sfRenderImage* renderImage, sfBool preserve); CSFML_API sfIntRect sfRenderImage_GetViewport(sfRenderImage* renderImage, sfView* view);
////////////////////////////////////////////////////////////
/// Convert a point in image coordinates into view coordinates
///
/// \param renderImage : Renderimage object
/// \param windowX : X coordinate of the point to convert, relative to the image
/// \param windowY : Y coordinate of the point to convert, relative to the image
/// \param viewX : Pointer to fill with the X coordinate of the converted point
/// \param viewY : Pointer to fill with the Y coordinate of the converted point
/// \param targetView : Target view to convert the point to (pass NULL to use the current view)
///
////////////////////////////////////////////////////////////
CSFML_API void sfRenderImage_ConvertCoords(sfRenderImage* renderImage, unsigned int windowX, unsigned int windowY, float* viewX, float* viewY, sfView* targetView);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Get the target image /// Get the target image

View File

@ -320,6 +320,17 @@ CSFML_API const sfView* sfRenderWindow_GetView(sfRenderWindow* renderWindow);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
CSFML_API sfView* sfRenderWindow_GetDefaultView(sfRenderWindow* renderWindow); CSFML_API sfView* sfRenderWindow_GetDefaultView(sfRenderWindow* renderWindow);
////////////////////////////////////////////////////////////
/// Get the viewport of a view applied to this target
///
/// \param renderWindow : Renderwindow
/// \param view : Target view
///
/// \return Viewport rectangle, expressed in pixels in the current target
///
////////////////////////////////////////////////////////////
CSFML_API sfIntRect sfRenderWindow_GetViewport(sfRenderWindow* renderWindow, sfView* view);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Convert a point in window coordinates into view coordinates /// Convert a point in window coordinates into view coordinates
/// ///
@ -333,19 +344,5 @@ CSFML_API sfView* sfRenderWindow_GetDefaultView(sfRenderWindow* renderWindow);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
CSFML_API void sfRenderWindow_ConvertCoords(sfRenderWindow* renderWindow, unsigned int windowX, unsigned int windowY, float* viewX, float* viewY, sfView* targetView); CSFML_API void sfRenderWindow_ConvertCoords(sfRenderWindow* renderWindow, unsigned int windowX, unsigned int windowY, float* viewX, float* viewY, sfView* targetView);
////////////////////////////////////////////////////////////
/// 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
///
/// \param renderWindow : Target Renderwindow
/// \param preserve : True to preserve OpenGL states, false to let SFML optimize
///
////////////////////////////////////////////////////////////
CSFML_API void sfRenderWindow_PreserveOpenGLStates(sfRenderWindow* renderWindow, sfBool preserve);
#endif // SFML_RENDERWINDOW_H #endif // SFML_RENDERWINDOW_H

View File

@ -157,16 +157,39 @@ sfView* sfRenderImage_GetDefaultView(sfRenderImage* renderImage)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Tell SFML to preserve external OpenGL states, at the expense of /// Get the viewport of a view applied to this target
/// 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 sfRenderImage_PreserveOpenGLStates(sfRenderImage* renderImage, sfBool preserve) sfIntRect sfRenderImage_GetViewport(sfRenderImage* renderImage, sfView* view)
{ {
CSFML_CALL(renderImage, PreserveOpenGLStates(preserve == sfTrue)); sfIntRect rect = {0, 0, 0, 0};
CSFML_CHECK_RETURN(view, rect);
CSFML_CHECK_RETURN(renderImage, rect);
sf::IntRect SFMLrect = renderImage->This.GetViewport(*view->This);
rect.Left = SFMLrect.Left;
rect.Top = SFMLrect.Top;
rect.Right = SFMLrect.Right;
rect.Bottom = SFMLrect.Bottom;
return rect;
}
////////////////////////////////////////////////////////////
/// Convert a point in image coordinates into view coordinates
////////////////////////////////////////////////////////////
void sfRenderImage_ConvertCoords(sfRenderImage* renderImage, unsigned int imageX, unsigned int imageY, float* viewX, float* viewY, sfView* targetView)
{
CSFML_CHECK(renderImage);
sf::Vector2f point;
if (targetView)
point = renderImage->This.ConvertCoords(imageX, imageY, *targetView->This);
else
point = renderImage->This.ConvertCoords(imageX, imageY);
if (viewX) *viewX = point.x;
if (viewY) *viewY = point.y;
} }

View File

@ -38,98 +38,98 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Construct a new renderwindow /// Construct a new renderwindow
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
sfRenderWindow* sfRenderWindow_Create(sfVideoMode Mode, const char* Title, unsigned long Style, sfContextSettings Params) sfRenderWindow* sfRenderWindow_Create(sfVideoMode mode, const char* title, unsigned long style, sfContextSettings params)
{ {
// Convert video mode // Convert video mode
sf::VideoMode VideoMode(Mode.Width, Mode.Height, Mode.BitsPerPixel); sf::VideoMode videoMode(mode.Width, mode.Height, mode.BitsPerPixel);
// Create the window // Create the window
sfRenderWindow* RenderWindow = new sfRenderWindow; sfRenderWindow* renderWindow = new sfRenderWindow;
sf::ContextSettings Settings(Params.DepthBits, Params.StencilBits, Params.AntialiasingLevel); sf::ContextSettings settings(params.DepthBits, params.StencilBits, params.AntialiasingLevel);
RenderWindow->This.Create(VideoMode, Title, Style, Settings); renderWindow->This.Create(videoMode, title, style, settings);
RenderWindow->Input.This = &RenderWindow->This.GetInput(); renderWindow->Input.This = &renderWindow->This.GetInput();
RenderWindow->DefaultView = new sfView(const_cast<sf::View*>(&RenderWindow->This.GetDefaultView())); renderWindow->DefaultView = new sfView(const_cast<sf::View*>(&renderWindow->This.GetDefaultView()));
RenderWindow->CurrentView = RenderWindow->DefaultView; renderWindow->CurrentView = renderWindow->DefaultView;
return RenderWindow; return renderWindow;
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Construct a renderwindow from an existing control /// Construct a renderwindow from an existing control
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
sfRenderWindow* sfRenderWindow_CreateFromHandle(sfWindowHandle Handle, sfContextSettings Params) sfRenderWindow* sfRenderWindow_CreateFromHandle(sfWindowHandle handle, sfContextSettings params)
{ {
sfRenderWindow* RenderWindow = new sfRenderWindow; sfRenderWindow* renderWindow = new sfRenderWindow;
sf::ContextSettings Settings(Params.DepthBits, Params.StencilBits, Params.AntialiasingLevel); sf::ContextSettings settings(params.DepthBits, params.StencilBits, params.AntialiasingLevel);
RenderWindow->This.Create(Handle, Settings); renderWindow->This.Create(handle, settings);
RenderWindow->Input.This = &RenderWindow->This.GetInput(); renderWindow->Input.This = &renderWindow->This.GetInput();
RenderWindow->DefaultView = new sfView(const_cast<sf::View*>(&RenderWindow->This.GetDefaultView())); renderWindow->DefaultView = new sfView(const_cast<sf::View*>(&renderWindow->This.GetDefaultView()));
RenderWindow->CurrentView = RenderWindow->DefaultView; renderWindow->CurrentView = renderWindow->DefaultView;
return RenderWindow; return renderWindow;
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Destroy an existing renderwindow /// Destroy an existing renderwindow
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void sfRenderWindow_Destroy(sfRenderWindow* RenderWindow) void sfRenderWindow_Destroy(sfRenderWindow* renderWindow)
{ {
delete RenderWindow->DefaultView; delete renderWindow->DefaultView;
delete RenderWindow; delete renderWindow;
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Close a renderwindow (but doesn't destroy the internal data) /// Close a renderwindow (but doesn't destroy the internal data)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void sfRenderWindow_Close(sfRenderWindow* RenderWindow) void sfRenderWindow_Close(sfRenderWindow* renderWindow)
{ {
CSFML_CALL(RenderWindow, Close()); CSFML_CALL(renderWindow, Close());
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Tell whether or not a renderwindow is opened /// Tell whether or not a renderwindow is opened
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
sfBool sfRenderWindow_IsOpened(sfRenderWindow* RenderWindow) sfBool sfRenderWindow_IsOpened(sfRenderWindow* renderWindow)
{ {
CSFML_CALL_RETURN(RenderWindow, IsOpened(), sfFalse); CSFML_CALL_RETURN(renderWindow, IsOpened(), sfFalse);
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Get the width of the rendering region of a window /// Get the width of the rendering region of a window
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
unsigned int sfRenderWindow_GetWidth(sfRenderWindow* RenderWindow) unsigned int sfRenderWindow_GetWidth(sfRenderWindow* renderWindow)
{ {
CSFML_CALL_RETURN(RenderWindow, GetWidth(), 0); CSFML_CALL_RETURN(renderWindow, GetWidth(), 0);
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Get the height of the rendering region of a window /// Get the height of the rendering region of a window
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
unsigned int sfRenderWindow_GetHeight(sfRenderWindow* RenderWindow) unsigned int sfRenderWindow_GetHeight(sfRenderWindow* renderWindow)
{ {
CSFML_CALL_RETURN(RenderWindow, GetHeight(), 0); CSFML_CALL_RETURN(renderWindow, GetHeight(), 0);
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Get the creation settings of a window /// Get the creation settings of a window
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
sfContextSettings sfRenderWindow_GetSettings(sfRenderWindow* RenderWindow) sfContextSettings sfRenderWindow_GetSettings(sfRenderWindow* renderWindow)
{ {
sfContextSettings Settings = {0, 0, 0}; sfContextSettings settings = {0, 0, 0};
CSFML_CHECK_RETURN(RenderWindow, Settings); CSFML_CHECK_RETURN(renderWindow, settings);
const sf::ContextSettings& Params = RenderWindow->This.GetSettings(); const sf::ContextSettings& params = renderWindow->This.GetSettings();
Settings.DepthBits = Params.DepthBits; settings.DepthBits = params.DepthBits;
Settings.StencilBits = Params.StencilBits; settings.StencilBits = params.StencilBits;
Settings.AntialiasingLevel = Params.AntialiasingLevel; settings.AntialiasingLevel = params.AntialiasingLevel;
return Settings; return settings;
} }
@ -137,68 +137,68 @@ sfContextSettings sfRenderWindow_GetSettings(sfRenderWindow* RenderWindow)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Get the event on top of events stack of a window, if any, and pop it /// Get the event on top of events stack of a window, if any, and pop it
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
sfBool sfRenderWindow_GetEvent(sfRenderWindow* RenderWindow, sfEvent* Event) sfBool sfRenderWindow_GetEvent(sfRenderWindow* renderWindow, sfEvent* event)
{ {
CSFML_CHECK_RETURN(RenderWindow, sfFalse); CSFML_CHECK_RETURN(renderWindow, sfFalse);
CSFML_CHECK_RETURN(Event, sfFalse); CSFML_CHECK_RETURN(event, sfFalse);
// Get the event // Get the event
sf::Event SFMLEvent; sf::Event SFMLEvent;
sfBool Ret = RenderWindow->This.GetEvent(SFMLEvent); sfBool ret = renderWindow->This.GetEvent(SFMLEvent);
// No event, return // No event, return
if (!Ret) if (!ret)
return sfFalse; return sfFalse;
// Convert its type // Convert its type
Event->Type = static_cast<sfEventType>(SFMLEvent.Type); event->Type = static_cast<sfEventType>(SFMLEvent.Type);
// Fill its fields // Fill its fields
switch (Event->Type) switch (event->Type)
{ {
case sfEvtResized : case sfEvtResized :
Event->Size.Width = SFMLEvent.Size.Width; event->Size.Width = SFMLEvent.Size.Width;
Event->Size.Height = SFMLEvent.Size.Height; event->Size.Height = SFMLEvent.Size.Height;
break; break;
case sfEvtTextEntered : case sfEvtTextEntered :
Event->Text.Unicode = SFMLEvent.Text.Unicode; event->Text.Unicode = SFMLEvent.Text.Unicode;
break; break;
case sfEvtKeyReleased : case sfEvtKeyReleased :
case sfEvtKeyPressed : case sfEvtKeyPressed :
Event->Key.Code = static_cast<sfKeyCode>(SFMLEvent.Key.Code); event->Key.Code = static_cast<sfKeyCode>(SFMLEvent.Key.Code);
Event->Key.Alt = SFMLEvent.Key.Alt ? sfTrue : sfFalse; event->Key.Alt = SFMLEvent.Key.Alt ? sfTrue : sfFalse;
Event->Key.Control = SFMLEvent.Key.Control ? sfTrue : sfFalse; event->Key.Control = SFMLEvent.Key.Control ? sfTrue : sfFalse;
Event->Key.Shift = SFMLEvent.Key.Shift ? sfTrue : sfFalse; event->Key.Shift = SFMLEvent.Key.Shift ? sfTrue : sfFalse;
break; break;
case sfEvtMouseWheelMoved : case sfEvtMouseWheelMoved :
Event->MouseWheel.Delta = SFMLEvent.MouseWheel.Delta; event->MouseWheel.Delta = SFMLEvent.MouseWheel.Delta;
break; break;
case sfEvtMouseButtonPressed : case sfEvtMouseButtonPressed :
case sfEvtMouseButtonReleased : case sfEvtMouseButtonReleased :
Event->MouseButton.Button = static_cast<sfMouseButton>(SFMLEvent.MouseButton.Button); event->MouseButton.Button = static_cast<sfMouseButton>(SFMLEvent.MouseButton.Button);
Event->MouseButton.X = SFMLEvent.MouseButton.X; event->MouseButton.X = SFMLEvent.MouseButton.X;
Event->MouseButton.Y = SFMLEvent.MouseButton.Y; event->MouseButton.Y = SFMLEvent.MouseButton.Y;
break; break;
case sfEvtMouseMoved : case sfEvtMouseMoved :
Event->MouseMove.X = SFMLEvent.MouseMove.X; event->MouseMove.X = SFMLEvent.MouseMove.X;
Event->MouseMove.Y = SFMLEvent.MouseMove.Y; event->MouseMove.Y = SFMLEvent.MouseMove.Y;
break; break;
case sfEvtJoyButtonPressed : case sfEvtJoyButtonPressed :
case sfEvtJoyButtonReleased : case sfEvtJoyButtonReleased :
Event->JoyButton.JoystickId = SFMLEvent.JoyButton.JoystickId; event->JoyButton.JoystickId = SFMLEvent.JoyButton.JoystickId;
Event->JoyButton.Button = SFMLEvent.JoyButton.Button; event->JoyButton.Button = SFMLEvent.JoyButton.Button;
break; break;
case sfEvtJoyMoved : case sfEvtJoyMoved :
Event->JoyMove.JoystickId = SFMLEvent.JoyMove.JoystickId; event->JoyMove.JoystickId = SFMLEvent.JoyMove.JoystickId;
Event->JoyMove.Axis = static_cast<sfJoyAxis>(SFMLEvent.JoyMove.Axis); event->JoyMove.Axis = static_cast<sfJoyAxis>(SFMLEvent.JoyMove.Axis);
Event->JoyMove.Position = SFMLEvent.JoyMove.Position; event->JoyMove.Position = SFMLEvent.JoyMove.Position;
break; break;
default : default :
@ -212,27 +212,27 @@ sfBool sfRenderWindow_GetEvent(sfRenderWindow* RenderWindow, sfEvent* Event)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Enable / disable vertical synchronization on a window /// Enable / disable vertical synchronization on a window
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void sfRenderWindow_UseVerticalSync(sfRenderWindow* RenderWindow, sfBool Enabled) void sfRenderWindow_UseVerticalSync(sfRenderWindow* renderWindow, sfBool enabled)
{ {
CSFML_CALL(RenderWindow, UseVerticalSync(Enabled == sfTrue)); CSFML_CALL(renderWindow, UseVerticalSync(enabled == sfTrue));
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Show or hide the mouse cursor on a window /// Show or hide the mouse cursor on a window
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void sfRenderWindow_ShowMouseCursor(sfRenderWindow* RenderWindow, sfBool Show) void sfRenderWindow_ShowMouseCursor(sfRenderWindow* renderWindow, sfBool show)
{ {
CSFML_CALL(RenderWindow, ShowMouseCursor(Show == sfTrue)); CSFML_CALL(renderWindow, ShowMouseCursor(show == sfTrue));
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Change the position of the mouse cursor on a window /// Change the position of the mouse cursor on a window
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void sfRenderWindow_SetCursorPosition(sfRenderWindow* RenderWindow, unsigned int Left, unsigned int Top) void sfRenderWindow_SetCursorPosition(sfRenderWindow* renderWindow, unsigned int left, unsigned int top)
{ {
CSFML_CALL(RenderWindow, SetCursorPosition(Left, Top)); CSFML_CALL(renderWindow, SetCursorPosition(left, top));
} }
@ -240,27 +240,27 @@ void sfRenderWindow_SetCursorPosition(sfRenderWindow* RenderWindow, unsigned int
/// Change the position of a window on screen. /// Change the position of a window on screen.
/// Only works for top-level windows /// Only works for top-level windows
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void sfRenderWindow_SetPosition(sfRenderWindow* RenderWindow, int Left, int Top) void sfRenderWindow_SetPosition(sfRenderWindow* renderWindow, int left, int top)
{ {
CSFML_CALL(RenderWindow, SetPosition(Left, Top)); CSFML_CALL(renderWindow, SetPosition(left, top));
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Change the size of the rendering region of a window /// Change the size of the rendering region of a window
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void sfRenderWindow_SetSize(sfRenderWindow* RenderWindow, unsigned int Width, unsigned int Height) void sfRenderWindow_SetSize(sfRenderWindow* renderWindow, unsigned int width, unsigned int height)
{ {
CSFML_CALL(RenderWindow, SetSize(Width, Height)) CSFML_CALL(renderWindow, SetSize(width, height))
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Show or hide a window /// Show or hide a window
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void sfRenderWindow_Show(sfRenderWindow* RenderWindow, sfBool State) void sfRenderWindow_Show(sfRenderWindow* renderWindow, sfBool show)
{ {
CSFML_CALL(RenderWindow, Show(State == sfTrue)); CSFML_CALL(renderWindow, Show(show == sfTrue));
} }
@ -268,65 +268,65 @@ void sfRenderWindow_Show(sfRenderWindow* RenderWindow, sfBool State)
/// Enable or disable automatic key-repeat for keydown events. /// Enable or disable automatic key-repeat for keydown events.
/// Automatic key-repeat is enabled by default /// Automatic key-repeat is enabled by default
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void sfRenderWindow_EnableKeyRepeat(sfRenderWindow* RenderWindow, sfBool Enabled) void sfRenderWindow_EnableKeyRepeat(sfRenderWindow* renderWindow, sfBool enabled)
{ {
CSFML_CALL(RenderWindow, EnableKeyRepeat(Enabled == sfTrue)); CSFML_CALL(renderWindow, EnableKeyRepeat(enabled == sfTrue));
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Change the window's icon /// Change the window's icon
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void sfRenderWindow_SetIcon(sfRenderWindow* RenderWindow, unsigned int Width, unsigned int Height, sfUint8* Pixels) void sfRenderWindow_SetIcon(sfRenderWindow* renderWindow, unsigned int width, unsigned int height, sfUint8* pixels)
{ {
CSFML_CALL(RenderWindow, SetIcon(Width, Height, Pixels)) CSFML_CALL(renderWindow, SetIcon(width, height, pixels))
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Set a window as the current target for rendering /// Set a window as the current target for rendering
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
sfBool sfRenderWindow_SetActive(sfRenderWindow* RenderWindow, sfBool Active) sfBool sfRenderWindow_SetActive(sfRenderWindow* renderWindow, sfBool active)
{ {
CSFML_CALL_RETURN(RenderWindow, SetActive(Active == sfTrue), sfFalse) CSFML_CALL_RETURN(renderWindow, SetActive(active == sfTrue), sfFalse)
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Display a window on screen /// Display a window on screen
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void sfRenderWindow_Display(sfRenderWindow* RenderWindow) void sfRenderWindow_Display(sfRenderWindow* renderWindow)
{ {
CSFML_CALL(RenderWindow, Display()); CSFML_CALL(renderWindow, Display());
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Get the input manager of a window /// Get the input manager of a window
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
sfInput* sfRenderWindow_GetInput(sfRenderWindow* RenderWindow) sfInput* sfRenderWindow_GetInput(sfRenderWindow* renderWindow)
{ {
CSFML_CHECK_RETURN(RenderWindow, NULL); CSFML_CHECK_RETURN(renderWindow, NULL);
return &RenderWindow->Input; return &renderWindow->Input;
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Limit the framerate to a maximum fixed frequency for a window /// Limit the framerate to a maximum fixed frequency for a window
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void sfRenderWindow_SetFramerateLimit(sfRenderWindow* RenderWindow, unsigned int Limit) void sfRenderWindow_SetFramerateLimit(sfRenderWindow* renderWindow, unsigned int limit)
{ {
CSFML_CALL(RenderWindow, SetFramerateLimit(Limit)); CSFML_CALL(renderWindow, SetFramerateLimit(limit));
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Get time elapsed since last frame of a window /// Get time elapsed since last frame of a window
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
float sfRenderWindow_GetFrameTime(sfRenderWindow* RenderWindow) float sfRenderWindow_GetFrameTime(sfRenderWindow* renderWindow)
{ {
CSFML_CALL_RETURN(RenderWindow, GetFrameTime(), 0.f); CSFML_CALL_RETURN(renderWindow, GetFrameTime(), 0.f);
} }
@ -334,121 +334,126 @@ float sfRenderWindow_GetFrameTime(sfRenderWindow* RenderWindow)
/// Change the joystick threshold, ie. the value below which /// Change the joystick threshold, ie. the value below which
/// no move event will be generated /// no move event will be generated
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void sfRenderWindow_SetJoystickThreshold(sfRenderWindow* RenderWindow, float Threshold) void sfRenderWindow_SetJoystickThreshold(sfRenderWindow* renderWindow, float threshold)
{ {
CSFML_CALL(RenderWindow, SetJoystickThreshold(Threshold)); CSFML_CALL(renderWindow, SetJoystickThreshold(threshold));
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Draw something on a renderwindow /// Draw something on a renderwindow
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void sfRenderWindow_DrawPostFX(sfRenderWindow* RenderWindow, sfPostFX* PostFX) void sfRenderWindow_DrawPostFX(sfRenderWindow* renderWindow, sfPostFX* postFX)
{ {
CSFML_CHECK(PostFX); CSFML_CHECK(postFX);
CSFML_CALL(RenderWindow, Draw(PostFX->This)); CSFML_CALL(renderWindow, Draw(postFX->This));
} }
void sfRenderWindow_DrawShape(sfRenderWindow* RenderWindow, sfShape* Shape) void sfRenderWindow_DrawShape(sfRenderWindow* renderWindow, sfShape* shape)
{ {
CSFML_CHECK(Shape); CSFML_CHECK(shape);
CSFML_CALL(RenderWindow, Draw(Shape->This)); CSFML_CALL(renderWindow, Draw(shape->This));
} }
void sfRenderWindow_DrawSprite(sfRenderWindow* RenderWindow, sfSprite* Sprite) void sfRenderWindow_DrawSprite(sfRenderWindow* renderWindow, sfSprite* sprite)
{ {
CSFML_CHECK(Sprite); CSFML_CHECK(sprite);
CSFML_CALL(RenderWindow, Draw(Sprite->This)); CSFML_CALL(renderWindow, Draw(sprite->This));
} }
void sfRenderWindow_DrawString(sfRenderWindow* RenderWindow, sfString* String) void sfRenderWindow_DrawString(sfRenderWindow* renderWindow, sfString* string)
{ {
CSFML_CHECK(String); CSFML_CHECK(string);
CSFML_CALL(RenderWindow, Draw(String->This)); CSFML_CALL(renderWindow, Draw(string->This));
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Save the content of a renderwindow to an image /// Save the content of a renderwindow to an image
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
sfImage* sfRenderWindow_Capture(sfRenderWindow* RenderWindow) sfImage* sfRenderWindow_Capture(sfRenderWindow* renderWindow)
{ {
CSFML_CHECK_RETURN(RenderWindow, NULL); CSFML_CHECK_RETURN(renderWindow, NULL);
sfImage* Image = new sfImage; sfImage* image = new sfImage;
*Image->This = RenderWindow->This.Capture(); *image->This = renderWindow->This.Capture();
return Image; return image;
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Clear the screen with the given color /// Clear the screen with the given color
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void sfRenderWindow_Clear(sfRenderWindow* RenderWindow, sfColor Color) void sfRenderWindow_Clear(sfRenderWindow* renderWindow, sfColor color)
{ {
sf::Color SFMLColor(Color.r, Color.g, Color.b, Color.a); sf::Color SFMLColor(color.r, color.g, color.b, color.a);
CSFML_CALL(RenderWindow, Clear(SFMLColor)); CSFML_CALL(renderWindow, Clear(SFMLColor));
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Change the current active view of a renderwindow /// Change the current active view of a renderwindow
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void sfRenderWindow_SetView(sfRenderWindow* RenderWindow, sfView* View) void sfRenderWindow_SetView(sfRenderWindow* renderWindow, sfView* view)
{ {
CSFML_CHECK(View); CSFML_CHECK(view);
CSFML_CALL(RenderWindow, SetView(*View->This)); CSFML_CALL(renderWindow, SetView(*view->This));
RenderWindow->CurrentView = View; renderWindow->CurrentView = view;
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Get the current active view of a renderwindow /// Get the current active view of a renderwindow
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
const sfView* sfRenderWindow_GetView(sfRenderWindow* RenderWindow) const sfView* sfRenderWindow_GetView(sfRenderWindow* renderWindow)
{ {
CSFML_CHECK_RETURN(RenderWindow, NULL); CSFML_CHECK_RETURN(renderWindow, NULL);
return RenderWindow->CurrentView; return renderWindow->CurrentView;
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Get the default view of a renderwindow /// Get the default view of a renderwindow
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
sfView* sfRenderWindow_GetDefaultView(sfRenderWindow* RenderWindow) sfView* sfRenderWindow_GetDefaultView(sfRenderWindow* renderWindow)
{ {
CSFML_CHECK_RETURN(RenderWindow, NULL); CSFML_CHECK_RETURN(renderWindow, NULL);
return RenderWindow->DefaultView; return renderWindow->DefaultView;
}
////////////////////////////////////////////////////////////
/// Get the viewport of a view applied to this target
////////////////////////////////////////////////////////////
sfIntRect sfRenderWindow_GetViewport(sfRenderWindow* renderWindow, sfView* view)
{
sfIntRect rect = {0, 0, 0, 0};
CSFML_CHECK_RETURN(view, rect);
CSFML_CHECK_RETURN(renderWindow, rect);
sf::IntRect SFMLrect = renderWindow->This.GetViewport(*view->This);
rect.Left = SFMLrect.Left;
rect.Top = SFMLrect.Top;
rect.Right = SFMLrect.Right;
rect.Bottom = SFMLrect.Bottom;
return rect;
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Convert a point in window coordinates into view coordinates /// Convert a point in window coordinates into view coordinates
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void sfRenderWindow_ConvertCoords(sfRenderWindow* RenderWindow, unsigned int WindowX, unsigned int WindowY, float* ViewX, float* ViewY, sfView* TargetView) void sfRenderWindow_ConvertCoords(sfRenderWindow* renderWindow, unsigned int windowX, unsigned int windowY, float* viewX, float* viewY, sfView* targetView)
{ {
CSFML_CHECK(RenderWindow); CSFML_CHECK(renderWindow);
sf::Vector2f Point; sf::Vector2f point;
if (TargetView) if (targetView)
Point = RenderWindow->This.ConvertCoords(WindowX, WindowY, *TargetView->This); point = renderWindow->This.ConvertCoords(windowX, windowY, *targetView->This);
else else
Point = RenderWindow->This.ConvertCoords(WindowX, WindowY); point = renderWindow->This.ConvertCoords(windowX, windowY);
if (ViewX) *ViewX = Point.x; if (viewX) *viewX = point.x;
if (ViewY) *ViewY = Point.y; if (viewY) *viewY = point.y;
}
////////////////////////////////////////////////////////////
/// 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 sfRenderWindow_PreserveOpenGLStates(sfRenderWindow* RenderWindow, sfBool Preserve)
{
CSFML_CALL(RenderWindow, PreserveOpenGLStates(Preserve == sfTrue));
} }

View File

@ -128,12 +128,15 @@
<Unit filename="..\..\include\SFML\Graphics\Rect.hpp" /> <Unit filename="..\..\include\SFML\Graphics\Rect.hpp" />
<Unit filename="..\..\include\SFML\Graphics\Rect.inl" /> <Unit filename="..\..\include\SFML\Graphics\Rect.inl" />
<Unit filename="..\..\include\SFML\Graphics\RenderImage.hpp" /> <Unit filename="..\..\include\SFML\Graphics\RenderImage.hpp" />
<Unit filename="..\..\include\SFML\Graphics\RenderQueue.hpp" />
<Unit filename="..\..\include\SFML\Graphics\RenderTarget.hpp" /> <Unit filename="..\..\include\SFML\Graphics\RenderTarget.hpp" />
<Unit filename="..\..\include\SFML\Graphics\RenderWindow.hpp" /> <Unit filename="..\..\include\SFML\Graphics\RenderWindow.hpp" />
<Unit filename="..\..\include\SFML\Graphics\Shape.hpp" /> <Unit filename="..\..\include\SFML\Graphics\Shape.hpp" />
<Unit filename="..\..\include\SFML\Graphics\Sprite.hpp" /> <Unit filename="..\..\include\SFML\Graphics\Sprite.hpp" />
<Unit filename="..\..\include\SFML\Graphics\String.hpp" /> <Unit filename="..\..\include\SFML\Graphics\String.hpp" />
<Unit filename="..\..\include\SFML\Graphics\View.hpp" /> <Unit filename="..\..\include\SFML\Graphics\View.hpp" />
<Unit filename="..\..\src\SFML\Graphics\Batch.cpp" />
<Unit filename="..\..\src\SFML\Graphics\Batch.hpp" />
<Unit filename="..\..\src\SFML\Graphics\Color.cpp" /> <Unit filename="..\..\src\SFML\Graphics\Color.cpp" />
<Unit filename="..\..\src\SFML\Graphics\Drawable.cpp" /> <Unit filename="..\..\src\SFML\Graphics\Drawable.cpp" />
<Unit filename="..\..\src\SFML\Graphics\Font.cpp" /> <Unit filename="..\..\src\SFML\Graphics\Font.cpp" />
@ -147,6 +150,14 @@
<Unit filename="..\..\src\SFML\Graphics\GLEW\glew.h" /> <Unit filename="..\..\src\SFML\Graphics\GLEW\glew.h" />
<Unit filename="..\..\src\SFML\Graphics\GLEW\glxew.h" /> <Unit filename="..\..\src\SFML\Graphics\GLEW\glxew.h" />
<Unit filename="..\..\src\SFML\Graphics\GLEW\wglew.h" /> <Unit filename="..\..\src\SFML\Graphics\GLEW\wglew.h" />
<Unit filename="..\..\src\SFML\Graphics\GeometryRenderer.cpp" />
<Unit filename="..\..\src\SFML\Graphics\GeometryRenderer.hpp" />
<Unit filename="..\..\src\SFML\Graphics\GeometryRendererIM.cpp" />
<Unit filename="..\..\src\SFML\Graphics\GeometryRendererIM.hpp" />
<Unit filename="..\..\src\SFML\Graphics\GeometryRendererVA.cpp" />
<Unit filename="..\..\src\SFML\Graphics\GeometryRendererVA.hpp" />
<Unit filename="..\..\src\SFML\Graphics\GeometryRendererVBO.cpp" />
<Unit filename="..\..\src\SFML\Graphics\GeometryRendererVBO.hpp" />
<Unit filename="..\..\src\SFML\Graphics\Image.cpp" /> <Unit filename="..\..\src\SFML\Graphics\Image.cpp" />
<Unit filename="..\..\src\SFML\Graphics\ImageLoader.cpp" /> <Unit filename="..\..\src\SFML\Graphics\ImageLoader.cpp" />
<Unit filename="..\..\src\SFML\Graphics\ImageLoader.hpp" /> <Unit filename="..\..\src\SFML\Graphics\ImageLoader.hpp" />
@ -159,6 +170,7 @@
<Unit filename="..\..\src\SFML\Graphics\RenderImageImplFBO.cpp" /> <Unit filename="..\..\src\SFML\Graphics\RenderImageImplFBO.cpp" />
<Unit filename="..\..\src\SFML\Graphics\RenderImageImplFBO.hpp" /> <Unit filename="..\..\src\SFML\Graphics\RenderImageImplFBO.hpp" />
<Unit filename="..\..\src\SFML\Graphics\RenderImageImplPBuffer.hpp" /> <Unit filename="..\..\src\SFML\Graphics\RenderImageImplPBuffer.hpp" />
<Unit filename="..\..\src\SFML\Graphics\RenderQueue.cpp" />
<Unit filename="..\..\src\SFML\Graphics\RenderTarget.cpp" /> <Unit filename="..\..\src\SFML\Graphics\RenderTarget.cpp" />
<Unit filename="..\..\src\SFML\Graphics\RenderWindow.cpp" /> <Unit filename="..\..\src\SFML\Graphics\RenderWindow.cpp" />
<Unit filename="..\..\src\SFML\Graphics\SOIL\SOIL.c"> <Unit filename="..\..\src\SFML\Graphics\SOIL\SOIL.c">

View File

@ -351,14 +351,6 @@
RelativePath="..\..\src\SFML\Audio\AudioDevice.hpp" RelativePath="..\..\src\SFML\Audio\AudioDevice.hpp"
> >
</File> </File>
<File
RelativePath="..\..\src\SFML\Audio\AudioResource.cpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Audio\AudioResource.hpp"
>
</File>
<File <File
RelativePath="..\..\src\SFML\Audio\Listener.cpp" RelativePath="..\..\src\SFML\Audio\Listener.cpp"
> >

View File

@ -362,18 +362,6 @@
<References> <References>
</References> </References>
<Files> <Files>
<Filter
Name="Win32"
>
<File
RelativePath="..\..\src\SFML\Graphics\Win32\RenderImageImplPBuffer.cpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\Win32\RenderImageImplPBuffer.hpp"
>
</File>
</Filter>
<Filter <Filter
Name="External libs" Name="External libs"
> >
@ -3298,6 +3286,138 @@
</File> </File>
</Filter> </Filter>
</Filter> </Filter>
<Filter
Name="Drawables"
>
<File
RelativePath="..\..\src\SFML\Graphics\Drawable.cpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Graphics\Drawable.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\Shape.cpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Graphics\Shape.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\Sprite.cpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Graphics\Sprite.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\String.cpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Graphics\String.hpp"
>
</File>
</Filter>
<Filter
Name="RenderImage"
>
<File
RelativePath="..\..\src\SFML\Graphics\RenderImage.cpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Graphics\RenderImage.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\RenderImageImpl.cpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\RenderImageImpl.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\RenderImageImplFBO.cpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\RenderImageImplFBO.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\RenderImageImplPBuffer.hpp"
>
</File>
<Filter
Name="Win32"
>
<File
RelativePath="..\..\src\SFML\Graphics\Win32\RenderImageImplPBuffer.cpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\Win32\RenderImageImplPBuffer.hpp"
>
</File>
</Filter>
</Filter>
<Filter
Name="RenderQueue"
>
<File
RelativePath="..\..\src\SFML\Graphics\Batch.cpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\Batch.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\GeometryRenderer.cpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\GeometryRenderer.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\GeometryRendererIM.cpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\GeometryRendererIM.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\GeometryRendererVA.cpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\GeometryRendererVA.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\GeometryRendererVBO.cpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\GeometryRendererVBO.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\RenderQueue.cpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Graphics\RenderQueue.hpp"
>
</File>
</Filter>
<File <File
RelativePath="..\..\src\SFML\Graphics\Color.cpp" RelativePath="..\..\src\SFML\Graphics\Color.cpp"
> >
@ -3306,14 +3426,6 @@
RelativePath="..\..\include\SFML\Graphics\Color.hpp" RelativePath="..\..\include\SFML\Graphics\Color.hpp"
> >
</File> </File>
<File
RelativePath="..\..\src\SFML\Graphics\Drawable.cpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Graphics\Drawable.hpp"
>
</File>
<File <File
RelativePath="..\..\src\SFML\Graphics\Font.cpp" RelativePath="..\..\src\SFML\Graphics\Font.cpp"
> >
@ -3418,34 +3530,6 @@
RelativePath="..\..\include\SFML\Graphics\Rect.inl" RelativePath="..\..\include\SFML\Graphics\Rect.inl"
> >
</File> </File>
<File
RelativePath="..\..\src\SFML\Graphics\RenderImage.cpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Graphics\RenderImage.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\RenderImageImpl.cpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\RenderImageImpl.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\RenderImageImplFBO.cpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\RenderImageImplFBO.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\RenderImageImplPBuffer.hpp"
>
</File>
<File <File
RelativePath="..\..\src\SFML\Graphics\RenderTarget.cpp" RelativePath="..\..\src\SFML\Graphics\RenderTarget.cpp"
> >
@ -3462,30 +3546,6 @@
RelativePath="..\..\include\SFML\Graphics\RenderWindow.hpp" RelativePath="..\..\include\SFML\Graphics\RenderWindow.hpp"
> >
</File> </File>
<File
RelativePath="..\..\src\SFML\Graphics\Shape.cpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Graphics\Shape.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\Sprite.cpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Graphics\Sprite.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\String.cpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Graphics\String.hpp"
>
</File>
<File <File
RelativePath="..\..\src\SFML\Graphics\View.cpp" RelativePath="..\..\src\SFML\Graphics\View.cpp"
> >

View File

@ -324,6 +324,7 @@
WarningLevel="4" WarningLevel="4"
DebugInformationFormat="0" DebugInformationFormat="0"
DisableSpecificWarnings="4996" DisableSpecificWarnings="4996"
EnablePREfast="false"
/> />
<Tool <Tool
Name="VCManagedResourceCompilerTool" Name="VCManagedResourceCompilerTool"
@ -361,14 +362,61 @@
</References> </References>
<Files> <Files>
<Filter <Filter
Name="Win32" Name="RenderQueue"
> >
<File <File
RelativePath="..\..\src\SFML\Graphics\Win32\RenderImageImplPBuffer.cpp" RelativePath="..\..\src\SFML\Graphics\Batch.cpp"
> >
</File> </File>
<File <File
RelativePath="..\..\src\SFML\Graphics\Win32\RenderImageImplPBuffer.hpp" RelativePath="..\..\src\SFML\Graphics\Batch.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\GeometryRenderer.cpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\GeometryRenderer.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\GeometryRendererIM.cpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\GeometryRendererIM.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\GeometryRendererVA.cpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\GeometryRendererVA.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\GeometryRendererVBO.cpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\GeometryRendererVBO.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\RenderQueue.cpp"
>
<FileConfiguration
Name="Release static|Win32"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\include\SFML\Graphics\RenderQueue.hpp"
> >
</File> </File>
</Filter> </Filter>
@ -3296,6 +3344,94 @@
</File> </File>
</Filter> </Filter>
</Filter> </Filter>
<Filter
Name="RenderImage"
>
<File
RelativePath="..\..\src\SFML\Graphics\RenderImage.cpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Graphics\RenderImage.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\RenderImageImpl.cpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\RenderImageImpl.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\RenderImageImplFBO.cpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\RenderImageImplFBO.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\RenderImageImplPBuffer.hpp"
>
</File>
<Filter
Name="Win32"
>
<File
RelativePath="..\..\src\SFML\Graphics\Win32\RenderImageImplPBuffer.cpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\Win32\RenderImageImplPBuffer.hpp"
>
</File>
</Filter>
</Filter>
<Filter
Name="Drawables"
>
<File
RelativePath="..\..\src\SFML\Graphics\Drawable.cpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Graphics\Drawable.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\PostFX.cpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Graphics\PostFX.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\Shape.cpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Graphics\Shape.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\Sprite.cpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Graphics\Sprite.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\String.cpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Graphics\String.hpp"
>
</File>
</Filter>
<File <File
RelativePath="..\..\src\SFML\Graphics\Color.cpp" RelativePath="..\..\src\SFML\Graphics\Color.cpp"
> >
@ -3304,14 +3440,6 @@
RelativePath="..\..\include\SFML\Graphics\Color.hpp" RelativePath="..\..\include\SFML\Graphics\Color.hpp"
> >
</File> </File>
<File
RelativePath="..\..\src\SFML\Graphics\Drawable.cpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Graphics\Drawable.hpp"
>
</File>
<File <File
RelativePath="..\..\src\SFML\Graphics\Font.cpp" RelativePath="..\..\src\SFML\Graphics\Font.cpp"
> >
@ -3400,14 +3528,6 @@
RelativePath="..\..\include\SFML\Graphics\Matrix3.inl" RelativePath="..\..\include\SFML\Graphics\Matrix3.inl"
> >
</File> </File>
<File
RelativePath="..\..\src\SFML\Graphics\PostFX.cpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Graphics\PostFX.hpp"
>
</File>
<File <File
RelativePath="..\..\include\SFML\Graphics\Rect.hpp" RelativePath="..\..\include\SFML\Graphics\Rect.hpp"
> >
@ -3416,34 +3536,6 @@
RelativePath="..\..\include\SFML\Graphics\Rect.inl" RelativePath="..\..\include\SFML\Graphics\Rect.inl"
> >
</File> </File>
<File
RelativePath="..\..\src\SFML\Graphics\RenderImage.cpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Graphics\RenderImage.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\RenderImageImpl.cpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\RenderImageImpl.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\RenderImageImplFBO.cpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\RenderImageImplFBO.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\RenderImageImplPBuffer.hpp"
>
</File>
<File <File
RelativePath="..\..\src\SFML\Graphics\RenderTarget.cpp" RelativePath="..\..\src\SFML\Graphics\RenderTarget.cpp"
> >
@ -3460,30 +3552,6 @@
RelativePath="..\..\include\SFML\Graphics\RenderWindow.hpp" RelativePath="..\..\include\SFML\Graphics\RenderWindow.hpp"
> >
</File> </File>
<File
RelativePath="..\..\src\SFML\Graphics\Shape.cpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Graphics\Shape.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\Sprite.cpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Graphics\Sprite.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\String.cpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Graphics\String.hpp"
>
</File>
<File <File
RelativePath="..\..\src\SFML\Graphics\View.cpp" RelativePath="..\..\src\SFML\Graphics\View.cpp"
> >

View File

@ -15,7 +15,6 @@ namespace sample_opengl
{ {
// Create main window // Create main window
RenderWindow window = new RenderWindow(new VideoMode(800, 600), "SFML.Net OpenGL"); RenderWindow window = new RenderWindow(new VideoMode(800, 600), "SFML.Net OpenGL");
window.PreserveOpenGLStates(true);
// Setup event handlers // Setup event handlers
window.Closed += new EventHandler(OnClosed); window.Closed += new EventHandler(OnClosed);

View File

@ -104,18 +104,48 @@ namespace SFML
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// <summary> /// <summary>
/// Tell SFML to preserve external OpenGL states, at the expense of /// Get the viewport of a view applied to this target
/// 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
/// </summary> /// </summary>
/// <param name="preserve">True to preserve OpenGL states, false to let SFML optimize</param> /// <param name="view">Target view</param>
/// <returns>Viewport rectangle, expressed in pixels in the current target</returns>
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
public void PreserveOpenGLStates(bool preserve) public IntRect GetViewport(View view)
{ {
sfRenderImage_PreserveOpenGLStates(This, preserve); return sfRenderImage_GetViewport(This, view.This);
}
////////////////////////////////////////////////////////////
/// <summary>
/// Convert a point in target coordinates into view coordinates
/// This version uses the current view of the window
/// </summary>
/// <param name="x">X coordinate of the point to convert, relative to the target</param>
/// <param name="y">Y coordinate of the point to convert, relative to the target</param>
/// <returns>Converted point</returns>
///
////////////////////////////////////////////////////////////
public Vector2 ConvertCoords(uint x, uint y)
{
return ConvertCoords(x, y, CurrentView);
}
////////////////////////////////////////////////////////////
/// <summary>
/// Convert a point in target coordinates into view coordinates
/// This version uses the given view
/// </summary>
/// <param name="x">X coordinate of the point to convert, relative to the target</param>
/// <param name="y">Y coordinate of the point to convert, relative to the target</param>
/// <param name="view">Target view to convert the point to</param>
/// <returns>Converted point</returns>
///
////////////////////////////////////////////////////////////
public Vector2 ConvertCoords(uint x, uint y, View view)
{
Vector2 point;
sfRenderImage_ConvertCoords(This, x, y, out point.X, out point.Y, view.This);
return point;
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -237,7 +267,10 @@ namespace SFML
static extern IntPtr sfRenderImage_GetDefaultView(IntPtr This); static extern IntPtr sfRenderImage_GetDefaultView(IntPtr This);
[DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity]
static extern void sfRenderImage_PreserveOpenGLStates(IntPtr This, bool Preserve); static extern IntRect sfRenderImage_GetViewport(IntPtr This, IntPtr TargetView);
[DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity]
static extern void sfRenderImage_ConvertCoords(IntPtr This, uint WindowX, uint WindowY, out float ViewX, out float ViewY, IntPtr TargetView);
[DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity]
static extern void sfRenderImage_DrawPostFX(IntPtr This, IntPtr PostFx); static extern void sfRenderImage_DrawPostFX(IntPtr This, IntPtr PostFx);

View File

@ -44,16 +44,37 @@ namespace SFML
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// <summary> /// <summary>
/// Tell SFML to preserve external OpenGL states, at the expense of /// Get the viewport of a view applied to this target
/// 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
/// </summary> /// </summary>
/// <param name="preserve">True to preserve OpenGL states, false to let SFML optimize</param> /// <param name="view">Target view</param>
/// <returns>Viewport rectangle, expressed in pixels in the current target</returns>
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void PreserveOpenGLStates(bool preserve); IntRect GetViewport(View view);
////////////////////////////////////////////////////////////
/// <summary>
/// Convert a point in target coordinates into view coordinates
/// This version uses the current view of the window
/// </summary>
/// <param name="x">X coordinate of the point to convert, relative to the target</param>
/// <param name="y">Y coordinate of the point to convert, relative to the target</param>
/// <returns>Converted point</returns>
///
////////////////////////////////////////////////////////////
Vector2 ConvertCoords(uint x, uint y);
////////////////////////////////////////////////////////////
/// <summary>
/// Convert a point in target coordinates into view coordinates
/// This version uses the given view
/// </summary>
/// <param name="x">X coordinate of the point to convert, relative to the target</param>
/// <param name="y">Y coordinate of the point to convert, relative to the target</param>
/// <param name="view">Target view to convert the point to</param>
/// <returns>Converted point</returns>
///
////////////////////////////////////////////////////////////
Vector2 ConvertCoords(uint x, uint y, View view);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// <summary> /// <summary>

View File

@ -317,49 +317,48 @@ namespace SFML
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// <summary> /// <summary>
/// Convert a point in window coordinates into view coordinates /// Get the viewport of a view applied to this target
/// using the current view of the window
/// </summary> /// </summary>
/// <param name="windowX">X coordinate of the point to convert, relative to the window</param> /// <param name="view">Target view</param>
/// <param name="windowY">Y coordinate of the point to convert, relative to the window</param> /// <returns>Viewport rectangle, expressed in pixels in the current target</returns>
/// <returns>Converted point</returns>
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
public Vector2 ConvertCoords(uint windowX, uint windowY) public IntRect GetViewport(View view)
{ {
return ConvertCoords(windowX, windowY, myCurrentView); return sfRenderWindow_GetViewport(This, view.This);
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// <summary> /// <summary>
/// Convert a point in window coordinates into view coordinates /// Convert a point in target coordinates into view coordinates
/// This version uses the current view of the window
/// </summary> /// </summary>
/// <param name="windowX">X coordinate of the point to convert, relative to the window</param> /// <param name="x">X coordinate of the point to convert, relative to the target</param>
/// <param name="windowY">Y coordinate of the point to convert, relative to the window</param> /// <param name="y">Y coordinate of the point to convert, relative to the target</param>
/// <param name="targetView">Target view to convert the point to</param>
/// <returns>Converted point</returns> /// <returns>Converted point</returns>
///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
public Vector2 ConvertCoords(uint windowX, uint windowY, View targetView) public Vector2 ConvertCoords(uint x, uint y)
{ {
Vector2 Point; return ConvertCoords(x, y, CurrentView);
sfRenderWindow_ConvertCoords(This, windowX, windowY, out Point.X, out Point.Y, targetView.This);
return Point;
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// <summary> /// <summary>
/// Tell SFML to preserve external OpenGL states, at the expense of /// Convert a point in target coordinates into view coordinates
/// more CPU charge. Use this function if you don't want SFML /// This version uses the given view
/// 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
/// </summary> /// </summary>
/// <param name="preserve">True to preserve OpenGL states, false to let SFML optimize</param> /// <param name="x">X coordinate of the point to convert, relative to the target</param>
/// <param name="y">Y coordinate of the point to convert, relative to the target</param>
/// <param name="view">Target view to convert the point to</param>
/// <returns>Converted point</returns>
///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
public void PreserveOpenGLStates(bool preserve) public Vector2 ConvertCoords(uint x, uint y, View view)
{ {
sfRenderWindow_PreserveOpenGLStates(This, preserve); Vector2 point;
sfRenderWindow_ConvertCoords(This, x, y, out point.X, out point.Y, view.This);
return point;
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -544,10 +543,10 @@ namespace SFML
static extern IntPtr sfRenderWindow_GetDefaultView(IntPtr This); static extern IntPtr sfRenderWindow_GetDefaultView(IntPtr This);
[DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity]
static extern void sfRenderWindow_ConvertCoords(IntPtr This, uint WindowX, uint WindowY, out float ViewX, out float ViewY, IntPtr TargetView); static extern IntRect sfRenderWindow_GetViewport(IntPtr This, IntPtr TargetView);
[DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity]
static extern void sfRenderWindow_PreserveOpenGLStates(IntPtr This, bool Preserve); static extern void sfRenderWindow_ConvertCoords(IntPtr This, uint WindowX, uint WindowY, out float ViewX, out float ViewY, IntPtr TargetView);
[DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity]
static extern void sfRenderWindow_DrawPostFX(IntPtr This, IntPtr PostFx); static extern void sfRenderWindow_DrawPostFX(IntPtr This, IntPtr PostFx);

View File

@ -25,6 +25,7 @@
#ifndef SFML_CONFIG_HPP #ifndef SFML_CONFIG_HPP
#define SFML_CONFIG_HPP #define SFML_CONFIG_HPP
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Identify the operating system // Identify the operating system
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -62,6 +63,23 @@
#endif #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 // Define a portable debug macro
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

View File

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

View File

@ -35,6 +35,7 @@
namespace sf namespace sf
{ {
class RenderQueue;
class RenderTarget; class RenderTarget;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -325,20 +326,22 @@ private :
friend class RenderTarget; 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 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 /// Render the specific geometry of the object
/// ///
/// \param target : Target into which render 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 // Member data

View File

@ -303,16 +303,6 @@ private :
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void EnsureArrayUpdate(); 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 /// Reset the image attributes
/// ///
@ -337,7 +327,6 @@ private :
std::vector<Color> myPixels; ///< Pixels of the image 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 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 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 bool myPixelsFlipped; ///< To work around the inconsistency in Y orientation
}; };

View File

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

View File

@ -65,7 +65,7 @@ public :
/// ///
/// \param width : Width of the render image /// \param width : Width of the render image
/// \param height : Height 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 /// \return True if creation has been successful
/// ///
@ -83,6 +83,12 @@ public :
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
bool SetActive(bool active = true); bool SetActive(bool active = true);
////////////////////////////////////////////////////////////
/// Update the contents of the target image
///
////////////////////////////////////////////////////////////
void Display();
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Get the width of the rendering region of the image /// Get the width of the rendering region of the image
/// ///
@ -117,26 +123,12 @@ public :
private : private :
friend class Image;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// /see RenderTarget::Activate /// /see RenderTarget::Activate
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
virtual bool Activate(bool active); 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 // 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 // Headers
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#include <SFML/Graphics/Color.hpp> #include <SFML/Graphics/Color.hpp>
#include <SFML/Graphics/View.hpp>
#include <SFML/Graphics/Rect.hpp> #include <SFML/Graphics/Rect.hpp>
#include <SFML/Graphics/RenderQueue.hpp>
#include <SFML/Graphics/View.hpp>
namespace sf namespace sf
@ -66,6 +67,22 @@ public :
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
virtual void Draw(const Drawable& object); 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 /// Get the width of the rendering region of the target
/// ///
@ -107,17 +124,39 @@ public :
View& GetDefaultView(); View& GetDefaultView();
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Tell SFML to preserve external OpenGL states, at the expense of /// Get the viewport of a view applied to this target
/// 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
/// ///
/// \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 : protected :
@ -145,19 +184,12 @@ private :
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
virtual bool Activate(bool active) = 0; virtual bool Activate(bool active) = 0;
////////////////////////////////////////////////////////////
/// Set the OpenGL render states needed for the SFML rendering
///
////////////////////////////////////////////////////////////
void SetRenderStates();
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Member data // Member data
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
View myDefaultView; ///< Default view RenderQueue myRenderQueue; ///< Rendering queue storing render commands
const View* myCurrentView; ///< Current active view View myDefaultView; ///< Default view
bool myPreserveStates; ///< Should we preserve external OpenGL states ? const View* myCurrentView; ///< Current active view
bool myIsDrawing; ///< True when Draw is called from inside, to allow some renderstates optimizations
}; };
} // namespace sf } // namespace sf

View File

@ -94,39 +94,6 @@ public :
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
virtual unsigned int GetHeight() const; 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 : private :
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -135,6 +102,12 @@ private :
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
virtual void OnCreate(); virtual void OnCreate();
////////////////////////////////////////////////////////////
/// /see Window::OnDisplay
///
////////////////////////////////////////////////////////////
virtual void OnDisplay();
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// /see RenderTarget::Activate /// /see RenderTarget::Activate
/// ///

View File

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

View File

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

View File

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

View File

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

View File

@ -15,9 +15,11 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
int main() int main()
{ {
// Create main window // Create the main window and activate it
sf::RenderWindow window(sf::VideoMode(800, 600), "SFML OpenGL"); sf::RenderWindow window(sf::VideoMode(800, 600), "SFML OpenGL");
window.PreserveOpenGLStates(true);
// Activate it as the target for OpenGL calls
window.SetActive();
// Create a sprite for the background // Create a sprite for the background
sf::Image backgroundImage; sf::Image backgroundImage;
@ -75,13 +77,23 @@ int main()
// Adjust the viewport when the window is resized // Adjust the viewport when the window is resized
if (event.Type == sf::Event::Resized) if (event.Type == sf::Event::Resized)
{
window.SetActive();
glViewport(0, 0, event.Size.Width, event.Size.Height); glViewport(0, 0, event.Size.Width, event.Size.Height);
} }
}
// Draw background // Draw the background
window.Draw(background); window.Draw(background);
// Clear depth buffer // Flush the window, to make sure that our OpenGL cube
// will be rendered on top of the background sprite
window.Flush();
// Activate the window
window.SetActive();
// Clear the depth buffer
glClear(GL_DEPTH_BUFFER_BIT); glClear(GL_DEPTH_BUFFER_BIT);
// We get the position of the mouse cursor, so that we can move the box accordingly // We get the position of the mouse cursor, so that we can move the box accordingly

View File

@ -17,6 +17,9 @@ int main()
// Create the main window // Create the main window
sf::Window window(sf::VideoMode(640, 480, 32), "SFML Window"); sf::Window window(sf::VideoMode(640, 480, 32), "SFML Window");
// Activate it as the target for OpenGL calls
window.SetActive();
// Create a clock for measuring the time elapsed // Create a clock for measuring the time elapsed
sf::Clock clock; sf::Clock clock;
@ -53,11 +56,6 @@ int main()
glViewport(0, 0, event.Size.Width, event.Size.Height); glViewport(0, 0, event.Size.Width, event.Size.Height);
} }
// Set the active window before using OpenGL commands
// It's useless here because the active window is always the same,
// but don't forget it if you use multiple windows
window.SetActive();
// Clear color and depth buffer // Clear color and depth buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

123
src/SFML/Graphics/Batch.cpp Normal file
View File

@ -0,0 +1,123 @@
////////////////////////////////////////////////////////////
//
// 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.
//
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Graphics/Batch.hpp>
#include <SFML/Graphics/Image.hpp>
#include <SFML/Graphics/GLCheck.hpp>
namespace sf
{
namespace priv
{
////////////////////////////////////////////////////////////
Batch::Batch(const Image* texture, Blend::Mode blendMode, const IntRect& viewport) :
myTexture (texture),
myBlendMode(blendMode),
myViewport (viewport),
myStart (0),
myCount (0)
{
}
////////////////////////////////////////////////////////////
bool Batch::Matches(const Image* texture, Blend::Mode blendMode, const IntRect& viewport) const
{
return myTexture == texture &&
myBlendMode == blendMode &&
myViewport.Left == viewport.Left &&
myViewport.Top == viewport.Top &&
myViewport.Right == viewport.Right &&
myViewport.Bottom == viewport.Bottom;
}
////////////////////////////////////////////////////////////
void Batch::Begin(std::size_t index)
{
myStart = index;
}
////////////////////////////////////////////////////////////
void Batch::End(std::size_t index)
{
myCount = index - myStart;
}
////////////////////////////////////////////////////////////
std::size_t Batch::GetStartIndex() const
{
return myStart;
}
////////////////////////////////////////////////////////////
std::size_t Batch::GetIndexCount() const
{
return myCount;
}
////////////////////////////////////////////////////////////
void Batch::ApplyStates() const
{
// Set the viewport
GLCheck(glViewport(myViewport.Left, myViewport.Top, myViewport.GetSize().x, myViewport.GetSize().y));
// Set the blending mode
if (myBlendMode == Blend::None)
{
GLCheck(glDisable(GL_BLEND));
}
else
{
GLCheck(glEnable(GL_BLEND));
// @todo the resulting alpha may not be correct, which matters when target is a RenderImage.
// find a fix for this (glBlendFuncSeparate -- but not supported by every graphics card)
switch (myBlendMode)
{
default :
case Blend::Alpha : GLCheck(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); break;
case Blend::Add : GLCheck(glBlendFunc(GL_SRC_ALPHA, GL_ONE)); break;
case Blend::Multiply : GLCheck(glBlendFunc(GL_DST_COLOR, GL_ZERO)); break;
}
}
// Bind the texture
if (myTexture)
myTexture->Bind();
else
GLCheck(glDisable(GL_TEXTURE_2D));
}
} // namespace priv
} // namespace sf

125
src/SFML/Graphics/Batch.hpp Normal file
View File

@ -0,0 +1,125 @@
////////////////////////////////////////////////////////////
//
// 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_BATCH_HPP
#define SFML_BATCH_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Graphics/Drawable.hpp>
#include <SFML/Graphics/Rect.hpp>
#include <vector>
namespace sf
{
class Image;
namespace priv
{
////////////////////////////////////////////////////////////
/// \brief Batch of geometry / render states to render
///
////////////////////////////////////////////////////////////
class Batch
{
public :
////////////////////////////////////////////////////////////
/// \brief Construct the batch with its render states
///
/// \param texture Texture to use
/// \param blendMode Blending mode
/// \param viewport Target viewport
///
////////////////////////////////////////////////////////////
Batch(const Image* texture = NULL, Blend::Mode blendMode = Blend::Alpha, const IntRect& viewport = IntRect());
////////////////////////////////////////////////////////////
/// \brief Check if the batch matches a set of render states
///
/// \param texture Texture to use
/// \param blendMode Blending mode
/// \param viewport Target viewport
///
////////////////////////////////////////////////////////////
bool Matches(const Image* texture, Blend::Mode blendMode, const IntRect& viewport) const;
////////////////////////////////////////////////////////////
/// \brief Setup the start index of the batch
///
/// \param index Start index
///
////////////////////////////////////////////////////////////
void Begin(std::size_t index);
////////////////////////////////////////////////////////////
/// \brief Setup the end index of the batch
///
/// \param index End index
///
////////////////////////////////////////////////////////////
void End(std::size_t index);
////////////////////////////////////////////////////////////
/// \brief Return the start index of the batch
///
/// \return Start index
///
////////////////////////////////////////////////////////////
std::size_t GetStartIndex() const;
////////////////////////////////////////////////////////////
/// \brief Return the number of indices to render with this batch
///
/// \return Index count
///
////////////////////////////////////////////////////////////
std::size_t GetIndexCount() const;
////////////////////////////////////////////////////////////
/// \brief Apply the render states of the batch
///
////////////////////////////////////////////////////////////
void ApplyStates() const;
private :
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
const Image* myTexture; ///< Texture used by the batch
Blend::Mode myBlendMode; ///< Blending mode used by the batch
IntRect myViewport; ///< Target viewport for the batch
std::size_t myStart; ///< Index of the first index to render with this batch
std::size_t myCount; ///< Number of indices to render with this batch
};
} // namespace priv
} // namespace sf
#endif // SFML_BATCH_HPP

View File

@ -26,8 +26,8 @@
// Headers // Headers
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#include <SFML/Graphics/Drawable.hpp> #include <SFML/Graphics/Drawable.hpp>
#include <SFML/Graphics/GLCheck.hpp> #include <SFML/Graphics/RenderQueue.hpp>
#include <SFML/Window/Window.hpp> #include <SFML/Graphics/RenderTarget.hpp>
#include <math.h> #include <math.h>
@ -358,44 +358,21 @@ const Matrix3& Drawable::GetInverseMatrix() const
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Draw the object into the specified window /// Draw the object into the specified render target
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void Drawable::Draw(RenderTarget& target) const void Drawable::Draw(RenderTarget& target, RenderQueue& queue) const
{ {
// Save the current modelview matrix and set the new one // Set the current model-view matrix
GLCheck(glMatrixMode(GL_MODELVIEW)); queue.ApplyModelView(GetMatrix());
GLCheck(glPushMatrix());
GLCheck(glMultMatrixf(GetMatrix().Get4x4Elements()));
// Setup alpha-blending // Set the current global color
if (myBlendMode == Blend::None) queue.ApplyColor(myColor);
{
GLCheck(glDisable(GL_BLEND));
}
else
{
GLCheck(glEnable(GL_BLEND));
// @todo the resulting alpha may not be correct, which matters when target is a RenderImage. // Set the current alpha-blending mode
// find a fix for this (glBlendFuncSeparate -- but not supported by every graphics card) queue.SetBlendMode(myBlendMode);
switch (myBlendMode)
{
case Blend::Alpha : GLCheck(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); break;
case Blend::Add : GLCheck(glBlendFunc(GL_SRC_ALPHA, GL_ONE)); break;
case Blend::Multiply : GLCheck(glBlendFunc(GL_DST_COLOR, GL_ZERO)); break;
default : break;
}
}
// Set color
GLCheck(glColor4ub(myColor.r, myColor.g, myColor.b, myColor.a));
// Let the derived class render the object geometry // Let the derived class render the object geometry
Render(target); Render(target, queue);
// Restore the previous modelview matrix
GLCheck(glMatrixMode(GL_MODELVIEW));
GLCheck(glPopMatrix());
} }
} // namespace sf } // namespace sf

View File

@ -214,6 +214,11 @@ FT_Error FontLoader::CreateBitmapFont(FT_Face face, unsigned int charSize, const
glyphs.insert(std::make_pair(bitmapGlyph, charset[i])); glyphs.insert(std::make_pair(bitmapGlyph, charset[i]));
} }
// Leave a small margin around characters, so that filtering doesn't
// pollute them with pixels from neighbours
unsigned int offset = 1;
unsigned int margin = offset + 1;
// Copy the rendered glyphs into the texture // Copy the rendered glyphs into the texture
unsigned int maxHeight = 0; unsigned int maxHeight = 0;
std::map<Uint32, IntRect> coords; std::map<Uint32, IntRect> coords;
@ -225,31 +230,31 @@ FT_Error FontLoader::CreateBitmapFont(FT_Face face, unsigned int charSize, const
FT_Bitmap& bitmap = bitmapGlyph->bitmap; FT_Bitmap& bitmap = bitmapGlyph->bitmap;
// Make sure we don't go over the texture width // Make sure we don't go over the texture width
if (left + bitmap.width + 1 >= texWidth) if (left + bitmap.width + margin >= texWidth)
left = 0; left = 0;
// Compute the top coordinate // Compute the top coordinate
top = tops[left]; top = tops[left];
for (int x = 0; x < bitmap.width + 1; ++x) for (unsigned int x = 0; x < bitmap.width + margin; ++x)
top = std::max(top, tops[left + x]); top = std::max(top, tops[left + x]);
top++; top += margin;
// Make sure we don't go over the texture height -- resize it if we need more space // Make sure we don't go over the texture height -- resize it if we need more space
if (top + bitmap.rows + 1 >= texHeight) if (top + bitmap.rows + margin >= texHeight)
{ {
texHeight *= 2; texHeight *= 2;
glyphsBuffer.resize(texWidth * texHeight * 4); glyphsBuffer.resize(texWidth * texHeight * 4);
} }
// Store the character's position and size // Store the character's position and size
curGlyph.Rectangle.Left = bitmapGlyph->left; curGlyph.Rectangle.Left = bitmapGlyph->left - offset;
curGlyph.Rectangle.Top = -bitmapGlyph->top; curGlyph.Rectangle.Top = -bitmapGlyph->top - offset;
curGlyph.Rectangle.Right = curGlyph.Rectangle.Left + bitmap.width; curGlyph.Rectangle.Right = (curGlyph.Rectangle.Left + bitmap.width + offset) / 1;
curGlyph.Rectangle.Bottom = bitmap.rows - bitmapGlyph->top; curGlyph.Rectangle.Bottom = bitmap.rows - bitmapGlyph->top + offset;
curGlyph.Advance = bitmapGlyph->root.advance.x >> 16; curGlyph.Advance = bitmapGlyph->root.advance.x >> 16;
// Texture size may change, so let the texture coordinates be calculated later // Texture size may change, so let the texture coordinates be calculated later
coords[i->second] = IntRect(left + 1, top + 1, left + bitmap.width + 1, top + bitmap.rows + 1); coords[i->second] = IntRect(left + offset, top + offset, left + bitmap.width + offset + margin, top + bitmap.rows + offset + margin);
// Draw the glyph into our bitmap font // Draw the glyph into our bitmap font
const Uint8* pixels = bitmap.buffer; const Uint8* pixels = bitmap.buffer;
@ -257,19 +262,19 @@ FT_Error FontLoader::CreateBitmapFont(FT_Face face, unsigned int charSize, const
{ {
for (int x = 0; x < bitmap.width; ++x) for (int x = 0; x < bitmap.width; ++x)
{ {
std::size_t index = x + left + 1 + (y + top + 1) * texWidth; std::size_t index = x + left + margin + (y + top + margin) * texWidth;
glyphsBuffer[index * 4 + 0] = 255; glyphsBuffer[index * 4 + 0] = 255;
glyphsBuffer[index * 4 + 1] = 255; glyphsBuffer[index * 4 + 1] = 255;
glyphsBuffer[index * 4 + 2] = 255; glyphsBuffer[index * 4 + 2] = 255;
glyphsBuffer[index * 4 + 3] = pixels[x]; glyphsBuffer[index * 4 + 3] = pixels[x] * pixels[x] / 255;
} }
pixels += bitmap.pitch; pixels += bitmap.pitch;
} }
// Update the rendering coordinates // Update the rendering coordinates
for (int x = 0; x < bitmap.width + 1; ++x) for (unsigned int x = 0; x < bitmap.width + margin; ++x)
tops[left + x] = top + bitmap.rows; tops[left + x] = top + bitmap.rows;
left += bitmap.width + 1; left += bitmap.width + margin;
if (top + bitmap.rows > maxHeight) if (top + bitmap.rows > maxHeight)
maxHeight = top + bitmap.rows; maxHeight = top + bitmap.rows;
@ -278,7 +283,7 @@ FT_Error FontLoader::CreateBitmapFont(FT_Face face, unsigned int charSize, const
} }
// Create the font's texture // Create the font's texture
texHeight = maxHeight + 1; texHeight = maxHeight + margin;
glyphsBuffer.resize(texWidth * texHeight * 4); glyphsBuffer.resize(texWidth * texHeight * 4);
font.myTexture.LoadFromPixels(texWidth, texHeight, &glyphsBuffer[0]); font.myTexture.LoadFromPixels(texWidth, texHeight, &glyphsBuffer[0]);

View File

@ -0,0 +1,68 @@
////////////////////////////////////////////////////////////
//
// 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.
//
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Graphics/GeometryRenderer.hpp>
#include <SFML/Graphics/GeometryRendererVBO.hpp>
#include <SFML/Graphics/GeometryRendererVA.hpp>
#include <SFML/Graphics/GeometryRendererIM.hpp>
namespace sf
{
namespace priv
{
////////////////////////////////////////////////////////////
GeometryRenderer* GeometryRenderer::New()
{
// Choose the best implementation according to the graphics card's capabilities
if (priv::GeometryRendererVBO::IsSupported())
{
// Use Vertex Buffer Objects
return new priv::GeometryRendererVBO;
}
else if (priv::GeometryRendererVA::IsSupported())
{
// Use Vertex Arrays
return new priv::GeometryRendererVA;
}
else
{
// Use Immediate Mode
return new priv::GeometryRendererIM;
}
}
////////////////////////////////////////////////////////////
GeometryRenderer::~GeometryRenderer()
{
// Nothing to do
}
} // namespace priv
} // namespace sf

View File

@ -0,0 +1,106 @@
////////////////////////////////////////////////////////////
//
// 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_GEOMETRYRENDERER_HPP
#define SFML_GEOMETRYRENDERER_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/System/NonCopyable.hpp>
#include <cstdlib>
namespace sf
{
namespace priv
{
////////////////////////////////////////////////////////////
/// \brief Abstract base class for optimized geometry renderers
///
////////////////////////////////////////////////////////////
class GeometryRenderer : NonCopyable
{
public :
////////////////////////////////////////////////////////////
/// \brief Construct a new GeometryRenderer
///
/// This function selects the best specialization available,
/// according to the capabilities of the system.
///
/// \return New instance of GeometryRenderer; cannot be NULL
///
////////////////////////////////////////////////////////////
static GeometryRenderer* New();
public :
////////////////////////////////////////////////////////////
/// \brief Virtual destructor
///
////////////////////////////////////////////////////////////
virtual ~GeometryRenderer();
////////////////////////////////////////////////////////////
/// \brief Prepare the geometry for rendering
///
/// This function is called once before all the triangles
/// are rendered.
///
/// \param vertices Pointer to the vertex array
/// \param verticesCount Number of vertices to render
/// \param indices Pointer to the index array
/// \param indicesCount Number of indices to render
///
////////////////////////////////////////////////////////////
virtual void Begin(const float* vertices, std::size_t verticesCount, const unsigned int* indices, std::size_t indicesCount) = 0;
////////////////////////////////////////////////////////////
/// \brief Stop rendering geometry
///
/// This function is called once after all the triangles
/// have been rendered.
///
////////////////////////////////////////////////////////////
virtual void End() = 0;
////////////////////////////////////////////////////////////
/// \brief Render a chunk of triangles
///
/// The primitives are rendered as a list of triangles (no strip or fan).
///
/// \param start Index in the indices array of the first index to be rendered
/// \param count Number of indices to be rendered
///
////////////////////////////////////////////////////////////
virtual void RenderTriangles(std::size_t start, std::size_t count) = 0;
};
} // namespace priv
} // namespace sf
#endif // SFML_GEOMETRYRENDERER_HPP

View File

@ -0,0 +1,95 @@
////////////////////////////////////////////////////////////
//
// 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.
//
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Graphics/GeometryRendererIM.hpp>
#include <SFML/Graphics/GLCheck.hpp>
namespace sf
{
namespace priv
{
////////////////////////////////////////////////////////////
bool GeometryRendererIM::IsSupported()
{
// Immediate mode is always supported
return true;
}
////////////////////////////////////////////////////////////
GeometryRendererIM::GeometryRendererIM() :
myVertices(NULL),
myIndices (NULL)
{
}
////////////////////////////////////////////////////////////
void GeometryRendererIM::Begin(const float* vertices, std::size_t, const unsigned int* indices, std::size_t)
{
// Store the geometry informations for later rendering
myVertices = vertices;
myIndices = indices;
}
////////////////////////////////////////////////////////////
void GeometryRendererIM::End()
{
// Nothing to do
}
////////////////////////////////////////////////////////////
void GeometryRendererIM::RenderTriangles(std::size_t start, std::size_t count)
{
// Caculate the bounds of the geometry range to render
const unsigned int* begin = myIndices + start;
const unsigned int* end = begin + count;
// Begin rendering
glBegin(GL_TRIANGLES);
// Send the vertices one by one
for (const unsigned int* index = begin; index != end; index++)
{
const float* vertex = myVertices + *index * 8;
glColor4f(vertex[2], vertex[3], vertex[4], vertex[5]);
glTexCoord2f(vertex[6], vertex[7]);
glVertex2f(vertex[0], vertex[1]);
}
// End rendering
glEnd();
}
} // namespace priv
} // namespace sf

View File

@ -0,0 +1,108 @@
////////////////////////////////////////////////////////////
//
// 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_GEOMETRYRENDERERIM_HPP
#define SFML_GEOMETRYRENDERERIM_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Graphics/GeometryRenderer.hpp>
namespace sf
{
namespace priv
{
////////////////////////////////////////////////////////////
/// \brief Geometry renderer using immediate mode
///
////////////////////////////////////////////////////////////
class GeometryRendererIM : public GeometryRenderer
{
public :
////////////////////////////////////////////////////////////
/// \brief Check if this implementation is supported by the system
///
/// \return True if the immediate mode renderer is supported
///
////////////////////////////////////////////////////////////
static bool IsSupported();
public :
////////////////////////////////////////////////////////////
/// \brief Default constructor
///
////////////////////////////////////////////////////////////
GeometryRendererIM();
////////////////////////////////////////////////////////////
/// \brief Prepare the geometry for rendering
///
/// This function is called once before all the triangles
/// are rendered.
///
/// \param vertices Pointer to the vertex array
/// \param verticesCount Number of vertices to render
/// \param indices Pointer to the index array
/// \param indicesCount Number of indices to render
///
////////////////////////////////////////////////////////////
virtual void Begin(const float* vertices, std::size_t verticesCount, const unsigned int* indices, std::size_t indicesCount);
////////////////////////////////////////////////////////////
/// \brief Stop rendering geometry
///
/// This function is called once after all the triangles
/// have been rendered.
///
////////////////////////////////////////////////////////////
virtual void End();
////////////////////////////////////////////////////////////
/// \brief Render a chunk of triangles
///
/// The primitives are rendered as a list of triangles (no strip or fan).
///
/// \param start Index in the indices array of the first index to be rendered
/// \param count Number of indices to be rendered
///
////////////////////////////////////////////////////////////
virtual void RenderTriangles(std::size_t start, std::size_t count);
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
const float* myVertices; ///< Pointer to the vertices to render
const unsigned int* myIndices; ///< Pointer to the indices to render
};
} // namespace priv
} // namespace sf
#endif // SFML_GEOMETRYRENDERERIM_HPP

View File

@ -0,0 +1,99 @@
////////////////////////////////////////////////////////////
//
// 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.
//
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Graphics/GeometryRendererVA.hpp>
#include <SFML/Graphics/GLCheck.hpp>
namespace sf
{
namespace priv
{
////////////////////////////////////////////////////////////
bool GeometryRendererVA::IsSupported()
{
EnsureGlewInit();
return glewIsSupported("GL_EXT_vertex_array") != 0;
}
////////////////////////////////////////////////////////////
GeometryRendererVA::GeometryRendererVA() :
myIndices(NULL)
{
EnsureGlewInit();
myCanLock = glewIsSupported("GL_EXT_compiled_vertex_array") != 0;
}
////////////////////////////////////////////////////////////
void GeometryRendererVA::Begin(const float* vertices, std::size_t verticesCount, const unsigned int* indices, std::size_t)
{
static const GLsizei stride = 8 * sizeof(float);
// Setup positions
GLCheck(glEnableClientState(GL_VERTEX_ARRAY));
GLCheck(glVertexPointer(2, GL_FLOAT, stride, vertices));
// Setup colors
GLCheck(glEnableClientState(GL_COLOR_ARRAY));
GLCheck(glColorPointer(4, GL_FLOAT, stride, vertices + 2));
// Setup texture coordinates
GLCheck(glClientActiveTextureARB(GL_TEXTURE0_ARB));
GLCheck(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
GLCheck(glTexCoordPointer(2, GL_FLOAT, stride, vertices + 6));
// Lock (compile) the vertex array if supported
if (myCanLock)
GLCheck(glLockArraysEXT(0, verticesCount / 8));
// Store indices for later use
myIndices = indices;
}
////////////////////////////////////////////////////////////
void GeometryRendererVA::End()
{
// Unlock the vertex array if it was locked
if (myCanLock)
GLCheck(glUnlockArraysEXT());
}
////////////////////////////////////////////////////////////
void GeometryRendererVA::RenderTriangles(std::size_t start, std::size_t count)
{
GLCheck(glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, myIndices + start));
}
} // namespace priv
} // namespace sf

View File

@ -0,0 +1,108 @@
////////////////////////////////////////////////////////////
//
// 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_GEOMETRYRENDERERVA_HPP
#define SFML_GEOMETRYRENDERERVA_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Graphics/GeometryRenderer.hpp>
namespace sf
{
namespace priv
{
////////////////////////////////////////////////////////////
/// \brief Geometry renderer using vertex arrays
///
////////////////////////////////////////////////////////////
class GeometryRendererVA : public GeometryRenderer
{
public :
////////////////////////////////////////////////////////////
/// \brief Check if this implementation is supported by the system
///
/// \return True if the vertex array renderer is supported
///
////////////////////////////////////////////////////////////
static bool IsSupported();
////////////////////////////////////////////////////////////
/// \brief Default constructor
///
////////////////////////////////////////////////////////////
GeometryRendererVA();
public :
////////////////////////////////////////////////////////////
/// \brief Prepare the geometry for rendering
///
/// This function is called once before all the triangles
/// are rendered.
///
/// \param vertices Pointer to the vertex array
/// \param verticesCount Number of vertices to render
/// \param indices Pointer to the index array
/// \param indicesCount Number of indices to render
///
////////////////////////////////////////////////////////////
virtual void Begin(const float* vertices, std::size_t verticesCount, const unsigned int* indices, std::size_t indicesCount);
////////////////////////////////////////////////////////////
/// \brief Stop rendering geometry
///
/// This function is called once after all the triangles
/// have been rendered.
///
////////////////////////////////////////////////////////////
virtual void End();
////////////////////////////////////////////////////////////
/// \brief Render a chunk of triangles
///
/// The primitives are rendered as a list of triangles (no strip or fan).
///
/// \param start Index in the indices array of the first index to be rendered
/// \param count Number of indices to be rendered
///
////////////////////////////////////////////////////////////
virtual void RenderTriangles(std::size_t start, std::size_t count);
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
bool myCanLock; ///< Is geometry locking supported?
const unsigned int* myIndices; ///< Pointer to the indices to render
};
} // namespace priv
} // namespace sf
#endif // SFML_GEOMETRYRENDERERVA_HPP

View File

@ -0,0 +1,127 @@
////////////////////////////////////////////////////////////
//
// 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.
//
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Graphics/GeometryRendererVBO.hpp>
namespace sf
{
namespace priv
{
////////////////////////////////////////////////////////////
bool GeometryRendererVBO::IsSupported()
{
EnsureGlewInit();
return glewIsSupported("GL_ARB_vertex_buffer_object") != 0;
}
////////////////////////////////////////////////////////////
GeometryRendererVBO::GeometryRendererVBO() :
myVertexBufferSize(0),
myIndexBufferSize (0)
{
EnsureGlewInit();
// Create the buffers
GLCheck(glGenBuffersARB(1, &myVertexBuffer));
GLCheck(glGenBuffersARB(1, &myIndexBuffer));
}
////////////////////////////////////////////////////////////
GeometryRendererVBO::~GeometryRendererVBO()
{
// Free the buffers
GLCheck(glDeleteBuffersARB(1, &myVertexBuffer));
GLCheck(glDeleteBuffersARB(1, &myIndexBuffer));
}
////////////////////////////////////////////////////////////
void GeometryRendererVBO::Begin(const float* vertices, std::size_t verticesCount, const unsigned int* indices, std::size_t indicesCount)
{
// Update the vertex buffer data (make it grow if it is not large enough)
GLCheck(glBindBufferARB(GL_ARRAY_BUFFER_ARB, myVertexBuffer));
if (verticesCount > myVertexBufferSize)
{
GLCheck(glBufferDataARB(GL_ARRAY_BUFFER_ARB, verticesCount * sizeof(float), vertices, GL_DYNAMIC_DRAW_ARB));
myVertexBufferSize = verticesCount;
}
else
{
GLCheck(glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, verticesCount * sizeof(float), vertices));
}
// Update the index buffer data (make it grow if it is not large enough)
GLCheck(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, myIndexBuffer));
if (indicesCount > myIndexBufferSize)
{
GLCheck(glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, indicesCount * sizeof(unsigned int), indices, GL_DYNAMIC_DRAW_ARB));
myIndexBufferSize = indicesCount;
}
else
{
GLCheck(glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, indicesCount * sizeof(unsigned int), indices));
}
static const GLsizei stride = 8 * sizeof(float);
static const float* pointer = NULL;
// Setup positions
GLCheck(glEnableClientState(GL_VERTEX_ARRAY));
GLCheck(glVertexPointer(2, GL_FLOAT, stride, pointer));
// Setup colors
GLCheck(glEnableClientState(GL_COLOR_ARRAY));
GLCheck(glColorPointer(4, GL_FLOAT, stride, pointer + 2));
// Setup texture coordinates
GLCheck(glClientActiveTextureARB(GL_TEXTURE0_ARB));
GLCheck(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
GLCheck(glTexCoordPointer(2, GL_FLOAT, stride, pointer + 6));
}
////////////////////////////////////////////////////////////
void GeometryRendererVBO::End()
{
// Nothing to do
}
////////////////////////////////////////////////////////////
void GeometryRendererVBO::RenderTriangles(std::size_t start, std::size_t count)
{
static const unsigned int* pointer = NULL;
GLCheck(glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, pointer + start));
}
} // namespace priv
} // namespace sf

View File

@ -0,0 +1,117 @@
////////////////////////////////////////////////////////////
//
// 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_GEOMETRYRENDERERVBO_HPP
#define SFML_GEOMETRYRENDERERVBO_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Graphics/GeometryRenderer.hpp>
#include <SFML/Graphics/GLCheck.hpp>
namespace sf
{
namespace priv
{
////////////////////////////////////////////////////////////
/// \brief Geometry renderer using vertex buffer objects
///
////////////////////////////////////////////////////////////
class GeometryRendererVBO : public GeometryRenderer
{
public :
////////////////////////////////////////////////////////////
/// \brief Check if this implementation is supported by the system
///
/// \return True if the vertex buffer objects renderer is supported
///
////////////////////////////////////////////////////////////
static bool IsSupported();
////////////////////////////////////////////////////////////
/// \brief Default constructor
///
////////////////////////////////////////////////////////////
GeometryRendererVBO();
////////////////////////////////////////////////////////////
/// \brief Destructor
///
////////////////////////////////////////////////////////////
~GeometryRendererVBO();
public :
////////////////////////////////////////////////////////////
/// \brief Prepare the geometry for rendering
///
/// This function is called once before all the triangles
/// are rendered.
///
/// \param vertices Pointer to the vertex array
/// \param verticesCount Number of vertices to render
/// \param indices Pointer to the index array
/// \param indicesCount Number of indices to render
///
////////////////////////////////////////////////////////////
virtual void Begin(const float* vertices, std::size_t verticesCount, const unsigned int* indices, std::size_t indicesCount);
////////////////////////////////////////////////////////////
/// \brief Stop rendering geometry
///
/// This function is called once after all the triangles
/// have been rendered.
///
////////////////////////////////////////////////////////////
virtual void End();
////////////////////////////////////////////////////////////
/// \brief Render a chunk of triangles
///
/// The primitives are rendered as a list of triangles (no strip or fan).
///
/// \param start Index in the indices array of the first index to be rendered
/// \param count Number of indices to be rendered
///
////////////////////////////////////////////////////////////
virtual void RenderTriangles(std::size_t start, std::size_t count);
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
GLuint myVertexBuffer;
GLuint myIndexBuffer;
std::size_t myVertexBufferSize;
std::size_t myIndexBufferSize;
};
} // namespace priv
} // namespace sf
#endif // SFML_GEOMETRYRENDERERVBO_HPP

View File

@ -50,7 +50,6 @@ myTexture (0),
myIsSmooth (true), myIsSmooth (true),
myNeedTextureUpdate(false), myNeedTextureUpdate(false),
myNeedArrayUpdate (false), myNeedArrayUpdate (false),
myUpdateSource (NULL),
myPixelsFlipped (false) myPixelsFlipped (false)
{ {
@ -71,7 +70,6 @@ myIsSmooth (copy.myIsSmooth),
myPixels (copy.myPixels), myPixels (copy.myPixels),
myNeedTextureUpdate(false), myNeedTextureUpdate(false),
myNeedArrayUpdate (false), myNeedArrayUpdate (false),
myUpdateSource (copy.myUpdateSource),
myPixelsFlipped (copy.myPixelsFlipped) myPixelsFlipped (copy.myPixelsFlipped)
{ {
CreateTexture(); CreateTexture();
@ -90,7 +88,6 @@ myTexture (0),
myIsSmooth (true), myIsSmooth (true),
myNeedTextureUpdate(false), myNeedTextureUpdate(false),
myNeedArrayUpdate (false), myNeedArrayUpdate (false),
myUpdateSource (NULL),
myPixelsFlipped (false) myPixelsFlipped (false)
{ {
Create(width, height, color); Create(width, height, color);
@ -109,7 +106,6 @@ myTexture (0),
myIsSmooth (true), myIsSmooth (true),
myNeedTextureUpdate(false), myNeedTextureUpdate(false),
myNeedArrayUpdate (false), myNeedArrayUpdate (false),
myUpdateSource (NULL),
myPixelsFlipped (false) myPixelsFlipped (false)
{ {
LoadFromPixels(width, height, data); LoadFromPixels(width, height, data);
@ -387,6 +383,9 @@ bool Image::CopyScreen(RenderWindow& window, const IntRect& sourceRect)
myWidth = srcRect.GetSize().x; myWidth = srcRect.GetSize().x;
myHeight = srcRect.GetSize().y; myHeight = srcRect.GetSize().y;
// Make sure that pending drawables are rendered on the target window
window.Flush();
// We can then create the texture // We can then create the texture
if (window.SetActive() && CreateTexture()) if (window.SetActive() && CreateTexture())
{ {
@ -402,6 +401,8 @@ bool Image::CopyScreen(RenderWindow& window, const IntRect& sourceRect)
myNeedArrayUpdate = true; myNeedArrayUpdate = true;
myPixelsFlipped = true; myPixelsFlipped = true;
window.SetActive(false);
return true; return true;
} }
else else
@ -553,12 +554,13 @@ FloatRect Image::GetTexCoords(const IntRect& rect) const
{ {
float width = static_cast<float>(myTextureWidth); float width = static_cast<float>(myTextureWidth);
float height = static_cast<float>(myTextureHeight); float height = static_cast<float>(myTextureHeight);
float offset = myIsSmooth ? 0.5f : 0.0f;
FloatRect coords; FloatRect coords;
coords.Left = rect.Left / width; coords.Left = (rect.Left + offset) / width;
coords.Top = rect.Top / height; coords.Top = (rect.Top + offset) / height;
coords.Right = rect.Right / width; coords.Right = (rect.Right - offset) / width;
coords.Bottom = rect.Bottom / height; coords.Bottom = (rect.Bottom - offset) / height;
if (myPixelsFlipped) if (myPixelsFlipped)
std::swap(coords.Top, coords.Bottom); std::swap(coords.Top, coords.Bottom);
@ -607,7 +609,6 @@ Image& Image::operator =(const Image& other)
std::swap(myIsSmooth, temp.myIsSmooth); std::swap(myIsSmooth, temp.myIsSmooth);
std::swap(myNeedArrayUpdate, temp.myNeedArrayUpdate); std::swap(myNeedArrayUpdate, temp.myNeedArrayUpdate);
std::swap(myNeedTextureUpdate, temp.myNeedTextureUpdate); std::swap(myNeedTextureUpdate, temp.myNeedTextureUpdate);
std::swap(myUpdateSource, temp.myUpdateSource);
std::swap(myPixelsFlipped, temp.myPixelsFlipped); std::swap(myPixelsFlipped, temp.myPixelsFlipped);
myPixels.swap(temp.myPixels); myPixels.swap(temp.myPixels);
@ -678,24 +679,15 @@ void Image::EnsureTextureUpdate()
{ {
if (myNeedTextureUpdate) if (myNeedTextureUpdate)
{ {
if (myTexture) if (myTexture && !myPixels.empty())
{ {
GLint previous; GLint previous;
GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous)); GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous));
if (myUpdateSource) // Update the texture with the pixels array in RAM
{ GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture));
// External update GLCheck(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, myWidth, myHeight, GL_RGBA, GL_UNSIGNED_BYTE, &myPixels[0]));
myPixelsFlipped = myUpdateSource->UpdateImage(*this); myPixelsFlipped = false;
myUpdateSource = NULL;
}
else if (!myPixels.empty())
{
// Update the texture with the pixels array in RAM
GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture));
GLCheck(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, myWidth, myHeight, GL_RGBA, GL_UNSIGNED_BYTE, &myPixels[0]));
myPixelsFlipped = false;
}
GLCheck(glBindTexture(GL_TEXTURE_2D, previous)); GLCheck(glBindTexture(GL_TEXTURE_2D, previous));
} }
@ -769,19 +761,6 @@ void Image::EnsureArrayUpdate()
} }
////////////////////////////////////////////////////////////
/// Notify the image that an external source has modified
/// its content.
/// For internal use only (see RenderImage class).
////////////////////////////////////////////////////////////
void Image::ExternalUpdate(RenderImage& source)
{
myNeedTextureUpdate = true;
myNeedArrayUpdate = true;
myUpdateSource = &source;
}
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Reset the image attributes /// Reset the image attributes
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -797,7 +776,6 @@ void Image::Reset()
myIsSmooth = true; myIsSmooth = true;
myNeedTextureUpdate = false; myNeedTextureUpdate = false;
myNeedArrayUpdate = false; myNeedArrayUpdate = false;
myUpdateSource = NULL;
myPixelsFlipped = false; myPixelsFlipped = false;
myPixels.clear(); myPixels.clear();
} }

View File

@ -275,7 +275,7 @@ bool PostFX::CanUsePostFX()
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// /see Drawable::Render /// /see Drawable::Render
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void PostFX::Render(RenderTarget& target) const void PostFX::Render(RenderTarget& target, RenderQueue&) const
{ {
// Check that we have a valid program // Check that we have a valid program
if (!myShaderProgram) if (!myShaderProgram)
@ -283,7 +283,9 @@ void PostFX::Render(RenderTarget& target) const
// Copy the current framebuffer pixels to our frame buffer texture // Copy the current framebuffer pixels to our frame buffer texture
// The ugly cast is temporary until PostFx are rewritten :) // The ugly cast is temporary until PostFx are rewritten :)
myFrameBuffer.CopyScreen((RenderWindow&)target); RenderWindow& window = static_cast<RenderWindow&>(target);
myFrameBuffer.CopyScreen(window);
window.SetActive();
// Enable program // Enable program
GLCheck(glUseProgramObjectARB(myShaderProgram)); GLCheck(glUseProgramObjectARB(myShaderProgram));

View File

@ -105,18 +105,24 @@ bool RenderImage::Create(unsigned int width, unsigned int height, bool depthBuff
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
bool RenderImage::SetActive(bool active) bool RenderImage::SetActive(bool active)
{ {
if (myRenderImage && myRenderImage->Activate(active)) return myRenderImage && myRenderImage->Activate(active);
{ }
// After the RenderImage has been modified, we have to notify
// the underlying image that its pixels have changed
if (!active)
myImage.ExternalUpdate(*this);
return true;
} ////////////////////////////////////////////////////////////
else /// Update the contents of the target
////////////////////////////////////////////////////////////
void RenderImage::Display()
{
// Render everything that has been drawn so far
Flush();
// Update the target image
if (myRenderImage)
{ {
return false; bool pixelsFlipped = myRenderImage->UpdateTexture(myImage.myTexture);
myImage.myPixelsFlipped = pixelsFlipped;
myImage.myNeedArrayUpdate = true;
} }
} }
@ -158,17 +164,6 @@ bool RenderImage::CanUseRenderImage()
} }
////////////////////////////////////////////////////////////
/// 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.
////////////////////////////////////////////////////////////
bool RenderImage::UpdateImage(Image& target)
{
return myRenderImage && myRenderImage->UpdateTexture(target.myTexture);
}
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Activate / deactivate the render image for rendering /// Activate / deactivate the render image for rendering
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

View File

@ -0,0 +1,328 @@
////////////////////////////////////////////////////////////
//
// 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.
//
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Graphics/RenderQueue.hpp>
#include <SFML/Graphics/Batch.hpp>
#include <SFML/Graphics/GeometryRenderer.hpp>
#include <SFML/Graphics/GLCheck.hpp>
////////////////////////////////////////////////////////////
// Private data
////////////////////////////////////////////////////////////
namespace
{
// Fast float to int conversion
inline sf::Int32 Round(double value)
{
value += 6755399441055744.0;
#if defined(SFML_ENDIAN_LITTLE)
return (reinterpret_cast<sf::Int32*>(&value))[0];
#else
return (reinterpret_cast<sf::Int32*>(&value))[1];
#endif
}
}
namespace sf
{
////////////////////////////////////////////////////////////
RenderQueue::RenderQueue() :
myCurrentTexture (NULL),
myCurrentBlendMode (Blend::Alpha),
myBaseIndex (0),
myRenderer (priv::GeometryRenderer::New()),
myCurrentBatch (NULL),
myVertices (512),
myIndices (512),
myCurrentVertexCount(0),
myCurrentIndexCount (0)
{
myCurrentStates = &myStatesStack[0];
}
////////////////////////////////////////////////////////////
RenderQueue::~RenderQueue()
{
// Destroy the geometry renderer
delete myRenderer;
}
////////////////////////////////////////////////////////////
void RenderQueue::PushStates()
{
myCurrentStates++;
*myCurrentStates = *(myCurrentStates - 1);
}
////////////////////////////////////////////////////////////
void RenderQueue::PopStates()
{
myCurrentStates--;
}
////////////////////////////////////////////////////////////
void RenderQueue::SetModelView(const Matrix3& matrix)
{
myCurrentStates->modelView = matrix;
}
////////////////////////////////////////////////////////////
void RenderQueue::ApplyModelView(const Matrix3& matrix)
{
myCurrentStates->modelView *= matrix;
}
////////////////////////////////////////////////////////////
void RenderQueue::SetProjection(const Matrix3& matrix)
{
myCurrentStates->projection = matrix;
}
////////////////////////////////////////////////////////////
void RenderQueue::ApplyProjection(const Matrix3& matrix)
{
myCurrentStates->projection *= matrix;
}
////////////////////////////////////////////////////////////
void RenderQueue::SetColor(const Color& color)
{
myCurrentStates->color = color;
}
////////////////////////////////////////////////////////////
void RenderQueue::ApplyColor(const Color& color)
{
myCurrentStates->color *= color;
}
////////////////////////////////////////////////////////////
void RenderQueue::SetViewport(const IntRect& viewport)
{
myCurrentViewport = viewport;
myCurrentViewportSize.x = viewport.GetSize().x / 2.f;
myCurrentViewportSize.y = viewport.GetSize().y / 2.f;
}
////////////////////////////////////////////////////////////
void RenderQueue::SetBlendMode(Blend::Mode mode)
{
myCurrentBlendMode = mode;
}
////////////////////////////////////////////////////////////
void RenderQueue::SetTexture(const Image* texture)
{
myCurrentTexture = texture;
}
////////////////////////////////////////////////////////////
void RenderQueue::BeginBatch()
{
// Check if the current batch differs from the new render states
if (!myCurrentBatch || !myCurrentBatch->Matches(myCurrentTexture, myCurrentBlendMode, myCurrentViewport))
{
// Close the current batch
if (myCurrentBatch)
myCurrentBatch->End(myCurrentIndexCount);
// Create a new one
priv::Batch batch(myCurrentTexture, myCurrentBlendMode, myCurrentViewport);
myBatches.push_back(batch);
myCurrentBatch = &myBatches.back();
myCurrentBatch->Begin(myCurrentIndexCount);
}
// Update the combined transform matrix
myCurrentTransform = myCurrentStates->projection * myCurrentStates->modelView;
// Update the current base index
myBaseIndex = myCurrentVertexCount / 8;
}
////////////////////////////////////////////////////////////
void RenderQueue::AddVertex(float x, float y)
{
AddVertex(x, y, 0.f, 0.f, Color::White);
}
////////////////////////////////////////////////////////////
void RenderQueue::AddVertex(float x, float y, float u, float v)
{
AddVertex(x, y, u, v, Color::White);
}
////////////////////////////////////////////////////////////
void RenderQueue::AddVertex(float x, float y, const Color& color)
{
AddVertex(x, y, 0.f, 0.f, color);
}
////////////////////////////////////////////////////////////
void RenderQueue::AddVertex(float x, float y, float u, float v, const Color& color)
{
// Apply the current transform matrix to the vertex position
sf::Vector2f transformedPoint = myCurrentTransform.Transform(sf::Vector2f(x, y));
// Apply the current global color
sf::Color combinedColor = myCurrentStates->color * color;
// Round the vertex position so that it matches the
// viewport's pixels, and thus avoid rendering artifacts
int i1 = Round((transformedPoint.x + 1.f) * myCurrentViewportSize.x);
int i2 = Round((transformedPoint.y + 1.f) * myCurrentViewportSize.y);
transformedPoint.x = i1 / myCurrentViewportSize.x - 1.f;
transformedPoint.y = i2 / myCurrentViewportSize.y - 1.f;
// Here we choose not to rely on vector::clear and vector::push_back,
// and to handle resizing and appending manually, for performances reasons
// Resize the vertex buffer if it is too small
std::size_t size = myVertices.size();
if (myCurrentVertexCount + 8 > size)
myVertices.resize(size + size / 2);
// Copy the vertex data
float* ptr = &myVertices[myCurrentVertexCount];
*ptr++ = transformedPoint.x;
*ptr++ = transformedPoint.y;
*ptr++ = combinedColor.r / 255.f;
*ptr++ = combinedColor.g / 255.f;
*ptr++ = combinedColor.b / 255.f;
*ptr++ = combinedColor.a / 255.f;
*ptr++ = u;
*ptr++ = v;
// Increase the vertex count
myCurrentVertexCount += 8;
}
////////////////////////////////////////////////////////////
void RenderQueue::AddTriangle(unsigned int index0, unsigned int index1, unsigned int index2)
{
// Here we choose not to rely on vector::clear and vector::push_back,
// and to handle resizing and appending manually, for performances reasons
// Resize the index buffer if it is too small
std::size_t size = myIndices.size();
if (myCurrentIndexCount + 3 > size)
myIndices.resize(size + size / 2);
// Copy the index data
myIndices[myCurrentIndexCount + 0] = index0 + myBaseIndex;
myIndices[myCurrentIndexCount + 1] = index1 + myBaseIndex;
myIndices[myCurrentIndexCount + 2] = index2 + myBaseIndex;
// Increase the index count
myCurrentIndexCount += 3;
}
////////////////////////////////////////////////////////////
void RenderQueue::Render()
{
if (myCurrentVertexCount && myCurrentIndexCount)
{
// Save the current OpenGL states
GLCheck(glPushAttrib(GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT | GL_TEXTURE_BIT | GL_VIEWPORT_BIT));
GLCheck(glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT));
GLCheck(glDisable(GL_LIGHTING));
GLCheck(glDisable(GL_DEPTH_TEST));
GLCheck(glEnable(GL_ALPHA_TEST));
GLCheck(glAlphaFunc(GL_GREATER, 0));
GLCheck(glMatrixMode(GL_MODELVIEW));
GLCheck(glPushMatrix());
GLCheck(glLoadIdentity());
GLCheck(glMatrixMode(GL_PROJECTION));
GLCheck(glPushMatrix());
GLCheck(glLoadIdentity());
// Close the last batch
if (myCurrentBatch)
myCurrentBatch->End(myCurrentIndexCount);
// Prepare the geometry renderer
myRenderer->Begin(&myVertices[0], myCurrentVertexCount, &myIndices[0], myCurrentIndexCount);
// Render the batches in order
for (BatchArray::const_iterator it = myBatches.begin(); it != myBatches.end(); ++it)
{
it->ApplyStates();
myRenderer->RenderTriangles(it->GetStartIndex(), it->GetIndexCount());
}
// Stop rendering
myRenderer->End();
// Restore the previous OpenGL states
GLCheck(glMatrixMode(GL_PROJECTION));
GLCheck(glPopMatrix());
GLCheck(glMatrixMode(GL_MODELVIEW));
GLCheck(glPopMatrix());
GLCheck(glPopAttrib());
GLCheck(glPopClientAttrib());
}
// Clear everything
Clear();
}
////////////////////////////////////////////////////////////
void RenderQueue::Clear()
{
// Reset the vertex and index counts
myCurrentVertexCount = 0;
myCurrentIndexCount = 0;
// Clear the batches
myBatches.clear();
myCurrentBatch = NULL;
}
} // namespace sf

View File

@ -37,9 +37,7 @@ namespace sf
/// Default constructor /// Default constructor
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
RenderTarget::RenderTarget() : RenderTarget::RenderTarget() :
myCurrentView (&myDefaultView), myCurrentView(&myDefaultView)
myPreserveStates(false),
myIsDrawing (false)
{ {
} }
@ -61,10 +59,13 @@ void RenderTarget::Clear(const Color& color)
{ {
if (Activate(true)) if (Activate(true))
{ {
// Clear the frame buffer // Clear the color buffer
GLCheck(glClearColor(color.r / 255.f, color.g / 255.f, color.b / 255.f, color.a / 255.f)); GLCheck(glClearColor(color.r / 255.f, color.g / 255.f, color.b / 255.f, color.a / 255.f));
GLCheck(glClear(GL_COLOR_BUFFER_BIT)); GLCheck(glClear(GL_COLOR_BUFFER_BIT));
// Clear the render queue
myRenderQueue.Clear();
Activate(false); Activate(false);
} }
} }
@ -75,59 +76,34 @@ void RenderTarget::Clear(const Color& color)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void RenderTarget::Draw(const Drawable& object) void RenderTarget::Draw(const Drawable& object)
{ {
// Check whether we are called from the outside or from a previous call to Draw // Save the current render states
if (!myIsDrawing) myRenderQueue.PushStates();
// Setup the viewport
myRenderQueue.SetViewport(GetViewport(*myCurrentView));
// Setup the projection matrix
myRenderQueue.SetProjection(myCurrentView->GetMatrix());
// Let the object draw itself
object.Draw(*this, myRenderQueue);
// Restore the previous render states
myRenderQueue.PopStates();
}
////////////////////////////////////////////////////////////
/// Make sure that what has been drawn so far is rendered
////////////////////////////////////////////////////////////
void RenderTarget::Flush()
{
if (Activate(true))
{ {
myIsDrawing = true; // Draw the whole render queue
myRenderQueue.Render();
// Set our target as the current target for rendering Activate(false);
if (Activate(true))
{
// 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();
}
// Setup the viewport
const FloatRect& viewport = myCurrentView->GetViewport();
int left = static_cast<int>(0.5f + GetWidth() * viewport.Left);
int top = static_cast<int>(0.5f + GetHeight() * (1.f - viewport.Bottom));
int width = static_cast<int>(0.5f + GetWidth() * viewport.GetSize().x);
int height = static_cast<int>(0.5f + GetHeight() * viewport.GetSize().y);
GLCheck(glViewport(left, top, width, height));
// Setup the transform matrices
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());
}
// Deactivate rendering on this target
Activate(false);
}
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);
} }
} }
@ -160,16 +136,48 @@ View& RenderTarget::GetDefaultView()
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Tell SFML to preserve external OpenGL states, at the expense of /// Get the viewport of a view applied to this target
/// 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 RenderTarget::PreserveOpenGLStates(bool preserve) IntRect RenderTarget::GetViewport(const View& view) const
{ {
myPreserveStates = preserve; float width = static_cast<float>(GetWidth());
float height = static_cast<float>(GetHeight());
const FloatRect& viewport = view.GetViewport();
IntRect rect;
rect.Left = static_cast<int>(0.5f + width * viewport.Left);
rect.Top = static_cast<int>(0.5f + height * (1.f - viewport.Bottom));
rect.Right = static_cast<int>(0.5f + width * viewport.Right);
rect.Bottom = static_cast<int>(0.5f + height * (1.f - viewport.Top));
return rect;
}
////////////////////////////////////////////////////////////
/// Convert a point in window coordinates into view coordinates
/// This version uses the current view of the window
////////////////////////////////////////////////////////////
sf::Vector2f RenderTarget::ConvertCoords(unsigned int x, unsigned int y) const
{
return ConvertCoords(x, y, GetView());
}
////////////////////////////////////////////////////////////
/// Convert a point in window coordinates into view coordinates
/// This version uses the given view
////////////////////////////////////////////////////////////
sf::Vector2f RenderTarget::ConvertCoords(unsigned int x, unsigned int y, const View& view) const
{
// First, convert from viewport coordinates to homogeneous coordinates
Vector2f coords;
IntRect viewport = GetViewport(view);
coords.x = -1.f + 2.f * (static_cast<int>(x) - viewport.Left) / viewport.GetSize().x;
coords.y = 1.f - 2.f * (static_cast<int>(y) - viewport.Top) / viewport.GetSize().y;
// Then transform by the inverse of the view matrix
return view.GetInverseMatrix().Transform(coords);
} }
@ -178,28 +186,12 @@ void RenderTarget::PreserveOpenGLStates(bool preserve)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void RenderTarget::Initialize() void RenderTarget::Initialize()
{ {
if (Activate(true)) // Setup the default view
{ myDefaultView.Reset(FloatRect(0, 0, static_cast<float>(GetWidth()), static_cast<float>(GetHeight())));
// Set the default rendering states SetView(myDefaultView);
SetRenderStates();
// Setup the default view // Clear the render queue
myDefaultView.Reset(FloatRect(0, 0, static_cast<float>(GetWidth()), static_cast<float>(GetHeight()))); myRenderQueue.Clear();
SetView(myDefaultView);
Activate(false);
}
}
////////////////////////////////////////////////////////////
/// Set the OpenGL render states needed for the SFML rendering
////////////////////////////////////////////////////////////
void RenderTarget::SetRenderStates()
{
GLCheck(glDisable(GL_ALPHA_TEST));
GLCheck(glDisable(GL_DEPTH_TEST));
GLCheck(glDisable(GL_LIGHTING));
} }
} // namespace sf } // namespace sf

View File

@ -75,11 +75,7 @@ RenderWindow::~RenderWindow()
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
bool RenderWindow::Activate(bool active) bool RenderWindow::Activate(bool active)
{ {
// For performances and consistency reasons, we only handle activation return SetActive(active);
if (active)
return SetActive();
else
return true;
} }
@ -101,70 +97,6 @@ unsigned int RenderWindow::GetHeight() const
} }
////////////////////////////////////////////////////////////
/// Save the content of the window to an image
////////////////////////////////////////////////////////////
Image RenderWindow::Capture() const
{
// Get the window dimensions
const unsigned int width = GetWidth();
const unsigned int height = GetHeight();
// Set our window as the current target for rendering
if (SetActive())
{
// Get pixels from the backbuffer
std::vector<Uint8> pixels(width * height * 4);
Uint8* ptr = &pixels[0];
GLCheck(glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, ptr));
// Flip the pixels
unsigned int pitch = width * 4;
for (unsigned int y = 0; y < height / 2; ++y)
std::swap_ranges(ptr + y * pitch, ptr + (y + 1) * pitch, ptr + (height - y - 1) * pitch);
// Create an image from the pixel buffer and return it
return Image(width, height, ptr);
}
else
{
return Image(width, height, Color::White);
}
}
////////////////////////////////////////////////////////////
/// Convert a point in window coordinates into view coordinates
/// This version uses the current view of the window
////////////////////////////////////////////////////////////
sf::Vector2f RenderWindow::ConvertCoords(unsigned int x, unsigned int y) const
{
return ConvertCoords(x, y, GetView());
}
////////////////////////////////////////////////////////////
/// Convert a point in window coordinates into view coordinates
/// This version uses the given view
////////////////////////////////////////////////////////////
sf::Vector2f RenderWindow::ConvertCoords(unsigned int x, unsigned int y, const View& view) const
{
// First, convert from viewport coordinates to homogeneous coordinates
const FloatRect& viewport = view.GetViewport();
int left = static_cast<int>(0.5f + GetWidth() * viewport.Left);
int top = static_cast<int>(0.5f + GetHeight() * viewport.Top);
int width = static_cast<int>(0.5f + GetWidth() * viewport.GetSize().x);
int height = static_cast<int>(0.5f + GetHeight() * viewport.GetSize().y);
Vector2f coords;
coords.x = -1.f + 2.f * (static_cast<int>(x) - left) / width;
coords.y = 1.f - 2.f * (static_cast<int>(y) - top) / height;
// Then transform by the inverse of the view matrix
return view.GetInverseMatrix().Transform(coords);
}
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Called after the window has been created /// Called after the window has been created
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -174,4 +106,14 @@ void RenderWindow::OnCreate()
RenderTarget::Initialize(); RenderTarget::Initialize();
} }
////////////////////////////////////////////////////////////
/// Called before the window has been displayed
////////////////////////////////////////////////////////////
void RenderWindow::OnDisplay()
{
// Render the drawables drawn so far
Flush();
}
} // namespace sf } // namespace sf

View File

@ -26,7 +26,7 @@
// Headers // Headers
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#include <SFML/Graphics/Shape.hpp> #include <SFML/Graphics/Shape.hpp>
#include <SFML/Graphics/GLCheck.hpp> #include <SFML/Graphics/RenderQueue.hpp>
#include <math.h> #include <math.h>
@ -281,7 +281,7 @@ Shape Shape::Circle(const Vector2f& center, float radius, const Color& color, fl
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// /see Drawable::Render /// /see Drawable::Render
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void Shape::Render(RenderTarget&) const void Shape::Render(RenderTarget&, RenderQueue& queue) const
{ {
// Make sure the shape has at least 3 points (4 if we count the center) // Make sure the shape has at least 3 points (4 if we count the center)
if (myPoints.size() < 4) if (myPoints.size() < 4)
@ -292,50 +292,69 @@ void Shape::Render(RenderTarget&) const
const_cast<Shape*>(this)->Compile(); const_cast<Shape*>(this)->Compile();
// Shapes only use color, no texture // Shapes only use color, no texture
GLCheck(glDisable(GL_TEXTURE_2D)); queue.SetTexture(NULL);
// Draw the shape // Draw the shape
if (myIsFillEnabled) if (myIsFillEnabled)
{ {
glBegin(GL_TRIANGLE_FAN); if (myPoints.size() == 4)
{ {
// Special case of a triangle
queue.BeginBatch();
queue.AddVertex(myPoints[1].Position.x, myPoints[1].Position.y, myPoints[1].Col);
queue.AddVertex(myPoints[2].Position.x, myPoints[2].Position.y, myPoints[2].Col);
queue.AddVertex(myPoints[3].Position.x, myPoints[3].Position.y, myPoints[3].Col);
queue.AddTriangle(0, 1, 2);
}
else if (myPoints.size() == 5)
{
// Special case of a quad
queue.BeginBatch();
queue.AddVertex(myPoints[1].Position.x, myPoints[1].Position.y, myPoints[1].Col);
queue.AddVertex(myPoints[2].Position.x, myPoints[2].Position.y, myPoints[2].Col);
queue.AddVertex(myPoints[3].Position.x, myPoints[3].Position.y, myPoints[3].Col);
queue.AddVertex(myPoints[4].Position.x, myPoints[4].Position.y, myPoints[4].Col);
queue.AddTriangle(0, 1, 3);
queue.AddTriangle(3, 1, 2);
}
else
{
// General case of a convex polygon
queue.BeginBatch();
for (std::vector<Point>::const_iterator i = myPoints.begin(); i != myPoints.end(); ++i) for (std::vector<Point>::const_iterator i = myPoints.begin(); i != myPoints.end(); ++i)
{ queue.AddVertex(i->Position.x, i->Position.y, i->Col);
Color color = i->Col * GetColor();
glColor4ub(color.r, color.g, color.b, color.a); for (std::size_t i = 1; i < myPoints.size() - 1; ++i)
glVertex2f(i->Position.x, i->Position.y); queue.AddTriangle(0, i, i + 1);
}
// Close the shape by duplicating the first point at the end // Close the shape by duplicating the first point at the end
Color color = myPoints[1].Col * GetColor(); queue.AddTriangle(0, myPoints.size() - 1, 1);
glColor4ub(color.r, color.g, color.b, color.a);
glVertex2f(myPoints[1].Position.x, myPoints[1].Position.y);
} }
glEnd();
} }
// Draw the outline // Draw the outline
if (myIsOutlineEnabled) if (myIsOutlineEnabled && (myOutline != 0))
{ {
glBegin(GL_TRIANGLE_STRIP); queue.BeginBatch();
for (std::vector<Point>::const_iterator i = myPoints.begin() + 1; i != myPoints.end(); ++i)
{ {
for (std::size_t i = 1; i < myPoints.size(); ++i) Vector2f point1 = i->Position;
{ Vector2f point2 = i->Position + i->Normal * myOutline;
Color color = myPoints[i].OutlineCol * GetColor(); queue.AddVertex(point1.x, point1.y, i->OutlineCol);
glColor4ub(color.r, color.g, color.b, color.a); queue.AddVertex(point2.x, point2.y, i->OutlineCol);
glVertex2f(myPoints[i].Position.x, myPoints[i].Position.y);
glColor4ub(color.r, color.g, color.b, color.a);
glVertex2f(myPoints[i].Position.x + myPoints[i].Normal.x * myOutline, myPoints[i].Position.y + myPoints[i].Normal.y * myOutline);
}
// Close the shape by duplicating the first point at the end
Color color = myPoints[1].OutlineCol * GetColor();
glColor4ub(color.r, color.g, color.b, color.a);
glVertex2f(myPoints[1].Position.x, myPoints[1].Position.y);
glColor4ub(color.r, color.g, color.b, color.a);
glVertex2f(myPoints[1].Position.x + myPoints[1].Normal.x * myOutline, myPoints[1].Position.y + myPoints[1].Normal.y * myOutline);
} }
glEnd();
for (std::size_t i = 0; i < myPoints.size() - 2; ++i)
{
queue.AddTriangle(i * 2 + 0, i * 2 + 1, i * 2 + 2);
queue.AddTriangle(i * 2 + 2, i * 2 + 1, i * 2 + 3);
}
// Close the shape by duplicating the first point at the end
unsigned int begin = 0;
unsigned int last = (myPoints.size() - 2) * 2;
queue.AddTriangle(last, last + 1, begin);
queue.AddTriangle(begin, last + 1, begin + 1);
} }
} }
@ -351,16 +370,17 @@ void Shape::Compile()
Point center(Vector2f(0, 0), Color(0, 0, 0, 0)); Point center(Vector2f(0, 0), Color(0, 0, 0, 0));
for (std::size_t i = 1; i < myPoints.size(); ++i) for (std::size_t i = 1; i < myPoints.size(); ++i)
{ {
center.Position += myPoints[i].Position / nbPoints; center.Position += myPoints[i].Position;
r += myPoints[i].Col.r / nbPoints; r += myPoints[i].Col.r;
g += myPoints[i].Col.g / nbPoints; g += myPoints[i].Col.g;
b += myPoints[i].Col.b / nbPoints; b += myPoints[i].Col.b;
a += myPoints[i].Col.a / nbPoints; a += myPoints[i].Col.a;
} }
center.Col.r = static_cast<Uint8>(r); center.Position /= nbPoints;
center.Col.g = static_cast<Uint8>(g); center.Col.r = static_cast<Uint8>(r / nbPoints);
center.Col.b = static_cast<Uint8>(b); center.Col.g = static_cast<Uint8>(g / nbPoints);
center.Col.a = static_cast<Uint8>(a); center.Col.b = static_cast<Uint8>(b / nbPoints);
center.Col.a = static_cast<Uint8>(a / nbPoints);
myPoints[0] = center; myPoints[0] = center;
// Compute the outline // Compute the outline

View File

@ -27,7 +27,8 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#include <SFML/Graphics/Sprite.hpp> #include <SFML/Graphics/Sprite.hpp>
#include <SFML/Graphics/Image.hpp> #include <SFML/Graphics/Image.hpp>
#include <SFML/Graphics/GLCheck.hpp> #include <SFML/Graphics/RenderQueue.hpp>
#include <utility>
namespace sf namespace sf
@ -181,50 +182,32 @@ Color Sprite::GetPixel(unsigned int x, unsigned int y) const
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// /see Drawable::Render /// /see Drawable::Render
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void Sprite::Render(RenderTarget&) const void Sprite::Render(RenderTarget&, RenderQueue& queue) const
{ {
// Get the sprite size // Get the sprite size
float width = static_cast<float>(mySubRect.GetSize().x); float width = static_cast<float>(mySubRect.GetSize().x);
float height = static_cast<float>(mySubRect.GetSize().y); float height = static_cast<float>(mySubRect.GetSize().y);
// Check if the image is valid // Check if the image is valid, and calculate the texture coordinates
FloatRect coords;
if (myImage && (myImage->GetWidth() > 0) && (myImage->GetHeight() > 0)) if (myImage && (myImage->GetWidth() > 0) && (myImage->GetHeight() > 0))
{ {
// Use the "offset trick" to get pixel-perfect rendering coords = myImage->GetTexCoords(mySubRect);
// see http://www.opengl.org/resources/faq/technical/transformations.htm#tran0030 if (myIsFlippedX) std::swap(coords.Left, coords.Right);
GLCheck(glTranslatef(0.375f, 0.375f, 0.f)); if (myIsFlippedY) std::swap(coords.Top, coords.Bottom);
// Bind the texture
myImage->Bind();
// Calculate the texture coordinates
FloatRect texCoords = myImage->GetTexCoords(mySubRect);
FloatRect rect(myIsFlippedX ? texCoords.Right : texCoords.Left,
myIsFlippedY ? texCoords.Bottom : texCoords.Top,
myIsFlippedX ? texCoords.Left : texCoords.Right,
myIsFlippedY ? texCoords.Top : texCoords.Bottom);
// Draw the sprite's triangles
glBegin(GL_QUADS);
glTexCoord2f(rect.Left, rect.Top); glVertex2f(0, 0);
glTexCoord2f(rect.Left, rect.Bottom); glVertex2f(0, height);
glTexCoord2f(rect.Right, rect.Bottom); glVertex2f(width, height);
glTexCoord2f(rect.Right, rect.Top); glVertex2f(width, 0) ;
glEnd();
} }
else
{
// Disable texturing
GLCheck(glDisable(GL_TEXTURE_2D));
// Draw the sprite's triangles // Bind the texture
glBegin(GL_QUADS); queue.SetTexture(myImage);
glVertex2f(0, 0);
glVertex2f(0, height); // Draw the sprite's geometry
glVertex2f(width, height); queue.BeginBatch();
glVertex2f(width, 0); queue.AddVertex(0, 0, coords.Left, coords.Top);
glEnd(); queue.AddVertex(0, height, coords.Left, coords.Bottom);
} queue.AddVertex(width, height, coords.Right, coords.Bottom);
queue.AddVertex(width, 0, coords.Right, coords.Top);
queue.AddTriangle(0, 1, 3);
queue.AddTriangle(3, 1, 2);
} }
} // namespace sf } // namespace sf

View File

@ -27,8 +27,7 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#include <SFML/Graphics/String.hpp> #include <SFML/Graphics/String.hpp>
#include <SFML/Graphics/Image.hpp> #include <SFML/Graphics/Image.hpp>
#include <SFML/Graphics/GLCheck.hpp> #include <SFML/Graphics/RenderQueue.hpp>
#include <locale>
namespace sf namespace sf
@ -210,7 +209,7 @@ FloatRect String::GetRect() const
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// /see sfDrawable::Render /// /see sfDrawable::Render
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void String::Render(RenderTarget&) const void String::Render(RenderTarget&, RenderQueue& queue) const
{ {
// First get the internal UTF-32 string of the text // First get the internal UTF-32 string of the text
const Unicode::UTF32String& text = myText; const Unicode::UTF32String& text = myText;
@ -222,10 +221,9 @@ void String::Render(RenderTarget&) const
// Set the scaling factor to get the actual size // Set the scaling factor to get the actual size
float charSize = static_cast<float>(myFont->GetCharacterSize()); float charSize = static_cast<float>(myFont->GetCharacterSize());
float factor = mySize / charSize; float factor = mySize / charSize;
GLCheck(glScalef(factor, factor, 1.f));
// Bind the font texture // Bind the font texture
myFont->GetImage().Bind(); queue.SetTexture(&myFont->GetImage());
// Initialize the rendering coordinates // Initialize the rendering coordinates
float x = 0.f; float x = 0.f;
@ -239,7 +237,8 @@ void String::Render(RenderTarget&) const
float italicCoeff = (myStyle & Italic) ? 0.208f : 0.f; // 12 degrees float italicCoeff = (myStyle & Italic) ? 0.208f : 0.f; // 12 degrees
// Draw one quad for each character // Draw one quad for each character
glBegin(GL_QUADS); unsigned int index = 0;
queue.BeginBatch();
for (std::size_t i = 0; i < text.size(); ++i) for (std::size_t i = 0; i < text.size(); ++i)
{ {
// Get the current character and its corresponding glyph // Get the current character and its corresponding glyph
@ -267,31 +266,67 @@ void String::Render(RenderTarget&) const
} }
// Draw a textured quad for the current character // Draw a textured quad for the current character
glTexCoord2f(coord.Left, coord.Top); glVertex2f(x + rect.Left - italicCoeff * rect.Top, y + rect.Top); queue.AddVertex(factor * (x + rect.Left - italicCoeff * rect.Top), factor * (y + rect.Top), coord.Left, coord.Top);
glTexCoord2f(coord.Left, coord.Bottom); glVertex2f(x + rect.Left - italicCoeff * rect.Bottom, y + rect.Bottom); queue.AddVertex(factor * (x + rect.Left - italicCoeff * rect.Bottom), factor * (y + rect.Bottom), coord.Left, coord.Bottom);
glTexCoord2f(coord.Right, coord.Bottom); glVertex2f(x + rect.Right - italicCoeff * rect.Bottom, y + rect.Bottom); queue.AddVertex(factor * (x + rect.Right - italicCoeff * rect.Bottom), factor * (y + rect.Bottom), coord.Right, coord.Bottom);
glTexCoord2f(coord.Right, coord.Top); glVertex2f(x + rect.Right - italicCoeff * rect.Top, y + rect.Top); queue.AddVertex(factor * (x + rect.Right - italicCoeff * rect.Top), factor * (y + rect.Top), coord.Right, coord.Top);
// If we're using the bold style, we must render the character 4 more times, queue.AddTriangle(index + 0, index + 1, index + 3);
// slightly offseted, to simulate a higher weight queue.AddTriangle(index + 3, index + 1, index + 2);
if (myStyle & Bold) index += 4;
{
static const float offsetsX[] = {-0.5f, 0.5f, 0.f, 0.f};
static const float offsetsY[] = {0.f, 0.f, -0.5f, 0.5f};
for (int j = 0; j < 4; ++j)
{
glTexCoord2f(coord.Left, coord.Top); glVertex2f(x + offsetsX[j] + rect.Left - italicCoeff * rect.Top, y + offsetsY[j] + rect.Top);
glTexCoord2f(coord.Left, coord.Bottom); glVertex2f(x + offsetsX[j] + rect.Left - italicCoeff * rect.Bottom, y + offsetsY[j] + rect.Bottom);
glTexCoord2f(coord.Right, coord.Bottom); glVertex2f(x + offsetsX[j] + rect.Right - italicCoeff * rect.Bottom, y + offsetsY[j] + rect.Bottom);
glTexCoord2f(coord.Right, coord.Top); glVertex2f(x + offsetsX[j] + rect.Right - italicCoeff * rect.Top, y + offsetsY[j] + rect.Top);
}
}
// Advance to the next character // Advance to the next character
x += advance; x += advance;
} }
glEnd();
// If we're using the bold style, we must render the string 4 more times,
// slightly offseted, to simulate a higher weight
if (myStyle & Bold)
{
float offset = mySize * 0.02f;
static const float offsetsX[] = {-offset, offset, 0.f, 0.f};
static const float offsetsY[] = {0.f, 0.f, -offset, offset};
for (int j = 0; j < 4; ++j)
{
index = 0;
x = 0.f;
y = charSize;
queue.BeginBatch();
for (std::size_t i = 0; i < text.size(); ++i)
{
// Get the current character and its corresponding glyph
Uint32 curChar = text[i];
const Glyph& curGlyph = myFont->GetGlyph(curChar);
int advance = curGlyph.Advance;
const IntRect& rect = curGlyph.Rectangle;
const FloatRect& coord = curGlyph.TexCoords;
// Handle special characters
switch (curChar)
{
case L' ' : x += advance; continue;
case L'\n' : y += charSize; x = 0; continue;
case L'\t' : x += advance * 4; continue;
case L'\v' : y += charSize * 4; continue;
}
// Draw a textured quad for the current character
queue.AddVertex(factor * (x + offsetsX[j] + rect.Left - italicCoeff * rect.Top), factor * (y + offsetsY[j] + rect.Top), coord.Left, coord.Top);
queue.AddVertex(factor * (x + offsetsX[j] + rect.Left - italicCoeff * rect.Bottom), factor * (y + offsetsY[j] + rect.Bottom), coord.Left, coord.Bottom);
queue.AddVertex(factor * (x + offsetsX[j] + rect.Right - italicCoeff * rect.Bottom), factor * (y + offsetsY[j] + rect.Bottom), coord.Right, coord.Bottom);
queue.AddVertex(factor * (x + offsetsX[j] + rect.Right - italicCoeff * rect.Top), factor * (y + offsetsY[j] + rect.Top), coord.Right, coord.Top);
queue.AddTriangle(index + 0, index + 1, index + 3);
queue.AddTriangle(index + 3, index + 1, index + 2);
index += 4;
// Advance to the next character
x += advance;
}
}
}
// Draw the underlines if needed // Draw the underlines if needed
if (myStyle & Underlined) if (myStyle & Underlined)
@ -304,16 +339,20 @@ void String::Render(RenderTarget&) const
underlineCoords.push_back(y + 2); underlineCoords.push_back(y + 2);
// Draw the underlines as quads // Draw the underlines as quads
GLCheck(glDisable(GL_TEXTURE_2D)); index = 0;
glBegin(GL_QUADS); queue.SetTexture(NULL);
queue.BeginBatch();
for (std::size_t i = 0; i < underlineCoords.size(); i += 2) for (std::size_t i = 0; i < underlineCoords.size(); i += 2)
{ {
glVertex2f(0, underlineCoords[i + 1]); queue.AddVertex(factor * (0), factor * (underlineCoords[i + 1]));
glVertex2f(0, underlineCoords[i + 1] + thickness); queue.AddVertex(factor * (0), factor * (underlineCoords[i + 1] + thickness));
glVertex2f(underlineCoords[i], underlineCoords[i + 1] + thickness); queue.AddVertex(factor * (underlineCoords[i]), factor * (underlineCoords[i + 1] + thickness));
glVertex2f(underlineCoords[i], underlineCoords[i + 1]); queue.AddVertex(factor * (underlineCoords[i]), factor * (underlineCoords[i + 1]));
queue.AddTriangle(index + 0, index + 1, index + 3);
queue.AddTriangle(index + 3, index + 1, index + 2);
index += 4;
} }
glEnd();
} }
} }

View File

@ -179,7 +179,8 @@ bool RenderImageImplPBuffer::Activate(bool active)
} }
else else
{ {
// We don't actually unbind the P-Buffer, for performances reasons // We don't actually unbind the P-Buffer,
// for performances and consistency reasons
} }
return true; return true;

View File

@ -140,21 +140,17 @@ void Window::Create(VideoMode mode, const std::string& title, unsigned long styl
delete myWindow; delete myWindow;
myWindow = priv::WindowImpl::New(mode, title, style); myWindow = priv::WindowImpl::New(mode, title, style);
{ // Make sure another context is bound, so that:
// Make sure another context is bound, so that: // - the context creation can request OpenGL extensions if necessary
// - the context creation can request OpenGL extensions if necessary // - myContext can safely be destroyed (it's no longer bound)
// - myContext can safely be destroyed (it's no longer bound) Context context;
Context context;
// Recreate the context // Recreate the context
delete myContext; delete myContext;
myContext = priv::ContextGL::New(myWindow, mode.BitsPerPixel, settings); myContext = priv::ContextGL::New(myWindow, mode.BitsPerPixel, settings);
Initialize(); // Perform common initializations
} Initialize();
// Activate the window's context
SetActive();
} }
@ -167,21 +163,17 @@ void Window::Create(WindowHandle handle, const ContextSettings& settings)
Close(); Close();
myWindow = priv::WindowImpl::New(handle); myWindow = priv::WindowImpl::New(handle);
{ // Make sure another context is bound, so that:
// Make sure another context is bound, so that: // - the context creation can request OpenGL extensions if necessary
// - the context creation can request OpenGL extensions if necessary // - myContext can safely be destroyed (it's no longer bound)
// - myContext can safely be destroyed (it's no longer bound) Context context;
Context context;
// Recreate the context // Recreate the context
delete myContext; delete myContext;
myContext = priv::ContextGL::New(myWindow, VideoMode::GetDesktopMode().BitsPerPixel, settings); myContext = priv::ContextGL::New(myWindow, VideoMode::GetDesktopMode().BitsPerPixel, settings);
Initialize(); // Perform common initializations
} Initialize();
// Activate the window's context
SetActive();
} }
@ -391,6 +383,9 @@ bool Window::SetActive(bool active) const
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void Window::Display() void Window::Display()
{ {
// Notify the derived class
OnDisplay();
// Limit the framerate if needed // Limit the framerate if needed
if (myFramerateLimit > 0) if (myFramerateLimit > 0)
{ {
@ -404,8 +399,11 @@ void Window::Display()
myClock.Reset(); myClock.Reset();
// Display the backbuffer on screen // Display the backbuffer on screen
if (SetActive()) if (SetActive(true))
{
myContext->Display(); myContext->Display();
SetActive(false);
}
} }
@ -456,6 +454,15 @@ void Window::OnCreate()
} }
////////////////////////////////////////////////////////////
/// Called before the window has been displayed
////////////////////////////////////////////////////////////
void Window::OnDisplay()
{
// Nothing by default
}
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Receive an event from window /// Receive an event from window
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////