Das folgende Beispiel demonstriert, wie realistisch Verbrennungsrauch mit OpenGL dargestellt werden kann. Hier handelt es sich nur um Rauch, der auf der Form empor gerechnet wird.
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:single;
end;
//
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(1,1,1,1);
gtmrcount:=5;
GLEnable(GL_BLEND);
//glBlendFunc(GL_SRC_ALPHA, GL_dst_ALPHA) ;
//glBlendFunc(GL_DST_ALPHA, GL_src_ALPHA) ;
//glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA) ;
//glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR) ;
glblendfunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
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);
var
n:word;
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);
for n:=1 to 33 do
glvertex2f(sin(n*((pi/180)*(360/32))),cos(n*((pi/180)*(360/32))));
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:integer;
c:GLFloat;
begin
gentimer:=gentimer+1;
if gentimer>=gtmrcount then
if pnow<100 then
inc(pnow);
glclear(GL_COLOR_BUFFER_BIT);
glloadidentity;
gltranslatef(0,-0.7,0);
glscalef(0.3,0.3,0.3);
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:=random(4)-2;
y:=-32;
dx:=random*0.5-0.25;
dy:=0.55+random*0.3;
life:=10+random(10);
state:=0;
end;
fire[n].state:=fire[n].state+0.1;
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);
gltranslatef(0,0,0.1*n);
glow((fire[n].life/fire[n].state)*0.1,
(fire[n].life/fire[n].state)*0.1,
(fire[n].life/fire[n].state)*0.1,
(fire[n].life/fire[n].state)*0.1,
(fire[n].life/fire[n].state)*0.01,
(fire[n].life/fire[n].state)*0.01,
(fire[n].life/fire[n].state)*0.01,0,
sqrt(fire[n].state)*10);
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