📄 cgscene.pas
字号:
LocalTransform := Items[i].LocalTransform;
Vertices.Count := Items[i].Vertices.Count;
CopyMemory(Vertices.Data, Items[i].Vertices.Data, Vertices.Count * SizeOf(TCGVertex));
Faces.Count := Items[i].Faces.Count;
CopyMemory(Faces.Data, Items[i].Faces.Data, Faces.Count * SizeOf(TCGFace));
end;
end;
{******************************************************************************}
{ TCGSCENE }
{******************************************************************************}
constructor TCGScene.Create;
var
i: Integer;
begin
inherited Create;
Objects := TCGObjectArray.Create;
for i := 0 to 7 do Lights[i] := TCGLight.Create(GL_LIGHT0 + i);
Materials := TCGMaterialLib.Create;
Textures := TCGTextureLib.Create;
Fog := TCGFog.Create;
LightModel := TCGLightModel.Create;
FillChar(ViewingVolume, SizeOf(ViewingVolume), 0);
end;
destructor TCGScene.Destroy;
var
i: Integer;
begin
Objects.Free;
for i := 0 to 7 do Lights[i].Free;
Materials.Free;
Textures.Free;
Fog.Free;
LightModel.Free;
inherited Destroy;
end;
function TCGScene.NewObject: Integer;
var
i: Integer;
begin
{ You can use this instead of manually calling a new object's constructor. This
way, the object is automatically linked to the scene's material and texture
libraries. Note: the return value is the index of the object created, so you
could create an object and immediately start working on it by calling
with myScene.Objects[myScene.NewObject] do
begin
...
end;
This might be practical in scenes that create a lot of objects at runtime. }
i := Objects.Count;
Objects[i] := TCGObject.Create;
with Objects[i] do
begin
MatLib := Materials;
TexLib := Textures;
end;
Result := i;
end;
procedure TCGScene.Render;
var
i: Integer;
begin
{ This may become slightly more complex in the future, as I intend to add
several rendering modes, maybe on a per-object basis, even. }
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
// Don't set viewing volume if it isn't valid.
with ViewingVolume do
begin
if (FOV > cgPrecision) and (Aspect > cgPrecision) and (zNear < zFar) and
(zNear > 0) then cgSetPerspective(ViewingVolume);
end;
// Test the camera before setting it.
with Camera do
begin
if (not cgVectorComp(Up, cgOrigin)) and (not cgVectorComp(Pos, Target)) then
cgSetCamera(Camera);
end;
glMatrixMode(GL_MODELVIEW);
glLoadIdentity;
for i := 0 to Objects.Count - 1 do Objects[i].Render;
glFinish;
end;
{******************************************************************************}
{ TCGSCENE FILE SUPPORT }
{******************************************************************************}
const
CG_CHUNK_LIGHTMODEL = 0;
CG_CHUNK_FOG = 1;
CG_CHUNK_LIGHT = 2;
CG_CHUNK_OBJECT = 3;
CG_CHUNK_MATLIB = 4;
CG_CHUNK_TEXLIB = 5;
CG_CHUNK_CAMERA = 6;
CG_CHUNK_VIEWING_VOL = 7;
// Etc.
procedure TCGScene.SaveToFile(filename: String);
var
s: TFileStream;
hdr: TCGSceneHeader;
chdr: TCGSChunkHeader;
clmodel: TCGSLightModelChunk;
cfog: TCGSFogChunk;
clight: TCGSLightChunk;
i: Integer;
begin
s := TFileStream.Create(filename, fmCreate or fmShareDenyWrite);
// HEADER:
FillChar(hdr, SizeOf(hdr), 0);
hdr.Version := CG_CURRENT_VERSION;
hdr.Name := Name;
s.Write(hdr, SizeOf(hdr));
// LIGHTMODEL:
chdr := CG_CHUNK_LIGHTMODEL;
s.Write(chdr, SizeOf(chdr));
FillChar(clmodel, SizeOf(clmodel), 0);
with clmodel do
begin
Ambient := LightModel.Ambient;
LocalViewer := LightModel.LocalViewer;
TwoSided := LightModel.TwoSided;
end;
s.Write(clmodel, SizeOf(clmodel));
// FOG:
chdr := CG_CHUNK_FOG;
s.Write(chdr, SizeOf(chdr));
FillChar(cfog, SizeOf(cfog), 0);
with cfog do
begin
Mode := Fog.Mode;
Density := Fog.Density;
FogStart := Fog.FogStart;
FogEnd := Fog.FogEnd;
Color := Fog.Color;
Enabled := glIsEnabled(GL_FOG) = GL_TRUE;
end;
s.Write(cfog, SizeOf(cfog));
// LIGHTS:
chdr := CG_CHUNK_LIGHT;
s.Write(chdr, SizeOf(chdr));
for i := 0 to 7 do
begin
FillChar(clight, SizeOf(clight), 0);
with clight do
begin
Index := i;
Ambient := Lights[i].Ambient;
Diffuse := Lights[i].Diffuse;
Specular := Lights[i].Specular;
Position := Lights[i].Position;
SpotDirection := Lights[i].SpotDirection;
SpotExponent := Lights[i].SpotExponent;
SpotCutoff := Lights[i].SpotCutOff;
ConstAtt := Lights[i].ConstAtt;
LinearAtt := Lights[i].LinearAtt;
QuadraticAtt := Lights[i].QuadraticAtt;
Infinite := Lights[i].Infinite;
Enabled := glIsEnabled(GL_LIGHT0 + i) = GL_TRUE;
end;
s.Write(clight, SizeOf(clight));
end;
// MATERIAL LIBRARY:
chdr := CG_CHUNK_MATLIB;
s.Write(chdr, SizeOf(chdr));
Materials.SaveToStream(s);
// TEXTURE LIBRARY:
chdr := CG_CHUNK_TEXLIB;
s.Write(chdr, SizeOf(chdr));
Textures.SaveToStream(s);
// CAMERA:
chdr := CG_CHUNK_CAMERA;
s.Write(chdr, SizeOf(chdr));
s.Write(Camera, SizeOf(Camera));
// VIEWING VOLUME:
chdr := CG_CHUNK_CAMERA;
s.Write(chdr, SizeOf(chdr));
s.Write(ViewingVolume, SizeOf(Camera));
// OBJECTS:
chdr := CG_CHUNK_OBJECT;
s.Write(chdr, SizeOf(chdr));
s.Write(Objects.Count, SizeOf(Integer));
for i := 0 to Objects.Count - 1 do Objects[i].SaveToStream(s);
s.Free;
end;
procedure TCGScene.LoadFromFile(filename: String);
var
s: TFileStream;
hdr: TCGSceneHeader;
chdr: TCGSChunkHeader;
clmodel: TCGSLightModelChunk;
cfog: TCGSFogChunk;
clight: TCGSLightChunk;
i: Integer;
begin
s := TFileStream.Create(filename, fmOpenRead or fmShareDenyWrite);
// HEADER:
s.Read(hdr, SizeOf(hdr));
if not cgIsVersion(hdr.Version[0], hdr.Version[1]) then
raise ECGException.CreateFmt('Scene file version invalid: %d.%d',
[hdr.Version[0], hdr.Version[1]]);
Name := hdr.Name;
while s.Position < s.Size do
begin
// Read chunk header.
s.Read(chdr, SizeOf(chdr));
case chdr of
CG_CHUNK_LIGHTMODEL: begin
s.Read(clmodel, SizeOf(clmodel));
with LightModel do
begin
Ambient := clmodel.Ambient;
LocalViewer := clmodel.LocalViewer;
TwoSided := clmodel.TwoSided;
end;
end;
CG_CHUNK_FOG: begin
s.Read(cfog, SizeOf(cfog));
with Fog do
begin
Mode := cfog.Mode;
Density := cfog.Density;
FogStart := cfog.FogStart;
FogEnd := cfog.FogEnd;
Color := cfog.Color;
if cfog.Enabled then Enable else Disable;
end;
end;
CG_CHUNK_LIGHT: begin
for i := 0 to 7 do
begin
s.Read(clight, SizeOf(clight));
with Lights[clight.Index] do
begin
Ambient := clight.Ambient;
Diffuse := clight.Diffuse;
Specular := clight.Specular;
Position := clight.Position;
SpotDirection := clight.SpotDirection;
SpotExponent := clight.SpotExponent;
SpotCutoff := clight.SpotCutOff;
ConstAtt := clight.ConstAtt;
LinearAtt := clight.LinearAtt;
QuadraticAtt := clight.QuadraticAtt;
Infinite := clight.Infinite;
if clight.Enabled then Enable else Disable;
end;
end;
end;
CG_CHUNK_CAMERA: begin
s.Read(Camera, SizeOf(Camera));
end;
CG_CHUNK_VIEWING_VOL: begin
s.Read(ViewingVolume, SizeOf(ViewingVolume));
end;
CG_CHUNK_OBJECT: begin
s.Read(i, SizeOf(i));
Objects.Count := i;
for i := 0 to Objects.Count - 1 do Objects[i].LoadFromStream(s);
end;
CG_CHUNK_MATLIB: Materials.LoadFromStream(s);
CG_CHUNK_TEXLIB: Textures.LoadFromStream(s);
end;
end;
s.Free;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -