Möglichst effizienter Pixel Draw?



  • Hallo!

    Es gibt ja verschiedene APIs wie GDI oder Direct X oder Open GL mit denen man auf dem Bildschirm was zeichnen kann bishin komplexe Games.

    Aber wie machen die das? Kann man auch direkt irgendwelche Pixel am Monitor umstellen, mal abgesehen davon dass Windows dann ggf. drüberzeichnet?
    Ich habe gelesen SetPixel von GDI ist langsam, wäre direktes Drawing dann am schnellsten?
    Welche Funktionen verwendet man für sowas bzw. wie macht Direct X das?

    Liebe Grüße


  • Mod

    Frag nach dem Ziel, das du vor hast, nicht danach, wie du denkst, wie man dieses Ziel erreicht. Es macht wenig Sinn sich damit zu beschäftigen, wie man einzelne Pixel möglichst schnell setzt, bloß um dann hinterher zu erfahren, dass du beispielsweise eigentlich eine Linie zeichnen wolltest, wo die schnellste Methode eben nicht wäre, diese aus einzelnen Pixeln zusammen zu setzen.



  • @SeppJ Naja ich will ein liebes Spiel programmieren mit buntem comicartigem Stil ohne wie die Masse eine fertige Engine zu downloaden und dabei verstehen wie man möglichst effizient arbeitet von anfang an.

    Wenn das Bild gerendert wurde, dann ist es ja in einem 2D Array oder so? Und dann wird das erst Pixel für Pixel aus diesem Buffer auf den Screen projiziert?

    Ist Direct X schon so gemacht, das maximale aus der CPU herauszuholen? Ist ja quasi eine Blackbox mit den ganzen fertigen Funktionen und keine Motivation da alles zu reversen.


  • Mod

    Du willst 150 Mannjahre in die Entwicklung einer eigenen Grafikengine investieren, weil du denkst das wäre der einfache Weg?!



  • @SeppJ Nein ich habe nie gesagt der einfache Weg, aber es nervt mich immer fertige Funktionen zu verwenden wo ich nicht sehe was die im Detail machen.

    Aber im Prinzip ist wohl das beste ich schaue mir einfach mal Direct X an und wenn ich soweit bin, dass meine CPU ans Limit kommt, denk ich nochmal über die Effizienz der API nach.



  • DirectX [Graphics], OpenGL als auch das neuere Vulkan verwenden hardware-basiertes Rendering, d.h. es wird hauptsächlich die GPU (also der Prozessor auf der Grafikkarte) benutzt, nicht die Computer-CPU.

    Außerdem wird nicht pixelbasiert gezeichnet, sondern die elementaren Objekte sind Dreiecke (Triangels), aus denen dann komplexe Objekte erzeugt werden.
    Um eine Pixelzeichen-Funktion anzubieten, wird dann von der Grafik-Lib ein Rechteck der Größe 1x1 gezeichnet.

    Weitere wichtige Begriffe diesbzgl. sind Front- und Backbuffer, s.a. Doppelpufferung: Funktionsweise bei der Bildausgabe.



  • @CUser1 sagte in Möglichst effizienter Pixel Draw?:

    Direct X an und wenn ich soweit bin, dass meine CPU ans Limit kommt, denk ich nochmal über die Effizienz der API nach.

    lol



  • @Th69 Ja aber im Endeffekt besteht das Triangle ja auch aus Pixeln die am Monitor leuchten?

    Das heißt man verwendet die CPU nur für Spielabläufe usw. und wenn man mit der Spielfigur um eine Einheit nach vorne geht, dann wird die GPU angewiesen, die Schatten und Lichter usw. für den nächsten Frame zu berechnen?

    Der Frontbuffer ist einfach nur ein Array entsprechend der Auflösung oder? Und beinhalten 1 zu 1 die Bildpunkte und wird dann mit 60 Hz z. B. projiziert?

    Und ist das was man als Welt oder Level bezeichnet im Endeffekt einfach ein 3D Array wo alle Bildpunkte drinn stehen und alles repräsentieren für den Moment und vorm Draw wird je nach Kameraposition ein 2D Array daraus gemacht?


  • Mod

    Wenn du ernsthaft jemals auch nur irgendwas in dieser Sache erreichen willst: Hör auf die Ratschläge hier! Vergiss das mit dem selber machen, schnapp dir eine fertige Engine, und dann hast du auch Aussicht, in den nächsten Jahren(!) ein eigenes Spiel zu machen, das so aussieht wie das was man so von der Indie-Szene her kennt.

    Falls es dir um Grafik an sich geht, dann hör auch auf die Ratschläge hier und beschäftige dich mit den gängigen Grafik-APIs! Dann hast du Aussicht, in ein paar Monaten(!) etwas zu schaffen, das halbwegs cool aussieht. Undauf dem Weg dahin kannst du in ein paar Tagen ein paar Linien damit zeichnen.

    Deine jetzige Vorstellung, wie Grafik überhaupt funktioniert, stimmt seit ca. 35 Jahren nicht mehr. Ich mag gar nicht anfangen, alle deine Fehlvorstellungen zu korrigieren. Folge einfach einem der Tipps von oben. Beim zweiten bekommst du auch mit, wie der technische Unterbau von Computergrafik in der echten Welt so ungefähr funktioniert.



  • @SeppJ Ja du hast eh recht damit dass es vernünftiger wäre mal ein Buch zu besorgen, ich will halt so wenig wie möglich kopieren und so viel wie möglich selber erschließen.

    Wie ist ein Level von so einem 3D Spiel im RAM gespeichert? Es existiert ja irgendwie auch ohne das wer hinsieht wie der Raum neben an jetzt in seinen Atomen besteht?

    Also wenn man mit Gameengine im Baukastenprinzip eine Map baut, was macht die dann beim Ausführen der Executeable?

    Und ja, ich glaube nicht dass ich die jahrzentelange Evolution der Games in einer Woche überspringen kann und erwarte mir nicht sowas wie mit UE5 in einer Woche zu erschaffen, es geht mir mal um fundamentale Basics bevor ich im Legobaukasten fertige Steine zusammensetze. Wobei das fertige Spiel zweitrangig sein darf und es sich lediglich um ein Hobby handelt.


  • Mod

    Das kann man nicht in ein paar Worten beschreiben, lies halt Grundlagen der 3D-Programmierung. Wobei du das gar nicht wissen brauchst, wenn du ein Spiel programmieren möchtest, denn mit solchen Details hat sich ja der Programmierer der Engine herumgeschlagen.

    Ganz grob wurde es ja schon gesagt: 3D-Level liegen als ein Netz aus Dreiecken vor. Die Dreieckspunkte haben auch noch Eigenschaften bezüglich ihrer Ausleuchtung, und der Oberfläche, wie das Dreieck aussieht. Außer, dass das was ich dir gerade erzähle in dieser Einfachheit vielleicht 1995 das letzte Mal gestimmt hat…



  • Wenn du einfach nur neugierig bist, wie man aus einzelnen Pixeln ein 2D oder 3D-Bild erstellt, dann versuche einfach nur eine Bitmap-Datei zu erstellen, wo du eine Linie reinmalst oder ein 3D-Würfel. So bekommst du erstmal ein Gefühl dafür, wie man aus einzelnen Pixeln Grafiken erzeugt. Das so erlernte Wissen wird dir dann zwar beim Erstellen des Spiels vielleicht erstmal nicht weiterhelfen aber so kannst du dich an die Grafik-Sachen rantasten. Der nächste Schritt wäre dann sich entweder mit einer Spiele-Engine oder z.B. DirectX zu beschäftigen. Je nachdem ob du dein Focus mehr auf die Spiellogik oder auf die Grafik-Logik richten willst.

    Die Idee ein Spiel zu schreiben, wo du in den Bildschirmspeicher schreibst, kenne ich noch von Turbo Pascal. Dort gab es den 13h-Mode (https://en.wikipedia.org/wiki/Mode_13h) Wenn du also wirklich in diese Richtung gehen willst, dann schau dir an, wie du also 13h verwendest. Ich bin mir aber nicht sicher, ob das mit den heutigen Programmiersprachen noch geht. Man braucht dazu ein MSDos-System (DosBox) um das zu nutzen.



  • @CUser1
    Wenn du die Grundladen von modernen 3D Engines verstehen willst würde ich dir empfehlen ein kleines Programm zu schreiben das mit Hilfe von Direct3D9 und Vertex Buffern ein Dreieck auf den Bildschirm malt. Als nächstes kannst du dort einen Pixel-Shader einbauen. Dann eine Textur die du im Pixel-Shader verwenden kannst. Dann vielleicht eine einfache Lichtberechnung. Dann kannst du aus dem Dreieck einen Würfel machen und den rumdrehen. Dann hast du einen texturierten, beleuchteten Würfel der mit halbwegs modernen Mitteln gezeichnet wird.

    Aktuelle D3D Versionen und Vulkan unterscheiden sich dann nochmal in einigen Punkten. Aber die Grundprinzipien sind durchaus ähnlich. Und davon direkt mit aktuellen D3D Versionen oder Vulkan einzusteigen würde ich abraten, da diese viel komplizierter zu verwenden sind als D3D9. Alles vor D3D9 würde ich auch eher nicht empfehlen, da es damit wie heute 3D gemacht wird dann schon viel weniger zu tun hat.

    OpenGL würde ich auch nicht empfehlen. Das Problem bei OpenGL ist, dass du als Anfänger nicht weisst welche der unzähligen Möglichkeiten die dir da zur Verfügung stehen noch aktuell ist - in dem Sinn als dass man es für moderne Projekte noch verwenden würde. Wenn du dann ein Tutorial findest wo z.B. noch glLight und Display-Lists verwendet werden, dann bringt dir das nichts wenn du lernen willst wie man das heutzutage macht.


  • Mod

    Unter der annahme, dass du c++ kannst, kannst du deinen wunsch, pixel zu manipulieren, bzw arrays von pixel anzeigen, mittels https://github.com/ColinGilbert/pixeltoaster erreichen.
    Unter der annahme, dass du c kannst, dasselbe bei https://github.com/erkkah/tigr .

    wenn du zu deiner zufriedenheit pixel anzeigen kannst, empfehle ich dir, als erstes vielleicht das game of life zu implementieren https://en.wikipedia.org/wiki/Conway's_Game_of_Life , weil du dazu nur deine programmierfaehigkeiten, die gerade elernte pixelausgabe und die logik die in wikipedia beschrieben wird brauchst.



  • @CUser1 sagte in Möglichst effizienter Pixel Draw?:

    Und ist das was man als Welt oder Level bezeichnet im Endeffekt einfach ein 3D Array wo alle Bildpunkte drinn stehen und alles repräsentieren für den Moment und vorm Draw wird je nach Kameraposition ein 2D Array daraus gemacht?

    das ist gar nicht soo falsch ....

    Stell dir eher vor, in der 3D engine sind die daten, die deine Welt/Level Objekte etc. beschreiben .... meist eine Kombo aus 3D daten (Triangle / Meshes), 2D daten (Texturen / Verläufe) und ne ganze Menge Verwaltungskrams ...

    und dann wird daraus deine "Scene" gerendert ... dazu wird so viel wie möglich auf die Graka geschoben und die macht das dann .... meist in mehreren stages, der wichtigste ist dann die Rasterization .... da wird nicht ein 2D Buffer erzeugt, sondern mehrere (meist 3) aber nur einer, (der ColorBuffer) intressiert als Endergebnis.

    Im Directmodus wird der buffer dann direct auf den monitor geschoben, aber oft wird das ergebnis auch wieder ans OS (CPU) gegeben, und das blitted es dann an die richtige Position (Fenster)

    Fuers Rastern und die primitiven 3D grafik stages hat man "simple" algos (interpolation und extrapolation) und das für viele viele daten die unabhängig voneinander ausgeführt werden können und kaum verwaltung -> Parralellisierung -> GPU ist das richtige Gerät dafür ....

    Rasterization wird auch im 2D bereich benötigt .... ellipsen malen z.b. da wird fix berechnet, welche punkt in welchen bereich farbe abbekommen oder nicht ... oder (poly)linien ... dafür haben Grakas schon lange Funktionen / Support für GDI Funktionen ....

    Wenn deine Basis Linen, Kreise, Ellipsen sind, und du nicht tonnenweisse parralell Vorbedingungen rechnen musst (Vertex/Geometry/Tesselation Stages) oder sowas, würde GDI (2D beschleunigte Grafikroutinen) kaum einen Nachteil haben ...

    Hasst du was ganz spezielles, ebenfalls viele schritte unabhängig voneinander auf einen Buffer bedingt, aber eben sehr speziell für deinen fall ist, so das es die renderpipline nicht kann(spezielle Image filter etc), dann sind direkte GPU programme(cuda opencl ...) das mittel der Wahl, das funktioniert ähnlich, und freier (weniger vorgeschriebene Workflows) und noch generischer ...


Anmelden zum Antworten