View Full Version : Frame Rate Regulator
Michael Clease
16-06-2007, 00:53
Here my quick attempt at a conversion of foos frame rate routine to thinbasic.
feel free to fix or amend as required.
not sure that it is working.
ABX
I've tried the Programme but it doesn't seem to work correctly. :(
But don't worry I've managed to write a simple routine in Basic4GL which fixes the 'Frame Rate' at 50 FPS.
The only problem is I'm having difficulty porting it to thinBASIC, lol. :D
Petr Schreiber
20-06-2007, 19:42
Hi Abraxas,
I am not sure I understand your code, could you explain more on it :-[ ?
Matthew, throw problematic code here and I will see what I can do :)
Bye,
Petr
Matthew, throw problematic code here and I will see what I can do :)
This might be a little difficult to explain. :)
Basic4GL has got a Command called 'SyncTimer()' which can be used for slowing down Screen Updates. thinBASIC doesn't appear to have a similar Command so I don't know what to do.
When the Basic4GL Routine is running the Frame Rate is Fixed at 50 FPS.
The following code is the Basic4GL Routine...
TextMode (TEXT_OVERLAID)
glEnable(GL_CULL_FACE)
glEnable(GL_DEPTH_TEST)
Dim Angle#
Dim OldTick, CurrentTick, TimeTick, Frames, FramesPerSecond#
OldTick = TickCount ()
While TRUE
glClear (GL_COLOR_BUFFER_BIT Or GL_DEPTH_BUFFER_BIT)
glLoadIdentity ()
glTranslatef (0, 0, -4)
glRotatef (Angle#, 0, 1, 0)
Gosub DrawPyramid
DrawText ()
SwapBuffers ()
While SyncTimer(20)
Gosub FPS_Routine
Angle# = Angle# + 1
Wend
Wend
DrawPyramid:
glBegin (GL_TRIANGLE_FAN)
glColor3f (0,.5, 1): glVertex3f ( 0, 1, 0)
glColor3f (1, 0, 0): glVertex3f (-1,-1, 1)
glColor3f (1, 1, 1): glVertex3f ( 1,-1, 1)
glColor3f (0, 0, 1): glVertex3f ( 1,-1,-1)
glColor3f (0, 1, 0): glVertex3f (-1,-1,-1)
glColor3f (1, 0, 0): glVertex3f (-1,-1, 1)
glEnd ()
Return
FPS_Routine:
CurrentTick = TickCount()
TimeTick = CurrentTick - OldTick
If TimeTick >= 1000 then FramesPerSecond# = Frames * (TimeTick/1000)
Locate 0,0 : Print "FPS:" + FramesPerSecond#
Frames = 0
OldTick = CurrentTick
EndIf
Frames = Frames + 1
Return
This is the thinBASIC Routine which runs as fast as it likes... :D
' Pyramid FPS, Conversion of a Basic4GL Programme.
' Include the thinBASIC OpenGL Library
uses "TBGL"
' Declare Our Constants and Variables here
' Rotation Variable
dim angle as single
' Timing Variables
dim frameCount, tick, prevTick as integer
dim time, fps as single
' Create a Window and Return Handle
dim hWnd as dword
hWnd = tbgl_createwindow("Pyramid FPS - Press 'Esc' to Quit")
' Reset State of all Keys
tbgl_getasynckeystate(-1)
' Main Programme Loop starts here
while tbgl_iswindow(hWnd)
tbgl_clearframe ' Clear Screen
tbgl_resetmatrix ' Reset the Current Matrix
tbgl_camera 0, 0, 1, 0, 0, 0 ' Default Camera Position
tbgl_translate 0, 0, -4 ' Move Pyramid to Centre of Screen
tbgl_rotate angle, 0.0, 1.0, 0.0 ' Rotation Setup
drawPyramid()
fpsRoutine()
tbgl_drawframe ' Swap the Drawing Buffers
angle += 1.0
if tbgl_getasynckeystate(%VK_ESCAPE) then exit while
wend
sub drawPyramid()
tbgl_beginpoly %GL_TRIANGLE_FAN
tbgl_color 0, 128, 255 : tbgl_vertex 0.0, 1.0, 0.0
tbgl_color 255, 0, 0 : tbgl_vertex -1.0, -1.0, 1.0
tbgl_color 255, 255, 255 : tbgl_vertex 1.0, -1.0, 1.0
tbgl_color 0, 0, 255 : tbgl_vertex 1.0, -1.0, -1.0
tbgl_color 0, 255, 0 : tbgl_vertex -1.0, -1.0, -1.0
tbgl_color 255, 0, 0 : tbgl_vertex -1.0, -1.0, 1.0
tbgl_endpoly
end sub
sub fpsRoutine()
tbgl_setwindowtitle(hWnd, "FPS: " + fps)
frameCount = frameCount + 1
if frameCount = 100 then
tick = gettickcount
time = (tick - prevTick) / 1000.0
if time > 0 then
fps = frameCount / time
endif
frameCount = 0
prevTick = tick
endif
end sub
Michael Clease
20-06-2007, 23:11
Hi Abraxas,
I am not sure I understand your code, could you explain more on it :-[ ?
Matthew, throw problematic code here and I will see what I can do :)
Bye,
Petr
http://lazyfoo.net/SDL_tutorials/lesson14/index.php
It doesnt work.
Petr Schreiber
20-06-2007, 23:39
Thanks Abraxas ( for the link ) and Matthew ( for explication'n'sample ),
I still think TBGL_GetFrameRate is the way ( and I start to be scared as I watch myself propagating own feature again and again :-\ )
Why do we want to limit FPS to fixed value ?
I presume because we want movements in our script to run at same speed on every PC !
So we need Matthews pyramid to make complete rotation ( 360° ) in 2 seconds for example.
If its rotation is controlled by Angle variable, we want to add to it such a values each frame, that it will result in ... already mentioned 1 rotation in 2 seconds.
At fixed 50 FPS => 180° during 50 frames in 1 second => In 1 frame it must turn about 180/50 = 3.6 => Angle += 3.6 in each frame.
At fixed 100 FPS => 180° during 100 frames in 1 second => In 1 frame it must turn about 180/100 = 1.8 => Angle += 1.8 in each frame.
But it is not so automatic we get stable framerate, because model is rotating, so its shape is changing and also number of visible "fragments" ( ~ pixels drawn ).
Way #1 : Angle is not added in chunks but always expressed in absolute value related to start time.
t = 2s = 360°
for 1s = 180°
Angle = ( CurrentTimeInSeconds - StartTimeInSeconds ) * 180
This is most precise, but we need to store start time, which is ... bothering for someone, for someone not.
Way #2 : Angle is added in delta angle, proportional to speed of rendering of current frame.
2s = 360° = ? frames
for 1s = 180°
Angle += 180 / FrameRate
Second way is of course less precise, but I use it very frequently :P
So code for second way ( modified from Matthews code ):
' Pyramid FPS, Conversion of a Basic4GL Programme.
' Include the thinBASIC OpenGL Library
uses "TBGL"
' Declare Our Constants and Variables here
' Rotation Variable
dim angle as single
' Timing Variables
dim FrameRate as number
' Create a Window and Return Handle
dim hWnd as dword
hWnd = tbgl_createwindow("Pyramid FPS - Press 'Esc' to Quit")
' Reset State of all Keys
tbgl_getasynckeystate(-1)
' Main Programme Loop starts here
while tbgl_iswindow(hWnd)
FrameRate = tbgl_GetFrameRate
tbgl_clearframe ' Clear Screen
tbgl_resetmatrix ' Reset the Current Matrix
tbgl_camera 0, 0, 1, 0, 0, 0 ' Default Camera Position
tbgl_translate 0, 0, -4 ' Move Pyramid to Centre of Screen
tbgl_rotate angle, 0.0, 1.0, 0.0 ' Rotation Setup
drawPyramid()
tbgl_drawframe ' Swap the Drawing Buffers
angle += 180.0/FrameRate
if tbgl_getasynckeystate(%VK_ESCAPE) then exit while
wend
sub drawPyramid()
tbgl_beginpoly %GL_TRIANGLE_FAN
tbgl_color 0, 128, 255 : tbgl_vertex 0.0, 1.0, 0.0
tbgl_color 255, 0, 0 : tbgl_vertex -1.0, -1.0, 1.0
tbgl_color 255, 255, 255 : tbgl_vertex 1.0, -1.0, 1.0
tbgl_color 0, 0, 255 : tbgl_vertex 1.0, -1.0, -1.0
tbgl_color 0, 255, 0 : tbgl_vertex -1.0, -1.0, -1.0
tbgl_color 255, 0, 0 : tbgl_vertex -1.0, -1.0, 1.0
tbgl_endpoly
end sub
Bye,
Petr
Ok, I am confused, what's new?
What would be the easiest and acceptable way then? I like easy as opposed to totally accurate :)
Hi Petr, I tried your Example and it ran at about 200 FPS and looked really smooth. :)
I'm going to try it in Basic4GL and see how it runs.
Over at the freeBASIC Forum a few years ago they were discussing FPS in games, some of you might find the discussion they were having interesting so here (http://www.freebasic.net/forum/viewtopic.php?t=705&postdays=0&postorder=asc&highlight=motion+blur&start=0&sid=03955cbfc5780e0a06f750da1a80a141) is a Link. :)
Petr Schreiber
22-06-2007, 22:38
Matthew,
thanks for the link,
really interesting discussion with different views.
Bye,
Petr