4 using System.Collections.Generic;
6 using SiliconStudio.Core.Collections;
7 using SiliconStudio.Core.Extensions;
11 namespace SiliconStudio.Paradox.Effects
18 private int meshPassSlot;
20 private readonly FastList<RenderMesh> meshesToRender;
23 private readonly
string effectName;
25 private readonly SafeDelegateList<AcceptModelDelegate> acceptModels;
27 private readonly SafeDelegateList<AcceptRenderModelDelegate> acceptRenderModels;
29 private readonly SafeDelegateList<AcceptMeshForRenderingDelegate> acceptPrepareMeshForRenderings;
31 private readonly SafeDelegateList<AcceptRenderMeshDelegate> acceptRenderMeshes;
33 private readonly SafeDelegateList<UpdateMeshesDelegate> updateMeshes;
35 private readonly SafeDelegateList<PreRenderDelegate> preRenders;
37 private readonly SafeDelegateList<PostRenderDelegate> postRenders;
39 private readonly SafeDelegateList<PreEffectUpdateDelegate> preEffectUpdates;
41 private readonly SafeDelegateList<PostEffectUpdateDelegate> postEffectUpdates;
48 public delegate
bool AcceptModelDelegate(
IModelInstance modelInstance);
50 public delegate
bool AcceptMeshForRenderingDelegate(
RenderModel renderModel,
Mesh mesh);
54 public delegate
bool AcceptRenderModelDelegate(
RenderModel renderModel);
58 public delegate
void PreRenderDelegate(
RenderContext context);
60 public delegate
void PostRenderDelegate(
RenderContext context);
73 if (effectName == null)
throw new ArgumentNullException(
"effectName");
74 this.effectName = effectName;
75 DebugName = string.Format(
"ModelRenderer [{0}]", effectName);
79 meshesToRender =
new FastList<RenderMesh>();
81 acceptModels =
new SafeDelegateList<AcceptModelDelegate>(
this);
82 acceptRenderModels =
new SafeDelegateList<AcceptRenderModelDelegate>(
this);
83 acceptPrepareMeshForRenderings =
new SafeDelegateList<AcceptMeshForRenderingDelegate>(
this);
84 acceptRenderMeshes =
new SafeDelegateList<AcceptRenderMeshDelegate>(
this);
85 updateMeshes =
new SafeDelegateList<UpdateMeshesDelegate>(
this) { UpdateMeshesDefault };
86 SortMeshes = DefaultSort;
87 preRenders =
new SafeDelegateList<PreRenderDelegate>(
this);
88 postRenders =
new SafeDelegateList<PostRenderDelegate>(
this);
89 preEffectUpdates =
new SafeDelegateList<PreEffectUpdateDelegate>(
this);
90 postEffectUpdates =
new SafeDelegateList<PostEffectUpdateDelegate>(
this);
93 public string EffectName
101 public SafeDelegateList<AcceptModelDelegate> AcceptModel
109 public SafeDelegateList<AcceptRenderModelDelegate> AcceptRenderModel
113 return acceptRenderModels;
117 public SafeDelegateList<AcceptMeshForRenderingDelegate> AcceptPrepareMeshForRendering
121 return acceptPrepareMeshForRenderings;
125 public SafeDelegateList<AcceptRenderMeshDelegate> AcceptRenderMesh
129 return acceptRenderMeshes;
133 public SafeDelegateList<UpdateMeshesDelegate> UpdateMeshes
141 public UpdateMeshesDelegate SortMeshes {
get; set; }
143 public SafeDelegateList<PreRenderDelegate> PreRender
151 public SafeDelegateList<PostRenderDelegate> PostRender
159 public SafeDelegateList<PreEffectUpdateDelegate> PreEffectUpdate
163 return preEffectUpdates;
167 public SafeDelegateList<PostEffectUpdateDelegate> PostEffectUpdate
171 return postEffectUpdates;
179 var pipelineModelState = Pass.GetOrCreateModelRendererState();
182 meshPassSlot = pipelineModelState.GetModelSlot(Pass);
185 pipelineModelState.AcceptModel += OnAcceptModel;
186 pipelineModelState.PrepareRenderModel += PrepareModelForRendering;
187 pipelineModelState.AcceptRenderModel += OnAcceptRenderModel;
194 var pipelineModelState = Pass.GetOrCreateModelRendererState();
197 pipelineModelState.AcceptModel -= OnAcceptModel;
198 pipelineModelState.PrepareRenderModel -= PrepareModelForRendering;
199 pipelineModelState.AcceptRenderModel -= OnAcceptRenderModel;
204 var state = Pass.GetModelRendererState();
207 meshesToRender.Clear();
208 foreach (var renderModel
in state.RenderModels)
210 var meshes = renderModel.RenderMeshes[meshPassSlot];
212 meshesToRender.AddRange(meshes);
216 foreach (var updateMeshesToRender
in updateMeshes)
218 updateMeshesToRender(context, meshesToRender);
222 if (SortMeshes != null)
224 SortMeshes(context, meshesToRender);
228 foreach (var preRender
in preRenders)
234 foreach (var mesh
in meshesToRender)
237 foreach (var preEffectUpdate
in preEffectUpdates)
239 preEffectUpdate(context, mesh);
246 foreach (var postEffectUpdate
in postEffectUpdates)
248 postEffectUpdate(context, mesh);
255 foreach (var postRender
in postRenders)
261 private void PrepareModelForRendering(
RenderModel renderModel)
265 if (acceptPrepareMeshForRenderings.Count > 0 && !OnAcceptPrepareMeshForRendering(renderModel, mesh))
270 var effectMesh =
new RenderMesh(renderModel, mesh);
271 UpdateEffect(effectMesh);
276 renderModel.RenderMeshes[meshPassSlot] =
new List<RenderMesh>();
278 renderModel.RenderMeshes[meshPassSlot].Add(effectMesh);
282 private void UpdateMeshesDefault(RenderContext context, FastList<RenderMesh> meshes)
284 for (var i = 0; i < meshes.Count; ++i)
286 var mesh = meshes[i];
288 if (!mesh.Enabled || (acceptRenderMeshes.Count > 0 && !OnAcceptRenderMesh(context, mesh)))
290 meshes.SwapRemoveAt(i--);
295 private void DefaultSort(RenderContext context, FastList<RenderMesh> meshes)
298 meshes.Sort(ModelComponentSorter.Default);
301 private bool OnAcceptRenderModel(RenderModel renderModel)
304 foreach (var acceptRenderModel
in AcceptRenderModel)
306 if (!acceptRenderModel(renderModel))
314 private bool OnAcceptModel(IModelInstance modelInstance)
317 foreach (var test
in acceptModels)
319 if (!test(modelInstance))
327 private bool OnAcceptPrepareMeshForRendering(RenderModel renderModel, Mesh mesh)
330 foreach (var test
in acceptPrepareMeshForRenderings)
332 if (!test(renderModel, mesh))
340 private bool OnAcceptRenderMesh(RenderContext context, RenderMesh renderMesh)
343 foreach (var test
in acceptRenderMeshes)
345 if (!test(context, renderMesh))
358 if (dynamicEffectCompiler.Update(renderMesh))
360 renderMesh.Initialize(GraphicsDevice);
368 public class SafeDelegateList<T> : ConstrainedList<T> where T : class
370 private const string ExceptionError =
"The delegate added to the list cannot be null";
374 : base(Constraint,
true, ExceptionError)
376 this.renderer = renderer;
387 base.Insert(index, item);
399 private class ModelComponentSorter :
IComparer<RenderMesh>
401 #region Constants and Fields
403 public static readonly ModelComponentSorter Default =
new ModelComponentSorter();
407 public int Compare(RenderMesh left, RenderMesh right)
409 var xModelComponent = left.RenderModel.ModelInstance;
410 var yModelComponent = right.RenderModel.ModelInstance;
413 if (xModelComponent == null || yModelComponent == null)
417 var leftMaterial = left.Mesh.Material;
418 var isLeftTransparent = (leftMaterial != null && leftMaterial.Parameters.Get(MaterialParameters.UseTransparent));
420 var rightMaterial = right.Mesh.Material;
421 var isRightTransparent = (rightMaterial != null && rightMaterial.Parameters.Get(MaterialParameters.UseTransparent));
423 if (isLeftTransparent && !isRightTransparent)
426 if (!isLeftTransparent && isRightTransparent)
430 return Math.Sign(xModelComponent.DrawOrder - yModelComponent.DrawOrder);
new ModelRenderer Add(T item)
SiliconStudio.Core.IServiceRegistry IServiceRegistry
Performs render pipeline transformations attached to a specific RenderPass.
ModelRenderer(IServiceRegistry services, string effectName)
Initializes a new instance of the ModelRenderer class.
void UpdateEffect(RenderMesh renderMesh)
Create or update the Effect of the effect mesh.
new ModelRenderer Insert(int index, T item)
Provides a dynamic compiler for an effect based on parameters changed.
Thread-local storage context used during rendering.
override void Unload()
Unloads this instance. This method is called when a RenderPass is de-attached (directly or indirectly...
delegate void UpdateMeshesDelegate(RenderPass currentRenderPass, ref FastList< RenderMesh > meshes)
Represent a collection associated with a constraint. When an item is added to this collection...
Instance of a model with its parameters.
Instantiation of a Model through a RenderPipeline.
override void Load()
Loads this instance. This method is called when a RenderPass is attached (directly or indirectly) to ...
List< Mesh > Meshes
Gets the meshes.
override void OnRendering(RenderContext context)
This Renderer is responsible to prepare and render meshes for a specific pass.
readonly List< RenderMesh >[] RenderMeshes
Gets the meshes instantiated for this view.
readonly Model Model
Gets the underlying model.