Formatting pass
parent
a0c57c7a59
commit
8973b3e658
|
@ -0,0 +1,14 @@
|
||||||
|
# EditorConfig is awesome: https://EditorConfig.org
|
||||||
|
|
||||||
|
# top-most EditorConfig file
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
indent_style = tab
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
[*.cs]
|
||||||
|
csharp_space_after_cast = true
|
||||||
|
charset = utf-8-bom
|
||||||
|
max_line_length = 100
|
|
@ -1,277 +1,277 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace MoonWorks.Audio
|
namespace MoonWorks.Audio
|
||||||
{
|
{
|
||||||
public class AudioDevice : IDisposable
|
public class AudioDevice : IDisposable
|
||||||
{
|
{
|
||||||
public IntPtr Handle { get; }
|
public IntPtr Handle { get; }
|
||||||
public byte[] Handle3D { get; }
|
public byte[] Handle3D { get; }
|
||||||
public IntPtr MasteringVoice { get; }
|
public IntPtr MasteringVoice { get; }
|
||||||
public FAudio.FAudioDeviceDetails DeviceDetails { get; }
|
public FAudio.FAudioDeviceDetails DeviceDetails { get; }
|
||||||
public IntPtr ReverbVoice { get; }
|
public IntPtr ReverbVoice { get; }
|
||||||
|
|
||||||
public float CurveDistanceScalar = 1f;
|
public float CurveDistanceScalar = 1f;
|
||||||
public float DopplerScale = 1f;
|
public float DopplerScale = 1f;
|
||||||
public float SpeedOfSound = 343.5f;
|
public float SpeedOfSound = 343.5f;
|
||||||
|
|
||||||
internal FAudio.FAudioVoiceSends ReverbSends;
|
internal FAudio.FAudioVoiceSends ReverbSends;
|
||||||
|
|
||||||
private readonly List<WeakReference<AudioResource>> resources = new List<WeakReference<AudioResource>>();
|
private readonly List<WeakReference<AudioResource>> resources = new List<WeakReference<AudioResource>>();
|
||||||
private readonly List<WeakReference<StreamingSound>> streamingSounds = new List<WeakReference<StreamingSound>>();
|
private readonly List<WeakReference<StreamingSound>> streamingSounds = new List<WeakReference<StreamingSound>>();
|
||||||
|
|
||||||
private bool IsDisposed;
|
private bool IsDisposed;
|
||||||
|
|
||||||
public unsafe AudioDevice()
|
public unsafe AudioDevice()
|
||||||
{
|
{
|
||||||
FAudio.FAudioCreate(out var handle, 0, 0);
|
FAudio.FAudioCreate(out var handle, 0, 0);
|
||||||
Handle = handle;
|
Handle = handle;
|
||||||
|
|
||||||
/* Find a suitable device */
|
/* Find a suitable device */
|
||||||
|
|
||||||
FAudio.FAudio_GetDeviceCount(Handle, out var devices);
|
FAudio.FAudio_GetDeviceCount(Handle, out var devices);
|
||||||
|
|
||||||
if (devices == 0)
|
if (devices == 0)
|
||||||
{
|
{
|
||||||
Logger.LogError("No audio devices found!");
|
Logger.LogError("No audio devices found!");
|
||||||
Handle = IntPtr.Zero;
|
Handle = IntPtr.Zero;
|
||||||
FAudio.FAudio_Release(Handle);
|
FAudio.FAudio_Release(Handle);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FAudio.FAudioDeviceDetails deviceDetails;
|
FAudio.FAudioDeviceDetails deviceDetails;
|
||||||
|
|
||||||
uint i = 0;
|
uint i = 0;
|
||||||
for (i = 0; i < devices; i++)
|
for (i = 0; i < devices; i++)
|
||||||
{
|
{
|
||||||
FAudio.FAudio_GetDeviceDetails(
|
FAudio.FAudio_GetDeviceDetails(
|
||||||
Handle,
|
Handle,
|
||||||
i,
|
i,
|
||||||
out deviceDetails
|
out deviceDetails
|
||||||
);
|
);
|
||||||
if ((deviceDetails.Role & FAudio.FAudioDeviceRole.FAudioDefaultGameDevice) == FAudio.FAudioDeviceRole.FAudioDefaultGameDevice)
|
if ((deviceDetails.Role & FAudio.FAudioDeviceRole.FAudioDefaultGameDevice) == FAudio.FAudioDeviceRole.FAudioDefaultGameDevice)
|
||||||
{
|
{
|
||||||
DeviceDetails = deviceDetails;
|
DeviceDetails = deviceDetails;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == devices)
|
if (i == devices)
|
||||||
{
|
{
|
||||||
i = 0; /* whatever we'll just use the first one I guess */
|
i = 0; /* whatever we'll just use the first one I guess */
|
||||||
FAudio.FAudio_GetDeviceDetails(
|
FAudio.FAudio_GetDeviceDetails(
|
||||||
Handle,
|
Handle,
|
||||||
i,
|
i,
|
||||||
out deviceDetails
|
out deviceDetails
|
||||||
);
|
);
|
||||||
DeviceDetails = deviceDetails;
|
DeviceDetails = deviceDetails;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Init Mastering Voice */
|
/* Init Mastering Voice */
|
||||||
IntPtr masteringVoice;
|
IntPtr masteringVoice;
|
||||||
|
|
||||||
if (FAudio.FAudio_CreateMasteringVoice(
|
if (FAudio.FAudio_CreateMasteringVoice(
|
||||||
Handle,
|
Handle,
|
||||||
out masteringVoice,
|
out masteringVoice,
|
||||||
FAudio.FAUDIO_DEFAULT_CHANNELS,
|
FAudio.FAUDIO_DEFAULT_CHANNELS,
|
||||||
FAudio.FAUDIO_DEFAULT_SAMPLERATE,
|
FAudio.FAUDIO_DEFAULT_SAMPLERATE,
|
||||||
0,
|
0,
|
||||||
i,
|
i,
|
||||||
IntPtr.Zero
|
IntPtr.Zero
|
||||||
) != 0)
|
) != 0)
|
||||||
{
|
{
|
||||||
Logger.LogError("No mastering voice found!");
|
Logger.LogError("No mastering voice found!");
|
||||||
Handle = IntPtr.Zero;
|
Handle = IntPtr.Zero;
|
||||||
FAudio.FAudio_Release(Handle);
|
FAudio.FAudio_Release(Handle);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
MasteringVoice = masteringVoice;
|
MasteringVoice = masteringVoice;
|
||||||
|
|
||||||
/* Init 3D Audio */
|
/* Init 3D Audio */
|
||||||
|
|
||||||
Handle3D = new byte[FAudio.F3DAUDIO_HANDLE_BYTESIZE];
|
Handle3D = new byte[FAudio.F3DAUDIO_HANDLE_BYTESIZE];
|
||||||
FAudio.F3DAudioInitialize(
|
FAudio.F3DAudioInitialize(
|
||||||
DeviceDetails.OutputFormat.dwChannelMask,
|
DeviceDetails.OutputFormat.dwChannelMask,
|
||||||
SpeedOfSound,
|
SpeedOfSound,
|
||||||
Handle3D
|
Handle3D
|
||||||
);
|
);
|
||||||
|
|
||||||
/* Init reverb */
|
/* Init reverb */
|
||||||
|
|
||||||
IntPtr reverbVoice;
|
IntPtr reverbVoice;
|
||||||
|
|
||||||
IntPtr reverb;
|
IntPtr reverb;
|
||||||
FAudio.FAudioCreateReverb(out reverb, 0);
|
FAudio.FAudioCreateReverb(out reverb, 0);
|
||||||
|
|
||||||
IntPtr chainPtr;
|
IntPtr chainPtr;
|
||||||
chainPtr = Marshal.AllocHGlobal(
|
chainPtr = Marshal.AllocHGlobal(
|
||||||
Marshal.SizeOf<FAudio.FAudioEffectChain>()
|
Marshal.SizeOf<FAudio.FAudioEffectChain>()
|
||||||
);
|
);
|
||||||
|
|
||||||
FAudio.FAudioEffectChain* reverbChain = (FAudio.FAudioEffectChain*) chainPtr;
|
FAudio.FAudioEffectChain* reverbChain = (FAudio.FAudioEffectChain*) chainPtr;
|
||||||
reverbChain->EffectCount = 1;
|
reverbChain->EffectCount = 1;
|
||||||
reverbChain->pEffectDescriptors = Marshal.AllocHGlobal(
|
reverbChain->pEffectDescriptors = Marshal.AllocHGlobal(
|
||||||
Marshal.SizeOf<FAudio.FAudioEffectDescriptor>()
|
Marshal.SizeOf<FAudio.FAudioEffectDescriptor>()
|
||||||
);
|
);
|
||||||
|
|
||||||
FAudio.FAudioEffectDescriptor* reverbDescriptor =
|
FAudio.FAudioEffectDescriptor* reverbDescriptor =
|
||||||
(FAudio.FAudioEffectDescriptor*) reverbChain->pEffectDescriptors;
|
(FAudio.FAudioEffectDescriptor*) reverbChain->pEffectDescriptors;
|
||||||
|
|
||||||
reverbDescriptor->InitialState = 1;
|
reverbDescriptor->InitialState = 1;
|
||||||
reverbDescriptor->OutputChannels = (uint) (
|
reverbDescriptor->OutputChannels = (uint) (
|
||||||
(DeviceDetails.OutputFormat.Format.nChannels == 6) ? 6 : 1
|
(DeviceDetails.OutputFormat.Format.nChannels == 6) ? 6 : 1
|
||||||
);
|
);
|
||||||
reverbDescriptor->pEffect = reverb;
|
reverbDescriptor->pEffect = reverb;
|
||||||
|
|
||||||
FAudio.FAudio_CreateSubmixVoice(
|
FAudio.FAudio_CreateSubmixVoice(
|
||||||
Handle,
|
Handle,
|
||||||
out reverbVoice,
|
out reverbVoice,
|
||||||
1, /* omnidirectional reverb */
|
1, /* omnidirectional reverb */
|
||||||
DeviceDetails.OutputFormat.Format.nSamplesPerSec,
|
DeviceDetails.OutputFormat.Format.nSamplesPerSec,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
IntPtr.Zero,
|
IntPtr.Zero,
|
||||||
chainPtr
|
chainPtr
|
||||||
);
|
);
|
||||||
FAudio.FAPOBase_Release(reverb);
|
FAudio.FAPOBase_Release(reverb);
|
||||||
|
|
||||||
Marshal.FreeHGlobal(reverbChain->pEffectDescriptors);
|
Marshal.FreeHGlobal(reverbChain->pEffectDescriptors);
|
||||||
Marshal.FreeHGlobal(chainPtr);
|
Marshal.FreeHGlobal(chainPtr);
|
||||||
|
|
||||||
ReverbVoice = reverbVoice;
|
ReverbVoice = reverbVoice;
|
||||||
|
|
||||||
/* Init reverb params */
|
/* Init reverb params */
|
||||||
// Defaults based on FAUDIOFX_I3DL2_PRESET_GENERIC
|
// Defaults based on FAUDIOFX_I3DL2_PRESET_GENERIC
|
||||||
|
|
||||||
IntPtr reverbParamsPtr = Marshal.AllocHGlobal(
|
IntPtr reverbParamsPtr = Marshal.AllocHGlobal(
|
||||||
Marshal.SizeOf<FAudio.FAudioFXReverbParameters>()
|
Marshal.SizeOf<FAudio.FAudioFXReverbParameters>()
|
||||||
);
|
);
|
||||||
|
|
||||||
FAudio.FAudioFXReverbParameters* reverbParams = (FAudio.FAudioFXReverbParameters*) reverbParamsPtr;
|
FAudio.FAudioFXReverbParameters* reverbParams = (FAudio.FAudioFXReverbParameters*) reverbParamsPtr;
|
||||||
reverbParams->WetDryMix = 100.0f;
|
reverbParams->WetDryMix = 100.0f;
|
||||||
reverbParams->ReflectionsDelay = 7;
|
reverbParams->ReflectionsDelay = 7;
|
||||||
reverbParams->ReverbDelay = 11;
|
reverbParams->ReverbDelay = 11;
|
||||||
reverbParams->RearDelay = FAudio.FAUDIOFX_REVERB_DEFAULT_REAR_DELAY;
|
reverbParams->RearDelay = FAudio.FAUDIOFX_REVERB_DEFAULT_REAR_DELAY;
|
||||||
reverbParams->PositionLeft = FAudio.FAUDIOFX_REVERB_DEFAULT_POSITION;
|
reverbParams->PositionLeft = FAudio.FAUDIOFX_REVERB_DEFAULT_POSITION;
|
||||||
reverbParams->PositionRight = FAudio.FAUDIOFX_REVERB_DEFAULT_POSITION;
|
reverbParams->PositionRight = FAudio.FAUDIOFX_REVERB_DEFAULT_POSITION;
|
||||||
reverbParams->PositionMatrixLeft = FAudio.FAUDIOFX_REVERB_DEFAULT_POSITION_MATRIX;
|
reverbParams->PositionMatrixLeft = FAudio.FAUDIOFX_REVERB_DEFAULT_POSITION_MATRIX;
|
||||||
reverbParams->PositionMatrixRight = FAudio.FAUDIOFX_REVERB_DEFAULT_POSITION_MATRIX;
|
reverbParams->PositionMatrixRight = FAudio.FAUDIOFX_REVERB_DEFAULT_POSITION_MATRIX;
|
||||||
reverbParams->EarlyDiffusion = 15;
|
reverbParams->EarlyDiffusion = 15;
|
||||||
reverbParams->LateDiffusion = 15;
|
reverbParams->LateDiffusion = 15;
|
||||||
reverbParams->LowEQGain = 8;
|
reverbParams->LowEQGain = 8;
|
||||||
reverbParams->LowEQCutoff = 4;
|
reverbParams->LowEQCutoff = 4;
|
||||||
reverbParams->HighEQGain = 8;
|
reverbParams->HighEQGain = 8;
|
||||||
reverbParams->HighEQCutoff = 6;
|
reverbParams->HighEQCutoff = 6;
|
||||||
reverbParams->RoomFilterFreq = 5000f;
|
reverbParams->RoomFilterFreq = 5000f;
|
||||||
reverbParams->RoomFilterMain = -10f;
|
reverbParams->RoomFilterMain = -10f;
|
||||||
reverbParams->RoomFilterHF = -1f;
|
reverbParams->RoomFilterHF = -1f;
|
||||||
reverbParams->ReflectionsGain = -26.0200005f;
|
reverbParams->ReflectionsGain = -26.0200005f;
|
||||||
reverbParams->ReverbGain = 10.0f;
|
reverbParams->ReverbGain = 10.0f;
|
||||||
reverbParams->DecayTime = 1.49000001f;
|
reverbParams->DecayTime = 1.49000001f;
|
||||||
reverbParams->Density = 100.0f;
|
reverbParams->Density = 100.0f;
|
||||||
reverbParams->RoomSize = FAudio.FAUDIOFX_REVERB_DEFAULT_ROOM_SIZE;
|
reverbParams->RoomSize = FAudio.FAUDIOFX_REVERB_DEFAULT_ROOM_SIZE;
|
||||||
FAudio.FAudioVoice_SetEffectParameters(
|
FAudio.FAudioVoice_SetEffectParameters(
|
||||||
ReverbVoice,
|
ReverbVoice,
|
||||||
0,
|
0,
|
||||||
reverbParamsPtr,
|
reverbParamsPtr,
|
||||||
(uint) Marshal.SizeOf<FAudio.FAudioFXReverbParameters>(),
|
(uint) Marshal.SizeOf<FAudio.FAudioFXReverbParameters>(),
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
Marshal.FreeHGlobal(reverbParamsPtr);
|
Marshal.FreeHGlobal(reverbParamsPtr);
|
||||||
|
|
||||||
/* Init reverb sends */
|
/* Init reverb sends */
|
||||||
|
|
||||||
ReverbSends = new FAudio.FAudioVoiceSends
|
ReverbSends = new FAudio.FAudioVoiceSends
|
||||||
{
|
{
|
||||||
SendCount = 2,
|
SendCount = 2,
|
||||||
pSends = Marshal.AllocHGlobal(
|
pSends = Marshal.AllocHGlobal(
|
||||||
2 * Marshal.SizeOf<FAudio.FAudioSendDescriptor>()
|
2 * Marshal.SizeOf<FAudio.FAudioSendDescriptor>()
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
FAudio.FAudioSendDescriptor* sendDesc = (FAudio.FAudioSendDescriptor*) ReverbSends.pSends;
|
FAudio.FAudioSendDescriptor* sendDesc = (FAudio.FAudioSendDescriptor*) ReverbSends.pSends;
|
||||||
sendDesc[0].Flags = 0;
|
sendDesc[0].Flags = 0;
|
||||||
sendDesc[0].pOutputVoice = MasteringVoice;
|
sendDesc[0].pOutputVoice = MasteringVoice;
|
||||||
sendDesc[1].Flags = 0;
|
sendDesc[1].Flags = 0;
|
||||||
sendDesc[1].pOutputVoice = ReverbVoice;
|
sendDesc[1].pOutputVoice = ReverbVoice;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update()
|
public void Update()
|
||||||
{
|
{
|
||||||
for (var i = streamingSounds.Count - 1; i >= 0; i--)
|
for (var i = streamingSounds.Count - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
var weakReference = streamingSounds[i];
|
var weakReference = streamingSounds[i];
|
||||||
if (weakReference.TryGetTarget(out var streamingSound))
|
if (weakReference.TryGetTarget(out var streamingSound))
|
||||||
{
|
{
|
||||||
streamingSound.Update();
|
streamingSound.Update();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
streamingSounds.RemoveAt(i);
|
streamingSounds.RemoveAt(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void AddDynamicSoundInstance(StreamingSound instance)
|
internal void AddDynamicSoundInstance(StreamingSound instance)
|
||||||
{
|
{
|
||||||
streamingSounds.Add(new WeakReference<StreamingSound>(instance));
|
streamingSounds.Add(new WeakReference<StreamingSound>(instance));
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void AddResourceReference(WeakReference<AudioResource> resourceReference)
|
internal void AddResourceReference(WeakReference<AudioResource> resourceReference)
|
||||||
{
|
{
|
||||||
lock (resources)
|
lock (resources)
|
||||||
{
|
{
|
||||||
resources.Add(resourceReference);
|
resources.Add(resourceReference);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void RemoveResourceReference(WeakReference<AudioResource> resourceReference)
|
internal void RemoveResourceReference(WeakReference<AudioResource> resourceReference)
|
||||||
{
|
{
|
||||||
lock (resources)
|
lock (resources)
|
||||||
{
|
{
|
||||||
resources.Remove(resourceReference);
|
resources.Remove(resourceReference);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void Dispose(bool disposing)
|
protected virtual void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
if (!IsDisposed)
|
if (!IsDisposed)
|
||||||
{
|
{
|
||||||
if (disposing)
|
if (disposing)
|
||||||
{
|
{
|
||||||
for (var i = streamingSounds.Count - 1; i >= 0; i--)
|
for (var i = streamingSounds.Count - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
var weakReference = streamingSounds[i];
|
var weakReference = streamingSounds[i];
|
||||||
|
|
||||||
if (weakReference.TryGetTarget(out var streamingSound))
|
if (weakReference.TryGetTarget(out var streamingSound))
|
||||||
{
|
{
|
||||||
streamingSound.Dispose();
|
streamingSound.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
streamingSounds.Clear();
|
streamingSounds.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
FAudio.FAudioVoice_DestroyVoice(ReverbVoice);
|
FAudio.FAudioVoice_DestroyVoice(ReverbVoice);
|
||||||
FAudio.FAudioVoice_DestroyVoice(MasteringVoice);
|
FAudio.FAudioVoice_DestroyVoice(MasteringVoice);
|
||||||
FAudio.FAudio_Release(Handle);
|
FAudio.FAudio_Release(Handle);
|
||||||
|
|
||||||
IsDisposed = true;
|
IsDisposed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources
|
// TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources
|
||||||
~AudioDevice()
|
~AudioDevice()
|
||||||
{
|
{
|
||||||
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
||||||
Dispose(disposing: false);
|
Dispose(disposing: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
||||||
Dispose(disposing: true);
|
Dispose(disposing: true);
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using MoonWorks.Math;
|
using MoonWorks.Math;
|
||||||
|
|
||||||
namespace MoonWorks.Audio
|
namespace MoonWorks.Audio
|
||||||
{
|
{
|
||||||
public class AudioEmitter : AudioResource
|
public class AudioEmitter : AudioResource
|
||||||
{
|
{
|
||||||
internal FAudio.F3DAUDIO_EMITTER emitterData;
|
internal FAudio.F3DAUDIO_EMITTER emitterData;
|
||||||
|
|
||||||
public float DopplerScale
|
public float DopplerScale
|
||||||
{
|
{
|
||||||
|
@ -107,17 +107,17 @@ namespace MoonWorks.Audio
|
||||||
GCHandleType.Pinned
|
GCHandleType.Pinned
|
||||||
);
|
);
|
||||||
|
|
||||||
public AudioEmitter(AudioDevice device) : base(device)
|
public AudioEmitter(AudioDevice device) : base(device)
|
||||||
{
|
{
|
||||||
emitterData = new FAudio.F3DAUDIO_EMITTER();
|
emitterData = new FAudio.F3DAUDIO_EMITTER();
|
||||||
|
|
||||||
DopplerScale = 1f;
|
DopplerScale = 1f;
|
||||||
Forward = Vector3.Forward;
|
Forward = Vector3.Forward;
|
||||||
Position = Vector3.Zero;
|
Position = Vector3.Zero;
|
||||||
Up = Vector3.Up;
|
Up = Vector3.Up;
|
||||||
Velocity = Vector3.Zero;
|
Velocity = Vector3.Zero;
|
||||||
|
|
||||||
/* Unexposed variables, defaults based on XNA behavior */
|
/* Unexposed variables, defaults based on XNA behavior */
|
||||||
emitterData.pCone = IntPtr.Zero;
|
emitterData.pCone = IntPtr.Zero;
|
||||||
emitterData.ChannelCount = 1;
|
emitterData.ChannelCount = 1;
|
||||||
emitterData.ChannelRadius = 1.0f;
|
emitterData.ChannelRadius = 1.0f;
|
||||||
|
@ -128,8 +128,8 @@ namespace MoonWorks.Audio
|
||||||
emitterData.pLPFReverbCurve = IntPtr.Zero;
|
emitterData.pLPFReverbCurve = IntPtr.Zero;
|
||||||
emitterData.pReverbCurve = IntPtr.Zero;
|
emitterData.pReverbCurve = IntPtr.Zero;
|
||||||
emitterData.CurveDistanceScaler = 1.0f;
|
emitterData.CurveDistanceScaler = 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Destroy() { }
|
protected override void Destroy() { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
using System;
|
using System;
|
||||||
using MoonWorks.Math;
|
using MoonWorks.Math;
|
||||||
|
|
||||||
namespace MoonWorks.Audio
|
namespace MoonWorks.Audio
|
||||||
{
|
{
|
||||||
public class AudioListener : AudioResource
|
public class AudioListener : AudioResource
|
||||||
{
|
{
|
||||||
internal FAudio.F3DAUDIO_LISTENER listenerData;
|
internal FAudio.F3DAUDIO_LISTENER listenerData;
|
||||||
|
|
||||||
public Vector3 Forward
|
public Vector3 Forward
|
||||||
{
|
{
|
||||||
|
@ -80,18 +80,18 @@ namespace MoonWorks.Audio
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public AudioListener(AudioDevice device) : base(device)
|
public AudioListener(AudioDevice device) : base(device)
|
||||||
{
|
{
|
||||||
listenerData = new FAudio.F3DAUDIO_LISTENER();
|
listenerData = new FAudio.F3DAUDIO_LISTENER();
|
||||||
Forward = Vector3.Forward;
|
Forward = Vector3.Forward;
|
||||||
Position = Vector3.Zero;
|
Position = Vector3.Zero;
|
||||||
Up = Vector3.Up;
|
Up = Vector3.Up;
|
||||||
Velocity = Vector3.Zero;
|
Velocity = Vector3.Zero;
|
||||||
|
|
||||||
/* Unexposed variables, defaults based on XNA behavior */
|
/* Unexposed variables, defaults based on XNA behavior */
|
||||||
listenerData.pCone = IntPtr.Zero;
|
listenerData.pCone = IntPtr.Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Destroy() { }
|
protected override void Destroy() { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,52 +1,52 @@
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace MoonWorks.Audio
|
namespace MoonWorks.Audio
|
||||||
{
|
{
|
||||||
public abstract class AudioResource : IDisposable
|
public abstract class AudioResource : IDisposable
|
||||||
{
|
{
|
||||||
public AudioDevice Device { get; }
|
public AudioDevice Device { get; }
|
||||||
|
|
||||||
public bool IsDisposed { get; private set; }
|
public bool IsDisposed { get; private set; }
|
||||||
|
|
||||||
private WeakReference<AudioResource> selfReference;
|
private WeakReference<AudioResource> selfReference;
|
||||||
|
|
||||||
public AudioResource(AudioDevice device)
|
public AudioResource(AudioDevice device)
|
||||||
{
|
{
|
||||||
Device = device;
|
Device = device;
|
||||||
|
|
||||||
selfReference = new WeakReference<AudioResource>(this);
|
selfReference = new WeakReference<AudioResource>(this);
|
||||||
Device.AddResourceReference(selfReference);
|
Device.AddResourceReference(selfReference);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void Destroy();
|
protected abstract void Destroy();
|
||||||
|
|
||||||
protected virtual void Dispose(bool disposing)
|
protected virtual void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
if (!IsDisposed)
|
if (!IsDisposed)
|
||||||
{
|
{
|
||||||
Destroy();
|
Destroy();
|
||||||
|
|
||||||
if (selfReference != null)
|
if (selfReference != null)
|
||||||
{
|
{
|
||||||
Device.RemoveResourceReference(selfReference);
|
Device.RemoveResourceReference(selfReference);
|
||||||
selfReference = null;
|
selfReference = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
IsDisposed = true;
|
IsDisposed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~AudioResource()
|
~AudioResource()
|
||||||
{
|
{
|
||||||
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
||||||
Dispose(disposing: false);
|
Dispose(disposing: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
||||||
Dispose(disposing: true);
|
Dispose(disposing: true);
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,271 +1,271 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using MoonWorks.Math;
|
using MoonWorks.Math;
|
||||||
|
|
||||||
namespace MoonWorks.Audio
|
namespace MoonWorks.Audio
|
||||||
{
|
{
|
||||||
public abstract class SoundInstance : AudioResource
|
public abstract class SoundInstance : AudioResource
|
||||||
{
|
{
|
||||||
internal IntPtr Handle { get; }
|
internal IntPtr Handle { get; }
|
||||||
internal FAudio.FAudioWaveFormatEx Format { get; }
|
internal FAudio.FAudioWaveFormatEx Format { get; }
|
||||||
public bool Loop { get; }
|
public bool Loop { get; }
|
||||||
|
|
||||||
protected FAudio.F3DAUDIO_DSP_SETTINGS dspSettings;
|
protected FAudio.F3DAUDIO_DSP_SETTINGS dspSettings;
|
||||||
|
|
||||||
protected bool is3D;
|
protected bool is3D;
|
||||||
|
|
||||||
public abstract SoundState State { get; protected set; }
|
public abstract SoundState State { get; protected set; }
|
||||||
|
|
||||||
private float _pan = 0;
|
private float _pan = 0;
|
||||||
public float Pan
|
public float Pan
|
||||||
{
|
{
|
||||||
get => _pan;
|
get => _pan;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_pan = value;
|
_pan = value;
|
||||||
|
|
||||||
if (_pan < -1f)
|
if (_pan < -1f)
|
||||||
{
|
{
|
||||||
_pan = -1f;
|
_pan = -1f;
|
||||||
}
|
}
|
||||||
if (_pan > 1f)
|
if (_pan > 1f)
|
||||||
{
|
{
|
||||||
_pan = 1f;
|
_pan = 1f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is3D) { return; }
|
if (is3D) { return; }
|
||||||
|
|
||||||
SetPanMatrixCoefficients();
|
SetPanMatrixCoefficients();
|
||||||
FAudio.FAudioVoice_SetOutputMatrix(
|
FAudio.FAudioVoice_SetOutputMatrix(
|
||||||
Handle,
|
Handle,
|
||||||
Device.MasteringVoice,
|
Device.MasteringVoice,
|
||||||
dspSettings.SrcChannelCount,
|
dspSettings.SrcChannelCount,
|
||||||
dspSettings.DstChannelCount,
|
dspSettings.DstChannelCount,
|
||||||
dspSettings.pMatrixCoefficients,
|
dspSettings.pMatrixCoefficients,
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private float _pitch = 1;
|
private float _pitch = 1;
|
||||||
public float Pitch
|
public float Pitch
|
||||||
{
|
{
|
||||||
get => _pitch;
|
get => _pitch;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_pitch = MathHelper.Clamp(value, -1f, 1f);
|
_pitch = MathHelper.Clamp(value, -1f, 1f);
|
||||||
UpdatePitch();
|
UpdatePitch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private float _volume = 1;
|
private float _volume = 1;
|
||||||
public float Volume
|
public float Volume
|
||||||
{
|
{
|
||||||
get => _volume;
|
get => _volume;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_volume = value;
|
_volume = value;
|
||||||
FAudio.FAudioVoice_SetVolume(Handle, _volume, 0);
|
FAudio.FAudioVoice_SetVolume(Handle, _volume, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private float _reverb;
|
private float _reverb;
|
||||||
public unsafe float Reverb
|
public unsafe float Reverb
|
||||||
{
|
{
|
||||||
get => _reverb;
|
get => _reverb;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_reverb = value;
|
_reverb = value;
|
||||||
|
|
||||||
float* outputMatrix = (float*) dspSettings.pMatrixCoefficients;
|
float* outputMatrix = (float*) dspSettings.pMatrixCoefficients;
|
||||||
outputMatrix[0] = _reverb;
|
outputMatrix[0] = _reverb;
|
||||||
if (dspSettings.SrcChannelCount == 2)
|
if (dspSettings.SrcChannelCount == 2)
|
||||||
{
|
{
|
||||||
outputMatrix[1] = _reverb;
|
outputMatrix[1] = _reverb;
|
||||||
}
|
}
|
||||||
|
|
||||||
FAudio.FAudioVoice_SetOutputMatrix(
|
FAudio.FAudioVoice_SetOutputMatrix(
|
||||||
Handle,
|
Handle,
|
||||||
Device.ReverbVoice,
|
Device.ReverbVoice,
|
||||||
dspSettings.SrcChannelCount,
|
dspSettings.SrcChannelCount,
|
||||||
1,
|
1,
|
||||||
dspSettings.pMatrixCoefficients,
|
dspSettings.pMatrixCoefficients,
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private float _lowPassFilter;
|
private float _lowPassFilter;
|
||||||
public float LowPassFilter
|
public float LowPassFilter
|
||||||
{
|
{
|
||||||
get => _lowPassFilter;
|
get => _lowPassFilter;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_lowPassFilter = value;
|
_lowPassFilter = value;
|
||||||
|
|
||||||
FAudio.FAudioFilterParameters p = new FAudio.FAudioFilterParameters
|
FAudio.FAudioFilterParameters p = new FAudio.FAudioFilterParameters
|
||||||
{
|
{
|
||||||
Type = FAudio.FAudioFilterType.FAudioLowPassFilter,
|
Type = FAudio.FAudioFilterType.FAudioLowPassFilter,
|
||||||
Frequency = _lowPassFilter,
|
Frequency = _lowPassFilter,
|
||||||
OneOverQ = 1f
|
OneOverQ = 1f
|
||||||
};
|
};
|
||||||
FAudio.FAudioVoice_SetFilterParameters(
|
FAudio.FAudioVoice_SetFilterParameters(
|
||||||
Handle,
|
Handle,
|
||||||
ref p,
|
ref p,
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private float _highPassFilter;
|
private float _highPassFilter;
|
||||||
public float HighPassFilter
|
public float HighPassFilter
|
||||||
{
|
{
|
||||||
get => _highPassFilter;
|
get => _highPassFilter;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_highPassFilter = value;
|
_highPassFilter = value;
|
||||||
|
|
||||||
FAudio.FAudioFilterParameters p = new FAudio.FAudioFilterParameters
|
FAudio.FAudioFilterParameters p = new FAudio.FAudioFilterParameters
|
||||||
{
|
{
|
||||||
Type = FAudio.FAudioFilterType.FAudioHighPassFilter,
|
Type = FAudio.FAudioFilterType.FAudioHighPassFilter,
|
||||||
Frequency = _highPassFilter,
|
Frequency = _highPassFilter,
|
||||||
OneOverQ = 1f
|
OneOverQ = 1f
|
||||||
};
|
};
|
||||||
FAudio.FAudioVoice_SetFilterParameters(
|
FAudio.FAudioVoice_SetFilterParameters(
|
||||||
Handle,
|
Handle,
|
||||||
ref p,
|
ref p,
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private float _bandPassFilter;
|
private float _bandPassFilter;
|
||||||
public float BandPassFilter
|
public float BandPassFilter
|
||||||
{
|
{
|
||||||
get => _bandPassFilter;
|
get => _bandPassFilter;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_bandPassFilter = value;
|
_bandPassFilter = value;
|
||||||
|
|
||||||
FAudio.FAudioFilterParameters p = new FAudio.FAudioFilterParameters
|
FAudio.FAudioFilterParameters p = new FAudio.FAudioFilterParameters
|
||||||
{
|
{
|
||||||
Type = FAudio.FAudioFilterType.FAudioBandPassFilter,
|
Type = FAudio.FAudioFilterType.FAudioBandPassFilter,
|
||||||
Frequency = _bandPassFilter,
|
Frequency = _bandPassFilter,
|
||||||
OneOverQ = 1f
|
OneOverQ = 1f
|
||||||
};
|
};
|
||||||
FAudio.FAudioVoice_SetFilterParameters(
|
FAudio.FAudioVoice_SetFilterParameters(
|
||||||
Handle,
|
Handle,
|
||||||
ref p,
|
ref p,
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public SoundInstance(
|
public SoundInstance(
|
||||||
AudioDevice device,
|
AudioDevice device,
|
||||||
ushort channels,
|
ushort channels,
|
||||||
uint samplesPerSecond,
|
uint samplesPerSecond,
|
||||||
bool is3D,
|
bool is3D,
|
||||||
bool loop
|
bool loop
|
||||||
) : base(device)
|
) : base(device)
|
||||||
{
|
{
|
||||||
var blockAlign = (ushort)(4 * channels);
|
var blockAlign = (ushort) (4 * channels);
|
||||||
var format = new FAudio.FAudioWaveFormatEx
|
var format = new FAudio.FAudioWaveFormatEx
|
||||||
{
|
{
|
||||||
wFormatTag = 3,
|
wFormatTag = 3,
|
||||||
wBitsPerSample = 32,
|
wBitsPerSample = 32,
|
||||||
nChannels = channels,
|
nChannels = channels,
|
||||||
nBlockAlign = blockAlign,
|
nBlockAlign = blockAlign,
|
||||||
nSamplesPerSec = samplesPerSecond,
|
nSamplesPerSec = samplesPerSecond,
|
||||||
nAvgBytesPerSec = blockAlign * samplesPerSecond
|
nAvgBytesPerSec = blockAlign * samplesPerSecond
|
||||||
};
|
};
|
||||||
|
|
||||||
Format = format;
|
Format = format;
|
||||||
|
|
||||||
FAudio.FAudio_CreateSourceVoice(
|
FAudio.FAudio_CreateSourceVoice(
|
||||||
Device.Handle,
|
Device.Handle,
|
||||||
out var handle,
|
out var handle,
|
||||||
ref format,
|
ref format,
|
||||||
FAudio.FAUDIO_VOICE_USEFILTER,
|
FAudio.FAUDIO_VOICE_USEFILTER,
|
||||||
FAudio.FAUDIO_DEFAULT_FREQ_RATIO,
|
FAudio.FAUDIO_DEFAULT_FREQ_RATIO,
|
||||||
IntPtr.Zero,
|
IntPtr.Zero,
|
||||||
IntPtr.Zero,
|
IntPtr.Zero,
|
||||||
IntPtr.Zero
|
IntPtr.Zero
|
||||||
);
|
);
|
||||||
|
|
||||||
if (handle == IntPtr.Zero)
|
if (handle == IntPtr.Zero)
|
||||||
{
|
{
|
||||||
Logger.LogError("SoundInstance failed to initialize!");
|
Logger.LogError("SoundInstance failed to initialize!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle = handle;
|
Handle = handle;
|
||||||
this.is3D = is3D;
|
this.is3D = is3D;
|
||||||
InitDSPSettings(Format.nChannels);
|
InitDSPSettings(Format.nChannels);
|
||||||
|
|
||||||
FAudio.FAudioVoice_SetOutputVoices(
|
FAudio.FAudioVoice_SetOutputVoices(
|
||||||
handle,
|
handle,
|
||||||
ref Device.ReverbSends
|
ref Device.ReverbSends
|
||||||
);
|
);
|
||||||
|
|
||||||
Loop = loop;
|
Loop = loop;
|
||||||
State = SoundState.Stopped;
|
State = SoundState.Stopped;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Apply3D(AudioListener listener, AudioEmitter emitter)
|
public void Apply3D(AudioListener listener, AudioEmitter emitter)
|
||||||
{
|
{
|
||||||
is3D = true;
|
is3D = true;
|
||||||
|
|
||||||
emitter.emitterData.CurveDistanceScaler = Device.CurveDistanceScalar;
|
emitter.emitterData.CurveDistanceScaler = Device.CurveDistanceScalar;
|
||||||
emitter.emitterData.ChannelCount = dspSettings.SrcChannelCount;
|
emitter.emitterData.ChannelCount = dspSettings.SrcChannelCount;
|
||||||
|
|
||||||
FAudio.F3DAudioCalculate(
|
FAudio.F3DAudioCalculate(
|
||||||
Device.Handle3D,
|
Device.Handle3D,
|
||||||
ref listener.listenerData,
|
ref listener.listenerData,
|
||||||
ref emitter.emitterData,
|
ref emitter.emitterData,
|
||||||
FAudio.F3DAUDIO_CALCULATE_MATRIX | FAudio.F3DAUDIO_CALCULATE_DOPPLER,
|
FAudio.F3DAUDIO_CALCULATE_MATRIX | FAudio.F3DAUDIO_CALCULATE_DOPPLER,
|
||||||
ref dspSettings
|
ref dspSettings
|
||||||
);
|
);
|
||||||
|
|
||||||
UpdatePitch();
|
UpdatePitch();
|
||||||
FAudio.FAudioVoice_SetOutputMatrix(
|
FAudio.FAudioVoice_SetOutputMatrix(
|
||||||
Handle,
|
Handle,
|
||||||
Device.MasteringVoice,
|
Device.MasteringVoice,
|
||||||
dspSettings.SrcChannelCount,
|
dspSettings.SrcChannelCount,
|
||||||
dspSettings.DstChannelCount,
|
dspSettings.DstChannelCount,
|
||||||
dspSettings.pMatrixCoefficients,
|
dspSettings.pMatrixCoefficients,
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void Play();
|
public abstract void Play();
|
||||||
public abstract void Pause();
|
public abstract void Pause();
|
||||||
public abstract void Stop(bool immediate);
|
public abstract void Stop(bool immediate);
|
||||||
|
|
||||||
private void InitDSPSettings(uint srcChannels)
|
private void InitDSPSettings(uint srcChannels)
|
||||||
{
|
{
|
||||||
dspSettings = new FAudio.F3DAUDIO_DSP_SETTINGS();
|
dspSettings = new FAudio.F3DAUDIO_DSP_SETTINGS();
|
||||||
dspSettings.DopplerFactor = 1f;
|
dspSettings.DopplerFactor = 1f;
|
||||||
dspSettings.SrcChannelCount = srcChannels;
|
dspSettings.SrcChannelCount = srcChannels;
|
||||||
dspSettings.DstChannelCount = Device.DeviceDetails.OutputFormat.Format.nChannels;
|
dspSettings.DstChannelCount = Device.DeviceDetails.OutputFormat.Format.nChannels;
|
||||||
|
|
||||||
int memsize = (
|
int memsize = (
|
||||||
4 *
|
4 *
|
||||||
(int) dspSettings.SrcChannelCount *
|
(int) dspSettings.SrcChannelCount *
|
||||||
(int) dspSettings.DstChannelCount
|
(int) dspSettings.DstChannelCount
|
||||||
);
|
);
|
||||||
|
|
||||||
dspSettings.pMatrixCoefficients = Marshal.AllocHGlobal(memsize);
|
dspSettings.pMatrixCoefficients = Marshal.AllocHGlobal(memsize);
|
||||||
unsafe
|
unsafe
|
||||||
{
|
{
|
||||||
byte* memPtr = (byte*) dspSettings.pMatrixCoefficients;
|
byte* memPtr = (byte*) dspSettings.pMatrixCoefficients;
|
||||||
for (int i = 0; i < memsize; i += 1)
|
for (int i = 0; i < memsize; i += 1)
|
||||||
{
|
{
|
||||||
memPtr[i] = 0;
|
memPtr[i] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SetPanMatrixCoefficients();
|
SetPanMatrixCoefficients();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdatePitch()
|
private void UpdatePitch()
|
||||||
{
|
{
|
||||||
|
@ -287,10 +287,10 @@ namespace MoonWorks.Audio
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Taken from https://github.com/FNA-XNA/FNA/blob/master/src/Audio/SoundEffectInstance.cs
|
// Taken from https://github.com/FNA-XNA/FNA/blob/master/src/Audio/SoundEffectInstance.cs
|
||||||
private unsafe void SetPanMatrixCoefficients()
|
private unsafe void SetPanMatrixCoefficients()
|
||||||
{
|
{
|
||||||
/* Two major things to notice:
|
/* Two major things to notice:
|
||||||
* 1. The spec assumes any speaker count >= 2 has Front Left/Right.
|
* 1. The spec assumes any speaker count >= 2 has Front Left/Right.
|
||||||
* 2. Stereo panning is WAY more complicated than you think.
|
* 2. Stereo panning is WAY more complicated than you think.
|
||||||
* The main thing is that hard panning does NOT eliminate an
|
* The main thing is that hard panning does NOT eliminate an
|
||||||
|
@ -307,7 +307,7 @@ namespace MoonWorks.Audio
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
outputMatrix[0] = (_pan > 0.0f) ? (1.0f - _pan) : 1.0f;
|
outputMatrix[0] = (_pan > 0.0f) ? (1.0f - _pan) : 1.0f;
|
||||||
outputMatrix[1] = (_pan < 0.0f) ? (1.0f + _pan) : 1.0f;
|
outputMatrix[1] = (_pan < 0.0f) ? (1.0f + _pan) : 1.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -339,14 +339,14 @@ namespace MoonWorks.Audio
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Destroy()
|
protected override void Destroy()
|
||||||
{
|
{
|
||||||
Stop(true);
|
Stop(true);
|
||||||
|
|
||||||
FAudio.FAudioVoice_DestroyVoice(Handle);
|
FAudio.FAudioVoice_DestroyVoice(Handle);
|
||||||
Marshal.FreeHGlobal(dspSettings.pMatrixCoefficients);
|
Marshal.FreeHGlobal(dspSettings.pMatrixCoefficients);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
namespace MoonWorks.Audio
|
namespace MoonWorks.Audio
|
||||||
{
|
{
|
||||||
public enum SoundState
|
public enum SoundState
|
||||||
{
|
{
|
||||||
Playing,
|
Playing,
|
||||||
Paused,
|
Paused,
|
||||||
Stopped
|
Stopped
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,82 +1,82 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace MoonWorks.Audio
|
namespace MoonWorks.Audio
|
||||||
{
|
{
|
||||||
public class StaticSound : AudioResource
|
public class StaticSound : AudioResource
|
||||||
{
|
{
|
||||||
internal FAudio.FAudioBuffer Handle;
|
internal FAudio.FAudioBuffer Handle;
|
||||||
public ushort Channels { get; }
|
public ushort Channels { get; }
|
||||||
public uint SamplesPerSecond { get; }
|
public uint SamplesPerSecond { get; }
|
||||||
|
|
||||||
public uint LoopStart { get; set; } = 0;
|
public uint LoopStart { get; set; } = 0;
|
||||||
public uint LoopLength { get; set; } = 0;
|
public uint LoopLength { get; set; } = 0;
|
||||||
|
|
||||||
public static StaticSound LoadOgg(AudioDevice device, string filePath)
|
public static StaticSound LoadOgg(AudioDevice device, string filePath)
|
||||||
{
|
{
|
||||||
var filePointer = FAudio.stb_vorbis_open_filename(filePath, out var error, IntPtr.Zero);
|
var filePointer = FAudio.stb_vorbis_open_filename(filePath, out var error, IntPtr.Zero);
|
||||||
|
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
{
|
{
|
||||||
throw new AudioLoadException("Error loading file!");
|
throw new AudioLoadException("Error loading file!");
|
||||||
}
|
}
|
||||||
var info = FAudio.stb_vorbis_get_info(filePointer);
|
var info = FAudio.stb_vorbis_get_info(filePointer);
|
||||||
var bufferSize = FAudio.stb_vorbis_stream_length_in_samples(filePointer) * info.channels;
|
var bufferSize = FAudio.stb_vorbis_stream_length_in_samples(filePointer) * info.channels;
|
||||||
var buffer = new float[bufferSize];
|
var buffer = new float[bufferSize];
|
||||||
|
|
||||||
FAudio.stb_vorbis_get_samples_float_interleaved(
|
FAudio.stb_vorbis_get_samples_float_interleaved(
|
||||||
filePointer,
|
filePointer,
|
||||||
info.channels,
|
info.channels,
|
||||||
buffer,
|
buffer,
|
||||||
(int) bufferSize
|
(int) bufferSize
|
||||||
);
|
);
|
||||||
|
|
||||||
FAudio.stb_vorbis_close(filePointer);
|
FAudio.stb_vorbis_close(filePointer);
|
||||||
|
|
||||||
return new StaticSound(
|
return new StaticSound(
|
||||||
device,
|
device,
|
||||||
(ushort) info.channels,
|
(ushort) info.channels,
|
||||||
info.sample_rate,
|
info.sample_rate,
|
||||||
buffer,
|
buffer,
|
||||||
0,
|
0,
|
||||||
(uint) buffer.Length
|
(uint) buffer.Length
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public StaticSound(
|
public StaticSound(
|
||||||
AudioDevice device,
|
AudioDevice device,
|
||||||
ushort channels,
|
ushort channels,
|
||||||
uint samplesPerSecond,
|
uint samplesPerSecond,
|
||||||
float[] buffer,
|
float[] buffer,
|
||||||
uint bufferOffset, /* in floats */
|
uint bufferOffset, /* in floats */
|
||||||
uint bufferLength /* in floats */
|
uint bufferLength /* in floats */
|
||||||
) : base(device)
|
) : base(device)
|
||||||
{
|
{
|
||||||
Channels = channels;
|
Channels = channels;
|
||||||
SamplesPerSecond = samplesPerSecond;
|
SamplesPerSecond = samplesPerSecond;
|
||||||
|
|
||||||
var bufferLengthInBytes = (int) (bufferLength * sizeof(float));
|
var bufferLengthInBytes = (int) (bufferLength * sizeof(float));
|
||||||
Handle = new FAudio.FAudioBuffer();
|
Handle = new FAudio.FAudioBuffer();
|
||||||
Handle.Flags = FAudio.FAUDIO_END_OF_STREAM;
|
Handle.Flags = FAudio.FAUDIO_END_OF_STREAM;
|
||||||
Handle.pContext = IntPtr.Zero;
|
Handle.pContext = IntPtr.Zero;
|
||||||
Handle.AudioBytes = (uint) bufferLengthInBytes;
|
Handle.AudioBytes = (uint) bufferLengthInBytes;
|
||||||
Handle.pAudioData = Marshal.AllocHGlobal(bufferLengthInBytes);
|
Handle.pAudioData = Marshal.AllocHGlobal(bufferLengthInBytes);
|
||||||
Marshal.Copy(buffer, (int) bufferOffset, Handle.pAudioData, (int) bufferLength);
|
Marshal.Copy(buffer, (int) bufferOffset, Handle.pAudioData, (int) bufferLength);
|
||||||
Handle.PlayBegin = 0;
|
Handle.PlayBegin = 0;
|
||||||
Handle.PlayLength = 0;
|
Handle.PlayLength = 0;
|
||||||
|
|
||||||
LoopStart = 0;
|
LoopStart = 0;
|
||||||
LoopLength = 0;
|
LoopLength = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public StaticSoundInstance CreateInstance(bool loop = false)
|
public StaticSoundInstance CreateInstance(bool loop = false)
|
||||||
{
|
{
|
||||||
return new StaticSoundInstance(Device, this, false, loop);
|
return new StaticSoundInstance(Device, this, false, loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Destroy()
|
protected override void Destroy()
|
||||||
{
|
{
|
||||||
Marshal.FreeHGlobal(Handle.pAudioData);
|
Marshal.FreeHGlobal(Handle.pAudioData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,96 +1,96 @@
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace MoonWorks.Audio
|
namespace MoonWorks.Audio
|
||||||
{
|
{
|
||||||
public class StaticSoundInstance : SoundInstance
|
public class StaticSoundInstance : SoundInstance
|
||||||
{
|
{
|
||||||
public StaticSound Parent { get; }
|
public StaticSound Parent { get; }
|
||||||
|
|
||||||
private SoundState _state = SoundState.Stopped;
|
private SoundState _state = SoundState.Stopped;
|
||||||
public override SoundState State
|
public override SoundState State
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
FAudio.FAudioSourceVoice_GetState(
|
FAudio.FAudioSourceVoice_GetState(
|
||||||
Handle,
|
Handle,
|
||||||
out var state,
|
out var state,
|
||||||
FAudio.FAUDIO_VOICE_NOSAMPLESPLAYED
|
FAudio.FAUDIO_VOICE_NOSAMPLESPLAYED
|
||||||
);
|
);
|
||||||
if (state.BuffersQueued == 0)
|
if (state.BuffersQueued == 0)
|
||||||
{
|
{
|
||||||
Stop(true);
|
Stop(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return _state;
|
return _state;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected set
|
protected set
|
||||||
{
|
{
|
||||||
_state = value;
|
_state = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal StaticSoundInstance(
|
internal StaticSoundInstance(
|
||||||
AudioDevice device,
|
AudioDevice device,
|
||||||
StaticSound parent,
|
StaticSound parent,
|
||||||
bool is3D,
|
bool is3D,
|
||||||
bool loop
|
bool loop
|
||||||
) : base(device, parent.Channels, parent.SamplesPerSecond, is3D, loop)
|
) : base(device, parent.Channels, parent.SamplesPerSecond, is3D, loop)
|
||||||
{
|
{
|
||||||
Parent = parent;
|
Parent = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Play()
|
public override void Play()
|
||||||
{
|
{
|
||||||
if (State == SoundState.Playing)
|
if (State == SoundState.Playing)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Loop)
|
if (Loop)
|
||||||
{
|
{
|
||||||
Parent.Handle.LoopCount = 255;
|
Parent.Handle.LoopCount = 255;
|
||||||
Parent.Handle.LoopBegin = Parent.LoopStart;
|
Parent.Handle.LoopBegin = Parent.LoopStart;
|
||||||
Parent.Handle.LoopLength = Parent.LoopLength;
|
Parent.Handle.LoopLength = Parent.LoopLength;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Parent.Handle.LoopCount = 0;
|
Parent.Handle.LoopCount = 0;
|
||||||
Parent.Handle.LoopBegin = 0;
|
Parent.Handle.LoopBegin = 0;
|
||||||
Parent.Handle.LoopLength = 0;
|
Parent.Handle.LoopLength = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
FAudio.FAudioSourceVoice_SubmitSourceBuffer(
|
FAudio.FAudioSourceVoice_SubmitSourceBuffer(
|
||||||
Handle,
|
Handle,
|
||||||
ref Parent.Handle,
|
ref Parent.Handle,
|
||||||
IntPtr.Zero
|
IntPtr.Zero
|
||||||
);
|
);
|
||||||
|
|
||||||
FAudio.FAudioSourceVoice_Start(Handle, 0, 0);
|
FAudio.FAudioSourceVoice_Start(Handle, 0, 0);
|
||||||
State = SoundState.Playing;
|
State = SoundState.Playing;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Pause()
|
public override void Pause()
|
||||||
{
|
{
|
||||||
if (State == SoundState.Paused)
|
if (State == SoundState.Paused)
|
||||||
{
|
{
|
||||||
FAudio.FAudioSourceVoice_Stop(Handle, 0, 0);
|
FAudio.FAudioSourceVoice_Stop(Handle, 0, 0);
|
||||||
State = SoundState.Paused;
|
State = SoundState.Paused;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Stop(bool immediate = true)
|
public override void Stop(bool immediate = true)
|
||||||
{
|
{
|
||||||
if (immediate)
|
if (immediate)
|
||||||
{
|
{
|
||||||
FAudio.FAudioSourceVoice_Stop(Handle, 0, 0);
|
FAudio.FAudioSourceVoice_Stop(Handle, 0, 0);
|
||||||
FAudio.FAudioSourceVoice_FlushSourceBuffers(Handle);
|
FAudio.FAudioSourceVoice_FlushSourceBuffers(Handle);
|
||||||
State = SoundState.Stopped;
|
State = SoundState.Stopped;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FAudio.FAudioSourceVoice_ExitLoop(Handle, 0);
|
FAudio.FAudioSourceVoice_ExitLoop(Handle, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,178 +1,178 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace MoonWorks.Audio
|
namespace MoonWorks.Audio
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// For streaming long playback.
|
/// For streaming long playback.
|
||||||
/// Can be extended to support custom decoders.
|
/// Can be extended to support custom decoders.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class StreamingSound : SoundInstance
|
public abstract class StreamingSound : SoundInstance
|
||||||
{
|
{
|
||||||
private readonly List<IntPtr> queuedBuffers = new List<IntPtr>();
|
private readonly List<IntPtr> queuedBuffers = new List<IntPtr>();
|
||||||
private readonly List<uint> queuedSizes = new List<uint>();
|
private readonly List<uint> queuedSizes = new List<uint>();
|
||||||
private const int MINIMUM_BUFFER_CHECK = 3;
|
private const int MINIMUM_BUFFER_CHECK = 3;
|
||||||
|
|
||||||
public int PendingBufferCount => queuedBuffers.Count;
|
public int PendingBufferCount => queuedBuffers.Count;
|
||||||
|
|
||||||
public StreamingSound(
|
public StreamingSound(
|
||||||
AudioDevice device,
|
AudioDevice device,
|
||||||
ushort channels,
|
ushort channels,
|
||||||
uint samplesPerSecond,
|
uint samplesPerSecond,
|
||||||
bool is3D,
|
bool is3D,
|
||||||
bool loop
|
bool loop
|
||||||
) : base(device, channels, samplesPerSecond, is3D, loop) { }
|
) : base(device, channels, samplesPerSecond, is3D, loop) { }
|
||||||
|
|
||||||
public override void Play()
|
public override void Play()
|
||||||
{
|
{
|
||||||
if (State == SoundState.Playing)
|
if (State == SoundState.Playing)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
State = SoundState.Playing;
|
State = SoundState.Playing;
|
||||||
Update();
|
Update();
|
||||||
FAudio.FAudioSourceVoice_Start(Handle, 0, 0);
|
FAudio.FAudioSourceVoice_Start(Handle, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Pause()
|
public override void Pause()
|
||||||
{
|
{
|
||||||
if (State == SoundState.Playing)
|
if (State == SoundState.Playing)
|
||||||
{
|
{
|
||||||
FAudio.FAudioSourceVoice_Stop(Handle, 0, 0);
|
FAudio.FAudioSourceVoice_Stop(Handle, 0, 0);
|
||||||
State = SoundState.Paused;
|
State = SoundState.Paused;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Stop(bool immediate = true)
|
public override void Stop(bool immediate = true)
|
||||||
{
|
{
|
||||||
if (immediate)
|
if (immediate)
|
||||||
{
|
{
|
||||||
FAudio.FAudioSourceVoice_Stop(Handle, 0, 0);
|
FAudio.FAudioSourceVoice_Stop(Handle, 0, 0);
|
||||||
FAudio.FAudioSourceVoice_FlushSourceBuffers(Handle);
|
FAudio.FAudioSourceVoice_FlushSourceBuffers(Handle);
|
||||||
ClearBuffers();
|
ClearBuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
State = SoundState.Stopped;
|
State = SoundState.Stopped;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Update()
|
internal void Update()
|
||||||
{
|
{
|
||||||
if (State != SoundState.Playing)
|
if (State != SoundState.Playing)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FAudio.FAudioSourceVoice_GetState(
|
FAudio.FAudioSourceVoice_GetState(
|
||||||
Handle,
|
Handle,
|
||||||
out var state,
|
out var state,
|
||||||
FAudio.FAUDIO_VOICE_NOSAMPLESPLAYED
|
FAudio.FAUDIO_VOICE_NOSAMPLESPLAYED
|
||||||
);
|
);
|
||||||
|
|
||||||
while (PendingBufferCount > state.BuffersQueued)
|
while (PendingBufferCount > state.BuffersQueued)
|
||||||
lock (queuedBuffers)
|
lock (queuedBuffers)
|
||||||
{
|
{
|
||||||
Marshal.FreeHGlobal(queuedBuffers[0]);
|
Marshal.FreeHGlobal(queuedBuffers[0]);
|
||||||
queuedBuffers.RemoveAt(0);
|
queuedBuffers.RemoveAt(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
QueueBuffers();
|
QueueBuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void QueueBuffers()
|
protected void QueueBuffers()
|
||||||
{
|
{
|
||||||
for (
|
for (
|
||||||
int i = MINIMUM_BUFFER_CHECK - PendingBufferCount;
|
int i = MINIMUM_BUFFER_CHECK - PendingBufferCount;
|
||||||
i > 0;
|
i > 0;
|
||||||
i -= 1
|
i -= 1
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
AddBuffer();
|
AddBuffer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void ClearBuffers()
|
protected void ClearBuffers()
|
||||||
{
|
{
|
||||||
lock (queuedBuffers)
|
lock (queuedBuffers)
|
||||||
{
|
{
|
||||||
foreach (IntPtr buf in queuedBuffers)
|
foreach (IntPtr buf in queuedBuffers)
|
||||||
{
|
{
|
||||||
Marshal.FreeHGlobal(buf);
|
Marshal.FreeHGlobal(buf);
|
||||||
}
|
}
|
||||||
queuedBuffers.Clear();
|
queuedBuffers.Clear();
|
||||||
queuedSizes.Clear();
|
queuedSizes.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void AddBuffer()
|
protected void AddBuffer()
|
||||||
{
|
{
|
||||||
AddBuffer(
|
AddBuffer(
|
||||||
out var buffer,
|
out var buffer,
|
||||||
out var bufferOffset,
|
out var bufferOffset,
|
||||||
out var bufferLength,
|
out var bufferLength,
|
||||||
out var reachedEnd
|
out var reachedEnd
|
||||||
);
|
);
|
||||||
|
|
||||||
var lengthInBytes = bufferLength * sizeof(float);
|
var lengthInBytes = bufferLength * sizeof(float);
|
||||||
|
|
||||||
IntPtr next = Marshal.AllocHGlobal((int) lengthInBytes);
|
IntPtr next = Marshal.AllocHGlobal((int) lengthInBytes);
|
||||||
Marshal.Copy(buffer, (int) bufferOffset, next, (int) bufferLength);
|
Marshal.Copy(buffer, (int) bufferOffset, next, (int) bufferLength);
|
||||||
|
|
||||||
lock (queuedBuffers)
|
lock (queuedBuffers)
|
||||||
{
|
{
|
||||||
queuedBuffers.Add(next);
|
queuedBuffers.Add(next);
|
||||||
if (State != SoundState.Stopped)
|
if (State != SoundState.Stopped)
|
||||||
{
|
{
|
||||||
FAudio.FAudioBuffer buf = new FAudio.FAudioBuffer
|
FAudio.FAudioBuffer buf = new FAudio.FAudioBuffer
|
||||||
{
|
{
|
||||||
AudioBytes = lengthInBytes,
|
AudioBytes = lengthInBytes,
|
||||||
pAudioData = next,
|
pAudioData = next,
|
||||||
PlayLength = (
|
PlayLength = (
|
||||||
lengthInBytes /
|
lengthInBytes /
|
||||||
Format.nChannels /
|
Format.nChannels /
|
||||||
(uint)(Format.wBitsPerSample / 8)
|
(uint) (Format.wBitsPerSample / 8)
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
FAudio.FAudioSourceVoice_SubmitSourceBuffer(
|
FAudio.FAudioSourceVoice_SubmitSourceBuffer(
|
||||||
Handle,
|
Handle,
|
||||||
ref buf,
|
ref buf,
|
||||||
IntPtr.Zero
|
IntPtr.Zero
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
queuedSizes.Add(lengthInBytes);
|
queuedSizes.Add(lengthInBytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We have reached the end of the file, what do we do? */
|
/* We have reached the end of the file, what do we do? */
|
||||||
if (reachedEnd)
|
if (reachedEnd)
|
||||||
{
|
{
|
||||||
if (Loop)
|
if (Loop)
|
||||||
{
|
{
|
||||||
SeekStart();
|
SeekStart();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Stop(false);
|
Stop(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void AddBuffer(
|
protected abstract void AddBuffer(
|
||||||
out float[] buffer,
|
out float[] buffer,
|
||||||
out uint bufferOffset, /* in floats */
|
out uint bufferOffset, /* in floats */
|
||||||
out uint bufferLength, /* in floats */
|
out uint bufferLength, /* in floats */
|
||||||
out bool reachedEnd
|
out bool reachedEnd
|
||||||
);
|
);
|
||||||
|
|
||||||
protected abstract void SeekStart();
|
protected abstract void SeekStart();
|
||||||
|
|
||||||
protected override void Destroy()
|
protected override void Destroy()
|
||||||
{
|
{
|
||||||
Stop(true);
|
Stop(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,89 +1,91 @@
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace MoonWorks.Audio
|
namespace MoonWorks.Audio
|
||||||
{
|
{
|
||||||
public class StreamingSoundOgg : StreamingSound
|
public class StreamingSoundOgg : StreamingSound
|
||||||
{
|
{
|
||||||
// FIXME: what should this value be?
|
// FIXME: what should this value be?
|
||||||
public const int BUFFER_SIZE = 1024 * 128;
|
public const int BUFFER_SIZE = 1024 * 128;
|
||||||
|
|
||||||
internal IntPtr FileHandle { get; }
|
internal IntPtr FileHandle { get; }
|
||||||
internal FAudio.stb_vorbis_info Info { get; }
|
internal FAudio.stb_vorbis_info Info { get; }
|
||||||
|
|
||||||
private readonly float[] buffer;
|
private readonly float[] buffer;
|
||||||
|
|
||||||
public override SoundState State { get; protected set; }
|
public override SoundState State { get; protected set; }
|
||||||
|
|
||||||
public static StreamingSoundOgg Load(
|
public static StreamingSoundOgg Load(
|
||||||
AudioDevice device,
|
AudioDevice device,
|
||||||
string filePath,
|
string filePath,
|
||||||
bool is3D = false,
|
bool is3D = false,
|
||||||
bool loop = false
|
bool loop = false
|
||||||
) {
|
)
|
||||||
var fileHandle = FAudio.stb_vorbis_open_filename(filePath, out var error, IntPtr.Zero);
|
{
|
||||||
if (error != 0)
|
var fileHandle = FAudio.stb_vorbis_open_filename(filePath, out var error, IntPtr.Zero);
|
||||||
{
|
if (error != 0)
|
||||||
Logger.LogError("Error opening OGG file!");
|
{
|
||||||
throw new AudioLoadException("Error opening OGG file!");
|
Logger.LogError("Error opening OGG file!");
|
||||||
}
|
throw new AudioLoadException("Error opening OGG file!");
|
||||||
|
}
|
||||||
|
|
||||||
var info = FAudio.stb_vorbis_get_info(fileHandle);
|
var info = FAudio.stb_vorbis_get_info(fileHandle);
|
||||||
|
|
||||||
return new StreamingSoundOgg(
|
return new StreamingSoundOgg(
|
||||||
device,
|
device,
|
||||||
fileHandle,
|
fileHandle,
|
||||||
info,
|
info,
|
||||||
is3D,
|
is3D,
|
||||||
loop
|
loop
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal StreamingSoundOgg(
|
internal StreamingSoundOgg(
|
||||||
AudioDevice device,
|
AudioDevice device,
|
||||||
IntPtr fileHandle,
|
IntPtr fileHandle,
|
||||||
FAudio.stb_vorbis_info info,
|
FAudio.stb_vorbis_info info,
|
||||||
bool is3D,
|
bool is3D,
|
||||||
bool loop
|
bool loop
|
||||||
) : base(device, (ushort) info.channels, info.sample_rate, is3D, loop)
|
) : base(device, (ushort) info.channels, info.sample_rate, is3D, loop)
|
||||||
{
|
{
|
||||||
FileHandle = fileHandle;
|
FileHandle = fileHandle;
|
||||||
Info = info;
|
Info = info;
|
||||||
buffer = new float[BUFFER_SIZE];
|
buffer = new float[BUFFER_SIZE];
|
||||||
|
|
||||||
device.AddDynamicSoundInstance(this);
|
device.AddDynamicSoundInstance(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void AddBuffer(
|
protected override void AddBuffer(
|
||||||
out float[] buffer,
|
out float[] buffer,
|
||||||
out uint bufferOffset,
|
out uint bufferOffset,
|
||||||
out uint bufferLength,
|
out uint bufferLength,
|
||||||
out bool reachedEnd
|
out bool reachedEnd
|
||||||
) {
|
)
|
||||||
buffer = this.buffer;
|
{
|
||||||
|
buffer = this.buffer;
|
||||||
|
|
||||||
/* NOTE: this function returns samples per channel, not total samples */
|
/* NOTE: this function returns samples per channel, not total samples */
|
||||||
var samples = FAudio.stb_vorbis_get_samples_float_interleaved(
|
var samples = FAudio.stb_vorbis_get_samples_float_interleaved(
|
||||||
FileHandle,
|
FileHandle,
|
||||||
Info.channels,
|
Info.channels,
|
||||||
buffer,
|
buffer,
|
||||||
buffer.Length
|
buffer.Length
|
||||||
);
|
);
|
||||||
|
|
||||||
var sampleCount = samples * Info.channels;
|
var sampleCount = samples * Info.channels;
|
||||||
bufferOffset = 0;
|
bufferOffset = 0;
|
||||||
bufferLength = (uint) sampleCount;
|
bufferLength = (uint) sampleCount;
|
||||||
reachedEnd = sampleCount < buffer.Length;
|
reachedEnd = sampleCount < buffer.Length;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void SeekStart()
|
protected override void SeekStart()
|
||||||
{
|
{
|
||||||
FAudio.stb_vorbis_seek_start(FileHandle);
|
FAudio.stb_vorbis_seek_start(FileHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Destroy()
|
protected override void Destroy()
|
||||||
{
|
{
|
||||||
FAudio.stb_vorbis_close(FileHandle);
|
FAudio.stb_vorbis_close(FileHandle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace MoonWorks
|
namespace MoonWorks
|
||||||
{
|
{
|
||||||
public class AudioLoadException : Exception
|
public class AudioLoadException : Exception
|
||||||
{
|
{
|
||||||
public AudioLoadException(string message) : base(message)
|
public AudioLoadException(string message) : base(message)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
219
src/Game.cs
219
src/Game.cs
|
@ -10,17 +10,17 @@ using System.Diagnostics;
|
||||||
|
|
||||||
namespace MoonWorks
|
namespace MoonWorks
|
||||||
{
|
{
|
||||||
public abstract class Game
|
public abstract class Game
|
||||||
{
|
{
|
||||||
public TimeSpan MAX_DELTA_TIME = TimeSpan.FromMilliseconds(100);
|
public TimeSpan MAX_DELTA_TIME = TimeSpan.FromMilliseconds(100);
|
||||||
|
|
||||||
private bool quit = false;
|
private bool quit = false;
|
||||||
bool debugMode;
|
bool debugMode;
|
||||||
|
|
||||||
private Stopwatch gameTimer;
|
private Stopwatch gameTimer;
|
||||||
private TimeSpan timestep;
|
private TimeSpan timestep;
|
||||||
private long previousTicks = 0;
|
private long previousTicks = 0;
|
||||||
TimeSpan accumulatedElapsedTime = TimeSpan.Zero;
|
TimeSpan accumulatedElapsedTime = TimeSpan.Zero;
|
||||||
// must be a power of 2 so we can do a bitmask optimization when checking worst case
|
// must be a power of 2 so we can do a bitmask optimization when checking worst case
|
||||||
private const int PREVIOUS_SLEEP_TIME_COUNT = 128;
|
private const int PREVIOUS_SLEEP_TIME_COUNT = 128;
|
||||||
private const int SLEEP_TIME_MASK = PREVIOUS_SLEEP_TIME_COUNT - 1;
|
private const int SLEEP_TIME_MASK = PREVIOUS_SLEEP_TIME_COUNT - 1;
|
||||||
|
@ -28,26 +28,27 @@ namespace MoonWorks
|
||||||
private int sleepTimeIndex = 0;
|
private int sleepTimeIndex = 0;
|
||||||
private TimeSpan worstCaseSleepPrecision = TimeSpan.FromMilliseconds(1);
|
private TimeSpan worstCaseSleepPrecision = TimeSpan.FromMilliseconds(1);
|
||||||
|
|
||||||
public OSWindow Window { get; }
|
public OSWindow Window { get; }
|
||||||
public GraphicsDevice GraphicsDevice { get; }
|
public GraphicsDevice GraphicsDevice { get; }
|
||||||
public AudioDevice AudioDevice { get; }
|
public AudioDevice AudioDevice { get; }
|
||||||
public Inputs Inputs { get; }
|
public Inputs Inputs { get; }
|
||||||
|
|
||||||
private Dictionary<PresentMode, RefreshCS.Refresh.PresentMode> moonWorksToRefreshPresentMode = new Dictionary<PresentMode, RefreshCS.Refresh.PresentMode>
|
private Dictionary<PresentMode, RefreshCS.Refresh.PresentMode> moonWorksToRefreshPresentMode = new Dictionary<PresentMode, RefreshCS.Refresh.PresentMode>
|
||||||
{
|
{
|
||||||
{ PresentMode.Immediate, RefreshCS.Refresh.PresentMode.Immediate },
|
{ PresentMode.Immediate, RefreshCS.Refresh.PresentMode.Immediate },
|
||||||
{ PresentMode.Mailbox, RefreshCS.Refresh.PresentMode.Mailbox },
|
{ PresentMode.Mailbox, RefreshCS.Refresh.PresentMode.Mailbox },
|
||||||
{ PresentMode.FIFO, RefreshCS.Refresh.PresentMode.FIFO },
|
{ PresentMode.FIFO, RefreshCS.Refresh.PresentMode.FIFO },
|
||||||
{ PresentMode.FIFORelaxed, RefreshCS.Refresh.PresentMode.FIFORelaxed }
|
{ PresentMode.FIFORelaxed, RefreshCS.Refresh.PresentMode.FIFORelaxed }
|
||||||
};
|
};
|
||||||
|
|
||||||
public Game(
|
public Game(
|
||||||
WindowCreateInfo windowCreateInfo,
|
WindowCreateInfo windowCreateInfo,
|
||||||
PresentMode presentMode,
|
PresentMode presentMode,
|
||||||
int targetTimestep = 60,
|
int targetTimestep = 60,
|
||||||
bool debugMode = false
|
bool debugMode = false
|
||||||
) {
|
)
|
||||||
timestep = TimeSpan.FromTicks(TimeSpan.TicksPerSecond / targetTimestep);
|
{
|
||||||
|
timestep = TimeSpan.FromTicks(TimeSpan.TicksPerSecond / targetTimestep);
|
||||||
gameTimer = Stopwatch.StartNew();
|
gameTimer = Stopwatch.StartNew();
|
||||||
|
|
||||||
for (int i = 0; i < previousSleepTimes.Length; i += 1)
|
for (int i = 0; i < previousSleepTimes.Length; i += 1)
|
||||||
|
@ -55,33 +56,33 @@ namespace MoonWorks
|
||||||
previousSleepTimes[i] = TimeSpan.FromMilliseconds(1);
|
previousSleepTimes[i] = TimeSpan.FromMilliseconds(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SDL.SDL_Init(SDL.SDL_INIT_VIDEO | SDL.SDL_INIT_TIMER | SDL.SDL_INIT_GAMECONTROLLER) < 0)
|
if (SDL.SDL_Init(SDL.SDL_INIT_VIDEO | SDL.SDL_INIT_TIMER | SDL.SDL_INIT_GAMECONTROLLER) < 0)
|
||||||
{
|
{
|
||||||
System.Console.WriteLine("Failed to initialize SDL!");
|
System.Console.WriteLine("Failed to initialize SDL!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.Initialize();
|
Logger.Initialize();
|
||||||
|
|
||||||
Inputs = new Inputs();
|
Inputs = new Inputs();
|
||||||
|
|
||||||
Window = new OSWindow(windowCreateInfo);
|
Window = new OSWindow(windowCreateInfo);
|
||||||
|
|
||||||
GraphicsDevice = new GraphicsDevice(
|
GraphicsDevice = new GraphicsDevice(
|
||||||
Window.Handle,
|
Window.Handle,
|
||||||
moonWorksToRefreshPresentMode[presentMode],
|
moonWorksToRefreshPresentMode[presentMode],
|
||||||
debugMode
|
debugMode
|
||||||
);
|
);
|
||||||
|
|
||||||
AudioDevice = new AudioDevice();
|
AudioDevice = new AudioDevice();
|
||||||
|
|
||||||
this.debugMode = debugMode;
|
this.debugMode = debugMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Run()
|
public void Run()
|
||||||
{
|
{
|
||||||
while (!quit)
|
while (!quit)
|
||||||
{
|
{
|
||||||
AdvanceElapsedTime();
|
AdvanceElapsedTime();
|
||||||
|
|
||||||
/* We want to wait until the next frame,
|
/* We want to wait until the next frame,
|
||||||
|
@ -111,33 +112,33 @@ namespace MoonWorks
|
||||||
HandleSDLEvents();
|
HandleSDLEvents();
|
||||||
|
|
||||||
// Do not let any step take longer than our maximum.
|
// Do not let any step take longer than our maximum.
|
||||||
if (accumulatedElapsedTime > MAX_DELTA_TIME)
|
if (accumulatedElapsedTime > MAX_DELTA_TIME)
|
||||||
{
|
{
|
||||||
accumulatedElapsedTime = MAX_DELTA_TIME;
|
accumulatedElapsedTime = MAX_DELTA_TIME;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!quit)
|
if (!quit)
|
||||||
{
|
{
|
||||||
while (accumulatedElapsedTime >= timestep)
|
while (accumulatedElapsedTime >= timestep)
|
||||||
{
|
{
|
||||||
Inputs.Mouse.Wheel = 0;
|
Inputs.Mouse.Wheel = 0;
|
||||||
|
|
||||||
Inputs.Update();
|
Inputs.Update();
|
||||||
AudioDevice.Update();
|
AudioDevice.Update();
|
||||||
|
|
||||||
Update(timestep);
|
Update(timestep);
|
||||||
|
|
||||||
accumulatedElapsedTime -= timestep;
|
accumulatedElapsedTime -= timestep;
|
||||||
}
|
}
|
||||||
|
|
||||||
var alpha = accumulatedElapsedTime / timestep;
|
var alpha = accumulatedElapsedTime / timestep;
|
||||||
|
|
||||||
Draw(timestep, alpha);
|
Draw(timestep, alpha);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GraphicsDevice.SubmitDestroyCommandBuffer();
|
GraphicsDevice.SubmitDestroyCommandBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
OnDestroy();
|
OnDestroy();
|
||||||
|
|
||||||
|
@ -146,64 +147,64 @@ namespace MoonWorks
|
||||||
Window.Dispose();
|
Window.Dispose();
|
||||||
|
|
||||||
SDL.SDL_Quit();
|
SDL.SDL_Quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleSDLEvents()
|
private void HandleSDLEvents()
|
||||||
{
|
{
|
||||||
while (SDL.SDL_PollEvent(out var _event) == 1)
|
while (SDL.SDL_PollEvent(out var _event) == 1)
|
||||||
{
|
{
|
||||||
switch (_event.type)
|
switch (_event.type)
|
||||||
{
|
{
|
||||||
case SDL.SDL_EventType.SDL_QUIT:
|
case SDL.SDL_EventType.SDL_QUIT:
|
||||||
quit = true;
|
quit = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDL.SDL_EventType.SDL_TEXTINPUT:
|
case SDL.SDL_EventType.SDL_TEXTINPUT:
|
||||||
HandleTextInput(_event);
|
HandleTextInput(_event);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDL.SDL_EventType.SDL_MOUSEWHEEL:
|
case SDL.SDL_EventType.SDL_MOUSEWHEEL:
|
||||||
Inputs.Mouse.Wheel += _event.wheel.y;
|
Inputs.Mouse.Wheel += _event.wheel.y;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void Update(TimeSpan dt);
|
protected abstract void Update(TimeSpan dt);
|
||||||
|
|
||||||
// alpha refers to a percentage value between the current and next state
|
// alpha refers to a percentage value between the current and next state
|
||||||
protected abstract void Draw(TimeSpan dt, double alpha);
|
protected abstract void Draw(TimeSpan dt, double alpha);
|
||||||
|
|
||||||
// Clean up any objects you created in this function
|
// Clean up any objects you created in this function
|
||||||
protected abstract void OnDestroy();
|
protected abstract void OnDestroy();
|
||||||
|
|
||||||
private void HandleTextInput(SDL2.SDL.SDL_Event evt)
|
private void HandleTextInput(SDL2.SDL.SDL_Event evt)
|
||||||
{
|
{
|
||||||
// Based on the SDL2# LPUtf8StrMarshaler
|
// Based on the SDL2# LPUtf8StrMarshaler
|
||||||
unsafe
|
unsafe
|
||||||
{
|
{
|
||||||
int bytes = MeasureStringLength(evt.text.text);
|
int bytes = MeasureStringLength(evt.text.text);
|
||||||
if (bytes > 0)
|
if (bytes > 0)
|
||||||
{
|
{
|
||||||
/* UTF8 will never encode more characters
|
/* UTF8 will never encode more characters
|
||||||
* than bytes in a string, so bytes is a
|
* than bytes in a string, so bytes is a
|
||||||
* suitable upper estimate of size needed
|
* suitable upper estimate of size needed
|
||||||
*/
|
*/
|
||||||
char* charsBuffer = stackalloc char[bytes];
|
char* charsBuffer = stackalloc char[bytes];
|
||||||
int chars = Encoding.UTF8.GetChars(
|
int chars = Encoding.UTF8.GetChars(
|
||||||
evt.text.text,
|
evt.text.text,
|
||||||
bytes,
|
bytes,
|
||||||
charsBuffer,
|
charsBuffer,
|
||||||
bytes
|
bytes
|
||||||
);
|
);
|
||||||
|
|
||||||
for (int i = 0; i < chars; i += 1)
|
for (int i = 0; i < chars; i += 1)
|
||||||
{
|
{
|
||||||
Inputs.OnTextInput(charsBuffer[i]);
|
Inputs.OnTextInput(charsBuffer[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private TimeSpan AdvanceElapsedTime()
|
private TimeSpan AdvanceElapsedTime()
|
||||||
{
|
{
|
||||||
|
@ -259,8 +260,8 @@ namespace MoonWorks
|
||||||
private unsafe static int MeasureStringLength(byte* ptr)
|
private unsafe static int MeasureStringLength(byte* ptr)
|
||||||
{
|
{
|
||||||
int bytes;
|
int bytes;
|
||||||
for (bytes = 0; *ptr != 0; ptr += 1, bytes += 1);
|
for (bytes = 0; *ptr != 0; ptr += 1, bytes += 1) ;
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
namespace MoonWorks.Graphics
|
namespace MoonWorks.Graphics
|
||||||
{
|
{
|
||||||
public struct BufferBinding
|
public struct BufferBinding
|
||||||
{
|
{
|
||||||
public Buffer Buffer;
|
public Buffer Buffer;
|
||||||
public ulong Offset;
|
public ulong Offset;
|
||||||
|
|
||||||
public BufferBinding(Buffer buffer, ulong offset)
|
public BufferBinding(Buffer buffer, ulong offset)
|
||||||
{
|
{
|
||||||
Buffer = buffer;
|
Buffer = buffer;
|
||||||
Offset = offset;
|
Offset = offset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
namespace MoonWorks.Graphics
|
namespace MoonWorks.Graphics
|
||||||
{
|
{
|
||||||
public struct TextureSamplerBinding
|
public struct TextureSamplerBinding
|
||||||
{
|
{
|
||||||
public Texture Texture;
|
public Texture Texture;
|
||||||
public Sampler Sampler;
|
public Sampler Sampler;
|
||||||
|
|
||||||
public TextureSamplerBinding(Texture texture, Sampler sampler)
|
public TextureSamplerBinding(Texture texture, Sampler sampler)
|
||||||
{
|
{
|
||||||
Texture = texture;
|
Texture = texture;
|
||||||
Sampler = sampler;
|
Sampler = sampler;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#region License
|
#region License
|
||||||
|
|
||||||
/* MoonWorks - Game Development Framework
|
/* MoonWorks - Game Development Framework
|
||||||
* Copyright 2021 Evan Hemsley
|
* Copyright 2021 Evan Hemsley
|
||||||
|
@ -41,7 +41,7 @@ namespace MoonWorks.Graphics
|
||||||
{
|
{
|
||||||
unchecked
|
unchecked
|
||||||
{
|
{
|
||||||
return (byte)(this.packedValue);
|
return (byte) (this.packedValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
|
@ -59,12 +59,12 @@ namespace MoonWorks.Graphics
|
||||||
{
|
{
|
||||||
unchecked
|
unchecked
|
||||||
{
|
{
|
||||||
return (byte)(this.packedValue >> 8);
|
return (byte) (this.packedValue >> 8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
this.packedValue = (this.packedValue & 0xffff00ff) | ((uint)value << 8);
|
this.packedValue = (this.packedValue & 0xffff00ff) | ((uint) value << 8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1538,27 +1538,27 @@ namespace MoonWorks.Graphics
|
||||||
RosyBrown = new Color(0xff8f8fbc);
|
RosyBrown = new Color(0xff8f8fbc);
|
||||||
RoyalBlue = new Color(0xffe16941);
|
RoyalBlue = new Color(0xffe16941);
|
||||||
SaddleBrown = new Color(0xff13458b);
|
SaddleBrown = new Color(0xff13458b);
|
||||||
Salmon= new Color(0xff7280fa);
|
Salmon = new Color(0xff7280fa);
|
||||||
SandyBrown = new Color(0xff60a4f4);
|
SandyBrown = new Color(0xff60a4f4);
|
||||||
SeaGreen = new Color(0xff578b2e);
|
SeaGreen = new Color(0xff578b2e);
|
||||||
SeaShell = new Color(0xffeef5ff);
|
SeaShell = new Color(0xffeef5ff);
|
||||||
Sienna = new Color(0xff2d52a0);
|
Sienna = new Color(0xff2d52a0);
|
||||||
Silver = new Color(0xffc0c0c0);
|
Silver = new Color(0xffc0c0c0);
|
||||||
SkyBlue = new Color(0xffebce87);
|
SkyBlue = new Color(0xffebce87);
|
||||||
SlateBlue= new Color(0xffcd5a6a);
|
SlateBlue = new Color(0xffcd5a6a);
|
||||||
SlateGray= new Color(0xff908070);
|
SlateGray = new Color(0xff908070);
|
||||||
Snow= new Color(0xfffafaff);
|
Snow = new Color(0xfffafaff);
|
||||||
SpringGreen= new Color(0xff7fff00);
|
SpringGreen = new Color(0xff7fff00);
|
||||||
SteelBlue= new Color(0xffb48246);
|
SteelBlue = new Color(0xffb48246);
|
||||||
Tan= new Color(0xff8cb4d2);
|
Tan = new Color(0xff8cb4d2);
|
||||||
Teal= new Color(0xff808000);
|
Teal = new Color(0xff808000);
|
||||||
Thistle= new Color(0xffd8bfd8);
|
Thistle = new Color(0xffd8bfd8);
|
||||||
Tomato= new Color(0xff4763ff);
|
Tomato = new Color(0xff4763ff);
|
||||||
Turquoise= new Color(0xffd0e040);
|
Turquoise = new Color(0xffd0e040);
|
||||||
Violet= new Color(0xffee82ee);
|
Violet = new Color(0xffee82ee);
|
||||||
Wheat= new Color(0xffb3def5);
|
Wheat = new Color(0xffb3def5);
|
||||||
White= new Color(uint.MaxValue);
|
White = new Color(uint.MaxValue);
|
||||||
WhiteSmoke= new Color(0xfff5f5f5);
|
WhiteSmoke = new Color(0xfff5f5f5);
|
||||||
Yellow = new Color(0xff00ffff);
|
Yellow = new Color(0xff00ffff);
|
||||||
YellowGreen = new Color(0xff32cd9a);
|
YellowGreen = new Color(0xff32cd9a);
|
||||||
}
|
}
|
||||||
|
@ -1623,7 +1623,7 @@ namespace MoonWorks.Graphics
|
||||||
R = (byte) MathHelper.Clamp(r, Byte.MinValue, Byte.MaxValue);
|
R = (byte) MathHelper.Clamp(r, Byte.MinValue, Byte.MaxValue);
|
||||||
G = (byte) MathHelper.Clamp(g, Byte.MinValue, Byte.MaxValue);
|
G = (byte) MathHelper.Clamp(g, Byte.MinValue, Byte.MaxValue);
|
||||||
B = (byte) MathHelper.Clamp(b, Byte.MinValue, Byte.MaxValue);
|
B = (byte) MathHelper.Clamp(b, Byte.MinValue, Byte.MaxValue);
|
||||||
A = (byte)255;
|
A = (byte) 255;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -1769,10 +1769,10 @@ namespace MoonWorks.Graphics
|
||||||
/// <returns><c>True</c> if the instances are equal; <c>false</c> otherwise.</returns>
|
/// <returns><c>True</c> if the instances are equal; <c>false</c> otherwise.</returns>
|
||||||
public static bool operator ==(Color a, Color b)
|
public static bool operator ==(Color a, Color b)
|
||||||
{
|
{
|
||||||
return ( a.A == b.A &&
|
return (a.A == b.A &&
|
||||||
a.R == b.R &&
|
a.R == b.R &&
|
||||||
a.G == b.G &&
|
a.G == b.G &&
|
||||||
a.B == b.B );
|
a.B == b.B);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -4,58 +4,59 @@ using RefreshCS;
|
||||||
|
|
||||||
namespace MoonWorks.Graphics
|
namespace MoonWorks.Graphics
|
||||||
{
|
{
|
||||||
public class GraphicsDevice : IDisposable
|
public class GraphicsDevice : IDisposable
|
||||||
{
|
{
|
||||||
public IntPtr Handle { get; }
|
public IntPtr Handle { get; }
|
||||||
|
|
||||||
public bool IsDisposed { get; private set; }
|
public bool IsDisposed { get; private set; }
|
||||||
|
|
||||||
private readonly List<WeakReference<GraphicsResource>> resources = new List<WeakReference<GraphicsResource>>();
|
private readonly List<WeakReference<GraphicsResource>> resources = new List<WeakReference<GraphicsResource>>();
|
||||||
private Dictionary<IntPtr, Action<IntPtr, IntPtr, IntPtr>> resourcesToDestroy = new Dictionary<IntPtr, Action<IntPtr, IntPtr, IntPtr>>();
|
private Dictionary<IntPtr, Action<IntPtr, IntPtr, IntPtr>> resourcesToDestroy = new Dictionary<IntPtr, Action<IntPtr, IntPtr, IntPtr>>();
|
||||||
|
|
||||||
public GraphicsDevice(
|
public GraphicsDevice(
|
||||||
IntPtr deviceWindowHandle,
|
IntPtr deviceWindowHandle,
|
||||||
Refresh.PresentMode presentMode,
|
Refresh.PresentMode presentMode,
|
||||||
bool debugMode,
|
bool debugMode,
|
||||||
int initialCommandBufferPoolSize = 4
|
int initialCommandBufferPoolSize = 4
|
||||||
) {
|
)
|
||||||
var presentationParameters = new Refresh.PresentationParameters
|
{
|
||||||
{
|
var presentationParameters = new Refresh.PresentationParameters
|
||||||
deviceWindowHandle = deviceWindowHandle,
|
{
|
||||||
presentMode = presentMode
|
deviceWindowHandle = deviceWindowHandle,
|
||||||
};
|
presentMode = presentMode
|
||||||
|
};
|
||||||
|
|
||||||
Handle = Refresh.Refresh_CreateDevice(
|
Handle = Refresh.Refresh_CreateDevice(
|
||||||
presentationParameters,
|
presentationParameters,
|
||||||
Conversions.BoolToByte(debugMode)
|
Conversions.BoolToByte(debugMode)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CommandBuffer AcquireCommandBuffer()
|
public CommandBuffer AcquireCommandBuffer()
|
||||||
{
|
{
|
||||||
return new CommandBuffer(this, Refresh.Refresh_AcquireCommandBuffer(Handle, 0));
|
return new CommandBuffer(this, Refresh.Refresh_AcquireCommandBuffer(Handle, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe void Submit(params CommandBuffer[] commandBuffers)
|
public unsafe void Submit(params CommandBuffer[] commandBuffers)
|
||||||
{
|
{
|
||||||
var commandBufferPtrs = stackalloc IntPtr[commandBuffers.Length];
|
var commandBufferPtrs = stackalloc IntPtr[commandBuffers.Length];
|
||||||
|
|
||||||
for (var i = 0; i < commandBuffers.Length; i += 1)
|
for (var i = 0; i < commandBuffers.Length; i += 1)
|
||||||
{
|
{
|
||||||
commandBufferPtrs[i] = commandBuffers[i].Handle;
|
commandBufferPtrs[i] = commandBuffers[i].Handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
Refresh.Refresh_Submit(
|
Refresh.Refresh_Submit(
|
||||||
Handle,
|
Handle,
|
||||||
(uint) commandBuffers.Length,
|
(uint) commandBuffers.Length,
|
||||||
(IntPtr) commandBufferPtrs
|
(IntPtr) commandBufferPtrs
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Wait()
|
public void Wait()
|
||||||
{
|
{
|
||||||
Refresh.Refresh_Wait(Handle);
|
Refresh.Refresh_Wait(Handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void SubmitDestroyCommandBuffer()
|
internal void SubmitDestroyCommandBuffer()
|
||||||
{
|
{
|
||||||
|
@ -77,60 +78,60 @@ namespace MoonWorks.Graphics
|
||||||
resourcesToDestroy.Add(resource.Handle, destroyFunction);
|
resourcesToDestroy.Add(resource.Handle, destroyFunction);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void AddResourceReference(WeakReference<GraphicsResource> resourceReference)
|
internal void AddResourceReference(WeakReference<GraphicsResource> resourceReference)
|
||||||
{
|
{
|
||||||
lock (resources)
|
lock (resources)
|
||||||
{
|
{
|
||||||
resources.Add(resourceReference);
|
resources.Add(resourceReference);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void RemoveResourceReference(WeakReference<GraphicsResource> resourceReference)
|
internal void RemoveResourceReference(WeakReference<GraphicsResource> resourceReference)
|
||||||
{
|
{
|
||||||
lock (resources)
|
lock (resources)
|
||||||
{
|
{
|
||||||
resources.Remove(resourceReference);
|
resources.Remove(resourceReference);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void Dispose(bool disposing)
|
protected virtual void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
if (!IsDisposed)
|
if (!IsDisposed)
|
||||||
{
|
{
|
||||||
if (disposing)
|
if (disposing)
|
||||||
{
|
{
|
||||||
lock (resources)
|
lock (resources)
|
||||||
{
|
{
|
||||||
for (var i = resources.Count - 1; i >= 0; i--)
|
for (var i = resources.Count - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
var resource = resources[i];
|
var resource = resources[i];
|
||||||
if (resource.TryGetTarget(out var target))
|
if (resource.TryGetTarget(out var target))
|
||||||
{
|
{
|
||||||
target.Dispose();
|
target.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
resources.Clear();
|
resources.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
SubmitDestroyCommandBuffer();
|
SubmitDestroyCommandBuffer();
|
||||||
Refresh.Refresh_DestroyDevice(Handle);
|
Refresh.Refresh_DestroyDevice(Handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
IsDisposed = true;
|
IsDisposed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~GraphicsDevice()
|
~GraphicsDevice()
|
||||||
{
|
{
|
||||||
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
||||||
Dispose(disposing: false);
|
Dispose(disposing: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
||||||
Dispose(disposing: true);
|
Dispose(disposing: true);
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,51 +2,51 @@
|
||||||
|
|
||||||
namespace MoonWorks.Graphics
|
namespace MoonWorks.Graphics
|
||||||
{
|
{
|
||||||
public abstract class GraphicsResource : IDisposable
|
public abstract class GraphicsResource : IDisposable
|
||||||
{
|
{
|
||||||
public GraphicsDevice Device { get; }
|
public GraphicsDevice Device { get; }
|
||||||
public IntPtr Handle { get; protected set; }
|
public IntPtr Handle { get; protected set; }
|
||||||
|
|
||||||
public bool IsDisposed { get; private set; }
|
public bool IsDisposed { get; private set; }
|
||||||
protected abstract Action<IntPtr, IntPtr, IntPtr> QueueDestroyFunction { get; }
|
protected abstract Action<IntPtr, IntPtr, IntPtr> QueueDestroyFunction { get; }
|
||||||
|
|
||||||
private WeakReference<GraphicsResource> selfReference;
|
private WeakReference<GraphicsResource> selfReference;
|
||||||
|
|
||||||
public GraphicsResource(GraphicsDevice device)
|
public GraphicsResource(GraphicsDevice device)
|
||||||
{
|
{
|
||||||
Device = device;
|
Device = device;
|
||||||
|
|
||||||
selfReference = new WeakReference<GraphicsResource>(this);
|
selfReference = new WeakReference<GraphicsResource>(this);
|
||||||
Device.AddResourceReference(selfReference);
|
Device.AddResourceReference(selfReference);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void Dispose(bool disposing)
|
protected virtual void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
if (!IsDisposed)
|
if (!IsDisposed)
|
||||||
{
|
{
|
||||||
Device.PrepareDestroyResource(this, QueueDestroyFunction);
|
Device.PrepareDestroyResource(this, QueueDestroyFunction);
|
||||||
|
|
||||||
if (selfReference != null)
|
if (selfReference != null)
|
||||||
{
|
{
|
||||||
Device.RemoveResourceReference(selfReference);
|
Device.RemoveResourceReference(selfReference);
|
||||||
selfReference = null;
|
selfReference = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
IsDisposed = true;
|
IsDisposed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~GraphicsResource()
|
~GraphicsResource()
|
||||||
{
|
{
|
||||||
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
||||||
Dispose(disposing: false);
|
Dispose(disposing: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
||||||
Dispose(disposing: true);
|
Dispose(disposing: true);
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#region License
|
#region License
|
||||||
|
|
||||||
/* MoonWorks - Game Development Framework
|
/* MoonWorks - Game Development Framework
|
||||||
* Copyright 2021 Evan Hemsley
|
* Copyright 2021 Evan Hemsley
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#region License
|
#region License
|
||||||
|
|
||||||
/* MoonWorks - Game Development Framework
|
/* MoonWorks - Game Development Framework
|
||||||
* Copyright 2021 Evan Hemsley
|
* Copyright 2021 Evan Hemsley
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#region License
|
#region License
|
||||||
|
|
||||||
/* MoonWorks - Game Development Framework
|
/* MoonWorks - Game Development Framework
|
||||||
* Copyright 2021 Evan Hemsley
|
* Copyright 2021 Evan Hemsley
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#region License
|
#region License
|
||||||
|
|
||||||
/* MoonWorks - Game Development Framework
|
/* MoonWorks - Game Development Framework
|
||||||
* Copyright 2021 Evan Hemsley
|
* Copyright 2021 Evan Hemsley
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#region License
|
#region License
|
||||||
|
|
||||||
/* MoonWorks - Game Development Framework
|
/* MoonWorks - Game Development Framework
|
||||||
* Copyright 2021 Evan Hemsley
|
* Copyright 2021 Evan Hemsley
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#region License
|
#region License
|
||||||
|
|
||||||
/* MoonWorks - Game Development Framework
|
/* MoonWorks - Game Development Framework
|
||||||
* Copyright 2021 Evan Hemsley
|
* Copyright 2021 Evan Hemsley
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#region License
|
#region License
|
||||||
|
|
||||||
/* MoonWorks - Game Development Framework
|
/* MoonWorks - Game Development Framework
|
||||||
* Copyright 2021 Evan Hemsley
|
* Copyright 2021 Evan Hemsley
|
||||||
|
@ -104,7 +104,7 @@ namespace MoonWorks.Graphics
|
||||||
internal static float Convert(ushort value)
|
internal static float Convert(ushort value)
|
||||||
{
|
{
|
||||||
uint rst;
|
uint rst;
|
||||||
uint mantissa = (uint)(value & 1023);
|
uint mantissa = (uint) (value & 1023);
|
||||||
uint exp = 0xfffffff2;
|
uint exp = 0xfffffff2;
|
||||||
|
|
||||||
if ((value & -33792) == 0)
|
if ((value & -33792) == 0)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#region License
|
#region License
|
||||||
|
|
||||||
/* MoonWorks - Game Development Framework
|
/* MoonWorks - Game Development Framework
|
||||||
* Copyright 2021 Evan Hemsley
|
* Copyright 2021 Evan Hemsley
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#region License
|
#region License
|
||||||
|
|
||||||
/* MoonWorks - Game Development Framework
|
/* MoonWorks - Game Development Framework
|
||||||
* Copyright 2021 Evan Hemsley
|
* Copyright 2021 Evan Hemsley
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#region License
|
#region License
|
||||||
|
|
||||||
/* MoonWorks - Game Development Framework
|
/* MoonWorks - Game Development Framework
|
||||||
* Copyright 2021 Evan Hemsley
|
* Copyright 2021 Evan Hemsley
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#region License
|
#region License
|
||||||
|
|
||||||
/* MoonWorks - Game Development Framework
|
/* MoonWorks - Game Development Framework
|
||||||
* Copyright 2021 Evan Hemsley
|
* Copyright 2021 Evan Hemsley
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#region License
|
#region License
|
||||||
|
|
||||||
/* MoonWorks - Game Development Framework
|
/* MoonWorks - Game Development Framework
|
||||||
* Copyright 2021 Evan Hemsley
|
* Copyright 2021 Evan Hemsley
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#region License
|
#region License
|
||||||
|
|
||||||
/* MoonWorks - Game Development Framework
|
/* MoonWorks - Game Development Framework
|
||||||
* Copyright 2021 Evan Hemsley
|
* Copyright 2021 Evan Hemsley
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#region License
|
#region License
|
||||||
|
|
||||||
/* MoonWorks - Game Development Framework
|
/* MoonWorks - Game Development Framework
|
||||||
* Copyright 2021 Evan Hemsley
|
* Copyright 2021 Evan Hemsley
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#region License
|
#region License
|
||||||
|
|
||||||
/* MoonWorks - Game Development Framework
|
/* MoonWorks - Game Development Framework
|
||||||
* Copyright 2021 Evan Hemsley
|
* Copyright 2021 Evan Hemsley
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#region License
|
#region License
|
||||||
|
|
||||||
/* MoonWorks - Game Development Framework
|
/* MoonWorks - Game Development Framework
|
||||||
* Copyright 2021 Evan Hemsley
|
* Copyright 2021 Evan Hemsley
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#region License
|
#region License
|
||||||
|
|
||||||
/* MoonWorks - Game Development Framework
|
/* MoonWorks - Game Development Framework
|
||||||
* Copyright 2021 Evan Hemsley
|
* Copyright 2021 Evan Hemsley
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#region License
|
#region License
|
||||||
|
|
||||||
/* MoonWorks - Game Development Framework
|
/* MoonWorks - Game Development Framework
|
||||||
* Copyright 2021 Evan Hemsley
|
* Copyright 2021 Evan Hemsley
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#region License
|
#region License
|
||||||
|
|
||||||
/* MoonWorks - Game Development Framework
|
/* MoonWorks - Game Development Framework
|
||||||
* Copyright 2021 Evan Hemsley
|
* Copyright 2021 Evan Hemsley
|
||||||
|
@ -192,7 +192,7 @@ namespace MoonWorks.Graphics
|
||||||
static ulong Pack(float x, float y, float z, float w)
|
static ulong Pack(float x, float y, float z, float w)
|
||||||
{
|
{
|
||||||
return (ulong) (
|
return (ulong) (
|
||||||
((long) System.Math.Round(MathHelper.Clamp(x, -32768, 32767)) & 0xFFFF ) |
|
((long) System.Math.Round(MathHelper.Clamp(x, -32768, 32767)) & 0xFFFF) |
|
||||||
(((long) System.Math.Round(MathHelper.Clamp(y, -32768, 32767)) << 16) & 0xFFFF0000) |
|
(((long) System.Math.Round(MathHelper.Clamp(y, -32768, 32767)) << 16) & 0xFFFF0000) |
|
||||||
(((long) System.Math.Round(MathHelper.Clamp(z, -32768, 32767)) << 32) & 0xFFFF00000000) |
|
(((long) System.Math.Round(MathHelper.Clamp(z, -32768, 32767)) << 32) & 0xFFFF00000000) |
|
||||||
((long) System.Math.Round(MathHelper.Clamp(w, -32768, 32767)) << 48)
|
((long) System.Math.Round(MathHelper.Clamp(w, -32768, 32767)) << 48)
|
||||||
|
|
|
@ -5,298 +5,298 @@
|
||||||
*/
|
*/
|
||||||
namespace MoonWorks.Graphics
|
namespace MoonWorks.Graphics
|
||||||
{
|
{
|
||||||
public enum PresentMode
|
public enum PresentMode
|
||||||
{
|
{
|
||||||
Immediate,
|
Immediate,
|
||||||
Mailbox,
|
Mailbox,
|
||||||
FIFO,
|
FIFO,
|
||||||
FIFORelaxed
|
FIFORelaxed
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum PrimitiveType
|
public enum PrimitiveType
|
||||||
{
|
{
|
||||||
PointList,
|
PointList,
|
||||||
LineList,
|
LineList,
|
||||||
LineStrip,
|
LineStrip,
|
||||||
TriangleList,
|
TriangleList,
|
||||||
TriangleStrip
|
TriangleStrip
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Describes the operation that a render pass will use when loading a render target.
|
/// Describes the operation that a render pass will use when loading a render target.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public enum LoadOp
|
public enum LoadOp
|
||||||
{
|
{
|
||||||
Load,
|
Load,
|
||||||
Clear,
|
Clear,
|
||||||
DontCare
|
DontCare
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Describes the operation that a render pass will use when storing a render target.
|
/// Describes the operation that a render pass will use when storing a render target.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public enum StoreOp
|
public enum StoreOp
|
||||||
{
|
{
|
||||||
Store,
|
Store,
|
||||||
DontCare
|
DontCare
|
||||||
}
|
}
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
public enum ClearOptionsFlags : uint
|
public enum ClearOptionsFlags : uint
|
||||||
{
|
{
|
||||||
Color = 1,
|
Color = 1,
|
||||||
Depth = 2,
|
Depth = 2,
|
||||||
Stencil = 4,
|
Stencil = 4,
|
||||||
DepthStencil = Depth | Stencil,
|
DepthStencil = Depth | Stencil,
|
||||||
All = Color | Depth | Stencil
|
All = Color | Depth | Stencil
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum IndexElementSize
|
public enum IndexElementSize
|
||||||
{
|
{
|
||||||
Sixteen,
|
Sixteen,
|
||||||
ThirtyTwo
|
ThirtyTwo
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum TextureFormat
|
public enum TextureFormat
|
||||||
{
|
{
|
||||||
R8G8B8A8,
|
R8G8B8A8,
|
||||||
R5G6B5,
|
R5G6B5,
|
||||||
A1R5G5B5,
|
A1R5G5B5,
|
||||||
B4G4R4A4,
|
B4G4R4A4,
|
||||||
BC1,
|
BC1,
|
||||||
BC2,
|
BC2,
|
||||||
BC3,
|
BC3,
|
||||||
R8G8_SNORM,
|
R8G8_SNORM,
|
||||||
R8G8B8A8_SNORM,
|
R8G8B8A8_SNORM,
|
||||||
A2R10G10B10,
|
A2R10G10B10,
|
||||||
R16G16,
|
R16G16,
|
||||||
R16G16B16A16,
|
R16G16B16A16,
|
||||||
R8,
|
R8,
|
||||||
R32_SFLOAT,
|
R32_SFLOAT,
|
||||||
R32G32_SFLOAT,
|
R32G32_SFLOAT,
|
||||||
R32G32B32A32_SFLOAT,
|
R32G32B32A32_SFLOAT,
|
||||||
R16_SFLOAT,
|
R16_SFLOAT,
|
||||||
R16G16_SFLOAT,
|
R16G16_SFLOAT,
|
||||||
R16G16B16A16_SFLOAT,
|
R16G16B16A16_SFLOAT,
|
||||||
D16,
|
D16,
|
||||||
D32,
|
D32,
|
||||||
D16S8,
|
D16S8,
|
||||||
D32S8
|
D32S8
|
||||||
}
|
}
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
public enum TextureUsageFlags : uint
|
public enum TextureUsageFlags : uint
|
||||||
{
|
{
|
||||||
Sampler = 1,
|
Sampler = 1,
|
||||||
ColorTarget = 2,
|
ColorTarget = 2,
|
||||||
DepthStencilTarget = 4
|
DepthStencilTarget = 4
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum SampleCount
|
public enum SampleCount
|
||||||
{
|
{
|
||||||
One,
|
One,
|
||||||
Two,
|
Two,
|
||||||
Four,
|
Four,
|
||||||
Eight,
|
Eight,
|
||||||
Sixteen,
|
Sixteen,
|
||||||
ThirtyTwo,
|
ThirtyTwo,
|
||||||
SixtyFour
|
SixtyFour
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum CubeMapFace : uint
|
public enum CubeMapFace : uint
|
||||||
{
|
{
|
||||||
PositiveX,
|
PositiveX,
|
||||||
NegativeX,
|
NegativeX,
|
||||||
PositiveY,
|
PositiveY,
|
||||||
NegativeY,
|
NegativeY,
|
||||||
PositiveZ,
|
PositiveZ,
|
||||||
NegativeZ
|
NegativeZ
|
||||||
}
|
}
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
public enum BufferUsageFlags : uint
|
public enum BufferUsageFlags : uint
|
||||||
{
|
{
|
||||||
Vertex = 1,
|
Vertex = 1,
|
||||||
Index = 2,
|
Index = 2,
|
||||||
Compute = 4
|
Compute = 4
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum VertexElementFormat
|
public enum VertexElementFormat
|
||||||
{
|
{
|
||||||
Single,
|
Single,
|
||||||
Vector2,
|
Vector2,
|
||||||
Vector3,
|
Vector3,
|
||||||
Vector4,
|
Vector4,
|
||||||
Color,
|
Color,
|
||||||
Byte4,
|
Byte4,
|
||||||
Short2,
|
Short2,
|
||||||
Short4,
|
Short4,
|
||||||
NormalizedShort2,
|
NormalizedShort2,
|
||||||
NormalizedShort4,
|
NormalizedShort4,
|
||||||
HalfVector2,
|
HalfVector2,
|
||||||
HalfVector4
|
HalfVector4
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum VertexInputRate
|
public enum VertexInputRate
|
||||||
{
|
{
|
||||||
Vertex,
|
Vertex,
|
||||||
Instance
|
Instance
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum FillMode
|
public enum FillMode
|
||||||
{
|
{
|
||||||
Fill,
|
Fill,
|
||||||
Line,
|
Line,
|
||||||
Point
|
Point
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum CullMode
|
public enum CullMode
|
||||||
{
|
{
|
||||||
None,
|
None,
|
||||||
Front,
|
Front,
|
||||||
Back,
|
Back,
|
||||||
FrontAndBack
|
FrontAndBack
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum FrontFace
|
public enum FrontFace
|
||||||
{
|
{
|
||||||
CounterClockwise,
|
CounterClockwise,
|
||||||
Clockwise
|
Clockwise
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum CompareOp
|
public enum CompareOp
|
||||||
{
|
{
|
||||||
Never,
|
Never,
|
||||||
Less,
|
Less,
|
||||||
Equal,
|
Equal,
|
||||||
LessOrEqual,
|
LessOrEqual,
|
||||||
Greater,
|
Greater,
|
||||||
NotEqual,
|
NotEqual,
|
||||||
GreaterOrEqual,
|
GreaterOrEqual,
|
||||||
Always
|
Always
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum StencilOp
|
public enum StencilOp
|
||||||
{
|
{
|
||||||
Keep,
|
Keep,
|
||||||
Zero,
|
Zero,
|
||||||
Replace,
|
Replace,
|
||||||
IncrementAndClamp,
|
IncrementAndClamp,
|
||||||
DecrementAndClamp,
|
DecrementAndClamp,
|
||||||
Invert,
|
Invert,
|
||||||
IncrementAndWrap,
|
IncrementAndWrap,
|
||||||
DecrementAndWrap
|
DecrementAndWrap
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum BlendOp
|
public enum BlendOp
|
||||||
{
|
{
|
||||||
Add,
|
Add,
|
||||||
Subtract,
|
Subtract,
|
||||||
ReverseSubtract,
|
ReverseSubtract,
|
||||||
Min,
|
Min,
|
||||||
Max
|
Max
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum LogicOp
|
public enum LogicOp
|
||||||
{
|
{
|
||||||
Clear,
|
Clear,
|
||||||
And,
|
And,
|
||||||
AndReverse,
|
AndReverse,
|
||||||
Copy,
|
Copy,
|
||||||
AndInverted,
|
AndInverted,
|
||||||
NoOp,
|
NoOp,
|
||||||
Xor,
|
Xor,
|
||||||
Or,
|
Or,
|
||||||
Nor,
|
Nor,
|
||||||
Equivalent,
|
Equivalent,
|
||||||
Invert,
|
Invert,
|
||||||
OrReverse,
|
OrReverse,
|
||||||
CopyInverted,
|
CopyInverted,
|
||||||
OrInverted,
|
OrInverted,
|
||||||
Nand,
|
Nand,
|
||||||
Set
|
Set
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum BlendFactor
|
public enum BlendFactor
|
||||||
{
|
{
|
||||||
Zero,
|
Zero,
|
||||||
One,
|
One,
|
||||||
SourceColor,
|
SourceColor,
|
||||||
OneMinusSourceColor,
|
OneMinusSourceColor,
|
||||||
DestinationColor,
|
DestinationColor,
|
||||||
OneMinusDestinationColor,
|
OneMinusDestinationColor,
|
||||||
SourceAlpha,
|
SourceAlpha,
|
||||||
OneMinusSourceAlpha,
|
OneMinusSourceAlpha,
|
||||||
DestinationAlpha,
|
DestinationAlpha,
|
||||||
OneMinusDestinationAlpha,
|
OneMinusDestinationAlpha,
|
||||||
ConstantColor,
|
ConstantColor,
|
||||||
OneMinusConstantColor,
|
OneMinusConstantColor,
|
||||||
ConstantAlpha,
|
ConstantAlpha,
|
||||||
OneMinusConstantAlpha,
|
OneMinusConstantAlpha,
|
||||||
SourceAlphaSaturate,
|
SourceAlphaSaturate,
|
||||||
SourceOneColor,
|
SourceOneColor,
|
||||||
OneMinusSourceOneColor,
|
OneMinusSourceOneColor,
|
||||||
SourceOneAlpha,
|
SourceOneAlpha,
|
||||||
OneMinusSourceOneAlpha
|
OneMinusSourceOneAlpha
|
||||||
}
|
}
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
public enum ColorComponentFlags : uint
|
public enum ColorComponentFlags : uint
|
||||||
{
|
{
|
||||||
R = 1,
|
R = 1,
|
||||||
G = 2,
|
G = 2,
|
||||||
B = 4,
|
B = 4,
|
||||||
A = 8,
|
A = 8,
|
||||||
|
|
||||||
RG = R | G,
|
RG = R | G,
|
||||||
RB = R | B,
|
RB = R | B,
|
||||||
RA = R | A,
|
RA = R | A,
|
||||||
GB = G | B,
|
GB = G | B,
|
||||||
GA = G | A,
|
GA = G | A,
|
||||||
BA = B | A,
|
BA = B | A,
|
||||||
|
|
||||||
RGB = R | G | B,
|
RGB = R | G | B,
|
||||||
RGA = R | G | A,
|
RGA = R | G | A,
|
||||||
GBA = G | B | A,
|
GBA = G | B | A,
|
||||||
|
|
||||||
RGBA = R | G | B | A,
|
RGBA = R | G | B | A,
|
||||||
None = 0
|
None = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum ShaderStageType
|
public enum ShaderStageType
|
||||||
{
|
{
|
||||||
Vertex,
|
Vertex,
|
||||||
Fragment
|
Fragment
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum Filter
|
public enum Filter
|
||||||
{
|
{
|
||||||
Nearest,
|
Nearest,
|
||||||
Linear,
|
Linear,
|
||||||
Cubic
|
Cubic
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum SamplerMipmapMode
|
public enum SamplerMipmapMode
|
||||||
{
|
{
|
||||||
Nearest,
|
Nearest,
|
||||||
Linear
|
Linear
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum SamplerAddressMode
|
public enum SamplerAddressMode
|
||||||
{
|
{
|
||||||
Repeat,
|
Repeat,
|
||||||
MirroredRepeat,
|
MirroredRepeat,
|
||||||
ClampToEdge,
|
ClampToEdge,
|
||||||
ClampToBorder
|
ClampToBorder
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum BorderColor
|
public enum BorderColor
|
||||||
{
|
{
|
||||||
FloatTransparentBlack,
|
FloatTransparentBlack,
|
||||||
IntTransparentBlack,
|
IntTransparentBlack,
|
||||||
FloatOpaqueBlack,
|
FloatOpaqueBlack,
|
||||||
IntOpaqueBlack,
|
IntOpaqueBlack,
|
||||||
FloatOpaqueWhite,
|
FloatOpaqueWhite,
|
||||||
IntOpaqueWhite
|
IntOpaqueWhite
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,115 +6,115 @@ using System.Runtime.InteropServices;
|
||||||
*/
|
*/
|
||||||
namespace MoonWorks.Graphics
|
namespace MoonWorks.Graphics
|
||||||
{
|
{
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public struct DepthStencilValue
|
public struct DepthStencilValue
|
||||||
{
|
{
|
||||||
public float Depth;
|
public float Depth;
|
||||||
public uint Stencil;
|
public uint Stencil;
|
||||||
|
|
||||||
// FIXME: can we do an unsafe cast somehow?
|
// FIXME: can we do an unsafe cast somehow?
|
||||||
public Refresh.DepthStencilValue ToRefresh()
|
public Refresh.DepthStencilValue ToRefresh()
|
||||||
{
|
{
|
||||||
return new Refresh.DepthStencilValue
|
return new Refresh.DepthStencilValue
|
||||||
{
|
{
|
||||||
depth = Depth,
|
depth = Depth,
|
||||||
stencil = Stencil
|
stencil = Stencil
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public struct Rect
|
public struct Rect
|
||||||
{
|
{
|
||||||
public int X;
|
public int X;
|
||||||
public int Y;
|
public int Y;
|
||||||
public int W;
|
public int W;
|
||||||
public int H;
|
public int H;
|
||||||
|
|
||||||
// FIXME: can we do an unsafe cast somehow?
|
// FIXME: can we do an unsafe cast somehow?
|
||||||
public Refresh.Rect ToRefresh()
|
public Refresh.Rect ToRefresh()
|
||||||
{
|
{
|
||||||
return new Refresh.Rect
|
return new Refresh.Rect
|
||||||
{
|
{
|
||||||
x = X,
|
x = X,
|
||||||
y = Y,
|
y = Y,
|
||||||
w = W,
|
w = W,
|
||||||
h = H
|
h = H
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public struct Viewport
|
public struct Viewport
|
||||||
{
|
{
|
||||||
public float X;
|
public float X;
|
||||||
public float Y;
|
public float Y;
|
||||||
public float W;
|
public float W;
|
||||||
public float H;
|
public float H;
|
||||||
public float MinDepth;
|
public float MinDepth;
|
||||||
public float MaxDepth;
|
public float MaxDepth;
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public struct VertexBinding
|
public struct VertexBinding
|
||||||
{
|
{
|
||||||
public uint Binding;
|
public uint Binding;
|
||||||
public uint Stride;
|
public uint Stride;
|
||||||
public VertexInputRate InputRate;
|
public VertexInputRate InputRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public struct VertexAttribute
|
public struct VertexAttribute
|
||||||
{
|
{
|
||||||
public uint Location;
|
public uint Location;
|
||||||
public uint Binding;
|
public uint Binding;
|
||||||
public VertexElementFormat Format;
|
public VertexElementFormat Format;
|
||||||
public uint Offset;
|
public uint Offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public struct ColorTargetDescription
|
public struct ColorTargetDescription
|
||||||
{
|
{
|
||||||
public TextureFormat Format;
|
public TextureFormat Format;
|
||||||
public SampleCount MultisampleCount;
|
public SampleCount MultisampleCount;
|
||||||
public LoadOp LoadOp;
|
public LoadOp LoadOp;
|
||||||
public StoreOp StoreOp;
|
public StoreOp StoreOp;
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public struct DepthStencilTargetDescription
|
public struct DepthStencilTargetDescription
|
||||||
{
|
{
|
||||||
public TextureFormat Format;
|
public TextureFormat Format;
|
||||||
public LoadOp LoadOp;
|
public LoadOp LoadOp;
|
||||||
public StoreOp StoreOp;
|
public StoreOp StoreOp;
|
||||||
public LoadOp StencilLoadOp;
|
public LoadOp StencilLoadOp;
|
||||||
public StoreOp StencilStoreOp;
|
public StoreOp StencilStoreOp;
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public struct StencilOpState
|
public struct StencilOpState
|
||||||
{
|
{
|
||||||
public StencilOp FailOp;
|
public StencilOp FailOp;
|
||||||
public StencilOp PassOp;
|
public StencilOp PassOp;
|
||||||
public StencilOp DepthFailOp;
|
public StencilOp DepthFailOp;
|
||||||
public CompareOp CompareOp;
|
public CompareOp CompareOp;
|
||||||
public uint CompareMask;
|
public uint CompareMask;
|
||||||
public uint WriteMask;
|
public uint WriteMask;
|
||||||
public uint Reference;
|
public uint Reference;
|
||||||
|
|
||||||
// FIXME: can we do an explicit cast here?
|
// FIXME: can we do an explicit cast here?
|
||||||
public Refresh.StencilOpState ToRefresh()
|
public Refresh.StencilOpState ToRefresh()
|
||||||
{
|
{
|
||||||
return new Refresh.StencilOpState
|
return new Refresh.StencilOpState
|
||||||
{
|
{
|
||||||
failOp = (Refresh.StencilOp)FailOp,
|
failOp = (Refresh.StencilOp) FailOp,
|
||||||
passOp = (Refresh.StencilOp)PassOp,
|
passOp = (Refresh.StencilOp) PassOp,
|
||||||
depthFailOp = (Refresh.StencilOp)DepthFailOp,
|
depthFailOp = (Refresh.StencilOp) DepthFailOp,
|
||||||
compareOp = (Refresh.CompareOp)CompareOp,
|
compareOp = (Refresh.CompareOp) CompareOp,
|
||||||
compareMask = CompareMask,
|
compareMask = CompareMask,
|
||||||
writeMask = WriteMask,
|
writeMask = WriteMask,
|
||||||
reference = Reference
|
reference = Reference
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,55 +1,55 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using RefreshCS;
|
using RefreshCS;
|
||||||
|
|
||||||
namespace MoonWorks.Graphics
|
namespace MoonWorks.Graphics
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Buffers are generic data containers that can be used by the GPU.
|
/// Buffers are generic data containers that can be used by the GPU.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Buffer : GraphicsResource
|
public class Buffer : GraphicsResource
|
||||||
{
|
{
|
||||||
protected override Action<IntPtr, IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroyBuffer;
|
protected override Action<IntPtr, IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroyBuffer;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a buffer.
|
/// Creates a buffer.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="device">An initialized GraphicsDevice.</param>
|
/// <param name="device">An initialized GraphicsDevice.</param>
|
||||||
/// <param name="usageFlags">Specifies how the buffer will be used.</param>
|
/// <param name="usageFlags">Specifies how the buffer will be used.</param>
|
||||||
/// <param name="sizeInBytes">The length of the array. Cannot be resized.</param>
|
/// <param name="sizeInBytes">The length of the array. Cannot be resized.</param>
|
||||||
public Buffer(
|
public Buffer(
|
||||||
GraphicsDevice device,
|
GraphicsDevice device,
|
||||||
BufferUsageFlags usageFlags,
|
BufferUsageFlags usageFlags,
|
||||||
uint sizeInBytes
|
uint sizeInBytes
|
||||||
) : base(device)
|
) : base(device)
|
||||||
{
|
{
|
||||||
Handle = Refresh.Refresh_CreateBuffer(
|
Handle = Refresh.Refresh_CreateBuffer(
|
||||||
device.Handle,
|
device.Handle,
|
||||||
(Refresh.BufferUsageFlags) usageFlags,
|
(Refresh.BufferUsageFlags) usageFlags,
|
||||||
sizeInBytes
|
sizeInBytes
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reads data out of a buffer and into an array.
|
/// Reads data out of a buffer and into an array.
|
||||||
/// This operation is only guaranteed to read up-to-date data if GraphicsDevice.Wait is called first.
|
/// This operation is only guaranteed to read up-to-date data if GraphicsDevice.Wait is called first.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="data">The array that data will be copied to.</param>
|
/// <param name="data">The array that data will be copied to.</param>
|
||||||
/// <param name="dataLengthInBytes">The length of the data to read.</param>
|
/// <param name="dataLengthInBytes">The length of the data to read.</param>
|
||||||
public unsafe void GetData<T>(
|
public unsafe void GetData<T>(
|
||||||
T[] data,
|
T[] data,
|
||||||
uint dataLengthInBytes
|
uint dataLengthInBytes
|
||||||
) where T : unmanaged
|
) where T : unmanaged
|
||||||
{
|
{
|
||||||
fixed (T* ptr = &data[0])
|
fixed (T* ptr = &data[0])
|
||||||
{
|
{
|
||||||
Refresh.Refresh_GetBufferData(
|
Refresh.Refresh_GetBufferData(
|
||||||
Device.Handle,
|
Device.Handle,
|
||||||
Handle,
|
Handle,
|
||||||
(IntPtr)ptr,
|
(IntPtr) ptr,
|
||||||
dataLengthInBytes
|
dataLengthInBytes
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,41 +4,42 @@ using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace MoonWorks.Graphics
|
namespace MoonWorks.Graphics
|
||||||
{
|
{
|
||||||
public class ComputePipeline : GraphicsResource
|
public class ComputePipeline : GraphicsResource
|
||||||
{
|
{
|
||||||
protected override Action<IntPtr, IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroyComputePipeline;
|
protected override Action<IntPtr, IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroyComputePipeline;
|
||||||
|
|
||||||
public ShaderStageState ComputeShaderState { get; }
|
public ShaderStageState ComputeShaderState { get; }
|
||||||
|
|
||||||
public unsafe ComputePipeline(
|
public unsafe ComputePipeline(
|
||||||
GraphicsDevice device,
|
GraphicsDevice device,
|
||||||
ShaderStageState computeShaderState,
|
ShaderStageState computeShaderState,
|
||||||
uint bufferBindingCount,
|
uint bufferBindingCount,
|
||||||
uint imageBindingCount
|
uint imageBindingCount
|
||||||
) : base(device) {
|
) : base(device)
|
||||||
var computePipelineLayoutCreateInfo = new Refresh.ComputePipelineLayoutCreateInfo
|
{
|
||||||
{
|
var computePipelineLayoutCreateInfo = new Refresh.ComputePipelineLayoutCreateInfo
|
||||||
bufferBindingCount = bufferBindingCount,
|
{
|
||||||
imageBindingCount = imageBindingCount
|
bufferBindingCount = bufferBindingCount,
|
||||||
};
|
imageBindingCount = imageBindingCount
|
||||||
|
};
|
||||||
|
|
||||||
var computePipelineCreateInfo = new Refresh.ComputePipelineCreateInfo
|
var computePipelineCreateInfo = new Refresh.ComputePipelineCreateInfo
|
||||||
{
|
{
|
||||||
pipelineLayoutCreateInfo = computePipelineLayoutCreateInfo,
|
pipelineLayoutCreateInfo = computePipelineLayoutCreateInfo,
|
||||||
computeShaderState = new Refresh.ShaderStageState
|
computeShaderState = new Refresh.ShaderStageState
|
||||||
{
|
{
|
||||||
entryPointName = computeShaderState.EntryPointName,
|
entryPointName = computeShaderState.EntryPointName,
|
||||||
shaderModule = computeShaderState.ShaderModule.Handle,
|
shaderModule = computeShaderState.ShaderModule.Handle,
|
||||||
uniformBufferSize = computeShaderState.UniformBufferSize
|
uniformBufferSize = computeShaderState.UniformBufferSize
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Handle = Refresh.Refresh_CreateComputePipeline(
|
Handle = Refresh.Refresh_CreateComputePipeline(
|
||||||
device.Handle,
|
device.Handle,
|
||||||
computePipelineCreateInfo
|
computePipelineCreateInfo
|
||||||
);
|
);
|
||||||
|
|
||||||
ComputeShaderState = computeShaderState;
|
ComputeShaderState = computeShaderState;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,81 +1,81 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using RefreshCS;
|
using RefreshCS;
|
||||||
|
|
||||||
namespace MoonWorks.Graphics
|
namespace MoonWorks.Graphics
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A framebuffer is a collection of render targets that is rendered to during a render pass.
|
/// A framebuffer is a collection of render targets that is rendered to during a render pass.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Framebuffer : GraphicsResource
|
public class Framebuffer : GraphicsResource
|
||||||
{
|
{
|
||||||
protected override Action<IntPtr, IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroyFramebuffer;
|
protected override Action<IntPtr, IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroyFramebuffer;
|
||||||
|
|
||||||
public RenderTarget DepthStencilTarget { get; }
|
public RenderTarget DepthStencilTarget { get; }
|
||||||
|
|
||||||
private RenderTarget[] colorTargets { get; }
|
private RenderTarget[] colorTargets { get; }
|
||||||
public IEnumerable<RenderTarget> ColorTargets => colorTargets;
|
public IEnumerable<RenderTarget> ColorTargets => colorTargets;
|
||||||
|
|
||||||
public RenderPass RenderPass { get; }
|
public RenderPass RenderPass { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a framebuffer.
|
/// Creates a framebuffer.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="device">An initialized GraphicsDevice.</param>
|
/// <param name="device">An initialized GraphicsDevice.</param>
|
||||||
/// <param name="width">The width of the framebuffer.</param>
|
/// <param name="width">The width of the framebuffer.</param>
|
||||||
/// <param name="height">The height of the framebuffer.</param>
|
/// <param name="height">The height of the framebuffer.</param>
|
||||||
/// <param name="renderPass">The reference render pass for the framebuffer.</param>
|
/// <param name="renderPass">The reference render pass for the framebuffer.</param>
|
||||||
/// <param name="depthStencilTarget">The depth stencil target. Can be null.</param>
|
/// <param name="depthStencilTarget">The depth stencil target. Can be null.</param>
|
||||||
/// <param name="colorTargets">Anywhere from 0-4 color targets can be provided.</param>
|
/// <param name="colorTargets">Anywhere from 0-4 color targets can be provided.</param>
|
||||||
public unsafe Framebuffer(
|
public unsafe Framebuffer(
|
||||||
GraphicsDevice device,
|
GraphicsDevice device,
|
||||||
uint width,
|
uint width,
|
||||||
uint height,
|
uint height,
|
||||||
RenderPass renderPass,
|
RenderPass renderPass,
|
||||||
RenderTarget depthStencilTarget,
|
RenderTarget depthStencilTarget,
|
||||||
params RenderTarget[] colorTargets
|
params RenderTarget[] colorTargets
|
||||||
) : base(device)
|
) : base(device)
|
||||||
{
|
{
|
||||||
IntPtr[] colorTargetHandles = new IntPtr[colorTargets.Length];
|
IntPtr[] colorTargetHandles = new IntPtr[colorTargets.Length];
|
||||||
for (var i = 0; i < colorTargets.Length; i += 1)
|
for (var i = 0; i < colorTargets.Length; i += 1)
|
||||||
{
|
{
|
||||||
colorTargetHandles[i] = colorTargets[i].Handle;
|
colorTargetHandles[i] = colorTargets[i].Handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
IntPtr depthStencilTargetHandle;
|
IntPtr depthStencilTargetHandle;
|
||||||
if (depthStencilTarget == null)
|
if (depthStencilTarget == null)
|
||||||
{
|
{
|
||||||
depthStencilTargetHandle = IntPtr.Zero;
|
depthStencilTargetHandle = IntPtr.Zero;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
depthStencilTargetHandle = depthStencilTarget.Handle;
|
depthStencilTargetHandle = depthStencilTarget.Handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
fixed (IntPtr* colorTargetHandlesPtr = colorTargetHandles)
|
fixed (IntPtr* colorTargetHandlesPtr = colorTargetHandles)
|
||||||
{
|
{
|
||||||
Refresh.FramebufferCreateInfo framebufferCreateInfo = new Refresh.FramebufferCreateInfo
|
Refresh.FramebufferCreateInfo framebufferCreateInfo = new Refresh.FramebufferCreateInfo
|
||||||
{
|
{
|
||||||
width = width,
|
width = width,
|
||||||
height = height,
|
height = height,
|
||||||
colorTargetCount = (uint) colorTargets.Length,
|
colorTargetCount = (uint) colorTargets.Length,
|
||||||
pColorTargets = (IntPtr) colorTargetHandlesPtr,
|
pColorTargets = (IntPtr) colorTargetHandlesPtr,
|
||||||
depthStencilTarget = depthStencilTargetHandle,
|
depthStencilTarget = depthStencilTargetHandle,
|
||||||
renderPass = renderPass.Handle
|
renderPass = renderPass.Handle
|
||||||
};
|
};
|
||||||
|
|
||||||
Handle = Refresh.Refresh_CreateFramebuffer(device.Handle, framebufferCreateInfo);
|
Handle = Refresh.Refresh_CreateFramebuffer(device.Handle, framebufferCreateInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
DepthStencilTarget = depthStencilTarget;
|
DepthStencilTarget = depthStencilTarget;
|
||||||
|
|
||||||
this.colorTargets = new RenderTarget[colorTargets.Length];
|
this.colorTargets = new RenderTarget[colorTargets.Length];
|
||||||
for (var i = 0; i < colorTargets.Length; i++)
|
for (var i = 0; i < colorTargets.Length; i++)
|
||||||
{
|
{
|
||||||
this.colorTargets[i] = colorTargets[i];
|
this.colorTargets[i] = colorTargets[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderPass = renderPass;
|
RenderPass = renderPass;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,132 +1,132 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using RefreshCS;
|
using RefreshCS;
|
||||||
|
|
||||||
namespace MoonWorks.Graphics
|
namespace MoonWorks.Graphics
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Graphics pipelines encapsulate all of the render state in a single object.
|
/// Graphics pipelines encapsulate all of the render state in a single object.
|
||||||
/// These pipelines are bound before draw calls are issued.
|
/// These pipelines are bound before draw calls are issued.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class GraphicsPipeline : GraphicsResource
|
public class GraphicsPipeline : GraphicsResource
|
||||||
{
|
{
|
||||||
protected override Action<IntPtr, IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroyGraphicsPipeline;
|
protected override Action<IntPtr, IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroyGraphicsPipeline;
|
||||||
|
|
||||||
public ShaderStageState VertexShaderState { get; }
|
public ShaderStageState VertexShaderState { get; }
|
||||||
public ShaderStageState FragmentShaderState { get; }
|
public ShaderStageState FragmentShaderState { get; }
|
||||||
public RenderPass RenderPass { get; }
|
public RenderPass RenderPass { get; }
|
||||||
|
|
||||||
public unsafe GraphicsPipeline(
|
public unsafe GraphicsPipeline(
|
||||||
GraphicsDevice device,
|
GraphicsDevice device,
|
||||||
in GraphicsPipelineCreateInfo graphicsPipelineCreateInfo
|
in GraphicsPipelineCreateInfo graphicsPipelineCreateInfo
|
||||||
) : base(device)
|
) : base(device)
|
||||||
{
|
{
|
||||||
ColorBlendState colorBlendState = graphicsPipelineCreateInfo.ColorBlendState;
|
ColorBlendState colorBlendState = graphicsPipelineCreateInfo.ColorBlendState;
|
||||||
DepthStencilState depthStencilState = graphicsPipelineCreateInfo.DepthStencilState;
|
DepthStencilState depthStencilState = graphicsPipelineCreateInfo.DepthStencilState;
|
||||||
ShaderStageState vertexShaderState = graphicsPipelineCreateInfo.VertexShaderState;
|
ShaderStageState vertexShaderState = graphicsPipelineCreateInfo.VertexShaderState;
|
||||||
ShaderStageState fragmentShaderState = graphicsPipelineCreateInfo.FragmentShaderState;
|
ShaderStageState fragmentShaderState = graphicsPipelineCreateInfo.FragmentShaderState;
|
||||||
MultisampleState multisampleState = graphicsPipelineCreateInfo.MultisampleState;
|
MultisampleState multisampleState = graphicsPipelineCreateInfo.MultisampleState;
|
||||||
GraphicsPipelineLayoutInfo pipelineLayoutInfo = graphicsPipelineCreateInfo.PipelineLayoutInfo;
|
GraphicsPipelineLayoutInfo pipelineLayoutInfo = graphicsPipelineCreateInfo.PipelineLayoutInfo;
|
||||||
RasterizerState rasterizerState = graphicsPipelineCreateInfo.RasterizerState;
|
RasterizerState rasterizerState = graphicsPipelineCreateInfo.RasterizerState;
|
||||||
PrimitiveType primitiveType = graphicsPipelineCreateInfo.PrimitiveType;
|
PrimitiveType primitiveType = graphicsPipelineCreateInfo.PrimitiveType;
|
||||||
VertexInputState vertexInputState = graphicsPipelineCreateInfo.VertexInputState;
|
VertexInputState vertexInputState = graphicsPipelineCreateInfo.VertexInputState;
|
||||||
ViewportState viewportState = graphicsPipelineCreateInfo.ViewportState;
|
ViewportState viewportState = graphicsPipelineCreateInfo.ViewportState;
|
||||||
RenderPass renderPass = graphicsPipelineCreateInfo.RenderPass;
|
RenderPass renderPass = graphicsPipelineCreateInfo.RenderPass;
|
||||||
|
|
||||||
var vertexAttributesHandle = GCHandle.Alloc(
|
var vertexAttributesHandle = GCHandle.Alloc(
|
||||||
vertexInputState.VertexAttributes,
|
vertexInputState.VertexAttributes,
|
||||||
GCHandleType.Pinned
|
GCHandleType.Pinned
|
||||||
);
|
);
|
||||||
var vertexBindingsHandle = GCHandle.Alloc(
|
var vertexBindingsHandle = GCHandle.Alloc(
|
||||||
vertexInputState.VertexBindings,
|
vertexInputState.VertexBindings,
|
||||||
GCHandleType.Pinned
|
GCHandleType.Pinned
|
||||||
);
|
);
|
||||||
var viewportHandle = GCHandle.Alloc(
|
var viewportHandle = GCHandle.Alloc(
|
||||||
viewportState.Viewports,
|
viewportState.Viewports,
|
||||||
GCHandleType.Pinned
|
GCHandleType.Pinned
|
||||||
);
|
);
|
||||||
var scissorHandle = GCHandle.Alloc(
|
var scissorHandle = GCHandle.Alloc(
|
||||||
viewportState.Scissors,
|
viewportState.Scissors,
|
||||||
GCHandleType.Pinned
|
GCHandleType.Pinned
|
||||||
);
|
);
|
||||||
|
|
||||||
var colorTargetBlendStates = stackalloc Refresh.ColorTargetBlendState[
|
var colorTargetBlendStates = stackalloc Refresh.ColorTargetBlendState[
|
||||||
colorBlendState.ColorTargetBlendStates.Length
|
colorBlendState.ColorTargetBlendStates.Length
|
||||||
];
|
];
|
||||||
|
|
||||||
for (var i = 0; i < colorBlendState.ColorTargetBlendStates.Length; i += 1)
|
for (var i = 0; i < colorBlendState.ColorTargetBlendStates.Length; i += 1)
|
||||||
{
|
{
|
||||||
colorTargetBlendStates[i] = colorBlendState.ColorTargetBlendStates[i].ToRefreshColorTargetBlendState();
|
colorTargetBlendStates[i] = colorBlendState.ColorTargetBlendStates[i].ToRefreshColorTargetBlendState();
|
||||||
}
|
}
|
||||||
|
|
||||||
Refresh.GraphicsPipelineCreateInfo refreshGraphicsPipelineCreateInfo;
|
Refresh.GraphicsPipelineCreateInfo refreshGraphicsPipelineCreateInfo;
|
||||||
|
|
||||||
refreshGraphicsPipelineCreateInfo.colorBlendState.logicOpEnable = Conversions.BoolToByte(colorBlendState.LogicOpEnable);
|
refreshGraphicsPipelineCreateInfo.colorBlendState.logicOpEnable = Conversions.BoolToByte(colorBlendState.LogicOpEnable);
|
||||||
refreshGraphicsPipelineCreateInfo.colorBlendState.logicOp = (Refresh.LogicOp) colorBlendState.LogicOp;
|
refreshGraphicsPipelineCreateInfo.colorBlendState.logicOp = (Refresh.LogicOp) colorBlendState.LogicOp;
|
||||||
refreshGraphicsPipelineCreateInfo.colorBlendState.blendStates = (IntPtr) colorTargetBlendStates;
|
refreshGraphicsPipelineCreateInfo.colorBlendState.blendStates = (IntPtr) colorTargetBlendStates;
|
||||||
refreshGraphicsPipelineCreateInfo.colorBlendState.blendStateCount = (uint) colorBlendState.ColorTargetBlendStates.Length;
|
refreshGraphicsPipelineCreateInfo.colorBlendState.blendStateCount = (uint) colorBlendState.ColorTargetBlendStates.Length;
|
||||||
refreshGraphicsPipelineCreateInfo.colorBlendState.blendConstants[0] = colorBlendState.BlendConstants.R;
|
refreshGraphicsPipelineCreateInfo.colorBlendState.blendConstants[0] = colorBlendState.BlendConstants.R;
|
||||||
refreshGraphicsPipelineCreateInfo.colorBlendState.blendConstants[1] = colorBlendState.BlendConstants.G;
|
refreshGraphicsPipelineCreateInfo.colorBlendState.blendConstants[1] = colorBlendState.BlendConstants.G;
|
||||||
refreshGraphicsPipelineCreateInfo.colorBlendState.blendConstants[2] = colorBlendState.BlendConstants.B;
|
refreshGraphicsPipelineCreateInfo.colorBlendState.blendConstants[2] = colorBlendState.BlendConstants.B;
|
||||||
refreshGraphicsPipelineCreateInfo.colorBlendState.blendConstants[3] = colorBlendState.BlendConstants.A;
|
refreshGraphicsPipelineCreateInfo.colorBlendState.blendConstants[3] = colorBlendState.BlendConstants.A;
|
||||||
|
|
||||||
refreshGraphicsPipelineCreateInfo.depthStencilState.backStencilState = depthStencilState.BackStencilState.ToRefresh();
|
refreshGraphicsPipelineCreateInfo.depthStencilState.backStencilState = depthStencilState.BackStencilState.ToRefresh();
|
||||||
refreshGraphicsPipelineCreateInfo.depthStencilState.compareOp = (Refresh.CompareOp) depthStencilState.CompareOp;
|
refreshGraphicsPipelineCreateInfo.depthStencilState.compareOp = (Refresh.CompareOp) depthStencilState.CompareOp;
|
||||||
refreshGraphicsPipelineCreateInfo.depthStencilState.depthBoundsTestEnable = Conversions.BoolToByte(depthStencilState.DepthBoundsTestEnable);
|
refreshGraphicsPipelineCreateInfo.depthStencilState.depthBoundsTestEnable = Conversions.BoolToByte(depthStencilState.DepthBoundsTestEnable);
|
||||||
refreshGraphicsPipelineCreateInfo.depthStencilState.depthTestEnable = Conversions.BoolToByte(depthStencilState.DepthTestEnable);
|
refreshGraphicsPipelineCreateInfo.depthStencilState.depthTestEnable = Conversions.BoolToByte(depthStencilState.DepthTestEnable);
|
||||||
refreshGraphicsPipelineCreateInfo.depthStencilState.depthWriteEnable = Conversions.BoolToByte(depthStencilState.DepthWriteEnable);
|
refreshGraphicsPipelineCreateInfo.depthStencilState.depthWriteEnable = Conversions.BoolToByte(depthStencilState.DepthWriteEnable);
|
||||||
refreshGraphicsPipelineCreateInfo.depthStencilState.frontStencilState = depthStencilState.FrontStencilState.ToRefresh();
|
refreshGraphicsPipelineCreateInfo.depthStencilState.frontStencilState = depthStencilState.FrontStencilState.ToRefresh();
|
||||||
refreshGraphicsPipelineCreateInfo.depthStencilState.maxDepthBounds = depthStencilState.MaxDepthBounds;
|
refreshGraphicsPipelineCreateInfo.depthStencilState.maxDepthBounds = depthStencilState.MaxDepthBounds;
|
||||||
refreshGraphicsPipelineCreateInfo.depthStencilState.minDepthBounds = depthStencilState.MinDepthBounds;
|
refreshGraphicsPipelineCreateInfo.depthStencilState.minDepthBounds = depthStencilState.MinDepthBounds;
|
||||||
refreshGraphicsPipelineCreateInfo.depthStencilState.stencilTestEnable = Conversions.BoolToByte(depthStencilState.StencilTestEnable);
|
refreshGraphicsPipelineCreateInfo.depthStencilState.stencilTestEnable = Conversions.BoolToByte(depthStencilState.StencilTestEnable);
|
||||||
|
|
||||||
refreshGraphicsPipelineCreateInfo.vertexShaderState.entryPointName = vertexShaderState.EntryPointName;
|
refreshGraphicsPipelineCreateInfo.vertexShaderState.entryPointName = vertexShaderState.EntryPointName;
|
||||||
refreshGraphicsPipelineCreateInfo.vertexShaderState.shaderModule = vertexShaderState.ShaderModule.Handle;
|
refreshGraphicsPipelineCreateInfo.vertexShaderState.shaderModule = vertexShaderState.ShaderModule.Handle;
|
||||||
refreshGraphicsPipelineCreateInfo.vertexShaderState.uniformBufferSize = vertexShaderState.UniformBufferSize;
|
refreshGraphicsPipelineCreateInfo.vertexShaderState.uniformBufferSize = vertexShaderState.UniformBufferSize;
|
||||||
|
|
||||||
refreshGraphicsPipelineCreateInfo.fragmentShaderState.entryPointName = fragmentShaderState.EntryPointName;
|
refreshGraphicsPipelineCreateInfo.fragmentShaderState.entryPointName = fragmentShaderState.EntryPointName;
|
||||||
refreshGraphicsPipelineCreateInfo.fragmentShaderState.shaderModule = fragmentShaderState.ShaderModule.Handle;
|
refreshGraphicsPipelineCreateInfo.fragmentShaderState.shaderModule = fragmentShaderState.ShaderModule.Handle;
|
||||||
refreshGraphicsPipelineCreateInfo.fragmentShaderState.uniformBufferSize = fragmentShaderState.UniformBufferSize;
|
refreshGraphicsPipelineCreateInfo.fragmentShaderState.uniformBufferSize = fragmentShaderState.UniformBufferSize;
|
||||||
|
|
||||||
refreshGraphicsPipelineCreateInfo.multisampleState.multisampleCount = (Refresh.SampleCount)multisampleState.MultisampleCount;
|
refreshGraphicsPipelineCreateInfo.multisampleState.multisampleCount = (Refresh.SampleCount) multisampleState.MultisampleCount;
|
||||||
refreshGraphicsPipelineCreateInfo.multisampleState.sampleMask = multisampleState.SampleMask;
|
refreshGraphicsPipelineCreateInfo.multisampleState.sampleMask = multisampleState.SampleMask;
|
||||||
|
|
||||||
refreshGraphicsPipelineCreateInfo.pipelineLayoutCreateInfo.vertexSamplerBindingCount = pipelineLayoutInfo.VertexSamplerBindingCount;
|
refreshGraphicsPipelineCreateInfo.pipelineLayoutCreateInfo.vertexSamplerBindingCount = pipelineLayoutInfo.VertexSamplerBindingCount;
|
||||||
refreshGraphicsPipelineCreateInfo.pipelineLayoutCreateInfo.fragmentSamplerBindingCount = pipelineLayoutInfo.FragmentSamplerBindingCount;
|
refreshGraphicsPipelineCreateInfo.pipelineLayoutCreateInfo.fragmentSamplerBindingCount = pipelineLayoutInfo.FragmentSamplerBindingCount;
|
||||||
|
|
||||||
refreshGraphicsPipelineCreateInfo.rasterizerState.cullMode = (Refresh.CullMode)rasterizerState.CullMode;
|
refreshGraphicsPipelineCreateInfo.rasterizerState.cullMode = (Refresh.CullMode) rasterizerState.CullMode;
|
||||||
refreshGraphicsPipelineCreateInfo.rasterizerState.depthBiasClamp = rasterizerState.DepthBiasClamp;
|
refreshGraphicsPipelineCreateInfo.rasterizerState.depthBiasClamp = rasterizerState.DepthBiasClamp;
|
||||||
refreshGraphicsPipelineCreateInfo.rasterizerState.depthBiasConstantFactor = rasterizerState.DepthBiasConstantFactor;
|
refreshGraphicsPipelineCreateInfo.rasterizerState.depthBiasConstantFactor = rasterizerState.DepthBiasConstantFactor;
|
||||||
refreshGraphicsPipelineCreateInfo.rasterizerState.depthBiasEnable = Conversions.BoolToByte(rasterizerState.DepthBiasEnable);
|
refreshGraphicsPipelineCreateInfo.rasterizerState.depthBiasEnable = Conversions.BoolToByte(rasterizerState.DepthBiasEnable);
|
||||||
refreshGraphicsPipelineCreateInfo.rasterizerState.depthBiasSlopeFactor = rasterizerState.DepthBiasSlopeFactor;
|
refreshGraphicsPipelineCreateInfo.rasterizerState.depthBiasSlopeFactor = rasterizerState.DepthBiasSlopeFactor;
|
||||||
refreshGraphicsPipelineCreateInfo.rasterizerState.depthClampEnable = Conversions.BoolToByte(rasterizerState.DepthClampEnable);
|
refreshGraphicsPipelineCreateInfo.rasterizerState.depthClampEnable = Conversions.BoolToByte(rasterizerState.DepthClampEnable);
|
||||||
refreshGraphicsPipelineCreateInfo.rasterizerState.fillMode = (Refresh.FillMode)rasterizerState.FillMode;
|
refreshGraphicsPipelineCreateInfo.rasterizerState.fillMode = (Refresh.FillMode) rasterizerState.FillMode;
|
||||||
refreshGraphicsPipelineCreateInfo.rasterizerState.frontFace = (Refresh.FrontFace)rasterizerState.FrontFace;
|
refreshGraphicsPipelineCreateInfo.rasterizerState.frontFace = (Refresh.FrontFace) rasterizerState.FrontFace;
|
||||||
refreshGraphicsPipelineCreateInfo.rasterizerState.lineWidth = rasterizerState.LineWidth;
|
refreshGraphicsPipelineCreateInfo.rasterizerState.lineWidth = rasterizerState.LineWidth;
|
||||||
|
|
||||||
refreshGraphicsPipelineCreateInfo.vertexInputState.vertexAttributes = vertexAttributesHandle.AddrOfPinnedObject();
|
refreshGraphicsPipelineCreateInfo.vertexInputState.vertexAttributes = vertexAttributesHandle.AddrOfPinnedObject();
|
||||||
refreshGraphicsPipelineCreateInfo.vertexInputState.vertexAttributeCount = (uint) vertexInputState.VertexAttributes.Length;
|
refreshGraphicsPipelineCreateInfo.vertexInputState.vertexAttributeCount = (uint) vertexInputState.VertexAttributes.Length;
|
||||||
refreshGraphicsPipelineCreateInfo.vertexInputState.vertexBindings = vertexBindingsHandle.AddrOfPinnedObject();
|
refreshGraphicsPipelineCreateInfo.vertexInputState.vertexBindings = vertexBindingsHandle.AddrOfPinnedObject();
|
||||||
refreshGraphicsPipelineCreateInfo.vertexInputState.vertexBindingCount = (uint) vertexInputState.VertexBindings.Length;
|
refreshGraphicsPipelineCreateInfo.vertexInputState.vertexBindingCount = (uint) vertexInputState.VertexBindings.Length;
|
||||||
|
|
||||||
refreshGraphicsPipelineCreateInfo.viewportState.viewports = viewportHandle.AddrOfPinnedObject();
|
refreshGraphicsPipelineCreateInfo.viewportState.viewports = viewportHandle.AddrOfPinnedObject();
|
||||||
refreshGraphicsPipelineCreateInfo.viewportState.viewportCount = (uint) viewportState.Viewports.Length;
|
refreshGraphicsPipelineCreateInfo.viewportState.viewportCount = (uint) viewportState.Viewports.Length;
|
||||||
refreshGraphicsPipelineCreateInfo.viewportState.scissors = scissorHandle.AddrOfPinnedObject();
|
refreshGraphicsPipelineCreateInfo.viewportState.scissors = scissorHandle.AddrOfPinnedObject();
|
||||||
refreshGraphicsPipelineCreateInfo.viewportState.scissorCount = (uint) viewportState.Scissors.Length;
|
refreshGraphicsPipelineCreateInfo.viewportState.scissorCount = (uint) viewportState.Scissors.Length;
|
||||||
|
|
||||||
refreshGraphicsPipelineCreateInfo.primitiveType = (Refresh.PrimitiveType) primitiveType;
|
refreshGraphicsPipelineCreateInfo.primitiveType = (Refresh.PrimitiveType) primitiveType;
|
||||||
refreshGraphicsPipelineCreateInfo.renderPass = renderPass.Handle;
|
refreshGraphicsPipelineCreateInfo.renderPass = renderPass.Handle;
|
||||||
|
|
||||||
Handle = Refresh.Refresh_CreateGraphicsPipeline(device.Handle, refreshGraphicsPipelineCreateInfo);
|
Handle = Refresh.Refresh_CreateGraphicsPipeline(device.Handle, refreshGraphicsPipelineCreateInfo);
|
||||||
|
|
||||||
vertexAttributesHandle.Free();
|
vertexAttributesHandle.Free();
|
||||||
vertexBindingsHandle.Free();
|
vertexBindingsHandle.Free();
|
||||||
viewportHandle.Free();
|
viewportHandle.Free();
|
||||||
scissorHandle.Free();
|
scissorHandle.Free();
|
||||||
|
|
||||||
VertexShaderState = vertexShaderState;
|
VertexShaderState = vertexShaderState;
|
||||||
FragmentShaderState = fragmentShaderState;
|
FragmentShaderState = fragmentShaderState;
|
||||||
RenderPass = renderPass;
|
RenderPass = renderPass;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,57 +3,57 @@ using RefreshCS;
|
||||||
|
|
||||||
namespace MoonWorks.Graphics
|
namespace MoonWorks.Graphics
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A render pass describes the kind of render targets that will be used in rendering.
|
/// A render pass describes the kind of render targets that will be used in rendering.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class RenderPass : GraphicsResource
|
public class RenderPass : GraphicsResource
|
||||||
{
|
{
|
||||||
protected override Action<IntPtr, IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroyRenderPass;
|
protected override Action<IntPtr, IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroyRenderPass;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a render pass using color target descriptions.
|
/// Creates a render pass using color target descriptions.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="device">An initialized GraphicsDevice.</param>
|
/// <param name="device">An initialized GraphicsDevice.</param>
|
||||||
/// <param name="colorTargetDescriptions">Up to 4 color target descriptions may be provided.</param>
|
/// <param name="colorTargetDescriptions">Up to 4 color target descriptions may be provided.</param>
|
||||||
public unsafe RenderPass(
|
public unsafe RenderPass(
|
||||||
GraphicsDevice device,
|
GraphicsDevice device,
|
||||||
params ColorTargetDescription[] colorTargetDescriptions
|
params ColorTargetDescription[] colorTargetDescriptions
|
||||||
) : base(device)
|
) : base(device)
|
||||||
{
|
{
|
||||||
fixed (ColorTargetDescription* ptr = colorTargetDescriptions)
|
fixed (ColorTargetDescription* ptr = colorTargetDescriptions)
|
||||||
{
|
{
|
||||||
Refresh.RenderPassCreateInfo renderPassCreateInfo;
|
Refresh.RenderPassCreateInfo renderPassCreateInfo;
|
||||||
renderPassCreateInfo.colorTargetCount = (uint) colorTargetDescriptions.Length;
|
renderPassCreateInfo.colorTargetCount = (uint) colorTargetDescriptions.Length;
|
||||||
renderPassCreateInfo.colorTargetDescriptions = (IntPtr) ptr;
|
renderPassCreateInfo.colorTargetDescriptions = (IntPtr) ptr;
|
||||||
renderPassCreateInfo.depthStencilTargetDescription = IntPtr.Zero;
|
renderPassCreateInfo.depthStencilTargetDescription = IntPtr.Zero;
|
||||||
|
|
||||||
Handle = Refresh.Refresh_CreateRenderPass(device.Handle, renderPassCreateInfo);
|
Handle = Refresh.Refresh_CreateRenderPass(device.Handle, renderPassCreateInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a render pass using a depth/stencil target description and optional color target descriptions.
|
/// Creates a render pass using a depth/stencil target description and optional color target descriptions.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="device">An initialized GraphicsDevice.</param>
|
/// <param name="device">An initialized GraphicsDevice.</param>
|
||||||
/// <param name="depthStencilTargetDescription">A depth/stencil target description.</param>
|
/// <param name="depthStencilTargetDescription">A depth/stencil target description.</param>
|
||||||
/// <param name="colorTargetDescriptions">Up to 4 color target descriptions may be provided.</param>
|
/// <param name="colorTargetDescriptions">Up to 4 color target descriptions may be provided.</param>
|
||||||
public unsafe RenderPass(
|
public unsafe RenderPass(
|
||||||
GraphicsDevice device,
|
GraphicsDevice device,
|
||||||
in DepthStencilTargetDescription depthStencilTargetDescription,
|
in DepthStencilTargetDescription depthStencilTargetDescription,
|
||||||
params ColorTargetDescription[] colorTargetDescriptions
|
params ColorTargetDescription[] colorTargetDescriptions
|
||||||
) : base(device)
|
) : base(device)
|
||||||
{
|
{
|
||||||
|
|
||||||
fixed (DepthStencilTargetDescription* depthStencilPtr = &depthStencilTargetDescription)
|
fixed (DepthStencilTargetDescription* depthStencilPtr = &depthStencilTargetDescription)
|
||||||
fixed (ColorTargetDescription* colorPtr = colorTargetDescriptions)
|
fixed (ColorTargetDescription* colorPtr = colorTargetDescriptions)
|
||||||
{
|
{
|
||||||
Refresh.RenderPassCreateInfo renderPassCreateInfo;
|
Refresh.RenderPassCreateInfo renderPassCreateInfo;
|
||||||
renderPassCreateInfo.colorTargetCount = (uint)colorTargetDescriptions.Length;
|
renderPassCreateInfo.colorTargetCount = (uint) colorTargetDescriptions.Length;
|
||||||
renderPassCreateInfo.colorTargetDescriptions = (IntPtr)colorPtr;
|
renderPassCreateInfo.colorTargetDescriptions = (IntPtr) colorPtr;
|
||||||
renderPassCreateInfo.depthStencilTargetDescription = (IntPtr) depthStencilPtr;
|
renderPassCreateInfo.depthStencilTargetDescription = (IntPtr) depthStencilPtr;
|
||||||
|
|
||||||
Handle = Refresh.Refresh_CreateRenderPass(device.Handle, renderPassCreateInfo);
|
Handle = Refresh.Refresh_CreateRenderPass(device.Handle, renderPassCreateInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,87 +3,89 @@ using RefreshCS;
|
||||||
|
|
||||||
namespace MoonWorks.Graphics
|
namespace MoonWorks.Graphics
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A render target is a structure that wraps a texture so that it can be rendered to.
|
/// A render target is a structure that wraps a texture so that it can be rendered to.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class RenderTarget : GraphicsResource
|
public class RenderTarget : GraphicsResource
|
||||||
{
|
{
|
||||||
public TextureSlice TextureSlice { get; }
|
public TextureSlice TextureSlice { get; }
|
||||||
public TextureFormat Format => TextureSlice.Texture.Format;
|
public TextureFormat Format => TextureSlice.Texture.Format;
|
||||||
|
|
||||||
protected override Action<IntPtr, IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroyRenderTarget;
|
protected override Action<IntPtr, IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroyRenderTarget;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a render target backed by a texture.
|
/// Creates a render target backed by a texture.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="device">An initialized GraphicsDevice.</param>
|
/// <param name="device">An initialized GraphicsDevice.</param>
|
||||||
/// <param name="width">The width of the render target.</param>
|
/// <param name="width">The width of the render target.</param>
|
||||||
/// <param name="height">The height of the render target.</param>
|
/// <param name="height">The height of the render target.</param>
|
||||||
/// <param name="format">The format of the render target.</param>
|
/// <param name="format">The format of the render target.</param>
|
||||||
/// <param name="canBeSampled">Whether the render target can be used by a sampler.</param>
|
/// <param name="canBeSampled">Whether the render target can be used by a sampler.</param>
|
||||||
/// <param name="sampleCount">The multisample count of the render target.</param>
|
/// <param name="sampleCount">The multisample count of the render target.</param>
|
||||||
/// <param name="levelCount">The mip level of the render target.</param>
|
/// <param name="levelCount">The mip level of the render target.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static RenderTarget CreateBackedRenderTarget(
|
public static RenderTarget CreateBackedRenderTarget(
|
||||||
GraphicsDevice device,
|
GraphicsDevice device,
|
||||||
uint width,
|
uint width,
|
||||||
uint height,
|
uint height,
|
||||||
TextureFormat format,
|
TextureFormat format,
|
||||||
bool canBeSampled,
|
bool canBeSampled,
|
||||||
SampleCount sampleCount = SampleCount.One,
|
SampleCount sampleCount = SampleCount.One,
|
||||||
uint levelCount = 1
|
uint levelCount = 1
|
||||||
) {
|
)
|
||||||
TextureUsageFlags flags = 0;
|
{
|
||||||
|
TextureUsageFlags flags = 0;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
format == TextureFormat.D16 ||
|
format == TextureFormat.D16 ||
|
||||||
format == TextureFormat.D32 ||
|
format == TextureFormat.D32 ||
|
||||||
format == TextureFormat.D16S8 ||
|
format == TextureFormat.D16S8 ||
|
||||||
format == TextureFormat.D32S8
|
format == TextureFormat.D32S8
|
||||||
) {
|
)
|
||||||
flags |= TextureUsageFlags.DepthStencilTarget;
|
{
|
||||||
}
|
flags |= TextureUsageFlags.DepthStencilTarget;
|
||||||
else
|
}
|
||||||
{
|
else
|
||||||
flags |= TextureUsageFlags.ColorTarget;
|
{
|
||||||
}
|
flags |= TextureUsageFlags.ColorTarget;
|
||||||
|
}
|
||||||
|
|
||||||
if (canBeSampled)
|
if (canBeSampled)
|
||||||
{
|
{
|
||||||
flags |= TextureUsageFlags.Sampler;
|
flags |= TextureUsageFlags.Sampler;
|
||||||
}
|
}
|
||||||
|
|
||||||
var texture = Texture.CreateTexture2D(
|
var texture = Texture.CreateTexture2D(
|
||||||
device,
|
device,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
format,
|
format,
|
||||||
flags,
|
flags,
|
||||||
sampleCount,
|
sampleCount,
|
||||||
levelCount
|
levelCount
|
||||||
);
|
);
|
||||||
|
|
||||||
return new RenderTarget(device, new TextureSlice(texture), sampleCount);
|
return new RenderTarget(device, new TextureSlice(texture), sampleCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a render target using a texture slice and an optional sample count.
|
/// Creates a render target using a texture slice and an optional sample count.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="device">An initialized GraphicsDevice.</param>
|
/// <param name="device">An initialized GraphicsDevice.</param>
|
||||||
/// <param name="textureSlice">The texture slice that will be rendered to.</param>
|
/// <param name="textureSlice">The texture slice that will be rendered to.</param>
|
||||||
/// <param name="sampleCount">The desired multisample count of the render target.</param>
|
/// <param name="sampleCount">The desired multisample count of the render target.</param>
|
||||||
public RenderTarget(
|
public RenderTarget(
|
||||||
GraphicsDevice device,
|
GraphicsDevice device,
|
||||||
in TextureSlice textureSlice,
|
in TextureSlice textureSlice,
|
||||||
SampleCount sampleCount = SampleCount.One
|
SampleCount sampleCount = SampleCount.One
|
||||||
) : base(device)
|
) : base(device)
|
||||||
{
|
{
|
||||||
Handle = Refresh.Refresh_CreateRenderTarget(
|
Handle = Refresh.Refresh_CreateRenderTarget(
|
||||||
device.Handle,
|
device.Handle,
|
||||||
textureSlice.ToRefreshTextureSlice(),
|
textureSlice.ToRefreshTextureSlice(),
|
||||||
(Refresh.SampleCount) sampleCount
|
(Refresh.SampleCount) sampleCount
|
||||||
);
|
);
|
||||||
TextureSlice = textureSlice;
|
TextureSlice = textureSlice;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +1,24 @@
|
||||||
using System;
|
using System;
|
||||||
using RefreshCS;
|
using RefreshCS;
|
||||||
|
|
||||||
namespace MoonWorks.Graphics
|
namespace MoonWorks.Graphics
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A sampler specifies how a texture will be sampled in a shader.
|
/// A sampler specifies how a texture will be sampled in a shader.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Sampler : GraphicsResource
|
public class Sampler : GraphicsResource
|
||||||
{
|
{
|
||||||
protected override Action<IntPtr, IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroySampler;
|
protected override Action<IntPtr, IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroySampler;
|
||||||
|
|
||||||
public Sampler(
|
public Sampler(
|
||||||
GraphicsDevice device,
|
GraphicsDevice device,
|
||||||
in SamplerCreateInfo samplerCreateInfo
|
in SamplerCreateInfo samplerCreateInfo
|
||||||
) : base(device)
|
) : base(device)
|
||||||
{
|
{
|
||||||
Handle = Refresh.Refresh_CreateSampler(
|
Handle = Refresh.Refresh_CreateSampler(
|
||||||
device.Handle,
|
device.Handle,
|
||||||
samplerCreateInfo.ToRefreshSamplerStateCreateInfo()
|
samplerCreateInfo.ToRefreshSamplerStateCreateInfo()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,25 +3,25 @@ using System;
|
||||||
|
|
||||||
namespace MoonWorks.Graphics
|
namespace MoonWorks.Graphics
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Shader modules expect input in SPIR-V bytecode format.
|
/// Shader modules expect input in SPIR-V bytecode format.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ShaderModule : GraphicsResource
|
public class ShaderModule : GraphicsResource
|
||||||
{
|
{
|
||||||
protected override Action<IntPtr, IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroyShaderModule;
|
protected override Action<IntPtr, IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroyShaderModule;
|
||||||
|
|
||||||
public unsafe ShaderModule(GraphicsDevice device, string filePath) : base(device)
|
public unsafe ShaderModule(GraphicsDevice device, string filePath) : base(device)
|
||||||
{
|
{
|
||||||
var bytecode = Bytecode.ReadBytecodeAsUInt32(filePath);
|
var bytecode = Bytecode.ReadBytecodeAsUInt32(filePath);
|
||||||
|
|
||||||
fixed (uint* ptr = bytecode)
|
fixed (uint* ptr = bytecode)
|
||||||
{
|
{
|
||||||
Refresh.ShaderModuleCreateInfo shaderModuleCreateInfo;
|
Refresh.ShaderModuleCreateInfo shaderModuleCreateInfo;
|
||||||
shaderModuleCreateInfo.codeSize = (UIntPtr) (bytecode.Length * sizeof(uint));
|
shaderModuleCreateInfo.codeSize = (UIntPtr) (bytecode.Length * sizeof(uint));
|
||||||
shaderModuleCreateInfo.byteCode = (IntPtr) ptr;
|
shaderModuleCreateInfo.byteCode = (IntPtr) ptr;
|
||||||
|
|
||||||
Handle = Refresh.Refresh_CreateShaderModule(device.Handle, shaderModuleCreateInfo);
|
Handle = Refresh.Refresh_CreateShaderModule(device.Handle, shaderModuleCreateInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,193 +3,196 @@ using RefreshCS;
|
||||||
|
|
||||||
namespace MoonWorks.Graphics
|
namespace MoonWorks.Graphics
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A container for pixel data.
|
/// A container for pixel data.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Texture : GraphicsResource
|
public class Texture : GraphicsResource
|
||||||
{
|
{
|
||||||
public uint Width { get; }
|
public uint Width { get; }
|
||||||
public uint Height { get; }
|
public uint Height { get; }
|
||||||
public uint Depth { get; }
|
public uint Depth { get; }
|
||||||
public TextureFormat Format { get; }
|
public TextureFormat Format { get; }
|
||||||
public bool IsCube { get; }
|
public bool IsCube { get; }
|
||||||
public uint LevelCount { get; }
|
public uint LevelCount { get; }
|
||||||
public SampleCount SampleCount { get; }
|
public SampleCount SampleCount { get; }
|
||||||
public TextureUsageFlags UsageFlags { get; }
|
public TextureUsageFlags UsageFlags { get; }
|
||||||
|
|
||||||
protected override Action<IntPtr, IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroyTexture;
|
protected override Action<IntPtr, IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroyTexture;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Loads a PNG from a file path.
|
/// Loads a PNG from a file path.
|
||||||
/// NOTE: You can queue as many of these as you want on to a command buffer but it MUST be submitted!
|
/// NOTE: You can queue as many of these as you want on to a command buffer but it MUST be submitted!
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="device"></param>
|
/// <param name="device"></param>
|
||||||
/// <param name="commandBuffer"></param>
|
/// <param name="commandBuffer"></param>
|
||||||
/// <param name="filePath"></param>
|
/// <param name="filePath"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static Texture LoadPNG(GraphicsDevice device, CommandBuffer commandBuffer, string filePath)
|
public static Texture LoadPNG(GraphicsDevice device, CommandBuffer commandBuffer, string filePath)
|
||||||
{
|
{
|
||||||
var pixels = Refresh.Refresh_Image_Load(
|
var pixels = Refresh.Refresh_Image_Load(
|
||||||
filePath,
|
filePath,
|
||||||
out var width,
|
out var width,
|
||||||
out var height,
|
out var height,
|
||||||
out var channels
|
out var channels
|
||||||
);
|
);
|
||||||
|
|
||||||
var byteCount = (uint)(width * height * channels);
|
var byteCount = (uint) (width * height * channels);
|
||||||
|
|
||||||
TextureCreateInfo textureCreateInfo;
|
TextureCreateInfo textureCreateInfo;
|
||||||
textureCreateInfo.Width = (uint)width;
|
textureCreateInfo.Width = (uint) width;
|
||||||
textureCreateInfo.Height = (uint)height;
|
textureCreateInfo.Height = (uint) height;
|
||||||
textureCreateInfo.Depth = 1;
|
textureCreateInfo.Depth = 1;
|
||||||
textureCreateInfo.Format = TextureFormat.R8G8B8A8;
|
textureCreateInfo.Format = TextureFormat.R8G8B8A8;
|
||||||
textureCreateInfo.IsCube = false;
|
textureCreateInfo.IsCube = false;
|
||||||
textureCreateInfo.LevelCount = 1;
|
textureCreateInfo.LevelCount = 1;
|
||||||
textureCreateInfo.SampleCount = SampleCount.One;
|
textureCreateInfo.SampleCount = SampleCount.One;
|
||||||
textureCreateInfo.UsageFlags = TextureUsageFlags.Sampler;
|
textureCreateInfo.UsageFlags = TextureUsageFlags.Sampler;
|
||||||
|
|
||||||
var texture = new Texture(device, textureCreateInfo);
|
var texture = new Texture(device, textureCreateInfo);
|
||||||
commandBuffer.SetTextureData(texture, pixels, byteCount);
|
commandBuffer.SetTextureData(texture, pixels, byteCount);
|
||||||
|
|
||||||
Refresh.Refresh_Image_Free(pixels);
|
Refresh.Refresh_Image_Free(pixels);
|
||||||
|
|
||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe static void SavePNG(string path, int width, int height, byte[] pixels)
|
public unsafe static void SavePNG(string path, int width, int height, byte[] pixels)
|
||||||
{
|
{
|
||||||
fixed (byte* ptr = &pixels[0])
|
fixed (byte* ptr = &pixels[0])
|
||||||
{
|
{
|
||||||
Refresh.Refresh_Image_SavePNG(path, width, height, (IntPtr) ptr);
|
Refresh.Refresh_Image_SavePNG(path, width, height, (IntPtr) ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a 2D texture.
|
/// Creates a 2D texture.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="device">An initialized GraphicsDevice.</param>
|
/// <param name="device">An initialized GraphicsDevice.</param>
|
||||||
/// <param name="width">The width of the texture.</param>
|
/// <param name="width">The width of the texture.</param>
|
||||||
/// <param name="height">The height of the texture.</param>
|
/// <param name="height">The height of the texture.</param>
|
||||||
/// <param name="format">The format of the texture.</param>
|
/// <param name="format">The format of the texture.</param>
|
||||||
/// <param name="usageFlags">Specifies how the texture will be used.</param>
|
/// <param name="usageFlags">Specifies how the texture will be used.</param>
|
||||||
/// <param name="sampleCount">Specifies the multisample count.</param>
|
/// <param name="sampleCount">Specifies the multisample count.</param>
|
||||||
/// <param name="levelCount">Specifies the number of mip levels.</param>
|
/// <param name="levelCount">Specifies the number of mip levels.</param>
|
||||||
public static Texture CreateTexture2D(
|
public static Texture CreateTexture2D(
|
||||||
GraphicsDevice device,
|
GraphicsDevice device,
|
||||||
uint width,
|
uint width,
|
||||||
uint height,
|
uint height,
|
||||||
TextureFormat format,
|
TextureFormat format,
|
||||||
TextureUsageFlags usageFlags,
|
TextureUsageFlags usageFlags,
|
||||||
SampleCount sampleCount = SampleCount.One,
|
SampleCount sampleCount = SampleCount.One,
|
||||||
uint levelCount = 1
|
uint levelCount = 1
|
||||||
) {
|
)
|
||||||
var textureCreateInfo = new TextureCreateInfo
|
{
|
||||||
{
|
var textureCreateInfo = new TextureCreateInfo
|
||||||
Width = width,
|
{
|
||||||
Height = height,
|
Width = width,
|
||||||
Depth = 1,
|
Height = height,
|
||||||
IsCube = false,
|
Depth = 1,
|
||||||
SampleCount = sampleCount,
|
IsCube = false,
|
||||||
LevelCount = levelCount,
|
SampleCount = sampleCount,
|
||||||
Format = format,
|
LevelCount = levelCount,
|
||||||
UsageFlags = usageFlags
|
Format = format,
|
||||||
};
|
UsageFlags = usageFlags
|
||||||
|
};
|
||||||
|
|
||||||
return new Texture(device, textureCreateInfo);
|
return new Texture(device, textureCreateInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a 3D texture.
|
/// Creates a 3D texture.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="device">An initialized GraphicsDevice.</param>
|
/// <param name="device">An initialized GraphicsDevice.</param>
|
||||||
/// <param name="width">The width of the texture.</param>
|
/// <param name="width">The width of the texture.</param>
|
||||||
/// <param name="height">The height of the texture.</param>
|
/// <param name="height">The height of the texture.</param>
|
||||||
/// <param name="depth">The depth of the texture.</param>
|
/// <param name="depth">The depth of the texture.</param>
|
||||||
/// <param name="format">The format of the texture.</param>
|
/// <param name="format">The format of the texture.</param>
|
||||||
/// <param name="usageFlags">Specifies how the texture will be used.</param>
|
/// <param name="usageFlags">Specifies how the texture will be used.</param>
|
||||||
/// <param name="sampleCount">Specifies the multisample count.</param>
|
/// <param name="sampleCount">Specifies the multisample count.</param>
|
||||||
/// <param name="levelCount">Specifies the number of mip levels.</param>
|
/// <param name="levelCount">Specifies the number of mip levels.</param>
|
||||||
public static Texture CreateTexture3D(
|
public static Texture CreateTexture3D(
|
||||||
GraphicsDevice device,
|
GraphicsDevice device,
|
||||||
uint width,
|
uint width,
|
||||||
uint height,
|
uint height,
|
||||||
uint depth,
|
uint depth,
|
||||||
TextureFormat format,
|
TextureFormat format,
|
||||||
TextureUsageFlags usageFlags,
|
TextureUsageFlags usageFlags,
|
||||||
SampleCount sampleCount = SampleCount.One,
|
SampleCount sampleCount = SampleCount.One,
|
||||||
uint levelCount = 1
|
uint levelCount = 1
|
||||||
) {
|
)
|
||||||
var textureCreateInfo = new TextureCreateInfo
|
{
|
||||||
{
|
var textureCreateInfo = new TextureCreateInfo
|
||||||
Width = width,
|
{
|
||||||
Height = height,
|
Width = width,
|
||||||
Depth = depth,
|
Height = height,
|
||||||
IsCube = false,
|
Depth = depth,
|
||||||
SampleCount = sampleCount,
|
IsCube = false,
|
||||||
LevelCount = levelCount,
|
SampleCount = sampleCount,
|
||||||
Format = format,
|
LevelCount = levelCount,
|
||||||
UsageFlags = usageFlags
|
Format = format,
|
||||||
};
|
UsageFlags = usageFlags
|
||||||
|
};
|
||||||
|
|
||||||
return new Texture(device, textureCreateInfo);
|
return new Texture(device, textureCreateInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a cube texture.
|
/// Creates a cube texture.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="device">An initialized GraphicsDevice.</param>
|
/// <param name="device">An initialized GraphicsDevice.</param>
|
||||||
/// <param name="size">The length of one side of the cube.</param>
|
/// <param name="size">The length of one side of the cube.</param>
|
||||||
/// <param name="format">The format of the texture.</param>
|
/// <param name="format">The format of the texture.</param>
|
||||||
/// <param name="usageFlags">Specifies how the texture will be used.</param>
|
/// <param name="usageFlags">Specifies how the texture will be used.</param>
|
||||||
/// <param name="sampleCount">Specifies the multisample count.</param>
|
/// <param name="sampleCount">Specifies the multisample count.</param>
|
||||||
/// <param name="levelCount">Specifies the number of mip levels.</param>
|
/// <param name="levelCount">Specifies the number of mip levels.</param>
|
||||||
public static Texture CreateTextureCube(
|
public static Texture CreateTextureCube(
|
||||||
GraphicsDevice device,
|
GraphicsDevice device,
|
||||||
uint size,
|
uint size,
|
||||||
TextureFormat format,
|
TextureFormat format,
|
||||||
TextureUsageFlags usageFlags,
|
TextureUsageFlags usageFlags,
|
||||||
SampleCount sampleCount = SampleCount.One,
|
SampleCount sampleCount = SampleCount.One,
|
||||||
uint levelCount = 1
|
uint levelCount = 1
|
||||||
) {
|
)
|
||||||
var textureCreateInfo = new TextureCreateInfo
|
{
|
||||||
{
|
var textureCreateInfo = new TextureCreateInfo
|
||||||
Width = size,
|
{
|
||||||
Height = size,
|
Width = size,
|
||||||
Depth = 1,
|
Height = size,
|
||||||
IsCube = true,
|
Depth = 1,
|
||||||
SampleCount = sampleCount,
|
IsCube = true,
|
||||||
LevelCount = levelCount,
|
SampleCount = sampleCount,
|
||||||
Format = format,
|
LevelCount = levelCount,
|
||||||
UsageFlags = usageFlags
|
Format = format,
|
||||||
};
|
UsageFlags = usageFlags
|
||||||
|
};
|
||||||
|
|
||||||
return new Texture(device, textureCreateInfo);
|
return new Texture(device, textureCreateInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new texture using a TextureCreateInfo struct.
|
/// Creates a new texture using a TextureCreateInfo struct.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="device">An initialized GraphicsDevice.</param>
|
/// <param name="device">An initialized GraphicsDevice.</param>
|
||||||
/// <param name="textureCreateInfo">The parameters to use when creating the texture.</param>
|
/// <param name="textureCreateInfo">The parameters to use when creating the texture.</param>
|
||||||
public Texture(
|
public Texture(
|
||||||
GraphicsDevice device,
|
GraphicsDevice device,
|
||||||
in TextureCreateInfo textureCreateInfo
|
in TextureCreateInfo textureCreateInfo
|
||||||
) : base(device)
|
) : base(device)
|
||||||
{
|
{
|
||||||
Handle = Refresh.Refresh_CreateTexture(
|
Handle = Refresh.Refresh_CreateTexture(
|
||||||
device.Handle,
|
device.Handle,
|
||||||
textureCreateInfo.ToRefreshTextureCreateInfo()
|
textureCreateInfo.ToRefreshTextureCreateInfo()
|
||||||
);
|
);
|
||||||
|
|
||||||
Format = textureCreateInfo.Format;
|
Format = textureCreateInfo.Format;
|
||||||
Width = textureCreateInfo.Width;
|
Width = textureCreateInfo.Width;
|
||||||
Height = textureCreateInfo.Height;
|
Height = textureCreateInfo.Height;
|
||||||
Depth = textureCreateInfo.Depth;
|
Depth = textureCreateInfo.Depth;
|
||||||
IsCube = textureCreateInfo.IsCube;
|
IsCube = textureCreateInfo.IsCube;
|
||||||
SampleCount = textureCreateInfo.SampleCount;
|
SampleCount = textureCreateInfo.SampleCount;
|
||||||
LevelCount = textureCreateInfo.LevelCount;
|
LevelCount = textureCreateInfo.LevelCount;
|
||||||
SampleCount = textureCreateInfo.SampleCount;
|
SampleCount = textureCreateInfo.SampleCount;
|
||||||
UsageFlags = textureCreateInfo.UsageFlags;
|
UsageFlags = textureCreateInfo.UsageFlags;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
namespace MoonWorks.Graphics
|
namespace MoonWorks.Graphics
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Describes how the graphics pipeline will blend colors.
|
/// Describes how the graphics pipeline will blend colors.
|
||||||
/// You must provide one ColorTargetBlendState per color target in the pipeline.
|
/// You must provide one ColorTargetBlendState per color target in the pipeline.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public unsafe struct ColorBlendState
|
public unsafe struct ColorBlendState
|
||||||
{
|
{
|
||||||
public bool LogicOpEnable;
|
public bool LogicOpEnable;
|
||||||
public LogicOp LogicOp;
|
public LogicOp LogicOp;
|
||||||
public BlendConstants BlendConstants;
|
public BlendConstants BlendConstants;
|
||||||
public ColorTargetBlendState[] ColorTargetBlendStates;
|
public ColorTargetBlendState[] ColorTargetBlendStates;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,120 +2,120 @@
|
||||||
|
|
||||||
namespace MoonWorks.Graphics
|
namespace MoonWorks.Graphics
|
||||||
{
|
{
|
||||||
public struct ColorTargetBlendState
|
public struct ColorTargetBlendState
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// If disabled, no blending will occur.
|
/// If disabled, no blending will occur.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool BlendEnable;
|
public bool BlendEnable;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Selects which blend operation to use with alpha values.
|
/// Selects which blend operation to use with alpha values.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public BlendOp AlphaBlendOp;
|
public BlendOp AlphaBlendOp;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Selects which blend operation to use with color values.
|
/// Selects which blend operation to use with color values.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public BlendOp ColorBlendOp;
|
public BlendOp ColorBlendOp;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Specifies which of the RGBA components are enabled for writing.
|
/// Specifies which of the RGBA components are enabled for writing.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ColorComponentFlags ColorWriteMask;
|
public ColorComponentFlags ColorWriteMask;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Selects which blend factor is used to determine the alpha destination factor.
|
/// Selects which blend factor is used to determine the alpha destination factor.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public BlendFactor DestinationAlphaBlendFactor;
|
public BlendFactor DestinationAlphaBlendFactor;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Selects which blend factor is used to determine the color destination factor.
|
/// Selects which blend factor is used to determine the color destination factor.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public BlendFactor DestinationColorBlendFactor;
|
public BlendFactor DestinationColorBlendFactor;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Selects which blend factor is used to determine the alpha source factor.
|
/// Selects which blend factor is used to determine the alpha source factor.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public BlendFactor SourceAlphaBlendFactor;
|
public BlendFactor SourceAlphaBlendFactor;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Selects which blend factor is used to determine the color source factor.
|
/// Selects which blend factor is used to determine the color source factor.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public BlendFactor SourceColorBlendFactor;
|
public BlendFactor SourceColorBlendFactor;
|
||||||
|
|
||||||
public static readonly ColorTargetBlendState Additive = new ColorTargetBlendState
|
public static readonly ColorTargetBlendState Additive = new ColorTargetBlendState
|
||||||
{
|
{
|
||||||
BlendEnable = true,
|
BlendEnable = true,
|
||||||
AlphaBlendOp = BlendOp.Add,
|
AlphaBlendOp = BlendOp.Add,
|
||||||
ColorBlendOp = BlendOp.Add,
|
ColorBlendOp = BlendOp.Add,
|
||||||
ColorWriteMask = ColorComponentFlags.RGBA,
|
ColorWriteMask = ColorComponentFlags.RGBA,
|
||||||
SourceColorBlendFactor = BlendFactor.SourceAlpha,
|
SourceColorBlendFactor = BlendFactor.SourceAlpha,
|
||||||
SourceAlphaBlendFactor = BlendFactor.SourceAlpha,
|
SourceAlphaBlendFactor = BlendFactor.SourceAlpha,
|
||||||
DestinationColorBlendFactor = BlendFactor.One,
|
DestinationColorBlendFactor = BlendFactor.One,
|
||||||
DestinationAlphaBlendFactor = BlendFactor.One
|
DestinationAlphaBlendFactor = BlendFactor.One
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly ColorTargetBlendState AlphaBlend = new ColorTargetBlendState
|
public static readonly ColorTargetBlendState AlphaBlend = new ColorTargetBlendState
|
||||||
{
|
{
|
||||||
BlendEnable = true,
|
BlendEnable = true,
|
||||||
AlphaBlendOp = BlendOp.Add,
|
AlphaBlendOp = BlendOp.Add,
|
||||||
ColorBlendOp = BlendOp.Add,
|
ColorBlendOp = BlendOp.Add,
|
||||||
ColorWriteMask = ColorComponentFlags.RGBA,
|
ColorWriteMask = ColorComponentFlags.RGBA,
|
||||||
SourceColorBlendFactor = BlendFactor.One,
|
SourceColorBlendFactor = BlendFactor.One,
|
||||||
SourceAlphaBlendFactor = BlendFactor.One,
|
SourceAlphaBlendFactor = BlendFactor.One,
|
||||||
DestinationColorBlendFactor = BlendFactor.OneMinusSourceAlpha,
|
DestinationColorBlendFactor = BlendFactor.OneMinusSourceAlpha,
|
||||||
DestinationAlphaBlendFactor = BlendFactor.OneMinusSourceAlpha
|
DestinationAlphaBlendFactor = BlendFactor.OneMinusSourceAlpha
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly ColorTargetBlendState NonPremultiplied = new ColorTargetBlendState
|
public static readonly ColorTargetBlendState NonPremultiplied = new ColorTargetBlendState
|
||||||
{
|
{
|
||||||
BlendEnable = true,
|
BlendEnable = true,
|
||||||
AlphaBlendOp = BlendOp.Add,
|
AlphaBlendOp = BlendOp.Add,
|
||||||
ColorBlendOp = BlendOp.Add,
|
ColorBlendOp = BlendOp.Add,
|
||||||
ColorWriteMask = ColorComponentFlags.RGBA,
|
ColorWriteMask = ColorComponentFlags.RGBA,
|
||||||
SourceColorBlendFactor = BlendFactor.SourceAlpha,
|
SourceColorBlendFactor = BlendFactor.SourceAlpha,
|
||||||
SourceAlphaBlendFactor = BlendFactor.SourceAlpha,
|
SourceAlphaBlendFactor = BlendFactor.SourceAlpha,
|
||||||
DestinationColorBlendFactor = BlendFactor.OneMinusSourceAlpha,
|
DestinationColorBlendFactor = BlendFactor.OneMinusSourceAlpha,
|
||||||
DestinationAlphaBlendFactor = BlendFactor.OneMinusSourceAlpha
|
DestinationAlphaBlendFactor = BlendFactor.OneMinusSourceAlpha
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly ColorTargetBlendState Opaque = new ColorTargetBlendState
|
public static readonly ColorTargetBlendState Opaque = new ColorTargetBlendState
|
||||||
{
|
{
|
||||||
BlendEnable = true,
|
BlendEnable = true,
|
||||||
AlphaBlendOp = BlendOp.Add,
|
AlphaBlendOp = BlendOp.Add,
|
||||||
ColorBlendOp = BlendOp.Add,
|
ColorBlendOp = BlendOp.Add,
|
||||||
ColorWriteMask = ColorComponentFlags.RGBA,
|
ColorWriteMask = ColorComponentFlags.RGBA,
|
||||||
SourceColorBlendFactor = BlendFactor.One,
|
SourceColorBlendFactor = BlendFactor.One,
|
||||||
SourceAlphaBlendFactor = BlendFactor.One,
|
SourceAlphaBlendFactor = BlendFactor.One,
|
||||||
DestinationColorBlendFactor = BlendFactor.Zero,
|
DestinationColorBlendFactor = BlendFactor.Zero,
|
||||||
DestinationAlphaBlendFactor = BlendFactor.Zero
|
DestinationAlphaBlendFactor = BlendFactor.Zero
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly ColorTargetBlendState None = new ColorTargetBlendState
|
public static readonly ColorTargetBlendState None = new ColorTargetBlendState
|
||||||
{
|
{
|
||||||
BlendEnable = false,
|
BlendEnable = false,
|
||||||
ColorWriteMask = ColorComponentFlags.RGBA
|
ColorWriteMask = ColorComponentFlags.RGBA
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly ColorTargetBlendState Disable = new ColorTargetBlendState
|
public static readonly ColorTargetBlendState Disable = new ColorTargetBlendState
|
||||||
{
|
{
|
||||||
BlendEnable = false,
|
BlendEnable = false,
|
||||||
ColorWriteMask = ColorComponentFlags.None
|
ColorWriteMask = ColorComponentFlags.None
|
||||||
};
|
};
|
||||||
|
|
||||||
public Refresh.ColorTargetBlendState ToRefreshColorTargetBlendState()
|
public Refresh.ColorTargetBlendState ToRefreshColorTargetBlendState()
|
||||||
{
|
{
|
||||||
return new Refresh.ColorTargetBlendState
|
return new Refresh.ColorTargetBlendState
|
||||||
{
|
{
|
||||||
blendEnable = Conversions.BoolToByte(BlendEnable),
|
blendEnable = Conversions.BoolToByte(BlendEnable),
|
||||||
alphaBlendOp = (Refresh.BlendOp)AlphaBlendOp,
|
alphaBlendOp = (Refresh.BlendOp) AlphaBlendOp,
|
||||||
colorBlendOp = (Refresh.BlendOp)ColorBlendOp,
|
colorBlendOp = (Refresh.BlendOp) ColorBlendOp,
|
||||||
colorWriteMask = (Refresh.ColorComponentFlags)ColorWriteMask,
|
colorWriteMask = (Refresh.ColorComponentFlags) ColorWriteMask,
|
||||||
destinationAlphaBlendFactor = (Refresh.BlendFactor)DestinationAlphaBlendFactor,
|
destinationAlphaBlendFactor = (Refresh.BlendFactor) DestinationAlphaBlendFactor,
|
||||||
destinationColorBlendFactor = (Refresh.BlendFactor)DestinationColorBlendFactor,
|
destinationColorBlendFactor = (Refresh.BlendFactor) DestinationColorBlendFactor,
|
||||||
sourceAlphaBlendFactor = (Refresh.BlendFactor)SourceAlphaBlendFactor,
|
sourceAlphaBlendFactor = (Refresh.BlendFactor) SourceAlphaBlendFactor,
|
||||||
sourceColorBlendFactor = (Refresh.BlendFactor)SourceColorBlendFactor
|
sourceColorBlendFactor = (Refresh.BlendFactor) SourceColorBlendFactor
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,79 +1,79 @@
|
||||||
namespace MoonWorks.Graphics
|
namespace MoonWorks.Graphics
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines how data is written to and read from the depth/stencil buffer.
|
/// Determines how data is written to and read from the depth/stencil buffer.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public struct DepthStencilState
|
public struct DepthStencilState
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// If disabled, no depth culling will occur.
|
/// If disabled, no depth culling will occur.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool DepthTestEnable;
|
public bool DepthTestEnable;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Describes the stencil operation for back-facing primitives.
|
/// Describes the stencil operation for back-facing primitives.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public StencilOpState BackStencilState;
|
public StencilOpState BackStencilState;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Describes the stencil operation for front-facing primitives.
|
/// Describes the stencil operation for front-facing primitives.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public StencilOpState FrontStencilState;
|
public StencilOpState FrontStencilState;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The comparison operator used in the depth test.
|
/// The comparison operator used in the depth test.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public CompareOp CompareOp;
|
public CompareOp CompareOp;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// If depth lies outside of these bounds the pixel will be culled.
|
/// If depth lies outside of these bounds the pixel will be culled.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool DepthBoundsTestEnable;
|
public bool DepthBoundsTestEnable;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Specifies whether depth values will be written to the buffer during rendering.
|
/// Specifies whether depth values will be written to the buffer during rendering.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool DepthWriteEnable;
|
public bool DepthWriteEnable;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The minimum depth value in the depth bounds test.
|
/// The minimum depth value in the depth bounds test.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float MinDepthBounds;
|
public float MinDepthBounds;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The maximum depth value in the depth bounds test.
|
/// The maximum depth value in the depth bounds test.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float MaxDepthBounds;
|
public float MaxDepthBounds;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// If disabled, no stencil culling will occur.
|
/// If disabled, no stencil culling will occur.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool StencilTestEnable;
|
public bool StencilTestEnable;
|
||||||
|
|
||||||
public static readonly DepthStencilState DepthReadWrite = new DepthStencilState
|
public static readonly DepthStencilState DepthReadWrite = new DepthStencilState
|
||||||
{
|
{
|
||||||
DepthTestEnable = true,
|
DepthTestEnable = true,
|
||||||
DepthWriteEnable = true,
|
DepthWriteEnable = true,
|
||||||
DepthBoundsTestEnable = false,
|
DepthBoundsTestEnable = false,
|
||||||
StencilTestEnable = false,
|
StencilTestEnable = false,
|
||||||
CompareOp = CompareOp.LessOrEqual
|
CompareOp = CompareOp.LessOrEqual
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly DepthStencilState DepthRead = new DepthStencilState
|
public static readonly DepthStencilState DepthRead = new DepthStencilState
|
||||||
{
|
{
|
||||||
DepthTestEnable = true,
|
DepthTestEnable = true,
|
||||||
DepthWriteEnable = false,
|
DepthWriteEnable = false,
|
||||||
DepthBoundsTestEnable = false,
|
DepthBoundsTestEnable = false,
|
||||||
StencilTestEnable = false,
|
StencilTestEnable = false,
|
||||||
CompareOp = CompareOp.LessOrEqual
|
CompareOp = CompareOp.LessOrEqual
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly DepthStencilState Disable = new DepthStencilState
|
public static readonly DepthStencilState Disable = new DepthStencilState
|
||||||
{
|
{
|
||||||
DepthTestEnable = false,
|
DepthTestEnable = false,
|
||||||
DepthWriteEnable = false,
|
DepthWriteEnable = false,
|
||||||
DepthBoundsTestEnable = false,
|
DepthBoundsTestEnable = false,
|
||||||
StencilTestEnable = false
|
StencilTestEnable = false
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
namespace MoonWorks.Graphics
|
namespace MoonWorks.Graphics
|
||||||
{
|
{
|
||||||
public struct GraphicsPipelineCreateInfo
|
public struct GraphicsPipelineCreateInfo
|
||||||
{
|
{
|
||||||
public ColorBlendState ColorBlendState;
|
public ColorBlendState ColorBlendState;
|
||||||
public DepthStencilState DepthStencilState;
|
public DepthStencilState DepthStencilState;
|
||||||
public ShaderStageState VertexShaderState;
|
public ShaderStageState VertexShaderState;
|
||||||
public ShaderStageState FragmentShaderState;
|
public ShaderStageState FragmentShaderState;
|
||||||
public MultisampleState MultisampleState;
|
public MultisampleState MultisampleState;
|
||||||
public GraphicsPipelineLayoutInfo PipelineLayoutInfo;
|
public GraphicsPipelineLayoutInfo PipelineLayoutInfo;
|
||||||
public RasterizerState RasterizerState;
|
public RasterizerState RasterizerState;
|
||||||
public PrimitiveType PrimitiveType;
|
public PrimitiveType PrimitiveType;
|
||||||
public VertexInputState VertexInputState;
|
public VertexInputState VertexInputState;
|
||||||
public ViewportState ViewportState;
|
public ViewportState ViewportState;
|
||||||
public RenderPass RenderPass;
|
public RenderPass RenderPass;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
namespace MoonWorks.Graphics
|
namespace MoonWorks.Graphics
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Describes how many samplers will be used in each shader stage.
|
/// Describes how many samplers will be used in each shader stage.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public struct GraphicsPipelineLayoutInfo
|
public struct GraphicsPipelineLayoutInfo
|
||||||
{
|
{
|
||||||
public uint VertexSamplerBindingCount;
|
public uint VertexSamplerBindingCount;
|
||||||
public uint FragmentSamplerBindingCount;
|
public uint FragmentSamplerBindingCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
namespace MoonWorks.Graphics
|
namespace MoonWorks.Graphics
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Specifies how many samples should be used in rasterization.
|
/// Specifies how many samples should be used in rasterization.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public struct MultisampleState
|
public struct MultisampleState
|
||||||
{
|
{
|
||||||
public SampleCount MultisampleCount;
|
public SampleCount MultisampleCount;
|
||||||
public uint SampleMask;
|
public uint SampleMask;
|
||||||
|
|
||||||
public static readonly MultisampleState None = new MultisampleState
|
public static readonly MultisampleState None = new MultisampleState
|
||||||
{
|
{
|
||||||
MultisampleCount = SampleCount.One,
|
MultisampleCount = SampleCount.One,
|
||||||
SampleMask = uint.MaxValue
|
SampleMask = uint.MaxValue
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,121 +1,121 @@
|
||||||
namespace MoonWorks.Graphics
|
namespace MoonWorks.Graphics
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Specifies how the rasterizer should be configured for a graphics pipeline.
|
/// Specifies how the rasterizer should be configured for a graphics pipeline.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public struct RasterizerState
|
public struct RasterizerState
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Specifies whether front faces, back faces, none, or both should be culled.
|
/// Specifies whether front faces, back faces, none, or both should be culled.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public CullMode CullMode;
|
public CullMode CullMode;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Specifies maximum depth bias of a fragment. Only applies if depth biasing is enabled.
|
/// Specifies maximum depth bias of a fragment. Only applies if depth biasing is enabled.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float DepthBiasClamp;
|
public float DepthBiasClamp;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The constant depth value added to each fragment. Only applies if depth biasing is enabled.
|
/// The constant depth value added to each fragment. Only applies if depth biasing is enabled.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float DepthBiasConstantFactor;
|
public float DepthBiasConstantFactor;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Specifies whether depth biasing is enabled. Only applies if depth biasing is enabled.
|
/// Specifies whether depth biasing is enabled. Only applies if depth biasing is enabled.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool DepthBiasEnable;
|
public bool DepthBiasEnable;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Factor applied to a fragment's slope in depth bias calculations. Only applies if depth biasing is enabled.
|
/// Factor applied to a fragment's slope in depth bias calculations. Only applies if depth biasing is enabled.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float DepthBiasSlopeFactor;
|
public float DepthBiasSlopeFactor;
|
||||||
public bool DepthClampEnable;
|
public bool DepthClampEnable;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Specifies how triangles should be drawn.
|
/// Specifies how triangles should be drawn.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public FillMode FillMode;
|
public FillMode FillMode;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Specifies which triangle winding order is designated as front-facing.
|
/// Specifies which triangle winding order is designated as front-facing.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public FrontFace FrontFace;
|
public FrontFace FrontFace;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Describes the width of the line rendering in terms of pixels.
|
/// Describes the width of the line rendering in terms of pixels.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float LineWidth;
|
public float LineWidth;
|
||||||
|
|
||||||
public static readonly RasterizerState CW_CullFront = new RasterizerState
|
public static readonly RasterizerState CW_CullFront = new RasterizerState
|
||||||
{
|
{
|
||||||
CullMode = CullMode.Front,
|
CullMode = CullMode.Front,
|
||||||
FrontFace = FrontFace.Clockwise,
|
FrontFace = FrontFace.Clockwise,
|
||||||
FillMode = FillMode.Fill,
|
FillMode = FillMode.Fill,
|
||||||
DepthBiasEnable = false,
|
DepthBiasEnable = false,
|
||||||
LineWidth = 1f
|
LineWidth = 1f
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly RasterizerState CW_CullBack = new RasterizerState
|
public static readonly RasterizerState CW_CullBack = new RasterizerState
|
||||||
{
|
{
|
||||||
CullMode = CullMode.Back,
|
CullMode = CullMode.Back,
|
||||||
FrontFace = FrontFace.Clockwise,
|
FrontFace = FrontFace.Clockwise,
|
||||||
FillMode = FillMode.Fill,
|
FillMode = FillMode.Fill,
|
||||||
DepthBiasEnable = false,
|
DepthBiasEnable = false,
|
||||||
LineWidth = 1f
|
LineWidth = 1f
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly RasterizerState CW_CullNone = new RasterizerState
|
public static readonly RasterizerState CW_CullNone = new RasterizerState
|
||||||
{
|
{
|
||||||
CullMode = CullMode.None,
|
CullMode = CullMode.None,
|
||||||
FrontFace = FrontFace.Clockwise,
|
FrontFace = FrontFace.Clockwise,
|
||||||
FillMode = FillMode.Fill,
|
FillMode = FillMode.Fill,
|
||||||
DepthBiasEnable = false,
|
DepthBiasEnable = false,
|
||||||
LineWidth = 1f
|
LineWidth = 1f
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly RasterizerState CW_Wireframe = new RasterizerState
|
public static readonly RasterizerState CW_Wireframe = new RasterizerState
|
||||||
{
|
{
|
||||||
CullMode = CullMode.None,
|
CullMode = CullMode.None,
|
||||||
FrontFace = FrontFace.Clockwise,
|
FrontFace = FrontFace.Clockwise,
|
||||||
FillMode = FillMode.Fill,
|
FillMode = FillMode.Fill,
|
||||||
DepthBiasEnable = false,
|
DepthBiasEnable = false,
|
||||||
LineWidth = 1f
|
LineWidth = 1f
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly RasterizerState CCW_CullFront = new RasterizerState
|
public static readonly RasterizerState CCW_CullFront = new RasterizerState
|
||||||
{
|
{
|
||||||
CullMode = CullMode.Front,
|
CullMode = CullMode.Front,
|
||||||
FrontFace = FrontFace.CounterClockwise,
|
FrontFace = FrontFace.CounterClockwise,
|
||||||
FillMode = FillMode.Fill,
|
FillMode = FillMode.Fill,
|
||||||
DepthBiasEnable = false,
|
DepthBiasEnable = false,
|
||||||
LineWidth = 1f
|
LineWidth = 1f
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly RasterizerState CCW_CullBack = new RasterizerState
|
public static readonly RasterizerState CCW_CullBack = new RasterizerState
|
||||||
{
|
{
|
||||||
CullMode = CullMode.Back,
|
CullMode = CullMode.Back,
|
||||||
FrontFace = FrontFace.CounterClockwise,
|
FrontFace = FrontFace.CounterClockwise,
|
||||||
FillMode = FillMode.Fill,
|
FillMode = FillMode.Fill,
|
||||||
DepthBiasEnable = false,
|
DepthBiasEnable = false,
|
||||||
LineWidth = 1f
|
LineWidth = 1f
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly RasterizerState CCW_CullNone = new RasterizerState
|
public static readonly RasterizerState CCW_CullNone = new RasterizerState
|
||||||
{
|
{
|
||||||
CullMode = CullMode.None,
|
CullMode = CullMode.None,
|
||||||
FrontFace = FrontFace.CounterClockwise,
|
FrontFace = FrontFace.CounterClockwise,
|
||||||
FillMode = FillMode.Fill,
|
FillMode = FillMode.Fill,
|
||||||
DepthBiasEnable = false,
|
DepthBiasEnable = false,
|
||||||
LineWidth = 1f
|
LineWidth = 1f
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly RasterizerState CCW_Wireframe = new RasterizerState
|
public static readonly RasterizerState CCW_Wireframe = new RasterizerState
|
||||||
{
|
{
|
||||||
CullMode = CullMode.None,
|
CullMode = CullMode.None,
|
||||||
FrontFace = FrontFace.CounterClockwise,
|
FrontFace = FrontFace.CounterClockwise,
|
||||||
FillMode = FillMode.Fill,
|
FillMode = FillMode.Fill,
|
||||||
DepthBiasEnable = false,
|
DepthBiasEnable = false,
|
||||||
LineWidth = 1f
|
LineWidth = 1f
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,134 +2,134 @@
|
||||||
|
|
||||||
namespace MoonWorks.Graphics
|
namespace MoonWorks.Graphics
|
||||||
{
|
{
|
||||||
public struct SamplerCreateInfo
|
public struct SamplerCreateInfo
|
||||||
{
|
{
|
||||||
public Filter MinFilter;
|
public Filter MinFilter;
|
||||||
public Filter MagFilter;
|
public Filter MagFilter;
|
||||||
public SamplerMipmapMode MipmapMode;
|
public SamplerMipmapMode MipmapMode;
|
||||||
public SamplerAddressMode AddressModeU;
|
public SamplerAddressMode AddressModeU;
|
||||||
public SamplerAddressMode AddressModeV;
|
public SamplerAddressMode AddressModeV;
|
||||||
public SamplerAddressMode AddressModeW;
|
public SamplerAddressMode AddressModeW;
|
||||||
public float MipLodBias;
|
public float MipLodBias;
|
||||||
public bool AnisotropyEnable;
|
public bool AnisotropyEnable;
|
||||||
public float MaxAnisotropy;
|
public float MaxAnisotropy;
|
||||||
public bool CompareEnable;
|
public bool CompareEnable;
|
||||||
public CompareOp CompareOp;
|
public CompareOp CompareOp;
|
||||||
public float MinLod;
|
public float MinLod;
|
||||||
public float MaxLod;
|
public float MaxLod;
|
||||||
public BorderColor BorderColor;
|
public BorderColor BorderColor;
|
||||||
|
|
||||||
public static readonly SamplerCreateInfo AnisotropicClamp = new SamplerCreateInfo
|
public static readonly SamplerCreateInfo AnisotropicClamp = new SamplerCreateInfo
|
||||||
{
|
{
|
||||||
MinFilter = Filter.Linear,
|
MinFilter = Filter.Linear,
|
||||||
MagFilter = Filter.Linear,
|
MagFilter = Filter.Linear,
|
||||||
MipmapMode = SamplerMipmapMode.Linear,
|
MipmapMode = SamplerMipmapMode.Linear,
|
||||||
AddressModeU = SamplerAddressMode.ClampToEdge,
|
AddressModeU = SamplerAddressMode.ClampToEdge,
|
||||||
AddressModeV = SamplerAddressMode.ClampToEdge,
|
AddressModeV = SamplerAddressMode.ClampToEdge,
|
||||||
AddressModeW = SamplerAddressMode.ClampToEdge,
|
AddressModeW = SamplerAddressMode.ClampToEdge,
|
||||||
CompareEnable = false,
|
CompareEnable = false,
|
||||||
AnisotropyEnable = true,
|
AnisotropyEnable = true,
|
||||||
MaxAnisotropy = 4,
|
MaxAnisotropy = 4,
|
||||||
MipLodBias = 0f,
|
MipLodBias = 0f,
|
||||||
MinLod = 0,
|
MinLod = 0,
|
||||||
MaxLod = 1000 /* VK_LOD_CLAMP_NONE */
|
MaxLod = 1000 /* VK_LOD_CLAMP_NONE */
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly SamplerCreateInfo AnisotropicWrap = new SamplerCreateInfo
|
public static readonly SamplerCreateInfo AnisotropicWrap = new SamplerCreateInfo
|
||||||
{
|
{
|
||||||
MinFilter = Filter.Linear,
|
MinFilter = Filter.Linear,
|
||||||
MagFilter = Filter.Linear,
|
MagFilter = Filter.Linear,
|
||||||
MipmapMode = SamplerMipmapMode.Linear,
|
MipmapMode = SamplerMipmapMode.Linear,
|
||||||
AddressModeU = SamplerAddressMode.Repeat,
|
AddressModeU = SamplerAddressMode.Repeat,
|
||||||
AddressModeV = SamplerAddressMode.Repeat,
|
AddressModeV = SamplerAddressMode.Repeat,
|
||||||
AddressModeW = SamplerAddressMode.Repeat,
|
AddressModeW = SamplerAddressMode.Repeat,
|
||||||
CompareEnable = false,
|
CompareEnable = false,
|
||||||
AnisotropyEnable = true,
|
AnisotropyEnable = true,
|
||||||
MaxAnisotropy = 4,
|
MaxAnisotropy = 4,
|
||||||
MipLodBias = 0f,
|
MipLodBias = 0f,
|
||||||
MinLod = 0,
|
MinLod = 0,
|
||||||
MaxLod = 1000 /* VK_LOD_CLAMP_NONE */
|
MaxLod = 1000 /* VK_LOD_CLAMP_NONE */
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly SamplerCreateInfo LinearClamp = new SamplerCreateInfo
|
public static readonly SamplerCreateInfo LinearClamp = new SamplerCreateInfo
|
||||||
{
|
{
|
||||||
MinFilter = Filter.Linear,
|
MinFilter = Filter.Linear,
|
||||||
MagFilter = Filter.Linear,
|
MagFilter = Filter.Linear,
|
||||||
MipmapMode = SamplerMipmapMode.Linear,
|
MipmapMode = SamplerMipmapMode.Linear,
|
||||||
AddressModeU = SamplerAddressMode.ClampToEdge,
|
AddressModeU = SamplerAddressMode.ClampToEdge,
|
||||||
AddressModeV = SamplerAddressMode.ClampToEdge,
|
AddressModeV = SamplerAddressMode.ClampToEdge,
|
||||||
AddressModeW = SamplerAddressMode.ClampToEdge,
|
AddressModeW = SamplerAddressMode.ClampToEdge,
|
||||||
CompareEnable = false,
|
CompareEnable = false,
|
||||||
AnisotropyEnable = false,
|
AnisotropyEnable = false,
|
||||||
MipLodBias = 0f,
|
MipLodBias = 0f,
|
||||||
MinLod = 0,
|
MinLod = 0,
|
||||||
MaxLod = 1000
|
MaxLod = 1000
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly SamplerCreateInfo LinearWrap = new SamplerCreateInfo
|
public static readonly SamplerCreateInfo LinearWrap = new SamplerCreateInfo
|
||||||
{
|
{
|
||||||
MinFilter = Filter.Linear,
|
MinFilter = Filter.Linear,
|
||||||
MagFilter = Filter.Linear,
|
MagFilter = Filter.Linear,
|
||||||
MipmapMode = SamplerMipmapMode.Linear,
|
MipmapMode = SamplerMipmapMode.Linear,
|
||||||
AddressModeU = SamplerAddressMode.Repeat,
|
AddressModeU = SamplerAddressMode.Repeat,
|
||||||
AddressModeV = SamplerAddressMode.Repeat,
|
AddressModeV = SamplerAddressMode.Repeat,
|
||||||
AddressModeW = SamplerAddressMode.Repeat,
|
AddressModeW = SamplerAddressMode.Repeat,
|
||||||
CompareEnable = false,
|
CompareEnable = false,
|
||||||
AnisotropyEnable = false,
|
AnisotropyEnable = false,
|
||||||
MipLodBias = 0f,
|
MipLodBias = 0f,
|
||||||
MinLod = 0,
|
MinLod = 0,
|
||||||
MaxLod = 1000
|
MaxLod = 1000
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly SamplerCreateInfo PointClamp = new SamplerCreateInfo
|
public static readonly SamplerCreateInfo PointClamp = new SamplerCreateInfo
|
||||||
{
|
{
|
||||||
MinFilter = Filter.Nearest,
|
MinFilter = Filter.Nearest,
|
||||||
MagFilter = Filter.Nearest,
|
MagFilter = Filter.Nearest,
|
||||||
MipmapMode = SamplerMipmapMode.Nearest,
|
MipmapMode = SamplerMipmapMode.Nearest,
|
||||||
AddressModeU = SamplerAddressMode.ClampToEdge,
|
AddressModeU = SamplerAddressMode.ClampToEdge,
|
||||||
AddressModeV = SamplerAddressMode.ClampToEdge,
|
AddressModeV = SamplerAddressMode.ClampToEdge,
|
||||||
AddressModeW = SamplerAddressMode.ClampToEdge,
|
AddressModeW = SamplerAddressMode.ClampToEdge,
|
||||||
CompareEnable = false,
|
CompareEnable = false,
|
||||||
AnisotropyEnable = false,
|
AnisotropyEnable = false,
|
||||||
MipLodBias = 0f,
|
MipLodBias = 0f,
|
||||||
MinLod = 0,
|
MinLod = 0,
|
||||||
MaxLod = 1000
|
MaxLod = 1000
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly SamplerCreateInfo PointWrap = new SamplerCreateInfo
|
public static readonly SamplerCreateInfo PointWrap = new SamplerCreateInfo
|
||||||
{
|
{
|
||||||
MinFilter = Filter.Nearest,
|
MinFilter = Filter.Nearest,
|
||||||
MagFilter = Filter.Nearest,
|
MagFilter = Filter.Nearest,
|
||||||
MipmapMode = SamplerMipmapMode.Nearest,
|
MipmapMode = SamplerMipmapMode.Nearest,
|
||||||
AddressModeU = SamplerAddressMode.Repeat,
|
AddressModeU = SamplerAddressMode.Repeat,
|
||||||
AddressModeV = SamplerAddressMode.Repeat,
|
AddressModeV = SamplerAddressMode.Repeat,
|
||||||
AddressModeW = SamplerAddressMode.Repeat,
|
AddressModeW = SamplerAddressMode.Repeat,
|
||||||
CompareEnable = false,
|
CompareEnable = false,
|
||||||
AnisotropyEnable = false,
|
AnisotropyEnable = false,
|
||||||
MipLodBias = 0f,
|
MipLodBias = 0f,
|
||||||
MinLod = 0,
|
MinLod = 0,
|
||||||
MaxLod = 1000
|
MaxLod = 1000
|
||||||
};
|
};
|
||||||
|
|
||||||
public Refresh.SamplerStateCreateInfo ToRefreshSamplerStateCreateInfo()
|
public Refresh.SamplerStateCreateInfo ToRefreshSamplerStateCreateInfo()
|
||||||
{
|
{
|
||||||
return new Refresh.SamplerStateCreateInfo
|
return new Refresh.SamplerStateCreateInfo
|
||||||
{
|
{
|
||||||
minFilter = (Refresh.Filter)MinFilter,
|
minFilter = (Refresh.Filter) MinFilter,
|
||||||
magFilter = (Refresh.Filter)MagFilter,
|
magFilter = (Refresh.Filter) MagFilter,
|
||||||
mipmapMode = (Refresh.SamplerMipmapMode)MipmapMode,
|
mipmapMode = (Refresh.SamplerMipmapMode) MipmapMode,
|
||||||
addressModeU = (Refresh.SamplerAddressMode)AddressModeU,
|
addressModeU = (Refresh.SamplerAddressMode) AddressModeU,
|
||||||
addressModeV = (Refresh.SamplerAddressMode)AddressModeV,
|
addressModeV = (Refresh.SamplerAddressMode) AddressModeV,
|
||||||
addressModeW = (Refresh.SamplerAddressMode)AddressModeW,
|
addressModeW = (Refresh.SamplerAddressMode) AddressModeW,
|
||||||
mipLodBias = MipLodBias,
|
mipLodBias = MipLodBias,
|
||||||
anisotropyEnable = Conversions.BoolToByte(AnisotropyEnable),
|
anisotropyEnable = Conversions.BoolToByte(AnisotropyEnable),
|
||||||
maxAnisotropy = MaxAnisotropy,
|
maxAnisotropy = MaxAnisotropy,
|
||||||
compareEnable = Conversions.BoolToByte(CompareEnable),
|
compareEnable = Conversions.BoolToByte(CompareEnable),
|
||||||
compareOp = (Refresh.CompareOp)CompareOp,
|
compareOp = (Refresh.CompareOp) CompareOp,
|
||||||
minLod = MinLod,
|
minLod = MinLod,
|
||||||
maxLod = MaxLod,
|
maxLod = MaxLod,
|
||||||
borderColor = (Refresh.BorderColor)BorderColor
|
borderColor = (Refresh.BorderColor) BorderColor
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
namespace MoonWorks.Graphics
|
namespace MoonWorks.Graphics
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Specifies how the graphics pipeline will make use of a shader.
|
/// Specifies how the graphics pipeline will make use of a shader.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public struct ShaderStageState
|
public struct ShaderStageState
|
||||||
{
|
{
|
||||||
public ShaderModule ShaderModule;
|
public ShaderModule ShaderModule;
|
||||||
public string EntryPointName;
|
public string EntryPointName;
|
||||||
public uint UniformBufferSize;
|
public uint UniformBufferSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,30 +2,30 @@
|
||||||
|
|
||||||
namespace MoonWorks.Graphics
|
namespace MoonWorks.Graphics
|
||||||
{
|
{
|
||||||
public struct TextureCreateInfo
|
public struct TextureCreateInfo
|
||||||
{
|
{
|
||||||
public uint Width;
|
public uint Width;
|
||||||
public uint Height;
|
public uint Height;
|
||||||
public uint Depth;
|
public uint Depth;
|
||||||
public bool IsCube;
|
public bool IsCube;
|
||||||
public SampleCount SampleCount;
|
public SampleCount SampleCount;
|
||||||
public uint LevelCount;
|
public uint LevelCount;
|
||||||
public TextureFormat Format;
|
public TextureFormat Format;
|
||||||
public TextureUsageFlags UsageFlags;
|
public TextureUsageFlags UsageFlags;
|
||||||
|
|
||||||
public Refresh.TextureCreateInfo ToRefreshTextureCreateInfo()
|
public Refresh.TextureCreateInfo ToRefreshTextureCreateInfo()
|
||||||
{
|
{
|
||||||
return new Refresh.TextureCreateInfo
|
return new Refresh.TextureCreateInfo
|
||||||
{
|
{
|
||||||
width = Width,
|
width = Width,
|
||||||
height = Height,
|
height = Height,
|
||||||
depth = Depth,
|
depth = Depth,
|
||||||
isCube = Conversions.BoolToByte(IsCube),
|
isCube = Conversions.BoolToByte(IsCube),
|
||||||
sampleCount = (Refresh.SampleCount) SampleCount,
|
sampleCount = (Refresh.SampleCount) SampleCount,
|
||||||
levelCount = LevelCount,
|
levelCount = LevelCount,
|
||||||
format = (Refresh.TextureFormat) Format,
|
format = (Refresh.TextureFormat) Format,
|
||||||
usageFlags = (Refresh.TextureUsageFlags) UsageFlags
|
usageFlags = (Refresh.TextureUsageFlags) UsageFlags
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
namespace MoonWorks.Graphics
|
namespace MoonWorks.Graphics
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Specifies how to interpet vertex data in a buffer to be passed to the vertex shader.
|
/// Specifies how to interpet vertex data in a buffer to be passed to the vertex shader.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public struct VertexInputState
|
public struct VertexInputState
|
||||||
{
|
{
|
||||||
public VertexBinding[] VertexBindings;
|
public VertexBinding[] VertexBindings;
|
||||||
public VertexAttribute[] VertexAttributes;
|
public VertexAttribute[] VertexAttributes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
namespace MoonWorks.Graphics
|
namespace MoonWorks.Graphics
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Describes the dimensions of viewports and scissor areas.
|
/// Describes the dimensions of viewports and scissor areas.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public struct ViewportState
|
public struct ViewportState
|
||||||
{
|
{
|
||||||
public Viewport[] Viewports;
|
public Viewport[] Viewports;
|
||||||
public Rect[] Scissors;
|
public Rect[] Scissors;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
namespace MoonWorks.Graphics
|
namespace MoonWorks.Graphics
|
||||||
{
|
{
|
||||||
public struct BlendConstants
|
public struct BlendConstants
|
||||||
{
|
{
|
||||||
public float R;
|
public float R;
|
||||||
public float G;
|
public float G;
|
||||||
public float B;
|
public float B;
|
||||||
public float A;
|
public float A;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,54 +2,54 @@
|
||||||
|
|
||||||
namespace MoonWorks.Graphics
|
namespace MoonWorks.Graphics
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A texture slice specifies a subregion of a texture.
|
/// A texture slice specifies a subregion of a texture.
|
||||||
/// Many operations can use texture slices in place of textures for the sake of convenience.
|
/// Many operations can use texture slices in place of textures for the sake of convenience.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public struct TextureSlice
|
public struct TextureSlice
|
||||||
{
|
{
|
||||||
public Texture Texture { get; }
|
public Texture Texture { get; }
|
||||||
public Rect Rectangle { get; }
|
public Rect Rectangle { get; }
|
||||||
public uint Depth { get; }
|
public uint Depth { get; }
|
||||||
public uint Layer { get; }
|
public uint Layer { get; }
|
||||||
public uint Level { get; }
|
public uint Level { get; }
|
||||||
|
|
||||||
public TextureSlice(Texture texture)
|
public TextureSlice(Texture texture)
|
||||||
{
|
{
|
||||||
Texture = texture;
|
Texture = texture;
|
||||||
Rectangle = new Rect
|
Rectangle = new Rect
|
||||||
{
|
{
|
||||||
X = 0,
|
X = 0,
|
||||||
Y = 0,
|
Y = 0,
|
||||||
W = (int) texture.Width,
|
W = (int) texture.Width,
|
||||||
H = (int) texture.Height
|
H = (int) texture.Height
|
||||||
};
|
};
|
||||||
Depth = 0;
|
Depth = 0;
|
||||||
Layer = 0;
|
Layer = 0;
|
||||||
Level = 0;
|
Level = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TextureSlice(Texture texture, Rect rectangle, uint depth = 0, uint layer = 0, uint level = 0)
|
public TextureSlice(Texture texture, Rect rectangle, uint depth = 0, uint layer = 0, uint level = 0)
|
||||||
{
|
{
|
||||||
Texture = texture;
|
Texture = texture;
|
||||||
Rectangle = rectangle;
|
Rectangle = rectangle;
|
||||||
Depth = depth;
|
Depth = depth;
|
||||||
Layer = layer;
|
Layer = layer;
|
||||||
Level = level;
|
Level = level;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Refresh.TextureSlice ToRefreshTextureSlice()
|
public Refresh.TextureSlice ToRefreshTextureSlice()
|
||||||
{
|
{
|
||||||
Refresh.TextureSlice textureSlice = new Refresh.TextureSlice
|
Refresh.TextureSlice textureSlice = new Refresh.TextureSlice
|
||||||
{
|
{
|
||||||
texture = Texture.Handle,
|
texture = Texture.Handle,
|
||||||
rectangle = Rectangle.ToRefresh(),
|
rectangle = Rectangle.ToRefresh(),
|
||||||
depth = Depth,
|
depth = Depth,
|
||||||
layer = Layer,
|
layer = Layer,
|
||||||
level = Level
|
level = Level
|
||||||
};
|
};
|
||||||
|
|
||||||
return textureSlice;
|
return textureSlice;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,32 +2,32 @@
|
||||||
|
|
||||||
namespace MoonWorks.Graphics
|
namespace MoonWorks.Graphics
|
||||||
{
|
{
|
||||||
public static class Bytecode
|
public static class Bytecode
|
||||||
{
|
{
|
||||||
public static uint[] ReadBytecodeAsUInt32(string filePath)
|
public static uint[] ReadBytecodeAsUInt32(string filePath)
|
||||||
{
|
{
|
||||||
byte[] data;
|
byte[] data;
|
||||||
int size;
|
int size;
|
||||||
using (FileStream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
|
using (FileStream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
|
||||||
{
|
{
|
||||||
size = (int)stream.Length;
|
size = (int) stream.Length;
|
||||||
data = new byte[size];
|
data = new byte[size];
|
||||||
stream.Read(data, 0, size);
|
stream.Read(data, 0, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint[] uintData = new uint[size / 4];
|
uint[] uintData = new uint[size / 4];
|
||||||
using (var memoryStream = new MemoryStream(data))
|
using (var memoryStream = new MemoryStream(data))
|
||||||
{
|
{
|
||||||
using (var reader = new BinaryReader(memoryStream))
|
using (var reader = new BinaryReader(memoryStream))
|
||||||
{
|
{
|
||||||
for (int i = 0; i < size / 4; i++)
|
for (int i = 0; i < size / 4; i++)
|
||||||
{
|
{
|
||||||
uintData[i] = reader.ReadUInt32();
|
uintData[i] = reader.ReadUInt32();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return uintData;
|
return uintData;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
namespace MoonWorks
|
namespace MoonWorks
|
||||||
{
|
{
|
||||||
public static class Conversions
|
public static class Conversions
|
||||||
{
|
{
|
||||||
public static byte BoolToByte(bool b)
|
public static byte BoolToByte(bool b)
|
||||||
{
|
{
|
||||||
return (byte)(b ? 1 : 0);
|
return (byte) (b ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool ByteToBool(byte b)
|
public static bool ByteToBool(byte b)
|
||||||
{
|
{
|
||||||
return b == 0 ? false : true;
|
return b == 0 ? false : true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,31 +1,31 @@
|
||||||
namespace MoonWorks.Input
|
namespace MoonWorks.Input
|
||||||
{
|
{
|
||||||
public class ButtonState
|
public class ButtonState
|
||||||
{
|
{
|
||||||
private ButtonStatus ButtonStatus { get; set; }
|
private ButtonStatus ButtonStatus { get; set; }
|
||||||
|
|
||||||
public bool IsPressed => ButtonStatus == ButtonStatus.Pressed;
|
public bool IsPressed => ButtonStatus == ButtonStatus.Pressed;
|
||||||
public bool IsHeld => ButtonStatus == ButtonStatus.Held;
|
public bool IsHeld => ButtonStatus == ButtonStatus.Held;
|
||||||
public bool IsDown => ButtonStatus == ButtonStatus.Pressed || ButtonStatus == ButtonStatus.Held;
|
public bool IsDown => ButtonStatus == ButtonStatus.Pressed || ButtonStatus == ButtonStatus.Held;
|
||||||
public bool IsReleased => ButtonStatus == ButtonStatus.Released;
|
public bool IsReleased => ButtonStatus == ButtonStatus.Released;
|
||||||
|
|
||||||
internal void Update(bool isPressed)
|
internal void Update(bool isPressed)
|
||||||
{
|
{
|
||||||
if (isPressed)
|
if (isPressed)
|
||||||
{
|
{
|
||||||
if (ButtonStatus == ButtonStatus.Pressed)
|
if (ButtonStatus == ButtonStatus.Pressed)
|
||||||
{
|
{
|
||||||
ButtonStatus = ButtonStatus.Held;
|
ButtonStatus = ButtonStatus.Held;
|
||||||
}
|
}
|
||||||
else if (ButtonStatus == ButtonStatus.Released)
|
else if (ButtonStatus == ButtonStatus.Released)
|
||||||
{
|
{
|
||||||
ButtonStatus = ButtonStatus.Pressed;
|
ButtonStatus = ButtonStatus.Pressed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ButtonStatus = ButtonStatus.Released;
|
ButtonStatus = ButtonStatus.Released;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
namespace MoonWorks.Input
|
namespace MoonWorks.Input
|
||||||
{
|
{
|
||||||
internal enum ButtonStatus
|
internal enum ButtonStatus
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Indicates that the input is not pressed.
|
/// Indicates that the input is not pressed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Released,
|
Released,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Indicates that the input was pressed this frame.
|
/// Indicates that the input was pressed this frame.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Pressed,
|
Pressed,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Indicates that the input has been held for multiple frames.
|
/// Indicates that the input has been held for multiple frames.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Held
|
Held
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,98 +1,98 @@
|
||||||
using System;
|
using System;
|
||||||
using MoonWorks.Math;
|
using MoonWorks.Math;
|
||||||
using SDL2;
|
using SDL2;
|
||||||
|
|
||||||
namespace MoonWorks.Input
|
namespace MoonWorks.Input
|
||||||
{
|
{
|
||||||
public class Gamepad
|
public class Gamepad
|
||||||
{
|
{
|
||||||
internal IntPtr Handle;
|
internal IntPtr Handle;
|
||||||
|
|
||||||
public ButtonState A { get; } = new ButtonState();
|
public ButtonState A { get; } = new ButtonState();
|
||||||
public ButtonState B { get; } = new ButtonState();
|
public ButtonState B { get; } = new ButtonState();
|
||||||
public ButtonState X { get; } = new ButtonState();
|
public ButtonState X { get; } = new ButtonState();
|
||||||
public ButtonState Y { get; } = new ButtonState();
|
public ButtonState Y { get; } = new ButtonState();
|
||||||
public ButtonState Back { get; } = new ButtonState();
|
public ButtonState Back { get; } = new ButtonState();
|
||||||
public ButtonState Guide { get; } = new ButtonState();
|
public ButtonState Guide { get; } = new ButtonState();
|
||||||
public ButtonState Start { get; } = new ButtonState();
|
public ButtonState Start { get; } = new ButtonState();
|
||||||
public ButtonState LeftStick { get; } = new ButtonState();
|
public ButtonState LeftStick { get; } = new ButtonState();
|
||||||
public ButtonState RightStick { get; } = new ButtonState();
|
public ButtonState RightStick { get; } = new ButtonState();
|
||||||
public ButtonState LeftShoulder { get; } = new ButtonState();
|
public ButtonState LeftShoulder { get; } = new ButtonState();
|
||||||
public ButtonState RightShoulder { get; } = new ButtonState();
|
public ButtonState RightShoulder { get; } = new ButtonState();
|
||||||
public ButtonState DpadUp { get; } = new ButtonState();
|
public ButtonState DpadUp { get; } = new ButtonState();
|
||||||
public ButtonState DpadDown { get; } = new ButtonState();
|
public ButtonState DpadDown { get; } = new ButtonState();
|
||||||
public ButtonState DpadLeft { get; } = new ButtonState();
|
public ButtonState DpadLeft { get; } = new ButtonState();
|
||||||
public ButtonState DpadRight { get; } = new ButtonState();
|
public ButtonState DpadRight { get; } = new ButtonState();
|
||||||
|
|
||||||
public float LeftX { get; private set; }
|
public float LeftX { get; private set; }
|
||||||
public float LeftY { get; private set; }
|
public float LeftY { get; private set; }
|
||||||
public float RightX { get; private set; }
|
public float RightX { get; private set; }
|
||||||
public float RightY { get; private set; }
|
public float RightY { get; private set; }
|
||||||
public float TriggerLeft { get; private set; }
|
public float TriggerLeft { get; private set; }
|
||||||
public float TriggerRight { get; private set; }
|
public float TriggerRight { get; private set; }
|
||||||
|
|
||||||
internal Gamepad(IntPtr handle)
|
internal Gamepad(IntPtr handle)
|
||||||
{
|
{
|
||||||
Handle = handle;
|
Handle = handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool SetVibration(float leftMotor, float rightMotor, uint durationInMilliseconds)
|
public bool SetVibration(float leftMotor, float rightMotor, uint durationInMilliseconds)
|
||||||
{
|
{
|
||||||
return SDL.SDL_GameControllerRumble(
|
return SDL.SDL_GameControllerRumble(
|
||||||
Handle,
|
Handle,
|
||||||
(ushort)(MathHelper.Clamp(leftMotor, 0f, 1f) * 0xFFFF),
|
(ushort) (MathHelper.Clamp(leftMotor, 0f, 1f) * 0xFFFF),
|
||||||
(ushort)(MathHelper.Clamp(rightMotor, 0f, 1f) * 0xFFFF),
|
(ushort) (MathHelper.Clamp(rightMotor, 0f, 1f) * 0xFFFF),
|
||||||
durationInMilliseconds
|
durationInMilliseconds
|
||||||
) == 0;
|
) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Update()
|
internal void Update()
|
||||||
{
|
{
|
||||||
A.Update(IsPressed(SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_A));
|
A.Update(IsPressed(SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_A));
|
||||||
B.Update(IsPressed(SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_B));
|
B.Update(IsPressed(SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_B));
|
||||||
X.Update(IsPressed(SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_X));
|
X.Update(IsPressed(SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_X));
|
||||||
Y.Update(IsPressed(SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_Y));
|
Y.Update(IsPressed(SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_Y));
|
||||||
Back.Update(IsPressed(SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_BACK));
|
Back.Update(IsPressed(SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_BACK));
|
||||||
Guide.Update(IsPressed(SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_GUIDE));
|
Guide.Update(IsPressed(SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_GUIDE));
|
||||||
Start.Update(IsPressed(SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_START));
|
Start.Update(IsPressed(SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_START));
|
||||||
LeftStick.Update(IsPressed(SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_LEFTSTICK));
|
LeftStick.Update(IsPressed(SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_LEFTSTICK));
|
||||||
RightStick.Update(IsPressed(SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_RIGHTSTICK));
|
RightStick.Update(IsPressed(SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_RIGHTSTICK));
|
||||||
LeftShoulder.Update(IsPressed(SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_LEFTSHOULDER));
|
LeftShoulder.Update(IsPressed(SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_LEFTSHOULDER));
|
||||||
RightShoulder.Update(IsPressed(SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_RIGHTSHOULDER));
|
RightShoulder.Update(IsPressed(SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_RIGHTSHOULDER));
|
||||||
DpadUp.Update(IsPressed(SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_DPAD_UP));
|
DpadUp.Update(IsPressed(SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_DPAD_UP));
|
||||||
DpadDown.Update(IsPressed(SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_DPAD_DOWN));
|
DpadDown.Update(IsPressed(SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_DPAD_DOWN));
|
||||||
DpadLeft.Update(IsPressed(SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_DPAD_LEFT));
|
DpadLeft.Update(IsPressed(SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_DPAD_LEFT));
|
||||||
DpadRight.Update(IsPressed(SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_DPAD_RIGHT));
|
DpadRight.Update(IsPressed(SDL.SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_DPAD_RIGHT));
|
||||||
|
|
||||||
LeftX = UpdateAxis(SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_LEFTX);
|
LeftX = UpdateAxis(SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_LEFTX);
|
||||||
LeftY = UpdateAxis(SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_LEFTY);
|
LeftY = UpdateAxis(SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_LEFTY);
|
||||||
RightX = UpdateAxis(SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_RIGHTX);
|
RightX = UpdateAxis(SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_RIGHTX);
|
||||||
RightY = UpdateAxis(SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_RIGHTY);
|
RightY = UpdateAxis(SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_RIGHTY);
|
||||||
TriggerLeft = UpdateTrigger(SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_TRIGGERLEFT);
|
TriggerLeft = UpdateTrigger(SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_TRIGGERLEFT);
|
||||||
TriggerRight = UpdateTrigger(SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_TRIGGERRIGHT);
|
TriggerRight = UpdateTrigger(SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_TRIGGERRIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsPressed(SDL.SDL_GameControllerButton button)
|
private bool IsPressed(SDL.SDL_GameControllerButton button)
|
||||||
{
|
{
|
||||||
return MoonWorks.Conversions.ByteToBool(SDL.SDL_GameControllerGetButton(Handle, button));
|
return MoonWorks.Conversions.ByteToBool(SDL.SDL_GameControllerGetButton(Handle, button));
|
||||||
}
|
}
|
||||||
|
|
||||||
private float UpdateAxis(SDL.SDL_GameControllerAxis axis)
|
private float UpdateAxis(SDL.SDL_GameControllerAxis axis)
|
||||||
{
|
{
|
||||||
var axisValue = SDL.SDL_GameControllerGetAxis(Handle, axis);
|
var axisValue = SDL.SDL_GameControllerGetAxis(Handle, axis);
|
||||||
return Normalize(axisValue, short.MinValue, short.MaxValue, -1, 1);
|
return Normalize(axisValue, short.MinValue, short.MaxValue, -1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Triggers only go from 0 to short.MaxValue
|
// Triggers only go from 0 to short.MaxValue
|
||||||
private float UpdateTrigger(SDL.SDL_GameControllerAxis trigger)
|
private float UpdateTrigger(SDL.SDL_GameControllerAxis trigger)
|
||||||
{
|
{
|
||||||
var triggerValue = SDL.SDL_GameControllerGetAxis(Handle, trigger);
|
var triggerValue = SDL.SDL_GameControllerGetAxis(Handle, trigger);
|
||||||
return Normalize(triggerValue, 0, short.MaxValue, 0, 1);
|
return Normalize(triggerValue, 0, short.MaxValue, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private float Normalize(float value, short min, short max, short newMin, short newMax)
|
private float Normalize(float value, short min, short max, short newMin, short newMax)
|
||||||
{
|
{
|
||||||
return ((value - min) * (newMax - newMin)) / (max - min) + newMin;
|
return ((value - min) * (newMax - newMin)) / (max - min) + newMin;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,60 +1,60 @@
|
||||||
using SDL2;
|
using SDL2;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace MoonWorks.Input
|
namespace MoonWorks.Input
|
||||||
{
|
{
|
||||||
public class Inputs
|
public class Inputs
|
||||||
{
|
{
|
||||||
public Keyboard Keyboard { get; }
|
public Keyboard Keyboard { get; }
|
||||||
public Mouse Mouse { get; }
|
public Mouse Mouse { get; }
|
||||||
|
|
||||||
List<Gamepad> gamepads = new List<Gamepad>();
|
List<Gamepad> gamepads = new List<Gamepad>();
|
||||||
|
|
||||||
public static event Action<char> TextInput;
|
public static event Action<char> TextInput;
|
||||||
|
|
||||||
internal Inputs()
|
internal Inputs()
|
||||||
{
|
{
|
||||||
Keyboard = new Keyboard();
|
Keyboard = new Keyboard();
|
||||||
Mouse = new Mouse();
|
Mouse = new Mouse();
|
||||||
|
|
||||||
for (int i = 0; i < SDL.SDL_NumJoysticks(); i++)
|
for (int i = 0; i < SDL.SDL_NumJoysticks(); i++)
|
||||||
{
|
{
|
||||||
if (SDL.SDL_IsGameController(i) == SDL.SDL_bool.SDL_TRUE)
|
if (SDL.SDL_IsGameController(i) == SDL.SDL_bool.SDL_TRUE)
|
||||||
{
|
{
|
||||||
gamepads.Add(new Gamepad(SDL.SDL_GameControllerOpen(i)));
|
gamepads.Add(new Gamepad(SDL.SDL_GameControllerOpen(i)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assumes that SDL_PumpEvents has been called!
|
// Assumes that SDL_PumpEvents has been called!
|
||||||
internal void Update()
|
internal void Update()
|
||||||
{
|
{
|
||||||
Keyboard.Update();
|
Keyboard.Update();
|
||||||
Mouse.Update();
|
Mouse.Update();
|
||||||
|
|
||||||
foreach (var gamepad in gamepads)
|
foreach (var gamepad in gamepads)
|
||||||
{
|
{
|
||||||
gamepad.Update();
|
gamepad.Update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool GamepadExists(int slot)
|
public bool GamepadExists(int slot)
|
||||||
{
|
{
|
||||||
return slot < gamepads.Count;
|
return slot < gamepads.Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Gamepad GetGamepad(int slot)
|
public Gamepad GetGamepad(int slot)
|
||||||
{
|
{
|
||||||
return gamepads[slot];
|
return gamepads[slot];
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void OnTextInput(char c)
|
internal static void OnTextInput(char c)
|
||||||
{
|
{
|
||||||
if (TextInput != null)
|
if (TextInput != null)
|
||||||
{
|
{
|
||||||
TextInput(c);
|
TextInput(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using SDL2;
|
using SDL2;
|
||||||
|
|
||||||
namespace MoonWorks.Input
|
namespace MoonWorks.Input
|
||||||
{
|
{
|
||||||
public class Keyboard
|
public class Keyboard
|
||||||
{
|
{
|
||||||
private ButtonState[] Keys { get; }
|
private ButtonState[] Keys { get; }
|
||||||
private int numKeys;
|
private int numKeys;
|
||||||
|
|
||||||
private static readonly char[] TextInputCharacters = new char[]
|
private static readonly char[] TextInputCharacters = new char[]
|
||||||
{
|
{
|
||||||
|
@ -21,69 +21,69 @@ namespace MoonWorks.Input
|
||||||
(char) 22 // Ctrl+V (Paste)
|
(char) 22 // Ctrl+V (Paste)
|
||||||
};
|
};
|
||||||
|
|
||||||
private static readonly Dictionary<Keycode, int> TextInputBindings = new Dictionary<Keycode, int>()
|
private static readonly Dictionary<Keycode, int> TextInputBindings = new Dictionary<Keycode, int>()
|
||||||
{
|
{
|
||||||
{ Keycode.Home, 0 },
|
{ Keycode.Home, 0 },
|
||||||
{ Keycode.End, 1 },
|
{ Keycode.End, 1 },
|
||||||
{ Keycode.Backspace, 2 },
|
{ Keycode.Backspace, 2 },
|
||||||
{ Keycode.Tab, 3 },
|
{ Keycode.Tab, 3 },
|
||||||
{ Keycode.Return, 4 },
|
{ Keycode.Return, 4 },
|
||||||
{ Keycode.Delete, 5 }
|
{ Keycode.Delete, 5 }
|
||||||
// Ctrl+V is special!
|
// Ctrl+V is special!
|
||||||
};
|
};
|
||||||
|
|
||||||
internal Keyboard()
|
internal Keyboard()
|
||||||
{
|
{
|
||||||
SDL.SDL_GetKeyboardState(out numKeys);
|
SDL.SDL_GetKeyboardState(out numKeys);
|
||||||
|
|
||||||
Keys = new ButtonState[numKeys];
|
Keys = new ButtonState[numKeys];
|
||||||
foreach (Keycode keycode in Enum.GetValues(typeof(Keycode)))
|
foreach (Keycode keycode in Enum.GetValues(typeof(Keycode)))
|
||||||
{
|
{
|
||||||
Keys[(int)keycode] = new ButtonState();
|
Keys[(int) keycode] = new ButtonState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Update()
|
internal void Update()
|
||||||
{
|
{
|
||||||
IntPtr keyboardState = SDL.SDL_GetKeyboardState(out _);
|
IntPtr keyboardState = SDL.SDL_GetKeyboardState(out _);
|
||||||
|
|
||||||
foreach (int keycode in Enum.GetValues(typeof(Keycode)))
|
foreach (int keycode in Enum.GetValues(typeof(Keycode)))
|
||||||
{
|
{
|
||||||
var keyDown = Marshal.ReadByte(keyboardState, keycode);
|
var keyDown = Marshal.ReadByte(keyboardState, keycode);
|
||||||
Keys[keycode].Update(Conversions.ByteToBool(keyDown));
|
Keys[keycode].Update(Conversions.ByteToBool(keyDown));
|
||||||
|
|
||||||
if (Conversions.ByteToBool(keyDown))
|
if (Conversions.ByteToBool(keyDown))
|
||||||
{
|
{
|
||||||
if (TextInputBindings.TryGetValue((Keycode)keycode, out var textIndex))
|
if (TextInputBindings.TryGetValue((Keycode) keycode, out var textIndex))
|
||||||
{
|
{
|
||||||
Inputs.OnTextInput(TextInputCharacters[(textIndex)]);
|
Inputs.OnTextInput(TextInputCharacters[(textIndex)]);
|
||||||
}
|
}
|
||||||
else if (IsDown(Keycode.LeftControl) && (Keycode)keycode == Keycode.V)
|
else if (IsDown(Keycode.LeftControl) && (Keycode) keycode == Keycode.V)
|
||||||
{
|
{
|
||||||
Inputs.OnTextInput(TextInputCharacters[6]);
|
Inputs.OnTextInput(TextInputCharacters[6]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsDown(Keycode keycode)
|
public bool IsDown(Keycode keycode)
|
||||||
{
|
{
|
||||||
return Keys[(int)keycode].IsDown;
|
return Keys[(int) keycode].IsDown;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsPressed(Keycode keycode)
|
public bool IsPressed(Keycode keycode)
|
||||||
{
|
{
|
||||||
return Keys[(int)keycode].IsPressed;
|
return Keys[(int) keycode].IsPressed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsHeld(Keycode keycode)
|
public bool IsHeld(Keycode keycode)
|
||||||
{
|
{
|
||||||
return Keys[(int)keycode].IsHeld;
|
return Keys[(int) keycode].IsHeld;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsReleased(Keycode keycode)
|
public bool IsReleased(Keycode keycode)
|
||||||
{
|
{
|
||||||
return Keys[(int)keycode].IsReleased;
|
return Keys[(int) keycode].IsReleased;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,113 +1,113 @@
|
||||||
namespace MoonWorks.Input
|
namespace MoonWorks.Input
|
||||||
{
|
{
|
||||||
// Enum values are equivalent to the SDL Scancode value.
|
// Enum values are equivalent to the SDL Scancode value.
|
||||||
public enum Keycode : int
|
public enum Keycode : int
|
||||||
{
|
{
|
||||||
Unknown = 0,
|
Unknown = 0,
|
||||||
A = 4,
|
A = 4,
|
||||||
B = 5,
|
B = 5,
|
||||||
C = 6,
|
C = 6,
|
||||||
D = 7,
|
D = 7,
|
||||||
E = 8,
|
E = 8,
|
||||||
F = 9,
|
F = 9,
|
||||||
G = 10,
|
G = 10,
|
||||||
H = 11,
|
H = 11,
|
||||||
I = 12,
|
I = 12,
|
||||||
J = 13,
|
J = 13,
|
||||||
K = 14,
|
K = 14,
|
||||||
L = 15,
|
L = 15,
|
||||||
M = 16,
|
M = 16,
|
||||||
N = 17,
|
N = 17,
|
||||||
O = 18,
|
O = 18,
|
||||||
P = 19,
|
P = 19,
|
||||||
Q = 20,
|
Q = 20,
|
||||||
R = 21,
|
R = 21,
|
||||||
S = 22,
|
S = 22,
|
||||||
T = 23,
|
T = 23,
|
||||||
U = 24,
|
U = 24,
|
||||||
V = 25,
|
V = 25,
|
||||||
W = 26,
|
W = 26,
|
||||||
X = 27,
|
X = 27,
|
||||||
Y = 28,
|
Y = 28,
|
||||||
Z = 29,
|
Z = 29,
|
||||||
D1 = 30,
|
D1 = 30,
|
||||||
D2 = 31,
|
D2 = 31,
|
||||||
D3 = 32,
|
D3 = 32,
|
||||||
D4 = 33,
|
D4 = 33,
|
||||||
D5 = 34,
|
D5 = 34,
|
||||||
D6 = 35,
|
D6 = 35,
|
||||||
D7 = 36,
|
D7 = 36,
|
||||||
D8 = 37,
|
D8 = 37,
|
||||||
D9 = 38,
|
D9 = 38,
|
||||||
D0 = 39,
|
D0 = 39,
|
||||||
Return = 40,
|
Return = 40,
|
||||||
Escape = 41,
|
Escape = 41,
|
||||||
Backspace = 42,
|
Backspace = 42,
|
||||||
Tab = 43,
|
Tab = 43,
|
||||||
Space = 44,
|
Space = 44,
|
||||||
Minus = 45,
|
Minus = 45,
|
||||||
Equals = 46,
|
Equals = 46,
|
||||||
LeftBracket = 47,
|
LeftBracket = 47,
|
||||||
RightBracket = 48,
|
RightBracket = 48,
|
||||||
Backslash = 49,
|
Backslash = 49,
|
||||||
NonUSHash = 50,
|
NonUSHash = 50,
|
||||||
Semicolon = 51,
|
Semicolon = 51,
|
||||||
Apostrophe = 52,
|
Apostrophe = 52,
|
||||||
Grave = 53,
|
Grave = 53,
|
||||||
Comma = 54,
|
Comma = 54,
|
||||||
Period = 55,
|
Period = 55,
|
||||||
Slash = 56,
|
Slash = 56,
|
||||||
CapsLock = 57,
|
CapsLock = 57,
|
||||||
F1 = 58,
|
F1 = 58,
|
||||||
F2 = 59,
|
F2 = 59,
|
||||||
F3 = 60,
|
F3 = 60,
|
||||||
F4 = 61,
|
F4 = 61,
|
||||||
F5 = 62,
|
F5 = 62,
|
||||||
F6 = 63,
|
F6 = 63,
|
||||||
F7 = 64,
|
F7 = 64,
|
||||||
F8 = 65,
|
F8 = 65,
|
||||||
F9 = 66,
|
F9 = 66,
|
||||||
F10 = 67,
|
F10 = 67,
|
||||||
F11 = 68,
|
F11 = 68,
|
||||||
F12 = 69,
|
F12 = 69,
|
||||||
PrintScreen = 70,
|
PrintScreen = 70,
|
||||||
ScrollLock = 71,
|
ScrollLock = 71,
|
||||||
Pause = 72,
|
Pause = 72,
|
||||||
Insert = 73,
|
Insert = 73,
|
||||||
Home = 74,
|
Home = 74,
|
||||||
PageUp = 75,
|
PageUp = 75,
|
||||||
Delete = 76,
|
Delete = 76,
|
||||||
End = 77,
|
End = 77,
|
||||||
PageDown = 78,
|
PageDown = 78,
|
||||||
Right = 79,
|
Right = 79,
|
||||||
Left = 80,
|
Left = 80,
|
||||||
Down = 81,
|
Down = 81,
|
||||||
Up = 82,
|
Up = 82,
|
||||||
NumLockClear = 83,
|
NumLockClear = 83,
|
||||||
KeypadDivide = 84,
|
KeypadDivide = 84,
|
||||||
KeypadMultiply = 85,
|
KeypadMultiply = 85,
|
||||||
KeypadMinus = 86,
|
KeypadMinus = 86,
|
||||||
KeypadPlus = 87,
|
KeypadPlus = 87,
|
||||||
KeypadEnter = 88,
|
KeypadEnter = 88,
|
||||||
Keypad1 = 89,
|
Keypad1 = 89,
|
||||||
Keypad2 = 90,
|
Keypad2 = 90,
|
||||||
Keypad3 = 91,
|
Keypad3 = 91,
|
||||||
Keypad4 = 92,
|
Keypad4 = 92,
|
||||||
Keypad5 = 93,
|
Keypad5 = 93,
|
||||||
Keypad6 = 94,
|
Keypad6 = 94,
|
||||||
Keypad7 = 95,
|
Keypad7 = 95,
|
||||||
Keypad8 = 96,
|
Keypad8 = 96,
|
||||||
Keypad9 = 97,
|
Keypad9 = 97,
|
||||||
Keypad0 = 98,
|
Keypad0 = 98,
|
||||||
KeypadPeriod = 99,
|
KeypadPeriod = 99,
|
||||||
NonUSBackslash = 100,
|
NonUSBackslash = 100,
|
||||||
LeftControl = 224,
|
LeftControl = 224,
|
||||||
LeftShift = 225,
|
LeftShift = 225,
|
||||||
LeftAlt = 226,
|
LeftAlt = 226,
|
||||||
LeftMeta = 227, // Windows, Command, Meta
|
LeftMeta = 227, // Windows, Command, Meta
|
||||||
RightControl = 228,
|
RightControl = 228,
|
||||||
RightShift = 229,
|
RightShift = 229,
|
||||||
RightAlt = 230,
|
RightAlt = 230,
|
||||||
RightMeta = 231 // Windows, Command, Meta
|
RightMeta = 231 // Windows, Command, Meta
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,52 +2,52 @@
|
||||||
|
|
||||||
namespace MoonWorks.Input
|
namespace MoonWorks.Input
|
||||||
{
|
{
|
||||||
public class Mouse
|
public class Mouse
|
||||||
{
|
{
|
||||||
public ButtonState LeftButton { get; } = new ButtonState();
|
public ButtonState LeftButton { get; } = new ButtonState();
|
||||||
public ButtonState MiddleButton { get; } = new ButtonState();
|
public ButtonState MiddleButton { get; } = new ButtonState();
|
||||||
public ButtonState RightButton { get; } = new ButtonState();
|
public ButtonState RightButton { get; } = new ButtonState();
|
||||||
|
|
||||||
public int X { get; private set; }
|
public int X { get; private set; }
|
||||||
public int Y { get; private set; }
|
public int Y { get; private set; }
|
||||||
public int DeltaX { get; private set; }
|
public int DeltaX { get; private set; }
|
||||||
public int DeltaY { get; private set; }
|
public int DeltaY { get; private set; }
|
||||||
|
|
||||||
public int Wheel { get; internal set; }
|
public int Wheel { get; internal set; }
|
||||||
|
|
||||||
private bool relativeMode;
|
private bool relativeMode;
|
||||||
public bool RelativeMode
|
public bool RelativeMode
|
||||||
{
|
{
|
||||||
get => relativeMode;
|
get => relativeMode;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
relativeMode = value;
|
relativeMode = value;
|
||||||
SDL.SDL_SetRelativeMouseMode(
|
SDL.SDL_SetRelativeMouseMode(
|
||||||
relativeMode ?
|
relativeMode ?
|
||||||
SDL.SDL_bool.SDL_TRUE :
|
SDL.SDL_bool.SDL_TRUE :
|
||||||
SDL.SDL_bool.SDL_FALSE
|
SDL.SDL_bool.SDL_FALSE
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Update()
|
internal void Update()
|
||||||
{
|
{
|
||||||
var buttonMask = SDL.SDL_GetMouseState(out var x, out var y);
|
var buttonMask = SDL.SDL_GetMouseState(out var x, out var y);
|
||||||
var _ = SDL.SDL_GetRelativeMouseState(out var deltaX, out var deltaY);
|
var _ = SDL.SDL_GetRelativeMouseState(out var deltaX, out var deltaY);
|
||||||
|
|
||||||
X = x;
|
X = x;
|
||||||
Y = y;
|
Y = y;
|
||||||
DeltaX = deltaX;
|
DeltaX = deltaX;
|
||||||
DeltaY = deltaY;
|
DeltaY = deltaY;
|
||||||
|
|
||||||
LeftButton.Update(IsPressed(buttonMask, SDL.SDL_BUTTON_LMASK));
|
LeftButton.Update(IsPressed(buttonMask, SDL.SDL_BUTTON_LMASK));
|
||||||
MiddleButton.Update(IsPressed(buttonMask, SDL.SDL_BUTTON_MMASK));
|
MiddleButton.Update(IsPressed(buttonMask, SDL.SDL_BUTTON_MMASK));
|
||||||
RightButton.Update(IsPressed(buttonMask, SDL.SDL_BUTTON_RMASK));
|
RightButton.Update(IsPressed(buttonMask, SDL.SDL_BUTTON_RMASK));
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsPressed(uint buttonMask, uint buttonFlag)
|
private bool IsPressed(uint buttonMask, uint buttonFlag)
|
||||||
{
|
{
|
||||||
return (buttonMask & buttonFlag) != 0;
|
return (buttonMask & buttonFlag) != 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
110
src/Logger.cs
110
src/Logger.cs
|
@ -1,69 +1,69 @@
|
||||||
using System;
|
using System;
|
||||||
using RefreshCS;
|
using RefreshCS;
|
||||||
|
|
||||||
namespace MoonWorks
|
namespace MoonWorks
|
||||||
{
|
{
|
||||||
public static class Logger
|
public static class Logger
|
||||||
{
|
{
|
||||||
public static Action<string> LogInfo;
|
public static Action<string> LogInfo;
|
||||||
public static Action<string> LogWarn;
|
public static Action<string> LogWarn;
|
||||||
public static Action<string> LogError;
|
public static Action<string> LogError;
|
||||||
|
|
||||||
private static RefreshCS.Refresh.Refresh_LogFunc LogInfoFunc = RefreshLogInfo;
|
private static RefreshCS.Refresh.Refresh_LogFunc LogInfoFunc = RefreshLogInfo;
|
||||||
private static RefreshCS.Refresh.Refresh_LogFunc LogWarnFunc = RefreshLogWarn;
|
private static RefreshCS.Refresh.Refresh_LogFunc LogWarnFunc = RefreshLogWarn;
|
||||||
private static RefreshCS.Refresh.Refresh_LogFunc LogErrorFunc = RefreshLogError;
|
private static RefreshCS.Refresh.Refresh_LogFunc LogErrorFunc = RefreshLogError;
|
||||||
|
|
||||||
internal static void Initialize()
|
internal static void Initialize()
|
||||||
{
|
{
|
||||||
if (Logger.LogInfo == null)
|
if (Logger.LogInfo == null)
|
||||||
{
|
{
|
||||||
Logger.LogInfo = Console.WriteLine;
|
Logger.LogInfo = Console.WriteLine;
|
||||||
}
|
}
|
||||||
if (Logger.LogWarn == null)
|
if (Logger.LogWarn == null)
|
||||||
{
|
{
|
||||||
Logger.LogWarn = Console.WriteLine;
|
Logger.LogWarn = Console.WriteLine;
|
||||||
}
|
}
|
||||||
if (Logger.LogError == null)
|
if (Logger.LogError == null)
|
||||||
{
|
{
|
||||||
Logger.LogError = Console.WriteLine;
|
Logger.LogError = Console.WriteLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
Refresh.Refresh_HookLogFunctions(
|
Refresh.Refresh_HookLogFunctions(
|
||||||
LogInfoFunc,
|
LogInfoFunc,
|
||||||
LogWarnFunc,
|
LogWarnFunc,
|
||||||
LogErrorFunc
|
LogErrorFunc
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void RefreshLogInfo(IntPtr msg)
|
private static void RefreshLogInfo(IntPtr msg)
|
||||||
{
|
{
|
||||||
LogInfo(UTF8_ToManaged(msg));
|
LogInfo(UTF8_ToManaged(msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void RefreshLogWarn(IntPtr msg)
|
private static void RefreshLogWarn(IntPtr msg)
|
||||||
{
|
{
|
||||||
LogWarn(UTF8_ToManaged(msg));
|
LogWarn(UTF8_ToManaged(msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void RefreshLogError(IntPtr msg)
|
private static void RefreshLogError(IntPtr msg)
|
||||||
{
|
{
|
||||||
LogError(UTF8_ToManaged(msg));
|
LogError(UTF8_ToManaged(msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
private unsafe static string UTF8_ToManaged(IntPtr s)
|
private unsafe static string UTF8_ToManaged(IntPtr s)
|
||||||
{
|
{
|
||||||
byte* ptr = (byte*) s;
|
byte* ptr = (byte*) s;
|
||||||
while (*ptr != 0)
|
while (*ptr != 0)
|
||||||
{
|
{
|
||||||
ptr += 1;
|
ptr += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
string result = System.Text.Encoding.UTF8.GetString(
|
string result = System.Text.Encoding.UTF8.GetString(
|
||||||
(byte*) s,
|
(byte*) s,
|
||||||
(int) (ptr - (byte*) s)
|
(int) (ptr - (byte*) s)
|
||||||
);
|
);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#region License
|
#region License
|
||||||
|
|
||||||
/* MoonWorks - Game Development Framework
|
/* MoonWorks - Game Development Framework
|
||||||
* Copyright 2021 Evan Hemsley
|
* Copyright 2021 Evan Hemsley
|
||||||
|
@ -91,23 +91,23 @@ namespace MoonWorks.Math
|
||||||
public ContainmentType Contains(BoundingBox box)
|
public ContainmentType Contains(BoundingBox box)
|
||||||
{
|
{
|
||||||
// Test if all corner is in the same side of a face by just checking min and max
|
// Test if all corner is in the same side of a face by just checking min and max
|
||||||
if ( box.Max.X < Min.X ||
|
if (box.Max.X < Min.X ||
|
||||||
box.Min.X > Max.X ||
|
box.Min.X > Max.X ||
|
||||||
box.Max.Y < Min.Y ||
|
box.Max.Y < Min.Y ||
|
||||||
box.Min.Y > Max.Y ||
|
box.Min.Y > Max.Y ||
|
||||||
box.Max.Z < Min.Z ||
|
box.Max.Z < Min.Z ||
|
||||||
box.Min.Z > Max.Z )
|
box.Min.Z > Max.Z)
|
||||||
{
|
{
|
||||||
return ContainmentType.Disjoint;
|
return ContainmentType.Disjoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ( box.Min.X >= Min.X &&
|
if (box.Min.X >= Min.X &&
|
||||||
box.Max.X <= Max.X &&
|
box.Max.X <= Max.X &&
|
||||||
box.Min.Y >= Min.Y &&
|
box.Min.Y >= Min.Y &&
|
||||||
box.Max.Y <= Max.Y &&
|
box.Max.Y <= Max.Y &&
|
||||||
box.Min.Z >= Min.Z &&
|
box.Min.Z >= Min.Z &&
|
||||||
box.Max.Z <= Max.Z )
|
box.Max.Z <= Max.Z)
|
||||||
{
|
{
|
||||||
return ContainmentType.Contains;
|
return ContainmentType.Contains;
|
||||||
}
|
}
|
||||||
|
@ -172,12 +172,12 @@ namespace MoonWorks.Math
|
||||||
|
|
||||||
public ContainmentType Contains(BoundingSphere sphere)
|
public ContainmentType Contains(BoundingSphere sphere)
|
||||||
{
|
{
|
||||||
if ( sphere.Center.X - Min.X >= sphere.Radius &&
|
if (sphere.Center.X - Min.X >= sphere.Radius &&
|
||||||
sphere.Center.Y - Min.Y >= sphere.Radius &&
|
sphere.Center.Y - Min.Y >= sphere.Radius &&
|
||||||
sphere.Center.Z - Min.Z >= sphere.Radius &&
|
sphere.Center.Z - Min.Z >= sphere.Radius &&
|
||||||
Max.X - sphere.Center.X >= sphere.Radius &&
|
Max.X - sphere.Center.X >= sphere.Radius &&
|
||||||
Max.Y - sphere.Center.Y >= sphere.Radius &&
|
Max.Y - sphere.Center.Y >= sphere.Radius &&
|
||||||
Max.Z - sphere.Center.Z >= sphere.Radius )
|
Max.Z - sphere.Center.Z >= sphere.Radius)
|
||||||
{
|
{
|
||||||
return ContainmentType.Contains;
|
return ContainmentType.Contains;
|
||||||
}
|
}
|
||||||
|
@ -261,12 +261,12 @@ namespace MoonWorks.Math
|
||||||
public void Contains(ref Vector3 point, out ContainmentType result)
|
public void Contains(ref Vector3 point, out ContainmentType result)
|
||||||
{
|
{
|
||||||
// Determine if point is outside of this box.
|
// Determine if point is outside of this box.
|
||||||
if ( point.X < this.Min.X ||
|
if (point.X < this.Min.X ||
|
||||||
point.X > this.Max.X ||
|
point.X > this.Max.X ||
|
||||||
point.Y < this.Min.Y ||
|
point.Y < this.Min.Y ||
|
||||||
point.Y > this.Max.Y ||
|
point.Y > this.Max.Y ||
|
||||||
point.Z < this.Min.Z ||
|
point.Z < this.Min.Z ||
|
||||||
point.Z > this.Max.Z )
|
point.Z > this.Max.Z)
|
||||||
{
|
{
|
||||||
result = ContainmentType.Disjoint;
|
result = ContainmentType.Disjoint;
|
||||||
}
|
}
|
||||||
|
@ -380,12 +380,12 @@ namespace MoonWorks.Math
|
||||||
|
|
||||||
public bool Intersects(BoundingSphere sphere)
|
public bool Intersects(BoundingSphere sphere)
|
||||||
{
|
{
|
||||||
if ( sphere.Center.X - Min.X > sphere.Radius &&
|
if (sphere.Center.X - Min.X > sphere.Radius &&
|
||||||
sphere.Center.Y - Min.Y > sphere.Radius &&
|
sphere.Center.Y - Min.Y > sphere.Radius &&
|
||||||
sphere.Center.Z - Min.Z > sphere.Radius &&
|
sphere.Center.Z - Min.Z > sphere.Radius &&
|
||||||
Max.X - sphere.Center.X > sphere.Radius &&
|
Max.X - sphere.Center.X > sphere.Radius &&
|
||||||
Max.Y - sphere.Center.Y > sphere.Radius &&
|
Max.Y - sphere.Center.Y > sphere.Radius &&
|
||||||
Max.Z - sphere.Center.Z > sphere.Radius )
|
Max.Z - sphere.Center.Z > sphere.Radius)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#region License
|
#region License
|
||||||
|
|
||||||
/* MoonWorks - Game Development Framework
|
/* MoonWorks - Game Development Framework
|
||||||
* Copyright 2021 Evan Hemsley
|
* Copyright 2021 Evan Hemsley
|
||||||
|
@ -230,12 +230,12 @@ namespace MoonWorks.Math
|
||||||
box.Intersects(ref this.planes[i], out planeIntersectionType);
|
box.Intersects(ref this.planes[i], out planeIntersectionType);
|
||||||
switch (planeIntersectionType)
|
switch (planeIntersectionType)
|
||||||
{
|
{
|
||||||
case PlaneIntersectionType.Front:
|
case PlaneIntersectionType.Front:
|
||||||
result = ContainmentType.Disjoint;
|
result = ContainmentType.Disjoint;
|
||||||
return;
|
return;
|
||||||
case PlaneIntersectionType.Intersecting:
|
case PlaneIntersectionType.Intersecting:
|
||||||
intersects = true;
|
intersects = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result = intersects ? ContainmentType.Intersects : ContainmentType.Contains;
|
result = intersects ? ContainmentType.Intersects : ContainmentType.Contains;
|
||||||
|
@ -269,12 +269,12 @@ namespace MoonWorks.Math
|
||||||
sphere.Intersects(ref this.planes[i], out planeIntersectionType);
|
sphere.Intersects(ref this.planes[i], out planeIntersectionType);
|
||||||
switch (planeIntersectionType)
|
switch (planeIntersectionType)
|
||||||
{
|
{
|
||||||
case PlaneIntersectionType.Front:
|
case PlaneIntersectionType.Front:
|
||||||
result = ContainmentType.Disjoint;
|
result = ContainmentType.Disjoint;
|
||||||
return;
|
return;
|
||||||
case PlaneIntersectionType.Intersecting:
|
case PlaneIntersectionType.Intersecting:
|
||||||
intersects = true;
|
intersects = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result = intersects ? ContainmentType.Intersects : ContainmentType.Contains;
|
result = intersects ? ContainmentType.Intersects : ContainmentType.Contains;
|
||||||
|
@ -597,7 +597,8 @@ namespace MoonWorks.Math
|
||||||
ref Plane b,
|
ref Plane b,
|
||||||
ref Plane c,
|
ref Plane c,
|
||||||
out Vector3 result
|
out Vector3 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
/* Formula used
|
/* Formula used
|
||||||
* d1 ( N2 * N3 ) + d2 ( N3 * N1 ) + d3 ( N1 * N2 )
|
* d1 ( N2 * N3 ) + d2 ( N3 * N1 ) + d3 ( N1 * N2 )
|
||||||
* P = -------------------------------------------------------------------
|
* P = -------------------------------------------------------------------
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#region License
|
#region License
|
||||||
|
|
||||||
/* MoonWorks - Game Development Framework
|
/* MoonWorks - Game Development Framework
|
||||||
* Copyright 2021 Evan Hemsley
|
* Copyright 2021 Evan Hemsley
|
||||||
|
@ -297,8 +297,8 @@ namespace MoonWorks.Math
|
||||||
/// <returns><c>true</c> if the instances are equal; <c>false</c> otherwise.</returns>
|
/// <returns><c>true</c> if the instances are equal; <c>false</c> otherwise.</returns>
|
||||||
public bool Equals(BoundingSphere other)
|
public bool Equals(BoundingSphere other)
|
||||||
{
|
{
|
||||||
return ( Center == other.Center &&
|
return (Center == other.Center &&
|
||||||
Radius == other.Radius );
|
Radius == other.Radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -474,7 +474,8 @@ namespace MoonWorks.Math
|
||||||
ref BoundingSphere original,
|
ref BoundingSphere original,
|
||||||
ref BoundingSphere additional,
|
ref BoundingSphere additional,
|
||||||
out BoundingSphere result
|
out BoundingSphere result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
Vector3 ocenterToaCenter = Vector3.Subtract(additional.Center, original.Center);
|
Vector3 ocenterToaCenter = Vector3.Subtract(additional.Center, original.Center);
|
||||||
float distance = ocenterToaCenter.Length();
|
float distance = ocenterToaCenter.Length();
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#region License
|
#region License
|
||||||
|
|
||||||
/* MoonWorks - Game Development Framework
|
/* MoonWorks - Game Development Framework
|
||||||
* Copyright 2021 Evan Hemsley
|
* Copyright 2021 Evan Hemsley
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#region License
|
#region License
|
||||||
|
|
||||||
/* MoonWorks - Game Development Framework
|
/* MoonWorks - Game Development Framework
|
||||||
* Copyright 2021 Evan Hemsley
|
* Copyright 2021 Evan Hemsley
|
||||||
|
@ -98,7 +98,8 @@ namespace MoonWorks.Math
|
||||||
float value3,
|
float value3,
|
||||||
float amount1,
|
float amount1,
|
||||||
float amount2
|
float amount2
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
return value1 + (value2 - value1) * amount1 + (value3 - value1) * amount2;
|
return value1 + (value2 - value1) * amount1 + (value3 - value1) * amount2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,7 +118,8 @@ namespace MoonWorks.Math
|
||||||
float value3,
|
float value3,
|
||||||
float value4,
|
float value4,
|
||||||
float amount
|
float amount
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
/* Using formula from http://www.mvps.org/directx/articles/catmull/
|
/* Using formula from http://www.mvps.org/directx/articles/catmull/
|
||||||
* Internally using doubles not to lose precision.
|
* Internally using doubles not to lose precision.
|
||||||
*/
|
*/
|
||||||
|
@ -184,7 +186,8 @@ namespace MoonWorks.Math
|
||||||
float value2,
|
float value2,
|
||||||
float tangent2,
|
float tangent2,
|
||||||
float amount
|
float amount
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
/* All transformed to double not to lose precision
|
/* All transformed to double not to lose precision
|
||||||
* Otherwise, for high numbers of param:amount the result is NaN instead
|
* Otherwise, for high numbers of param:amount the result is NaN instead
|
||||||
* of Infinity.
|
* of Infinity.
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,4 @@
|
||||||
#region License
|
#region License
|
||||||
|
|
||||||
/* MoonWorks - Game Development Framework
|
/* MoonWorks - Game Development Framework
|
||||||
* Copyright 2021 Evan Hemsley
|
* Copyright 2021 Evan Hemsley
|
||||||
|
@ -316,7 +316,8 @@ namespace MoonWorks.Math
|
||||||
float m21, float m22, float m23, float m24,
|
float m21, float m22, float m23, float m24,
|
||||||
float m31, float m32, float m33, float m34,
|
float m31, float m32, float m33, float m34,
|
||||||
float m41, float m42, float m43, float m44
|
float m41, float m42, float m43, float m44
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
M11 = m11;
|
M11 = m11;
|
||||||
M12 = m12;
|
M12 = m12;
|
||||||
M13 = m13;
|
M13 = m13;
|
||||||
|
@ -350,7 +351,8 @@ namespace MoonWorks.Math
|
||||||
out Vector3 scale,
|
out Vector3 scale,
|
||||||
out Quaternion rotation,
|
out Quaternion rotation,
|
||||||
out Vector3 translation
|
out Vector3 translation
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
translation.X = M41;
|
translation.X = M41;
|
||||||
translation.Y = M42;
|
translation.Y = M42;
|
||||||
translation.Z = M43;
|
translation.Z = M43;
|
||||||
|
@ -363,9 +365,9 @@ namespace MoonWorks.Math
|
||||||
scale.Y = ys * (float) System.Math.Sqrt(M21 * M21 + M22 * M22 + M23 * M23);
|
scale.Y = ys * (float) System.Math.Sqrt(M21 * M21 + M22 * M22 + M23 * M23);
|
||||||
scale.Z = zs * (float) System.Math.Sqrt(M31 * M31 + M32 * M32 + M33 * M33);
|
scale.Z = zs * (float) System.Math.Sqrt(M31 * M31 + M32 * M32 + M33 * M33);
|
||||||
|
|
||||||
if ( MathHelper.WithinEpsilon(scale.X, 0.0f) ||
|
if (MathHelper.WithinEpsilon(scale.X, 0.0f) ||
|
||||||
MathHelper.WithinEpsilon(scale.Y, 0.0f) ||
|
MathHelper.WithinEpsilon(scale.Y, 0.0f) ||
|
||||||
MathHelper.WithinEpsilon(scale.Z, 0.0f) )
|
MathHelper.WithinEpsilon(scale.Z, 0.0f))
|
||||||
{
|
{
|
||||||
rotation = Quaternion.Identity;
|
rotation = Quaternion.Identity;
|
||||||
return false;
|
return false;
|
||||||
|
@ -413,7 +415,7 @@ namespace MoonWorks.Math
|
||||||
/// <returns><c>true</c> if the instances are equal; <c>false</c> otherwise.</returns>
|
/// <returns><c>true</c> if the instances are equal; <c>false</c> otherwise.</returns>
|
||||||
public bool Equals(Matrix4x4 other)
|
public bool Equals(Matrix4x4 other)
|
||||||
{
|
{
|
||||||
return ( M11 == other.M11 &&
|
return (M11 == other.M11 &&
|
||||||
M12 == other.M12 &&
|
M12 == other.M12 &&
|
||||||
M13 == other.M13 &&
|
M13 == other.M13 &&
|
||||||
M14 == other.M14 &&
|
M14 == other.M14 &&
|
||||||
|
@ -428,7 +430,7 @@ namespace MoonWorks.Math
|
||||||
M41 == other.M41 &&
|
M41 == other.M41 &&
|
||||||
M42 == other.M42 &&
|
M42 == other.M42 &&
|
||||||
M43 == other.M43 &&
|
M43 == other.M43 &&
|
||||||
M44 == other.M44 );
|
M44 == other.M44);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -555,7 +557,8 @@ namespace MoonWorks.Math
|
||||||
Vector3 cameraPosition,
|
Vector3 cameraPosition,
|
||||||
Vector3 cameraUpVector,
|
Vector3 cameraUpVector,
|
||||||
Nullable<Vector3> cameraForwardVector
|
Nullable<Vector3> cameraForwardVector
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
Matrix4x4 result;
|
Matrix4x4 result;
|
||||||
|
|
||||||
// Delegate to the other overload of the function to do the work
|
// Delegate to the other overload of the function to do the work
|
||||||
|
@ -584,7 +587,8 @@ namespace MoonWorks.Math
|
||||||
ref Vector3 cameraUpVector,
|
ref Vector3 cameraUpVector,
|
||||||
Vector3? cameraForwardVector,
|
Vector3? cameraForwardVector,
|
||||||
out Matrix4x4 result
|
out Matrix4x4 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
Vector3 vector;
|
Vector3 vector;
|
||||||
Vector3 vector2;
|
Vector3 vector2;
|
||||||
Vector3 vector3;
|
Vector3 vector3;
|
||||||
|
@ -642,7 +646,8 @@ namespace MoonWorks.Math
|
||||||
Vector3 rotateAxis,
|
Vector3 rotateAxis,
|
||||||
Nullable<Vector3> cameraForwardVector,
|
Nullable<Vector3> cameraForwardVector,
|
||||||
Nullable<Vector3> objectForwardVector
|
Nullable<Vector3> objectForwardVector
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
Matrix4x4 result;
|
Matrix4x4 result;
|
||||||
CreateConstrainedBillboard(
|
CreateConstrainedBillboard(
|
||||||
ref objectPosition,
|
ref objectPosition,
|
||||||
|
@ -671,7 +676,8 @@ namespace MoonWorks.Math
|
||||||
Vector3? cameraForwardVector,
|
Vector3? cameraForwardVector,
|
||||||
Vector3? objectForwardVector,
|
Vector3? objectForwardVector,
|
||||||
out Matrix4x4 result
|
out Matrix4x4 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
float num;
|
float num;
|
||||||
Vector3 vector;
|
Vector3 vector;
|
||||||
Vector3 vector2;
|
Vector3 vector2;
|
||||||
|
@ -777,7 +783,8 @@ namespace MoonWorks.Math
|
||||||
ref Vector3 axis,
|
ref Vector3 axis,
|
||||||
float angle,
|
float angle,
|
||||||
out Matrix4x4 result
|
out Matrix4x4 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
float x = axis.X;
|
float x = axis.X;
|
||||||
float y = axis.Y;
|
float y = axis.Y;
|
||||||
float z = axis.Z;
|
float z = axis.Z;
|
||||||
|
@ -883,7 +890,8 @@ namespace MoonWorks.Math
|
||||||
float pitch,
|
float pitch,
|
||||||
float roll,
|
float roll,
|
||||||
out Matrix4x4 result
|
out Matrix4x4 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
Quaternion quaternion;
|
Quaternion quaternion;
|
||||||
Quaternion.CreateFromYawPitchRoll(yaw, pitch, roll, out quaternion);
|
Quaternion.CreateFromYawPitchRoll(yaw, pitch, roll, out quaternion);
|
||||||
CreateFromQuaternion(ref quaternion, out result);
|
CreateFromQuaternion(ref quaternion, out result);
|
||||||
|
@ -900,7 +908,8 @@ namespace MoonWorks.Math
|
||||||
Vector3 cameraPosition,
|
Vector3 cameraPosition,
|
||||||
Vector3 cameraTarget,
|
Vector3 cameraTarget,
|
||||||
Vector3 cameraUpVector
|
Vector3 cameraUpVector
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
Matrix4x4 matrix;
|
Matrix4x4 matrix;
|
||||||
CreateLookAt(ref cameraPosition, ref cameraTarget, ref cameraUpVector, out matrix);
|
CreateLookAt(ref cameraPosition, ref cameraTarget, ref cameraUpVector, out matrix);
|
||||||
return matrix;
|
return matrix;
|
||||||
|
@ -918,7 +927,8 @@ namespace MoonWorks.Math
|
||||||
ref Vector3 cameraTarget,
|
ref Vector3 cameraTarget,
|
||||||
ref Vector3 cameraUpVector,
|
ref Vector3 cameraUpVector,
|
||||||
out Matrix4x4 result
|
out Matrix4x4 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
Vector3 vectorA = Vector3.Normalize(cameraPosition - cameraTarget);
|
Vector3 vectorA = Vector3.Normalize(cameraPosition - cameraTarget);
|
||||||
Vector3 vectorB = Vector3.Normalize(Vector3.Cross(cameraUpVector, vectorA));
|
Vector3 vectorB = Vector3.Normalize(Vector3.Cross(cameraUpVector, vectorA));
|
||||||
Vector3 vectorC = Vector3.Cross(vectorA, vectorB);
|
Vector3 vectorC = Vector3.Cross(vectorA, vectorB);
|
||||||
|
@ -953,7 +963,8 @@ namespace MoonWorks.Math
|
||||||
float height,
|
float height,
|
||||||
float zNearPlane,
|
float zNearPlane,
|
||||||
float zFarPlane
|
float zFarPlane
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
Matrix4x4 matrix;
|
Matrix4x4 matrix;
|
||||||
CreateOrthographic(width, height, zNearPlane, zFarPlane, out matrix);
|
CreateOrthographic(width, height, zNearPlane, zFarPlane, out matrix);
|
||||||
return matrix;
|
return matrix;
|
||||||
|
@ -973,7 +984,8 @@ namespace MoonWorks.Math
|
||||||
float zNearPlane,
|
float zNearPlane,
|
||||||
float zFarPlane,
|
float zFarPlane,
|
||||||
out Matrix4x4 result
|
out Matrix4x4 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
result.M11 = 2f / width;
|
result.M11 = 2f / width;
|
||||||
result.M12 = result.M13 = result.M14 = 0f;
|
result.M12 = result.M13 = result.M14 = 0f;
|
||||||
result.M22 = 2f / height;
|
result.M22 = 2f / height;
|
||||||
|
@ -1002,7 +1014,8 @@ namespace MoonWorks.Math
|
||||||
float top,
|
float top,
|
||||||
float zNearPlane,
|
float zNearPlane,
|
||||||
float zFarPlane
|
float zFarPlane
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
Matrix4x4 matrix;
|
Matrix4x4 matrix;
|
||||||
CreateOrthographicOffCenter(
|
CreateOrthographicOffCenter(
|
||||||
left,
|
left,
|
||||||
|
@ -1034,7 +1047,8 @@ namespace MoonWorks.Math
|
||||||
float zNearPlane,
|
float zNearPlane,
|
||||||
float zFarPlane,
|
float zFarPlane,
|
||||||
out Matrix4x4 result
|
out Matrix4x4 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
result.M11 = (float) (2.0 / ((double) right - (double) left));
|
result.M11 = (float) (2.0 / ((double) right - (double) left));
|
||||||
result.M12 = 0.0f;
|
result.M12 = 0.0f;
|
||||||
result.M13 = 0.0f;
|
result.M13 = 0.0f;
|
||||||
|
@ -1075,7 +1089,8 @@ namespace MoonWorks.Math
|
||||||
float height,
|
float height,
|
||||||
float nearPlaneDistance,
|
float nearPlaneDistance,
|
||||||
float farPlaneDistance
|
float farPlaneDistance
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
Matrix4x4 matrix;
|
Matrix4x4 matrix;
|
||||||
CreatePerspective(width, height, nearPlaneDistance, farPlaneDistance, out matrix);
|
CreatePerspective(width, height, nearPlaneDistance, farPlaneDistance, out matrix);
|
||||||
return matrix;
|
return matrix;
|
||||||
|
@ -1095,7 +1110,8 @@ namespace MoonWorks.Math
|
||||||
float nearPlaneDistance,
|
float nearPlaneDistance,
|
||||||
float farPlaneDistance,
|
float farPlaneDistance,
|
||||||
out Matrix4x4 result
|
out Matrix4x4 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
if (nearPlaneDistance <= 0f)
|
if (nearPlaneDistance <= 0f)
|
||||||
{
|
{
|
||||||
throw new ArgumentException("nearPlaneDistance <= 0");
|
throw new ArgumentException("nearPlaneDistance <= 0");
|
||||||
|
@ -1135,7 +1151,8 @@ namespace MoonWorks.Math
|
||||||
float aspectRatio,
|
float aspectRatio,
|
||||||
float nearPlaneDistance,
|
float nearPlaneDistance,
|
||||||
float farPlaneDistance
|
float farPlaneDistance
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
Matrix4x4 result;
|
Matrix4x4 result;
|
||||||
CreatePerspectiveFieldOfView(
|
CreatePerspectiveFieldOfView(
|
||||||
fieldOfView,
|
fieldOfView,
|
||||||
|
@ -1161,7 +1178,8 @@ namespace MoonWorks.Math
|
||||||
float nearPlaneDistance,
|
float nearPlaneDistance,
|
||||||
float farPlaneDistance,
|
float farPlaneDistance,
|
||||||
out Matrix4x4 result
|
out Matrix4x4 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
if ((fieldOfView <= 0f) || (fieldOfView >= 3.141593f))
|
if ((fieldOfView <= 0f) || (fieldOfView >= 3.141593f))
|
||||||
{
|
{
|
||||||
throw new ArgumentException("fieldOfView <= 0 or >= PI");
|
throw new ArgumentException("fieldOfView <= 0 or >= PI");
|
||||||
|
@ -1210,7 +1228,8 @@ namespace MoonWorks.Math
|
||||||
float top,
|
float top,
|
||||||
float nearPlaneDistance,
|
float nearPlaneDistance,
|
||||||
float farPlaneDistance
|
float farPlaneDistance
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
Matrix4x4 result;
|
Matrix4x4 result;
|
||||||
CreatePerspectiveOffCenter(
|
CreatePerspectiveOffCenter(
|
||||||
left,
|
left,
|
||||||
|
@ -1242,7 +1261,8 @@ namespace MoonWorks.Math
|
||||||
float nearPlaneDistance,
|
float nearPlaneDistance,
|
||||||
float farPlaneDistance,
|
float farPlaneDistance,
|
||||||
out Matrix4x4 result
|
out Matrix4x4 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
if (nearPlaneDistance <= 0f)
|
if (nearPlaneDistance <= 0f)
|
||||||
{
|
{
|
||||||
throw new ArgumentException("nearPlaneDistance <= 0");
|
throw new ArgumentException("nearPlaneDistance <= 0");
|
||||||
|
@ -1408,7 +1428,8 @@ namespace MoonWorks.Math
|
||||||
float yScale,
|
float yScale,
|
||||||
float zScale,
|
float zScale,
|
||||||
out Matrix4x4 result
|
out Matrix4x4 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
result.M11 = xScale;
|
result.M11 = xScale;
|
||||||
result.M12 = 0;
|
result.M12 = 0;
|
||||||
result.M13 = 0;
|
result.M13 = 0;
|
||||||
|
@ -1527,7 +1548,8 @@ namespace MoonWorks.Math
|
||||||
float xPosition,
|
float xPosition,
|
||||||
float yPosition,
|
float yPosition,
|
||||||
float zPosition
|
float zPosition
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
Matrix4x4 result;
|
Matrix4x4 result;
|
||||||
CreateTranslation(xPosition, yPosition, zPosition, out result);
|
CreateTranslation(xPosition, yPosition, zPosition, out result);
|
||||||
return result;
|
return result;
|
||||||
|
@ -1582,7 +1604,8 @@ namespace MoonWorks.Math
|
||||||
float yPosition,
|
float yPosition,
|
||||||
float zPosition,
|
float zPosition,
|
||||||
out Matrix4x4 result
|
out Matrix4x4 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
result.M11 = 1;
|
result.M11 = 1;
|
||||||
result.M12 = 0;
|
result.M12 = 0;
|
||||||
result.M13 = 0;
|
result.M13 = 0;
|
||||||
|
@ -1672,7 +1695,8 @@ namespace MoonWorks.Math
|
||||||
ref Vector3 forward,
|
ref Vector3 forward,
|
||||||
ref Vector3 up,
|
ref Vector3 up,
|
||||||
out Matrix4x4 result
|
out Matrix4x4 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
Vector3 x, y, z;
|
Vector3 x, y, z;
|
||||||
Vector3.Normalize(ref forward, out z);
|
Vector3.Normalize(ref forward, out z);
|
||||||
Vector3.Cross(ref forward, ref up, out x);
|
Vector3.Cross(ref forward, ref up, out x);
|
||||||
|
@ -2069,7 +2093,8 @@ namespace MoonWorks.Math
|
||||||
ref Matrix4x4 matrix2,
|
ref Matrix4x4 matrix2,
|
||||||
float amount,
|
float amount,
|
||||||
out Matrix4x4 result
|
out Matrix4x4 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
result.M11 = matrix1.M11 + ((matrix2.M11 - matrix1.M11) * amount);
|
result.M11 = matrix1.M11 + ((matrix2.M11 - matrix1.M11) * amount);
|
||||||
result.M12 = matrix1.M12 + ((matrix2.M12 - matrix1.M12) * amount);
|
result.M12 = matrix1.M12 + ((matrix2.M12 - matrix1.M12) * amount);
|
||||||
result.M13 = matrix1.M13 + ((matrix2.M13 - matrix1.M13) * amount);
|
result.M13 = matrix1.M13 + ((matrix2.M13 - matrix1.M13) * amount);
|
||||||
|
@ -2097,7 +2122,8 @@ namespace MoonWorks.Math
|
||||||
public static Matrix4x4 Multiply(
|
public static Matrix4x4 Multiply(
|
||||||
Matrix4x4 matrix1,
|
Matrix4x4 matrix1,
|
||||||
Matrix4x4 matrix2
|
Matrix4x4 matrix2
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
float m11 = (
|
float m11 = (
|
||||||
(matrix1.M11 * matrix2.M11) +
|
(matrix1.M11 * matrix2.M11) +
|
||||||
(matrix1.M12 * matrix2.M21) +
|
(matrix1.M12 * matrix2.M21) +
|
||||||
|
@ -2548,7 +2574,8 @@ namespace MoonWorks.Math
|
||||||
ref Matrix4x4 value,
|
ref Matrix4x4 value,
|
||||||
ref Quaternion rotation,
|
ref Quaternion rotation,
|
||||||
out Matrix4x4 result
|
out Matrix4x4 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
Matrix4x4 rotMatrix = CreateFromQuaternion(rotation);
|
Matrix4x4 rotMatrix = CreateFromQuaternion(rotation);
|
||||||
Multiply(ref value, ref rotMatrix, out result);
|
Multiply(ref value, ref rotMatrix, out result);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#region License
|
#region License
|
||||||
|
|
||||||
/* MoonWorks - Game Development Framework
|
/* MoonWorks - Game Development Framework
|
||||||
* Copyright 2021 Evan Hemsley
|
* Copyright 2021 Evan Hemsley
|
||||||
|
@ -233,7 +233,8 @@ namespace MoonWorks.Math
|
||||||
ref Plane plane,
|
ref Plane plane,
|
||||||
ref Matrix4x4 matrix,
|
ref Matrix4x4 matrix,
|
||||||
out Plane result
|
out Plane result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
/* See "Transforming Normals" in
|
/* See "Transforming Normals" in
|
||||||
* http://www.glprogramming.com/red/appendixf.html
|
* http://www.glprogramming.com/red/appendixf.html
|
||||||
* for an explanation of how this works.
|
* for an explanation of how this works.
|
||||||
|
@ -277,7 +278,8 @@ namespace MoonWorks.Math
|
||||||
ref Plane plane,
|
ref Plane plane,
|
||||||
ref Quaternion rotation,
|
ref Quaternion rotation,
|
||||||
out Plane result
|
out Plane result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
Vector3.Transform(
|
Vector3.Transform(
|
||||||
ref plane.Normal,
|
ref plane.Normal,
|
||||||
ref rotation,
|
ref rotation,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#region License
|
#region License
|
||||||
|
|
||||||
/* MoonWorks - Game Development Framework
|
/* MoonWorks - Game Development Framework
|
||||||
* Copyright 2021 Evan Hemsley
|
* Copyright 2021 Evan Hemsley
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#region License
|
#region License
|
||||||
|
|
||||||
/* MoonWorks - Game Development Framework
|
/* MoonWorks - Game Development Framework
|
||||||
* Copyright 2021 Evan Hemsley
|
* Copyright 2021 Evan Hemsley
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#region License
|
#region License
|
||||||
|
|
||||||
/* MoonWorks - Game Development Framework
|
/* MoonWorks - Game Development Framework
|
||||||
* Copyright 2021 Evan Hemsley
|
* Copyright 2021 Evan Hemsley
|
||||||
|
@ -157,10 +157,10 @@ namespace MoonWorks.Math
|
||||||
/// <returns><c>true</c> if the instances are equal; <c>false</c> otherwise.</returns>
|
/// <returns><c>true</c> if the instances are equal; <c>false</c> otherwise.</returns>
|
||||||
public bool Equals(Quaternion other)
|
public bool Equals(Quaternion other)
|
||||||
{
|
{
|
||||||
return ( X == other.X &&
|
return (X == other.X &&
|
||||||
Y == other.Y &&
|
Y == other.Y &&
|
||||||
Z == other.Z &&
|
Z == other.Z &&
|
||||||
W == other.W );
|
W == other.W);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -266,7 +266,8 @@ namespace MoonWorks.Math
|
||||||
ref Quaternion quaternion1,
|
ref Quaternion quaternion1,
|
||||||
ref Quaternion quaternion2,
|
ref Quaternion quaternion2,
|
||||||
out Quaternion result
|
out Quaternion result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
result.X = quaternion1.X + quaternion2.X;
|
result.X = quaternion1.X + quaternion2.X;
|
||||||
result.Y = quaternion1.Y + quaternion2.Y;
|
result.Y = quaternion1.Y + quaternion2.Y;
|
||||||
result.Z = quaternion1.Z + quaternion2.Z;
|
result.Z = quaternion1.Z + quaternion2.Z;
|
||||||
|
@ -296,7 +297,8 @@ namespace MoonWorks.Math
|
||||||
ref Quaternion value1,
|
ref Quaternion value1,
|
||||||
ref Quaternion value2,
|
ref Quaternion value2,
|
||||||
out Quaternion result
|
out Quaternion result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
float x1 = value1.X;
|
float x1 = value1.X;
|
||||||
float y1 = value1.Y;
|
float y1 = value1.Y;
|
||||||
float z1 = value1.Z;
|
float z1 = value1.Z;
|
||||||
|
@ -359,7 +361,8 @@ namespace MoonWorks.Math
|
||||||
ref Vector3 axis,
|
ref Vector3 axis,
|
||||||
float angle,
|
float angle,
|
||||||
out Quaternion result
|
out Quaternion result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
float half = angle * 0.5f;
|
float half = angle * 0.5f;
|
||||||
float sin = (float) System.Math.Sin((double) half);
|
float sin = (float) System.Math.Sin((double) half);
|
||||||
float cos = (float) System.Math.Cos((double) half);
|
float cos = (float) System.Math.Cos((double) half);
|
||||||
|
@ -415,12 +418,12 @@ namespace MoonWorks.Math
|
||||||
else if (matrix.M22 > matrix.M33)
|
else if (matrix.M22 > matrix.M33)
|
||||||
{
|
{
|
||||||
sqrt = (float) System.Math.Sqrt(1.0f + matrix.M22 - matrix.M11 - matrix.M33);
|
sqrt = (float) System.Math.Sqrt(1.0f + matrix.M22 - matrix.M11 - matrix.M33);
|
||||||
half = 0.5f/sqrt;
|
half = 0.5f / sqrt;
|
||||||
|
|
||||||
result.X = (matrix.M21 + matrix.M12)*half;
|
result.X = (matrix.M21 + matrix.M12) * half;
|
||||||
result.Y = 0.5f*sqrt;
|
result.Y = 0.5f * sqrt;
|
||||||
result.Z = (matrix.M32 + matrix.M23)*half;
|
result.Z = (matrix.M32 + matrix.M23) * half;
|
||||||
result.W = (matrix.M31 - matrix.M13)*half;
|
result.W = (matrix.M31 - matrix.M13) * half;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -499,7 +502,8 @@ namespace MoonWorks.Math
|
||||||
ref Quaternion quaternion1,
|
ref Quaternion quaternion1,
|
||||||
ref Quaternion quaternion2,
|
ref Quaternion quaternion2,
|
||||||
out Quaternion result
|
out Quaternion result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
float x = quaternion1.X;
|
float x = quaternion1.X;
|
||||||
float y = quaternion1.Y;
|
float y = quaternion1.Y;
|
||||||
float z = quaternion1.Z;
|
float z = quaternion1.Z;
|
||||||
|
@ -551,7 +555,8 @@ namespace MoonWorks.Math
|
||||||
ref Quaternion quaternion1,
|
ref Quaternion quaternion1,
|
||||||
ref Quaternion quaternion2,
|
ref Quaternion quaternion2,
|
||||||
out float result
|
out float result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
result = (
|
result = (
|
||||||
(quaternion1.X * quaternion2.X) +
|
(quaternion1.X * quaternion2.X) +
|
||||||
(quaternion1.Y * quaternion2.Y) +
|
(quaternion1.Y * quaternion2.Y) +
|
||||||
|
@ -603,7 +608,8 @@ namespace MoonWorks.Math
|
||||||
Quaternion quaternion1,
|
Quaternion quaternion1,
|
||||||
Quaternion quaternion2,
|
Quaternion quaternion2,
|
||||||
float amount
|
float amount
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
Quaternion quaternion;
|
Quaternion quaternion;
|
||||||
Lerp(ref quaternion1, ref quaternion2, amount, out quaternion);
|
Lerp(ref quaternion1, ref quaternion2, amount, out quaternion);
|
||||||
return quaternion;
|
return quaternion;
|
||||||
|
@ -621,7 +627,8 @@ namespace MoonWorks.Math
|
||||||
ref Quaternion quaternion2,
|
ref Quaternion quaternion2,
|
||||||
float amount,
|
float amount,
|
||||||
out Quaternion result
|
out Quaternion result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
float num = amount;
|
float num = amount;
|
||||||
float num2 = 1f - num;
|
float num2 = 1f - num;
|
||||||
float num5 = (
|
float num5 = (
|
||||||
|
@ -668,7 +675,8 @@ namespace MoonWorks.Math
|
||||||
Quaternion quaternion1,
|
Quaternion quaternion1,
|
||||||
Quaternion quaternion2,
|
Quaternion quaternion2,
|
||||||
float amount
|
float amount
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
Quaternion quaternion;
|
Quaternion quaternion;
|
||||||
Slerp(ref quaternion1, ref quaternion2, amount, out quaternion);
|
Slerp(ref quaternion1, ref quaternion2, amount, out quaternion);
|
||||||
return quaternion;
|
return quaternion;
|
||||||
|
@ -686,7 +694,8 @@ namespace MoonWorks.Math
|
||||||
ref Quaternion quaternion2,
|
ref Quaternion quaternion2,
|
||||||
float amount,
|
float amount,
|
||||||
out Quaternion result
|
out Quaternion result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
float num2;
|
float num2;
|
||||||
float num3;
|
float num3;
|
||||||
float num = amount;
|
float num = amount;
|
||||||
|
@ -743,7 +752,8 @@ namespace MoonWorks.Math
|
||||||
ref Quaternion quaternion1,
|
ref Quaternion quaternion1,
|
||||||
ref Quaternion quaternion2,
|
ref Quaternion quaternion2,
|
||||||
out Quaternion result
|
out Quaternion result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
result.X = quaternion1.X - quaternion2.X;
|
result.X = quaternion1.X - quaternion2.X;
|
||||||
result.Y = quaternion1.Y - quaternion2.Y;
|
result.Y = quaternion1.Y - quaternion2.Y;
|
||||||
result.Z = quaternion1.Z - quaternion2.Z;
|
result.Z = quaternion1.Z - quaternion2.Z;
|
||||||
|
@ -786,7 +796,8 @@ namespace MoonWorks.Math
|
||||||
ref Quaternion quaternion1,
|
ref Quaternion quaternion1,
|
||||||
ref Quaternion quaternion2,
|
ref Quaternion quaternion2,
|
||||||
out Quaternion result
|
out Quaternion result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
float x = quaternion1.X;
|
float x = quaternion1.X;
|
||||||
float y = quaternion1.Y;
|
float y = quaternion1.Y;
|
||||||
float z = quaternion1.Z;
|
float z = quaternion1.Z;
|
||||||
|
@ -815,7 +826,8 @@ namespace MoonWorks.Math
|
||||||
ref Quaternion quaternion1,
|
ref Quaternion quaternion1,
|
||||||
float scaleFactor,
|
float scaleFactor,
|
||||||
out Quaternion result
|
out Quaternion result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
result.X = quaternion1.X * scaleFactor;
|
result.X = quaternion1.X * scaleFactor;
|
||||||
result.Y = quaternion1.Y * scaleFactor;
|
result.Y = quaternion1.Y * scaleFactor;
|
||||||
result.Z = quaternion1.Z * scaleFactor;
|
result.Z = quaternion1.Z * scaleFactor;
|
||||||
|
@ -881,15 +893,15 @@ namespace MoonWorks.Math
|
||||||
result.W = quaternion.W * num;
|
result.W = quaternion.W * num;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Quaternion LookAt(in Vector3 forward, in Vector3 up)
|
public static Quaternion LookAt(in Vector3 forward, in Vector3 up)
|
||||||
{
|
{
|
||||||
Matrix4x4 orientation = Matrix4x4.Identity;
|
Matrix4x4 orientation = Matrix4x4.Identity;
|
||||||
orientation.Forward = forward;
|
orientation.Forward = forward;
|
||||||
orientation.Right = Vector3.Normalize(Vector3.Cross(forward, up));
|
orientation.Right = Vector3.Normalize(Vector3.Cross(forward, up));
|
||||||
orientation.Up = Vector3.Cross(orientation.Right, forward);
|
orientation.Up = Vector3.Cross(orientation.Right, forward);
|
||||||
|
|
||||||
return Quaternion.CreateFromRotationMatrix(orientation);
|
return Quaternion.CreateFromRotationMatrix(orientation);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#region License
|
#region License
|
||||||
|
|
||||||
/* MoonWorks - Game Development Framework
|
/* MoonWorks - Game Development Framework
|
||||||
* Copyright 2021 Evan Hemsley
|
* Copyright 2021 Evan Hemsley
|
||||||
|
@ -70,8 +70,8 @@ namespace MoonWorks.Math
|
||||||
|
|
||||||
public bool Equals(Ray other)
|
public bool Equals(Ray other)
|
||||||
{
|
{
|
||||||
return ( this.Position.Equals(other.Position) &&
|
return (this.Position.Equals(other.Position) &&
|
||||||
this.Direction.Equals(other.Direction) );
|
this.Direction.Equals(other.Direction));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -124,8 +124,8 @@ namespace MoonWorks.Math
|
||||||
tMaxY = temp;
|
tMaxY = temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (tMin.HasValue && tMin > tMaxY) ||
|
if ((tMin.HasValue && tMin > tMaxY) ||
|
||||||
(tMax.HasValue && tMinY > tMax) )
|
(tMax.HasValue && tMinY > tMax))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -153,8 +153,8 @@ namespace MoonWorks.Math
|
||||||
tMaxZ = temp;
|
tMaxZ = temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (tMin.HasValue && tMin > tMaxZ) ||
|
if ((tMin.HasValue && tMin > tMaxZ) ||
|
||||||
(tMax.HasValue && tMinZ > tMax) )
|
(tMax.HasValue && tMinZ > tMax))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#region License
|
#region License
|
||||||
|
|
||||||
/* MoonWorks - Game Development Framework
|
/* MoonWorks - Game Development Framework
|
||||||
* Copyright 2021 Evan Hemsley
|
* Copyright 2021 Evan Hemsley
|
||||||
|
@ -117,10 +117,10 @@ namespace MoonWorks.Math
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return ( (Width == 0) &&
|
return ((Width == 0) &&
|
||||||
(Height == 0) &&
|
(Height == 0) &&
|
||||||
(X == 0) &&
|
(X == 0) &&
|
||||||
(Y == 0) );
|
(Y == 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,10 +218,10 @@ namespace MoonWorks.Math
|
||||||
/// <returns><c>true</c> if the provided coordinates lie inside this <see cref="Rectangle"/>. <c>false</c> otherwise.</returns>
|
/// <returns><c>true</c> if the provided coordinates lie inside this <see cref="Rectangle"/>. <c>false</c> otherwise.</returns>
|
||||||
public bool Contains(int x, int y)
|
public bool Contains(int x, int y)
|
||||||
{
|
{
|
||||||
return ( (this.X <= x) &&
|
return ((this.X <= x) &&
|
||||||
(x < (this.X + this.Width)) &&
|
(x < (this.X + this.Width)) &&
|
||||||
(this.Y <= y) &&
|
(this.Y <= y) &&
|
||||||
(y < (this.Y + this.Height)) );
|
(y < (this.Y + this.Height)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -231,10 +231,10 @@ namespace MoonWorks.Math
|
||||||
/// <returns><c>true</c> if the provided <see cref="Point"/> lies inside this <see cref="Rectangle"/>. <c>false</c> otherwise.</returns>
|
/// <returns><c>true</c> if the provided <see cref="Point"/> lies inside this <see cref="Rectangle"/>. <c>false</c> otherwise.</returns>
|
||||||
public bool Contains(Point value)
|
public bool Contains(Point value)
|
||||||
{
|
{
|
||||||
return ( (this.X <= value.X) &&
|
return ((this.X <= value.X) &&
|
||||||
(value.X < (this.X + this.Width)) &&
|
(value.X < (this.X + this.Width)) &&
|
||||||
(this.Y <= value.Y) &&
|
(this.Y <= value.Y) &&
|
||||||
(value.Y < (this.Y + this.Height)) );
|
(value.Y < (this.Y + this.Height)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -244,26 +244,26 @@ namespace MoonWorks.Math
|
||||||
/// <returns><c>true</c> if the provided <see cref="Rectangle"/>'s bounds lie entirely inside this <see cref="Rectangle"/>. <c>false</c> otherwise.</returns>
|
/// <returns><c>true</c> if the provided <see cref="Rectangle"/>'s bounds lie entirely inside this <see cref="Rectangle"/>. <c>false</c> otherwise.</returns>
|
||||||
public bool Contains(Rectangle value)
|
public bool Contains(Rectangle value)
|
||||||
{
|
{
|
||||||
return ( (this.X <= value.X) &&
|
return ((this.X <= value.X) &&
|
||||||
((value.X + value.Width) <= (this.X + this.Width)) &&
|
((value.X + value.Width) <= (this.X + this.Width)) &&
|
||||||
(this.Y <= value.Y) &&
|
(this.Y <= value.Y) &&
|
||||||
((value.Y + value.Height) <= (this.Y + this.Height)) );
|
((value.Y + value.Height) <= (this.Y + this.Height)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Contains(ref Point value, out bool result)
|
public void Contains(ref Point value, out bool result)
|
||||||
{
|
{
|
||||||
result = ( (this.X <= value.X) &&
|
result = ((this.X <= value.X) &&
|
||||||
(value.X < (this.X + this.Width)) &&
|
(value.X < (this.X + this.Width)) &&
|
||||||
(this.Y <= value.Y) &&
|
(this.Y <= value.Y) &&
|
||||||
(value.Y < (this.Y + this.Height)) );
|
(value.Y < (this.Y + this.Height)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Contains(ref Rectangle value, out bool result)
|
public void Contains(ref Rectangle value, out bool result)
|
||||||
{
|
{
|
||||||
result = ( (this.X <= value.X) &&
|
result = ((this.X <= value.X) &&
|
||||||
((value.X + value.Width) <= (this.X + this.Width)) &&
|
((value.X + value.Width) <= (this.X + this.Width)) &&
|
||||||
(this.Y <= value.Y) &&
|
(this.Y <= value.Y) &&
|
||||||
((value.Y + value.Height) <= (this.Y + this.Height)) );
|
((value.Y + value.Height) <= (this.Y + this.Height)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -349,10 +349,10 @@ namespace MoonWorks.Math
|
||||||
/// <returns><c>true</c> if other <see cref="Rectangle"/> intersects with this rectangle; <c>false</c> otherwise.</returns>
|
/// <returns><c>true</c> if other <see cref="Rectangle"/> intersects with this rectangle; <c>false</c> otherwise.</returns>
|
||||||
public bool Intersects(Rectangle value)
|
public bool Intersects(Rectangle value)
|
||||||
{
|
{
|
||||||
return ( value.Left < Right &&
|
return (value.Left < Right &&
|
||||||
Left < value.Right &&
|
Left < value.Right &&
|
||||||
value.Top < Bottom &&
|
value.Top < Bottom &&
|
||||||
Top < value.Bottom );
|
Top < value.Bottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -362,10 +362,10 @@ namespace MoonWorks.Math
|
||||||
/// <param name="result"><c>true</c> if other <see cref="Rectangle"/> intersects with this rectangle; <c>false</c> otherwise. As an output parameter.</param>
|
/// <param name="result"><c>true</c> if other <see cref="Rectangle"/> intersects with this rectangle; <c>false</c> otherwise. As an output parameter.</param>
|
||||||
public void Intersects(ref Rectangle value, out bool result)
|
public void Intersects(ref Rectangle value, out bool result)
|
||||||
{
|
{
|
||||||
result = ( value.Left < Right &&
|
result = (value.Left < Right &&
|
||||||
Left < value.Right &&
|
Left < value.Right &&
|
||||||
value.Top < Bottom &&
|
value.Top < Bottom &&
|
||||||
Top < value.Bottom );
|
Top < value.Bottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -374,10 +374,10 @@ namespace MoonWorks.Math
|
||||||
|
|
||||||
public static bool operator ==(Rectangle a, Rectangle b)
|
public static bool operator ==(Rectangle a, Rectangle b)
|
||||||
{
|
{
|
||||||
return ( (a.X == b.X) &&
|
return ((a.X == b.X) &&
|
||||||
(a.Y == b.Y) &&
|
(a.Y == b.Y) &&
|
||||||
(a.Width == b.Width) &&
|
(a.Width == b.Width) &&
|
||||||
(a.Height == b.Height) );
|
(a.Height == b.Height));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool operator !=(Rectangle a, Rectangle b)
|
public static bool operator !=(Rectangle a, Rectangle b)
|
||||||
|
@ -396,7 +396,8 @@ namespace MoonWorks.Math
|
||||||
ref Rectangle value1,
|
ref Rectangle value1,
|
||||||
ref Rectangle value2,
|
ref Rectangle value2,
|
||||||
out Rectangle result
|
out Rectangle result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
if (value1.Intersects(value2))
|
if (value1.Intersects(value2))
|
||||||
{
|
{
|
||||||
int right_side = System.Math.Min(
|
int right_side = System.Math.Min(
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#region License
|
#region License
|
||||||
|
|
||||||
/* MoonWorks - Game Development Framework
|
/* MoonWorks - Game Development Framework
|
||||||
* Copyright 2021 Evan Hemsley
|
* Copyright 2021 Evan Hemsley
|
||||||
|
@ -163,8 +163,8 @@ namespace MoonWorks.Math
|
||||||
/// <returns><c>true</c> if the instances are equal; <c>false</c> otherwise.</returns>
|
/// <returns><c>true</c> if the instances are equal; <c>false</c> otherwise.</returns>
|
||||||
public bool Equals(Vector2 other)
|
public bool Equals(Vector2 other)
|
||||||
{
|
{
|
||||||
return ( X == other.X &&
|
return (X == other.X &&
|
||||||
Y == other.Y );
|
Y == other.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -264,7 +264,8 @@ namespace MoonWorks.Math
|
||||||
Vector2 value3,
|
Vector2 value3,
|
||||||
float amount1,
|
float amount1,
|
||||||
float amount2
|
float amount2
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
return new Vector2(
|
return new Vector2(
|
||||||
MathHelper.Barycentric(value1.X, value2.X, value3.X, amount1, amount2),
|
MathHelper.Barycentric(value1.X, value2.X, value3.X, amount1, amount2),
|
||||||
MathHelper.Barycentric(value1.Y, value2.Y, value3.Y, amount1, amount2)
|
MathHelper.Barycentric(value1.Y, value2.Y, value3.Y, amount1, amount2)
|
||||||
|
@ -287,7 +288,8 @@ namespace MoonWorks.Math
|
||||||
float amount1,
|
float amount1,
|
||||||
float amount2,
|
float amount2,
|
||||||
out Vector2 result
|
out Vector2 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
result.X = MathHelper.Barycentric(value1.X, value2.X, value3.X, amount1, amount2);
|
result.X = MathHelper.Barycentric(value1.X, value2.X, value3.X, amount1, amount2);
|
||||||
result.Y = MathHelper.Barycentric(value1.Y, value2.Y, value3.Y, amount1, amount2);
|
result.Y = MathHelper.Barycentric(value1.Y, value2.Y, value3.Y, amount1, amount2);
|
||||||
}
|
}
|
||||||
|
@ -307,7 +309,8 @@ namespace MoonWorks.Math
|
||||||
Vector2 value3,
|
Vector2 value3,
|
||||||
Vector2 value4,
|
Vector2 value4,
|
||||||
float amount
|
float amount
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
return new Vector2(
|
return new Vector2(
|
||||||
MathHelper.CatmullRom(value1.X, value2.X, value3.X, value4.X, amount),
|
MathHelper.CatmullRom(value1.X, value2.X, value3.X, value4.X, amount),
|
||||||
MathHelper.CatmullRom(value1.Y, value2.Y, value3.Y, value4.Y, amount)
|
MathHelper.CatmullRom(value1.Y, value2.Y, value3.Y, value4.Y, amount)
|
||||||
|
@ -330,7 +333,8 @@ namespace MoonWorks.Math
|
||||||
ref Vector2 value4,
|
ref Vector2 value4,
|
||||||
float amount,
|
float amount,
|
||||||
out Vector2 result
|
out Vector2 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
result.X = MathHelper.CatmullRom(value1.X, value2.X, value3.X, value4.X, amount);
|
result.X = MathHelper.CatmullRom(value1.X, value2.X, value3.X, value4.X, amount);
|
||||||
result.Y = MathHelper.CatmullRom(value1.Y, value2.Y, value3.Y, value4.Y, amount);
|
result.Y = MathHelper.CatmullRom(value1.Y, value2.Y, value3.Y, value4.Y, amount);
|
||||||
}
|
}
|
||||||
|
@ -362,7 +366,8 @@ namespace MoonWorks.Math
|
||||||
ref Vector2 min,
|
ref Vector2 min,
|
||||||
ref Vector2 max,
|
ref Vector2 max,
|
||||||
out Vector2 result
|
out Vector2 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
result.X = MathHelper.Clamp(value1.X, min.X, max.X);
|
result.X = MathHelper.Clamp(value1.X, min.X, max.X);
|
||||||
result.Y = MathHelper.Clamp(value1.Y, min.Y, max.Y);
|
result.Y = MathHelper.Clamp(value1.Y, min.Y, max.Y);
|
||||||
}
|
}
|
||||||
|
@ -413,7 +418,8 @@ namespace MoonWorks.Math
|
||||||
ref Vector2 value1,
|
ref Vector2 value1,
|
||||||
ref Vector2 value2,
|
ref Vector2 value2,
|
||||||
out float result
|
out float result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
float v1 = value1.X - value2.X, v2 = value1.Y - value2.Y;
|
float v1 = value1.X - value2.X, v2 = value1.Y - value2.Y;
|
||||||
result = (v1 * v1) + (v2 * v2);
|
result = (v1 * v1) + (v2 * v2);
|
||||||
}
|
}
|
||||||
|
@ -507,7 +513,8 @@ namespace MoonWorks.Math
|
||||||
Vector2 value2,
|
Vector2 value2,
|
||||||
Vector2 tangent2,
|
Vector2 tangent2,
|
||||||
float amount
|
float amount
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
Vector2 result = new Vector2();
|
Vector2 result = new Vector2();
|
||||||
Hermite(ref value1, ref tangent1, ref value2, ref tangent2, amount, out result);
|
Hermite(ref value1, ref tangent1, ref value2, ref tangent2, amount, out result);
|
||||||
return result;
|
return result;
|
||||||
|
@ -529,7 +536,8 @@ namespace MoonWorks.Math
|
||||||
ref Vector2 tangent2,
|
ref Vector2 tangent2,
|
||||||
float amount,
|
float amount,
|
||||||
out Vector2 result
|
out Vector2 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
result.X = MathHelper.Hermite(value1.X, tangent1.X, value2.X, tangent2.X, amount);
|
result.X = MathHelper.Hermite(value1.X, tangent1.X, value2.X, tangent2.X, amount);
|
||||||
result.Y = MathHelper.Hermite(value1.Y, tangent1.Y, value2.Y, tangent2.Y, amount);
|
result.Y = MathHelper.Hermite(value1.Y, tangent1.Y, value2.Y, tangent2.Y, amount);
|
||||||
}
|
}
|
||||||
|
@ -561,7 +569,8 @@ namespace MoonWorks.Math
|
||||||
ref Vector2 value2,
|
ref Vector2 value2,
|
||||||
float amount,
|
float amount,
|
||||||
out Vector2 result
|
out Vector2 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
result.X = MathHelper.Lerp(value1.X, value2.X, amount);
|
result.X = MathHelper.Lerp(value1.X, value2.X, amount);
|
||||||
result.Y = MathHelper.Lerp(value1.Y, value2.Y, amount);
|
result.Y = MathHelper.Lerp(value1.Y, value2.Y, amount);
|
||||||
}
|
}
|
||||||
|
@ -773,7 +782,8 @@ namespace MoonWorks.Math
|
||||||
ref Vector2 value2,
|
ref Vector2 value2,
|
||||||
float amount,
|
float amount,
|
||||||
out Vector2 result
|
out Vector2 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
result.X = MathHelper.SmoothStep(value1.X, value2.X, amount);
|
result.X = MathHelper.SmoothStep(value1.X, value2.X, amount);
|
||||||
result.Y = MathHelper.SmoothStep(value1.Y, value2.Y, amount);
|
result.Y = MathHelper.SmoothStep(value1.Y, value2.Y, amount);
|
||||||
}
|
}
|
||||||
|
@ -827,7 +837,8 @@ namespace MoonWorks.Math
|
||||||
ref Vector2 position,
|
ref Vector2 position,
|
||||||
ref Matrix4x4 matrix,
|
ref Matrix4x4 matrix,
|
||||||
out Vector2 result
|
out Vector2 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
float x = (position.X * matrix.M11) + (position.Y * matrix.M21) + matrix.M41;
|
float x = (position.X * matrix.M11) + (position.Y * matrix.M21) + matrix.M41;
|
||||||
float y = (position.X * matrix.M12) + (position.Y * matrix.M22) + matrix.M42;
|
float y = (position.X * matrix.M12) + (position.Y * matrix.M22) + matrix.M42;
|
||||||
result.X = x;
|
result.X = x;
|
||||||
|
@ -856,7 +867,8 @@ namespace MoonWorks.Math
|
||||||
ref Vector2 value,
|
ref Vector2 value,
|
||||||
ref Quaternion rotation,
|
ref Quaternion rotation,
|
||||||
out Vector2 result
|
out Vector2 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
float x = 2 * -(rotation.Z * value.Y);
|
float x = 2 * -(rotation.Z * value.Y);
|
||||||
float y = 2 * (rotation.Z * value.X);
|
float y = 2 * (rotation.Z * value.X);
|
||||||
float z = 2 * (rotation.X * value.Y - rotation.Y * value.X);
|
float z = 2 * (rotation.X * value.Y - rotation.Y * value.X);
|
||||||
|
@ -875,7 +887,8 @@ namespace MoonWorks.Math
|
||||||
Vector2[] sourceArray,
|
Vector2[] sourceArray,
|
||||||
ref Matrix4x4 matrix,
|
ref Matrix4x4 matrix,
|
||||||
Vector2[] destinationArray
|
Vector2[] destinationArray
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
Transform(sourceArray, 0, ref matrix, destinationArray, 0, sourceArray.Length);
|
Transform(sourceArray, 0, ref matrix, destinationArray, 0, sourceArray.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -895,7 +908,8 @@ namespace MoonWorks.Math
|
||||||
Vector2[] destinationArray,
|
Vector2[] destinationArray,
|
||||||
int destinationIndex,
|
int destinationIndex,
|
||||||
int length
|
int length
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
for (int x = 0; x < length; x += 1)
|
for (int x = 0; x < length; x += 1)
|
||||||
{
|
{
|
||||||
Vector2 position = sourceArray[sourceIndex + x];
|
Vector2 position = sourceArray[sourceIndex + x];
|
||||||
|
@ -918,7 +932,8 @@ namespace MoonWorks.Math
|
||||||
Vector2[] sourceArray,
|
Vector2[] sourceArray,
|
||||||
ref Quaternion rotation,
|
ref Quaternion rotation,
|
||||||
Vector2[] destinationArray
|
Vector2[] destinationArray
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
Transform(
|
Transform(
|
||||||
sourceArray,
|
sourceArray,
|
||||||
0,
|
0,
|
||||||
|
@ -945,7 +960,8 @@ namespace MoonWorks.Math
|
||||||
Vector2[] destinationArray,
|
Vector2[] destinationArray,
|
||||||
int destinationIndex,
|
int destinationIndex,
|
||||||
int length
|
int length
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
for (int i = 0; i < length; i += 1)
|
for (int i = 0; i < length; i += 1)
|
||||||
{
|
{
|
||||||
Vector2 position = sourceArray[sourceIndex + i];
|
Vector2 position = sourceArray[sourceIndex + i];
|
||||||
|
@ -979,7 +995,8 @@ namespace MoonWorks.Math
|
||||||
ref Vector2 normal,
|
ref Vector2 normal,
|
||||||
ref Matrix4x4 matrix,
|
ref Matrix4x4 matrix,
|
||||||
out Vector2 result
|
out Vector2 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
float x = (normal.X * matrix.M11) + (normal.Y * matrix.M21);
|
float x = (normal.X * matrix.M11) + (normal.Y * matrix.M21);
|
||||||
float y = (normal.X * matrix.M12) + (normal.Y * matrix.M22);
|
float y = (normal.X * matrix.M12) + (normal.Y * matrix.M22);
|
||||||
result.X = x;
|
result.X = x;
|
||||||
|
@ -996,7 +1013,8 @@ namespace MoonWorks.Math
|
||||||
Vector2[] sourceArray,
|
Vector2[] sourceArray,
|
||||||
ref Matrix4x4 matrix,
|
ref Matrix4x4 matrix,
|
||||||
Vector2[] destinationArray
|
Vector2[] destinationArray
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
TransformNormal(
|
TransformNormal(
|
||||||
sourceArray,
|
sourceArray,
|
||||||
0,
|
0,
|
||||||
|
@ -1023,7 +1041,8 @@ namespace MoonWorks.Math
|
||||||
Vector2[] destinationArray,
|
Vector2[] destinationArray,
|
||||||
int destinationIndex,
|
int destinationIndex,
|
||||||
int length
|
int length
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
for (int i = 0; i < length; i += 1)
|
for (int i = 0; i < length; i += 1)
|
||||||
{
|
{
|
||||||
Vector2 position = sourceArray[sourceIndex + i];
|
Vector2 position = sourceArray[sourceIndex + i];
|
||||||
|
@ -1058,8 +1077,8 @@ namespace MoonWorks.Math
|
||||||
/// <returns><c>true</c> if the instances are equal; <c>false</c> otherwise.</returns>
|
/// <returns><c>true</c> if the instances are equal; <c>false</c> otherwise.</returns>
|
||||||
public static bool operator ==(Vector2 value1, Vector2 value2)
|
public static bool operator ==(Vector2 value1, Vector2 value2)
|
||||||
{
|
{
|
||||||
return ( value1.X == value2.X &&
|
return (value1.X == value2.X &&
|
||||||
value1.Y == value2.Y );
|
value1.Y == value2.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#region License
|
#region License
|
||||||
|
|
||||||
/* MoonWorks - Game Development Framework
|
/* MoonWorks - Game Development Framework
|
||||||
* Copyright 2021 Evan Hemsley
|
* Copyright 2021 Evan Hemsley
|
||||||
|
@ -270,9 +270,9 @@ namespace MoonWorks.Math
|
||||||
/// <returns><c>true</c> if the instances are equal; <c>false</c> otherwise.</returns>
|
/// <returns><c>true</c> if the instances are equal; <c>false</c> otherwise.</returns>
|
||||||
public bool Equals(Vector3 other)
|
public bool Equals(Vector3 other)
|
||||||
{
|
{
|
||||||
return ( X == other.X &&
|
return (X == other.X &&
|
||||||
Y == other.Y &&
|
Y == other.Y &&
|
||||||
Z == other.Z );
|
Z == other.Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -383,7 +383,8 @@ namespace MoonWorks.Math
|
||||||
Vector3 value3,
|
Vector3 value3,
|
||||||
float amount1,
|
float amount1,
|
||||||
float amount2
|
float amount2
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
return new Vector3(
|
return new Vector3(
|
||||||
MathHelper.Barycentric(value1.X, value2.X, value3.X, amount1, amount2),
|
MathHelper.Barycentric(value1.X, value2.X, value3.X, amount1, amount2),
|
||||||
MathHelper.Barycentric(value1.Y, value2.Y, value3.Y, amount1, amount2),
|
MathHelper.Barycentric(value1.Y, value2.Y, value3.Y, amount1, amount2),
|
||||||
|
@ -407,7 +408,8 @@ namespace MoonWorks.Math
|
||||||
float amount1,
|
float amount1,
|
||||||
float amount2,
|
float amount2,
|
||||||
out Vector3 result
|
out Vector3 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
result.X = MathHelper.Barycentric(value1.X, value2.X, value3.X, amount1, amount2);
|
result.X = MathHelper.Barycentric(value1.X, value2.X, value3.X, amount1, amount2);
|
||||||
result.Y = MathHelper.Barycentric(value1.Y, value2.Y, value3.Y, amount1, amount2);
|
result.Y = MathHelper.Barycentric(value1.Y, value2.Y, value3.Y, amount1, amount2);
|
||||||
result.Z = MathHelper.Barycentric(value1.Z, value2.Z, value3.Z, amount1, amount2);
|
result.Z = MathHelper.Barycentric(value1.Z, value2.Z, value3.Z, amount1, amount2);
|
||||||
|
@ -428,7 +430,8 @@ namespace MoonWorks.Math
|
||||||
Vector3 value3,
|
Vector3 value3,
|
||||||
Vector3 value4,
|
Vector3 value4,
|
||||||
float amount
|
float amount
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
return new Vector3(
|
return new Vector3(
|
||||||
MathHelper.CatmullRom(value1.X, value2.X, value3.X, value4.X, amount),
|
MathHelper.CatmullRom(value1.X, value2.X, value3.X, value4.X, amount),
|
||||||
MathHelper.CatmullRom(value1.Y, value2.Y, value3.Y, value4.Y, amount),
|
MathHelper.CatmullRom(value1.Y, value2.Y, value3.Y, value4.Y, amount),
|
||||||
|
@ -452,7 +455,8 @@ namespace MoonWorks.Math
|
||||||
ref Vector3 value4,
|
ref Vector3 value4,
|
||||||
float amount,
|
float amount,
|
||||||
out Vector3 result
|
out Vector3 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
result.X = MathHelper.CatmullRom(value1.X, value2.X, value3.X, value4.X, amount);
|
result.X = MathHelper.CatmullRom(value1.X, value2.X, value3.X, value4.X, amount);
|
||||||
result.Y = MathHelper.CatmullRom(value1.Y, value2.Y, value3.Y, value4.Y, amount);
|
result.Y = MathHelper.CatmullRom(value1.Y, value2.Y, value3.Y, value4.Y, amount);
|
||||||
result.Z = MathHelper.CatmullRom(value1.Z, value2.Z, value3.Z, value4.Z, amount);
|
result.Z = MathHelper.CatmullRom(value1.Z, value2.Z, value3.Z, value4.Z, amount);
|
||||||
|
@ -486,24 +490,26 @@ namespace MoonWorks.Math
|
||||||
ref Vector3 min,
|
ref Vector3 min,
|
||||||
ref Vector3 max,
|
ref Vector3 max,
|
||||||
out Vector3 result
|
out Vector3 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
result.X = MathHelper.Clamp(value1.X, min.X, max.X);
|
result.X = MathHelper.Clamp(value1.X, min.X, max.X);
|
||||||
result.Y = MathHelper.Clamp(value1.Y, min.Y, max.Y);
|
result.Y = MathHelper.Clamp(value1.Y, min.Y, max.Y);
|
||||||
result.Z = MathHelper.Clamp(value1.Z, min.Z, max.Z);
|
result.Z = MathHelper.Clamp(value1.Z, min.Z, max.Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Clamps the magnitude of the specified vector.
|
/// Clamps the magnitude of the specified vector.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="value">The vector to clamp.</param>
|
/// <param name="value">The vector to clamp.</param>
|
||||||
/// <param name="maxLength">The maximum length of the vector.</param>
|
/// <param name="maxLength">The maximum length of the vector.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static Vector3 ClampMagnitude(
|
public static Vector3 ClampMagnitude(
|
||||||
Vector3 value,
|
Vector3 value,
|
||||||
float maxLength
|
float maxLength
|
||||||
) {
|
)
|
||||||
return (value.LengthSquared() > maxLength * maxLength) ? (Vector3.Normalize(value) * maxLength) : value;
|
{
|
||||||
}
|
return (value.LengthSquared() > maxLength * maxLength) ? (Vector3.Normalize(value) * maxLength) : value;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Computes the cross product of two vectors.
|
/// Computes the cross product of two vectors.
|
||||||
|
@ -583,7 +589,8 @@ namespace MoonWorks.Math
|
||||||
ref Vector3 value1,
|
ref Vector3 value1,
|
||||||
ref Vector3 value2,
|
ref Vector3 value2,
|
||||||
out float result
|
out float result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
result = (
|
result = (
|
||||||
(value1.X - value2.X) * (value1.X - value2.X) +
|
(value1.X - value2.X) * (value1.X - value2.X) +
|
||||||
(value1.Y - value2.Y) * (value1.Y - value2.Y) +
|
(value1.Y - value2.Y) * (value1.Y - value2.Y) +
|
||||||
|
@ -688,7 +695,8 @@ namespace MoonWorks.Math
|
||||||
Vector3 value2,
|
Vector3 value2,
|
||||||
Vector3 tangent2,
|
Vector3 tangent2,
|
||||||
float amount
|
float amount
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
Vector3 result = new Vector3();
|
Vector3 result = new Vector3();
|
||||||
Hermite(ref value1, ref tangent1, ref value2, ref tangent2, amount, out result);
|
Hermite(ref value1, ref tangent1, ref value2, ref tangent2, amount, out result);
|
||||||
return result;
|
return result;
|
||||||
|
@ -710,7 +718,8 @@ namespace MoonWorks.Math
|
||||||
ref Vector3 tangent2,
|
ref Vector3 tangent2,
|
||||||
float amount,
|
float amount,
|
||||||
out Vector3 result
|
out Vector3 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
result.X = MathHelper.Hermite(value1.X, tangent1.X, value2.X, tangent2.X, amount);
|
result.X = MathHelper.Hermite(value1.X, tangent1.X, value2.X, tangent2.X, amount);
|
||||||
result.Y = MathHelper.Hermite(value1.Y, tangent1.Y, value2.Y, tangent2.Y, amount);
|
result.Y = MathHelper.Hermite(value1.Y, tangent1.Y, value2.Y, tangent2.Y, amount);
|
||||||
result.Z = MathHelper.Hermite(value1.Z, tangent1.Z, value2.Z, tangent2.Z, amount);
|
result.Z = MathHelper.Hermite(value1.Z, tangent1.Z, value2.Z, tangent2.Z, amount);
|
||||||
|
@ -744,7 +753,8 @@ namespace MoonWorks.Math
|
||||||
ref Vector3 value2,
|
ref Vector3 value2,
|
||||||
float amount,
|
float amount,
|
||||||
out Vector3 result
|
out Vector3 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
result.X = MathHelper.Lerp(value1.X, value2.X, amount);
|
result.X = MathHelper.Lerp(value1.X, value2.X, amount);
|
||||||
result.Y = MathHelper.Lerp(value1.Y, value2.Y, amount);
|
result.Y = MathHelper.Lerp(value1.Y, value2.Y, amount);
|
||||||
result.Z = MathHelper.Lerp(value1.Z, value2.Z, amount);
|
result.Z = MathHelper.Lerp(value1.Z, value2.Z, amount);
|
||||||
|
@ -992,7 +1002,8 @@ namespace MoonWorks.Math
|
||||||
ref Vector3 value2,
|
ref Vector3 value2,
|
||||||
float amount,
|
float amount,
|
||||||
out Vector3 result
|
out Vector3 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
result.X = MathHelper.SmoothStep(value1.X, value2.X, amount);
|
result.X = MathHelper.SmoothStep(value1.X, value2.X, amount);
|
||||||
result.Y = MathHelper.SmoothStep(value1.Y, value2.Y, amount);
|
result.Y = MathHelper.SmoothStep(value1.Y, value2.Y, amount);
|
||||||
result.Z = MathHelper.SmoothStep(value1.Z, value2.Z, amount);
|
result.Z = MathHelper.SmoothStep(value1.Z, value2.Z, amount);
|
||||||
|
@ -1047,7 +1058,8 @@ namespace MoonWorks.Math
|
||||||
ref Vector3 position,
|
ref Vector3 position,
|
||||||
ref Matrix4x4 matrix,
|
ref Matrix4x4 matrix,
|
||||||
out Vector3 result
|
out Vector3 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
float x = (
|
float x = (
|
||||||
(position.X * matrix.M11) +
|
(position.X * matrix.M11) +
|
||||||
(position.Y * matrix.M21) +
|
(position.Y * matrix.M21) +
|
||||||
|
@ -1081,7 +1093,8 @@ namespace MoonWorks.Math
|
||||||
Vector3[] sourceArray,
|
Vector3[] sourceArray,
|
||||||
ref Matrix4x4 matrix,
|
ref Matrix4x4 matrix,
|
||||||
Vector3[] destinationArray
|
Vector3[] destinationArray
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
Debug.Assert(
|
Debug.Assert(
|
||||||
destinationArray.Length >= sourceArray.Length,
|
destinationArray.Length >= sourceArray.Length,
|
||||||
"The destination array is smaller than the source array."
|
"The destination array is smaller than the source array."
|
||||||
|
@ -1121,7 +1134,8 @@ namespace MoonWorks.Math
|
||||||
Vector3[] destinationArray,
|
Vector3[] destinationArray,
|
||||||
int destinationIndex,
|
int destinationIndex,
|
||||||
int length
|
int length
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
Debug.Assert(
|
Debug.Assert(
|
||||||
sourceArray.Length - sourceIndex >= length,
|
sourceArray.Length - sourceIndex >= length,
|
||||||
"The source array is too small for the given sourceIndex and length."
|
"The source array is too small for the given sourceIndex and length."
|
||||||
|
@ -1173,7 +1187,8 @@ namespace MoonWorks.Math
|
||||||
ref Vector3 value,
|
ref Vector3 value,
|
||||||
ref Quaternion rotation,
|
ref Quaternion rotation,
|
||||||
out Vector3 result
|
out Vector3 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
float x = 2 * (rotation.Y * value.Z - rotation.Z * value.Y);
|
float x = 2 * (rotation.Y * value.Z - rotation.Z * value.Y);
|
||||||
float y = 2 * (rotation.Z * value.X - rotation.X * value.Z);
|
float y = 2 * (rotation.Z * value.X - rotation.X * value.Z);
|
||||||
float z = 2 * (rotation.X * value.Y - rotation.Y * value.X);
|
float z = 2 * (rotation.X * value.Y - rotation.Y * value.X);
|
||||||
|
@ -1193,7 +1208,8 @@ namespace MoonWorks.Math
|
||||||
Vector3[] sourceArray,
|
Vector3[] sourceArray,
|
||||||
ref Quaternion rotation,
|
ref Quaternion rotation,
|
||||||
Vector3[] destinationArray
|
Vector3[] destinationArray
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
Debug.Assert(
|
Debug.Assert(
|
||||||
destinationArray.Length >= sourceArray.Length,
|
destinationArray.Length >= sourceArray.Length,
|
||||||
"The destination array is smaller than the source array."
|
"The destination array is smaller than the source array."
|
||||||
|
@ -1236,7 +1252,8 @@ namespace MoonWorks.Math
|
||||||
Vector3[] destinationArray,
|
Vector3[] destinationArray,
|
||||||
int destinationIndex,
|
int destinationIndex,
|
||||||
int length
|
int length
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
Debug.Assert(
|
Debug.Assert(
|
||||||
sourceArray.Length - sourceIndex >= length,
|
sourceArray.Length - sourceIndex >= length,
|
||||||
"The source array is too small for the given sourceIndex and length."
|
"The source array is too small for the given sourceIndex and length."
|
||||||
|
@ -1289,7 +1306,8 @@ namespace MoonWorks.Math
|
||||||
ref Vector3 normal,
|
ref Vector3 normal,
|
||||||
ref Matrix4x4 matrix,
|
ref Matrix4x4 matrix,
|
||||||
out Vector3 result
|
out Vector3 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
float x = (normal.X * matrix.M11) + (normal.Y * matrix.M21) + (normal.Z * matrix.M31);
|
float x = (normal.X * matrix.M11) + (normal.Y * matrix.M21) + (normal.Z * matrix.M31);
|
||||||
float y = (normal.X * matrix.M12) + (normal.Y * matrix.M22) + (normal.Z * matrix.M32);
|
float y = (normal.X * matrix.M12) + (normal.Y * matrix.M22) + (normal.Z * matrix.M32);
|
||||||
float z = (normal.X * matrix.M13) + (normal.Y * matrix.M23) + (normal.Z * matrix.M33);
|
float z = (normal.X * matrix.M13) + (normal.Y * matrix.M23) + (normal.Z * matrix.M33);
|
||||||
|
@ -1308,7 +1326,8 @@ namespace MoonWorks.Math
|
||||||
Vector3[] sourceArray,
|
Vector3[] sourceArray,
|
||||||
ref Matrix4x4 matrix,
|
ref Matrix4x4 matrix,
|
||||||
Vector3[] destinationArray
|
Vector3[] destinationArray
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
Debug.Assert(
|
Debug.Assert(
|
||||||
destinationArray.Length >= sourceArray.Length,
|
destinationArray.Length >= sourceArray.Length,
|
||||||
"The destination array is smaller than the source array."
|
"The destination array is smaller than the source array."
|
||||||
|
@ -1339,7 +1358,8 @@ namespace MoonWorks.Math
|
||||||
Vector3[] destinationArray,
|
Vector3[] destinationArray,
|
||||||
int destinationIndex,
|
int destinationIndex,
|
||||||
int length
|
int length
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
if (sourceArray == null)
|
if (sourceArray == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("sourceArray");
|
throw new ArgumentNullException("sourceArray");
|
||||||
|
@ -1396,9 +1416,9 @@ namespace MoonWorks.Math
|
||||||
/// <returns><c>true</c> if the instances are equal; <c>false</c> otherwise.</returns>
|
/// <returns><c>true</c> if the instances are equal; <c>false</c> otherwise.</returns>
|
||||||
public static bool operator ==(Vector3 value1, Vector3 value2)
|
public static bool operator ==(Vector3 value1, Vector3 value2)
|
||||||
{
|
{
|
||||||
return ( value1.X == value2.X &&
|
return (value1.X == value2.X &&
|
||||||
value1.Y == value2.Y &&
|
value1.Y == value2.Y &&
|
||||||
value1.Z == value2.Z );
|
value1.Z == value2.Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#region License
|
#region License
|
||||||
|
|
||||||
/* MoonWorks - Game Development Framework
|
/* MoonWorks - Game Development Framework
|
||||||
* Copyright 2021 Evan Hemsley
|
* Copyright 2021 Evan Hemsley
|
||||||
|
@ -234,10 +234,10 @@ namespace MoonWorks.Math
|
||||||
/// <returns><c>true</c> if the instances are equal; <c>false</c> otherwise.</returns>
|
/// <returns><c>true</c> if the instances are equal; <c>false</c> otherwise.</returns>
|
||||||
public bool Equals(Vector4 other)
|
public bool Equals(Vector4 other)
|
||||||
{
|
{
|
||||||
return ( X == other.X &&
|
return (X == other.X &&
|
||||||
Y == other.Y &&
|
Y == other.Y &&
|
||||||
Z == other.Z &&
|
Z == other.Z &&
|
||||||
W == other.W );
|
W == other.W);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -344,7 +344,8 @@ namespace MoonWorks.Math
|
||||||
Vector4 value3,
|
Vector4 value3,
|
||||||
float amount1,
|
float amount1,
|
||||||
float amount2
|
float amount2
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
return new Vector4(
|
return new Vector4(
|
||||||
MathHelper.Barycentric(value1.X, value2.X, value3.X, amount1, amount2),
|
MathHelper.Barycentric(value1.X, value2.X, value3.X, amount1, amount2),
|
||||||
MathHelper.Barycentric(value1.Y, value2.Y, value3.Y, amount1, amount2),
|
MathHelper.Barycentric(value1.Y, value2.Y, value3.Y, amount1, amount2),
|
||||||
|
@ -369,7 +370,8 @@ namespace MoonWorks.Math
|
||||||
float amount1,
|
float amount1,
|
||||||
float amount2,
|
float amount2,
|
||||||
out Vector4 result
|
out Vector4 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
result.X = MathHelper.Barycentric(value1.X, value2.X, value3.X, amount1, amount2);
|
result.X = MathHelper.Barycentric(value1.X, value2.X, value3.X, amount1, amount2);
|
||||||
result.Y = MathHelper.Barycentric(value1.Y, value2.Y, value3.Y, amount1, amount2);
|
result.Y = MathHelper.Barycentric(value1.Y, value2.Y, value3.Y, amount1, amount2);
|
||||||
result.Z = MathHelper.Barycentric(value1.Z, value2.Z, value3.Z, amount1, amount2);
|
result.Z = MathHelper.Barycentric(value1.Z, value2.Z, value3.Z, amount1, amount2);
|
||||||
|
@ -391,7 +393,8 @@ namespace MoonWorks.Math
|
||||||
Vector4 value3,
|
Vector4 value3,
|
||||||
Vector4 value4,
|
Vector4 value4,
|
||||||
float amount
|
float amount
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
return new Vector4(
|
return new Vector4(
|
||||||
MathHelper.CatmullRom(value1.X, value2.X, value3.X, value4.X, amount),
|
MathHelper.CatmullRom(value1.X, value2.X, value3.X, value4.X, amount),
|
||||||
MathHelper.CatmullRom(value1.Y, value2.Y, value3.Y, value4.Y, amount),
|
MathHelper.CatmullRom(value1.Y, value2.Y, value3.Y, value4.Y, amount),
|
||||||
|
@ -416,7 +419,8 @@ namespace MoonWorks.Math
|
||||||
ref Vector4 value4,
|
ref Vector4 value4,
|
||||||
float amount,
|
float amount,
|
||||||
out Vector4 result
|
out Vector4 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
result.X = MathHelper.CatmullRom(value1.X, value2.X, value3.X, value4.X, amount);
|
result.X = MathHelper.CatmullRom(value1.X, value2.X, value3.X, value4.X, amount);
|
||||||
result.Y = MathHelper.CatmullRom(value1.Y, value2.Y, value3.Y, value4.Y, amount);
|
result.Y = MathHelper.CatmullRom(value1.Y, value2.Y, value3.Y, value4.Y, amount);
|
||||||
result.Z = MathHelper.CatmullRom(value1.Z, value2.Z, value3.Z, value4.Z, amount);
|
result.Z = MathHelper.CatmullRom(value1.Z, value2.Z, value3.Z, value4.Z, amount);
|
||||||
|
@ -452,7 +456,8 @@ namespace MoonWorks.Math
|
||||||
ref Vector4 min,
|
ref Vector4 min,
|
||||||
ref Vector4 max,
|
ref Vector4 max,
|
||||||
out Vector4 result
|
out Vector4 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
result.X = MathHelper.Clamp(value1.X, min.X, max.X);
|
result.X = MathHelper.Clamp(value1.X, min.X, max.X);
|
||||||
result.Y = MathHelper.Clamp(value1.Y, min.Y, max.Y);
|
result.Y = MathHelper.Clamp(value1.Y, min.Y, max.Y);
|
||||||
result.Z = MathHelper.Clamp(value1.Z, min.Z, max.Z);
|
result.Z = MathHelper.Clamp(value1.Z, min.Z, max.Z);
|
||||||
|
@ -507,7 +512,8 @@ namespace MoonWorks.Math
|
||||||
ref Vector4 value1,
|
ref Vector4 value1,
|
||||||
ref Vector4 value2,
|
ref Vector4 value2,
|
||||||
out float result
|
out float result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
result = (
|
result = (
|
||||||
(value1.W - value2.W) * (value1.W - value2.W) +
|
(value1.W - value2.W) * (value1.W - value2.W) +
|
||||||
(value1.X - value2.X) * (value1.X - value2.X) +
|
(value1.X - value2.X) * (value1.X - value2.X) +
|
||||||
|
@ -572,7 +578,8 @@ namespace MoonWorks.Math
|
||||||
ref Vector4 value1,
|
ref Vector4 value1,
|
||||||
ref Vector4 value2,
|
ref Vector4 value2,
|
||||||
out Vector4 result
|
out Vector4 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
result.W = value1.W / value2.W;
|
result.W = value1.W / value2.W;
|
||||||
result.X = value1.X / value2.X;
|
result.X = value1.X / value2.X;
|
||||||
result.Y = value1.Y / value2.Y;
|
result.Y = value1.Y / value2.Y;
|
||||||
|
@ -626,7 +633,8 @@ namespace MoonWorks.Math
|
||||||
Vector4 value2,
|
Vector4 value2,
|
||||||
Vector4 tangent2,
|
Vector4 tangent2,
|
||||||
float amount
|
float amount
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
return new Vector4(
|
return new Vector4(
|
||||||
MathHelper.Hermite(value1.X, tangent1.X, value2.X, tangent2.X, amount),
|
MathHelper.Hermite(value1.X, tangent1.X, value2.X, tangent2.X, amount),
|
||||||
MathHelper.Hermite(value1.Y, tangent1.Y, value2.Y, tangent2.Y, amount),
|
MathHelper.Hermite(value1.Y, tangent1.Y, value2.Y, tangent2.Y, amount),
|
||||||
|
@ -651,7 +659,8 @@ namespace MoonWorks.Math
|
||||||
ref Vector4 tangent2,
|
ref Vector4 tangent2,
|
||||||
float amount,
|
float amount,
|
||||||
out Vector4 result
|
out Vector4 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
result.W = MathHelper.Hermite(value1.W, tangent1.W, value2.W, tangent2.W, amount);
|
result.W = MathHelper.Hermite(value1.W, tangent1.W, value2.W, tangent2.W, amount);
|
||||||
result.X = MathHelper.Hermite(value1.X, tangent1.X, value2.X, tangent2.X, amount);
|
result.X = MathHelper.Hermite(value1.X, tangent1.X, value2.X, tangent2.X, amount);
|
||||||
result.Y = MathHelper.Hermite(value1.Y, tangent1.Y, value2.Y, tangent2.Y, amount);
|
result.Y = MathHelper.Hermite(value1.Y, tangent1.Y, value2.Y, tangent2.Y, amount);
|
||||||
|
@ -687,7 +696,8 @@ namespace MoonWorks.Math
|
||||||
ref Vector4 value2,
|
ref Vector4 value2,
|
||||||
float amount,
|
float amount,
|
||||||
out Vector4 result
|
out Vector4 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
result.X = MathHelper.Lerp(value1.X, value2.X, amount);
|
result.X = MathHelper.Lerp(value1.X, value2.X, amount);
|
||||||
result.Y = MathHelper.Lerp(value1.Y, value2.Y, amount);
|
result.Y = MathHelper.Lerp(value1.Y, value2.Y, amount);
|
||||||
result.Z = MathHelper.Lerp(value1.Z, value2.Z, amount);
|
result.Z = MathHelper.Lerp(value1.Z, value2.Z, amount);
|
||||||
|
@ -905,7 +915,8 @@ namespace MoonWorks.Math
|
||||||
ref Vector4 value2,
|
ref Vector4 value2,
|
||||||
float amount,
|
float amount,
|
||||||
out Vector4 result
|
out Vector4 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
result.X = MathHelper.SmoothStep(value1.X, value2.X, amount);
|
result.X = MathHelper.SmoothStep(value1.X, value2.X, amount);
|
||||||
result.Y = MathHelper.SmoothStep(value1.Y, value2.Y, amount);
|
result.Y = MathHelper.SmoothStep(value1.Y, value2.Y, amount);
|
||||||
result.Z = MathHelper.SmoothStep(value1.Z, value2.Z, amount);
|
result.Z = MathHelper.SmoothStep(value1.Z, value2.Z, amount);
|
||||||
|
@ -1081,7 +1092,8 @@ namespace MoonWorks.Math
|
||||||
Vector4[] sourceArray,
|
Vector4[] sourceArray,
|
||||||
ref Matrix4x4 matrix,
|
ref Matrix4x4 matrix,
|
||||||
Vector4[] destinationArray
|
Vector4[] destinationArray
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
if (sourceArray == null)
|
if (sourceArray == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("sourceArray");
|
throw new ArgumentNullException("sourceArray");
|
||||||
|
@ -1122,7 +1134,8 @@ namespace MoonWorks.Math
|
||||||
Vector4[] destinationArray,
|
Vector4[] destinationArray,
|
||||||
int destinationIndex,
|
int destinationIndex,
|
||||||
int length
|
int length
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
if (sourceArray == null)
|
if (sourceArray == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("sourceArray");
|
throw new ArgumentNullException("sourceArray");
|
||||||
|
@ -1202,7 +1215,8 @@ namespace MoonWorks.Math
|
||||||
ref Vector2 value,
|
ref Vector2 value,
|
||||||
ref Quaternion rotation,
|
ref Quaternion rotation,
|
||||||
out Vector4 result
|
out Vector4 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
double xx = rotation.X + rotation.X;
|
double xx = rotation.X + rotation.X;
|
||||||
double yy = rotation.Y + rotation.Y;
|
double yy = rotation.Y + rotation.Y;
|
||||||
double zz = rotation.Z + rotation.Z;
|
double zz = rotation.Z + rotation.Z;
|
||||||
|
@ -1240,7 +1254,8 @@ namespace MoonWorks.Math
|
||||||
ref Vector3 value,
|
ref Vector3 value,
|
||||||
ref Quaternion rotation,
|
ref Quaternion rotation,
|
||||||
out Vector4 result
|
out Vector4 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
double xx = rotation.X + rotation.X;
|
double xx = rotation.X + rotation.X;
|
||||||
double yy = rotation.Y + rotation.Y;
|
double yy = rotation.Y + rotation.Y;
|
||||||
double zz = rotation.Z + rotation.Z;
|
double zz = rotation.Z + rotation.Z;
|
||||||
|
@ -1281,7 +1296,8 @@ namespace MoonWorks.Math
|
||||||
ref Vector4 value,
|
ref Vector4 value,
|
||||||
ref Quaternion rotation,
|
ref Quaternion rotation,
|
||||||
out Vector4 result
|
out Vector4 result
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
double xx = rotation.X + rotation.X;
|
double xx = rotation.X + rotation.X;
|
||||||
double yy = rotation.Y + rotation.Y;
|
double yy = rotation.Y + rotation.Y;
|
||||||
double zz = rotation.Z + rotation.Z;
|
double zz = rotation.Z + rotation.Z;
|
||||||
|
@ -1322,7 +1338,8 @@ namespace MoonWorks.Math
|
||||||
Vector4[] sourceArray,
|
Vector4[] sourceArray,
|
||||||
ref Quaternion rotation,
|
ref Quaternion rotation,
|
||||||
Vector4[] destinationArray
|
Vector4[] destinationArray
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
if (sourceArray == null)
|
if (sourceArray == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentException("sourceArray");
|
throw new ArgumentException("sourceArray");
|
||||||
|
@ -1363,7 +1380,8 @@ namespace MoonWorks.Math
|
||||||
Vector4[] destinationArray,
|
Vector4[] destinationArray,
|
||||||
int destinationIndex,
|
int destinationIndex,
|
||||||
int length
|
int length
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
if (sourceArray == null)
|
if (sourceArray == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentException("sourceArray");
|
throw new ArgumentException("sourceArray");
|
||||||
|
@ -1405,10 +1423,10 @@ namespace MoonWorks.Math
|
||||||
|
|
||||||
public static bool operator ==(Vector4 value1, Vector4 value2)
|
public static bool operator ==(Vector4 value1, Vector4 value2)
|
||||||
{
|
{
|
||||||
return ( value1.X == value2.X &&
|
return (value1.X == value2.X &&
|
||||||
value1.Y == value2.Y &&
|
value1.Y == value2.Y &&
|
||||||
value1.Z == value2.Z &&
|
value1.Z == value2.Z &&
|
||||||
value1.W == value2.W );
|
value1.W == value2.W);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool operator !=(Vector4 value1, Vector4 value2)
|
public static bool operator !=(Vector4 value1, Vector4 value2)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#region License
|
#region License
|
||||||
|
|
||||||
/* MoonWorks - Game Development Framework
|
/* MoonWorks - Game Development Framework
|
||||||
* Copyright 2021 Evan Hemsley
|
* Copyright 2021 Evan Hemsley
|
||||||
|
@ -42,7 +42,7 @@ namespace MoonWorks
|
||||||
}
|
}
|
||||||
else if (OperatingSystem.IsMacOS())
|
else if (OperatingSystem.IsMacOS())
|
||||||
{
|
{
|
||||||
return "osx";
|
return "osx";
|
||||||
}
|
}
|
||||||
else if (OperatingSystem.IsLinux())
|
else if (OperatingSystem.IsLinux())
|
||||||
{
|
{
|
||||||
|
@ -67,7 +67,8 @@ namespace MoonWorks
|
||||||
string libraryName,
|
string libraryName,
|
||||||
Assembly assembly,
|
Assembly assembly,
|
||||||
DllImportSearchPath? dllImportSearchPath
|
DllImportSearchPath? dllImportSearchPath
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
string mappedName;
|
string mappedName;
|
||||||
if (!mapDictionary.TryGetValue(libraryName, out mappedName))
|
if (!mapDictionary.TryGetValue(libraryName, out mappedName))
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,66 +1,66 @@
|
||||||
using System;
|
using System;
|
||||||
using SDL2;
|
using SDL2;
|
||||||
|
|
||||||
namespace MoonWorks.Window
|
namespace MoonWorks.Window
|
||||||
{
|
{
|
||||||
public class OSWindow : IDisposable
|
public class OSWindow : IDisposable
|
||||||
{
|
{
|
||||||
internal IntPtr Handle { get; }
|
internal IntPtr Handle { get; }
|
||||||
public ScreenMode ScreenMode { get; }
|
public ScreenMode ScreenMode { get; }
|
||||||
|
|
||||||
private bool IsDisposed;
|
private bool IsDisposed;
|
||||||
|
|
||||||
public OSWindow(WindowCreateInfo windowCreateInfo)
|
public OSWindow(WindowCreateInfo windowCreateInfo)
|
||||||
{
|
{
|
||||||
var windowFlags = SDL.SDL_WindowFlags.SDL_WINDOW_VULKAN;
|
var windowFlags = SDL.SDL_WindowFlags.SDL_WINDOW_VULKAN;
|
||||||
|
|
||||||
if (windowCreateInfo.ScreenMode == ScreenMode.Fullscreen)
|
if (windowCreateInfo.ScreenMode == ScreenMode.Fullscreen)
|
||||||
{
|
{
|
||||||
windowFlags |= SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN;
|
windowFlags |= SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN;
|
||||||
}
|
}
|
||||||
else if (windowCreateInfo.ScreenMode == ScreenMode.BorderlessWindow)
|
else if (windowCreateInfo.ScreenMode == ScreenMode.BorderlessWindow)
|
||||||
{
|
{
|
||||||
windowFlags |= SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN_DESKTOP;
|
windowFlags |= SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScreenMode = windowCreateInfo.ScreenMode;
|
ScreenMode = windowCreateInfo.ScreenMode;
|
||||||
|
|
||||||
Handle = SDL.SDL_CreateWindow(
|
Handle = SDL.SDL_CreateWindow(
|
||||||
windowCreateInfo.WindowTitle,
|
windowCreateInfo.WindowTitle,
|
||||||
SDL.SDL_WINDOWPOS_UNDEFINED,
|
SDL.SDL_WINDOWPOS_UNDEFINED,
|
||||||
SDL.SDL_WINDOWPOS_UNDEFINED,
|
SDL.SDL_WINDOWPOS_UNDEFINED,
|
||||||
(int)windowCreateInfo.WindowWidth,
|
(int) windowCreateInfo.WindowWidth,
|
||||||
(int)windowCreateInfo.WindowHeight,
|
(int) windowCreateInfo.WindowHeight,
|
||||||
windowFlags
|
windowFlags
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ChangeScreenMode(ScreenMode screenMode)
|
public void ChangeScreenMode(ScreenMode screenMode)
|
||||||
{
|
{
|
||||||
SDL.SDL_WindowFlags windowFlag = 0;
|
SDL.SDL_WindowFlags windowFlag = 0;
|
||||||
|
|
||||||
if (screenMode == ScreenMode.Fullscreen)
|
if (screenMode == ScreenMode.Fullscreen)
|
||||||
{
|
{
|
||||||
windowFlag = SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN;
|
windowFlag = SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN;
|
||||||
}
|
}
|
||||||
else if (screenMode == ScreenMode.BorderlessWindow)
|
else if (screenMode == ScreenMode.BorderlessWindow)
|
||||||
{
|
{
|
||||||
windowFlag = SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN_DESKTOP;
|
windowFlag = SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL.SDL_SetWindowFullscreen(Handle, (uint) windowFlag);
|
SDL.SDL_SetWindowFullscreen(Handle, (uint) windowFlag);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Resizes the window.
|
/// Resizes the window.
|
||||||
/// Note that you are responsible for recreating any graphics resources that need to change as a result of the size change.
|
/// Note that you are responsible for recreating any graphics resources that need to change as a result of the size change.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="width"></param>
|
/// <param name="width"></param>
|
||||||
/// <param name="height"></param>
|
/// <param name="height"></param>
|
||||||
public void SetWindowSize(uint width, uint height)
|
public void SetWindowSize(uint width, uint height)
|
||||||
{
|
{
|
||||||
SDL.SDL_SetWindowSize(Handle, (int)width, (int)height);
|
SDL.SDL_SetWindowSize(Handle, (int) width, (int) height);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void Dispose(bool disposing)
|
protected virtual void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
|
@ -79,8 +79,8 @@ namespace MoonWorks.Window
|
||||||
|
|
||||||
~OSWindow()
|
~OSWindow()
|
||||||
{
|
{
|
||||||
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
||||||
Dispose(disposing: false);
|
Dispose(disposing: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
namespace MoonWorks.Window
|
namespace MoonWorks.Window
|
||||||
{
|
{
|
||||||
public enum ScreenMode
|
public enum ScreenMode
|
||||||
{
|
{
|
||||||
Fullscreen,
|
Fullscreen,
|
||||||
BorderlessWindow,
|
BorderlessWindow,
|
||||||
Windowed
|
Windowed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
namespace MoonWorks.Window
|
namespace MoonWorks.Window
|
||||||
{
|
{
|
||||||
public struct WindowCreateInfo
|
public struct WindowCreateInfo
|
||||||
{
|
{
|
||||||
public string WindowTitle;
|
public string WindowTitle;
|
||||||
public uint WindowWidth;
|
public uint WindowWidth;
|
||||||
public uint WindowHeight;
|
public uint WindowHeight;
|
||||||
public ScreenMode ScreenMode;
|
public ScreenMode ScreenMode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue