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

📄 cgobject.pas

📁 一款RPG游戏的引擎可以自己制作一款RPG游戏的引擎可以自己制作
💻 PAS
📖 第 1 页 / 共 2 页
字号:
unit CgObject;

{ CgLib: 3D object structures.
  Version 1.0
  (c) 1998-2000 Tom Nuydens. Use at your own risk. See cglib.txt for details. }

interface

uses
  Classes, DArrays, CgTypes, CgMaterials, CgTexture;

type
  TCGVertexArray = class(TDArray)
  public
    constructor Create; override;
    function GetVertex(i: Integer): TCGVertex;
    procedure SetVertex(i: Integer; vertex: TCGVertex);
    property Items[i: Integer]: TCGVertex read GetVertex write SetVertex; default;
    function VertexPtr(i: Integer): PCGVertex;
  end;

  TCGObject = class;  // Forward declaration to allow for the following event type:
  TCGAddFaceEvent = procedure(o: TCGObject; f: TCGFace; i: Integer);
  
  TCGFaceArray = class(TDArray)
  protected
    OnAddFace: TCGAddFaceEvent;
    Parent: TCGObject;
  public
    constructor Create; override;
    function GetFace(i: Integer): TCGFace;
    procedure SetFace(i: Integer; Face: TCGFace);
    property Items[i: Integer]: TCGFace read GetFace write SetFace; default;
    function FacePtr(i: Integer): PCGFace;
  end;

  TCGVectorArray = class(TDArray)
  public
    constructor Create; override;
    function GetVector(i: Integer): TCGVector;
    procedure SetVector(i: Integer; Vector: TCGVector);
    property Items[i: Integer]: TCGVector read GetVector write SetVector; default;
    function VectorPtr(i: Integer): PCGVector;
  end;

  TCGObject = class(TObject)
  private
    FDisplayList: Cardinal;
  public
    Name: String[32];             // Name of object.
    Vertices: TCGVertexArray;
    Faces: TCGFaceArray;
    Normals: TCGVectorArray;      // Face normals.
    Origin: TCGVector;            // Object origin.
    LocalTransform: TCGMatrix;    // Local transformation matrix for object.
    MatLib: TCGMaterialLib;       // Points to material library for this object.
    TexLib: TCGTextureLib;        // Points to texture library for this object.
    constructor Create;
    destructor Destroy; override;
    procedure Render;
    procedure MakeDisplayList;    // Create a display list that draws the object.
    procedure CallDisplayList;    // Draw the object by calling its display list.
    procedure LoadFromFile(filename: String);
    procedure LoadFromStream(s: TStream);
    procedure SaveToFile(filename: String);
    procedure SaveToStream(s: TStream);
  end;
  // CGO File format header:
  TCGObjectHeader = record
    Name: String[32];
    Origin: TCGVector;
    LocalTransform: TCGMatrix;
    VertCount: Integer;
    FaceCount: Integer;
    HasNormals: Boolean;
    Filler: array [1..131] of Byte;
  end;

const
  CG_NO_MATERIAL = -1;  // Face has no material library index.
  CG_NO_TEXTURE  = -1;  // Face has no texture library index.

function cgCube(s: Single): TCGObject;
function cgCone(r, height: Single; segs: Integer): TCGObject;

implementation

uses
  GL, Glut, CgGeometry, SysUtils;

{******************************************************************************}
{ TCGVERTEXARRAY IMPLEMENTATION                                                }
{******************************************************************************}

constructor TCGVertexArray.Create;
begin

  // Create a TDArray of vertices.
  inherited Create;
  FItemSize := SizeOf(TCGVertex);

end;

function TCGVertexArray.GetVertex(i: Integer): TCGVertex;
begin

  // Guess what this does...
  GetItem(i, Result);

end;

procedure TCGVertexArray.SetVertex(i: Integer; vertex: TCGVertex);
begin

  // Why am I writing comments for this???
  SetItem(i, vertex);

end;

function TCGVertexArray.VertexPtr(i: Integer): PCGVertex;
begin

  // Return a pointer to one of the vertices.
  Result := Pointer(Integer(Data) + (i * ItemSize));

end;

{******************************************************************************}
{ TCGFACEARRAY IMPLEMENTATION                                                }
{******************************************************************************}

