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

Author Topic: FPS Help  (Read 3132 times)

0 Members and 1 Guest are viewing this topic.

dpixel

  • Newbie
  • *
  • Posts: 20
    • View Profile
FPS Help
« on: August 29, 2013, 03:43:39 am »
I just started SFML after being an SDL user.   I'm trying to dial in this FPS code.  For some reason the timing is off.

If I set
int FPSQ = 60;
 
I get about 120FPS

To get 60FPS I have to set
int FPSQ = 33;
 

#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <SFML/System.hpp>
#include <iostream>
#include <string>
#include <sstream>


using namespace sf;
sf::RenderWindow window;

    sf::Texture Tplayer;
    sf::Texture SmallAlpha;
    sf::Texture Back;
    sf::Texture mainchar;

    sf::Sprite Splayer;
    sf::Sprite Splayer1;
    sf::Sprite smallalpha;
    sf::Sprite background;
    sf::Sprite char1;

void Walk_Right(int x, int y, int index);

std::string GetFullScreen(int mode)
{
    int newsizeX = 0;
    int newsizeY = 0;
    switch (mode)
    {
    case 0:
        newsizeX = 1920;
        newsizeY = 1080;
        window.setTitle("1920x1080");
        break;
    case 1:
        newsizeX = 800;
        newsizeY = 450;
        window.setTitle("800x450");
        break;
    case 2:
        newsizeX = 1200;
        newsizeY = 675;
        window.setTitle("1200x675");
        break;
    case 3:
        newsizeX = 1600;
        newsizeY = 900;
        window.setTitle("1600x900");
        break;
    default:
        break;
    }
    sf::Vector2u windowsize(newsizeX, newsizeY);
    window.setSize(windowsize);
    window.setPosition(sf::Vector2i(0, 0));
    //For display text
    std::string Result;
    std::ostringstream convert;
    convert << windowsize.x << " x " << windowsize.y;
    Result = convert.str();
    return Result;
}

