Allow gpubuffers to be drawn out of bounds

This commit is contained in:
Alessandro Proto 2023-02-10 14:12:12 +01:00
parent 8b5fa96a74
commit cf12454a83
2 changed files with 32 additions and 30 deletions

View file

@ -16,6 +16,7 @@ public class Drawing : IDisposable
private Texture2D _whitePixel; private Texture2D _whitePixel;
private RenderTarget2D _canvas; private RenderTarget2D _canvas;
private bool _isDrawing; private bool _isDrawing;
private HashSet<Texture2D> _disposeTextures = new();
public RenderTarget2D Canvas public RenderTarget2D Canvas
{ {
get => _canvas; get => _canvas;
@ -34,7 +35,7 @@ public class Drawing : IDisposable
Begin(); Begin();
} }
} }
public Drawing() public Drawing()
{ {
_fontSystem = new FontSystem(); _fontSystem = new FontSystem();
@ -59,6 +60,11 @@ public class Drawing : IDisposable
_spriteBatch.End(); _spriteBatch.End();
_graphicsDevice.SetRenderTarget(null); _graphicsDevice.SetRenderTarget(null);
foreach (var t in _disposeTextures)
t.Dispose();
_disposeTextures.Clear();
_isDrawing = false; _isDrawing = false;
} }
@ -78,10 +84,10 @@ public class Drawing : IDisposable
{ {
if (point.X < 0 || point.Y < 0) return; if (point.X < 0 || point.Y < 0) return;
if (point.X >= _canvas.Width || point.Y >= _canvas.Height) return; if (point.X >= _canvas.Width || point.Y >= _canvas.Height) return;
var grid = new Color[_canvas.Width * _canvas.Height]; var grid = new Color[_canvas.Width * _canvas.Height];
_canvas.GetData(grid); _canvas.GetData(grid);
grid[point.X + (point.Y * _canvas.Width)] = color; grid[point.X + (point.Y * _canvas.Width)] = color;
_canvas.SetData(grid); _canvas.SetData(grid);
@ -178,6 +184,20 @@ public class Drawing : IDisposable
_spriteBatch.Draw(_whitePixel, position3, null, color, rotation, Vector2.Zero, scale, SpriteEffects.None, layerDepth); _spriteBatch.Draw(_whitePixel, position3, null, color, rotation, Vector2.Zero, scale, SpriteEffects.None, layerDepth);
} }
public void DrawTexture(Texture2D texture, Vector2 pos)
{
_spriteBatch.Draw(texture, pos, null, Color.White, 0f, Vector2.Zero, 1, SpriteEffects.None, 0f);
}
public void DrawBuffer(uint[] buffer, Rectangle rect)
{
var texture = new Texture2D(_graphicsDevice, rect.Width, rect.Height, false, SurfaceFormat.Color);
texture.SetData(buffer);
DrawTexture(texture, new(rect.X, rect.Y));
_disposeTextures.Add(texture);
}
public void Dispose() public void Dispose()
{ {
GC.SuppressFinalize(this); GC.SuppressFinalize(this);

View file

@ -435,8 +435,8 @@ public class GPU : IPlugin
{ {
var L = Lua.FromIntPtr(state); var L = Lua.FromIntPtr(state);
var from = L.CheckObject<uint[]>(1, GPUBuffer.ObjectType, false); var buffer = L.CheckObject<uint[]>(1, GPUBuffer.ObjectType, false);
if (from is null) if (buffer is null)
{ {
L.ArgumentError(1, GPUBuffer.ObjectType + " expected, got " + L.TypeName(L.Type(1))); L.ArgumentError(1, GPUBuffer.ObjectType + " expected, got " + L.TypeName(L.Type(1)));
} }
@ -445,32 +445,14 @@ public class GPU : IPlugin
var y = (int)L.CheckInteger(3) - 1; var y = (int)L.CheckInteger(3) - 1;
var w = (int)L.CheckInteger(4); var w = (int)L.CheckInteger(4);
var h = (int)L.CheckInteger(5); var h = (int)L.CheckInteger(5);
try
{
_game.Drawing.Canvas.SetData(0, new Rectangle
{
X = x,
Y = y,
Width = w,
Height = h,
}, from, 0, from.Length);
}
catch (Exception e)
{
if (w * h != from.Length)
{
L.Error("buffer size does not match width and height");
return 0;
}
if(x < 0 || y < 0 || x + w >= _game.Drawing.Canvas.Width || y + h >= _game.Drawing.Canvas.Height) _game.Drawing.DrawBuffer(buffer, new()
{ {
L.Error("position out of bounds"); X = x,
return 0; Y = y,
} Width = w,
Height = h,
L.Error(e.ToString()); });
}
return 0; return 0;
} }