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_GetView
sfRenderImage_GetDefaultView
sfRenderImage_PreserveOpenGLStates
sfRenderImage_GetViewport
sfRenderImage_ConvertCoords
sfRenderImage_GetImage
sfRenderImage_CanUseRenderImage
sfRenderWindow_Create
@ -214,8 +215,8 @@ EXPORTS
sfRenderWindow_SetView
sfRenderWindow_GetView
sfRenderWindow_GetDefaultView
sfRenderWindow_GetViewport
sfRenderWindow_ConvertCoords
sfRenderWindow_PreserveOpenGLStates
sfView_Create
sfView_CreateFromRect
sfView_Destroy

View File

@ -134,18 +134,28 @@ CSFML_API const sfView* sfRenderImage_GetView(sfRenderImage* renderImage);
CSFML_API sfView* sfRenderImage_GetDefaultView(sfRenderImage* renderImage);
////////////////////////////////////////////////////////////
/// Tell SFML to preserve external OpenGL states, at the expense of
/// more CPU charge. Use this function if you don't want SFML
/// to mess up your own OpenGL states (if any).
/// Don't enable state preservation if not needed, as it will allow
/// SFML to do internal optimizations and improve performances.
/// This parameter is false by default
/// Get the viewport of a view applied to this target
///
/// \param renderImage : Target renderimage
/// \param preserve : True to preserve OpenGL states, false to let SFML optimize
/// \param renderImage : Renderimage object
/// \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

View File

@ -320,6 +320,17 @@ CSFML_API const sfView* sfRenderWindow_GetView(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
///
@ -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);
////////////////////////////////////////////////////////////
/// 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

View File

