[Projekt] CyberDive (MARPG)

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.
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: [Projekt] CyberDive (MARPG)

Beitrag von Artificial Mind »

Ok, Font-Rendering-Engine schreiben, die auch noch performant und cool ist, ist nicht-trivial :D

Ich möchte ja Signed Distance Fonts benutzen, um kostengünstig Alphablending, Outlines, Glows, Shadows usw. in den Fonts unterstützen zu können und gleichzeitig an der Auflösung der Basis-Texturen zu sparen.
Folgende Schritte gehen bereits:
  1. für jeden Char ein High-Res (erstmal 512 Höhe) Bild zeichnen (per System.Drawing)
  2. für jeden Char die Signed Distance High-Res Karte berechnen
  3. alle High-Res Bilder auf die gewünschte Höhe zum Speichern (nicht mit der nachher zum Zeichnen gewünschte Höhe) runterskalieren (hier z. B. 128 angedacht)
  4. jedes Bild links und rechts so weit beschneiden wie es geht (sprich bis die signed distance function nicht mehr 0 ist)
  5. alle Bilder auf eine gemeinsame Höhe zusammencroppen (hier 108)
  6. alle Bilder per LPT-Algorithmus (4/3-Approximation für Scheduling) in eine power-of-two Texture packen
Signed Distance Font Texture
Signed Distance Font Texture
uff.

Nachtrag:
Ich bin natürlich Unicode-kompatibel ;)
Hiragana + Katakana in Signed Distance
Hiragana + Katakana in Signed Distance
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: [Projekt] CyberDive (MARPG)

Beitrag von Artificial Mind »

So, endlich funktioniert der Font-Renderer! (per Geometry Shader)
Allerdings muss ich noch ne ganze Menge Caching einbauen damit große Mengen Text mit vergleichsmäßig wenig dynamischen Texten performant gezeichnet werden können.
Signed Distance Font mit Outline und Glow
Signed Distance Font mit Outline und Glow
mit der signed distance kann man sehr viele coole Effekte hinbekommen, eignet sich auch für irgendwelche Decals.
Obwohl die Font-Textur nur mit ca. 108 Pixeln Höhe pro Zeichen gespeichert ist und nachher mit ~250 Pixel Höhe angezeigt wird, sieht man nahezu keine Artefakte, ich bin begeistert.
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: [Projekt] CyberDive (MARPG)

Beitrag von Artificial Mind »

So, das basic-GUI-System steht und es gibt Labels.
Strings können jetzt nach Wunsch automatisch gewrappt werden.
Nachdem ein GUI auf ein solches Quad gerendert wurden, werden auch die Mipmaps neu generiert.
Der Text wird hier gerade auf das GUI in einen seperaten Framebuffer gezeichnet, sodass die Schriftauflösung durch die GUI-Auflösung begrenzt ist. Später möchte ich allerdings auch alternativ Text direkt in 3D zeichnen können, sodass ich dort durch die signed distance function wieder sehr viel bessere Qualität bei Magnifikation habe.
3D GUIs mit Labels
3D GUIs mit Labels
Rechts gibt es wieder den Shader Debugger mit Hotswap, erweitert um Scintilla.NET Source Code Editor mit Syntax Highlighting (mit C# Highlighting, keine Lust gehabt, einen GLSL Lexer zu erstellen) und vernünftigem Undo.
Außerdem sieht man hier mein Shader "Specification" System, das mit einfachen #ifs im ShaderSource arbeitet und dann runtime die Shader mit den gewünschten Flags kompiliert, sodass ich z. B. beim normalen Geometrie-Shader per Flag einstellen kann, ob ich alle Textur-Channels mit einzelnen Texturkoordinaten habe oder eine Koordinate für alle Channels, ohne mehrere Kopien des Shaders im Projekt zu haben.
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: [Projekt] CyberDive (MARPG)

Beitrag von Artificial Mind »

Neustes GUI-Element: Panels
ebenfalls per Signed Distance Function, diesmal aber prozedural aus nem Shader und nicht per Textur. Optionales Chamfering pro Ecke (hier left-upper und right-bottom).
Panels
Panels
Benutzeravatar
Jeason
Beiträge: 41
Registriert: 07.09.2010, 22:58

Re: [Projekt] CyberDive (MARPG)

Beitrag von Jeason »

Sieht sehr gut aus :) Wie performant läuft das ganze? Ist dir da C# nicht im weg?
Ich verkaufe diese feinen Lederjacken.
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: [Projekt] CyberDive (MARPG)

