SFML community forums
Help => Graphics => Topic started by: dreimalbla on July 16, 2008, 05:15:25 pm
-
Hi,
I've got huge performance issue when using SFML's draw text.
Let's take the SFML opengl sample as an example.
600fps while drawing the rotating cube and drawing the fps.
300fps while drawing the rotating cube and drawing the fps three times.
250fps while drawing the rotating cube and drawing the fps four times.
I'm using SFML 1.3. Is this a known issue or is it on my side only?
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Graphics.hpp>
#include <iostream>
#include <sstream>
#include <string>
////////////////////////////////////////////////////////////
/// Entry point of application
///
/// \return Application exit code
///
////////////////////////////////////////////////////////////
int main()
{
// Create main window
sf::RenderWindow App(sf::VideoMode(800, 600), "SFML OpenGL");
App.PreserveOpenGLStates(true);
// Create a sprite for the background
sf::Image BackgroundImage;
if (!BackgroundImage.LoadFromFile("datas/opengl/background.jpg"))
return EXIT_FAILURE;
sf::Sprite Background(BackgroundImage);
// Load an OpenGL texture.
// We could directly use a sf::Image as an OpenGL texture (with its Bind() member function),
// but here we want more control on it (generate mipmaps, ...) so we create a new one
GLuint Texture = 0;
{
sf::Image Image;
if (!Image.LoadFromFile("datas/opengl/texture.jpg"))
return EXIT_FAILURE;
glGenTextures(1, &Texture);
glBindTexture(GL_TEXTURE_2D, Texture);
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, Image.GetWidth(), Image.GetHeight(), GL_RGBA, GL_UNSIGNED_BYTE, Image.GetPixelsPtr());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
}
// Enable Z-buffer read and write
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glClearDepth(1.f);
// Setup a perspective projection
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90.f, 1.f, 1.f, 500.f);
// Bind our texture
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, Texture);
glColor4f(1.f, 1.f, 1.f, 1.f);
// Create a clock for measuring the time elapsed
sf::Clock Clock;
double currTime = Clock.GetElapsedTime();
double lastTime = Clock.GetElapsedTime();
double deltaTime;
// Start game loop
while (App.IsOpened())
{
currTime = Clock.GetElapsedTime();
deltaTime = currTime - lastTime;
// Process events
sf::Event Event;
while (App.GetEvent(Event))
{
// Close window : exit
if (Event.Type == sf::Event::Closed)
App.Close();
// Escape key : exit
if ((Event.Type == sf::Event::KeyPressed) && (Event.Key.Code == sf::Key::Escape))
App.Close();
// Adjust the viewport when the window is resized
if (Event.Type == sf::Event::Resized)
glViewport(0, 0, Event.Size.Width, Event.Size.Height);
}
// Draw background
App.Draw(Background);
// Clear depth buffer
glClear(GL_DEPTH_BUFFER_BIT);
// Apply some transformations
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.f, 0.f, -200.f);
glRotatef(Clock.GetElapsedTime() * 50, 1.f, 0.f, 0.f);
glRotatef(Clock.GetElapsedTime() * 30, 0.f, 1.f, 0.f);
glRotatef(Clock.GetElapsedTime() * 90, 0.f, 0.f, 1.f);
//Draw a cube
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex3f(-50.f, -50.f, -50.f);
glTexCoord2f(0, 1); glVertex3f(-50.f, 50.f, -50.f);
glTexCoord2f(1, 1); glVertex3f( 50.f, 50.f, -50.f);
glTexCoord2f(1, 0); glVertex3f( 50.f, -50.f, -50.f);
glTexCoord2f(0, 0); glVertex3f(-50.f, -50.f, 50.f);
glTexCoord2f(0, 1); glVertex3f(-50.f, 50.f, 50.f);
glTexCoord2f(1, 1); glVertex3f( 50.f, 50.f, 50.f);
glTexCoord2f(1, 0); glVertex3f( 50.f, -50.f, 50.f);
glTexCoord2f(0, 0); glVertex3f(-50.f, -50.f, -50.f);
glTexCoord2f(0, 1); glVertex3f(-50.f, 50.f, -50.f);
glTexCoord2f(1, 1); glVertex3f(-50.f, 50.f, 50.f);
glTexCoord2f(1, 0); glVertex3f(-50.f, -50.f, 50.f);
glTexCoord2f(0, 0); glVertex3f(50.f, -50.f, -50.f);
glTexCoord2f(0, 1); glVertex3f(50.f, 50.f, -50.f);
glTexCoord2f(1, 1); glVertex3f(50.f, 50.f, 50.f);
glTexCoord2f(1, 0); glVertex3f(50.f, -50.f, 50.f);
glTexCoord2f(0, 1); glVertex3f(-50.f, -50.f, 50.f);
glTexCoord2f(0, 0); glVertex3f(-50.f, -50.f, -50.f);
glTexCoord2f(1, 0); glVertex3f( 50.f, -50.f, -50.f);
glTexCoord2f(1, 1); glVertex3f( 50.f, -50.f, 50.f);
glTexCoord2f(0, 1); glVertex3f(-50.f, 50.f, 50.f);
glTexCoord2f(0, 0); glVertex3f(-50.f, 50.f, -50.f);
glTexCoord2f(1, 0); glVertex3f( 50.f, 50.f, -50.f);
glTexCoord2f(1, 1); glVertex3f( 50.f, 50.f, 50.f);
glEnd();
lastTime = currTime;
std::ostringstream ss;
ss << 1/deltaTime;
std::string s = ss.str();
// Draw some text on top of our OpenGL object
sf::String Text(s);
Text.SetPosition(250.f, 300.f);
Text.SetColor(sf::Color(128, 0, 128));
App.Draw(Text);
Text.SetText(s);
Text.SetPosition(250.f, 330.f);
Text.SetColor(sf::Color(128, 0, 128));
App.Draw(Text);
Text.SetText(s);
Text.SetPosition(250.f, 360.f);
Text.SetColor(sf::Color(128, 0, 128));
App.Draw(Text);
Text.SetText(s);
Text.SetPosition(250.f, 360.f);
Text.SetColor(sf::Color(128, 0, 128));
App.Draw(Text);
// Finally, display the rendered frame on screen
App.Display();
}
// Don't forget to destroy our texture
glDeleteTextures(1, &Texture);
return EXIT_SUCCESS;
}
-
Hi dreimalbla,
it's a known issue with String. Problem is not the String display, but SetText method which is very slow with visual studio (you use VS, right ?). Try to comment the 3 others SetText methods, and you'll have your ~600 fps back.
Another workaround is to use only std::wstring and not std::string to prevent call to String::SetText(std::string) (actually the bottleneck into this method is conversion between string and wstring because SFML String handle only wstring) and use String::SetText(std::wstring) instead.
I've already mentioned this problem to Laurent on the french forum, and he's working on it. =)
-
thx for the answer, let's hope he'll fix it soon ;)
-
It will probably be fixed in the next commit, actually ;)
-
great :)
keep up the good work
-
but SetText method which is very slow with visual studio (you use VS, right ?)
What do you mean by that? Why would it be slower using visual studio?
-
Yep !
From string.cpp :
void String::SetText(const std::string& Text)
{
myNeedRectUpdate = true;
if (!Text.empty())
{
std::vector<wchar_t> Buffer(Text.size());
#if defined(__MINGW32__)
// MinGW has a bad support for wstring conversions (and wchar_t based standard classes in general)
mbstowcs(&Buffer[0], Text.c_str(), Text.size());
#else
std::locale Locale("");
std::use_facet<std::ctype<wchar_t> >(Locale).widen(Text.data(), Text.data() + Text.size(), &Buffer[0]);
#endif
myText.assign(&Buffer[0], Buffer.size());
}
else
{
myText = L"";
}
}
Actually the specific Mingw part is a lot faster (by a factor of 100, maybe a little less) for all compiler I have tested (MinGW, VS9 and DMC).
Here's a test comparing the two methods, using svn, VC9 express and with SetText customized version (which doesn't use std stuff) and SetTextOriginal the actual SetText method :
int main()
{
sf::String myString("Test");
__int64 l;
for(int i = 0; i < 10; i++)
{
l = __rdtsc();
myString.SetText("Blabla");
printf("New SetText : %d\n", __rdtsc() - l);
}
for(int i = 0; i < 10; i++)
{
l = __rdtsc();
myString.SetTextOriginal("Blabla");
printf("Original SetText : %d\n", __rdtsc() - l);
}
getchar();
return EXIT_SUCCESS;
}
New SetText : 7051
New SetText : 27200
New SetText : 13952
New SetText : 10928
New SetText : 7979
New SetText : 11511
New SetText : 10730
New SetText : 11259
New SetText : 10047
New SetText : 10761
Original SetText : 1839609
Original SetText : 1165118
Original SetText : 813238
Original SetText : 783113
Original SetText : 801104
Original SetText : 774272
Original SetText : 806911
Original SetText : 775008
Original SetText : 784999
Original SetText : 718220
So, it's not an issue with Visual itself, but with String implementation when you compile with visual. =)[/code]
-
So we who love visual studio will be forced to use something else in order to get great performance out of sfml? I'm currently experiencing the same performance issue as the one above.
-
So we who love visual studio will be forced to use something else in order to get great performance out of sfml?
It will probably be fixed in the next commit, actually
-
So we who love visual studio will be forced to use something else in order to get great performance out of sfml?
It will probably be fixed in the next commit, actually
Ok, thanks for making me look stupid :D Should have seen that.
-
So we who love visual studio will be forced to use something else in order to get great performance out of sfml? I'm currently experiencing the same performance issue as the one above.
Another workaround is to use only std::wstring and not std::string to prevent call to String::SetText(std::string) (actually the bottleneck into this method is conversion between string and wstring because SFML String handle only wstring) and use String::SetText(std::wstring) instead.
You missed that too. =p
-
Another workaround is to use only std::wstring and not std::string to prevent call to String::SetText(std::string) (actually the bottleneck into this method is conversion between string and wstring because SFML String handle only wstring) and use String::SetText(std::wstring) instead.
You missed that too. =p
Well actually I saw that, but I don't know how to use wstring, I get a lot of errors all the time.
-
Don't bother with std::wstring, it will no longer be used in the new version. In fact std::wstring and wchar_t are evil : we don't know anything about them, neither their size (can be 2 or 4 bytes) nor how characters are encoded (can be UTF-32 or UTF-16 depending on the platform).
The new version will define propre unicode types, as well as functions to convert between them and locale-dependent ANSI strings.
-
Ok thanks, the last part sounds great. Let us know when it's done :)
-
Should be ready in a couple of days. The only problem actually is the lack of proper unicode handling in MinGW standard library.
-
Take your time, no hurry.
-
I read the road map and I noticed this:
Done - ready for next version
- SYSTEM Added types and conversion functions to handle all Unicode formats
- GENERAL SFML now uses UTF-32 for all text related stuff instead of UCS-2
Will this speed up the SetText-method for visual studio that you were talking about earlier or is it something else?
-
Actually, the performances issue with strings was a stupid thing which is fixed.
I'm also going to improve the sf::String rendering code to optimize it, but it's already way faster than before.
-
It definitely got faster. I got 5000 fps before, now I get 24000 fps.
I almost thought that there was something wrong with my message box rendering code. :P
-
It definitely got faster. I got 5000 fps before, now I get 24000 fps.
I almost thought that there was something wrong with my message box rendering code. :P
OMFG ! You work on a Cray XT5 ? =D
I confirm, string is now a lot faster than before.
-
Nope, it's a 8800GTX, rendering nothing but a message box (only a few lines of OpenGL code) + fps string in a 320x240 window (it drops to an average 15000 fps if I change the resolution to 640x480).
Don't worry, it gets slower the more I draw on the screen. :wink:
-
Nope, it's a 8800GTX, rendering nothing but a message box (only a few lines of OpenGL code) + fps string in a 320x240 window (it drops to an average 15000 fps if I change the resolution to 640x480).
Don't worry, it gets slower the more I draw on the screen. :wink:
lollll 320X240... I will draw an fps string in a 10X100 window and we will see wich fps i will get XD.
-
Sounds great. So I don't have to change any of my code to get this speed up, only download the new source?
-
@Dabo :
Yeap, maybe you'll need to do some changes on your code with the new unicode stuffs. If you don't use wchar at all, just update your svn.
-
It's faster for sure :) Great job!
-
lollll 320X240... I will draw an fps string in a 10X100 window and we will see wich fps i will get XD.
Any results? :wink:
-
ROFL!!! I will do it this night if you really want a result XD.
-
Hi boys.. I have the same problem and read all but not see results..
I'm using SFML 1.3 too as wrote on first post.
updated/fixed SFML Code that work faster with SetText
is 1.3 or is in SVN source?? :?:
Thanks
-
The svn source. =)
-
Hi Sir.
Yesterday I try svn source but without different results.
I just put svn include/lib dirs into sfml 1.3 sdk and recompile all.
I'm using VC9.
Now I'm working using wstringstream.
-
I just put svn include/lib dirs into sfml 1.3 sdk and recompile all.
And what about the src dir ? :roll:
-
Sorry boys.
I usually get SDK version..
Yesterday I was tired and get "SFML development files" of ver1.3 instead of "SVN sources".
My sentence "..and recompile all" was referred only to my source.
You don't plain to update 1.3 version?