replace Campari with MoonWorks.Graphics
							parent
							
								
									2b58edb257
								
							
						
					
					
						commit
						2cabaa6186
					
				|  | @ -1,9 +1,9 @@ | |||
| [submodule "lib/SDL2-CS"] | ||||
| 	path = lib/SDL2-CS | ||||
| 	url = https://github.com/flibitijibibo/SDL2-CS.git | ||||
| [submodule "lib/Campari"] | ||||
| 	path = lib/Campari | ||||
| 	url = https://gitea.moonside.games/MoonsideGames/Campari.git | ||||
| [submodule "lib/FAudio"] | ||||
| 	path = lib/FAudio | ||||
| 	url = https://github.com/FNA-XNA/FAudio.git | ||||
| [submodule "lib/RefreshCS"] | ||||
| 	path = lib/RefreshCS | ||||
| 	url = https://gitea.moonside.games/MoonsideGames/RefreshCS.git | ||||
|  |  | |||
|  | @ -12,8 +12,7 @@ | |||
| 
 | ||||
|   <ItemGroup> | ||||
|     <ProjectReference Include=".\lib\SDL2-CS\SDL2-CS.Core.csproj" /> | ||||
|     <ProjectReference Include=".\lib\Campari\Campari.csproj" /> | ||||
|     <ProjectReference Include=".\lib\Campari\lib\RefreshCS\RefreshCS.csproj" /> | ||||
|     <ProjectReference Include=".\lib\RefreshCS\RefreshCS.csproj" /> | ||||
|     <ProjectReference Include=".\lib\FAudio\csharp\FAudio-CS.Core.csproj" /> | ||||
|   </ItemGroup> | ||||
| </Project> | ||||
|  |  | |||
|  | @ -10,12 +10,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MoonWorks", "MoonWorks.cspr | |||
| EndProject | ||||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SDL2-CS.Core", "lib\SDL2-CS\SDL2-CS.Core.csproj", "{0929F2D8-8FE4-4452-AD1E-50760A1A19A5}" | ||||
| EndProject | ||||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Campari", "lib\Campari\Campari.csproj", "{D09577DE-99F5-4C30-9165-4012C37CE0CE}" | ||||
| EndProject | ||||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RefreshCS", "lib\Campari\lib\RefreshCS\RefreshCS.csproj", "{66116A40-B360-4BA3-966A-A54F3E562EC1}" | ||||
| EndProject | ||||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FAudio-CS.Core", "lib\FAudio\csharp\FAudio-CS.Core.csproj", "{608AA31D-F163-4096-B4EF-B9C7D21D52BB}" | ||||
| EndProject | ||||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RefreshCS", "lib\RefreshCS\RefreshCS.csproj", "{AD7C94E4-0AFA-44CA-889C-110142369893}" | ||||
| EndProject | ||||
| Global | ||||
| 	GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||||
| 		Debug|x64 = Debug|x64 | ||||
|  | @ -30,18 +28,14 @@ Global | |||
| 		{0929F2D8-8FE4-4452-AD1E-50760A1A19A5}.Debug|x64.Build.0 = Debug|x64 | ||||
| 		{0929F2D8-8FE4-4452-AD1E-50760A1A19A5}.Release|x64.ActiveCfg = Release|x64 | ||||
| 		{0929F2D8-8FE4-4452-AD1E-50760A1A19A5}.Release|x64.Build.0 = Release|x64 | ||||
| 		{D09577DE-99F5-4C30-9165-4012C37CE0CE}.Debug|x64.ActiveCfg = Debug|x64 | ||||
| 		{D09577DE-99F5-4C30-9165-4012C37CE0CE}.Debug|x64.Build.0 = Debug|x64 | ||||
| 		{D09577DE-99F5-4C30-9165-4012C37CE0CE}.Release|x64.ActiveCfg = Release|x64 | ||||
| 		{D09577DE-99F5-4C30-9165-4012C37CE0CE}.Release|x64.Build.0 = Release|x64 | ||||
| 		{66116A40-B360-4BA3-966A-A54F3E562EC1}.Debug|x64.ActiveCfg = Debug|x64 | ||||
| 		{66116A40-B360-4BA3-966A-A54F3E562EC1}.Debug|x64.Build.0 = Debug|x64 | ||||
| 		{66116A40-B360-4BA3-966A-A54F3E562EC1}.Release|x64.ActiveCfg = Release|x64 | ||||
| 		{66116A40-B360-4BA3-966A-A54F3E562EC1}.Release|x64.Build.0 = Release|x64 | ||||
| 		{608AA31D-F163-4096-B4EF-B9C7D21D52BB}.Debug|x64.ActiveCfg = Debug|x64 | ||||
| 		{608AA31D-F163-4096-B4EF-B9C7D21D52BB}.Debug|x64.Build.0 = Debug|x64 | ||||
| 		{608AA31D-F163-4096-B4EF-B9C7D21D52BB}.Release|x64.ActiveCfg = Release|x64 | ||||
| 		{608AA31D-F163-4096-B4EF-B9C7D21D52BB}.Release|x64.Build.0 = Release|x64 | ||||
| 		{AD7C94E4-0AFA-44CA-889C-110142369893}.Debug|x64.ActiveCfg = Debug|x64 | ||||
| 		{AD7C94E4-0AFA-44CA-889C-110142369893}.Debug|x64.Build.0 = Debug|x64 | ||||
| 		{AD7C94E4-0AFA-44CA-889C-110142369893}.Release|x64.ActiveCfg = Release|x64 | ||||
| 		{AD7C94E4-0AFA-44CA-889C-110142369893}.Release|x64.Build.0 = Release|x64 | ||||
| 	EndGlobalSection | ||||
| 	GlobalSection(SolutionProperties) = preSolution | ||||
| 		HideSolutionNode = FALSE | ||||
|  |  | |||
|  | @ -1 +0,0 @@ | |||
| Subproject commit f01b9a3a9acff8672e0d7da253ee2402fcdaa281 | ||||
|  | @ -0,0 +1 @@ | |||
| Subproject commit ba183e8c0f9d21e4397d76941078b4969d4f6686 | ||||
|  | @ -1,5 +1,5 @@ | |||
| using SDL2; | ||||
| using Campari; | ||||
| using MoonWorks.Graphics; | ||||
| using System.Collections.Generic; | ||||
| using MoonWorks.Audio; | ||||
| 
 | ||||
