PDA

View Full Version : Back to the future - little taste of new TBGL



Petr Schreiber
18-05-2009, 16:56
Hi all,

if you are using latest TB beta (http://community.thinbasic.com/index.php?topic=2588.msg19386#msg19386), you can taste a bit of next TBGL.
Do you want to create fullscreen/windowed application, but still stay CPU friendly?
Do you want to get rid of DOEVENTs, SLEEPs and other workarounds in WHILE/WEND loops?

What about periodically launched function...



Uses "TBGL"

TYPE tFan
STATIC eventSwitch AS STRING
STATIC eventRender AS STRING
STATIC eventPhysics AS STRING
running AS LONG
speed AS SINGLE
angle AS SINGLE
END TYPE

DIM Fan AS tFan
WITH Fan
.eventSwitch = "Fan_Switch"
.eventRender = "Fan_Render"
.eventPhysics = "Fan_Physics"
END WITH

GLOBAL FrameRate AS DOUBLE
GLOBAL hWnd AS DWORD

FUNCTION TBMAIN()


' -- Create and show window
hWnd = TBGL_CreateWindowEx("Fan for Eros :D, SPACE to turn on off", 640, 480, 32, %TBGL_WS_WINDOWED or %TBGL_WS_CLOSEBOX)
TBGL_ShowWindow

' -- Initialize lighting
TBGL_UseLighting %TRUE
TBGL_UseLightSource %GL_LIGHT0, %TRUE

tbgl_SetLightParameter %GL_LIGHT0, %TBGL_LIGHT_POSITION, 15, 10, 15, 1

' -- Resets status of all keys
TBGL_ResetKeyState()

' -- We will set GameLoop function to be executed each 10ms
TBGL_PeriodicBindFunction( hWnd, "GameLoop", 10 )

' -- Once the command below is executed, further script execution
' -- is halted and only periodic calling of the bound function is performed
TBGL_PeriodicProcessFunction(hWnd)

' -- Once we leave periodically launched function, we can destroy the window
TBGL_DestroyWindow
END FUNCTION

SUB GameLoop()
FrameRate = TBGL_GetFrameRate

TBGL_ClearFrame
TBGL_Camera 5, 5, 5, 0, 1.5, 0

Call Fan.eventPhysics(Fan)
Call Fan.eventRender(Fan)

TBGL_DrawFrame

' -- ESCAPE key to exit application
If TBGL_GetWindowKeyState(hWnd, %VK_ESCAPE) Then TBGL_PeriodicUnBindFunction( hWnd )
If TBGL_GetWindowKeyOnce(hWnd, %VK_SPACE) Then Call Fan.eventSwitch(Fan)

END SUB

' -- Functions to manipulate fan
FUNCTION Fan_Switch( byref property AS tFan )
property.running = not property.running
END FUNCTION

FUNCTION Fan_Physics( property AS tFan )
if property.running then
property.speed += 90/FrameRate
if property.speed > 720 then property.speed = 720
else
property.speed -= 180/FrameRate
if property.speed < 0 then property.speed = 0
end if
property.angle += property.speed/FrameRate
END FUNCTION

FUNCTION Fan_Render( property AS tFan )
static i as long
tbgl_PushMatrix
tbgl_Color 255, 128, 0
' -- Base
tbgl_PushMatrix
tbgl_Scale 4, 0.5, 4
tbgl_Sphere 0.25
tbgl_PopMatrix

tbgl_Cylinder 0.125, 0.125, 2
tbgl_PushMatrix
tbgl_Translate 0, 2, 0
tbgl_Scale 0.5, 0.5, 1
tbgl_Sphere 1
tbgl_PopMatrix

' -- Fan
tbgl_Color 255, 255, 255
tbgl_PushMatrix
tbgl_Translate 0, 2, 0.5
tbgl_Rotate property.angle, 0, 0, 1
for i = 1 to 360 step 60
tbgl_PushMatrix
tbgl_Rotate i, 0, 0, 1
tbgl_Translate 0.75, 0, 0
tbgl_Rotate -45, 1, 0, 0
tbgl_Box 1, 0.3, 0.01
tbgl_PopMatrix
next
tbgl_PopMatrix
tbgl_PopMatrix
END FUNCTION


Let us know whether your CPU usage is really kept low using this sample ;)

ErosOlmi
18-05-2009, 17:16
Ok, now I got some fresh air :eusadance:

CPU usage is from 0% to 1%

GSAC3
18-05-2009, 18:14
Petr:

That's a "cool" solution to Eros' heat problem.

Don

ErosOlmi
18-05-2009, 18:23
Petr,

I just realized you already took advantages of new STATIC UDT elements in a clever way.
Plus new TBGL_ProcessPeriodicFunction functionality seems giving great reasult.

I think there will be great and powerful news in a short time window on TBGL area.

Fantastic.

dcromley
18-05-2009, 22:00
You guys are doing great things.
I spent the time on this, and now I've got to share it.
It should be titled "A fallacy in Petr's fan".
But sometimes my sense of humor gets me in trouble.

Keep up the good work -- I'm trying to keep up, but there's a lot.



Uses "TBGL", "Math"

TYPE tFan
STATIC eventSwitch AS STRING
STATIC eventRender AS STRING
STATIC eventPhysics AS STRING
running AS LONG
speed AS SINGLE
angle AS SINGLE
END TYPE

DIM Fan AS tFan
WITH Fan
.eventSwitch = "Fan_Switch"
.eventRender = "Fan_Render"
.eventPhysics = "Fan_Physics"
END WITH

GLOBAL FrameRate AS DOUBLE
GLOBAL hWnd AS DWORD
GLOBAL gcx, gcy, gcz as single = 5
GLOBAL g0x, g0y, g0z as single: g0y = 1.5

FUNCTION TBMAIN()

' -- Create and show window
hWnd = TBGL_CreateWindowEx("Fan for Eros :D, SPACE to turn on off", 640, 480, 32, %TBGL_WS_WINDOWED or %TBGL_WS_CLOSEBOX)
TBGL_ShowWindow

' -- Initialize lighting
TBGL_UseLighting %TRUE
TBGL_UseLightSource %GL_LIGHT0, %TRUE

tbgl_SetLightParameter %GL_LIGHT0, %TBGL_LIGHT_POSITION, 15, 10, 15, 1

' -- Resets status of all keys
TBGL_ResetKeyState()

' -- We will set GameLoop function to be executed each 10ms
TBGL_BindPeriodicFunction( hWnd, "GameLoop", 10 )

' -- Once the command below is executed, further script execution
' -- is halted and only periodic calling of the bound function is performed
TBGL_ProcessPeriodicFunction(hWnd)

' -- Once we leave periodically launched function, we can destroy the window
TBGL_DestroyWindow
END FUNCTION

SUB GameLoop()
static nCount as long
local Ang as single
incr nCount
if nCount < 100 then
elseif nCount < 600 then
Ang = (-45 + (nCount - 100) / 500 * 135) / 180 * pi
gcx = sqr(50) * cos(Ang)
gcz = -sqr(50) * sin(Ang)
gcy = (5 * (600 - nCount) + 2.125 * (nCount - 100)) / 500
g0y = (1.5 * (600 - nCount) + 2 * (nCount - 100)) / 500
elseif ncount < 1100 then
gcz = (-sqr(50) * (1100 - nCount) + -1 * (nCount - 600)) / 500
end if
FrameRate = TBGL_GetFrameRate

TBGL_ClearFrame
TBGL_Camera gcx,gcy,gcz, g0x,g0y,g0z

Call Fan.eventPhysics(Fan)
Call Fan.eventRender(Fan)

TBGL_DrawFrame

