View Full Version : Dynamic membrame with borders - TBGL
Hi all,
Intented as a test for OČ generated DLL's (somewhat out of order for this program). I think I found something interesting to define a dynamic membrane near the borders - to make them fixed I used the logistic function z(z-1) over the surface.
This function is of extreme importance in chaos theory -- it delivers both Feigenbaum constants in an easy way - you can connect it with p.e. Mandelbrot http://www.dagmarkuntz.de/mathematik/bilder/verhulst_mandelbrot_bifurkation_300.jpg
(of course I did not iterate the logistic function here - as in the linked image).
Oops , maths , but it shows the fine cooperation between OČ - TB - TBGL
best Rob
Petr Schreiber
04-01-2014, 21:33
Hi Rob,
very nice demo!
I would just add the latest Oxy (http://www.thinbasic.com/community/showthread.php?t=12175) is needed to make it run.
I did a minor modification - it runs 7x faster on my PC.
The trick is simple - because X, Z never changes, why not cache it ahead and then draw using GBuffer?:
Uses "tbgl" , "oxygen"
' -- Define vector array, to hold X, Y, Z
Dim m(100, 100) As TBGL_TVECTOR3F
Dim p , q , t As Single
Dim src As String
src="
% filename "membrane.dll"
% dll
include "RTL32.inc"
type vector3f
x as single
y as single
z as single
end type
dim m at #m as vector3f
dim p at #p as single
dim q at #q as single
dim i , j as single
function sin3(byval x as single,byval y as single ,byval t as single ) as single, export
return sin(p*x*pi*0.01 ) * sin(q*y*pi*0.01) * sin(t)/250000
end function
function membrane(byval t as single) , export
for i=0 to 99
for j=0 to 99
m(1+i+100*j).y = i * (99-i) * j * (99-j) * sin3(i,j,t)
next
next
end function
" 'end src
Dim pmemb As Long
o2_basic src
if o2_errno then
msgbox 0, o2_error
stop
else
o2_exec
end if
Declare Function sin3 Lib "membrane.dll" Alias "sin3" (ByVal x As Single , _
ByVal y As Single , ByVal t As Single ) As Single
Declare Function membrane Lib "membrane.dll" Alias "membrane" (ByVal x As Single )
p=6
q=6
t=1
MsgBox (0,"Instructions in the TBGL Window title")
Function TBMain()
Local hWnd As DWord
Local FrameRate As Double
Local width, height As Long
Local i , j , rx , vp As Single
src="dynamic Membran with borders : up,down,right,left
to change frequences - SPC to reset - PGUP/DN change viewpoint Esc to End"
' -- Create and show window
hWnd = TBGL_CreateWindowEx(src, 800, 600, 32, %TBGL_WS_WINDOWED Or %TBGL_WS_CLOSEBOX)
TBGL_ShowWindow
' -- Retrieve window client, to setup 2D render matrix later
TBGL_GetWindowClient( hWnd, width, height )
' -- The following line enables order dependent drawing
TBGL_DepthFunc(%TBGL_ALWAYS)
' -- Resets status of all keys
TBGL_ResetKeyState()
' -- Define GBuffer, initially as a flat grid
DWord gbGrid = TBGL_GBufferCreate(%TBGL_POINTS, %TBGL_3D)
For i = 1 To UBound(m, 1)
For j = 1 To UBound(m, 2)
m(i, j).x = i - 50
m(i, j).z = j - 50
Next
Next
' -- Bind the GBuffer to array
TBGL_GBufferDefineFromArray(gbGrid, %TBGL_DYNAMIC, 100*100, m)
While TBGL_IsWindow(hWnd)
' -- Read the current frame rate.
TBGL_ClearFrame
membrane(t)
TBGL_RenderMatrix3D
TBGL_Camera(0, 60+vp, 160, 0, 0, 0)
TBGL_SetDrawDistance 320
TBGL_Rotate rx,0,1,0
TBGL_Color(0,200,0)
' -- No need to iterate over elements, just raw power
TBGL_GBufferRender(gbGrid)
TBGL_DrawFrame
framerate=TBGL_GetFrameRate
If TBGL_GetWindowKeyState(hWnd, %VK_UP) Then p += 0.1
If TBGL_GetWindowKeyState(hWnd, %VK_DOWN) Then p -= 0.1
If TBGL_GetWindowKeyState(hWnd, %VK_LEFT) Then q += 0.1
If TBGL_GetWindowKeyState(hWnd, %VK_RIGHT) Then q -= 0.1
If TBGL_GetWindowKeyState(hWnd, %VK_SPACE) Then q=0 : p=q : t=0
If TBGL_GetWindowKeyState(hWnd, %VK_PGUP) Then vp += 1
If TBGL_GetWindowKeyState(hWnd, %VK_PGDN) Then vp -= 1
If TBGL_GetWindowKeyState(hWnd, %VK_ESCAPE) Then Exit While
rx += 25/framerate
t += 0.04
Wend
TBGL_DestroyWindow
End Function
Petr
Charles Pegge
05-01-2014, 08:27
Hi Rob,
Using Petr's example but creating the array within the DLL, then mapping it on the TB side:
Oxygen side
dim m(100*100) as vector3f
...
function mptr() as sys, export
return @m
end function
TB side:
Dim m(100, 100) As TBGL_TVECTOR3F at mptr()
Uses "tbgl", "oxygen"
' -- Define vector array, to hold X, Y, Z
'Dim m(100, 100) As TBGL_TVECTOR3F
Dim p , q , t As Single
Dim src As String
src="
% filename "membrane.dll"
% dll
include "RTL32.inc"
type vector3f
x as single
y as single
z as single
end type
dim m(100*100) as vector3f
'dim m at #m as vector3f
dim p at #p as single
dim q at #q as single
dim i , j as single
function mptr() as sys, export
return @m
end function
function sin3(byval x as single,byval y as single ,byval t as single ) as single, export
return sin(p*x*pi*0.01 ) * sin(q*y*pi*0.01) * sin(t)/250000
end function
function membrane(byval t as single) , export
for i=0 to 99
for j=0 to 99
m(1+i+100*j).y = i * (99-i) * j * (99-j) * sin3(i,j,t)
next
next
end function
" 'end src
Dim pmemb As Long
o2_basic src
if o2_errno then
msgbox 0, o2_error
stop
else
o2_exec
end if
Declare Function mptr Lib "membrane.dll" Alias "mptr" () As long
Declare Function sin3 Lib "membrane.dll" Alias "sin3" (ByVal x As Single , _
ByVal y As Single , ByVal t As Single ) As Single
Declare Function membrane Lib "membrane.dll" Alias "membrane" (ByVal x As Single )
Dim m(100, 100) As TBGL_TVECTOR3F at mptr()
p=6
q=6
t=1
MsgBox (0,"Instructions in the TBGL Window title")
Function TBMain()
Local hWnd As DWord
Local FrameRate As Double
Local width, height As Long
Local i , j , rx , vp As Single
src="dynamic Membran with borders : up,down,right,left
to change frequences - SPC to reset - PGUP/DN change viewpoint Esc to End"
' -- Create and show window
hWnd = TBGL_CreateWindowEx(src, 800, 600, 32, %TBGL_WS_WINDOWED Or %TBGL_WS_CLOSEBOX)
TBGL_ShowWindow
' -- Retrieve window client, to setup 2D render matrix later
TBGL_GetWindowClient( hWnd, width, height )
' -- The following line enables order dependent drawing
TBGL_DepthFunc(%TBGL_ALWAYS)
' -- Resets status of all keys
TBGL_ResetKeyState()
' -- Define GBuffer, initially as a flat grid
DWord gbGrid = TBGL_GBufferCreate(%TBGL_POINTS, %TBGL_3D)
For i = 1 To UBound(m, 1)
For j = 1 To UBound(m, 2)
m(i, j).x = i - 50
m(i, j).z = j - 50
Next
Next
' -- Bind the GBuffer to array
TBGL_GBufferDefineFromArray(gbGrid, %TBGL_DYNAMIC, 100*100, m)
While TBGL_IsWindow(hWnd)
' -- Read the current frame rate.
TBGL_ClearFrame
membrane(t)
TBGL_RenderMatrix3D
TBGL_Camera(0, 60+vp, 160, 0, 0, 0)
TBGL_SetDrawDistance 320
TBGL_Rotate rx,0,1,0
TBGL_Color(0,200,0)
' -- No need to iterate over elements, just raw power
TBGL_GBufferRender(gbGrid)
TBGL_DrawFrame
framerate=TBGL_GetFrameRate
If TBGL_GetWindowKeyState(hWnd, %VK_UP) Then p += 0.1
If TBGL_GetWindowKeyState(hWnd, %VK_DOWN) Then p -= 0.1
If TBGL_GetWindowKeyState(hWnd, %VK_LEFT) Then q += 0.1
If TBGL_GetWindowKeyState(hWnd, %VK_RIGHT) Then q -= 0.1
If TBGL_GetWindowKeyState(hWnd, %VK_SPACE) Then q=0 : p=q : t=0
If TBGL_GetWindowKeyState(hWnd, %VK_PGUP) Then vp += 1
If TBGL_GetWindowKeyState(hWnd, %VK_PGDN) Then vp -= 1
If TBGL_GetWindowKeyState(hWnd, %VK_ESCAPE) Then Exit While
rx += 25/framerate
t += 0.04
Wend
TBGL_DestroyWindow
End Function
Many thanks Charles , Petr !
array->Gbuffer , I should read your documentation first - ;-( ...
function mptr() as sys, export
return @m
end function
That's what I needed !! -- I intended storing the address in a shared variable , but then ......
In Lisp it is very easy : as for variable declaration (set p q) is done by Ref and (setq p q) by value .
best Rob