Meine 2.5D Engine (alternative? xD)

Es gibt 68 Antworten in diesem Thema. Der letzte Beitrag () ist von jvbsl.

    Meine 2.5D Engine (alternative? xD)

    Hi, ich bin grade dabei ein Spiel im Format "Wolfenstein 3D" zu basteln. Das ganze soll Multiplayerfähig werden.

    Seht das hier bitte nicht nur als Fragethread, ich zeige auch mal was ich bereits gebastelt habe.

    Da ich von 3D-Programmierung (DX,OpenGL,SlimDX,etc) keine ahnung habe dachte ich mir ich programmiere meine Engine einfach selbst. Nun bin ich an einem Punkt angelangt andem ich sagen kann, dass ich damit nicht weiterkomme. Funktionsfähig ist die Grafikengine nur bedingt - frisst eben doch ganz schön Performance^^ Wenn ich daran denke noch mehr Sprites einzurechnen + Himmel,Bodentextur... naja die Framerate geht in den Keller^^

    Bei einer Auflösung von 320x240 Pixel läuft das Ganze mit ca. 50FPS - die 800x600Pixel Screenshots sind unter 10FPS entstanden. Das berechnen läuft in < als 10 ms ab (=>100FPS), nur das Zeichnen (mit Lockbits) dauert ewigkeiten... Für den, den es interessiert: Das Bild wird mittels RayCasting berechnet. Ich verwende KEIN DX,OpenGL oder sonstiges - ist alles reine Mathematik, entwickelt in vb.net - auch die berechnungen wo welche Textur hingezeichnet werden soll.. alles selbst programmiert. Hier gibts ein Tutorial, dass das System mal veranschaulicht - ich gehe allerdings nicht den Weg über die Winkel sonder den über Vektoren da man sich so Ärger mit den Polen der Tangensfunktion erspart xD





    Geplant sind noch Boden+Deckentextur ggf. eine Skybox. Die "Männchen" würden animierbar sein indem man die Textur entsprechend verändert. All diese Berechnungen drücken die Framerate in den Keller und ich will nicht noch mehr Zeit mit optimieren verbringen..

    Soviel zu meinem Gebastel, jetzt meine Fragen:

    Wie ist der einfachste Weg soetwas (Spiel im Stil von Wolfenstein3D) mit VB.NET zu realisieren, sodass die Performance hinterher (bei größeren Auflösungen) stimmt? Gibt es für diese 2.5D Welt eine gute und brauchbare Engine? Hat schon jemand etwas ähnliches gemacht?

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

    Wenn das alles wirklich in GDI+ gemacht ist, wirst du es nicht viel schneller machen können. Es sei denn natürlich, du hast dir an zu vielen Stellen eine derbe unperformanz gegönnt. Das wirst du aber selber finden müssen.

    Was Zeichnen angeht, kommt die CPU lange nicht an die GPU ran. Das wird hier ganz nett veranschaulicht. XNA bzw. DirectX wäre da um längen performanter.
    Ich behaupte einfach mal, dass das, was du da in GDI+ gemacht hast, in XNA einfacher wäre.
    Von meinem iPhone gesendet
    @Samus Aran
    @nikeee13

    GDI?! Das ist alles per Lockbits (Lib von Kevin89) gemacht! Kein scherz. So werden auch die Texturen einberechnet. (Okay, das Laden der Texturen mache ich per GDI, danach liegen sie nur noch als 2D-Color-Array vor. Gezeichnet wird nicht mit GDI).

    Ich erkläre einfach mal kurz meine Engine:
    Man durchläuft den Bildschirm von Links nach Rechts. Das Bild baut sich also Spaltenweise auf. Es werden also z.b. 320 "Sehstrahle" vom Betrachter ausgesendet. Man berechnet die Schnittpunkte mit den MauerBlöcken. So weiß man die Distanz, den genauen Schnittpunk an der Blockfläche (z.b. 0.6 Blockeinheiten) und welcher Block geschnitten wurde. So kann man berechnen wie hoch die Wand auf dem Bildschirm dargestellt werden muss (abhänig von der Distanz, die Wandhöhe ist ja immer gleich). Zusätzlich weiß man wo die Blockfläche geschnitten wurde - so kann man eine ganze Texturspalte auf die sichtbaren Blockbereich übertragen - Übertragen in den zbuffer, ein 2D array der farben und entfernungswerte enthält. Diese Werte braucht man, wenn man mit dem gleichen verfahren Sprites einberechnen will.
    Gezeichnet wird letzen endes nur der "zbuffer" - per lockbits auf eine Bitmap. Es ist also keinerlei GDI bei den Rendervorgängen von nöten.

    Das ganze ist zwar schön und gut, eine Zukunft hat es aber nicht. Darum steige ich um xD

    Mit XNA bin ich bereits am tüfteln. Dazu mal eine Frage: Ist es irgendwie ungewollt, dass man einzelne Polygone (also dreiecke) zeichnet? Ich habe den Eindruck, dass es so ist.. Immer werden nur "Meshes" etc gerendert... Meine Map besteht ja nur aus würfelförmigen Blöcken. Ist es nun die richtige Vorgehensweise die Polygone jedes Blocks zu berechnen (wären 8 pro Block) und diese dann zu zeichnen? Oder kann man das vereinfachen, quasie einmal einen Block deklarieren und diesen dann immer wieder woanders platzieren?

    lg

    FreakJNS schrieb:

    Gezeichnet wird letzen endes nur der "zbuffer" - per lockbits auf eine Bitmap. Es ist also keinerlei GDI bei den Rendervorgängen von nöten.

    Genau dort verwendest du GDI+. Klar kannst du die Bitmap noch manuell manipulieren, aber die wird dann ja irgendwie auf dem Bildschirm ausgegeben. Wetten, per GDI+?

    Übrigens Respekt. Sieht nach einer Menge Arbeit aus. Erschließt sich mir nur nicht so ganz, warum du nicht direkt XNA genommen hast ^^

    Skybird schrieb:

    Das sind ja Ubisoftmethoden hier !

    okay - letzten endes wird eine fertige Bitmap per GDI auf den Bildschirm gezeichnet. Das frisst aber nicht die Performance.

    Wie auch immer, ich will ja weg von der selbst programmierten Engine, da diese die Leistung nicht bringt, die ich brauche. War ein schönes Wochenend-Projekt, das demnächst bei all dem anderen Kram auf der HDD verstaubt^^

    ps: das CPU vs GPU - video ist klasse!

    @vb-checker
    Danke! So viel arbeit ist es eigentlich garnicht, man musst nur das Hauptproblem lösen - hat mich viel Nerven gekostet... Ab dann ist es einfach(er). Ich wollte schon immer mal soetwas komplett selbst Programmieren. Habe vor längerer Zeit etwas gebastelt, dass HeighMaps von Terrains rendert, was ja so ählich funktioniert.

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

    @TanoshiiSuta
    Ja, bin ich! Dein Textursystem habe ich nicht so ganz verstanden, darum habe ich mir den code nicht noch genauer angesehen. Außerdem mache ich im "Kern des Algorithmus" alles mit Vektoren - da Ärgert man sich nicht mit den trig. Funktionen rum (tan(270°) = enjoy your programmabsturz).
    Was mir jedoch sehr gut gefällt ist wie du den Renderpart mit dem Berechnen der Bewegungen verbindst - werde ich wohl genauso machen.

    Wie auch immer, ich habe weiter an meiner Engine gearbeitet. Es gibt jezt einen halb fertigen Level-Editor, ein SkyBox-System, Bodentexturen (ermöglichen Pseudo-Schattendarstellungen) und funktionierende Sprites mit zBuffer (werden vor dem Zeichnen nach Kameradistanz sortiert, also ein ganz anderes system als beim zeichnen der Mauern/Böden verwendet wird).






    Als nächstes will ich den Level-Editor weiter ausbauen. Vor allem das Multiplayer-system wird wieder ein ganzer Brocken, da ich auch "Bots" einbauen will. Diese will ich mit meiner PathFinderLib auf vorgegebenen Routen laufen und bei "Feindkontakt" angreifen lassen. Dann muss noch ein Soundsystem her - ich denke dafür werde ich SFML nutzen (mir reichts wenn ich die Geräusche unterschiedlich laut, je nach entfernung, dartellen kann). Ist für mich grade desshalb ein sehr interessantes Projekt: alles findet hier Verwendung! :thumbsup:
    @Samus Aran

    bei einer Auflösung von 200x160 > 60FPS
    bei 800x600 < 10 FPS xDD

    Also eher bescheiden. Darum gehts mir aber auch nicht mehr so - ist selbst bei dieser sehr geringen Auflösung von der Grafik her spielbar. Ich will das auf jeden Fall komplett fertig machen, von Anfang bis Ende - wer kann das von sich behaupten xD Ich denke, dann hab ich auch für die Zukunft, wenn ich vllt die Grafikengine absetze und umsteige, den vorteil, dass ich schon weiß wie ich zum Verbinden der Komponenten (Sound, Multiplayer, Pfadfindung, etc) vorgehen muss.

    Ich bin mir aber sicher, dass ich noch den Ein oder Anderen Frame rausholen kann wenn ich ans optimieren gehe - allein schon die gleichbleibenden Berechnungen außerhalb von Schleifen auslagern..

    lg^^
    @nikeee13
    Danke! Wenn ich soweit bin, dass es spielbar läuft werde ich es im Showroom posten. Jenachdem wie aufgeräumt der Code ist vllt sogar als OpenSource-Projekt. Aber wie gesagt, die Auflösung muss zum zocken klein bleiben...
    Naja, wenn er das Bild sowieso über ein Array und LockBits generiert, wäre es prinzipiell auch eigentlich kein Problem, eine Art Möglichkeit für Shader anzubieten, da er wahrscheinlich eh jeden Pixel durchgeht ;) Performant wird das aber definitiv nicht sein.

    Btw, hast du mal versucht etwas Performance herauszuholen, indem du das endgültige Bild mit anderen GDI Einstellungen zeichnest und quasi nur den Buffer auf dein Control kopierst? Das dürfte eine Menge reißen, falls du das nicht schon machst.

    VB.NET-Quellcode

    1. e.Graphics.CompositingMode = CompositingMode.SourceCopy
    2. e.Graphics.CompositingQuality = CompositingQuality.HighSpeed
    3. e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor
    4. e.Graphics.SmoothingMode = SmoothingMode.HighSpeed
    5. e.Graphics.PixelOffsetMode = PixelOffsetMode.HighSpeed


    MfG

    Bewegte Bilder!!

    So, es gibt sehr gute Neuigkeiten: Ich habe (eigentlich schon gestern) meinen "GameTicker" - ein SpezialTimer, der mittels Stopwatch eine konstante FrameRate ermöglicht und die Daten (Positionen, etc) aktualisiert - programmiert und mit der Engine "verbunden". Das Ergebnis: eine Framerate von 66FPS bei einer Auflösung von 320x240!! Hört sich nach nichts an, so lässt es sich aber zocken xD Außerdem ist der Code noch größtenteils unoptimiert.
    Auch komisch ist, dass eine Framerate von ca. 70 das Maximum ist, bei sehr kleinen Auflösungen sollte aber eine deutlich höhere Framerate (300FPS hatte ich im Dauerloop bei 160x120 glaubich) erzielt werden - tut es aber nicht.. Wie auch immer, optimiert wird später.
    Ein viel größeres Problem bereiten mir die NPCs, diese will ich mit meiner PathFinderLib steuern - und dann der Multiplayer... Das wird ein Akt

    Das Demo-Video zeigt übrigens auch die erste Sprite-Animation! Man schenke dem Feuer große Achtung xD Die Lichteffekte sind übrigens nicht "echt". Soetwas muss man vorher in die Textur einarbeiten - GIMP2 lässt grüßen.

    @vb-checker
    @Samus Aran
    An solche Filter/Shader(?) habe ich auch schon gedacht^^ Finde ich immer wieder fazinierend wie die Renderqualität eines Gamboy-Emulators durch Nutzung eines solchen aufpoliert wird. Würde bei mir sicher auch ein kleines Wunder bewirken. Weiß jemand mehr darüber?

    @Krissel095
    Danke für den Tipp, werde ich demnächst definitiv testen! Momentan realisiere ich das noch mit einer Bastellösung: das Bild wird gerendert, dann ruft der GameTicker das UpdateGUI-Event auf und das gerenderte bild wird auf den Bildschirm gebracht- per Picturebox xDDD wie immer: optimiert wird später


    Wie auch immer, hier ist Bildmaterial:
    dead links/404 an dieser Stelle entfernt ~VaporiZed

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

    Hehe.. Trollface..
    Alle Achtung. :)

    Wie wäre es, wenn du auf DirektX umsteigen würdest.
    Da könnte man deutlich mehr und besseres machen.
    Du hast es drauf! Es sieht im Vergleich zu anderen "Engine"s komisch aus, aber die gesagt.. das ist GDI + :D
    @Krschy
    von DirektX und konsorten habe ich keine Ahnung, darum auch die Engine xD
    Das es etwas "anders" aussieht liegt aber nicht an GDI, sondern an der Mathematik. Es ist eben auch kein echtes 3D, sondern nur 2.5D

    @kinsi
    danke! Da ich davon noch nie gehört habe vermute ich mal ja, da es wahrscheinlich schlecht ist^^
    Beschleunigt der Wert den GDI-Zeichenvorgang oder ist er nur gegen Flimmern?