void Blit(int x, int y, int srcX, int srcY, int srcW, int srcH, sf::Sprite sprt)
{
    sprt.setPosition(x, y);
    sprt.setTextureRect(sf::IntRect(srcX, srcY, srcW, srcH));
    window.draw(sprt);
}
void BlitWithAlpha(int x, int y, int srcX, int srcY, int srcW, int srcH, sf::Sprite sprt, int alphachannel)
{
    sprt.setPosition(x, y);
    sprt.setTextureRect(sf::IntRect(srcX, srcY, srcW, srcH));
    sprt.setColor(Color(255, 255, 255, alphachannel));
    window.draw(sprt);
}
void BlitImage8x16(int x, int y, int srcX, int srcY, sf::Sprite sprt)
{
    sprt.setPosition(x, y);
    sprt.setTextureRect(sf::IntRect(srcX, srcY, 8, 16));
    window.draw(sprt);
}
void CustomText(int x, int y, std::string st)
{
    int StringLength, FontXPos, CharacterSpacing = 8;
    std::string character;
    StringLength = st.length();
    for (int n=0; n<=StringLength-1; n++)
    {
            character = st.substr(n,1);
            if (character == "A") FontXPos = 0;
            if (character == "B") FontXPos = 8;
            if (character == "C") FontXPos = 16;
            if (character == "D") FontXPos = 24;
            if (character == "E") FontXPos = 32;
            if (character == "F") FontXPos = 40;
            if (character == "G") FontXPos = 48;
            if (character == "H") FontXPos = 56;
            if (character == "I") FontXPos = 64;
            if (character == "J") FontXPos = 72;
            if (character == "K") FontXPos = 80;
            if (character == "L") FontXPos = 88;
            if (character == "M") FontXPos = 96;
            if (character == "N") FontXPos = 104;
            if (character == "O") FontXPos = 112;
            if (character == "P") FontXPos = 120;
            if (character == "Q") FontXPos = 128;
            if (character == "R") FontXPos = 136;
            if (character == "S") FontXPos = 144;
            if (character == "T") FontXPos = 152;
            if (character == "U") FontXPos = 160;
            if (character == "V") FontXPos = 168;
            if (character == "W") FontXPos = 176;
            if (character == "X") FontXPos = 184;
            if (character == "Y") FontXPos = 192;
            if (character == "Z") FontXPos = 200;
            if (character == "a") FontXPos = 208;
            if (character == "b") FontXPos = 216;
            if (character == "c") FontXPos = 224;
            if (character == "d") FontXPos = 232;
            if (character == "e") FontXPos = 240;
            if (character == "f") FontXPos = 248;
            if (character == "g") FontXPos = 256;
            if (character == "h") FontXPos = 264;
            if (character == "i") FontXPos = 272;
            if (character == "j") FontXPos = 280;
            if (character == "k") FontXPos = 288;
            if (character == "l") FontXPos = 296;
            if (character == "m") FontXPos = 304;
            if (character == "n") FontXPos = 312;
            if (character == "o") FontXPos = 320;
            if (character == "p") FontXPos = 328;
            if (character == "q") FontXPos = 336;
            if (character == "r") FontXPos = 344;
            if (character == "s") FontXPos = 352;
            if (character == "t") FontXPos = 360;
            if (character == "u") FontXPos = 368;
            if (character == "v") FontXPos = 376;
            if (character == "w") FontXPos = 384;
            if (character == "x") FontXPos = 392;
            if (character == "y") FontXPos = 400;
            if (character == "z") FontXPos = 408;
            if (character == "0") FontXPos = 416;
            if (character == "1") FontXPos = 424;
            if (character == "2") FontXPos = 432;
            if (character == "3") FontXPos = 440;
            if (character == "4") FontXPos = 448;
            if (character == "5") FontXPos = 456;
            if (character == "6") FontXPos = 464;
            if (character == "7") FontXPos = 472;
            if (character == "8") FontXPos = 480;
            if (character == "9") FontXPos = 488;
            if (character == "=") FontXPos = 496;
            if (character == "(") FontXPos = 504;
            if (character == ")") FontXPos = 512;
            if (character == "-") FontXPos = 520;
            if (character == "+") FontXPos = 528;
            //if (character == "\") FontXPos = 536;
            if (character == "/") FontXPos = 544;
            if (character == ".") FontXPos = 552;
            if (character == ",") FontXPos = 560;
            if (character == "!") FontXPos = 568;
            if (character == "?") FontXPos = 576;
            if (character == ";") FontXPos = 584;
            if (character == ":") FontXPos = 592;
            if (character == "`") FontXPos = 600;
            if (character == " ") FontXPos = 608;
                BlitImage8x16(x + (CharacterSpacing * n), y, FontXPos, 0, smallalpha);
    }
}
std::string ConvertToString(float num)
{
    std::stringstream ss;
    ss << num;
    std::string StringValue = ss.str();
    return StringValue;
}

int main()
{
      sf::Time SFMLtime;
      sf::Clock SFMLclock;
      SFMLtime = SFMLclock.getElapsedTime();
      float clk = SFMLtime.asMilliseconds();
    //FPS...
    Uint32 currentTick = clk;
    int pastFPS = 0, currentFPS = 0, FPScounter = 0;
    int FPSQ = 33;
    Uint32 waittime = 1000/FPSQ;
    Uint32 framestarttime = 0;
    //Sint32 delaytime = 0;
    unsigned int delaytime = 0;
    //End FPS


    std::string Resolution;
    //Get current video resolution...
    //sf::VideoMode Vid = sf::VideoMode::getDesktopMode();

    window.create(sf::VideoMode(800, 450, 32), "A New Window");
    //window.setFramerateLimit(60);


    Tplayer.loadFromFile("player.png");
    Splayer1.setTexture(Tplayer);
    SmallAlpha.loadFromFile("smallalpha.png");
    smallalpha.setTexture(SmallAlpha);
    Back.loadFromFile("background.png");
    background.setTexture(Back);
    mainchar.loadFromFile("spritesheet2.png");
    char1.setTexture(mainchar);

    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
            if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))
                window.close();
            if (event.type == sf::Event::KeyPressed)
            {
                if (event.key.code == sf::Keyboard::F12) Resolution = GetFullScreen(0);
                if (event.key.code == sf::Keyboard::F11) Resolution = GetFullScreen(1);
                if (event.key.code == sf::Keyboard::F10) Resolution = GetFullScreen(2);
                if (event.key.code == sf::Keyboard::F9) Resolution = GetFullScreen(3);
            }
            if (event.type == sf::Event::KeyReleased)
            {
            }
        }

        window.clear();

        Blit(0, 0, 0, 0, 800, 450, background);

        SFMLtime = SFMLclock.getElapsedTime();
        float clk = SFMLtime.asMilliseconds();

        CustomText(10, 10, "SFML 2.1");
        CustomText(10, 30, ConvertToString(clk));
        CustomText(10, 50, Resolution);

        Blit(200, 200, 0, 0, 32, 32, Splayer1);
        Blit(768, 360, 32, 0, 32, 32, Splayer1);
        //for(int i = 0; i <= 255; i = i + 10)
        //{
        //    BlitWithAlpha(i+(i*2), 400, 0, 0, 32, 32, Splayer1, i);

        //}
        BlitWithAlpha(418, 250, 0, 0, 32, 32, Splayer1, 128);
        Walk_Right(125, 125, 0);


CustomText(50, 100, ConvertToString(currentTick));
CustomText(50, 120, ConvertToString(delaytime));
CustomText(50, 140, ConvertToString(pastFPS));
CustomText(50, 160, ConvertToString(framestarttime));
CustomText(50, 180, ConvertToString(FPScounter));

CustomText(200, 100, "currentTick");
CustomText(200, 120, "delaytime");
CustomText(200, 140, "pastFPS");
CustomText(200, 160, "framestarttime");
CustomText(200, 180, "FPScounter");

        //Display FPS in upper corner
        CustomText(770, 5, ConvertToString(currentFPS));
        SFMLtime = SFMLclock.getElapsedTime();
        clk = SFMLtime.asMilliseconds();
        currentTick = clk;
        window.display();
        FPScounter++;

        delaytime = waittime - (currentTick - framestarttime);
        if(delaytime > 0)
        {
            sf::sleep(sf::milliseconds(delaytime));
            framestarttime = clk;
        }

        if ( currentTick - pastFPS >= 1000 )
        {
            currentFPS = FPScounter;
            FPScounter = 0;
            pastFPS = currentTick;
        }
//        window.display();
    }

    return 0;
}

int frametime[100] = {0};
void Walk_Right(int x, int y, int index)
{
    frametime[index]++;
    if (frametime[index] > 21) frametime[index] = 0;
    if ((frametime[index] >= 0) && (frametime[index] <= 3)) Blit(x, y, 0, 0, 72, 72, char1);
    if ((frametime[index] >= 4) && (frametime[index] <= 6)) Blit(x, y, 72, 0, 72, 72, char1);
    if ((frametime[index] >= 7) && (frametime[index] <= 9)) Blit(x, y, 144, 0, 72, 72, char1);
    if ((frametime[index] >= 10) && (frametime[index] <= 12)) Blit(x, y, 216, 0, 72, 72, char1);
    if ((frametime[index] >= 13) && (frametime[index] <= 15)) Blit(x, y, 288, 0, 72, 72, char1);
    if ((frametime[index] >= 16) && (frametime[index] <= 18)) Blit(x, y, 360, 0, 72, 72, char1);
    if ((frametime[index] >= 19) && (frametime[index] <= 21)) Blit(x, y, 432, 0, 72, 72, char1);
}
 

slotdev

  • Sr. Member
  • ****
  • Posts: 385
    • View Profile
Re: FPS Help
« Reply #1 on: August 29, 2013, 05:54:13 pm »
Firstly, welcome to SFML, I am sure you will soon prefer it to SDL ;)

Have you just tried to use window.setFramerateLimit? SFML handles most things for you (even your code which converts a string and displays it, you can do in about 3 lines of code with SFML ;)).
SFML 2.1

