Files
doom-dm/Engine/src/Graphics/Render/Quad/QuadRenderer.cs
2025-01-02 05:15:16 +03:00

73 lines
2.2 KiB
C#

using Engine.Graphics.Shader;
using Engine.Graphics.Texture;
using OpenTK.Graphics.OpenGL;
using OpenTK.Mathematics;
namespace Engine.Graphics.Render.Quad;
public class QuadRenderer : InstancedRenderer<QuadCommonVertex, QuadInstanceVertex>
{
private readonly TextureUnitMap _textureUnitMap = new(16);
private readonly int[] _textureUnitIndices = new int[16];
private int _frameHash;
private int _previousHash;
public QuadRenderer(Engine parEngine, int parInstanceCount)
: base(PrimitiveType.Triangles, parInstanceCount, [0, 2, 1, 2, 3, 1], [
new QuadCommonVertex { _position = new Vector3(-0.5f, -0.5f, 0), _uv = new Vector2(0, 0) },
new QuadCommonVertex { _position = new Vector3(-0.5f, 0.5f, 0), _uv = new Vector2(0, 1) },
new QuadCommonVertex { _position = new Vector3(0.5f, -0.5f, 0), _uv = new Vector2(1, 0) },
new QuadCommonVertex { _position = new Vector3(0.5f, 0.5f, 0), _uv = new Vector2(1, 1) },
],
parEngine.EngineResourceManager.Load<Program>("shader/quad"))
{
}
public void Commit(in Matrix4 parModelMatrix, in Vector4 parColor, Texture.Texture? parTexture = null)
{
if (_queuedInstanceCount >= _instanceCount)
{
throw new InvalidOperationException("Instance count exceeded");
}
var textureId = -1;
if (parTexture != null)
{
textureId = _textureUnitMap.GetUnit(parTexture);
}
_instanceVertices[_queuedInstanceCount]._modelMatrix = parModelMatrix;
_instanceVertices[_queuedInstanceCount]._color = parColor;
_instanceVertices[_queuedInstanceCount]._textureId = textureId;
_frameHash = HashCode.Combine(_frameHash, _instanceVertices[_queuedInstanceCount]);
_queuedInstanceCount++;
}
protected override void SetAdditionalUniforms(Program parProgram)
{
foreach (var (texture, unit) in _textureUnitMap.Textures)
{
texture.BindUnit(unit);
_textureUnitIndices[unit] = unit;
}
parProgram.SetUniform("uTexture", _textureUnitIndices);
}
protected override bool DataChanged()
{
return _frameHash != _previousHash;
}
public override void Reset()
{
base.Reset();
_textureUnitMap.Reset();
_previousHash = _frameHash;
_frameHash = 0;
}
}