' -- ESCAPE key to exit application
If TBGL_GetWindowKeyState(hWnd, %VK_ESCAPE) Then TBGL_UnBindPeriodicFunction( hWnd )
If TBGL_GetWindowKeyOnce(hWnd, %VK_SPACE) Then Call Fan.eventSwitch(Fan)

END SUB

' -- Functions to manipulate fan
FUNCTION Fan_Switch( byref property AS tFan )
property.running = not property.running
END FUNCTION

FUNCTION Fan_Physics( property AS tFan )
if property.running then
property.speed += 90/FrameRate
if property.speed > 720 then property.speed = 720
else
property.speed -= 180/FrameRate
if property.speed < 0 then property.speed = 0
end if
property.angle += property.speed/FrameRate
END FUNCTION

FUNCTION Fan_Render( property AS tFan )
static i as long
tbgl_PushMatrix
tbgl_Color 255, 128, 0
' -- Base
tbgl_PushMatrix
tbgl_Scale 4, 0.5, 4
tbgl_Sphere 0.25
tbgl_PopMatrix
' -- Case
tbgl_Cylinder 0.125, 0.125, 2
tbgl_PushMatrix
tbgl_Translate 0, 2, 0
tbgl_Scale 0.5, 0.5, 1
tbgl_Sphere 1
tbgl_PopMatrix

' -- Fan
tbgl_Color 255, 255, 255
tbgl_PushMatrix
tbgl_Translate 0, 2, 0.5
tbgl_Rotate property.angle, 0, 0, 1
for i = 1 to 360 step 60
tbgl_PushMatrix
tbgl_Rotate i, 0, 0, 1
tbgl_Translate 0.75, 0, 0
tbgl_Rotate -45, 1, 0, 0
tbgl_Box 1, 0.3, 0.01
tbgl_PopMatrix
next
tbgl_PopMatrix
tbgl_PopMatrix
END FUNCTION

ErosOlmi
18-05-2009, 22:15
For the series: how things are done ... from inside :D

Again: CPU is almost zero percent usage even when window is moved on screen CPU just jump high for a while but than I can move window around and script is still running.

It is not usual to see so well designed applications working in realtime even for compiled one.

Petr Schreiber
18-05-2009, 22:29
Niiice modification :),

it reminds me of scene from Indiana Jones/Raiders of the Lost Ark where indy fights with that boxer nearby airplane rotor :P


Thanks,
Petr

kryton9
19-05-2009, 01:15
Petr you 3D whiz, ok now I am expecting wind to come from my screen :)

dcromley, nice cinematic touch!

zak
14-06-2009, 13:04
hi Petr, hi all
thanks for your toy, the code is of great educational value for the opengl ideas. and it is suitable for the hot summer also.
thanks also for dcromley for the animation.
i have added few lines to make the fan blades and the sphere moving horizontally within 110 degrees back and forth, to blow the air for the guests also.


Uses "TBGL"

TYPE tFan
STATIC eventSwitch AS STRING
STATIC eventRender AS STRING
STATIC eventPhysics AS STRING
running AS LONG
speed AS SINGLE
angle AS SINGLE
END TYPE

DIM Fan AS tFan
WITH Fan
.eventSwitch = "Fan_Switch"
.eventRender = "Fan_Render"
.eventPhysics = "Fan_Physics"
END WITH

GLOBAL FrameRate AS DOUBLE
GLOBAL hWnd AS DWORD

global angle_horizontal as SINGLE
global angle_step as SINGLE = 0.3

FUNCTION TBMAIN()


' -- Create and show window
hWnd = TBGL_CreateWindowEx("Fan for Eros :D, SPACE to turn on off", 640, 480, 32, %TBGL_WS_WINDOWED or %TBGL_WS_CLOSEBOX)
TBGL_ShowWindow

' -- Initialize lighting
TBGL_UseLighting %TRUE
TBGL_UseLightSource %GL_LIGHT0, %TRUE

