2
// This unit is part of the GLScene Engine https://github.com/glscene
5
A TGLImmaterialSceneObject drawing 6 quads (plus another quad as "Cloud" plane)
6
for use as a skybox always centered on the camera.
9
16/03/11 - Yar - Fixes after emergence of GLMaterialEx
10
23/08/10 - Yar - Added OpenGLTokens to uses, replaced OpenGL1x functions to OpenGLAdapter
11
22/04/10 - Yar - Fixes after GLState revision
12
05/03/10 - DanB - More state added to TGLStateCache
13
26/03/09 - DanB - Skybox is now a TGLCameraInvariantObject
14
10/10/08 - DanB - changed Skybox DoRender to use rci instead
15
of Scene.CurrentGLCamera
16
30/03/07 - DaStr - Added $I GLScene.inc
17
28/03/07 - DaStr - Renamed parameters in some methods
18
(thanks Burkhard Carstens) (Bugtracker ID = 1678658)
19
21/01/07 - DaStr - Added IGLMaterialLibrarySupported support
20
12/04/04 - EG - Added Style property, multipass support
21
27/11/03 - EG - Cleanup and fixes
22
09/11/03 - MRQZZZ - mandatory changes suggested by Eric.
23
02/09/03 - MRQZZZ - Creation
46
TGLSkyBoxStyle = (sbsFull, sbsTopHalf, sbsBottomHalf, sbTopTwoThirds,
51
TGLSkyBox = class(TGLCameraInvariantObject, IGLMaterialLibrarySupported)
55
FMatNameRight: string;
56
FMatNameFront: string;
59
FMatNameBottom: string;
60
FMatNameClouds: string;
61
FMaterialLibrary: TGLMaterialLibrary;
62
FCloudsPlaneOffset: Single;
63
FCloudsPlaneSize: Single;
64
FStyle: TGLSkyBoxStyle;
66
//implementing IGLMaterialLibrarySupported
67
function GetMaterialLibrary: TGLAbstractMaterialLibrary;
70
procedure SetMaterialLibrary(const Value: TGLMaterialLibrary);
71
procedure SetMatNameBack(const Value: string);
72
procedure SetMatNameBottom(const Value: string);
73
procedure SetMatNameFront(const Value: string);
74
procedure SetMatNameLeft(const Value: string);
75
procedure SetMatNameRight(const Value: string);
76
procedure SetMatNameTop(const Value: string);
77
procedure SetMatNameClouds(const Value: string);
78
procedure SetCloudsPlaneOffset(const Value: single);
79
procedure SetCloudsPlaneSize(const Value: single);
80
procedure SetStyle(const value: TGLSkyBoxStyle);
84
constructor Create(AOwner: TComponent); override;
85
destructor Destroy; override;
87
procedure DoRender(var ARci: TGLRenderContextInfo;
88
ARenderSelf, ARenderChildren: Boolean); override;
89
procedure BuildList(var ARci: TGLRenderContextInfo); override;
90
procedure Notification(AComponent: TComponent; Operation: TOperation);
95
property MaterialLibrary: TGLMaterialLibrary read FMaterialLibrary write
97
property MatNameTop: TGLLibMaterialName read FMatNameTop write
99
property MatNameBottom: TGLLibMaterialName read FMatNameBottom write
101
property MatNameLeft: TGLLibMaterialName read FMatNameLeft write
103
property MatNameRight: TGLLibMaterialName read FMatNameRight write
105
property MatNameFront: TGLLibMaterialName read FMatNameFront write
107
property MatNameBack: TGLLibMaterialName read FMatNameBack write
109
property MatNameClouds: TGLLibMaterialName read FMatNameClouds write
111
property CloudsPlaneOffset: Single read FCloudsPlaneOffset write
112
SetCloudsPlaneOffset;
113
property CloudsPlaneSize: Single read FCloudsPlaneSize write
115
property Style: TGLSkyBoxStyle read FStyle write FStyle default sbsFull;
118
// ------------------------------------------------------------------
119
// ------------------------------------------------------------------
120
// ------------------------------------------------------------------
122
// ------------------------------------------------------------------
123
// ------------------------------------------------------------------
124
// ------------------------------------------------------------------
131
// ------------------ TGLSkyBox ------------------
137
constructor TGLSkyBox.Create(AOwner: TComponent);
139
inherited Create(AOwner);
140
CamInvarianceMode := cimPosition;
141
ObjectStyle := ObjectStyle + [osDirectDraw, osNoVisibilityCulling];
142
FCloudsPlaneOffset := 0.2;
143
// this should be set far enough to avoid near plane clipping
144
FCloudsPlaneSize := 32;
145
// the bigger, the more this extends the clouds cap to the horizon
151
destructor TGLSkyBox.Destroy;
159
function TGLSkyBox.GetMaterialLibrary: TGLAbstractMaterialLibrary;
161
Result := FMaterialLibrary;
167
procedure TGLSkyBox.Notification(AComponent: TComponent; Operation: TOperation);
169
if (Operation = opRemove) and (AComponent = FMaterialLibrary) then
170
MaterialLibrary := nil;
177
procedure TGLSkyBox.DoRender(var ARci: TGLRenderContextInfo; ARenderSelf,
178
ARenderChildren: Boolean);
180
// We want children of the sky box to appear far away too
181
// (note: simply not writing to depth buffer may not make this not work,
182
// child objects may need the depth buffer to render themselves properly,
183
// this may require depth buffer cleared after that. - DanB)
184
Arci.GLStates.DepthWriteMask := False;
185
Arci.ignoreDepthRequests := true;
187
Arci.ignoreDepthRequests := False;
192
procedure TGLSkyBox.BuildList(var ARci: TGLRenderContextInfo);
194
f, cps, cof1: Single;
195
oldStates: TGLStates;
196
libMat: TGLLibMaterial;
198
if FMaterialLibrary = nil then
201
with ARci.GLStates do
204
Disable(stDepthTest);
210
f := ARci.rcci.farClippingDistance * 0.5;
216
sbsTopHalf, sbsTopHalfClamped:
218
GL.Translatef(0, 0.5, 0);
219
GL.Scalef(1, 0.5, 1);
223
GL.Translatef(0, -0.5, 0);
224
GL.Scalef(1, 0.5, 1);
228
GL.Translatef(0, 1 / 3, 0);
229
GL.Scalef(1, 2 / 3, 1);
234
libMat := MaterialLibrary.LibMaterialByName(FMatNameFront);
235
if libMat <> nil then
240
xgl.TexCoord2f(0.002, 0.998);
241
GL.Vertex3f(-1, 1, -1);
242
xgl.TexCoord2f(0.002, 0.002);
243
GL.Vertex3f(-1, -1, -1);
244
xgl.TexCoord2f(0.998, 0.002);
245
GL.Vertex3f(1, -1, -1);
246
xgl.TexCoord2f(0.998, 0.998);
247
GL.Vertex3f(1, 1, -1);
248
if Style = sbsTopHalfClamped then
250
xgl.TexCoord2f(0.002, 0.002);
251
GL.Vertex3f(-1, -1, -1);
252
xgl.TexCoord2f(0.002, 0.002);
253
GL.Vertex3f(-1, -3, -1);
254
xgl.TexCoord2f(0.998, 0.002);
255
GL.Vertex3f(1, -3, -1);
256
xgl.TexCoord2f(0.998, 0.002);
257
GL.Vertex3f(1, -1, -1);
260
until not libMat.UnApply(ARci);
263
libMat := MaterialLibrary.LibMaterialByName(FMatNameBack);
264
if libMat <> nil then
269
xgl.TexCoord2f(0.002, 0.998);
270
GL.Vertex3f(1, 1, 1);
271
xgl.TexCoord2f(0.002, 0.002);
272
GL.Vertex3f(1, -1, 1);
273
xgl.TexCoord2f(0.998, 0.002);
274
GL.Vertex3f(-1, -1, 1);
275
xgl.TexCoord2f(0.998, 0.998);
276
GL.Vertex3f(-1, 1, 1);
277
if Style = sbsTopHalfClamped then
279
xgl.TexCoord2f(0.002, 0.002);
280
GL.Vertex3f(1, -1, 1);
281
xgl.TexCoord2f(0.002, 0.002);
282
GL.Vertex3f(1, -3, 1);
283
xgl.TexCoord2f(0.998, 0.002);
284
GL.Vertex3f(-1, -3, 1);
285
xgl.TexCoord2f(0.998, 0.002);
286
GL.Vertex3f(-1, -1, 1);
289
until not libMat.UnApply(ARci);
292
libMat := MaterialLibrary.LibMaterialByName(FMatNameTop);
293
if libMat <> nil then
298
xgl.TexCoord2f(0.002, 0.998);
299
GL.Vertex3f(-1, 1, 1);
300
xgl.TexCoord2f(0.002, 0.002);
301
GL.Vertex3f(-1, 1, -1);
302
xgl.TexCoord2f(0.998, 0.002);
303
GL.Vertex3f(1, 1, -1);
304
xgl.TexCoord2f(0.998, 0.998);
305
GL.Vertex3f(1, 1, 1);
307
until not libMat.UnApply(ARci);
310
libMat := MaterialLibrary.LibMaterialByName(FMatNameBottom);
311
if libMat <> nil then
316
xgl.TexCoord2f(0.002, 0.998);
317
GL.Vertex3f(-1, -1, -1);
318
xgl.TexCoord2f(0.002, 0.002);
319
GL.Vertex3f(-1, -1, 1);
320
xgl.TexCoord2f(0.998, 0.002);
321
GL.Vertex3f(1, -1, 1);
322
xgl.TexCoord2f(0.998, 0.998);
323
GL.Vertex3f(1, -1, -1);
325
until not libMat.UnApply(ARci);
328
libMat := MaterialLibrary.LibMaterialByName(FMatNameLeft);
329
if libMat <> nil then
334
xgl.TexCoord2f(0.002, 0.998);
335
GL.Vertex3f(-1, 1, 1);
336
xgl.TexCoord2f(0.002, 0.002);
337
GL.Vertex3f(-1, -1, 1);
338
xgl.TexCoord2f(0.998, 0.002);
339
GL.Vertex3f(-1, -1, -1);
340
xgl.TexCoord2f(0.998, 0.998);
341
GL.Vertex3f(-1, 1, -1);
342
if Style = sbsTopHalfClamped then
344
xgl.TexCoord2f(0.002, 0.002);
345
GL.Vertex3f(-1, -1, 1);
346
xgl.TexCoord2f(0.002, 0.002);
347
GL.Vertex3f(-1, -3, 1);
348
xgl.TexCoord2f(0.998, 0.002);
349
GL.Vertex3f(-1, -3, -1);
350
xgl.TexCoord2f(0.998, 0.002);
351
GL.Vertex3f(-1, -1, -1);
354
until not libMat.UnApply(ARci);
357
libMat := MaterialLibrary.LibMaterialByName(FMatNameRight);
358
if libMat <> nil then
363
xgl.TexCoord2f(0.002, 0.998);
364
GL.Vertex3f(1, 1, -1);
365
xgl.TexCoord2f(0.002, 0.002);
366
GL.Vertex3f(1, -1, -1);
367
xgl.TexCoord2f(0.998, 0.002);
368
GL.Vertex3f(1, -1, 1);
369
xgl.TexCoord2f(0.998, 0.998);
370
GL.Vertex3f(1, 1, 1);
371
if Style = sbsTopHalfClamped then
373
xgl.TexCoord2f(0.002, 0.002);
374
GL.Vertex3f(1, -1, -1);
375
xgl.TexCoord2f(0.002, 0.002);
376
GL.Vertex3f(1, -3, -1);
377
xgl.TexCoord2f(0.998, 0.002);
378
GL.Vertex3f(1, -3, 1);
379
xgl.TexCoord2f(0.998, 0.002);
380
GL.Vertex3f(1, -1, 1);
383
until not libMat.UnApply(ARci);
386
libMat := MaterialLibrary.LibMaterialByName(FMatNameClouds);
387
if libMat <> nil then
389
// pre-calculate possible values to speed up
390
cps := FCloudsPlaneSize * 0.5;
391
cof1 := FCloudsPlaneOffset;
396
xgl.TexCoord2f(0, 1);
397
GL.Vertex3f(-cps, cof1, cps);
398
xgl.TexCoord2f(0, 0);
399
GL.Vertex3f(-cps, cof1, -cps);
400
xgl.TexCoord2f(1, 0);
401
GL.Vertex3f(cps, cof1, -cps);
402
xgl.TexCoord2f(1, 1);
403
GL.Vertex3f(cps, cof1, cps);
405
until not libMat.UnApply(ARci);
410
if stLighting in oldStates then
411
ARci.GLStates.Enable(stLighting);
412
if stFog in oldStates then
413
ARci.GLStates.Enable(stFog);
414
if stDepthTest in oldStates then
415
ARci.GLStates.Enable(stDepthTest);
421
procedure TGLSkyBox.SetCloudsPlaneOffset(const Value: single);
423
FCloudsPlaneOffset := Value;
427
procedure TGLSkyBox.SetCloudsPlaneSize(const Value: single);
429
FCloudsPlaneSize := Value;
436
procedure TGLSkyBox.SetStyle(const value: TGLSkyBoxStyle);
445
procedure TGLSkyBox.SetMaterialLibrary(const value: TGLMaterialLibrary);
447
FMaterialLibrary := value;
451
procedure TGLSkyBox.SetMatNameBack(const Value: string);
453
FMatNameBack := Value;
457
procedure TGLSkyBox.SetMatNameBottom(const Value: string);
459
FMatNameBottom := Value;
463
procedure TGLSkyBox.SetMatNameClouds(const Value: string);
465
FMatNameClouds := Value;
469
procedure TGLSkyBox.SetMatNameFront(const Value: string);
471
FMatNameFront := Value;
475
procedure TGLSkyBox.SetMatNameLeft(const Value: string);
477
FMatNameLeft := Value;
481
procedure TGLSkyBox.SetMatNameRight(const Value: string);
483
FMatNameRight := Value;
487
procedure TGLSkyBox.SetMatNameTop(const Value: string);
489
FMatNameTop := Value;
493
// ------------------------------------------------------------------
494
// ------------------------------------------------------------------
495
// ------------------------------------------------------------------
497
// ------------------------------------------------------------------
498
// ------------------------------------------------------------------
499
// ------------------------------------------------------------------
501
RegisterClass(TGLSkyBox);