Draw Reality Fire (49 fps)

Das folgende Beispiel demonstriert, wie nahe realistisches Feuer in OpenGL programmiert werden kann.

Der Timer sollte auf 49 fps gestellt werden.
uses OpenGL

var
  Form1: TForm1;
  DC:HDC;
  hrc:HGLRC;
  GenTimer:real=0;
  GTmrCount:single=0;
  pnow:byte=0;
  Fire:array[1..100]of record
  x,y:glfloat;
  dx,dy:glfloat;
  life:word;
  state:word;
  end;

const
  Cols:array[1..4,1..4]of glfloat=
            ((1,1,0,1),(1,0,0,0),(0.1,0.1,0.1,1),(0,0,0,0));
   
//

procedure SetDCPixelFormat (hdc : HDC);
var
  pfd : TPixelFormatDescriptor;
  nPixelFormat : Integer;
begin
  FillChar (pfd, SizeOf (pfd), 0);
  pfd.dwFlags :=PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER;
  nPixelFormat :=ChoosePixelFormat (hdc, @pfd);
  SetPixelFormat(hdc, nPixelFormat, @pfd);
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  m, n:integer;
  DST:GLFloat;
begin
  randomize;
  dc:=getdc(handle);
  setdcpixelformat(dc);
  hrc:=wglcreatecontext(dc);
  wglmakecurrent(dc,hrc);

  glclearcolor(0,0,0,1);
  gtmrcount:=5;

  GLEnable(GL_BLEND);
  glBlendFunc(GL_SRC_ALPHA, GL_one) ;
end;

function znak(VAR X):ShortInt;
begin
  if GLDouble(X)<0 then result:=-1
 else
  if GLDouble(X)>0 then result:=1
 else
  result:=0;
end;

procedure Glow(CR,CG,CB,CA,RR,RG,RB,RA,Size:GLFloat);
begin
  glscalef(size+1,size+1,size+1);
  glbegin(GL_TRIANGLE_FAN);
  glcolor4f(cr,cg,cb,ca);
  glvertex2f(0,0);
  glcolor4f(rr,rg,rb,ra);
  glvertex2f(0,1);
  glvertex2f(-0.866025403,0.5);
  glvertex2f(-0.866025403,-0.5);
  glvertex2f(0,-1);
  glvertex2f(0.866025403,-0.5);
  glvertex2f(0.866025403,0.5);
  glvertex2f(0,1);
  glend;
end;

function DecBound(Dec,Min,Max:single):Single;
begin
  if(dec>min)and(dec<max)then result:=dec;
  if(dec<min)then result:=min;
  if(dec>max)then result:=max;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
  m, n,i:integer;
  c:GLFloat;
begin
  gentimer:=gentimer+1;

  if gentimer>=gtmrcount then
   if pnow < 100 then
    inc(pnow);
    glclear(GL_COLOR_BUFFER_BIT);
    glloadidentity;
    glscalef(0.03,0.03,0.03);

    for n:=1 to pnow do
    begin

    if(fire[n].life=0)or(fire[n].state>=fire[n].life)then
    with fire[n] do
    begin
      x:=0;
      y:=-32;
      dx:=random*0.5-0.25;
      dy:=0.55+random*0.3;
      life:=30+random(20);
      state:=0;
    end;

    inc(fire[n].state);
    fire[n].dy:=fire[n].dy*1.003;
    fire[n].x:=fire[n].x+fire[n].dx;
    fire[n].y:=fire[n].y+fire[n].dy;

    glpopmatrix;
    glpushmatrix;
    gltranslatef(fire[n].x,fire[n].y,0);

{gllinewidth(1);
//stripes
glcolor3f(1,0.85,0.75);
glbegin(GL_LINES);
glvertex2f(0,0);
glvertex2f(-fire[n].dx,-fire[n].dy);
glend;}
//c:=(1-1/(fire[n].life/fire[n].state)*0.5);

    if fire[n].life/fire[n].state<2 then
    i:=3 else i:=1;
    glow(cols[i,1],
         cols[i,2],
         cols[i,3],
         cols[i,4],
         cols[i+1,1],
         cols[i+1,2],
         cols[i+1,3],
         cols[i+1,4],i*2);

    //glow(c,c,1/(fire[n].life/fire[n].state)*0.5,c,c*2,0,0,0);
  end;
  swapbuffers(dc);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  wglmakecurrent(0,0);
  wgldeletecontext(hrc);
  releasedc(handle,dc);
  deletedc(dc);
end;

Keine Kommentare:

Kommentar veröffentlichen

Beliebte Posts