make new opengl source generator

This commit is contained in:
Youmu Liu
2026-08-26 18:12:08 +08:00
parent 65041ff8bc
commit 75bf7fc139
126 changed files with 8934 additions and 26139 deletions
@@ -0,0 +1,36 @@
// -----------------------------------------------------------------------------
// file="Image.Native"
// Project: StgSharp
// Copyright (c) Nitload.
// SPDX-License-Identifier: MIT
// -----------------------------------------------------------------------------
using StgSharp.Internal;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace StgSharp.Graphics
{
internal static unsafe partial class GraphicFramework
{
[LibraryImport(
Native.LibName,
EntryPoint = "loadImageData",
StringMarshalling = StringMarshalling.Utf8)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
internal static partial void InternalLoadImage(
string fileName,
ImageInfo* output,
ImageLoader loader
);
[LibraryImport(Native.LibName, EntryPoint = "unloadImageData")]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
internal static partial void InternalUnloadImage(
ImageInfo* output
);
}
}
+176
View File
@@ -0,0 +1,176 @@
// -----------------------------------------------------------------------------
// file="Image"
// Project: StgSharp
// Copyright (c) Nitload.
// SPDX-License-Identifier: MIT
// -----------------------------------------------------------------------------
using StgSharp.Graphics.OpenGL;
using System;
using System.Runtime.CompilerServices;
namespace StgSharp.Graphics
{
public class Image : IImageProvider
{
private byte[] _data;
private ImageInfo _rawInfo;
private int _pixelUpdateCount = 0;
internal unsafe Image()
{
_rawInfo = new ImageInfo();
}
internal Image(
ImageInfo information
)
{
_rawInfo = information;
_data = [];
// int length = _rawInfo.width * _rawInfo.height * _rawInfo.channel;
}
public (int width, int height) Size => (_rawInfo.Width, _rawInfo.Height);
public byte[] PixelBuffer
{
get
{
if ((_data.Length == 0) || (_data == null))
{
GetBytes();
return _data!;
}
return _data;
}
}
public ImageChannel Channel => _rawInfo.Channel;
/// <summary>
/// Hash code of time pixels updated last time.
/// </summary>
public int PixelUpdateCount
{
get => _pixelUpdateCount;
internal set => _pixelUpdateCount = value;
}
public int ChannelCount => _rawInfo.ChannelCount;
public int Height
{
get => _rawInfo.Height;
internal set => _rawInfo.Height = value;
}
public int Width
{
get => _rawInfo.Width;
internal set => _rawInfo.Width = value;
}
public int PixelSize => ImageInfo.GetPixelSize(_rawInfo.pixelLayout, _rawInfo.Channel);
public PixelChannelLayout PixelLayout
{
get => _rawInfo.pixelLayout;
private set => _rawInfo.pixelLayout = value;
}
internal ref byte[] Data => ref _data;
public void FromBytes(
byte[] stream
) { }
public static unsafe Image FromFile(
string route,
ImageLoader loader
)
{
Image ret = new Image();
fixed (ImageInfo* iptr = &ret._rawInfo) {
GraphicFramework.InternalLoadImage(route, iptr, loader);
}
return ret;
}
public static Image FromMemory(
(int width, int height) size,
ImageChannel channel,
byte[] stream
)
{
ImageInfo _info = new ImageInfo
{
Height = size.height,
Width = size.width,
Channel = channel,
StreamPtr = IntPtr.Zero
};
Image ret = new Image(_info);
ret.PixelLayout = PixelChannelLayout.Byte;
ret._data = stream;
return ret;
}
public static Image FromMemory(
(int width, int height) size,
ImageChannel channel,
PixelChannelLayout layout,
byte[] stream
)
{
ImageInfo _info = new ImageInfo
{
Height = size.height,
Width = size.width,
Channel = channel,
StreamPtr = IntPtr.Zero
};
Image ret = new Image(_info);
ret.PixelLayout = layout;
ret._data = stream;
return ret;
}
public unsafe byte[] GetBytes()
{
if (_data.Length == 0)
{
int size = Width * Height * ImageInfo.GetPixelSize(PixelLayout, Channel);
_data = new Span<byte>((byte*)_rawInfo.StreamPtr, size).ToArray();
fixed (ImageInfo* pptr = &_rawInfo) {
GraphicFramework.InternalUnloadImage(pptr);
}
_rawInfo.StreamPtr = IntPtr.Zero;
}
return _data;
}
public Image ProvideImage()
{
return this;
}
internal static Image FromMemory(
ImageInfo info,
byte[] data,
int operationCount
)
{
return new Image
{
_rawInfo = info,
_data = data,
_pixelUpdateCount = operationCount
};
}
}
}
File diff suppressed because it is too large Load Diff
@@ -111,4 +111,4 @@ namespace StgSharp.Graphics.OpenGL
}
}
}
}
+67
View File
@@ -0,0 +1,67 @@
# StgSharp.Graphics retired sources
This directory contains source snapshots retired during the Graphics/OpenGL
reorganization on 2026-08-26. Files use the `.cs.old` suffix so that SDK-style
project globbing does not compile them.
## Retired without an active replacement
- `framework.cs.old`: unused GL/debug delegate declarations.
- `Vulkan.*.cs.old`: unreferenced Vulkan placeholders.
- `OpenGL.glRenderStream.ThreadSecurity.cs.old`: unused thread/context fields.
- `OpenGL.Generated.GlCommandHistory.g.cs.old`: generator report data that does
not belong in the runtime assembly.
## Split before retirement
- `gl.cs.old`: image P/Invokes were temporarily split out and later retired;
legacy OpenGL native helpers were replaced with direct calls through the
OpenGL function table.
- `glfw.dtruct.cs.old`: reduced to the four opaque GLFW types currently used by
the wrapper in `glfw.struct.cs`.
- `OpenGL.glType.cs.old`: only `glSync` remains active in `OpenGL/glSync.cs`.
- `ShaderEdit.ShaderGenerator.cs.old`: only the temporary
`InternalShaderType` compatibility enum remains active.
- `GraphicInitializer.cs.old`: merged into the correctly named `GraphicModule`
in `glfw.cs`.
- `OpenGL.glApiManager.cs.old` and `OpenGL.glApiManager.Const.cs.old`: the active
compatibility loader retains only core-version loading; the unused extension
classification table and 619 write-only flags were retired.
## Retired during the image simplification
- `Image.cs.old`: the former image/decoder/OpenGL-format aggregate.
- `ImageInfo.cs.old` and `Image.Native.cs.old`: the mismatched native decoder
state and its P/Invoke bridge.
- `Pixels.cs.old`: the unused and incorrectly sized legacy pixel abstraction.
- `CPUanimation.ImageHelper.cs.old`: incomplete resizing and movement logic;
image transformations now belong to a caller-selected codec or image library.
- `CPUanimation.IImageProvider.cs.old`: the redundant image-returns-itself
provider contract.
- `TexturePipeline.cs.old`: an unused pipeline payload tied to the retired
non-generic image type.
- `OpenGL.Buffer.AutoTexture.cs.old`: the unused texture cache depended on image
mutation counters and also contained incorrect slot/recycling bookkeeping.
## Retired during the data-only OpenGL resource migration
- `Define.BufferObjectBase.cs.old` and
`OpenGL.Buffer.GLBufferObjectBase.cs.old`: the former resource base classes
injected `glRender`/`OpenGLFunction` and attempted context-bound disposal from
resource objects and finalizers.
- `OpenGL.glRenderObjectGenrator.cs.old`: the former factories implicitly
created resources through a render-stream instance.
- `OpenGL.ShaderEdit.IglConvertable.cs.old`, `ShaderEdit.ShaderStruct.cs.old`,
and `ShaderEdit.InternalShaderType.cs.old`: the obsolete shader conversion
layer submitted uniforms through the global `CurrentGL` context.
Active OpenGL resource and shader types are passive handle records. Creation,
binding, upload, compilation, use, and deletion are explicitly submitted to an
`OpenGLFunction` instance.
The active `Image<TPixel>` is only a tightly packed managed bitmap buffer. It
does not load files, convert formats, resize pixels, or retain native memory.
These files are historical references, not candidates for restoration as a
group. Restore individual behavior only after checking it against the new
Graphics and OpenGL architecture.
@@ -0,0 +1,37 @@
// -----------------------------------------------------------------------------
// file="InternalShaderType"
// Project: StgSharp
// Copyright (c) Nitload.
// SPDX-License-Identifier: MIT
// -----------------------------------------------------------------------------
namespace StgSharp.Graphics.ShaderEdit
{
// Temporary compatibility type for ShaderStruct. The new shader model will replace it.
public enum InternalShaderType
{
#pragma warning disable CS1591
Struct,
Void,
Int,
UInt,
Float,
Double,
Vector2,
Vector3,
Vector4,
VectorD2,
VectorD3,
VectorD4,
Matrix2x2,
Matrix2x3,
Matrix2x4,
Matrix3x2,
Matrix3x3,
Matrix3x4,
Matrix4x2,
Matrix4x3,
Matrix4x4,
#pragma warning restore CS1591
}
}
+1 -48
View File
@@ -5,14 +5,11 @@
// SPDX-License-Identifier: MIT
// -----------------------------------------------------------------------------
using StgSharp.Graphics.OpenGL;
using StgSharp.Graphics.ShaderEdit;
using System;
namespace StgSharp.Mathematics.Graphics
{
public sealed class Camera : IglConvertable
public sealed class Camera
{
private bool _isLookAtAvailable;
@@ -24,7 +21,6 @@ namespace StgSharp.Mathematics.Graphics
internal Radius _pitch;
internal Radius _row;
internal Radius _yaw;
internal Uniform<GraphicsMatrix> convertedUniform;
internal Vec3 _target, up;
public Camera()
@@ -75,36 +71,6 @@ namespace StgSharp.Mathematics.Graphics
return Projection * View;
}
public void DisplayGLtypeDefinition()
{
Console.WriteLine("uniform matrix4x4 cameraName;");
}
/// <summary>
/// Get all uniform related to this <see cref="Camera" />.
/// </summary>
/// <param _label="source">
/// Shader program requires this camera.
/// </param>
/// <param _label="uniformName">
/// ContextName of all related uniforms. If you fallow form from <see ///
/// cref="IglConvertable.DisplayGLtypeDefinition" />
/// </param>
/// <exception cref="ArgumentException">
///
/// </exception>
public unsafe void GainAllUniforms(
ShaderProgram source,
params string[] uniformName
)
{
if ((uniformName is null) || (uniformName.Length != 1)) {
throw new ArgumentException(
"Camera needs exactly one uniform.", nameof(uniformName));
}
convertedUniform = source.GetUniform<GraphicsMatrix>(uniformName[0]);
}
public void MoveNear(
float distance
)
@@ -129,12 +95,6 @@ namespace StgSharp.Mathematics.Graphics
_isLookAtAvailable = false;
}
public unsafe void SetAllUniforms()
{
// Console.WriteLine(Projection * ViewBase);
OpenGLFunction.CurrentGL.SetUniformValue(convertedUniform, Projection * View);
}
public void SetViewDirection(
Vec3 position,
Vec3 target,
@@ -212,13 +172,6 @@ namespace StgSharp.Mathematics.Graphics
}
}
ShaderStruct IglConvertable.GetConvertedGLtype()
{
throw new NotImplementedException();
}
~Camera() { }
#region rotation
public void Yaw(
+73 -143
View File
@@ -5,172 +5,102 @@
// SPDX-License-Identifier: MIT
// -----------------------------------------------------------------------------
using StgSharp.Graphics.OpenGL;
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace StgSharp.Graphics
{
public class Image : IImageProvider
/// <summary>
/// Owns a tightly packed, two-dimensional managed pixel buffer.
/// </summary>
/// <typeparam name="TPixel">
/// Unmanaged storage layout of one pixel.
/// </typeparam>
public sealed class Image<TPixel> where TPixel : unmanaged
{
private byte[] _data;
private ImageInfo _rawInfo;
private int _pixelUpdateCount = 0;
private readonly TPixel[] _pixels;
internal unsafe Image()
{
_rawInfo = new ImageInfo();
}
public Image(
int width,
int height
) : this(width, height, new TPixel[GetRequiredPixelCount(width, height)]) { }
internal Image(
ImageInfo information
)
{
_rawInfo = information;
_data = [];
// int length = _rawInfo.width * _rawInfo.height * _rawInfo.channel;
}
public (int width, int height) Size => (_rawInfo.Width, _rawInfo.Height);
public byte[] PixelBuffer
{
get
{
if ((_data.Length == 0) || (_data == null))
{
GetBytes();
return _data!;
}
return _data;
}
}
public ImageChannel Channel => _rawInfo.Channel;
public Image(
(int width, int height) size
) : this(size.width, size.height) { }
/// <summary>
/// Hash code of time pixels updated last time.
/// Wraps <paramref name="pixels" /> without copying it.
/// </summary>
public int PixelUpdateCount
{
get => _pixelUpdateCount;
internal set => _pixelUpdateCount = value;
}
public int ChannelCount => _rawInfo.ChannelCount;
public int Height
{
get => _rawInfo.Height;
internal set => _rawInfo.Height = value;
}
public int Width
{
get => _rawInfo.Width;
internal set => _rawInfo.Width = value;
}
public int PixelSize => ImageInfo.GetPixelSize(_rawInfo.pixelLayout, _rawInfo.Channel);
public PixelChannelLayout PixelLayout
{
get => _rawInfo.pixelLayout;
private set => _rawInfo.pixelLayout = value;
}
internal ref byte[] Data => ref _data;
public void FromBytes(
byte[] stream
) { }
public static unsafe Image FromFile(
string route,
ImageLoader loader
public Image(
int width,
int height,
TPixel[] pixels
)
{
Image ret = new Image();
fixed (ImageInfo* iptr = &ret._rawInfo) {
GraphicFramework.InternalLoadImage(route, iptr, loader);
ArgumentNullException.ThrowIfNull(pixels);
int requiredLength = GetRequiredPixelCount(width, height);
if (pixels.Length != requiredLength)
{
throw new ArgumentException(
$"Pixel buffer length must be exactly {requiredLength}, but was {pixels.Length}.",
nameof(pixels));
}
return ret;
Width = width;
Height = height;
_pixels = pixels;
}
public static Image FromMemory(
(int width, int height) size,
ImageChannel channel,
byte[] stream
public Image(
(int width, int height) size,
TPixel[] pixels
) : this(size.width, size.height, pixels) { }
/// <summary>
/// Gets a writable byte view over the pixel buffer without copying it.
/// </summary>
public Span<byte> Bytes => MemoryMarshal.AsBytes(_pixels.AsSpan());
public int ByteLength => Bytes.Length;
public int Height { get; }
public int PixelCount => _pixels.Length;
/// <summary>
/// Gets a writable typed view over the pixel buffer without copying it.
/// </summary>
public Span<TPixel> Pixels => _pixels;
public ReadOnlySpan<byte> ReadOnlyBytes => MemoryMarshal.AsBytes(_pixels.AsSpan());
public ReadOnlySpan<TPixel> ReadOnlyPixels => _pixels;
public (int width, int height) Size => (Width, Height);
public int Width { get; }
public static explicit operator Span<byte>(
Image<TPixel> image
)
{
ImageInfo _info = new ImageInfo
{
Height = size.height,
Width = size.width,
Channel = channel,
StreamPtr = IntPtr.Zero
};
Image ret = new Image(_info);
ret.PixelLayout = PixelChannelLayout.Byte;
ret._data = stream;
return ret;
ArgumentNullException.ThrowIfNull(image);
return image.Bytes;
}
public static Image FromMemory(
(int width, int height) size,
ImageChannel channel,
PixelChannelLayout layout,
byte[] stream
private static int GetRequiredPixelCount(
int width,
int height
)
{
ImageInfo _info = new ImageInfo
{
Height = size.height,
Width = size.width,
Channel = channel,
StreamPtr = IntPtr.Zero
};
Image ret = new Image(_info);
ret.PixelLayout = layout;
ret._data = stream;
return ret;
}
ArgumentOutOfRangeException.ThrowIfNegative(width);
ArgumentOutOfRangeException.ThrowIfNegative(height);
public unsafe byte[] GetBytes()
{
if (_data.Length == 0)
{
int size = Width * Height * ImageInfo.GetPixelSize(PixelLayout, Channel);
_data = new Span<byte>((byte*)_rawInfo.StreamPtr, size).ToArray();
fixed (ImageInfo* pptr = &_rawInfo) {
GraphicFramework.InternalUnloadImage(pptr);
}
_rawInfo.StreamPtr = IntPtr.Zero;
}
return _data;
}
public Image ProvideImage()
{
return this;
}
internal static Image FromMemory(
ImageInfo info,
byte[] data,
int operationCount
)
{
return new Image
{
_rawInfo = info,
_data = data,
_pixelUpdateCount = operationCount
};
return checked(width * height);
}
}
}
}
@@ -5,13 +5,8 @@
// SPDX-License-Identifier: MIT
// -----------------------------------------------------------------------------
using StgSharp.Mathematics.Numeric;
using System;
using System.Diagnostics.CodeAnalysis;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace StgSharp.Graphics.OpenGL
{
@@ -28,136 +23,51 @@ namespace StgSharp.Graphics.OpenGL
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe void DeleteBuffer(
GlHandle handle
public void DeleteBuffer(
GlHandle handle
)
{
_context->glDeleteBuffers(1, (uint*)&handle);
_context->glDeleteBuffers(1, &handle.Value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe void DeleteBuffers(
GlHandle[] handle
public void DeleteBuffers(
ReadOnlySpan<GlHandle> handles
)
{
if ((handle == null) || (handle.Length == 0)) {
throw new ArgumentNullException(nameof(handle));
}
fixed (GlHandle* hptr = handle)
{
uint* iptr = (uint*)hptr;
for (int i = 0; i < handle.Length; i++) {
_context->glDeleteBuffers(1, iptr + i);
}
fixed (GlHandle* handlesPtr = handles) {
_context->glDeleteBuffers(handles.Length, (uint*)handlesPtr);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe GlHandle[] GenBuffers(
int count
public GlHandle[] GenBuffers(
int count
)
{
GlHandle[] h = new GlHandle[count];
fixed (GlHandle* hptr = h)
{
for (int i = 0; i < count; i++) {
_context->glGenBuffers(count, ((uint*)hptr) + i);
}
ArgumentOutOfRangeException.ThrowIfNegative(count);
GlHandle[] handles = new GlHandle[count];
if (handles.Length == 0) {
return handles;
}
return h;
fixed (GlHandle* handlesPtr = handles) {
_context->glGenBuffers(count, (uint*)handlesPtr);
}
return handles;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe void SetBufferData<T>(
BufferType bufferType,
T bufferData,
BufferUsage usage
) where T : unmanaged, INumber<T>
public void SetBufferData<T>(
BufferType bufferType,
ReadOnlySpan<T> bufferData,
BufferUsage usage
) where T : unmanaged
{
int size = Marshal.SizeOf<T>();
T* p = &bufferData;
_context->glBufferData((uint)bufferType, size, (nint*)p, (uint)usage);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe void SetBufferData<T>(
BufferType bufferType,
[NotNull] T[] bufferArray,
BufferUsage usage
) where T : unmanaged, INumber<T>
{
int size = bufferArray.Length * Marshal.SizeOf<T>();
if (bufferArray == null) {
return;
}
fixed (void* bufferPtr = bufferArray) {
_context->glBufferData((uint)bufferType, size, (nint*)bufferPtr, (uint)usage);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe void SetBufferData<T>(
BufferType bufferType,
ReadOnlySpan<T> bufferSpan,
BufferUsage usage
) where T : unmanaged, INumber<T>
{
int size = bufferSpan.Length * Marshal.SizeOf<T>();
if (bufferSpan.IsEmpty) {
return;
}
fixed (void* bufferPtr = bufferSpan) {
_context->glBufferData((uint)bufferType, size, (IntPtr*)bufferPtr, (uint)usage);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe void SetBufferData<T>(
BufferType bufferType,
Span<T> bufferArray,
BufferUsage usage
) where T : unmanaged, INumber<T>
{
int size = bufferArray.Length * Marshal.SizeOf<T>();
if (bufferArray.IsEmpty) {
return;
}
fixed (void* bufferPtr = bufferArray) {
_context->glBufferData((uint)bufferType, size, (IntPtr*)bufferPtr, (uint)usage);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe void SetBufferVectorData<T>(
BufferType bufferType,
ReadOnlySpan<T> bufferSpan,
BufferUsage usage
) where T : unmanaged, IUnmanagedVector<T>
{
int size = bufferSpan.Length * Marshal.SizeOf<T>();
fixed (void* bufferPtr = bufferSpan) {
_context->glBufferData((uint)bufferType, size, (IntPtr*)bufferPtr, (uint)usage);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe void SetBufferVectorData<T>(
BufferType bufferType,
T[] bufferArray,
BufferUsage usage
) where T : unmanaged, IUnmanagedVector<T>
{
int size = bufferArray.Length * Marshal.SizeOf(typeof(T));
if (bufferArray == null) {
return;
}
fixed (void* bufferPtr = bufferArray) {
_context->glBufferData((uint)bufferType, (nuint)size, (IntPtr*)bufferPtr,
(uint)usage);
nint sizeInBytes = checked((nint)bufferData.Length * sizeof(T));
fixed (T* bufferPtr = bufferData) {
_context->glBufferData((uint)bufferType, sizeInBytes, bufferPtr, (uint)usage);
}
}
@@ -19,11 +19,26 @@ namespace StgSharp.Graphics.OpenGL
Span<GlHandle> framebuffers
)
{
if (framebuffers.IsEmpty) {
return;
}
fixed (GlHandle* framebuffersPtr = framebuffers) {
Context.glGenFramebuffers(framebuffers.Length, (uint*)framebuffersPtr);
}
}
/// <summary>Delete framebuffer object handles.</summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void DeleteFramebuffers(
ReadOnlySpan<GlHandle> framebuffers
)
{
fixed (GlHandle* framebuffersPtr = framebuffers) {
Context.glDeleteFramebuffers(framebuffers.Length, (uint*)framebuffersPtr);
}
}
/// <summary>
/// Bind a framebuffer object to a framebuffer target.
/// </summary>
@@ -73,6 +88,17 @@ namespace StgSharp.Graphics.OpenGL
_context->glDeleteRenderbuffers(1, &bufferHandle.Value);
}
/// <summary>Delete renderbuffer object handles.</summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void DeleteRenderbuffers(
ReadOnlySpan<GlHandle> renderbuffers
)
{
fixed (GlHandle* renderbuffersPtr = renderbuffers) {
Context.glDeleteRenderbuffers(renderbuffers.Length, (uint*)renderbuffersPtr);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void FrameBufferTexture2d(
FrameBufferTarget target,
@@ -91,7 +117,13 @@ namespace StgSharp.Graphics.OpenGL
int count
)
{
ArgumentOutOfRangeException.ThrowIfNegative(count);
GlHandle[] h = new GlHandle[count];
if (h.Length == 0) {
return h;
}
fixed (GlHandle* hptr = h) {
_context->glGenRenderbuffers(count, (uint*)hptr);
}
@@ -5,11 +5,8 @@
// SPDX-License-Identifier: MIT
// -----------------------------------------------------------------------------
using StgSharp.Graphics;
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
namespace StgSharp.Graphics.OpenGL
@@ -18,114 +15,179 @@ namespace StgSharp.Graphics.OpenGL
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe GlHandle CreateGraphicProgram()
public GlHandle CreateGraphicProgram()
{
return GlHandle.Create(_context->glCreateProgram());
return CreateProgram();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe GlHandle[] CreateProgram(
int count
public GlHandle[] CreateProgram(
int count
)
{
GlHandle[] h = new GlHandle[count];
for (int i = 0; i < count; i++) {
h.SetValue(i, _context->glCreateProgram());
ArgumentOutOfRangeException.ThrowIfNegative(count);
GlHandle[] handles = new GlHandle[count];
for (int i = 0; i < handles.Length; i++) {
handles[i] = CreateProgram();
}
return h;
return handles;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public GlHandle CreateShader(
ShaderType type
)
{
GlHandle handle = CreateShader((uint)type);
if (handle.Value == 0)
{
uint error = _context->glGetError();
throw new InvalidOperationException($"Failed in creating shader: {error}");
}
return handle;
}
public GlHandle[] CreateShaderSet(
int count,
ShaderType type
)
{
GlHandle[] ret = new GlHandle[count];
uint t = (uint)type;
for (int i = 0; i < count; i++)
{
uint id = _context->glCreateShader(t);
if (id == 0)
{
uint error = _context->glGetError();
throw new InvalidOperationException($"Failed in creating shader: {error}");
}
ret[i] = GlHandle.Create(id);
ArgumentOutOfRangeException.ThrowIfNegative(count);
GlHandle[] handles = new GlHandle[count];
for (int i = 0; i < handles.Length; i++) {
handles[i] = CreateShader(type);
}
return ret;
return handles;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public string GetShaderStatus(
GlHandle shader,
ShaderStatus status
)
{
return GetShaderStatus(shader, (uint)status);
}
public string GetShaderStatus(
Shader s,
int index,
int key
GlHandle shader,
uint statusName
)
{
IntPtr sptr = IntPtr.Zero;
if (GraphicFramework.glCheckShaderStatus(ref Context, s.handle[index].Value, key,
ref sptr) == 0) {
return Marshal.PtrToStringAnsi(sptr) ?? string.Empty;
int status;
_context->glGetShaderiv(shader.Value, statusName, &status);
if (status != 0) {
return string.Empty;
}
return string.Empty;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe GlHandle GetUniformLocation(
GlHandle program,
string name
)
{
byte[] code = Encoding.UTF8.GetBytes(name);
fixed (byte* ptr = code)
int logLength;
_context->glGetShaderiv(shader.Value, glConst.INFO_LOG_LENGTH, &logLength);
if (logLength <= 1) {
return string.Empty;
}
byte[] log = new byte[logLength];
fixed (byte* logPtr = log)
{
int ret = _context->glGetUniformLocation(program.Value, ptr);
#if DEBUG
if (ret is glConst.INVALID_OPERATION or glConst.INVALID_VALUE)
{
throw new InvalidOperationException();
}
if (ret == -1) {
throw new UniformEmptyReferenceException(nameof(program), name);
}
#endif
return GlHandle.CreateSigned(ret);
int written;
_context->glGetShaderInfoLog(shader.Value, log.Length, &written, logPtr);
return Encoding.UTF8.GetString(log, 0, Math.Clamp(written, 0, log.Length));
}
}
public GlHandle GetUniformLocation(
GlHandle program,
string name
)
{
ArgumentNullException.ThrowIfNull(name);
int byteCount = Encoding.UTF8.GetByteCount(name);
Span<byte> utf8Name = byteCount < 256
? stackalloc byte[byteCount + 1]
: new byte[byteCount + 1];
int written = Encoding.UTF8.GetBytes(name.AsSpan(), utf8Name);
utf8Name[written] = 0;
int location;
fixed (byte* namePtr = utf8Name) {
location = _context->glGetUniformLocation(program.Value, namePtr);
}
#if DEBUG
if (location == -1) {
throw new UniformEmptyReferenceException(nameof(program), name);
}
#endif
return GlHandle.CreateSigned(location);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe void LoadShaderSource(
GlHandle shaderHandle,
byte[] codeStream
)
public Uniform<T> GetUniform<T>(
GlHandle program,
string name
) where T : unmanaged
{
fixed (byte* streamPtr = codeStream) {
_context->glShaderSource(shaderHandle.Value, 1, &streamPtr, (int*)0);
}
return new Uniform<T>(GetUniformLocation(program, name));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe void LoadShaderSource(
GlHandle shaderHandle,
ReadOnlySpan<char> codeStream
)
public Uniform<T, U> GetUniform<T, U>(
GlHandle program,
string name
) where T : unmanaged where U : struct
{
fixed (char* streamPtr = codeStream) {
_context->glShaderSource(shaderHandle.Value, 1, (byte**)&streamPtr, (int*)0);
}
return new Uniform<T, U>(GetUniformLocation(program, name));
}
public unsafe void LoadShaderSource(
GlHandle shaderHandle,
ReadOnlySpan<byte> codeStream
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Uniform<T, U, V> GetUniform<T, U, V>(
GlHandle program,
string name
) where T : unmanaged where U : struct where V : struct
{
return new Uniform<T, U, V>(GetUniformLocation(program, name));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Uniform<T, U, V, W> GetUniform<T, U, V, W>(
GlHandle program,
string name
) where T : unmanaged where U : struct where V : struct where W : struct
{
return new Uniform<T, U, V, W>(GetUniformLocation(program, name));
}
public void ShaderSource(
GlHandle shader,
ReadOnlySpan<byte> source
)
{
fixed (byte* streamPtr = codeStream)
int length = source.Length;
fixed (byte* sourcePtr = source)
{
byte* bptr = streamPtr;
_context->glShaderSource(shaderHandle.Value, 1, &bptr, (int*)0);
byte emptySource = 0;
byte* sourceAddress = sourcePtr == null ? &emptySource : sourcePtr;
_context->glShaderSource(shader.Value, 1, &sourceAddress, &length);
}
}
public void ShaderSource(
GlHandle shader,
string source
)
{
ArgumentNullException.ThrowIfNull(source);
int byteCount = Encoding.UTF8.GetByteCount(source);
Span<byte> utf8Source = byteCount < 1024
? stackalloc byte[byteCount]
: new byte[byteCount];
int written = Encoding.UTF8.GetBytes(source.AsSpan(), utf8Source);
ShaderSource(shader, utf8Source[..written]);
}
}
}
@@ -5,10 +5,7 @@
// SPDX-License-Identifier: MIT
// -----------------------------------------------------------------------------
using StgSharp.Graphics;
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
namespace StgSharp.Graphics.OpenGL
@@ -29,25 +26,42 @@ namespace StgSharp.Graphics.OpenGL
int count
)
{
ArgumentOutOfRangeException.ThrowIfNegative(count);
GlHandle[] h = new GlHandle[count];
if (h.Length == 0) {
return h;
}
fixed (GlHandle* hptr = h) {
_context->glGenTextures(count, (uint*)hptr);
}
return h;
}
/// <summary>Delete texture object handles.</summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void DeleteTextures(
ReadOnlySpan<GlHandle> textures
)
{
fixed (GlHandle* texturesPtr = textures) {
Context.glDeleteTextures(textures.Length, (uint*)texturesPtr);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe void GetTextureImage<T>(
Texture2DTarget target,
int level,
ImageChannel channel,
FrameBufferChannel channel,
PixelChannelLayout channelLayout,
T[] dataStream
) where T : unmanaged, INumber<T>
Span<T> destination
) where T : unmanaged
{
fixed (T* tptr = dataStream) {
fixed (T* tptr = destination) {
_context->glGetTexImage((uint)target, level, (uint)channel, (uint)channelLayout,
(nint*)tptr);
tptr);
}
}
@@ -65,73 +79,50 @@ namespace StgSharp.Graphics.OpenGL
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ReadPixels(
public void ReadPixels<T>(
(int X, int Y) beginPosition,
(int width, int height) size,
FrameBufferChannel format,
PixelChannelLayout dataType,
ref byte[] stream
)
Span<T> destination
) where T : unmanaged
{
fixed (byte* bptr = stream) {
fixed (T* destinationPtr = destination) {
_context->glReadPixels(beginPosition.X, beginPosition.Y, size.width, size.height,
(uint)format, (uint)dataType, (nint*)bptr);
(uint)format, (uint)dataType, destinationPtr);
}
}
public void RereadImage(
in Image i,
(int X, int Y) beginPosition,
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void TextureImage2d(
Texture2DTarget target,
int level,
int internalFormat,
int width,
int height,
FrameBufferChannel format,
PixelChannelLayout dataType
PixelChannelLayout type
)
{
byte[] pixels = i.PixelBuffer;
if (!pixels.CheckArrayFormat(dataType)) {
throw new GlArrayFormatException(dataType, "i.PixelArray");
}
fixed (byte* bptr = pixels) {
_context->glReadPixels(beginPosition.X, beginPosition.Y, i.Width, i.Height,
(uint)format, (uint)dataType, (nint*)bptr);
}
i.PixelUpdateCount++;
_context->glTexImage2D((uint)target, level, internalFormat, width, height, 0,
(uint)format, (uint)type, (void*)0);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void TextureImage2d<T>(
Texture2DTarget target,
int level,
ImageChannel sourceChannel,
int internalFormat,
int width,
int height,
ImageChannel targetChannel,
FrameBufferChannel format,
PixelChannelLayout type,
T[] pixels
) where T : unmanaged, INumber<T>
ReadOnlySpan<T> pixels
) where T : unmanaged
{
fixed (T* tptr = pixels)
{
T* ptr = ((pixels == null) || (pixels.Length == 0)) ? (T*)IntPtr.Zero : tptr;
_context->glTexImage2D((uint)target, level, (int)sourceChannel, width, height, 0,
(uint)targetChannel, (uint)type, (nint*)tptr);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void TextureImage2d<T>(
Texture2DTarget target,
int level,
ImageChannel sourceChannel,
int width,
int height,
ImageChannel targetChannel,
PixelChannelLayout type,
Span<T> pixelSpan
) where T : unmanaged, INumber<T>
{
fixed (T* tPtr = pixelSpan) {
_context->glTexImage2D((uint)target, level, (int)sourceChannel, width, height, 0,
(uint)targetChannel, (uint)type, (nint*)tPtr);
fixed (T* pixelPtr = pixels) {
_context->glTexImage2D((uint)target, level, internalFormat, width, height, 0,
(uint)format, (uint)type, pixelPtr);
}
}
@@ -25,15 +25,11 @@ namespace StgSharp.Graphics.OpenGL
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe void DeleteVertexArrays(
GlHandle[] arrays
ReadOnlySpan<GlHandle> arrays
)
{
fixed (GlHandle* hptr = arrays)
{
uint* iptr = (uint*)hptr;
for (int i = 0; i < arrays.Length; i++) {
_context->glDeleteVertexArrays(1, iptr + i);
}
fixed (GlHandle* arraysPtr = arrays) {
_context->glDeleteVertexArrays(arrays.Length, (uint*)arraysPtr);
}
}
@@ -41,7 +37,13 @@ namespace StgSharp.Graphics.OpenGL
int count
)
{
ArgumentOutOfRangeException.ThrowIfNegative(count);
GlHandle[] h = new GlHandle[count];
if (h.Length == 0) {
return h;
}
fixed (GlHandle* hptr = h) {
_context->glGenVertexArrays(count, (uint*)hptr);
}
@@ -58,7 +60,18 @@ namespace StgSharp.Graphics.OpenGL
int pointer
)
{
uint type = GraphicFramework.GLtype[(int)t];
uint type = t switch
{
TypeCode.Single => glConst.FLOAT,
TypeCode.Int32 => glConst.INT,
TypeCode.UInt32 => glConst.UNSIGNED_INT,
TypeCode.Int16 => glConst.SHORT,
TypeCode.UInt16 => glConst.UNSIGNED_SHORT,
TypeCode.SByte => glConst.BYTE,
TypeCode.Byte => glConst.UNSIGNED_BYTE,
_ => throw new ArgumentOutOfRangeException(nameof(t), t,
"The type cannot be used as an OpenGL vertex attribute."),
};
_context->glVertexAttribPointer(index, size, type, (byte)(normalized ? 1 : 0), stride,
(nint*)pointer);
_context->glEnableVertexAttribArray(index);
+7 -62
View File
@@ -5,72 +5,17 @@
// SPDX-License-Identifier: MIT
// -----------------------------------------------------------------------------
using StgSharp.Graphics;
using StgSharp.Graphics.OpenGL;
using StgSharp.Mathematics;
using System;
using System.Collections.Generic;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
namespace StgSharp.Graphics.OpenGL
{
/// <summary>
/// A collection of handle to Element BufferHandle Object in OpenglFunc. Each <see ///
/// langword="uint" /> value indexed from instance of this class this is the only handle to
/// one Element BufferHandle Object.
/// </summary>
public sealed unsafe class ElementBuffer : GlBufferObjectBase
/// <summary>A set of OpenGL element-buffer handles.</summary>
public sealed record class ElementBuffer(
GlHandle[] Handles
)
{
internal ElementBuffer(
int n,
glRender binding
)
: base(binding)
{
_bufferHandle = GL.GenBuffers(n);
}
public int Count => Handles.Length;
public sealed override void Bind(
int index
)
{
GL.BindBuffer(BufferType.ElementArrayBuffer, _bufferHandle[index]);
}
public void SetValue<T>(
int index,
T[] bufferArray,
BufferUsage usage
) where T : unmanaged, INumber<T>
{
GL.BindBuffer(BufferType.ElementArrayBuffer, _bufferHandle[index]);
GL.SetBufferData<T>(BufferType.ElementArrayBuffer, bufferArray, usage);
}
public void SetValue<T>(
int index,
ReadOnlySpan<T> bufferSpan,
BufferUsage usage
) where T : unmanaged, INumber<T>
{
GL.BindBuffer(BufferType.ElementArrayBuffer, _bufferHandle[index]);
GL.SetBufferData<T>(BufferType.ElementArrayBuffer, bufferSpan, usage);
}
protected sealed override void Dispose(
bool disposing
)
{
if (disposing) {
GL.DeleteBuffers(_bufferHandle);
}
}
public GlHandle this[int index] => Handles[index];
}
}
}
+10 -71
View File
@@ -5,22 +5,13 @@
// SPDX-License-Identifier: MIT
// -----------------------------------------------------------------------------
using StgSharp.Graphics;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.Graphics.OpenGL
{
#pragma warning disable CA1008
#pragma warning disable CA1028
#pragma warning disable CA1008
#pragma warning disable CA1028
public enum FrameBufferTarget : uint
#pragma warning restore CA1028
#pragma warning restore CA1008
#pragma warning restore CA1028
#pragma warning restore CA1008
{
Read = glConst.READ_FRAMEBUFFER,
@@ -29,67 +20,15 @@ namespace StgSharp.Graphics.OpenGL
}
public sealed class FrameBuffer : GlBufferObjectBase
/// <summary>A set of OpenGL framebuffer handles.</summary>
public sealed record class FrameBuffer(
GlHandle[] Handles
)
{
internal unsafe FrameBuffer(
int count,
glRender binding
)
: base(binding)
{
_bufferHandle = new GlHandle[count];
GL.GenFrameBuffers(_bufferHandle);
}
public int Count => Handles.Length;
/// <summary>
/// Bind the frame BufferHandle object with _label frame BufferHandle to the frame
/// BufferHandle target specified by target. <see langword="FrameBufferTarget.All" /> will
/// be set as default target.
/// </summary>
/// <param _label="index">
/// Index of object to be binded in handle set
/// </param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override unsafe void Bind(
int index
)
{
GL.BindFrameBuffer(FrameBufferTarget.All, _bufferHandle[index]);
}
/// <summary>
/// Bind the frame BufferHandle object with _label frame BufferHandle to the frame
/// BufferHandle target specified by target. Target of this frame BufferHandle should be
/// set manually.
/// </summary>
/// <param _label="target">
/// The frame BufferHandle target of the binding operation.
/// </param>
/// <param _label="index">
/// Index of object to be binded in handle set
/// </param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe void Bind(
FrameBufferTarget target,
int index
)
{
GL.BindFrameBuffer(target, _bufferHandle[index]);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void BindNull()
{
OpenGLFunction.CurrentGL.BindFrameBuffer(FrameBufferTarget.All, GlHandle.Zero);
}
protected override void Dispose(
bool disposing
)
{
throw new NotImplementedException();
}
public GlHandle this[int index] => Handles[index];
}
}
+6 -42
View File
@@ -5,53 +5,17 @@
// SPDX-License-Identifier: MIT
// -----------------------------------------------------------------------------
using StgSharp.Graphics;
using System;
using System.Collections.Generic;
using System.Security.Principal;
using System.Text;
namespace StgSharp.Graphics.OpenGL
{
public sealed class RenderBuffer : GlBufferObjectBase
/// <summary>A set of OpenGL renderbuffer handles.</summary>
public sealed record class RenderBuffer(
GlHandle[] Handles
)
{
public RenderBuffer(
int count,
glRender binding
)
: base(binding)
{
_bufferHandle = GL.GenRenderBuffer(count);
}
public int Count => Handles.Length;
public override void Bind(
int index
)
{
GL.BindRenderBuffer(this[index]);
}
public void Store(
RenderBufferInternalFormat format,
(int width, int height) size
)
{
if ((size.width > binding.Width) || (size.height > binding.Height)) {
World.LogWarning("FrameBuffer is larger than current canvas binding");
}
}
protected override void Dispose(
bool disposing
)
{
foreach (GlHandle item in _bufferHandle)
{
Console.WriteLine("removing a render buffer");
GL.DeleteRenderBuffer(item);
}
}
public GlHandle this[int index] => Handles[index];
}
}
+15 -223
View File
@@ -5,235 +5,27 @@
// SPDX-License-Identifier: MIT
// -----------------------------------------------------------------------------
using StgSharp.Graphics;
using StgSharp.HighPerformance.ProcessorAbstraction;
using StgSharp.Mathematics;
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace StgSharp.Graphics.OpenGL
{
public sealed unsafe class TextureGL
/// <summary>A set of OpenGL texture handles.</summary>
public sealed record class TextureGL(
GlHandle[] Handles
)
{
private int currentEditingTextureIndex;
public int Count => Handles.Length;
private OpenGLFunction _gl;
internal GlHandle[] _textureHandle;
internal TextureGL(
int count,
glRender binding
)
{
// sourceList = new Image[count];
this._gl = binding.GL;
_textureHandle = _gl.GenTextures(count);
}
public GlHandle this[
int index
]
{
get => _textureHandle[index];
}
public int Count => _textureHandle.Length;
// internal Image[] sourceList;
public int IndexOfCurrentTexture => currentEditingTextureIndex;
internal OpenGLFunction GL => _gl;
public void ActivateAs(
TextureUnit unit
)
{
_gl.ActiveTextureUnit((uint)unit);
}
public void Bind2D(
int index
)
{
currentEditingTextureIndex = index;
_gl.BindTexture(glConst.TEXTURE_2D, _textureHandle[index]);
}
/// <summary>
/// Load an <see cref="Image" /> to certain texture.
/// </summary>
/// <param _label="index">
///
/// </param>
/// <param _label="i">
///
/// </param>
public unsafe void LoadTexture(
int index,
Image i
)
{
byte[] handle = i.PixelBuffer;
_gl.TextureImage2d(Texture2DTarget.Texture2D, 0, i.Channel, i.Width, i.Height,
i.Channel, i.PixelLayout, pixels:handle);
_gl.GenerateMipmap(Texture2DTarget.Texture2D);
}
#region texture setting
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Set2dFilterProperty(
int index,
TextureFilter onMinify,
TextureFilter onMagnify
)
{
#if DEBUG
if (index != currentEditingTextureIndex)
{
throw new InvalidOperationException(
"Texture to be editted is not the one being activated.");
}
#endif
_gl.TextureParameter(glConst.TEXTURE_2D, glConst.TEXTURE_MIN_FILTER, (int)onMinify);
_gl.TextureParameter(glConst.TEXTURE_2D, glConst.TEXTURE_MAG_FILTER,
(int)onMagnify);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Set2dWrapProperty(
int index,
TextureWrap onHorizontial,
TextureWrap onVertical
)
{
#if DEBUG
if (index != currentEditingTextureIndex)
{
throw new InvalidOperationException(
"Texture to be editted is not the one being activated.");
}
#endif
_gl.TextureParameter(glConst.TEXTURE_2D, glConst.TEXTURE_WRAP_S,
(int)onHorizontial);
_gl.TextureParameter(glConst.TEXTURE_2D, glConst.TEXTURE_WRAP_T, (int)onVertical);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Set2dProperty(
int index,
TextureProperty property
)
{
Set2dFilterProperty(index, property.FilterOnMinify, property.FilterOnMagnify);
Set2dWrapProperty(index, property.WrapOnHorizontial, property.WrapOnVertical);
}
#endregion texture setting
}
[StructLayout(LayoutKind.Explicit)]
public struct TextureProperty
{
[FieldOffset(0)] private M128 mask;
[FieldOffset(0)] private TextureFilter mag;
[FieldOffset(4)] private TextureFilter min;
[FieldOffset(8)] private TextureWrap hori;
[FieldOffset(12)] private TextureWrap vert;
public TextureProperty(
TextureFilter onMagnify,
TextureFilter onMinify,
TextureWrap onHorizontal,
TextureWrap onVertical
)
{
FilterOnMagnify = onMagnify;
FilterOnMinify = onMinify;
WrapOnHorizontial = onHorizontal;
WrapOnVertical = onVertical;
}
public TextureFilter FilterOnMagnify
{
get => mag;
set => mag = value;
}
public TextureFilter FilterOnMinify
{
get => min;
set => min = value;
}
public TextureWrap WrapOnHorizontial
{
get => hori;
set => hori = value;
}
public TextureWrap WrapOnVertical
{
get => vert;
set => vert = value;
}
public override bool Equals(
[NotNullWhen(true)] object obj
)
{
return base.Equals(obj);
}
public override int GetHashCode()
{
return HashCode.Combine(FilterOnMagnify, FilterOnMagnify, WrapOnHorizontial,
WrapOnVertical);
}
public override string ToString()
{
return $"FilterOnMagnify:{FilterOnMagnify}, " + $"FilterOnMagnify:{FilterOnMagnify}, " + $"WrapOnHorizontial:{WrapOnHorizontial}, " + $"WrapOnVertical:{WrapOnVertical}";
}
public static bool operator !=(
TextureProperty left,
TextureProperty right
)
{
return left.mask != right.mask;
}
public static bool operator ==(
TextureProperty left,
TextureProperty right
)
{
return left.mask == right.mask;
}
public static implicit operator TextureProperty(
(
TextureFilter onMagnify, TextureFilter onMinify,
TextureWrap onHorizontial, TextureWrap onVertical
) propertyValueTuple
)
{
return new TextureProperty(propertyValueTuple.onMagnify, propertyValueTuple.onMinify,
propertyValueTuple.onHorizontial,
propertyValueTuple.onVertical);
}
public GlHandle this[int index] => Handles[index];
}
public readonly record struct TextureProperty(
TextureFilter FilterOnMagnify,
TextureFilter FilterOnMinify,
TextureWrap WrapOnHorizontal,
TextureWrap WrapOnVertical
);
#pragma warning disable CA1008
public enum TextureFilter
#pragma warning restore CA1008
@@ -272,9 +64,9 @@ namespace StgSharp.Graphics.OpenGL
}
#pragma warning disable CA1008
#pragma warning disable CA1008
public enum TextureWrap
#pragma warning restore CA1008
#pragma warning restore CA1008
{
Repeat = glConst.REPEAT,
+7 -52
View File
@@ -5,62 +5,17 @@
// SPDX-License-Identifier: MIT
// -----------------------------------------------------------------------------
using StgSharp.Graphics;
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Text;
namespace StgSharp.Graphics.OpenGL
{
public sealed unsafe class VertexArray : GlBufferObjectBase
/// <summary>A set of OpenGL vertex-array handles.</summary>
public sealed record class VertexArray(
GlHandle[] Handles
)
{
internal VertexArray(
int n,
glRender binding
)
: base(binding)
{
_bufferHandle = GL.GenVertexArrays(n);
}
public int Count => Handles.Length;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public sealed override void Bind(
int index
)
{
GL.BindVertexArray(_bufferHandle[index]);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void BindNull()
{
OpenGLFunction.CurrentGL.BindVertexArray(GlHandle.Zero);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetVertexAttribute(
uint attributeIndex,
int vertexLength,
TypeCode dataType,
bool isNomalized,
int stride,
int pointer
)
{
GL.SetVertexAttribute(attributeIndex, vertexLength, dataType, isNomalized, stride,
pointer);
}
protected sealed override void Dispose(
bool disposing
)
{
if (disposing) {
GL.DeleteVertexArrays(_bufferHandle);
}
}
public GlHandle this[int index] => Handles[index];
}
}
}
+7 -147
View File
@@ -5,157 +5,17 @@
// SPDX-License-Identifier: MIT
// -----------------------------------------------------------------------------
using StgSharp.Graphics;
using StgSharp.Mathematics;
using StgSharp.Mathematics.Numeric;
using System;
using System.Collections.Generic;
using System.Net.Security;
using System.Numerics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
namespace StgSharp.Graphics.OpenGL
{
public sealed unsafe class VertexBuffer : GlBufferObjectBase
/// <summary>A set of OpenGL vertex-buffer handles.</summary>
public sealed record class VertexBuffer(
GlHandle[] Handles
)
{
internal VertexBuffer(
int n,
glRender binding
)
: base(binding)
{
_bufferHandle = GL.GenBuffers(n);
}
public int Count => Handles.Length;
public sealed override void Bind(
int index
)
{
GL.BindBuffer(BufferType.ArrayBuffer, _bufferHandle[index]);
}
/// <summary>
///
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Unbind()
{
GL.BindBuffer(BufferType.ArrayBuffer, GlHandle.Zero);
}
/// <summary>
/// Set _data to current vertex BufferHandle object
/// </summary>
/// <typeparam _label="TItem">
/// Type of bufferData
/// </typeparam>
/// <param _label="index">
/// Index to find certain VBO in this instance
/// </param>
/// <param _label="bufferArray">
/// Data to write in
/// </param>
/// <param _label="usage">
/// How OpenGL use these _data, defined by <see cref="BufferUsage" />
/// </param>
public void WriteScalerData<T>(
int index,
T[] bufferArray,
BufferUsage usage
) where T : unmanaged, INumber<T>
{
GL.BindBuffer(BufferType.ArrayBuffer, _bufferHandle[index]);
GL.SetBufferData(BufferType.ArrayBuffer, bufferArray, usage);
}
/// <summary>
/// Set _data to current vertex BufferHandle object
/// </summary>
/// <typeparam _label="TItem">
/// Type of bufferData
/// </typeparam>
/// <param _label="index">
/// Index to find certain VBO in this instance
/// </param>
/// <param _label="scalerSpan">
/// A <see cref="Span{T}" /> of _data to write in
/// </param>
/// <param _label="usage">
/// How OpenGL use these _data, defined by <see cref="BufferUsage" />
/// </param>
public void WriteScalerData<T>(
int index,
ReadOnlySpan<T> scalerSpan,
BufferUsage usage
) where T : unmanaged,INumber<T>
{
GL.BindBuffer(BufferType.ArrayBuffer, _bufferHandle[index]);
GL.SetBufferData(BufferType.ArrayBuffer, scalerSpan, usage);
}
/// <summary>
/// Set data to current vertex BufferHandle object
/// </summary>
/// <typeparam _label="TItem">
/// Type of bufferData
/// </typeparam>
/// <param _label="index">
/// Index to find certain VBO in this instance
/// </param>
/// <param _label="vectorSpan">
/// A <see cref="Span{T}" /> of data to write in
/// </param>
/// <param _label="usage">
/// How OpenGL use these data, defined by <see cref="BufferUsage" />
/// </param>
public void WriteVectorData<T>(
int index,
ReadOnlySpan<T> vectorSpan,
BufferUsage usage
) where T : unmanaged, IUnmanagedVector<T>
{
GL.BindBuffer(BufferType.ArrayBuffer, _bufferHandle[index]);
GL.SetBufferVectorData(BufferType.ArrayBuffer, vectorSpan, usage);
}
/// <summary>
/// Set _data to current vertex BufferHandle object
/// </summary>
/// <typeparam _label="TItem">
/// Type of bufferData
/// </typeparam>
/// <param _label="index">
/// Index to find certain VBO in this instance
/// </param>
/// <param _label="vectorArray">
/// A array of _data to write in
/// </param>
/// <param _label="usage">
/// How OpenGL use these _data, defined by <see cref="BufferUsage" />
/// </param>
public void WriteVectorData<T>(
int index,
T[] vectorArray,
BufferUsage usage
) where T : unmanaged, IUnmanagedVector<T>
{
GL.BindBuffer(BufferType.ArrayBuffer, _bufferHandle[index]);
GL.SetBufferVectorData(BufferType.ArrayBuffer, vectorArray, usage);
}
protected sealed override void Dispose(
bool disposing
)
{
if (disposing) {
GL.DeleteBuffers(_bufferHandle);
}
}
public GlHandle this[int index] => Handles[index];
}
}
}
+19 -266
View File
@@ -5,163 +5,33 @@
// SPDX-License-Identifier: MIT
// -----------------------------------------------------------------------------
using StgSharp;
using StgSharp.Graphics;
using StgSharp.Internal;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Xml.Linq;
namespace StgSharp.Graphics.OpenGL
{
public abstract partial class glRender : RenderStream
/// <summary>
/// A set of OpenGL shader handles with their common stage type.
/// </summary>
public sealed record Shader
{
/// <summary>
/// Create an instance of <see cref="Shader" /> program
/// </summary>
/// <returns>
/// New instance of <see cref="Shader" /> instance.
/// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected sealed override ShaderProgram CreateShaderProgram()
{
return new ShaderProgram(this);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected sealed override Shader CreateShaderSegment(
ShaderType type,
int count
public Shader(
GlHandle[] handles,
ShaderType type
)
{
return new Shader(GL.CreateShaderSet(count, type), type, this);
ArgumentNullException.ThrowIfNull(handles);
Handles = handles;
Type = type;
}
}
public int Count => Handles.Length;
public class Shader
{
public GlHandle[] Handles { get; }
private readonly OpenGLFunction GL;
internal readonly GlHandle[] handle;
public readonly ShaderType type;
public ShaderType Type { get; }
internal unsafe Shader(
GlHandle[] handle,
ShaderType usage,
glRender stream
)
{
this.handle = handle;
GL = stream.GL;
type = usage;
}
/// <summary>
/// Attach one shader code to a shader program.
/// </summary>
/// <param _label="target">
/// Shader program to attach
/// </param>
/// <param _label="index">
/// Index of shader code in current shader code set.
/// </param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void AttachTo(
int index,
[NotNull]ShaderProgram target
)
{
GL.AttachShader(target.handle, handle[index]);
}
public void CheckStatus(
int index,
ShaderStatus status
)
{
string log = GL.GetShaderStatus(this, index, (int)status);
if (!string.IsNullOrEmpty(log)) {
throw new InvalidOperationException($"{$"Shader Error \t{status}\n"}{log}");
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe void Compile(
int index,
ReadOnlySpan<byte> codeU8Stream
)
{
GL.LoadShaderSource(handle[index], codeU8Stream);
GL.CompileShader(handle[index]);
CheckStatus(index, ShaderStatus.CompileStatus);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe void Compile(
int index,
byte[] codeStream
)
{
ArgumentNullException.ThrowIfNull(codeStream);
GL.LoadShaderSource(handle[index], codeStream);
GL.CompileShader(handle[index]);
CheckStatus(index, ShaderStatus.CompileStatus);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe void Compile(
int index,
string codeStream
)
{
ArgumentNullException.ThrowIfNull(codeStream);
GL.LoadShaderSource(handle[index], codeStream.AsSpan());
GL.CompileShader(handle[index]);
CheckStatus(index, ShaderStatus.CompileStatus);
}
public void FromBytes(
byte[] stream
)
{
throw new NotImplementedException();
}
public static byte[] FromCodeFile(
string fileRoute
)
{
string str = File.ReadAllText(fileRoute);
if (string.IsNullOrEmpty(str)) {
throw new InvalidOperationException($"Cannot load and GLSL code from {fileRoute}");
}
return Encoding.UTF8.GetBytes(str);
}
public byte[] GetBytes()
{
return Array.Empty<byte>();
}
public byte[] GetBytes(
out int length
)
{
throw new NotImplementedException();
}
public override string ToString()
{
return $"This is a {type} shader, its shader handles are {handle.ToString()}.";
}
public GlHandle this[int index] => Handles[index];
}
@@ -172,125 +42,8 @@ namespace StgSharp.Graphics.OpenGL
}
public class ShaderProgram
{
private readonly OpenGLFunction GL;
internal readonly GlHandle handle;
/// <summary>
/// CustomizeInit a program with no shader attached.
/// </summary>
internal unsafe ShaderProgram(
glRender binding
)
{
GL = binding.GL;
handle = GL.CreateProgram();
}
/// <summary>
/// Get a uniform form current shader, the value type of the uniform should be provided.
/// </summary>
/// <param _label="name">
/// ContextName of the Uniform in shader code
/// </param>
/// <returns>
///
/// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe Uniform<T> GetUniform<T>(
string name
) where T : unmanaged
{
return new Uniform<T>(GL.GetUniformLocation(this.handle, name));
}
/// <summary>
/// Get a uniform form current shader, the value type of the uniform should be provided.
/// </summary>
/// <param _label="name">
/// ContextName of the Uniform in shader code
/// </param>
/// <returns>
///
/// </returns>
public unsafe Uniform<T, U> GetUniform<T, U>(
string name
) where T : unmanaged where U : struct
{
return new Uniform<T, U>(GL.GetUniformLocation(this.handle, name));
}
/// <summary>
/// Get a uniform form current shader, the value type of the uniform should be provided.
/// </summary>
/// <param _label="name">
/// ContextName of the Uniform in shader code
/// </param>
/// <returns>
///
/// </returns>
public unsafe Uniform<T, U, V> GetUniform<T, U, V>(
string name
) where T : unmanaged where U : struct where V : struct
{
return new Uniform<T, U, V>(GL.GetUniformLocation(this.handle, name));
}
/// <summary>
/// Get a uniform form current shader, the value type of the uniform should be provided.
/// </summary>
/// <param _label="name">
/// ContextName of the Uniform in shader code
/// </param>
/// <returns>
///
/// </returns>
public unsafe Uniform<T, U, V, W> GetUniform<T, U, V, W>(
string name
) where T : unmanaged where U : struct where V : struct where W : struct
{
return new Uniform<T, U, V, W>(GL.GetUniformLocation(this.handle, name));
}
/// <summary>
/// Link the shader to current viewPortDisplay.
/// </summary>
public unsafe void Link()
{
if (GraphicFramework.InternalLinkShaderProgram(
(OpenglContext*)this.GL.ContextHandle, handle.Value) == 0)
{
IntPtr logPtr = GraphicFramework.InternalReadSSCLog();
try
{
byte[] logByte = new byte[512];
Marshal.Copy(logPtr, logByte, 0, 512);
string log = Encoding.UTF8.GetString(logByte);
log = log.Replace("\0", string.Empty);
DefaultLog.InternalWriteLog(log, LogType.Error);
}
catch (Exception ex)
{
DefaultLog.InternalWriteLog(ex.Message, LogType.Error);
}
}
}
/// <summary>
/// Let the current viewPortDisplay use this shader.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe void Use()
{
GL.UseProgram(handle);
}
~ShaderProgram()
{
// handle.Dispose();
}
}
}
/// <summary>
/// An OpenGL shader-program handle.
/// </summary>
public readonly record struct ShaderProgram(GlHandle Handle);
}
@@ -7,10 +7,17 @@
namespace StgSharp.Graphics.OpenGL
{
public class Uniform
public abstract class Uniform
{
internal GlHandle id;
internal readonly GlHandle id;
protected Uniform(
GlHandle handle
)
{
id = handle;
}
public GlHandle Handle => id;
@@ -19,48 +26,20 @@ namespace StgSharp.Graphics.OpenGL
public sealed class Uniform<T> : Uniform where T : unmanaged
{
internal Uniform() { }
internal unsafe Uniform(
GlHandle id
public Uniform(
GlHandle handle
)
{
this.id = id;
}
internal static Uniform<T> FromHandle(
GlHandle handle
)
{
return new Uniform<T>
{
id = handle
};
}
: base(handle) { }
}
public sealed class Uniform<T, U> : Uniform where T : unmanaged where U : struct
{
internal Uniform() { }
internal unsafe Uniform(
GlHandle id
public Uniform(
GlHandle handle
)
{
this.id = id;
}
internal static Uniform<T, U> FromHandle(
GlHandle handle
)
{
return new Uniform<T, U>
{
id = handle
};
}
: base(handle) { }
}
@@ -68,24 +47,10 @@ namespace StgSharp.Graphics.OpenGL
where V : struct
{
internal Uniform() { }
internal unsafe Uniform(
GlHandle id
public Uniform(
GlHandle handle
)
{
this.id = id;
}
internal static Uniform<T, U, V> FromHandle(
GlHandle handle
)
{
return new Uniform<T, U, V>
{
id = handle
};
}
: base(handle) { }
}
@@ -94,25 +59,10 @@ namespace StgSharp.Graphics.OpenGL
where W : struct
{
internal Uniform() { }
internal unsafe Uniform(
GlHandle id
public Uniform(
GlHandle handle
)
{
this.id = id;
}
internal static Uniform<T, U, V, W> FromHandle(
GlHandle handle
)
{
return new Uniform<T, U, V, W>
{
id = handle
};
}
: base(handle) { }
}
}
File diff suppressed because it is too large Load Diff
+1 -6
View File
@@ -4532,12 +4532,7 @@ namespace StgSharp.Graphics.OpenGL
int i
)
{
#if DEBUG
if ((i > OpenGLFunction.CurrentGL.AttachmentColorRange) || (i < 0))
{
throw new ArgumentOutOfRangeException();
}
#endif
ArgumentOutOfRangeException.ThrowIfNegative(i);
return (uint)(glConst.COLOR_ATTACHMENT0 + i);
}
@@ -6,12 +6,6 @@
// -----------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Text;
namespace StgSharp.Graphics.OpenGL
{
@@ -37,65 +31,4 @@ namespace StgSharp.Graphics.OpenGL
}
public sealed class GlArrayFormatException : Exception
{
internal GlArrayFormatException(
string message
)
: base(message) { }
internal GlArrayFormatException(
SerializationInfo info,
StreamingContext context
)
: base(info, context) { }
internal GlArrayFormatException(
string message,
Exception innerException
)
: base(message, innerException) { }
public GlArrayFormatException(
PixelChannelLayout layout,
string arrayname
)
: base($"{arrayname} cannot be used as layout of {layout}") { }
}
public static partial class GlHelper
{
public static bool CheckArrayFormat(
this Array array,
PixelChannelLayout layout
)
{
return layout switch
{
PixelChannelLayout.Byte or PixelChannelLayout.UByte332 or PixelChannelLayout.UByte233Rev => (array is byte[]) ||
(array is sbyte[]),
PixelChannelLayout.Short => array is short[],
PixelChannelLayout.UShort => array is ushort[],
PixelChannelLayout.Int => array is int[],
PixelChannelLayout.Float => array is float[],
PixelChannelLayout.UShort4444 => (array is ushort[]) || (array is byte[]),
PixelChannelLayout.UByte => (array is byte[]) || (array is sbyte[]),
PixelChannelLayout.UInt => array is uint[],
PixelChannelLayout.UShort565 or
PixelChannelLayout.UShort565Rev or
PixelChannelLayout.UShort4444Rev or
PixelChannelLayout.UShort5551 or
PixelChannelLayout.UShort1555Rev => array is ushort[],
PixelChannelLayout.UInt8888Rev or
PixelChannelLayout.UInt1010102 or
PixelChannelLayout.UInt2101010Rev => array is int[],
PixelChannelLayout.UInt8888 => array is uint[] or byte[],
_ => false,
};
}
}
}
@@ -117,15 +117,6 @@ namespace StgSharp.Graphics.OpenGL
CustomizeDeinit();
}
protected sealed override Uniform<GraphicsMatrix> NativeCameraUniform(
ShaderProgram source,
string name
)
{
NativeCamera.GainAllUniforms(source, name);
return NativeCamera.convertedUniform;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected sealed override void NativeCameraViewRange(
Radius fieldOfRange,
+20
View File
@@ -0,0 +1,20 @@
// -----------------------------------------------------------------------------
// file="glSync"
// Project: StgSharp
// Copyright (c) Nitload.
// SPDX-License-Identifier: MIT
// -----------------------------------------------------------------------------
using System;
using System.Runtime.InteropServices;
namespace StgSharp.Graphics.OpenGL
{
[StructLayout(LayoutKind.Sequential)]
public struct glSync
{
public IntPtr Handle;
}
}
+4 -6
View File
@@ -38,11 +38,9 @@ namespace StgSharp.Graphics
_shape = shape;
}
// private Image _texture;
public PlainGeometryMesh(
PlainGeometry shape,
Image texture,
Image<Rgba8> texture,
Vec2[] texCoord
)
{
@@ -59,10 +57,10 @@ namespace StgSharp.Graphics
public Vec4[] VertexArray => _shape.VertexStream;
public Image TextureImage
public Image<Rgba8> TextureImage
{
get => _texture.ProvideImage();
internal set => _texture.ReadImage(value);
get => _texture.Image;
internal set => _texture.Image = value;
}
public ReadOnlySpan<int> MeshIndices => _shape.VertexIndices;
-32
View File
@@ -5,7 +5,6 @@
// SPDX-License-Identifier: MIT
// -----------------------------------------------------------------------------
using StgSharp.Graphics.OpenGL;
using StgSharp.Mathematics;
using StgSharp.Mathematics.Graphics;
using StgSharp.Timing;
@@ -133,27 +132,6 @@ namespace StgSharp.Graphics
Vec3 up
);
/// <summary>
/// Get <see cref="Uniform{T}" />(TView is <see cref="GraphicsMatrix" />) uniform from a
/// shader. This uniform will be used as projection matrix of this camera. Additionally,
/// for multi- shader rendering, each shader requires a uniform, so do not ignore return
/// value of this method.
/// </summary>
/// <param _label="source">
/// Shader using this camera
/// </param>
/// <param _label="name">
/// ContextName of projection camera named in shader
/// </param>
/// <returns>
/// <see cref="Uniform{T}" />(TView is <see cref="GraphicsMatrix" />) representing
/// projection matrix in shader program.
/// </returns>
protected abstract Uniform<GraphicsMatrix> NativeCameraUniform(
ShaderProgram source,
string name
);
#endregion
#region internal operation
@@ -200,15 +178,5 @@ namespace StgSharp.Graphics
#endregion
#region public resource generator
protected abstract Shader CreateShaderSegment(
ShaderType type,
int count
);
protected abstract ShaderProgram CreateShaderProgram();
#endregion
}
}
+38
View File
@@ -0,0 +1,38 @@
// -----------------------------------------------------------------------------
// file="Rgba8"
// Project: StgSharp
// Copyright (c) Nitload.
// SPDX-License-Identifier: MIT
// -----------------------------------------------------------------------------
using System.Runtime.InteropServices;
namespace StgSharp.Graphics
{
/// <summary>
/// Four-channel, eight-bit-per-channel RGBA pixel storage.
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 1, Size = 4)]
public struct Rgba8
{
public byte R;
public byte G;
public byte B;
public byte A;
public Rgba8(
byte red,
byte green,
byte blue,
byte alpha
)
{
R = red;
G = green;
B = blue;
A = alpha;
}
}
}
+12 -29
View File
@@ -8,23 +8,25 @@
using StgSharp.Mathematics.Graphics;
using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
namespace StgSharp.Graphics
{
public class TextureProvider : IImageProvider
public class TextureProvider
{
private Vec2[] _texCoord;
private Image _tex;
private Image<Rgba8> _image;
public TextureProvider(
Image image,
Image<Rgba8> image,
Vec2[] coord
)
{
_tex = image;
ArgumentNullException.ThrowIfNull(image);
ArgumentNullException.ThrowIfNull(coord);
_image = image;
_texCoord = coord;
}
@@ -38,32 +40,13 @@ namespace StgSharp.Graphics
public Span<Vec2> TextureCoordinate => new Span<Vec2>(_texCoord);
public Image ProvideImage()
public Image<Rgba8> Image
{
return _tex;
}
public void ReadImage(
IImageProvider provider
)
{
_tex = provider.ProvideImage();
}
public void UpdateFromImage(
[NotNull]Image i
)
{
if (i == _tex) {
return;
}
if (i.Size == _tex.Size)
get => _image;
set
{
_tex = i;
} else
{
throw new ArgumentException(
$"Size of {nameof(i)} does not equals to current image.");
ArgumentNullException.ThrowIfNull(value);
_image = value;
}
}
+6 -3
View File
@@ -16,7 +16,7 @@ namespace StgSharp.Graphics
public class GraphicModule : IStaticModule
{
public string ModuleName => "Graphic";
public string ModuleName => "Graphics";
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void InitializeModule(
@@ -24,6 +24,9 @@ namespace StgSharp.Graphics
)
{
GraphicFramework.LoadGlfw();
if (GraphicFramework.glfwInit() == 0) {
throw new InvalidOperationException("Failed to initialize GLFW.");
}
}
public void UninitializeModule()
@@ -325,7 +328,7 @@ namespace StgSharp.Graphics
internal static unsafe void glfwSetWindowIcon(
IntPtr window,
int count,
GLFWimage* images
GlfwImageNative* images
)
{
_glfw.glfwSetWindowIcon(window, count, (IntPtr)images);
@@ -750,7 +753,7 @@ namespace StgSharp.Graphics
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static unsafe IntPtr glfwCreateCursor(
GLFWimage* image,
GlfwImageNative* image,
int xhot,
int yhot
)
+32
View File
@@ -0,0 +1,32 @@
// -----------------------------------------------------------------------------
// file="glfw.struct"
// Project: StgSharp
// Copyright (c) Nitload.
// SPDX-License-Identifier: MIT
// -----------------------------------------------------------------------------
using System.Runtime.InteropServices;
namespace StgSharp.Internal
{
// GLFW owns these objects. The managed layer only passes opaque pointers to them.
[StructLayout(LayoutKind.Sequential)]
public struct glfwVideomode { }
[StructLayout(LayoutKind.Sequential)]
public struct glfwGammaramp { }
[StructLayout(LayoutKind.Sequential)]
internal unsafe struct GlfwImageNative
{
internal int Width;
internal int Height;
internal byte* Pixels;
}
[StructLayout(LayoutKind.Sequential)]
public struct GLFWgamepadstate { }
}
-4
View File
@@ -133,10 +133,6 @@ target_compile_definitions(${PROJECT_NAME}
set(STGSHARP_NATIVE_EXTERNAL_TARGET ${PROJECT_NAME})
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/lib)
if(WIN32)
target_link_libraries(${PROJECT_NAME} PRIVATE opengl32)
endif()
message(STATUS "StgSharp.Native target OS: ${SN_RESOLVED_OS_NAME} (${SN_RESOLVED_OS_DEFINE})")
message(STATUS "StgSharp.Native target ISA: ${SN_RESOLVED_ARCH_NAME} (${SN_RESOLVED_ARCH_DEFINE})")
message(STATUS "StgSharp.Native output dir: ${STGSHARP_BUILD_OUTPUT_DIR}")
+2 -6
View File
@@ -115,7 +115,7 @@
<Link>
<!-- DLL 应该用 Windows,不是 Console -->
<SubSystem>Windows</SubSystem>
<AdditionalDependencies>opengl32.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<!-- Debug 特有 -->
@@ -185,7 +185,6 @@
<ClCompile Include="sn-src\load_glfw.c" />
<ClCompile Include="sn-src\simdid.x86.c" />
<ClCompile Include="sn-src\simdid_compare.x86.c" />
<ClCompile Include="sn-src\sn_native.c" />
<ClCompile Include="sn-src\thread.linux.c" />
<ClCompile Include="sn-src\thread.windows.c" />
<ClCompile Include="sn-src\vector.c" />
@@ -198,9 +197,7 @@
<ClInclude Include="lib\glfw\glfw3.h" />
<ClInclude Include="lib\glfw\glfw3native.h" />
<ClInclude Include="lib\stbi\stb_image.h" />
<ClInclude Include="sn-head\gl.h" />
<ClInclude Include="sn-head\glfw_function.h" />
<ClInclude Include="sn-head\khrplatform.h" />
<ClInclude Include="sn-head\sn_internal.h" />
<ClInclude Include="sn-head\sn_intrinsic.context.x86.h" />
<ClInclude Include="sn-head\sn_intrinsic.std.h" />
@@ -208,7 +205,6 @@
<ClInclude Include="sn-head\sn_intrinsic.matkernel.h" />
<ClInclude Include="sn-head\sn_target.h" />
<ClInclude Include="sn-head\StgSharpNative.h" />
<ClInclude Include="sn-head\wgl.h" />
<ClInclude Include="sn-template\sn_template.fma.x86.h" />
</ItemGroup>
<ItemGroup>
@@ -218,4 +214,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>
@@ -36,9 +36,6 @@
<ClCompile Include="sn-src\vector_dot.c">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="sn-src\sn_native.c">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="sn-src\load_glfw.c">
<Filter>源文件</Filter>
</ClCompile>
@@ -77,21 +74,12 @@
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="sn-head\gl.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="sn-head\khrplatform.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="sn-head\sn_internal.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="sn-head\StgSharpNative.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="sn-head\wgl.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="sn-head\glfw_function.h">
<Filter>头文件</Filter>
</ClInclude>
@@ -139,4 +127,4 @@
<Filter>Document</Filter>
</None>
</ItemGroup>
</Project>
</Project>
@@ -8,13 +8,6 @@
#include "sn_internal.h"
#include "sn_target.h"
#define STBIDEF SN_API
#include "../lib/stbi/stb_image.h"
#include "gl.h"
// #include "wgl.h"
// #define GLFWAPI INTERNAL
#include "glfw\glfw3.h"
#include <immintrin.h>
#include <assert.h>
#include <glfw_function.h>
@@ -26,24 +19,6 @@
#ifndef SN_
#endif
typedef struct Image {
int width;
int height;
int channel;
char *pixelPtr;
} Image;
typedef char *(*imageLoader)(char const *filename, int *x, int *y, int *channels_in_file,
int desired_channels);
extern SN_API char infolog[512];
SN_API int SN_DECL glCheckShaderStat(GladGLContext *context, uint64_t shaderHandle, int key,
char **logRef);
SN_API void SN_DECL initGL(int majorVersion, int minorVersion);
SN_API void SN_DECL loadImageData(char *location, Image *out, imageLoader loader);
SN_API GLFWglproc SN_DECL loadGlfuncDefault(char *procName);
SN_API void SN_DECL unloadImageData(Image *out);
SN_API char *SN_DECL readLog(void);
SN_API void SN_DECL load_glfw_functions(GLFWFunctionTable *table);
SN_API void SN_DECL load_intrinsic_function(void *intrinsic_context, uint64_t id);
SN_API SIMDID SN_DECL sn_get_simd_level_global();
File diff suppressed because one or more lines are too long
@@ -1,6 +1,10 @@
#ifndef GLFW_FUNCTION_TABLE_H
#define GLFW_FUNCTION_TABLE_H
#ifndef GLFW_INCLUDE_NONE
#define GLFW_INCLUDE_NONE
#endif
#include "../lib/glfw/glfw3.h"
#ifdef __cplusplus
-310
View File
@@ -1,310 +0,0 @@
#ifndef __khrplatform_h_
#define __khrplatform_h_
/*
** Copyright (c) 2008-2018 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Materials.
**
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
/* Khronos platform-specific types and definitions.
*
* The master copy of khrplatform.h is maintained in the Khronos EGL
* Registry repository at https://github.com/KhronosGroup/EGL-Registry
* The last semantic modification to khrplatform.h was at commit ID:
* 67a3e0864c2d75ea5287b9f3d2eb74a745936692
*
* Adopters may modify this file to suit their platform. Adopters are
* encouraged to submit platform specific modifications to the Khronos
* group so that they can be included in future versions of this file.
* Please submit changes by filing pull requests or issues on
* the EGL Registry repository linked above.
*
*
* See the Implementer's Guidelines for information about where this file
* should be located on your system and for more details of its use:
* http://www.khronos.org/registry/implementers_guide.pdf
*
* This file should be included as
* #include <KHR/khrplatform.h>
* by Khronos client API header files that use its types and defines.
*
* The types in khrplatform.h should only be used to define API-specific types.
*
* Types defined in khrplatform.h:
* khronos_int8_t signed 8 bit
* khronos_uint8_t unsigned 8 bit
* khronos_int16_t signed 16 bit
* khronos_uint16_t unsigned 16 bit
* khronos_int32_t signed 32 bit
* khronos_uint32_t unsigned 32 bit
* khronos_int64_t signed 64 bit
* khronos_uint64_t unsigned 64 bit
* khronos_intptr_t signed same number of bits as a pointer
* khronos_uintptr_t unsigned same number of bits as a pointer
* khronos_ssize_t signed size
* khronos_usize_t unsigned size
* khronos_float_t signed 32 bit floating point
* khronos_time_ns_t unsigned 64 bit time in nanoseconds
* khronos_utime_nanoseconds_t unsigned time interval or absolute time in
* nanoseconds
* khronos_stime_nanoseconds_t signed time interval in nanoseconds
* khronos_boolean_enum_t enumerated boolean type. This should
* only be used as a base type when a client API's boolean type is
* an enum. Client APIs which use an integer or other type for
* booleans cannot use this as the base type for their boolean.
*
* Tokens defined in khrplatform.h:
*
* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
*
* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
*
* Calling convention macros defined in this file:
* KHRONOS_APICALL
* KHRONOS_APIENTRY
* KHRONOS_APIATTRIBUTES
*
* These may be used in function prototypes as:
*
* KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
* int arg1,
* int arg2) KHRONOS_APIATTRIBUTES;
*/
#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC)
#define KHRONOS_STATIC 1
#endif
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APICALL
*-------------------------------------------------------------------------
* This precedes the return type of the function in the function prototype.
*/
#if defined(KHRONOS_STATIC)
/* If the preprocessor constant KHRONOS_STATIC is defined, make the
* header compatible with static linking. */
#define KHRONOS_APICALL
#elif defined(_WIN32)
#define KHRONOS_APICALL __declspec(dllimport)
#elif defined(__SYMBIAN32__)
#define KHRONOS_APICALL IMPORT_C
#elif defined(__ANDROID__)
#define KHRONOS_APICALL __attribute__((visibility("default")))
#else
#define KHRONOS_APICALL
#endif
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APIENTRY
*-------------------------------------------------------------------------
* This follows the return type of the function and precedes the function
* name in the function prototype.
*/
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
/* Win32 but not WinCE */
#define KHRONOS_APIENTRY __stdcall
#else
#define KHRONOS_APIENTRY
#endif
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APIATTRIBUTES
*-------------------------------------------------------------------------
* This follows the closing parenthesis of the function prototype arguments.
*/
#if defined(__ARMCC_2__)
#define KHRONOS_APIATTRIBUTES __softfp
#else
#define KHRONOS_APIATTRIBUTES
#endif
/*-------------------------------------------------------------------------
* basic type definitions
*-----------------------------------------------------------------------*/
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || \
defined(__SCO__) || defined(__USLC__)
/*
* Using <stdint.h>
*/
#include <stdint.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
/*
* To support platform where unsigned long cannot be used interchangeably with
* inptr_t (e.g. CHERI-extended ISAs), we can use the stdint.h intptr_t.
* Ideally, we could just use (u)intptr_t everywhere, but this could result in
* ABI breakage if khronos_uintptr_t is changed from unsigned long to
* unsigned long long or similar (this results in different C++ name mangling).
* To avoid changes for existing platforms, we restrict usage of intptr_t to
* platforms where the size of a pointer is larger than the size of long.
*/
#if defined(__SIZEOF_LONG__) && defined(__SIZEOF_POINTER__)
#if __SIZEOF_POINTER__ > __SIZEOF_LONG__
#define KHRONOS_USE_INTPTR_T
#endif
#endif
#elif defined(__VMS) || defined(__sgi)
/*
* Using <inttypes.h>
*/
#include <inttypes.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
/*
* Win32
*/
typedef __int32 khronos_int32_t;
typedef unsigned __int32 khronos_uint32_t;
typedef __int64 khronos_int64_t;
typedef unsigned __int64 khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(__sun__) || defined(__digital__)
/*
* Sun or Digital
*/
typedef int khronos_int32_t;
typedef unsigned int khronos_uint32_t;
#if defined(__arch64__) || defined(_LP64)
typedef long int khronos_int64_t;
typedef unsigned long int khronos_uint64_t;
#else
typedef long long int khronos_int64_t;
typedef unsigned long long int khronos_uint64_t;
#endif /* __arch64__ */
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif 0
/*
* Hypothetical platform with no float or int64 support
*/
typedef int khronos_int32_t;
typedef unsigned int khronos_uint32_t;
#define KHRONOS_SUPPORT_INT64 0
#define KHRONOS_SUPPORT_FLOAT 0
#else
/*
* Generic fallback
*/
#include <stdint.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#endif
/*
* Types that are (so far) the same on all platforms
*/
typedef signed char khronos_int8_t;
typedef unsigned char khronos_uint8_t;
typedef signed short int khronos_int16_t;
typedef unsigned short int khronos_uint16_t;
/*
* Types that differ between LLP64 and LP64 architectures - in LLP64,
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
* to be the only LLP64 architecture in current use.
*/
#ifdef KHRONOS_USE_INTPTR_T
typedef intptr_t khronos_intptr_t;
typedef uintptr_t khronos_uintptr_t;
#elif defined(_WIN64)
typedef signed long long int khronos_intptr_t;
typedef unsigned long long int khronos_uintptr_t;
#else
typedef signed long int khronos_intptr_t;
typedef unsigned long int khronos_uintptr_t;
#endif
#if defined(_WIN64)
typedef signed long long int khronos_ssize_t;
typedef unsigned long long int khronos_usize_t;
#else
typedef signed long int khronos_ssize_t;
typedef unsigned long int khronos_usize_t;
#endif
#if KHRONOS_SUPPORT_FLOAT
/*
* Float type
*/
typedef float khronos_float_t;
#endif
#if KHRONOS_SUPPORT_INT64
/* Time types
*
* These types can be used to represent a time interval in nanoseconds or
* an absolute Unadjusted System Time. Unadjusted System Time is the number
* of nanoseconds since some arbitrary system event (e.g. since the last
* time the system booted). The Unadjusted System Time is an unsigned
* 64 bit value that wraps back to 0 every 584 years. Time intervals
* may be either signed or unsigned.
*/
typedef khronos_uint64_t khronos_utime_nanoseconds_t;
typedef khronos_int64_t khronos_stime_nanoseconds_t;
#endif
/*
* Dummy value used to pad enum types to 32 bits.
*/
#ifndef KHRONOS_MAX_ENUM
#define KHRONOS_MAX_ENUM 0x7FFFFFFF
#endif
/*
* Enumerated boolean type
*
* Values other than zero should be considered to be true. Therefore
* comparisons should not be made against KHRONOS_TRUE.
*/
typedef enum {
KHRONOS_FALSE = 0,
KHRONOS_TRUE = 1,
KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
} khronos_boolean_enum_t;
#endif /* __khrplatform_h_ */
File diff suppressed because it is too large Load Diff
-1
View File
@@ -1,5 +1,4 @@
#include "StgSharpNative.h"
#include "glfw_function.h"
SN_API void SN_DECL load_glfw_functions(GLFWFunctionTable *table)
{
-64
View File
@@ -1,64 +0,0 @@
#ifndef STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_IMPLEMENTATION
#endif
#include "StgSharpNative.h"
#include "gl.h"
#include "../lib/glfw/glfw3.h"
#include <stdio.h>
#include <string.h>
extern GladGLContext *currentContext;
char infolog[512];
SN_API int SN_DECL glCheckShaderStat(GladGLContext *context, uint64_t shaderHandle, int key,
char **logRef)
{
int stat = 0;
context->GetShaderiv(shaderHandle, key, &stat);
if (!stat) {
context->GetShaderInfoLog(shaderHandle, 512, NULL, infolog);
}
*logRef = infolog;
return stat;
}
SN_API void SN_DECL initGL(int majorVersion, int minorVersion)
{
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, majorVersion);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, minorVersion);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
}
SN_API GLFWglproc SN_DECL loadGlfuncDefault(char *procName)
{
void *ret = glfwGetProcAddress(procName);
// printf("%llu\n", (uint64_t)ret);
if (ret == NULL) {
strcpy_s(infolog, 30, "Failed to load OpenGL api:");
for (size_t i = 0; i < sizeof(procName); i++) {
infolog[30 + i] = procName[i];
}
//printf("%s\n", infolog);
}
return (GLFWglproc)ret;
}
SN_API void SN_DECL loadImageData(char *location, Image *out, imageLoader loader)
{
if (loader == NULL) {
loader = (imageLoader)stbi_load;
}
out->pixelPtr = loader(location, &(out->width), &(out->height), &(out->channel), 0);
}
SN_API void SN_DECL unloadImageData(Image *out)
{
free(out->pixelPtr);
}
SN_API char *SN_DECL readLog()
{
infolog[511] = '\0';
return infolog;
}