Frame rate independent game loop
Frame rate independent game loop
Hi everybody
I coded a very simple demo to show how you can implement a frame rate independent game loop. You can download it from here:
https://github.com/glasyalabolas/fb-metaball-demo
Controls:
Arrow keys: move the 'player' (it is just a crappy white ball)
+/- : add/remove metaballs
'p': pauses/unpauses the simulation (but not the rendering, that it's still performed)
The code is copiously commented, and shows a few interesting licks. Be warned, however, that the code is fully OO. Questions, comments and suggestions are greatly appreciated (such as how to upload files to GitHub XD)
Have fun!
Paul
PS: there's another, well-loved forum member that already posted something like this before. See if you can find who he is ;)
UPDATE: 10/31/2017 small code refactoring. Bug fix.
UPDATE: 10/29/2017 small bugfix.
UPDATE: 10/29/2017 added 'metaballsGL.bas', to test the new OpenGL patch to GFX lib by angros47 (need FreeBasic 1.06.0).
UPDATE: added two missing properties to the interface of ILoop. Grrr.
UPDATE: included 'interfaces.bi' which I seem to have dropped when I dragged the folder with ALL needed files to the GitHub file drop box ;)
I coded a very simple demo to show how you can implement a frame rate independent game loop. You can download it from here:
https://github.com/glasyalabolas/fb-metaball-demo
Controls:
Arrow keys: move the 'player' (it is just a crappy white ball)
+/- : add/remove metaballs
'p': pauses/unpauses the simulation (but not the rendering, that it's still performed)
The code is copiously commented, and shows a few interesting licks. Be warned, however, that the code is fully OO. Questions, comments and suggestions are greatly appreciated (such as how to upload files to GitHub XD)
Have fun!
Paul
PS: there's another, well-loved forum member that already posted something like this before. See if you can find who he is ;)
UPDATE: 10/31/2017 small code refactoring. Bug fix.
UPDATE: 10/29/2017 small bugfix.
UPDATE: 10/29/2017 added 'metaballsGL.bas', to test the new OpenGL patch to GFX lib by angros47 (need FreeBasic 1.06.0).
UPDATE: added two missing properties to the interface of ILoop. Grrr.
UPDATE: included 'interfaces.bi' which I seem to have dropped when I dragged the folder with ALL needed files to the GitHub file drop box ;)
Last edited by paul doe on Nov 01, 2017 1:33, edited 9 times in total.
Re: Frame rate independent game loop
missing: interfaces.bi
Re: Frame rate independent game loop
Fixed now. Thanks for pointing it out, dafhi.dafhi wrote:missing: interfaces.bi
Re: Frame rate independent game loop
To better be able to compare how two different implementations manage a render-intensive game loop, a fixed-framerate version, implemented using the regulate() function by dodicat, is in 'loop comparison.bas'. Press '1' to switch to the framerate-independent version, and '2' to switch to the fixed-framerate version. The class is a wrapper for the independent frame rate one, and is named, of course, DodiLoop XD
Another wrapper is shown in 'metaballsGL.bas' and uses the OpenGL patch implemented to the FBGFX by angros47. Use '1' to use the normal FBGX, '2' to use the OpenGL version.
Play around with them to see the similarities and differences. Refer to the articles that I mentioned on the first post to see the pros and cons of each one. Questions, comments, insults, are all welcome.
Have fun!
Paul
EDIT: removed the outdated source code. Simply download the code from the repository to have an up to date version.
Another wrapper is shown in 'metaballsGL.bas' and uses the OpenGL patch implemented to the FBGFX by angros47. Use '1' to use the normal FBGX, '2' to use the OpenGL version.
Play around with them to see the similarities and differences. Refer to the articles that I mentioned on the first post to see the pros and cons of each one. Questions, comments, insults, are all welcome.
Have fun!
Paul
EDIT: removed the outdated source code. Simply download the code from the repository to have an up to date version.
Last edited by paul doe on Nov 01, 2017 1:38, edited 1 time in total.
Re: Frame rate independent game loop
dodiLoop.bi
Code: Select all
Not overriding any virtual method, found 'override' in 'declare property state() as IState ptr override
Element not defined, state in 'return( m_gameLoop->state
Element not defined, renderDevice in 'return( m_gameLoop->renderDevice
Expected expression, found '->' in 'dim as integer metaballCount = m_gameLoop->state->entityList->count - 1
Re: Frame rate independent game loop
It works for me. Did you updated the thing? See the first post, I corrected this bug (which wasn't a 'bug', just GitHub not accepting the commit <grrrrr>)dafhi wrote:dodiLoop.biCode: Select all
Not overriding any virtual method, found 'override' in 'declare property state() as IState ptr override Element not defined, state in 'return( m_gameLoop->state Element not defined, renderDevice in 'return( m_gameLoop->renderDevice Expected expression, found '->' in 'dim as integer metaballCount = m_gameLoop->state->entityList->count - 1
Re: Frame rate independent game loop
Glad to hear that. I just finished uploading everything (again) to Sh*tHub, including the loop comparison. Geez, I don't know what the #%$@ is going on with that site today >:(dafhi wrote:works!
Re: Frame rate independent game loop
This is really nice work, points for sharing your code. I took a quick glance at your metaball drawing algorithm and got rid of the nasty doubly for-loop nested square root call in renderer.bi:
Cheers, Mike
Code: Select all
sub FBRenderer.drawMetaballImage( byval context as IRenderContext ptr )
/'
Draws a 'metaball'
This function draws an image to be used as a 'metaball' representation. It's declared directly
in the interface to avoid having to implement low level primitives like pset(), so it's purely
a convenience.
The parameter it takes is a render context, and fills it with the appropriate image based on
the size of said context
'/
' old version:
'Dim as uint32 ptr mb = context->handle
'dim as single maxDistance = context->width / 2
'dim as vec2h centerPoint = vec2h( context->width \ 2, context->height \ 2 )
'dim as single dist = any
'
'for y as uinteger = 0 to context->height - 1
' for x as uinteger = 0 to context->width - 1
' dist = max( 0, 1 - ( ( centerPoint - vec2h( x, y ) ).length / ( maxDistance ) ) )
'
' pset mb, ( x, y ), rgba( 255 * dist, 255 * dist, 255 * dist, 255 * dist )
' next
'Next
' new version:
dim as uint32 ptr mb = context->handle
dim as single invMaxDistance = 1.0 / ( context->width * context->width * 0.125 )
dim as vec2h centerPoint = vec2h( context->width \ 2, context->height \ 2 )
dim as single dist = any
for y as uinteger = 0 to context->height - 1
for x as uinteger = 0 to context->width - 1
dist = max( 0, 1 - ( centerPoint - vec2h( x, y ) ).squaredlength * invMaxDistance )
pset mb, ( x, y ), rgba( 255 * dist, 255 * dist, 255 * dist, 255 * dist )
next
Next
end sub
Re: Frame rate independent game loop
Hi Mike,h4tt3n wrote:This is really nice work, points for sharing your code. I took a quick glance at your metaball drawing algorithm and got rid of the nasty doubly for-loop nested square root call in renderer.bi:
Glad you like it. Nice optimization here, Mike. Extra points for actually using the vec2 utility functions ;) Do note, however, that this is only performed at metaball creation, not actual rendering. Very keen eye, indeed.
I will have to point out that the really interesting thing was in the actual game loop, not on the rendering code (which is left intentionally unoptimized, as well as the entire memory management), to better be able to 'feel the effects' of the game loop implementation, so to speak. Nonetheless, some boxes (like deltarho's one) just fly by this thing as if nothing happened LOL
Thanks for the interest, I was beginning to think that the GameDev forum was dead :'(
Paul
Re: Frame rate independent game loop
Hi there Paul,
Yeah, I just realized that the rendering was only used for setting up the demo, not in the main loop, so never mind. It's just an old habit of mine to optimize stuff :-)
I don't think the forum is dead at all, there's new exciting stuff to look into almost every day - like your nice engine right here. I'm wondering if you are having any plans to expand on this and build a game out of it? I'm asking because I've been brewing on a physics engine for some time and I'm starting to look for like-minded people who might want to team up for game development.
Cheers, Mike
Yeah, I just realized that the rendering was only used for setting up the demo, not in the main loop, so never mind. It's just an old habit of mine to optimize stuff :-)
I don't think the forum is dead at all, there's new exciting stuff to look into almost every day - like your nice engine right here. I'm wondering if you are having any plans to expand on this and build a game out of it? I'm asking because I've been brewing on a physics engine for some time and I'm starting to look for like-minded people who might want to team up for game development.
Cheers, Mike
Re: Frame rate independent game loop
A good habit. No problem, it was just coded that way to be easy to tell what the code is doing. Looks like I've succeeded, no? ;)h4tt3n wrote:Hi there Paul,
Yeah, I just realized that the rendering was only used for setting up the demo, not in the main loop, so never mind. It's just an old habit of mine to optimize stuff :-)
Yes, indeed. In fact, these are just snippets of code from a bigger framework (coded in another language), like dafhi wittingly guesses in this thread:h4tt3n wrote: I don't think the forum is dead at all, there's new exciting stuff to look into almost every day - like your nice engine right here. I'm wondering if you are having any plans to expand on this and build a game out of it? I'm asking because I've been brewing on a physics engine for some time and I'm starting to look for like-minded people who might want to team up for game development.
viewtopic.php?f=8&t=26000
That code was written from scratch (not all of them, however) for explanation purposes, and I designed it to be easy to follow for someone who doesn't quite dig OOP yet.
Teaming up for something? Count me in! What kind of stuff you're interested in? 2D? 3D? And what kind of game, concretely? I need some fun (I'm sick of financial coding stuff) so this could be very interesting.
I would love to see your physics stuff. If time permits, I'll show you a simple implementation of a barebones 2D physics engine that uses Verlet. It's simplistic, but you can do mighty interesting stuff with it. It can be useful for debugging purposes, much like the 3D stuff in the thread that I pointed you before. Looking forward!
Have fun!
Paul
Re: Frame rate independent game loop
waa
Code: Select all
glRenderDevice.bi(30) error 222: Not overriding any virtual method, found 'override' in 'declare function setRes(..
glRenderDevice.bi(31) error 222: Not overriding any virtual method, found 'override' in 'declare sub setRenderer(..
Re: Frame rate independent game loop
You have the latest version? You need fbc 1.06.0 also ;)dafhi wrote:waaCode: Select all
glRenderDevice.bi(30) error 222: Not overriding any virtual method, found 'override' in 'declare function setRes(.. glRenderDevice.bi(31) error 222: Not overriding any virtual method, found 'override' in 'declare sub setRenderer(..
Re: Frame rate independent game loop
Damnit, GitHub! The latest commit was NOT uploaded. Hang on, mate. I'm reuploading it now.