劳动局招聘信息:黑客帝国中的字符雨特效
来源:百度文库 编辑:偶看新闻 时间:2024/04/20 00:09:29
那天在论坛里看见篇帖子说是做黑客帝国中的字符雨特效
那个屏保我也用过,确实很酷,学了这么长时间的OPENGL,现在想想实现其实也不算太难
于是回来自己写了这个代码,本打算用3D字符来实现,但仔细一想,还是用贴图来的又快又爽
里面又引用了Textures单元(这个单元太好用了!),这次索性贴出来,想用的兄弟到我的BLOG里找吧
简单说说代码
其实就是个粒子系统,每个粒子带一个贴图,贴图是我自己画的,不过效果还凑合,我想那个屏保里的随机数的感觉,大概是用了几张贴图,然后随机的换吧
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, OPENGL, Textures;
type
TParticle = record //粒子
active: Boolean; //激活
life: GLfloat; //生命期
fade: GLfloat; //衰减
r, g, b: GLfloat; //颜色
x, y, z: GLfloat; //坐标
xi, yi, zi: GLfloat; //方向和速度
end;
//粒子类
TParticles = class
ParticleSpeed: GLfloat;
ParticleNum: Integer;
Particle: array of TParticle;
public
constructor Create(Num: Integer = 100);
destructor Destroy; override;
procedure ParticleBorn(index: Integer);
procedure ParticleOld(index: Integer);
procedure ParticleDead(index: Integer);
procedure ParticleDraw(index: Integer);
end;
TForm1 = class(TForm)
procedure FormResize(Sender: TObject);
procedure FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure FormKeyUp(Sender: TObject; var Key: Word;
Shift: TShiftState);
private
h_RC: HGLRC;
h_DC: HDC;
Keys: array[0..255] of Boolean;
Particles: TParticles;
Texture: GLuint;
rx, ry, rz: GLfloat;
public
constructor Create(Aowner: TComponent); override;
destructor Destroy; override;
procedure SetRCToDC();
procedure glInit();
procedure glResize;
procedure glDraw;
procedure MainLoop(Sender: TObject; var Done: Boolean);
procedure Initparticle;
end;
var
Form1: TForm1;
procedure glBindTexture(Target: GLenum; Texture: GLuint); stdcall; external opengl32; //纹理绑定
implementation
{$R *.dfm}
constructor TForm1.Create(Aowner: TComponent);
begin
inherited;
SetRCToDC;
Randomize;
glInit;
Application.OnIdle := MainLoop;
end;
destructor TForm1.Destroy;
begin
wglMakeCurrent(0, 0);
wglDeleteContext(h_RC);
inherited;
end;
procedure TForm1.FormResize(Sender: TObject);
begin
glResize;
end;
procedure TForm1.glDraw;
var
i: integer;
begin
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0, 0, -20);
glRotatef(rx, 1, 0, 0);
glRotatef(ry, 0, 1, 0);
glRotatef(rz, 0, 0, 1);
with Particles do
for i := 0 to ParticleNum - 1 do
if Particle[i].active then
begin
ParticleDraw(i);
ParticleOld(i);
end;
end;
procedure TForm1.glInit;
begin
glShadeModel(GL_SMOOTH);
glClearColor(0.0, 0.0, 0.0, 0.0);
glClearDepth(1.0);
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
glEnable(GL_TEXTURE_2D);
LoadTexture('..\Pic\01.bmp', Texture, False);
glBindTexture(GL_TEXTURE_2D, Texture);
Particles := TParticles.Create(200);
Initparticle;
end;
procedure TForm1.glResize;
begin
glViewport(0, 0, Width, Height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, Width / Height, 0, 1000);
glMatrixMode(GL_MODELVIEW);
end;
procedure TForm1.Initparticle;
var
i: Integer;
begin
with Particles do
for i := 0 to ParticleNum - 1 do
ParticleBorn(i);
end;
procedure TForm1.MainLoop(Sender: TObject; var Done: Boolean);
begin
Done := False;
glDraw();
SwapBuffers(h_DC);
if Keys[VK_ESCAPE] then
Close;
if Keys[Ord('X')] then
rx := rx + 0.1;
if Keys[Ord('Y')] then
ry := ry + 0.1;
if Keys[Ord('Z')] then
rz := rz + 0.1;
end;
procedure TForm1.SetRCToDC;
var
pfd: TPIXELFORMATDESCRIPTOR;
pf: Integer;
begin
h_DC := GetDC(Handle);
with pfd do
begin
nSize := SizeOf(pfd);
nVersion := 1;
dwFlags := PFD_DRAW_TO_WINDOW
or PFD_SUPPORT_OPENGL
or PFD_DOUBLEBUFFER;
iPixelType := PFD_TYPE_RGBA;
cColorBits := 16;
cDepthBits := 16;
iLayerType := PFD_MAIN_PLANE;
end;
pf := ChoosePixelFormat(h_DC, @pfd);
SetPixelFormat(h_DC, pf, @pfd);
h_RC := wglCreateContext(h_DC);
wglMakeCurrent(h_DC, h_RC);
end;
constructor TParticles.Create(Num: Integer);
begin
ParticleNum := Num;
SetLength(Particle, ParticleNum);
ParticleSpeed := 2.0;
end;
destructor TParticles.Destroy;
begin
inherited;
end;
procedure TParticles.ParticleBorn(index: Integer);
begin
with Particle[index] do
begin
active := True;
life := 20;
fade := Trunc(random(100)) / 1000 + 0.003;
yi := -20;
r := 0;
g := 1;
b := 0;
x := random(50) - 25;
y := 10;
z := random(50) - 25;
end;
end;
procedure TParticles.ParticleDead(index: Integer);
begin
with Particle[index] do
begin
active := False;
ParticleBorn(index);
end;
end;
procedure TParticles.ParticleDraw(index: Integer);
begin
with Particle[index] do
begin
glColor4f(r, g, b, life);
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2d(1, 1);
glVertex3f(x + 0.25, y + 2.5, z);
glTexCoord2d(0, 1);
glVertex3f(x - 0.25, y + 2.5, z);
glTexCoord2d(1, 0);
glVertex3f(x + 0.25, y - 2.5, z);
glTexCoord2d(0, 0);
glVertex3f(x - 0.25, y - 2.5, z);
glEnd();
end;
end;
procedure TParticles.ParticleOld(index: Integer);
begin
with Particle[index] do
begin
y := y + yi / (ParticleSpeed * 1000);
life := life - fade;
if life < 0 then
ParticleDead(index);
end;
end;
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
Keys[Key] := True;
end;
procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
Keys[Key] := False;
end;
end.
加了几个控制键,ESC退出,X,Y,Z分别控制相应坐标轴的旋转
运行一下看看效果,哈,还真有点黑客帝国的感觉
旋转一下再看看
这是我那个蹩脚的纹理,哈哈
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/chijingde/archive/2005/03/29/333645.aspx