Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
SpriteBatch.cs
Go to the documentation of this file.
1using System;
3using System.Text;
4
6
8{
9 private struct SpriteInfo
10 {
12
14
16
17 public float Rotation;
18
19 public float Depth;
20
22
23 public Color Color;
24 }
25
26 private class TextureComparer : IComparer<int>
27 {
29
31 {
32 this.parent = parent;
33 }
34
35 public int Compare(int x, int y)
36 {
37 Texture texture = parent.spriteTextures[x];
39 return texture.CompareTo(other);
40 }
41 }
42
43 private class BackToFrontComparer : IComparer<int>
44 {
46
48 {
49 this.parent = parent;
50 }
51
52 public int Compare(int x, int y)
53 {
54 float depth = parent.spriteQueue[x].Depth;
55 float depth2 = parent.spriteQueue[y].Depth;
56 if (depth > depth2)
57 {
58 return -1;
59 }
60 if (depth < depth2)
61 {
62 return 1;
63 }
64 return 0;
65 }
66 }
67
68 private class FrontToBackComparer : IComparer<int>
69 {
71
73 {
74 this.parent = parent;
75 }
76
77 public int Compare(int x, int y)
78 {
79 float depth = parent.spriteQueue[x].Depth;
80 float depth2 = parent.spriteQueue[y].Depth;
81 if (depth > depth2)
82 {
83 return 1;
84 }
85 if (depth < depth2)
86 {
87 return -1;
88 }
89 return 0;
90 }
91 }
92
93 private const int MaxBatchSize = 2048;
94
96
98
100
102
103 private static readonly float[] xCornerOffsets = new float[4] { 0f, 1f, 1f, 0f };
104
105 private static readonly float[] yCornerOffsets = new float[4] { 0f, 0f, 1f, 1f };
106
108
110
112
114
116
118
120
122
124
125 private bool inBeginEndPair;
126
127 private SpriteInfo[] spriteQueue = new SpriteInfo[2048];
128
129 private int spriteQueueCount;
130
132
133 private int[] sortIndices;
134
136
138
140
142
143 private static Vector2 vector2Zero = Vector2.Zero;
144
145 private static Rectangle? nullRectangle = null;
146
148 {
150 }
151
152 private void DisposePlatformData()
153 {
154 if (vertexBuffer != null)
155 {
157 }
158 if (indexBuffer != null)
159 {
161 }
162 }
163
164 private void AllocateBuffers()
165 {
166 if (vertexBuffer == null || vertexBuffer.IsDisposed)
167 {
170 vertexBuffer.ContentLost += delegate
171 {
173 };
174 }
175 if (indexBuffer == null || indexBuffer.IsDisposed)
176 {
177 indexBuffer = new DynamicIndexBuffer(_parent, typeof(short), 12288, BufferUsage.WriteOnly);
178 indexBuffer.SetData(CreateIndexData());
179 indexBuffer.ContentLost += delegate
180 {
181 indexBuffer.SetData(CreateIndexData());
182 };
183 }
184 }
185
186 private static short[] CreateIndexData()
187 {
188 short[] array = new short[12288];
189 for (int i = 0; i < 2048; i++)
190 {
191 array[i * 6] = (short)(i * 4);
192 array[i * 6 + 1] = (short)(i * 4 + 1);
193 array[i * 6 + 2] = (short)(i * 4 + 2);
194 array[i * 6 + 3] = (short)(i * 4);
195 array[i * 6 + 4] = (short)(i * 4 + 2);
196 array[i * 6 + 5] = (short)(i * 4 + 3);
197 }
198 return array;
199 }
200
202 {
205 _parent.Indices = indexBuffer;
206 }
207
208 private unsafe void PlatformRenderBatch(Texture2D texture, SpriteInfo[] sprites, int offset, int count)
209 {
210 float num = 1f / (float)texture.Width;
211 float num2 = 1f / (float)texture.Height;
212 while (count > 0)
213 {
215 int num3 = count;
216 if (num3 > 2048 - vertexBufferPosition)
217 {
218 num3 = 2048 - vertexBufferPosition;
219 if (num3 < 256)
220 {
222 options = SetDataOptions.Discard;
223 num3 = count;
224 if (num3 > 2048)
225 {
226 num3 = 2048;
227 }
228 }
229 }
231 {
233 {
236 for (int i = 0; i < num3; i++)
237 {
238 float num4;
239 float num5;
240 if (ptr2->Rotation != 0f)
241 {
242 num4 = (float)Math.Cos(ptr2->Rotation);
243 num5 = (float)Math.Sin(ptr2->Rotation);
244 }
245 else
246 {
247 num4 = 1f;
248 num5 = 0f;
249 }
250 float num6 = ((ptr2->Source.Z != 0f) ? (ptr2->Origin.X / ptr2->Source.Z) : (ptr2->Origin.X * 2E+32f));
251 float num7 = ((ptr2->Source.W != 0f) ? (ptr2->Origin.Y / ptr2->Source.W) : (ptr2->Origin.Y * 2E+32f));
252 for (int j = 0; j < 4; j++)
253 {
254 float num8 = xCornerOffsets[j];
255 float num9 = yCornerOffsets[j];
256 float num10 = (num8 - num6) * ptr2->Destination.Z;
257 float num11 = (num9 - num7) * ptr2->Destination.W;
258 float x = ptr2->Destination.X + num10 * num4 - num11 * num5;
259 float y = ptr2->Destination.Y + num10 * num5 + num11 * num4;
260 if ((ptr2->Effects & SpriteEffects.FlipHorizontally) != 0)
261 {
262 num8 = 1f - num8;
263 }
264 if ((ptr2->Effects & SpriteEffects.FlipVertically) != 0)
265 {
266 num9 = 1f - num9;
267 }
268 ptr4->Position.X = x;
269 ptr4->Position.Y = y;
270 ptr4->Position.Z = ptr2->Depth;
271 ptr4->Color = ptr2->Color;
272 ptr4->TextureCoordinate.X = (ptr2->Source.X + num8 * ptr2->Source.Z) * num;
273 ptr4->TextureCoordinate.Y = (ptr2->Source.Y + num9 * ptr2->Source.W) * num2;
274 ptr4++;
275 }
276 ptr2++;
277 }
278 }
279 }
280 int num12 = sizeof(VertexPositionColorTexture);
284 int numVertices = num3 * 4;
286 int primitiveCount = num3 * 2;
287 _parent.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, minVertexIndex, numVertices, startIndex, primitiveCount);
289 offset += num3;
290 count -= num3;
291 }
292 }
293
294 public SpriteBatch(GraphicsDevice graphicsDevice)
295 {
296 if (graphicsDevice == null)
297 {
299 }
300 _parent = graphicsDevice;
301 spriteEffect = new Effect(graphicsDevice, SpriteEffectCode.Code);
302 effectMatrixTransform = spriteEffect.Parameters["MatrixTransform"];
304 }
305
306 protected override void Dispose(bool disposing)
307 {
308 try
309 {
310 if (disposing && !base.IsDisposed)
311 {
312 if (spriteEffect != null)
313 {
315 }
317 }
318 }
319 finally
320 {
321 base.Dispose(disposing);
322 }
323 }
324
325 public void Begin()
326 {
327 Begin(SpriteSortMode.Deferred, null, null, null, null, null, Matrix.Identity);
328 }
329
331 {
332 Begin(sortMode, blendState, null, null, null, null, Matrix.Identity);
333 }
334
339
344
374
375 public void End()
376 {
377 if (!inBeginEndPair)
378 {
380 }
381 if (spriteSortMode != SpriteSortMode.Immediate)
382 {
384 }
385 else
386 {
388 }
389 if (spriteQueueCount > 0)
390 {
391 Flush();
392 }
393 inBeginEndPair = false;
395 }
396
397 public void Draw(Texture2D texture, Vector2 position, Color color)
398 {
399 Vector4 destination = default(Vector4);
400 destination.X = position.X;
401 destination.Y = position.Y;
402 destination.Z = 1f;
403 destination.W = 1f;
405 }
406
407 public void Draw(Texture2D texture, Vector2 position, Rectangle? sourceRectangle, Color color)
408 {
409 Vector4 destination = default(Vector4);
410 destination.X = position.X;
411 destination.Y = position.Y;
412 destination.Z = 1f;
413 destination.W = 1f;
415 }
416
417 public void Draw(Texture2D texture, Vector2 position, Rectangle? sourceRectangle, Color color, float rotation, Vector2 origin, float scale, SpriteEffects effects, float layerDepth)
418 {
419 Vector4 destination = default(Vector4);
420 destination.X = position.X;
421 destination.Y = position.Y;
422 destination.Z = scale;
423 destination.W = scale;
424 InternalDraw(texture, ref destination, scaleDestination: true, ref sourceRectangle, color, rotation, ref origin, effects, layerDepth);
425 }
426
427 public void Draw(Texture2D texture, Vector2 position, Rectangle? sourceRectangle, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth)
428 {
429 Vector4 destination = default(Vector4);
430 destination.X = position.X;
431 destination.Y = position.Y;
432 destination.Z = scale.X;
433 destination.W = scale.Y;
434 InternalDraw(texture, ref destination, scaleDestination: true, ref sourceRectangle, color, rotation, ref origin, effects, layerDepth);
435 }
436
437 public void Draw(Texture2D texture, Rectangle destinationRectangle, Color color)
438 {
439 Vector4 destination = default(Vector4);
440 destination.X = destinationRectangle.X;
441 destination.Y = destinationRectangle.Y;
442 destination.Z = destinationRectangle.Width;
443 destination.W = destinationRectangle.Height;
445 }
446
447 public void Draw(Texture2D texture, Rectangle destinationRectangle, Rectangle? sourceRectangle, Color color)
448 {
449 Vector4 destination = default(Vector4);
450 destination.X = destinationRectangle.X;
451 destination.Y = destinationRectangle.Y;
452 destination.Z = destinationRectangle.Width;
453 destination.W = destinationRectangle.Height;
455 }
456
457 public void Draw(Texture2D texture, Rectangle destinationRectangle, Rectangle? sourceRectangle, Color color, float rotation, Vector2 origin, SpriteEffects effects, float layerDepth)
458 {
459 Vector4 destination = default(Vector4);
460 destination.X = destinationRectangle.X;
461 destination.Y = destinationRectangle.Y;
462 destination.Z = destinationRectangle.Width;
463 destination.W = destinationRectangle.Height;
464 InternalDraw(texture, ref destination, scaleDestination: false, ref sourceRectangle, color, rotation, ref origin, effects, layerDepth);
465 }
466
467 public void DrawString(SpriteFont spriteFont, string text, Vector2 position, Color color)
468 {
469 if (spriteFont == null)
470 {
471 throw new ArgumentNullException("spriteFont");
472 }
473 if (text == null)
474 {
475 throw new ArgumentNullException("text");
476 }
478 Vector2 scale = Vector2.One;
479 spriteFont.InternalDraw(ref text2, this, position, color, 0f, Vector2.Zero, ref scale, SpriteEffects.None, 0f);
480 }
481
483 {
484 if (spriteFont == null)
485 {
486 throw new ArgumentNullException("spriteFont");
487 }
488 if (text == null)
489 {
490 throw new ArgumentNullException("text");
491 }
493 Vector2 scale = Vector2.One;
494 spriteFont.InternalDraw(ref text2, this, position, color, 0f, Vector2.Zero, ref scale, SpriteEffects.None, 0f);
495 }
496
497 public void DrawString(SpriteFont spriteFont, string text, Vector2 position, Color color, float rotation, Vector2 origin, float scale, SpriteEffects effects, float layerDepth)
498 {
499 if (spriteFont == null)
500 {
501 throw new ArgumentNullException("spriteFont");
502 }
503 if (text == null)
504 {
505 throw new ArgumentNullException("text");
506 }
508 Vector2 scale2 = default(Vector2);
509 scale2.X = scale;
510 scale2.Y = scale;
511 spriteFont.InternalDraw(ref text2, this, position, color, rotation, origin, ref scale2, effects, layerDepth);
512 }
513
514 public void DrawString(SpriteFont spriteFont, StringBuilder text, Vector2 position, Color color, float rotation, Vector2 origin, float scale, SpriteEffects effects, float layerDepth)
515 {
516 if (spriteFont == null)
517 {
518 throw new ArgumentNullException("spriteFont");
519 }
520 if (text == null)
521 {
522 throw new ArgumentNullException("text");
523 }
525 Vector2 scale2 = default(Vector2);
526 scale2.X = scale;
527 scale2.Y = scale;
528 spriteFont.InternalDraw(ref text2, this, position, color, rotation, origin, ref scale2, effects, layerDepth);
529 }
530
531 public void DrawString(SpriteFont spriteFont, string text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth)
532 {
533 if (spriteFont == null)
534 {
535 throw new ArgumentNullException("spriteFont");
536 }
537 if (text == null)
538 {
539 throw new ArgumentNullException("text");
540 }
542 spriteFont.InternalDraw(ref text2, this, position, color, rotation, origin, ref scale, effects, layerDepth);
543 }
544
545 public void DrawString(SpriteFont spriteFont, StringBuilder text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth)
546 {
547 if (spriteFont == null)
548 {
549 throw new ArgumentNullException("spriteFont");
550 }
551 if (text == null)
552 {
553 throw new ArgumentNullException("text");
554 }
556 spriteFont.InternalDraw(ref text2, this, position, color, rotation, origin, ref scale, effects, layerDepth);
557 }
558
559 private unsafe void InternalDraw(Texture2D texture, ref Vector4 destination, bool scaleDestination, ref Rectangle? sourceRectangle, Color color, float rotation, ref Vector2 origin, SpriteEffects effects, float depth)
560 {
561 if (texture == null)
562 {
564 }
565 if (!inBeginEndPair)
566 {
568 }
569 if (spriteQueueCount >= spriteQueue.Length)
570 {
571 Array.Resize(ref spriteQueue, spriteQueue.Length * 2);
572 }
574 {
575 float num = destination.Z;
576 float num2 = destination.W;
577 if (sourceRectangle.HasValue)
578 {
580 ptr->Source.X = value.X;
581 ptr->Source.Y = value.Y;
582 ptr->Source.Z = value.Width;
583 ptr->Source.W = value.Height;
585 {
586 num *= (float)value.Width;
587 num2 *= (float)value.Height;
588 }
589 }
590 else
591 {
592 float num3 = texture.Width;
593 float num4 = texture.Height;
594 ptr->Source.X = 0f;
595 ptr->Source.Y = 0f;
596 ptr->Source.Z = num3;
597 ptr->Source.W = num4;
599 {
600 num *= num3;
601 num2 *= num4;
602 }
603 }
604 ptr->Destination.X = destination.X;
605 ptr->Destination.Y = destination.Y;
606 ptr->Destination.Z = num;
607 ptr->Destination.W = num2;
608 ptr->Origin.X = origin.X;
609 ptr->Origin.Y = origin.Y;
610 ptr->Rotation = rotation;
611 ptr->Depth = depth;
612 ptr->Effects = effects;
613 ptr->Color = color;
614 }
615 if (spriteSortMode == SpriteSortMode.Immediate)
616 {
617 RenderBatch(texture, spriteQueue, 0, 1);
618 return;
619 }
620 if (spriteTextures == null || spriteTextures.Length != spriteQueue.Length)
621 {
622 Array.Resize(ref spriteTextures, spriteQueue.Length);
623 }
626 }
627
628 private void Flush()
629 {
631 if (spriteSortMode == SpriteSortMode.Deferred)
632 {
634 }
635 else
636 {
637 SortSprites();
639 }
640 int num = 0;
641 Texture2D texture2D = null;
642 for (int i = 0; i < spriteQueueCount; i++)
643 {
645 if (spriteSortMode == SpriteSortMode.Deferred)
646 {
648 }
649 else
650 {
651 int num2 = sortIndices[i];
655 }
656 if (texture2D2 != texture2D)
657 {
658 if (i > num)
659 {
660 RenderBatch(texture2D, array, num, i - num);
661 }
662 num = i;
664 }
665 }
669 }
670
671 private void SortSprites()
672 {
673 if (sortIndices == null || sortIndices.Length < spriteQueueCount)
674 {
675 sortIndices = new int[spriteQueueCount];
677 }
679 switch (spriteSortMode)
680 {
681 case SpriteSortMode.Texture:
682 if (textureComparer == null)
683 {
685 }
687 break;
688 case SpriteSortMode.BackToFront:
689 if (backToFrontComparer == null)
690 {
692 }
694 break;
695 case SpriteSortMode.FrontToBack:
696 if (frontToBackComparer == null)
697 {
699 }
701 break;
702 default:
703 throw new NotSupportedException();
704 }
705 for (int i = 0; i < spriteQueueCount; i++)
706 {
707 sortIndices[i] = i;
708 }
710 }
711
712 private void RenderBatch(Texture2D texture, SpriteInfo[] sprites, int offset, int count)
713 {
714 if (customEffect != null)
715 {
717 for (int i = 0; i < count2; i++)
718 {
720 _parent.Textures[0] = texture;
722 }
723 }
724 else
725 {
726 _parent.Textures[0] = texture;
728 }
729 }
730
731 private void SetRenderState()
732 {
733 if (blendState != null)
734 {
735 _parent.BlendState = blendState;
736 }
737 else
738 {
739 _parent.BlendState = BlendState.AlphaBlend;
740 }
741 if (depthStencilState != null)
742 {
743 _parent.DepthStencilState = depthStencilState;
744 }
745 else
746 {
747 _parent.DepthStencilState = DepthStencilState.None;
748 }
749 if (rasterizerState != null)
750 {
751 _parent.RasterizerState = rasterizerState;
752 }
753 else
754 {
755 _parent.RasterizerState = RasterizerState.CullCounterClockwise;
756 }
757 if (samplerState != null)
758 {
760 }
761 else
762 {
764 }
765 Viewport viewport = _parent.Viewport;
766 float num = ((viewport.Width > 0) ? (1f / (float)viewport.Width) : 0f);
767 float num2 = ((viewport.Height > 0) ? (-1f / (float)viewport.Height) : 0f);
768 Matrix matrix = default(Matrix);
769 matrix.M11 = num * 2f;
770 matrix.M22 = num2 * 2f;
771 matrix.M33 = 1f;
772 matrix.M44 = 1f;
773 matrix.M41 = -1f;
774 matrix.M42 = 1f;
775 matrix.M41 -= num;
776 matrix.M42 -= num2;
780 }
781}
static readonly BlendState AlphaBlend
Definition BlendState.cs:36
override void Dispose([MarshalAs(UnmanagedType.U1)] bool P_0)
Definition Effect.cs:516
EffectParameterCollection Parameters
Definition Effect.cs:29
unsafe EffectTechnique CurrentTechnique
Definition Effect.cs:34
unsafe void SetVertexBuffer(VertexBuffer vertexBuffer, int vertexOffset)
unsafe void DrawIndexedPrimitives(PrimitiveType primitiveType, int baseVertex, int minVertexIndex, int numVertices, int startIndex, int primitiveCount)
override void Dispose([MarshalAs(UnmanagedType.U1)] bool P_0)
static readonly RasterizerState CullCounterClockwise
static readonly SamplerState LinearClamp
void Draw(Texture2D texture, Vector2 position, Rectangle? sourceRectangle, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth)
VertexPositionColorTexture[] outputVertices
void Draw(Texture2D texture, Vector2 position, Rectangle? sourceRectangle, Color color)
void Begin(SpriteSortMode sortMode, BlendState blendState)
void Draw(Texture2D texture, Rectangle destinationRectangle, Rectangle? sourceRectangle, Color color)
void Begin(SpriteSortMode sortMode, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, RasterizerState rasterizerState, Effect effect)
void Draw(Texture2D texture, Vector2 position, Color color)
void DrawString(SpriteFont spriteFont, StringBuilder text, Vector2 position, Color color)
void DrawString(SpriteFont spriteFont, StringBuilder text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth)
void Draw(Texture2D texture, Rectangle destinationRectangle, Rectangle? sourceRectangle, Color color, float rotation, Vector2 origin, SpriteEffects effects, float layerDepth)
void DrawString(SpriteFont spriteFont, string text, Vector2 position, Color color)
void Begin(SpriteSortMode sortMode, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, RasterizerState rasterizerState)
override void Dispose(bool disposing)
void DrawString(SpriteFont spriteFont, string text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth)
unsafe void InternalDraw(Texture2D texture, ref Vector4 destination, bool scaleDestination, ref Rectangle? sourceRectangle, Color color, float rotation, ref Vector2 origin, SpriteEffects effects, float depth)
void Begin(SpriteSortMode sortMode, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, RasterizerState rasterizerState, Effect effect, Matrix transformMatrix)
SpriteBatch(GraphicsDevice graphicsDevice)
void DrawString(SpriteFont spriteFont, StringBuilder text, Vector2 position, Color color, float rotation, Vector2 origin, float scale, SpriteEffects effects, float layerDepth)
unsafe void PlatformRenderBatch(Texture2D texture, SpriteInfo[] sprites, int offset, int count)
void RenderBatch(Texture2D texture, SpriteInfo[] sprites, int offset, int count)
void Draw(Texture2D texture, Vector2 position, Rectangle? sourceRectangle, Color color, float rotation, Vector2 origin, float scale, SpriteEffects effects, float layerDepth)
void Draw(Texture2D texture, Rectangle destinationRectangle, Color color)
void DrawString(SpriteFont spriteFont, string text, Vector2 position, Color color, float rotation, Vector2 origin, float scale, SpriteEffects effects, float layerDepth)
unsafe int CompareTo(Texture other)
Definition Texture.cs:364
override void Dispose([MarshalAs(UnmanagedType.U1)] bool P_0)
static void Sort(Array array)
Definition Array.cs:2329
static unsafe void Clear(Array array)
Definition Array.cs:755
static double Cos(double d)
static double Sin(double a)