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

Author Topic: sf::Sleep problem and mouse input problem.  (Read 4328 times)

0 Members and 1 Guest are viewing this topic.

tntexplosivesltd

  • Full Member
  • ***
  • Posts: 163
    • View Profile
sf::Sleep problem and mouse input problem.
« on: December 27, 2010, 06:10:17 am »
I have a bit of a problem, stemming from this code:
Code: [Select]
while (App->IsOpened())
    {
        sf::Sleep(0.001);
        // Process all "application" 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();

            // Resize event : adjust viewport
            if (Event.Type == sf::Event::Resized)
                glViewport(0, 0, Event.Size.Width, Event.Size.Height);

            /*
            if (Event.Key.Code == sf::Key::F1)
            {
                sf::Image Screen = App->Capture();
                Screen.SaveToFile("screenshot.jpg");
            }
            */
        }

        cout << "" << 1/App->GetFrameTime() << endl;
        moving = false;
        // adjust x- y- and z- step amounts based on current direction/view rotation
        xStep = playerSpeed * sin((PI * zRotation) / 180);
        yStep = playerSpeed * cos((PI * zRotation) / 180);
        zStep = -playerSpeed * sin((PI * rotation) / 180);
        //cout << "zRot: " << zRotation << " rot: " << rotation << endl;

        // process real-time input
        if (Input.IsKeyDown(sf::Key::W))    // W = forwards
        {
            moving = true;
            playerX -= (xStep * cos((PI * rotation) / 180));
            playerY -= (yStep * cos((PI * rotation) / 180));
            playerZ -= zStep;
        }

        if (Input.IsKeyDown(sf::Key::S))    // S = backwards
        {
            moving = true;
            playerX += (xStep * cos((PI * rotation) / 180));
            playerY += (yStep * cos((PI * rotation) / 180));
            playerZ += zStep;
        }

        if (Input.IsKeyDown(sf::Key::A))    //A = strafe left
        {
            if ((moving = true))
            {
                xStep *= 0.707106;
                yStep *= 0.707106;
            }
            playerX += yStep;
            playerY -= xStep;
        }

        if (Input.IsKeyDown(sf::Key::D))    //D = strafe right
        {
            if ((moving = true))
            {
                xStep *= 0.707106;
                yStep *= 0.707106;
            }
            playerX -= yStep;
            playerY += xStep;
        }
        // Rotate view based on mouse movement
        mouseDeltaX = Input.GetMouseX() - centreX;
        mouseDeltaY = Input.GetMouseY() - centreY;
        zRotation += (mouseDeltaX / 10);
        rotation += (mouseDeltaY / 10);
        //cout << "DeltaX: " << mouseDeltaX << " DeltaY: " << mouseDeltaY << endl;

        // Z rotation normalisation - between 0 and 360
        if (zRotation >= 360)
        {
            zRotation -= 360;
        }

        if (zRotation < 0)
        {
            zRotation += 360;
        }

        // X/Y rotation limits
        if (rotation < -90)
        {
            rotation = -90;
        }
        if (rotation >= 90)
        {
            rotation = 90;
        }


        // Set the active window before using OpenGL commands
        // It's useless here because active window is always the same,
        // but don't forget it if you use multiple windows or controls
        App->SetActive();

        //  color and depth buffer
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();

        // Rotate the view first
        glRotatef(-90 + rotation, 1.f, 0.f, 0.f);
        glRotatef(zRotation, 0.f, 0.f, 1.f);

        // Then translate it
        glTranslatef(playerX, playerY, playerZ);

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glCallList(ALL_CUBES);
        glFlush();

        App->Display();
        App->SetCursorPosition(centreX, centreY);
    }
    return EXIT_SUCCESS;
}


What is happening is when I have the sf::Sleep(0.001) in there, the framerate drops to ~60FPS. When I comment it out, it shoots up to ~300-400FPS. Even if it's drawing only one block, the FPS is ~60FPS with sf::Sleep(0.001). This is weird.

Additionally, I still have the same problem listed in this thread, with the mouse input.

So I have a few questions:
1) What is happening with the framerate varying so much?
2) What is the difference between Input.GetMouseX() and Event.MouseMoved.X?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
sf::Sleep problem and mouse input problem.
« Reply #1 on: December 27, 2010, 08:05:46 am »
Quote
1) What is happening with the framerate varying so much?

What's your OS?

Quote
2) What is the difference between Input.GetMouseX() and Event.MouseMoved.X?

There's none. The first one is always available, the second one is given when you receive a MouseMoved event.
Laurent Gomila - SFML developer

tntexplosivesltd

  • Full Member
  • ***
  • Posts: 163
    • View Profile
sf::Sleep problem and mouse input problem.
« Reply #2 on: December 27, 2010, 08:49:38 am »
I'm using Windows 7 32-bit, and Arch Linux X86_64, and getting the same problem on both operating systems :(

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
sf::Sleep problem and mouse input problem.
« Reply #3 on: December 27, 2010, 09:12:01 am »
Thread schedulers in common OSes usually have a time quantum of approx. 16 ms (ie. once a thread goes to bed, it can only wake up after a minimum of 16 ms). And 16ms = 1/0.016 Hz = approx. 60Hz. That could be an explanation.
Laurent Gomila - SFML developer

