Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Di Mär 19, 2024 08:42

Foren-Übersicht » Sonstiges » Projekte
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 50 Beiträge ]  Gehe zu Seite Vorherige  1, 2, 3, 4  Nächste
Autor Nachricht
 Betreff des Beitrags: Re: [Game] Gael
BeitragVerfasst: Di Jun 22, 2010 22:19 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Mär 09, 2005 15:54
Beiträge: 372
Wohnort: München
Programmiersprache: Delphi, C#, FPC
Ich nochmal ;-)

Ich wollte nochmal den aktuellen Stand präsentieren - diesmal nicht zum Lesen, sondern zum selber ausprobieren. Insgesamt hat sich zu der letzten TechDemo nicht viel verändert. Die Schuss-Decals sind mit drinnen sowie eine verbesserte Steuerung. Man hat jetzt nun noch 10% Air-Control (man kann also nicht mehr in der Luft stehen bleiben), und es gibt den seit UT2003 bekannten Double-Jump.

Bei den Optionen hat sich auch was geändert: der Forward-Renderer ist nun endgültig rausgeflogen. Stattdessen findet man jetzt einen SSAO-Checkbox, die vor allem Performance frisst, die Qualität jedoch nicht besonders steigert. Daher werde ich das später wahrscheinlich auch wieder ausnehmen.

Bevor ich das noch vergesse: ich habe das Rendering der Lichter im Deferred-Renderer komplett überarbeitet. Das ganze sollte nun um einiges schneller laufen als bisher: jetzt läuft bei mir auf meinem Laptop die Map mit ca. 20 Lichtern und 10 Bots immer noch flüssig.

Statt jedes mal die Requirements sowie die Steuerung erneut hinzuschreiben, habe ich das nun in die Readme ausgelagert. Das sollte mir nun künftig etwas Arbeit ersparen ;-).

Der Download-Link befindet sich auf dieser Seite (ca. 11 MB)

Gruß
David

PS: diesmal habe ich die Echse endlich mal umbenannt ;-)

_________________
Aktuelles Projekt: Gael - Development Blog
Website: LightBlackSoft.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: [Game] Gael
BeitragVerfasst: Di Jul 06, 2010 21:07 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Mär 09, 2005 15:54
Beiträge: 372
Wohnort: München
Programmiersprache: Delphi, C#, FPC
Hallo,

Gleitpfad bei Kollisionserkennung
Es haben ja einige zurecht bemängelt, dass man viel zu häufig stecken bleibt und nicht immer an Gegenständen entlang gleitet. Im Moment bin ich dabei, dieses Problem zu lösen. Es geht mittlerweile schon um einiges besser, jedoch ist es noch nicht ganz perfekt. Zudem gibt jetzt zum Teil wieder andere Probleme (man bleibt im Boden stecken, man kann nicht mehr aufstehen, ...), aber das werde ich schon irgendwie hinbekommen.

Verbesserung der Funken
Die bisherigen Funken waren ja nicht so der Hit. Das habe ich nun verbessert. Der von igel vorgeschlagene Blauton wirkt wirklich ganz gut. Ein Überblenden durch die Funken habe ich nicht eingebaut, aber den Effekt konnte ich relativ einfach nachbilden. Es wird einfach kurz ein heller, etwas größere Kreis beim Ursprung der Funken für ca. 0,1 Sekunden angezeigt. Danach blendet der Kreis innerhalb von weiteren 0,1 Sekunden aus. Der Kreis ist dabei ebenfalls ein einfacher Partikel.

Zudem gab es noch das Problem, dass man die Funken in ca. 2 Meter Entfernung kaum noch gesehen hat. Jedoch konnte ich die einzelnen Partikel nicht einfach größer machen, da diese dann aus der Nähe sehr schlecht aussahen. Also habe ich - etwas unrealistisch aber einfach - einen weiteren Parameter in den Partikel-Emitter eingebaut. Mit diesem Parameter kann ich die Partikelgröße abhängig vom Abstand zur Kamera skalieren bzw. größer machen.

Die letzten beiden Screenshots weiter unten zeigen die Funken.

Neue Karte
Ich habe ja bereits geschrieben, dass ich an einer neuen Karte arbeite. Jedoch gab es eine kleine Kompikation: ich habe mir Datei mit der Karte zerschossen :-( - vier Wochen Arbeit umsonst. Das Problem war folgendes: das Laden und Speichern der Daten in die Datei dauerte relativ lange, da ich fast byte-weise in die Datei geschrieben habe. Somit habe ich einen Buffer eingebaut, der die Daten im Speicher temporär zwischenspeichert und diese dann Blockweise in die Datei schreibt. Der Buffer hatte jedoch einen winzigen Bug - statt einem "<=" habe ich ein "<" geschrieben. Dadurch fehlten zwischendurch immer wieder ein paar Byte - insgesamt 400 KB von 14.000 KB. Ich mache zwar vor dem Speichern immer ein Backup der letzten Dateiversion, doch ich habe leider einmal zu oft auf Speichern gedrückt: somit war die Backup-Datei genauso für den Hintern. Mit einem verzweifelten Rettungsversuch konnte ich aber ca. 5% der Karte wieder herstellen :-). Auf der Grundlage habe ich dann wieder aufgebaut und sogar ein paar Design-Schnitzer der ursprünglichen Karte ausgemerzt - natürlich mit mittlerweile 5 Backups in 4 Tagen ;-).

Jedenfalls wollte ich euch mal den aktuellen Stand zeigen. Ich denke, dass das der Nachfolger der ersten großen Karte wird. Die alte gefällt mir irgendwie nicht mehr und mir fällt gerade nichts kreatives für diese Karte ein. Daher der Neuanfang. Da ich diesmal einige neue Sachen im Editor drinnen habe, kann ich einfacher detailliertere Umgebungen basteln. Im Moment arbeite ich - wer hätte es gedacht - an einer Lagerhalle ;-). Naja, eigentlich sind es drei, wobei zwei von ihnen leicht versetzt zueinander sind und der Schnittpunkt komplett offen ist. Die dritte Lagerhalle wird über drei Toren erreichbar sein - im Moment ist aber nur ein Tor vorhanden. Der aus der alten Karte bekannte Gang innerhalb der Halle ist auch schon da, jedoch "etwas" höher.

zum Vergrößern klicken
Bild Bild Bild Bild Bild Bild Bild

Script-Libraries
Im Moment kopiere ich den Script-Quelltext zwischen den einzelnen Test-Projekten immer hin und her. Das ist natürlich nicht wirklich sinnvoll. Daher habe ich angefangen mir eine Script-Library aufzubauen. Die Library ist dabei einfach ein eigenes Script-Projekt. Den Quelltext des Projektes speichere ich dann in eine einzelne Script-Library-Datei. Diese Datei kann dann von den anderen Projekten einfach referenziert werden - so wie eine DLL. Die Library an sich benutze ich noch nicht, da diese noch nicht fertig ist. Im Moment arbeite ich an einem Spieler-Controller - der auch schon Netzwerkunterstützung drinnen hat.

Das wars auch schon wieder :-)
Gruß

_________________
Aktuelles Projekt: Gael - Development Blog
Website: LightBlackSoft.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: [Game] Gael
BeitragVerfasst: So Jul 18, 2010 22:43 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Mär 09, 2005 15:54
Beiträge: 372
Wohnort: München
Programmiersprache: Delphi, C#, FPC
Hallo,

es gibt mal wieder was kurzes zu berichten:

Volumetic Lighting
Ich habe schon länger drüber nachgedacht, ob ich nicht "God Rays/Volumetic Light Scattering/Light Shafts/ und wie sie alle heißen" einbauen will. Bisher habe ich immer gedacht, dass sich der Aufwand nicht lohnt. Dieses Wochenende habe ich mich dann doch mal hingesetzt und ein wenig herumprobiert. Was die Qualität betrifft bin ich mehr als zufrieden - nur die Performance ist noch nicht so der Knüller.

Das Rendern der Light Shafts ist an sich nicht so schwer wie ich anfangs dachte. Im Endeffekt kann man es mit der normalen Beleuchtung beim Deferred-Renderer vergleichen. Ich rendere für die Light-Shafts die Licht-Bounding-Volume mehrmals hintereinander, jedoch jeweils etwas kleiner. Somit bekomme ich mehrere Layer. Jeder Layer wird dabei wie eine normale Wand beleuchtet, nur ohne Normal-Tests oder Texturen. Die einzelnen Layer werden dann additiv in den Framebuffer geschrieben - das war es auch schon. Der einzig wirklich große Nachteil ist die Performance: für eine relativ gute Qualität muss ich ca. 30 bis 40 Light-Volumes für jedes Licht zeichnen. Für sehr gute Qualität mindestens 70. Da sind die Füllrate und die Shader-Einheiten der Grafikkarte schon extrem gefordert. Ich habe mir noch nicht überlegt, ob ich eine andere Methode nehme oder meine versuche zu verbessern. Aber ich werde auf keinen Fall für jedes Licht einen Light-Shaft zeichnen lassen. Für die Taschenlampe wahrscheinlich und vielleicht noch ein oder zwei Lichter der Karte.

Ich habe mal kurz ein paar Screenshots gemacht, links immer vorher und rechts nacher (zum Vergrößern klicken)
Die neue Map
Bild Bild Bild

Die bekannte Testmap
Bild Bild

Ich habe zudem nochmal meine Disco-Map entstaupt und die Light-Shafts testweise mal eingebaut. Der Ergebnis habe ich mal wieder als YouTube-Video hochgeladen.

Ich hoffe, es gefällt
Gruß
David

_________________
Aktuelles Projekt: Gael - Development Blog
Website: LightBlackSoft.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: [Game] Gael
BeitragVerfasst: Di Aug 31, 2010 21:18 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Mär 09, 2005 15:54
Beiträge: 372
Wohnort: München
Programmiersprache: Delphi, C#, FPC
Hallo,

kurz vor meinem Urlaub wollte ich noch den aktuellen Stand präsentieren. Da ich in den letzten Wochen nicht viel Zeit hatte, an Gael weiter zu machen, ist leider nicht so viel passiert.

Spieler-Kamera
Als "Inspirations-Vorlage" schaue ich mir in letzter Zeit viele Videos von Splinter-Cell-Multiplayer-Matches auf YouTube an (gibt erstaunlich wenig). Dabei versuche ich zu analysieren, wie sich Spieler verhalten, welche Sachen fürs Balancing beachtet werden müssen, usw. Dabei ist mir Aufgefallen, dass es für den Dieb relativ schwer ist, sich zu verstecken. Dies liegt nicht an den Versteckmöglichkeiten, sondern am eingeschränkten Sichtfeld durch die First-Person-Sicht. Dies ist mir vor allem durch die Splinter-Cell-Videos erst aufgefallen. Daher habe ich mal eine Third-Person-Camera eingebaut und geschaut, wie sich das ganze damit spielen könnte. Für den Dieb ist es damit extrem einfacher abzuschätzen, wie gut sich das aktuelle Versteck eignet. Für den Wächter bleibt es natürlich bei der 1st-Person-Camera. Dabei ist mir leider wieder einmal aufgefallen, wie "schlecht" meine Models eigentlich sind. Für einen ersten Release werde ich mich damit aber erstmal nicht weiter beschäftigen. Aber für später ist da auf jeden Fall noch viel Luft nach oben. Gerade bei Models fällt einem immer wieder auf, wie wichtig gute Designer sind.

