mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-09-16 07:12:27 +02:00
Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
91 lines
2.9 KiB
C#
91 lines
2.9 KiB
C#
using System.Runtime.CompilerServices;
|
|
using OpenToolkit.Graphics.OpenGL4;
|
|
|
|
namespace Robust.Client.Graphics.Clyde
|
|
{
|
|
internal partial class Clyde
|
|
{
|
|
/// <summary>
|
|
/// Represents some set of uniforms that can be backed by a uniform buffer or by regular uniforms.
|
|
/// Implies you're using this on a properly setup struct.
|
|
/// </summary>
|
|
private interface IAppliableUniformSet
|
|
{
|
|
/// <summary>
|
|
/// Applies the uniform set directly to a program.
|
|
/// </summary>
|
|
void Apply(Clyde clyde, GLShaderProgram program);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Represents some set of uniforms that can be backed by a uniform buffer or by regular uniforms.
|
|
/// </summary>
|
|
private sealed class GLUniformBuffer<T> where T : unmanaged, IAppliableUniformSet
|
|
{
|
|
private readonly Clyde _clyde;
|
|
private readonly int _index;
|
|
|
|
/// <summary>
|
|
/// GPU Buffer (only used when uniform buffers are available)
|
|
/// </summary>
|
|
private GLBuffer? _implUBO = null;
|
|
|
|
/// <summary>
|
|
/// Mirror (only used when uniform buffers are unavailable)
|
|
/// </summary>
|
|
private T _implMirror;
|
|
|
|
public GLUniformBuffer(Clyde clyde, int index, string? name = null)
|
|
{
|
|
_clyde = clyde;
|
|
_index = index;
|
|
if (_clyde._hasGLUniformBuffers)
|
|
{
|
|
_implUBO = new GLBuffer(_clyde, BufferTarget.UniformBuffer, BufferUsageHint.StreamDraw, name);
|
|
unsafe {
|
|
_implUBO.Reallocate(sizeof(T));
|
|
}
|
|
|
|
Rebind();
|
|
}
|
|
}
|
|
|
|
public void Rebind()
|
|
{
|
|
if (_implUBO != null)
|
|
{
|
|
GL.BindBufferBase(BufferRangeTarget.UniformBuffer, _index, (int) _implUBO!.ObjectHandle);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates the buffer contents.
|
|
/// </summary>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public void Reallocate(in T data)
|
|
{
|
|
if (_implUBO != null)
|
|
{
|
|
_implUBO.Reallocate(data);
|
|
}
|
|
else
|
|
{
|
|
_implMirror = data;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// This is important for use on GLES2 - it ensures the uniforms in the specific program are up-to-date.
|
|
/// </summary>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public void Apply(GLShaderProgram program)
|
|
{
|
|
if (_implUBO == null)
|
|
{
|
|
_implMirror.Apply(_clyde, program);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|