PDA

View Full Version : Dynamic membrame with borders - TBGL



RobbeK
04-01-2014, 17:49
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

RobbeK
05-01-2014, 22:06
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