constructor TCGFaceArray.Create;
begin

  // Create a TDArray of faces.
  inherited Create;
  FItemSize := SizeOf(TCGFace);

end;

function TCGFaceArray.GetFace(i: Integer): TCGFace;
begin

  // TO DO: Write some profound comment for this method.
  GetItem(i, Result);

end;

procedure TCGFaceArray.SetFace(i: Integer; Face: TCGFace);
begin

  // Tip of the day: You don't need to call this method to add faces to your array.
  SetItem(i, Face);
  OnAddFace(Parent, Face, i);

end;

function TCGFaceArray.FacePtr(i: Integer): PCGFace;
begin

  // Return a pointer to a face.
  Result := Pointer(Integer(Data) + (i * ItemSize));

end;

{******************************************************************************}
{ TCGVECTORARRAY IMPLEMENTATION                                                }
{******************************************************************************}

constructor TCGVectorArray.Create;
begin

  // Create an array of vectors.
  inherited Create;
  FItemSize := SizeOf(TCGVector);

end;

function TCGVectorArray.GetVector(i: Integer): TCGVector;
begin

  // I'm very disciplined about this: _every_ routine should be commented!
  GetItem(i, Result);

end;

procedure TCGVectorArray.SetVector(i: Integer; Vector: TCGVector);
begin

  // You've seen enough TDArray descendants in CgLib to know what this does.
  SetItem(i, Vector);

end;

function TCGVectorArray.VectorPtr(i: Integer): PCGVector;
begin

  // Return a pointer to a vector.
  Result := Pointer(Integer(Data) + (i * ItemSize));

end;

{******************************************************************************}
{ OBJECT RENDERING COMMANDS                                                    }
{******************************************************************************}

{ The following procedure exists only because in the future, when rendering 3D
  objects from within a TCGScene class, several objects might need to be aware
  of eachother (for collision detection or whatever). The way an object is
  rendered might be dependent on the state of other objects. For this reason,
  the rendering procedure cannot be made local to TCGObject. This procedure
  should never be called by the user, as it may disappear or drastically change
  behaviour due to changes to TCGScene. }

procedure cgRenderObject(obj: TCGObject);
var
  f: Integer;
begin

  // Render object.
  with obj do
  begin
    if Faces.Count > 0 then
    begin
      glPushAttrib(GL_ALL_ATTRIB_BITS);
      glPushMatrix;
        // Apply local transformation.
        glTranslatef(Origin.x, Origin.y, Origin.z);
        glMultMatrixf(@LocalTransform);
        // Draw faces.
        glBegin(GL_TRIANGLES);
          for f := 0 to Faces.Count - 1 do
          begin
            glNormal3fv(@Normals.VectorPtr(f)^.x);
            // Set material and texture.
            if Faces[f].Material <> CG_NO_MATERIAL then
              cgApplyMaterial(MatLib[Faces[f].Material])
            else CgApplyMaterial(cgDefaultMaterial);
            if Faces[f].Texture <> CG_NO_TEXTURE then
                TexLib[Faces[f].Texture].Enable;
            // Set color and texture coordinates, then draw vertex.
            glColor4ubv(@Vertices.VertexPtr(Faces[f].A)^.Color);
            glTexCoord2f(Vertices[Faces[f].A].u, Vertices[Faces[f].A].v);
            glVertex3fv(@Vertices.VertexPtr(Faces[f].A)^.p);

            glColor4ubv(@Vertices.VertexPtr(Faces[f].B)^.Color);
            glTexCoord2f(Vertices[Faces[f].B].u, Vertices[Faces[f].B].v);
            glVertex3fv(@Vertices.VertexPtr(Faces[f].B)^.p);

            glColor4ubv(@Vertices.VertexPtr(Faces[f].C)^.Color);
            glTexCoord2f(Vertices[Faces[f].C].u, Vertices[Faces[f].C].v);
            glVertex3fv(@Vertices.VertexPtr(Faces[f].C)^.p);
            if Faces[f].Texture <> CG_NO_TEXTURE then
                TexLib[Faces[f].Texture].Disable;
          end;
        glEnd;
      glPopMatrix;

⌨️ 快捷键说明

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