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

Author Topic: sf::Input.GetMouseX() and Y()  (Read 5365 times)

0 Members and 1 Guest are viewing this topic.

tntexplosivesltd

  • Full Member
  • ***
  • Posts: 163
    • View Profile
sf::Input.GetMouseX() and Y()
« on: December 15, 2010, 12:33:05 am »
I have written some movement code for SFML 1.6 as follows:
Code: [Select]

while (App.IsOpened())
    {
        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);
        App.SetCursorPosition(centreX, centreY);


I then use OpenGL to rotate and translate blah, but that's not important.

Now, in Arch Linux x86_64 (with X11 and XFCE), this works fine. The view rotates fine.
In Windows (Windows 7 32-bit), it's a different story. The view hardly moves with the same mouse movements. It's so annoying! However, the keyboard movement is exactly the same.

What's going on?

tntexplosivesltd

  • Full Member
  • ***
  • Posts: 163
    • View Profile
sf::Input.GetMouseX() and Y()
« Reply #1 on: December 15, 2010, 02:44:50 am »
Fixed it somewhat. Added sf::Sleep(0.005) to the mail game loop, but this does expectedly lower the framerate. Is there a better way to give the inputs a chance to register, but keep a higher framerate?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
sf::Input.GetMouseX() and Y()
« Reply #2 on: December 15, 2010, 08:02:55 am »
Where do you call GetEvent?
Laurent Gomila - SFML developer

tntexplosivesltd

  • Full Member
  • ***
  • Posts: 163
    • View Profile
sf::Input.GetMouseX() and Y()
« Reply #3 on: December 16, 2010, 08:06:56 am »
I call it just after creating my sf::RenderWindow() object (outside the game loop). I tried moving it to the main loop, but it didn't help out.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
sf::Input.GetMouseX() and Y()
« Reply #4 on: December 16, 2010, 08:38:32 am »
Can you show your complete code please?
Laurent Gomila - SFML developer

tntexplosivesltd

  • Full Member
  • ***
  • Posts: 163
    • View Profile
sf::Input.GetMouseX() and Y()
« Reply #5 on: December 17, 2010, 10:21:56 am »
Complete code? Here we go...
(keep in mind it's not finished/optimised yet, and I'm relatively new to C++ and SFML)
Code: [Select]

////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////

#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <cmath>
#include <iostream>

#define ALL_CUBES 1
using namespace std;

////////////////////////////////////////////////////////////
/// Entry point of application
///
/// \return Application exit code
///
////////////////////////////////////////////////////////////

class Block
{
    public:
        int x, y, z, size;
        Block(int blockSize, int xCoord, int yCoord, int zCoord) {x = xCoord; y=yCoord; z=zCoord; size = blockSize; }
};