tntexplosivesltd

  • Full Member
  • ***
  • Posts: 163
    • View Profile
sf::Sleep problem and mouse input problem.
« Reply #4 on: December 27, 2010, 09:41:55 am »
Okay, thanks.
I changed from Input.GetMouseX() to Event.MouseMove.X, and it hasn't changed how the mouse behaves under Windows 7, as outlined in my other thread. I put the sf::Sleep(0.005) in there because it seemed to fix it, but it drags the FPS down to ~60FPS. How can I fix this? Will it improve if I put the rendering in a thread on its own, and everything else in a second thread?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
sf::Sleep problem and mouse input problem.
« Reply #5 on: December 27, 2010, 09:48:24 am »
Quote
How can I fix this?

Seriously, I don't understand why you get these problems with mouse input.
But is it such a bad workaround? I mean, 60 FPS should be enough.

Quote
Will it improve if I put the rendering in a thread on its own, and everything else in a second thread?

I don't know, it depends on the origin of your problem. But you can try.
Laurent Gomila - SFML developer

model76

  • Full Member
  • ***
  • Posts: 231
    • View Profile
sf::Sleep problem and mouse input problem.
« Reply #6 on: December 27, 2010, 12:13:42 pm »
Quote from: "Laurent"
Quote
2) What is the difference between Input.GetMouseX() and Event.MouseMoved.X?

There's none. The first one is always available, the second one is given when you receive a MouseMoved event.
This is not true in SFML 1.6, because Input and Event aren't synchronized. So there are situations where Input.GetMouseX() is not equal to Event.MouseMoved.X.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
sf::Sleep problem and mouse input problem.
« Reply #7 on: December 27, 2010, 12:24:27 pm »
Quote
This is not true in SFML 1.6, because Input and Event aren't synchronized. So there are situations where Input.GetMouseX() is not equal to Event.MouseMoved.X.

Right. However this is a detail, at worst sf::Input will get delayed by one frame. So it can't explain the problems that we're talking about.
Laurent Gomila - SFML developer

tntexplosivesltd

  • Full Member
  • ***
  • Posts: 163
    • View Profile
sf::Sleep problem and mouse input problem.
« Reply #8 on: December 27, 2010, 11:29:13 pm »
Has anyone ever had this problem before? It seems a bit odd.

model76

  • Full Member
  • ***
  • Posts: 231
    • View Profile
sf::Sleep problem and mouse input problem.
« Reply #9 on: December 28, 2010, 03:20:14 am »
If you create a test program in a single file, I will happily compile and run it on my computer. Well, if you are using 1.6, that is...

tntexplosivesltd

  • Full Member
  • ***
  • Posts: 163
    • View Profile
sf::Sleep problem and mouse input problem.
« Reply #10 on: December 28, 2010, 05:26:25 am »
Finally fixed it. I looked back at one of my previous snapshots and found that if I moved App->SetCursorPosition(centreX, centreY); from after App->Display(); to just before I take mouse input:
Code: [Select]
App->SetCursorPosition(centreX, centreY);
mouseDeltaX = Input.GetMouseX() - centreX;
mouseDeltaY = Input.GetMouseY() - centreY;
zRotation += (mouseDeltaX / 10);
rotation += (mouseDeltaY / 10);

it works fine. Yay!
On a side note, why does this change it?

model76

  • Full Member
  • ***
  • Posts: 231
    • View Profile
sf::Sleep problem and mouse input problem.
« Reply #11 on: December 29, 2010, 02:18:48 am »
I don't have an answer to your question, but I would suggest that you make the following changes to your program:

Move the cursor position/rotation stuff to the event loop, and only do the calculations if the cursor has moved.

Also, make the rotation speed independent of the application speed, by dividing the rotation amount by the frame delta time, instead of some constant.

Pseudo code:
Code: [Select]
if( Event.Type == MouseMove )
{
    if( centreX != Event.MouseMoved.X )
        zRotation += (Event.MouseMoved.X - centreX) / frameTime;

    if( centreY != Event.MouseMoved.Y )
        rotation += (Event.MouseMoved.Y - centreY) / frameTime;

    App->SetCursorPosition(centreX, centreY);
}


If you haven't already, I still think you should take a gander at that game loop article I linked to in the other thread.
Here is the link again for good measure:  http://www.koonsolo.com/news/dewitters-gameloop/

You might enjoy it - I did!
Wonderful bedtime reading. :)

tntexplosivesltd

  • Full Member
  • ***
  • Posts: 163
    • View Profile
sf::Sleep problem and mouse input problem.
« Reply #12 on: December 29, 2010, 05:44:53 am »
Okay thanks for that.
I tried scaling the mouse movement by the frame time, but the view moves less when the frame rate is lower. Not sure if this is expected?

model76

  • Full Member
  • ***
  • Posts: 231
    • View Profile
sf::Sleep problem and mouse input problem.
« Reply #13 on: December 29, 2010, 05:54:47 am »
Um, no. Ignore the frame time thing, that was just me not thinking clearly. Sorry  :oops: