Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: mixing opengl and sfml2 calls (found speed drops when moving from sfml1.6 to 2)  (Read 4002 times)

0 Members and 2 Guests are viewing this topic.

amdlintuxos

  • Newbie
  • *
  • Posts: 17
    • View Profile
Greetings!

I noticed some unpleasant issue when moved from sfml1.6 to 2.0.

I have render which is mainly using standard opengl calls and sfml is handling the font drawing.
So, sfml drawing calls are mixed with native opengl, and happens in many layers of my code.
I want to keep thing separated, my code is on the left and sfml code is on the right, so i created some agregator which manage all sfml calls inside.

with using SFML2:

sf::RenderWindow window;

void SFML_Wrapper::DrawText(const std::string& str, int font_size, const Vec2<float>& pos, const Color4<int>& color)
{
        sf::Text text(str, font, font_size);
        text.setColor(sf::Color(color.r, color.g, color.b));
        text.setPosition(pos.x, GetHeight() - pos.y);
                                               
   window.pushGLStates();
   window.draw(text);
   window.popGLStates();           
}

I know that push/popGLStates() calls are very expensive(and actually they are the root of my problem). i have a significant fps drop when text is rendering.

with using SFML1.6: i had no need to use push/popGLStates(). And my font rendering served me with good fps. I was using
window.PreserveOpenGLStates(true); which was configured once in constructor.
I guess it does something similar to push/popGLStates() in a background, but i have no so significant render speed drop as in SFML2.

Is it possible to avoid this? Or at least to get speed near to SFML1.6 without code redesign (i had an idea to agregate all text and render it at once at the end of render, but don't want to make code more complex than it actually is now). I don't want to downgrade.
Many thanks in advance!
« Last Edit: May 29, 2013, 09:33:42 pm by amdlintuxos »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Are you sure that it's these functions that are slower in SFML 2? Have you tried without Preserve/push/popGLStates (rendering will be messed up but we don't care, we're only interesetd in the FPS)?

Some general advice: functions such as DrawText are really bad because you recreate the whole text objects everytime, even for texts that never change; you lose the opportunity to precompute the heavy stuff.
« Last Edit: May 29, 2013, 09:42:10 pm by Laurent »
Laurent Gomila - SFML developer

amdlintuxos

  • Newbie
  • *
  • Posts: 17
    • View Profile
Hi Laurent.

Thanks for you input. Yes you are right, i was mistaken into identifying the bottleneck. It seems my bottleneck in text render itself.
My task is to render 200 short strings. Let it be number between "0-9". Explosion damage ships within circle and they are aware me about damaging value(also these numbers are showed me the circle of explosion affection).
Each string is separated and has own position, moving speed.

I made short benchmark. It creates 200 short texts with string "1".
For theoretic purpose i moved out some stuff from the render loop, such as:
{
   text12.setFont(font);
   text12.setCharacterSize(12);
   text12.setColor(sf::Color(255,0,0,255));
   text12.setString("1");
   text12.setPosition(200, 300);
} performing only once.

My main loop have only:
{
window.pushGLStates();
window.draw(text12);
window.popGLStates();   
}
case 1:
if i comment
//window.draw(text12);
i got 42-45fps.

if i uncomment
window.draw(text12);
i got 10-13 fps.

With my previous approach: text12 is created within gameloop i got 9-10 fps(worst case).

Is it theoretically possible to render many short strings with good performance? I am not sure now, but it seems with sfml1.6 i never had fps drop below 30 fps. It hard for me to check this now to be sure exactly.

Cheers, Alex

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Using your short benchmark, what FPS do you have if you remove the calls to push/popGLStates?

Can't you do it only once:
pushGLStates();
draw ALL sf::Texts
popGLStates();
Laurent Gomila - SFML developer

amdlintuxos

  • Newbie
  • *
  • Posts: 17
    • View Profile
same bench 200 short separated texts with string "1"
case 1 (push/popGLStates calls removed):
{     
   text12.setString(str);
        text12.setPosition(pos.x, GetHeight() - pos.y);
                                               
    //window.pushGLStates();
   window.draw(text12);
   //window.popGLStates();   
}
~35fps (blank screen, screwed).

case 2: all uncommented(renders everything correct)
~10fps

case 3: render ok, but without texts
{
   //window.pushGLStates();
   // window.draw(text12);
   //window.popGLStates();   
}
~55fps

For my test i could do it only once, but not for my project. I got many layers, each may generate text info. I got thought to push all texts into std::vector, and render it at final stage, but:
1) don't want to do things complicated now
2) not sure how pushing the std::strings will influence on performance.