//DrawCube - creates 6 face polygons, with size and position arguments
void DrawCube(float size, float xOffset, float yOffset, float zOffset)
{
    size = size / 2;
    //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    glBegin(GL_QUADS);
        glEdgeFlag(GL_TRUE);

        glColor3f(((xOffset/16+10)/20), ((yOffset/16+10)/20), ((zOffset/16+10)/20));

        glVertex3f(-size + xOffset, -size + yOffset, -size + zOffset);
        glVertex3f(-size + xOffset,  size + yOffset, -size + zOffset);
        glVertex3f( size + xOffset,  size + yOffset, -size + zOffset);
        glVertex3f( size + xOffset, -size + yOffset, -size + zOffset);

        glVertex3f(-size + xOffset, -size + yOffset, size + zOffset);
        glVertex3f(-size + xOffset,  size + yOffset, size + zOffset);
        glVertex3f( size + xOffset,  size + yOffset, size + zOffset);
        glVertex3f( size + xOffset, -size + yOffset, size + zOffset);

        glVertex3f(-size + xOffset, -size + yOffset, -size + zOffset);
        glVertex3f(-size + xOffset,  size + yOffset, -size + zOffset);
        glVertex3f(-size + xOffset,  size + yOffset,  size + zOffset);
        glVertex3f(-size + xOffset, -size + yOffset,  size + zOffset);

        glVertex3f(size + xOffset, -size + yOffset, -size + zOffset);
        glVertex3f(size + xOffset,  size + yOffset, -size + zOffset);
        glVertex3f(size + xOffset,  size + yOffset,  size + zOffset);
        glVertex3f(size + xOffset, -size + yOffset,  size + zOffset);

        glVertex3f(-size + xOffset, -size + yOffset,  size + zOffset);
        glVertex3f(-size + xOffset, -size + yOffset, -size + zOffset);
        glVertex3f( size + xOffset, -size + yOffset, -size + zOffset);
        glVertex3f( size + xOffset, -size + yOffset,  size + zOffset);

        glVertex3f(-size + xOffset, size + yOffset,  size + zOffset);
        glVertex3f(-size + xOffset, size + yOffset, -size + zOffset);
        glVertex3f( size + xOffset, size + yOffset, -size + zOffset);
        glVertex3f( size + xOffset, size + yOffset,  size + zOffset);
    glEnd();
}
int main()
{
    bool moving = false;
    //up/down rotation
    float rotation = 0;
    //horizintal rotation
    float zRotation = 0;

    //player movement variables - need to make into player class - maybe
    float playerSpeed = 1;
    float playerX = 0;
    float playerY = 0;
    float playerZ = 0;
    float xStep = 0;
    float yStep = 0;
    float zStep = 0;

    float mouseDeltaX = 0;
    float mouseDeltaY = 0;

    int mousePrevX;
    int mousePrevY;

    //PI
    const float PI = 3.14159265358979323846264338329750288419716939937510582;

    //settings for OpenGL rendering context
    sf::WindowSettings Settings;
    Settings.DepthBits         = 24; // Request a 24 bits depth buffer
    Settings.StencilBits       = 8;  // Request a 8 bits stencil buffer
    Settings.AntialiasingLevel = 8;  // Request 8 levels of antialiasing

    // Create the main window and appropriate variables
    sf::VideoMode bestMode = sf::VideoMode::GetMode(0);
    int bestWidth = bestMode.Width;
    int bestHeight = bestMode.Height;
    int centreX = bestWidth / 2;
    int centreY = bestHeight / 2;

    Block * allBlocks[8000];

    sf::RenderWindow * App = new sf::RenderWindow(sf::VideoMode(bestWidth, bestHeight, 32), "Rendering Test", sf::Style::Fullscreen, Settings); //, sf::Style::Fullscreen

    // Hide the cursor
    App->ShowMouseCursor(false);
    //App->SetFramerateLimit(200);

    // real-time input handler
    //const sf::Input& Input = App->GetInput();

    // Set color and depth clear value
    glShadeModel(GL_SMOOTH);
    // Colours and depths to clear to
    glClearDepth(1.f);
    glClearColor(0.f, 0.f, 0.3f, 0.f);


    // Enable Z-buffer read and write
    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_TRUE);

    // Setup a perspective projection
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum(-1.f, 1.f, -1.f, 1.f, 1.5f, 10000.f);
    glViewport (0, 0, bestWidth, bestHeight);

    // DisplayList for cubes
    int iterator = 0;
    for (int i = -10; i < 10;i++)
    {
        for (int j = -10; j < 10; j++)
        {
            for (int k = -10; k < 10; k++)
            {
                allBlocks[iterator] = new Block(16, i*60, j*60, k*60);
                iterator++;
            }
        }
    }

    glNewList(ALL_CUBES, GL_COMPILE);
    for (int i = 0; i < 8000; i++)
    {
        DrawCube(allBlocks[i]->size, allBlocks[i]->x, allBlocks[i]->y, allBlocks[i]->z);
        //cout << "" << allBlocks[i]->size << " " << allBlocks[i]->x << " " << allBlocks[i]->y << " " << allBlocks[i]->z << endl;
        delete allBlocks[i];
    }
    glEndList();


    //cout << "zRot: " << zRotation << " rot: " << rotation << endl;
    // Start game loop
    while (App->IsOpened())
    {
        const sf::Input& Input = App->GetInput();
        //sf::Sleep(0.005);
        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;
        }

        // 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");
            }
        }

        // 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;
}

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
sf::Input.GetMouseX() and Y()
« Reply #6 on: December 17, 2010, 10:45:30 am »
Try moving your event loop atthe beginning of your main loop.

