/// <summary> /// Create "default compositor" /// </summary> protected void CreateOriginalScene() { this.originalSceneMaterial = this.viewport.MaterialScheme; string compName = "Axiom/Scene/" + this.originalSceneMaterial; var scene = (Compositor)CompositorManager.Instance.GetByName(compName); if (scene == null) { scene = (Compositor)CompositorManager.Instance.Create(compName, ResourceGroupManager.InternalResourceGroupName); CompositionTechnique t = scene.CreateTechnique(); t.SchemeName = string.Empty; CompositionTargetPass tp = t.OutputTarget; tp.VisibilityMask = 0xFFFFFFFF; { CompositionPass pass = tp.CreatePass(); pass.Type = CompositorPassType.Clear; } { CompositionPass pass = tp.CreatePass(); pass.Type = CompositorPassType.RenderScene; //Render everything, including skies pass.FirstRenderQueue = RenderQueueGroupID.Background; pass.LastRenderQueue = RenderQueueGroupID.SkiesLate; } scene = (Compositor)CompositorManager.Instance.Load(compName, ResourceGroupManager.InternalResourceGroupName); } this.originalScene = new CompositorInstance(scene.GetSupportedTechniqueByScheme(), this); }
///<summary> /// Create an instance of this technique. ///</summary> public virtual CompositorInstance CreateInstance(CompositorChain chain) { CompositorInstance mew = new CompositorInstance(parent, this, chain); instances.Add(mew); return(mew); }
///<summary> /// Apply a compositor. Initially, the filter is enabled. ///</summary> ///<param name="filter">Filter to apply</param> ///<param name="addPosition">Position in filter chain to insert this filter at; defaults to the end (last applied filter)</param> ///<param name="technique">Technique to use; CompositorChain::BEST (default) chooses to the best one /// available (first technique supported) ///</param> ///<param name="scheme"></param> private CompositorInstance AddCompositor(Compositor filter, int addPosition, int technique, string scheme) { filter.Touch(); CompositionTechnique tech = filter.GetSupportedTechniqueByScheme(scheme); if (tech == null) { LogManager.Instance.DefaultLog.Write("CompositorChain: Compositor " + filter.Name + " has no supported techniques."); } var t = new CompositorInstance(tech, this); if (addPosition == lastCompositor) { addPosition = this.instances.Count; } else { Debug.Assert(addPosition <= this.instances.Count, "Index out of bounds."); } this.instances.Insert(addPosition, t); this.dirty = true; this.anyCompositorsEnabled = true; return(t); }
///<summary> /// Remove a compositor by pointer. This is internally used by CompositionTechnique to /// "weak" remove any instanced of a deleted technique. ///</summary> public void RemoveInstance(CompositorInstance instance) { instance.Dispose(); this.instances.Remove(instance); instance = null; this.dirty = true; }
///<summary> /// Remove a compositor. ///</summary> ///<param name="position">Position in filter chain of filter to remove</param> public void RemoveCompositor(int position) { CompositorInstance instance = instances[position]; instances.RemoveAt(position); instance.Technique.DestroyInstance(instance); dirty = true; }
/// <summary> /// Destroy default compositor /// </summary> protected void DestroyOriginalScene() { if (this.originalScene != null) { this.originalScene.Dispose(); this.originalScene = null; } }
public RSQuadOperation(CompositorInstance instance, uint pass_id, Material mat) { this.mat = mat; this.instance = instance; this.pass_id = pass_id; mat.Load(); instance.FireNotifyMaterialSetup(pass_id, mat); technique = mat.GetTechnique(0); Debug.Assert(technique != null); }
/// <summary> /// /// </summary> /// <param name="instance"></param> /// <param name="localName"></param> /// <returns></returns> private bool IsInputPreviousTarget( CompositorInstance instance, string localName ) { foreach ( var tp in instance.Technique.TargetPasses ) { if ( tp.InputMode == CompositorInputMode.Previous && tp.OutputName == localName ) { return true; } } return false; }
///<summary> /// Compile this Composition chain into a series of RenderTarget operations. ///</summary> protected void Compile() { ClearCompiledState(); bool compositorsEnabled = false; /// Set previous CompositorInstance for each compositor in the list CompositorInstance lastComposition = originalScene; originalScene.PreviousInstance = null; CompositionPass pass = originalScene.Technique.OutputTarget.GetPass(0); pass.ClearBuffers = viewport.ClearBuffers; pass.ClearColor = viewport.BackgroundColor; foreach (CompositorInstance instance in instances) { if (instance.Enabled) { compositorsEnabled = true; instance.PreviousInstance = lastComposition; lastComposition = instance; } } /// Compile misc targets lastComposition.CompileTargetOperations(compiledState); /// Final target viewport (0) outputOperation.RenderSystemOperations.Clear(); lastComposition.CompileOutputOperation(outputOperation); // Deal with viewport settings if (compositorsEnabled != anyCompositorsEnabled) { anyCompositorsEnabled = compositorsEnabled; if (anyCompositorsEnabled) { // Save old viewport clearing options oldClearEveryFrameBuffers = viewport.ClearBuffers; // Don't clear anything every frame since we have our own clear ops viewport.SetClearEveryFrame(false); } else { // Reset clearing options viewport.SetClearEveryFrame(oldClearEveryFrameBuffers > 0, oldClearEveryFrameBuffers); } } dirty = false; }
public CompositorChain(Viewport vp) { this.viewport = vp; originalScene = null; instances = new List <CompositorInstance>(); dirty = true; anyCompositorsEnabled = false; compiledState = new List <CompositorTargetOperation>(); outputOperation = null; oldClearEveryFrameBuffers = viewport.ClearBuffers; renderSystemOperations = new List <CompositorRenderSystemOperation>(); listener = new RQListener(); Debug.Assert(viewport != null); }
/// <summary> /// another overload to remove a compositor instance from its chain /// </summary> /// <param name="remInstance"></param> public void RemoveCompositor( CompositorInstance remInstance ) { var chain = remInstance.Chain; for ( var i = 0; i < chain.Instances.Count; i++ ) { var instance = chain.GetCompositor( i ); if ( instance == remInstance ) { chain.RemoveCompositor( i ); break; } } }
///<summary> /// Remove a compositor from a viewport ///</summary> public void RemoveCompositor(Viewport vp, string compositor) { CompositorChain chain = GetCompositorChain(vp); for (int i = 0; i < chain.Instances.Count; i++) { CompositorInstance instance = chain.GetCompositor(i); if (instance.Compositor.Name == compositor) { chain.RemoveCompositor(i); break; } } }
///<summary> /// Set the state of a compositor on a viewport to enabled or disabled. /// Disabling a compositor stops it from rendering but does not free any resources. /// This can be more efficient than using removeCompositor and addCompositor in cases /// the filter is switched on and off a lot. ///</summary> public void SetCompositorEnabled(Viewport vp, string compositor, bool value) { CompositorChain chain = GetCompositorChain(vp); for (int i = 0; i < chain.Instances.Count; i++) { CompositorInstance instance = chain.GetCompositor(i); if (instance.Compositor.Name == compositor) { chain.SetCompositorEnabled(i, value); break; } } }
/// <summary> /// /// </summary> /// <param name="instance"></param> /// <param name="localName"></param> /// <returns></returns> private bool IsInputToOutputTarget( CompositorInstance instance, string localName ) { var tp = instance.Technique.OutputTarget; foreach ( var p in tp.Passes ) { for ( var i = 0; i < p.Inputs.Length; i++ ) { if ( p.GetInput( i ).Name == localName ) { return true; } } } return false; }
/// <summary> /// /// </summary> /// <param name="instance"></param> /// <param name="texture"></param> /// <returns></returns> private bool IsInputToOutputTarget( CompositorInstance instance, Texture texture ) { var tp = instance.Technique.OutputTarget; foreach ( var p in tp.Passes ) { for ( var i = 0; i < p.Inputs.Length; i++ ) { var t = instance.GetTextureInstance( p.GetInput( i ).Name, 0 ); if ( t != null && t == texture ) { return true; } } } return false; }
/// <summary> /// /// </summary> /// <param name="instance"></param> /// <param name="texture"></param> /// <returns></returns> private bool IsInputPreviousTarget( CompositorInstance instance, Texture texture ) { foreach ( var tp in instance.Technique.TargetPasses ) { if ( tp.InputMode == CompositorInputMode.Previous ) { // Don't have to worry about an MRT, because no MRT can be input previous var t = instance.GetTextureInstance( tp.OutputName, 0 ); if ( t != null && t == texture ) { return true; } } } return false; }
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; }
/// <summary> /// Get the previous instance in this chain to the one specified. /// </summary> /// <param name="curr"></param> /// <param name="activeOnly"></param> /// <returns></returns> public CompositorInstance GetPreviousInstance(CompositorInstance curr, bool activeOnly) { var found = false; for (int i = this.instances.Count - 1; i >= 0; i--) { if (found) { if (this.instances[i].IsEnabled || !activeOnly) { return(this.instances[i]); } } else if (this.instances[i] == curr) { found = true; } } return(null); }
/// <summary> /// Get the next instance in this chain to the one specified. /// </summary> /// <param name="curr"></param> /// <param name="activeOnly"></param> /// <returns></returns> public CompositorInstance GetNextInstance(CompositorInstance curr, bool activeOnly) { var found = false; for (var i = 0; i < this.instances.Count; i++) { if (found) { if (this.instances[i].IsEnabled || !activeOnly) { return(this.instances[i]); } } else if (this.instances[i] == curr) { found = true; } } return(null); }
///<summary> /// Apply a compositor. Initially, the filter is enabled. ///</summary> ///<param name="filter">Filter to apply</param> ///<param name="addPosition">Position in filter chain to insert this filter at; defaults to the end (last applied filter)</param> ///<param name="technique">Technique to use; CompositorChain::BEST (default) chooses to the best one /// available (first technique supported) ///</param> CompositorInstance AddCompositor(Compositor filter, int addPosition, int technique) { // Init on demand if (originalScene == null) { viewport.Target.BeforeUpdate += BeforeRenderTargetUpdate; // viewport.Target.AfterUpdate += AfterRenderTargetUpdate; viewport.Target.BeforeViewportUpdate += BeforeViewportUpdate; viewport.Target.AfterViewportUpdate += AfterViewportUpdate; /// Create base "original scene" compositor Compositor baseCompositor = (Compositor)CompositorManager.Instance.LoadExisting("Ogre/Scene"); originalScene = baseCompositor.GetSupportedTechnique(0).CreateInstance(this); } filter.Touch(); if (technique >= filter.SupportedTechniques.Count) { /// Warn user LogManager.Instance.Write("CompositorChain: Compositor " + filter.Name + " has no supported techniques."); return(null); } CompositionTechnique tech = filter.GetSupportedTechnique(technique); CompositorInstance t = tech.CreateInstance(this); if (addPosition == lastCompositor) { instances.Add(t); } else { Debug.Assert(addPosition <= instances.Count); instances.Insert(addPosition, t); } dirty = true; anyCompositorsEnabled = true; return(t); }
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; }
/// <summary> /// Destroy default compositor /// </summary> protected void DestroyOriginalScene() { if ( this.originalScene != null ) { this.originalScene.Dispose(); this.originalScene = null; } }
/// <summary> /// Called when a compositor instance has been destroyed /// </summary> /// <remarks> /// The chain that contained the compositor is still alive during this call. /// </remarks> /// <param name="destroyedInstance"></param> public virtual void CompositorInstanceDestroyed(CompositorInstance destroyedInstance) { }
///<summary> /// Remove a compositor by pointer. This is internally used by CompositionTechnique to /// "weak" remove any instanced of a deleted technique. ///</summary> public void RemoveInstance( CompositorInstance instance ) { instance.Dispose(); this.instances.Remove( instance ); instance = null; this.dirty = true; }
///<summary> /// Destroy an instance of this technique. ///</summary> public virtual void DestroyInstance(CompositorInstance instance) { instances.Remove(instance); }
/// <summary> /// Called when a compositor instance has been destroyed /// </summary> /// <remarks> /// The chain that contained the compositor is still alive during this call. /// </remarks> /// <param name="destroyedInstance"></param> public virtual void CompositorInstanceDestroyed( CompositorInstance destroyedInstance ) { }
/// <summary> /// Get the next instance in this chain to the one specified. /// </summary> /// <param name="curr"></param> /// <returns></returns> public CompositorInstance GetNextInstance( CompositorInstance curr ) { return GetNextInstance( curr, true ); }
/// <summary> /// Get the next instance in this chain to the one specified. /// </summary> /// <param name="curr"></param> /// <param name="activeOnly"></param> /// <returns></returns> public CompositorInstance GetNextInstance( CompositorInstance curr, bool activeOnly ) { var found = false; for ( var i = 0; i < this.instances.Count; i++ ) { if ( found ) { if ( this.instances[ i ].IsEnabled || !activeOnly ) { return this.instances[ i ]; } } else if ( this.instances[ i ] == curr ) { found = true; } } return null; }
/// <summary> /// /// </summary> /// <param name="name"></param> /// <param name="localName"></param> /// <param name="width"></param> /// <param name="height"></param> /// <param name="format"></param> /// <param name="aa"></param> /// <param name="aaHint"></param> /// <param name="srgb"></param> /// <param name="textureAllreadyAssigned"></param> /// <param name="instance"></param> /// <param name="scope"></param> /// <returns></returns> public Texture GetPooledTexture( string name, string localName, int width, int height, PixelFormat format, int aa, string aaHint, bool srgb, List<Texture> textureAllreadyAssigned, CompositorInstance instance, CompositionTechnique.TextureScope scope) { if ( scope == CompositionTechnique.TextureScope.Global ) { throw new AxiomException( "Global scope texture can not be pooled." ); } var def = new TextureDefinition( width, height, format, aa, aaHint, srgb ); if ( scope == CompositionTechnique.TextureScope.Chain ) { var pair = new Pair<string>( instance.Compositor.Name, localName ); SortedList<TextureDefinition, Texture> defMap = null; if ( this.chainTexturesByRef.TryGetValue( pair, out defMap ) ) { Texture tex; if ( defMap.TryGetValue( def, out tex ) ) { return tex; } } // ok, we need to create a new one if ( defMap == null ) { defMap = new SortedList<TextureDefinition, Texture>( new TextureDefLess() ); } var newTex = TextureManager.Instance.CreateManual( name, ResourceGroupManager.InternalResourceGroupName, TextureType.TwoD, width, height, 0, format, TextureUsage.RenderTarget, null, srgb, aa, aaHint ); defMap.Add( def, newTex ); if ( this.chainTexturesByRef.ContainsKey( pair ) ) { this.chainTexturesByRef[ pair ] = defMap; } else { this.chainTexturesByRef.Add( pair, defMap ); } return newTex; } //end if scope List<Texture> i = null; if ( !this.texturesByDef.TryGetValue( def, out i ) ) { i = new List<Texture>(); this.texturesByDef.Add( def, i ); } var previous = instance.Chain.GetPreviousInstance( instance ); var next = instance.Chain.GetNextInstance( instance ); Texture ret = null; // iterate over the existing textures and check if we can re-use foreach ( var tex in i ) { // check not already used if ( !textureAllreadyAssigned.Contains( tex ) ) { var allowReuse = true; // ok, we didn't use this one already // however, there is an edge case where if we re-use a texture // which has an 'input previous' pass, and it is chained from another // compositor, we can end up trying to use the same texture for both // so, never allow a texture with an input previous pass to be // shared with its immediate predecessor in the chain if ( IsInputPreviousTarget( instance, localName ) ) { // Check whether this is also an input to the output target of previous // can't use CompositorInstance._previousInstance, only set up // during compile if ( previous != null && IsInputToOutputTarget( previous, tex ) ) { allowReuse = false; } } // now check the other way around since we don't know what order they're bound in if ( IsInputToOutputTarget( instance, localName ) ) { if ( next != null && IsInputPreviousTarget( next, tex ) ) { allowReuse = false; } } if ( allowReuse ) { ret = tex; break; } } } if ( ret == null ) { // ok, we need to create a new one ret = TextureManager.Instance.CreateManual( name, ResourceGroupManager.InternalResourceGroupName, TextureType.TwoD, width, height, 0, format, TextureUsage.RenderTarget, null, srgb, aa, aaHint ); i.Add( ret ); this.texturesByDef[ def ] = i; } // record that we used this one in the requester's list textureAllreadyAssigned.Add( ret ); return ret; }
/// <summary> /// another overload to remove a compositor instance from its chain /// </summary> /// <param name="remInstance"></param> public void RemoveCompositor(CompositorInstance remInstance) { CompositorChain chain = remInstance.Chain; for (int i = 0; i < chain.Instances.Count; i++) { CompositorInstance instance = chain.GetCompositor(i); if (instance == remInstance) { chain.RemoveCompositor(i); break; } } }
/// <summary> /// Called when a compositor instance has been created. /// </summary> /// <remarks> /// This happens after its setup was finished, so the chain is also accessible. /// This is an ideal method to automatically attach a compositor listener. /// </remarks> /// <param name="newInstance"></param> public virtual void CompositorInstanceCreated( CompositorInstance newInstance ) { }
/// <summary> /// Get the previous instance in this chain to the one specified. /// </summary> /// <param name="curr"></param> /// <param name="activeOnly"></param> /// <returns></returns> public CompositorInstance GetPreviousInstance( CompositorInstance curr, bool activeOnly ) { var found = false; for ( int i = this.instances.Count - 1; i >= 0; i-- ) { if ( found ) { if ( this.instances[ i ].IsEnabled || !activeOnly ) { return this.instances[ i ]; } } else if ( this.instances[ i ] == curr ) { found = true; } } return null; }
/// <summary> /// Get the previous instance in this chain to the one specified. /// </summary> /// <param name="curr"></param> /// <returns></returns> public CompositorInstance GetPreviousInstance( CompositorInstance curr ) { return GetPreviousInstance( curr, true ); }
///<summary> /// Create an instance of this technique. ///</summary> public virtual CompositorInstance CreateInstance(CompositorChain chain) { CompositorInstance mew = new CompositorInstance(parent, this, chain); instances.Add(mew); return mew; }
public CompositorChain(Viewport vp) { this.viewport = vp; originalScene = null; instances = new List<CompositorInstance>(); dirty = true; anyCompositorsEnabled = false; compiledState = new List<CompositorTargetOperation>(); outputOperation = null; oldClearEveryFrameBuffers = viewport.ClearBuffers; renderSystemOperations = new List<CompositorRenderSystemOperation>(); listener = new RQListener(); Debug.Assert(viewport != null); }
public RSQuadOperation(CompositorInstance instance, uint pass_id, Material mat) { this.mat = mat; this.instance = instance; this.pass_id = pass_id; mat.Load(); instance.FireNotifyMaterialSetup(pass_id, mat); technique = mat.GetTechnique(0); Debug.Assert(technique != null); }
///<summary> /// Remove a compositor by pointer. This is internally used by CompositionTechnique to /// "weak" remove any instanced of a deleted technique. ///</summary> public void RemoveInstance(CompositorInstance instance) { instances.Remove(instance); instance.Technique.DestroyInstance(instance); }
///<summary> /// Destroy an instance of this technique. ///</summary> public virtual void DestroyInstance(CompositorInstance instance) { instances.Remove(instance); }
///<summary> /// Apply a compositor. Initially, the filter is enabled. ///</summary> ///<param name="filter">Filter to apply</param> ///<param name="addPosition">Position in filter chain to insert this filter at; defaults to the end (last applied filter)</param> ///<param name="technique">Technique to use; CompositorChain::BEST (default) chooses to the best one /// available (first technique supported) ///</param> CompositorInstance AddCompositor(Compositor filter, int addPosition, int technique) { // Init on demand if (originalScene == null) { viewport.Target.BeforeUpdate += BeforeRenderTargetUpdate; // viewport.Target.AfterUpdate += AfterRenderTargetUpdate; viewport.Target.BeforeViewportUpdate += BeforeViewportUpdate; viewport.Target.AfterViewportUpdate += AfterViewportUpdate; /// Create base "original scene" compositor Compositor baseCompositor = (Compositor)CompositorManager.Instance.LoadExisting("Ogre/Scene"); originalScene = baseCompositor.GetSupportedTechnique(0).CreateInstance(this); } filter.Touch(); if (technique >= filter.SupportedTechniques.Count) { /// Warn user LogManager.Instance.Write("CompositorChain: Compositor " + filter.Name + " has no supported techniques."); return null; } CompositionTechnique tech = filter.GetSupportedTechnique(technique); CompositorInstance t = tech.CreateInstance(this); if (addPosition == lastCompositor) instances.Add(t); else { Debug.Assert(addPosition <= instances.Count); instances.Insert(addPosition, t); } dirty = true; anyCompositorsEnabled = true; return t; }
/// <summary> /// Called when a compositor instance has been created. /// </summary> /// <remarks> /// This happens after its setup was finished, so the chain is also accessible. /// This is an ideal method to automatically attach a compositor listener. /// </remarks> /// <param name="newInstance"></param> public virtual void CompositorInstanceCreated(CompositorInstance newInstance) { }
public void SetCompositor( CompositorInstance compositor ) { // Get some RTT dimensions for later calculations foreach ( CompositionTechnique.TextureDefinition textureDefinition in compositor.Technique.TextureDefinitions ) { if ( textureDefinition.Name == "rt_bloom0" ) { bloomSize = (int)textureDefinition.Width; // should be square // Calculate gaussian texture offsets & weights float deviation = 3.0f; float texelSize = 1.0f / (float)bloomSize; // central sample, no offset bloomTexOffsetsHorz[ 0 ] = 0.0f; bloomTexOffsetsHorz[ 1 ] = 0.0f; bloomTexOffsetsVert[ 0 ] = 0.0f; bloomTexOffsetsVert[ 1 ] = 0.0f; bloomTexWeights[ 0 ] = bloomTexWeights[ 1 ] = bloomTexWeights[ 2 ] = Utility.GaussianDistribution( 0, 0, deviation ); bloomTexWeights[ 3 ] = 1.0f; // 'pre' samples for ( int i = 1; i < 8; ++i ) { int offset = i * 4; bloomTexWeights[ offset + 0 ] = bloomTexWeights[ offset + 1 ] = bloomTexWeights[ offset + 2 ] = 1.25f * Utility.GaussianDistribution( i, 0, deviation ); bloomTexWeights[ offset + 3 ] = 1.0f; bloomTexOffsetsHorz[ offset + 0 ] = i * texelSize; bloomTexOffsetsHorz[ offset + 1 ] = 0.0f; bloomTexOffsetsVert[ offset + 0 ] = 0.0f; bloomTexOffsetsVert[ offset + 1 ] = i * texelSize; } // 'post' samples for ( int i = 8; i < 15; ++i ) { int offset = i * 4; bloomTexWeights[ offset + 0 ] = bloomTexWeights[ offset + 1 ] = bloomTexWeights[ offset + 2 ] = bloomTexWeights[ offset - 7 * 4 + 0 ]; bloomTexWeights[ offset + 3 ] = 1.0f; bloomTexOffsetsHorz[ offset + 0 ] = -bloomTexOffsetsHorz[ offset - 7 * 4 + 0 ]; bloomTexOffsetsHorz[ offset + 1 ] = 0.0f; bloomTexOffsetsVert[ offset + 0 ] = 0.0f; bloomTexOffsetsVert[ offset + 1 ] = -bloomTexOffsetsVert[ offset - 7 * 4 + 1 ]; } } } }
///<summary> /// Apply a compositor. Initially, the filter is enabled. ///</summary> ///<param name="filter">Filter to apply</param> ///<param name="addPosition">Position in filter chain to insert this filter at; defaults to the end (last applied filter)</param> ///<param name="technique">Technique to use; CompositorChain::BEST (default) chooses to the best one /// available (first technique supported) ///</param> ///<param name="scheme"></param> private CompositorInstance AddCompositor( Compositor filter, int addPosition, int technique, string scheme ) { filter.Touch(); CompositionTechnique tech = filter.GetSupportedTechniqueByScheme( scheme ); if ( tech == null ) { LogManager.Instance.DefaultLog.Write( "CompositorChain: Compositor " + filter.Name + " has no supported techniques." ); } var t = new CompositorInstance( tech, this ); if ( addPosition == lastCompositor ) { addPosition = this.instances.Count; } else { Debug.Assert( addPosition <= this.instances.Count, "Index out of bounds." ); } this.instances.Insert( addPosition, t ); this.dirty = true; this.anyCompositorsEnabled = true; return t; }
void OnMaterialSetup( CompositorInstance source, CompositorInstanceMaterialEventArgs e ) { this.SetViewport( source.Chain.Viewport ); this.SetCompositor( source ); // Prepare the fragment params offsets switch ( e.PassID ) { //case 994: // rt_lum4 case 993: // rt_lum3 case 992: // rt_lum2 case 991: // rt_lum1 case 990: // rt_lum0 break; case 800: // rt_brightpass break; case 701: // rt_bloom1 { // horizontal bloom e.Material.Load(); GpuProgramParameters fparams = e.Material.GetBestTechnique().GetPass( 0 ).FragmentProgramParameters; fparams.SetNamedConstant( "sampleOffsets", bloomTexOffsetsHorz ); fparams.SetNamedConstant( "sampleWeights", bloomTexWeights ); break; } case 700: // rt_bloom0 { // vertical bloom e.Material.Load(); GpuProgramParameters fparams = e.Material.GetTechnique( 0 ).GetPass( 0 ).FragmentProgramParameters; fparams.SetNamedConstant( "sampleOffsets", bloomTexOffsetsHorz ); fparams.SetNamedConstant( "sampleWeights", bloomTexWeights ); break; } } }
/// <summary> /// Create "default compositor" /// </summary> protected void CreateOriginalScene() { this.originalSceneMaterial = this.viewport.MaterialScheme; string compName = "Axiom/Scene/" + this.originalSceneMaterial; var scene = (Compositor)CompositorManager.Instance.GetByName( compName ); if ( scene == null ) { scene = (Compositor)CompositorManager.Instance.Create( compName, ResourceGroupManager.InternalResourceGroupName ); CompositionTechnique t = scene.CreateTechnique(); t.SchemeName = string.Empty; CompositionTargetPass tp = t.OutputTarget; tp.VisibilityMask = 0xFFFFFFFF; { CompositionPass pass = tp.CreatePass(); pass.Type = CompositorPassType.Clear; } { CompositionPass pass = tp.CreatePass(); pass.Type = CompositorPassType.RenderScene; //Render everything, including skies pass.FirstRenderQueue = RenderQueueGroupID.Background; pass.LastRenderQueue = RenderQueueGroupID.SkiesLate; } scene = (Compositor)CompositorManager.Instance.Load( compName, ResourceGroupManager.InternalResourceGroupName ); } this.originalScene = new CompositorInstance( scene.GetSupportedTechniqueByScheme(), this ); }
void OnMaterialRender( CompositorInstance source, CompositorInstanceMaterialEventArgs e ) { }
/// <summary> /// Get the previous instance in this chain to the one specified. /// </summary> /// <param name="curr"></param> /// <returns></returns> public CompositorInstance GetPreviousInstance(CompositorInstance curr) { return(GetPreviousInstance(curr, true)); }
/// <summary> /// Called when a compositor instance has been created. /// </summary> /// <remarks> /// This happens after its setup was finished, so the chain is also accessible. /// This is an ideal method to automatically attach a compositor listener. /// </remarks> /// <param name="newInstance"></param> public override void CompositorInstanceCreated( CompositorInstance newInstance ) { newInstance.MaterialRender += new CompositorInstanceMaterialEventHandler( OnMaterialRender ); newInstance.MaterialSetup += new CompositorInstanceMaterialEventHandler( OnMaterialSetup ); }
/// <summary> /// Get the next instance in this chain to the one specified. /// </summary> /// <param name="curr"></param> /// <returns></returns> public CompositorInstance GetNextInstance(CompositorInstance curr) { return(GetNextInstance(curr, true)); }
/// <summary> /// Called when a compositor instance has been destroyed /// </summary> /// <remarks> /// The chain that contained the compositor is still alive during this call. /// </remarks> /// <param name="destroyedInstance"></param> public override void CompositorInstanceDestroyed( CompositorInstance destroyedInstance ) { destroyedInstance.MaterialRender -= new CompositorInstanceMaterialEventHandler( OnMaterialRender ); destroyedInstance.MaterialSetup -= new CompositorInstanceMaterialEventHandler( OnMaterialSetup ); }
public RSQuadOperation( CompositorInstance instance, uint pass_id, Material mat ) { Material = mat; Instance = instance; PassId = pass_id; QuadLeft = -1; QuadRight = 1; QuadTop = 1; QuadBottom = -1; mat.Load(); instance.OnMaterialSetup( new CompositorInstanceMaterialEventArgs( PassId, Material ) ); Technique = mat.GetTechnique( 0 ); Debug.Assert( Technique != null, "Material has no supported technique." ); }
///<summary> /// Remove a compositor by pointer. This is internally used by CompositionTechnique to /// "weak" remove any instanced of a deleted technique. ///</summary> public void RemoveInstance(CompositorInstance instance) { instances.Remove(instance); instance.Technique.DestroyInstance(instance); }