Script-Library
In einem der letzten Posts habe ich bereits geschrieben, dass ich angefangen habe, eine Script-Library zu erstellen. Die Libraries sind nichts besonderes. Es sind einfach nur eine Ansammlung von Klassen, die komplett in der Script-Engine geschrieben sind. In dieser Library habe ich die Basis-Sachen für die Spiellogik geschrieben. Dabei gibt es erste Erfolge zu verzeichnen. Ich habe eine Basis-Version für den Server und den Client geschrieben. Diese beiden funktionieren grundsätzlich schon mal. Man kann nun einen Server erstellen und Clients können sich zu diesem Server verbinden und bereits ein paar Einstellungen vornehmen: Die Rundenzeit einstellen, das Team auswählen und auch Chatten. Die möglichen Einstellungen sind relativ flexibel implementiert: um z.B. die Rundenzeit zu ändern, sendet der Client ein bestimmte Command-Id, in der als Nutzdaten ein String drinnen steht. Dieser String wird dann vom Server geparst und ausgeführt. Falls der Command erfolgreich war, sendet der Server einen Broadcast an alle Clients, dass sich die Einstellungen geändert haben. Der Command zum Setzen der Rundenzeit schaut z.B. so aus: "set time 00:15:00" (setzt die Rundenzeit auf 15 min). Der Server kann jedoch noch keine Spiele verwalten bzw. Spielerpositionen senden und empfangen. Daher kann ich noch keine Spiel-Basis-Tests ausführen. Da jedoch das Grundgerüst schon mal steht, ist ein großer Teil des Aufwands bereits erledigt.

Die Einstellungen werden im Script in einzelne Klassen ausgelagert. Der Inhalt der Klassen kann dann über eine einfache Funktion in einen Stream serialisiert und de-serialisiert werden.

GUI
Ich habe mich auch mal daran gesetzt und eine GUI für das Hauptmenü zu erstellen. Diese ist auch wieder sehr schlicht gehalten und sollte auch nicht zu unübersichtlich sein. Die GUI besteht aus mehreren einzelnen Seiten, durch die man sich einfach durchnavigiert. Zwar kann man nicht von überall in alle Menüpunkte springen, aber das ignoriere ich erstmal ;-). Über das Hauptmenü kann man bereits einen Server stellen, sich zu diesem Server verbinden und das Team wechseln und die Rundenzeit einstellen. Was jedoch noch ein offener Punkt ist: man kann noch keine Eingaben in Form von Textfeldern erstellen, den ein solches Control habe ich in meiner GUI-Library noch nicht implementiert. Insgesamt fehlen noch ein paar wichtige Controls, dich in nach dem Urlaub in Angriff nehmen werde. Dazu zählen unter anderem ein Textfeld, eine ListBox und eine ListView. Sobald dann diese Controls fertig sind und man im Menü chatten kann, werde ich mich an den Server setzen und die Logik für das eigentliche Spiel sowie die Spieler-Positions-Sachen einbauen.

Script-Engine
In den letzten Wochen habe ich aus Zeitgründen eher mit "leichter" Kost beschäftigt und ein Paar Bugs in der Script-Engine behoben. Auf Grund der Komplexität fallen solche Sachen erst auf, wenn man die Script-Engine wirklich an die Grenzen bringt. Aber auch einfache Sachen, die einem eigentlich auffallen sollten, haben es in die Bug-Liste geschafft. Was jedoch auch sehr wichtig wahr, war die Performance-Verbesserung des Compilers. Bei mittlerweile über 12.000 Zeilen Script-Quelltext war der unoptimierte Compiler ein zu großes Problem, da die Produktivität dadurch sehr gelitten hat. Der alte Compiler hat für die 12.000 Zeilen über 15 Sekunden gebraucht, der neue braucht dafür nur noch 2 Sekunden.

GeForce-Probleme
Wie ich bereits festgestellt habe, gibt es unter anderem ein Problem mit GeForce7x-Karten und Floating-Point-Buffern. Das äußert sich in einem kompletten System-Freeze, was das Debuggen relativ schwer macht. Daher habe ich folgendes gemacht. Zum einen habe ich das Erstellen der Floating-Point-Textur geändert: bei Floating-Point-Texturen erstelle ich die Texturen nicht mehr mit "glCopyTexImage2D" sondern mit "glTexImage2D". Ob das was ändert, weiß ich leider noch nicht, denn mein GeForce7x-Tower verstaubt seid dem Umzug unter meinem Schreibtisch. Falls das Problem jedoch weiterhin besteht, kann man nun alle Floating-Point-Texturen über eine Option deaktivieren. Das ist eigentlich nur als kleiner Wink an LordHorazont gedacht, damit er beim nächsten Release nochmal testen kann.

So, der Post ist jetzt doch etwas länger geworden als gedacht, jedoch sind die einzelnen Punkte nicht so umfangreich.

Gruß
David

_________________
Aktuelles Projekt: Gael - Development Blog
Website: LightBlackSoft.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: [Game] Gael
BeitragVerfasst: Di Okt 05, 2010 23:07 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Mär 09, 2005 15:54
Beiträge: 372
Wohnort: München
Programmiersprache: Delphi, C#, FPC
Ich bins mal wieder,

Im letzten Post habe ich geschrieben, dass ich aktuell am Hauptmenü des Spiels sowie parallel am Server arbeite. Diesmal möchte ich mich jedoch mal etwas mehr auf die GUI konzentrieren, da diese bisher ja doch relativ kurz gekommen ist.

Haupt-Menü/GUI/...
Mittlerweile bin ich mit der GUI ganz gut voran gekommen: man kann in Zwischen bereits mit der GUI interagieren. Bisher gibt es wirklich noch keine große Ansammlung an Controls, ein paar sind es jedoch bereits so gut wie fertig. Mit dabei ist bisher ein Panel, ein Label, ein Button, eine ProgressBar, ein Edit-Feld sowie ein Popup-Menü. Alle bis auf das Popup-Menü sind bereits voll funktionsfähig und ohne Probleme nutzbar. Beim Popup-Menü fehlen nur noch Kleinigkeiten, wie z.B. eine Checked-Markierung am Anfang und Untermenüs - wobei die Logik dahinter bereits funktioniert - lediglich das Rendern ist noch nicht eingebaut.

GUIs laden/erzeugen
Die Positionierung sowie die Gestaltung der Menüs passiert komplett in XML-Dateien. Es werden bisher keine GUI-Elemente dynamisch im ScriptQuelltext erzeugt - wobei das natürlich möglich ist. Damit so eine GUI-XML-Datei auch wartbar bleibt, gibt es nicht nur eine Datei, in der alles definiert wird. Eine GUI-Definition kann sich nämlich über mehrere Dateien erstrecken. Damit die Engine auch weiß, in welchen Dateien die benötigten GUI-Elemente zu finden sind, werden die Zusatzdateien über einfache Links angegeben. Die Haupt-GUI-Datei schaut damit wie z.B. in folgendem Beispiel aus:
Code:
<?xml version="1.0" encoding="utf-8"?>
<gui>
  <fonts>
    <font Name="Text" Font="Arial" Size="12" />   
    <font Name="Text.Italic" Font="Arial" Style="Italic" Size="12" />
  </fonts>
  <root Name="root" Enabled="1" Visible="1"> 
    <Children>

      <link Type="Panel" ref="relative:///subMainMenu.xml" />                                             
      <link Type="Panel" ref="relative:///subOptionsMenu.xml" />

    </Children> 
  </root>
</gui>

Wie man sehen kann, ist das Hauptmenü sowie das Options-Menü hier in eine separate XML-Datei ausgelagert. Das macht das ganze sehr übersichtlich, wart- und erweiterbar, da jede dieser Unterdateien bisher max. 300 Zeilen XML-Code hat. Würde diese Auftrennung nicht passieren, hätte die GUI-Definitions-Datei wahrscheinlich über 1200 Zeilen XML-Code - und das Hauptmenü ist noch lange nicht fertig.

Verbindung: Logik-GUI
Nachdem die GUI-Elemente in den Speicher geladen wurden, verbindet sich die Logik mit den GUI-Elementen. Doch bevor ich dazu komme, muss ich nochmal generell etwas über den Aufbau des Hauptmenüs schreiben. Für dieses habe ich mir einfach folgende Definition überlegt: Das Menü ist in einzelne Seiten unterteilt, wobei immer nur eine sichtbar ist. Jede Seite hat einen Vorgänger und ein oder mehrere Unterseiten. Eine Seite besteht dabei nur aus einem großen Panel, in dem sich beliebig viele GUI-Elemente befinden können. Für jede Seite wird in der Script-Engine eine eigene Klasse definiert. Diese Klasse kümmert sich dann darum, die Untermenüs korrekt zu öffnen, Eingaben zu verwalten, usw.

Nachdem die Elemente wie gesagt geladen wurden, werden von der Script-Engine die entsprechenden Klassen für die jeweiligen Seiten geladen. Dies einzelnen Klassen bekommen dann als Haupt-Menü-Punkt immer nur das Panel der jeweiligen Seite. Alle benötigten Controls holt sich die Klasse nach dem initialisieren automatisch. Nach der Initialisierung der Klassen werden diese miteinander verlinkt. Sobald das erledigt ist, weiß das Hauptmenü dann z.B. welche Klasse und somit auch welche Seite geöffnet werden muss, wenn der Benutzer zu den Optionen will. Sobald das dann alles fertig geladen ist, werden die Event der GUI-Elemente mit den Funktionen der jeweiligen "Seiten-Controll-Klassen" verknüpft. Das Ganze funktioniert so: in der XML-Datei stehen bei den Events nur die Namen der Methoden, die bei dem entsprechendem Ereignis aufgerufen werden sollen. Das GUI-Framework ist dabei in der Lage, die Namen der Methode direkt an eine Methode in der Script-Engine zu mappen. Dafür wird im kompilierten ByteCode der Script-Engine nach der Methode gesucht, die den angegebenen Namen und die korrekte Signatur hat. Wurde die Methode gefunden, wird das Event des GUI-Elements automatisch an die Script-Methode gebunden. Das ganze funktioniert prächtig und bisher komplett ohne Probleme.

Das Menü in Aktion
Nach soviel trockenem Text (den wahrscheinlich kaum einen interessiert), ist es mal wieder Zeit für einfache Kost. Daher gibt es mal wieder ein Video mit dem aktuellen Menü in Aktion. Ich möchte darauf hinweisen, dass so gut wie alles noch als Platzhalter gedacht ist - vor allem die beiden Progress-Bars unten (die sind nur zum Testen der ProgressBar-Komponente gut). Ich verbinde mich im Video übrigens auf meinen kleinen Testserver, der soweit schon ganz gut funktioniert. Aber nicht wundern, warum die Spiel-Lobby so leer ist - es fehlen immer noch die Komponenten für den Chat und für die Spielerliste.

Hier ist der Link zum Video

Ich hoffe, es gefällt.

Gruß
David

_________________
Aktuelles Projekt: Gael - Development Blog
Website: LightBlackSoft.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: [Game] Gael
BeitragVerfasst: Mo Okt 25, 2010 23:27 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Mär 09, 2005 15:54
Beiträge: 372
Wohnort: München
Programmiersprache: Delphi, C#, FPC
Hallo,

momentan komme ich bei mir so gut wie überhaupt nicht voran :-(. Das liegt vor allem daran, dass die nächsten Schritte, die ich machen muss, wahrscheinlich sehr viel Ärger bereiten. Darauf habe ich im Moment irgendwie kein Nerv. Daher beschäftige ich mich im Moment mit kleinen Belanglosigkeiten, die mich im großen und ganzen nicht wirklich weiterbringen. Z.B. habe ich dem GUI-Framework ein Template-System verpasst. Jedes Template hat da z.B. eine Definition für die Schriftfarbe und die Hintergrundfarbe eines GUI-Elements. Den einzelnen GUI-Elementen kann ich dann einfach ein Template zuweisen und erspare mir dadurch ein paar Zeilen XML-Config-Datei. Hat insgesamt ca. 5 Stunden gedauert und hat mich jedoch nicht wirklich weiter gebracht.

Weil ich gerade bei der GUI war, habe ich mir gedacht: versuchst du mal einen dynamischen Hintergrund. Das ging relativ flott und schaut auch ganz schick aus. Jedoch so ganz zufrieden bin ich noch nicht. Es soll aber auch nicht zu aufdringlich und zuuuuu viel Bewegung haben - ist ja schließlich nur das Hauptmenü ;-). Jedenfalls wollte ich euch hier den Test als "Komme-Im-Moment-Nicht-So-Gut-Voran-Aber-Das-Wird-Schon"-Lebenszeichen-Video zeigen.

Gruß
David

_________________
Aktuelles Projekt: Gael - Development Blog
Website: LightBlackSoft.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: [Game] Gael
BeitragVerfasst: Mo Nov 22, 2010 16:00 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Mär 09, 2005 15:54
Beiträge: 372
Wohnort: München
Programmiersprache: Delphi, C#, FPC
Hi

ich schreibe mal wieder den aktuellen Status hier her:

Fortschritt der Karte
In letzter Zeit habe ich mal wieder an der bisher einzigen Karte weitergearbeitet. Es gab noch einigen freien Raum, den ich noch ausfüllen musste. Die Karte ist damit noch nicht fertig, aber ein Großteil ist damit schon mal abgeschlossen.

Beim Testen der Karte fiel mir auch gleich ein kleines Performance-Problem auf. Die Map hat im Moment ca. 250.000 Vertice und ca. 30 dynamische, schattenwerfende, Lichter. Bei den Tests kam ich jedoch meistens kaum über 10 FPS hinaus. Also habe lange nach Bottle-Necks gesucht und geschaut, wo ich gut noch Performance herausholen kann. Das hat einiges gebraucht. Von vorher durchschnittlich 10 FPS habe ich nun 40 FPS - da war ich selbst etwas erstaunt. Im Moment schaufelt mein Laptop daher ca. 50-60 Millionen Vertice pro Sekunde aufm Bildschirm hin und her (wobei viele bei der Shadow-Map-Generierung anfallen). Im Moment bin ich aber wieder Füllraten-Limitiert, denn bei einer geringeren Auflösung habe ich fast durchgehend 60 FPS. Da muss ich mir die Shader nochmal genauer anschauen.

Ich habe noch ein paar Screenshots der aktuellen Karte für euch hochgeladen.
(zum Vergrößern klicken)
Bild Bild Bild Bild Bild Bild

Erweiterungen an der Partikel-Engine
Vor etwas längerer Zeit hatte ich bereits eine Idee zur Erweiterung meiner Partikel-Engine, jedoch bin ich aus zeitlichen Gründen bisher nicht dazu gekommen, das umzusetzen. Jedoch habe ich mir jetzt mal die Zeit genommen und die Particle-Engine erweitert. Genauer gesagt geht es um Sub-Emitter. Jedem Emitter kann man nun einen Sub-Emitter hinzufügen. Mit Hilfe des Sub-Emitters werden dann weitere Partikel auf dem Weg des Root-Partikels erzeugt. Sagen wir, wir haben einen Funken. Dieser Funken fliegt durch den Raum. Zusätzlich soll der Funken noch einen Rauch-Schleier hinter sich her ziehen. Um das zu erreichen, erstelle ich einen neuen Emitter, der sich um die Erstellung und Verwaltung des Rauches kümmert. Dem Funken-Emitter weise ich dann den Rauch-Emitter als Sub-Emitter zu. Für jeden Funken, den der Funk-Emitter nun verarbeitet (also Position, etc.) weist er seinen Sub-Rauch-Emitter nun an, an der aktuellen Position des Funken selbst ein paar Partikel erstellen soll. Ich weiß, dass das jetzt nicht so leicht zu verstehen ist - ich bin im Moment etwas im Prüfungsstress und kann mich daher nicht besser ausdrücken ;-) aber ich hoffe, dass es einigermaßen zu verstehen ist.

Natürlich habe ich auch gleich mal ein Video einer Test-Explosion erstellt. Die Explosion besteht aus 7 Emittern, die von der Script-Engine heraus automatisch getriggert werden. Zusätzlich ist noch ein PointLight in der Mitte, damit die Explosion auch Licht emittiert. Am deutlichsten erkennt man die Sub-Emitter bei den großen Funken, die eine Rauchfahne hinter sich herziehen.
(für das Video klicken)
Bild

Ich habe auch schon wieder eine neue Idee für die Partikel-Engine: ich will versuchen, den Rauch auch komplett beleuchten zu lassen. Im Kopf wollte ich dabei so vorgehen: ich rendere die Karte genauso wie im Moment. Da der Rauch ja auch zum Teil transparent sein soll, kann ich den natürlich nicht einfach so mit in den G-Buffer für das Deferred-Shading mit hinein packen. Daher wollte ich - nachdem die Karte beleuchtet wurde - den Farb-Buffer des G-Buffers leeren und die Rauch-Partikel hineinschreiben. Durch den bereits vorhandenen Tiefenbuffer im G-Buffer sollte das keine große Probleme bereiten. Danach Beleuchte ich den Rauch im "neuen" G-Buffer genau wie die anderen Vertice bisher auch und render das ganze Additiv in Buffer mit der bereits fertig beleuchteten Karte. Das ganze wird dann wie gehabt durch den Post-Processing-Shader gejagt. Ob das so klappt, weiß ich noch nicht. Jedoch muss ich jetzt erstmal wieder weiter lernen.

Ich hoffe, es gefällt
Gruß
David

_________________
Aktuelles Projekt: Gael - Development Blog
Website: LightBlackSoft.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: [Game] Gael
BeitragVerfasst: Mo Feb 07, 2011 21:43 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Mär 09, 2005 15:54
Beiträge: 372
Wohnort: München
Programmiersprache: Delphi, C#, FPC
Nach gut 2,5 Monaten wollte ich mal wieder ein kleines Update bringen ;-)

Erstmal vielen vielen Dank für den Jahresaward - hätte nicht gedacht, dass ich den bekomme. Natürlich auch danke für das Vertrauen - für fast 2 Jahren Entwicklung und bisher nur "Tech-Demo" - Releases einen weiteren Jahresaward bekommen - das ist schon sehr erstaunlich.

In den letzten Monaten hatte ich nicht wirklich Zeit, groß an Gael weiter zu machen. Das liegt zum einen daran, dass ich tagsüber mit einem sehr anstrengendes Projekt beschäftigt bin und daher am Abend nicht mehr viel Kraft für Gael übrig habe. Zum anderen hatte ich in den letzten 3 Monaten meine Abschlussprüfung meiner Ausbildung - die ich nun am 02.02.2011 erfolgreich abgeschlossen habe :-D

Nun aber wieder zu dem Thema, dass euch wahrscheinlich mehr interessieren wird ;-) was gibt es neues zu Berichten: Leider gibt es da nicht viel, was wirklich erwähnenswert ist. Jedoch gibt es zwei Punkte, die ich euch präsentieren will.

Skybox-Rendering
Ich habe mich nun endlich hingesetzt und den Skybox-Render-Pfad eingebaut und getestet. Das ganze ist relativ simpel aufgebaut: In den Material-Properties kann man einstellen, ob das Material ein "Fixed"-Material ist. Wenn dies der Fall ist, werden die Vertice mit diesem Material ohne die Translation der Kamera gezeichnet. Da dies unabhängig von den Vertice ist, kann jedes beliebige Objekt "fixed" sein. Dadurch sind z.B. Sky-Spheres oder Sky-Boxes ohne Probleme möglich.

Camera-Management
Komplett neu ist das Camera-Management der Engine. Bisher gab es nur ein Kamera-Objekt, dass durch die Welt bewegt wurde. Nun sind beliebig viele Kameras möglich. Jetzt mag sich der ein oder andere Fragen: wozu mehrere Kameras? - man sieht doch nur aus einer Kamera!?! Das ist korrekt, jedoch sind die Kameras eher für Offscreen-Rendering gedacht. Man kann also die Szene aus einer beliebigen Kamera-Position in eine beliebige Textur rendern. Somit sind z.B. Live-Bilder einer Überwachungskamera ohne Probleme möglich. Die Kamera-Objekte lassen sich zudem in der Script-Sprache genau wie Lichter und Objekte beliebig verschieben und drehen. Dadurch sind auch schwenkende Überwachungskameras kein Problem.

Aber das war's noch nicht alles. Ich weiß nicht mehr, wann und wer es im Kommentar-Thread angesprochen hat (wahr sehr am Anfang), jedenfalls ging es um die Frage, ob ich wieder Water-Rendering wie in meiner vorherigen Engine einbauen will. Damals habe ich gesagt, dass ich das wahrscheinlich nicht machen werde. Doch nun habe ich mich dazu entschieden, wenigstens reflektierende Oberflächen zu ermöglichen. Dabei kommt der gerade erwähnte Camera-Manager zum Einsatz. Die reflektierende Oberfläche wird dabei auch in eine Textur gerendert, wobei die Reflektions-Kamera automatisch an die Hauptkamera des Betrachtes gekoppelt wird. Da ich - im Gegensatz zu meiner alten Engine - komplett auf Shader setze und somit auch ein starkes Framework um den Renderer habe, habe ich beim Anzeigen der Reflektions-Textur sehr viel mehr Möglichkeiten als in der alten Engine.

