forked from MoonsideGames/MoonWorks
replace Campari with MoonWorks.Graphics
parent
2b58edb257
commit
2cabaa6186
|
@ -1,9 +1,9 @@
|
||||||
[submodule "lib/SDL2-CS"]
|
[submodule "lib/SDL2-CS"]
|
||||||
path = lib/SDL2-CS
|
path = lib/SDL2-CS
|
||||||
url = https://github.com/flibitijibibo/SDL2-CS.git
|
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"]
|
[submodule "lib/FAudio"]
|
||||||
path = lib/FAudio
|
path = lib/FAudio
|
||||||
url = https://github.com/FNA-XNA/FAudio.git
|
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>
|
<ItemGroup>
|
||||||
<ProjectReference Include=".\lib\SDL2-CS\SDL2-CS.Core.csproj" />
|
<ProjectReference Include=".\lib\SDL2-CS\SDL2-CS.Core.csproj" />
|
||||||
<ProjectReference Include=".\lib\Campari\Campari.csproj" />
|
<ProjectReference Include=".\lib\RefreshCS\RefreshCS.csproj" />
|
||||||
<ProjectReference Include=".\lib\Campari\lib\RefreshCS\RefreshCS.csproj" />
|
|
||||||
<ProjectReference Include=".\lib\FAudio\csharp\FAudio-CS.Core.csproj" />
|
<ProjectReference Include=".\lib\FAudio\csharp\FAudio-CS.Core.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -10,12 +10,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MoonWorks", "MoonWorks.cspr
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SDL2-CS.Core", "lib\SDL2-CS\SDL2-CS.Core.csproj", "{0929F2D8-8FE4-4452-AD1E-50760A1A19A5}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SDL2-CS.Core", "lib\SDL2-CS\SDL2-CS.Core.csproj", "{0929F2D8-8FE4-4452-AD1E-50760A1A19A5}"
|
||||||
EndProject
|
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}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FAudio-CS.Core", "lib\FAudio\csharp\FAudio-CS.Core.csproj", "{608AA31D-F163-4096-B4EF-B9C7D21D52BB}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RefreshCS", "lib\RefreshCS\RefreshCS.csproj", "{AD7C94E4-0AFA-44CA-889C-110142369893}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|x64 = Debug|x64
|
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}.Debug|x64.Build.0 = Debug|x64
|
||||||
{0929F2D8-8FE4-4452-AD1E-50760A1A19A5}.Release|x64.ActiveCfg = Release|x64
|
{0929F2D8-8FE4-4452-AD1E-50760A1A19A5}.Release|x64.ActiveCfg = Release|x64
|
||||||
{0929F2D8-8FE4-4452-AD1E-50760A1A19A5}.Release|x64.Build.0 = 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.ActiveCfg = Debug|x64
|
||||||
{608AA31D-F163-4096-B4EF-B9C7D21D52BB}.Debug|x64.Build.0 = 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.ActiveCfg = Release|x64
|
||||||
{608AA31D-F163-4096-B4EF-B9C7D21D52BB}.Release|x64.Build.0 = 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
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit f01b9a3a9acff8672e0d7da253ee2402fcdaa281
|
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit ba183e8c0f9d21e4397d76941078b4969d4f6686
|
|
@ -1,5 +1,5 @@
|
||||||
using SDL2;
|
using SDL2;
|
||||||
using Campari;
|
using MoonWorks.Graphics;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using MoonWorks.Audio;
|
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;
|
ScreenMode = windowCreateInfo.ScreenMode;
|
||||||
|
|
||||||
Handle = SDL.SDL_CreateWindow(
|
Handle = SDL.SDL_CreateWindow(
|
||||||
"CampariTest",
|
"MoonWorks.GraphicsTest",
|
||||||
SDL.SDL_WINDOWPOS_UNDEFINED,
|
SDL.SDL_WINDOWPOS_UNDEFINED,
|
||||||
SDL.SDL_WINDOWPOS_UNDEFINED,
|
SDL.SDL_WINDOWPOS_UNDEFINED,
|
||||||
(int)windowCreateInfo.WindowWidth,
|
(int)windowCreateInfo.WindowWidth,
|
||||||
|
|
Loading…
Reference in New Issue