⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 openglapp.dpr

📁 particle lines project having a bit errors which u can find out
💻 DPR
📖 第 1 页 / 共 2 页
字号:
//------------------------------------------------------------------------
//
// Author      : Jan Horn
// Email       : jhorn@global.co.za
// Website     : http://www.sulaco.co.za
//               http://home.global.co.za/~jhorn
// Date        : 15 April 2002
// Version     : 1.0
// Description : Particle Lines. I saw a similar effect on a demo once
//               and tried to reproduce the effect here.
//
//------------------------------------------------------------------------
program OpenGLApp;

uses
  Windows,
  Messages,
  OpenGL,
  BMP;

const
  WND_TITLE = 'Particle Lines by Jan Horn';
  FPS_TIMER = 1;                     // Timer to calculate FPS
  FPS_INTERVAL = 500;                // Calculate FPS every 1000 ms

  GRID_WIDTH = 30;
  GRID_HEIGHT = 9;
  TAIL_LENGTH = 6;
  MAX_PARTICLES = 500;

type TVertex = Record
       X, Y, Z : glInt;
     end;
     TParticle = Record
       NextVertex : Integer;         // vertex its traveling to
       DestValue  : Integer;         // speed*elapsedtime value when it gets there.
       Visited : Array[1..TAIL_LENGTH] of Integer;  // last 5 visited vertices
       Speed   : Single;             // speed of the particle
       Step    : glFloat;
     end;

var
  h_Wnd  : HWND;                     // Global window handle
  h_DC   : HDC;                      // Global device context
  h_RC   : HGLRC;                    // OpenGL rendering context
  keys : Array[0..255] of Boolean;   // Holds keystrokes
  FPSCount : Integer = 0;            // Counter for FPS
  ElapsedTime : Integer;             // Elapsed time between frames

  // Textures
  particleTex : glUint;
  backgroundTex : glUint;

  // User variables
  Particles : Integer = 150;
  Grid     : Array[0..GRID_WIDTH*GRID_WIDTH*GRID_HEIGHT] of TVertex;  // grid of 100x100x7
  Particle : Array[1..MAX_PARTICLES] of TParticle;
  ShowBackground : Boolean = TRUE;
  
{$R *.RES}

procedure glBindTexture(target: GLenum; texture: GLuint); stdcall; external opengl32;

{------------------------------------------------------------------}
{  Function to convert int to string.                              }
{------------------------------------------------------------------}
function IntToStr(Num : Integer) : String;  // using SysUtils increase file size by 100K
begin
  Str(Num, result);
end;


//--- Check if the particle has reached its destination. If it has, select a new destination
procedure UpdateParticles;
var I, P : Integer;
begin
  for P :=1 to PARTICLES do
  with Particle[P] do
  begin
    if ElapsedTime >= DestValue then      // Check if the particle has reached its destination
    begin
      for I :=TAIL_LENGTH downto 2 do     // store current location in visited list and thift the other up
        Visited[I] :=Visited[I-1];
      Visited[1] :=NextVertex;

      // select a new random direction
      repeat
        I :=Random(6);
        case I of
          0 : if Visited[1] MOD GRID_WIDTH > 0 then NextVertex := Visited[1] - 1;                 // left
          1 : if Visited[1] MOD GRID_WIDTH < GRID_WIDTH-1 then NextVertex := Visited[1] + 1;      // right
          2 : if Visited[1] MOD (GRID_WIDTH*GRID_WIDTH) > GRID_WIDTH then NextVertex := Visited[1] - GRID_WIDTH;      // back
          3 : if Visited[1] MOD (GRID_WIDTH*GRID_WIDTH) < GRID_WIDTH*GRID_WIDTH-GRID_WIDTH then NextVertex := Visited[1] + GRID_WIDTH;   // forward
          4 : if Visited[1] DIV (GRID_WIDTH*GRID_WIDTH) > 0 then NextVertex := Visited[1] - GRID_WIDTH*GRID_WIDTH;              // down
          5 : if Visited[1] DIV (GRID_WIDTH*GRID_WIDTH) < GRID_HEIGHT-1 then NextVertex := Visited[1] + GRID_WIDTH*GRID_WIDTH;  // up
        end;
        if NextVertex <> Visited[1] then    // not equal current vertex
          if NextVertex <> Visited[2] then  // not equal previous vertex
            I :=-1;
      until I = -1;

      // calculate when the next endpoint will be reached
      DestValue :=Round(((ElapsedTime DIV (Round(10/Speed)))*10+10)/Speed);
    end;
  end;
