2
Copyright 2003-2013 Michalis Kamburelis.
4
This file is part of "Castle Game Engine".
6
"Castle Game Engine" is free software; see the file COPYING.txt,
7
included in this distribution, for details about the copyright.
9
"Castle Game Engine" is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
----------------------------------------------------------------------------
16
{ Demo of fog culling. When rendering with fog turned "on" (the default),
17
we do not render objects outside of the fog visibility radius.
18
This can make a hude speedup if you have dense fog and exterior-like level
19
(where frustum culing leaves too many shapes visible).
21
This always loads models/fog_culling_final.x3dv X3D file.
22
Be sure to run it with proper current directory (examples/3d_rendering_processing/).
23
It's a crafted scene, with some green and dense fog and a lot of
24
spheres scattered around. Fog culling will work best on it.
27
'f' turns fog culling on/off
33
uses SysUtils, CastleVectors, GL, GLU, CastleWindow, CastleStringUtils,
34
CastleClassUtils, CastleUtils, Classes, CastleWarnings,
35
CastleGLUtils, X3DNodes, CastleSceneCore, CastleScene,
36
CastleProgress, CastleProgressConsole, CastleFilesUtils, Castle3D,
37
CastleSceneManager, CastleParameters, CastleRenderingCamera, CastleKeysMouse;
40
Window: TCastleWindowCustom;
44
TMySceneManager = class(TCastleSceneManager)
46
function TestFogVisibility(Shape: TGLShape): boolean;
48
procedure Render3D(const Params: TRenderParams); override;
49
procedure RenderFromViewEverything; override;
53
SceneManager: TMySceneManager;
55
function TMySceneManager.TestFogVisibility(Shape: TGLShape): boolean;
57
{ Test for collision between two spheres.
58
1st is the bounding sphere of Shape.
59
2nd is the sphere around current camera position,
60
with the radius taken from fog scaled visibilityRadius.
61
If there is no collision than we don't have to render given Shape. }
62
Result := PointsDistanceSqr(Shape.BoundingSphereCenter, Camera.GetPosition) <=
63
Sqr(Scene.FogStack.Top.FdVisibilityRange.Value *
64
Scene.FogStack.Top.TransformScale +
65
Sqrt(Shape.BoundingSphereRadiusSqr));
69
FogCulling: boolean = true;
71
procedure TMySceneManager.Render3D(const Params: TRenderParams);
74
Scene.Render(@TestFogVisibility, RenderingCamera.Frustum, Params) else
78
procedure TMySceneManager.RenderFromViewEverything;
81
Writeln(Format('Rendered Shapes: %d / %d (fog culling: %s)',
82
[ Statistics.ShapesRendered, Statistics.ShapesVisible,
83
BoolToStr[FogCulling] ]));
86
procedure Open(Window: TCastleWindowBase);
88
{ We use quite large triangles for fog_culling level demo wall.
89
This means that fog must be correctly rendered,
90
with perspective correction hint, otherwise ugly artifacts
92
glHint(GL_FOG_HINT, GL_NICEST);
95
procedure Press(Window: TCastleWindowBase; const Event: TInputPressRelease);
99
if Event.IsKey(K_F) then
101
FogCulling := not FogCulling;
103
{ Also, turn on/off actual fog on the model (if any).
104
We do it by changing Fog.VisibilityRange (0 means no fog). }
105
FogNode := Scene.FogStack.Top as TFogNode;
106
if FogNode <> nil then
108
FogNode.FdVisibilityRange.Send(30) else
109
FogNode.FdVisibilityRange.Send(0);
111
Window.PostRedisplay;
116
Parameters.CheckHigh(0);
118
Window := TCastleWindowCustom.Create(Application);
120
SceneManager := TMySceneManager.Create(Application);
121
Window.Controls.Add(SceneManager);
123
Scene := TCastleScene.Create(Application);
124
OnWarning := @OnWarningWrite;
125
Scene.Load('models' + PathDelim + 'fog_culling_final.x3dv');
126
SceneManager.MainScene := Scene;
127
SceneManager.Items.Add(Scene);
129
Writeln(Scene.Info(true, true, false));
132
Progress.UserInterface := ProgressConsoleInterface;
133
Scene.TriangleOctreeProgressTitle := 'Building triangle octree';
134
Scene.ShapeOctreeProgressTitle := 'Building Shape octree';
135
Scene.Spatial := [ssRendering, ssDynamicCollisions];
137
Window.OnOpen := @Open;
138
Window.OnPress := @Press;
139
Window.SetDemoOptions(K_F11, CharEscape, true);