@ -157,16 +157,39 @@ sfView* sfRenderImage_GetDefaultView(sfRenderImage* renderImage)
////////////////////////////////////////////////////////////
/// Tell SFML to preserve external OpenGL states, at the expense of
/// more CPU charge. Use this function if you don't want SFML
/// to mess up your own OpenGL states (if any).
/// Don't enable state preservation if not needed, as it will allow
/// SFML to do internal optimizations and improve performances.
/// This parameter is false by default
/// Get the viewport of a view applied to this target
////////////////////////////////////////////////////////////
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
////////////////////////////////////////////////////////////
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
sf::VideoMode VideoMode(Mode.Width, Mode.Height, Mode.BitsPerPixel);
sf::VideoMode videoMode(mode.Width, mode.Height, mode.BitsPerPixel);
// Create the window
sfRenderWindow* RenderWindow = new sfRenderWindow;
sf::ContextSettings Settings(Params.DepthBits, Params.StencilBits, Params.AntialiasingLevel);
RenderWindow->This.Create(VideoMode, Title, Style, Settings);
RenderWindow->Input.This = &RenderWindow->This.GetInput();
RenderWindow->DefaultView = new sfView(const_cast<sf::View*>(&RenderWindow->This.GetDefaultView()));
RenderWindow->CurrentView = RenderWindow->DefaultView;
sfRenderWindow* renderWindow = new sfRenderWindow;
sf::ContextSettings settings(params.DepthBits, params.StencilBits, params.AntialiasingLevel);
renderWindow->This.Create(videoMode, title, style, settings);
renderWindow->Input.This = &renderWindow->This.GetInput();
renderWindow->DefaultView = new sfView(const_cast<sf::View*>(&renderWindow->This.GetDefaultView()));
renderWindow->CurrentView = renderWindow->DefaultView;
return RenderWindow;
return renderWindow;
}
////////////////////////////////////////////////////////////
/// 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;
sf::ContextSettings Settings(Params.DepthBits, Params.StencilBits, Params.AntialiasingLevel);
RenderWindow->This.Create(Handle, Settings);
RenderWindow->Input.This = &RenderWindow->This.GetInput();
RenderWindow->DefaultView = new sfView(const_cast<sf::View*>(&RenderWindow->This.GetDefaultView()));
RenderWindow->CurrentView = RenderWindow->DefaultView;
sfRenderWindow* renderWindow = new sfRenderWindow;
sf::ContextSettings settings(params.DepthBits, params.StencilBits, params.AntialiasingLevel);
renderWindow->This.Create(handle, settings);
renderWindow->Input.This = &renderWindow->This.GetInput();
renderWindow->DefaultView = new sfView(const_cast<sf::View*>(&renderWindow->This.GetDefaultView()));
renderWindow->CurrentView = renderWindow->DefaultView;
return RenderWindow;
return renderWindow;
}
////////////////////////////////////////////////////////////
/// Destroy an existing renderwindow
////////////////////////////////////////////////////////////
void sfRenderWindow_Destroy(sfRenderWindow* RenderWindow)
void sfRenderWindow_Destroy(sfRenderWindow* renderWindow)
{
delete RenderWindow->DefaultView;
delete RenderWindow;
delete renderWindow->DefaultView;
delete renderWindow;
}
////////////////////////////////////////////////////////////
/// 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
////////////////////////////////////////////////////////////
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
////////////////////////////////////////////////////////////
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
////////////////////////////////////////////////////////////
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
////////////////////////////////////////////////////////////
sfContextSettings sfRenderWindow_GetSettings(sfRenderWindow* RenderWindow)
sfContextSettings sfRenderWindow_GetSettings(sfRenderWindow* renderWindow)
{
sfContextSettings Settings = {0, 0, 0};
CSFML_CHECK_RETURN(RenderWindow, Settings);
sfContextSettings settings = {0, 0, 0};
CSFML_CHECK_RETURN(renderWindow, settings);
const sf::ContextSettings& Params = RenderWindow->This.GetSettings();
Settings.DepthBits = Params.DepthBits;
Settings.StencilBits = Params.StencilBits;
Settings.AntialiasingLevel = Params.AntialiasingLevel;
const sf::ContextSettings& params = renderWindow->This.GetSettings();
settings.DepthBits = params.DepthBits;
settings.StencilBits = params.StencilBits;
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
////////////////////////////////////////////////////////////
sfBool sfRenderWindow_GetEvent(sfRenderWindow* RenderWindow, sfEvent* Event)
sfBool sfRenderWindow_GetEvent(sfRenderWindow* renderWindow, sfEvent* event)
{
CSFML_CHECK_RETURN(RenderWindow, sfFalse);
CSFML_CHECK_RETURN(Event, sfFalse);
CSFML_CHECK_RETURN(renderWindow, sfFalse);
CSFML_CHECK_RETURN(event, sfFalse);
// Get the event
sf::Event SFMLEvent;
sfBool Ret = RenderWindow->This.GetEvent(SFMLEvent);
sfBool ret = renderWindow->This.GetEvent(SFMLEvent);
// No event, return
if (!Ret)
if (!ret)
return sfFalse;
// Convert its type
Event->Type = static_cast<sfEventType>(SFMLEvent.Type);
event->Type = static_cast<sfEventType>(SFMLEvent.Type);
// Fill its fields
switch (Event->Type)
switch (event->Type)
{
case sfEvtResized :
Event->Size.Width = SFMLEvent.Size.Width;
Event->Size.Height = SFMLEvent.Size.Height;
event->Size.Width = SFMLEvent.Size.Width;
event->Size.Height = SFMLEvent.Size.Height;
break;
case sfEvtTextEntered :
Event->Text.Unicode = SFMLEvent.Text.Unicode;
event->Text.Unicode = SFMLEvent.Text.Unicode;
break;
case sfEvtKeyReleased :
case sfEvtKeyPressed :
Event->Key.Code = static_cast<sfKeyCode>(SFMLEvent.Key.Code);
Event->Key.Alt = SFMLEvent.Key.Alt ? sfTrue : sfFalse;
Event->Key.Control = SFMLEvent.Key.Control ? sfTrue : sfFalse;
Event->Key.Shift = SFMLEvent.Key.Shift ? sfTrue : sfFalse;
event->Key.Code = static_cast<sfKeyCode>(SFMLEvent.Key.Code);
event->Key.Alt = SFMLEvent.Key.Alt ? sfTrue : sfFalse;
event->Key.Control = SFMLEvent.Key.Control ? sfTrue : sfFalse;
event->Key.Shift = SFMLEvent.Key.Shift ? sfTrue : sfFalse;
break;
case sfEvtMouseWheelMoved :
Event->MouseWheel.Delta = SFMLEvent.MouseWheel.Delta;
event->MouseWheel.Delta = SFMLEvent.MouseWheel.Delta;
break;
case sfEvtMouseButtonPressed :
case sfEvtMouseButtonReleased :
Event->MouseButton.Button = static_cast<sfMouseButton>(SFMLEvent.MouseButton.Button);
Event->MouseButton.X = SFMLEvent.MouseButton.X;
Event->MouseButton.Y = SFMLEvent.MouseButton.Y;
event->MouseButton.Button = static_cast<sfMouseButton>(SFMLEvent.MouseButton.Button);
event->MouseButton.X = SFMLEvent.MouseButton.X;
event->MouseButton.Y = SFMLEvent.MouseButton.Y;
break;
case sfEvtMouseMoved :
Event->MouseMove.X = SFMLEvent.MouseMove.X;
Event->MouseMove.Y = SFMLEvent.MouseMove.Y;
event->MouseMove.X = SFMLEvent.MouseMove.X;
event->MouseMove.Y = SFMLEvent.MouseMove.Y;
break;
case sfEvtJoyButtonPressed :
case sfEvtJoyButtonReleased :
Event->JoyButton.JoystickId = SFMLEvent.JoyButton.JoystickId;
Event->JoyButton.Button = SFMLEvent.JoyButton.Button;
event->JoyButton.JoystickId = SFMLEvent.JoyButton.JoystickId;
event->JoyButton.Button = SFMLEvent.JoyButton.Button;
break;
case sfEvtJoyMoved :
Event->JoyMove.JoystickId = SFMLEvent.JoyMove.JoystickId;
Event->JoyMove.Axis = static_cast<sfJoyAxis>(SFMLEvent.JoyMove.Axis);
Event->JoyMove.Position = SFMLEvent.JoyMove.Position;
event->JoyMove.JoystickId = SFMLEvent.JoyMove.JoystickId;
event->JoyMove.Axis = static_cast<sfJoyAxis>(SFMLEvent.JoyMove.Axis);
event->JoyMove.Position = SFMLEvent.JoyMove.Position;
break;
default :
@ -212,27 +212,27 @@ sfBool sfRenderWindow_GetEvent(sfRenderWindow* RenderWindow, sfEvent* Event)
////////////////////////////////////////////////////////////
/// 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
////////////////////////////////////////////////////////////
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
////////////////////////////////////////////////////////////
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.
/// 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
////////////////////////////////////////////////////////////
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
////////////////////////////////////////////////////////////
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.
/// 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
////////////////////////////////////////////////////////////
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
////////////////////////////////////////////////////////////
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
////////////////////////////////////////////////////////////
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
////////////////////////////////////////////////////////////
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
////////////////////////////////////////////////////////////
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
////////////////////////////////////////////////////////////
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
/// 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
////////////////////////////////////////////////////////////
void sfRenderWindow_DrawPostFX(sfRenderWindow* RenderWindow, sfPostFX* PostFX)
void sfRenderWindow_DrawPostFX(sfRenderWindow* renderWindow, sfPostFX* postFX)
{
CSFML_CHECK(PostFX);
CSFML_CALL(RenderWindow, Draw(PostFX->This));
CSFML_CHECK(postFX);
CSFML_CALL(renderWindow, Draw(postFX->This));
}
void sfRenderWindow_DrawShape(sfRenderWindow* RenderWindow, sfShape* Shape)
void sfRenderWindow_DrawShape(sfRenderWindow* renderWindow, sfShape* shape)
{
CSFML_CHECK(Shape);
CSFML_CALL(RenderWindow, Draw(Shape->This));
CSFML_CHECK(shape);
CSFML_CALL(renderWindow, Draw(shape->This));
}
void sfRenderWindow_DrawSprite(sfRenderWindow* RenderWindow, sfSprite* Sprite)
void sfRenderWindow_DrawSprite(sfRenderWindow* renderWindow, sfSprite* sprite)
{
CSFML_CHECK(Sprite);
CSFML_CALL(RenderWindow, Draw(Sprite->This));
CSFML_CHECK(sprite);
CSFML_CALL(renderWindow, Draw(sprite->This));
}
void sfRenderWindow_DrawString(sfRenderWindow* RenderWindow, sfString* String)
void sfRenderWindow_DrawString(sfRenderWindow* renderWindow, sfString* string)
{
CSFML_CHECK(String);
CSFML_CALL(RenderWindow, Draw(String->This));
CSFML_CHECK(string);
CSFML_CALL(renderWindow, Draw(string->This));
}
////////////////////////////////////////////////////////////
/// 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;
*Image->This = RenderWindow->This.Capture();
sfImage* image = new sfImage;
*image->This = renderWindow->This.Capture();
return Image;
return image;
}
////////////////////////////////////////////////////////////
/// 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
////////////////////////////////////////////////////////////
void sfRenderWindow_SetView(sfRenderWindow* RenderWindow, sfView* View)
void sfRenderWindow_SetView(sfRenderWindow* renderWindow, sfView* view)
{
CSFML_CHECK(View);
CSFML_CALL(RenderWindow, SetView(*View->This));
RenderWindow->CurrentView = View;
CSFML_CHECK(view);
CSFML_CALL(renderWindow, SetView(*view->This));
renderWindow->CurrentView = view;
}
////////////////////////////////////////////////////////////
/// 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
////////////////////////////////////////////////////////////
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
////////////////////////////////////////////////////////////
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;
if (TargetView)
Point = RenderWindow->This.ConvertCoords(WindowX, WindowY, *TargetView->This);
sf::Vector2f point;
if (targetView)
point = renderWindow->This.ConvertCoords(windowX, windowY, *targetView->This);
else
Point = RenderWindow->This.ConvertCoords(WindowX, WindowY);
point = renderWindow->This.ConvertCoords(windowX, windowY);
if (ViewX) *ViewX = Point.x;
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));
if (viewX) *viewX = point.x;
if (viewY) *viewY = point.y;
}

View File

@ -128,12 +128,15 @@
<Unit filename="..\..\include\SFML\Graphics\Rect.hpp" />
<Unit filename="..\..\include\SFML\Graphics\Rect.inl" />
<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\RenderWindow.hpp" />
<Unit filename="..\..\include\SFML\Graphics\Shape.hpp" />
<Unit filename="..\..\include\SFML\Graphics\Sprite.hpp" />
<Unit filename="..\..\include\SFML\Graphics\String.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\Drawable.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\glxew.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\ImageLoader.cpp" />
<Unit filename="..\..\src\SFML\Graphics\ImageLoader.hpp" />
@ -159,6 +170,7 @@
<Unit filename="..\..\src\SFML\Graphics\RenderImageImplFBO.cpp" />
<Unit filename="..\..\src\SFML\Graphics\RenderImageImplFBO.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\RenderWindow.cpp" />
<Unit filename="..\..\src\SFML\Graphics\SOIL\SOIL.c">

View File

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

View File

@ -362,18 +362,6 @@
<References>
</References>
<Files>
<Filter
Name="Win32"
>
<File
RelativePath="..\..\src\SFML\Graphics\Win32\RenderImageImplPBuffer.cpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\Win32\RenderImageImplPBuffer.hpp"
>
</File>
</Filter>
<Filter
Name="External libs"
>
@ -3298,6 +3286,138 @@
</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\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
RelativePath="..\..\src\SFML\Graphics\Color.cpp"
>
@ -3306,14 +3426,6 @@
RelativePath="..\..\include\SFML\Graphics\Color.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\Drawable.cpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Graphics\Drawable.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\Font.cpp"
>
@ -3418,34 +3530,6 @@
RelativePath="..\..\include\SFML\Graphics\Rect.inl"
>
</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
RelativePath="..\..\src\SFML\Graphics\RenderTarget.cpp"
>
@ -3462,30 +3546,6 @@
RelativePath="..\..\include\SFML\Graphics\RenderWindow.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>
<File
RelativePath="..\..\src\SFML\Graphics\View.cpp"
>