Um euch mal das aktuelle Ergebnis zu zeigen, habe ich mal wieder ein paar Screenshots erstellt (diesmal auch mal etwas hellere). Ich habe mir die Crytek-Version des Sponza-Models heruntergeladen und in den Editor importiert. Hier sind die Ergebnisse. Diese sind direkt aus dem Editor, daher ohne Post-Scene-Effects:

Sponza - 48 Lichter (zum Vergrößern klicken)
Bild Bild Bild Bild Bild Bild Bild

(und für die Freunde düsterer Maps) Die Test-Map (zum Vergrößern klicken)
Bild Bild Bild Bild

Gruß
David

_________________
Aktuelles Projekt: Gael - Development Blog
Website: LightBlackSoft.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: [Game] Gael
BeitragVerfasst: Do Mai 19, 2011 19:08 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Mär 09, 2005 15:54
Beiträge: 372
Wohnort: München
Programmiersprache: Delphi, C#, FPC
Hallo allerseits,

nach einer längeren Pause melde ich mich mal wieder mit einem längeren Status-Update zurück.

In den letzten 3 Monaten habe ich eine kleine Auszeit von Gael genommen. Leider nicht ganz freiwillig, da ich in letzter Zeit relativ viel Konzentrationskraft in der Arbeit verbraucht habe und ich dann am Abend nicht mehr viel Lust hatte, mich groß mit Gael zu beschäftigen. Zudem habe ich mir mal ein Smartphone gegönnt und kann immer noch nicht aufhören, damit rumzuspielen. Aber vor ca. 2 Wochen habe ich mich mal wieder hingesetzt und schwups - die Motivation war wieder da.

Aufräumarbeiten
Nach dieser etwas längeren Pause hat man natürlich einen etwas anderen Blick auf seinen eigenen Quellcode. Mir sind da jetzt ein paar Sachen so richtig ins Auge gesprungen, die ich zwar vorher bemerkt hatte - sie jedoch als unwichtig abgestempelt hatte. Jedenfalls war es Zeit, um den eigenen Code mal etwas aufzuräumen. Konkret gesagt habe ich das komplette Script-Interface angepasst und erweitert. Angepasst heißt, dass ich die einzelnen Script-To-Gael-Interface-Klassen in Namespaces unterteilt habe, wodurch das schon viel aufgeräumter wirkt. Wenn jetzt der eine oder andere mit einem ganz großen Fragezeichen vor dem Bildschirm sitzt: Die Scripts haben über Script-Klassen Zugriff auf die Engine selber. Diese Klassen befanden sich alle sozusagen in einer großen Unit. Diese habe ich nun aufgesplittet und in Kategorien (oder halt namespaces) aufgeteilt. Also ein Bereich für die GUI, ein Bereich für den Renderer, ein Bereich für die Utilities, usw. Das mag jetzt zwar sehr banal klingen, jedoch macht das Arbeiten in den Scripts jetzt wieder mehr Spaß, da ich schneller die korrekten Klassen finde. Das ist sehr wichtig, da ja das komplette Spiel in der Scriptsprache geschrieben wird und ich somit sehr viel Zeit beim Schreiben der Spiellogik verbringe.

GUI-Erweiterungen
Als weitere Disziplin habe ich die GUI-Control-Liste um ein paar wichtige Controls erweitert. Zum einen sei da das ListBox-Control genannt, das sehr flexibel implementiert ist. Ich habe mich da etwas vom iOS-Framework (mit dem ich auf der Arbeit im Moment viel Arbeite) inspirieren lassen. Im Endeffekt ist die ListBox keine wirkliche Listbox wie in Delphi. Stattdessen ist die Listbox nur eine Scrollbox, die die einzelnen Child-Controls automatisch korrekt positioniert und ausrichtet. Da ich beliebige Child-Controls in eine ListBox packen kann, habe ich da sehr viele Möglichkeiten. Bilder, Text, usw, ist alles ohne große Mühe in einer ListBox möglich. Das einzige, was noch fehlt ist der Selektiermodus - also das Auswählen einer Zeile und das auslesen des Index der ausgewählten Zeile. Aber da ich das im Moment noch nicht brauche, habe ich das erstmal auf die lange Bank geschoben.

Als weiteres Feature sind die aus der VCL bekannten "Anchors". Ich kann nun Controls links, rechts, oben und unten "anpinnen". Wenn ein Control an eine Richtung angepinnt ist, dann hält es automatisch den zu beginn gesetzten Abstand zum entsprechenden Rand beim Resizen. Das aus der VCL bekannte "Align" habe ich aus Komplexitätgründen jedoch nicht eingebaut.

Dafür gibt es noch ein weiteres Control, das so erstmal nicht in Delphi drinnen ist: ein StackPanel. Ein StackPanel ist dabei ein unsichtbares Control, dass sich nur um die Positionierung und die Größe der Child-Controls kümmert. Dabei fügt mal einem StackPanel einfach eine oder mehrere "Schubladen" hinzu. Diese werden hintereinander bzw. untereinander positioniert. Die Größe einer Schublade kann entweder in Pixel oder in Prozent zum dazugehörigen StackPanel angegeben werden. Des weiteren gibt es noch eine Property für die minimale und für die maximale Größe (ebenfalls in Pixel oder in Prozent).

Damit lassen sich schon gute Sachen machen und ich muss mich im Code nicht mehr manuell um das Resizen und das Positionieren von Controls kümmern. Das ist vor allem in der Ingame-GUI wichtig, da ich dort genau solche Features brauche und die Controls nicht per Script-Code positionieren will.

Spiellogik
Ein sehr wichtiger Teil eines Spiels ist natürlich ...
a) die Spiellogik
b) eine Wanduhr
Rufen Sie jetzt an unter .... Spaß beiseite. Die richtige Antwort sollte euch auf den Inhalt des kommenden Absatz vorbereiten. Falls nicht, dann ... weiß ich auch nicht. Jedenfalls habe ich mich, nachdem dem Aufräumen der Engine-Header, mal wieder auf die Spiellogik geworfen. Konkret gesagt habe ich mich um den Server sowie um den Client gekümmert. Ich hatte ja schon geschrieben, dass ich bereits an der Serverlogik gearbeitet hatte. Damit war damals vor allem die Grundlogik und mehrere Verwaltungsstrukturen gemeint. Nun hat der Server endlich mal etwas Logik für die Spielsteuerung bekommen. Das heißt genauer gesagt: der Server kann jetzt verschiedene "Spielmodi-Zustände" korrekt verwalten und zwischen diesen hin- und her-wechseln. Gemeint ist damit, welche Teillogik gerade auf dem Server aktiv ist und welche somit vom Client aktiviert werden muss - also Spiellobby, oder die aktive Runde, etc. Zudem hat der Server jetzt bereits ein paar Validierungschecks drinnen, die für die Spiellogik wichtig sind.

Start eines Spiels
Nun kommt mal etwas konkretes zum Ablauf eines Spielrunde. Folgendes ist bereits implementiert und getestet (außer ich schreibe explizit hin, dass der Teil noch nicht fertig ist). Zu Beginn startet man einen Server. Dabei wird ein temporäres Admin-Passwort generiert mit dem sich der Host-Spieler verbindet. Danach wird das Admin-Passwort automatisch auf "Leer" gesetzt. Da zum Einloggen als Admin immer ein Passwort nötig ist, können andere Spieler somit keinen Admin-Status bekommen. Wenn man mal Admin-Rechte auf dem Server hat, kann man das Passwort natürlich ändern. Somit können sich dann auch andere Mitspieler, die mit dem Server verbunden sind und das Passwort kennen, sich als Admin einloggen.

Als Admin hat man das Recht, Spieleinstellungen zu ändern oder andere Mitspieler zu kicken (nicht implementiert). Als "normaler" Mitspieler kann ich hingegen nur das Team und meinen Namen ändern.

Wenn man sich zu einem Server verbunden hat, landet man erstmal in einer Lobby im Hauptmenü. In dieser Lobby kann man schon mal sein Team auswählen und mit den anderen Mitspielern chatten. Sobald alle Mitspieler ihr Team ausgewählt haben und sich selbst auf "Ready" gesetzt haben, wechselt der Server in den "Lade-Modus" und die Spieler laden die Map. Danach landen alle in einer weiteren "Lobby". Dort haben sie wiederum nochmals die Möglichkeit ihr Team auszuwählen. Diese zweite Lobby dient dabei als Startpunkt für jeder Runde. Wenn sich jetzt ein neuer Spieler zum Server verbindet, landet dieser wie jeder andere auch - erstmal in der Menü-Lobby. Dort kann er dann auch dem Spiel beitreten. Jedoch ist er dann erstmal als Spectator markiert und kann somit nicht in eine laufende Partie einspringen. Falls jedoch gerade keine Runde gespielt wird, landet der neue Spieler in der gerade genannten "Spielrunden-Lobby". Da er dort auch sein Team auswählen kann, kann er bei der nächsten Runde auch mitspielen oder auch als Spectator pausieren. Der Grund, warum er erstmal als Spectator in die Partie startet ist relativ einfach: es kann sein, dass eine Spielrunde bereits gestartet hat, während er noch am Laden der Karte ist. Daher markiert ihn der Server erstmal als Spectator.

Um eine Runde zu Starten müssen alle Spieler, die nicht als Spectator teilnehmen, sich selbst als "Ready" deklarieren. Damit man nicht ewig warten muss, wird es noch einen automatischen Start nach wahrscheinlich 1min geben (nicht implementiert), der das Spiel automatisch startet. Sobald eine Runde startet, laden die Spieler noch die Models in den Arbeitsspeicher und werden dann vom Server an die korrekten Positionen gespawnt. Sobald eine Runde beendet ist (wird anhand der Spielregeln festgelegt), geht der Server wieder in den "Ingame-Lobby-Modus" zurück und jeder kann wieder sein Team wechseln.

Wer das ganze mal in Aktion sehen will, es gibt auch mal wieder ein Video

Weitere Planung
Eigentlich wollte ich mal wieder eine TechDemo mit der aktuellen Karte herausbringen. Jedoch habe ich mich spontan dagegen entschieden. Der Grund ist relativ einfach: einen simplen "MapViewer" würde den aktuellen Entwicklungsstand nicht wirklich repräsentieren. Daher habe ich mir gedacht, dass ich einen Entwicklungsstand veröffentliche, sobald man sich zu einem Server verbinden kann und bereits mit anderen durch die Map laufen kann. Wann das genau sein wird, kann ich noch nicht sagen. Aber ich kann schon mal ungefähr auflisten, was dafür noch alles zu tun ist:

  • Ein Masterserver, bei dem sich alle Server registrieren (ist nicht so schwer - ein relativ einfaches php-Script mit einer MySQL-Datenbank reicht da vollkommen aus)
  • Das Detektieren von Verbindungsabbrüchen im Client (Server wird beendet, etc.). Wenn ein Client sich vom Server trennt, dann wird das vom Server auch korrekt erkannt und an die anderen Clients gemeldet. Falls der Server jedoch beendet wird, bekommen das die Client nicht mit.
  • Man muss Spieler kicken können
  • Beim Server muss die Spiellogik-Verarbeitung und Prüfung eingebaut werden (eine vereinfachte Form für den ersten Test-Release reicht hier aber vollkommen aus)
  • Die Spieler müssen Positionsnachrichten von anderen Spielern empfangen und eigene Senden
  • Ein Equipment-System muss eingebaut werden (Dieb: Nachtsichtgerät, Wächter: Taschenlampe, usw)
  • Testen, Testen, Testen, Testen und, falls ich es noch nicht erwähnt habe, testen

Der Einfachheit halber werde ich erstmal alles über die TCP-Verbindung zum Server abwickeln, auch die Positionsdaten. Später wird dann die bereits eingebaute UDP-Verbindung für die Positionsdaten benutzt. Außerdem steht noch ein richtig großer Brocken vor mir: einen Remote-Debugger für die Script-Engine. Das Debugger-Interface ist bereits so gut wie fertig, die Debug-Infos werden wahrscheinlich auch nicht mehr so lange brauchen. Da das ganze jedoch als abstrakte Klasse bereits schön herausgelöst ist, muss für den Remote-Debugger wahrscheinlich nur noch wenig Logik eingebaut werden. Ein einfaches TCP-Protokoll reicht für diesen Zweck vollkommen aus - und keine Sorge: der Remote-Debugger wird in jedem Release deaktiviert sein - ich brauche ihn nur für mich zum testen.

Sobald erstmal ein relativ stabiles System vorhanden ist, werde ich mich um die eigentliche Spielrunden-Logik kümmern. Ist diese dann auch funktionsfähig, kommt noch ein weiterer wichtiger Punkt: Sound! Da ich im Moment noch nicht genau sagen kann, welche Anforderungen ich für den Sound habe (nicht Sound-Engine-spezifisch, sondern Implementierungs-spezifisch in die Engine) verschiebe ich das noch etwas nach hinten.

Das wars fürs erste auch schon wieder.

Gruß
David

_________________
Aktuelles Projekt: Gael - Development Blog
Website: LightBlackSoft.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: [Game] Gael
BeitragVerfasst: Fr Jun 10, 2011 19:27 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Mär 09, 2005 15:54
Beiträge: 372
Wohnort: München
Programmiersprache: Delphi, C#, FPC
Howdy an alle,

Mal wieder was zum ausprobieren!!
Wie im Meinungs-Thread kurz angekündigt bin ich in letzter Zeit gut voran gekommen und habe einiges geschafft. Eigentlich hatte ich vor, nächste Woche den Release der neuen Demo zu veröffentlichen. Jedoch bin ich schneller mit den noch zu erledigenden Punkten fertig geworden als ich gedacht habe. Da ich aber für den Release keine große Sache mehr angehen wollte, habe ich mir spontan gedacht: machste heute den Release.

In der Hoffnung, dass manch einer doch noch ein ein paar Zeilen lesen will, schreibe ich noch etwas über die Punkte der ToDo-Liste:

  • Master-Server
    Der Master-Server besteht wie bereits gesagt aus wenigen php-Scripts im Zusammenspiel mit einer MySQL-Datenbank. Da im Kommentar-Thread über mögliche Performance-Engpässe nachgedacht wurde, wollte ich nochmal schreiben, dass diese "Befürchtungen" erstmal nicht eintreten werden. Selbst wenn es zu dem im Moment unwahrscheinlichen Fall kommen sollte, dass 100 Server gleichzeitig aktiv sind, sollte der MasterServer nicht zusammenbrechen. Dieser hat nur die Aufgabe, eine Liste mit momentan aktiven Servern bereit zu stellen. Zusätzlich meldet sich jeder Server (aktuell) jede Minute mit einem "HeartBeat" beim MasterServer um zu sagen "Ich bin noch da". Falls ein Server sich länger nicht gemeldet hat, wird dieser vom MasterServer automatisch gelöscht und erscheint somit nicht mehr in der Server Liste. Später will ich die Update-Frequenz noch etwas verringern, doch zum Testen finde ich 1x pro Minute in Ordnung.

    Als Kommunikations-Protokoll habe ich ein einfaches XML-Format gewählt. Ein einzelner Server besteht dabei aus einer einzelnen XML-Node, wobei dessen Eigenschaften als Attribute in der Node gespeichert sind. Somit ist der Transfer-Overhead von XML nicht so gigantisch.
  • Verbindungsabbrüche
    Das Detektieren der Verbindungsabbrüche funktioniert an sich bereits (dank TCP *grins*) ganz gut. Jedoch ist die Logik im Spiel selber noch nicht komplett. Im Moment wird man einfach zurück in die Spiel-Lobby im Hauptmenü geworfen und im Chat-Fenster wird eine Meldung angezeigt, dass die Verbindung weg ist. Später wird dass dann über eine Message-Box in der GUI gelöst - somit ist das bisher nur temporär.
  • Einfache Spiellogik
    Da ich für den ersten Test nicht gleich die komplette Spiellogik implementieren wollte, habe ich fürs erste nur eine super simple Logik eingebaut - nämlich keine ;-). Das hat auch einen Grund: wenn im jetzigem Test herauskommen sollte, dass die bisherige Update-Logik der Spielerpositionen komplett ungeeignet sein sollte, will ich nicht - falls notwendig - eine eventuell vorhandene Spiellogik erneut anpassen müssen. Daher ist die "Logik" - wenn man sie überhaupt so nennen darf - so einfach wie möglich: es gibt nur einen Timer, der die Rundenzeit herunter zählt - nicht mehr und nicht weniger.

Nun zum eigentlichen Punkt: der Release der Demo. Diesmal schreibe ich extra nicht hin, dass es eine TechDemo ist. Das hat auch einen Grund: der Script-Quellcode, dem die aktuelle Spielmechanik zu Grunde liegt, ist jetzt kein Test mehr sondern tatsächlich der Entwicklungsstand, auf dem ich das fertige Spiel aufbauen will. Alles was bisher zu sehen war, war nur auf temporären Scripts aufgebaut, doch nun hoffe ich, dass der aktuelle (bereits recht umfangreiche) Script-Quellcode so erweiterbar ist, dass er für die finale Version ausreicht. Ich habe einige Teile aus dem bereits vorhandenen Testscripts übernommen, jedoch fehlt noch einiges. Daher wundert euch bitte nicht über Sachen, die vorher bereits mal vorhanden waren und jetzt nicht mehr zu sehen sind (z.B. weiches Treppensteigen).

Was ist in der Demo drinnen?
In der Demo ist bereits das relativ weit fortgeschrittene Menü. Ich denke nicht, dass ich das noch komplett neu machen werde und würde im Moment sagen, dass es so auch in der ersten 1.0-Version aussehen wird. Eventuell gibt es ein paar Kleinigkeiten, die ich noch ändern werde bzw. muss. Aber im Großen und Ganzen dürfte das so bleiben wie es ist. Noch ein kleiner Hinweis: Das Hauptmenü lässt sich zum einen komplett per Tastatur und zum anderen per Maus steuern. Mit der Tastatur-Eingabe wechselt ihr den Fokus mit Hilfe der "Pfeil-Hoch" und der "Pfeil-Runter-Taste", mit "Enter" klickt ihr auf den entsprechenden Punkt und mit "Backspace" oder "Escape" kommt ihr zum vorherigen Menü - außer ihr seid bereits zu einem Server verbunden.

Die mitgelieferte Map ist bisher nur in Screenshots und Videos sichtbar gewesen. Ich bin mit dem aktuellen Stand noch nicht fertig, es kommt also noch was hinzu. Dafür sind aber intern noch einige Sachen vorher zu erledigen. Ich habe mal bereits angesprochen, dass ich den Octree komplett überarbeiten will - was leider auch notwendig ist. Ein Performance-Gewinn ist aktuellen nur ganz selten vorhanden, meistens ist der Overhead durch den Octree jedoch größer als der Gewinn. Das muss ich noch beheben.

Zudem gibt es in der aktuellen Variante keine Waffen oder ähnliches. Man kann also nur durch die Map laufen, wobei der Dieb ein Nachtsichtgerät hat und der Wächter eine Taschenlampe. Der Dieb hat eine besondere "Fähigkeit": einen Double-Jump. Somit kann der Dieb auch Positionen erreichen, die der Wächter nicht erreichen kann. Ob das so bleibt weiß ich noch nicht, aber bisher finde ich das eine ganz gute Idee - auch wenn sie etwas unrealistisch umgesetzt ist.

Kurze Hilfe zur Demo
  • Einen Server Starten
    Um einen Server zu starten muss man Menü nur den Punkt "Host Server" auswählen. Dabei wird ein Server erstellt und man verbindet sich automatisch mit dem Server. Zudem wird der Server automatisch beim Master-Server registriert. Der letzte Punkt ist zwar deaktivierbar, jedoch mit etwas größerem Aufwand, da die GUI diese Option noch nicht zulässt. Also bitte nicht wundern wenn beim erstellen des Servers eine HTTP-Verbindung hergestellt wird.

    Damit sich andere zu eurem Server verbinden können, müsst ihr in eurem Router das Port-Forwarding korrekt konfigurieren. Dem NAT muss dabei gesagt werden, dass eingehende TCP-Verbindungen am Port 9594 zu eurer lokalen LAN-IP-Adresse weitergeleitet werden sollen. Wie ihr das bei eurem Router genau einstellt, kann ich hier leider nicht sagen. Aber wenn ihr bei Google nach den Begriffen "NAT Routing" oder "NAT Port Forwarding" sucht, solltet ihr fündig werden.
  • Zu einem Server verbinden
    Um euch zu einem Server zu Verbinden müsst ihr im Start-Menü die Option "Connect to server" auswählen. Danach habt ihr zwei Möglichkeiten: einmal könnt ihr die Server-Liste vom Master-Server abrufen oder ihr gebt die IP-Adresse manuell ein. Die Server-Liste wird dabei nicht automatisch aktualisiert, ihr müsst also immer manuell auf "Refresh" drücken. Nachdem ihr einen Server dann in der Liste markiert habt, klickt ihr unten auf "Connect".
  • Spielablauf
    Nachdem ihr bei einem Server gelandet seit, landet ihr in einer Art "Vorlobby". Dort könnt ihr bereits euer Team auswählen und Nachrichten schreiben. Sobald ihr das dann gemacht habt, klickt ihr unten rechts den Punkt "Ready". Sobald alle Spieler auch "Ready" sind, wird die Karte geladen. Danach landet ihr nochmal in einer Lobby. Dort könnt ihr dann nochmals euer Team auswählen. Nachdem alle aktiven Spieler sich wieder als "Ready" markiert haben, startet die Spielrunde. Wenn aktuell eine Spielrunde läuft, könnt ihr dieser nicht teilnehmen. Leider funktioniert der Spectator-Modus noch nicht wirklich, daher muss man leider warten.
  • Verfügbare Commands
    Wenn ihr den Fokus im Chat-Fenster habt, könnt ihr ein paar Commands ausführen. Dafür müsst ihr zuerst per "TAB" zwischen dem Command-Modus und dem Chat-Modus wechseln. Wenn ihr im Command-Modus seid, steht vor dem Eingabefeld der Text "cmd", ansonsten "say". Dann könnt ihr folgende Sachen eingeben:
    • name [neuer Name]: Ändert euren Namen auf [neuer Name]
    • changeteam [Team]: Wechsel in das Team [Team], wobei Team entweder "0" "1" oder "2" sein kann (ohne Anführungsstriche). "0" = Dieb, "1" = Wächter, "2" = Spectator.
    • say [text]: Schreibt eine Chat-Nachricht mit [Text]
    • net set time [TimeOut]: Ändert die Rundenzeit (nur Admin), Time muss dabei im Format "mm:ss" angegeben werden. Eine max. Rundendauer von 0 Sekunden wird dabei als "Unendlich" angesehen.
    • net set thieflives [value]: (nur Admin) Setzt die Anzahl der Leben für die Diebe, [value] ist dabei eine Zahl (ist noch unerheblich)
    • net set guardlives [value]: (nur Admin) Setzt die Anzahl der Leben für die Wächter, [value] ist dabei eine Zahl (ist noch unerheblich)
    • net set adminpassword [new value]: (nur Admin) Ändert das "Admin"-Password auf [new value]
    • net set servername [new value]: (nur Admin) Ändert den Server-Namen auf [new value]
    • net admin [Passwort]: Meldet euch als "Admin" an ([Password] ist dabei das Admin-Password)
    • net logoffadmin: (nur Admin) Meldet euch als "Admin" ab
    • net kick [Spielername]: (nur Admin) Trennt die Verbindung zum Spieler [Spielername]
  • Steuerung
    • WSAD: Steuerung
    • Leertaste: Springen
    • Shift: Rennen (gedrückt halten)
    • C: Hinkniehen / wieder aufstehen
    • TAB: Nachtsichtgerät (nur Dieb)
    • F: Taschenlampe (nur Wächter)
    • Strg: Eingabefelder aktivieren (gedrückt halten), mit S zum gewünschten Menüpunkt durchklicken und dann wieder zum Auswählen Strg loslassen
    • T: Chat-Eingabe-Fenster anzeigen

Anforderungen an die Demo
  • CPU mit mindestens 2 GHz
  • OpenGL 2.1 Grafikkarte (mindestens GeForce 7600 GT)
  • mindestens 256 MB Grafikkartenspeicher
  • mindestens 256 MB RAM

Ich schaue, dass ich heute den ganzen Abend einen Server laufen lasse - damit nicht jeder einen eigenen erstellen muss. Am Wochenende werde ich leider kaum Zeit haben und somit nicht online sein. Jedoch habe ich nächste Woche frei und schaue, dass ich dann öfter einen Server am Laufen habe.
Download: *klick* (ca. 22 MB, Version 0.2.2)

Grüße
David

_________________
Aktuelles Projekt: Gael - Development Blog
Website: LightBlackSoft.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: [Game] Gael
BeitragVerfasst: So Jun 26, 2011 23:45 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Mär 09, 2005 15:54
Beiträge: 372
Wohnort: München
Programmiersprache: Delphi, C#, FPC
So, mal wieder ein Update

*Bäng* - *Zisch* - *Keuch* ...
In Gael stand ich vor einer kleinen Entscheidung - entweder ich gebe alle Sounds "gezeichen" auf dem Bildschirm aus oder ich spiele sie über die Sound-Karte aus. Nach langem Überlegen habe ich mich natürlich für die Sound-Karte entschieden ;-).

Bisher habe ich bei meinen Projekten immer auf FMod gesetzt, doch diesmal habe ich einen Bruch gewagt. Gael benutzt nun Audorra!! :-) Hiermit wollte ich nochmal ein Lob an igel457 aussprechen für die wirklich gute Arbeit - auch wenn noch einiges zu tun ist. Ich hatte und habe immer noch einige kritische Probleme mit der Thread-Synchronisierung. Konkret geht es darum, dass ich einen TAu3DStaticEmitter im "OnStop"-Event freigebe. In der Demo "soundlist" habe ich mir das abgekuckt, daher denke ich, dass das allgemein kein Problem sein sollte. Jedoch bekomme ich immer wieder Access-Violations, die das komplette Programm runterziehen. Anscheinend wird das Event manchmal bereits aufgerufen obwohl der Emitter noch in Gebrauch ist. Ich habe das Problem für mich lokal erstmal damit behoben, dass ich die Emitter nicht direkt freigebe sondern sie zuerst manuell aus der Notification-Queue-Liste und aus der Emitter-Liste der Sound-Resource entferne. Danach füge ich den Emitter zu einer eigenen Liste hinzu, die den Emitter dann nach weiteren 10 Sekunden freigibt. Bis jetzt habe ich dadurch keine Probleme mehr gehabt. Um das Problem konkret nachzuvollziehen ist einiges zu tun, da in dem relativ einfachen Programm "soundlist" das Problem nicht auftritt. Je mehr das Programm arbeitet, desto wahrscheinlicher sind die Access-Violations. Igel habe ich übrigens noch nicht angeschrieben, da ich erst sicher gehen will, dass das Problem nicht bei mir liegt.

Naja, genug gemeckert ;-). Wie gesagt, die Engine kann nun Sounds abspielen (lassen) und das funktioniert bereits prächtig. Für alle, die nicht so häufig in den Kommentar-Thread schauen: seid dem letzten Release habe ich noch eine weitere Version veröffentlicht, die bereits Schüsse erlaubt. Das ganze habe ich nun mit Sounds aufgebessert und es funktioniert wirklich prächtig. Nun ist es nicht mehr ganz so eintönig, da man nun einiges auf die Ohren bekommt ;-) (bevor jetzt alle eifrig einen Download-Link suchen: in der Download-Version gibt es keine Sounds ...). Man hört nun die Fußtritte von einem selber und von anderen, die Schüsse sowie die Einschläge. Damit ihr euch das etwas besser vorstellen könnt, habe ich trotz der späten Stunde noch ein Video gemacht (Link). Die NPC haben keine Sounds, also nicht wundern ;-).

Die komplette Sound-Engine habe ich über ein abstraktes Interface implementiert. Dieses Interface kümmert sich dabei um die korrekte Resourcen-Verwaltung und um ein paar Helfer-Methoden. Die eigentliche Implementierung leitet die entsprechenden Commands dann nur noch an die benutzte Sound-Engine weiter. Es gibt zwei Sound-Engines in Gael. Einmal eine "NullSoundEngine", die alle Commands sozusagen verwirft. Als zweite gibt es die "AudorraSoundEngine", die die Commands an Audorra weitergibt. So könnte ich rein theoretisch noch zurück zu FMod ohne dass ich am eigentlichen Quelltext was ändern müsste. Jedoch möchte ich nicht wechseln, da ich mit Audorra zufrieden bin :-).

Usability-Verbesserungen
In den Tests ist mir erst so richtig klar geworden, dass die Lobby doch sehr unübersichtlich ist. Diese habe ich nun komplett überarbeitet und sollte nun um einiges intuitiver sein. Ein paar Sachen muss ich noch ändern, jedoch denke ich, dass es nun doch etwas besser sein sollte.

Das wars auch schon wieder (ist ja auch nicht so lange her seit dem letzten Post). Aber im Moment geht es wirklich gut voran. Im aktuellen Zustand könnte ich wahrscheinlich bereits 95% der geplanten Spiellogik ohne Probleme/Erweiterungen umsetzen.

Gruß
David

_________________
Aktuelles Projekt: Gael - Development Blog
Website: LightBlackSoft.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: [Game] Gael
BeitragVerfasst: Do Jul 14, 2011 21:08 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Mär 09, 2005 15:54
Beiträge: 372
Wohnort: München
Programmiersprache: Delphi, C#, FPC
Hallo,

nach ein paar erfolgreichen Wochen folgte nun wieder eine kurze Zeit, in der ich nicht groß an Gael weiterarbeiten konnte. Doch nun hab ich wieder was leckeres ;-)

(Realtime) Global Illumination
Manche von euch kennen das bestimmt - man liegt nachts im Bett und kann nicht einschlafen. Genau dann kommen einem jedoch die besten Ideen - und genau das ist mir am Montag wieder passiert.

Ich habe ja bereits vorher mal versucht indirektes Licht in Gael einzubauen. Dabei bin ich jedoch kläglich gescheitert. Nun habe ich mir Montag Nacht nochmals darüber Gedanken gemacht und habe mir eine Lösung überlegt. Ich habe mir bisher schon mehrere Paper zum Thema Global Illumination durchgelesen, habe jedoch immer relativ schnell auf Grund der Komplexität die Motivation daran verloren. Aber anscheinend ist bei mir doch was von den Papern im Kopf hängen geblieben, denn sonst wäre ich nicht auf die Lösung gekommen.

Gleich vorweg: mein Weg war zwar bisher relativ einfach zu Implementieren (ca. 6-8 Stunden), ist jedoch noch lange nicht ausgereift. Ich kann also noch nicht sagen, wie sich meine Vorgehensweise mit mehreren Lichtern verhält geschweige denn ob sich das Ganze in meiner Lagerhallen-Map überhaupt gescheit anwenden lässt. Zudem ist der Begriff "Realtime" nicht ganz so richtig - ich schaffe bei einem Licht in der relativ einfachen Testmap gerade mal 20 FPS.

Nun endlich zu den Implementierungsdetails: das indirekte Licht wird bei mir auf der CPU und nicht auf der Grafikkarte berechnet - ist zwar nicht optimal, reicht aber fürs erste. Also wie habe ich das ganze umgesetzt? -> Zuerst habe ich ein dreidimensionales Raster über meine Karte gelegt. Dieses Raster hat bei meiner Karte eine Auflösung von 32x16x16. Wie das geschulte Auge erkennt, sind diese Werte alle Power-Of-Two. Das hat auch einen Grund -> denn das Raster repräsentiert später eine 3D-Textur.

Nachdem ich nun dieses Raster korrekt über die Karte gelegt und korrekt skaliert habe, repräsentiert jeder Punkt in dem Raster (und somit auch in der späteren 3D-Textur) einen Koordinaten-Punkt auf der Karte. Nun mache folgendes: ausgehend von meinem Licht schieße ich mehrere Rays durch die Karte und schaue, wo sie mit der Karten-Geometrie kollidieren. Bisher habe ich 16 Punkte verwendet. Nun gehe ich das Raster durch und schaue, welche Punkte im Raster welche der 16 gerade berechneten Lichtpunkte sehen können - ebenfalls wieder simple Line-Intersection. Wenn nun ein Punkt im Raster einen Lichtpunkt sehen kann, speichere ich die Lichtfarbe sowie die Lichtrichtung in meinem Raster. Die Lichtfarbe berechnen sich dabei anhand der Entfernung, des Winkels sowie die Farbe der Lightsource multipliziert mit einer Reflection-Color der Wand.

Bevor ich nun mein Raster in zwei 3D-Texturen auf die Grafikkarte hochlade, bilde ich noch den Farbdurchschnitt der Farbpunkte und der Lichtrichtungen.

Nun zum Rendern: im Ambient-Light-Pass des Deferred-Renderes lese ich für jedes Fragment einfach den Farbwert sowie die Lichtrichtung aus dem nächstgelegenen Punkt in den beiden 3D-Texturen. Dafür berechne ich zuerst an welcher Position sich das Fragment in der Karte befindet. Da ich im Shader auch die Skalierung und die Transformation des 3D-Rasters, das ich bei der Berechnung benutzt habe, kenne, kann ich die Position auch einem Punkt in der 3D-Textur zuordnen. Danach lese ich einfach noch den Farbwert aus der 3D-Textur, schwäche ihn etwas (nicht komplett) anhand der Lichtrichtung in der 2. 3D-Textur ab und multipliziere das dann mit der Diffuse-Color des Fragments.

Da ich die 3D-Textur ja rein theoretisch nicht dauern neu berechnen muss, kann ich diese ja einmal für alle Lichter, die sich nicht ändern, berechnen und kann diese dann immer wieder verwenden. Problemtisch wird es, wenn sich eine Lichtquelle ändert - dann muss ich wieder für alle Lichter alles neu berechnen. Aber wie gesagt - ich bin gerade erst am Anfang ;-)

Nun ist aber Schluss mit Text - endlich Bilder ;-):
Szene 1 (links: nur direktes Licht, rechts: direktes + indirektes Licht): (zum Vergrößern klicken)
Bild Bild

Szene 2 (links: nur direktes Licht, rechts: direktes + indirektes Licht): (zum Vergrößern klicken)
Bild Bild

Szene 3 (links: nur direktes Licht, rechts: direktes + indirektes Licht): (zum Vergrößern klicken)
Bild Bild

Und weils so schön ist - hier noch ein Video

Ich hoffe, es gefällt.

Gruß
David

_________________
Aktuelles Projekt: Gael - Development Blog
Website: LightBlackSoft.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: [Game] Gael
BeitragVerfasst: Do Jul 21, 2011 19:37 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Mär 09, 2005 15:54
Beiträge: 372
Wohnort: München
Programmiersprache: Delphi, C#, FPC
Hallo,

nach wenigen Tagen gibts diesmal schon wieder ein Update.

Ich habe mittlerweile meinen Global-Illumination-Algorithmus etwas verfeinert und ein paar Fehler beseitigt. Er ist zwar noch lange nicht perfekt und es gibt auch noch ein paar Fehler, doch gemessen an der Zeit, die für die Berechnung benötigt wird, bin ich mit dem Resultat ganz zufrieden.

Als eine Optimierung speichere ich nun in einer PreProcessing-Phase, welche Punkte in der 3D-Textur von jedem Punkt aus sichtbar sind. Da eine komplette Sichtbarkeitstabelle zu viel Speicher brauchen würde (bei einem 32x32x32 Grid mehr als 1 Gigabyte), speichere ich bei jeder Node nur, welche Nachbarnodes sichtbar sind. Beim Berechnen gehe ich nun von einem Startpunkt aus rekursiv alle sichtbaren Nachbarnodes durch. Ich habe da zwar noch ein paar Probleme zu lösen (Stack-Overflow-Exceptions, Abarbeitung der Nachbarnodes noch nicht fehlerfrei, etc.), doch das kann erstmal warten.

Als nächstes will ich das GI-Data Handling erweitern. Und zwar soll man später mehrere Layer definieren können. Jedes Licht kann dann einem Layer zugeordnet werden. Da bei einer Lichtänderung die komplette 3D-Textur neu berechnet werden muss, müssen beim Layersystem dann nur die Daten für die Lichtquellen, die sich im geändertem Layer befinden, aktualisiert werden. So müsste ich später die GI-Daten für „statische“ Lichter nur ein mal berechnen, denn dynamische Lichter würde ich in separaten Layern unterbringen. Dadurch steigt zwar der Speicherverbrauch auf der GPU, aber das nehme ich in kauf. Ob ich das indirektes Licht überhaupt bei dynamischen Lichtern benutzen kann, hängt jedoch weiterhin primär davon ab, ob ich die Performance in den Griff bekomme.

Gestern Abend habe ich auch noch ein Video gemacht, welches das GI noch etwas verdeutlichen soll. Als Szene habe ich mal wieder das Sponza-Model von Crytek benutzt. Die Szene ist deutlich besser beleuchtet als damals bei meinen Reflection-Tests. Damals hatte ich noch 48 Lichter aktiv - nun sind es nur noch 8 (mit Sonne sind es 9). Jedoch schaut die Beleuchtung um einiges besser aus. Die kurzen Lags in dem Video entstehen übrigens bei der Neuberechnung des indirekten Lichtes. Zwischendurch mache ich zu Vergleichszwecken das indirekte Licht aus, also nicht wundern, wenn's mal sehr dunkel wird ;-).

Hier gibts das Video (ich empfehle Full-Screen).

Gruß
David

_________________
Aktuelles Projekt: Gael - Development Blog
Website: LightBlackSoft.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: [Game] Gael
BeitragVerfasst: Sa Feb 25, 2012 20:02 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Mär 09, 2005 15:54
Beiträge: 372
Wohnort: München
Programmiersprache: Delphi, C#, FPC
Nach langer Funkstille gibt es mal wieder ein Update.

Ich habe länger nichts mehr an Gael gearbeitet, da ich eine kleine Motivationsflaute hatte. Das lag daran, dass zum einen im November Skyrim herauskam ich für Wochen relativ abgelenkt war ;-). Zum anderen lag es an einer sehr gravierenden Änderung im Material-System, die zum einen lange keine Ergebnisse zeigte und zum anderen sehr viele Baustellen aufgerissen hat. Irgendwann habe ich mir dann gedacht - machste eine kleine Auszeit und überdenkst die Änderung nochmal. Doch in den letzten Wochen ist die Motivation wieder zurückgekommen und habe mich wieder an die ungeliebte aber nötige Änderung heran gesetzt. Nun funktioniert sie schon wieder einigermaßen und die Motivation war wieder voll da :-).

Es haben sich mittlerweile so viele Änderungen angesammelt, dass der Post extrem lang werden würde. Daher will ich nur kurz auf die wichtigste Sachen eingehen:

Multithreading
In der Script-Engine war schon lange Multi-Threading möglich - jedoch konnte ich das noch nicht so wirklich einsetzen, da ich den OpenGL-RenderContext-Manager nicht so erweitert hatte, dass ich weitere Contexte für weitere Threads erstellen konnte. Dies habe ich nun nachgeholt und habe erst mal das Laden einer Map in einen separaten Thread ausgelagert. Während dem Laden einer Map habe ich dann zum Test den Hintergrund aus dem Hauptmenü weiter gerendert - und es hat funktioniert :-). Im gleichen Zuge habe ich dann die Script-Engine für das Multi-Threading extrem erweitert. Inspiration habe ich mir dabei von der TPL (Task Parallel Library) von .NET 4.0 geholt. Meine Script-Engine hat jetzt ein voll funktionsfähiges Monitor-Objekt, eine ConcurrentList, eine ConcurrentQueue sowie einen Task-Scheduler. Mein Task-Scheduler ist dabei eine Mischung aus dem Task-Scheduler aus .NET und aus dem iOS-Framework - wobei das ganze natürlich nicht so komplex aufgebaut und optimiert ist. Zudem sind anonyme Methoden inklusive Closures in meine Script-Engine hinzugekommen. Hier mal ein Beispiel, wie ich extrem einfach eine Methode in einen Thread auslagern kann:

Code:
  1.  
  2. uses
  3.   System.Threading;  
  4.  
  5. procedure WaitForValue(WaitFor: function: boolean of object; WaitAction: TActionEvent);
  6. begin
  7.   if @WaitFor = nil then
  8.      raise ENullReference.Create('Wait value can not be nil');
  9.   if @WaitAction = nil then
  10.      raise ENullReference.Create('Wait action can not be nil');
  11.      
  12.   while not WaitFor() do
  13.     WaitAction();
  14. end;
  15.  
  16. var bDone  : boolean;
  17.     action : TActionEvent;
  18. begin
  19.   bDone := False;
  20.   Console.WriteLine('Performing some action in background ...');
  21.  
  22.   // Define a long background action
  23.   action := procedure() => for var i: integer := 1 to 5 do
  24.                            begin                                        
  25.                              Console.WriteLine('Step ' + i.ToString);
  26.                              TThread.Sleep(TTimeSpan.FromSeconds(0.6));
  27.                            end;
  28.                            
  29.   // Run in background thread - after work is done, the anonymous method is called
  30.   action.InBackground(procedure(Sender: TObject) => bDone := True);
  31.  
  32.   // Wait until the anonymous method trigges the Done-Variable; while waiting, this wait-method is constantly called
  33.   WaitForValue(function()  => result := bDone,
  34.                procedure() => TThread.Delay(TTimeSpan.FromSeconds(0.1)));
  35.    
  36.   // Write "we are done"
  37.   Console.WriteLine('Action done - press ESC to quit');
  38.   WaitForValue(function()  => result := Console.ReadKey.ToASCIIIndex = KeyCodes.Escape,
  39.                procedure() => );
  40. end.

Klar ist das mit dem WaitFor-Pulling nicht optimal, aber das ist ja nur ein Beispiel. Das Threading ist in Zeile 23: action.InBackground(...) versteckt.

Indirect-Lighting-Changes
Eine weitere große Änderung habe ich beim Indirekten Licht vorgenommen. Ich habe schon mal geschrieben, dass ich mehrere Layer für das indirekte Licht definiert habe. Dies habe ich nun erweitert. Erstmal wie es bisher war: Ein Layer für indirektes Licht ist im Endeffekt eine 3D-Textur, die auf die Geometry gemappt wird. Die einzelnen Farbwerte der 3D-Textur werden dabei von den Lichtern gefüllt, die mit dem Layer verknüpft sind. Sobald nun ein Licht sich ändert, musste ich alle Farbwerte aktualisieren - dabei musste ich die Lichter auch mit einbeziehen, die sich nicht geändert haben. Nun habe ich folgendes gemacht: Jedes Licht speichert, welche Farbwerte in die 3D-Textur des Layers geschrieben werden sollte. Falls sich nun ein Licht ändert, berechne ich für dieses Licht einfach die neuen Farbwerte und merge dann die neuen Daten des geänderten Lichtes mit den Daten der anderen Lichter in dem Layer. Zwar ist die Berechnung der einzelnen Farbwerte immer noch nicht Realtime-Fähig, aber ich kann ohne Aufwand Lichter an- und ausschalten und den Layern einfach mit den Lichtern, die an sind, neu befüllen. Zwar braucht diese Methode je nach Auflösung der 3D-Textur viel Arbeitsspeicher, aber RAM habe ich ja genügend. Wenn ich stattdessen für jedes Licht einen einzelnen Layer definieren würde, hätte ich zum einen den gleichen RAM-Verbrauch, zum anderen würde die 3D-Textur auf der Grafikkarte auch noch Speicher verbrauchen - und dort habe ich nicht so viel.

Render-Octree und Portal-Engine
Ich habe ja schon mal geschrieben, dass ich den bisherigen Octree komplett durch ein neues System ersetzen will. Der bisherige Octree war sehr schlecht designed und es war oft langsamer, mit dem Octree zu Rendern als einfach alles blind auf die Grafikkarte hochzuschicken. Daher habe ich mich hingesetzt, und diesen Teil komplett ersetzt. Ich habe jetzt ein Portal-System, wobei jeder Sector einen eigenen Octree hat. Wenn der Inhalt eines Sektors sehr klein ist, besteht der Octree nur aus einer Node, ansonsten so wie man das von einem Octree auch kennt. Ein Sektor definiert sich 1..n verschiedene Ebenen. So muss ich mich nicht auf einen Würfel oder ähnliches Beschränken. Die Portale bestehen aus einer beliebigen Fläche, wobei hier meistens natürlich ein einfaches Rechteck reicht. Das Ganze flutscht schon ganz gut, wobei ich später bestimmt noch ein paar Stellen finde, an denen ich noch ein paar Sachen optimieren kann.

Editor
Was bringt mir die Engine, wenn ich keinen Content erstellen kann - richtig, relativ wenig. Daher habe ich mich nun endlich mal hingesetzt und den Editor extrem erweitert und verbessert. Dabei habe ich zum einen das Handling mit den Objekten und deren Triangles erweitert bzw. mehr Manipulationsmöglichkeiten eingebaut und ich habe das neue Material-System in den Editor integriert. Das neue Materialsystem erlaubt es mir nun endlich, die Materials an sich in Ordner zu speichern und diese schnell in die aktuelle Karte zu importieren. Das war vorher nicht möglich, da ich anfangs die unsinnige Idee hatte, dass jede Map ihre eigene Material-Definition speichert. Ich weiß auch nicht, was mich dazu bewogen hat - auf jeden Fall hat diese Entscheidung einiges an Zeit gekostet. Das neue, Datei-basierte System erlaubt es mir nun, einen Content-Browser zu erstellen, in dem ich alle verfügbaren Materials sehen und bearbeiten kann. Dieser Library-Browser ist noch nicht fertig, aber die Grundstruktur ist bereits vorhanden.

Den aktuellen Stand des Editors könnt ihr wieder mal in einem Video sehen - nun alle festhalten - mit Ton :-). In dem Video zeige ich euch, wie ich mir ungefähr vorstelle, dass man eine simple Karte mit zwei Räumen erstellt. Für die Qualität des Videos möchte mich im gleich mal entschuldigen - ich habe auf die schnelle nichts besseres hinbekommen.

Hier gehts zum Video, ich empfehle wieder Fullscreen und 1080p-Qualität.

Gruß
David

_________________
Aktuelles Projekt: Gael - Development Blog
Website: LightBlackSoft.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: [Game] Gael
BeitragVerfasst: So Sep 23, 2012 23:24 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Mär 09, 2005 15:54
Beiträge: 372
Wohnort: München
Programmiersprache: Delphi, C#, FPC
Hi an alle,

nach sehr langer Abstinenz melde ich mich auch mal wieder. Tja, woran liegt das? - ich habe in den letzten Monaten wenig Zeit gehabt, um an Gael weiterzuarbeiten. Es gab zwar ab und zu ein paar Wochen, an denen ich wirklich was machen konnte, aber was wirklich sichtbares ist dabei nicht herausgekommen. Daher habe ich meine heutige Errungenschaft mal als Anlass genommen, wieder mal ein Update zu bringen. Es gibt mal wieder was zu sehen :-).

Realtime Local Reflections
Ich bin zufällig im Netz über ein paar Videos über Realtime Local Reflections (oder auch Screenspace Reflections) gestoßen und fand den Effekt wirklich gut. Also habe ich mich auf die Suche nach Papers, Beispielen, etc. gemacht. Nach ein paar Stunden wusste ich dann, wie der Effekt funktioniert, welche Einschränkungen er hat usw. Also habe ich mir gedacht: das will ich auch haben. Also habe ich einfach mal angefangen und Shader-Code geschrieben. Nachdem jetzt 6 Tage vorüber sind und sehr viele Stunden Arbeit erledigt wurde, habe ich es endlich geschafft: es gibt eine funktionierende Version. Über die Qualität und Geschwindigkeit war ich wirklich positiv überrascht, wobei meine Implementierung bestimmt noch einige Optimierungen vertragen könnte - eine Woche Arbeit produziert einiges an Shader-Code-Leichen. An der Engine musste ich eigentlich nichts ändern - es war eigentlich schon alles vorhanden. Eigentlich in dem Sinne, dass ich die Engine doch kurz anfassen musste um ein paar neue Uniform-Variablen einzubauen. Im nun laufenden Shader-Code werden diese neuen uniforms jedoch überhaupt nicht benutzt, also doch nur sinnlose Arbeit gewesen.

Funktionsweise
An alle, die mit dem Begriff noch nicht viel anfangen können, versuche ich das ganze kurz zu erklären.
Wenn ich bisher immer an reflektierende Oberflächen gedacht habe, habe ich immer an Render-To-Texture, Planare Reflektion und CubeMaps gedacht. Zudem hatte ich immer im Hinterkopf: Reflektionen sind extrem Rechenaufwendig, da die Scene mehrfach gerendert werden muss. Das mag für eine einfache Fläche noch gehen, aber sobald mehrere Flächen gleichzeitig reflektieren sollen, wurde das Ganze ganz schnell zum Problem.

Dieses Problem versucht RLR zu beheben: mit RLR werden Reflektionen als Post-Scene-Effekt erstellt, ohne das die Scene neu gezeichnet werden muss. Das ganze basiert von der Idee her auf Raytracing. Im Fragmentshader erstelle ich für jeden reflektierenden Pixel einen Reflection-Ray, den ich dann durch die Scene schicke. Bei einer Intersection halte ich an, nehme mir den Farbklecks an der Intersection-Position und addiere ihn an den Ursprungsort der Reflection-Rays. Wenn man es genau nimmt, prüfe ich jeden Pixel auf dem Bildschirm, welcher Pixel sich in diesem spiegelt. Somit gibt es bei RLR keine wirkliche Unterscheidung mehr zwischen einer planaren Reflektion und einer CubeMap. Jeder Pixel für sich ist eine Reflektions-Plane.

Leistung
Das klinkt sehr aufwendig, ist es auch, aber doch nicht ganz so schlimm wie man meint. Bei mir läuft der Shader in meiner Testszene auf FullHD und ca. 70% Reflektierende Pixel auf der gesamten Bildschirmfläche mit ca. 30 FPS - ohne Shader-Optimierungen. Es sind noch ein paar unnötige Texturzugriffe drinnen, die ich auf jeden Fall beseitigen kann. Zudem muss man sich vor Augen halten, wie oft ich die Scene für den gleichen Effekt hätte neu zeichnen müssen, um das ganze mit planaren Reflektionen zu machen. Ich gehe mal von ca. 30-50x aus - also grob geschätzt etwas weniger als 30 FPS :-).

Limitierung
Wer jetzt denkt, RLR ist perfekt für überall, der hat sich natürlich geschnitten. RLR ist gut für leicht spiegelnde Oberflächen wie z.B. sauberes Parkett oder Fließen, jedoch nicht für wirklich spiegelnde Oberflächen wie z.B. einen Spiegel :-). Zudem ist das Problem: da man die Reflektionen als Post-Scene-Effekt einbaut, können auch nur diese Pixel reflektiert werden, die auch ganz normal sichtbar sind - man kann also nicht um die Ecke oder hinter sich schauen.

Video!!!111elf
Damit ihr euch mal ein Bild davon machen könnt, habe ich wie immer ein Video gemacht. Das findet ihr hier (ich empfehle FullHD und Vollbild). Bei dem Video solltet ihr beachten, dass alle Reflektionen "echte" Reflektionen sind, also keine Specular-Punkte von Lichtquellen oder ähnliches. Auch schön zu sehen ist zum einen die Flexibilität und gleichzeitig auch die Limitung der Technik - und zwar anhand des roten Balles links unten. Bei den Spiegelungen sei noch gesagt - es reflektiert sehr viel (manches auch etwas zu viel aus Demonstrationsgründen). Unter anderem die Lüftungsrohre, die Wasserrohre an der Wand, alle Wände sowie der komplette Fußboden. Es gibt auch noch ein kleines Problem: die Decals auf dem Boden reflektieren auch - obwohl sie nicht sollten. Das liegt nicht an der Technik, sondern an einem kleine Bug meinerseits.

Ich versuche morgen Abend noch ein paar Screenshots zu machen, mit denen ich die Vorteile, aber auch die Limitierungen noch etwas besser herausarbeite.

PS: der Ausschnitt der Map ist von einer Idee, die ich seit mehreren Wochen versuche umzusetzen, die sich etwas Abseits der ursprünglichen Spielidee bewegt. Aber dazu sage ich jetzt noch nichts ;-)

Gruß
David

_________________
Aktuelles Projekt: Gael - Development Blog
Website: LightBlackSoft.com


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 50 Beiträge ]  Gehe zu Seite Vorherige  1, 2, 3, 4  Nächste
Foren-Übersicht » Sonstiges » Projekte


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 6 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.037s | 17 Queries | GZIP : On ]