Dieses Thema
  • Alles
  • Dieses Thema
  • Dieses Forum
  • Artikel
  • Seiten
  • Forum
  • Dateien
  • Erweiterte Suche
  1. Forum
  2. Downloads
  3. Changelog*
  4. Mitglieder
    1. Letzte Aktivitäten
    2. Benutzer online
    3. Team
    4. Mitgliedersuche
  • Anmelden
  • Registrieren
  • Suche
  1. Envile Media
  2. Forum
  3. Terranigma 2
  4. Engine-Entwicklung

Status: Beginn der Arbeiten an der neuen Engine

  • Juliean
  • 22. September 2013 um 23:08
  • Juliean
    Administrator
    Reaktionen
    12
    Beiträge
    1.538
    Dateien
    1
    • 22. September 2013 um 23:08
    • #1

    Hallo,

    für alle die es noch nicht im anderen Thread eben gelesen haben, ich werde für die weitere Arbeit an Terranigma 2 vom Maker weggehen und stattdessen eine Integration in meinen eigene, bereits existente Game-Engine "Acclimate Engine" vornehmen. Das bedeutet leider, dass ich einiges an Arbeit wiederholen muss, dank weniger Einschränkungen (z.B. der vollen Kontroller über den Editor) sollte es aber nach der Anfangsphase zügig voran gehen, und im Endeffekt schneller als es vorher möglich gewesen wäre, gerade in Hinsicht auf z.B. die Episode III.

    Nun, hier werde ich immer mal wieder ein paar Updates posten. Es wird noch ne Weile dauern bis ich dazu komme etwas spielbares, geschweige denn neuen Content zu posten, jedoch schaue ich dass ich so bald als nur möglich eine Techdemo veröffentlichen kann (aber erst, wenn sich zumindest der Nicht-Kampf-Part wieder so spielt wie im Original bzw. in der Maker-Umsetzung). Die Arbeiten habe ich aber schon begonnen, und hier ein paar kleine Screens dazu.

    Der erste Screen zeigt, dass der Tilemap-Import und die Darstellung schon funktionieren, bis auf die Autotiles und einige Prioritäts-Einstellungen. Der zweite Screen ist ein kleiner Stresstest. Dort lasse ich sage und schreibe 5000 mal einen animierten Ark anzeigen, der zusammen mit der Tilemap immer noch auf sagenhaft flüssige 75 FPS kommt. Ein Wert, von dem man am Maker nur träumen kann (zum Vergleich, trotz geringerer Auflösung/Map kratzt der Maker bei solch einer Menge an puren, unanimierten Sprites an der 10 FPS-Grenze. Mal schauen wie sich das mit weiterer Funktionalität noch angleicht, dennoch bin ich sehr zuversichtlich, habe ich hier immerhin noch nichtmal in die ganze GPU-Trickkiste geriffen. Ja, das ganze wird DX9/DX11 verwenden und dadurch Hardwarebeschleunigt laufen. Ziel-FPS sind derzeit 60 geplant, weil das noch ne Spur flüssiger ist als der Maker, und dann garantiert ohne großartige Laggs (5000 Sprites auf einer Map kommt praktisch nicht mal vor ;)). Vielleicht auch noch nett zu erwähnen, das ganze verbraucht im Moment gerade mal 10 Mb (!) Arbeitsspeicher, wo der Standard-Maker schonmal an die 100 ohne groß was frisst, mit meinem Tilemap-Edit kams schon mal auf die 1-1,5 GB. Wird sich natürlich auch nicht erhöhen, aber dennoch, kein Vergleich zu vorher ^^

    So, dazu erstmal das kleine Update, werd als nächstes schauen dass ich leichte Steuerung und die Tilemap fertig bekomme, dann die grundlegende Editor-Integration, werd euch jedenfalls auf dem laufenden halten. Kann hoffentlich demnächst schon was posten was nach bisschen mehr aussieht.

    Mfg
    The King

    EDIT: Für die Hardware-versierten, zum Thema "GPU-Trickkiste", damit meine ich z.B. die Verwendung des Z-Buffers um die Darstellung gerade von so vielen Sprites zu erhöhen. Im Moment muss ich alles von hinten nach vorne Darstellen, und deshalb die Sprites vorm Rendern nach z-position sortieren. Ich könnte aber mit aktiviertem Alpha-Testing auch bestimmte Sprites wie den Ark hier als "undurchsichtig" markieren, und dann von vorne nach hinten mit aktiviertem Tiefenbuffer zeichnen. Weiß nicht ob sich das praktisch viel bring, weil ja nie so viele Sprites da sind, könnte aber in der Praxis doch nen ordentlichen Boost geben, die Szene würde dann auf ca. ~200-250 FPS kommen (tut sie in etwa ohne sortierung, und danach wäre dann der Overdraw noch massiv reduziert, von daher ;) )

    Dateien

    TilemapImport.png 458,45 kB – 366 Downloads Stresstest.png 1,34 MB – 353 Downloads
  • Corvus
    Schüler
    Beiträge
    74
    • 23. September 2013 um 16:58
    • #2

    Guten Tag King,

    Arbeitest du bei deiner neuen Engine zufälligerweise mit OpenGL? Ich selbst arbeite nun schon seit einem Jahr sehr ausgiebig mit OpenGL, besonders im 2D-Bereich. Es wäre sicher interessant von Zeit zu Zeit ein paar Werte zu vergleichen.
    Was das sortieren der Sprites angeht so würde ich dir davon abraten so weit wie möglich. Eine Möglichkeit ist immer eine kommutative Blending-Funktion zu verwenden damit die Render-Reihenfolge keine Rolle mehr spielt. Falls unbedingt eine nicht kommutative Funktion verwendet werden muss sollte zwischen transparenten und nicht transparenten Sprites unterschieden werden.

    Beste Grüße nach langer Zeit.

    Rechtschreibfehler dienen der allgemeinen Belustigung. Ihr könnt sie sammeln und ab 100 gegen einen Preis eintauschen.

  • Juliean
    Administrator
    Reaktionen
    12
    Beiträge
    1.538
    Dateien
    1
    • 23. September 2013 um 18:29
    • #3

    Hallo,

    nun, grundsätzlich verwende ich DirectX9/DirectX11, komplett auf shader-basis (11er gehts eh nicht anders), die Engine ist aber grundlegend API-unabhängig aufgebaut, es lässt sich also auch ein OpenGL-Renderer einbauen, was ich vmtl im laufe dieses Studienjahres auch noch machen werde. Die Grundprinzipien sind ja bei DirectX/OpenGl auch ziemlich ähnliche, gerade wenn man keine Fixen-Function verwendet...

    Zitat

    Was das sortieren der Sprites angeht so würde ich dir davon abraten so weit wie möglich. Eine Möglichkeit ist immer eine kommutative Blending-Funktion zu verwenden damit die Render-Reihenfolge keine Rolle mehr spielt. Falls unbedingt eine nicht kommutative Funktion verwendet werden muss sollte zwischen transparenten und nicht transparenten Sprites unterschieden werden.

    Ja, dem bin ich mir definitiv bewusst, gerade bei 3d-Partikelsystem ist eine Sortierfunktion FPS-Killer Nr1. Kommutatives, sprich additives/subtraktives blending ist leider bei den normalen Sprites nicht möglich, deshalb werde ich als alternative vorerst aufs sortieren zurückgreifen müssen. Ich gebe dir aber Recht, und hab bereits eine alternative, nämlich werde ich mittels Z-Buffer, Alpha-Testing und einer Sortierung nach Opaque, Transparent, Additive/Subtraktiv zumindest den Großteil der normalen Sprites von der Sortierung ausnehmen können. Eben genau wie du sagst, die Unterscheidung muss ich erst nur einbauen. Aber auch so ist die Performance im Moment zufriedenestellend, mittlerweile 8000 Arks und die Tilemap mit stabilen 72 FPS. Mit Maker-Auflösung sogar bei 85. Dennoch, optimieren werde ich noch was es nur geht (der 2D-Sprite-Renderer findet auch im GUI für die 3D-Spiele Verwendung), danke also auch für den Input.

    Und falls du trotzdem mal Werte oder so Vergleichen willst, lass es mich wissen.

    Mfg
    The King

  • Corvus
    Schüler
    Beiträge
    74
    • 24. September 2013 um 21:29
    • #4

    Falls du nicht zu viel Bedacht auf die Alpha-Channel legst könntest du auch darüber nachdenken die sogenannte "screen door transparency" zu verwenden. Also deine 2D-Grafiken mit einem Stichmuster zu rendern um gewisse Fragmente auszulassen. Für manch einen könnte dies bereits genug sein, und es erfordert ebenfalls keine Sortierung der Sprites.

    Rechtschreibfehler dienen der allgemeinen Belustigung. Ihr könnt sie sammeln und ab 100 gegen einen Preis eintauschen.

  • Juliean
    Administrator
    Reaktionen
    12
    Beiträge
    1.538
    Dateien
    1
    • 24. September 2013 um 21:45
    • #5
    Zitat

    Falls du nicht zu viel Bedacht auf die Alpha-Channel legst könntest du auch darüber nachdenken die sogenannte "screen door transparency" zu verwenden. Also deine 2D-Grafiken mit einem Stichmuster zu rendern um gewisse Fragmente auszulassen. Für manch einen könnte dies bereits genug sein, und es erfordert ebenfalls keine Sortierung der Sprites.

    Aye, das ist im Endeffekt genau was das von mir erwähnte Alpha-Testing macht - jedoch im Pixelshader mit einer einfachen clip(alpha > 0.001f ? 1 : - 1) - operation je Pixel, und daher in den meisten Fällen auch hundertmal schneller. Ich verwende das bereits um die Performance noch leicht zu erhöhen. Alpha-Channel brauch ich allein für einige Effekte auf der Tilemap bzw. viele Charsets, also kann ich drauf grundlegend nicht verzichten, aber die Kosten für den Z-Buffer sind minimal, ich muss im Endeffekt nur noch ein Zuordnungs-flag für die verschiedenen Blending-Operationen finden. Bisher (= im Rpg-Maker) war das Verhältnis opaque - transparente Sprites immer so ca. 100:5 maximal, die paar Alpha-Sprites zu sortieren sollte ohne Probleme gehen. Gerade eben nochmal mit dem Profiler drübergelaufen, das sortieren von 8000 Sprites mit zufälliger Z-Position dauert gerade mal 0,8 ms - und das sind extrem, exterm unrealistische Zahlen, da ich z.B. die Tilemap später vmtl komplett Hardware-beschleunigt darstellen werden, und dadurch im höchstfall 500 sprites auf einer Map gleichzeitig aktiv sein sollten - auf einem Screen? Allerhöchstens 50-100. Aber naja, sortieren 0,8 ms... Da braucht GPU teilweise wesentlich mehr Leistung, weswegen ich es in Betracht ziehe grundsätzlich nach Textur zu sortieren, und bei nicht-transparenten Sprites von vorne nach hinten, um den Overdraw optimal zu minimieren. Werd natürlich sämtliche Optionen testen und profilen, und eventuell eine Tech-Demo mit einem Test, der die verschiedenen Methoden auf unterschiedlichen PCs analysiert rausbringen...

    EDIT: Aus Neugierde, mit welcher Version von OpenGL arbeitest du denn, und verwendest du noch die Fixed Function Pipeline oder bereits Shaderprogrammierung?

    EDIT2: Textursortierung wirds ohnehin werden. Da ich nämlich die Sprites rigoros batche, also zu einem Draw-Call zusammenfüge, und da müssen die Textur-Sortiert sein. Das bring wesentlich mehr (~50-100% Performance) als ich durch das sortieren selbst verliere. Auf meinen PCs jedenfalls, mal schauen was die anderen Rechner dazu sagen.

  • Corvus
    Schüler
    Beiträge
    74
    • 24. September 2013 um 22:37
    • #6

    Für 2D benötigt man nicht wirklich eine OpenGL-Version oberhalb von 1.5; das wichtigste ist, dass man VBO's verwenden kann. Ich benutze aber 2.1 um eigene Vertex- und Fragmentshader zu programmieren; das hilft besonders bei kleinen grafischen Spielereien wie verschiedenen Farbverläufen bei Tageslichtänderungen und Palette-Swapping.

    Nach Texturen sollte man sowieso sortieren falls möglich da das binden einer Textur immer einen kleinen zusätzlichen Kostenaufwand mit sich zieht. Falls du allerdings gleichzeitig auch mehrere Shader verwendest solltest du testen ob es schneller ist eine Textur zu wechseln oder einen Shader zu wechseln.

    Rechtschreibfehler dienen der allgemeinen Belustigung. Ihr könnt sie sammeln und ab 100 gegen einen Preis eintauschen.

  • Juliean
    Administrator
    Reaktionen
    12
    Beiträge
    1.538
    Dateien
    1
    • 24. September 2013 um 22:49
    • #7
    Zitat

    Für 2D benötigt man nicht wirklich eine OpenGL-Version oberhalb von 1.5; das wichtigste ist, dass man VBO's verwenden kann. Ich benutze aber 2.1 um eigene Vertex- und Fragmentshader zu programmieren; das hilft besonders bei kleinen grafischen Spielereien wie verschiedenen Farbverläufen bei Tageslichtänderungen und Palette-Swapping.

    Da geb ich dir Recht, trotzdem schadet es nie eine neuere Version zu verwenden - sei es wegen verbesserter Performance (sogar mit mehr oder minder 1:1 Port läuft z.B. Dx11 um einiges schneller), und den neuen Features, die einige Sachen auch im 2D-Bereich leichter/performanter machen könne (ich sag nur Compute/Geometry-Shader, da kann man auch im 2D-Bereich viel machen). 2D kann man sogar noch mit DirectX8 machen, ist aber nicht Zielführend ;) Auch eines der tollsten Sachen die ich mir so vorstelle mit den Pixelshadern, was sich da alles machen lässt was mitm Maker performance-technisch nicht möglich gewesen wäre... hach :D

    Zitat

    Nach Texturen sollte man sowieso sortieren falls möglich da das binden einer Textur immer einen kleinen zusätzlichen Kostenaufwand mit sich zieht. Falls du allerdings gleichzeitig auch mehrere Shader verwendest solltest du testen ob es schneller ist eine Textur zu wechseln oder einen Shader zu wechseln.

    Wobei die Kosten gerade bei DirectX mittlerweile viel geringer geworden sind. Hab aber allein dadurch, dass ich redundante State-Settings rausfiltere, im Wort-Case (jedes Sprite ein einzelner Draw-Call, bei 8k), von 46 auf 51 noch ne ganze Menge rausholen können, hat also sicher auch da noch Auswirkungen. Gerade für den 2D-Bereich werde ich aber denke ich weitestgehen denselben Shader verwenden, deshalb sollte sich die Textursortierung mehr auszahlen... naja, profilen schadet nie.

  • Corvus
    Schüler
    Beiträge
    74
    • 24. September 2013 um 22:57
    • #8

    Die neueren OpenGL-Versionen bringen nicht viel nützliches für mich. VAO's sind generell als langsamer, beziehungsweise bestensfalls genausoschnell wie VBO's, eingestuft. Tesselation- und Geometrie-Shader benutze ich ebenfalls nicht und sehe für diese im Moment auch keinen Nutzen in meinem Projekt.
    Zudem muss man bedenken, dass auch nicht alle Grafikkarten (oder integrierten Chips) die neueren OpenGL-Versionen unterstützen. Ich habe schon diverse Laptops gesehen, welche die neueren Versionen nicht umsetzen, beziehungsweise nur auf Treiberebene anbieten. Da ist (noch) nicht viel zu gewinnen.

    Ein draw-call pro Sprite ist meistens keine gute Idee. Was du machen willst ist einen Buffer zu füllen welcher die geometrie und texturdaten von vielen Sprites enthält und dann diesen Buffer direkt auf die Grafik-Karte auszulagern. Dadurch kannst du die Performance sehr einfach verzehnfachen.

    Rechtschreibfehler dienen der allgemeinen Belustigung. Ihr könnt sie sammeln und ab 100 gegen einen Preis eintauschen.

  • Juliean
    Administrator
    Reaktionen
    12
    Beiträge
    1.538
    Dateien
    1
    • 24. September 2013 um 23:08
    • #9
    Zitat

    Die neueren OpenGL-Versionen bringen nicht viel nützliches für mich. VAO's sind generell als langsamer, beziehungsweise bestensfalls genausoschnell wie VBO's, eingestuft. Tesselation- und Geometrie-Shader benutze ich ebenfalls nicht und sehe für diese im Moment auch keinen Nutzen in meinem Projekt.

    Ich denke ich werde definitiv für die neueren Grafikkarten die Kollisionsroutine als Compute-Shader optional zur Verfügung stellen, falls möglich, allein schon als Lern-Projekt. Tessalation mit Displacement-Mapping werde ich denke ich experimentiell benutzen um eventuell die Weltkarte noch etwas aufzupimpen, Mode07 gut und schön, aber vielleicht kriegt man das ganze noch etwas platischer und immer noch im Retro-Look hin.

    Zitat

    Zudem muss man bedenken, dass auch nicht alle Grafikkarten (oder integrierten Chips) die neueren OpenGL-Versionen unterstützen. Ich habe schon diverse Laptops gesehen, welche die neueren Versionen nicht umsetzen, beziehungsweise nur auf Treiberebene anbieten. Da ist (noch) nicht viel zu gewinnen.

    Ja, Fallback ist definitiv so ne Sache, dafür biete ich ja immer eine DirectX9-Variante an, die läuft dann auf so ziemlich allem. DX11 bietet auch Feature-Levels die, Windows Vista+ vorausgesetzt, den DirectX11-Renderer auf die Kapazität der Grafikkarte anpasst, muss man halt gegebenenfalls auf bestimmte Features verzichten.

    Zitat

    Ein draw-call pro Sprite ist meistens keine gute Idee. Was du machen willst ist einen Buffer zu füllen welcher die geometrie und texturdaten von vielen Sprites enthält und dann diesen Buffer direkt auf die Grafik-Karte auszulagern. Dadurch kannst du die Performance sehr einfach verzehnfachen.

    Jup, danke für den Einwand, aber wie erwähnt (batching) mache ich das ebenfalls bereits, die 8000 Draw-Call-Per-Sprite war ein Test für den Worst-Case, der z.B. dann zustande kommt wenn jedes Sprite tatsächlich eine andere Texture haben sollte. Optimierte Benchmarks bringen ja relativ wenig, 20000-Sprites mit gleicher Grafik und ohne Sortierung liefern immernoch Werte jenseits der 200 FPS-Marke, da test ich lieber was passiert wenn alles schief laufen würde^^ Der Performance-Gewinn durch das Batching ist tatsächlich abhängig von der Szene - grundsätzlich hast du Recht, bloß die Zahlen stimmen mit meinen Tests derzeit nicht ganz überein, zwischen 1 Call / Sprite und 1 Call / All sind es ca. 79% Performance-Gewinn in meiner Test-App (bin aber auch auf entsprechende 5-10x Faktoren gekommen, nur in etwas syntetischeren Testszenen). Muss aber dazusagen, auch ohne nach Textur zu Batchen wird lediglich ein Buffer verwendet, das einzige was sich da ändert ist halt die Anzahl der tatsächlichen Draw-Befehle, sowie das Start-Vertex-Argument, also sind auch da die Kosten *vergleichsweise* gering.

    EDIT: Ich könnte denke ich noch ne Menge rausholen indem ich möglichst viele Texturen in einen Atlas merge und somit die Draw-Calls weiter minimiere, das spar ich mir aber für irgendwann später auf...

  • Juliean
    Administrator
    Reaktionen
    12
    Beiträge
    1.538
    Dateien
    1
    • 25. September 2013 um 01:56
    • #10

    So, Mapimport funktioniert soweit schonmal, texturen muss ich derweil noch manuell zuweisen, lässt sich aber leicht nachbessern. Animiert sind die Autotiles auch noch nicht. Dafür sind schon teile des GUIs da, so ungefähr kann der Editor später aussehen, Design/Farben etc.. natürlich Änderungen vorbehalten, und die Textdarstellung macht gerade auch Faxen. FPS ~400, trotz derzeit exterm unoptimaler sortierung der Tiles wegen der Layer (da muss ich mir noch was besseres überlegen). Morgen muss ich mich noch auf die Klausur vorbereiten, dann schau ich dass es animiert läuft.

    Bilder

    • MapImport.jpg
      • 2,2 MB
      • 2.560 × 1.600
  • Juliean
    Administrator
    Reaktionen
    12
    Beiträge
    1.538
    Dateien
    1
    • 27. September 2013 um 01:59
    • #11

    Gestern hat sich, noch bedingt durch meine Klausur, relativ wenig getan. Dennoch, die Autotile-Animation (z.B. das Wasser) funktioniert nun bereits. Leider derzeit nur für die Autotiles die aus einer 32*32-Grafik je Animationsframe bestehen, für die Größeren muss ich erst den Algorythmus vom Maker portieren (oder mir gleich selber einen besseren einfallen lassen, und einen Konverter schreiben).

    Ein Vorteil der mir dabei aufgefallen ist (außer die 2500 FPS auf der Map => komplett Krysta ist geladen, das Screen-Culling geht ziemlich ab), ist dass hier die Map im Vollbild pixelgenau skaliert wird, beim Maker war das eher so ein verwischter bilinearer Filter. Werd in der Techdemo dennoch beide Optionen offen lassen, und mal schauen was im Endeffekt besser gefällt...

    Bilder

    • Ingame.jpg
      • 983,15 kB
      • 2.560 × 1.600
  • EnigmaThePhoenix
    Fortgeschrittener
    Beiträge
    242
    • 28. September 2013 um 23:38
    • #12

    Ich rate dir im Fall der Fälle was eigenes zu schreiben, da kann man immer was dran drehen.
    Kennst das ja schon, wenn mans selber gemacht hat is es bearbeitbar und sonst war mans selber. ^^

  • Juliean
    Administrator
    Reaktionen
    12
    Beiträge
    1.538
    Dateien
    1
    • 1. Oktober 2013 um 00:45
    • #13
    Zitat

    Ich rate dir im Fall der Fälle was eigenes zu schreiben, da kann man immer was dran drehen.
    Kennst das ja schon, wenn mans selber gemacht hat is es bearbeitbar und sonst war mans selber. ^^

    Ich bin mir grad nicht sicher ob du komplett verstanden hast was ich meinte, oder ob ich verstehe worauf du hinauswillst, jedenfalls steht selber schreiben direkt ja nicht zur Debatte - Maker-Code kann ich nicht 1:1 übernehmen. Die Frage war nur ob ich die Art wie der Maker Autotiles handlet ähnlich nachbaue, oder mir eine komplett eigene Idee dazu einfallen lasse. Habe aber bis jetzt nichts gefunden das ich entsprechend verbessern könnte, von daher werd ich es erstmal dabei belassen - bearbeitbar ist das in jedem Fall, da ich ja jetzt schon zum zweiten Mal den Algorythmus ausimplementiere, ist nicht so als würde ich C&P einfach was vom Maker rausnehmen ;). Die Änderung hier wird halt vor allem sein, dass es beliebig viele geben kann, und die Attribute wie Animations-Geschwindigkeit und Transparenz direkt im Editor bearbeiten lassen werden.

    Das bringt mich auch schon zum Statusbericht. Die Grundfunktionen hab ich soweit implementiert - Autotiles, Priorities für die Tilemap und die Charaktere, wird mittlerweile alles super dargestellt. Kollisionsabfrage ist soweit ebenfalls implementiert, sowohl mit der Tilemap als auch Charaktere untereinander. Da muss ich mir aber noch etwas von der Performance her einfallen lassen, ein nicht unbeträchtlicher Teil geht da durch die Abstraktionsschicht des Plugin-Systems verloren (Tilemap ist ein eigenes Plugin), bei 500-700 Charakteren bricht die Framerate ein - zugegeben, das ist erneut ein recht hoher und unrealistischer Wert. Aber z.B. führe ich gerade noch N^2, also jeder-gegen-jeden Kollisionsabfrage durch, da lässt sich noch enorm optimieren (das sind bei 500 Charakteren bereits 250.000 Vergleiche, unoptimiert).

    Ebenso bereits funktionieren tut die Grundbewegung von Ark - das heißt gehen, laufen, die Verschiebung wenn man Nahe an einer Ecke geht. Diesesmal, da das System grundsätzlich darauf aufgebaut ist, ohne die im Maker mehr oder minder notwendigen Hacks. Ebenso ist das System diesesmal komplett pixelperfekt. In der Makerversion hat sich Ark mindestens um 8 Pixel pro Schritt bewegt. Es ist nicht so schlimm aufgefallen, aber man merkt definitiv den unterschied. Auch kann ich jetzt aus dem SNES-Emulator die exakten Bewegungs- und Animationsgeschwindigkeiten des Originals auslesen. Dies ist bereits für die Gehen und Rennen passiert, und man muss wirklich sagen, es macht nochmal einen spürbaren Unterschied, zumindest für mein geübtes Auge. Hab leider noch keinen neuen Screenshot/kein Video mit etwas aussagekräftigem...

    Dafür werde ich noch die Woche eine Tech-Demo rausbringen. Zuerst muss ich aber noch den DX9-Renderer nachrüsten, war ehrlich gesagt etwas schlampig mit den letzten Features die ich nur im Interface und für die DirectX11-Variante eingebaut habe, sobald ich das nachgebaut habe, könnt ihr euch dann selber vom aktuellen Stand überzeugen. Wäre mit wichtig dass viele Leute diese ausprobieren und mir Performance-Werte mitteilen, sowie grundsätzlich auf Funktion testen - bisher wurde meine Engine nur auf einigen wenigen PCs getestet, brauche also auch Vergleichswerte, hoffe es haben genug Leute für 5-10 Minuten schauen ob Spiel startet, bisschen in Krysta rumlaufen und paar FPS-Werte notieren Zeit :D

    EDIT:

    Naja, hab mir dann doch noch paar Screenshots gemacht. Screen 1 zeigt dass die Autotiles funktionieren, nichts aufregendes. Screen 2 zeigt nochmal die Armee von Arks, diesesmal aber tatsächlich in die Spielwelt integriert, indem sie nach ihrere Position auf der Map sortiert sind. Alle dieses Arks kopieren übrigens im Moment die Bewegungen des Spielers, mit nur einer Zeile Code zusätzlich, nur nebenbei. Insofern auch interessant da (wenn auch bei der Zahl von 8000 als Diashow) die ganzen Arks perfekt miteinern und der Umgebung interagieren, wegen Kollisionsabfrage und so. Beim Maker war das ja, natürlich auch bedingt durch die Hack-artige Weise wie ich es implementiert habe, nicht so leicht möglich gewesen. Screen 3 zeigt nochmal das die Prioritäten auch der Tiles funktionieren. Alle Screens haben auch eine andere Auflösung, die sich ganz leicht ingame wechseln lässt. Werde das auch in die Techdemo integrieren, ich würd gern wissen was ihr zu den Auflösungen 800x600 und 1024x768 im Vergleich zur alten 640x480er sagt (Größer wäre zu groß, weil man da schon fast die ganze Map sieht, aber das könnte ich mir definitiv vorstellen...).

    Dateien

    Autotiles.png 253,56 kB – 191 Downloads Priority.png 311,04 kB – 198 Downloads Priority2.png 580,66 kB – 169 Downloads
  • ChaosAdmiral
    Flammendämon
    Beiträge
    161
    • 1. Oktober 2013 um 05:57
    • #14

    king mal ne frage wenn du die neue engine fertig hast werden die ecken und kanten besser sein oder genauso wie beim alten (rpg version)

    ich sprechen von blizstich gegen wände so das man die animation durch scheinen sieht

    wer fehler findet bei meinen posts kann se behalten :D

  • EnigmaThePhoenix
    Fortgeschrittener
    Beiträge
    242
    • 1. Oktober 2013 um 12:59
    • #15

    Sieht soweit gut aus und hört sich gut an. Bin mal auf die Techdemo gespannt.

    ChaosAdmiral: Denke schon das sich das verbessern lässt, jetzt hat King ja völlig freie Hand was solche Dinge betrifft.
    Er meinte ja schon in einem Post das die Pixelei genauer wird.

  • ChaosAdmiral
    Flammendämon
    Beiträge
    161
    • 1. Oktober 2013 um 16:26
    • #16

    wird man sehen wäre halt cool wenn das gehen würde ;)
    aber bin auch gespand auf die tech demo

    wer fehler findet bei meinen posts kann se behalten :D

  • Corvus
    Schüler
    Beiträge
    74
    • 2. Oktober 2013 um 14:00
    • #17

    Ich frage mich wie groß der Unterschied zwischen der Arbeit mit DirectX und OpenGL bei 2D-Anwendungen ist. Ich kann mir vorstellen, dass es sehr ähnlich ist, aber möglicherweise gibt es doch sehr grundlegende Unterschiede.

    Ich habe auf jedenfall Heute einen Benchmark durchgeführt, weil du Werte vergleichen wolltest. Bei konstanten 60 frames pro Sekunde kam ich auf 600 000 farbige, texturierte Dreiecke, welche sich konstant über den Bildschirm bewegen Bei 700 000 Dreiecken merkte ich den ersten Abfall der Frame-Rate auf ca 55 frames pro Sekunde. Alles jedoch mit der gleichen Textur in einem einzigen Buffer. Bei einer realen Anwendung wären es wahrscheinlich 5 oder sogar mehr Buffer / Texturen. Für ein tatsächliches Spiel habe ich allerdings noch keine Werte.
    Die Grafikkarte auf dem Computer, mit dem getestet wurde, ist eine ATI HD Radeon 5770.

    Es wäre sicher interessant sich einmal darüber zu unterhalten wie die Engines so aufgebaut sind.
    Beste Grüße, Cornix.

    Rechtschreibfehler dienen der allgemeinen Belustigung. Ihr könnt sie sammeln und ab 100 gegen einen Preis eintauschen.

  • Juliean
    Administrator
    Reaktionen
    12
    Beiträge
    1.538
    Dateien
    1
    • 2. Oktober 2013 um 16:30
    • #18

    ChaosAdmiral:

    Zitat


    king mal ne frage wenn du die neue engine fertig hast werden die ecken und kanten besser sein oder genauso wie beim alten (rpg version)

    ich sprechen von blizstich gegen wände so das man die animation durch scheinen sieht

    Ja, das werde ich denk ich definitiv verbessern, so weit es geht. War ja vorher doch recht beschränkt durch die höchstmöglichen 5 verschiedenen Prioritäts-Einstellungen. Hier werde ich wohl auch mehr geometrische Daten in die Map einbauen, also zB. relative Höhe eines Tiles und damit eben auch das Spielers, da sollte sich auch hier was verbessern lassen.

    @Cornis:

    Zitat

    Ich frage mich wie groß der Unterschied zwischen der Arbeit mit DirectX und OpenGL bei 2D-Anwendungen ist. Ich kann mir vorstellen, dass es sehr ähnlich ist, aber möglicherweise gibt es doch sehr grundlegende Unterschiede.

    Ich hab mit beiden ein wenig gearbeitet, und der größte Unterschied soweit lieg darin dass in DirectX so gut wie alles über Klassen (Interfaces) geregelt wird, wohingegen OpenGL ja großteils globale Methoden verwendet. Mir gefällt die Variante von DirectX persönlich etwas besser, weil schon vom Prinizip der Entkapselung eher gegeben ist, lässt sich aber natürlich bei beidem bewerkstelligen.

    Zitat

    Ich habe auf jedenfall Heute einen Benchmark durchgeführt, weil du Werte vergleichen wolltest. Bei konstanten 60 frames pro Sekunde kam ich auf 600 000 farbige, texturierte Dreiecke, welche sich konstant über den Bildschirm bewegen Bei 700 000 Dreiecken merkte ich den ersten Abfall der Frame-Rate auf ca 55 frames pro Sekunde. Alles jedoch mit der gleichen Textur in einem einzigen Buffer. Bei einer realen Anwendung wären es wahrscheinlich 5 oder sogar mehr Buffer / Texturen. Für ein tatsächliches Spiel habe ich allerdings noch keine Werte.
    Die Grafikkarte auf dem Computer, mit dem getestet wurde, ist eine ATI HD Radeon 5770.

    700k â 55 FPS? Definitiv nicht schlecht, würde mich jetzt noch für folgende Details interessieren:

    - Wie hoch ist der grad an Abstraktion/Entkapselung? (verwendest du mehr oder weniger direkte OpenGl-Befehle oder Klassen, mit denen man auch ohne Probleme andere Sprites darstellen könnte?)
    - Wie groß ist der betriebene Rechenaufwand für die Berechnung der Position? (geht mehr oder minder mit der ersten Frage einher, ist es ein Array aus Vec3 die du direkt übermittelst oder über eine "Sprite"-klasse wo die koordinaten umgerechnet werden müssen?)
    - Welche Daten übermittelst du - bloß Position, oder auch Texturkoordinaten? (da ja CPU-GPU-Datentransfer bei einer großen Menge leicht der Flaschenhals werden kann; und Texturkoordinaten 60% mehr Daten bedeuten)
    - Bin durch die Formulierung "farbig, texturiert" auch etwas verwirrt - nimmst du also die Farben von einer Textur, aus dem Vertexbuffer, durch eine Shaderkonstante...?
    - Wie groß sind die Dreiecke ca, im Vergleich zum Screen, und was für Auflösung hast du? (größere Dreiecke = eher Füllratenlimitiert)
    - Verwendest du Techniken um den Overdraw zu reduzieren (Zbuffer?)
    - Updatest du den Buffer auf einmal z.B. in einer Schleife, oder getrennt? (bin nicht mehr sicher wie es in OpenGL läuft, in DirectX muss ich halt den Buffer jedesmal sperren wenn ich ihn verändern will - ah, da fällt mir ne gute Optimisation für meinen Sprite-Renderer ein, auch mit dem Batch sperre ich den Buffer mittlerweile noch für jedes Sprite extra)

    Wären alles interessante Punkte um direkt vergleichen zu können. Mit 2.100.000 Vertices müsstest du langsam schon ans Vertex-Processing-Limit der Karte kommen ( 126 mio vertices pro sekunde).

    Zitat

    Bei einer realen Anwendung wären es wahrscheinlich 5 oder sogar mehr Buffer / Texturen.

    Außer wenn ich dich missverstanden habe oder OpenGL anders arbeitet, sind mehrere Buffer meines Wissens nach nie notwendig. In DirectX zumindestens kannst du einen Bereich spezifizieren, aus dem du renderest - zB. von Vertex 0 bis 6400. Damit kann ich alle anderes texturierten Sprites zumindestens in einem Vertexbuffer halten, und lediglich Texturen wechseln und einen zusätzlichen Draw-Call absetzen.

    Zitat

    Es wäre sicher interessant sich einmal darüber zu unterhalten wie die Engines so aufgebaut sind.

    Sehe ich genauso, würde mich definitiv auch interessieren. Würde dann eher sogar als private Konversation auslegen, um die Forenleser nicht mit zu viel technischem Krimskrams zu langweilen. Ich werde meine Engine sobald so weit auch in der Version 1.0 in näherer Zeit online zur Verfügung stellen, wäre vorher sicher interessant mal zu schauen wie du das so handhabst.

    Gruß,
    The King

  • Corvus
    Schüler
    Beiträge
    74
    • 2. Oktober 2013 um 18:59
    • #19
    Zitat von The King


    - Wie hoch ist der grad an Abstraktion/Entkapselung? (verwendest du mehr oder weniger direkte OpenGl-Befehle oder Klassen, mit denen man auch ohne Probleme andere Sprites darstellen könnte?)


    Ich habe mehrere Ebenen der Abstraktion in meiner Engine. Ich arbeite direkt auf den blanken OpenGL-Befehlen, verkapsele diese ersteinmal in passende Klassen, und baue dann aus dieser groben objektorientierten OpenGL-Implementation eine objektorientierte Grafik-Engine.
    Letzten Endes will ich, dass die äußerste Ebene, diejenige, welche von dem Benutzer am ehesten Verwendet wird, so sicher und zuverlässig ist wie nur möglich. Auch wenn dadurch möglicherweise die Performance ein wenig leidet. Mir ist am wichtigsten, dass es unmöglich ist, durch schlechte Parameterwahl ein unvorhersehbares Programmverhalten zu verursachen. Alle Parameter werden daher auf der äußersten Schicht überprüft und gegebenenfalls Exceptions geworfen.

    Zitat von The King

    - Wie groß ist der betriebene Rechenaufwand für die Berechnung der Position? (geht mehr oder minder mit der ersten Frage einher, ist es ein Array aus Vec3 die du direkt übermittelst oder über eine "Sprite"-klasse wo die koordinaten umgerechnet werden müssen?)


    Bei einer 2D-Implementierung ist der Rechenaufwand sowieso sehr gering. Ich habe eine Sprite-Klasse geschrieben, welche verwendet werden kann um einfach und schnell Bilder anzeigen zu können, der Rechenaufwand auf CPU-Seite ist dabei relativ minimal. Änderungen an Position, Skalierung, Rotation, Textur-Koordinaten und Farbverläufen werden sowohl auf Anwendungsseite zwischengespeichert, als auch direkt in den Grafikkarten-Speicher übertragen.

    Zitat von The King

    - Welche Daten übermittelst du - bloß Position, oder auch Texturkoordinaten? (da ja CPU-GPU-Datentransfer bei einer großen Menge leicht der Flaschenhals werden kann; und Texturkoordinaten 60% mehr Daten bedeuten)


    Im Moment übertrage ich nur pro Vertex 3 Koordinaten für die Position, 2 Koordinaten für die Texturierung und 4 Werte für einen multiplikative Farbeinfluss, das macht pro Dreieck 27 und pro Rechteck 36 4-bit floating point Werte.

    Zitat von The King

    - Bin durch die Formulierung "farbig, texturiert" auch etwas verwirrt - nimmst du also die Farben von einer Textur, aus dem Vertexbuffer, durch eine Shaderkonstante...?


    Ich habe einfach noch eine Farbe pro Vertex hinzugefügt welche auf die Farbe aus der Textur multipliziert wird. Das hat derzeit noch keinen großen Sinn sondern dient einfach nur als kleine Spielerei.

    Zitat von The King

    - Wie groß sind die Dreiecke ca, im Vergleich zum Screen, und was für Auflösung hast du? (größere Dreiecke = eher Füllratenlimitiert)


    Diesen ganz speziellen Test habe ich mit einer Fenstergröße von 1024x1024 Pixeln (und 1 zu 1 Auflösung) durchgeführt. Bei den 600 000 Dreiecken handelt es sich eigentlich um 300 000 Quadrate, welche jedoch natürlich jeweils aus 2 Dreiecken gezeichnet werden. Jedes dieser Quadrate ist 32x32 Pixel in der Größe.

    Zitat von The King

    - Verwendest du Techniken um den Overdraw zu reduzieren (Zbuffer?)


    Bei diesem Test habe ich lediglich Back-Face-Culling verwendet und sonst keinerlei Arten von Optimierung. Es ging um einen reinen Brute-Force performance Test um die Effizienz zu testen mit welcher ich die Buffer füllen kann.

    Zitat von The King

    - Updatest du den Buffer auf einmal z.B. in einer Schleife, oder getrennt? (bin nicht mehr sicher wie es in OpenGL läuft, in DirectX muss ich halt den Buffer jedesmal sperren wenn ich ihn verändern will - ah, da fällt mir ne gute Optimisation für meinen Sprite-Renderer ein, auch mit dem Batch sperre ich den Buffer mittlerweile noch für jedes Sprite extra)


    Ich befülle den Buffer im Moment noch pro Sprite extra. Sobald sich ein Wert von einem Sprite ändert updated dieser Sprite die entsprechenden Werte in seinem Teil des Buffers. Ich hatte darüber nachgedacht, ob ich die Änderungen vielleicht cachen sollte und jeweils zum Beginn des nächsten Frames den ganzen Buffer neu füllen sollte. Der Best-Case würde dadurch natürlich sehr viel effizienter werden. Der Worst-Case aber sehr viel ineffizienter.
    Da der Großteil der Grafiken wahrscheinlich eher statisch sein wird (Gelände, HUD) und nur wenige Sprites (< 1000) regelmäßige Änderungen benötigen werden bleibe ich vorerst auch bei meiner ersten Methode.

    Zitat von The King

    Wären alles interessante Punkte um direkt vergleichen zu können. Mit 2.100.000 Vertices müsstest du langsam schon ans Vertex-Processing-Limit der Karte kommen ( 126 mio vertices pro sekunde).


    Ja. Interessante Nebenbeobachtung: Sobald ich den Test (mit 800 000 Dreiecken) ausführe höre ich wie die Lüfter der Grafikkarte ordentlich Gas geben. Das ist schon ein klein wenig besonders. Vielleicht bedeutet das aber auch nur, dass ich mal wieder Staubputzen sollte.

    Zitat von The King

    Außer wenn ich dich missverstanden habe oder OpenGL anders arbeitet, sind mehrere Buffer meines Wissens nach nie notwendig. In DirectX zumindestens kannst du einen Bereich spezifizieren, aus dem du renderest - zB. von Vertex 0 bis 6400. Damit kann ich alle anderes texturierten Sprites zumindestens in einem Vertexbuffer halten, und lediglich Texturen wechseln und einen zusätzlichen Draw-Call absetzen.


    Die Sache mit den Buffern ist immer ein wenig kritisch zu sehen. Rein theoretisch kann man beliebig große Buffer verwenden und alles in einem Buffer speichern. Allerdings ist es mir von verschiedenen unabhängigen Quellen bekannt geworden, dass Buffer ab einer gewissen Größe (> 10mb) drastisch an Performance verlieren. (Abhängig von der Hardware)
    Was ich daher vorhabe ist es Sprites nach Textur und Shader sortiert auf verschiedene Buffer zu verteilen.
    Außerdem denke ich dabei immer an den Overhead auf der CPU-Seite. Ich werde für kein Projekt jemals so viele Sprites benötigen wie ich in diesem Test dargestellt habe. Ich gehe von nicht mehr als 20 000 zu einem gegebenen Zeitpunkt aus. Daher ist die Effizienz im Grafik-Bereich nicht das Hauptaugenmerk meiner Arbeit. Eher lege ich Wert darauf den Overhead auf Anwendungsseite gering zu halten.
    Wenn man Sprites mit verschiedenen Texturen in einem Buffer ablegen will muss man den Inhalt des Buffers nach Textur sortieren. Jedesmal wenn zusätzliche Sprites von der Anwendung erstellt werden muss man Inhalte im Buffer verschieben. Das sind beides sehr kostspieliege Operationen. Daher habe ich mich entschieden lieber den Cutoff bei den Buffern in Kauf zu nehmen als den zusätzlichen Rechenaufwand bei der Anwendung.

    Rechtschreibfehler dienen der allgemeinen Belustigung. Ihr könnt sie sammeln und ab 100 gegen einen Preis eintauschen.

  • Juliean
    Administrator
    Reaktionen
    12
    Beiträge
    1.538
    Dateien
    1
    • 2. Oktober 2013 um 22:27
    • #20
    Zitat

    Ich habe mehrere Ebenen der Abstraktion in meiner Engine. Ich arbeite direkt auf den blanken OpenGL-Befehlen, verkapsele diese ersteinmal in passende Klassen, und baue dann aus dieser groben objektorientierten OpenGL-Implementation eine objektorientierte Grafik-Engine.
    Letzten Endes will ich, dass die äußerste Ebene, diejenige, welche von dem Benutzer am ehesten Verwendet wird, so sicher und zuverlässig ist wie nur möglich. Auch wenn dadurch möglicherweise die Performance ein wenig leidet. Mir ist am wichtigsten, dass es unmöglich ist, durch schlechte Parameterwahl ein unvorhersehbares Programmverhalten zu verursachen. Alle Parameter werden daher auf der äußersten Schicht überprüft und gegebenenfalls Exceptions geworfen.

    Ich verfolge selber einen ähnlichen Ansatz, wobei ich nicht ganz so rigide mit dem abfangen schlechter Paramter bin. Natürlich sollte nicht das Programm abstürzen weil ich als Position 1.05f angebe, aber man kann gerade in C++ nur sehr schwer (und aufwendig) verhindern dass sich jemand in das eigene Bein schießt. Verwendet man z.B. eine Referenz zum übergeben einer Klasse statt eines Pointers, kann der Benutzer immer noch einen nullptr dereferenziere - nichtsdestotrotz verwende ich Referenzen woimmer möglich und wo "nullptr" keine gültige Eingabe ist, auch auf den oberen Schichten, und lege genug Vertrauen in den Nutzer, dass dieser keine nullptr reinpasst.

    Zitat

    Die Sache mit den Buffern ist immer ein wenig kritisch zu sehen. Rein theoretisch kann man beliebig große Buffer verwenden und alles in einem Buffer speichern. Allerdings ist es mir von verschiedenen unabhängigen Quellen bekannt geworden, dass Buffer ab einer gewissen Größe (> 10mb) drastisch an Performance verlieren. (Abhängig von der Hardware)

    Hm, das wage ich gerade mit der heutigen Hardware stark zu bezweifeln. Außerdem müsstest du da allein bei deiner Spritegröße ~72.000 Sprites füllen, damit der Buffer auf eine annähernde Größe kommt. Die Devise hat ja gelautet, und lautet auch bis heute noch "Batchen, batchen, batchen". Deshalb, ohne dass ich es noch gebenchmarkt habe, wiegen die gewonnen Kosten durch die Verwendung eines einzelnen Buffers für so gut wie das ganze Programm (d.h. kein Bufferwechsel) garantiert jeden etwaigen Verlust durch die Größe aus.

    Zitat

    Wenn man Sprites mit verschiedenen Texturen in einem Buffer ablegen will muss man den Inhalt des Buffers nach Textur sortieren. Jedesmal wenn zusätzliche Sprites von der Anwendung erstellt werden muss man Inhalte im Buffer verschieben. Das sind beides sehr kostspieliege Operationen. Daher habe ich mich entschieden lieber den Cutoff bei den Buffern in Kauf zu nehmen als den zusätzlichen Rechenaufwand bei der Anwendung.

    Nein, das muss man so nicht machen, wäre in jedem Fall definitiv viel zu viel Aufwand, da geb ich dir Recht. Ich habe das so gelöst, dass ich die Sprite-Zeichen-Befehle nicht direkt auf den Buffer übertrage, sondern in einer Kommando-Queue zwischenspeichere. Diese sortiere ich dann nach Z und Textur (später noch shader), dauert wie ich bereits geschrieben habe nur wenige Millisekunden bei einer plausiblen Anzahl an Sprites. Damit kann ich dann einen Buffer verwenden, und den auch in einem Rutsch befüllen.

    Zitat

    Da der Großteil der Grafiken wahrscheinlich eher statisch sein wird (Gelände, HUD) und nur wenige Sprites (< 1000) regelmäßige Änderungen benötigen werden bleibe ich vorerst auch bei meiner ersten Methode.

    Ein interessanter Unterschied der scheinbar zwischen OpenGL und DirectX existiert, in letzterem ist bis 9 die Performance enorm gesteigert wenn man jedes Frame den ganzen Buffer neu befüllt (da ansonsten die Grafikkarte hängt während man den Buffer sperrt). Dazu sperre ich am Ende des Frames den gesammten Buffer mit dem "DISCARD"-flag, damit er gelöscht wird, und danach bei jedem Sprite mit "NO-OVERWRITE", das garantiert der Grafikkarte dass sie den Buffer auch verwenden kann während die CPU arbeitet. Ab DirectX11 ist es sogar ohne diese Flags nicht mehr möglich, einen Buffer von CPU-Seite aus zu befüllen, d.h. es entsteht keinerleich Nachteil durch statische oder dynamische Sprites...

    EDIT:

    Ah, den Buffer nur einmal zu sperren gibt einen Performance-Boost von ca 60% (450 FPS auf 750FPS in meiner Testszene, ~10000 Sprites, 2560x1600). Das erklärt auch warum der Gewinn dadurch nicht so gut war wie erwartet, damit muss ich mir wohl nochmal anschauen mein GUI auch noch mit dem Batcher zu rendern...

    EDIT2:

    Zitat

    Außerdem denke ich dabei immer an den Overhead auf der CPU-Seite. Ich werde für kein Projekt jemals so viele Sprites benötigen wie ich in diesem Test dargestellt habe. Ich gehe von nicht mehr als 20 000 zu einem gegebenen Zeitpunkt aus. Daher ist die Effizienz im Grafik-Bereich nicht das Hauptaugenmerk meiner Arbeit. Eher lege ich Wert darauf den Overhead auf Anwendungsseite gering zu halten.

    Das würd ich so nicht unbedingt sagen. Zumindestens die Sache multiple Bufferschreibvorgänge und mehrere Buffer erzeugt auch einen gewissen Overhead auf CPU-Seite, allein wegen der API-Aufrufe und des Speichertransfers... das wären in dem Fall 19k weniger Aufrufe zum Sperren des Buffers, das hat bei mir noch ne Menge Performance für die (noch) unoptimierte N^2 Kollisionabfrage rausgeholt...

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!

