📄 cgobject.pas
字号:
glPopAttrib;
end;
end;
end;
{******************************************************************************}
{ TCGOBJECT IMPLEMENTATION }
{******************************************************************************}
procedure cgObjectAddFace(o: TCGObject; f: TCGFace; i: Integer);
begin
{ This is executed when a face is added to the object. This is to make sure
the normal is calculated automatically. }
with o do
begin
Normals.Count := Normals.Count + 1;
Normals[i] := cgGetNormal(Vertices[f.A].p,
Vertices[f.B].p,
Vertices[f.C].p);
end;
end;
constructor TCGObject.Create;
begin
// Create new 3D object.
inherited Create;
Vertices := TCGVertexArray.Create;
Faces := TCGFaceArray.Create;
Faces.Parent := Self;
Faces.OnAddFace := cgObjectAddFace;
Normals := TCGVectorArray.Create;
FDisplayList := 0;
Origin := cgOrigin;
LocalTransform := cgIdentity;
end;
destructor TCGObject.Destroy;
begin
// Free vertex, face and normal arrays first.
Vertices.Free;
Faces.Free;
Normals.Free;
inherited Destroy;
end;
procedure TCGObject.Render;
begin
// Just call the rendering routine implemented above.
cgRenderObject(Self);
end;
procedure TCGObject.MakeDisplayList;
begin
// Create a display list to render the object.
FDisplayList := glGenLists(1);
glNewList(FDisplayList, GL_COMPILE);
Render;
glEndList;
end;
procedure TCGObject.CallDisplayList;
begin
// If one has been created, call the display list.
if glIsList(FDisplayList) = GL_TRUE then glCallList(FDisplayList);
end;
procedure TCGObject.LoadFromFile(filename: String);
var
f: File;
hdr: TCGObjectHeader;
begin
// Load object from a .CGO file.
AssignFile(f, filename);
Reset(f, 1);
BlockRead(f, hdr, SizeOf(hdr));
Vertices.Count := hdr.VertCount;
BlockRead(f, Vertices.Data^, Vertices.ItemSize * hdr.VertCount);
Faces.Count := hdr.FaceCount;
BlockRead(f, Faces.Data^, Faces.ItemSize * hdr.FaceCount);
if hdr.HasNormals then
begin
Normals.Count := hdr.FaceCount;
BlockRead(f, Normals.Data^, Normals.ItemSize * hdr.FaceCount);
end;
Name := hdr.Name;
Origin := hdr.Origin;
LocalTransform := hdr.LocalTransform;
CloseFile(f);
end;
procedure TCGObject.LoadFromStream(s: TStream);
var
hdr: TCGObjectHeader;
begin
// Load object from stream.
s.Read(hdr, SizeOf(hdr));
Vertices.Count := hdr.VertCount;
s.Read(Vertices.Data^, Vertices.ItemSize * hdr.VertCount);
Faces.Count := hdr.FaceCount;
s.Read(Faces.Data^, Faces.ItemSize * hdr.FaceCount);
if hdr.HasNormals then
begin
Normals.Count := hdr.FaceCount;
s.Read(Normals.Data^, Normals.ItemSize * hdr.FaceCount);
end;
Name := hdr.Name;
Origin := hdr.Origin;
LocalTransform := hdr.LocalTransform;
end;
procedure TCGObject.SaveToFile(filename: String);
var
f: File;
hdr: TCGObjectHeader;
begin
// Save object to a .CGO file.
AssignFile(f, filename);
Rewrite(f, 1);
FillChar(hdr, SizeOf(hdr), 0);
hdr.Name := Name;
hdr.Origin := Origin;
hdr.LocalTransform := LocalTransform;
hdr.VertCount := Vertices.Count;
hdr.FaceCount := Faces.Count;
hdr.HasNormals := Normals.Count > 0;
BlockWrite(f, hdr, SizeOf(hdr));
BlockWrite(f, Vertices.Data^, Vertices.ItemSize * hdr.VertCount);
BlockWrite(f, Faces.Data^, Faces.ItemSize * hdr.FaceCount);
if hdr.HasNormals then BlockWrite(f, Normals.Data^, Normals.ItemSize * hdr.FaceCount);
CloseFile(f);
end;
procedure TCGObject.SaveToStream(s: TStream);
var
hdr: TCGObjectHeader;
begin
// Save object to a .CGO file.
FillChar(hdr, SizeOf(hdr), 0);
hdr.Name := Name;
hdr.Origin := Origin;
hdr.LocalTransform := LocalTransform;
hdr.VertCount := Vertices.Count;
hdr.FaceCount := Faces.Count;
hdr.HasNormals := Normals.Count > 0;
s.Write(hdr, SizeOf(hdr));
s.Write(Vertices.Data^, Vertices.ItemSize * hdr.VertCount);
s.Write(Faces.Data^, Faces.ItemSize * hdr.FaceCount);
if hdr.HasNormals then s.Write(Normals.Data^, Normals.ItemSize * hdr.FaceCount);
end;
{******************************************************************************}
{ PRIMITIVE CREATION ROUTINES }
{******************************************************************************}
function cgCone(r, height: Single; segs: Integer): TCGObject;
var
i: Integer;
begin
// Create a cone.
Result := TCGObject.Create;
with Result do
begin
Vertices[0] := cgVertex(0, height, 0, cgColorB(255, 255, 255, 255), 0.5, 1);
Vertices[1] := cgVertex(0, 0, r, cgColorB(255, 255, 255, 255), 0, 0);
for i := 2 to segs do
begin
Vertices[i] := Vertices[i-1];
cgRotateY(Vertices.VertexPtr(i)^.p, 2*pi/segs);
if i <> segs then Vertices.VertexPtr(i)^.u := 1 / (segs - i);
end;
Vertices[segs+1] := cgVertex(0, 0, 0, cgColorB(255, 255, 255, 255), 0.5, 0.5);
for i := 0 to segs-1 do
begin
Faces[i] := cgFace(0, 1+(i+1) mod segs, 1+(i+2) mod segs, CG_NO_MATERIAL, CG_NO_TEXTURE);
Faces[i + segs] := cgFace(1+(i+2) mod segs, 1+(i+1) mod segs, segs+1, CG_NO_MATERIAL, CG_NO_TEXTURE);
end;
end;
end;
function cgCube(s: Single): TCGObject;
begin
Result := TCGObject.Create;
s := s / 2;
with Result do
begin
// Front face:
Vertices[0] := cgVertex(-s, -s, s, cgColorB(255, 255, 255, 255), 0, 0);
Vertices[1] := cgVertex(s, -s, s, cgColorB(255, 255, 255, 255), 1, 0);
Vertices[2] := cgVertex(s, s, s, cgColorB(255, 255, 255, 255), 1, 1);
Vertices[3] := cgVertex(-s, s, s, cgColorB(255, 255, 255, 255), 0, 1);
Faces[0] := cgFace(0, 1, 2, CG_NO_MATERIAL, CG_NO_TEXTURE);
Faces[1] := cgFace(2, 3, 0, CG_NO_MATERIAL, CG_NO_TEXTURE);
// Back face:
Vertices[4] := cgVertex(s, -s, -s, cgColorB(255, 255, 255, 255), 0, 0);
Vertices[5] := cgVertex(-s, -s, -s, cgColorB(255, 255, 255, 255), 1, 0);
Vertices[6] := cgVertex(-s, s, -s, cgColorB(255, 255, 255, 255), 1, 1);
Vertices[7] := cgVertex(s, s, -s, cgColorB(255, 255, 255, 255), 0, 1);
Faces[2] := cgFace(4, 5, 6, CG_NO_MATERIAL, CG_NO_TEXTURE);
Faces[3] := cgFace(6, 7, 4, CG_NO_MATERIAL, CG_NO_TEXTURE);
// Top face:
Vertices[8] := cgVertex(-s, s, s, cgColorB(255, 255, 255, 255), 0, 0);
Vertices[9] := cgVertex(s, s, s, cgColorB(255, 255, 255, 255), 1, 0);
Vertices[10] := cgVertex(s, s, -s, cgColorB(255, 255, 255, 255), 1, 1);
Vertices[11] := cgVertex(-s, s, -s, cgColorB(255, 255, 255, 255), 0, 1);
Faces[4] := cgFace(8, 9, 10, CG_NO_MATERIAL, CG_NO_TEXTURE);
Faces[5] := cgFace(10, 11, 8, CG_NO_MATERIAL, CG_NO_TEXTURE);
// Bottom face:
Vertices[12] := cgVertex(-s, -s, -s, cgColorB(255, 255, 255, 255), 0, 0);
Vertices[13] := cgVertex(s, -s, -s, cgColorB(255, 255, 255, 255), 1, 0);
Vertices[14] := cgVertex(s, -s, s, cgColorB(255, 255, 255, 255), 1, 1);
Vertices[15] := cgVertex(-s, -s, s, cgColorB(255, 255, 255, 255), 0, 1);
Faces[6] := cgFace(12, 13, 14, CG_NO_MATERIAL, CG_NO_TEXTURE);
Faces[7] := cgFace(14, 15, 12, CG_NO_MATERIAL, CG_NO_TEXTURE);
// Left face:
Vertices[16] := cgVertex(s, -s, -s, cgColorB(255, 255, 255, 255), 0, 0);
Vertices[17] := cgVertex(s, -s, s, cgColorB(255, 255, 255, 255), 1, 0);
Vertices[18] := cgVertex(s, s, s, cgColorB(255, 255, 255, 255), 1, 1);
Vertices[19] := cgVertex(s, s, -s, cgColorB(255, 255, 255, 255), 0, 1);
Faces[8] := cgFace(18, 17, 16, CG_NO_MATERIAL, CG_NO_TEXTURE);
Faces[9] := cgFace(16, 19, 18, CG_NO_MATERIAL, CG_NO_TEXTURE);
// Right face:
Vertices[20] := cgVertex(-s, -s, s, cgColorB(255, 255, 255, 255), 0, 0);
Vertices[21] := cgVertex(-s, -s, -s, cgColorB(255, 255, 255, 255), 1, 0);
Vertices[22] := cgVertex(-s, s, -s, cgColorB(255, 255, 255, 255), 1, 1);
Vertices[23] := cgVertex(-s, s, s, cgColorB(255, 255, 255, 255), 0, 1);
Faces[10] := cgFace(22, 21, 20, CG_NO_MATERIAL, CG_NO_TEXTURE);
Faces[11] := cgFace(20, 23, 22, CG_NO_MATERIAL, CG_NO_TEXTURE);
end;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -