 |
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Lloyd

Anmeldungsdatum: 27.06.2008 Beiträge: 37 Wohnort: Nähe Frankfurt
|
Verfasst am: 29.06.2008, 01:39 Titel: Brauch Hilfe bei Fluid Simulation |
|
|
So, ich hab den Code jetzt endlich fertig, zumindest die Subs.
Leider hab' ich Probleme, in welcher Reihenfolge sie aufgerufen werden müssen. Aber...also ertma von vorne.
Ich hab mich dran versucht, http://npshare.de/files/37/8770/code.rar <<diesen C Code in FB umzuschreiben.
Das ganze besteht eigentlich nur aus Subs (bzw. Voids). Beim compilen kommen auch keine Fehlermeldungen, dennoch startet das Prog nicht richtig.
Schaut es euch am besten selbst an:
http://npshare.de/files/37/4758/Fluid.rar
Es wäre super, wenn mir einer helfen könnte. Es ist nämlich alles sozusagen nur Theorie, weil ichs nicht testen konnte. Und es wäre Schade um den ganzen Code :<
Achja! Hier die PDF, wo der Code erklärt wird:
http://www.dgp.toronto.edu/people/stam/reality/Research/pdf/GDC03.pdf |
|
Nach oben |
|
 |
micha
Anmeldungsdatum: 09.12.2005 Beiträge: 72
|
Verfasst am: 30.06.2008, 11:27 Titel: |
|
|
Gibts auf dem englishen Forum ist aber gerade nicht erreichbar.
Hier einmal "simple 2D water" und noch den "Fluid Solver" den Du meinst.
simple 2D water:
Code: | Sub CalcIt(Byval lpDes As Ubyte Ptr, _
Byval lpSrc As Ubyte Ptr, _
Byval size As Integer)
asm
mov edi,[lpDes]
mov esi,[lpSrc]
mov ebx,[size]
mov eax,ebx
mul ebx
mov ecx,eax
Sub ecx,ebx
Sub ecx,ebx
dec ecx
Xor edx,edx
Sub edx,ebx
add edi,ebx
add esi,ebx
push ebp
loopit:
movzx ax,Byte Ptr [esi-1]
movzx bp,Byte Ptr [esi+1]
add ax,bp
movzx bp,Byte Ptr [esi+edx]
add ax,bp
movzx bp,Byte Ptr [esi+ebx]
add ax,bp
Shr ax,1
movzx bp,Byte Ptr [edi]
Sub ax,bp
And ah,&HFF
jz saveit
Xor al,al
saveit:
mov [edi],al
inc esi
inc edi
dec ecx
jnz loopit
pop ebp
End asm
End Sub
Sub DrawIt(Byval lpSrc As Ubyte Ptr, _
Byval Size As Integer)
Static As Ubyte Ptr lpScreen
Dim As Integer i
lpScreen=ScreenPtr
For i=0 To (size*size-1)
lpScreen[i]=lpSrc[i]
Next
End Sub
#define map_size 512
Dim As Ubyte Ptr lpDes=allocate(map_size*map_size)
Dim As Ubyte Ptr lpSrc=allocate(map_size*map_size)
Static As Integer mx,my,mb,i,x,y,frames,fps
Static As Double t1,t2
screenres map_size,map_size
For i=0 To 255:Palette i,i,i,i:Next
Color 255
windowtitle "[ESC]=quit draw with the mouse"
t1=Timer
While Asc(Inkey)<>27
If GetMouse(mx,my,,mb)=0 And mb<>0 Then
For i=1 To 50
x=mx+Rnd*50-25
y=my+Rnd*50-25
If (x>-1 And x<=map_size) And _
(y>-1 And x<=map_size) Then
lpSrc[x+y*map_size]=255
End If
Next
End If
CalcIt(lpDes,lpSrc,map_size)
screensync
screenlock:Cls
DrawIt (lpDes,map_size)
Print "FPS=" & fps
screenunlock
frames+=1
If frames=100 Then
t2=Timer
fps=frames/(t2-t1)
t1=Timer
frames=0
End If
Swap lpDes,lpSrc
Wend
If lpSrc<>0 Then deallocate(lpSrc)
If lpDes<>0 Then deallocate(lpDes)
End |
fluid solver 2D OpenGL:
Code: | #include "GL/glut.bi"
Const As Integer g_Rows = 64
Const As Integer g_steps = 10
Const As Single g_delta = 0.1
Const As Single g_density = 0.00001
Const As Single g_viscose = 0.001
Const As Single g_force = 1.0
Const As Single g_source = 10.0
Const As Integer g_N = g_Rows-2
Const As Integer g_N2 = g_N*g_N
Const As Integer g_nCells = g_Rows*g_Rows
Const As Integer g_lt = 0
Const As Integer g_rt = g_rows-1
Const As Integer g_rb = g_nCells-1
Const As Integer g_lb = g_rb-g_rows
Const As Single g_Nd2 = g_N*0.5
Const As Single g_Nm2 = g_N*2
Const As Single g_dn2 =-1.0/g_Nm2
Dim Shared As Integer g_dvel
Dim Shared As Single Ptr g_u,g_v,g_u_prev,g_v_prev
Dim Shared As Single Ptr g_d, g_d_prev
Dim Shared As Integer g_hWin,g_hWin2
Dim Shared As Integer g_scr_w, g_scr_h
Dim Shared As Integer g_mouse_down(2)
Dim Shared As Integer g_omx, g_omy, g_mx, g_my
/' macros '/
#define IX(i,j) ((i)+(g_Rows)*(j))
Sub scale(des As Single Ptr, _
s As Single)
asm
mov edi,[des]
mov ecx,g_nCells
mov edx,4
fld dword Ptr [s]
loop_scale:
fld st(0)
fmul dword Ptr [edi]
fstp dword Ptr [edi]
add edi,edx
dec ecx
jnz loop_scale
ffree st(0)
End asm
End Sub
sub add_scale(des As Single Ptr, _
src As Single Ptr, _
s As Single)
asm
mov edi,[des]
mov esi,[src]
mov eax,g_N
inc eax
inc eax
mul eax
mov ecx,eax
dec eax
fld dword Ptr [s]
loop_add_scale:
fld st(0)
fmul dword Ptr [esi]
fadd dword Ptr [edi]
fstp dword Ptr [edi]
add esi,4
add edi,4
Loop loop_add_scale
ffree st(0)
End asm
End Sub
Sub move_edges(des As Single Ptr)
des[g_lt]=des[g_lt+1]+des[g_lt+g_rows]:des[g_lt]*=0.5
des[g_rt]=des[g_rt-1]+des[g_rt+g_rows]:des[g_rt]*=0.5
des[g_lb]=des[g_lb+1]+des[g_lb-g_rows]:des[g_lb]*=0.5
des[g_rb]=des[g_rb-1]+des[g_rb-g_rows]:des[g_rb]*=0.5
End Sub
Sub move_left(des As Single Ptr)
asm
mov edi,[des]
mov esi,edi
add esi,4
mov edx,g_Rows
mov ecx,edx
Sub ecx,3
Shl edx,2 ' rows 2 pitch
loop_left:
add esi,edx ' + pitch
add edi,edx ' + pitch
mov eax,[esi]
mov [edi],eax
Loop loop_left
End asm
End Sub
Sub move_left_neg(des As Single Ptr)
Static As Single n=-1
asm
mov edi,[des]
mov esi,edi
add esi,4
mov edx,g_Rows
mov ecx,edx
Sub ecx,3
Shl edx,2 ' rows 2 pitch
fld dword Ptr [n]
loop_left_neg:
add esi,edx ' + pitch
fld st(0) ' -1,-1
add edi,edx ' + pitch
fmul dword Ptr [esi]
fstp dword Ptr [edi]
Loop loop_left_neg
ffree st(0)
End asm
End Sub
Sub move_right(des As Single Ptr)
asm
mov edx,g_Rows
mov ecx,edx
Sub ecx,3
Shl edx,2 ' rows 2 pitch
mov edi,[des]
add edi,edx
Sub edi,4
mov esi,edi
Sub esi,4
loop_right:
add esi,edx ' + pitch
add edi,edx ' + pitch
mov eax,[esi]
mov [edi],eax
Loop loop_right
End asm
End Sub
Sub move_right_neg(des As Single Ptr)
Static As Single n=-1
asm
mov edx,g_Rows
mov ecx,edx
Sub ecx,3
Shl edx,2 ' rows 2 pitch
mov edi,[des]
add edi,edx
Sub edi,4
mov esi,edi
Sub esi,4
fld dword Ptr [n]
loop_right_neg:
add esi,edx ' + pitch
fld st(0)
add edi,edx ' + pitch
fmul dword Ptr [esi]
fstp dword Ptr [edi]
mov eax,[esi]
mov [edi],eax
Loop loop_right_neg
ffree st(0)
End asm
End Sub
Sub move_up(des As Single Ptr)
asm
mov edi,[des]
mov esi,edi
mov edx,g_Rows
mov ecx,edx
Sub ecx,3
Shl edx,2 ' rows 2 pitch
add esi,edx
loop_up:
add esi,4
add edi,4
mov eax,[esi]
mov [edi],eax
Loop loop_up
End asm
End Sub
Sub move_up_neg(des As Single Ptr)
Static As Single n=-1
asm
mov edi,[des]
mov esi,edi
mov edx,g_Rows
mov ecx,edx
Sub ecx,3
Shl edx,2 ' rows 2 pitch
add esi,edx
fld dword Ptr [n]
loop_up_neg:
add esi,4
fld st(0)
add edi,4
fmul dword Ptr [esi]
fstp dword Ptr [edi]
Loop loop_up_neg
ffree st(0)
End asm
End Sub
Sub move_down(des As Single Ptr)
asm
mov edi,[des]
mov ebx,g_Rows
mov ecx,ebx
Sub ecx,3
mov eax,ebx
Shl eax,2
dec ebx
Xor edx,edx
mul ebx
add edi,eax
mov esi,edi
mov ebx,g_Rows
Shl ebx,2
Sub esi,ebx ' - pitch
loop_down:
add esi,4
add edi,4
mov eax,[esi]
mov [edi],eax
Loop loop_down
End asm
End Sub
Sub move_down_neg(des As Single Ptr)
Static As Single n=-1
asm
mov edi,[des]
mov ebx,g_Rows
mov ecx,ebx
Sub ecx,3
mov eax,ebx
Shl eax,2
dec ebx
Xor edx,edx
mul ebx
add edi,eax
mov esi,edi
mov ebx,g_Rows
Shl ebx,2
Sub esi,ebx
fld dword Ptr [n]
loop_down_neg:
add esi,4
fld st(0)
add edi,4
fmul dword Ptr [esi]
fstp dword Ptr [edi]
Loop loop_down_neg
ffree st(0)
End asm
End Sub
Sub move(des As Single Ptr)
move_left (des)
move_right(des)
move_up (des)
move_down (des)
move_edges(des)
End Sub
Sub move_u(des As Single Ptr)
move_left_neg (des)
move_right_neg(des)
move_up (des)
move_down (des)
move_edges (des)
End Sub
Sub move_v(des As Single Ptr)
move_left (des)
move_right (des)
move_up_neg (des)
move_down_neg(des)
move_edges (des)
End Sub
Sub solver (des As Single Ptr, _
src As Single Ptr, _
a As Single , _
b As Single)
asm
fld dword Ptr [b]
fld dword Ptr [a]
mov ebx,[des]
mov edx,[src]
mov eax,g_Rows
push ebp
mov ebp,eax
mov ecx,ebp
Sub ecx,2
Shl eax,2
loop_x:
push ecx
add eax,4
mov edi,ebx
mov esi,edx
add edi,eax
add esi,eax
mov ecx,ebp
Sub ecx,2
Shl ebp,2 'row to pitch
push eax
mov eax,ebp
neg eax
loop_y:
fld dword Ptr [edi-4]
fadd dword Ptr [edi+4]
fadd dword Ptr [edi+eax]
fadd dword Ptr [edi+ebp]
fmul st(1)
fadd dword Ptr [esi]
fmul st(2)
fstp dword Ptr [edi]
add esi,ebp
add edi,ebp
Loop loop_y
Shr ebp,2 ' pitch 2 g_Rows
pop eax
pop ecx
Loop loop_x
ffree st(1)
ffree st(0)
pop ebp
End asm
End Sub
Sub move_uv(des As Single Ptr, _
src As Single Ptr, _
up As Single Ptr, _
vp As Single Ptr, _
delta As Single)
Dim As Integer i0,j0,i1,j1
Dim As Single u,v,x,y,s0,t0,s1,t1,dt0=g_N*delta
For x As Integer=1 To g_N
For y As Integer=1 To g_N
u = x-dt0*up[IX(x,y)]
If u<0.5f Then
u=0.5f
Elseif u>(g_N+0.5f) Then
u=g_N+0.5f
End If
i0=Int(u)
i1=i0+1
v = y-dt0*vp[IX(x,y)]
If v<0.5f Then
v=0.5f
Elseif v>(g_N+0.5f) Then
v=g_N+0.5f
End If
j0=Int(v)
j1=j0+1
s1 = u-i0
s0 = 1-s1
t1 = v-j0
t0 = 1-t1
des[IX(x,y)] = s0 * ( t0 * src[IX(i0,j0)] + t1 * src[IX(i0,j1)]) _
+ s1 * ( t0 * src[IX(i1,j0)] + t1 * src[IX(i1,j1)])
Next
Next
End Sub
Sub project (u As Single Ptr, _
v As Single Ptr, _
p As Single Ptr, _
d As Single Ptr)
For i As Integer=1 To g_N
For j As Integer=1 To g_N
d[IX(i,j)] = (u[IX(i+1,j)]-u[IX(i-1,j)]+v[IX(i,j+1)]-v[IX(i,j-1)])*g_dn2
p[IX(i,j)] = 0
Next
Next
move(d)
move(p)
For s As Integer=1 To g_steps
solver (p,d,1,0.25)
move(p)
Next
For i As Integer=1 To g_N
For j As Integer=1 To g_N
u[IX(i,j)] -= g_Nd2*(p[IX(i+1,j )]-p[IX(i-1,j )])
v[IX(i,j)] -= g_Nd2*(p[IX(i ,j+1)]-p[IX(i ,j-1)])
Next
Next
End Sub
Sub sim_step(viscose As Single, _
density As Single, _
delta As Single)
Dim As Single a,b
viscose*=delta
a=viscose*g_N2*delta:b=a*4+1
add_scale(g_u,g_u_prev,delta)
For s As Integer=1 To g_steps
solver(g_u_prev,g_u,a,1.0/b)
move_u(g_u_prev)
Next
add_scale(g_v,g_v_prev,delta)
For s As Integer=1 To g_steps
solver(g_v_prev,g_v,a,1.0/b)
move_v(g_v_prev)
Next
project(g_u_prev,g_v_prev,g_u,g_v)
move_uv(g_u,g_u_prev,g_u_prev,g_v_prev,delta)
move_u (g_u)
move_uv(g_v,g_v_prev,g_u_prev,g_v_prev,delta)
move_v (g_v)
project(g_u,g_v,g_u_prev,g_v_prev)
move_u (g_u)
move_v (g_v)
#if 0
For x As Integer=0 To g_N
g_u[x+g_rows*g_N]*=0
g_v[x+g_rows* 4]*=0
Next
#endif
density*=delta
a=density*g_N2*delta
b=a*4+1
add_scale (g_d,g_d_prev,delta)
For s As Integer=1 To g_steps
solver(g_d_prev,g_d,a,1.0/b)
move(g_d_prev)
Next
move_uv(g_d,g_d_prev,g_u,g_v,delta)
move(g_d)
'scale(g_d,0.9999999)
End Sub
/'
----------------------------------------------------------------------
free/clear/allocate simulation data
----------------------------------------------------------------------
'/
Sub free_data ()
If (g_u) Then deallocate (g_u):g_u=0
End Sub
Sub clear_data ()
For i As Integer=0 To g_nCells-1
g_u[i] = 0.0f
g_v[i] = 0.0f
g_u_prev[i] = 0.0f
g_v_prev[i] = 0.0f
g_d[i] = 0.0f
g_d_prev[i] = 0.0f
Next
End Sub
Function allocate_data () As Integer
Dim As Integer size = g_nCells
g_u = callocate( g_nCells*4*6)
If g_u=0 Then
Print "error: cannot allocate data!"
Beep:Return 0
End If
g_v = g_u+g_nCells*1
g_u_prev = g_u+g_nCells*2
g_v_prev = g_u+g_nCells*3
g_d = g_u+g_nCells*4
g_d_prev = g_u+g_nCells*5
Return 1
End Function
/'
----------------------------------------------------------------------
OpenGL specific drawing routines
----------------------------------------------------------------------
'/
Sub pre_display ()
glViewport (0,0,g_scr_w,g_scr_h)
glMatrixMode (GL_PROJECTION)
glLoadIdentity ()
gluOrtho2D (0.0, 1.0, 0.0, 1.0)
glEnable (GL_BLEND)
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
glClearColor (0,0,0,0)
glClear (GL_COLOR_BUFFER_BIT)
End Sub
Sub post_display ()
glutSwapBuffers()
End Sub
Sub draw_velocity ()
Dim As Integer i,j
Dim As Single x,y,h
h = 1.0f/g_N
glColor3f ( 1.0f, 1.0f, 1.0f )
glLineWidth ( 1.0f )
glBegin(GL_LINES)
For i=1 To g_n-1
x = (i-0.5f)*h
For j=1 To g_n-1
y = (j-0.5f)*h
glVertex2f ( x, y )
glVertex2f ( x+g_u[IX(i,j)], y+g_v[IX(i,j)] )
Next
Next
glEnd()
End Sub
Sub draw_density ()
Dim As Single h = 1.0f/g_N
glBegin (GL_QUADS)
For i As Integer=0 To g_N'-1
Dim As Single x = (i-0.5f)*h
For j As Integer=0 To g_N'-1
Dim As Single y = (j-0.5f)*h
Dim As Single c1 = g_d[IX(i ,j )]
Dim As Single c2 = g_d[IX(i+1,j )]
Dim As Single c3 = g_d[IX(i+1,j+1)]
Dim As Single c4 = g_d[IX(i ,j+1)]
Dim As Single c=c1+c2+c3+c4
c*=0.25
glColor4F(c1,c1,c1,c1):glVertex2f(x ,y )
glColor4F(c2,c2,c2,c2):glVertex2f(x+h,y )
glColor4F(c3,c3,c3,c3):glVertex2f(x+h,y+h)
glColor4F(c4,c4,c4,c4):glVertex2f(x ,y+h)
Next
Next
glEnd()
End Sub
/'
----------------------------------------------------------------------
relates mouse movements to forces sources
----------------------------------------------------------------------
'/
Sub get_from_UI (d As Single Ptr, _
u As Single Ptr, _
v As Single Ptr)
Dim As Integer i,j
For i=0 To g_nCells-1
d[i]=0
u[i]=0
v[i]=0
Next
If (g_mouse_down(0)=0) And (g_mouse_down(2)=0) Then Return
i = (( g_mx /g_scr_w)*g_N+1)
j = (((g_scr_h-g_my)/g_scr_h)*g_N+1)
If i<1 Or i>g_N Or j<1 Or j>g_N Then Return
If ( g_mouse_down(0) ) Then
u[IX(i,j)] = g_force * (g_mx-g_omx)
v[IX(i,j)] = g_force * (g_omy-g_my)
End If
If ( g_mouse_down(2) ) Then
d[IX(i,j)] = g_source
End If
g_omx = g_mx
g_omy = g_my
End Sub
/'
----------------------------------------------------------------------
GLUT callback routines
----------------------------------------------------------------------
'/
Sub key_func Cdecl (Key As Ubyte, _
x As Integer, _
y As Integer)
Select Case Key
Case 27
free_data()
End
Case Asc("c"),Asc("C")
clear_data ()
Case Asc("q"),Asc("Q")
free_data()
End
Case Asc("v"),Asc("V")
g_dvel = Not g_dvel
End Select
End Sub
Sub mouse_func Cdecl (button As Integer, _
state As Integer, _
x As Integer, _
y As Integer)
g_omx =x:g_mx = x
g_omx =y:g_my = y
If state= GLUT_DOWN Then
g_mouse_down(button) = 1
Else
g_mouse_down(button) = 0
End If
End Sub
Sub motion_func Cdecl (x As Integer, _
y As Integer)
g_mx=x:g_my=y
End Sub
Sub reshape_func Cdecl (w As Integer, _
h As Integer)
glutSetWindow (g_hWin)
glutReshapeWindow (w,h)
g_scr_w=w
g_scr_h=h
End Sub
Sub idle_func Cdecl ()
get_from_UI ( g_d_prev, g_u_prev, g_v_prev )
sim_step(g_viscose,g_density,g_delta)
glutSetWindow ( g_hWin)
glutPostRedisplay ()
End Sub
Sub display_func Cdecl ()
pre_display()
If (g_dvel) Then
draw_velocity()
Else
draw_density()
End If
post_display()
End Sub
/'
----------------------------------------------------------------------
open_glut_window --- open a glut compatible window and set callbacks
----------------------------------------------------------------------
'/
Sub open_glut_window()
glutInitDisplayMode ( GLUT_RGBA Or GLUT_DOUBLE )
glutInitWindowPosition (0,0)
glutInitWindowSize (g_scr_w, g_scr_h)
g_hWin=glutCreateWindow ( "simple 2D fluid solver" )
glClearColor (0,0,0,0)
glClear ( GL_COLOR_BUFFER_BIT )
glutSwapBuffers()
glClear ( GL_COLOR_BUFFER_BIT )
glutSwapBuffers()
pre_display ()
glutKeyboardFunc (@key_func)
glutMouseFunc (@mouse_func)
glutMotionFunc (@motion_func)
glutReshapeFunc (@reshape_func)
glutIdleFunc (@idle_func)
glutDisplayFunc (@display_func)
End Sub
/'
----------------------------------------------------------------------
main --- main routine
----------------------------------------------------------------------
'/
Function main() As Integer
glutInit (1, Strptr(" "))
If ( allocate_data ()=0 ) Then Return 1
clear_data ()
screeninfo g_scr_w,g_scr_h
g_scr_w*=0.5:g_scr_h*=0.5
open_glut_window ()
glutMainLoop()
Return 0
End Function
End main |
|
|
Nach oben |
|
 |
Lloyd

Anmeldungsdatum: 27.06.2008 Beiträge: 37 Wohnort: Nähe Frankfurt
|
Verfasst am: 30.06.2008, 12:11 Titel: |
|
|
Ja, das erste ist ja nicht sonderlich spektakulär, aber das zweite konnt ich nicht compilen:
Code: | Passing different pointer types, at parameter 1 of GLUTKEYBOARDFUNC() |
Dasselbe noch mit den Zeilen 681-683.
Ist aber btw sehr viel Code, dafür, dass der solver weniger als 100 Zeilen haben sollte O_O |
|
Nach oben |
|
 |
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|