Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
TileBatch.cs
Go to the documentation of this file.
1using System;
4
5namespace Terraria.Graphics;
6
7public class TileBatch
8{
9 private struct SpriteData
10 {
12
14
16
18
20
21 public float Rotation;
22 }
23
24 private static readonly float[] CORNER_OFFSET_X = new float[4] { 0f, 1f, 1f, 0f };
25
26 private static readonly float[] CORNER_OFFSET_Y = new float[4] { 0f, 0f, 1f, 1f };
27
29
30 private SpriteData[] _spriteDataQueue = new SpriteData[2048];
31
33
34 private int _queuedSpriteCount;
35
37
38 private static Vector2 _vector2Zero;
39
40 private static Rectangle? _nullRectangle;
41
43
45
46 private short[] _fallbackIndexData;
47
49
51
52 public TileBatch(GraphicsDevice graphicsDevice)
53 {
54 _graphicsDevice = graphicsDevice;
55 _spriteBatch = new SpriteBatch(graphicsDevice);
56 Allocate();
57 }
58
59 private void Allocate()
60 {
62 {
65 _vertexBuffer.ContentLost += delegate
66 {
68 };
69 }
70 if (_indexBuffer != null && !_indexBuffer.IsDisposed)
71 {
72 return;
73 }
74 if (_fallbackIndexData == null)
75 {
76 _fallbackIndexData = new short[12288];
77 for (int i = 0; i < 2048; i++)
78 {
79 _fallbackIndexData[i * 6] = (short)(i * 4);
80 _fallbackIndexData[i * 6 + 1] = (short)(i * 4 + 1);
81 _fallbackIndexData[i * 6 + 2] = (short)(i * 4 + 2);
82 _fallbackIndexData[i * 6 + 3] = (short)(i * 4);
83 _fallbackIndexData[i * 6 + 4] = (short)(i * 4 + 2);
84 _fallbackIndexData[i * 6 + 5] = (short)(i * 4 + 3);
85 }
86 }
87 _indexBuffer = new DynamicIndexBuffer(_graphicsDevice, typeof(short), 12288, BufferUsage.WriteOnly);
89 _indexBuffer.ContentLost += delegate
90 {
92 };
93 }
94
95 private void FlushRenderState()
96 {
97 Allocate();
99 _graphicsDevice.Indices = _indexBuffer;
101 }
102
103 public void Dispose()
104 {
105 if (_vertexBuffer != null)
106 {
108 }
109 if (_indexBuffer != null)
110 {
112 }
113 }
114
115 public void Begin(RasterizerState rasterizer, Matrix transformation)
116 {
117 _spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, rasterizer, null, transformation);
119 }
120
121 public void Begin()
122 {
125 }
126
127 public void Draw(Texture2D texture, Vector2 position, VertexColors colors)
128 {
129 Vector4 destination = default(Vector4);
130 destination.X = position.X;
131 destination.Y = position.Y;
132 destination.Z = 1f;
133 destination.W = 1f;
134 InternalDraw(texture, ref destination, scaleDestination: true, ref _nullRectangle, ref colors, ref _vector2Zero, SpriteEffects.None, 0f);
135 }
136
137 public void Draw(Texture2D texture, Vector2 position, Rectangle? sourceRectangle, VertexColors colors, Vector2 origin, float scale, SpriteEffects effects)
138 {
139 Vector4 destination = default(Vector4);
140 destination.X = position.X;
141 destination.Y = position.Y;
142 destination.Z = scale;
143 destination.W = scale;
144 InternalDraw(texture, ref destination, scaleDestination: true, ref sourceRectangle, ref colors, ref origin, effects, 0f);
145 }
146
147 public void Draw(Texture2D texture, Vector4 destination, VertexColors colors)
148 {
149 InternalDraw(texture, ref destination, scaleDestination: false, ref _nullRectangle, ref colors, ref _vector2Zero, SpriteEffects.None, 0f);
150 }
151
152 public void Draw(Texture2D texture, Vector2 position, VertexColors colors, Vector2 scale)
153 {
154 Vector4 destination = default(Vector4);
155 destination.X = position.X;
156 destination.Y = position.Y;
157 destination.Z = scale.X;
158 destination.W = scale.Y;
159 InternalDraw(texture, ref destination, scaleDestination: true, ref _nullRectangle, ref colors, ref _vector2Zero, SpriteEffects.None, 0f);
160 }
161
162 public void Draw(Texture2D texture, Vector4 destination, Rectangle? sourceRectangle, VertexColors colors)
163 {
164 InternalDraw(texture, ref destination, scaleDestination: false, ref sourceRectangle, ref colors, ref _vector2Zero, SpriteEffects.None, 0f);
165 }
166
167 public void Draw(Texture2D texture, Vector4 destination, Rectangle? sourceRectangle, VertexColors colors, Vector2 origin, SpriteEffects effects, float rotation)
168 {
169 InternalDraw(texture, ref destination, scaleDestination: false, ref sourceRectangle, ref colors, ref origin, effects, rotation);
170 }
171
172 public void Draw(Texture2D texture, Rectangle destinationRectangle, Rectangle? sourceRectangle, VertexColors colors)
173 {
174 Vector4 destination = default(Vector4);
175 destination.X = destinationRectangle.X;
176 destination.Y = destinationRectangle.Y;
177 destination.Z = destinationRectangle.Width;
178 destination.W = destinationRectangle.Height;
179 InternalDraw(texture, ref destination, scaleDestination: false, ref sourceRectangle, ref colors, ref _vector2Zero, SpriteEffects.None, 0f);
180 }
181
182 private static short[] CreateIndexData()
183 {
184 short[] array = new short[12288];
185 for (int i = 0; i < 2048; i++)
186 {
187 array[i * 6] = (short)(i * 4);
188 array[i * 6 + 1] = (short)(i * 4 + 1);
189 array[i * 6 + 2] = (short)(i * 4 + 2);
190 array[i * 6 + 3] = (short)(i * 4);
191 array[i * 6 + 4] = (short)(i * 4 + 2);
192 array[i * 6 + 5] = (short)(i * 4 + 3);
193 }
194 return array;
195 }
196
197 private unsafe void InternalDraw(Texture2D texture, ref Vector4 destination, bool scaleDestination, ref Rectangle? sourceRectangle, ref VertexColors colors, ref Vector2 origin, SpriteEffects effects, float rotation)
198 {
200 {
201 Array.Resize(ref _spriteDataQueue, _spriteDataQueue.Length << 1);
202 }
204 {
205 float num = destination.Z;
206 float num2 = destination.W;
207 if (sourceRectangle.HasValue)
208 {
209 Rectangle value = sourceRectangle.Value;
210 ptr->Source.X = value.X;
211 ptr->Source.Y = value.Y;
212 ptr->Source.Z = value.Width;
213 ptr->Source.W = value.Height;
214 if (scaleDestination)
215 {
216 num *= (float)value.Width;
217 num2 *= (float)value.Height;
218 }
219 }
220 else
221 {
222 float num3 = texture.Width;
223 float num4 = texture.Height;
224 ptr->Source.X = 0f;
225 ptr->Source.Y = 0f;
226 ptr->Source.Z = num3;
227 ptr->Source.W = num4;
228 if (scaleDestination)
229 {
230 num *= num3;
231 num2 *= num4;
232 }
233 }
234 ptr->Destination.X = destination.X;
235 ptr->Destination.Y = destination.Y;
236 ptr->Destination.Z = num;
237 ptr->Destination.W = num2;
238 ptr->Origin.X = origin.X;
239 ptr->Origin.Y = origin.Y;
240 ptr->Effects = effects;
241 ptr->Colors = colors;
242 ptr->Rotation = rotation;
243 }
244 if (_spriteTextures == null || _spriteTextures.Length != _spriteDataQueue.Length)
245 {
246 Array.Resize(ref _spriteTextures, _spriteDataQueue.Length);
247 }
249 }
250
251 public void End()
252 {
253 if (_queuedSpriteCount != 0)
254 {
256 Flush();
257 }
258 }
259
260 private void Flush()
261 {
262 Texture2D texture2D = null;
263 int num = 0;
264 for (int i = 0; i < _queuedSpriteCount; i++)
265 {
266 if (_spriteTextures[i] != texture2D)
267 {
268 if (i > num)
269 {
270 RenderBatch(texture2D, _spriteDataQueue, num, i - num);
271 }
272 num = i;
273 texture2D = _spriteTextures[i];
274 }
275 }
276 RenderBatch(texture2D, _spriteDataQueue, num, _queuedSpriteCount - num);
279 }
280
281 private unsafe void RenderBatch(Texture2D texture, SpriteData[] sprites, int offset, int count)
282 {
283 _graphicsDevice.Textures[0] = texture;
284 float num = 1f / (float)texture.Width;
285 float num2 = 1f / (float)texture.Height;
286 while (count > 0)
287 {
289 int num3 = count;
290 if (num3 > 2048 - _vertexBufferPosition)
291 {
292 num3 = 2048 - _vertexBufferPosition;
293 if (num3 < 256)
294 {
296 options = SetDataOptions.Discard;
297 num3 = count;
298 if (num3 > 2048)
299 {
300 num3 = 2048;
301 }
302 }
303 }
304 fixed (SpriteData* ptr = &sprites[offset])
305 {
306 fixed (VertexPositionColorTexture* ptr3 = &_vertices[0])
307 {
308 SpriteData* ptr2 = ptr;
309 VertexPositionColorTexture* ptr4 = ptr3;
310 for (int i = 0; i < num3; i++)
311 {
312 float num4;
313 float num5;
314 if (ptr2->Rotation != 0f)
315 {
316 num4 = (float)Math.Cos(ptr2->Rotation);
317 num5 = (float)Math.Sin(ptr2->Rotation);
318 }
319 else
320 {
321 num4 = 1f;
322 num5 = 0f;
323 }
324 float num6 = ptr2->Origin.X / ptr2->Source.Z;
325 float num7 = ptr2->Origin.Y / ptr2->Source.W;
326 ptr4->Color = ptr2->Colors.TopLeftColor;
327 ptr4[1].Color = ptr2->Colors.TopRightColor;
328 ptr4[2].Color = ptr2->Colors.BottomRightColor;
329 ptr4[3].Color = ptr2->Colors.BottomLeftColor;
330 for (int j = 0; j < 4; j++)
331 {
332 float num8 = CORNER_OFFSET_X[j];
333 float num9 = CORNER_OFFSET_Y[j];
334 float num10 = (num8 - num6) * ptr2->Destination.Z;
335 float num11 = (num9 - num7) * ptr2->Destination.W;
336 float x = ptr2->Destination.X + num10 * num4 - num11 * num5;
337 float y = ptr2->Destination.Y + num10 * num5 + num11 * num4;
338 if ((ptr2->Effects & SpriteEffects.FlipVertically) != 0)
339 {
340 num9 = 1f - num9;
341 }
342 if ((ptr2->Effects & SpriteEffects.FlipHorizontally) != 0)
343 {
344 num8 = 1f - num8;
345 }
346 ptr4->Position.X = x;
347 ptr4->Position.Y = y;
348 ptr4->Position.Z = 0f;
349 ptr4->TextureCoordinate.X = (ptr2->Source.X + num8 * ptr2->Source.Z) * num;
350 ptr4->TextureCoordinate.Y = (ptr2->Source.Y + num9 * ptr2->Source.W) * num2;
351 ptr4++;
352 }
353 ptr2++;
354 }
355 }
356 }
357 int offsetInBytes = _vertexBufferPosition * sizeof(VertexPositionColorTexture) * 4;
358 _vertexBuffer.SetData(offsetInBytes, _vertices, 0, num3 * 4, sizeof(VertexPositionColorTexture), options);
359 int minVertexIndex = _vertexBufferPosition * 4;
360 int numVertices = num3 * 4;
362 int primitiveCount = num3 * 2;
363 _graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, minVertexIndex, numVertices, startIndex, primitiveCount);
364 _vertexBufferPosition += num3;
365 offset += num3;
366 count -= num3;
367 }
368 }
369}
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 SamplerState PointClamp
override void Dispose([MarshalAs(UnmanagedType.U1)] bool P_0)
static unsafe void Clear(Array array)
Definition Array.cs:755
static double Cos(double d)
static double Sin(double a)
void Draw(Texture2D texture, Vector4 destination, VertexColors colors)
Definition TileBatch.cs:147
unsafe void InternalDraw(Texture2D texture, ref Vector4 destination, bool scaleDestination, ref Rectangle? sourceRectangle, ref VertexColors colors, ref Vector2 origin, SpriteEffects effects, float rotation)
Definition TileBatch.cs:197
void Draw(Texture2D texture, Vector2 position, VertexColors colors, Vector2 scale)
Definition TileBatch.cs:152
void Draw(Texture2D texture, Rectangle destinationRectangle, Rectangle? sourceRectangle, VertexColors colors)
Definition TileBatch.cs:172
DynamicVertexBuffer _vertexBuffer
Definition TileBatch.cs:42
void Draw(Texture2D texture, Vector2 position, VertexColors colors)
Definition TileBatch.cs:127
void Draw(Texture2D texture, Vector4 destination, Rectangle? sourceRectangle, VertexColors colors, Vector2 origin, SpriteEffects effects, float rotation)
Definition TileBatch.cs:167
DynamicIndexBuffer _indexBuffer
Definition TileBatch.cs:44
unsafe void RenderBatch(Texture2D texture, SpriteData[] sprites, int offset, int count)
Definition TileBatch.cs:281
static readonly float[] CORNER_OFFSET_Y
Definition TileBatch.cs:26
static Vector2 _vector2Zero
Definition TileBatch.cs:38
static ? Rectangle _nullRectangle
Definition TileBatch.cs:40
GraphicsDevice _graphicsDevice
Definition TileBatch.cs:28
static short[] CreateIndexData()
Definition TileBatch.cs:182
SpriteData[] _spriteDataQueue
Definition TileBatch.cs:30
void Begin(RasterizerState rasterizer, Matrix transformation)
Definition TileBatch.cs:115
VertexPositionColorTexture[] _vertices
Definition TileBatch.cs:48
TileBatch(GraphicsDevice graphicsDevice)
Definition TileBatch.cs:52
void Draw(Texture2D texture, Vector2 position, Rectangle? sourceRectangle, VertexColors colors, Vector2 origin, float scale, SpriteEffects effects)
Definition TileBatch.cs:137
static readonly float[] CORNER_OFFSET_X
Definition TileBatch.cs:24
void Draw(Texture2D texture, Vector4 destination, Rectangle? sourceRectangle, VertexColors colors)
Definition TileBatch.cs:162