View File

@ -324,6 +324,7 @@
WarningLevel="4"
DebugInformationFormat="0"
DisableSpecificWarnings="4996"
EnablePREfast="false"
/>
<Tool
Name="VCManagedResourceCompilerTool"
@ -361,14 +362,61 @@
</References>
<Files>
<Filter
Name="Win32"
Name="RenderQueue"
>
<File
RelativePath="..\..\src\SFML\Graphics\Win32\RenderImageImplPBuffer.cpp"
RelativePath="..\..\src\SFML\Graphics\Batch.cpp"
>
</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>
</Filter>
@ -3296,6 +3344,94 @@
</File>
</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
RelativePath="..\..\src\SFML\Graphics\Color.cpp"
>
@ -3304,14 +3440,6 @@
RelativePath="..\..\include\SFML\Graphics\Color.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\Drawable.cpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Graphics\Drawable.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\Font.cpp"
>
@ -3400,14 +3528,6 @@
RelativePath="..\..\include\SFML\Graphics\Matrix3.inl"
>
</File>
<File
RelativePath="..\..\src\SFML\Graphics\PostFX.cpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Graphics\PostFX.hpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Graphics\Rect.hpp"
>
@ -3416,34 +3536,6 @@
RelativePath="..\..\include\SFML\Graphics\Rect.inl"
>
</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
RelativePath="..\..\src\SFML\Graphics\RenderTarget.cpp"
>
@ -3460,30 +3552,6 @@
RelativePath="..\..\include\SFML\Graphics\RenderWindow.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>
<File
RelativePath="..\..\src\SFML\Graphics\View.cpp"
>

View File

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

View File

@ -104,18 +104,48 @@ namespace SFML
////////////////////////////////////////////////////////////
/// <summary>
/// Tell SFML to preserve external OpenGL states, at the expense of
/// more CPU charge. Use this function if you don't want SFML
/// to mess up your own OpenGL states (if any).
/// Don't enable state preservation if not needed, as it will allow
/// SFML to do internal optimizations and improve performances.
/// This parameter is false by default
/// Get the viewport of a view applied to this target
/// </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);
[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]
static extern void sfRenderImage_DrawPostFX(IntPtr This, IntPtr PostFx);

View File

@ -44,16 +44,37 @@ namespace SFML
////////////////////////////////////////////////////////////
/// <summary>
/// Tell SFML to preserve external OpenGL states, at the expense of
/// more CPU charge. Use this function if you don't want SFML
/// to mess up your own OpenGL states (if any).
/// Don't enable state preservation if not needed, as it will allow
/// SFML to do internal optimizations and improve performances.
/// This parameter is false by default
/// Get the viewport of a view applied to this target
/// </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>

View File

@ -317,49 +317,48 @@ namespace SFML
////////////////////////////////////////////////////////////
/// <summary>
/// Convert a point in window coordinates into view coordinates
/// using the current view of the window
/// Get the viewport of a view applied to this target
/// </summary>
/// <param name="windowX">X coordinate of the point to convert, relative to the window</param>
/// <param name="windowY">Y coordinate of the point to convert, relative to the window</param>
/// <returns>Converted point</returns>
/// <param name="view">Target view</param>
/// <returns>Viewport rectangle, expressed in pixels in the current target</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>
/// 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>
/// <param name="windowX">X coordinate of the point to convert, relative to the window</param>
/// <param name="windowY">Y coordinate of the point to convert, relative to the window</param>
/// <param name="targetView">Target view to convert the point to</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>
/// <returns>Converted point</returns>
///
////////////////////////////////////////////////////////////
public Vector2 ConvertCoords(uint windowX, uint windowY, View targetView)
public Vector2 ConvertCoords(uint x, uint y)
{
Vector2 Point;
sfRenderWindow_ConvertCoords(This, windowX, windowY, out Point.X, out Point.Y, targetView.This);
return Point;
return ConvertCoords(x, y, CurrentView);
}
////////////////////////////////////////////////////////////
/// <summary>
/// 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
/// Convert a point in target coordinates into view coordinates
/// This version uses the given view
/// </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);
[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]
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]
static extern void sfRenderWindow_DrawPostFX(IntPtr This, IntPtr PostFx);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -15,9 +15,11 @@
////////////////////////////////////////////////////////////
int main()
{
// Create main window
// Create the main window and activate it
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
sf::Image backgroundImage;
@ -75,13 +77,23 @@ int main()
// Adjust the viewport when the window is resized
if (event.Type == sf::Event::Resized)
{
window.SetActive();
glViewport(0, 0, event.Size.Width, event.Size.Height);
}
}
}
// Draw background
// Draw the 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);
// 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
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
sf::Clock clock;
@ -53,11 +56,6 @@ int main()
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
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
////////////////////////////////////////////////////////////
#include <SFML/Graphics/Drawable.hpp>
#include <SFML/Graphics/GLCheck.hpp>
#include <SFML/Window/Window.hpp>
#include <SFML/Graphics/RenderQueue.hpp>
#include <SFML/Graphics/RenderTarget.hpp>
#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
GLCheck(glMatrixMode(GL_MODELVIEW));
GLCheck(glPushMatrix());
GLCheck(glMultMatrixf(GetMatrix().Get4x4Elements()));
// Set the current model-view matrix
queue.ApplyModelView(GetMatrix());
// Setup alpha-blending
if (myBlendMode == Blend::None)
{
GLCheck(glDisable(GL_BLEND));
}
else
{
GLCheck(glEnable(GL_BLEND));
// Set the current global color
queue.ApplyColor(myColor);
// @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)
{
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));
// Set the current alpha-blending mode
queue.SetBlendMode(myBlendMode);
// Let the derived class render the object geometry
Render(target);
// Restore the previous modelview matrix
GLCheck(glMatrixMode(GL_MODELVIEW));
GLCheck(glPopMatrix());
Render(target, queue);
}
} // 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]));
}
// 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
unsigned int maxHeight = 0;
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;
// Make sure we don't go over the texture width
if (left + bitmap.width + 1 >= texWidth)
if (left + bitmap.width + margin >= texWidth)
left = 0;
// Compute the top coordinate
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++;
top += margin;
// 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;
glyphsBuffer.resize(texWidth * texHeight * 4);
}
// Store the character's position and size
curGlyph.Rectangle.Left = bitmapGlyph->left;
curGlyph.Rectangle.Top = -bitmapGlyph->top;
curGlyph.Rectangle.Right = curGlyph.Rectangle.Left + bitmap.width;
curGlyph.Rectangle.Bottom = bitmap.rows - bitmapGlyph->top;
curGlyph.Rectangle.Left = bitmapGlyph->left - offset;
curGlyph.Rectangle.Top = -bitmapGlyph->top - offset;
curGlyph.Rectangle.Right = (curGlyph.Rectangle.Left + bitmap.width + offset) / 1;
curGlyph.Rectangle.Bottom = bitmap.rows - bitmapGlyph->top + offset;
curGlyph.Advance = bitmapGlyph->root.advance.x >> 16;
// 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
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)
{
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 + 1] = 255;
glyphsBuffer[index * 4 + 2] = 255;
glyphsBuffer[index * 4 + 3] = pixels[x];
glyphsBuffer[index * 4 + 3] = pixels[x] * pixels[x] / 255;
}
pixels += bitmap.pitch;
}
// 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;
left += bitmap.width + 1;
left += bitmap.width + margin;
if (top + bitmap.rows > maxHeight)
maxHeight = top + bitmap.rows;
@ -278,7 +283,7 @@ FT_Error FontLoader::CreateBitmapFont(FT_Face face, unsigned int charSize, const
}
// Create the font's texture
texHeight = maxHeight + 1;
texHeight = maxHeight + margin;
glyphsBuffer.resize(texWidth * texHeight * 4);
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),
myNeedTextureUpdate(false),
myNeedArrayUpdate (false),
myUpdateSource (NULL),
myPixelsFlipped (false)
{
@ -71,7 +70,6 @@ myIsSmooth (copy.myIsSmooth),
myPixels (copy.myPixels),
myNeedTextureUpdate(false),
myNeedArrayUpdate (false),
myUpdateSource (copy.myUpdateSource),
myPixelsFlipped (copy.myPixelsFlipped)
{
CreateTexture();
@ -90,7 +88,6 @@ myTexture (0),
myIsSmooth (true),
myNeedTextureUpdate(false),
myNeedArrayUpdate (false),
myUpdateSource (NULL),
myPixelsFlipped (false)
{
Create(width, height, color);
@ -109,7 +106,6 @@ myTexture (0),
myIsSmooth (true),
myNeedTextureUpdate(false),
myNeedArrayUpdate (false),
myUpdateSource (NULL),
myPixelsFlipped (false)
{
LoadFromPixels(width, height, data);
@ -387,6 +383,9 @@ bool Image::CopyScreen(RenderWindow& window, const IntRect& sourceRect)
myWidth = srcRect.GetSize().x;
myHeight = srcRect.GetSize().y;
// Make sure that pending drawables are rendered on the target window
window.Flush();
// We can then create the texture
if (window.SetActive() && CreateTexture())
{
@ -402,6 +401,8 @@ bool Image::CopyScreen(RenderWindow& window, const IntRect& sourceRect)
myNeedArrayUpdate = true;
myPixelsFlipped = true;
window.SetActive(false);
return true;
}
else
@ -553,12 +554,13 @@ FloatRect Image::GetTexCoords(const IntRect& rect) const
{
float width = static_cast<float>(myTextureWidth);
float height = static_cast<float>(myTextureHeight);
float offset = myIsSmooth ? 0.5f : 0.0f;
FloatRect coords;
coords.Left = rect.Left / width;
coords.Top = rect.Top / height;
coords.Right = rect.Right / width;
coords.Bottom = rect.Bottom / height;
coords.Left = (rect.Left + offset) / width;
coords.Top = (rect.Top + offset) / height;
coords.Right = (rect.Right - offset) / width;
coords.Bottom = (rect.Bottom - offset) / height;
if (myPixelsFlipped)
std::swap(coords.Top, coords.Bottom);
@ -607,7 +609,6 @@ Image& Image::operator =(const Image& other)
std::swap(myIsSmooth, temp.myIsSmooth);
std::swap(myNeedArrayUpdate, temp.myNeedArrayUpdate);
std::swap(myNeedTextureUpdate, temp.myNeedTextureUpdate);
std::swap(myUpdateSource, temp.myUpdateSource);
std::swap(myPixelsFlipped, temp.myPixelsFlipped);
myPixels.swap(temp.myPixels);
@ -678,24 +679,15 @@ void Image::EnsureTextureUpdate()
{
if (myNeedTextureUpdate)
{
if (myTexture)
if (myTexture && !myPixels.empty())
{
GLint previous;
GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous));
if (myUpdateSource)
{
// External update
myPixelsFlipped = myUpdateSource->UpdateImage(*this);
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;
}
// 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));
}
@ -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
////////////////////////////////////////////////////////////
@ -797,7 +776,6 @@ void Image::Reset()
myIsSmooth = true;
myNeedTextureUpdate = false;
myNeedArrayUpdate = false;
myUpdateSource = NULL;
myPixelsFlipped = false;
myPixels.clear();
}

View File

@ -275,7 +275,7 @@ bool PostFX::CanUsePostFX()
////////////////////////////////////////////////////////////
/// /see Drawable::Render
////////////////////////////////////////////////////////////
void PostFX::Render(RenderTarget& target) const
void PostFX::Render(RenderTarget& target, RenderQueue&) const
{
// Check that we have a valid program
if (!myShaderProgram)
@ -283,7 +283,9 @@ void PostFX::Render(RenderTarget& target) const
// Copy the current framebuffer pixels to our frame buffer texture
// 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
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)
{
if (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 myRenderImage && myRenderImage->Activate(active);
}
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
////////////////////////////////////////////////////////////

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
////////////////////////////////////////////////////////////
RenderTarget::RenderTarget() :
myCurrentView (&myDefaultView),
myPreserveStates(false),
myIsDrawing (false)
myCurrentView(&myDefaultView)
{
}
@ -61,10 +59,13 @@ void RenderTarget::Clear(const Color& color)
{
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(glClear(GL_COLOR_BUFFER_BIT));
// Clear the render queue
myRenderQueue.Clear();
Activate(false);
}
}
@ -75,59 +76,34 @@ void RenderTarget::Clear(const Color& color)
////////////////////////////////////////////////////////////
void RenderTarget::Draw(const Drawable& object)
{
// Check whether we are called from the outside or from a previous call to Draw
if (!myIsDrawing)
// Save the current render states
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
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);
Activate(false);
}
}
@ -160,16 +136,48 @@ View& RenderTarget::GetDefaultView()
////////////////////////////////////////////////////////////
/// Tell SFML to preserve external OpenGL states, at the expense of
/// more CPU charge. Use this function if you don't want SFML
/// to mess up your own OpenGL states (if any).
/// Don't enable state preservation if not needed, as it will allow
/// SFML to do internal optimizations and improve performances.
/// This parameter is false by default
/// Get the viewport of a view applied to this target
////////////////////////////////////////////////////////////
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()
{
if (Activate(true))
{
// Set the default rendering states
SetRenderStates();
// Setup the default view
myDefaultView.Reset(FloatRect(0, 0, static_cast<float>(GetWidth()), static_cast<float>(GetHeight())));
SetView(myDefaultView);
// Setup the default view
myDefaultView.Reset(FloatRect(0, 0, static_cast<float>(GetWidth()), static_cast<float>(GetHeight())));
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));
// Clear the render queue
myRenderQueue.Clear();
}
} // namespace sf

