劳动局招聘信息:黑客帝国中的字符雨特效

来源:百度文库 编辑:偶看新闻 时间:2024/04/20 00:09:29
黑客帝国中的字符雨特效2009-09-18 13:53

那天在论坛里看见篇帖子说是做黑客帝国中的字符雨特效

那个屏保我也用过,确实很酷,学了这么长时间的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