I'm learning basic frame independent movement, but I have a necessary need in the implementation.
Right now, I'm searching for C++ code, but I need a complete example inside a GameLoop that allows an increase in speed. Not a gradual increase, but just the ability to move my sprite faster. I have to translate the C++ code to vb .net since there are not many examples. So let me be clear about this ->
I have a simple GameLoop. In the GameLoop, I have two calls to functions
Update()
Render()
I understand that for the Update() function I should put a deltaTime parameter. So it should be
Update(deltaTime As double)
Since this is how most examples on the web are shown, I just copied the idea but I don't have an actual frame independent setup yet.
How can I set this up and call the Render function.
Please keep in mind, that if it works, that's fine - I cut and paste a different example like that before, but there was no way to increase the speed of the moving sprite. I don't even know where to begin with this?
Please note if you only have C++ code, I will do my best to translate it, so for me it's acceptable.
I wont give you code, cause I'm positive that you will be able to fix this with a proper description, but I will gladly explain how to move your sprite without frame rate dependency.
As you said, you already pass a delta-time in to the function.
The delta time is the time that it took between now and the last time the function was called (a frame).
When you move your sprite, you probably move it by a specific number of pixels, instead of doing this every frame, you should multiply the pixel range with the delta time.
This will make into a quite simple formula:
DetlaTime * TheNumberOfPixelsToMoveInASecond.
If you mul it with 10, then the sprite will move 10 pixels in one second. Mul it with 100, it will move 100 pixels in one second.
That deltaTime idea is to allow your game to run in a way where the perceived speed of the gameplay is constant no matter how fast or slow the machine and environment are that are running the game.
You might notice if you run some poorly coded games designed for old hardware on hardware much newer that the gameplay goes way too fast and becomes unplayable on those fast machines without deliberately slowing things down. There are actual slowdown utilities just to deal with that problem, like Mo'Slow and Cpukiller. This is because these old games were coded in a way where things were being changed by a constant amount every frame instead of a variable amount based on the time that has passed.
So to avoid this problem, you move all your sprites each frame by numbers that are multiples of deltaTime. That'll give you the sense of consistent speed regardless of the speed of the machine/environment.
Now if you want an adjustable game speed on top of that where you want to allow users to deliberately make the game faster, then you introduce a second variable on top of deltaTime that you also multiply by, like gameSpeed. So your sprites should move in Update by a multiple of both deltaTime and gameSpeed.
Related
I am creating a physics simulator of sorts and I have thousands of point-like objects (single pixels) moving at the same time. The way I have this setup currently is each point moving only one pixel per frame, which makes it easy to keep track of them in a two dimensional array and check if they're going to collide. However, this solution doesn't permit frame independent movement, which is necessary, because the collision detection is very slow. What is the most efficient way of doing collision detection in this case?
Okay, first things first:
On any modern OS, your app will be either
Sharing processor time with another app, or the OS itself, which is about the same thing
Doing different amounts of work at different times - like, loading assets in the background, rebuilding collision trees, or playing Pac-Man
Fighting the flying toasters
Also, you never know what kind of hardware your app, if distributed, will be running on. This entails lots of headaches, but the first and foremost is that you never know, at compile time, how much real time has elapsed between frames.
(A funny situation recently arose when a customer wanted an orbital calculation to be correct after he had closed his laptop, got on a plane, and reopened it. Easy enough to fix, but you might want to anticipate a 12 hour per frame situation.)
So, how do you deal with this?
Any framework will provide a timer of some sort. I'm not sure how SDL handles this, but typically, on Windows, you'd use GetTickCount() to get the elapsed milliseconds between frames. Each particle has a velocity, expressed in units per second. (Please use meters. Save the world the pain of Units Of user1868866).
When moving the particle,
pos += velocity * elapsed_time;
Or, as a concrete example, if I am in a car moving at 50 mph,
position += 50 miles/hr * 2 hr = 100 miles.
Doing this will solve the problem where particles are moving in frame time instead of simulation/game/real time.
Now, the collision-detection problem. Since we're working in 2D here...
With more than a handful of objects, you can't compare every object to every other object in a reasonable amount of time to see if they collide.
So, we have fancy things like Quadtrees. The idea is to partition your space recursively into quadrants, each of which is really a data structure that somehow "contains" all of the items that fall within its bounds. Then, you only have to check for collision between items within the same quadtree node.
Implementation of a quadtree for your specific applicatino is way, way too long to be appropriate for an SO answer, but I encourage you to research it, try and implement it, and come back here with any issues you have. Another great resource is gamedev.stackexchange.com, which is more game/graphics focused than SO.
Good luck.
I need to update a QPixmap 1024x128 (math function paints a picture) 30...60 times a second and i don't want to use Animation Framework - i think that is overkill for this purpose. Math function works much faster than 1/60 second and takes constant time to work, so it is not an issue.
Should i use QTimer with 30...60 ticks per second (TPS) and call update() in timer SLOT? But QTimer is not syncronized with actual screen updates and QTimer is inaccurate. My QTimer rate may be too low (not smooth motion) or too high (eat too much CPU) - how to find good one? My experiments showed that i need different QTimer intervals for my linux and windows test machines to get smooth update: linux: 30 TPS, windows: 50...60 TPS (i see rugged motion if i set 1000/30 msec).
Or maybe i mis-understood Animation Framework and actually it is very simple and appropriate for this task?
Long shot, but with ruling out the animation framework you don't leave us many options. One idea, which only works, if your math function can calculate all frames beforehand, is to greate an animated gif or mng on the fly and play this with QMovie. But from the overhead, I am not sure that is is better than the animation framework.
You don't need the Animation Framework to do any animation, but it is one option that may be of use to you.
It sounds like you think the QTimer should be synchronised to the paint event, but actually it doesn't matter.
If you imagine an object is to travel from A to B. Many people when starting to animate something like this for the first time, without the framework, would simply have an update function and do something like this: -
QPoint pos(pObject->getPos()); // get the current position
pObject->setPos(pos + QPoint(2, 0); // set the position to previous + 2;
In this situation, the update of the object is dependent on how quickly the computer will run; the faster the machine, the quicker the object will move, regardless of the render frame rate
To fix this, so that the object moves at the same rate, regardless of the computational power of the machine, the update function needs to consider the time since the last update and factor that in: -
QPoint updateSpeed(30,0); // speed at which the object will move
int deltaTime = m_timer.elapsed(); // how long since we last updated
QPoint newPos = pObject->getPos() + QPoint(updateSpeed.X() * deltaTime, updateSpeed.Y());
pObject->setPos(newPos);
So, now that the object's animation is reliant on time, regardless of the speed at which the renderer draws the object, it will always run at the same rate. On a slow machine the elapsed time between updates is greater, so the distance the object moves is further between updates, compared with a faster machine. Two machines running at different speeds will preserve the object's movement to be the same distance in the same amount of time.
Going back to your question, you said you're calculating the image from a math function, so long as the image is updated according to time, in the same way that the animated object in the above example is animated, then you just need a timer to call the update() function on the QPixmap at 30 or 60 frames per second, and there is no need to link it to the updating of the calculation of image data.
Finally, if this is not answering your question, as I understand it, please post an example of how the QPixmap data is being generated.
Is there any way to calculate how much updates should be made to reach desired frame rate, NOT system specific? I found that for windows, but I would like to know if something like this exists in openGL itself. It should be some sort of timer.
Or how else can I prevent FPS to drop or raise dramatically? For this time I'm testing it on drawing big number of vertices in line, and using fraps I can see frame rate to go from 400 to 200 fps with evident slowing down of drawing it.
You have two different ways to solve this problem:
Suppose that you have a variable called maximum_fps, which contains for the maximum number of frames you want to display.
Then You measure the amount of time spent on the last frame (a timer will do)
Now suppose that you said that you wanted a maximum of 60FPS on your application. Then you want that the time measured be no lower than 1/60. If the time measured s lower, then you call sleep() to reach the amount of time left for a frame.
Or you can have a variable called tick, that contains the current "game time" of the application. With the same timer, you will incremented it at each main loop of your application. Then, on your drawing routines you calculate the positions based on the tick var, since it contains the current time of the application.
The big advantage of option 2 is that your application will be much easier to debug, since you can play around with the tick variable, go forward and back in time whenever you want. This is a big plus.
Rule #1. Do not make update() or loop() kind of functions rely on how often it gets called.
You can't really get your desired FPS. You could try to boost it by skipping some expensive operations or slow it down by calling sleep() kind of functions. However, even with those techniques, FPS will be almost always different from the exact FPS you want.
The common way to deal with this problem is using elapsed time from previous update. For example,
// Bad
void enemy::update()
{
position.x += 10; // this enemy moving speed is totally up to FPS and you can't control it.
}
// Good
void enemy::update(elapsedTime)
{
position.x += speedX * elapsedTime; // Now, you can control its speedX and it doesn't matter how often it gets called.
}
Is there any way to calculate how much updates should be made to reach desired frame rate, NOT system specific?
No.
There is no way to precisely calculate how many updates should be called to reach desired framerate.
However, you can measure how much time has passed since last frame, calculate current framerate according to it, compare it with desired framerate, then introduce a bit of Sleeping to reduce current framerate to the desired value. Not a precise solution, but it will work.
I found that for windows, but I would like to know if something like this exists in openGL itself. It should be some sort of timer.
OpenGL is concerned only about rendering stuff, and has nothing to do with timers. Also, using windows timers isn't a good idea. Use QueryPerformanceCounter, GetTickCount or SDL_GetTicks to measure how much time has passed, and sleep to reach desired framerate.
Or how else can I prevent FPS to drop or raise dramatically?
You prevent FPS from raising by sleeping.
As for preventing FPS from dropping...
It is insanely broad topic. Let's see. It goes something like this: use Vertex buffer objects or display lists, profile application, do not use insanely big textures, do not use too much alpha-blending, avoid "RAW" OpenGL (glVertex3f), do not render invisible objects (even if no polygons are being drawn, processing them takes time), consider learning about BSPs or OCTrees for rendering complex scenes, in parametric surfaces and curves, do not needlessly use too many primitives (if you'll render a circle using one million polygons, nobody will notice the difference), disable vsync. In short - reduce to absolute possible minimum number of rendering calls, number of rendered polygons, number of rendered pixels, number of texels read, read every available performance documentation from NVidia, and you should get a performance boost.
You're asking the wrong question. Your monitor will only ever display at 60 fps (50 fps in Europe, or possibly 75 fps if you're a pro-gamer).
Instead you should be seeking to lock your fps at 60 or 30. There are OpenGL extensions that allow you to do that. However the extensions are not cross platform (luckily they are not video card specific or it'd get really scary).
windows: wglSwapIntervalEXT
x11 (linux): glXSwapIntervalSGI
max os x: ?
These extensions are closely tied to your monitor's v-sync. Once enabled calls to swap the OpenGL back-buffer will block until the monitor is ready for it. This is like putting a sleep in your code to enforce 60 fps (or 30, or 15, or some other number if you're not using a monitor which displays at 60 Hz). The difference it the "sleep" is always perfectly timed instead of an educated guess based on how long the last frame took.
You absolutely do wan't to throttle your frame-rate it all depends on what you got
going on in that rendering loop and what your application does. Especially with it's
Physics/Network related. Or if your doing any type of graphics processing with an out side toolkit (Cairo, QPainter, Skia, AGG, ...) unless you want out of sync results or 100% cpu usage.
This code may do the job, roughly.
static int redisplay_interval;
void timer(int) {
glutPostRedisplay();
glutTimerFunc(redisplay_interval, timer, 0);
}
void setFPS(int fps)
{
redisplay_interval = 1000 / fps;
glutTimerFunc(redisplay_interval, timer, 0);
}
Here is a similar question, with my answer and worked example
I also like deft_code's answer, and will be looking into adding what he suggests to my solution.
The crucial part of my answer is:
If you're thinking about slowing down AND speeding up frames, you have to think carefully about whether you mean rendering or animation frames in each case. In this example, render throttling for simple animations is combined with animation acceleration, for any cases when frames might be dropped in a potentially slow animation.
The example is for animation code that renders at the same speed regardless of whether benchmarking mode, or fixed FPS mode, is active. An animation triggered before the change even keeps a constant speed after the change.
I made a program (in C++, using gl/glut) for study purposes where you can basically run around a screen (in first person), and it has several solids around the scene. I tried to run it on a different computer and the speed was completely different, so I searched on the subject and I'm currently doing something like this:
Idle function:
start = glutGet (GLUT_ELAPSED_TIME);
double dt = (start-end)*30/1000;
<all the movement*dt>
glutPostRedisplay ();
end = glutGet (GLUT_ELAPSED_TIME);
Display function:
<rendering for all objects>
glutSwapBuffers ();
My question is: is this the proper way to do it? The scene is being displayed after the idle function right?
I tried placing end = glutGet (GLUT_ELAPSED_TIME) before glutSwapBuffers () and didn't notice any change, but when I put it after glutSwapBuffers () it slows down alot and even stops sometimes.
EDIT: I just noticed that in the way I'm thinking, end-start should end up being the time that passed since all the drawing was done and before the movement update, as idle () would be called as soon as display () ends, so is it true that the only time that's not being accounted for here is the time the computer takes to do all of the movement? (Which should be barely nothing?)
Sorry if this is too confusing..
Thanks in advance.
I don't know what "Glut" is, but as a general rule of game development, I would never base movement speed off of how fast the computer can process the directives. That's what they did in the late 80's and that's why when you play an old game, things move at light speed.
I would set up a timer, and base all of my movements off of clear and specific timed events.
Set up a high-resolution timer (eg. QueryPerformanceCounter on Windows) and measure the time between every frame. This time, called delta-time (dt), should be used in all movement calculations, eg. every frame, set an object's position to:
obj.x += 100.0f * dt; // to move 100 units every second
Since the sum of dt should always be 1 over 1 second, the above code increments x by 100 every second, no matter what the framerate is. You should do this for all values which change over time. This way your game proceeds at the same rate on all machines (framerate independent), rather than depending on the rate the computer processes the logic (framerate dependent). This is also useful if the framerate starts to drop - the game doesn't suddenly start running in slow-motion, it keeps going at the same speed, just rendering less frequently.
I wouldn't use a timer. Things can go wrong, and events can stack up if the PC is too slow or too busy to run at the required rate. I'd let the loop run as fast as it's allowed, and each time calculate how much time has passed and put this into your movement/logic calculations.
Internally, you might actually implement small fixed-time sub-steps, because trying to make everything work right on variable time-steps is not as simple as x+=v*dt.
Try gamedev.net for stuff like this. lots of articles and a busy forum.
There is a perfect article about game loops that should give you all the information you need.
You have plenty of answers on how to do it the "right" way, but you're using GLUT, and GLUT sometimes sacrifices the "right" way for simplicity and maintaining platform independence. The GLUT way is to register a timer callback function with glutTimerFunc().
static void timerCallback (int value)
{
// Calculate the deltas
glutPostRedisplay(); // Have GLUT call your display function
glutTimerFunc(elapsedMilliseconds, timerCallback, value);
}
If you set elapsedMilliseconds to 40, this function will be called slightly less than 25 times a second. That slightly less will depend upon how long the computer takes to process your delta calculation code. If you keep that code simple, your animation will run the same speed on all systems, as long as each system can process the display function in less than 40 milliseconds. For more flexibility, you can adjust the frame rate at runtime with a command line option or by adding a control to your interface.
You start the timer loop by calling glutTimerFunc(elapsedMilliseconds, timerCallback, value); in your initialization process.
I'm a games programmer and have done this many times.
Most games run the AI in fixed time increments like 60hz for example. Also most are synced to the monitor refresh to avoid screen tearing so the max rate would be 60 even if the machine was really fast and could do 1000 fps. So if the machine was slow and was running at 20 fps then it would call the update ai function 3 times per render. Doing it this way solves rounding error problems with small values and also makes the AI deterministic across multiple machines since the AI update rate is decoupled from the machine speed ( necessary for online multiplayer games).
This is a very hard question.
The first thing you need to awnser yourself is, do you really want your application to really run at the same speed or just appear to run the same speed? 99% of the time you only want it to appear to run the same speed.
Now there are two problems: Speeding up you application or slowing it down.
Speeding up your application is really hard, since that requires things like dynamic LOD that adjusts to the current speed. This means LOD in everything, not only graphics.
Slowing your application down is fairly easy. You have two options sleeping or "busy waiting". It basically depends on your target frame rate for your simulation. If your simulation is way above something like 50 ms you can sleep. The problem is that when sleeping you are depended on the process scheduler and it works on average system at granularity of 10 ms.
In games busy waiting is not such a bad idea. What you do is you update your simulation and render your frame, then you use an time accumulator for the next frame. When rendering frames without simulation you then interpolate the state to get a smooth animation. A really great article on the subject can be found at http://gafferongames.com/game-physics/fix-your-timestep/.
I am programming a game using Visual C++ 2008 Express and the Ogre3D sdk.
My core gameplay logic is designed to run at 100 times/second. For simplicity, I'll say it's a method called 'gamelogic()'. It is not time-based, which means if I want to "advance" game time by 1 second, I have to call 'gamelogic()' 100 times. 'gamelogic()' is lightweight in comparison to the game's screen rendering.
Ogre has a "listener" logic that informs your code when it's about to draw a frame and when it has finished drawing a frame. If I just call 'gamelogic()' just before the frame rendering, then the gameplay will be greatly affected by screen rendering speed, which could vary from 5fps to 120 fps.
The easy solution that comes to mind is : calculate the time elapsed since last rendered frame and call 'gamelogic()' this many times before the next frame: 100 * timeElapsedInSeconds
However, I pressume that the "right" way to do it is with multithreading; have a separate thread that runs 'gamelogic()' 100 times/sec.
The question is, how do I achieve this and what can be done when there is a conflict between the 2 separate threads : gamelogic changing screen content (3d object coordinates) while Ogre is rendering the screen at the same time .
Many thanks in advance.
If this is your first game application, using multi-threading to achieve your results might be more work than you should really tackle on your first game. Sychronizing a game loop and render loop in different threads is not an easy problem to solve.
As you correctly point out, rendering time can greatly affect the "speed" of your game. I would suggest that you do not make your game logic dependent on a set time slice (i.e. 1/100 of a second). Make it dependent on the current frametime (well, the last frametime since you don't know how long your current frame will take to render).
Typically I would write something like below (what I wrote is greatly simplified):
float Frametime = 1.0f / 30.0f;
while(1) {
game_loop(Frametime); // maniuplate objects, etc.
render_loop(); // render the frame
calculate_new_frametime();
}
Where Frametime is the calculcated frametime that the current frame took. When you process your game loop you are using the frametime from the previous frame (so set the initial value to something reasonable, like 1/30th or 1/15th of a second). Running it on the previous frametime is close enough to get you the results that you need. Run your game loop using that time frame, then render your stuff. You might have to change the logic in your game loop to not assume a fixed time interval, but generally those kinds of fixes are pretty easy.
Asynchoronous game/render loops may be something that you ultimately need, but that is a tough problem to solve. It involves taking snapshops of objects and their relevant data, putting those snapshots into a buffer and then passing the buffer to the rendering engine. That memory buffer will have to be correctly partitioned around critical sections to avoid having the game loop write to it while the render loop is reading from it. You'll have to take care to make sure that you copy all relevant data into the buffer before passing to the render loop. Additionally, you'll have to write logic to stall either the game or render loops while waiting for one or the other to complete.
This complexity is why I suggest writing it in a more serial manner first (unless you have experience, which you might). The reason being is that doing it the "easy" way first will force you to learn about how your code works, how the rendering engine works, what kind of data the rendering engine needs, etc. Multithreading knowledge is defintely required in complex game development these days, but knowing how to do it well requires indepth knowledge of how game systems interact with each other.
There's not a whole lot of benefit to your core game logic running faster than the player can respond. About the only time it's really useful is for physics simulations, where running at a fast, fixed time step can make the sim behave more consistently.
Apart from that, just update your game loop once per frame, and pass in a variable time delta instead of relying on the fixed one. The benefit you'll get from doing multithreading is minimal compared to the cost, especially if this is your first game.
Double buffering your render-able objects is an approach you could explore. Meaning, the rendering component is using 1 buffer which is updated when all game actions have updated the relevant object in the 2nd buffer.
But personally I don't like it, I'd (and have, frequently) employ Mark's approach.