/// <summary> /// Prompts the class to send its contents to the renderer. /// </summary> /// <remarks> /// This method prompts the scene manager to send the /// contents of the scene it manages to the rendering /// pipeline, possibly preceded by some sorting, culling /// or other scene management tasks. Note that this method is not normally called /// directly by the user application; it is called automatically /// by the engine's rendering loop. /// </remarks> /// <param name="camera">Pointer to a camera from whose viewpoint the scene is to be rendered.</param> /// <param name="viewport">The target viewport</param> /// <param name="showOverlays">Whether or not any overlay objects should be rendered</param> protected internal void RenderScene( Camera camera, Viewport viewport, bool showOverlays ) { // let the engine know this is the current scene manager Root.Instance.SceneManager = this; if ( this.IsShadowTechniqueInUse ) { // initialize shadow volume materials this.InitShadowVolumeMaterials(); } // Perform a quick pre-check to see whether we should override far distance // When using stencil volumes we have to use infinite far distance // to prevent dark caps getting clipped if ( this.IsShadowTechniqueStencilBased && camera.Far != 0 && this.targetRenderSystem.Capabilities.HasCapability( Capabilities.InfiniteFarPlane ) && this.shadowUseInfiniteFarPlane ) { // infinite far distance camera.Far = 0.0f; } this.cameraInProgress = camera; this.hasCameraChanged = true; // Update the scene, only do this once per frame ulong thisFrameNumber = Root.Instance.CurrentFrameCount; if ( thisFrameNumber != this.lastFrameNumber ) { // Update animations this.ApplySceneAnimations(); // Update controllers ControllerManager.Instance.UpdateAll(); this.lastFrameNumber = thisFrameNumber; } // Update scene graph for this camera (can happen multiple times per frame) this.UpdateSceneGraph( camera ); // Auto-track nodes foreach ( SceneNode sn in autoTrackingSceneNodes.Values ) { sn.AutoTrack(); } // ask the camera to auto track if it has a target camera.AutoTrack(); // Are we using any shadows at all? if ( this.IsShadowTechniqueInUse && this.illuminationStage != IlluminationRenderStage.RenderToTexture && viewport.ShowShadows && this.findVisibleObjects ) { // Locate any lights which could be affecting the frustum this.FindLightsAffectingFrustum( camera ); if ( this.IsShadowTechniqueTextureBased ) { // ******* // WARNING // ******* // This call will result in re-entrant calls to this method // therefore anything which comes before this is NOT // guaranteed persistent. Make sure that anything which // MUST be specific to this camera / target is done // AFTER THIS POINT this.PrepareShadowTextures( camera, viewport ); // reset the cameras because of the re-entrant call this.cameraInProgress = camera; this.hasCameraChanged = true; } } // Invert vertex winding? this.targetRenderSystem.InvertVertexWinding = camera.IsReflected; // Tell params about viewport this.autoParamDataSource.Viewport = viewport; // Set the viewport this.SetViewport( viewport ); // set the current camera for use in the auto GPU program params this.autoParamDataSource.Camera = camera; // Set autoparams for finite dir light extrusion this.autoParamDataSource.SetShadowDirLightExtrusionDistance( this.shadowDirLightExtrudeDist ); // sets the current ambient light color for use in auto GPU program params this.autoParamDataSource.AmbientLight = this.ambientColor; // Tell rendersystem this.targetRenderSystem.AmbientLight = this.ambientColor; // Tell params about render target this.autoParamDataSource.RenderTarget = viewport.Target; // set fog params float fogScale = 1f; if ( this.fogMode == FogMode.None ) { fogScale = 0f; } this.autoParamDataSource.FogParams = new Vector4( this.fogStart, this.fogEnd, fogScale, 0 ); // set the time in the auto param data source //autoParamDataSource.Time = ((float)Root.Instance.Timer.Milliseconds) / 1000f; // Set camera window clipping planes (if any) if ( this.targetRenderSystem.Capabilities.HasCapability( Capabilities.UserClipPlanes ) ) { // TODO: Add ClipPlanes to RenderSystem.cs if ( camera.IsWindowSet ) { targetRenderSystem.ResetClipPlanes(); IList<Plane> planeList = camera.WindowPlanes; for ( ushort i = 0; i < 4; ++i ) { targetRenderSystem.AddClipPlane( planeList[ i ] ); //this.targetRenderSystem.EnableClipPlane( i, true ); //this.targetRenderSystem.SetClipPlane( i, planeList[ i ] ); } } // this disables any user-set clipplanes... this should be done manually //else //{ // for (ushort i = 0; i < 4; ++i) // { // targetRenderSystem.EnableClipPlane(i, false); // } //} } // Prepare render queue for receiving new objects this.PrepareRenderQueue(); // Parse the scene and tag visibles if ( this.findVisibleObjects ) { if ( this.PreFindVisibleObjects != null ) PreFindVisibleObjects( this, this.illuminationStage, viewport ); this.FindVisibleObjects( camera, this.illuminationStage == IlluminationRenderStage.RenderToTexture ); if ( this.PostFindVisibleObjects != null ) PostFindVisibleObjects( this, this.illuminationStage, viewport ); } // Add overlays, if viewport deems it if ( viewport.ShowOverlays && this.illuminationStage != IlluminationRenderStage.RenderToTexture ) { // Queue overlays for rendering OverlayManager.Instance.QueueOverlaysForRendering( camera, this.GetRenderQueue(), viewport ); } // queue overlays and skyboxes for rendering if ( viewport.ShowSkies && this.findVisibleObjects && this.illuminationStage != IlluminationRenderStage.RenderToTexture ) { this.QueueSkiesForRendering( camera ); } // begin frame geometry count this.targetRenderSystem.BeginGeometryCount(); // clear the device if need be if ( viewport.ClearEveryFrame ) { this.targetRenderSystem.ClearFrameBuffer( viewport.ClearBuffers, viewport.BackgroundColor ); } // being a frame of animation this.targetRenderSystem.BeginFrame(); // use the camera's current scene detail level this.targetRenderSystem.PolygonMode = camera.PolygonMode; // Set initial camera state this.targetRenderSystem.ProjectionMatrix = camera.ProjectionMatrixRS; this.targetRenderSystem.ViewMatrix = camera.ViewMatrix; // render all visible objects this.RenderVisibleObjects(); // end the current frame this.targetRenderSystem.EndFrame(); // Notify camera of the number of rendered faces camera.NotifyRenderedFaces( this.targetRenderSystem.FaceCount ); // Notify camera of the number of rendered batches camera.NotifyRenderedBatches( this.targetRenderSystem.BatchCount ); }
/// <summary> /// Prompts the class to send its contents to the renderer. /// </summary> /// <remarks> /// This method prompts the scene manager to send the /// contents of the scene it manages to the rendering /// pipeline, possibly preceded by some sorting, culling /// or other scene management tasks. Note that this method is not normally called /// directly by the user application; it is called automatically /// by the engine's rendering loop. /// </remarks> /// <param name="camera">Pointer to a camera from whose viewpoint the scene is to be rendered.</param> /// <param name="viewport">The target viewport</param> /// <param name="showOverlays">Whether or not any overlay objects should be rendered</param> internal void RenderScene(Camera camera, Viewport viewport, bool showOverlays) { renderSceneMeter.Enter(); // let the engine know this is the current scene manager Root.Instance.SceneManager = this; if (IsShadowTechniqueInUse) { // initialize shadow volume materials InitShadowVolumeMaterials(); } // Perform a quick pre-check to see whether we should override far distance // When using stencil volumes we have to use infinite far distance // to prevent dark caps getting clipped if (IsShadowTechniqueStencilBased && camera.Far != 0 && targetRenderSystem.Caps.CheckCap(Capabilities.InfiniteFarPlane) && shadowUseInfiniteFarPlane) { // infinite far distance camera.Far = 0.0f; } cameraInProgress = camera; hasCameraChanged = true; // Update the scene, only do this once per frame ulong thisFrameNumber = Root.Instance.CurrentFrameCount; if (thisFrameNumber != lastFrameNumber) { // Update animations animationsMeter.Enter(); ApplySceneAnimations(); animationsMeter.Exit(); // Update controllers ControllerManager.Instance.UpdateAll(); lastFrameNumber = thisFrameNumber; } // Update scene graph for this camera (can happen multiple times per frame) UpdateSceneGraph(camera); // Auto-track nodes for(int i = 0; i < autoTrackingSceneNodes.Count; i++) { autoTrackingSceneNodes[i].AutoTrack(); } // ask the camera to auto track if it has a target camera.AutoTrack(); // Are we using any shadows at all? if (IsShadowTechniqueInUse && illuminationStage != IlluminationRenderStage.RenderToTexture && viewport.ShadowsEnabled && findVisibleObjects) { // Locate any lights which could be affecting the frustum FindLightsAffectingFrustum(camera); if (IsShadowTechniqueTextureBased) { // ******* // WARNING // ******* // This call will result in re-entrant calls to this method // therefore anything which comes before this is NOT // guaranteed persistent. Make sure that anything which // MUST be specific to this camera / target is done // AFTER THIS POINT PrepareShadowTextures(camera, viewport); // reset the cameras because of the re-entrant call cameraInProgress = camera; hasCameraChanged = true; } } // Invert vertex winding? targetRenderSystem.InvertVertexWinding = camera.IsReflected; // Tell params about viewport autoParamDataSource.Viewport = viewport; // Set the viewport SetViewport(viewport); // set the current camera for use in the auto GPU program params autoParamDataSource.Camera = camera; // Set autoparams for finite dir light extrusion autoParamDataSource.SetShadowDirLightExtrusionDistance(shadowDirLightExtrudeDist); // sets the current ambient light color for use in auto GPU program params autoParamDataSource.AmbientLight = ambientColor; // Tell rendersystem targetRenderSystem.AmbientLight = ambientColor; // Tell params about render target autoParamDataSource.RenderTarget = viewport.Target; // set fog params float fogScale = 1f; if (fogMode == FogMode.None) { fogScale = 0f; } autoParamDataSource.FogParams = new Vector4(fogStart, fogEnd, fogScale, 0); // set the time in the auto param data source // autoParamDataSource.Time = ((float)Root.Instance.Timer.Milliseconds) / 1000f; // Set camera window clipping planes (if any) if (targetRenderSystem.Caps.CheckCap(Capabilities.UserClipPlanes)) { // TODO: Add ClipPlanes to RenderSystem.cs /* if (camera.IsWindowSet) { PlaneList planeList = camera.WindowPlanes; for (ushort i = 0; i < 4; ++i) { targetRenderSystem.EnableClipPlane(i, true); targetRenderSystem.SetClipPlane(i, planeList[i]); } } else { for (ushort i = 0; i < 4; ++i) { targetRenderSystem.EnableClipPlane(i, false); } } */ } // Prepare render queue for receiving new objects PrepareRenderQueue(); // Parse the scene and tag visibles if (findVisibleObjects) { VisibleObjectsBoundsInfo bounds; if (!camVisibleObjectsMap.TryGetValue(camera, out bounds)) Debug.Assert(false, "Should never fail to find a visible object bound for a camera, " + "did you override SceneManager.CreateCamera or something?"); else { bounds.Reset(); findVisibleMeter.Enter(); FindVisibleObjects(camera, bounds, illuminationStage == IlluminationRenderStage.RenderToTexture); findVisibleMeter.Exit(); autoParamDataSource.MainCamBoundsInfo = bounds; } } // Add overlays, if viewport deems it if(viewport.OverlaysEnabled && illuminationStage != IlluminationRenderStage.RenderToTexture) { // Queue overlays for rendering OverlayManager.Instance.QueueOverlaysForRendering(camera, GetRenderQueue(), viewport); } // queue overlays and skyboxes for rendering if (viewport.SkiesEnabled && findVisibleObjects && illuminationStage != IlluminationRenderStage.RenderToTexture) QueueSkiesForRendering(camera); // begin frame geometry count targetRenderSystem.BeginGeometryCount(); // Clear the viewport if required if (currentViewport.ClearEveryFrame) targetRenderSystem.ClearFrameBuffer(currentViewport.ClearBuffers, currentViewport.BackgroundColor); // being a frame of animation targetRenderSystem.BeginFrame(); // use the camera's current scene detail level targetRenderSystem.RasterizationMode = camera.SceneDetail; // Set initial camera state targetRenderSystem.ProjectionMatrix = camera.ProjectionMatrixRS; targetRenderSystem.ViewMatrix = camera.ViewMatrix; // render all visible objects renderVisibleMeter.Enter(); RenderVisibleObjects(); renderVisibleMeter.Exit(); // end the current frame targetRenderSystem.EndFrame(); // Notify camera of the number of rendered faces camera.NotifyRenderedFaces(targetRenderSystem.FacesRendered); renderSceneMeter.Exit(); }