Beitrag von Artificial Mind »

Läuft alles ziemlich performant, in C# konnte ich schnell nen vernünftiges Caching-System bauen, um OGL-Calls zu minimieren. Der OpenTK Wrapper hat nahezu keinen Overhead. Bei der Rendering Engine ist mir C# sicher nicht im Weg. Ich denke bei aufwendigen AI Berechnungen (Viele Graphsuchen, Decision Tree Learning, Planning, Neural Networks etc.) könnte es problematisch werden, da muss ich eben eventuell C++ Module für schreiben (welche sich ja zum Glück gut einbinden lassen und unter Windows gibt es sogar eine Art "Mixed Mode" wo man nahezu keinen Overhead zwischen native/C# Wechsel hat (darauf basiert Mogre z. B. mittlerweile)).
Um mal Werte zu nennen: ich bin bei 13 ms GPU Zeit, 1.5ms CPU Zeit pro Frame und das bei meiner 9800 GT die schon durch meine 4 Full HD Bildschirme stark ausgelastet ist (Bevor jemand fragt: ich habe 2 9800 GT dran, jede mit zwei Bildschirmen, aber der Windows DWM muss die Ressourcen zwischen den beiden Grafikkarten synchronisieren, damit man Fenster rumschieben kann, ohne dass man die "Grafikkartengrenze" merkt. 4 Bildschirme lasten die Grafikkarten gut aus ;) ) Dabei sind die 13 ms inklusive HDR, Bloom, Deferred Shading und Transparent Composition (Brechung und so) zu verstehen, also sehr viel konstanter Overhead schon mit drin, sodass Szenenkomplexität erstmal nicht so viel ausmacht.
Momentan braucht das Updaten eines der lorem-ipsum-GUIs leider noch relativ lange (0.5 ms oder so) weil ich beim Font-Rendering noch kein Caching habe und viel Framebuffer und Shader umgebunden und konfiguriert werden müssen ... da lässt sich noch gut was rausholen, denke ich.
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: [Projekt] CyberDive (MARPG)

Beitrag von Artificial Mind »

So:
  • Text kann aligned werden (selbst automatisch umgebrochene lange Texte)
  • Schnittpunktberechnung zwischen Mouse-Ray und GUI-Plane in 3D
  • "Hover-Stack" mit Mouse-Handling für GUIs
  • Buttons
  • Die Panels können jetzt unterschiedliche Transparenzwerte für Innen, Outline und Glow haben (sodass z. B. das Outline opaque ist, aber Innen 30% transparent)
Buttons
Buttons
Ja, man kann GUIs auch von hinten benutzen *g*
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: [Projekt] CyberDive (MARPG)

Beitrag von Artificial Mind »

So es hat sich wieder ein bisschen getam:
  • Es gibt nun GUI-Templates, die die Gelegenheit haben, die Controls zu stylen.
  • GUIs können serialisiert und deserialisiert werden.
  • Es gibt einen rudimentären Designer, um die GUIs runtime zu verändern (siehe Screenshot)
  • Ich habe eine Scenen-Klasse zum verwalten aller Szenendaten erstellt, die unter anderem den Input der GUIs verwaltet, sodass sich Fokus und Mouse-Events richtig verhalten, wenn man mehrere GUIs in 3D übereinandersieht (man kann auch durch "leere" Bereiche eines GUIs "durchklicken")
GUI Designer
GUI Designer
Hier sieht man den aktiven Designer. Der GUI-Renderer erkennt den Designer-Modus und malt dann automatisch farbige Rechtecke um die Controls, damit man die Mouse-Over Bereiche richtig einschätzen kann und so. (Man sieht auch, dass die Labels noch keine richtige Größe haben, obwohl der Text richtig ist. Steht schon auf meine "TODO" ;) )
Ohne GUI-Designer kann man nicht arbeiten, statische GUIs per Code handerstellen ist ja wohl die Manifestation schlechten Codes ohnegleichen.

