Wie funktionieren Grafik APIs ?



  • Hallo,

    man benutzt immer OpenGl, DirectX oder andere API´s, um Grafikprogrammierung zu betreiben. Wurden diese auch mit einer Programmiersprache wie C erstellt? Wie ist es möglich zum Beispiel mit C direkt den Bildschirm zu Programmieren?

    MfG M1SMR



  • Dieser Thread wurde von Moderator/in SeppJ aus dem Forum C++ (alle ISO-Standards) in das Forum Rund um die Programmierung verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.


  • Mod

    Unterscheide zwischen den Schnittstellen und der Implementierung! Die Schnittstelle ist nirgendwo programmiert, das ist ein Industriestandard, auf den man sich irgendwann einmal geeinigt hat, was ein Grafiktreiber für Funktionen anzubieten hat. Ein Grafiktreiber implementiert diese Schnittstellen in der Sprache der Wahl der Entwickler, dabei wird tatsächlich sehr oft C eingesetzt. Den Grafiktreiber hat entweder der Hersteller der Grafikkarte/des Grafikchips selber programmiert, weil er weiß, wie seine Hardware genau funktioniert; oder jemand anderes, weil er irgendwoher weiß, wie die Grafikhardware (ganz oder wenigstens teilweise) anzusprechen ist.

    Die Ansprache der Grafikhardware funktioniert auf unterster Ebene so, dass die Befehle und Daten an bestimmte Speicheradressen im Computer geschrieben werden, die dann in der Hardware so verschaltet sind, dass die Daten an die Grafikhardware gehen. Der Grafiktreiber wird diese Schnittstellen in aller Regel aber nicht selber bedienen, sondern sich stattdessen einer Schnittstelle des Betriebssystems zur Hardwarekommunikation, als quasi eines Treibers für die Hardwarekommunikation, bedienen.

    Ein normales Anwendungsprogramm kann normalerweise nichts davon tun, weil das Betriebssystem ihm nur die letztliche Schnittstelle anbietet, die von den Treibern angeboten wird. Die Funktionen zur direkten Ansprache der Hardware sind für normale Anwendungen nicht verfügbar und sie können auch nicht auf eigene Faust an die "magischen" Speicheradressen schreiben, weil diese niemals auf den Speicherbereich eines normalen Anwendungsprozesses gemappt werden.



  • Hi SeppJ,

    ich hab das Thema nicht eröffnet, finde es aber auch interessant.

    Danke für deine ausführliche Beschreibung. Mir kam da gerade die Frage in den Kopf, wieso es unter Linux, so weit ich mich erinnern kann, einen Kernel-Treiber für die Grafikkarte und dann nochmal irgendeine X11-Lib, die auch den Namen der Grafikkarte im Namen des Paketes aus dem Paketmanager hatte, gibt. Welche Aufgabe übernimmt der grafikkartenspezifische Kernel-Treiber und welche die X11-Lib? Konkret dürften das Treiber für irgendeine Intel HD Graphics Karte gewesen sein.


  • Mod

    Meine Beschreibung war natürlich stark vereinfacht und ich bin absichtlich möglichst systemunabhängig geblieben. In der Praxis kann und wird das, was ich oben "Grafiktreiber" genannt habe, in mehrere Teile aufgeteilt sein. Wie genau, das hängt stark vom Gesamtsystem ab. Eine Übersicht für Linux mitsamt historischer Entwicklung gibt es zum Beispiel hier:
    https://blogs.igalia.com/itoral/2014/07/29/a-brief-introduction-to-the-linux-graphics-stack/
    Da wird auch noch einmal etwas ausführlicher erklärt, was ich kurz zusammen gefasst habe.



  • Lober schrieb:

    Hi SeppJ,

    ich hab das Thema nicht eröffnet, finde es aber auch interessant.

    Danke für deine ausführliche Beschreibung. Mir kam da gerade die Frage in den Kopf, wieso es unter Linux, so weit ich mich erinnern kann, einen Kernel-Treiber für die Grafikkarte und dann nochmal irgendeine X11-Lib, die auch den Namen der Grafikkarte im Namen des Paketes aus dem Paketmanager hatte, gibt. Welche Aufgabe übernimmt der grafikkartenspezifische Kernel-Treiber und welche die X11-Lib? Konkret dürften das Treiber für irgendeine Intel HD Graphics Karte gewesen sein.

    X11 läuft nur im Userspace. Wenn es schnell gehen soll, dann braucht man also im Kernel eine Schnittstelle mit kürzerem Weg die im Kernelspace läuft.
    Deswegen gibt es für X11 und dem Kernel jeweils einen Treiber die miteinander arbeiten.



  • Also ich könnte quasi einen eigenen Grafiktreiber für Hardware schreiben die ich gut kenne oder selbst erstellt habe? (ich weiß das zweite ist unrealistisch)

    Und das ginge nur mit C oder anderen Sprachen, die die Hardware direkt ansprechen können oder?



  • M1SMR schrieb:

    Und das ginge nur mit C oder anderen Sprachen, die die Hardware direkt ansprechen können oder?

    bei memory-mapped-i/o mit jeder sprache, die physikalische speicherzellen adressieren kann.


  • Mod

    M1SMR schrieb:

    Also ich könnte quasi einen eigenen Grafiktreiber für Hardware schreiben die ich gut kenne oder selbst erstellt habe? (ich weiß das zweite ist unrealistisch)

    Klar, wie sonst sollte jemals ein Treiber geschrieben werden? Dafür braucht man keine polizeiliche Genehmigung.

    Und das ginge nur mit C oder anderen Sprachen, die die Hardware direkt ansprechen können oder?

    Was sollte an C in dieser Hinsicht anders sein als an anderen Sprachen? Die einzige echte Voraussetzung ist, dass die Sprache die Funktionen des Betriebssystems zur Hardwarekommunikation ansprechen kann.

    Es spricht natürlich vieles anderes für C, aber C kann nicht magisch mit Hardware reden.



  • SeppJ damit meine ich genau diese Sprachen und das es zum Beispiel mit Java nicht funktionieren würde.



  • M1SMR schrieb:

    SeppJ damit meine ich genau diese Sprachen und das es zum Beispiel mit Java nicht funktionieren würde.

    java kann das nicht. java läuft in einer sandbox aka virtual machine.
    wenn du in java hardware ansprechen willst, brauchste libraries, die ein native interface implementieren. und die sind meistens in c geschrieben.


  • Mod

    M1SMR schrieb:

    Wie ist es möglich zum Beispiel mit C direkt den Bildschirm zu Programmieren?

    Wie ist es möglich, mit C einen Prozessor zu Programmieren?



  • Ich hätte dazu auch mal eine Frage, vielleicht kann mir das jemand leicht und verständlich erklären.

    Wie funktionieren Grafiklibs, zum Beispiel SDL oder Glut, oder GUI Toolkits wie zum Beispiel Qt, wxWidgets oder auch Gtk?

    Sprechen diese mit Bibliotheken auf dem OS um "Zeichenvorgängen" zu realisieren?
    Oder werden die APIs von Windows/Linux/OSX dafür beansprucht die Darstellung von Dropdowns, Listboxen, Inputfeldern und anderen Elementen zu realisieren?

    Ich würde gerne mal in diese Programmierung einsteigen, aber überall werden in der Regel "irgendwelche" Libs verwendet, so das man gar nicht Low-Level gehen kann/muß.
    Ist mir klar das man das Rad nicht zwingend neu erfinden wollen sollte - aber ich würde gerne mal einen Einblick bekommen, wie so etwas im "Detail"/Low-Level funktioniert.

    Vermutlich eine komplexe Materie - aber das, frei sein, wäre schon interessant. Und da ich ein wenig Ahnung mit C habe, würde ich gerne mal so etwas realisieren.

    Ziel sollte es sein, sich nicht immer auf eine GUI Bibliothek zu verlassen, die dann auch vielleicht noch mit irgendwelchen Lizenzen verbunden daherkommt und mich gleich vorweg in Schranken weist was ich darf und nicht darf. 😉

    Bzw. auch, was für Kenntnisse müsste ich mitbringen, wenn ich selbst mal ein Fenster Zeichen will und mir selbst UI Komponenten zusammenbasteln will?

    Vielleicht auch jetzt der Einfachheit halber unter Linux, das würde ich sogar bevorzugen 🙂



  • theSplit schrieb:

    Ich hätte dazu auch mal eine Frage, vielleicht kann mir das jemand leicht und verständlich erklären.

    Wie funktionieren Grafiklibs, zum Beispiel SDL oder Glut, oder GUI Toolkits wie zum Beispiel Qt, wxWidgets oder auch Gtk?

    Sprechen diese mit Bibliotheken auf dem OS um "Zeichenvorgängen" zu realisieren?
    Oder werden die APIs von Windows/Linux/OSX dafür beansprucht die Darstellung von Dropdowns, Listboxen, Inputfeldern und anderen Elementen zu realisieren?

    Ich würde gerne mal in diese Programmierung einsteigen, aber überall werden in der Regel "irgendwelche" Libs verwendet, so das man gar nicht Low-Level gehen kann/muß.
    Ist mir klar das man das Rad nicht zwingend neu erfinden wollen sollte - aber ich würde gerne mal einen Einblick bekommen, wie so etwas im "Detail"/Low-Level funktioniert.

    Vermutlich eine komplexe Materie - aber das, frei sein, wäre schon interessant. Und da ich ein wenig Ahnung mit C habe, würde ich gerne mal so etwas realisieren.

    Ziel sollte es sein, sich nicht immer auf eine GUI Bibliothek zu verlassen, die dann auch vielleicht noch mit irgendwelchen Lizenzen verbunden daherkommt und mich gleich vorweg in Schranken weist was ich darf und nicht darf. 😉

    Bzw. auch, was für Kenntnisse müsste ich mitbringen, wenn ich selbst mal ein Fenster Zeichen will und mir selbst UI Komponenten zusammenbasteln will?

    Vielleicht auch jetzt der Einfachheit halber unter Linux, das würde ich sogar bevorzugen 🙂

    SDL und Glut verwenden OpenGL zum zeichnen. OpenGL braucht einen sogenannten Context um überhaupt zu funktionieren. Dieser Context wird in Platform abhängiger weise „erworben“, d.h. unter X Server gibt es die GLX API, unter einem Linux Wayland Compositor verwendet man EGL, unter Windows verwendet man die WGL API um an einen Context zu gelangen. Warum so kompliziert? Weil jede grafische Umgebung anders mit dem Betriebsystem kommuniziert. Das erlaubt es schließlich mit Grafikkartenbeschleunigung zu zeichnen.

    Toolkits wie Qt, wxWidgets und GTK haben eine ganz andere Aufgabe. Das (Haupt-)Ziel dieser Libs ist es normale Fenster mit Widgets (Buttons, Scrollbars, etc.) zu ermöglichen. Das kann je nach Platform wieder anders aussehen:
    Unter Windows gibt es schon fertige Widgets, die von den Libs verwendet werden können (damit sie sich von dem Look&Feel der anderen Anwendungen nicht unterscheiden).
    Unter einem X Server und einem Wayland Compositor gibt es solche primitiven Widgets nicht, d.h. die Toolkits müssen jedes Widget selbst zeichnen und auch selbst die ganze Logik von denen implememtieren.
    Die Toolkits können natürlich unter Windows auch die ganzen Widgets selbst zeichen, damit die Anwendungen eines Toolkits unter verschiedenen Platformen gleich aussieht.

    Wie geht dieses selbst zeichnen nun? Grob:
    Du bekommst von der jeweiligen API (Xlib/xcb/wayland-client/WinAPI) einen Pixel-Puffer in der Größe deines Fensters, in das du nun nach Herzenslust deine Widgets zeichnen kannst. Maus- und Tastatureingaben musst du selbst abfangen und behandeln, je nachdem wo der Fokus ist (Fokus musst du auch selbst implementieren ;))
    Den Puffer kann man auch z.B. mit OpenGL/Vulkan/DirectX füllen um ihn dann anzuzeigen.

    Wenn du damit mal ein bisschen herumspielen möchtest, kann ich libwayland-client unter Linux empfehlen. Das ist im Vergleich zu den anderen Grafikumgebungen recht einfach zu verwenden. Eine einfaches Beispiel findest du z.B. unter https://cgit.freedesktop.org/wayland/weston/tree/clients/simple-shm.c
    Hier werden zwar keine Widgets erstellt, sondern nur das Fenster, aber man sieht wie hier verschiedene Farben in diesen Puffer geschrieben werden um sie anschließend anzuzeigen.



  • Hi,

    sehr schön war das in der alten MS-DOS-Zeit zu beobachten, wo sich viele praktisch ihre eigene Grafik-API geschrieben haben.
    Falls genaueres interessiert, so kann man das immer noch sehr anschaulich mit jeder Menge Beispielquelltext im PC-Intern von Michael Tischer nachlesen.
    https://www.amazon.de/PC-intern-Systemprogrammierung-Michael-Tischer/dp/3815811694/ref=sr_1_3?ie=UTF8&qid=1478078085&sr=8-3&keywords=pc+intern
    Da sind die ganzen einzelnen Treiber und Systemfunktionen die man dafür braucht beschrieben und entsprechender Quelltext bereit gestellt.
    Im übrigen brauchts dafür nicht mal unbedingt C. Nicolaus Wirth hat auch mal ein Betriebssystem komplett in Modula 2 geschrieben. Muss wohl nicht so der Brüller gewesen sein, denn es ist keines von den großen geworden, aber da er ja in erster Linie Informatikprofessor war gings ihm auch wohl mehr um den Beweis der Machbarkeit.
    Letztlich ist auch sein Modula 2 in der Versenkung der Zeit verschwunden und nur das von ihm wesentlich früher entworfene Pascal lebt heute in der weiterentwickelten Version Delphi weiter.

    Gruß Mümmel


  • Mod

    muemmel schrieb:

    Im übrigen brauchts dafür nicht mal unbedingt C.

    Das ist wohl vor allem eine Bequemlichkeitsfrage. Die ganzen Schnittstellen sind so ausgelegt, als ob man C benutzen würde. In anderen Sprachen muss man dann prügeln, damit es sich wie C verhält.



  • swapper schrieb:

    M1SMR schrieb:

    SeppJ damit meine ich genau diese Sprachen und das es zum Beispiel mit Java nicht funktionieren würde.

    java kann das nicht. java läuft in einer sandbox aka virtual machine.
    wenn du in java hardware ansprechen willst, brauchste libraries, die ein native interface implementieren. und die sind meistens in c geschrieben.

    Mit JNI ist das so (Standardmethode).
    Mit JNA ist das nicht mehr so, sondern

    JNA provides Java programs easy access to native shared libraries without writing anything but Java code - no JNI or native code is required. This functionality is comparable to Windows' Platform/Invoke and Python's ctypes.

    Allerdings nur wenn die Platform von JNA supportet ist.



  • theSplit schrieb:

    Ziel sollte es sein, sich nicht immer auf eine GUI Bibliothek zu verlassen, die dann auch vielleicht noch mit irgendwelchen Lizenzen verbunden daherkommt und mich gleich vorweg in Schranken weist was ich darf und nicht darf. 😉

    Wenn du mal professionell GUI Anwendungen schreiben solltest, dann zahlst du diese Lizenzen gerne, weil die Lizenzkosten dafür deutlich günstiger sind, als die Kosten, die zu stemmen müsstest, wenn du die ganze GUI Lib selber schreiben würdest.

    Bzw. auch, was für Kenntnisse müsste ich mitbringen, wenn ich selbst mal ein Fenster Zeichen will und mir selbst UI Komponenten zusammenbasteln will?

    Die typischen Vertreter und Algorithmen zur Darstellung von Linien und Co, wobei man heutzutage das alles über die Grafikkarte und deren 3d Beschleunigereinheit macht, insofern würde man heute das ganze auf Direct3d oder OpenGL bzw. OpenEL und vielleicht auch Vulkan aufsetzen und somit mit 3d Vektoren bzw. genauer Matrizen rechnen. Die Algorithmen dafür sind etwas anders, als die für Linien im 2d Raum.

    Als Buchempfehlung solltest du dir mal das Buch Windows-Programmierung von Charles Petzold ansehen und davon eine ältere Ausgabe z.b. die 5. Auflage oder alles davor.
    Auf keinen Fall die neue mit WinForms & Co.

    Vielleicht auch jetzt der Einfachheit halber unter Linux, das würde ich sogar bevorzugen 🙂

    Du könntest in den Linux Framebuffer schreiben. Das ist einfacher, als wenn du dich jetzt noch mit X Window abquälst.

    Wenn es aber nur um das Prinzip geht das zeugs zu verstehen, dann würde ich mir an deiner Stelle so etwas die die SDL und deren mal nur einen Pixel Funktion schnappen und darauf basierend deine GUI realisieren.
    Das wird langsam sein, da du jede Menge Overhead hast, aber zum Verstehen genügt das.



  • Zeus schrieb:

    swapper schrieb:

    M1SMR schrieb:

    SeppJ damit meine ich genau diese Sprachen und das es zum Beispiel mit Java nicht funktionieren würde.

    java kann das nicht. java läuft in einer sandbox aka virtual machine.
    wenn du in java hardware ansprechen willst, brauchste libraries, die ein native interface implementieren. und die sind meistens in c geschrieben.

    Mit JNI ist das so (Standardmethode).
    Mit JNA ist das nicht mehr so, sondern

    JNA provides Java programs easy access to native shared libraries without writing anything but Java code - no JNI or native code is required. This functionality is comparable to Windows' Platform/Invoke and Python's ctypes.

    Allerdings nur wenn die Platform von JNA supportet ist.

    Was aber auch schon wieder auf shared libraries abzielt. Wüsste jetzt kein OS, bei dem Hardwarekommunikation als shared library vorliegt. Und selbst wenn, müsste die JVM im Kernel laufen. Sehr unrealistisch.



  • @Ethon
    Lese meine post bitte und versteh worin mein Einspruch besteht.



  • Die beiden Bibliotheken habe ich mir schon ein wenig angesehen - und bin eigentlich positiv überrascht.

    Xlib ist gut, wenn auch etwas kompliziert, dokumentiert - aber man findet eigentlich alles und es gibt auch das ein oder andere Tutorial dazu.

    Xcb soll grundlegend besser sein, ist aber irgendwie nur marginal dokumentiert. Und ich bin mir nicht sicher ob ich in der Lage bin anderen Code zu lesen und mir daraus nachzuvollziehen wie ich meinen Code zu strukturieren habe - das ist wirklich nicht so einfach.
    Bei xcb ist mir auch nicht ganz ersichtlich ob das ein XLib Ersatz ist, aktuell meine ich, oder ob man dann noch Code mit Xlib mischen muß.

    Im X.org Wiki wird zumindest von X11/Xlib abgeraten und man sollte doch auf xcb umschwenken für neue Entwicklungen. Aber wie gesagt, xcb ist so gut wie kaum dokumentiert.
    Leider muß man dazu sagen, scheint es etwas still geworden zu sein um die Projekte bzw. Wikis und Co. Nichts desto trotz würde ich mich wohl mit Xlib noch einmal auseinandersetzen, da dies dokumentiert ist.

    Was ich aber gänzlich noch nicht herausbekommen habe bei der Durchsicht der XLib-Dokumentation, wie man Text selektierbar macht - schließlich sind das auch nur "Pixel", muß man dann ernsthaft für jedes Zeichen die x und y Position festhalten und mit dem Cursor abgleichen? Und dann die Selektion "zeichnen"?

    Ansonsten, vielleicht genau das Spielzeug das mir gerade genügen freie Hand gibt glaube ich, aber auch das Darstellen eines Fensters zumindest im Ansatz schon übernimmt durch den X Window Server und XClient Aufbau.

    Auch interessant wäre es Bilder darzustellen, das scheint auch mit Xlib ohne Probleme zu funktionieren, so fern die Standardbibliotheken dafür vorhanden sind, so lässt es sich zumindest nachlesen.
    Interessant wären natürlich auch RGB Daten allgemein, zum Beispiel um einen Videoframe darzustellen der mit ffmpeg eingelesen wurde.

    Und halt so was. 😋

    Aber auch mit den Zeichenoperationen, (Texture)-Tiling und ähnlichem lässt sich bestimmt eine Menge machen. Werde ich definitiv mal testen, ist was für die Weihnachtsfeiertage und Jahreswende.. 👍

    PS: Das Buch zur Windows Programmierung kann ich mir gern mal antun, vielleicht findet sich eine Ausgabe irgendwo die nicht Windows-Forms behandelt.

    Und das Wayland "simple-client"-Beispiel sieht etwas sehr kompliziert aus, da müßte man sich wohl auch noch intensiver mit beschäftigen, wäre natürlich praktisch wenn es dazu auch noch eine "Hands on Guide" geben könnte der zumindest den Aufbau ein wenig erklärt wie was zusammenspielt.
    Den Code finde ich dann doch etwas nichtssagend auch wenn dieser kommentiert ist. 😉


Anmelden zum Antworten