Operation setup for a RenderTarget (collected).
		///<summary>
		///    Compile the final (output) operation. This is done seperately because this
		///    is combined with the input in chained filters.
		///</summary>
		public void CompileOutputOperation( CompositeTargetOperation finalState )
		{
			// Final target
			var tpass = this.technique.OutputTarget;

			// Logical-and together the visibilityMask, and multiply the lodBias
			finalState.VisibilityMask &= tpass.VisibilityMask;
			finalState.LodBias *= tpass.LodBias;

			if ( tpass.InputMode == CompositorInputMode.Previous )
			{
				// Collect target state for previous compositor
				// The TargetOperation for the final target is collected seperately as it is merged
				// with later operations
				this.previousInstance.CompileOutputOperation( finalState );
			}
			// Collect passes
			CollectPasses( finalState, tpass );
		}
		///<summary>
		///    Queue a render system operation.
		///</summary>
		///<returns>destination pass</returns>
		protected void QueueRenderSystemOp( CompositeTargetOperation finalState, CompositeRenderSystemOperation op )
		{
			// Store operation for current QueueGroup ID
			finalState.RenderSystemOperations.Add( new QueueIDAndOperation( finalState.CurrentQueueGroupId, op ) );
			// Save a pointer, so that it will be freed on recompile
			this.chain.RenderSystemOperations.Add( op );
		}
		///<summary>
		///    Collect rendering passes. Here, passes are converted into render target operations
		///    and queued with queueRenderSystemOp.
		///</summary>
		protected void CollectPasses( CompositeTargetOperation finalState, CompositionTargetPass target )
		{
			// Here, passes are converted into render target operations
			Pass targetPass = null;
			Technique srctech = null;
			Material mat = null, srcmat = null;

			foreach ( var pass in target.Passes )
			{
				switch ( pass.Type )
				{
					case CompositorPassType.Clear:
					{
						QueueRenderSystemOp( finalState,
						                     new RSClearOperation( pass.ClearBuffers, pass.ClearColor, pass.ClearDepth, pass.ClearStencil ) );
					}
						break;
					case CompositorPassType.Stencil:
					{
						QueueRenderSystemOp( finalState,
						                     new RSStencilOperation( pass.StencilCheck, pass.StencilFunc, pass.StencilRefValue,
						                                             pass.StencilMask, pass.StencilFailOp, pass.StencilDepthFailOp,
						                                             pass.StencilPassOp, pass.StencilTwoSidedOperation ) );
					}
						break;
					case CompositorPassType.RenderScene:
					{
						if ( pass.FirstRenderQueue < finalState.CurrentQueueGroupId )
						{
							// Mismatch -- warn user
							// XXX We could support repeating the last queue, with some effort
							LogManager.Instance.Write( "Warning in compilation of Compositor {0}: Attempt to render queue {1} before {2}.",
							                           this.compositor.Name, pass.FirstRenderQueue, finalState.CurrentQueueGroupId );
						}
						RSSetSchemeOperation setSchemeOperation = null;
						if ( pass.MaterialScheme != string.Empty )
						{
							//Add the triggers that will set the scheme and restore it each frame
							finalState.CurrentQueueGroupId = pass.FirstRenderQueue;
							setSchemeOperation = new RSSetSchemeOperation( pass.MaterialScheme );
							QueueRenderSystemOp( finalState, setSchemeOperation );
						}
						// Add render queues
						for ( var x = (int)pass.FirstRenderQueue; x < (int)pass.LastRenderQueue; x++ )
						{
							Debug.Assert( x >= 0 );
							finalState.RenderQueues.Set( x, true );
						}
						finalState.CurrentQueueGroupId = pass.LastRenderQueue + 1;
						if ( setSchemeOperation != null )
						{
							//Restoring the scheme after the queues have been rendered
							QueueRenderSystemOp( finalState, new RSRestoreSchemeOperation( setSchemeOperation ) );
						}
						finalState.FindVisibleObjects = true;
						finalState.MaterialScheme = target.MaterialScheme;
						finalState.ShadowsEnabled = target.ShadowsEnabled;
					}
						break;
					case CompositorPassType.RenderQuad:
					{
						srcmat = pass.Material;
						if ( srcmat == null )
						{
							// No material -- warn user
							LogManager.Instance.Write(
								"Warning in compilation of Compositor {0}: No material defined for composition pass.", this.compositor.Name );
							break;
						}
						srcmat.Load();
						if ( srcmat.SupportedTechniques.Count == 0 )
						{
							// No supported techniques -- warn user
							LogManager.Instance.Write(
								"Warning in compilation of Compositor {0}: material {1} has no supported techniques.", this.compositor.Name,
								srcmat.Name );
							break;
						}

						srctech = srcmat.GetBestTechnique( 0 );
						// Create local material
						mat = CreateLocalMaterial( srcmat.Name );
						// Copy and adapt passes from source material
						for ( var i = 0; i < srctech.PassCount; i++ )
						{
							var srcpass = srctech.GetPass( i );
							// Create new target pass
							targetPass = mat.GetTechnique( 0 ).CreatePass();
							srcpass.CopyTo( targetPass );
							// Set up inputs
							for ( var x = 0; x < pass.InputsCount; x++ )
							{
								var inp = pass.GetInput( x );
								if ( !string.IsNullOrEmpty( inp.Name ) )
								{
									if ( x < targetPass.TextureUnitStatesCount )
									{
										targetPass.GetTextureUnitState( x ).SetTextureName( GetTextureInstance( inp.Name, inp.MrtIndex ).Name );
									}
									else
									{
										// Texture unit not there
										LogManager.Instance.Write(
											"Warning in compilation of Compositor {0}: material {1} texture unit {2} out of bounds.",
											this.compositor.Name,
											srcmat.Name, x );
									}
								}
							} //end for inputs.length
						} //end for passcount

						var rsQuadOperation = new RSQuadOperation( this, pass.Identifier, mat );
						float left, top, right, bottom;
						if ( pass.GetQuadCorners( out left, out top, out right, out bottom ) )
						{
							rsQuadOperation.SetQuadCorners( left, top, right, bottom );
						}
						rsQuadOperation.SetQuadFarCorners( pass.QuadFarCorners, pass.QuadFarCornersViewSpace );
						QueueRenderSystemOp( finalState, rsQuadOperation );
					}
						break;
					case CompositorPassType.RenderCustom:
					{
						var customOperation = CompositorManager.Instance.CustomCompositionPasses[ pass.CustomType ].CreateOperation(
							this, pass );
						QueueRenderSystemOp( finalState, customOperation );
					}
						break;
				}
			}
		}
		///<summary>
		///    Recursively collect target states (except for final Pass).
		///</summary>
		///<param name="compiledState">This vector will contain a list of TargetOperation objects</param>
		public void CompileTargetOperations( List<CompositeTargetOperation> compiledState )
		{
			// Collect targets of previous state
			if ( this.previousInstance != null )
			{
				this.previousInstance.CompileTargetOperations( compiledState );
			}
			// Texture targets
			foreach ( var target in this.technique.TargetPasses )
			{
				var ts = new CompositeTargetOperation( GetTextureInstance( target.OutputName ).GetBuffer().GetRenderTarget() );
				// Set "only initial" flag, visibilityMask and lodBias according to CompositionTargetPass.
				ts.OnlyInitial = target.OnlyInitial;
				ts.VisibilityMask = target.VisibilityMask;
				ts.LodBias = target.LodBias;
				ts.ShadowsEnabled = target.ShadowsEnabled;
				// Check for input mode previous
				if ( target.InputMode == CompositorInputMode.Previous && this.previousInstance != null )
				{
					// Collect target state for previous compositor
					// The TargetOperation for the final target is collected seperately as it is merged
					// with later operations
					this.previousInstance.CompileOutputOperation( ts );
				}
				// Collect passes of our own target
				CollectPasses( ts, target );
				compiledState.Add( ts );
			}
		}