Then, what does "The view hardly moves with the same mouse movements" mean exactly? What framerate do you have?
Laurent Gomila - SFML developer

tntexplosivesltd

  • Full Member
  • ***
  • Posts: 163
    • View Profile
sf::Input.GetMouseX() and Y()
« Reply #7 on: December 17, 2010, 10:50:42 am »
Quote from: "Laurent"
Try moving your event loop at the beginning of your main loop.

Hasn't worked :(

Quote from: "Laurent"

Then, what does "The view hardly moves with the same mouse movements" mean exactly? What framerate do you have?

In Linux, if I move the mouse say 5cm, the view on screen moves as expected in the window.
However, in Windows, for the same 5cm mouse movement, the view moves a much smaller amount, and in jumps. The framerate stays relatively constant. (~300-400 FPS)

tntexplosivesltd

  • Full Member
  • ***
  • Posts: 163
    • View Profile
sf::Input.GetMouseX() and Y()
« Reply #8 on: December 18, 2010, 09:50:57 am »
Any ideas? I don't want to be limited to 200FPS. Also, if I set the framerate limit, the problem persists.

Terrydil

  • Jr. Member
  • **
  • Posts: 51
    • View Profile
sf::Input.GetMouseX() and Y()
« Reply #9 on: December 18, 2010, 04:32:57 pm »
This is slightly off-topic as it doesn't relate to fixing your problem, so feel free to ignore...

But am I missing something about framerates?  Why would you not want to be limited to 200fps?  I keep seeing stuff like "I need more than 400 fps".  Do you just hate having idle cpu time?   Visually you can't tell the difference right?  Just curious if there was some other reason.  :)

tntexplosivesltd

  • Full Member
  • ***
  • Posts: 163
    • View Profile
sf::Input.GetMouseX() and Y()
« Reply #10 on: December 19, 2010, 07:44:12 am »
Well, if someone has an older computer, I don't want them to have the 5ms pause because it will introduce more lag for the computer, i.e. I want the game to be able to run as fast as possible on any computer, without any built-in pauses.

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
sf::Input.GetMouseX() and Y()
« Reply #11 on: December 19, 2010, 12:17:56 pm »
Well, if you use sf::Window::SetFrameLimit(60), it won't "pause" your app unless it runs fast enough to have 60fps (ie. if your computer is slow and you only get 50fps you won't have any sleep function call). So there's no need of 400fps on one's computer to run at 60fps on another pc.

(Moreover it's illogical.)
SFML / OS X developer

tntexplosivesltd

  • Full Member
  • ***
  • Posts: 163
    • View Profile
sf::Input.GetMouseX() and Y()
« Reply #12 on: December 19, 2010, 10:14:21 pm »
That is true, but using sf::Window::SetFrameLimit(60) doesn't fix my problem :(

tntexplosivesltd

  • Full Member
  • ***
  • Posts: 163
    • View Profile
sf::Input.GetMouseX() and Y()
« Reply #13 on: December 20, 2010, 10:33:44 am »
I'll just use sf::Sleep(0.005). It gives the CPU(s) some idle time, and basically fixes my problem.

Terrydil

  • Jr. Member
  • **
  • Posts: 51
    • View Profile
sf::Input.GetMouseX() and Y()
« Reply #14 on: December 20, 2010, 02:38:36 pm »
If it works it might not be worth messing with anymore, but do you get roughly the same values from GetMouseX/Y with similar movements on both Linux and Windows?