XGL - Open Source GameLibrary

    • Release

    Es gibt 35 Antworten in diesem Thema. Der letzte Beitrag () ist von nikeee13.

      Neue Version:

      Changelog:
      • Implemented subscene system
      • Implemented render and tick index for sorted scene rendering
      • Implemented abstracted sound system
      • Implemented support for looped audio tracks
      • Implemented surround sound system for 2D games


      Download:
      xgl-stable-0.1.11.zip

      Eine der wohl wichtigsten Neuerungen der neuen Version ist der implementierte Sound-Support. Die Benutzung ähnelt dabei der des Rendering-Systems, wobei das Soundsystem über eine zentrale Klasse abläuft. Auch hier wird wieder über Interfaces abstrahiert, man kann also seinen eigenen ISoundProvider implementieren, um z.B. die Soundausgabe über DirectSound o.ä. zu handlen.

      Beispielcode für die simple Wiedergabe einer Wave-Datei:

      Quellcode

      1. SoundManager soundManager = XGL.GetComponent<SoundManager>();
      2. ISound sound = soundManager.CreateSound(@"Resources\sound.wav");
      3. soundManager.Play(sound);


      Beispielcode für zweidimensionalen Surround-Sound:

      Quellcode

      1. SoundManager soundManager = XGL.GetComponent<SoundManager>();
      2. ISound sound = soundManager.CreateSound(@"Resources\sound.wav");
      3. soundManager.Play(sound, new Vector2(-20, -20));


      In diesem Fall wird die Soundquelle als folgender Punkte angegeben:


      Die dunkelrote Raute stellt dabei die Position der Soundquelle dar, der schwarze Kreis die Schallreichweite und der rote Kreis die Position des Spielers. Je weiter der Spieler von der Soundquelle entfernt ist, desto leiser erscheint einem der Sound, wobei er außerhalb der Schallreichweite nicht mehr wahrnehmbar ist.

      Die Implementierung dazu kann man sich gerne anschauen (Locate-Methode):
      github.com/XemioNetwork/GameLi…ary/Sound/SoundManager.cs

      Momentan wird für die interne Implementierung auf WPF zurückgegriffen.

      Sounds als Loop wiedergeben:

      Quellcode

      1. SoundManager soundManager = XGL.GetComponent<SoundManager>();
      2. ISound sound = soundManager.CreateSound(@"Resources\sound.wav");
      3. LoopManager loopManager = XGL.GetComponent<LoopManager>();
      4. loopManager.Register(sound);
      5. sound.Play();


      Um Sounds aus der Loop-Wiedergabe zu entfernen, kann die LoopManager.Remove-Methode verwendet werden. Der LoopManager ist dabei direkt an den Gameloop angebunden.

      MfG
      Für 3D Sound kannst du dir ja mal die Implementierung von SFML zu OpenAL angucken. Die haben es ganz gut hingekriegt. github.com/LaurentGomila/SFML/tree/master/src/SFML/Audio

      Mangafreak1995 schrieb:

      Für 3D Sound kannst du dir ja mal die Implementierung von SFML zu OpenAL angucken. Die haben es ganz gut hingekriegt.


      Wozu? XGL ist eine 2D game library, was hat 3D Sound in einer 2D Library zu suchen?

      MfG
      Ich meinte damit generell orientierten Sound.
      Genau das wird doch bereits über den SoundManager bereitgestellt, hast du meinen Beitrag dazu nicht gelesen?

      MfG
      Doch und ich habe es gepostet besonders weil du ihn geschrieben hast :P Deine Anmerkung, dass das ganze zZ über WPF implementiert wurde(n musste) machte mich stutzig, dass man WPF dafür nutzen muss und deswegen hab ich halt ne Option gepostet für nen anderen Sound"Renderer".
      Man muss dafür gar nichts nutzen, wie es intern funktioniert kümmert den Endnutzer ja wenig und da WPF in .NET 4.0 integriert ist bzw. nur der PresentationCore referenziert wird, ist das denke ich kein großes Problem.

      Es gibt in .NET keine mir bekannte Möglichkeit, ohne externe Libraries Features wie Panning oder Volume Control zu implementieren und mehrere Sounds gleichzeitig wiederzugeben, daher über die PresentationCore.dll ;)

      Dass du mir C++ Quelltext schickst in schön und gut, soweit ich das erkennen kann verwenden die allerdings OpenAL, wodurch eine weitere Abhängigkeit für das Projekt enstehen würde.

      MfG
      DirectSound kannste machen wobei jedoch erneut eine zusätzliche Abhängigkeit entstehen würde. Außerdem sind die Comimporte für DirectSound auch immer so eine Sache. Microsoft hat es leider versäumt die Interfaces STA- und MTA-Threadmodel kompatibel zu machen. Mit herkömmlichen Comimporten wirste also nicht glücklich, denn das Zeug fliegt dir schon sehr sehr früh um die Ohren. Außerdem unterstützt DirectSound wie alle anderen Schnittstellen "nur" Rohdaten in Form von PCM und dort ist es Treiberabhängig ob 16 oder nur 8 bit und stero oder nur mono unterstützt wird. Somit müsste man für Formate wie MP3,... extra decoder programmieren,... und ich denke darauf liegt bei der Lib nicht der Focus. Alleine schon um das Problem mit den Comimporten zu lösen musste entweder auf C++/CLI zurückgreifen oder einen Postcompiler schreiben(so habe ich es bei meiner Audiolib gelöst). Und das wiederum erzeugt noch mehr Code und Overhead für eine kleine Gamelib. Muss sagen mir gefällt die Lib recht gut und solange es mit PresentationCore auch gut und performant läuft reicht es ja.


      Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.
      Moin,

      ich habe mich mal (mehr oder weniger) rangesetzt und einen DirectX/Direct2D-Renderer programmiert, der auf SharpDX basiert.
      Systemvoraussetzungen ist das .Net Framework 4.0 und DirectX 10.0.

      Im Gegensatz zum XNA-Renderer von Krissel beherrscht meiner auch den Großteil vom GeometryProvider.

      Bisher nicht implementiert ist:
      • Farbton Veränderungen über RenderManager.Tint(), wenn jemand weiß, wie man das macht, bau ich das auch ein
      • GeometryProvider.FillPolygon() (Funktioniert nicht warum auch immer)
      • Arc's und Pie's (Wenn ich Zeit und Lust habe, kümmer ich mich mal darum)
      • Texture-Brushes
      • Saubere Implementierung vom GradientBrush, bisher kann man den Winkel nur indirekt über die Breite und Höhe bestimmen, außerdem wiederholt sich der Brush nicht


      Da XGL ja eigentlich für Pixel-Spiele gedacht ist, ich aber Anti-Aliasing brauchte, hab ich noch ne Anti-Aliasing Einstellung mit reingepackt:

      C-Quellcode

      1. new SharpDXGraphicsInitializer(bool enableAntiAliasing);


      Der Source-Code ist mit in der angehängten ZIP-Datei mit drinnen und ich würde mich sehr freuen, wenn jemand der sich mit DirectX auskennt, mal drüber schauen könnte :)
      Die Knackpunkte finden sich in SharpDXRenderManager.cs und Geometry\SharpDXGeometryProvider.cs.

      ... Und am Schluss nochmal ein großes Dankeschön an Krissel, der mir unzählige Fragen zur Spieleprogrammierung beantwortet hat :)

      MfG,
      Trudi
      Dateien
      • XGL.SharpDX.zip

        (388,05 kB, 85 mal heruntergeladen, zuletzt: )

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Trudi“ ()

      Würde wohl nen GL-Renderer anbieten hab aber zZ kein VS drauf. Wie sieht das mit nativen C++ aus? :D

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Mangafreak1995“ ()

      Wollt grad sagen wenn jemand OGL implementieren würde könnte man sogar darüber nachdenken das auch über Mono laufen zu lassen.
      Könnte außerdem versuchen den Vorschlag mit DirectSound etc. zu implementieren.


      Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.

      Update 14.08.2013

      Da wir seit gut 5 Monaten hier kein Update mehr gepostet haben und innerhalb der letzten Monate relativ konstant an der XGL gearbeitet wurde, werde ich versuchen, alle Features und Änderungen mithilfe der Namespaces in einen Post zusammenzufassen.

      Namespace Änderungen
      Spoiler anzeigen
      Components
      Der ComponentManager, das Herzstück der XGL, kann nun hinzugefügte Komponenten nach Interfaces auflösen. Interfaces, die mit dem AbstractComponent Attribut gekennzeichnet wurden, werden ebenfalls als aufzulösender Typ dem Komponentensystem hinzugefügt.

      Beispiel:

      PHP-Quellcode

      1. [AbstractComponent]
      2. public interface ITestComponent : IComponent
      3. {
      4. void DoSomething();
      5. }
      6. public class MyTestComponent : ITestComponent
      7. {
      8. public void DoSomething()
      9. {
      10. Console.WriteLine("Hallo Welt");
      11. }
      12. }


      PHP-Quellcode

      1. XGL.Components.Add(new MyTestComponent());
      2. var testComponent1 = XGL.Components.Get<ITestComponent>();
      3. var testComponent2 = XGL.Components.Get<MyTestComponent>(); //Selbe Instanz wie testComponent1


      Außerdem wurden die IValueProvider entfernt, die in der alten Version der XGL zum Halten von Werten verwendet wurden.

      Content
      Der ContentManager ist ähnlich nutzbar wie Microsofts XNA ContentManager. Mithilfe unserer Content.Load<T> Methode können Datentypen über das Serialisierungsframework aufgelöst und geladen werden. Der ContentManager berücksichtigt dabei das aktuelle IFileSystem, d.H. Daten müssen nicht zwangsläufig von der Festplatte kommen.

      PHP-Quellcode

      1. ITexture texture = this.Content.Load<ITexture>("./Resources/sprite.png");


      .FileSystem
      Die XGL bietet unterschiedliche Dateisystemabstraktionen, unter anderem für virtuelle Dateisysteme, die ihren Content aus einer Datei laden können. Geplant sind außerdem IFileSystem Implementierungen für einen Zip-Ordner und via FTP.

      .Serialization
      Umfangreiches Serialisierungsframework, das über den ContentManager aufgelöst werden kann. Jeder Serializer ist einem Type zugeordnet. In diesem Namespace befinden sich Serializer für alle Basisdatentypen.

      .Texts
      Vereinfachte Serialisierung von Texten.

      Entities
      Komponentenbasiertes Entity-System. Der Entities Namespace bietet außerdem Zugriff auf DataContainer und EntityComponents, wobei DataContainer serialisierbare Daten einer Entity darstellen und EntityComponents die Logik einer Entity beschreiben. Alle DataContainer werden dabei automatisch serialisiert.

      Events
      Im Vergleich zur Vorgängerversion hat sich die Performance des Eventsystems um einiges verbessert. Im Zuge unserer Kollisionsimplementierung wurde auch das Eventsystem geupdated, da der alte EventManager zu langsam für die unzähligen Events des Kollisionssystems war.

      PHP-Quellcode

      1. var eventManager = XGL.Components.Get<EventManager>();
      2. eventManager.Publish(new TestEvent());


      Game
      .Scenes
      GameScene Management. Das neue System unterstützt unter anderem hierarchische Verschachtelung von Szenen, Tick und Render Indizes.

      .Timing
      Der Timing Namespace stellt Klassen wie den GameLoop und eine GameTime Klasse bereit, die anders als in XNA für die Handhabung virtueller Tage bzw. Zeitsimulationen eines Spiels zuständig ist.

      Input
      Anders als in vielen anderen Gamelibraries handhaben wir Mauseingaben ebenfalls als Key, d.H. LeftMouse und RightMouse sind ebenfalls Mitglieder unseres Key Enums. Dabei bietet der InputManager Support für Mehrspielerinputs, die unter anderem über unsere Syncput Library auch über das Netzwerk kommen können und so einfach Multiplayer Games möglich machen. Der InputManager hält zusätzlich IInputListener Instanzen und unterstützt somit verschiedene Devices, eine externe GamePad Library bzw. Kinect Support wären damit problemlos machbar.

      PHP-Quellcode

      1. InputManager inputManager = XGL.Components.Get<InputManager>();
      2. PlayerInput playerInput = inputManager.LocalInput; //für weitere Inputs => inputManager[playerIndex]
      3. if (playerInput.IsKeyPressed(Keys.Enter))
      4. {
      5. }


      Localization
      Namespace für mehrsprachige Anwendungen.

      Math
      Namespace für allgemeine mathematische- und Vektoroperationen.

      .Collision
      Die XGL unterstützt in der neuen Version lediglich ein CollisionGrid, das auf dem Spatial Hash Grid Prinzip basiert und selbst bei über 1000 Entities noch extrem performant läuft.

      Network
      Client und Server wurden mittlerweile abstrahiert, sodass unter anderem eigene Implementierungen möglich sind. Das Netzwerksystem ist paketbasiert, wobei Client und Server ihre eigene Logik über die IClientLogic und IServerLogic Schnittstellen implementieren können. Pakete werden automatisch serialisiert und es gibt im Kern der Library bereits einen Mechanismus zur Bestimmung der Latenz zwischen Clients und Server.

      Zudem sind sämtliche Protokolle abstrahiert, d.H. um von TCP auf ein beliebiges anderes Protokoll umzusteigen wird lediglich eine Zeile Code benötigt, unter anderem bietet die XGL auch ein LocalProtocol, das für Singleplayerspiele mit Netzwerkcode genutzt werden kann.

      Plugins
      Der Plugins Namespace bietet umfangreiche Möglichkeiten zur Erweiterung der XGL. Unter anderem basiert die gesamte Library auf dem ImplementationManager, der Interfaces mit einer eindeutigen Id in eine Instanz auflösen kann. Sämtliche Abstrahierungen können ohne Probleme durch externe Libraries erweitert werden, mit ILibraryInitializern kann sich eine externe Library zusätzlich an unsere Event- und Komponentensysteme anmelden. Ein Beispiel dafür ist unser Script System: Alle durch das ICommand Interface abstrahierten Commands können sich auch in externen Libraries befinden.

      PHP-Quellcode

      1. ImplementationManager implementations = XGL.Components.Get<ImplementationManager>();
      2. ICommand command = implementations.Get<string, ICommand>("TestCommand"); //Wird auch aus externen Assemblies aufgelöst.


      Rendering
      Umfangreiche Abstrahierung unseres Rendering-Systems. Momentan gibt es einen GDI+ und XNA Renderer, die mit je einer Codezeile ausgetauscht werden können. Das Rendersystem unterstützt zudem Spritesheets, Animationen, Geometrieoperationen und RenderTargets.

      Script
      Das Script-System basiert auf C# und bedient sich somit der gesamten Funktionsfähigkeit des .NET Frameworks. Das besondere daran ist, dass Commands die Scriptausführung unterbrechen und vom Tick des GameLoops abhängig machen. Gedacht ist diese Funktionalität zur stabilen Ausführung von Scripts, ohne das Spiel dabei für längere Zeit zu unterbrechen oder auf Multithreading zurückzugreifen.

      Sound
      Sound Abstrahierung.


      Configuration
      Die XGL lässt sich in der neuen Version zudem fluent konfigurieren:

      PHP-Quellcode

      1. MainForm mainForm = new MainForm();
      2. mainForm.ClientSize = new Size(800, 600);
      3. var config = XGL.Configure()
      4. .FrameRate(60)
      5. .BackBuffer(800, 600)
      6. .DefaultComponents()
      7. .DefaultInput()
      8. .Components(new MyComponent())
      9. .Graphics<GDIGraphicsInitializer>() //wahlweise XnaGraphicsInitializer
      10. .Scenes(new MainScene(), new DebugOverlay())
      11. .BuildConfiguration();
      12. XGL.Run(mainForm, config);


      NuGet Packages
      Alle Libraries und Erweiterungen zur XGL gibt es jetzt als NuGet Paket.

      Trello Project Management
      Features, Vorschläge und geplante Änderungen dokumentieren und planen wir in unserem Trello Projekt. Sollte also jemand Lust haben, zu sehen, was wir für die XGL geplant haben, einfach reinschauen. Votes und Kommentare sind auch für Gäste aktiviert.

      Xemio Syncput
      Syncput ist eine von uns als Erweiterung für die XGL entwickelte Netzwerkbibliothek, die Inputsynchronisation aller teilnehmenden Spieler ermöglicht. Dabei können alle Spieler eine Lobby betreten, der Host das Spiel starten und ohne, dass der Entwickler seinen Code auf netzwerktauglichkeit ausgelegt hat läuft in allen Clients parallel die selbe Simulation ab. Das System ist primär auf Gameplay über LAN Netzwerke ausgelegt und für Internetspiele eher ungeeignet.





      Der Sourcecode für Syncput befindet sich in unserem Contrib Projekt.

      Open Source
      Der gesamte Sourcecode der XGL kann hier eingesehen werden. Bei Verwendung bitte auf unsere Lizenz achten. Alle Erweiterungen der XGL befinden sich ebenfalls im Contrib Projekt.

      Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Krissel095“ ()

      Sehr schöne Neuerungen! Das hier stört mich aber etwas:

      Krissel095 schrieb:

      C-Quellcode

      1. var config = XGL.Configure()
      2. .FrameRate(60)
      3. .BackBuffer(800, 600)
      4. .DefaultComponents()
      5. .DefaultInput()
      6. .Components(new MyComponent())
      7. .Graphics<GDIGraphicsInitializer>() //wahlweise XnaGraphicsInitializer
      8. .Scenes(new MainScene(), new DebugOverlay())
      9. .BuildConfiguration();

      "Chaining" is in .NET eher unüblich. Mir ist nur eine Stelle im .NET Framework bekannt, bei der das verwendet wurde, nämlich beim StingBuilder(.Append()). Das dient aber wohl nur der Übersichtlichkeit.
      Dieses Chaining ist eher ein gängiges Pattern aus z. B. JavaScript. Dort macht man das wahrscheinlich, da man bisher keine Getter und Setter von Eigenschaften hat (ja, ich weiß, da gibt es mittlerweile auch einen Standard zu).

      In .NET würde man wohl einfach die Eigenschaften setzen. Die kann man ja auch gleich via Objet Initializer direkt nach dem Konstruktor setzen. Würde dann so aussehen:

      C-Quellcode

      1. var config = new XGL.Confuguration()
      2. {
      3. FrameRate = 60,
      4. BackBuffer = new Buffer(800, 600),
      5. Scenes = new List<Scene>(new MainScene(), new DebugOverlay())
      6. }
      Von meinem iPhone gesendet

      nikeee13 schrieb:

      "Chaining" is in .NET eher unüblich. Mir ist nur eine Stelle im .NET Framework bekannt, bei der das verwendet wurde, nämlich beim StingBuilder(.Append()). Das dient aber wohl nur der Übersichtlichkeit.
      Das würde ich jetzt so nicht verallgemeinern, diese "Fluent" APIs sind mittlerweile ziemlicher Trend in .NET.
      Ein weiteres Beispiel wo das auch im .NET-Framework benutzt wird ist z. B. LINQ.

      PHP-Quellcode

      1. myList.Where(f => f.Name.StartsWith("VB")).Select(f => f.Name).Count();

      Aber das schöne an unserer ganzen Konfiguration ist, dass die Fluent-Konfig nur eine Möglichkeit ist die XGL zu konfigurieren.
      Als zweite Möglichkeit kann man noch eine eigene Klasse erstellen, die von "Configuration" erbt, und dann die entsprechenden Properties setzt.
      Diese Konfiguration gibt man dann einfach als generischer Typ bei XGL.Run an:

      PHP-Quellcode

      1. XGL.Run<MyConfiguration>(new MainWindow());
      Stimmt - an die LINQ habe ich nicht gedacht. Das ist dort allerdings auch wohl nur so implementiert, damit der Compiler die SQL-Mäßigen-LINQ-Querys vernünftig compilen kann. Wohlgemerkt handelt es sich dort auch um Extension-Methods, die nicht einfach this returnen, sondern eine veränderte bzw. "gefiltete" Instanz der Eingabe.
      Hab ich noch was übersehen? Wenn nein, gibt es ganze 2 Anwendungsfälle im .NET Framework. :P

      Aber hey - das ist Geschmackssache. Ich kenne keine MS-Guideline, die sowas explizit erwünscht oder verbietet. Lässt sich also drüber streiten.
      Von meinem iPhone gesendet