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

📄 openglapp.dpr

📁 3D火焰效果2好
💻 DPR
📖 第 1 页 / 共 2 页
字号:
//------------------------------------------------------------------------
//
// Author      : Jan Horn
// Email       : jhorn@global.co.za
// Website     : http://home.global.co.za/~jhorn
// Date        : 7 October 2001
// Version     : 1.0
// Description : Quake 3 Model Loader (MD3 Loader) 
//
//------------------------------------------------------------------------
program OpenGLApp;

uses
  Windows,
  Messages,
  OpenGL,
  model,
  Textures,
  SysUtils;

const
  WND_TITLE = 'Quake 3 MD3 Loader by Jan Horn';
  FPS_TIMER = 1;                     // Timer to calculate FPS
  FPS_INTERVAL = 1000;               // Calculate FPS every 1000 ms

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

  // User vaiables
  YRot, XRot     : glFloat;    // Y Rotation
  Depth  : glFloat;
  Xcoord, Ycoord, Zcoord : Integer;
  MouseButton : Integer;

  WireFrame  : Boolean;
  ShowFrames : Boolean;
  fontBase : GLuint;                // base to the font display lists

  Player : Q3Player;
  Weapon : TMD3Model;

{$R *.RES}

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

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


{----------------------------------------------------------------}
{  Procedures used to create and write text                      }
{----------------------------------------------------------------}
procedure BuildFont;
var font : HFONT;
begin
  fontBase := glGenLists(96);                       // Generate enough display lists to hold

  font := CreateFont(-16,                           // height of font
		     0,                             // average character width
		     0,                             // angle of escapement
		     0,                             // base-line orientation angle
		     FW_BOLD,                       // font weight
		     0,			            // italic
		     0,                             // underline
		     0,			            // strikeout
		     ANSI_CHARSET,                  // character set
		     OUT_TT_PRECIS,	            // output precision
		     CLIP_DEFAULT_PRECIS,           // clipping precision
		     ANTIALIASED_QUALITY,           // output quality
		     FF_DONTCARE or DEFAULT_PITCH,  // pitch and family
		     'Arial');                      // font

  SelectObject(h_DC, font);                   // Sets the new font as the current font in the device context
  wglUseFontBitmaps(h_DC, 32, 96, fontBase);  // Creates a set display lists containing the bitmap fonts
end;

procedure KillFont;
begin
  glDeleteLists(fontBase, 96);                // Delete the font display lists, returning used memory
end;

procedure glWrite(X, Y : GLUint; text : PChar);
var drawRect : TRect;
begin
  glPushAttrib(GL_DEPTH_TEST);  // Save the current Depth test settings (Used for blending )
  glDisable(GL_DEPTH_TEST);     // Turn off depth testing (otherwise we get no FPS)
  glDisable(GL_TEXTURE_2D);     // Turn off textures, don't want our text textured
  glMatrixMode(GL_PROJECTION);  // Switch to the projection matrix
  glPushMatrix();               // Save current projection matrix
  glLoadIdentity();

  GetWindowRect(GetDesktopWindow(), drawRect);  // Get current window size
  glOrtho(0, drawRect.right, 0, drawRect.bottom, -1, 1);  // Change the projection matrix using an orthgraphic projection
  glMatrixMode(GL_MODELVIEW);  // Return to the modelview matrix
  glPushMatrix();              // Save the current modelview matrix
  glLoadIdentity();
  glColor3f(1.0, 1.0, 1.0);    // Text color

  glRasterPos2i(X, Y);                                // Position the Text
  glPushAttrib(GL_LIST_BIT);                          // Save's the current base list
  glListBase(fontBase - 32);                              // Set the base list to our character list
  glCallLists(length(text), GL_UNSIGNED_BYTE, PChar(text));  // Display the text
  glPopAttrib();                                      // Restore the old base list

  glMatrixMode(GL_PROJECTION);  // Switch to projection matrix
  glPopMatrix();                // Restore the old projection matrix
  glMatrixMode(GL_MODELVIEW);   // Return to modelview matrix
  glPopMatrix();                // Restore old modelview matrix
  glEnable(GL_TEXTURE_2D);      // Turn on textures, don't want our text textured
  glPopAttrib();                // Restore depth testing
