Castle Game Engine: CastleScene: Class TCastleScene

# Class TCastleScene
Description | Hierarchy | Fields | Methods | Properties
## Unit CastleScene ## Declaration `type TCastleScene = class(TCastleSceneCore)` ## Description Complete handling and rendering of a 3D VRML/X3D scene. This is a descendant of TCastleSceneCore that adds efficient rendering using OpenGL. This uses internal TGLRenderer instance, adding some features and comfortable methods on top of it (like blending). See Render method for some details. This class also provides comfortable management for Background instance to render the VRML/X3D background of this scene. Calling methods PrepareResources, Render or Background connects this class with current OpenGL context. Which means that all the following calls should be done with the same OpenGL context set as current. Calling GLContextClose or the destructor removes this connection. ## Hierarchy TComponent T3D TX3DEventsEngine TCastleSceneCore TCastleScene ## Overview ### Methods
| `constructor Create(AOwner: TComponent); override;`
| `constructor CreateCustomCache(AOwner: TComponent; ACache: TGLRendererContextCache);`
| `constructor CreateCustomRenderer(AOwner: TComponent; ACustomRenderer: TGLRenderer);`
| `destructor Destroy; override;`
| `procedure GLContextClose; override;`
| `procedure PrepareResources(Options: TPrepareResourcesOptions; ProgressStep: boolean; BaseLights: TAbstractLightInstancesList); override;`
| `procedure Render(TestShapeVisibility: TTestShapeVisibility; const Frustum: TFrustum; const Params: TRenderParams);`
| `procedure Render(const Frustum: TFrustum; const Params: TRenderParams); override;`
| `procedure BeforeNodesFree(const InternalChangedAll: boolean = false); override;`
| `procedure RenderShadowVolume( ShadowVolumeRenderer: TBaseShadowVolumeRenderer; const ParentTransformIsIdentity: boolean; const ParentTransform: TMatrix4Single); override;`
| `procedure RenderSilhouetteEdges( const ObserverPos: TVector4Single; const Transform: TMatrix4Single);`
| `procedure RenderBorderEdges( const Transform: TMatrix4Single);`
| `function Background: TBackground;`
| `function Attributes: TSceneRenderingAttributes;`
| `procedure UpdateGeneratedTextures( const RenderFunc: TRenderFromViewFunction; const ProjectionNear, ProjectionFar: Single; const OriginalViewportX, OriginalViewportY: LongInt; const OriginalViewportWidth, OriginalViewportHeight: Cardinal); override;`
| `procedure ViewChangedSuddenly; override;`
| `procedure VisibleChangeNotification(const Changes: TVisibleChanges); override;`
| `function ScreenEffects(Index: Integer): TGLSLProgram;`
| `function ScreenEffectsCount: Integer;`
| `function ScreenEffectsNeedDepth: boolean;`
### Properties
| `property BackgroundSkySphereRadius: Single read FBackgroundSkySphereRadius write SetBackgroundSkySphereRadius default 1;`
| `property FrustumCulling: TFrustumCulling read FFrustumCulling write SetFrustumCulling default fcBox;`
| `property OctreeFrustumCulling: TFrustumCulling read FOctreeFrustumCulling write SetOctreeFrustumCulling default fcBox;`
| `property ReceiveShadowVolumes: boolean read FReceiveShadowVolumes write FReceiveShadowVolumes default true;`
## Description ### Methods
| `constructor Create(AOwner: TComponent); override;`
| `constructor CreateCustomCache(AOwner: TComponent; ACache: TGLRendererContextCache);`
| `constructor CreateCustomRenderer(AOwner: TComponent; ACustomRenderer: TGLRenderer);`
A very special constructor, that forces this class to use provided ACustomRenderer. ACustomRenderer must be <> `Nil`. Note that this renderer must be created with AttributesClass = TSceneRenderingAttributes. Don't use this unless you really know what you're doing! In all normal circumstances you should use normal Create constructor, that will internally create and use internal renderer object. If you use this constructor you will have to understand how internally this class synchronizes itself with underlying Renderer object. Once again, if you're not sure, then simply don't use this constructor. It's for internal use — namely it's internally used by TCastlePrecalculatedAnimation, this way all scenes of the animation share the same renderer which means that they also share the same information about textures and images loaded into OpenGL. And this is crucial for TCastlePrecalculatedAnimation, otherwise animation with 100 scenes would load the same texture to OpenGL 100 times.
| `destructor Destroy; override;`
| `procedure GLContextClose; override;`
Destroy any associations of this object with current OpenGL context. For example, release any allocated texture names. Generally speaking, destroys everything that is allocated by PrepareResources call. It's harmless to call this method when there are already no associations with current OpenGL context. This is called automatically from the destructor.
| `procedure PrepareResources(Options: TPrepareResourcesOptions; ProgressStep: boolean; BaseLights: TAbstractLightInstancesList); override;`
| `procedure Render(TestShapeVisibility: TTestShapeVisibility; const Frustum: TFrustum; const Params: TRenderParams);`
Render for OpenGL. The rendering parameters are configurable by Attributes, see TSceneRenderingAttributes and TRenderingAttributes. For more details about rendering, see CastleRenderer unit comments. This method internally uses TGLRenderer instance, additionally handling the blending: OpenGL state of glDepthMask, glEnable/Disable(GL_BLEND), glBlendFunc is controlled by this function. This function will unconditionally change (and restore later to original value) this state, to perform correct blending (transparency rendering). To make a correct rendering, we always render transparent shapes at the end (after all opaque), and with depth-buffer in read-only mode. Only a subset of shapes indicated by Params.Transparent is rendered. This is necessary if you want to mix in one 3D world many scenes (like TCastleScene instances), and each of them may have some opaque and some transparent parts. In such case, you want to render everything opaque (from every scene) first, and only then render everything transparent. For shadow volumes, this is even more complicated. Note that when Attributes.Blending is `False` then everything is always opaque, so tgOpaque renders everything and tgTransparent renders nothing. ###### Parameters TestShapeVisibility Filters which shapes are visible. You can use this to optimize rendering. For example you can reject shapes because their bounding volume (bounding boxes or bounding spheres) doesn't intersect with frustum or such. This is called frustum culling, and in fact is done automatically by other overloaded Render methods in this class, see FrustumCulling and OctreeFrustumCulling. TestShapeVisibility callback may be used to implement frustum culling, or some other visibility algorithm.
| `procedure Render(const Frustum: TFrustum; const Params: TRenderParams); override;`
| `procedure BeforeNodesFree(const InternalChangedAll: boolean = false); override;`
| `procedure RenderShadowVolume( ShadowVolumeRenderer: TBaseShadowVolumeRenderer; const ParentTransformIsIdentity: boolean; const ParentTransform: TMatrix4Single); override;`
Render shadow volume (sides and caps) of this scene, for shadow volume algorithm. Checks ShadowVolumeRenderer.InitScene to know if the shadow needs to be rendered at all. It will calculate current bounding box (looking at ParentTransform, ParentTransformIsIdentity and BoundingBox method). It always uses silhouette optimization. This is the usual, fast method of rendering shadow volumes. Will not do anything (treat scene like not casting shadows, like CastShadowVolumes = false) if the model is not perfect 2-manifold, i.e. has some BorderEdges (although we could handle some BorderEdges for some points of view, this was always inherently dangerous and leading to rendering artifacts). See RenderSilhouetteShadowVolume, RenderAllShadowVolume comments in code for more explanation. All shadow quads are generated from scene triangles transformed by ParentTransform. We must be able to correctly detect front and back facing triangles with respect to light position, so ShadowVolumeRenderer.LightPosition and "this scene transformed by ParentTransform" must be in the same coordinate system. That's why explicit ParentTransform parameter is needed, you can't get away with simply doing glPush/PopMatrix and glMultMatrix around `RenderShadowVolume` call. If ParentTransformIsIdentity then ParentTransform value is ignored and everything works like ParentTransform = identity matrix (and is a little faster in this special case). Uses TrianglesListShadowCasters and ManifoldEdges and BorderEdges (so you may prefer to prepare it before, e.g. by calling PrepareResources with prShadowVolume included). We look at some Attributes, like Attributes.Blending, because transparent triangles have to be handled a little differently, and when Attributes.Blending = false then all triangles are forced to be opaque. In other words, this takes Attributes into account, to cooperate with our Render method. ShadowVolumeRenderer.LightPosition is the light position. ShadowVolumeRenderer.LightPosition[3] must be 1 (to indicate positional light) or 0 (a directional light). It's expected that ShadowVolumeRenderer is already initialized by ShadowVolumeRenderer.InitFrustumAndLight. Faces (both shadow quads and caps) are rendered such that CCW <=> you're looking at it from outside (i.e. it's considered front face of this shadow volume). All the commands passed to OpenGL by this methods are: glBegin, sequence of glVertex, then glEnd.
| `procedure RenderSilhouetteEdges( const ObserverPos: TVector4Single; const Transform: TMatrix4Single);`
Render silhouette edges. Silhouette is determined from the ObserverPos. Whole scene is transformed by Transform (before checking which edges are silhouette and before rendering). In other words, Transform must transform the scene to the same coord space where given ObserverPos is. When they are in the same space, just use IdentityMatrix4Single. This implicitly creates and uses ManifoldEdges. In fact, one of the uses of this is to visually see that ManifoldEdges are coorect.
| `procedure RenderBorderEdges( const Transform: TMatrix4Single);`
Render all border edges (the edges without neighbor). This implicitly creates and uses BorderEdges. In fact, one of the uses of this is to visually see that BorderEdges are coorect.
| `function Background: TBackground;`
TBackground instance to render current background. Current background is the top node on the BackgroundStack of this scene, following VRML/X3D specifications, and can be dynamic. The scene manager should use this to render background. We use the current value of BackgroundSkySphereRadius. Returns `Nil` if there is no currently bound background node in this scene, or if the bound background is not supported for now (the latter case right now happens with TextureBakckground). This instance is managed (automatically created/freed and so on) by this TCastleScene instance. It is cached (so that it's recreated only when relevant things change, like VRML/X3D nodes affecting this background, or changes to BackgroundSkySphereRadius, or OpenGL context is closed).
| `function Attributes: TSceneRenderingAttributes;`
Rendering attributes. You are free to change them all at any time. Although note that changing some attributes (the ones defined in base TRenderingAttributes class) may be a costly operation (next PrepareResources with prRender, or Render call, may need to recalculate some things).
| `procedure UpdateGeneratedTextures( const RenderFunc: TRenderFromViewFunction; const ProjectionNear, ProjectionFar: Single; const OriginalViewportX, OriginalViewportY: LongInt; const OriginalViewportWidth, OriginalViewportHeight: Cardinal); override;`
| `procedure ViewChangedSuddenly; override;`
| `procedure VisibleChangeNotification(const Changes: TVisibleChanges); override;`
| `function ScreenEffects(Index: Integer): TGLSLProgram;`
Screen effects information, used by TCastleAbstractViewport.ScreenEffects. ScreenEffectsCount may actually prepare screen effects.
| `function ScreenEffectsCount: Integer;`
| `function ScreenEffectsNeedDepth: boolean;`
### Properties
| `property BackgroundSkySphereRadius: Single read FBackgroundSkySphereRadius write SetBackgroundSkySphereRadius default 1;`
| `property FrustumCulling: TFrustumCulling read FFrustumCulling write SetFrustumCulling default fcBox;`
Fine-tune performance of Render when OctreeRendering is not available. Render tests each Shape for collision with given Frustum before rendering this Shape. It can use Shape.BoundingBox or Shape.BoundingSphere or both. See TFrustumCulling. Shape.BoundingBox is (in a current implementation) always a better approximation of shape geometry than Shape.BoundingSphere. So advantage of using Shape.BoundingBox is that more Shapes may be eliminated. Advantage of using Shape.BoundingSphere is that checking for collision Frustum<->Sphere is faster, so you don't waste so much time on testing for collisions between frustum and Shape.
| `property OctreeFrustumCulling: TFrustumCulling read FOctreeFrustumCulling write SetOctreeFrustumCulling default fcBox;`
Fine-tune performance of Render when OctreeRendering is available. See TFrustumCulling.
| `property ReceiveShadowVolumes: boolean read FReceiveShadowVolumes write FReceiveShadowVolumes default true;`
Generated by PasDoc 0.13.0 on 2013-08-17 21:27:13