Renderer optimizations.

Nothing major, but it should be a bit faster now.
This commit is contained in:
Pieter-Jan Briers
2019-08-01 02:14:03 +02:00
parent 85a4375905
commit 6f201ccddc
9 changed files with 276 additions and 100 deletions

View File

@@ -11,7 +11,7 @@ namespace Robust.Client.Graphics
[PublicAPI]
public sealed class AtlasTexture : Texture
{
public AtlasTexture(Texture texture, UIBox2 subRegion)
public AtlasTexture(Texture texture, UIBox2 subRegion) : base((Vector2i) subRegion.Size)
{
DebugTools.Assert(SubRegion.Right < texture.Width);
DebugTools.Assert(SubRegion.Bottom < texture.Height);
@@ -31,8 +31,5 @@ namespace Robust.Client.Graphics
/// Our sub region within our source, in pixel coordinates.
/// </summary>
public UIBox2 SubRegion { get; }
public override int Width => (int) SubRegion.Width;
public override int Height => (int) SubRegion.Height;
}
}

View File

@@ -20,9 +20,6 @@ namespace Robust.Client.Graphics.Clyde
{
var map = _eyeManager.CurrentMap;
GL.Enable(EnableCap.PrimitiveRestart);
GL.PrimitiveRestartIndex(ushort.MaxValue);
var atlasTexture = _tileDefinitionManager.TileTextureAtlas;
var loadedTex = _loadedTextures[((ClydeTexture) atlasTexture).TextureId];
@@ -43,10 +40,10 @@ namespace Robust.Client.Graphics.Clyde
var gridProgram = _loadedShaders[_defaultShader.Handle].Program;
gridProgram.Use();
gridProgram.SetUniformTextureMaybe(UniMainTexture, TextureUnit.Texture0);
gridProgram.SetUniformTextureMaybe(UniLightTexture, TextureUnit.Texture1);
gridProgram.SetUniform(UniModUV, new Vector4(0, 0, 1, 1));
gridProgram.SetUniform(UniModulate, Color.White);
gridProgram.SetUniformTextureMaybe(UniIMainTexture, TextureUnit.Texture0);
gridProgram.SetUniformTextureMaybe(UniILightTexture, TextureUnit.Texture1);
gridProgram.SetUniform(UniIModUV, new Vector4(0, 0, 1, 1));
gridProgram.SetUniform(UniIModulate, Color.White);
foreach (var mapGrid in _mapManager.GetMap(map).GetAllGrids())
{
@@ -59,7 +56,7 @@ namespace Robust.Client.Graphics.Clyde
var model = Matrix3.Identity;
model.R0C2 = grid.WorldPosition.X;
model.R1C2 = grid.WorldPosition.Y;
gridProgram.SetUniform(UniModelMatrix, model);
gridProgram.SetUniform(UniIModelMatrix, model);
foreach (var (index, chunk) in grid.GetMapChunks())
{
@@ -82,8 +79,6 @@ namespace Robust.Client.Graphics.Clyde
GL.DrawElements(BeginMode.TriangleStrip, datum.TileCount * 5, DrawElementsType.UnsignedShort, 0);
}
}
GL.Disable(EnableCap.PrimitiveRestart);
}
private void _updateChunkMesh(IMapGrid grid, IMapChunk chunk)

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@@ -36,7 +37,7 @@ namespace Robust.Client.Graphics.Clyde
private Matrix3 _currentModelMatrix = Matrix3.Identity;
// The amount of quads we can render with ushort indices, leaving open 65536 for primitive restart.
private const ushort MaxBatchQuads = (2 << 13) - 1; // In human terms: (2**16/4)-1
private const ushort MaxBatchQuads = (2 << 13) - 1; // In human terms: (2**16/4)-1 = 16383
private readonly Vertex2D[] BatchVertexData = new Vertex2D[MaxBatchQuads * 4];
@@ -433,7 +434,7 @@ namespace Robust.Client.Graphics.Clyde
{
DebugTools.Assert(BatchingModulate.HasValue);
if (BatchingTexture.Value != command.TextureId ||
BatchingModulate.Value != command.Modulate)
!StrictColorEquality(BatchingModulate.Value, command.Modulate))
{
_flushBatchBuffer();
BatchingTexture = command.TextureId;
@@ -481,16 +482,16 @@ namespace Robust.Client.Graphics.Clyde
if (command.Angle == Angle.Zero)
{
bl = _currentModelMatrix.Transform(command.PositionA);
br = _currentModelMatrix.Transform((command.PositionB.X, command.PositionA.Y));
br = _currentModelMatrix.Transform(new Vector2(command.PositionB.X, command.PositionA.Y));
tr = _currentModelMatrix.Transform(command.PositionB);
tl = _currentModelMatrix.Transform((command.PositionA.X, command.PositionB.Y));
tl = _currentModelMatrix.Transform(new Vector2(command.PositionA.X, command.PositionB.Y));
}
else
{
bl = _currentModelMatrix.Transform(command.Angle.RotateVec(command.PositionA));
br = _currentModelMatrix.Transform(command.Angle.RotateVec((command.PositionB.X, command.PositionA.Y)));
br = _currentModelMatrix.Transform(command.Angle.RotateVec(new Vector2(command.PositionB.X, command.PositionA.Y)));
tr = _currentModelMatrix.Transform(command.Angle.RotateVec(command.PositionB));
tl = _currentModelMatrix.Transform(command.Angle.RotateVec((command.PositionA.X, command.PositionB.Y)));
tl = _currentModelMatrix.Transform(command.Angle.RotateVec(new Vector2(command.PositionA.X, command.PositionB.Y)));
}
var vIdx = BatchIndex * 4;
BatchVertexData[vIdx + 0] = new Vertex2D(bl, sr.BottomLeft);
@@ -517,8 +518,8 @@ namespace Robust.Client.Graphics.Clyde
var program = loaded.Program;
program.Use();
program.SetUniformMaybe(UniModUV, new Vector4(0, 0, 1, 1));
program.SetUniformMaybe(UniModulate, renderCommandLine.Color);
program.SetUniformMaybe(UniIModUV, new Vector4(0, 0, 1, 1));
program.SetUniformMaybe(UniIModulate, renderCommandLine.Color);
var white = _loadedTextures[((ClydeTexture) Texture.White).TextureId].OpenGLObject;
GL.ActiveTexture(TextureUnit.Texture0);
@@ -535,8 +536,8 @@ namespace Robust.Client.Graphics.Clyde
GL.BindTexture(TextureTarget.Texture2D, white.Handle);
}
program.SetUniformTextureMaybe(UniMainTexture, TextureUnit.Texture0);
program.SetUniformTextureMaybe(UniLightTexture, TextureUnit.Texture1);
program.SetUniformTextureMaybe(UniIMainTexture, TextureUnit.Texture0);
program.SetUniformTextureMaybe(UniILightTexture, TextureUnit.Texture1);
var a = renderCommandLine.PositionA;
var b = renderCommandLine.PositionB;
@@ -546,7 +547,7 @@ namespace Robust.Client.Graphics.Clyde
(rectTransform.R0C0, rectTransform.R1C1) = b - a;
(rectTransform.R0C2, rectTransform.R1C2) = a;
rectTransform.Multiply(ref _currentModelMatrix);
program.SetUniformMaybe(UniModelMatrix, rectTransform);
program.SetUniformMaybe(UniIModelMatrix, rectTransform);
GL.DrawArrays(PrimitiveType.Lines, 0, 2);
}
@@ -557,7 +558,7 @@ namespace Robust.Client.Graphics.Clyde
(rectTransform.R0C0, rectTransform.R1C1) = b - a;
(rectTransform.R0C2, rectTransform.R1C2) = a;
rectTransform.Multiply(ref modelMatrix);
program.SetUniformMaybe(UniModelMatrix, rectTransform);
program.SetUniformMaybe(UniIModelMatrix, rectTransform);
GL.DrawArrays(PrimitiveType.TriangleStrip, 0, 4);
}
@@ -614,22 +615,19 @@ namespace Robust.Client.Graphics.Clyde
program.Use();
program.SetUniformTextureMaybe(UniMainTexture, TextureUnit.Texture0);
program.SetUniformTextureMaybe(UniLightTexture, TextureUnit.Texture1);
program.SetUniformTextureMaybe(UniIMainTexture, TextureUnit.Texture0);
program.SetUniformTextureMaybe(UniILightTexture, TextureUnit.Texture1);
// Model matrix becomes identity since it's built into the batch mesh.
program.SetUniformMaybe(UniModelMatrix, Matrix3.Identity);
program.SetUniformMaybe(UniIModelMatrix, Matrix3.Identity);
// Reset ModUV to ensure it's identity and doesn't touch anything.
program.SetUniformMaybe(UniModUV, new Vector4(0, 0, 1, 1));
program.SetUniformMaybe(UniIModUV, new Vector4(0, 0, 1, 1));
// Set modulate.
DebugTools.Assert(BatchingModulate.HasValue);
program.SetUniformMaybe(UniModulate, BatchingModulate.Value);
program.SetUniformMaybe(UniTexturePixelSize, Vector2.One / loadedTexture.Size);
// Enable primitive restart & do that draw.
GL.Enable(EnableCap.PrimitiveRestart);
GL.PrimitiveRestartIndex(ushort.MaxValue);
program.SetUniformMaybe(UniIModulate, BatchingModulate.Value);
program.SetUniformMaybe(UniITexturePixelSize, Vector2.One / loadedTexture.Size);
GL.DrawElements(PrimitiveType.TriangleStrip, BatchIndex * 5, DrawElementsType.UnsignedShort, 0);
GL.Disable(EnableCap.PrimitiveRestart);
// Reset batch state.
BatchIndex = 0;
@@ -696,6 +694,12 @@ namespace Robust.Client.Graphics.Clyde
}
}
[SuppressMessage("ReSharper", "CompareOfFloatsByEqualityOperator")]
private static bool StrictColorEquality(in Color a, in Color b)
{
return a.R == b.R && a.G == b.G && a.B == b.B && a.A == b.A;
}
private sealed class RenderHandle : IRenderHandle
{
private readonly Clyde _clyde;

View File

@@ -3,11 +3,11 @@ using System.Collections.Generic;
using System.IO;
using System.Threading;
using OpenTK.Graphics.OpenGL;
using Robust.Shared.Maths;
using Robust.Shared.Utility;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.PixelFormats;
using Robust.Shared.Maths;
using Robust.Shared.Utility;
using OGLTextureWrapMode = OpenTK.Graphics.OpenGL.TextureWrapMode;
namespace Robust.Client.Graphics.Clyde
@@ -145,7 +145,7 @@ namespace Robust.Client.Graphics.Clyde
var id = ++_nextTextureId;
_loadedTextures.Add(id, loaded);
return new ClydeTexture(id, width, height, this);
return new ClydeTexture(id, size, this);
}
private void _deleteTexture(ClydeTexture texture)
@@ -186,19 +186,14 @@ namespace Robust.Client.Graphics.Clyde
internal int TextureId { get; }
public override int Width { get; }
public override int Height { get; }
public override void Delete()
{
_clyde._deleteTexture(this);
}
internal ClydeTexture(int id, int width, int height, Clyde clyde)
internal ClydeTexture(int id, Vector2i size, Clyde clyde) : base(size)
{
TextureId = id;
Width = width;
Height = height;
_clyde = clyde;
}
}