View File

@ -75,11 +75,7 @@ RenderWindow::~RenderWindow()
////////////////////////////////////////////////////////////
bool RenderWindow::Activate(bool active)
{
// For performances and consistency reasons, we only handle activation
if (active)
return SetActive();
else
return true;
return SetActive(active);
}
@ -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
////////////////////////////////////////////////////////////
@ -174,4 +106,14 @@ void RenderWindow::OnCreate()
RenderTarget::Initialize();
}
////////////////////////////////////////////////////////////
/// Called before the window has been displayed
////////////////////////////////////////////////////////////
void RenderWindow::OnDisplay()
{
// Render the drawables drawn so far
Flush();
}
} // namespace sf

View File

@ -26,7 +26,7 @@
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Graphics/Shape.hpp>
#include <SFML/Graphics/GLCheck.hpp>
#include <SFML/Graphics/RenderQueue.hpp>
#include <math.h>
@ -281,7 +281,7 @@ Shape Shape::Circle(const Vector2f& center, float radius, const Color& color, fl
////////////////////////////////////////////////////////////
/// /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)
if (myPoints.size() < 4)
@ -292,50 +292,69 @@ void Shape::Render(RenderTarget&) const
const_cast<Shape*>(this)->Compile();
// Shapes only use color, no texture
GLCheck(glDisable(GL_TEXTURE_2D));
queue.SetTexture(NULL);
// Draw the shape
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)
{
Color color = i->Col * GetColor();
glColor4ub(color.r, color.g, color.b, color.a);
glVertex2f(i->Position.x, i->Position.y);
}
queue.AddVertex(i->Position.x, i->Position.y, i->Col);
for (std::size_t i = 1; i < myPoints.size() - 1; ++i)
queue.AddTriangle(0, i, i + 1);
// Close the shape by duplicating the first point at the end
Color color = myPoints[1].Col * GetColor();
glColor4ub(color.r, color.g, color.b, color.a);
glVertex2f(myPoints[1].Position.x, myPoints[1].Position.y);
queue.AddTriangle(0, myPoints.size() - 1, 1);
}
glEnd();
}
// 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)
{
Color color = myPoints[i].OutlineCol * GetColor();
glColor4ub(color.r, color.g, color.b, color.a);
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);
Vector2f point1 = i->Position;
Vector2f point2 = i->Position + i->Normal * myOutline;
queue.AddVertex(point1.x, point1.y, i->OutlineCol);
queue.AddVertex(point2.x, point2.y, i->OutlineCol);
}
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));
for (std::size_t i = 1; i < myPoints.size(); ++i)
{
center.Position += myPoints[i].Position / nbPoints;
r += myPoints[i].Col.r / nbPoints;
g += myPoints[i].Col.g / nbPoints;
b += myPoints[i].Col.b / nbPoints;
a += myPoints[i].Col.a / nbPoints;
center.Position += myPoints[i].Position;
r += myPoints[i].Col.r;
g += myPoints[i].Col.g;
b += myPoints[i].Col.b;
a += myPoints[i].Col.a;
}
center.Col.r = static_cast<Uint8>(r);
center.Col.g = static_cast<Uint8>(g);
center.Col.b = static_cast<Uint8>(b);
center.Col.a = static_cast<Uint8>(a);
center.Position /= nbPoints;
center.Col.r = static_cast<Uint8>(r / nbPoints);
center.Col.g = static_cast<Uint8>(g / nbPoints);
center.Col.b = static_cast<Uint8>(b / nbPoints);
center.Col.a = static_cast<Uint8>(a / nbPoints);
myPoints[0] = center;
// Compute the outline