AlexxanderX

  • Full Member
  • ***
  • Posts: 128
    • View Profile
    • AlexanderX
Re: FPS Help
« Reply #2 on: August 29, 2013, 06:38:01 pm »
Welcome at our lands :D. Regarding to your code: instead of define a class like "GetFullScreen(int mode)" for get the sizes for a fullscreen, SFML do this for you with the function sf::VideoMode::getFullscreenModes() - http://www.sfml-dev.org/documentation/2.1/classsf_1_1VideoMode.php .
Here you can find my blog and tutorials about SFML - http://alexanderx.net/ (died...) - http://web.archive.org/web/20160110002847/http://alexanderx.net/

dpixel

  • Newbie
  • *
  • Posts: 20
    • View Profile
Re: FPS Help
« Reply #3 on: August 30, 2013, 12:39:37 am »
First, thanks for the replys.

@ slotdev - Yes, I have tried window.setFramerateLimit.  It seems to work fairly well, but I've noticed some inconsistencies at higher frame rates.  For an example, if I set the fps @ 150 at a screen resolution of 800x450 and then change the resolution to say 1600x900 and then back to 800x450, the fps changes to ~130 fps.  The code I have here doesn't do that.  So I didn't know how accurate window.setFramerateLimit was.

@ AlexxanderX - Does sf::VideoMode::getFullscreenModes() keep the aspect ratio if initially set to a non-full screen mode?  Another words...a black border around what it can't fill.   
One of the reasons I'm messing around with SFML is the way the textures and sprites stretch with the screen.  I think SDL 2.0 does this, but I wanted to see what SFML can do.  I'm a pixel artist, so I don't want my pixels stretching the wrong way.   ;)

My code here is just for testing/learning purposes. 

AlexxanderX

  • Full Member
  • ***
  • Posts: 128
    • View Profile
    • AlexanderX
Re: FPS Help
« Reply #4 on: August 30, 2013, 08:30:22 am »
No will don't keep same aspect ratio. Anyway for switching to fullscreen still need to apply to the window sf::Style::Fullscreen.
Here you can find my blog and tutorials about SFML - http://alexanderx.net/ (died...) - http://web.archive.org/web/20160110002847/http://alexanderx.net/

zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
Re: FPS Help
« Reply #5 on: August 30, 2013, 01:40:39 pm »
Yes, I have tried window.setFramerateLimit.  It seems to work fairly well, but I've noticed some inconsistencies at higher frame rates.  For an example, if I set the fps @ 150 at a screen resolution of 800x450 and then change the resolution to say 1600x900 and then back to 800x450, the fps changes to ~130 fps.  The code I have here doesn't do that.  So I didn't know how accurate window.setFramerateLimit was.

You shouldn't worry so much about the exact framerate your code is running at. Instead you should focus on making your code be framerate independent. After all some computers will be just so slow you might at best get 15 FPS on them without any thread sleeping. Take a look at this article on how to implement a fixed timestep that is framerate independent.

SFML's framerate limit is as accurate as the underlying OS's sleep function (which with a low resolution timer will be quite off).
Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor

dpixel

  • Newbie
  • *
  • Posts: 20
    • View Profile
Re: FPS Help
« Reply #6 on: August 31, 2013, 03:10:07 am »
No will don't keep same aspect ratio.
That's what I was afraid of.  I don't need a full screen, although it would be nice.  Just a bigger screen. 
I did my pixels in Graphics Gale and then resampled them to 200%.  The screen size on the game I'm working on is 800x450 which is 16:9 ratio, so doubled to 1600x900, they look perfect.  Almost any 16:9 ratio setting should look ok depending on the interpolation...some monitors can do it better than others I've found.  The monitor I have has a native resolution of 1920x1080, 16:9 which also looks good, but not as crisp as 1600x900.

@zsbzsb - That's a great article.  Thanks. 
I was thinking about something like those ideas as opposed to my hard coded Walk_Right() animation function below.  I've been programming for 20+ years and developed some bad habits.  "Old dog, new tricks syndrome"  :D

 

anything