end;


//--- Draws the tail of the particle. Color fades away. Fast particles are red
procedure drawParticleTail;
var I, P : Integer;
    C : glFloat;
begin
  for P :=1 to PARTICLES do
  with Particle[P] do
  begin

    // Draw the path of the particle and fade the color
    Step := 1-(DestValue - ElapsedTime)/10*Speed;
    glBegin(GL_LINE_STRIP);
      glColor3f(1, 1, 1);
      glVertex3f((Grid[NextVertex].X-Grid[Visited[1]].X)*Step + Grid[Visited[1]].X,
                 (Grid[NextVertex].Y-Grid[Visited[1]].Y)*Step + Grid[Visited[1]].Y,
                 (Grid[NextVertex].Z-Grid[Visited[1]].Z)*Step + Grid[Visited[1]].Z);
      for I :=1 to TAIL_LENGTH-1 do
      begin
        C :=(TAIL_LENGTH-I)/TAIL_LENGTH - Step/TAIL_LENGTH;
        if Speed < 0.05 then
          glColor3f(C, C, 0.5+C)
        else
          glColor3f(0.5+C, C, C);    // faster particles are red
        glVertex3iv(@Grid[Visited[I]]);
      end;
      glColor3f(0, 0, 0.1);
      glVertex3f((Grid[Visited[TAIL_LENGTH-1]].X-Grid[Visited[TAIL_LENGTH]].X)*Step + Grid[Visited[TAIL_LENGTH]].X,
                 (Grid[Visited[TAIL_LENGTH-1]].Y-Grid[Visited[TAIL_LENGTH]].Y)*Step + Grid[Visited[TAIL_LENGTH]].Y,
                 (Grid[Visited[TAIL_LENGTH-1]].Z-Grid[Visited[TAIL_LENGTH]].Z)*Step + Grid[Visited[TAIL_LENGTH]].Z);
    glEnd();
  end;
end;


//--- Draws the head of the particle. Fast particles are red
procedure drawParticleHead();
var P : Integer;
    X, Y, Z : glFloat;
begin
  glBindTexture(GL_TEXTURE_2D, particleTex);
  glEnable(GL_TEXTURE_2D);
  glEnable(GL_BLEND);
  for P :=1 to Particles do
  with Particle[P] do
  begin
    X :=(Grid[NextVertex].X-Grid[Visited[1]].X)*Step + Grid[Visited[1]].X;
    Y :=(Grid[NextVertex].Y-Grid[Visited[1]].Y)*Step + Grid[Visited[1]].Y;
    Z :=(Grid[NextVertex].Z-Grid[Visited[1]].Z)*Step + Grid[Visited[1]].Z;
    if Particle[P].Speed < 0.05 then
      glColor3f(1, 1, 1)
    else
      glColor3f(1, 0.7, 0.7);     // faster particles are red
    glBegin(GL_QUADS);
      glTexCoord2f(0.0, 0.0); glVertex3f(X-0.5, Y-0.5, Z);
      glTexCoord2f(1.0, 0.0); glVertex3f(X+0.5, Y-0.5, Z);
      glTexCoord2f(1.0, 1.0); glVertex3f(X+0.5, Y+0.5, Z);
      glTexCoord2f(0.0, 1.0); glVertex3f(X-0.5, Y+0.5, Z);
    glEnd();
  end;
  glDisable(GL_BLEND);
  glDisable(GL_TEXTURE_2D);
end;


{------------------------------------------------------------------}
{  Function to draw the actual scene                               }
{------------------------------------------------------------------}
procedure glDraw();
begin
  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);    // Clear The Screen And The Depth Buffer
  glLoadIdentity();                                       // Reset The View

  if ShowBackground then
  begin
    glPushMatrix();
      glEnable(GL_TEXTURE_2D);
      glBindTexture(GL_TEXTURE_2D, backgroundTex);
      glTranslatef(0.0,0.0,-2.8);
      glRotate(ElapsedTime/500, 0, 0, 1);
      glColor3f(1, 1, 1);
      glBegin(GL_QUADS);
        glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -0.9, 0);
        glTexCoord2f(1.0, 0.0); glVertex3f(+1.0, -0.9, 0);
        glTexCoord2f(1.0, 1.0); glVertex3f(+1.0, +0.9, 0);
        glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, +0.9, 0);
      glEnd();
      glDisable(GL_TEXTURE_2D);
    glPopMatrix;
  end;

  glTranslatef(0.0,0.0,-31);

  glRotatef(20, 1, 0, 0);
  glRotatef(ElapsedTime/300, 0, 1, 0);

  // Check if the particle has reached its destination. If so, select a new destination
  updateParticles;

  // Draw the particle tail
  drawParticleTail;

  // Draw the actual particles
  drawParticleHead;
end;


{------------------------------------------------------------------}
{  Initialise OpenGL                                               }
{------------------------------------------------------------------}
procedure glInit();
var I, J : Integer;
begin
  glClearColor(0.1, 0.1, 0.4, 0.0); 	   // Black Background
  glShadeModel(GL_SMOOTH);                 // Enables Smooth Color Shading
  glClearDepth(1.0);                       // Depth Buffer Setup
//  glEnable(GL_DEPTH_TEST);                 // Enable Depth Buffer
  glDepthFunc(GL_LESS);		           // The Type Of Depth Test To Do
  glBlendFunc(GL_ONE, GL_ONE);

  glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);   //Realy Nice perspective calculations
  glEnable(GL_TEXTURE_2D);                     // Enable Texture Mapping
  LoadTexture('particle.bmp', particleTex);    // Load the Texture
  LoadTexture('background.bmp', backgroundTex);    // Load the Texture
  glBindTexture(GL_TEXTURE_2D, particleTex);  // Bind the Texture to the object

  Randomize;
  // Initialise all particles
  for I :=1 to MAX_PARTICLES do
  begin
    Particle[I].Visited[1] :=random(GRID_WIDTH*GRID_WIDTH*GRID_HEIGHT);
    for J :=2 to TAIL_LENGTH do
      Particle[I].Visited[J] :=Particle[I].Visited[1];
    Particle[I].NextVertex :=Particle[I].Visited[1];
    Particle[I].Speed :=0.01 + Round(Random(5))/100;
    Particle[I].DestValue :=0;
  end;

  // initialise grid
  for I :=0 to GRID_WIDTH * GRID_WIDTH * GRID_HEIGHT-1 do
  begin
    Grid[I].X :=  I MOD GRID_WIDTH - (GRID_WIDTH DIV 2);
    Grid[I].Z := (I DIV GRID_WIDTH) MOD GRID_WIDTH - (GRID_WIDTH DIV 2);
    Grid[I].Y := (I DIV (GRID_WIDTH*GRID_WIDTH)) MOD GRID_HEIGHT - (GRID_HEIGHT DIV 2);
  end;
end;


{------------------------------------------------------------------}
{  Handle window resize                                            }
{------------------------------------------------------------------}
procedure glResizeWnd(Width, Height : Integer);
begin
  if (Height = 0) then                // prevent divide by zero exception
    Height := 1;
  glViewport(0, 0, Width, Height);    // Set the viewport for the OpenGL window
  glMatrixMode(GL_PROJECTION);        // Change Matrix Mode to Projection
  glLoadIdentity();                   // Reset View
  gluPerspective(45.0, Width/Height, 1.0, 100.0);  // Do the perspective calculations. Last value = max clipping depth

  glMatrixMode(GL_MODELVIEW);         // Return to the modelview matrix
  glLoadIdentity();                   // Reset View
end;


{------------------------------------------------------------------}
{  Processes all the keystrokes                                    }
{------------------------------------------------------------------}
procedure ProcessKeys;
begin
  if Keys[VK_ADD] then
  begin
    Inc(Particles);
    if Particles > MAX_PARTICLES then
      Particles :=MAX_PARTICLES;
  end;

  if Keys[VK_SUBTRACT] then
  begin
    Dec(Particles);
    if Particles = 0then
      Particles :=1;
  end;

  if Keys[Ord('B')] then
  begin
    ShowBackground :=NOT(ShowBackground);
    Keys[Ord('B')] :=FALSE;
  end;
end;


{------------------------------------------------------------------}
{  Determines the application抯 response to the messages received  }
{------------------------------------------------------------------}
function WndProc(hWnd: HWND; Msg: UINT;  wParam: WPARAM;  lParam: LPARAM): LRESULT; stdcall;
begin
  case (Msg) of
    WM_CREATE:
      begin
        // Insert stuff you want executed when the program starts
      end;
    WM_CLOSE:
      begin
        PostQuitMessage(0);
        Result := 0
      end;
    WM_KEYDOWN:       // Set the pressed key (wparam) to equal true so we can check if its pressed
      begin
        keys[wParam] := True;
        Result := 0;
      end;
    WM_KEYUP:         // Set the released key (wparam) to equal false so we can check if its pressed

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -