PageRenderTime 84ms CodeModel.GetById 41ms app.highlight 7ms RepoModel.GetById 33ms app.codeStats 0ms

/Rendering/Basics/Materials/Material2DColored.cs

#
C# | 255 lines | 114 code | 16 blank | 125 comment | 8 complexity | a786dbfeab1ebca91b83da5f5a602f2c MD5 | raw file
  1using Delta.ContentSystem;
  2using Delta.Graphics.Basics;
  3using Delta.Rendering.Enums;
  4using Delta.Utilities.Datatypes;
  5using Delta.Utilities.Graphics.ShaderFeatures;
  6
  7namespace Delta.Rendering.Basics.Materials
  8{
  9	/// <summary>
 10	/// Vertex colored Material 2D, used for particle effects and coloring UI
 11	/// elements in UI screens. Using this class instead of Material2D is a bit
 12	/// slower because we need to send vertex colors to the GPU.
 13	/// </summary>
 14	public class Material2DColored : MaterialColored
 15	{
 16		#region Default (Static)
 17		/// <summary>
 18		/// The default material which is always used if no material is explictly
 19		/// set. Will be created the first time this is used, which is quite
 20		/// likely for unit test code and if some material is missing or wrong,
 21		/// but not so much true for the real games later. Also delayed loading
 22		/// is much better for the application initialization time.
 23		/// </summary>
 24		public new static Material2DColored Default
 25		{
 26			get
 27			{
 28				if (defaultMaterial2DColored == null)
 29				{
 30					defaultMaterial2DColored = new Material2DColored(Content.EmptyName);
 31				}
 32
 33				return defaultMaterial2DColored;
 34			}
 35		}
 36		#endregion
 37
 38		#region Private
 39
 40		#region defaultMaterial2DColored (Private)
 41		/// <summary>
 42		/// Default material 2D
 43		/// </summary>
 44		private static Material2DColored defaultMaterial2DColored;
 45		#endregion
 46
 47		#endregion
 48
 49		#region Constructors
 50		/// <summary>
 51		/// Create material from just a diffuse map image name and a the default
 52		/// blend color. The material will always just use the basic shader with
 53		/// vertex coloring. That is mostly used for UI rendering.
 54		/// </summary>
 55		/// <param name="setDiffuseMapName">
 56		/// The name of the  diffuse map to use.
 57		/// </param>
 58		public Material2DColored(string setDiffuseMapName)
 59			: base(setDiffuseMapName, Shader.Create(
 60				ShaderFeatureFlags.Basic |
 61				ShaderFeatureFlags.UI2D |
 62				ShaderFeatureFlags.ColoredVertices))
 63		{
 64			// Note: The shader is always 2D, no need to check: shader.Is2D
 65		}
 66
 67		/// <summary>
 68		/// Create material from just a diffuse map image name and a given
 69		/// blend color. The material will always just use the basic shader with
 70		/// vertex coloring. That is mostly used for UI rendering.
 71		/// </summary>
 72		/// <param name="setDiffuseMapName">Diffuse map name.</param>
 73		/// <param name="setColor">The tint color to apply during draw.</param>
 74		public Material2DColored(string setDiffuseMapName, Color setColor)
 75			: base(setDiffuseMapName, Shader.Create(
 76				ShaderFeatureFlags.Basic |
 77				ShaderFeatureFlags.UI2D |
 78				ShaderFeatureFlags.ColoredVertices))
 79		{
 80			BlendColor = setColor;
 81			// Note: The shader is always 2D, no need to check: shader.Is2D
 82		}
 83
 84		/// <summary>
 85		/// Create material from just a diffuse map image name and a the default
 86		/// blend color. The material will always just use the basic shader with
 87		/// vertex coloring. That is mostly used for UI rendering.
 88		/// </summary>
 89		/// <param name="setColor">The color that the material should have.</param>
 90		public Material2DColored(Color setColor)
 91			: base(Content.EmptyName, Shader.Create(
 92				ShaderFeatureFlags.UI2D |
 93				ShaderFeatureFlags.NoTexturing |
 94				ShaderFeatureFlags.ColoredVertices))
 95		{
 96			BlendColor = setColor;
 97			// Note: The shader is always 2D, no need to check: shader.Is2D
 98		}
 99		#endregion
100
101		#region Clone (Public)
102		/// <summary>
103		/// Returns a new instance of this Material2DColored, which we can change
104		/// without modifying the original. Useful for the Default material (see
105		/// property above) or for different material settings on the same image.
106		/// </summary>
107		/// <returns>New Material2DColored with the same settings</returns>
108		public Material2DColored Clone()
109		{
110			return new Material2DColored(BlendColor)
111			{
112				shader = shader,
113				diffuseMap = diffuseMap,
114			};
115		}
116		#endregion
117
118		#region Draw (Public)
119		/// <summary>
120		/// Draw this colored 2D material at the specified rectangle location.
121		/// Use the other overloads for more options (at the cost of performance)
122		/// like rotation, flipping, overwriting UVs, etc.
123		/// </summary>
124		/// <param name="drawArea">
125		/// Draw area to render to, rendering will be skipped if this is
126		/// completely outside of the 0-1 quadratic screen space.
127		/// </param>
128		public void Draw(Rectangle drawArea)
129		{
130			// Skip if the drawArea is certainly outside of the quadratic space.
131			// Checking the screen area would work too, but is a little slower and
132			// won't exclude much more anyway.
133			if (drawArea.Left >= 1.0f ||
134					drawArea.Top >= 1.0f ||
135					drawArea.Left < -drawArea.Width ||
136					drawArea.Top < -drawArea.Height)
137			{
138				// Skip this material rendering, not visible this frame.
139				return;
140			}
141
142			cachedLayer.Add(this, drawArea);
143		}
144
145		/// <summary>
146		/// Draw this colored 2D material at the specified rectangle location.
147		/// Use the other overloads for more options (at the cost of performance)
148		/// like rotation, flipping, overwriting UVs, etc.
149		/// </summary>
150		/// <param name="drawArea">
151		/// Draw area to render to, rendering will be skipped if this is
152		/// completely outside of the 0-1 quadratic screen space.
153		/// </param>
154		/// <param name="rotation">
155		/// Rotation for this material drawing in degrees. By default unused=0.
156		/// </param>
157		/// <param name="flipMode">
158		/// Flipping is useful to display materials in different ways. Just
159		/// rotating is often enough, but sometimes flipping is needed (e.g. for
160		/// RenderTargets or to make non-tileable textures pseudo-tilable).
161		/// FlipMode.Vertical and FlipMode.Horizontal can be combined (which is
162		/// FlipMode.VerticalAndHorizontal, the same as rotating 180 degrees).
163		/// </param>
164		public void Draw(Rectangle drawArea, float rotation,
165			FlipMode flipMode = FlipMode.None)
166		{
167			// Skip if the drawArea is certainly outside of the quadratic space.
168			// Checking the screen area would work too, but is a little slower and
169			// won't exclude much more anyway.
170			if (drawArea.Left >= 1.0f ||
171					drawArea.Top >= 1.0f ||
172					drawArea.Left < -drawArea.Width ||
173					drawArea.Top < -drawArea.Height)
174			{
175				// Skip this material rendering, not visible this frame.
176				return;
177			}
178
179			// No rotation needed? Then render a bit faster.
180			if (rotation == 0.0f &&
181				flipMode == FlipMode.None)
182			{
183				cachedLayer.Add(this, drawArea);
184			}
185			else
186			{
187				cachedLayer.Add(this, drawArea, rotation, drawArea.Center, flipMode);
188			}
189		}
190
191		/// <summary>
192		/// Draw this 2D material at the specified rectangle location and
193		/// optionally rotating and flipping it.
194		/// </summary>
195		/// <param name="drawArea">
196		/// Draw area to render to, rendering will be skipped if this is
197		/// completely outside of the 0-1 quadratic screen space.
198		/// </param>
199		/// <param name="rotation">
200		/// Rotation for this material drawing in degrees. By default unused=0.
201		/// </param>
202		/// <param name="rotationCenter">
203		/// Center for the rotation. If you want it to be centered around the
204		/// drawArea use drawArea.Center or just use the other Draw overloads.
205		/// Note: This rotationCenter is always absolute, add drawArea.Center to
206		/// make it relative to the local drawArea.
207		/// </param>
208		/// <param name="flipMode">
209		/// Flipping is useful to display materials in different ways. Just
210		/// rotating is often enough, but sometimes flipping is needed (e.g. for
211		/// RenderTargets or to make non-tileable textures pseudo-tilable).
212		/// FlipMode.Vertical and FlipMode.Horizontal can be combined (which is
213		/// FlipMode.VerticalAndHorizontal, the same as rotating 180 degrees).
214		/// </param>
215		public void Draw(Rectangle drawArea, float rotation, Point rotationCenter,
216			FlipMode flipMode = FlipMode.None)
217		{
218			// Skip if the drawArea is certainly outside of the quadratic space.
219			// Checking the screen area would work too, but is a little slower and
220			// won't exclude much more anyway.
221			if (drawArea.Left >= 1.0f ||
222			    drawArea.Top >= 1.0f ||
223			    drawArea.Left < -drawArea.Width ||
224			    drawArea.Top < -drawArea.Height)
225			{
226				// Skip this material rendering, not visible this frame.
227				return;
228			}
229
230			cachedLayer.Add(this, drawArea, rotation, rotationCenter, flipMode);
231		}
232
233		/// <summary>
234		/// Draw this 2D material at the specified rectangle location and custom
235		/// UV rectangle and optionally rotating it.
236		/// </summary>
237		/// <param name="drawArea">
238		/// Draw area to render to, rendering will be skipped if this is
239		/// completely outside of the 0-1 quadratic screen space.
240		/// </param>
241		/// <param name="uvAreaOverride">
242		/// UV area override to render a custom UV rectangle (you must apply all
243		/// atlas UV remapping yourself).
244		/// </param>
245		/// <param name="rotation">
246		/// Rotation for this material drawing in degrees. By default unused=0.
247		/// </param>
248		public void Draw(Rectangle drawArea, Rectangle uvAreaOverride,
249			float rotation = 0.0f)
250		{
251			cachedLayer.Add(this, drawArea, rotation, BlendColor, uvAreaOverride);
252		}
253		#endregion
254	}
255}