tbgl_SetLightParameter %GL_LIGHT0, %TBGL_LIGHT_POSITION, 15, 10, 15, 1

' -- Resets status of all keys
TBGL_ResetKeyState()

' -- We will set GameLoop function to be executed each 10ms
TBGL_BindPeriodicFunction( hWnd, "GameLoop", 10 )

' -- Once the command below is executed, further script execution
' -- is halted and only periodic calling of the bound function is performed
TBGL_ProcessPeriodicFunction(hWnd)

' -- Once we leave periodically launched function, we can destroy the window
TBGL_DestroyWindow
END FUNCTION

SUB GameLoop()
FrameRate = TBGL_GetFrameRate

TBGL_ClearFrame
TBGL_Camera 5, 5, 5, 0, 1.5, 0

Call Fan.eventPhysics(Fan)
Call Fan.eventRender(Fan)

TBGL_DrawFrame

' -- ESCAPE key to exit application
If TBGL_GetWindowKeyState(hWnd, %VK_ESCAPE) Then TBGL_UnBindPeriodicFunction( hWnd )
If TBGL_GetWindowKeyOnce(hWnd, %VK_SPACE) Then Call Fan.eventSwitch(Fan)

END SUB

' -- Functions to manipulate fan
FUNCTION Fan_Switch( byref property AS tFan )
property.running = not property.running
END FUNCTION

FUNCTION Fan_Physics( property AS tFan )
if property.running then
'the 6 lines below for the horizontal rotation
angle_horizontal = angle_horizontal + angle_step
if angle_horizontal > 110 then
angle_step = -0.3
elseif angle_horizontal < 0 then
angle_step = 0.3
end if
'--------------------------------------------
property.speed += 90/FrameRate
if property.speed > 720 then property.speed = 720
else
property.speed -= 180/FrameRate
if property.speed < 0 then property.speed = 0
end if
property.angle += property.speed/FrameRate
END FUNCTION

FUNCTION Fan_Render( property AS tFan )
static i as long
tbgl_PushMatrix
tbgl_Color 255, 128, 0
' -- Base
tbgl_PushMatrix
tbgl_Scale 4, 0.5, 4
tbgl_Sphere 0.25
tbgl_PopMatrix

tbgl_Cylinder 0.125, 0.125, 2
tbgl_PushMatrix
tbgl_Translate 0, 2, 0
tbgl_Rotate angle_horizontal, 0, 1, 0 'for the horizontal rotation of the sphere
tbgl_Scale 0.5, 0.5, 1

tbgl_Sphere 1
tbgl_PopMatrix

' -- Fan
tbgl_Color 255, 255, 255
tbgl_PushMatrix
tbgl_Rotate angle_horizontal, 0, 1, 0 'for the horizontal rotation of the blades

tbgl_PushMatrix
tbgl_Translate 0, 2, 0.5
tbgl_Rotate property.angle, 0, 0, 1
for i = 1 to 360 step 60
tbgl_PushMatrix
tbgl_Rotate i, 0, 0, 1
tbgl_Translate 0.75, 0, 0
tbgl_Rotate -45, 1, 0, 0
tbgl_Box 1, 0.3, 0.01
tbgl_PopMatrix
next
tbgl_PopMatrix
tbgl_PopMatrix
tbgl_PopMatrix
END FUNCTION

Petr Schreiber
14-06-2009, 14:13
Hi Zak,

thanks for the modification, this handles much better the air flow in room here :)

One little detail - it is good idea to scale all movements to rendering speed, that makes sure the animation goes at same speed on all PCs. So instead of:


angle_horizontal = angle_horizontal + angle_step


you can do


angle_horizontal = angle_horizontal + angle_step/FrameRate


This way, angle_step will mean degrees/second. So in this case you can change angle_step to +/- 30, and it will mean the fan will turn 30° in one second.


Thank you,
Petr