|  |  | |||
|  | @ -0,0 +1,10 @@ | |||
| namespace MoonWorks.Graphics | ||||
| { | ||||
|     public struct BlendConstants | ||||
|     { | ||||
|         public float R; | ||||
|         public float G; | ||||
|         public float B; | ||||
|         public float A; | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,73 @@ | |||
| using System; | ||||
| using RefreshCS; | ||||
| 
 | ||||
| namespace MoonWorks.Graphics | ||||
| { | ||||
|     public class Buffer : GraphicsResource | ||||
|     { | ||||
|         protected override Action<IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroyBuffer; | ||||
| 
 | ||||
|         public Buffer( | ||||
|             GraphicsDevice device, | ||||
|             Refresh.BufferUsageFlags usageFlags, | ||||
|             uint sizeInBytes | ||||
|         ) : base(device) | ||||
|         { | ||||
|             Handle = Refresh.Refresh_CreateBuffer( | ||||
|                 device.Handle, | ||||
|                 usageFlags, | ||||
|                 sizeInBytes | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
|         public unsafe void SetData<T>( | ||||
|             uint offsetInBytes, | ||||
|             T[] data, | ||||
|             uint dataLengthInBytes | ||||
|         ) where T : unmanaged | ||||
|         { | ||||
|             fixed (T* ptr = &data[0]) | ||||
|             { | ||||
|                 Refresh.Refresh_SetBufferData( | ||||
|                     Device.Handle, | ||||
|                     Handle, | ||||
|                     offsetInBytes, | ||||
|                     (IntPtr) ptr, | ||||
|                     dataLengthInBytes | ||||
|                 ); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public unsafe void SetData<T>( | ||||
|             uint offsetInBytes, | ||||
|             T* data, | ||||
|             uint dataLengthInBytes | ||||
|         ) where T : unmanaged | ||||
|         { | ||||
|             Refresh.Refresh_SetBufferData( | ||||
|                 Device.Handle, | ||||
|                 Handle, | ||||
|                 offsetInBytes, | ||||
|                 (IntPtr) data, | ||||
|                 dataLengthInBytes | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
|         // NOTE: You want to wait on the device before calling this | ||||
|         public unsafe void GetData<T>( | ||||
|             T[] data, | ||||
|             uint dataLengthInBytes | ||||
|         ) where T : unmanaged | ||||
|         { | ||||
|             fixed (T* ptr = &data[0]) | ||||
|             { | ||||
|                 Refresh.Refresh_GetBufferData( | ||||
|                     Device.Handle, | ||||
|                     Handle, | ||||
|                     (IntPtr)ptr, | ||||
|                     dataLengthInBytes | ||||
|                 ); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,14 @@ | |||
| namespace MoonWorks.Graphics | ||||
| { | ||||
|     public struct BufferBinding | ||||
|     { | ||||
|         public Buffer Buffer; | ||||
|         public ulong Offset; | ||||
| 
 | ||||
|         public BufferBinding(Buffer buffer, ulong offset) | ||||
|         { | ||||
|             Buffer = buffer; | ||||
|             Offset = offset; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,33 @@ | |||
| using System.IO; | ||||
| 
 | ||||
| namespace MoonWorks.Graphics | ||||
| { | ||||
|     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; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,50 @@ | |||
| using System; | ||||
| using RefreshCS; | ||||
| 
 | ||||
| namespace MoonWorks.Graphics | ||||
| { | ||||
|     public class ColorTarget : GraphicsResource | ||||
|     { | ||||
|         public uint Width { get; } | ||||
|         public uint Height { get; } | ||||
| 
 | ||||
|         public Texture Texture { get; } | ||||
|         public Refresh.ColorFormat Format => Texture.Format; | ||||
| 
 | ||||
|         protected override Action<IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroyColorTarget; | ||||
| 
 | ||||
|         public static ColorTarget CreateBackedColorTarget2D( | ||||
|             GraphicsDevice device, | ||||
|             uint width, | ||||
|             uint height, | ||||
|             Refresh.ColorFormat format, | ||||
|             bool canBeSampled, | ||||
|             Refresh.SampleCount sampleCount = Refresh.SampleCount.One, | ||||
|             uint levelCount = 1 | ||||
|         ) | ||||
|         { | ||||
|             var flags = Refresh.TextureUsageFlags.ColorTargetBit; | ||||
|             if (canBeSampled) { flags |= Refresh.TextureUsageFlags.SamplerBit; } | ||||
| 
 | ||||
|             var texture = Texture.CreateTexture2D( | ||||
|                 device, | ||||
|                 width, | ||||
|                 height, | ||||
|                 format, | ||||
|                 flags, | ||||
|                 sampleCount, | ||||
|                 levelCount | ||||
|             ); | ||||
| 
 | ||||
|             var textureSlice = new TextureSlice(texture); | ||||
| 
 | ||||
|             return new ColorTarget(device, sampleCount, ref textureSlice); | ||||
|         } | ||||
| 
 | ||||
|         public ColorTarget(GraphicsDevice device, Refresh.SampleCount sampleCount, ref TextureSlice textureSlice) : base(device) | ||||
|         { | ||||
|             var refreshTextureSlice = textureSlice.ToRefreshTextureSlice(); | ||||
|             Handle = Refresh.Refresh_CreateColorTarget(device.Handle, sampleCount, ref refreshTextureSlice); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,414 @@ | |||
| using System; | ||||
| using System.Runtime.InteropServices; | ||||
| using RefreshCS; | ||||
| 
 | ||||
| namespace MoonWorks.Graphics | ||||
| { | ||||
|     public class CommandBuffer | ||||
|     { | ||||
|         public GraphicsDevice Device { get; } | ||||
|         public IntPtr Handle { get; internal set; } | ||||
| 
 | ||||
|         // called from RefreshDevice | ||||
|         internal CommandBuffer(GraphicsDevice device) | ||||
|         { | ||||
|             Device = device; | ||||
|             Handle = IntPtr.Zero; | ||||
|         } | ||||
| 
 | ||||
|         public unsafe void BeginRenderPass( | ||||
|             RenderPass renderPass, | ||||
|             Framebuffer framebuffer, | ||||
|             ref Refresh.Rect renderArea, | ||||
|             ref Refresh.DepthStencilValue depthStencilClearValue, | ||||
|             params Refresh.Color[] clearColors | ||||
|         ) { | ||||
|             fixed (Refresh.Color* clearColorPtr = &clearColors[0]) | ||||
|             { | ||||
|                 Refresh.Refresh_BeginRenderPass( | ||||
|                     Device.Handle, | ||||
|                     Handle, | ||||
|                     renderPass.Handle, | ||||
|                     framebuffer.Handle, | ||||
|                     ref renderArea, | ||||
|                     (IntPtr) clearColorPtr, | ||||
|                     (uint)clearColors.Length, | ||||
|                     ref depthStencilClearValue | ||||
|                 ); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public unsafe void BeginRenderPass( | ||||
|             RenderPass renderPass, | ||||
|             Framebuffer framebuffer, | ||||
|             ref Refresh.Rect renderArea, | ||||
|             params Refresh.Color[] clearColors | ||||
|         ) { | ||||
|             fixed (Refresh.Color* clearColorPtr = &clearColors[0]) | ||||
|             { | ||||
|                 Refresh.Refresh_BeginRenderPass( | ||||
|                     Device.Handle, | ||||
|                     Handle, | ||||
|                     renderPass.Handle, | ||||
|                     framebuffer.Handle, | ||||
|                     ref renderArea, | ||||
|                     (IntPtr) clearColorPtr, | ||||
|                     (uint) clearColors.Length, | ||||
|                     IntPtr.Zero | ||||
|                 ); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public void BindComputePipeline( | ||||
|             ComputePipeline computePipeline | ||||
|         ) { | ||||
|             Refresh.Refresh_BindComputePipeline( | ||||
|                 Device.Handle, | ||||
|                 Handle, | ||||
|                 computePipeline.Handle | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
|         public unsafe uint PushComputeShaderParams<T>( | ||||
|             params T[] uniforms | ||||
|         ) where T : unmanaged | ||||
|         { | ||||
|             fixed (T* ptr = &uniforms[0]) | ||||
|             { | ||||
|                 return Refresh.Refresh_PushComputeShaderParams( | ||||
|                     Device.Handle, | ||||
|                     Handle, | ||||
|                     (IntPtr) ptr, | ||||
|                     (uint) uniforms.Length | ||||
|                 ); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public unsafe void BindComputeBuffers( | ||||
|             params Buffer[] buffers | ||||
|         ) { | ||||
|             var bufferPtrs = stackalloc IntPtr[buffers.Length]; | ||||
| 
 | ||||
|             for (var i = 0; i < buffers.Length; i += 1) | ||||
|             { | ||||
|                 bufferPtrs[i] = buffers[i].Handle; | ||||
|             } | ||||
| 
 | ||||
|             Refresh.Refresh_BindComputeBuffers( | ||||
|                 Device.Handle, | ||||
|                 Handle, | ||||
|                 (IntPtr) bufferPtrs | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
|         public unsafe void BindComputeTextures( | ||||
|             params Texture[] textures | ||||
|         ) { | ||||
|             var texturePtrs = stackalloc IntPtr[textures.Length]; | ||||
| 
 | ||||
|             for (var i = 0; i < textures.Length; i += 1) | ||||
|             { | ||||
|                 texturePtrs[i] = textures[i].Handle; | ||||
|             } | ||||
| 
 | ||||
|             Refresh.Refresh_BindComputeTextures( | ||||
|                 Device.Handle, | ||||
|                 Handle, | ||||
|                 (IntPtr) texturePtrs | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
|         public void BindGraphicsPipeline( | ||||
|             GraphicsPipeline graphicsPipeline | ||||
|         ) { | ||||
|             Refresh.Refresh_BindGraphicsPipeline( | ||||
|                 Device.Handle, | ||||
|                 Handle, | ||||
|                 graphicsPipeline.Handle | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
|         public unsafe uint PushVertexShaderParams<T>( | ||||
|             params T[] uniforms | ||||
|         ) where T : unmanaged | ||||
|         { | ||||
|             fixed (T* ptr = &uniforms[0]) | ||||
|             { | ||||
|                 return Refresh.Refresh_PushVertexShaderParams( | ||||
|                     Device.Handle, | ||||
|                     Handle, | ||||
|                     (IntPtr) ptr, | ||||
|                     (uint) uniforms.Length | ||||
|                 ); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public unsafe uint PushFragmentShaderParams<T>( | ||||
|             params T[] uniforms | ||||
|         ) where T : unmanaged | ||||
|         { | ||||
|             fixed (T* ptr = &uniforms[0]) | ||||
|             { | ||||
|                 return Refresh.Refresh_PushFragmentShaderParams( | ||||
|                     Device.Handle, | ||||
|                     Handle, | ||||
|                     (IntPtr) ptr, | ||||
|                     (uint) uniforms.Length | ||||
|                 ); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public unsafe void BindVertexBuffers( | ||||
|             uint firstBinding, | ||||
|             params BufferBinding[] bufferBindings | ||||
|         ) { | ||||
|             var bufferPtrs = stackalloc IntPtr[bufferBindings.Length]; | ||||
|             var offsets = stackalloc ulong[bufferBindings.Length]; | ||||
| 
 | ||||
|             for (var i = 0; i < bufferBindings.Length; i += 1) | ||||
|             { | ||||
|                 bufferPtrs[i] = bufferBindings[i].Buffer.Handle; | ||||
|                 offsets[i] = bufferBindings[i].Offset; | ||||
|             } | ||||
| 
 | ||||
|             Refresh.Refresh_BindVertexBuffers( | ||||
|                 Device.Handle, | ||||
|                 Handle, | ||||
|                 firstBinding, | ||||
|                 (uint) bufferBindings.Length, | ||||
|                 (IntPtr) bufferPtrs, | ||||
|                 (IntPtr) offsets | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
|         public void BindIndexBuffer( | ||||
|             Buffer indexBuffer, | ||||
|             uint offset, | ||||
|             Refresh.IndexElementSize indexElementSize | ||||
|         ) { | ||||
|             Refresh.Refresh_BindIndexBuffer( | ||||
|                 Device.Handle, | ||||
|                 Handle, | ||||
|                 indexBuffer.Handle, | ||||
|                 offset, | ||||
|                 indexElementSize | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
|         public unsafe void BindVertexSamplers( | ||||
|             Texture[] textures, | ||||
|             Sampler[] samplers | ||||
|         ) { | ||||
|             var texturePtrs = stackalloc IntPtr[textures.Length]; | ||||
|             var samplerPtrs = stackalloc IntPtr[samplers.Length]; | ||||
| 
 | ||||
|             for (var i = 0; i < textures.Length; i += 1) | ||||
|             { | ||||
|                 texturePtrs[i] = textures[i].Handle; | ||||
|             } | ||||
| 
 | ||||
|             for (var i = 0; i < samplers.Length; i += 1) | ||||
|             { | ||||
|                 samplerPtrs[i] = samplers[i].Handle; | ||||
|             } | ||||
| 
 | ||||
|             Refresh.Refresh_BindVertexSamplers( | ||||
|                 Device.Handle, | ||||
|                 Handle, | ||||
|                 (IntPtr) texturePtrs, | ||||
|                 (IntPtr) samplerPtrs | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
|         public unsafe void BindFragmentSamplers( | ||||
|             params TextureSamplerBinding[] textureSamplerBindings | ||||
|         ) { | ||||
|             var texturePtrs = stackalloc IntPtr[textureSamplerBindings.Length]; | ||||
|             var samplerPtrs = stackalloc IntPtr[textureSamplerBindings.Length]; | ||||
| 
 | ||||
|             for (var i = 0; i < textureSamplerBindings.Length; i += 1) | ||||
|             { | ||||
|                 texturePtrs[i] = textureSamplerBindings[i].Texture.Handle; | ||||
|                 samplerPtrs[i] = textureSamplerBindings[i].Sampler.Handle; | ||||
|             } | ||||
| 
 | ||||
|             Refresh.Refresh_BindFragmentSamplers( | ||||
|                 Device.Handle, | ||||
|                 Handle, | ||||
|                 (IntPtr) texturePtrs, | ||||
|                 (IntPtr) samplerPtrs | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
|         public void Clear( | ||||
|             ref Refresh.Rect clearRect, | ||||
|             Refresh.ClearOptionsFlags clearOptions, | ||||
|             ref Refresh.Color[] colors, | ||||
|             float depth, | ||||
|             int stencil | ||||
|         ) { | ||||
|             Refresh.Refresh_Clear( | ||||
|                 Device.Handle, | ||||
|                 Handle, | ||||
|                 ref clearRect, | ||||
|                 clearOptions, | ||||
|                 ref colors, | ||||
|                 (uint) colors.Length, | ||||
|                 depth, | ||||
|                 stencil | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
|         public void DrawInstancedPrimitives( | ||||
|             uint baseVertex, | ||||
|             uint startIndex, | ||||
|             uint primitiveCount, | ||||
|             uint instanceCount, | ||||
|             uint vertexParamOffset, | ||||
|             uint fragmentParamOffset | ||||
|         ) { | ||||
|             Refresh.Refresh_DrawInstancedPrimitives( | ||||
|                 Device.Handle, | ||||
|                 Handle, | ||||
|                 baseVertex, | ||||
|                 startIndex, | ||||
|                 primitiveCount, | ||||
|                 instanceCount, | ||||
|                 vertexParamOffset, | ||||
|                 fragmentParamOffset | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
|         public void DrawIndexedPrimitives( | ||||
|             uint baseVertex, | ||||
|             uint startIndex, | ||||
|             uint primitiveCount, | ||||
|             uint vertexParamOffset, | ||||
|             uint fragmentParamOffset | ||||
|         ) { | ||||
|             Refresh.Refresh_DrawIndexedPrimitives( | ||||
|                 Device.Handle, | ||||
|                 Handle, | ||||
|                 baseVertex, | ||||
|                 startIndex, | ||||
|                 primitiveCount, | ||||
|                 vertexParamOffset, | ||||
|                 fragmentParamOffset | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
|         public void DrawPrimitives( | ||||
|             uint vertexStart, | ||||
|             uint primitiveCount, | ||||
|             uint vertexParamOffset, | ||||
|             uint fragmentParamOffset | ||||
|         ) { | ||||
|             Refresh.Refresh_DrawPrimitives( | ||||
|                 Device.Handle, | ||||
|                 Handle, | ||||
|                 vertexStart, | ||||
|                 primitiveCount, | ||||
|                 vertexParamOffset, | ||||
|                 fragmentParamOffset | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
|         public void EndRenderPass() | ||||
|         { | ||||
|             Refresh.Refresh_EndRenderPass( | ||||
|                 Device.Handle, | ||||
|                 Handle | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
|         public void QueuePresent( | ||||
|             ref TextureSlice textureSlice, | ||||
|             ref Refresh.Rect destinationRectangle, | ||||
|             Refresh.Filter filter | ||||
|         ) { | ||||
|             var refreshTextureSlice = textureSlice.ToRefreshTextureSlice(); | ||||
| 
 | ||||
|             Refresh.Refresh_QueuePresent( | ||||
|                 Device.Handle, | ||||
|                 Handle, | ||||
|                 ref refreshTextureSlice, | ||||
|                 ref destinationRectangle, | ||||
|                 filter | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
|         public void QueuePresent( | ||||
|             ref TextureSlice textureSlice, | ||||
|             Refresh.Filter filter | ||||
|         ) { | ||||
|             var refreshTextureSlice = textureSlice.ToRefreshTextureSlice(); | ||||
| 
 | ||||
|             Refresh.Refresh_QueuePresent( | ||||
|                 Device.Handle, | ||||
|                 Handle, | ||||
|                 ref refreshTextureSlice, | ||||
|                 IntPtr.Zero, | ||||
|                 filter | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
|         public void QueuePresent( | ||||
|             Texture texture, | ||||
|             Refresh.Filter filter | ||||
|         ) { | ||||
|             var refreshTextureSlice = new Refresh.TextureSlice | ||||
|             { | ||||
|                 texture = texture.Handle, | ||||
|                 rectangle = new Refresh.Rect | ||||
|                 { | ||||
|                     x = 0, | ||||
|                     y = 0, | ||||
|                     w = (int) texture.Width, | ||||
|                     h = (int) texture.Height | ||||
|                 }, | ||||
|                 layer = 0, | ||||
|                 level = 0, | ||||
|                 depth = 0 | ||||
|             }; | ||||
| 
 | ||||
|             Refresh.Refresh_QueuePresent( | ||||
|                 Device.Handle, | ||||
|                 Handle, | ||||
|                 ref refreshTextureSlice, | ||||
|                 IntPtr.Zero, | ||||
|                 filter | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
|         public void CopyTextureToTexture( | ||||
|             ref TextureSlice sourceTextureSlice, | ||||
|             ref TextureSlice destinationTextureSlice, | ||||
|             Refresh.Filter filter | ||||
|         ) { | ||||
|             var sourceRefreshTextureSlice = sourceTextureSlice.ToRefreshTextureSlice(); | ||||
|             var destRefreshTextureSlice = destinationTextureSlice.ToRefreshTextureSlice(); | ||||
| 
 | ||||
|             Refresh.Refresh_CopyTextureToTexture( | ||||
|                 Device.Handle, | ||||
|                 Handle, | ||||
|                 ref sourceRefreshTextureSlice, | ||||
|                 ref destRefreshTextureSlice, | ||||
|                 filter | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
|         public void CopyTextureToBuffer( | ||||
|             ref TextureSlice textureSlice, | ||||
|             Buffer buffer | ||||
|         ) { | ||||
|             var refreshTextureSlice = textureSlice.ToRefreshTextureSlice(); | ||||
| 
 | ||||
|             Refresh.Refresh_CopyTextureToBuffer( | ||||
|                 Device.Handle, | ||||
|                 Handle, | ||||
|                 ref refreshTextureSlice, | ||||
|                 buffer.Handle | ||||
|             ); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,39 @@ | |||
| using RefreshCS; | ||||
| using System; | ||||
| 
 | ||||
| namespace MoonWorks.Graphics | ||||
| { | ||||
|     public class ComputePipeline : GraphicsResource | ||||
|     { | ||||
|         protected override Action<IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroyComputePipeline; | ||||
| 
 | ||||
|         public unsafe ComputePipeline( | ||||
|             GraphicsDevice device, | ||||
|             ShaderStageState computeShaderState, | ||||
|             uint bufferBindingCount, | ||||
|             uint imageBindingCount | ||||
|         ) : base(device) { | ||||
|             var computePipelineLayoutCreateInfo = new Refresh.ComputePipelineLayoutCreateInfo | ||||
|             { | ||||
|                 bufferBindingCount = bufferBindingCount, | ||||
|                 imageBindingCount = imageBindingCount | ||||
|             }; | ||||
| 
 | ||||
|             var computePipelineCreateInfo = new Refresh.ComputePipelineCreateInfo | ||||
|             { | ||||
|                 pipelineLayoutCreateInfo = computePipelineLayoutCreateInfo, | ||||
|                 computeShaderState = new Refresh.ShaderStageState | ||||
|                 { | ||||
|                     entryPointName = computeShaderState.EntryPointName, | ||||
|                     shaderModule = computeShaderState.ShaderModule.Handle, | ||||
|                     uniformBufferSize = computeShaderState.UniformBufferSize | ||||
|                 } | ||||
|             }; | ||||
| 
 | ||||
|             Handle = Refresh.Refresh_CreateComputePipeline( | ||||
|                 device.Handle, | ||||
|                 ref computePipelineCreateInfo | ||||
|             ); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,10 @@ | |||
| namespace MoonWorks.Graphics | ||||
| { | ||||
|     public static class Conversions | ||||
|     { | ||||
|         public static byte BoolToByte(bool b) | ||||
|         { | ||||
|             return (byte)(b ? 1 : 0); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,26 @@ | |||
| using System; | ||||
| using RefreshCS; | ||||
| 
 | ||||
| namespace MoonWorks.Graphics | ||||
| { | ||||
|     public class DepthStencilTarget : GraphicsResource | ||||
|     { | ||||
|         public uint Width { get; } | ||||
|         public uint Height { get; } | ||||
|         public Refresh.DepthFormat Format { get; } | ||||
| 
 | ||||
|         protected override Action<IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroyDepthStencilTarget; | ||||
| 
 | ||||
|         public DepthStencilTarget( | ||||
|             GraphicsDevice device, | ||||
|             uint width, | ||||
|             uint height, | ||||
|             Refresh.DepthFormat depthFormat | ||||
|         ) : base(device) | ||||
|         { | ||||
|             Handle = Refresh.Refresh_CreateDepthStencilTarget(device.Handle, width, height, depthFormat); | ||||
|             Width = width; | ||||
|             Height = height; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,51 @@ | |||
| using System; | ||||
| using RefreshCS; | ||||
| 
 | ||||
| namespace MoonWorks.Graphics | ||||
| { | ||||
|     public class Framebuffer : GraphicsResource | ||||
|     { | ||||
|         protected override Action<IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroyFramebuffer; | ||||
| 
 | ||||
|         public unsafe Framebuffer( | ||||
|             GraphicsDevice device, | ||||
|             uint width, | ||||
|             uint height, | ||||
|             RenderPass renderPass, | ||||
|             DepthStencilTarget depthStencilTarget, /* can be NULL */ | ||||
|             params ColorTarget[] colorTargets | ||||
|         ) : base(device) | ||||
|         { | ||||
|             IntPtr[] colorTargetHandles = new IntPtr[colorTargets.Length]; | ||||
|             for (var i = 0; i < colorTargets.Length; i += 1) | ||||
|             { | ||||
|                 colorTargetHandles[i] = colorTargets[i].Handle; | ||||
|             } | ||||
| 
 | ||||
|             IntPtr depthStencilTargetHandle; | ||||
|             if (depthStencilTarget == null) | ||||
|             { | ||||
|                 depthStencilTargetHandle = IntPtr.Zero; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 depthStencilTargetHandle = depthStencilTarget.Handle; | ||||
|             } | ||||
| 
 | ||||
|             fixed (IntPtr* colorTargetHandlesPtr = colorTargetHandles) | ||||
|             { | ||||
|                 Refresh.FramebufferCreateInfo framebufferCreateInfo = new Refresh.FramebufferCreateInfo | ||||
|                 { | ||||
|                     width = width, | ||||
|                     height = height, | ||||
|                     colorTargetCount = (uint) colorTargets.Length, | ||||
|                     pColorTargets = (IntPtr) colorTargetHandlesPtr, | ||||
|                     depthStencilTarget = depthStencilTargetHandle, | ||||
|                     renderPass = renderPass.Handle | ||||
|                 }; | ||||
| 
 | ||||
|                 Handle = Refresh.Refresh_CreateFramebuffer(device.Handle, ref framebufferCreateInfo); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,109 @@ | |||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using RefreshCS; | ||||
| 
 | ||||
| namespace MoonWorks.Graphics | ||||
| { | ||||
|     public class GraphicsDevice : IDisposable | ||||
|     { | ||||
|         public IntPtr Handle { get; } | ||||
| 
 | ||||
|         public bool IsDisposed { get; private set; } | ||||
| 
 | ||||
|         private readonly Queue<CommandBuffer> commandBufferPool; | ||||
| 
 | ||||
|         public GraphicsDevice( | ||||
|             IntPtr deviceWindowHandle, | ||||
|             Refresh.PresentMode presentMode, | ||||
|             bool debugMode, | ||||
|             int initialCommandBufferPoolSize = 4 | ||||
|         ) { | ||||
|             var presentationParameters = new Refresh.PresentationParameters | ||||
|             { | ||||
|                 deviceWindowHandle = deviceWindowHandle, | ||||
|                 presentMode = presentMode | ||||
|             }; | ||||
| 
 | ||||
|             Handle = Refresh.Refresh_CreateDevice( | ||||
|                 ref presentationParameters, | ||||
|                 Conversions.BoolToByte(debugMode) | ||||
|             ); | ||||
| 
 | ||||
|             commandBufferPool = new Queue<CommandBuffer>(initialCommandBufferPoolSize); | ||||
|             for (var i = 0; i < initialCommandBufferPoolSize; i += 1) | ||||
|             { | ||||
|                 commandBufferPool.Enqueue(new CommandBuffer(this)); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public CommandBuffer AcquireCommandBuffer() | ||||
|         { | ||||
|             var commandBufferHandle = Refresh.Refresh_AcquireCommandBuffer(Handle, 0); | ||||
|             if (commandBufferPool.Count == 0) | ||||
|             { | ||||
|                 commandBufferPool.Enqueue(new CommandBuffer(this)); | ||||
|             } | ||||
| 
 | ||||
|             var commandBuffer = commandBufferPool.Dequeue(); | ||||
|             commandBuffer.Handle = commandBufferHandle; | ||||
| 
 | ||||
|             return commandBuffer; | ||||
|         } | ||||
| 
 | ||||
|         public unsafe void Submit(params CommandBuffer[] commandBuffers) | ||||
|         { | ||||
|             var commandBufferPtrs = stackalloc IntPtr[commandBuffers.Length]; | ||||
| 
 | ||||
|             for (var i = 0; i < commandBuffers.Length; i += 1) | ||||
|             { | ||||
|                 commandBufferPtrs[i] = commandBuffers[i].Handle; | ||||
|             } | ||||
| 
 | ||||
|             Refresh.Refresh_Submit( | ||||
|                 Handle, | ||||
|                 (uint) commandBuffers.Length, | ||||
|                 (IntPtr) commandBufferPtrs | ||||
|             ); | ||||
| 
 | ||||
|             // return to pool | ||||
|             for (var i = 0; i < commandBuffers.Length; i += 1) | ||||
|             { | ||||
|                 commandBuffers[i].Handle = IntPtr.Zero; | ||||
|                 commandBufferPool.Enqueue(commandBuffers[i]); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public void Wait() | ||||
|         { | ||||
|             Refresh.Refresh_Wait(Handle); | ||||
|         } | ||||
| 
 | ||||
|         protected virtual void Dispose(bool disposing) | ||||
|         { | ||||
|             if (!IsDisposed) | ||||
|             { | ||||
|                 if (disposing) | ||||
|                 { | ||||
|                     // TODO: dispose managed state (managed objects) | ||||
|                 } | ||||
| 
 | ||||
|                 Refresh.Refresh_DestroyDevice(Handle); | ||||
|                 IsDisposed = true; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources | ||||
|         ~GraphicsDevice() | ||||
|         { | ||||
|             // 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); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,104 @@ | |||
| using System; | ||||
| using System.Runtime.InteropServices; | ||||
| using RefreshCS; | ||||
| 
 | ||||
| namespace MoonWorks.Graphics | ||||
| { | ||||
|     public class GraphicsPipeline : GraphicsResource | ||||
|     { | ||||
|         protected override Action<IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroyGraphicsPipeline; | ||||
| 
 | ||||
|         public unsafe GraphicsPipeline( | ||||
|             GraphicsDevice device, | ||||
|             ColorBlendState colorBlendState, | ||||
|             DepthStencilState depthStencilState, | ||||
|             ShaderStageState vertexShaderState, | ||||
|             ShaderStageState fragmentShaderState, | ||||
|             MultisampleState multisampleState, | ||||
|             GraphicsPipelineLayoutCreateInfo pipelineLayoutCreateInfo, | ||||
|             RasterizerState rasterizerState, | ||||
|             Refresh.PrimitiveType primitiveType, | ||||
|             VertexInputState vertexInputState, | ||||
|             ViewportState viewportState, | ||||
|             RenderPass renderPass | ||||
|         ) : base(device) | ||||
|         { | ||||
|             var vertexAttributesHandle = GCHandle.Alloc(vertexInputState.VertexAttributes, GCHandleType.Pinned); | ||||
|             var vertexBindingsHandle = GCHandle.Alloc(vertexInputState.VertexBindings, GCHandleType.Pinned); | ||||
|             var viewportHandle = GCHandle.Alloc(viewportState.Viewports, GCHandleType.Pinned); | ||||
|             var scissorHandle = GCHandle.Alloc(viewportState.Scissors, GCHandleType.Pinned); | ||||
| 
 | ||||
|             var colorTargetBlendStates = stackalloc Refresh.ColorTargetBlendState[colorBlendState.ColorTargetBlendStates.Length]; | ||||
| 
 | ||||
|             for (var i = 0; i < colorBlendState.ColorTargetBlendStates.Length; i += 1) | ||||
|             { | ||||
|                 colorTargetBlendStates[i] = colorBlendState.ColorTargetBlendStates[i].ToRefreshColorTargetBlendState(); | ||||
|             } | ||||
| 
 | ||||
|             Refresh.GraphicsPipelineCreateInfo graphicsPipelineCreateInfo; | ||||
| 
 | ||||
|             graphicsPipelineCreateInfo.colorBlendState.logicOpEnable = Conversions.BoolToByte(colorBlendState.LogicOpEnable); | ||||
|             graphicsPipelineCreateInfo.colorBlendState.logicOp = colorBlendState.LogicOp; | ||||
|             graphicsPipelineCreateInfo.colorBlendState.blendStates = (IntPtr) colorTargetBlendStates; | ||||
|             graphicsPipelineCreateInfo.colorBlendState.blendStateCount = (uint) colorBlendState.ColorTargetBlendStates.Length; | ||||
|             graphicsPipelineCreateInfo.colorBlendState.blendConstants[0] = colorBlendState.BlendConstants.R; | ||||
|             graphicsPipelineCreateInfo.colorBlendState.blendConstants[1] = colorBlendState.BlendConstants.G; | ||||
|             graphicsPipelineCreateInfo.colorBlendState.blendConstants[2] = colorBlendState.BlendConstants.B; | ||||
|             graphicsPipelineCreateInfo.colorBlendState.blendConstants[3] = colorBlendState.BlendConstants.A; | ||||
| 
 | ||||
|             graphicsPipelineCreateInfo.depthStencilState.backStencilState = depthStencilState.BackStencilState; | ||||
|             graphicsPipelineCreateInfo.depthStencilState.compareOp = depthStencilState.CompareOp; | ||||
|             graphicsPipelineCreateInfo.depthStencilState.depthBoundsTestEnable = Conversions.BoolToByte(depthStencilState.DepthBoundsTestEnable); | ||||
|             graphicsPipelineCreateInfo.depthStencilState.depthTestEnable = Conversions.BoolToByte(depthStencilState.DepthTestEnable); | ||||
|             graphicsPipelineCreateInfo.depthStencilState.depthWriteEnable = Conversions.BoolToByte(depthStencilState.DepthWriteEnable); | ||||
|             graphicsPipelineCreateInfo.depthStencilState.frontStencilState = depthStencilState.FrontStencilState; | ||||
|             graphicsPipelineCreateInfo.depthStencilState.maxDepthBounds = depthStencilState.MaxDepthBounds; | ||||
|             graphicsPipelineCreateInfo.depthStencilState.minDepthBounds = depthStencilState.MinDepthBounds; | ||||
|             graphicsPipelineCreateInfo.depthStencilState.stencilTestEnable = Conversions.BoolToByte(depthStencilState.StencilTestEnable); | ||||
| 
 | ||||
|             graphicsPipelineCreateInfo.vertexShaderState.entryPointName = vertexShaderState.EntryPointName; | ||||
|             graphicsPipelineCreateInfo.vertexShaderState.shaderModule = vertexShaderState.ShaderModule.Handle; | ||||
|             graphicsPipelineCreateInfo.vertexShaderState.uniformBufferSize = vertexShaderState.UniformBufferSize; | ||||
| 
 | ||||
|             graphicsPipelineCreateInfo.fragmentShaderState.entryPointName = fragmentShaderState.EntryPointName; | ||||
|             graphicsPipelineCreateInfo.fragmentShaderState.shaderModule = fragmentShaderState.ShaderModule.Handle; | ||||
|             graphicsPipelineCreateInfo.fragmentShaderState.uniformBufferSize = fragmentShaderState.UniformBufferSize; | ||||
| 
 | ||||
|             graphicsPipelineCreateInfo.multisampleState.multisampleCount = multisampleState.MultisampleCount; | ||||
|             graphicsPipelineCreateInfo.multisampleState.sampleMask = multisampleState.SampleMask; | ||||
| 
 | ||||
|             graphicsPipelineCreateInfo.pipelineLayoutCreateInfo.vertexSamplerBindingCount = pipelineLayoutCreateInfo.VertexSamplerBindingCount; | ||||
|             graphicsPipelineCreateInfo.pipelineLayoutCreateInfo.fragmentSamplerBindingCount = pipelineLayoutCreateInfo.FragmentSamplerBindingCount; | ||||
| 
 | ||||
|             graphicsPipelineCreateInfo.rasterizerState.cullMode = rasterizerState.CullMode; | ||||
|             graphicsPipelineCreateInfo.rasterizerState.depthBiasClamp = rasterizerState.DepthBiasClamp; | ||||
|             graphicsPipelineCreateInfo.rasterizerState.depthBiasConstantFactor = rasterizerState.DepthBiasConstantFactor; | ||||
|             graphicsPipelineCreateInfo.rasterizerState.depthBiasEnable = Conversions.BoolToByte(rasterizerState.DepthBiasEnable); | ||||
|             graphicsPipelineCreateInfo.rasterizerState.depthBiasSlopeFactor = rasterizerState.DepthBiasSlopeFactor; | ||||
|             graphicsPipelineCreateInfo.rasterizerState.depthClampEnable = Conversions.BoolToByte(rasterizerState.DepthClampEnable); | ||||
|             graphicsPipelineCreateInfo.rasterizerState.fillMode = rasterizerState.FillMode; | ||||
|             graphicsPipelineCreateInfo.rasterizerState.frontFace = rasterizerState.FrontFace; | ||||
|             graphicsPipelineCreateInfo.rasterizerState.lineWidth = rasterizerState.LineWidth; | ||||
| 
 | ||||
|             graphicsPipelineCreateInfo.vertexInputState.vertexAttributes = vertexAttributesHandle.AddrOfPinnedObject(); | ||||
|             graphicsPipelineCreateInfo.vertexInputState.vertexAttributeCount = (uint) vertexInputState.VertexAttributes.Length; | ||||
|             graphicsPipelineCreateInfo.vertexInputState.vertexBindings = vertexBindingsHandle.AddrOfPinnedObject(); | ||||
|             graphicsPipelineCreateInfo.vertexInputState.vertexBindingCount = (uint) vertexInputState.VertexBindings.Length; | ||||
| 
 | ||||
|             graphicsPipelineCreateInfo.viewportState.viewports = viewportHandle.AddrOfPinnedObject(); | ||||
|             graphicsPipelineCreateInfo.viewportState.viewportCount = (uint) viewportState.Viewports.Length; | ||||
|             graphicsPipelineCreateInfo.viewportState.scissors = scissorHandle.AddrOfPinnedObject(); | ||||
|             graphicsPipelineCreateInfo.viewportState.scissorCount = (uint) viewportState.Scissors.Length; | ||||
| 
 | ||||
|             graphicsPipelineCreateInfo.primitiveType = primitiveType; | ||||
|             graphicsPipelineCreateInfo.renderPass = renderPass.Handle; | ||||
| 
 | ||||
|             Handle = Refresh.Refresh_CreateGraphicsPipeline(device.Handle, ref graphicsPipelineCreateInfo); | ||||
| 
 | ||||
|             vertexAttributesHandle.Free(); | ||||
|             vertexBindingsHandle.Free(); | ||||
|             viewportHandle.Free(); | ||||
|             scissorHandle.Free(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,42 @@ | |||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Text; | ||||
| 
 | ||||
| namespace MoonWorks.Graphics | ||||
| { | ||||
|     public abstract class GraphicsResource : IDisposable | ||||
|     { | ||||
|         public GraphicsDevice Device { get; } | ||||
|         public IntPtr Handle { get; protected set; } | ||||
| 
 | ||||
|         public bool IsDisposed { get; private set; } | ||||
|         protected abstract Action<IntPtr, IntPtr> QueueDestroyFunction { get; } | ||||
| 
 | ||||
|         public GraphicsResource(GraphicsDevice 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); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,45 @@ | |||
| using System; | ||||
| using RefreshCS; | ||||
| 
 | ||||
| namespace MoonWorks.Graphics | ||||
| { | ||||
|     public class RenderPass : GraphicsResource | ||||
|     { | ||||
|         protected override Action<IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroyRenderPass; | ||||
| 
 | ||||
|         public unsafe RenderPass( | ||||
|             GraphicsDevice 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( | ||||
|             GraphicsDevice 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); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,23 @@ | |||
| using System; | ||||
| using RefreshCS; | ||||
| 
 | ||||
| namespace MoonWorks.Graphics | ||||
| { | ||||
|     public class Sampler : GraphicsResource | ||||
|     { | ||||
|         protected override Action<IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroySampler; | ||||
| 
 | ||||
|         public Sampler( | ||||
|             GraphicsDevice device, | ||||
|             ref SamplerState samplerState | ||||
|         ) : base(device) | ||||
|         { | ||||
|             var refreshSamplerStateCreateInfo = samplerState.ToRefreshSamplerStateCreateInfo(); | ||||
| 
 | ||||
|             Handle = Refresh.Refresh_CreateSampler( | ||||
|                 device.Handle, | ||||
|                 ref refreshSamplerStateCreateInfo | ||||
|             ); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,23 @@ | |||
| using RefreshCS; | ||||
| using System; | ||||
| using System.IO; | ||||
| 
 | ||||
| namespace MoonWorks.Graphics | ||||
| { | ||||
|     public class ShaderModule : GraphicsResource | ||||
|     { | ||||
|         protected override Action<IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroyShaderModule; | ||||
| 
 | ||||
|         public unsafe ShaderModule(GraphicsDevice 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); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,12 @@ | |||
| using RefreshCS; | ||||
| 
 | ||||
| namespace MoonWorks.Graphics | ||||
| { | ||||
|     public unsafe struct ColorBlendState | ||||
|     { | ||||
|         public bool LogicOpEnable; | ||||
|         public Refresh.LogicOp LogicOp; | ||||
|         public BlendConstants BlendConstants; | ||||
|         public ColorTargetBlendState[] ColorTargetBlendStates; | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,85 @@ | |||
| using RefreshCS; | ||||
| 
 | ||||
| namespace MoonWorks.Graphics | ||||
| { | ||||
|     public struct ColorTargetBlendState | ||||
|     { | ||||
|         public bool BlendEnable; | ||||
|         public Refresh.BlendOp AlphaBlendOp; | ||||
|         public Refresh.BlendOp ColorBlendOp; | ||||
|         public Refresh.ColorComponentFlags ColorWriteMask; | ||||
|         public Refresh.BlendFactor DestinationAlphaBlendFactor; | ||||
|         public Refresh.BlendFactor DestinationColorBlendFactor; | ||||
|         public Refresh.BlendFactor SourceAlphaBlendFactor; | ||||
|         public Refresh.BlendFactor SourceColorBlendFactor; | ||||
| 
 | ||||
|         public static readonly ColorTargetBlendState Additive = new ColorTargetBlendState | ||||
|         { | ||||
|             BlendEnable = true, | ||||
|             AlphaBlendOp = Refresh.BlendOp.Add, | ||||
|             ColorBlendOp = Refresh.BlendOp.Add, | ||||
|             ColorWriteMask = Refresh.ColorComponentFlags.RGBA, | ||||
|             SourceColorBlendFactor = Refresh.BlendFactor.SourceAlpha, | ||||
|             SourceAlphaBlendFactor = Refresh.BlendFactor.SourceAlpha, | ||||
|             DestinationColorBlendFactor = Refresh.BlendFactor.One, | ||||
|             DestinationAlphaBlendFactor = Refresh.BlendFactor.One | ||||
|         }; | ||||
| 
 | ||||
|         public static readonly ColorTargetBlendState AlphaBlend = new ColorTargetBlendState | ||||
|         { | ||||
|             BlendEnable = true, | ||||
|             AlphaBlendOp = Refresh.BlendOp.Add, | ||||
|             ColorBlendOp = Refresh.BlendOp.Add, | ||||
|             ColorWriteMask = Refresh.ColorComponentFlags.RGBA, | ||||
|             SourceColorBlendFactor = Refresh.BlendFactor.One, | ||||
|             SourceAlphaBlendFactor = Refresh.BlendFactor.One, | ||||
|             DestinationColorBlendFactor = Refresh.BlendFactor.OneMinusSourceAlpha, | ||||
|             DestinationAlphaBlendFactor = Refresh.BlendFactor.OneMinusSourceAlpha | ||||
|         }; | ||||
| 
 | ||||
|         public static readonly ColorTargetBlendState NonPremultiplied = new ColorTargetBlendState | ||||
|         { | ||||
|             BlendEnable = true, | ||||
|             AlphaBlendOp = Refresh.BlendOp.Add, | ||||
|             ColorBlendOp = Refresh.BlendOp.Add, | ||||
|             ColorWriteMask = Refresh.ColorComponentFlags.RGBA, | ||||
|             SourceColorBlendFactor = Refresh.BlendFactor.SourceAlpha, | ||||
|             SourceAlphaBlendFactor = Refresh.BlendFactor.SourceAlpha, | ||||
|             DestinationColorBlendFactor = Refresh.BlendFactor.OneMinusSourceAlpha, | ||||
|             DestinationAlphaBlendFactor = Refresh.BlendFactor.OneMinusSourceAlpha | ||||
|         }; | ||||
| 
 | ||||
|         public static readonly ColorTargetBlendState Opaque = new ColorTargetBlendState | ||||
|         { | ||||
|             BlendEnable = true, | ||||
|             AlphaBlendOp = Refresh.BlendOp.Add, | ||||
|             ColorBlendOp = Refresh.BlendOp.Add, | ||||
|             ColorWriteMask = Refresh.ColorComponentFlags.RGBA, | ||||
|             SourceColorBlendFactor = Refresh.BlendFactor.One, | ||||
|             SourceAlphaBlendFactor = Refresh.BlendFactor.One, | ||||
|             DestinationColorBlendFactor = Refresh.BlendFactor.Zero, | ||||
|             DestinationAlphaBlendFactor = Refresh.BlendFactor.Zero | ||||
|         }; | ||||
| 
 | ||||
|         public static readonly ColorTargetBlendState None = new ColorTargetBlendState | ||||
|         { | ||||
|             BlendEnable = false, | ||||
|             ColorWriteMask = Refresh.ColorComponentFlags.RGBA | ||||
|         }; | ||||
| 
 | ||||
|         public Refresh.ColorTargetBlendState ToRefreshColorTargetBlendState() | ||||
|         { | ||||
|             return new Refresh.ColorTargetBlendState | ||||
|             { | ||||
|                 blendEnable = Conversions.BoolToByte(BlendEnable), | ||||
|                 alphaBlendOp = AlphaBlendOp, | ||||
|                 colorBlendOp = ColorBlendOp, | ||||
|                 colorWriteMask = ColorWriteMask, | ||||
|                 destinationAlphaBlendFactor = DestinationAlphaBlendFactor, | ||||
|                 destinationColorBlendFactor = DestinationColorBlendFactor, | ||||
|                 sourceAlphaBlendFactor = SourceAlphaBlendFactor, | ||||
|                 sourceColorBlendFactor = SourceColorBlendFactor | ||||
|             }; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,43 @@ | |||
| using RefreshCS; | ||||
| 
 | ||||
| namespace MoonWorks.Graphics | ||||
| { | ||||
|     public struct DepthStencilState | ||||
|     { | ||||
|         public bool DepthTestEnable; | ||||
|         public Refresh.StencilOpState BackStencilState; | ||||
|         public Refresh.StencilOpState FrontStencilState; | ||||
|         public Refresh.CompareOp CompareOp; | ||||
|         public bool DepthBoundsTestEnable; | ||||
|         public bool DepthWriteEnable; | ||||
|         public float MinDepthBounds; | ||||
|         public float MaxDepthBounds; | ||||
|         public bool StencilTestEnable; | ||||
| 
 | ||||
|         public static readonly DepthStencilState DepthReadWrite = new DepthStencilState | ||||
|         { | ||||
|             DepthTestEnable = true, | ||||
|             DepthWriteEnable = true, | ||||
|             DepthBoundsTestEnable = false, | ||||
|             StencilTestEnable = false, | ||||
|             CompareOp = Refresh.CompareOp.LessOrEqual | ||||
|         }; | ||||
| 
 | ||||
|         public static readonly DepthStencilState DepthRead = new DepthStencilState | ||||
|         { | ||||
|             DepthTestEnable = true, | ||||
|             DepthWriteEnable = false, | ||||
|             DepthBoundsTestEnable = false, | ||||
|             StencilTestEnable = false, | ||||
|             CompareOp = Refresh.CompareOp.LessOrEqual | ||||
|         }; | ||||
| 
 | ||||
|         public static readonly DepthStencilState Disable = new DepthStencilState | ||||
|         { | ||||
|             DepthTestEnable = false, | ||||
|             DepthWriteEnable = false, | ||||
|             DepthBoundsTestEnable = false, | ||||
|             StencilTestEnable = false | ||||
|         }; | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,8 @@ | |||
| namespace MoonWorks.Graphics | ||||
| { | ||||
|     public struct GraphicsPipelineLayoutCreateInfo | ||||
|     { | ||||
|         public uint VertexSamplerBindingCount; | ||||
|         public uint FragmentSamplerBindingCount; | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,16 @@ | |||
| using RefreshCS; | ||||
| 
 | ||||
| namespace MoonWorks.Graphics | ||||
| { | ||||
|     public struct MultisampleState | ||||
|     { | ||||
|         public Refresh.SampleCount MultisampleCount; | ||||
|         public uint SampleMask; | ||||
| 
 | ||||
|         public static readonly MultisampleState None = new MultisampleState | ||||
|         { | ||||
|             MultisampleCount = Refresh.SampleCount.One, | ||||
|             SampleMask = uint.MaxValue | ||||
|         }; | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,53 @@ | |||
| using RefreshCS; | ||||
| 
 | ||||
| namespace MoonWorks.Graphics | ||||
| { | ||||
|     public struct RasterizerState | ||||
|     { | ||||
|         public Refresh.CullMode CullMode; | ||||
|         public float DepthBiasClamp; | ||||
|         public float DepthBiasConstantFactor; | ||||
|         public bool DepthBiasEnable; | ||||
|         public float DepthBiasSlopeFactor; | ||||
|         public bool DepthClampEnable; | ||||
|         public Refresh.FillMode FillMode; | ||||
|         public Refresh.FrontFace FrontFace; | ||||
|         public float LineWidth; | ||||
| 
 | ||||
|         public static readonly RasterizerState CullClockwise = new RasterizerState | ||||
|         { | ||||
|             CullMode = Refresh.CullMode.Front, | ||||
|             FrontFace = Refresh.FrontFace.Clockwise, | ||||
|             FillMode = Refresh.FillMode.Fill, | ||||
|             DepthBiasEnable = false, | ||||
|             LineWidth = 1f | ||||
|         }; | ||||
| 
 | ||||
|         public static readonly RasterizerState CullCounterClockwise = new RasterizerState | ||||
|         { | ||||
|             CullMode = Refresh.CullMode.Back, | ||||
|             FrontFace = Refresh.FrontFace.Clockwise, | ||||
|             FillMode = Refresh.FillMode.Fill, | ||||
|             DepthBiasEnable = false, | ||||
|             LineWidth = 1f | ||||
|         }; | ||||
| 
 | ||||
|         public static readonly RasterizerState CullNone = new RasterizerState | ||||
|         { | ||||
|             CullMode = Refresh.CullMode.None, | ||||
|             FrontFace = Refresh.FrontFace.Clockwise, | ||||
|             FillMode = Refresh.FillMode.Fill, | ||||
|             DepthBiasEnable = false, | ||||
|             LineWidth = 1f | ||||
|         }; | ||||
| 
 | ||||
|         public static readonly RasterizerState Wireframe = new RasterizerState | ||||
|         { | ||||
|             CullMode = Refresh.CullMode.None, | ||||
|             FrontFace = Refresh.FrontFace.Clockwise, | ||||
|             FillMode = Refresh.FillMode.Fill, | ||||
|             DepthBiasEnable = false, | ||||
|             LineWidth = 1f | ||||
|         }; | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,135 @@ | |||
| using RefreshCS; | ||||
| 
 | ||||
| namespace MoonWorks.Graphics | ||||
| { | ||||
|     public struct SamplerState | ||||
|     { | ||||
|         public Refresh.Filter MinFilter; | ||||
|         public Refresh.Filter MagFilter; | ||||
|         public Refresh.SamplerMipmapMode MipmapMode; | ||||
|         public Refresh.SamplerAddressMode AddressModeU; | ||||
|         public Refresh.SamplerAddressMode AddressModeV; | ||||
|         public Refresh.SamplerAddressMode AddressModeW; | ||||
|         public float MipLodBias; | ||||
|         public bool AnisotropyEnable; | ||||
|         public float MaxAnisotropy; | ||||
|         public bool CompareEnable; | ||||
|         public Refresh.CompareOp CompareOp; | ||||
|         public float MinLod; | ||||
|         public float MaxLod; | ||||
|         public Refresh.BorderColor BorderColor; | ||||
| 
 | ||||
|         public static readonly SamplerState AnisotropicClamp = new SamplerState | ||||
|         { | ||||
|             MinFilter = Refresh.Filter.Linear, | ||||
|             MagFilter = Refresh.Filter.Linear, | ||||
|             MipmapMode = Refresh.SamplerMipmapMode.Linear, | ||||
|             AddressModeU = Refresh.SamplerAddressMode.ClampToEdge, | ||||
|             AddressModeV = Refresh.SamplerAddressMode.ClampToEdge, | ||||
|             AddressModeW = Refresh.SamplerAddressMode.ClampToEdge, | ||||
|             CompareEnable = false, | ||||
|             AnisotropyEnable = true, | ||||
|             MaxAnisotropy = 4, | ||||
|             MipLodBias = 0f, | ||||
|             MinLod = 0, | ||||
|             MaxLod = 1000 /* VK_LOD_CLAMP_NONE */ | ||||
|         }; | ||||
| 
 | ||||
|         public static readonly SamplerState AnisotropicWrap = new SamplerState | ||||
|         { | ||||
|             MinFilter = Refresh.Filter.Linear, | ||||
|             MagFilter = Refresh.Filter.Linear, | ||||
|             MipmapMode = Refresh.SamplerMipmapMode.Linear, | ||||
|             AddressModeU = Refresh.SamplerAddressMode.Repeat, | ||||
|             AddressModeV = Refresh.SamplerAddressMode.Repeat, | ||||
|             AddressModeW = Refresh.SamplerAddressMode.Repeat, | ||||
|             CompareEnable = false, | ||||
|             AnisotropyEnable = true, | ||||
|             MaxAnisotropy = 4, | ||||
|             MipLodBias = 0f, | ||||
|             MinLod = 0, | ||||
|             MaxLod = 1000 /* VK_LOD_CLAMP_NONE */ | ||||
|         }; | ||||
| 
 | ||||
|         public static readonly SamplerState LinearClamp = new SamplerState | ||||
|         { | ||||
|             MinFilter = Refresh.Filter.Linear, | ||||
|             MagFilter = Refresh.Filter.Linear, | ||||
|             MipmapMode = Refresh.SamplerMipmapMode.Linear, | ||||
|             AddressModeU = Refresh.SamplerAddressMode.ClampToEdge, | ||||
|             AddressModeV = Refresh.SamplerAddressMode.ClampToEdge, | ||||
|             AddressModeW = Refresh.SamplerAddressMode.ClampToEdge, | ||||
|             CompareEnable = false, | ||||
|             AnisotropyEnable = false, | ||||
|             MipLodBias = 0f, | ||||
|             MinLod = 0, | ||||
|             MaxLod = 1000 | ||||
|         }; | ||||
| 
 | ||||
|         public static readonly SamplerState LinearWrap = new SamplerState | ||||
|         { | ||||
|             MinFilter = Refresh.Filter.Linear, | ||||
|             MagFilter = Refresh.Filter.Linear, | ||||
|             MipmapMode = Refresh.SamplerMipmapMode.Linear, | ||||
|             AddressModeU = Refresh.SamplerAddressMode.Repeat, | ||||
|             AddressModeV = Refresh.SamplerAddressMode.Repeat, | ||||
|             AddressModeW = Refresh.SamplerAddressMode.Repeat, | ||||
|             CompareEnable = false, | ||||
|             AnisotropyEnable = false, | ||||
|             MipLodBias = 0f, | ||||
|             MinLod = 0, | ||||
|             MaxLod = 1000 | ||||
|         }; | ||||
| 
 | ||||
|         public static readonly SamplerState PointClamp = new SamplerState | ||||
|         { | ||||
|             MinFilter = Refresh.Filter.Nearest, | ||||
|             MagFilter = Refresh.Filter.Nearest, | ||||
|             MipmapMode = Refresh.SamplerMipmapMode.Nearest, | ||||
|             AddressModeU = Refresh.SamplerAddressMode.ClampToEdge, | ||||
|             AddressModeV = Refresh.SamplerAddressMode.ClampToEdge, | ||||
|             AddressModeW = Refresh.SamplerAddressMode.ClampToEdge, | ||||
|             CompareEnable = false, | ||||
|             AnisotropyEnable = false, | ||||
|             MipLodBias = 0f, | ||||
|             MinLod = 0, | ||||
|             MaxLod = 1000 | ||||
|         }; | ||||
| 
 | ||||
|         public static readonly SamplerState PointWrap = new SamplerState | ||||
|         { | ||||
|             MinFilter = Refresh.Filter.Nearest, | ||||
|             MagFilter = Refresh.Filter.Nearest, | ||||
|             MipmapMode = Refresh.SamplerMipmapMode.Nearest, | ||||
|             AddressModeU = Refresh.SamplerAddressMode.Repeat, | ||||
|             AddressModeV = Refresh.SamplerAddressMode.Repeat, | ||||
|             AddressModeW = Refresh.SamplerAddressMode.Repeat, | ||||
|             CompareEnable = false, | ||||
|             AnisotropyEnable = false, | ||||
|             MipLodBias = 0f, | ||||
|             MinLod = 0, | ||||
|             MaxLod = 1000 | ||||
|         }; | ||||
| 
 | ||||
|         public Refresh.SamplerStateCreateInfo ToRefreshSamplerStateCreateInfo() | ||||
|         { | ||||
|             return new Refresh.SamplerStateCreateInfo | ||||
|             { | ||||
|                 minFilter = MinFilter, | ||||
|                 magFilter = MagFilter, | ||||
|                 mipmapMode = MipmapMode, | ||||
|                 addressModeU = AddressModeU, | ||||
|                 addressModeV = AddressModeV, | ||||
|                 addressModeW = AddressModeW, | ||||
|                 mipLodBias = MipLodBias, | ||||
|                 anisotropyEnable = Conversions.BoolToByte(AnisotropyEnable), | ||||
|                 maxAnisotropy = MaxAnisotropy, | ||||
|                 compareEnable = Conversions.BoolToByte(CompareEnable), | ||||
|                 compareOp = CompareOp, | ||||
|                 minLod = MinLod, | ||||
|                 maxLod = MaxLod, | ||||
|                 borderColor = BorderColor | ||||
|             }; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,9 @@ | |||
| namespace MoonWorks.Graphics | ||||
| { | ||||
|     public struct ShaderStageState | ||||
|     { | ||||
|         public ShaderModule ShaderModule; | ||||
|         public string EntryPointName; | ||||
|         public uint UniformBufferSize; | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,31 @@ | |||
| using RefreshCS; | ||||
| 
 | ||||
| namespace MoonWorks.Graphics | ||||
| { | ||||
|     public struct TextureCreateInfo | ||||
|     { | ||||
|         public uint Width; | ||||
|         public uint Height; | ||||
|         public uint Depth; | ||||
|         public bool IsCube; | ||||
|         public Refresh.SampleCount SampleCount; | ||||
|         public uint LevelCount; | ||||
|         public Refresh.ColorFormat Format; | ||||
|         public Refresh.TextureUsageFlags UsageFlags; | ||||
| 
 | ||||
|         public Refresh.TextureCreateInfo ToRefreshTextureCreateInfo() | ||||
|         { | ||||
|             return new Refresh.TextureCreateInfo | ||||
|             { | ||||
|                 width = Width, | ||||
|                 height = Height, | ||||
|                 depth = Depth, | ||||
|                 isCube = Conversions.BoolToByte(IsCube), | ||||
|                 sampleCount = SampleCount, | ||||
|                 levelCount = LevelCount, | ||||
|                 format = Format, | ||||
|                 usageFlags = UsageFlags | ||||
|             }; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,10 @@ | |||
| using RefreshCS; | ||||
| 
 | ||||
| namespace MoonWorks.Graphics | ||||
| { | ||||
|     public struct VertexInputState | ||||
|     { | ||||
|         public Refresh.VertexBinding[] VertexBindings; | ||||
|         public Refresh.VertexAttribute[] VertexAttributes; | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,10 @@ | |||
| using RefreshCS; | ||||
| 
 | ||||
| namespace MoonWorks.Graphics | ||||
| { | ||||
|     public struct ViewportState | ||||
|     { | ||||
|         public Refresh.Viewport[] Viewports; | ||||
|         public Refresh.Rect[] Scissors; | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,171 @@ | |||
| using System; | ||||
| using System.IO; | ||||
| using RefreshCS; | ||||
| 
 | ||||
| namespace MoonWorks.Graphics | ||||
| { | ||||
|     public class Texture : GraphicsResource | ||||
|     { | ||||
|         public uint Width { get; } | ||||
|         public uint Height { get; } | ||||
|         public Refresh.ColorFormat Format { get; } | ||||
| 
 | ||||
|         protected override Action<IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroyTexture; | ||||
| 
 | ||||
|         public static Texture LoadPNG(GraphicsDevice device, FileInfo fileInfo) | ||||
|         { | ||||
|             var pixels = Refresh.Refresh_Image_Load( | ||||
|                 fileInfo.FullName, | ||||
|                 out var width, | ||||
|                 out var height, | ||||
|                 out var channels | ||||
|             ); | ||||
| 
 | ||||
|             MoonWorks.Graphics.TextureCreateInfo textureCreateInfo; | ||||
|             textureCreateInfo.Width = (uint)width; | ||||
|             textureCreateInfo.Height = (uint)height; | ||||
|             textureCreateInfo.Depth = 1; | ||||
|             textureCreateInfo.Format = Refresh.ColorFormat.R8G8B8A8; | ||||
|             textureCreateInfo.IsCube = false; | ||||
|             textureCreateInfo.LevelCount = 1; | ||||
|             textureCreateInfo.SampleCount = Refresh.SampleCount.One; | ||||
|             textureCreateInfo.UsageFlags = Refresh.TextureUsageFlags.SamplerBit; | ||||
| 
 | ||||
|             var texture = new Texture(device, ref textureCreateInfo); | ||||
| 
 | ||||
|             texture.SetData(pixels, (uint)(width * height * 4)); | ||||
| 
 | ||||
|             Refresh.Refresh_Image_Free(pixels); | ||||
|             return texture; | ||||
|         } | ||||
| 
 | ||||
|         public unsafe static void SavePNG(string path, int width, int height, byte[] pixels) | ||||
|         { | ||||
|             fixed (byte* ptr = &pixels[0]) | ||||
|             { | ||||
|                 Refresh.Refresh_Image_SavePNG(path, width, height, (IntPtr) ptr); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public static Texture CreateTexture2D( | ||||
|             GraphicsDevice device, | ||||
|             uint width, | ||||
|             uint height, | ||||
|             Refresh.ColorFormat format, | ||||
|             Refresh.TextureUsageFlags usageFlags, | ||||
|             Refresh.SampleCount sampleCount = Refresh.SampleCount.One, | ||||
|             uint levelCount = 1 | ||||
|         ) | ||||
|         { | ||||
|             var textureCreateInfo = new MoonWorks.Graphics.TextureCreateInfo | ||||
|             { | ||||
|                 Width = width, | ||||
|                 Height = height, | ||||
|                 Depth = 1, | ||||
|                 IsCube = false, | ||||
|                 SampleCount = sampleCount, | ||||
|                 LevelCount = levelCount, | ||||
|                 Format = format, | ||||
|                 UsageFlags = usageFlags | ||||
|             }; | ||||
| 
 | ||||
|             return new Texture(device, ref textureCreateInfo); | ||||
|         } | ||||
| 
 | ||||
|         public static Texture CreateTexture3D( | ||||
|             GraphicsDevice device, | ||||
|             uint width, | ||||
|             uint height, | ||||
|             uint depth, | ||||
|             Refresh.ColorFormat format, | ||||
|             Refresh.TextureUsageFlags usageFlags, | ||||
|             Refresh.SampleCount sampleCount = Refresh.SampleCount.One, | ||||
|             uint levelCount = 1 | ||||
|         ) | ||||
|         { | ||||
|             var textureCreateInfo = new MoonWorks.Graphics.TextureCreateInfo | ||||
|             { | ||||
|                 Width = width, | ||||
|                 Height = height, | ||||
|                 Depth = depth, | ||||
|                 IsCube = false, | ||||
|                 SampleCount = sampleCount, | ||||
|                 LevelCount = levelCount, | ||||
|                 Format = format, | ||||
|                 UsageFlags = usageFlags | ||||
|             }; | ||||
| 
 | ||||
|             return new Texture(device, ref textureCreateInfo); | ||||
|         } | ||||
| 
 | ||||
|         public static Texture CreateTextureCube( | ||||
|             GraphicsDevice device, | ||||
|             uint size, | ||||
|             Refresh.ColorFormat format, | ||||
|             Refresh.TextureUsageFlags usageFlags, | ||||
|             Refresh.SampleCount sampleCount = Refresh.SampleCount.One, | ||||
|             uint levelCount = 1 | ||||
|         ) | ||||
|         { | ||||
|             var textureCreateInfo = new MoonWorks.Graphics.TextureCreateInfo | ||||
|             { | ||||
|                 Width = size, | ||||
|                 Height = size, | ||||
|                 Depth = 1, | ||||
|                 IsCube = true, | ||||
|                 SampleCount = sampleCount, | ||||
|                 LevelCount = levelCount, | ||||
|                 Format = format, | ||||
|                 UsageFlags = usageFlags | ||||
|             }; | ||||
| 
 | ||||
|             return new Texture(device, ref textureCreateInfo); | ||||
|         } | ||||
| 
 | ||||
|         public Texture(GraphicsDevice device, ref MoonWorks.Graphics.TextureCreateInfo textureCreateInfo) : base(device) | ||||
|         { | ||||
|             var refreshTextureCreateInfo = textureCreateInfo.ToRefreshTextureCreateInfo(); | ||||
| 
 | ||||
|             Handle = Refresh.Refresh_CreateTexture( | ||||
|                 device.Handle, | ||||
|                 ref refreshTextureCreateInfo | ||||
|             ); | ||||
| 
 | ||||
|             Format = textureCreateInfo.Format; | ||||
|             Width = textureCreateInfo.Width; | ||||
|             Height = textureCreateInfo.Height; | ||||
|         } | ||||
| 
 | ||||
|         public void SetData(IntPtr data, uint dataLengthInBytes) | ||||
|         { | ||||
|             Refresh.TextureSlice textureSlice; | ||||
|             textureSlice.texture = Handle; | ||||
|             textureSlice.rectangle.x = 0; | ||||
|             textureSlice.rectangle.y = 0; | ||||
|             textureSlice.rectangle.w = (int)Width; | ||||
|             textureSlice.rectangle.h = (int)Height; | ||||
|             textureSlice.level = 0; | ||||
|             textureSlice.layer = 0; | ||||
|             textureSlice.depth = 0; | ||||
| 
 | ||||
|             Refresh.Refresh_SetTextureData( | ||||
|                 Device.Handle, | ||||
|                 ref textureSlice, | ||||
|                 data, | ||||
|                 dataLengthInBytes | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
|         public void SetData(ref TextureSlice textureSlice, IntPtr data, uint dataLengthInBytes) | ||||
|         { | ||||
|             var refreshTextureSlice = textureSlice.ToRefreshTextureSlice(); | ||||
| 
 | ||||
|             Refresh.Refresh_SetTextureData( | ||||
|                 Device.Handle, | ||||
|                 ref refreshTextureSlice, | ||||
|                 data, | ||||
|                 dataLengthInBytes | ||||
|             ); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,14 @@ | |||
| namespace MoonWorks.Graphics | ||||
| { | ||||
|     public struct TextureSamplerBinding | ||||
|     { | ||||
|         public Texture Texture; | ||||
|         public Sampler Sampler; | ||||
| 
 | ||||
|         public TextureSamplerBinding(Texture texture, Sampler sampler) | ||||
|         { | ||||
|             Texture = texture; | ||||
|             Sampler = sampler; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,51 @@ | |||
| using RefreshCS; | ||||
| 
 | ||||
| namespace MoonWorks.Graphics | ||||
| { | ||||
|     public struct TextureSlice | ||||
|     { | ||||
|         public Texture Texture { get; } | ||||
|         public Refresh.Rect Rectangle { get;  } | ||||
|         public uint Depth { get; } | ||||
|         public uint Layer { get; } | ||||
|         public uint Level { get; } | ||||
| 
 | ||||
|         public TextureSlice(Texture texture) | ||||
|         { | ||||
|             Texture = texture; | ||||
|             Rectangle = new Refresh.Rect | ||||
|             { | ||||
|                 x = 0, | ||||
|                 y = 0, | ||||
|                 w = (int) texture.Width, | ||||
|                 h = (int) texture.Height | ||||
|             }; | ||||
|             Depth = 0; | ||||
|             Layer = 0; | ||||
|             Level = 0; | ||||
|         } | ||||
| 
 | ||||
|         public TextureSlice(Texture texture, Refresh.Rect rectangle, uint depth = 0, uint layer = 0, uint level = 0) | ||||
|         { | ||||
|             Texture = texture; | ||||
|             Rectangle = rectangle; | ||||
|             Depth = depth; | ||||
|             Layer = layer; | ||||
|             Level = level; | ||||
|         } | ||||
| 
 | ||||
|         public RefreshCS.Refresh.TextureSlice ToRefreshTextureSlice() | ||||
|         { | ||||
|             RefreshCS.Refresh.TextureSlice textureSlice = new RefreshCS.Refresh.TextureSlice | ||||
|             { | ||||
|                 texture = Texture.Handle, | ||||
|                 rectangle = Rectangle, | ||||
|                 depth = Depth, | ||||
|                 layer = Layer, | ||||
|                 level = Level | ||||
|             }; | ||||
| 
 | ||||
|             return textureSlice; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -24,7 +24,7 @@ namespace MoonWorks | |||
|             ScreenMode = windowCreateInfo.ScreenMode; | ||||
| 
 | ||||
|             Handle = SDL.SDL_CreateWindow( | ||||
|                 "CampariTest", | ||||
|                 "MoonWorks.GraphicsTest", | ||||
|                 SDL.SDL_WINDOWPOS_UNDEFINED, | ||||
|                 SDL.SDL_WINDOWPOS_UNDEFINED, | ||||
|                 (int)windowCreateInfo.WindowWidth, | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue