GetBufferSubData doesn't like being called too much, too bad

This commit is contained in:
Asval 2023-08-12 19:09:48 +02:00
parent d97f570328
commit 51516cd7d7
3 changed files with 36 additions and 21 deletions

View File

@ -22,6 +22,7 @@ public class Skeleton : IDisposable
public readonly int BoneCount;
public readonly Dictionary<string, Bone> BonesByLoweredName;
private Matrix4x4[] _boneMatriceAtFrame;
public Skeleton()
{
@ -116,6 +117,12 @@ public class Skeleton : IDisposable
_ssbo = new BufferObject<Matrix4x4>(BoneCount, BufferTarget.ShaderStorageBuffer);
_ssbo.UpdateRange(BoneCount, Matrix4x4.Identity);
_boneMatriceAtFrame = new Matrix4x4[BoneCount];
for (int boneIndex = 0; boneIndex < _boneMatriceAtFrame.Length; boneIndex++)
{
_boneMatriceAtFrame[boneIndex] = Matrix4x4.Identity;
}
}
public void UpdateAnimationMatrices(Animation animation, bool rotationOnly)
@ -126,7 +133,7 @@ public class Skeleton : IDisposable
foreach (var bone in BonesByLoweredName.Values)
{
var boneRelation = bone.IsRoot ? bone.Rest.Relation : bone.Rest.LocalMatrix * _ssbo.Get(bone.ParentIndex);
var boneMatrix = bone.IsRoot ? bone.Rest.Relation : bone.Rest.LocalMatrix * _boneMatriceAtFrame[bone.ParentIndex];
if (bone.IsAnimated)
{
var (s, f) = GetBoneFrameData(bone, animation);
@ -136,18 +143,20 @@ public class Skeleton : IDisposable
var boneScale = bone.Rest.Scale;
sequence.Tracks[bone.SkeletonIndex].GetBoneTransform(f, sequence.NumFrames, ref boneOrientation, ref bonePosition, ref boneScale);
if (!bone.IsRoot) boneRelation = _ssbo.Get(bone.ParentIndex);
if (!bone.IsRoot) boneMatrix = _boneMatriceAtFrame[bone.ParentIndex];
bonePosition = rotationOnly ? bone.Rest.Position : bonePosition * Constants.SCALE_DOWN_RATIO;
_ssbo.Update(bone.Index, new Transform
boneMatrix = new Transform
{
Relation = boneRelation,
Relation = boneMatrix,
Rotation = boneOrientation,
Position = bonePosition,
Scale = boneScale
}.Matrix);
}.Matrix;
}
else _ssbo.Update(bone.Index, boneRelation);
_ssbo.Update(bone.Index, boneMatrix);
_boneMatriceAtFrame[bone.Index] = boneMatrix;
}
_ssbo.Unbind();

View File

@ -6,24 +6,26 @@ namespace FModel.Views.Snooper.Buffers;
public class BufferObject<TDataType> : IDisposable where TDataType : unmanaged
{
private readonly int _handle;
private readonly int _sizeOf;
private readonly BufferTarget _bufferTarget;
private BufferObject(BufferTarget bufferTarget)
private unsafe BufferObject(BufferTarget bufferTarget)
{
_bufferTarget = bufferTarget;
_handle = GL.GenBuffer();
_sizeOf = sizeof(TDataType);
Bind();
}
public unsafe BufferObject(TDataType[] data, BufferTarget bufferTarget) : this(bufferTarget)
public BufferObject(TDataType[] data, BufferTarget bufferTarget) : this(bufferTarget)
{
GL.BufferData(bufferTarget, data.Length * sizeof(TDataType), data, BufferUsageHint.StaticDraw);
GL.BufferData(bufferTarget, data.Length * _sizeOf, data, BufferUsageHint.StaticDraw);
}
public unsafe BufferObject(int length, BufferTarget bufferTarget) : this(bufferTarget)
public BufferObject(int length, BufferTarget bufferTarget) : this(bufferTarget)
{
GL.BufferData(bufferTarget, length * sizeof(TDataType), IntPtr.Zero, BufferUsageHint.DynamicDraw);
GL.BufferData(bufferTarget, length * _sizeOf, IntPtr.Zero, BufferUsageHint.DynamicDraw);
}
public void UpdateRange(int count, TDataType data)
@ -33,22 +35,22 @@ public class BufferObject<TDataType> : IDisposable where TDataType : unmanaged
Unbind();
}
public unsafe void Update(int offset, TDataType data)
public void Update(int offset, TDataType data)
{
GL.BufferSubData(_bufferTarget, (IntPtr) (offset * sizeof(TDataType)), sizeof(TDataType), ref data);
GL.BufferSubData(_bufferTarget, (IntPtr) (offset * _sizeOf), _sizeOf, ref data);
}
public unsafe void Update(TDataType[] data)
public void Update(TDataType[] data)
{
Bind();
GL.BufferSubData(_bufferTarget, IntPtr.Zero, data.Length * sizeof(TDataType), data);
GL.BufferSubData(_bufferTarget, IntPtr.Zero, data.Length * _sizeOf, data);
Unbind();
}
public unsafe TDataType Get(int offset)
public TDataType Get(int offset)
{
TDataType data = default;
GL.GetBufferSubData(_bufferTarget, (IntPtr) (offset * sizeof(TDataType)), sizeof(TDataType), ref data);
GL.GetBufferSubData(_bufferTarget, (IntPtr) (offset * _sizeOf), _sizeOf, ref data);
return data;
}

View File

@ -7,25 +7,29 @@ namespace FModel.Views.Snooper.Buffers;
public class VertexArrayObject<TVertexType, TIndexType> : IDisposable where TVertexType : unmanaged where TIndexType : unmanaged
{
private readonly int _handle;
private readonly int _sizeOfVertex;
private readonly int _sizeOfIndex;
public VertexArrayObject(BufferObject<TVertexType> vbo, BufferObject<TIndexType> ebo)
public unsafe VertexArrayObject(BufferObject<TVertexType> vbo, BufferObject<TIndexType> ebo)
{
_handle = GL.GenVertexArray();
_sizeOfVertex = sizeof(TVertexType);
_sizeOfIndex = sizeof(TIndexType);
Bind();
vbo.Bind();
ebo.Bind();
}
public unsafe void VertexAttributePointer(uint index, int count, VertexAttribPointerType type, int vertexSize, int offset)
public void VertexAttributePointer(uint index, int count, VertexAttribPointerType type, int vertexSize, int offset)
{
switch (type)
{
case VertexAttribPointerType.Int:
GL.VertexAttribIPointer(index, count, VertexAttribIntegerType.Int, vertexSize * sizeof(TVertexType), (IntPtr) (offset * sizeof(TVertexType)));
GL.VertexAttribIPointer(index, count, VertexAttribIntegerType.Int, vertexSize * _sizeOfVertex, (IntPtr) (offset * _sizeOfVertex));
break;
default:
GL.VertexAttribPointer(index, count, type, false, vertexSize * sizeof(TVertexType), offset * sizeof(TVertexType));
GL.VertexAttribPointer(index, count, type, false, vertexSize * _sizeOfVertex, offset * _sizeOfVertex);
break;
}
GL.EnableVertexAttribArray(index);