Ich hatte mich Sonntag und Montag auch mal um eine vernünftige Serialisierung und Deserialisierung meiner Weltdaten (wisst ihr noch, die generierte Welt aus 60.000 Geozonen der Größe 100km x 100km) gekümmert. Bis auf die Straßenssysteme (die noch mal eine gründliche Überarbeitung brauchen) wird alles in ca. 2-3 sec gespeichert und das Laden aller Daten, die für die Städte relevant sind dauer ca. 1 sec. Soll die ganze Welt (also alle Geozonen) geladen werden, brauchts ca. 6-7 Sekunden. Dabei ist mein Format noch relativ verbose, es werden zu den Daten auch noch Feldname und Typname gespeichert, sodass ich bei fehlerhaftem Laden nicht nur den erwarteten Feldnamen sondern auch den Typen davon habe. In diesem Format ist die bisherige Welt ca. 100 MB Groß, in der nächst kleineren Variante (Hashvalue des Feld-Typ-Strings speichern) ist es sicherlich unter 20MB.
Ist schon echt angenehm, alle relevanten Daten in ca. 1 sec zu laden, anstatt min. 5 Minuten völlig ausgelastete 8 Kerne zu haben.
Ich arbeite momentan auf ein "Hauptmenü" im Client hin, welches die Weltkarte vom Server bekommt und rudimentäre Charactererstellung erlaubt.
RazorX
Establishment
Beiträge: 156
Registriert: 23.12.2010, 14:13
Kontaktdaten:

Re: [Projekt] CyberDive (MARPG)

Beitrag von RazorX »

Krass! (mehr fällt mir dazu nicht mehr ein^^)
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: [Projekt] CyberDive (MARPG)

Beitrag von Artificial Mind »

Danke, sowas motiviert immer gut :)
Ich hätte auch kein Problem die Render-Engine im Endeffekt Open Source zu machen, allerdings weiß ich nicht inwieweit Interesse bestünde und die hat sicher auch nicht so viel technische Genialität wie breeze ;)
RazorX
Establishment
Beiträge: 156
Registriert: 23.12.2010, 14:13
Kontaktdaten:

Re: [Projekt] CyberDive (MARPG)

Beitrag von RazorX »

Mich motiviert deine Arbeit auch ungemein wieder was in die Richtung zu machen (nachdem ich nächsten Dienstag die letzte Prüfung geschrieben habe :D). Wie ich schonmal erwähnte, finde ich es interessant wie komfortabel das doch mit C# erscheint und ich denke ich werde das mal ausprobieren. Arbeite aber erstmal noch an deiner Engine bevor du die OpenSource machst (bei breeze2 hat es ja auch seine Zeit gedauert) und ich bin mir sicher das dann bestimmt Leute dafür Verwendung finden werden.
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: [Projekt] CyberDive (MARPG)

Beitrag von BeRsErKeR »

Kann mich da nur anschließen. Sieht ziemlich vielversprechend aus und motiviert mich auch mal wieder bischen was zu Coden. Gerade in Hinblick darauf, dass ich seit kurzem auch mit C# arbeite.
Ohne Input kein Output.
RazorX
Establishment
Beiträge: 156
Registriert: 23.12.2010, 14:13
Kontaktdaten:

Re: [Projekt] CyberDive (MARPG)

Beitrag von RazorX »

Hab gestern auch mal angefangen (ich hab doch keine Ruhe mehr gehabt :D) und muss sagen, dass es sehr angenehm ist mit dem OpenTK zu arbeiten. Ich habe dann auchmal als erstes einen LiveShader Editor mit ScintillaNET gebastelt und eine kleine GLSL Konfigurationsdatei geschrieben (mit AutoComplete). Leider hab ich es nicht hinbekommen mehr als zwei Keyword Gruppen zu färben, da der Cpp-Lexer auf WORD und WORD2 beschränkt ist :(. Wie man sehen kann sind die Wörter noch ein bisschen formatiert, sodass man es einfach in neue Gruppen bauen kann. Wäre cool wenn jemand weiß wie das geht, ansonsten ist es denke ich auch so schon eine Erweiterung (@Artificial Mind: ich dachte ich poste die mal hier, da du ja keine geschrieben hast und mit C# Highlighting arbeitest).

001 - Tools - Shader Live Editor.png
Dateianhänge
scintilla_glsl.xml
(6.84 KiB) 428-mal heruntergeladen
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: [Projekt] CyberDive (MARPG)

Beitrag von Artificial Mind »

Vielen Dank für das Engagement, ich werde das gleich mal einbauen ;)
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: [Projekt] CyberDive (MARPG)

Beitrag von Artificial Mind »

So nochmal danke, RazorX, ich habe die xml eingebunden und es sieht soweit gut aus (Credit-Hinweis-Notiz ist auch erstellt ;) )
Dann gibt es nun das neue GUI Control "TextBox" und halbwegs vernünftiges Key-Handling.
Man kann neue Controls platzieren und ganze Control-Teilbäume per Strg-C kopieren.
Ganze GUIs können nun gespeichert und geladen werden.
Der Zugriff vom Programm auf die Controls wird per Name gemacht, der pro GUI einzigartig ist für jeden Control (Name kann auch null sein, dann wird das Feld ignoriert)
GUI Designer
GUI Designer
Ich bin immer noch am überlegen wie ich für TextBoxen einbaue, dass die Cursor-Position richtig gesetzt wird, wenn man reinklickt. Denn die komplette Rendering-Logik ist von der GUI-Logik getrennt (also die GUI-Logik ist sogar eine eigene dll), die einzelnen Buchstabengrößen kann aber eigentlich nur der Renderer kennen ... Vielleicht muss ich da irgendwie nen ekligen Feedbackweg einbauen, der dann das schöne Public-Interface der Klasse beschmutzt. Oder hat jemand einen besseren Vorschlag?^^