View File

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

View File

@ -27,8 +27,7 @@
////////////////////////////////////////////////////////////
#include <SFML/Graphics/String.hpp>
#include <SFML/Graphics/Image.hpp>
#include <SFML/Graphics/GLCheck.hpp>
#include <locale>
#include <SFML/Graphics/RenderQueue.hpp>
namespace sf
@ -210,7 +209,7 @@ FloatRect String::GetRect() const
////////////////////////////////////////////////////////////
/// /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
const Unicode::UTF32String& text = myText;
@ -222,10 +221,9 @@ void String::Render(RenderTarget&) const
// Set the scaling factor to get the actual size
float charSize = static_cast<float>(myFont->GetCharacterSize());
float factor = mySize / charSize;
GLCheck(glScalef(factor, factor, 1.f));
// Bind the font texture
myFont->GetImage().Bind();
queue.SetTexture(&myFont->GetImage());
// Initialize the rendering coordinates
float x = 0.f;
@ -239,7 +237,8 @@ void String::Render(RenderTarget&) const
float italicCoeff = (myStyle & Italic) ? 0.208f : 0.f; // 12 degrees
// 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)
{
// 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
glTexCoord2f(coord.Left, coord.Top); glVertex2f(x + rect.Left - italicCoeff * rect.Top, y + rect.Top);
glTexCoord2f(coord.Left, coord.Bottom); glVertex2f(x + rect.Left - italicCoeff * rect.Bottom, y + rect.Bottom);
glTexCoord2f(coord.Right, coord.Bottom); glVertex2f(x + rect.Right - italicCoeff * rect.Bottom, y + rect.Bottom);
glTexCoord2f(coord.Right, coord.Top); glVertex2f(x + rect.Right - italicCoeff * rect.Top, y + rect.Top);
queue.AddVertex(factor * (x + rect.Left - italicCoeff * rect.Top), factor * (y + rect.Top), coord.Left, coord.Top);
queue.AddVertex(factor * (x + rect.Left - italicCoeff * rect.Bottom), factor * (y + rect.Bottom), coord.Left, coord.Bottom);
queue.AddVertex(factor * (x + rect.Right - italicCoeff * rect.Bottom), factor * (y + rect.Bottom), coord.Right, coord.Bottom);
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,
// slightly offseted, to simulate a higher weight
if (myStyle & Bold)
{
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);
}
}
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;
}
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
if (myStyle & Underlined)
@ -304,16 +339,20 @@ void String::Render(RenderTarget&) const
underlineCoords.push_back(y + 2);
// Draw the underlines as quads
GLCheck(glDisable(GL_TEXTURE_2D));
glBegin(GL_QUADS);
index = 0;
queue.SetTexture(NULL);
queue.BeginBatch();
for (std::size_t i = 0; i < underlineCoords.size(); i += 2)
{
glVertex2f(0, underlineCoords[i + 1]);
glVertex2f(0, underlineCoords[i + 1] + thickness);
glVertex2f(underlineCoords[i], underlineCoords[i + 1] + thickness);
glVertex2f(underlineCoords[i], underlineCoords[i + 1]);
queue.AddVertex(factor * (0), factor * (underlineCoords[i + 1]));
queue.AddVertex(factor * (0), factor * (underlineCoords[i + 1] + thickness));
queue.AddVertex(factor * (underlineCoords[i]), factor * (underlineCoords[i + 1] + thickness));
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
{
// 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;

View File

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