Of course i understand that my code is not optimized, and some my tricks are really bad. But for now i didn't plane to do optimization, not time yet. And the sfml1.6 allow me to not make my attention on that behaviour.

By the way, i maid short replacement of text render by http://nehe.gamedev.net/tutorial/freetype_fonts_in_opengl/24001/
And it gives me 49-50 fps, compare to SFML2 (10 fps). But i didn't compare the quality, and probably sfml2 overcome it with bigger text(i tested only with short slices of texts).

And i am not sure if this matter, my videocard is not so powerfull (radeon5550).

Cheers, Alex
« Last Edit: May 30, 2013, 10:48:24 am by amdlintuxos »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Could you upload your short benchmark code? I'd like to do some tests. Also make sure that the code is really minimal.
Laurent Gomila - SFML developer

amdlintuxos

  • Newbie
  • *
  • Posts: 17
    • View Profile
Laurent.
My benchmark is integrated into my game render loop. But i think i may cut off everything irrelevant and lleave only important (opengl init, blank game render loop + text render). I will provide short example but i need time to prepare it.

Cheers, Alex

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Thanks. But don't cut lines of code from your initial project, it usually leads to ugly code with unnecessary stuff inside. Write a new small app from scratch instead.
Laurent Gomila - SFML developer

amdlintuxos

  • Newbie
  • *
  • Posts: 17
    • View Profile
Hi Laurent.

Sorry for late response only recently found time to return to my project and write a short bench for text rendering issue.

Just to remind you: my task is to render 200 separated pieces of text with SFML2.
I attached test written in one file which draws simple Quad by plain opengl + text by SFML2. By changing value in global variable N, the size of text matrix drawing on screen is changed. On top right angle of the screen the FPS value is drawn. I also put limit to 100fps for SFML app. For test you need to put the ttf font file and link following: sfml-system sfml-graphics sfml-window  ${OPENGL_LIBRARIES}. I know it's obvious, but maybe will save couple of minutes to look at.

So my bench result:
N=2 (2x2=4 pieces of text) = ~98fps
N=5 (5x5=25 pieces of text) = ~40fps (almost twice drop down)
N=15 (15x15=225 pieces of text) = ~5fps.
I also attached picture from my machine to demonstrate this.
I tested on Ubuntu X64, Radeon5550 (catalyst driver, not open source), AMD X64 2.4Ghz

Cheers, Alex
« Last Edit: June 15, 2013, 10:19:45 am by amdlintuxos »

Mario

  • SFML Team
  • Hero Member
  • *****
  • Posts: 879
    • View Profile
Are you using/changing some STL container quite a lot around the rendering code? I remember doing something like that once and using sf::Text dropped performance by a huge margin. Maybe your culprit is somewhere around that corner, although I'm not 100% sure how/why they'd interact that way.

amdlintuxos

  • Newbie
  • *
  • Posts: 17
    • View Profile
Hi Mario, thanks for you input, but it seems there is issue in something else.
Here is my observation:
Are you using/changing some STL container quite a lot around the rendering code?
yes i do in my project, but the problem totally is not in STL, as the:
1) if i commented just drawing function in my project then fps still is ok
2) the benchmark i attached produse fps drop without using STL (never mind at #include <vector> in attached bench, this is overtyping, actually in bench i didn't use STL code at all)
I remember doing something like that once and using sf::Text dropped performance by a huge margin.
that's not my case either, as in bench i created sf::Text only once, out of game loop.

Cheers, Alex
« Last Edit: June 15, 2013, 06:13:36 pm by amdlintuxos »