Nachtrag: GUI-Entwicklung ist schon architekturiell herausfordernd *g*
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: [Projekt] CyberDive (MARPG)

Beitrag von CodingCat »

Die Frameworks, die ich kenne, bieten in irgendeiner Weise eine separate Font-Metrics-Komponente, die sowohl dem Rendering als auch dem Layouting Informationen über die Ausmaße von Buchstaben / Zeichenketten bereitstellt. Ansonsten ja, UI-Entwicklung ist anstrengend, quäle mich gerade selbst durch (und ich nutze dabei schon ein fertiges Framework ;)). Sieht auf jeden Fall gut aus und hört sich gut an, was du da machst; über Ingame-UI will ich eigentlich gar nicht nachdenken. :mrgreen: Aber diese Distance-Field-Geschichte wollte ich auch schon immer mal implementieren, schön, dass sie auch bei dir gut funktioniert.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: [Projekt] CyberDive (MARPG)

Beitrag von Artificial Mind »

Ja, ich bin über die Signed-Distance-Fields auch echt positiv überrascht, die lassen sich auch für nahezu alle anderen 2D-Formen benutzen.

Wenn meine Ingame-UIs nachher alle in 3D bedienbar sind, bin ich eigentlich an meinem Ziel. Leicht futuristische Welt mit 3D-Overlay-Glow-GUIs, das passt einfach. (*hust* Ghost in the Shell *hust*) Wenn man in nen Laden reinkommt und keinen vernünftigen Spam-Schutz hat, dann "ploppen" überall so kleine 3D-Werbefenster auf und wollen einem irgendwas andrehen oder so, da lässt sich viel Unsinn mit treiben :)

Eine Font-Metrics-Klasse hört sicht super an, da kann ich dann auch in hübsch Zeilen-Wrapping, Alignment usw. implementieren.
Benutzeravatar
Schrompf
Moderator
Beiträge: 5402
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas
Wohnort: Dresden
Kontaktdaten:

Re: [Projekt] CyberDive (MARPG)

Beitrag von Schrompf »

Ich habe bei meiner GUI dasselbe Problem... der Renderer ist getrennt von der GUI, demzufolge kann die GUI manche Eingabeereignisse nicht so genau interpretieren. Das gleiche Spiel ja auch bei automatischem Layout - zur Erklärung: ich bin einer der vollkommenen Idioten, von denen Du so charmant vorhin gesprochen hast, die die größte Sünde überhaupt begehen: ich baue meine GUI im Code zusammen. Sind vielleicht zwei drei Zeilen pro Komponente, das Layout passiert automatisch. Jede Komponente hat eine Minimalgröße und optional einen Wachstumswunsch, und das Layout ordnet nach diesen Vorgaben die Komponenten untereinander an. Nur wär es halt manchmal doch praktisch, die Kenntnisse des Renderers da zu haben, um z.B. zu bestimmen, wie groß eine Textbox sein müsste, um allen Text darin darzustellen.