Beispiel #5
0
			///<summary>
			///    Set current operation and target */
			///</summary>
			public void SetOperation( CompositeTargetOperation op, SceneManager sm, RenderSystem rs )
			{
				this.operation = op;
				this.sceneManager = sm;
				this.renderSystem = rs;
				this.currentOp = 0;
				this.lastOp = op.RenderSystemOperations.Count;
			}
Beispiel #6
0
		protected void ClearCompiledState()
		{
			this.renderSystemOperations.Clear();
			this.compiledState.Clear();
			this.outputOperation = new CompositeTargetOperation( null );
		}
Beispiel #7
0
		///<summary>
		///    Restore a viewport, the camera and the scene after a rendering operation
		///</summary>
		protected void PostTargetOperation( CompositeTargetOperation op, Viewport vp, Camera cam )
		{
			if ( cam != null )
			{
				var sm = cam.SceneManager;
				// Unregister our listener
				sm.QueueStarted -= this.listener.OnRenderQueueStarted;
				sm.QueueEnded -= this.listener.OnRenderQueueEnded;
				// Restore default scene and camera settings
				sm.VisibilityMask = this.oldVisibilityMask;
				sm.FindVisibleObjectsBool = this.oldFindVisibleObjects;
				cam.LodBias = this.oldLodBias;
			}

			vp.MaterialScheme = this.oldMaterialScheme;
			vp.ShowShadows = this.oldShowShadows;
		}
