[Projekt] OpenWorld.Engine

Hier könnt ihr euch selbst, eure Homepage, euren Entwicklerstammtisch, Termine oder eure Projekte vorstellen.
Forumsregeln
Bitte Präfixe benutzen. Das Präfix "[Projekt]" bewirkt die Aufnahme von Bildern aus den Beiträgen des Themenerstellers in den Showroom. Alle Bilder aus dem Thema Showroom erscheinen ebenfalls im Showroom auf der Frontpage. Es werden nur Bilder berücksichtigt, die entweder mit dem attachement- oder dem img-BBCode im Beitrag angezeigt werden.

Die Bildersammelfunktion muss manuell ausgeführt werden, die URL dazu und weitere Details zum Showroom sind hier zu finden.

This forum is primarily intended for German-language video game developers. Please don't post promotional information targeted at end users.
Antworten
Benutzeravatar
xq
Establishment
Beiträge: 1581
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

[Projekt] OpenWorld.Engine

Beitrag von xq »

Hallo!

Ich habe die letzten zwei Wochen damit verbracht, eine Game-Engine zu programmieren. Das Resultat:

OpenWorld.Engine

Die Engine wurde in C# mit OpenTK entwickelt und soll für mich persönlich ein Ersatz zu XNA darstellen. Daher orientiert sich die API der Engine auch stark am XNA Framework 4.0.

Was kann die Engine?
  • Vereinfachtes Handling von OpenGL3.3 durch Modelle, Texturen und verschiedene Buffer-Objekte
  • PostProcessing Pipelines
  • AssetManager (Model-Import mit Assimp.Net)
  • GUI mit wenigen Controls, aber einigen Events (orientiert sich an Windows.Forms)
  • Theoretische Multiplatform-Fähigkeit für Linux und Mac
  • Source-Code vollständig mit Dokumentationskommentaren versehen und erfüllt alle Microsoft-Code-Analyse-Regeln
  • Demo-Anwendungen
Kann man sich das anschauen?
Wer sich die Engine (in einem aktuell gehaltenen Repo) anschauen möchte, kann sich das Projekt gerne auf GitHub forken:
https://github.com/MasterQ32/OpenWorld.Engine

Was die Engine leistet:
Custom shader (Night Sky Rendering a'la Krishty und Athomspheric Scattering):
Bild

Post-Processing:
Bild

GUI-System:
Bild
Was bringt die Zukunft?
  • Sound (3D und Musik)
  • Szenen-Management mit einfachen Komponenten-basierten Entitäten (ähnlich Unity3D)
  • Verbesserter Asset Manager
  • Demos
  • Dokumentation nicht nur in Doku-Kommentaren
  • Was hier noch so an Wünschen anfällt, die sinnvoll in die Engine passen.
Warum machst du dir eigentlich den Aufwand?
Unzufriedenheit mit anderen Engines. Es gibt nicht viele gute kostenlose (und mir bekannte) Game-Engines, die modern sind, aber auch dem Coder die Freiheit bieten, die er (in dem Fall vorallem ich) möchte.
Außerdem war mir XNA irgendwann zu blöd, weil man ständig irgendwelche doofe Workarounds machen musste, um zum Ziel zu kommen. Zudem hab ich so ein schönes Projekt, an dem man immer irgendwas machen kann.

Kann ich mitmachen?
Ja, gerne! Ich möchte aber die Code-Qualität der Engine auf einem hohen Niveau halten, ihr solltet also Erfahrung mit C#, VisualStudio und OpenGL haben.

Gibts noch irgendwas?
Probiert die Engine doch mal aus! Übt Kritik und Lob, aber übertreibt es nicht.
Und wenn ihr wollt, baut doch mal ein Spiel damit!
Ich hoffe ihr habt eure Freude an der Engine.

Grüße
Felix

EDIT 1:
Habe jetzt 3 einfache Demos (BasicSetup, Gui und 3D) hinzugefügt.
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…

Programmiert viel in ⚡️Zig⚡️ und nervt Leute damit.
Benutzeravatar
xq
Establishment
Beiträge: 1581
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

Re: [Projekt] OpenWorld.Engine

Beitrag von xq »

*Push*

Update: Das Gui System hat ein paar neue Controls und Rendering-Verbesserungen abbekommen, außerdem habe ich angefangen, ein Szenen-Management zu implementieren.
Außerdem gibt es mittlerweile sogar 3 Demos ;)

