Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
SpriteRenderer.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 
4 using System;
5 using System.Collections.Generic;
6 
7 using SiliconStudio.Core;
8 using SiliconStudio.Core.Mathematics;
9 using SiliconStudio.Paradox.Effects.Modules;
10 using SiliconStudio.Paradox.Engine;
11 using SiliconStudio.Paradox.EntityModel;
12 using SiliconStudio.Paradox.Games;
13 using SiliconStudio.Paradox.Graphics;
14 
15 namespace SiliconStudio.Paradox.Effects
16 {
17  /// <summary>
18  /// This <see cref="Renderer"/> is responsible to prepare and render sprites for a specific pass.
19  /// </summary>
20  public class SpriteRenderer : Renderer
21  {
22  private SpriteBatch spriteBatch;
23 
24  private readonly IVirtualResolution gameVirtualResolution;
25 
26  private readonly RenderSystem renderSystem;
27 
28  internal readonly List<Entity> EntitiesToRender = new List<Entity>();
29 
30  private static readonly Dictionary<string, List<Entity>> effectNamesToEntityDatas = new Dictionary<string, List<Entity>>();
31 
33  : base(services)
34  {
35  renderSystem = (RenderSystem)services.GetService(typeof(RenderSystem));
36  gameVirtualResolution = (IVirtualResolution)services.GetService(typeof(IVirtualResolution));
37  }
38 
39  private void GameVirtualResolutionChanged(object sender, EventArgs eventArgs)
40  {
41  spriteBatch.VirtualResolution = gameVirtualResolution.VirtualResolution;
42  }
43 
44  public override void Load()
45  {
46  base.Load();
47 
48  spriteBatch = new SpriteBatch(GraphicsDevice);
49 
50  gameVirtualResolution.VirtualResolutionChanged += GameVirtualResolutionChanged;
51  GameVirtualResolutionChanged(null, EventArgs.Empty);
52 
53  renderSystem.SpriteRenderProcessors.Add(this);
54  }
55 
56  public override void Unload()
57  {
58  base.Unload();
59 
60  renderSystem.SpriteRenderProcessors.Remove(this);
61 
62  gameVirtualResolution.VirtualResolutionChanged -= GameVirtualResolutionChanged;
63 
64  spriteBatch.Dispose();
65  }
66 
67  protected override void OnRendering(RenderContext context)
68  {
69  // draw opaque sprites
70  SelectAndSortEntitiesByEffects(SpriteIsOpaque);
71  DrawSprites(context, SpriteSortMode.FrontToBack, GraphicsDevice.BlendStates.Opaque);
72 
73  // draw transparent objects
74  SelectAndSortEntitiesByEffects(SpriteIsTransparent);
75  DrawSprites(context, SpriteSortMode.BackToFront, GraphicsDevice.BlendStates.AlphaBlend);
76  }
77 
78  private bool SpriteIsTransparent(SpriteComponent spriteComponent)
79  {
80  return spriteComponent.CurrentSprite.IsTransparent;
81  }
82 
83  private bool SpriteIsOpaque(SpriteComponent spriteComponent)
84  {
85  return !SpriteIsTransparent(spriteComponent);
86  }
87 
88  private void SelectAndSortEntitiesByEffects(Func<SpriteComponent, bool> shouldSelect)
89  {
90  // clear current cache
91  foreach (var entities in effectNamesToEntityDatas.Values)
92  entities.Clear();
93 
94  // select and sort the entities
95  foreach (var entity in EntitiesToRender)
96  {
97  var spriteComp = entity.Get(SpriteComponent.Key);
98 
99  if (spriteComp.SpriteGroup == null || spriteComp.SpriteGroup.Images == null || !shouldSelect(spriteComp))
100  continue;
101 
102  var effectName = spriteComp.Effect != null ? spriteComp.Effect.Name : "SpriteBatch.DefaultEffect";
103 
104  if (!effectNamesToEntityDatas.ContainsKey(effectName))
105  effectNamesToEntityDatas.Add(effectName, new List<Entity>());
106 
107  effectNamesToEntityDatas[effectName].Add(entity);
108  }
109  }
110 
111  private void DrawSprites(RenderContext context, SpriteSortMode sortMode, BlendState blendState)
112  {
113  var viewParameters = context.CurrentPass.Parameters;
114 
115  var viewMatrix = viewParameters.Get(TransformationKeys.View);
116  var projectionMatrix = viewParameters.Get(TransformationKeys.Projection);
117 
118  foreach (var entities in effectNamesToEntityDatas.Values)
119  {
120  if (entities.Count == 0)
121  continue;
122 
123  spriteBatch.Begin(viewMatrix, projectionMatrix, sortMode, blendState, effect: entities[0].Get(SpriteComponent.Key).Effect);
124 
125  foreach (var entity in entities)
126  {
127  var spriteComp = entity.Get(SpriteComponent.Key);
128  var transfoComp = entity.Get(TransformationComponent.Key);
129 
130  var sprite = spriteComp.CurrentSprite;
131  if (sprite == null)
132  continue;
133 
134  sprite.Draw(
135  spriteBatch,
136  new Vector2(transfoComp.Translation.X, transfoComp.Translation.Y),
138  new Vector2(transfoComp.Scaling.X, transfoComp.Scaling.Y),
139  transfoComp.RotationEulerXYZ.Z,
140  transfoComp.Translation.Z,
141  spriteComp.SpriteEffect);
142  }
143 
144  spriteBatch.End();
145  }
146  }
147  }
148 }
SiliconStudio.Paradox.Games.Mathematics.Vector2 Vector2
Interface providing services to deal with the virtual resolution of the game. The virtual resolution ...
SpriteRenderer(IServiceRegistry services)
Performs render pipeline transformations attached to a specific RenderPass.
Definition: Renderer.cs:13
This Renderer is responsible to prepare and render sprites for a specific pass.
A service registry is a IServiceProvider that provides methods to register and unregister services...
Add a Sprite to an Entity. It could be an animated sprite.
Performs primitive-based rendering, creates resources, handles system-level variables, adjusts gamma ramp levels, and creates shaders. See The+GraphicsDevice+class to learn more about the class.
override void OnRendering(RenderContext context)
readonly BlendState Opaque
A built-in state object with settings for opaque blend, that is overwriting the source with the desti...
SpriteSortMode
Defines sprite sort-rendering options.
Thread-local storage context used during rendering.
SiliconStudio.Core.Mathematics.Color Color
Definition: ColorPicker.cs:14
Renders its RenderSystem.Pipeline, which will usually result in drawing all meshes, UI, etc...
Definition: RenderSystem.cs:18
readonly BlendState AlphaBlend
A built-in state object with settings for alpha blend, that is blending the source and destination da...
override void Unload()
Unloads this instance. This method is called when a RenderPass is de-attached (directly or indirectly...
BlendStateFactory BlendStates
Gets the BlendStates factory.
override void Load()
Loads this instance. This method is called when a RenderPass is attached (directly or indirectly) to ...