end;


{------------------------------------------------------------------}
{  Function used to write out the current upper and lower frames   }
{------------------------------------------------------------------}
procedure DrawCurrentFrames;
begin
  case Player.animLower of
    BOTH_DEATH1 : glWrite(15, 700, 'Lower : Death 1');
    BOTH_DEAD1  : glWrite(15, 700, 'Lower : Dead 1');
    BOTH_DEATH2 : glWrite(15, 700, 'Lower : Death 2');
    BOTH_DEAD2  : glWrite(15, 700, 'Lower : Dead 2');
    BOTH_DEATH3 : glWrite(15, 700, 'Lower : Death 3');
    BOTH_DEAD3  : glWrite(15, 700, 'Lower : Dead 3');

    LEGS_WALKCR : glWrite(15, 700, 'Lower : Walk Crouch');
    LEGS_WALK   : glWrite(15, 700, 'Lower : Walk');
    LEGS_RUN    : glWrite(15, 700, 'Lower : Run');
    LEGS_BACK   : glWrite(15, 700, 'Lower : Backwarks');
    LEGS_SWIM   : glWrite(15, 700, 'Lower : Swim');
    LEGS_JUMP   : glWrite(15, 700, 'Lower : Jump');
    LEGS_LAND   : glWrite(15, 700, 'Lower : Land');
    LEGS_JUMPB  : glWrite(15, 700, 'Lower : Jump Backwards');
    LEGS_LANDB  : glWrite(15, 700, 'Lower : Land Backwards');
    LEGS_IDLE   : glWrite(15, 700, 'Lower : Idle');
    LEGS_IDLECR : glWrite(15, 700, 'Lower : Idel Crouch');
    LEGS_TURN   : glWrite(15, 700, 'Lower : Turn');
  end;

  case Player.animUpper of
    BOTH_DEATH1 : glWrite(800, 700, 'Upper : Death 1');
    BOTH_DEAD1  : glWrite(800, 700, 'Upper : Dead 1');
    BOTH_DEATH2 : glWrite(800, 700, 'Upper : Death 2');
    BOTH_DEAD2  : glWrite(800, 700, 'Upper : Dead 2');
    BOTH_DEATH3 : glWrite(800, 700, 'Upper : Death 3');
    BOTH_DEAD3  : glWrite(800, 700, 'Upper : Dead 3');

    TORSO_GESTURE : glWrite(800, 700, 'Upper : Gesture');
    TORSO_ATTACK  : glWrite(800, 700, 'Upper : Attack');
    TORSO_ATTACK2 : glWrite(800, 700, 'Upper : Attack2');
    TORSO_DROP    : glWrite(800, 700, 'Upper : Drop');
    TORSO_RAISE   : glWrite(800, 700, 'Upper : Raise');
    TORSO_STAND   : glWrite(800, 700, 'Upper : Stand');
    LEGS_LAND     : glWrite(800, 700, 'Upper : Land');
    TORSO_STAND2  : glWrite(800, 700, 'Upper : Stand2');
  end;
end;


{------------------------------------------------------------------}
{  Function used to load a railgin and join it to the player       }
{------------------------------------------------------------------}
procedure LoadRailgun;

  procedure LoadMeshTexture(const imagename, meshname : String);
  var I : Integer;
  begin
    // Find the right mesh item to assign the skin to
    for I :=0 to Weapon.header.numMeshes-1 do
    begin
      // check it the two names are the same
      if UpperCase(CharArrToStr(Weapon.meshes[i].MeshHeader.Name)) = Uppercase(meshname) then
      begin
        LoadTexture(ImageName, Weapon.meshes[i].Texture, FALSE);
        Weapon.meshes[i].SetTexture :=TRUE;
      end;
    end;
  end;