Ich werde das wahrscheinlich per Callback-Interface lösen. Immerhin ist ja üblicherweise eine GUI an einen Renderer gebunden, Austausch zur Laufzeit passiert nur selten. Und wenn, kann man halt einfach das automatische Layout nochmal anstoßen. Mit dem Interface könnte dann die GUI bequem Textbreiten, -größen und -positionen abfragen, ohne sich selbst die Hände mit Layout-Details schmutzig zu machen. Bisher bin ich aber ehrlich gesagt komplett ohne ausgekommen... die GUI sollte gleichermaßen per Tastatur, Maus oder Gamepad bedienbar sein, da ist die genaue Positionierung des Cursors im Eingabefeld das kleinste Problem.

[edit] Das Callback-Interface wär ja quasi die Font Metrics... am Ende reden wir doch alle vom Gleichen :-)
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: [Projekt] CyberDive (MARPG)

Beitrag von Artificial Mind »

Ich habe selbst auch schon genügend GUIs per Hand gecoded und mich ab und zu nichtmal geschämt. Die Screenshots deiner GUIs sahen aber auch nach Konsolen-GUIs aus (also GamePad-kompatibel wie du sagtest), da ist ein lineares Layout und einfache Struktur ja quasi Rahmenbedingung. Dort ist auch der GUI-Code nicht so unübersichtlich. Meine GUIs haben allerdings absolute Positionierungen und sollen auch für komplexere GUIs benutzt werden können. Und wenn ich mir mal den Characterscreen von einem handelsüblichen MMORPG angucke (ja, ich wähle hier ein Extrembeispiel, aber ARPG Char-Screens sehen meist nicht allzu viel weniger komplex aus), dann möchte ich die 100 Labels, 30 Images, 50 Buttons in Kreuz-und-Quer-Anordnung nicht per Hand coden müssen. Ich denke für dein Spiel ist dein GUI genau richtig, aber ich glaube nicht, dass ich bei meinem Spiel mit so einfachen Layouts und Bedienungen auskommen werde.
Dazu kommt, dass ich das Gefühl habe, dass die meisten Spiele mittlerweile (oder immernoch) die GUI-Bedienbarkeit nicht durch gute Technik lösen, sondern durch Trivial-GUIs. Wenn ich mir z. B. Skyrim angucke, dann muss ich sagen, dass das GUI dort grauenvoll ist. Nicht nur, dass es ein Konsolen-GUI auf den PC portiert ist, es ist auch noch schlecht portiert und die Maussteuerung im GUI hat sicher der Kopier-Kaffee-Praktikant in der Mittagpause geschrieben.
Ich plane für mein Spiel, dass viel Wert auf Information gelegt wird und da brauche ich einfach ein solides GUI für. Insbesondere Strg-C/Strg-V sollte bei nahezu allen Texten funktionieren. Es ist auch ein kleines "Internet" im Spiel geplant, für dass ich dann noch einen dezenten HTML-Converter in mein GUI-Format schreiben werde.

[edit] @Schrompf: Ja, dass das Callback-Interface die Font-Metric-Klasse repräsentiert ist mir auch eben aufgefallen^^ Um ehrlich zu sein habe ich die strikte Trennung von Rendering und Logik im GUI von dir abgekupfert, weil ich die Idee so gut fand, als du das in deinem Thread geschrieben hast ;)
Benutzeravatar
dot
Establishment
Beiträge: 1752
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [Projekt] CyberDive (MARPG)

Beitrag von dot »

Artificial Mind hat geschrieben:Ich bin immer noch am überlegen wie ich für TextBoxen einbaue, dass die Cursor-Position richtig gesetzt wird, wenn man reinklickt. Denn die komplette Rendering-Logik ist von der GUI-Logik getrennt (also die GUI-Logik ist sogar eine eigene dll), die einzelnen Buchstabengrößen kann aber eigentlich nur der Renderer kennen ... Vielleicht muss ich da irgendwie nen ekligen Feedbackweg einbauen, der dann das schöne Public-Interface der Klasse beschmutzt. Oder hat jemand einen besseren Vorschlag?^^
Ich weiß nicht wie dein Font-Rendering genau abläuft, aber machs doch so wie DirectWrite: Trenn das Layouting vom Rendering ab. Dann hast du eine eigene Komponente für das Text-Layout, die dir zu String und Layout-Box ein Objekt liefert, das einen fertig gesetzten Textblock repräsentiert. Und das kann dir eine Methode hitTest() bieten oder sowas...
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: [Projekt] CyberDive (MARPG)

Beitrag von Artificial Mind »

