Entwickler-Ecke

Sonstiges (Delphi) - Real Time Fluids


F34r0fTh3D4rk - So 08.10.06 18:23
Titel: Real Time Fluids
hi, ich hab vor einiger zeit diesen code von c++ nach delphi portiert, es geht um die berechnung von flüssigkeiten in echtzeit, jedoch habe ich keine ahnung wie ich den code verwende, hat da jemand ne idee, oder kann ein beispiel posten ?

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
const
  N = 105;
  size = (N+2)*(N+2);

type
  TSingleArray = array [1..size-1of Single;

var
  u, v, u_prev, v_prev,
  dens, dens_prev: TSingleArray;
  visc, diff,
  dt: single;

//MACROS - BEGIN
function IX(i, j: integer): integer;
begin
  result := ((i)+(N+2)*(j));
end;

procedure SWAP(x0, x: TSingleArray);
var
  tmp: TSingleArray;
begin
  tmp := x0;
  x0 := x;
  x := tmp;
end;
//MACROS - END

procedure set_bnd(N, b: integer; x: TSingleArray);
var
  i: integer;
begin
  for i := 1 to N do
  begin
    if b = 1 then
    begin
      x[IX(0, i)] := -x[IX(1, i)];
      x[IX(N+1,i)] := -x[IX(N, i)];
    end else
    begin
      x[IX(0, i)] :=  x[IX(1, i)];
      x[IX(N+1,i)] := x[IX(N, i)];
    end;
    if b = 2 then
    begin
      x[IX(i, 0)] := -x[IX(i, 1)];
      x[IX(i, N+1)] := -x[IX(i, N)];
    end else
    begin
      x[IX(i, 0)] := x[IX(i,1 )];
      x[IX(i, N+1)] := x[IX(i, N)];
    end;
  end;
  x[IX(00)] := 0.5*(x[IX(10)]+x[IX(01)]);
  x[IX(0, N+1)] := 0.5*(x[IX(1,N+1)]+x[IX(0 ,N)]);
  x[IX(N+10)] := 0.5*(x[IX(N, 0)]+x[IX(N+11)]);
  x[IX(N+1, N+1)] := 0.5*(x[IX(N, N+1)]+x[IX(N+1, N)]);
end;

procedure project(N: integer; u, v, p, divi: TSingleArray);
var
  i, j, k: integer;
  h: single;
begin
  h := 1/N;
  for i := 1 to N do
    for j := 1 to N do
    begin
      divi[IX(i, j)] := -0.5*h*(u[IX(i+1, j)]-u[IX(i-1, j)]+v[IX(i, j+1)]-v[IX(i, j-1)]);
      p[IX(i, j)] := 0;
    end;
  set_bnd(N, 0, divi);
  set_bnd(N, 0, p);
  for k := 0 to 19 do
    for i := 1 to N do
      for j := 1 to N do
        p[IX(i, j)] := (divi[IX(i, j)]+p[IX(i-1, j)]+p[IX(i+1, j)]+p[IX(i, j-1)]+p[IX(i, j+1)])/4;
  set_bnd(N, 0, p);
  for i := 1 to N do
    for j := 1 to N do
    begin
      u[IX(i, j)] := u[IX(i, j)] - (0.5*(p[IX(i+1, j)]-p[IX(i-1, j)])/h);
      v[IX(i, j)] := v[IX(i, j)] - (0.5*(p[IX(i, j+1)]-p[IX(i, j-1)])/h)
    end;
  set_bnd(N, 1, u);
  set_bnd(N, 2, v);
end;

procedure add_source(N: integer; x, s: TSingleArray; dt: single);
var
  i: integer;
begin
  for i := 1 to size-1 do
    x[i] := x[i]+dt*s[i];
end;

procedure diffuse(N, b: integer; x, x0: TSingleArray; diff, dt: single);
var
  i, j, k: integer;
  a: single;
begin
  a := dt*diff*N*N;
  for k := 0 to 19 do
    for i := 1 to N do
      for j := 1 to N do
        x[IX(i, j)] :=  (x0[IX(i, j)] + a*(x[IX(i-1, j)]+x[IX(i+1, j)] + x[IX(i, j-1)] + x[IX(i, j+1)])) / (1+4*a);
  set_bnd(N, b, x);
end;

procedure advect(N, b: integer; d, d0, u, v: TSingleArray; dt: single);
var
  i, j, i0, j0, i1, j1: integer;
  x, y, s0, t0, s1, t1, dt0: single;
begin
  dt0 := dt*N;
  for i := 1 to N do
    for j := 1 to N do
    begin
      x := i-dt0*u[IX(i, j)];
      y := j-dt0*v[IX(i, j)];
      if (x < 0.5then
        x := 0.5;
      if (x > N + 0.5then
        x := N + 0.5;
      i0 := round(x);
      i1 := i0 + 1;
      if (y < 0.5then
        y := 0.5;
      if (y > N + 0.5then
        y := N + 0.5;
      j0 := round(y);
      j1 := j0 + 1;
      s1 := x-i0;
      s0 := 1-s1;
      t1 := y-j0;
      t0 := 1-t1;
      d[IX(i, j)] := s0*(t0*d0[IX(i0, j0)]+t1*d0[IX(i0, j1)])+s1*(t0*d0[IX(i1, j0)]+t1*d0[IX(i1, j1)]);
    end;
  set_bnd(N, b, d);
end;

procedure dens_step(N: integer; x, x0, u, v: TSingleArray; diff, dt: single);
begin
  add_source(N, x, x0, dt);
  SWAP(x0, x);
  diffuse(N, 0, x, x0, diff, dt);
  SWAP(x0, x);
  advect(N, 0, x, x0, u, v, dt);
end;

procedure vel_step(N: integer; u, v, u0, v0: TSingleArray; visc, dt: single);
begin
  add_source(N, u, u0, dt);
  add_source(N, v, v0, dt);
  SWAP(u0, u);
  diffuse(N, 1, u, u0, visc, dt);
  SWAP(v0, v);
  diffuse(N, 2, v, v0, visc, dt);
  project(N, u, v, u0, v0);
  SWAP(u0, u);
  SWAP(v0, v);
  advect(N, 1, u, u0, u0, v0, dt);
  advect(N, 2, v, v0, u0, v0, dt);
  project(N, u, v, u0, v0);
end;


vielen dank schonmal ;)

mfg


AXMD - So 08.10.06 19:00

Da weder aussagekräftige Namen noch Kommentare im Code sind, halte ich es für nahezu unmöglich, den Code als "Außenstehender" zu verstehen - meine Meinung.

AXMD


alias5000 - So 08.10.06 19:04

Sieht das original auch so unkommentiert aus?


Chryzler - So 08.10.06 20:04

Ich glaube er meint den Code hier: http://jgt.akpeters.com/papers/Stam01/solver03.html
Und hier ist ein Beispielcode: http://jgt.akpeters.com/papers/Stam01/demo03.html
Und hier ist nochmal alles schön erklärt: http://www.dgp.toronto.edu/people/stam/reality/Research/pdf/GDC03.pdf


F34r0fTh3D4rk - Mo 09.10.06 17:30

ah, opengl, das ist schonmal was was ich verstehe und das net spezifisch für c++ ist.

danke ;)


Martok - Mo 09.10.06 17:47

Wenn du was funktionierendes in Delphi hast, postest du das dann mal?

Irgendwie interessiert mich das auch, aber ich bin im Moment zu faul den Code selbst zu übersetzen ;)


user profile iconF34r0fTh3D4rk hat folgendes geschrieben:
ah, opengl, das ist schonmal was was ich verstehe und das net spezifisch für c++ ist.

Hehe, der wird schon nicht umsonst Opengl genommen haben. Auch wenn glut schon "etwas" veraltet ist....


JayEff - Mo 09.10.06 17:48

Verzeiht mir die Off-Topic Frage: Hat das was mit deiner Fear-Engine zu tun? Planst du eine Physik-Engine? Eine 3D, womöglich sogar? Ich musste einfach fragen ... :(


Martok - Mo 09.10.06 17:52

3D-Physik wäre für eine 2D-OpenGL-Engine ziemlich sinnlos, oder?
Sorry, musste sein ;)

Für 3d würde ich zu Newton raten. (Suchst du sowas?)


JayEff - Mo 09.10.06 18:18

Ok, ich dachte, das kann man nicht falsch verstehen aber dann ergänze ich meinen Satz eben...:
Planst du eine Physik-Engine? Eine 3D-Engine, womöglich sogar?
Der erste teil hat was mit Fear2d zu tun. der zweite mit Fear3D (so fern sowas in Planung ist)
Alles klar, jetzt? ;)


F34r0fTh3D4rk - Mo 09.10.06 18:24

ich habs soweit dass es gehen müsste, aber ich sehe rein garnix,
der typ hat seinen code auch kein stück kommentiert, ich hab jetzt das weggelassen, wovon ich denke dass es c++ non-vcl spezifisch ist:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
296:
297:
298:
299:
300:
301:
302:
303:
304:
305:
306:
307:
308:
309:
310:
311:
312:
313:
314:
315:
316:
317:
318:
319:
320:
321:
322:
323:
324:
325:
326:
327:
328:
329:
330:
331:
332:
333:
334:
335:
336:
337:
338:
339:
340:
341:
342:
343:
344:
345:
346:
347:
348:
349:
350:
351:
352:
353:
354:
355:
356:
357:
358:
359:
360:
361:
362:
363:
364:
365:
366:
367:
368:
369:
370:
371:
372:
373:
374:
375:
376:
377:
378:
379:
380:
381:
382:
383:
384:
385:
386:
387:
388:
389:
390:
391:
392:
393:
394:
395:
396:
397:
398:
399:
400:
401:
unit UMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, dglopengl, glBitmap,
  F2D_Core;

const
  N = 128;
  size = (N+2)*(N+2);

type
  TSingleArray = array [1..size-1of Single;

var
  u, v, u_prev, v_prev,
  dens, dens_prev: TSingleArray;
  visc, diff,
  dt: single;
  force, source: single;

type
  TMainForm = class(TForm)
    procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
    procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
    procedure FormDestroy(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure ApplicationEventsIdle(Sender: TObject; var Done: Boolean);
    procedure getstates(d, u, v: TSingleArray);
  private
    CalcTime,
    Frequency: int64;
  public
    Engine: TEngine;
  end;

var
  MainForm: TMainForm;
  veldenstoggle: boolean;
  omx, omy, mx, my: integer;
  mouse1, mouse2: boolean;

implementation

{$R *.dfm}

//MACROS - BEGIN
function IX(i, j: integer): integer;
begin
  result := ((i)+(N+2)*(j));
end;

procedure SWAP(x0, x: TSingleArray);
var
  tmp: TSingleArray;
begin
  tmp := x0;
  x0 := x;
  x := tmp;
end;
//MACROS - END

procedure set_bnd(N, b: integer; x: TSingleArray);
var
  i: integer;
begin
  for i := 1 to N do
  begin
    if b = 1 then
    begin
      x[IX(0, i)] := -x[IX(1, i)];
      x[IX(N+1,i)] := -x[IX(N, i)];
    end else
    begin
      x[IX(0, i)] :=  x[IX(1, i)];
      x[IX(N+1,i)] := x[IX(N, i)];
    end;
    if b = 2 then
    begin
      x[IX(i, 0)] := -x[IX(i, 1)];
      x[IX(i, N+1)] := -x[IX(i, N)];
    end else
    begin
      x[IX(i, 0)] := x[IX(i,1 )];
      x[IX(i, N+1)] := x[IX(i, N)];
    end;
  end;
  x[IX(00)] := 0.5*(x[IX(10)]+x[IX(01)]);
  x[IX(0, N+1)] := 0.5*(x[IX(1,N+1)]+x[IX(0 ,N)]);
  x[IX(N+10)] := 0.5*(x[IX(N, 0)]+x[IX(N+11)]);
  x[IX(N+1, N+1)] := 0.5*(x[IX(N, N+1)]+x[IX(N+1, N)]);
end;

procedure project(N: integer; u, v, p, divi: TSingleArray);
var
  i, j, k: integer;
  h: single;
begin
  h := 1/N;
  for i := 1 to N do
    for j := 1 to N do
    begin
      divi[IX(i, j)] := -0.5*h*(u[IX(i+1, j)]-u[IX(i-1, j)]+v[IX(i, j+1)]-v[IX(i, j-1)]);
      p[IX(i, j)] := 0;
    end;
  set_bnd(N, 0, divi);
  set_bnd(N, 0, p);
  for k := 0 to 19 do
    for i := 1 to N do
      for j := 1 to N do
        p[IX(i, j)] := (divi[IX(i, j)]+p[IX(i-1, j)]+p[IX(i+1, j)]+p[IX(i, j-1)]+p[IX(i, j+1)])/4;
  set_bnd(N, 0, p);
  for i := 1 to N do
    for j := 1 to N do
    begin
      u[IX(i, j)] := u[IX(i, j)] - (0.5*(p[IX(i+1, j)]-p[IX(i-1, j)])/h);
      v[IX(i, j)] := v[IX(i, j)] - (0.5*(p[IX(i, j+1)]-p[IX(i, j-1)])/h)
    end;
  set_bnd(N, 1, u);
  set_bnd(N, 2, v);
end;

procedure add_source(N: integer; x, s: TSingleArray; dt: single);
var
  i: integer;
begin
  for i := 1 to size-1 do
    x[i] := x[i]+dt*s[i];
end;

procedure diffuse(N, b: integer; x, x0: TSingleArray; diff, dt: single);
var
  i, j, k: integer;
  a: single;
begin
  a := dt*diff*N*N;
  for k := 0 to 19 do
    for i := 1 to N do
      for j := 1 to N do
        x[IX(i, j)] :=  (x0[IX(i, j)] + a*(x[IX(i-1, j)]+x[IX(i+1, j)] + x[IX(i, j-1)] + x[IX(i, j+1)])) / (1+4*a);
  set_bnd(N, b, x);
end;

procedure advect(N, b: integer; d, d0, u, v: TSingleArray; dt: single);
var
  i, j, i0, j0, i1, j1: integer;
  x, y, s0, t0, s1, t1, dt0: single;
begin
  dt0 := dt*N;
  for i := 1 to N do
    for j := 1 to N do
    begin
      x := i-dt0*u[IX(i, j)];
      y := j-dt0*v[IX(i, j)];
      if (x < 0.5then
        x := 0.5;
      if (x > N + 0.5then
        x := N + 0.5;
      i0 := round(x);
      i1 := i0 + 1;
      if (y < 0.5then
        y := 0.5;
      if (y > N + 0.5then
        y := N + 0.5;
      j0 := round(y);
      j1 := j0 + 1;
      s1 := x-i0;
      s0 := 1-s1;
      t1 := y-j0;
      t0 := 1-t1;
      d[IX(i, j)] := s0*(t0*d0[IX(i0, j0)]+t1*d0[IX(i0, j1)])+s1*(t0*d0[IX(i1, j0)]+t1*d0[IX(i1, j1)]);
    end;
  set_bnd(N, b, d);
end;

procedure dens_step(N: integer; x, x0, u, v: TSingleArray; diff, dt: single);
begin
  add_source(N, x, x0, dt);
  SWAP(x0, x);
  diffuse(N, 0, x, x0, diff, dt);
  SWAP(x0, x);
  advect(N, 0, x, x0, u, v, dt);
end;

procedure vel_step(N: integer; u, v, u0, v0: TSingleArray; visc, dt: single);
begin
  add_source(N, u, u0, dt);
  add_source(N, v, v0, dt);
  SWAP(u0, u);
  diffuse(N, 1, u, u0, visc, dt);
  SWAP(v0, v);
  diffuse(N, 2, v, v0, visc, dt);
  project(N, u, v, u0, v0);
  SWAP(u0, u);
  SWAP(v0, v);
  advect(N, 1, u, u0, u0, v0, dt);
  advect(N, 2, v, v0, u0, v0, dt);
  project(N, u, v, u0, v0);
end;

procedure draw_velocity;
var
  i, j: integer;
  x, y, h: single;
begin
  h := 1 / N;

  glColor3f(111);
  glLineWidth(1);

  glBegin(GL_LINES);
  for i := 1 to N do
  begin
    x := (i - 0.5) * h;
    for j := 1 to N do
    begin
      y := (j - 0.5) * h;
      glVertex2f(x, y);
      glVertex2f(x + u[IX(i, j)], y + v[IX(i, j)]);
    end
  end;
  glEnd;
end;

procedure draw_density;
var
  i, j: integer;
  x, y, h, d00, d01, d10, d11: single;
begin
  h := 1 / N;
  glBegin(GL_QUADS);
    for i := 0 to N do
    begin
      x := (i - 0.5) *h;
      for j := 0 to N do
      begin
        y := (j - 0.5) *h;
        d00 := dens[IX(i, j)];
        d01 := dens[IX(i, j + 1)];
        d10 := dens[IX(i + 1, j)];
        d11 := dens[IX(i + 1, j + 1)];

        glColor3f(d00, d00, d00); glVertex2f(x, y);
        glColor3f(d10, d10, d10); glVertex2f(x + h, y);
        glColor3f(d11, d11, d11); glVertex2f(x + h, y + h);
        glColor3f(d01, d01, d01); glVertex2f(x, y + h);
      end;
    end;
  glEnd;
end;

procedure ResetSimulation;
const
  size = (N + 2) * (N + 2);
var
  i: integer;
begin
  for i := 0 to size - 1 do
  begin
    u[i] := 0;
    v[i] := 0;
    u_prev[i] := 0;
    v_prev[i] := 0;
    dens[i] := 0;
    dens_prev[i] := 0;
  end;
end;

procedure TMainForm.FormCreate(Sender: TObject);
begin
//INIT VARS
  diff := 0;
  visc := 0;
  force := 5;
  source := 100;

  mouse1 := false;
  mouse2 := false;

  veldenstoggle := true;

  Engine := TEngine.Create(false);
  Engine.Init(self);
  Application.OnIdle := ApplicationEventsIdle;
end;

procedure TMainForm.FormDestroy(Sender: TObject);
begin
  Engine.Free;
end;

procedure TMainForm.getstates(d, u, v: TSingleArray);
const
  size = (N + 2) * (N + 2);
var
  i, j: integer;
begin
  for i := 0 to size - 1 do
  begin
    u[i] := 0;
    v[i] := 0;
    d[i] := 0;
  end;

  if (not mouse1) and (not mouse2) then
    exit;

  i := round((mx / Engine.width) * N + 1);
  j := round(((Engine.Height - my) / Engine.Height) * N + 1);

  if (i < 1or (i > N) or (j < 1or (j > N) then
    exit;

  if mouse1 then
  begin
    u[IX(i, j)] := force * (mx - omx);
    v[IX(i, j)] := force * (omy - my);
  end;

  if mouse2 then
    d[IX(i, j)] := source;

  omx := mx;
  omy := my;
end;

procedure TMainForm.ApplicationEventsIdle(Sender: TObject; var Done: Boolean);
begin
  Engine.DoBegin;

  //COMPUTE

  dt := Engine.Timestep;

  getstates(dens_prev, u_prev, v_prev);

  vel_step(N, u, v, u_prev, v_prev, visc, dt);
  dens_step(N, dens, dens_prev, u, v, diff, dt);

  //DRAW

  if veldenstoggle = true then
    draw_velocity else
      draw_density;

  //FPS

  MainForm.Caption := 'FPS: ' + floattostr(Engine.FPS);

  Engine.DoEnd;
  done := false;
end;

procedure TMainForm.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if key = ord('v'then
    veldenstoggle := not veldenstoggle;
  if key = ord('c'then
    ResetSimulation;  
end;

procedure TMainForm.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if ssleft in shift then
    mouse1 := true;
  if ssright in shift then
    mouse2 := true;
  omx := x;
  omx := y;
  mx := x;
  my := y;
end;

procedure TMainForm.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  mx := x;
  my := y;
end;

procedure TMainForm.FormMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if ssleft in shift then
    mouse1 := false;
  if ssright in shift then
    mouse2 := false;
end;

Initialization
  randomize;

end.

die funktionen die ich aus meiner engine nutze sehen so aus:

Engine.Init
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
  // Handle holen
  DC := GetDC(Form.Handle);

  // RenderContext erstellen und aktivieren
  RC := CreateRenderingContext(DC, [opDoubleBuffered], 32240000);
  ActivateRenderingContext(DC, RC);

  // Aktivieren von Texturen, Tiefen-Tests, etc.
  glEnable(GL_TEXTURE_2D);
  glEnable(GL_DEPTH_TEST);
  glDepthFunc(GL_LESS);
  glEnable(GL_CULL_FACE);
  glCullFace(GL_FRONT);


Engine.DoBegin
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
  // Bild leeren
  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);

  // Projektion ausrichten
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity;
  glViewport(00, Form.ClientWidth, Form.ClientHeight);

  // Setzt den Ursprung links oben an
  glOrtho(0, Form.ClientWidth, Form.ClientHeight, 00, maxdepth);

  // ModelMatrix ausrichten
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity;

  glTranslatef(form.width / 2, form.Height / 20);
  //Zoom
  glScalef(zoom, zoom, 1);
  glTranslatef(-form.width / 2, -form.Height / 20);

  // Setz den Zeichenpunkt auf das Offset
  glTranslatef(x, y, 0);


Engine.DoEnd
1:
2:
  //SwapBuffers
  SwapBuffers(DC);

Engine.Timestep liefert mir das aktuelle delta t

Das einzige was passiert ist, eben, dass die FPS heruntersachen, zu sehen ist schwarz, ich kenne die kompilierte original demo ja auch net, sonst wüsste ich vielleicht weiter :(

danke schonmal

ich hänge mal das komplette projekt an:

mfg


Martok - Mo 09.10.06 18:48

Also, die Parameter der Funktionen müssen TSingleArray immer als var-Parameter erhalten. Sons ändern sie nur an den Kopien was.

Hab ich mal gemacht, man sieht auch was, aber immer noch nicht das richtige. Nur einen Satz Linien links oben :(
Aber das schaffen wir auch noch^^


F34r0fTh3D4rk - Mo 09.10.06 18:59

das sind wieder so Füchtigkeitsfehler :lol:

das spiel wurde mit dem c++ code entwickelt, deshalb bin ich erst dadrauf gekommen:

http://www.plasmapong.com/

und das tastenzeug muss in keypressed net keydown und dann eben ohne das ord(), aber ich sehe schon striche, auch wenn sie alle von oben links kommen ^^

mit

Delphi-Quelltext
1:
2:
  Engine.X := 128;
  Engine.Y := 128;


sieht mans besser aber irgendwas stimmt da noch net ...

mfg


Martok - Mo 09.10.06 19:05

Kenn ich, ist nicht schlecht. Aber die Musik....

Hier, es funzt. Könnte aber sein, dass ohne Engine die Sache einfacher wird...

Werd mich mal ans umschreiben machen...


F34r0fTh3D4rk - Mo 09.10.06 19:10

user profile iconMartok hat folgendes geschrieben:
Kenn ich, ist nicht schlecht. Aber die Musik....

Hier, es funzt. Könnte aber sein, dass ohne Engine die Sache einfacher wird...

Werd mich mal ans umschreiben machen...


ich find die musik gerade geil (ab einer bestimmten geschwindigkeit)

ich guck mal, danke

danke martoks hilfe und beistand läufts jetzt endlich (anhang)

€: ok eine zeile ist noch falsch, wenn ich weiter bin poste ich hier nochmal

mfg


Chryzler - Di 10.10.06 17:32

Fluid Dynamics... das scheint ja ein ganz interessantes Thema zu sein :D
So sieht's aus, wenn es funktioniert...


JayEff - Di 10.10.06 17:41

Bitte nächstes mal glut32.dll mitgeben, falls sie nich in irgent einem vertrackten Windows-Ordner sein müsste >.> Ich würds auch gern sehn können ... :(


Chryzler - Di 10.10.06 17:53

Sorry, wusste nicht dass man da noch ne DLL braucht.


sekzero - Di 10.10.06 18:50

Das macht echt Spaß, mit diesen Flüssigkeiten "rumzuspielen"...


F34r0fTh3D4rk - Di 10.10.06 19:57

ich hab noch irgendwo nen fehler bei der berechnung der Dichte, es sieht halt sehr merkwürdig aus, wenn man dichten hinzufügt, ich hab bei mir noch ein objekt inner demo, welches sich durch die flüssigkeit hindurch bewegt, wo liegt der fehler ?

in der demo wird die Dichte grad net gezeichnet, aber das ist für den findigen delphi programmier ja kein beinbruch ;)

ich kann bei meiner demo auch net so schön alles vollmalen mit den Dichten, erstens weil die maus woanders ist und zweitens, weil das net so wirklich geht und beim bewegen sind da immer so streifen drin Oo

die dinger sind bei der c++ version auch viel breiter, ich versteh dat net

mein programm verhält sich ohne viskosität völlig merkwürdig, irgendwie muss da mal jemand drübergucken um das mal durch zu korrigieren, ich häng nochmal neu an:

mfg


alias5000 - Mi 11.10.06 20:03

grrrr da kriegt man ja Augenschmerzen :nut: :nut:

Ne, naja, bin gespannt, was das später mal wird.

Rein aus Interesse: gibts sowas auch schon in 3D? (Ich habs net so mit Grafikprogrammierung, würd mir aber gerne mal ne Demo oder so anschaun)

Gruß alias5000


F34r0fTh3D4rk - Mi 11.10.06 20:09

jo, schau mal hier, da gibts schon recht schicke sachen:

http://graphics.stanford.edu/~fedkiw/

sowas braucht man halt heutzutage in der film/animationsindustrie ;)

aber mein code stimmt immmer noch net, da ist irgendwas faul, nur weiß ich net was, ich bin da schon ewig dran am wursteln, bald bin ich soweit, den ganzen source nochmal zu übersetzen *grml*

mfg


alias5000 - Do 12.10.06 15:45

[Edit] hab's rausgelöscht, weil falscher Thread...[/Edit]


F34r0fTh3D4rk - Fr 13.10.06 12:52

naja ich werd wohl morgen früh aufstehen und mich dann dran machen den source nochmal zu übersetzen und dann so lange zu probieren bis das klappt und wenn das abend wird :!:

edit: so weit schonmal:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
unit fluid_solver;

interface

type
  TSingleArray = array of Single;
  TFluidSimulation = class
  private
    fN,
    fsize: integer;
    procedure SetN(const Value: integer);
    function IX(i, j: integer): integer;
    procedure SWAP(var x0, x: TSingleArray);
    procedure add_source(var x: TSingleArray; s: TSingleArray; dt: single);
    procedure set_bnd(b: integer; var x: TSingleArray);
    procedure lin_solve(b: integer; var x: TSingleArray; x0: TSingleArray; a, c: single);
    procedure diffuse(b: integer; var x: TSingleArray; x0: TSingleArray; diff, dt: single);
    procedure advect(b: integer; var d: TSingleArray; d0, u, v: TSingleArray; dt: single);
    procedure project(var u, v, p, d: TSingleArray);
  public
    procedure dens_step(var x, x0: TSingleArray; u, v: TSingleArray; diff, dt: single);
    procedure vel_step(var u, v, u0, v0: TSingleArray; visc, dt: single);
    property N: integer read fN write SetN;
  end;

implementation

procedure TFluidSimulation.SetN(const Value: integer);
begin
  fN := value;
  fsize := (fN + 2) * (fN + 2)
end;

function TFluidSimulation.IX(i, j: integer): integer;
begin
  result := i + (fN + 2) * j;
end;

procedure TFluidSimulation.SWAP(var x0, x: TSingleArray);
var
  tmp: TSingleArray;
  i: integer;
begin
  setlength(tmp, length(x0));
  for i := low(x0) to high(x0) do
    tmp[i] := x0[i];
  setlength(x0, length(x));
  for i := low(x) to high(x) do
    x0[i] := x[i];
  setlength(x, length(tmp));
  for i := low(tmp) to high(tmp) do
    x[i] := tmp[i];
end;

procedure TFluidSimulation.add_source(var x: TSingleArray; s: TSingleArray; dt: single);
var
  i: integer;
begin
  for i := 0 to fsize - 1 do
    x[i] := x[i] + dt * s[i];
end;

procedure TFluidSimulation.set_bnd(b: integer; var x: TSingleArray);
var
  i: integer;
begin
  for i := 1 to fN - 1 do
  begin
    if b = 1 then
    begin
      x[IX(0     , i)] := -x[IX(1 , i)];
      x[IX(fN + 1, i)] := -x[IX(fN, i)];
    end else
      begin
        x[IX(0     , i)] := x[IX(1 , i)];
        x[IX(fN + 1, i)] := x[IX(fN, i)];
      end;
    if b = 2 then
    begin
      x[IX(i, 0     )] := -x[IX(i, 1 )];
      x[IX(i, fN + 1)] := -x[IX(i, fN)];
    end else
      begin
        x[IX(i, 0     )] := x[IX(i, 1 )];
        x[IX(i, fN + 1)] := x[IX(i, fN)];
      end;
  end;
  x[IX(0     , 0     )] := 0.5 * (x[IX(1 , 0     )] + x[IX(0     , 1 )]);
  x[IX(0     , fN + 1)] := 0.5 * (x[IX(1 , fN + 1)] + x[IX(0     , fN)]);
  x[IX(fN + 10     )] := 0.5 * (x[IX(fN, 0     )] + x[IX(fN + 11 )]);
  x[IX(fN + 1, fN + 1)] := 0.5 * (x[IX(fN, fN + 1)] + x[IX(fN + 1, fN)]);
end;

procedure TFluidSimulation.lin_solve(b: integer; var x: TSingleArray; x0: TSingleArray; a, c: single);
var
  i, j, k: integer;
begin
  for k := 0 to 19 do
  begin
    for i := 1 to fN do
      for j := 1 to fN do
        x[IX(i, j)] := (x0[IX(i, j)] + a * (x[IX(i - 1, j)] + x[IX(i + 1, j)] + x[IX(i, j - 1)] + x[IX(i, j + 1)])) / c;
    set_bnd(b, x);
  end;
end;

procedure TFluidSimulation.diffuse(b: integer; var x: TSingleArray; x0: TSingleArray; diff, dt: single);
var
  a: single;
begin
  a := dt * diff * fN * fN;
  lin_solve(b, x, x0, a, 1 + 4 * a);
end;

procedure TFluidSimulation.advect(b: integer; var d: TSingleArray; d0, u, v: TSingleArray; dt: single);
var
  i, j, i0, j0, i1, j1: integer;
  x, y, s0, t0, s1, t1, dt0: single;
begin
  dt0 := dt * fN;
  for i := 1 to fN do
    for j := 1 to fN do
    begin
      x := i - dt0 * u[IX(i, j)];
      y := j - dt0 * v[IX(i, j)];
      if (x < 0.5then
        x := 0.5;
      if (x > fN + 0.5then
        x := fN + 0.5;
      i0 := round(x);
      i1 := i0 + 1;
      if (y < 0.5then
        y := 0.5;
      if (y > fN + 0.5then
        y := fN + 0.5;
      j0 := round(y);
      j1 := j0 + 1;
      s1 := x - i0;
      s0 := 1 - s1;
      t1 := y - j0;
      t0 := 1 - t1;
      d[IX(i, j)] := s0 * (t0 * d0[IX(i0, j0)] + t1 * d0[IX(i0, j1)]) + s1 * (t0 * d0[IX(i1, j0)] + t1 * d0[IX(i1, j1)]);
    end;
  set_bnd(b, d);
end;

procedure TFluidSimulation.project(var u, v, p, d: TSingleArray);
var
  i, j: integer;
begin
  for i := 1 to N do
    for j := 1 to N do
    begin
      d[IX(i, j)] := -0.5 * (u[IX(i + 1, j)] - u[IX(i - 1, j)] + v[IX(i, j + 1)] - v[IX(i, j - 1)]) / N;
      p[IX(i, j)] := 0;
    end;
  set_bnd(0, d);
  set_bnd(0, p);
  lin_solve(0, p, d, 14);
  for i := 1 to fN do
    for j := 1 to fN do
    begin
      u[IX(i,j)] := u[IX(i,j)] - (0.5 * N * (p[IX(i + 1, j)] - p[IX(i - 1, j)]));
      v[IX(i,j)] := v[IX(i,j)] - (0.5 * N * (p[IX(i, j + 1)] - p[IX(i, j - 1)]));
    end;
  set_bnd(1, u);
  set_bnd(2, v);
end;

procedure TFluidSimulation.dens_step(var x, x0: TSingleArray; u, v: TSingleArray; diff, dt: single);
begin
  add_source(x, x0, dt);
  SWAP(x0, x);
  diffuse(0, x, x0, diff, dt);
  SWAP(x0, x);
  advect(0, x, x0, u, v, dt);
end;

procedure TFluidSimulation.vel_step(var u, v, u0, v0: TSingleArray; visc, dt: single);
begin
  add_source(u, u0, dt);
  add_source(v, v0, dt);
  SWAP(u0, u);
  diffuse(1, u, u0, visc, dt);
  SWAP(v0, v);
  diffuse(2, v, v0, visc, dt);
  project(u, v, u0, v0);
  SWAP(u0, u);
  SWAP(v0, v);
  advect(1, u, u0, u0, v0, dt);
  advect(2, v, v0, u0, v0, dt);
  project(u, v, u0, v0);
end;

end.

jetzt wird die klasse noch brauchbar gemacht und die zeichen prozeduren etc hinzugefügt

mfg


F34r0fTh3D4rk - Sa 14.10.06 16:52

so, aus der neuen übersetzung ist jetzt diese klasse hier geworden, die erstmal alle features der demo beinhaltet:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
296:
unit fluid_solver;

interface

uses
  dglOpengl;

type
  TSingleArray = array of Single;
  TFluidSimulation = class
  private
    fN,
    fsize: integer;
    fu, fv, fu_prev, fv_prev,
    fdens, fdens_prev: TSingleArray;
    fdiff, fvisc: single;
    procedure SetN(const Value: integer);
    function IX(i, j: integer): integer;
    procedure SWAP(var x0, x: TSingleArray);
    procedure add_source(var x: TSingleArray; s: TSingleArray; dt: single);
    procedure set_bnd(b: integer; var x: TSingleArray);
    procedure lin_solve(b: integer; var x: TSingleArray; x0: TSingleArray; a, c: single);
    procedure diffuse(b: integer; var x: TSingleArray; x0: TSingleArray; diff, dt: single);
    procedure advect(b: integer; var d: TSingleArray; d0, u, v: TSingleArray; dt: single);
    procedure project(var u, v, p, d: TSingleArray);
    procedure dens_step(var x, x0: TSingleArray; u, v: TSingleArray; diff, dt: single);
    procedure vel_step(var u, v, u0, v0: TSingleArray; visc, dt: single);
  public
    procedure Initialize(pN: integer; pvisc, pdiff: single);
    procedure Reset;
    procedure NextStep(pTimestep: single);
    procedure AddForce(px, py: integer; pForceX, pForceY: single);
    procedure AddSource(px, py: integer; pSource: single);
    procedure Draw_Velocity;
    procedure Draw_Density;
  end;

implementation

procedure TFluidSimulation.Initialize(pN: integer; pvisc, pdiff: single);
begin
  SetN(pN);
  setlength(fu, fsize);
  setlength(fv, fsize);
  setlength(fu_prev, fsize);
  setlength(fv_prev, fsize);
  setlength(fdens, fsize);
  setlength(fdens_prev, fsize);
  fvisc := pvisc;
  fdiff := pdiff;
end;

procedure TFluidSimulation.SetN(const Value: integer);
begin
  fN := value;
  fsize := (fN + 2) * (fN + 2);
end;

function TFluidSimulation.IX(i, j: integer): integer;
begin
  result := i + (fN + 2) * j;
end;

procedure TFluidSimulation.SWAP(var x0, x: TSingleArray);
var
  tmp: TSingleArray;
begin
   tmp := x0;
   x0 := x;
   x := tmp;   
end;

procedure TFluidSimulation.add_source(var x: TSingleArray; s: TSingleArray; dt: single);
var
  i: integer;
begin
  for i := 0 to fsize - 1 do
    x[i] := x[i] + dt * s[i];
end;

procedure TFluidSimulation.set_bnd(b: integer; var x: TSingleArray);
var
  i: integer;
begin
  for i := 1 to fN - 1 do
  begin
    if b = 1 then
    begin
      x[IX(0     , i)] := -x[IX(1 , i)];
      x[IX(fN + 1, i)] := -x[IX(fN, i)];
    end else
      begin
        x[IX(0     , i)] := x[IX(1 , i)];
        x[IX(fN + 1, i)] := x[IX(fN, i)];
      end;
    if b = 2 then
    begin
      x[IX(i, 0     )] := -x[IX(i, 1 )];
      x[IX(i, fN + 1)] := -x[IX(i, fN)];
    end else
      begin
        x[IX(i, 0     )] := x[IX(i, 1 )];
        x[IX(i, fN + 1)] := x[IX(i, fN)];
      end;
  end;
  x[IX(0     , 0     )] := 0.5 * (x[IX(1 , 0     )] + x[IX(0     , 1 )]);
  x[IX(0     , fN + 1)] := 0.5 * (x[IX(1 , fN + 1)] + x[IX(0     , fN)]);
  x[IX(fN + 10     )] := 0.5 * (x[IX(fN, 0     )] + x[IX(fN + 11 )]);
  x[IX(fN + 1, fN + 1)] := 0.5 * (x[IX(fN, fN + 1)] + x[IX(fN + 1, fN)]);
end;

procedure TFluidSimulation.lin_solve(b: integer; var x: TSingleArray; x0: TSingleArray; a, c: single);
var
  i, j, k: integer;
begin
  for k := 0 to 19 do
  begin
    for i := 1 to fN do
      for j := 1 to fN do
        x[IX(i, j)] := (x0[IX(i, j)] + a * (x[IX(i - 1, j)] + x[IX(i + 1, j)] + x[IX(i, j - 1)] + x[IX(i, j + 1)])) / c;
    set_bnd(b, x);
  end;
end;

procedure TFluidSimulation.diffuse(b: integer; var x: TSingleArray; x0: TSingleArray; diff, dt: single);
var
  a: single;
begin
  a := dt * diff * fN * fN;
  lin_solve(b, x, x0, a, 1 + 4 * a);
end;

procedure TFluidSimulation.advect(b: integer; var d: TSingleArray; d0, u, v: TSingleArray; dt: single);
var
  i, j, i0, j0, i1, j1: integer;
  x, y, s0, t0, s1, t1, dt0: single;
begin
  dt0 := dt * fN;
  for i := 1 to fN do
    for j := 1 to fN do
    begin
      x := i - dt0 * u[IX(i, j)];
      y := j - dt0 * v[IX(i, j)];
      if (x < 0.5then
        x := 0.5;
      if (x > fN + 0.5then
        x := fN + 0.5;
      i0 := round(x);
      i1 := i0 + 1;
      if (y < 0.5then
        y := 0.5;
      if (y > fN + 0.5then
        y := fN + 0.5;
      j0 := round(y);
      j1 := j0 + 1;
      s1 := x - i0;
      s0 := 1 - s1;
      t1 := y - j0;
      t0 := 1 - t1;
      d[IX(i, j)] := s0 * (t0 * d0[IX(i0, j0)] + t1 * d0[IX(i0, j1)]) + s1 * (t0 * d0[IX(i1, j0)] + t1 * d0[IX(i1, j1)]);
    end;
  set_bnd(b, d);
end;

procedure TFluidSimulation.project(var u, v, p, d: TSingleArray);
var
  i, j: integer;
begin
  for i := 1 to fN do
    for j := 1 to fN do
    begin
      d[IX(i, j)] := -0.5 * (u[IX(i + 1, j)] - u[IX(i - 1, j)] + v[IX(i, j + 1)] - v[IX(i, j - 1)]) / fN;
      p[IX(i, j)] := 0;
    end;
  set_bnd(0, d);
  set_bnd(0, p);
  lin_solve(0, p, d, 14);
  for i := 1 to fN do
    for j := 1 to fN do
    begin
      u[IX(i,j)] := u[IX(i,j)] - (0.5 * fN * (p[IX(i + 1, j)] - p[IX(i - 1, j)]));
      v[IX(i,j)] := v[IX(i,j)] - (0.5 * fN * (p[IX(i, j + 1)] - p[IX(i, j - 1)]));
    end;
  set_bnd(1, u);
  set_bnd(2, v);
end;

procedure TFluidSimulation.dens_step(var x, x0: TSingleArray; u, v: TSingleArray; diff, dt: single);
begin
  add_source(x, x0, dt);
  SWAP(x0, x);
  diffuse(0, x, x0, diff, dt);
  SWAP(x0, x);
  advect(0, x, x0, u, v, dt);
end;

procedure TFluidSimulation.vel_step(var u, v, u0, v0: TSingleArray; visc, dt: single);
begin
  add_source(u, u0, dt);
  add_source(v, v0, dt);
  SWAP(u0, u);
  diffuse(1, u, u0, visc, dt);
  SWAP(v0, v);
  diffuse(2, v, v0, visc, dt);
  project(u, v, u0, v0);
  SWAP(u0, u);
  SWAP(v0, v);
  advect(1, u, u0, u0, v0, dt);
  advect(2, v, v0, u0, v0, dt);
  project(u, v, u0, v0);
end;

procedure TFluidSimulation.NextStep(pTimestep: single);
begin
  vel_step(fu, fv, fu_prev, fv_prev, fvisc, pTimestep);
  dens_step(fdens, fdens_prev, fu, fv, fdiff, pTimestep);
end;

procedure TFluidSimulation.Reset;
var
  i: integer;
begin
  for i := 0 to fsize - 1 do
  begin
    fu[i] := 0;
    fv[i] := 0;
    fu_prev[i] := 0;
    fv_prev[i] := 0;
    fdens[i] := 0;
    fdens_prev[i] := 0;
  end;
end;

procedure TFluidSimulation.AddForce(px, py: integer; pForceX, pForceY: single);
begin
  fu_prev[IX(px, py)] := pForceX;
  fv_prev[IX(px, py)] := pForceY;
end;

procedure TFluidSimulation.AddSource(px, py: integer; pSource: single);
begin
  fdens_prev[IX(px, py)] := pSource;
end;

procedure TFluidSimulation.Draw_Velocity;
var
  i, j: integer;
  x, y, h: single;
begin
  h := 1 / fN;

  glColor3f(111);
  glLineWidth(1);

  glBegin(GL_LINES);
  for i := 1 to fN do
  begin
    x := (i - 0.5) * h;
    for j := 1 to fN do
    begin
      y := (j - 0.5) * h;
      glColor3f(111);
      glVertex2f(x, y);
      glVertex2f(x + fu[IX(i, j)], y + fv[IX(i, j)]);
    end
  end;
  glEnd;
end;

procedure TFluidSimulation.Draw_Density;
var
  i, j: integer;
  x, y, h, d00, d01, d10, d11: single;
begin
  h := 1 / fN;
  glBegin(GL_QUADS);
    for i := 0 to fN do
    begin
      x := (i - 0.5) * h;
      for j := 0 to fN do
      begin
        y := (j - 0.5) * h;
        d00 := fdens[IX(i    , j    )];
        d01 := fdens[IX(i    , j + 1)];
        d10 := fdens[IX(i + 1, j    )];
        d11 := fdens[IX(i + 1, j + 1)];
        glColor3f(d00, 00); glVertex2f(x    , y    );
        glColor3f(d10, 00); glVertex2f(x + h, y    );
        glColor3f(d11, 00); glVertex2f(x + h, y + h);
        glColor3f(d01, 00); glVertex2f(x    , y + h);
      end;
    end;
  glEnd;
end;

end.

jedoch klappt es leider immer noch nicht. nach einiger zeit spielt das velocity gitter verrückt und beim zeichnen der density bilden sich streifen Oo

und ich glaube nicht, dass ich beim zweiten übersetzen den gleichen fehler gemacht haben könnte, also muss die ursache woanders zu suchen sein, nur wo ?

mfg