Grüße
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…

Programmiert viel in ⚡️Zig⚡️ und nervt Leute damit.
Benutzeravatar
Schrompf
Moderator
Beiträge: 4859
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: [Projekt] OpenWorld.Engine

Beitrag von Schrompf »

Schönes Hobbyprojekt, an dem man immer rumbasteln kann. Viel Spaß damit!
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
xq
Establishment
Beiträge: 1581
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

Re: [Projekt] OpenWorld.Engine

Beitrag von xq »

Vielen Dank!

Hier mal eine kleine Updateinformation:
Sound ist in Entwicklung, Einfaches Szenenmanagement mit einem Stub-Rendering ist implementiert. Man kann Objekte mit Lua scripten. Der AssetManager wurde komplett überarbeitet und kann nun aus verschiedensten Quellen Assets laden (Dateisystem, Zip-Dateien, Webserver, ...). Die GUI hat mittlerweile einen guten Satz an Controls bekommen, aber es fehlen immer noch einige. Zudem gibt es jetzt schon mal den Beginn einer Dokumentation und verschiedene, einfach gehaltene Demos.
Als nächstes steht ein Deferred Renderer und die Integration einer Physik-Engine (geplant ist Jitter) an.

Grüße
Felix
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…

Programmiert viel in ⚡️Zig⚡️ und nervt Leute damit.
Benutzeravatar
xq
Establishment
Beiträge: 1581
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

Re: [Projekt] OpenWorld.Engine

Beitrag von xq »

Lange Zeit keine Updates. Hatte in letzter Zeit leider wenig freie Zeit für die Engine, aber die Planung ist noch im Gange. Ich werde die Engine nochmal im Kern umbauen, sodass das ganze dann multi-threaded ist und man Asset-Loading und andere Sachen nebenläufig programmieren kann.
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…

Programmiert viel in ⚡️Zig⚡️ und nervt Leute damit.
Benutzeravatar
xq
Establishment
Beiträge: 1581
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

Re: [Projekt] OpenWorld.Engine

Beitrag von xq »

So, schon wieder fast zwei Monate rum. Das Projekt ist nicht tot, ich komme nur selten dazu. Hier mal ein aktueller Screenshot meines Spiels/dessen Editor:

Die Würfel und das Charactermodell werden via Drag'n'Drop erstellt, in dem man sie einfach aus der Liste links auf das Level zieht. Die gesamte UI wurde mit HTML5/Javascript implementiert und wird mit Awesomium gerendert. Die UI kann jederzeit vom Spiel modifiziert werden oder Callbacks an das Spiel schicken. Sehr angenehm, damit zu arbeiten, vorallem weil man das ganze einfach in Chrome debuggen und testen kann.

Bild
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…

Programmiert viel in ⚡️Zig⚡️ und nervt Leute damit.
Benutzeravatar
xq
Establishment
Beiträge: 1581
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

Re: [Projekt] OpenWorld.Engine

Beitrag von xq »

Soo, wieder mal ein Update:

Bloom ist implementiert:
Bild

Zudem habe ich die ganzen Shader-Sachen überarbeitet, es ist jetzt wieder wesentlich einfach, eigene Custom-Shader in das System zu integrieren. Noch ein paar Sachen fehlen natürlich noch, aber bald sollte auch Skinning möchlich sein.

Grüße
Felix
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…

Programmiert viel in ⚡️Zig⚡️ und nervt Leute damit.
Benutzeravatar
xq
Establishment
Beiträge: 1581
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

Re: [Projekt] OpenWorld.Engine

Beitrag von xq »

So, heute mal ein paar Worte zum neuen Shader-System:

Da die Engine zur Zeit noch sehr spärlich dokumentiert ist, hier mal ein kleines "Tutorial":

Schritt 1: Demo-Projekt anlegen
Für das Demo-Projekt verwendet man folgenden Sourcecode:

Code: Alles auswählen

using OpenTK;
using OpenWorld.Engine;
using OpenWorld.Engine.SceneManagement;

namespace OpenWorld.Demo.ShaderDemo
{
	class ShaderDemo : Game
	{
		static void Main(string[] args)
		{
			// Just create an instance and run it...
			new ShaderDemo().Run();
		}

		// Some global fields
		Scene scene;
		SceneRenderer renderer;
		CompositeCamera camera;

		protected override PresentationParameters GetPresentationParameters()
		{
			var p = base.GetPresentationParameters();
			// Change the demo window title.
			p.Title = "Shader Demo";
			return p;
		}

		protected override void OnLoad()
		{
			// Basic setup

			Assets.Sources.Add(new FileSystemAssetSource("./Assets/"));

			this.scene = new Scene();

			this.renderer = new DeferredRenderer();
			this.renderer.Sky = new ColorSky() { Color = Color.DeepSkyBlue };

			this.camera = new CompositeCamera();
			this.camera.ProjectionMatrixSource = new Perspective(75);
			this.camera.ViewMatrixSource = new LookAt(
				new Vector3(-4, 2.5f, -2.5f),
				new Vector3(0, 0.5f, 0));

			var root = this.scene.Root;
			var cube = Model.CreateCube(1.0f);

			// Create a default cube
			var @default = new SceneNode();
			@default.Components.Add<Renderer>().Model = cube;
			@default.Parent = root;

			// Create a cube with emissive lighting (deferred renderer will apply bloom)
			var mtl = new SceneNode();
			mtl.Components.Add<Renderer>().Model = cube;
			mtl.Transform.LocalPosition = new Vector3(0.5f, 0.1f, 1.6f);
			mtl.Material = new Material()
			{
				Emissive = Color.Lime
			};
			mtl.Parent = root;

			// Create a node with a custom shader on it
			var shd = new SceneNode();
			shd.Components.Add<Renderer>().Model = cube;
			shd.Transform.LocalPosition = new Vector3(-0.5f, 0.1f, -1.6f);
			shd.Material = new NoiseMaterial()
			{
				// Load our custom noise shader here:
				Shader = Assets.Load<Shader>("noise")
			};
			shd.Parent = root;
		}

		protected override void OnUpdate(GameTime time)
		{
			this.scene.Update(time);
		}

		protected override void OnDrawPreState(GameTime time)
		{
			FrameBuffer.Clear();
			this.scene.Draw(this.camera, this.renderer, time);
		}
	}
}
Der Code sollte selbsterklärend sein, also keine weiteren Worte dazu...

Schritt 2: Shader erstellen
Um einen Custom-Shader zu schreiben, verwendet man Shader-Z (fragt nicht nach dem Namen, ich habe einen gebraucht), eine Sprache ähnlich zu Unitys ShaderLab, aber wesentlich flexibler.
Shader-Z ist ein Lua-Script, welches Shadercode initalisiert. Man könnte also auch beliebige Scripte darin ausführen, welche Shader-Code erzeugen oder laden...

Shader-Z bietet eine Menge Möglichkeiten, schnell und einfach eigene Shader zu entwickeln, welche sich vollständig in die Engine integrieren lassen.
Der Beispielshader hier zeigt einen Noise-Shader, welcher eine leuchtende, wabernde Oberfläche erzeugt:

Code: Alles auswählen

shader:include("time")
shader:include("noise3d");

shader:addDefault("vertex")

shader:add
{
	type = "fragment",
	source = 
[[
	out vec4 color;
	in vec3 position;

	void main()
	{
		float f = 
			0.5f + 0.5f * snoise3d(
				5.0f * position +
				1.0f * vec3(sin(timeTotal), 0.0f, sin(1.1f * timeTotal + 0.3f)) + 
				0.3f * timeTotal * vec3(1.0f, 0.8f, -0.7f));
		if(f < 0.6f)
			color.rgb = vec3(1.0f, 1.0f, 0.0f); // Base yellow
		else
			color.rgb = vec3(100.0f, 0.0f, 0.0f); // "Hot" red
		color.a = 1.0f;
	}
]]
}
Shader-Z stellt eine globale Variable "shader" im Script bereit, welche dazu verwendet wird, den Shader zu initialisieren und zu erstellen.
shader:include bindet eine Include-Datei in das Shader-Script ein, welche am Anfang zum Shader hinzugefügt wird.
Die Include-Dateien können Engine-Intern (mesh, transform, material, ...) sein oder aber wie hier eine externe Include-Datei namens "noise3d".
Externe Dateien werden über das Asset-System geladen und benötigen die Dateiendung .shi
shader:addDefault fügt einen der Default-Shader hinzu, hier der Vertex-Shader.
Die Default-Shader sind optimiert für die Benutzung mit der Engine und ersparen einem die eigene Implementierung.
shader:add fügt dem Shader ein Fragment hinzu.
Ein Shader-Fragment ist ein Teil eines Shaders, welches nachher zur bedingten Shader-Kompilierung verwendet wird. In diesem Beispiel definieren wir nur ein Fragment für den Fragment-Shader, es sind aber Fragmente für alle normalen Shadertypen (vertex, tess-control, tess-eval, geometry und fragment) verfügbar.
Ein Fragment kann zusätzlich für eine Klasse definiert werden. Die Engine wählt dann je nach Klasse die passenden Fragmente und setzt sich so einen passenden Shader zusammen. So lassen sich für eigene Renderer sehr leicht Spezialfälle hinzufügen (Es gibt die Standardklasse "DeferredRenderer", welche für den internen deferred Renderer verwendet werden kann).

Zudem kann man beim Selektieren eines Shaders in der Engine auswählen, ob man Shader-Fragmente überschreiben möchte. So kann man zum Beispiel sehr einfach Shadowmapping implementieren, da man keinen speziellen Shader dafür schreibt, sondern nur den Fragment-Shader überschreibt, welcher dann die Tiefeninformationen in das RT schreibt.
Es gibt folgende Möglichkeiten, einen Shader zu selektieren:

Code: Alles auswählen

// Load a shader
shader = Assets.LoadSync<Shader>("myCustomShader");

// Select the default shader:
CompiledShader cs = shader.Select();

// Select the shader with class modifier:
CompiledShader cs = shader.Select("DeferredRenderer");

// Create a custom fragment shader
var geometryPixelShader = new ShaderFragment(ShaderType.FragmentShader, geomPixSource);

// Select the shader with class and override the pixel shader.
CompiledShader cs = shader.Select("DeferredRenderer", geometryPixelShader);

// Calls glUseProgram for the compiled shader.
cs.Bind();
Zudem unterstützt die Engine ein sehr bequemes System, um Uniforms an die Shader zu passen:

Code: Alles auswählen

var obj = new Material(); // Create some demo object
cs.BindUniform(obj); // Bind all uniforms defined in obj to the shader.
Das Codeschnipsel erzeugt ein Material (Source Code), welches verschiedene, via Attribut definierte Uniforms direkt in den Shader passed. Nicht vorhandene Uniforms werden ignoriert.
Für Texture-Uniforms kann man zudem noch eine Default-Textur (Farbe) angeben, welche anstelle der Textur-Fehlt-Textur gebunden wird.

Man kann aber natürlich Uniforms auch manuell setzen:

Code: Alles auswählen

cs["myUniform"].SetValue(myValue);
Wenn für ein Uniform ein Wert gesetzt wird, überprüft die Engine dessen Typ und lässt nur Uniforms vom passenden Typ zu. Heißt, man kann einem Sampler-Objekt nicht einen float-Wert zuweisen und vice versa.

Falls ihr Fragen habt, fragt!

Hier noch ein recht unhübsches Bild des Shaders/Scripts oben in Aktion:
Bild

Grüße
Felix
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…

Programmiert viel in ⚡️Zig⚡️ und nervt Leute damit.
Benutzeravatar
ponx
Establishment
Beiträge: 217
Registriert: 04.05.2008, 12:52
Echter Name: Andy Ponx
Wohnort: Hamburg
Kontaktdaten:

Re: [Projekt] OpenWorld.Engine

Beitrag von ponx »

hey Felix, ich versteh zwar nur die Hälfte, aber sieht toll aus!
Benutzeravatar
xq
Establishment
Beiträge: 1581
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

Re: [Projekt] OpenWorld.Engine

Beitrag von xq »

Ist das jetzt ein Lob oder Kritik? :D
Und meine Frage ist jetzt: Sieht der Screenshot oder der Source toll aus?
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…

Programmiert viel in ⚡️Zig⚡️ und nervt Leute damit.
Benutzeravatar
ponx
Establishment
Beiträge: 217
Registriert: 04.05.2008, 12:52
Echter Name: Andy Ponx
Wohnort: Hamburg
Kontaktdaten:

Re: [Projekt] OpenWorld.Engine

Beitrag von ponx »

das war Lob! :) Ich mag den Glow-Effekt, sowas hätte ich beim Aquarium gerne gehabt, bei der Score-Anzeige. Zum Source-Code: Den hab ich nur kurz überflogen und reicht, um mich als Shader-Noob ordentlich zu beeindrucken.
Antworten