View File

@@ -28,7 +28,6 @@ using Robust.Shared.Utility;
using Matrix3 = Robust.Shared.Maths.Matrix3;
using Vector2 = Robust.Shared.Maths.Vector2;
using Vector3 = Robust.Shared.Maths.Vector3;
using DependencyAttribute = Robust.Shared.IoC.DependencyAttribute;
namespace Robust.Client.Graphics.Clyde
{
@@ -38,15 +37,15 @@ namespace Robust.Client.Graphics.Clyde
internal sealed partial class Clyde : DisplayManager, IClydeInternal, IClydeAudio, IDisposable
{
#pragma warning disable 649
[Dependency] private readonly IResourceCache _resourceCache;
[Dependency] private readonly IEyeManager _eyeManager;
[Dependency] private readonly IMapManager _mapManager;
[Dependency] private readonly IOverlayManager _overlayManager;
[Dependency] private readonly IEntityManager _entityManager;
[Dependency] private readonly IComponentManager _componentManager;
[Dependency] private readonly IUserInterfaceManagerInternal _userInterfaceManager;
[Dependency] private readonly IClydeTileDefinitionManager _tileDefinitionManager;
[Dependency] private readonly ILightManager _lightManager;
[Shared.IoC.Dependency] private readonly IResourceCache _resourceCache;
[Shared.IoC.Dependency] private readonly IEyeManager _eyeManager;
[Shared.IoC.Dependency] private readonly IMapManager _mapManager;
[Shared.IoC.Dependency] private readonly IOverlayManager _overlayManager;
[Shared.IoC.Dependency] private readonly IEntityManager _entityManager;
[Shared.IoC.Dependency] private readonly IComponentManager _componentManager;
[Shared.IoC.Dependency] private readonly IUserInterfaceManagerInternal _userInterfaceManager;
[Shared.IoC.Dependency] private readonly IClydeTileDefinitionManager _tileDefinitionManager;
[Shared.IoC.Dependency] private readonly ILightManager _lightManager;
#pragma warning restore 649
private static readonly Version MinimumOpenGLVersion = new Version(3, 3);
@@ -75,6 +74,13 @@ namespace Robust.Client.Graphics.Clyde
private Buffer LineVBO;
private OGLHandle LineVAO;
private const int UniIModUV = 0;
private const int UniIModelMatrix = 1;
private const int UniIModulate = 2;
private const int UniITexturePixelSize = 3;
private const int UniIMainTexture = 4;
private const int UniILightTexture = 5;
private const int UniCount = 6;
private const string UniModUV = "modifyUV";
private const string UniModelMatrix = "modelMatrix";
private const string UniModulate = "modulate";
@@ -253,6 +259,8 @@ namespace Robust.Client.Graphics.Clyde
GL.Enable(EnableCap.Blend);
GL.Enable(EnableCap.FramebufferSrgb);
GL.Enable(EnableCap.PrimitiveRestart);
GL.PrimitiveRestartIndex(ushort.MaxValue);
GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
var vendor = GL.GetString(StringName.Vendor);

View File

@@ -65,13 +65,13 @@ namespace Robust.Client.Graphics.Clyde
public Texture LoadTextureFromImage<T>(Image<T> image, string name = null,
TextureLoadParameters? loadParams = null) where T : unmanaged, IPixel<T>
{
return new DummyTexture(image.Width, image.Height);
return new DummyTexture((image.Width, image.Height));
}
public IRenderTarget CreateRenderTarget(Vector2i size, RenderTargetColorFormat colorFormat,
TextureSampleParameters? sampleParameters = null, string name = null)
{
return new DummyRenderTarget(size, new DummyTexture(size.X, size.Y));
return new DummyRenderTarget(size, new DummyTexture(size));
}
public ClydeHandle LoadShader(ParsedShader shader, string name = null)
@@ -144,18 +144,13 @@ namespace Robust.Client.Graphics.Clyde
private sealed class DummyTexture : OwnedTexture
{
public override int Width { get; }
public override int Height { get; }
public override void Delete()
{
// Hey that was easy.
}
public DummyTexture(int width, int height)
public DummyTexture(Vector2i size) : base(size)
{
Width = width;
Height = height;
}
}

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using OpenTK.Graphics.OpenGL;
using Robust.Shared.Maths;
using Robust.Shared.Utility;
@@ -15,6 +16,7 @@ namespace Robust.Client.Graphics.Clyde
/// </summary>
private class ShaderProgram
{
private readonly sbyte?[] _uniformIntCache = new sbyte?[Clyde.UniCount];
private readonly Dictionary<string, int> _uniformCache = new Dictionary<string, int>();
private uint _handle = 0;
private Shader _fragmentShader;
@@ -30,7 +32,7 @@ namespace Robust.Client.Graphics.Clyde
public void Add(Shader shader)
{
_uniformCache.Clear();
ClearCaches();
switch (shader.Type)
{
case ShaderType.VertexShader:
@@ -46,7 +48,7 @@ namespace Robust.Client.Graphics.Clyde
public void Link()
{
_uniformCache.Clear();
ClearCaches();
_handle = (uint) GL.CreateProgram();
if (Name != null)
{
@@ -100,7 +102,17 @@ namespace Robust.Client.Graphics.Clyde
{
if (!TryGetUniform(name, out var result))
{
throw new ArgumentException("Could not get uniform!");
ThrowCouldNotGetUniform();
}
return result;
}
public int GetUniform(int id)
{
if (!TryGetUniform(id, out var result))
{
ThrowCouldNotGetUniform();
}
return result;
@@ -112,7 +124,7 @@ namespace Robust.Client.Graphics.Clyde
if (_uniformCache.TryGetValue(name, out index))
{
return true;
return index != -1;
}
index = GL.GetUniformLocation(_handle, name);
@@ -120,11 +132,59 @@ namespace Robust.Client.Graphics.Clyde
return index != -1;
}
public bool TryGetUniform(int id, out int index)
{
DebugTools.Assert(_handle != 0);
DebugTools.Assert(id < UniCount);
var value = _uniformIntCache[id];
if (value.HasValue)
{
index = value.Value;
return index != -1;
}
return InitIntUniform(id, out index);
}
private bool InitIntUniform(int id, out int index)
{
string name;
switch (id)
{
case UniIModUV:
name = UniModUV;
break;
case UniIModulate:
name = UniModulate;
break;
case UniILightTexture:
name = UniLightTexture;
break;
case UniIMainTexture:
name = UniMainTexture;
break;
case UniIModelMatrix:
name = UniModelMatrix;
break;
case UniITexturePixelSize:
name = UniTexturePixelSize;
break;
default:
throw new ArgumentOutOfRangeException();
}
index = GL.GetUniformLocation(_handle, name);
_uniformIntCache[id] = (sbyte)index;
return index != -1;
}
public bool HasUniform(string name) => TryGetUniform(name, out _);
public bool HasUniform(int id) => TryGetUniform(id, out _);
public void BindBlock(string blockName, uint blockBinding)
{
var index = (uint)GL.GetUniformBlockIndex(_handle, blockName);
var index = (uint) GL.GetUniformBlockIndex(_handle, blockName);
GL.UniformBlockBinding(_handle, index, blockBinding);
}
@@ -143,42 +203,78 @@ namespace Robust.Client.Graphics.Clyde
public void SetUniform(string uniformName, in Matrix3 matrix)
{
var uniformId = GetUniform(uniformName);
unsafe
SetUniformDirect(uniformId, matrix);
}
public void SetUniform(int uniformName, in Matrix3 matrix)
{
var uniformId = GetUniform(uniformName);
SetUniformDirect(uniformId, matrix);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static unsafe void SetUniformDirect(int slot, in Matrix3 value)
{
fixed (Matrix3* ptr = &value)
{
fixed (Matrix3* ptr = &matrix)
{
GL.UniformMatrix3(uniformId, 1, true, (float*) ptr);
}
GL.UniformMatrix3(slot, 1, true, (float*) ptr);
}
}
public void SetUniform(string uniformName, in Matrix4 matrix)
{
var uniformId = GetUniform(uniformName);
unsafe
SetUniformDirect(uniformId, matrix);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static unsafe void SetUniformDirect(int uniformId, in Matrix4 value)
{
fixed (Matrix4* ptr = &value)
{
fixed (Matrix4* ptr = &matrix)
{
GL.UniformMatrix4(uniformId, 1, true, (float*) ptr);
}
GL.UniformMatrix4(uniformId, 1, true, (float*) ptr);
}
}
public void SetUniform(string uniformName, in Vector4 vector)
{
var uniformId = GetUniform(uniformName);
SetUniformDirect(uniformId, vector);
}
public void SetUniform(int uniformName, in Vector4 vector)
{
var uniformId = GetUniform(uniformName);
SetUniformDirect(uniformId, vector);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void SetUniformDirect(int slot, in Vector4 vector)
{
unsafe
{
fixed (Vector4* ptr = &vector)
{
GL.Uniform4(uniformId, 1, (float*) ptr);
GL.Uniform4(slot, 1, (float*)ptr);
}
}
}
public void SetUniform(string uniformName, in Color color, bool convertToLinear=true)
public void SetUniform(string uniformName, in Color color, bool convertToLinear = true)
{
var uniformId = GetUniform(uniformName);
SetUniformDirect(uniformId, color, convertToLinear);
}
public void SetUniform(int uniformName, in Color color, bool convertToLinear = true)
{
var uniformId = GetUniform(uniformName);
SetUniformDirect(uniformId, color, convertToLinear);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void SetUniformDirect(int slot, in Color color, bool convertToLinear=true)
{
var converted = color;
if (convertToLinear)
{
@@ -187,18 +283,24 @@ namespace Robust.Client.Graphics.Clyde
unsafe
{
GL.Uniform4(uniformId, 1, (float*) &converted);
GL.Uniform4(slot, 1, (float*) &converted);
}
}
public void SetUniform(string uniformName, in Vector3 vector)
{
var uniformId = GetUniform(uniformName);
SetUniformDirect(uniformId, vector);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void SetUniformDirect(int slot, in Vector3 vector)
{
unsafe
{
fixed (Vector3* ptr = &vector)
{
GL.Uniform3(uniformId, 1, (float*) ptr);
GL.Uniform3(slot, 1, (float*)ptr);
}
}
}
@@ -206,11 +308,17 @@ namespace Robust.Client.Graphics.Clyde
public void SetUniform(string uniformName, in Vector2 vector)
{
var uniformId = GetUniform(uniformName);
SetUniformDirect(uniformId, vector);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void SetUniformDirect(int slot, in Vector2 vector)
{
unsafe
{
fixed (Vector2* ptr = &vector)
{
GL.Uniform2(uniformId, 1, (float*) ptr);
GL.Uniform2(slot, 1, (float*)ptr);
}
}
}
@@ -218,48 +326,108 @@ namespace Robust.Client.Graphics.Clyde
public void SetUniformTexture(string uniformName, TextureUnit textureUnit)
{
var uniformId = GetUniform(uniformName);
GL.Uniform1(uniformId, textureUnit - TextureUnit.Texture0);
SetUniformTextureDirect(uniformId, textureUnit);
}
public void SetUniformTextureMaybe(string uniformName, TextureUnit textureUnit)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void SetUniformTextureDirect(int slot, TextureUnit value)
{
if (HasUniform(uniformName))
GL.Uniform1(slot, value - TextureUnit.Texture0);
}
public void SetUniformTextureMaybe(string uniformName, TextureUnit value)
{
if (TryGetUniform(uniformName, out var slot))
{
SetUniformTexture(uniformName, textureUnit);
SetUniformTextureDirect(slot, value);
}
}
public void SetUniformTextureMaybe(int uniformName, TextureUnit value)
{
if (TryGetUniform(uniformName, out var slot))
{
SetUniformTextureDirect(slot, value);
}
}
public void SetUniformMaybe(string uniformName, in Vector4 value)
{
if (HasUniform(uniformName))
if (TryGetUniform(uniformName, out var slot))
{
SetUniform(uniformName, value);
SetUniformDirect(slot, value);
}
}
public void SetUniformMaybe(int uniformName, in Vector4 value)
{
if (TryGetUniform(uniformName, out var slot))
{
SetUniformDirect(slot, value);
}
}
public void SetUniformMaybe(string uniformName, in Color value)
{
if (HasUniform(uniformName))
if (TryGetUniform(uniformName, out var slot))
{
SetUniform(uniformName, value);
SetUniformDirect(slot, value);
}
}
public void SetUniformMaybe(int uniformName, in Color value)
{
if (TryGetUniform(uniformName, out var slot))
{
SetUniformDirect(slot, value);
}
}
public void SetUniformMaybe(string uniformName, in Matrix3 value)
{
if (HasUniform(uniformName))
if (TryGetUniform(uniformName, out var slot))
{
SetUniform(uniformName, value);
SetUniformDirect(slot, value);
}
}
public void SetUniformMaybe(int uniformName, in Matrix3 value)
{
if (TryGetUniform(uniformName, out var slot))
{
SetUniformDirect(slot, value);
}
}
public void SetUniformMaybe(string uniformName, in Vector2 value)
{
if (HasUniform(uniformName))
if (TryGetUniform(uniformName, out var slot))
{
SetUniform(uniformName, value);
SetUniformDirect(slot, value);
}
}
public void SetUniformMaybe(int uniformName, in Vector2 value)
{
if (TryGetUniform(uniformName, out var slot))
{
SetUniformDirect(slot, value);
}
}
private void ClearCaches()
{
_uniformCache.Clear();
for (var i = 0; i < UniCount; i++)
{
_uniformIntCache[i] = null;
}
}
private static void ThrowCouldNotGetUniform()
{
throw new ArgumentException("Could not get uniform!");
}
}
}
}

View File

@@ -1,3 +1,5 @@
using Robust.Shared.Maths;
namespace Robust.Client.Graphics
{
// TODO: Maybe implement IDisposable for owned textures. I got lazy and didn't.
@@ -7,5 +9,9 @@ namespace Robust.Client.Graphics
public abstract class OwnedTexture : Texture
{
public abstract void Delete();
protected OwnedTexture(Vector2i size) : base(size)
{
}
}
}

View File

@@ -1,12 +1,12 @@
using System;
using System.IO;
using JetBrains.Annotations;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using Robust.Client.Interfaces.Graphics;
using Robust.Shared.IoC;
using Robust.Shared.Maths;
using Robust.Shared.Utility;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using YamlDotNet.RepresentationModel;
namespace Robust.Client.Graphics
@@ -20,14 +20,22 @@ namespace Robust.Client.Graphics
/// <summary>
/// The width of the texture, in pixels.
/// </summary>
public abstract int Width { get; }
public int Width => Size.X;
/// <summary>
/// The height of the texture, in pixels.
/// </summary>
public abstract int Height { get; }
public int Height => Size.Y;
public Vector2i Size => new Vector2i(Width, Height);
/// <summary>
/// The size of the texture, in pixels.
/// </summary>
public Vector2i Size { get; }
protected Texture(Vector2i size)
{
Size = size;
}
public static Texture Transparent { get; internal set; }
public static Texture White { get; internal set; }