Beispiel #8
0
		///<summary>
		///    Prepare a viewport, the camera and the scene for a rendering operation
		///</summary>
		protected void PreTargetOperation( CompositeTargetOperation op, Viewport vp, Camera cam )
		{
			if ( cam != null )
			{
				var sm = cam.SceneManager;
				// Set up render target listener
				this.listener.SetOperation( op, sm, sm.TargetRenderSystem );
				this.listener.Viewport = vp;
				// Register it
				sm.QueueStarted += this.listener.OnRenderQueueStarted;
				sm.QueueEnded += this.listener.OnRenderQueueEnded;
				// Set visiblity mask
				this.oldVisibilityMask = sm.VisibilityMask;
				sm.VisibilityMask = op.VisibilityMask;
				// Set whether we find visibles
				this.oldFindVisibleObjects = sm.FindVisibleObjectsBool;
				sm.FindVisibleObjectsBool = op.FindVisibleObjects;
				// Set LOD bias level
				this.oldLodBias = cam.LodBias;
				cam.LodBias = cam.LodBias*op.LodBias;
			}


			// Set material scheme
			this.oldMaterialScheme = vp.MaterialScheme;
			vp.MaterialScheme = op.MaterialScheme;
			// Set Shadows Enabled
			this.oldShowShadows = vp.ShowShadows;
			vp.ShowShadows = op.ShadowsEnabled;

			//vp.ClearEveryFrame = true;
			//vp.ShowOverlays = false;
			//vp.BackgroundColor = op.ClearColor;
		}
Beispiel #9
0
		public CompositorChain( Viewport vp )
		{
			this.viewport = vp;
			this.originalScene = null;
			this.instances = new List<CompositorInstance>();
			this.dirty = true;
			this.anyCompositorsEnabled = false;
			this.compiledState = new List<CompositeTargetOperation>();
			this.outputOperation = null;
			this.oldClearEveryFrameBuffers = this.viewport.ClearBuffers;
			this.renderSystemOperations = new List<CompositeRenderSystemOperation>();

			CreateOriginalScene();
			this.listener = new RQListener();
			Debug.Assert( this.viewport != null );

			this.viewport.Target.BeforeUpdate += BeforeRenderTargetUpdate;
			this.viewport.Target.AfterUpdate += AfterRenderTargetUpdate;
			this.viewport.Target.BeforeViewportUpdate += BeforeViewportUpdate;
			this.viewport.Target.AfterViewportUpdate += AfterViewportUpdate;
		}