begin
  Weapon.LoadModel('model\railgun\railgun.md3');

  LoadMeshTexture('model\railgun\railgun1.jpg',      'w_railgun1');
  LoadMeshTexture('model\railgun\railgun2.glow.jpg', 'w_railgun2');
  LoadMeshTexture('model\railgun\railgun4.jpg',      'w_railgun4');
  LoadMeshTexture('model\railgun\railgun3.glow.jpg', 'w_railgun3');
  LoadMeshTexture('model\railgun\railgun1.jpg',      'w_railgun05');

  Player.Upper.LinkModel('tag_weapon', Weapon);
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

  glTranslatef(0.0, -10.0, Depth);

  glRotatef(xRot, 1, 0, 0);
  glRotatef(yRot, 0, 0, 1);

  Player.Draw(ElapsedTime/1000);
  if ShowFrames then
    DrawCurrentFrames;
end;


{------------------------------------------------------------------}
{  Initialise OpenGL                                               }
{------------------------------------------------------------------}
procedure glInit();
begin
  glClearColor(0.0, 0.0, 0.0, 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

  glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);   //Realy Nice perspective calculations

  glEnable(GL_TEXTURE_2D);                     // Enable Texture Mapping

  xRot :=-90;
  yRot :=-85;
  Depth :=-100;

  ShowFrames :=TRUE;
  BuildFont();

  Player.LoadPlayer('model\sarge\', 'default');
  LoadRailgun;
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, 500.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[Ord('F')] then       // Show the current upper and lower frames
  begin
    ShowFrames :=Not(ShowFrames);
    keys[Ord('F')] :=FALSE;
  end;

  if keys[Ord('W')] then       // Enable and Disable wireframe mode
  begin
    WireFrame :=Not(WireFrame);
    if WireFrame then
    begin
      glDisable(GL_TEXTURE_2D);
      glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    end
    else
    begin
      glEnable(GL_TEXTURE_2D);
      glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    end;
    keys[Ord('W')] :=FALSE;
  end;

  if (keys[VK_SPACE]) then      // Reset Position to default
  begin
    Player.animLower :=LEGS_WALK;
    Player.animUpper :=TORSO_STAND;
    Player.SetAnim(Player.animLower);
    Player.SetAnim(Player.animUpper);
  end;

  if keys[Ord('Z')] then       // Go to next leg movement
  begin
    Inc(Player.animLower);
    if (Player.animLower > BOTH_DEAD3) AND (Player.animLower < LEGS_WALKCR) then
    begin
       Player.animLower := LEGS_WALKCR;
       Player.animUpper := TORSO_STAND;
       Player.SetAnim(Player.animUpper);
    end;
    if Player.animLower > LEGS_TURN then
       Player.animLower :=BOTH_DEATH1;
    Player.SetAnim(Player.animLower);
    keys[Ord('Z')] :=FALSE;
  end;

  if keys[Ord('X')] then      // go to previous leg movement
  begin
    Dec(Player.animLower);
    if (Player.animLower > BOTH_DEAD3) AND (Player.animLower < LEGS_WALKCR) then
       Player.animLower := BOTH_DEAD3;
    if Player.animLower < BOTH_DEATH1 then
       Player.animLower :=LEGS_TURN;
    Player.SetAnim(Player.animLower);
    keys[Ord('X')] :=FALSE;
  end;

  if keys[Ord('A')] then      // go to next torso movement
  begin
    Inc(Player.animUpper);
    if Player.animUpper > TORSO_STAND2 then
       Player.animUpper :=TORSO_GESTURE;
    Player.SetAnim(Player.animUpper);
    keys[Ord('A')] :=FALSE;
  end;

  if keys[Ord('S')] then      // go to previous torso movement
  begin
    Dec(Player.animUpper);
    if Player.animUpper < TORSO_GESTURE then
       Player.animUpper :=TORSO_STAND2;
    Player.SetAnim(Player.animUpper);
    keys[Ord('S')] :=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 + -