diff --git a/Campari.csproj b/Campari.csproj index 9d7b99d..dfa4d85 100644 --- a/Campari.csproj +++ b/Campari.csproj @@ -3,6 +3,7 @@ netstandard2.0 x64 + true diff --git a/Texture.cs b/Texture.cs deleted file mode 100644 index 287d516..0000000 --- a/Texture.cs +++ /dev/null @@ -1,82 +0,0 @@ -using System; -using RefreshCS; - -namespace Campari -{ - public class Texture : IDisposable - { - public RefreshDevice Device { get; } - public IntPtr Handle { get; } - public uint Height { get; } - public uint Width { get; } - - public bool IsDisposed { get; private set; } - - public static Texture Load(RefreshDevice device, string path) - { - var pixels = Refresh.Refresh_Image_Load(path, out var width, out var height, out var channels); - IntPtr textureHandle = Refresh.Refresh_CreateTexture2D( - device.Handle, - Refresh.ColorFormat.R8G8B8A8, - (uint) width, - (uint) height, - 1, - (uint) Refresh.TextureUsageFlagBits.SamplerBit - ); - - Refresh.TextureSlice textureSlice; - textureSlice.texture = textureHandle; - textureSlice.rectangle.x = 0; - textureSlice.rectangle.y = 0; - textureSlice.rectangle.w = width; - textureSlice.rectangle.h = height; - textureSlice.level = 0; - textureSlice.layer = 0; - textureSlice.depth = 0; - - Refresh.Refresh_SetTextureData( - device.Handle, - ref textureSlice, - pixels, - (uint) (width * height * 4) - ); - - return new Texture( - device, - textureHandle, - (uint) width, - (uint) height - ); - } - - public Texture(RefreshDevice device, IntPtr handle, uint width, uint height) - { - Device = device; - Handle = handle; - Width = width; - Height = height; - } - - protected virtual void Dispose(bool disposing) - { - if (!IsDisposed) - { - Refresh.Refresh_QueueDestroyTexture(Device.Handle, Handle); - IsDisposed = true; - } - } - - ~Texture() - { - // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method - Dispose(disposing: false); - } - - public void Dispose() - { - // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method - Dispose(disposing: true); - GC.SuppressFinalize(this); - } - } -} diff --git a/lib/RefreshCS b/lib/RefreshCS index c33e62b..c6fddad 160000 --- a/lib/RefreshCS +++ b/lib/RefreshCS @@ -1 +1 @@ -Subproject commit c33e62b9e46f9c86c40fffe56bce461739b71bf8 +Subproject commit c6fddad50aaf4a6d00ca8571fb8f94876d0fcbef diff --git a/src/Bytecode.cs b/src/Bytecode.cs new file mode 100644 index 0000000..8f33e7f --- /dev/null +++ b/src/Bytecode.cs @@ -0,0 +1,33 @@ +using System.IO; + +namespace Campari +{ + public static class Bytecode + { + public static uint[] ReadBytecode(FileInfo fileInfo) + { + byte[] data; + int size; + using (FileStream stream = new FileStream(fileInfo.FullName, FileMode.Open, FileAccess.Read)) + { + size = (int)stream.Length; + data = new byte[size]; + stream.Read(data, 0, size); + } + + uint[] uintData = new uint[size / 4]; + using (var memoryStream = new MemoryStream(data)) + { + using (var reader = new BinaryReader(memoryStream)) + { + for (int i = 0; i < size / 4; i++) + { + uintData[i] = reader.ReadUInt32(); + } + } + } + + return uintData; + } + } +} diff --git a/src/GraphicsResource.cs b/src/GraphicsResource.cs new file mode 100644 index 0000000..2c77ef5 --- /dev/null +++ b/src/GraphicsResource.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Campari +{ + public abstract class GraphicsResource : IDisposable + { + public RefreshDevice Device { get; } + public IntPtr Handle { get; protected set; } + + public bool IsDisposed { get; private set; } + protected abstract Action QueueDestroyFunction { get; } + + public GraphicsResource(RefreshDevice device) + { + Device = device; + } + + protected virtual void Dispose(bool disposing) + { + if (!IsDisposed) + { + QueueDestroyFunction(Device.Handle, Handle); + IsDisposed = true; + } + } + + ~GraphicsResource() + { + // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + Dispose(disposing: false); + } + + public void Dispose() + { + // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + Dispose(disposing: true); + GC.SuppressFinalize(this); + } + } +} diff --git a/RefreshDevice.cs b/src/RefreshDevice.cs similarity index 100% rename from RefreshDevice.cs rename to src/RefreshDevice.cs diff --git a/src/RenderPass.cs b/src/RenderPass.cs new file mode 100644 index 0000000..ece64e7 --- /dev/null +++ b/src/RenderPass.cs @@ -0,0 +1,42 @@ +using System; +using RefreshCS; + +namespace Campari +{ + public class RenderPass : GraphicsResource + { + protected override Action QueueDestroyFunction => Refresh.Refresh_QueueDestroyRenderPass; + + public unsafe RenderPass(RefreshDevice device, params Refresh.ColorTargetDescription[] colorTargetDescriptions) : base(device) + { + fixed (Refresh.ColorTargetDescription* ptr = colorTargetDescriptions) + { + Refresh.RenderPassCreateInfo renderPassCreateInfo; + renderPassCreateInfo.colorTargetCount = (uint) colorTargetDescriptions.Length; + renderPassCreateInfo.colorTargetDescriptions = (IntPtr) ptr; + renderPassCreateInfo.depthStencilTargetDescription = IntPtr.Zero; + + Handle = Refresh.Refresh_CreateRenderPass(device.Handle, ref renderPassCreateInfo); + } + } + + public unsafe RenderPass( + RefreshDevice device, + Refresh.DepthStencilTargetDescription depthStencilTargetDescription, + params Refresh.ColorTargetDescription[] colorTargetDescriptions + ) : base(device) + { + Refresh.DepthStencilTargetDescription* depthStencilPtr = &depthStencilTargetDescription; + + fixed (Refresh.ColorTargetDescription* colorPtr = colorTargetDescriptions) + { + Refresh.RenderPassCreateInfo renderPassCreateInfo; + renderPassCreateInfo.colorTargetCount = (uint)colorTargetDescriptions.Length; + renderPassCreateInfo.colorTargetDescriptions = (IntPtr)colorPtr; + renderPassCreateInfo.depthStencilTargetDescription = (IntPtr) depthStencilPtr; + + Handle = Refresh.Refresh_CreateRenderPass(device.Handle, ref renderPassCreateInfo); + } + } + } +} diff --git a/src/ShaderModule.cs b/src/ShaderModule.cs new file mode 100644 index 0000000..e932857 --- /dev/null +++ b/src/ShaderModule.cs @@ -0,0 +1,23 @@ +using RefreshCS; +using System; +using System.IO; + +namespace Campari +{ + public class ShaderModule : GraphicsResource + { + protected override Action QueueDestroyFunction => Refresh.Refresh_QueueDestroyShaderModule; + + public unsafe ShaderModule(RefreshDevice device, FileInfo fileInfo) : base(device) + { + fixed (uint* ptr = Bytecode.ReadBytecode(fileInfo)) + { + Refresh.ShaderModuleCreateInfo shaderModuleCreateInfo; + shaderModuleCreateInfo.codeSize = (UIntPtr) fileInfo.Length; + shaderModuleCreateInfo.byteCode = (IntPtr) ptr; + + Handle = Refresh.Refresh_CreateShaderModule(device.Handle, ref shaderModuleCreateInfo); + } + } + } +} diff --git a/src/Texture.cs b/src/Texture.cs new file mode 100644 index 0000000..5857f29 --- /dev/null +++ b/src/Texture.cs @@ -0,0 +1,55 @@ +using System; +using System.IO; +using RefreshCS; + +namespace Campari +{ + public class Texture : GraphicsResource + { + public uint Height { get; } + public uint Width { get; } + + protected override Action QueueDestroyFunction => Refresh.Refresh_QueueDestroyTexture; + + public Texture(RefreshDevice device, FileInfo fileInfo) : base(device) + { + var pixels = Refresh.Refresh_Image_Load( + fileInfo.FullName, + out var width, + out var height, + out var channels + ); + + IntPtr textureHandle = Refresh.Refresh_CreateTexture2D( + device.Handle, + Refresh.ColorFormat.R8G8B8A8, + (uint)width, + (uint)height, + 1, + (uint)Refresh.TextureUsageFlagBits.SamplerBit + ); + + Refresh.TextureSlice textureSlice; + textureSlice.texture = textureHandle; + textureSlice.rectangle.x = 0; + textureSlice.rectangle.y = 0; + textureSlice.rectangle.w = width; + textureSlice.rectangle.h = height; + textureSlice.level = 0; + textureSlice.layer = 0; + textureSlice.depth = 0; + + Refresh.Refresh_SetTextureData( + device.Handle, + ref textureSlice, + pixels, + (uint)(width * height * 4) + ); + + Refresh.Refresh_Image_Free(pixels); + + Width = (uint) width; + Height = (uint) height; + } + } +}