Benutzerkonto erstellen Anmelden

Discord

Mitglieder Online 48
  • aiZ Dante
  • Ali REMATCH
  • Argo Overwatch 2
  • Argosax87
  • Ark
  • Asor/Jürgen DARK SOULS III
  • Bollwerk
  • c... Project Zomboid
  • Calabiyaur
  • Camu
  • CharismaticEnigma/Sakuran Elsword
  • Cliqz
  • d...
  • Da_Rayz
  • Darknesslink81
  • Denis
  • Derxu
  • Distli/Distelo
  • EnigmaThePhoenix
  • Exec Grand Theft Auto V
  • Foxalor
  • Fraktalchen
  • h...
  • Ichigo3400 STAR WARS™ Battlefront™ II
  • Jarron
  • Jazzysan RetroArch
  • Jekkts
  • Jim
  • Manakaiser
  • Marcicore
  • Mave3rick
  • Megax VEIN Demo
  • Mozi
  • Mr.TopperH.
  • Peni in the Mech
  • Rng_Gaming87
  • Ryen
  • Saber
  • ShadeArk
  • Sid That Time I Got Reincarnated as a Slime ISEKAI Chronicles
  • Slanion
  • Sozi
  • Trekki2018
  • Vaan
  • WarriorOfIce
  • XeNoN3560
  • Zatox
  • Zorg0
Discord-Server beitreten
Discord-Widget © 2018-2025 by SoftCreatR.dev
  1. Datenschutzerklärung
  2. Impressum
Community-Software: WoltLab Suite™ 6.1.11
Design: BlueFire von simon-dev