diff --git a/NHEngine/BootStrap.cs b/NHEngine/BootStrap.cs index f9068a5..c53763b 100644 --- a/NHEngine/BootStrap.cs +++ b/NHEngine/BootStrap.cs @@ -8,6 +8,7 @@ using OpenTK; using OpenTK.Audio.OpenAL; using OpenTK.Audio; +using nhengine.Audio; using ImageSharp; using ImageSharp.Processing; @@ -38,6 +39,7 @@ namespace nhengine public BootStrap() { bootGraphics(); + bootAudio(); bootMap(); } @@ -54,9 +56,19 @@ namespace nhengine } public void bootAudio(){ - AL.Enable(ALCapability.Invalid); + + + + AudioDelegate.init(); + AudioDelegate.DistanceModel("exponential", true); + nhBuffers.addSearchPath("./sounds"); + nhBuffers.loadSound("HowFire", "HowHit", "st1"); + //AudioDelegate.test(); + } + + public void bootMap(){ ImageSharp.Image i = ImageSharp.Image.Load( new FileStream("M3-wip.png",FileMode.Open)); i.Flip(ImageSharp.Processing.FlipType.Vertical); @@ -80,6 +92,7 @@ namespace nhengine public void run(){ glWindow.MakeCurrent(); glWindow.Run(25,25); + } diff --git a/NHEngine/OpenGLWindow.cs b/NHEngine/OpenGLWindow.cs index b54598b..fabc954 100644 --- a/NHEngine/OpenGLWindow.cs +++ b/NHEngine/OpenGLWindow.cs @@ -238,6 +238,7 @@ namespace nhengine private void fireBallistic(){ Console.WriteLine("Fire Ballistic..."); BallisticActor ba = new BallisticActor(0); + ba.fire(); ba.Position = BootStrap.instance().SquaredMap.ground(new Vector2(10,10)); ba.Velocity = new Vector3(0,1,1);// + (Matrix4.CreateRotationZ(arcLeftRight) * Vector4.UnitY).Xyz; diff --git a/NHEngine/nhengine.csproj b/NHEngine/nhengine.csproj index 17c528f..e928980 100644 --- a/NHEngine/nhengine.csproj +++ b/NHEngine/nhengine.csproj @@ -65,8 +65,12 @@ - - + + PreserveNewest + + + PreserveNewest + @@ -82,6 +86,21 @@ PreserveNewest + + + + + + PreserveNewest + + + + + PreserveNewest + + + PreserveNewest + @@ -93,5 +112,8 @@ org.hwo.contracts + + + \ No newline at end of file diff --git a/NHEngine/sounds/HowFire.wav b/NHEngine/sounds/HowFire.wav new file mode 100644 index 0000000..cbe0c35 Binary files /dev/null and b/NHEngine/sounds/HowFire.wav differ diff --git a/NHEngine/sounds/HowHit.wav b/NHEngine/sounds/HowHit.wav new file mode 100644 index 0000000..6834d08 Binary files /dev/null and b/NHEngine/sounds/HowHit.wav differ diff --git a/NHEngine/sounds/seq01.wav b/NHEngine/sounds/seq01.wav new file mode 100644 index 0000000..644db40 Binary files /dev/null and b/NHEngine/sounds/seq01.wav differ diff --git a/NHEngine/sounds/seq02.wav b/NHEngine/sounds/seq02.wav new file mode 100644 index 0000000..fcbc06b Binary files /dev/null and b/NHEngine/sounds/seq02.wav differ diff --git a/NHEngine/sounds/seq03.wav b/NHEngine/sounds/seq03.wav new file mode 100644 index 0000000..2ed40bb Binary files /dev/null and b/NHEngine/sounds/seq03.wav differ diff --git a/NHEngine/sounds/sfx1.wav b/NHEngine/sounds/sfx1.wav new file mode 100644 index 0000000..875ba8b Binary files /dev/null and b/NHEngine/sounds/sfx1.wav differ diff --git a/NHEngine/sounds/sfx2.wav b/NHEngine/sounds/sfx2.wav new file mode 100644 index 0000000..8b139a6 Binary files /dev/null and b/NHEngine/sounds/sfx2.wav differ diff --git a/NHEngine/sounds/st1.wav b/NHEngine/sounds/st1.wav new file mode 100644 index 0000000..98ec8af Binary files /dev/null and b/NHEngine/sounds/st1.wav differ diff --git a/NHEngine/sounds/st2.wav b/NHEngine/sounds/st2.wav new file mode 100644 index 0000000..f84316c Binary files /dev/null and b/NHEngine/sounds/st2.wav differ diff --git a/org.niclasundharald.engine/Actor.cs b/org.niclasundharald.engine/Actor.cs index e73f444..c045b6a 100644 --- a/org.niclasundharald.engine/Actor.cs +++ b/org.niclasundharald.engine/Actor.cs @@ -4,6 +4,8 @@ using System.Collections.Generic; using OpenTK; using org.niclasundharald.engine.graphics; +using nhengine.Audio; + namespace org.niclasundharald.engine { @@ -12,13 +14,19 @@ namespace org.niclasundharald.engine public static List activeActors = new List(); public static List finishedActors = new List(); - public static void updateAll(float timespan){ - foreach (Actor a in activeActors){ + + public static void updateAll(float timespan) + { + foreach (Actor a in activeActors) + { a.update(timespan); } - foreach (Actor a in finishedActors){ + foreach (Actor a in finishedActors) + { activeActors.Remove(a); + + } finishedActors.Clear(); @@ -31,10 +39,16 @@ namespace org.niclasundharald.engine Console.WriteLine("New Actor: {0} / {1}",id,this); this.id = id; activeActors.Add(this); + + _player = new nhPlayer(); + activePlayers.Add(_player); + } public void destroy(){ finishedActors.Add(this); + _player.deletePlayer(); + } public Vector3 Heading { get; set; } @@ -68,5 +82,53 @@ namespace org.niclasundharald.engine return Model3D; } + + //>>>>>>>>AUDIO + + private static List activePlayers = new List(); + private static Dictionary aBuffers = new Dictionary(); + + private nhPlayer _player; + + public bool isPlaying = false; + + + + + public void setDistanceAttenuation(float rollOf = 2.0f, float refDistance = 1.0f, float maxDistance = 100.0f) + { + _player.setDistanceAttenuation(rollOf, refDistance, maxDistance); + + } + + public void setBuffers(params string[] buffers) + { + foreach (string i in buffers) + { + if(!aBuffers.ContainsKey(i)) + aBuffers.Add(i, nhBuffers.buffers[i]); + } + } + + public void playSound(string sound, float gain = 1.0f, bool loop = false) + { + + _player.position = this.Position; + _player.velocity = this.Velocity; + _player.play(aBuffers[sound], gain, loop); + } + + public void setPlayerPosition(Vector3 positon, Vector3 velocity) + { + _player.setPosition(positon); + _player.setVelocity(velocity); + } + + public void updateSoundState() + { + isPlaying = _player.state(); + + } + } } diff --git a/org.niclasundharald.engine/BallisticActor.cs b/org.niclasundharald.engine/BallisticActor.cs index 946b730..ac5db7b 100644 --- a/org.niclasundharald.engine/BallisticActor.cs +++ b/org.niclasundharald.engine/BallisticActor.cs @@ -4,6 +4,8 @@ using org.niclasundharald.engine.graphics; using OpenTK; + + namespace org.niclasundharald.engine { public class BallisticActor : Actor @@ -18,12 +20,19 @@ namespace org.niclasundharald.engine } this.Model3D.rebind(); + + setBuffers("HowFire", "HowHit"); + setDistanceAttenuation(2, 200, 800); } + byte hit = 0; + + public override void update(float timespan) { base.update(timespan); + Velocity += (Physics.Gravitation * timespan); Position += Velocity * timespan; Scale = Matrix4.CreateScale(3.0f); @@ -32,18 +41,42 @@ namespace org.niclasundharald.engine Console.WriteLine("BallisticActor update: {0} / {1}",Position,Velocity); + updateSoundState(); + Console.WriteLine("Playing:" + isPlaying); + try{ Vector3 ground = SquaredMap.activeMap.ground(Position.Xy); if (Position.Z <= ground.Z){ - destroy(); + + if(hit != 1) + { + playSound("HowHit"); + updateSoundState(); + hit = 1; + } + + if(!isPlaying) + { + destroy(); + } } - } catch (OutOfWorldException e){ + } catch (OutOfWorldException e){ + + if(!isPlaying) destroy(); } + } + + + + public void fire() + { + playSound("HowFire"); } + } } diff --git a/org.niclasundharald.engine/audio/AudioDelegate.cs b/org.niclasundharald.engine/audio/AudioDelegate.cs new file mode 100644 index 0000000..8776a8a --- /dev/null +++ b/org.niclasundharald.engine/audio/AudioDelegate.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using OpenTK.Audio; +using OpenTK.Audio.OpenAL; +using OpenTK; + + + + + +namespace nhengine.Audio +{ + + + public static class AudioDelegate + { + + + //private static bool debug = true; + + + public static AudioContext context = new AudioContext(); + //public static EffectsExtension efx = new EffectsExtension(); + + /* <<<<<<<<<<>>>>>>>>>> */ + public static void init() + { + nhBuffers.init(); + DistanceModel(); + //nhAux reverb = new nhAux(); + Console.WriteLine("nhengine.Audio initialized."); + } + + + public static void test() + { + nhPlayer testPlayer = new nhPlayer(); + testPlayer.play(nhBuffers.buffers["st1"]); + } + + public static void DistanceModel(string distanceModel = "exponential", bool clamped = false) + { + if (!clamped) + { + switch (distanceModel) + { + case "exponential": + AL.DistanceModel(ALDistanceModel.ExponentDistance); + break; + case "inverse": + AL.DistanceModel(ALDistanceModel.InverseDistance); + break; + case "linear": + AL.DistanceModel(ALDistanceModel.LinearDistance); + break; + } + } + else if (clamped) + { + switch (distanceModel) + { + case "exponential": + AL.DistanceModel(ALDistanceModel.ExponentDistanceClamped); + break; + case "inverse": + AL.DistanceModel(ALDistanceModel.InverseDistanceClamped); + break; + case "linear": + AL.DistanceModel(ALDistanceModel.LinearDistanceClamped); + break; + } + } + else + { + throw new NotSupportedException("DistanceModel not supported!"); + } + } + + + } +} \ No newline at end of file diff --git a/org.niclasundharald.engine/audio/nhAux.cs b/org.niclasundharald.engine/audio/nhAux.cs new file mode 100644 index 0000000..b427a31 --- /dev/null +++ b/org.niclasundharald.engine/audio/nhAux.cs @@ -0,0 +1,24 @@ +using System; +using OpenTK; +using OpenTK.Audio; +using OpenTK.Audio.OpenAL; + + + +namespace nhengine.Audio +{ + public class nhAux + { + + + public nhAux() + { + + + } + + + + + } +} diff --git a/org.niclasundharald.engine/audio/nhBuffers.cs b/org.niclasundharald.engine/audio/nhBuffers.cs new file mode 100644 index 0000000..830f24c --- /dev/null +++ b/org.niclasundharald.engine/audio/nhBuffers.cs @@ -0,0 +1,150 @@ +using System; +using System.IO; +using System.Collections.Generic; +using OpenTK.Audio; +using OpenTK.Audio.OpenAL; +using org.niclasundharald.engine; + + + + +namespace nhengine.Audio +{ + + + public static class nhBuffers + { + + //public static List buffers = new List(); + //public static List buffersNames = new List(); + + public static Dictionary buffers = new Dictionary(); + + private static List _files = new List(); + private static List _searchPaths = new List(); + //private static string filepath; + + + + + + public static void init() + { + + buffers.Clear(); + _files.Clear(); + //_searchPaths = new List(); + _searchPaths.Add("."); + + } + + + public static void addSearchPath(string sPath) + { + _searchPaths.Add(sPath); + } + + public static void loadSound(params string[] sName) + { + foreach(string a in sName) + { + string fullName = FileHelper.findFile(String.Format("{0}.wav", a), _searchPaths.ToArray()); + Console.WriteLine("TEST: " + fullName); + if (fullName != null) + { + Console.WriteLine("Sound found: {0}", fullName); + _createBuffer(fullName, a); + }else + throw new FileNotFoundException("File not found."); + } + + + } + + + private static void _createBuffer(string path, string sName) + { + + Stream stream = File.Open(path, FileMode.Open); + string name = sName; + + if (stream == null) + throw new ArgumentNullException(nameof(stream)); + + using (BinaryReader reader = new BinaryReader(stream)) + { + + + //RIFF HEADER + string signature = new string(reader.ReadChars(4)); + if (signature != "RIFF") + throw new NotSupportedException("File is not RIFF."); + + reader.ReadInt32(); + + string format = new string(reader.ReadChars(4)); + if (format != "WAVE") + throw new NotSupportedException("File is not WAVE."); + + + + //WAVE HEADER + string format_sig = new string(reader.ReadChars(4)); + if (format_sig != "fmt ") + throw new NotSupportedException("File is not supported."); + + + + //Format Chunk Size + reader.ReadInt32(); + //Format + reader.ReadInt16(); + int channels = reader.ReadInt16(); + int sample_rate = reader.ReadInt32(); + //Byterate + reader.ReadInt32(); + reader.ReadInt16(); + //Block allign + int bits = reader.ReadInt16(); + + + + string data_sig = new string(reader.ReadChars(4)); + if (data_sig != "data") + throw new NotSupportedException("File is not supported"); + + //Data chunk Size + reader.ReadInt32(); + + byte[] soundData = reader.ReadBytes((int)reader.BaseStream.Length); + + ALFormat fileFormat; + + switch (channels) + { + case 1: + fileFormat = bits == 8 ? ALFormat.Mono8 : ALFormat.Mono16; + break; + case 2: + fileFormat = bits == 8 ? ALFormat.Stereo8 : ALFormat.Stereo16; + break; + default: throw new NotSupportedException("File is not supported."); + } + + + int buffer = AL.GenBuffer(); + AL.BufferData(buffer, fileFormat, soundData, soundData.Length, sample_rate); + buffers.Add(name, buffer); + + + } + + } + + + + + + + } +} diff --git a/org.niclasundharald.engine/audio/nhListener.cs b/org.niclasundharald.engine/audio/nhListener.cs new file mode 100644 index 0000000..5a567c5 --- /dev/null +++ b/org.niclasundharald.engine/audio/nhListener.cs @@ -0,0 +1,74 @@ +using System; +using OpenTK; +using OpenTK.Audio; +using OpenTK.Audio.OpenAL; + + +namespace nhengine.Audio + +{ + public static class nhListener + { + + private static Vector3 _pos = new Vector3(0.0f, 0.0f, 0.0f); + private static Vector3 _vel = new Vector3(0.0f, 0.0f, 0.0f); + + private static Vector3 _top = new Vector3(0.0f, 0.0f, -1.0f); + private static Vector3 _view = new Vector3(0.0f, 1.0f, 0.0f); + + + + + + + + private static void _setValues() + { + AL.Listener(ALListener3f.Position, _pos.X, _pos.Y, _pos.Z); + AL.Listener(ALListener3f.Velocity, _vel.X, _vel.Y, _vel.Z); + AL.Listener(ALListenerfv.Orientation, ref _view, ref _top); + Console.WriteLine("listener:" + _pos); + } + + + + public static void setListener(Vector3 position, Vector3 velocity, Vector3 orientationUp, Vector3 orientationAt) + { + + _pos = position; + _vel = velocity; + _top = orientationUp; + _view = orientationAt; + + _setValues(); + + } + + public static void setPosition(Vector3 position) + { + _pos = position; + + _setValues(); + } + + public static void setVelocity(Vector3 velocity) + { + _vel = velocity; + + _setValues(); + } + + public static void setTop(Vector3 Top) + { + _top = Top; + _setValues(); + } + + public static void setView(Vector3 View) + { + _view = View; + _setValues(); + } + + } +} diff --git a/org.niclasundharald.engine/audio/nhMixer.cs b/org.niclasundharald.engine/audio/nhMixer.cs new file mode 100644 index 0000000..6ae8f28 --- /dev/null +++ b/org.niclasundharald.engine/audio/nhMixer.cs @@ -0,0 +1,27 @@ +using System; +using System.IO; +using System.Collections.Generic; +using System.Threading; +using OpenTK.Audio; +using OpenTK.Audio.OpenAL; +using System.Windows.Forms; + + +namespace nhengine.Audio +{ + public static class nhMixer + { + + + public static void init(){ + + } + + + + + + + + } +} diff --git a/org.niclasundharald.engine/audio/nhPlayer.cs b/org.niclasundharald.engine/audio/nhPlayer.cs new file mode 100644 index 0000000..030c4dc --- /dev/null +++ b/org.niclasundharald.engine/audio/nhPlayer.cs @@ -0,0 +1,228 @@ +using System; +using System.Threading; +//using System.Threading.Tasks; +using OpenTK; +using OpenTK.Audio; +using OpenTK.Audio.OpenAL; + + + +namespace nhengine.Audio +{ + public class nhPlayer + { + + private int _source = AL.GenSource(); + public int source + { + get + {return _source;} + } + + + private static int _playerNumber; + public int number + { + get + { return _playerNumber;} + } + + //private static EffectsExtension _efx; + //private int _filter; + + + + private float _gain = 1.0f; + public float gain + { + set + { + if (value <= 0.0f) + { + _gain = 0.0f; + } + else if (value >= 1.0f) + { + _gain = 1.0f; + }else + { + _gain = value; + } + } + get + {return _gain;} + } + + public Vector3 position = new Vector3(0.0f, 0.0f, 0.0f); + public Vector3 velocity = new Vector3(0.0f, 0.0f, 0.0f); + //public bool loop = false; + + private float _rollOf = 2.0f; + private float _refDist = 0.0f; + private float _maxDist = 100.0f; + + + private int _state; + + + //private int[] _seqBuffer = { }; + + + + public nhPlayer() + { + + //_filter = _efx.GenFilter(); + //_efx.BindFilterToSource(_source, _filter); + + AL.Source(_source, ALSourcef.RolloffFactor, _rollOf); + AL.Source(_source, ALSourcef.ReferenceDistance, _refDist); + AL.Source(_source, ALSourcef.MaxDistance, _maxDist); + //AL.Source(_source, ALSourcei.EfxDirectFilter, _filter); + //AL.Source(_source, ALSourcei.EfxDirectFilter, ) + + + //_filterEfx.Filter(_filter, EfxFilteri.FilterType, EfxFilterType.Lowpass); + //_efx.Filter(_filter, EfxFilterf.LowpassGainHF, 0.5f); + Interlocked.Increment(ref _playerNumber); + + } + + + //>>>>>>>>>>>>>>>>>METHODS + + public bool state() + { + AL.GetSource(_source, ALGetSourcei.SourceState, out _state); + + if ((ALSourceState)_state == ALSourceState.Playing) + { + return true; + }else if((ALSourceState)_state == ALSourceState.Stopped) + { + return false; + }else + { + return false; + } + + + } + public void play(int buffer = 0, float gain = 1.0f, bool loop = false) + { + + _gain = gain; + AL.Source(_source, ALSourcef.RolloffFactor, _rollOf); + AL.Source(_source, ALSourcef.ReferenceDistance, _refDist); + AL.Source(_source, ALSourcef.MaxDistance, _maxDist); + + if (buffer != 0) + { + AL.Source(_source, ALSourcei.Buffer, buffer); + }else{ + throw new NotSupportedException("Not existing Buffer."); + } + + AL.Source(_source, ALSourceb.Looping, loop); + AL.SourcePlay(_source); + AL.Source(_source, ALSourcef.Gain, _gain); + AL.Source(_source, ALSource3f.Position, position.X, position.Y, position.Z); + AL.Source(_source, ALSource3f.Velocity, velocity.X, velocity.Y, velocity.Z); + + } + + + public void stop() + { + AL.SourceStop(_source); + } + + public void setDistanceAttenuation(float rollOf = 2.0f, float refDistance = 1.0f, float maxDistance = 100.0f) + { + _rollOf = rollOf; + _refDist = refDistance; + _maxDist = maxDistance; + } + + public void setPosition(Vector3 position) + { + this.position = position; + } + + public void setVelocity(Vector3 velocity) + { + this.velocity = velocity; + } + + +/* + + + public void playSeq(int buffer01, int buffer02, int buffer03) + { + _seqBuffer[0] = buffer01; + _seqBuffer[1] = buffer02; + _seqBuffer[2] = buffer03; + + Thread _playThread = new Thread(_playSeq); + _playThread.Start(); + } + + + + + + + private void _playSeq() + { + + + int _buffersToProcess = 3; + + AL.Source(_source, ALSourcei.Buffer, _buffer); + AL.Source(_source, ALSourceb.Looping, loop); + + AL.SourceQueueBuffers(_source, 3, _seqBuffer); + + + AL.SourcePlay(_source); + //_isplaying = true; + + AL.Source(_source, ALSourcef.Gain, _gain); + AL.Source(_source, ALSource3f.Position, position[0], position[1], position[2]); + AL.Source(_source, ALSource3f.Velocity, velocity[0], velocity[1], velocity[2]); + + + do + { + Thread.Sleep(16); + AL.GetSource(_source, ALGetSourcei.SourceState, out _state); + AL.GetSource(_source, ALGetSourcei.BuffersProcessed, out _buffersToProcess); + + while(_buffersToProcess != 0) + { + //AL.SourceUnqueueBuffers(_source, 1, ); + } + + } + while ((ALSourceState)_state == ALSourceState.Playing); + + + AL.SourceStop(_source); + + + } + +*/ + + + public void deletePlayer() + { + AL.DeleteSource(_source); + } + + + + + } +} diff --git a/org.niclasundharald.engine/graphics/GLCamera.cs b/org.niclasundharald.engine/graphics/GLCamera.cs index 60d999e..a855f71 100644 --- a/org.niclasundharald.engine/graphics/GLCamera.cs +++ b/org.niclasundharald.engine/graphics/GLCamera.cs @@ -3,6 +3,7 @@ using OpenTK.Graphics.OpenGL; using OpenTK.Graphics; using OpenTK; +using nhengine.Audio; namespace org.niclasundharald.engine.graphics { @@ -16,6 +17,8 @@ namespace org.niclasundharald.engine.graphics vView, vTop; + + public GLCamera() { fov = MathHelper.PiOver2; @@ -57,18 +60,18 @@ namespace org.niclasundharald.engine.graphics public Vector3 Position { get { return new Vector3(vPosition); } - set { this.vPosition = new Vector3(value); buildMatrices(); } + set { this.vPosition = new Vector3(value); buildMatrices(); nhListener.setPosition(this.vPosition);} } public Vector3 View { get { return new Vector3(vView); } - set { this.vView = new Vector3(value).Normalized(); buildMatrices(); } + set { this.vView = new Vector3(value).Normalized(); buildMatrices(); nhListener.setView(this.vView); } } public Vector3 Top { get { return new Vector3(vTop); } - set { this.vTop = new Vector3(value).Normalized(); buildMatrices(); } + set { this.vTop = new Vector3(value).Normalized(); buildMatrices(); nhListener.setTop(this.vTop);} } private void buildMatrices(){ @@ -132,5 +135,8 @@ namespace org.niclasundharald.engine.graphics return pr; } + + + } } diff --git a/org.niclasundharald.engine/org.niclasundharald.engine.csproj b/org.niclasundharald.engine/org.niclasundharald.engine.csproj index a49b5dc..6cadc95 100644 --- a/org.niclasundharald.engine/org.niclasundharald.engine.csproj +++ b/org.niclasundharald.engine/org.niclasundharald.engine.csproj @@ -34,6 +34,15 @@ ..\packages\OpenTK.GLControl.1.1.2349.61993\lib\NET40\OpenTK.GLControl.dll + + contrib\ImageSharp.dll + + + + + + ..\packages\System.Buffers.4.3.0\lib\netstandard1.1\System.Buffers.dll + @@ -59,6 +68,10 @@ + + + + @@ -67,10 +80,16 @@ + + + + + +