Formatting pass

pull/14/head
cosmonaut 2022-02-22 21:14:32 -08:00
parent a0c57c7a59
commit 8973b3e658
93 changed files with 5236 additions and 5080 deletions

14
.editorconfig Normal file
View File

@ -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

View File

@ -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);
} }
} }
} }

View File

@ -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() { }
} }
} }

View File

@ -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() { }
} }
} }

View File

@ -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);
} }
} }
} }

View File

@ -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);
} }
} }
} }

View File

@ -1,9 +1,9 @@
namespace MoonWorks.Audio namespace MoonWorks.Audio
{ {
public enum SoundState public enum SoundState
{ {
Playing, Playing,
Paused, Paused,
Stopped Stopped
} }
} }

View File

@ -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);
} }
} }
} }

View File

@ -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);
} }
} }
} }
} }

View File

@ -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);
} }
} }
} }

View File

@ -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);
} }
} }
} }

View File

@ -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)
{ {
} }
} }
} }

View File

@ -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;
} }
} }
} }

View File

@ -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;
} }
} }
} }

View File

@ -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;
} }
} }
} }

View File

@ -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

View File

@ -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);
} }
} }
} }

View File

@ -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);
} }
} }
} }

View File

@ -1,4 +1,4 @@
#region License #region License
/* MoonWorks - Game Development Framework /* MoonWorks - Game Development Framework
* Copyright 2021 Evan Hemsley * Copyright 2021 Evan Hemsley

View File

@ -1,4 +1,4 @@
#region License #region License
/* MoonWorks - Game Development Framework /* MoonWorks - Game Development Framework
* Copyright 2021 Evan Hemsley * Copyright 2021 Evan Hemsley

View File

@ -1,4 +1,4 @@
#region License #region License
/* MoonWorks - Game Development Framework /* MoonWorks - Game Development Framework
* Copyright 2021 Evan Hemsley * Copyright 2021 Evan Hemsley

View File

@ -1,4 +1,4 @@
#region License #region License
/* MoonWorks - Game Development Framework /* MoonWorks - Game Development Framework
* Copyright 2021 Evan Hemsley * Copyright 2021 Evan Hemsley

View File

@ -1,4 +1,4 @@
#region License #region License
/* MoonWorks - Game Development Framework /* MoonWorks - Game Development Framework
* Copyright 2021 Evan Hemsley * Copyright 2021 Evan Hemsley

View File

@ -1,4 +1,4 @@
#region License #region License
/* MoonWorks - Game Development Framework /* MoonWorks - Game Development Framework
* Copyright 2021 Evan Hemsley * Copyright 2021 Evan Hemsley

View File

@ -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)

View File

@ -1,4 +1,4 @@
#region License #region License
/* MoonWorks - Game Development Framework /* MoonWorks - Game Development Framework
* Copyright 2021 Evan Hemsley * Copyright 2021 Evan Hemsley

View File

@ -1,4 +1,4 @@
#region License #region License
/* MoonWorks - Game Development Framework /* MoonWorks - Game Development Framework
* Copyright 2021 Evan Hemsley * Copyright 2021 Evan Hemsley

View File

@ -1,4 +1,4 @@
#region License #region License
/* MoonWorks - Game Development Framework /* MoonWorks - Game Development Framework
* Copyright 2021 Evan Hemsley * Copyright 2021 Evan Hemsley

View File

@ -1,4 +1,4 @@
#region License #region License
/* MoonWorks - Game Development Framework /* MoonWorks - Game Development Framework
* Copyright 2021 Evan Hemsley * Copyright 2021 Evan Hemsley

View File

@ -1,4 +1,4 @@
#region License #region License
/* MoonWorks - Game Development Framework /* MoonWorks - Game Development Framework
* Copyright 2021 Evan Hemsley * Copyright 2021 Evan Hemsley

View File

@ -1,4 +1,4 @@
#region License #region License
/* MoonWorks - Game Development Framework /* MoonWorks - Game Development Framework
* Copyright 2021 Evan Hemsley * Copyright 2021 Evan Hemsley

View File

@ -1,4 +1,4 @@
#region License #region License
/* MoonWorks - Game Development Framework /* MoonWorks - Game Development Framework
* Copyright 2021 Evan Hemsley * Copyright 2021 Evan Hemsley

View File

@ -1,4 +1,4 @@
#region License #region License
/* MoonWorks - Game Development Framework /* MoonWorks - Game Development Framework
* Copyright 2021 Evan Hemsley * Copyright 2021 Evan Hemsley

View File

@ -1,4 +1,4 @@
#region License #region License
/* MoonWorks - Game Development Framework /* MoonWorks - Game Development Framework
* Copyright 2021 Evan Hemsley * Copyright 2021 Evan Hemsley

View File

@ -1,4 +1,4 @@
#region License #region License
/* MoonWorks - Game Development Framework /* MoonWorks - Game Development Framework
* Copyright 2021 Evan Hemsley * Copyright 2021 Evan Hemsley

View File

@ -1,4 +1,4 @@
#region License #region License
/* MoonWorks - Game Development Framework /* MoonWorks - Game Development Framework
* Copyright 2021 Evan Hemsley * Copyright 2021 Evan Hemsley

View File

@ -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)

View File

@ -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
} }
} }

View File

@ -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
}; };
} }
} }
} }

View File

@ -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
); );
} }
} }
} }
} }

View File

@ -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;
} }
} }
} }

View File

@ -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;
} }
} }
} }

View File

@ -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;
} }
} }
} }

View File

@ -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);
} }
} }
} }
} }

View File

@ -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;
} }
} }
} }

View File

@ -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()
); );
} }
} }
} }

View File

@ -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);
} }
} }
} }
} }

View File

@ -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;
} }
} }
} }

View File

@ -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;
} }
} }

View File

@ -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
}; };
} }
} }
} }

View File

@ -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
}; };
} }
} }

View File

@ -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;
} }
} }

View File

@ -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;
} }
} }

View File

@ -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
}; };
} }
} }

View File

@ -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
}; };
} }
} }

View File

@ -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
}; };
} }
} }
} }

View File

@ -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;
} }
} }

View File

@ -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
}; };
} }
} }
} }

View File

@ -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;
} }
} }

View File

@ -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;
} }
} }

View File

@ -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;
} }
} }

View File

@ -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;
} }
} }
} }

View File

@ -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;
} }
} }
} }

View File

@ -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;
} }
} }
} }

View File

@ -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;
} }
} }
} }
} }

View File

@ -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
} }
} }

View File

@ -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;
} }
} }
} }

View File

@ -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);
} }
} }
} }
} }

View File

@ -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;
} }
} }
} }

View File

@ -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
} }
} }

View File

@ -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;
} }
} }
} }

View File

@ -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;
} }
} }
} }

View File

@ -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;
} }

View File

@ -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 = -------------------------------------------------------------------

View File

@ -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();

View File

@ -1,4 +1,4 @@
#region License #region License
/* MoonWorks - Game Development Framework /* MoonWorks - Game Development Framework
* Copyright 2021 Evan Hemsley * Copyright 2021 Evan Hemsley

View File

@ -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

View File

@ -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);
} }

View File

@ -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,

View File

@ -1,4 +1,4 @@
#region License #region License
/* MoonWorks - Game Development Framework /* MoonWorks - Game Development Framework
* Copyright 2021 Evan Hemsley * Copyright 2021 Evan Hemsley

View File

@ -1,4 +1,4 @@
#region License #region License
/* MoonWorks - Game Development Framework /* MoonWorks - Game Development Framework
* Copyright 2021 Evan Hemsley * Copyright 2021 Evan Hemsley

View File

@ -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

View File

@ -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;
} }

View File

@ -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(

View File

@ -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>

View File

@ -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>

View File

@ -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)

View File

@ -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))
{ {

View File

@ -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()

View File

@ -1,9 +1,9 @@
namespace MoonWorks.Window namespace MoonWorks.Window
{ {
public enum ScreenMode public enum ScreenMode
{ {
Fullscreen, Fullscreen,
BorderlessWindow, BorderlessWindow,
Windowed Windowed
} }
} }

View File

@ -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;
} }
} }