dot hat geschrieben:Ich weiß nicht wie dein Font-Rendering genau abläuft, aber machs doch so wie DirectWrite: Trenn das Layouting vom Rendering ab. Dann hast du eine eigene Komponente für das Text-Layout und die kann dir einen HitTest für Textblöcke liefern.
Ja, diesen Job soll die Font-Metrics-Klasse bzw. dass Callback-Interface übernehmen.
Allerdings kann das nicht komplett vom Renderer entkoppelt werden, weil ja z. B. nur die Font (die mit in der RenderEngine-dll ist) wirklich weiß, wie groß die einzelnen Buchstaben sind. Ich werde also gucken, dass ich in meiner GUI-dll die Font-Metrics-Basisklasse habe und in der RenderEngine-dll die Signed-Distance-Font-Klasse die entsprechenden Metriken zur Verfügung stellt.
Ich muss allerdings noch gucken wie ich so allgemein wie möglich im GUI eine "Font" angeben kann, egal wie die im Endeffekt realisiert ist. Allzu lose Kopplung ist halt auch problematisch. Ich denke ich werde im GUI sowas wie eine "Wunsch-Font" angeben und der aktuelle Renderer muss dann gucken wie den Wunsch so gut wie möglich erfüllen kann.
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: [Projekt] CyberDive (MARPG)

Beitrag von Artificial Mind »

So, ich habe nun eine Font-Metrics Klasse.
Damit werden jetzt alle 9 Text-Aligns richtig unterstützt und AutoSize von Labels funktioniert.
Außerdem funktioniert Text-Selektion, inklusive multi-line Selektion.
Text-Selektion
Text-Selektion
Hier sieht man einen selektierten Textblock aus einem etwas längeren Text, der sowohl horizontal, als auch vertikal zentriert ist.
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: [Projekt] CyberDive (MARPG)

Beitrag von Artificial Mind »

So es hat sich wieder ein bisschen was getan (wie gesagt, einfach schreien wenn ich zu viele kleine Updates raushau, ich werd mich dann zusammenreißen)
  • Neues Control: PictureBox, Renderer wieder als signed-distance (für den Rahmen) implementiert
  • Login-Logik geht wieder
  • Ressourcensystem
    • Virtuelles Ressourcendateisystem (Pfadtrennung über beliebige Menge an Trennsymbolen, momentan einfach / und \ )
    • Verschiedene Ressourcenprovider können an verschiedene "Nodes" im "Ressourcen-Baum"/"Ressourcen-DAC" eingehängt werden, die ab dort die Auflösung des Ressourcenpfades übernehmen
    • Filesystem-Node für normale Filesystem-Zugriffe mit jeweils eigenem Basispfad
    • Link-Node für "symbolische" Links innerhalb des Ressourcensystems
    • Ressourcen werden asynchron geladen
    • C#-Generic-und-Reflection-Wizardry ;)
Login - City Karte
Login - City Karte
Ich erzähl mal kurz die Geschichte dahinter, wie das Bild geladen wird:
  • Client stellt dem RessourcenManager eine Anfrage nach "DynamicContent/Images/citymap.png"
  • DynamicContent ist ein FileSystem-Node mit Basispfad "Content/Dynamic/" und löst die Ressourcenanfrage also nach "Content/Dynamic/Images/citymap.png" auf
  • Die Datei ist allerdings nicht vorhanden, also wird das OnMissing-Event von der Ressourcenbeschreibung aufgerufen
  • Bei Erstellung der Anfrage wurde dort hinterlegt, dass im Falle OnMissing der Server nach der Ressource gefragt werden soll
  • Es wird also eine Nachricht an der Server verfasst, dass man doch bitte die Datei "Images/citymap.png" haben möchte (ich benutze den Node "DynamicContent" für Content, der vom Server kommt)
  • Der Server erhält die Anfrage, dass ein User-Client Content haben will und übersetzt den Pfad in "UserContent/Images/citymap.png"
  • UserContent ist ein Link-Node und enthält momentan eine einfache Übersetzungstabelle von Pfaden
  • Dort steht "Images/citymap.png" (der relative Pfad von UserContent aus gesehen) als Link nach "FileSystem/WorldSave/Cities/citymap.png" drin
  • FileSystem ist ein FileSystem-Node mit Basispfad "" (also relativ zur Working Dir)
  • Es wird also die Datei "WorldSave/Cities/citymap.png" aus dem Dateisystem geladen
  • Dieses Bild wird (momentan noch unkomprimiert) an den Client als Antwort gesendet
  • Der Client bekommt also seinen Content und speichert diesen erstmal ab (einfach ins Dateisystem), damit das nächste Mal der Server nicht gefragt werden muss
  • Daraufhin wird der Ressource beim Client gesagt, dass das Laden nochmal versucht werden soll
  • Datei ist nun da, also wird das Bild geladen, OnLoad getriggert und das Bild als Image für die PictureBox gesetzt
Natürlich gibt es da noch dran zu feilen, aber so wird relativ transparent eine Ressource vom Server geladen.
Der Grund, warum "UserContent/Images/citymap.png" als Link implementiert ist, ist der, dass zum einen die Ordnerstruktur auf Server und Client anders ist und zum anderen, damit der Client nicht unbeschränkten Zugriff auf das Dateisystem des Servers hat. (Über diesen Link-Node lässt sich sehr gut filtern, was geladen werden darf und was nicht, ohne das eigentliche Laden doppelt schreiben zu müssen)
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: [Projekt] CyberDive (MARPG)

Beitrag von Artificial Mind »

Direction Dependent Transparency
Direction Dependent Transparency
Solange man sich nicht innerhalb oder dicht an diesem transparenten Objekt befindet, werden die Transparenzen aus allen Kamerarichtungen richtig gezeichnet, ohne, dass ich pro Frame 260.000 Indices sortieren muss.

Ich habe das einfach mal "Direction Dependent Transparency" getauft.
Anstatt in meinem Mesh einen Vertex Buffer und einen Index Buffer zu haben, habe ich einen Vertex Buffer und mehrere Index Buffer, wobei jeder Index Buffer einer Richtung entspricht. Man kann dann einfach eine beliebige Anzahl von Richtungen angeben und das Mesh errechnet für jede Richtung einen Index Buffer. Dies mache ich einfach, indem ich alle Mittelpunkte der Faces auf die Gerade Objektmittelpunkt + lambda * Richtung projeziere und jeweils den gerichteten Abstand (sprich positiv für "in die Richtung" und negativ für "entgegen" der Richtung) zum Objektmittelpunkt ausrechne. Das ist mein Sortiertkriterium für die Indizes zu dieser Richtung. Im Bild habe ich das z. B. für 4 Richtungen (die 4 Diagonalen der xz-Ebene, y ist Oben) gemacht. Beim Rendern muss ich dann einfach nur noch die Richtung auswählen, die den kleinsten Winkel zur Kamerarichtung (Richtung vom Objekt zur Kamera) hat, den entsprechenden Index Buffer binden und rendern. Und 4 mal Punktprodukt ist einfach weniger Aufwand als 260k Indizes zu sortieren ;)
Das Verfahren versagt halt, wenn man sich zu dicht am Objekt befindet, weil dann die Projection auf die Kamerarichtung eine sehr schlechte Approximation zum Kameraabstand ist. Ich denke auch für nicht-Heightmaps (im Bild ist das ja nur eine Heightmap) sollte man mit 8 Richtungen gute Ergebnisse erzielen.

Und nun darf jemand mir verraten, wie das Verfahren wirklich heißt, denn ich hab mir das zwar ausgedacht, aber dass muss es ja schon irgendwie geben ;)

Ist auf alle Fälle eine sehr gute und kostengünstige Variante zum "Alle-Faces-Sortieren", solange man halt einige Rahmenbedingungen erfüllt hat. (Natürlich gibt es Fälle, wo Sortieren alleine nicht reicht, aber in allen anderen sollte meine Approximation aus sicherer Entfernung funktionieren, notfalls muss man mehr Richtungen testen) Achso, man bezahlt natürlich auch mit VRAM, aber ich hoffe, die Indexbuffer sind nicht allzu groß ;)

Edit: man könnte in die Versuchung geraten und behaupten die Transparenzen im Bild seien falsch, weil ja ab und zu irgendwas "abgeschnitten" aussieht, aber das ist richtig so, weil dort die Krümmung für eine "Doppellage" sorgt. Es geht ein bisschen der 3D-Eindruck dadurch verloren, dass ich noch keine Beleuchtung für transparente Objekte habe.
Zuletzt geändert von Artificial Mind am 01.03.2012, 09:25, insgesamt 1-mal geändert.
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: [Projekt] CyberDive (MARPG)

Beitrag von Artificial Mind »

Hm, ein einfacher Fresnel-Term macht das ganze schon etwas besser :)
Transparenz mit Fresnel-Term
Transparenz mit Fresnel-Term
Andre
Establishment
Beiträge: 186
Registriert: 21.12.2011, 20:33

Re: [Projekt] CyberDive (MARPG)

Beitrag von Andre »

Das ist eine ziemlich coole Idee.

Sieht man das umwechseln der IndexBuffer sehr stark? (Wenn ich das richtig verstanden habe)
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: [Projekt] CyberDive (MARPG)

Beitrag von Artificial Mind »

Wenn du nicht zu nah am Objekt bist, sieht man das gar nicht, weil die Dreiecke dann immer richtig sind.
Wenn du nah dran bist, gibt es halt Artefakte, weil einige Dreiecke in der falschen Reihenfolge gezeichnet werden und diese Artefakte springen im Allgemeinen, wenn der IndexBuffer gewechselt wird.
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: [Projekt] CyberDive (MARPG)

Beitrag von Artificial Mind »

So ich habe wieder ein kleines Update.
Der Client hat jetzt Zugriff auf Ressourcen zu den einzelnen Städten.
Außerdem gibt es eine neue Rendering Pipeline, die "Basic Rendering Pipeline", die einen einfachen Forward Renderer ohne weiteren Schnickschnack (allerdings inklusive Transparenzen und optional HDR, also RGBA16) implementiert. Dieser ist für das Offscreen-Rendern kleinerer Szenen gedacht, wie z. B. eine transparente Version der Heightmaps der Städte. (Die Höhenskalierung ist allerdings wieder überproportional, da die einzelnen Stadtumgebungen 300km x 300km umfassen und man "normale" Höhendifferenzen sonst gar nicht sehen würde ;) )
Die Heightmaps werden dabei in ein neues Control, die sogenannte "TextureBox" gerendert. Das ist quasi ein Control für ein Rendertarget bzw. eine beliebige Textur.
City Preview - weit
City Preview - weit
Erwähnenswert ist außerdem, dass die Heightmaps in der TextureBox mit 2-fach Supersampling berechnet werden, indem sie einfach in der doppelten Größe gerendert sind ;)
City Preview - nah
City Preview - nah
Video zu den Transparenzen (sieht in bewegt auch viel eindrucksvoller aus)
[youtube]a3ys-2Jy47w[/youtube]
(Die Ruckler sind halt fraps, wie man das nunmal kennt ...)
LONy
Establishment
Beiträge: 145
Registriert: 29.09.2011, 10:04

Re: [Projekt] CyberDive (MARPG)

Beitrag von LONy »

Ich find deine ausführliche Berichterstattung klasse, so wie es mit deinem Projekt weiter geht :) da bekommt man richtig lust selbst wieder was zu machen! weiter so, ich verfolg die Entwicklung gerne...
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: [Projekt] CyberDive (MARPG)

Beitrag von Artificial Mind »

LONy hat geschrieben:Ich find deine ausführliche Berichterstattung klasse, so wie es mit deinem Projekt weiter geht :) da bekommt man richtig lust selbst wieder was zu machen! weiter so, ich verfolg die Entwicklung gerne...
Danke, sowas motiviert beide Seiten ;)

Kurzupdate:
Beim Generieren meiner prozeduralen Meshes (wie z. B. Heightmaps), habe ich bei vier Vertices, die im Prinzip ein Viereck bilden, ja zwei Möglichkeiten daraus zwei Dreiecke zu bilden (ich habe die Freiheit die Richtung der Diagonalen zu wählen). Vorher hatte ich immer eine feste Richtung eingebaut, was dazu führte, dass bei niedriger Gitterauflösung teilweise sehr sichtbare Artefakte (in Form von "Zacken") entstanden. Nun prüfe ich beim Generieren welche Diagonale welchen Approximationsfehler zur Oberfläche macht (jedenfalls eine Abschätzung dieses Fehlers ;) ) und wähle die Diagonale mit dem kleineren Fehler.
Edge Flipping in Procedural Mesh Generation
Edge Flipping in Procedural Mesh Generation
Im Bild: Oben: Worst-Case, Unten: korrigierte Variante. (Beide Bilder haben die gleichen Vertices und damit die gleiche Meshauflösung)
Antworten