368 lines
14 KiB
C#
368 lines
14 KiB
C#
// Decompiled with JetBrains decompiler
|
|
// Type: Terraria.Graphics.TileBatch
|
|
// Assembly: Terraria, Version=1.4.0.5, Culture=neutral, PublicKeyToken=null
|
|
// MVID: 67F9E73E-0A81-4937-A22C-5515CD405A83
|
|
// Assembly location: C:\Users\mikeyisbaeyt\Downloads\depotdownloader-2.4.5\depots\105601\6707058\Terraria.exe
|
|
|
|
using Microsoft.Xna.Framework;
|
|
using Microsoft.Xna.Framework.Graphics;
|
|
using System;
|
|
|
|
namespace Terraria.Graphics
|
|
{
|
|
public class TileBatch
|
|
{
|
|
private static readonly float[] CORNER_OFFSET_X = new float[4]
|
|
{
|
|
0.0f,
|
|
1f,
|
|
1f,
|
|
0.0f
|
|
};
|
|
private static readonly float[] CORNER_OFFSET_Y = new float[4]
|
|
{
|
|
0.0f,
|
|
0.0f,
|
|
1f,
|
|
1f
|
|
};
|
|
private GraphicsDevice _graphicsDevice;
|
|
private TileBatch.SpriteData[] _spriteDataQueue = new TileBatch.SpriteData[2048];
|
|
private Texture2D[] _spriteTextures;
|
|
private int _queuedSpriteCount;
|
|
private SpriteBatch _spriteBatch;
|
|
private static Vector2 _vector2Zero;
|
|
private static Rectangle? _nullRectangle;
|
|
private DynamicVertexBuffer _vertexBuffer;
|
|
private DynamicIndexBuffer _indexBuffer;
|
|
private short[] _fallbackIndexData;
|
|
private VertexPositionColorTexture[] _vertices = new VertexPositionColorTexture[8192];
|
|
private int _vertexBufferPosition;
|
|
|
|
public TileBatch(GraphicsDevice graphicsDevice)
|
|
{
|
|
this._graphicsDevice = graphicsDevice;
|
|
this._spriteBatch = new SpriteBatch(graphicsDevice);
|
|
this.Allocate();
|
|
}
|
|
|
|
private void Allocate()
|
|
{
|
|
if (this._vertexBuffer == null || this._vertexBuffer.IsDisposed)
|
|
{
|
|
this._vertexBuffer = new DynamicVertexBuffer(this._graphicsDevice, typeof (VertexPositionColorTexture), 8192, BufferUsage.WriteOnly);
|
|
this._vertexBufferPosition = 0;
|
|
this._vertexBuffer.ContentLost += (EventHandler<EventArgs>) ((_param1, _param2) => this._vertexBufferPosition = 0);
|
|
}
|
|
if (this._indexBuffer != null && !this._indexBuffer.IsDisposed)
|
|
return;
|
|
if (this._fallbackIndexData == null)
|
|
{
|
|
this._fallbackIndexData = new short[12288];
|
|
for (int index = 0; index < 2048; ++index)
|
|
{
|
|
this._fallbackIndexData[index * 6] = (short) (index * 4);
|
|
this._fallbackIndexData[index * 6 + 1] = (short) (index * 4 + 1);
|
|
this._fallbackIndexData[index * 6 + 2] = (short) (index * 4 + 2);
|
|
this._fallbackIndexData[index * 6 + 3] = (short) (index * 4);
|
|
this._fallbackIndexData[index * 6 + 4] = (short) (index * 4 + 2);
|
|
this._fallbackIndexData[index * 6 + 5] = (short) (index * 4 + 3);
|
|
}
|
|
}
|
|
this._indexBuffer = new DynamicIndexBuffer(this._graphicsDevice, typeof (short), 12288, BufferUsage.WriteOnly);
|
|
this._indexBuffer.SetData<short>(this._fallbackIndexData);
|
|
this._indexBuffer.ContentLost += (EventHandler<EventArgs>) ((_param1, _param2) => this._indexBuffer.SetData<short>(this._fallbackIndexData));
|
|
}
|
|
|
|
private void FlushRenderState()
|
|
{
|
|
this.Allocate();
|
|
this._graphicsDevice.SetVertexBuffer((VertexBuffer) this._vertexBuffer);
|
|
this._graphicsDevice.Indices = (IndexBuffer) this._indexBuffer;
|
|
this._graphicsDevice.SamplerStates[0] = SamplerState.PointClamp;
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
if (this._vertexBuffer != null)
|
|
this._vertexBuffer.Dispose();
|
|
if (this._indexBuffer == null)
|
|
return;
|
|
this._indexBuffer.Dispose();
|
|
}
|
|
|
|
public void Begin(Matrix transformation)
|
|
{
|
|
this._spriteBatch.Begin(SpriteSortMode.Deferred, (BlendState) null, (SamplerState) null, (DepthStencilState) null, (RasterizerState) null, (Effect) null, transformation);
|
|
this._spriteBatch.End();
|
|
}
|
|
|
|
public void Begin()
|
|
{
|
|
this._spriteBatch.Begin();
|
|
this._spriteBatch.End();
|
|
}
|
|
|
|
public void Draw(Texture2D texture, Vector2 position, VertexColors colors) => this.InternalDraw(texture, ref new Vector4()
|
|
{
|
|
X = position.X,
|
|
Y = position.Y,
|
|
Z = 1f,
|
|
W = 1f
|
|
}, true, ref TileBatch._nullRectangle, ref colors, ref TileBatch._vector2Zero, SpriteEffects.None, 0.0f);
|
|
|
|
public void Draw(
|
|
Texture2D texture,
|
|
Vector2 position,
|
|
Rectangle? sourceRectangle,
|
|
VertexColors colors,
|
|
Vector2 origin,
|
|
float scale,
|
|
SpriteEffects effects)
|
|
{
|
|
this.InternalDraw(texture, ref new Vector4()
|
|
{
|
|
X = position.X,
|
|
Y = position.Y,
|
|
Z = scale,
|
|
W = scale
|
|
}, true, ref sourceRectangle, ref colors, ref origin, effects, 0.0f);
|
|
}
|
|
|
|
public void Draw(Texture2D texture, Vector4 destination, VertexColors colors) => this.InternalDraw(texture, ref destination, false, ref TileBatch._nullRectangle, ref colors, ref TileBatch._vector2Zero, SpriteEffects.None, 0.0f);
|
|
|
|
public void Draw(Texture2D texture, Vector2 position, VertexColors colors, Vector2 scale) => this.InternalDraw(texture, ref new Vector4()
|
|
{
|
|
X = position.X,
|
|
Y = position.Y,
|
|
Z = scale.X,
|
|
W = scale.Y
|
|
}, true, ref TileBatch._nullRectangle, ref colors, ref TileBatch._vector2Zero, SpriteEffects.None, 0.0f);
|
|
|
|
public void Draw(
|
|
Texture2D texture,
|
|
Vector4 destination,
|
|
Rectangle? sourceRectangle,
|
|
VertexColors colors)
|
|
{
|
|
this.InternalDraw(texture, ref destination, false, ref sourceRectangle, ref colors, ref TileBatch._vector2Zero, SpriteEffects.None, 0.0f);
|
|
}
|
|
|
|
public void Draw(
|
|
Texture2D texture,
|
|
Vector4 destination,
|
|
Rectangle? sourceRectangle,
|
|
VertexColors colors,
|
|
Vector2 origin,
|
|
SpriteEffects effects,
|
|
float rotation)
|
|
{
|
|
this.InternalDraw(texture, ref destination, false, ref sourceRectangle, ref colors, ref origin, effects, rotation);
|
|
}
|
|
|
|
public void Draw(
|
|
Texture2D texture,
|
|
Rectangle destinationRectangle,
|
|
Rectangle? sourceRectangle,
|
|
VertexColors colors)
|
|
{
|
|
this.InternalDraw(texture, ref new Vector4()
|
|
{
|
|
X = (float) destinationRectangle.X,
|
|
Y = (float) destinationRectangle.Y,
|
|
Z = (float) destinationRectangle.Width,
|
|
W = (float) destinationRectangle.Height
|
|
}, false, ref sourceRectangle, ref colors, ref TileBatch._vector2Zero, SpriteEffects.None, 0.0f);
|
|
}
|
|
|
|
private static short[] CreateIndexData()
|
|
{
|
|
short[] numArray = new short[12288];
|
|
for (int index = 0; index < 2048; ++index)
|
|
{
|
|
numArray[index * 6] = (short) (index * 4);
|
|
numArray[index * 6 + 1] = (short) (index * 4 + 1);
|
|
numArray[index * 6 + 2] = (short) (index * 4 + 2);
|
|
numArray[index * 6 + 3] = (short) (index * 4);
|
|
numArray[index * 6 + 4] = (short) (index * 4 + 2);
|
|
numArray[index * 6 + 5] = (short) (index * 4 + 3);
|
|
}
|
|
return numArray;
|
|
}
|
|
|
|
private unsafe void InternalDraw(
|
|
Texture2D texture,
|
|
ref Vector4 destination,
|
|
bool scaleDestination,
|
|
ref Rectangle? sourceRectangle,
|
|
ref VertexColors colors,
|
|
ref Vector2 origin,
|
|
SpriteEffects effects,
|
|
float rotation)
|
|
{
|
|
if (this._queuedSpriteCount >= this._spriteDataQueue.Length)
|
|
Array.Resize<TileBatch.SpriteData>(ref this._spriteDataQueue, this._spriteDataQueue.Length << 1);
|
|
fixed (TileBatch.SpriteData* spriteDataPtr = &this._spriteDataQueue[this._queuedSpriteCount])
|
|
{
|
|
float z = destination.Z;
|
|
float w = destination.W;
|
|
if (sourceRectangle.HasValue)
|
|
{
|
|
Rectangle rectangle = sourceRectangle.Value;
|
|
spriteDataPtr->Source.X = (float) rectangle.X;
|
|
spriteDataPtr->Source.Y = (float) rectangle.Y;
|
|
spriteDataPtr->Source.Z = (float) rectangle.Width;
|
|
spriteDataPtr->Source.W = (float) rectangle.Height;
|
|
if (scaleDestination)
|
|
{
|
|
z *= (float) rectangle.Width;
|
|
w *= (float) rectangle.Height;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
float width = (float) texture.Width;
|
|
float height = (float) texture.Height;
|
|
spriteDataPtr->Source.X = 0.0f;
|
|
spriteDataPtr->Source.Y = 0.0f;
|
|
spriteDataPtr->Source.Z = width;
|
|
spriteDataPtr->Source.W = height;
|
|
if (scaleDestination)
|
|
{
|
|
z *= width;
|
|
w *= height;
|
|
}
|
|
}
|
|
spriteDataPtr->Destination.X = destination.X;
|
|
spriteDataPtr->Destination.Y = destination.Y;
|
|
spriteDataPtr->Destination.Z = z;
|
|
spriteDataPtr->Destination.W = w;
|
|
spriteDataPtr->Origin.X = origin.X;
|
|
spriteDataPtr->Origin.Y = origin.Y;
|
|
spriteDataPtr->Effects = effects;
|
|
spriteDataPtr->Colors = colors;
|
|
spriteDataPtr->Rotation = rotation;
|
|
}
|
|
if (this._spriteTextures == null || this._spriteTextures.Length != this._spriteDataQueue.Length)
|
|
Array.Resize<Texture2D>(ref this._spriteTextures, this._spriteDataQueue.Length);
|
|
this._spriteTextures[this._queuedSpriteCount++] = texture;
|
|
}
|
|
|
|
public void End()
|
|
{
|
|
if (this._queuedSpriteCount == 0)
|
|
return;
|
|
this.FlushRenderState();
|
|
this.Flush();
|
|
}
|
|
|
|
private void Flush()
|
|
{
|
|
Texture2D texture = (Texture2D) null;
|
|
int offset = 0;
|
|
for (int index = 0; index < this._queuedSpriteCount; ++index)
|
|
{
|
|
if (this._spriteTextures[index] != texture)
|
|
{
|
|
if (index > offset)
|
|
this.RenderBatch(texture, this._spriteDataQueue, offset, index - offset);
|
|
offset = index;
|
|
texture = this._spriteTextures[index];
|
|
}
|
|
}
|
|
this.RenderBatch(texture, this._spriteDataQueue, offset, this._queuedSpriteCount - offset);
|
|
Array.Clear((Array) this._spriteTextures, 0, this._queuedSpriteCount);
|
|
this._queuedSpriteCount = 0;
|
|
}
|
|
|
|
private unsafe void RenderBatch(
|
|
Texture2D texture,
|
|
TileBatch.SpriteData[] sprites,
|
|
int offset,
|
|
int count)
|
|
{
|
|
this._graphicsDevice.Textures[0] = (Texture) texture;
|
|
float num1 = 1f / (float) texture.Width;
|
|
float num2 = 1f / (float) texture.Height;
|
|
int num3;
|
|
for (; count > 0; count -= num3)
|
|
{
|
|
SetDataOptions options = SetDataOptions.NoOverwrite;
|
|
num3 = count;
|
|
if (num3 > 2048 - this._vertexBufferPosition)
|
|
{
|
|
num3 = 2048 - this._vertexBufferPosition;
|
|
if (num3 < 256)
|
|
{
|
|
this._vertexBufferPosition = 0;
|
|
options = SetDataOptions.Discard;
|
|
num3 = count;
|
|
if (num3 > 2048)
|
|
num3 = 2048;
|
|
}
|
|
}
|
|
fixed (TileBatch.SpriteData* spriteDataPtr1 = &sprites[offset])
|
|
fixed (VertexPositionColorTexture* positionColorTexturePtr1 = &this._vertices[0])
|
|
{
|
|
TileBatch.SpriteData* spriteDataPtr2 = spriteDataPtr1;
|
|
VertexPositionColorTexture* positionColorTexturePtr2 = positionColorTexturePtr1;
|
|
for (int index1 = 0; index1 < num3; ++index1)
|
|
{
|
|
float num4;
|
|
float num5;
|
|
if ((double) spriteDataPtr2->Rotation != 0.0)
|
|
{
|
|
num4 = (float) Math.Cos((double) spriteDataPtr2->Rotation);
|
|
num5 = (float) Math.Sin((double) spriteDataPtr2->Rotation);
|
|
}
|
|
else
|
|
{
|
|
num4 = 1f;
|
|
num5 = 0.0f;
|
|
}
|
|
float num6 = spriteDataPtr2->Origin.X / spriteDataPtr2->Source.Z;
|
|
float num7 = spriteDataPtr2->Origin.Y / spriteDataPtr2->Source.W;
|
|
positionColorTexturePtr2->Color = spriteDataPtr2->Colors.TopLeftColor;
|
|
positionColorTexturePtr2[1].Color = spriteDataPtr2->Colors.TopRightColor;
|
|
positionColorTexturePtr2[2].Color = spriteDataPtr2->Colors.BottomRightColor;
|
|
positionColorTexturePtr2[3].Color = spriteDataPtr2->Colors.BottomLeftColor;
|
|
for (int index2 = 0; index2 < 4; ++index2)
|
|
{
|
|
float num8 = TileBatch.CORNER_OFFSET_X[index2];
|
|
float num9 = TileBatch.CORNER_OFFSET_Y[index2];
|
|
float num10 = (num8 - num6) * spriteDataPtr2->Destination.Z;
|
|
float num11 = (num9 - num7) * spriteDataPtr2->Destination.W;
|
|
float num12 = (float) ((double) spriteDataPtr2->Destination.X + (double) num10 * (double) num4 - (double) num11 * (double) num5);
|
|
float num13 = (float) ((double) spriteDataPtr2->Destination.Y + (double) num10 * (double) num5 + (double) num11 * (double) num4);
|
|
if ((spriteDataPtr2->Effects & SpriteEffects.FlipVertically) != SpriteEffects.None)
|
|
num8 = 1f - num8;
|
|
if ((spriteDataPtr2->Effects & SpriteEffects.FlipHorizontally) != SpriteEffects.None)
|
|
num9 = 1f - num9;
|
|
positionColorTexturePtr2->Position.X = num12;
|
|
positionColorTexturePtr2->Position.Y = num13;
|
|
positionColorTexturePtr2->Position.Z = 0.0f;
|
|
positionColorTexturePtr2->TextureCoordinate.X = (spriteDataPtr2->Source.X + num8 * spriteDataPtr2->Source.Z) * num1;
|
|
positionColorTexturePtr2->TextureCoordinate.Y = (spriteDataPtr2->Source.Y + num9 * spriteDataPtr2->Source.W) * num2;
|
|
++positionColorTexturePtr2;
|
|
}
|
|
++spriteDataPtr2;
|
|
}
|
|
}
|
|
this._vertexBuffer.SetData<VertexPositionColorTexture>(this._vertexBufferPosition * sizeof (VertexPositionColorTexture) * 4, this._vertices, 0, num3 * 4, sizeof (VertexPositionColorTexture), options);
|
|
this._graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, this._vertexBufferPosition * 4, num3 * 4, this._vertexBufferPosition * 6, num3 * 2);
|
|
this._vertexBufferPosition += num3;
|
|
offset += num3;
|
|
}
|
|
}
|
|
|
|
private struct SpriteData
|
|
{
|
|
public Vector4 Source;
|
|
public Vector4 Destination;
|
|
public Vector2 Origin;
|
|
public SpriteEffects Effects;
|
|
public VertexColors Colors;
|
|
public float Rotation;
|
|
}
|
|
}
|
|
}
|