PDA

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

matthew
17-06-2007, 18:03
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
20-06-2007, 20:03
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

kryton9
20-06-2007, 23:54
Ok, I am confused, what's new?

What would be the easiest and acceptable way then? I like easy as opposed to totally accurate :)

matthew
21-06-2007, 04:10
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