Implement the first version of the direct rendering API.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Drawing;
|
||||
using System.Numerics;
|
||||
|
||||
namespace Dashboard.Drawing
|
||||
{
|
||||
@@ -31,11 +32,9 @@ namespace Dashboard.Drawing
|
||||
UnsignedByte,
|
||||
UnsignedShort,
|
||||
UnsignedInt,
|
||||
UnsignedLong,
|
||||
Byte,
|
||||
Short,
|
||||
Int,
|
||||
Long,
|
||||
Half,
|
||||
Float,
|
||||
Double,
|
||||
@@ -48,7 +47,6 @@ namespace Dashboard.Drawing
|
||||
UnsignedLong,
|
||||
Short,
|
||||
Int,
|
||||
Long,
|
||||
}
|
||||
|
||||
public enum BlendFunction
|
||||
@@ -138,10 +136,12 @@ namespace Dashboard.Drawing
|
||||
|
||||
public readonly record struct BlendMode(bool Enabled, BlendFactor Color, BlendFactor Alpha)
|
||||
{
|
||||
[MemberNotNullWhen(true, nameof(Unified))]
|
||||
[MemberNotNullWhen(false, nameof(Unified), nameof(UnifiedEquation))]
|
||||
public bool IsSeparate => Color != Alpha;
|
||||
public BlendFactor? Unified => IsSeparate ? null : Color;
|
||||
public BlendEquation Equation { get; init; } = BlendEquation.Add;
|
||||
public BlendEquation? UnifiedEquation => IsSeparate ? null : ColorEquation;
|
||||
public BlendEquation ColorEquation { get; init; } = BlendEquation.Add;
|
||||
public BlendEquation AlphaEquation { get; init; } = BlendEquation.Add;
|
||||
public Color Constant { get; init; } = System.Drawing.Color.Black;
|
||||
|
||||
public BlendMode(BlendFunction source, BlendFunction destination)
|
||||
@@ -176,13 +176,13 @@ namespace Dashboard.Drawing
|
||||
public int Divisor { get; init; } = 1;
|
||||
}
|
||||
|
||||
public record struct UniformDescriptor(UniformType Type, long Offset, long Size);
|
||||
public record struct UniformDescriptor(int Location, UniformType Type, long Offset, long Size);
|
||||
|
||||
public struct DrawCall(MeshPrimitive primitive, IBuffer vertexBuffer)
|
||||
public struct DrawCall(MeshPrimitive primitive, IBuffer vertexBuffer, int first, int count)
|
||||
{
|
||||
public IShader? ShaderPipeline { get; init; }
|
||||
public Box2d ViewportRegion { get; init; }
|
||||
public Box2d ScissorRegion { get; init; }
|
||||
public Box2d ViewportRegion { get; init; } = new Box2d(Vector2.Zero, Vector2.PositiveInfinity);
|
||||
public Box2d ScissorRegion { get; init; } = new Box2d(Vector2.PositiveInfinity, Vector2.PositiveInfinity);
|
||||
public WindingOrder FrontFace { get; init; } = WindingOrder.Counterclockwise;
|
||||
public FaceCulling CullMode { get; init; } = FaceCulling.Back;
|
||||
public BlendMode BlendMode { get; init; } = BlendMode.Normal;
|
||||
@@ -198,13 +198,19 @@ namespace Dashboard.Drawing
|
||||
public float LineWidth { get; init; }= 1.0f;
|
||||
|
||||
public MeshPrimitive Primitive { get; init; } = primitive;
|
||||
public List<ITexture> Textures { get; init; } = [];
|
||||
public List<ITexture?> Textures { get; init; } = [];
|
||||
public List<VertexAttribute> Attributes { get; init; } = [];
|
||||
public List<UniformDescriptor> Uniforms { get; init; } = [];
|
||||
public IndexType IndexType { get; init; } = IndexType.UnsignedShort;
|
||||
|
||||
public int First { get; init; } = first;
|
||||
public int Count { get; init; } = count;
|
||||
public long Offset { get; init; } = 0;
|
||||
public int BaseVertex { get; init; } = 0;
|
||||
|
||||
public IBuffer VertexBuffer { get; init; } = vertexBuffer;
|
||||
public IBuffer? ElementBuffer { get; init; }
|
||||
public ReadOnlyMemory<byte> UniformData { get; init; } = ReadOnlyMemory<byte>.Empty;
|
||||
public IBuffer? UniformBuffer { get; init; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
using System.Drawing;
|
||||
using System.Numerics;
|
||||
using Dashboard.Drawing;
|
||||
using Dashboard.Pal;
|
||||
using OpenTK.Graphics.OpenGL;
|
||||
@@ -12,10 +14,11 @@ namespace Dashboard.OpenGL.Drawing
|
||||
public Version DriverVersion { get; } = new Version(0, 1);
|
||||
IContextBase IContextExtensionBase.Context => Context;
|
||||
|
||||
private int _vao = -1;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
GC.SuppressFinalize(this);
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Require(DeviceContext context) => Context = context;
|
||||
@@ -23,7 +26,10 @@ namespace Dashboard.OpenGL.Drawing
|
||||
|
||||
public void Begin()
|
||||
{
|
||||
|
||||
if (_vao == -1)
|
||||
{
|
||||
GL.CreateVertexArray(out _vao);
|
||||
}
|
||||
}
|
||||
|
||||
public void End()
|
||||
@@ -51,7 +57,22 @@ namespace Dashboard.OpenGL.Drawing
|
||||
|
||||
public void Draw(DrawCall drawCall)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
Vector2 size = Context.FramebufferSize;
|
||||
drawCall.SetAll(size, _vao, false);
|
||||
|
||||
if (drawCall.ElementBuffer is null)
|
||||
{
|
||||
GL.DrawArrays(drawCall.Primitive.OpenGL, drawCall.First, drawCall.Count);
|
||||
}
|
||||
else if (drawCall.BaseVertex == 0)
|
||||
{
|
||||
GL.DrawElements(drawCall.Primitive.OpenGL, drawCall.Count, drawCall.IndexType.OpenGL, (nint)drawCall.Offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
GL.DrawElementsBaseVertex(drawCall.Primitive.OpenGL, drawCall.Count, drawCall.IndexType.OpenGL, (nint)drawCall.Offset, drawCall.BaseVertex);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,474 @@
|
||||
using System.Drawing;
|
||||
using System.Reflection.Emit;
|
||||
using System.Runtime.InteropServices;
|
||||
using Dashboard.Drawing;
|
||||
using OpenTK.Graphics.OpenGL;
|
||||
using OpenTK.Mathematics;
|
||||
using UniformType = Dashboard.Drawing.UniformType;
|
||||
using Vector2 = System.Numerics.Vector2;
|
||||
|
||||
namespace Dashboard.OpenGL.Drawing
|
||||
{
|
||||
public static class GLStateExtensions
|
||||
{
|
||||
extension(VertexAttributeType type)
|
||||
{
|
||||
public All OpenGL => type switch
|
||||
{
|
||||
VertexAttributeType.UnsignedByte => All.UnsignedByte,
|
||||
VertexAttributeType.UnsignedShort => All.UnsignedShort,
|
||||
VertexAttributeType.UnsignedInt => All.UnsignedInt,
|
||||
VertexAttributeType.Byte => All.Byte,
|
||||
VertexAttributeType.Short => All.Short,
|
||||
VertexAttributeType.Int => All.Int,
|
||||
VertexAttributeType.Half => All.HalfFloat,
|
||||
VertexAttributeType.Float => All.Float,
|
||||
VertexAttributeType.Double => All.Double,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
|
||||
public VertexAttribType VertexAttribType => (VertexAttribType)type.OpenGL;
|
||||
public VertexAttribPointerType VertexAttribPointerType => (VertexAttribPointerType)type.OpenGL;
|
||||
}
|
||||
|
||||
extension(TextureType type)
|
||||
{
|
||||
public TextureTarget OpenGL => type switch
|
||||
{
|
||||
TextureType.Texture1D => TextureTarget.Texture1D,
|
||||
TextureType.Texture2D => TextureTarget.Texture2D,
|
||||
TextureType.Texture2DArray => TextureTarget.Texture2DArray,
|
||||
TextureType.Texture2DCube => TextureTarget.TextureCubeMap,
|
||||
TextureType.Texture3D => TextureTarget.Texture3D,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
}
|
||||
|
||||
extension(BlendEquation eq)
|
||||
{
|
||||
public BlendEquationMode OpenGL => eq switch
|
||||
{
|
||||
BlendEquation.Add => BlendEquationMode.FuncAdd,
|
||||
BlendEquation.Subtract => BlendEquationMode.FuncSubtract,
|
||||
BlendEquation.Max => BlendEquationMode.Max,
|
||||
BlendEquation.Min => BlendEquationMode.Min,
|
||||
BlendEquation.ReverseSubtract => BlendEquationMode.FuncReverseSubtract,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
}
|
||||
|
||||
extension(BlendFunction mode)
|
||||
{
|
||||
public BlendingFactor OpenGL => mode switch
|
||||
{
|
||||
BlendFunction.One => BlendingFactor.One,
|
||||
BlendFunction.Zero => BlendingFactor.Zero,
|
||||
BlendFunction.SourceAlpha => BlendingFactor.SrcAlpha,
|
||||
BlendFunction.OneMinusSourceAlpha => BlendingFactor.OneMinusSrcAlpha,
|
||||
BlendFunction.DestinationAlpha => BlendingFactor.DstAlpha,
|
||||
BlendFunction.OneMinusDestinationAlpha => BlendingFactor.OneMinusDstAlpha,
|
||||
BlendFunction.SourceColor => BlendingFactor.SrcColor,
|
||||
BlendFunction.OneMinusSourceColor => BlendingFactor.OneMinusSrcColor,
|
||||
BlendFunction.DestinationColor => BlendingFactor.DstColor,
|
||||
BlendFunction.OneMinusDestinationColor => BlendingFactor.OneMinusDstColor,
|
||||
BlendFunction.ConstantColor => BlendingFactor.OneMinusConstantColor,
|
||||
BlendFunction.OneMinusConstantColor => BlendingFactor.OneMinusConstantColor,
|
||||
BlendFunction.ConstantAlpha => BlendingFactor.OneMinusConstantAlpha,
|
||||
BlendFunction.OneMinusConstantAlpha => BlendingFactor.OneMinusConstantAlpha,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
}
|
||||
|
||||
extension(TestFunction test)
|
||||
{
|
||||
public All OpenGL => test switch
|
||||
{
|
||||
TestFunction.Always => All.Always,
|
||||
TestFunction.Equal => All.Equal,
|
||||
TestFunction.Greater => All.Greater,
|
||||
TestFunction.GreaterThanOrEqual => All.Gequal,
|
||||
TestFunction.LessThan => All.Less,
|
||||
TestFunction.LessThanOrEqual => All.Lequal,
|
||||
TestFunction.Never => All.Never,
|
||||
TestFunction.NotEqual => All.Notequal,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
|
||||
public DepthFunction DepthFunction => (DepthFunction)test.OpenGL;
|
||||
public StencilFunction StencilFunction => (StencilFunction)test.OpenGL;
|
||||
}
|
||||
|
||||
extension(StencilOperation op)
|
||||
{
|
||||
public StencilOp OpenGL => op switch
|
||||
{
|
||||
StencilOperation.Keep => StencilOp.Keep,
|
||||
StencilOperation.Zero => StencilOp.Zero,
|
||||
StencilOperation.Replace => StencilOp.Replace,
|
||||
StencilOperation.Increment => StencilOp.Incr,
|
||||
StencilOperation.UncheckedIncrement => StencilOp.IncrWrap,
|
||||
StencilOperation.Decrement => StencilOp.Decr,
|
||||
StencilOperation.UncheckedDecrement => StencilOp.DecrWrap,
|
||||
StencilOperation.Invert => StencilOp.Invert,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
}
|
||||
|
||||
extension(MeshPrimitive primitive)
|
||||
{
|
||||
public PrimitiveType OpenGL => primitive switch
|
||||
{
|
||||
MeshPrimitive.Line => PrimitiveType.Lines,
|
||||
MeshPrimitive.Point => PrimitiveType.Points,
|
||||
MeshPrimitive.Triangle => PrimitiveType.Triangles,
|
||||
MeshPrimitive.TriangleFan => PrimitiveType.TriangleFan,
|
||||
MeshPrimitive.TriangleStrip => PrimitiveType.TriangleStrip,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
}
|
||||
|
||||
extension(IndexType index)
|
||||
{
|
||||
public DrawElementsType OpenGL => index switch
|
||||
{
|
||||
IndexType.Int or IndexType.UnsignedInt => DrawElementsType.UnsignedInt,
|
||||
IndexType.Short or IndexType.UnsignedShort => DrawElementsType.UnsignedShort,
|
||||
IndexType.UnsignedLong => throw new NotSupportedException(),
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
}
|
||||
|
||||
extension(BlendMode mode)
|
||||
{
|
||||
public void SetEnabled()
|
||||
{
|
||||
if (mode.Enabled)
|
||||
GL.Enable(EnableCap.Blend);
|
||||
else
|
||||
GL.Disable(EnableCap.Blend);
|
||||
}
|
||||
|
||||
public void SetMode()
|
||||
{
|
||||
if (mode.IsSeparate)
|
||||
{
|
||||
GL.BlendEquationSeparate(mode.ColorEquation.OpenGL, mode.AlphaEquation.OpenGL);
|
||||
GL.BlendFuncSeparate(
|
||||
mode.Color.Source.OpenGL, mode.Color.Destination.OpenGL,
|
||||
mode.Alpha.Source.OpenGL, mode.Alpha.Destination.OpenGL);
|
||||
}
|
||||
else
|
||||
{
|
||||
GL.BlendEquation(mode.UnifiedEquation.Value.OpenGL);
|
||||
GL.BlendFunc(mode.Unified.Value.Source.OpenGL, mode.Unified.Value.Destination.OpenGL);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetConstant()
|
||||
{
|
||||
GL.BlendColor(mode.Constant.R / 255f, mode.Constant.G / 255f,mode.Constant.B / 255f,mode.Constant.A / 255f);
|
||||
}
|
||||
|
||||
public void SetAll()
|
||||
{
|
||||
mode.SetEnabled();
|
||||
mode.SetConstant();
|
||||
mode.SetMode();
|
||||
}
|
||||
}
|
||||
|
||||
extension(DepthMode mode)
|
||||
{
|
||||
public void SetEnabled()
|
||||
{
|
||||
if (mode.Test)
|
||||
GL.Enable(EnableCap.DepthTest);
|
||||
else
|
||||
GL.Disable(EnableCap.DepthTest);
|
||||
}
|
||||
|
||||
public void SetMask() => GL.DepthMask(mode.Mask);
|
||||
|
||||
public void SetFunction() => GL.DepthFunc(mode.Function.DepthFunction);
|
||||
|
||||
public void SetAll()
|
||||
{
|
||||
mode.SetEnabled();
|
||||
mode.SetMask();
|
||||
mode.SetFunction();
|
||||
}
|
||||
}
|
||||
|
||||
extension(StencilMode mode)
|
||||
{
|
||||
public void SetEnabled()
|
||||
{
|
||||
if (mode.Enabled)
|
||||
GL.Enable(EnableCap.StencilTest);
|
||||
else
|
||||
GL.Disable(EnableCap.StencilTest);
|
||||
}
|
||||
|
||||
public void SetFunction() => GL.StencilFunc(mode.Function.StencilFunction, mode.Reference, (uint)mode.Mask);
|
||||
|
||||
public void SetOperations() => GL.StencilOp(mode.Fail.OpenGL, mode.DepthFail.OpenGL, mode.Pass.OpenGL);
|
||||
|
||||
public void SetAll()
|
||||
{
|
||||
mode.SetEnabled();
|
||||
mode.SetFunction();
|
||||
mode.SetOperations();
|
||||
}
|
||||
}
|
||||
|
||||
extension(DrawCall call)
|
||||
{
|
||||
public void UsePipeline() => GL.UseProgram((call.ShaderPipeline as GLShader)?.Handle ?? 0);
|
||||
|
||||
// TODO: clamp to viewport size
|
||||
|
||||
public void SetViewport(Vector2 size)
|
||||
{
|
||||
Vector2 min = Vector2.Max(Vector2.Zero, call.ViewportRegion.Min);
|
||||
Vector2 max = Vector2.Min(size, call.ViewportRegion.Max);
|
||||
|
||||
GL.Viewport(
|
||||
(int)Math.Round(min.X),
|
||||
(int)Math.Round(size.Y - max.Y),
|
||||
(int)Math.Round(max.X - min.X),
|
||||
(int)Math.Round(max.Y - min.Y));
|
||||
}
|
||||
|
||||
public void SetScissor(Vector2 size)
|
||||
{
|
||||
if (call.ScissorRegion == new Box2d(Vector2.PositiveInfinity, Vector2.PositiveInfinity))
|
||||
{
|
||||
GL.Disable(EnableCap.ScissorTest);
|
||||
return;
|
||||
}
|
||||
|
||||
GL.Enable(EnableCap.ScissorTest);
|
||||
GL.Scissor(
|
||||
(int)Math.Round(call.ViewportRegion.Left),
|
||||
(int)Math.Round(size.Y - call.ViewportRegion.Top),
|
||||
(int)Math.Round(call.ViewportRegion.Right - call.ViewportRegion.Left),
|
||||
(int)Math.Round(call.ViewportRegion.Bottom - call.ViewportRegion.Top));
|
||||
}
|
||||
|
||||
public void SetFrontFace()
|
||||
{
|
||||
GL.FrontFace(call.FrontFace switch
|
||||
{
|
||||
WindingOrder.Clockwise => FrontFaceDirection.Cw,
|
||||
WindingOrder.Counterclockwise => FrontFaceDirection.Ccw,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
});
|
||||
}
|
||||
|
||||
public void SetCullMode()
|
||||
{
|
||||
if (call.CullMode == FaceCulling.None)
|
||||
{
|
||||
GL.Disable(EnableCap.CullFace);
|
||||
return;
|
||||
}
|
||||
|
||||
GL.Enable(EnableCap.CullFace);
|
||||
|
||||
GL.CullFace(call.CullMode switch
|
||||
{
|
||||
FaceCulling.Both => TriangleFace.FrontAndBack,
|
||||
FaceCulling.Front => TriangleFace.Front,
|
||||
FaceCulling.Back => TriangleFace.Back,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
});
|
||||
}
|
||||
|
||||
public void SetBlendMode() => call.BlendMode.SetAll();
|
||||
public void SetDepthMode() => call.DepthMode.SetAll();
|
||||
public void SetStencilMode() => call.StencilMode.SetAll();
|
||||
|
||||
public void SetPrimitiveRestart()
|
||||
{
|
||||
if (!call.EnableRestart)
|
||||
{
|
||||
GL.Disable(EnableCap.PrimitiveRestart);
|
||||
return;
|
||||
}
|
||||
|
||||
GL.Enable(EnableCap.PrimitiveRestart);
|
||||
GL.PrimitiveRestartIndex((uint)call.RestartIndex);
|
||||
}
|
||||
|
||||
public void SetColorMask()
|
||||
{
|
||||
GL.ColorMask(call.RedMask, call.GreenMask, call.BlueMask, call.AlphaMask);
|
||||
}
|
||||
|
||||
public void SetPointSize()
|
||||
{
|
||||
GL.PointSize(call.PointSize);
|
||||
}
|
||||
|
||||
public void SetLineWidth()
|
||||
{
|
||||
GL.LineWidth(call.LineWidth);
|
||||
}
|
||||
|
||||
public void UseTextures()
|
||||
{
|
||||
int i = 0;
|
||||
foreach (ITexture? texture in call.Textures)
|
||||
{
|
||||
GL.ActiveTexture((TextureUnit)((int)TextureUnit.Texture0 + i));
|
||||
if (texture is GLTexture glTexture)
|
||||
{
|
||||
GL.BindTexture(glTexture.Type.OpenGL, glTexture.Handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
GL.BindTexture(TextureTarget.Texture2D, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateVertexArrays(int vao)
|
||||
{
|
||||
GL.BindVertexArray(vao);
|
||||
|
||||
if (call.ElementBuffer != null)
|
||||
{
|
||||
GL.BindBuffer(BufferTarget.ElementArrayBuffer, (call.ElementBuffer as GLBuffer)?.Handle ?? 0);
|
||||
}
|
||||
|
||||
GL.BindBuffer(BufferTarget.ArrayBuffer, (call.VertexBuffer as GLBuffer)?.Handle ?? 0);
|
||||
|
||||
foreach(VertexAttribute attrib in call.Attributes)
|
||||
{
|
||||
GL.VertexAttribPointer(
|
||||
(uint)attrib.Location,
|
||||
attrib.Components,
|
||||
attrib.Type.VertexAttribPointerType,
|
||||
false,
|
||||
(int)attrib.Stride,
|
||||
(nint)attrib.Offset);
|
||||
GL.EnableVertexAttribArray((uint)attrib.Location);
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateUniforms(bool transpose = false)
|
||||
{
|
||||
int bufferIndex = 0;
|
||||
foreach (UniformDescriptor uniform in call.Uniforms)
|
||||
{
|
||||
ReadOnlySpan<byte> uniformData = call.UniformData.Span;
|
||||
|
||||
switch (uniform.Type)
|
||||
{
|
||||
case UniformType.I1:
|
||||
{
|
||||
ReadOnlySpan<int> span = CastSpan<int>(uniformData, uniform.Offset, uniform.Size);
|
||||
GL.Uniform1i(uniform.Location, span.Length, span);
|
||||
break;
|
||||
}
|
||||
case UniformType.I2:
|
||||
{
|
||||
ReadOnlySpan<Vector2i> span = CastSpan<Vector2i>(uniformData, uniform.Offset, uniform.Size);
|
||||
GL.Uniform2i(uniform.Location, span.Length, span);
|
||||
break;
|
||||
}
|
||||
case UniformType.I3:
|
||||
{
|
||||
ReadOnlySpan<Vector3i> span = CastSpan<Vector3i>(uniformData, uniform.Offset, uniform.Size);
|
||||
GL.Uniform3i(uniform.Location, span.Length, span);
|
||||
break;
|
||||
}
|
||||
case UniformType.I4:
|
||||
{
|
||||
ReadOnlySpan<Vector4i> span = CastSpan<Vector4i>(uniformData, uniform.Offset, uniform.Size);
|
||||
GL.Uniform4i(uniform.Location, span.Length, span);
|
||||
break;
|
||||
}
|
||||
case UniformType.F1:
|
||||
{
|
||||
ReadOnlySpan<float> span = CastSpan<float>(uniformData, uniform.Offset, uniform.Size);
|
||||
GL.Uniform1f(uniform.Location, span.Length, span);
|
||||
break;
|
||||
}
|
||||
case UniformType.F2:
|
||||
{
|
||||
ReadOnlySpan<Vector2> span = CastSpan<Vector2>(uniformData, uniform.Offset, uniform.Size);
|
||||
GL.Uniform2f(uniform.Location, span.Length, span);
|
||||
break;
|
||||
}
|
||||
case UniformType.F3:
|
||||
{
|
||||
ReadOnlySpan<Vector3> span = CastSpan<Vector3>(uniformData, uniform.Offset, uniform.Size);
|
||||
GL.Uniform3f(uniform.Location, span.Length, span);
|
||||
break;
|
||||
}
|
||||
case UniformType.F4:
|
||||
{
|
||||
ReadOnlySpan<Vector4> span = CastSpan<Vector4>(uniformData, uniform.Offset, uniform.Size);
|
||||
GL.Uniform4f(uniform.Location, span.Length, span);
|
||||
break;
|
||||
}
|
||||
case UniformType.Mat2:
|
||||
{
|
||||
ReadOnlySpan<Matrix2> span = CastSpan<Matrix2>(uniformData, uniform.Offset, uniform.Size);
|
||||
GL.UniformMatrix2f(uniform.Location, span.Length, transpose, span);
|
||||
break;
|
||||
}
|
||||
case UniformType.Mat3:
|
||||
{
|
||||
ReadOnlySpan<Matrix3> span = CastSpan<Matrix3>(uniformData, uniform.Offset, uniform.Size);
|
||||
GL.UniformMatrix3f(uniform.Location, span.Length, transpose, span);
|
||||
break;
|
||||
}
|
||||
case UniformType.Mat4:
|
||||
{
|
||||
ReadOnlySpan<Matrix4> span = CastSpan<Matrix4>(uniformData, uniform.Offset, uniform.Size);
|
||||
GL.UniformMatrix4f(uniform.Location, span.Length, transpose, span);
|
||||
break;
|
||||
}
|
||||
case UniformType.Buffer:
|
||||
{
|
||||
int buffer = (call.UniformBuffer as GLBuffer)?.Handle ?? 0;
|
||||
int index = bufferIndex++;
|
||||
GL.BindBufferRange(BufferTarget.UniformBuffer, (uint)index, buffer, (nint)uniform.Offset, (int)uniform.Size);
|
||||
break;
|
||||
}
|
||||
default: throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
ReadOnlySpan<T> CastSpan<T>(ReadOnlySpan<byte> bytes, long offset, long size)
|
||||
where T : unmanaged
|
||||
{
|
||||
return MemoryMarshal.Cast<byte, T>(bytes.Slice((int)offset, (int)size));
|
||||
}
|
||||
}
|
||||
|
||||
public void SetAll(Vector2 size, int vao, bool transpose = false)
|
||||
{
|
||||
call.UsePipeline();
|
||||
call.SetViewport(size); call.SetScissor(size);
|
||||
call.SetFrontFace();
|
||||
call.SetCullMode();
|
||||
call.SetBlendMode();
|
||||
call.SetDepthMode();
|
||||
call.SetStencilMode();
|
||||
call.SetPrimitiveRestart();
|
||||
call.SetColorMask();
|
||||
call.SetDepthMode();
|
||||
call.SetPointSize();
|
||||
call.SetLineWidth();
|
||||
call.UseTextures();
|
||||
call.UpdateUniforms(transpose);
|
||||
call.UpdateVertexArrays(vao);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -37,7 +37,7 @@ namespace Dashboard.OpenGL.Drawing
|
||||
GL.LinkProgram(program);
|
||||
GL.GetProgrami(program, ProgramProperty.LinkStatus, out int flag);
|
||||
|
||||
if (flag == 0)
|
||||
if (flag != 0)
|
||||
return program;
|
||||
|
||||
GL.GetProgramInfoLog(program, out log);
|
||||
|
||||
@@ -60,6 +60,8 @@ namespace Dashboard.Controls
|
||||
dcb.ResetScissor();
|
||||
dcb.ResetTransforms();
|
||||
|
||||
dcb.ClearDepth();
|
||||
|
||||
if (Background is SolidColorBrush solidColorBrush)
|
||||
dcb.ClearColor(solidColorBrush.Color);
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ Application app = new Pal2Application(new ToolkitOptions()
|
||||
{
|
||||
GraphicsApiHints = new OpenGLGraphicsApiHints()
|
||||
{
|
||||
Version = new Version(3, 2),
|
||||
Version = new Version(4, 1),
|
||||
ForwardCompatibleFlag = true,
|
||||
DebugFlag = true,
|
||||
Profile = OpenGLProfile.Core,
|
||||
@@ -82,9 +82,39 @@ float[] vertices = new float[]
|
||||
};
|
||||
vertex.Write(0, vertices);
|
||||
|
||||
DrawCall call = new DrawCall(MeshPrimitive.Triangle, vertex)
|
||||
IShader shader = direct.CreatePipeline(new GlslShaderCreateInfo()
|
||||
{
|
||||
ShaderPipeline = null,
|
||||
VertexShader =
|
||||
"""
|
||||
#version 410
|
||||
layout (location = 0) in vec3 apos;
|
||||
layout (location = 1) in vec4 acolor;
|
||||
|
||||
out vec4 vcolor;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(apos, 1);
|
||||
vcolor = acolor;
|
||||
}
|
||||
""",
|
||||
FragmentShader =
|
||||
"""
|
||||
#version 410
|
||||
in vec4 vcolor;
|
||||
out vec4 fcolor;
|
||||
|
||||
void main()
|
||||
{
|
||||
fcolor = vcolor;
|
||||
}
|
||||
|
||||
""",
|
||||
});
|
||||
|
||||
DrawCall call = new DrawCall(MeshPrimitive.Triangle, vertex, 0, 3)
|
||||
{
|
||||
ShaderPipeline = shader,
|
||||
Attributes =
|
||||
[
|
||||
new VertexAttribute(0, 3, VertexAttributeType.Float, 0, 8 * sizeof(float)),
|
||||
|
||||
Reference in New Issue
Block a user