this slowpoke moves

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

Translate