SFML community forums
Help => Window => Topic started by: tntexplosivesltd on December 15, 2010, 12:33:05 am
-
I have written some movement code for SFML 1.6 as follows:
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?
-
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?
-
Where do you call GetEvent?
-
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.
-
Can you show your complete code please?
-
Complete code? Here we go...
(keep in mind it's not finished/optimised yet, and I'm relatively new to C++ and SFML)
////////////////////////////////////////////////////////////
// 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;
}
-
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?
-
Try moving your event loop at the beginning of your main loop.
Hasn't worked :(
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)
-
Any ideas? I don't want to be limited to 200FPS. Also, if I set the framerate limit, the problem persists.
-
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. :)
-
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.
-
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.)
-
That is true, but using sf::Window::SetFrameLimit(60) doesn't fix my problem :(
-
I'll just use sf::Sleep(0.005). It gives the CPU(s) some idle time, and basically fixes my problem.
-
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?
-
If it works, it works. Or does it?
I recommend you take a step back and examine the intricacies of the game loop. Here is a good article:
http://www.koonsolo.com/news/dewitters-gameloop/
:)