C, C++, Assembler? Wiedereinstieg in die Programmierung

Erst einmal herzlichen Dank an Alle für die vielen Vorschläge.

Meine Tendenz geht im Moment in Richtung C++/C# wobei ich jetzt sehen muss, was davon besser für mich ist.

Für C# spricht, das es sowohl für Windows als auch für die 360 geeignet ist.

Für C++ spricht, das es eben auch ausserhalb des Microsoft Universums eine Rolle spielt.


Auf jeden Fall wird es für mich wichtig, den objektorientierten Ansatz komplett zu verinnerlichen und zu sehen, ob sich mein Gehirn soweit daran gewöhnen kann, das ich damit zurecht komme. Dazu werde ich mich wirklich erstmal ohne Gedanken an projekte da "durchqälen" müssen. Gut möglich, das es mir damals wegen der MFC so bescheuert vorkam.


Assembler werde ich wohl eher unter "währe schön gewesen" abhaken, aus verschiedenen Gründen:

Erstens halte ich die Aussage, Compiler würden besser optimieren, für durchaus nachvollziehbar, ein Programm kann viel besser Taktzyklen zählen als ein Mensch und das Programm macht dies immer ohne zu ermüden. Ob man das immer durch trickreiche Programmierung ausgleichen kann, ist die Frage.

Zweitens gibt es auch keine klar definierte Hardware mehr, das direkte Schreiben in Register ist daher sowieso obsolet geworden, da eh alles über Treiber läuft. Diesen Level der Kontrolle wird man wohl heute nicht mehr erreichen.
 
motzerator schrieb:
Zweitens gibt es auch keine klar definierte Hardware mehr, das direkte Schreiben in Register ist daher sowieso obsolet geworden, da eh alles über Treiber läuft. Diesen Level der Kontrolle wird man wohl heute nicht mehr erreichen.

Nein, Register werden nicht in irgendeiner Form wegabstrahiert. In einem kompilierten Programm stehen dies weiterhin drin.
In dem Assemblercode den ich gepostet habe bezeichen eax, ebx und so weiter 32 Bit Register einer x86 CPU. Und Konstrukte wie 20(%ebp) bedeutet das er als Wert den mit der Speicheradresse der in ebp (Extended BasePointer, Extended bedeutet übrigens immer 32 Bit, eine x86 CPU kann ja auch 16Bit Code)+20Bytes weiter, verwenden soll. Wenn da also bspw. addl 8(%ebp), %eax da steht, heißt das er den Wert an der Speicherstelle ebp+8, sowie den Wert in eax addieren soll, und das Ergebnis in eax schreiben soll. Das da viermal was mit add steht und nicht zwei Additionen wie im C Code stehen, ist der Tatsache geschuldet, das ich für 32 Bit kompiliert habe, aber long long 64Bit breit ist, so das zwei 32 Bit Additionen pro eigentlicher Addition stattfinden. mov verschiebt den Speicherinhalt, push/pop kümmern sich um den Stack und ret=return. Aber x86 hat sehr wenige Register, weswegen der Quellcode fürchertlich zu lesen ist, weswegen man nicht in dem Stil "pro Register eine Variable" progammieren kann, sondern eigentlich nur mit Speicheradresse rumhantiert, weil die Register so rar sind. Wenn du also unbedingt Assembler programmieren willst, hol dir einen Microcontroller ins Haus, der Quellcode ist bedeutet angenehmer zu lesen, da diese sehr viele Register haben und damit einfacher zu programmieren sind und ihr Befehlssatz ist so spärlich, das es realistisch ist, da einigermaßen den Überblick zu behalten. Zum Vergleich: Ein Ivy Bridge (Intels neuster) hat ungefähr 440 verschiedene Assembler-Befehle (mit AVX2 steht mit der nächsten Prozesssoren Generation die nächsten neuen Instruktionen an) und nur vier (!) Mehrzweckregister und jede Menge Spezialregister...

Es gibt auch keinen anderen Weg dies zu machen, es gibt keine Treiber o.ä. für Register, nativer Code läuft wirklich direkt auf der CPU, ganz ohne Softwareschicht dazwischen. Deswegen muss ja ein Programm für andere Prozessorarchitekturen neu compiliert werden, also für ARM, x86/x86-64,.. Und AMD und Intel tauschen deswegen ja auch immer ihre Patente untereinander aus, damit Intel bspw. die 64 Bit Erweiterung genauso benutzen kann wie sie AMD verwendet und AMD im Gegenzug x86 und all die SSE Erweiterungen etc. Die sind also klar definiert. Wie die CPU den Maschinencode ausführt hingegen ist eine andere Sache, da ist nichts definiert, deswegen sind die Dinger von AMD und Intel ja auch unterschiedlich schnell, aber das hat mit dem Maschinencode nichts zu tun.
 
Zuletzt bearbeitet:
geisterfahrer schrieb:
Nein, Register werden nicht in irgendeiner Form wegabstrahiert. In einem kompilierten Programm stehen dies weiterhin drin.

Hier liegt ein Missverständniss vor.

Ich meinte nicht die Prozessorregister, die muss es ja weiterhin geben, sondern in adresse und Funktion klar definierte Hardwareegister, beispielsweise der Grafikchips.

Sowohl beim 8-Bit Atari als auch beim Amiga gab es damals Speicheradressen, die nicht zu einem RAM Baustein gehörten, sondern zu einem Grafikchip. Beispielsweise gab es ein Register, wo man die Hintergrundfarbe einstellen konnte. Wollte man die Farbe ändern, hat man den neuen Wert einfach in diese Speicheradresse geschrieben. Der Fachbegriff war "Memory Mapped".

LDA #FARBWERT ; Lade 8-Bit Farbwert in den Accu (Prozessorregister)
STA $BGCOLOR ; Beschreibe damit die Speicheradresse der Hintergrundfarbe (Chipregister)

Wobei Farbwert (eine Konstante) und BGCOLOR (eine 16-Bit Speicheradresse) Macros sind, die ich hier mal einführe weil ich die genauen Hexadresse nach 25 Jahren nicht mehr im Kopf habe. :)

Auch der Joystick funktionierte über eine Memory Mapped Register, nur das man eben durch Auslesen des Registers direkt die Stellung ermitteln konnte. Der alte Atari Joystick hatte einfach vier Kontakte, Oben, Unten, Links und Rechts. Die waren direkt auslesbar. Drückte der Spieler nach Oben, war das entsprechende Bit halt gesetzt.

Solche "Memory Mapped Hardwareregister" gibt es sicher auch heute noch, allerdings haben die Grafikkarten sicher nicht die gleichen Adressen und nicht die identische Funktionalität. Die Übersetzung übernimmt ja der Treiber. Das meinte ich, es gibt wenn man verschiedene Grafikkarten bedenkt keine festen Hardwarregister der anzusprechenden Coprozessoren mehr. Die Hardware ist nicht mehr Homogen.

Ich kann nicht mehr einen Effekt erzielen, indem ich einen Wert in einen bestimmten Speicher schreibe. Ich kann die Hardware nur noch indirekt ansprechen, alleine schon deshalb, weil sie nicht gleich aufgebaut ist. Eine NVIDIA Karte und eine ATI Karte werden erst durch die Treiber angesprochen. Das meinte ich. Soweit ich weis halten die Grafikkarten Hersteller diese Datails sogar geheim, weshalb es nicht möglich ist, open source Treiber für viele Grafikkarten zu schreiben.

Auf dem 8Bit Atari konnte man damit viel zaubern. Es gab beispielseise einen Interupt, der nach jeder Bildschirmzeile aufgerufen werden konnte, änderte man dort die Hintergrundfarbe, konnte man schöne Farbverläufe in einer eigentlich einfarbigen Fläche erzielen. Das war bei einem Gerät, das normalerweise je nach Grafikmodus nur 2 oder 4 Farben gleichzeitig darstellen konnte, schon was wichtiges.

Das ging natürlich auch mit Vordergrundfarben:

http://www.atarimania.com/game-atari-400-800-xl-xe-home-pong_2482.html

Hier hab ich das damals für den Metalliceffect der Schrift eingesetzt.

Der Atari benutzte übrigens eine indizierte Farbdarstellung, man hat nicht für jeden Pixel den Farbwert gespeichert, sondern nur mit 1 oder 2 bit pro Pixel einen Index in eine Farbtabelle gesetzt. Diese Farbtabelle war eben mit Hardware Registern realisiert, änderte man dort einen Wert, änderte sich die Farbe von jedem Pixel, das dem gleichen Farbindex zugeordnet ist.

Diese direkte Art der Programmierung hat mir halt sehr gefallen und dafür war Assembler einfach wunderbar geeignet. Natürlich kann man das alles auch mit C erreichen, aber für diese direkte Art der Programmierung ist Assembler einfach am besten.

Da man heute also eh nur noch Funktionen des Betriebssystems anspringt, das in C/C++/C# geschrieben wurde, um die Hardware anzusprechen, macht Assembler wohl wirklich nicht mehr so viel Sinn.
 
Zuletzt bearbeitet:
motzerator schrieb:
Diese direkte Art der Programmierung hat mir halt sehr gefallen und dafür war Assembler einfach wunderbar geeignet. Natürlich kann man das alles auch mit C erreichen, aber für diese direkte Art der Programmierung ist Assembler einfach am besten.

Da man heute also eh nur noch Funktionen des Betriebssystems anspringt, das in C/C++/C# geschrieben wurde, um die Hardware anzusprechen, macht Assembler wohl wirklich nicht mehr so viel Sinn.
Keine Ahnung, was du damals für Programme geschrieben hast, aber stell dir nur mal die armen Programmierer vor, die ein Crysis über Register schreiben müssten. ;)
Davon abgesehen glaube ich, dass diese Art der Programmierung sehr speziell ist. Was stellt man mit einem Register für die Hintergrundfarbe an, wenn man keinen Hintergrund braucht (bzw. der extrem komplex ist).
Sowas wird heutzutage über die Shader geregelt. Im Endeffekt sind das kleine Befehlsansammlungen, die etwas mit einem Pixel machen. Wenn also im Shader steht "Mache alle Pixel rot", hast du eigentl. den selben Effekt mit dem Unterschied viel allgemeiner zu schreiben und die Hardware besser nutzen zu können.


Und zum Anspringen von Funktionen: Der Linuxkernel ist in C, der Windowskernel in C und C++. Prinzipiell schreiben diese Sprachen direkt auf die Hardware. Wenn ein Programm kompiliert wurde, dann läuft es direkt in der CPU. Was unterschiedlich ist, ist jeweils die Schnittstelle zum Betriebssystem (Der Punkt wo die Ausführung einsetzt als Lowlevel-Beispiel, und z.B. die Ausgabe der Konsole) oder die Zusammenarbeit mit dem Scheduler. Deswegen sind versch. Compiler notwendig.
Aber C und C++ sind auf keinen Fall vom Betriebssystem virtualisiert. Sogar virtuelle Maschinen sind heutzutage dermaßen transparent, dass die Software mit relativ geringen Geschwindigkeitseinbußen läuft. Und das deshalb, weil die Programme zwar ein BS brauchen, aber trotzdem direkt CPU-Befehle ausführen können.

Deswegen schlagen abstrahierte Programme reine Assemblerprogramme auch oft in der Performance, weil die Compiler besser Assembler schreiben, als Menschen.

Ich möchte das prozedurale Programmieren aber nicht schlecht machen. Früher war es halt das beste, was man hatte. ^^
Aber ich möchte dir mal diesen Link ans Herz legen: http://channel9.msdn.com/Events/GoingNative/GoingNative-2012/Keynote-Bjarne-Stroustrup-Cpp11-Style
Der Mann hat auch Assembler und C und wahrscheinlich noch viele unbekannte, abstruse Sprachen benutzt und ist auch ein älteres Semester. Aber vllt. ist das genau das Richtige für dich. ;)
 
Zuletzt bearbeitet:
Damals wurde so programmiert und das würde man auch heute noch tun, wenn man nicht wegen der unterschiedlichen Hardware auf die Treiber angewiesen währe. Denn jeder Funktionsaufruf kostet Zeit. Eine Aufgabe direkt auszuführen, ist immer flotter, als einem Treiber zu sagen, das zu tun. Würden alle Grafikkarten hier gleich aufgebaut sein, würde der Kern der Gameengine so programmiert werden.

Diese alten Grafiklösungen waren ja sehr komplex, weil man kaum Speicher hatte. Heute kann man bequem pro Pixel 3 Byte verwenden und so 16,7 Millionen Farben darstellen.

Bis etwa Mitte der 90er Jahre gab es aber eben das Konzept der indizierten Farbdarstellung. Man hatte eine Farbtabelle, in der man die konkreten Farbwerte eintrug und im Grafikspeicher stand nur die Nummer des Farbregisters. Das war wie Malen nach Zahlen und sparte Speicher. Der letzte Vertreter war VGA auf dem PC, das einen Modi mit 256 Farben bot. Da kam man mit eiem Byte pro Pixel aus. Nachteil: Es standen gleichzeitig nur beschränkt Farben zur Verfügung. Vorteil: Es brauchte viel weniger Speicher und man konnte alle Pixel, die einem Farbtopf zugeordnet waren, in der Farbe ändern, indem man nur das Farbregister änderte. Der Pixel behielt ja seinen Index.

Heute braucht man das alles nicht mehr, man hat genug Speicher und flotte Prozessoren und Grafikbausteine, um den auch ständig mit neuem Inhalt zu füllen. Shader sind da ein viel aufwendigeres Konzept und ändern den Wert im Grafikspeicher.

Aber lange Rede kurzer Sinn, wir sind uns glaube ich beide Einig, das diese extrem Hardwarenahe Programmierung heute nicht mehr möglich ist, zumindest für den normalen Anwendungs und Spieleprogramierer. Wobei ich wetten möchte, das in den Grafiktreibern und im Windows Kernel durchaus noch so gearbeitet wird.

Nicht mit Farbregistern, die gibt es heute sicher nicht mehr, aber auch die Shader müssen ja zum Beispiel irgendwie an ihre Daten kommen und dazu gibt es sicher auch Register, selbst wenn man dort nur einen Pointer auf das Shaderprogramm einträgt. Irgendwie müssen die Informationen ja an den Baustein gelangen.


Was finde ich eigentlich an dem Prozeduralen Programmieren so gut? Es scheint einfach meiner Denkweise zu entsprechen: Ich habe da Dinge, von denen weis ich ganz genau, wie sie Funktionieren und was ich damit machen kann, und ich wende diese Dinge an. Aber danke für den Link, das werd ich mir mal ansehen.
 
Zuletzt bearbeitet:
motzerator schrieb:
Damals wurde so programmiert und das würde man auch heute noch tun, wenn man nicht wegen der unterschiedlichen Hardware auf die Treiber angewiesen währe.
Bezweifel ich. Alleine schon aus Sicherheits/Stabilitätsgründen darf eine Endbenutzeranwendung nicht auf Hardware zugreifen, x86 Prozessoren haben ein "integriertes Rechtemanagement". Eine Anwendung kann kein schaden anrichten, da normale Anwendungen nicht im "Kernel-Mode" auf dem Prozessor ausgeführt werden. Außerdem muss man bedenken, das eine Anwendung nicht den kompletten Bildschirm (außer 3D Spiele) ausfüllt, sondern nur im Fenster laufen, man also unmengen mehr Dinge brücksichtigen muss. Da wird dann bspw. auch noch ein Cache vorgehalten (softwaremäßig), wenn ein Fenster wieder aufgedeckt wird, damit die Anwendung nicht neu zeichnen muss (stelle dir vor: du verschiebst ein kleines Fenster das vor einem maximierten Fenster ist: manche Stellen werden aufgedeckt, manche verdeckt, der Bildinhalt beider Anwendungen bleibt aber eigentlich gleich). Direkter Grafikkartenzugriff widerspricht also Multitasking, Stabilität und Sicherheit. Es ist also nicht nur die nicht einheitliche Hardware, die einen Strich durch die Rechnung macht, sondern einfach auch einfach jedes moderne Betriebssystem.

motzerator schrieb:
Denn jeder Funktionsaufruf kostet Zeit. Eine Aufgabe direkt auszuführen, ist immer flotter, als einem Treiber zu sagen, das zu tun. Würden alle Grafikkarten hier gleich aufgebaut sein, würde der Kern der Gameengine so programmiert werden.
Grafikkarten machen heute mehr als Pixel darzustellen und erst recht die Treiber bieten bedeutend komplexere Funktionen an. Ab einer gewissen Größe fällt dann auch nicht mehr der Overhead eines Funktionsaufrufes ins Gewicht. Davon abgesehen, müsstest du auch in Assembler Funktionen implementieren, um wiederkehrende Probleme zu lösen, nur das diese eben im eigenen Programm sind (was dem Prozessor aber herzlich egal ist). OpenGL/DirectX sagt man eben nur "stelle grünen Würfel, beleuchte ihn von oben links", da ruft man dann auch nicht allzu viele Funktionen auf... Mit direkter Hardwareprogrammierung würde einhergehen, jedes mal das Rad neu zu erfinden - bei der Komplexität heutiger Systeme völlig undenkbar. Die vielen Schichten die heute existieren sind schon sinnvoll so wie sie sind.

motzerator schrieb:
Aber lange Rede kurzer Sinn, wir sind uns glaube ich beide Einig, das diese extrem Hardwarenahe Programmierung heute nicht mehr möglich ist, zumindest für den normalen Anwendungs und Spieleprogramierer. Wobei ich wetten möchte, das in den Grafiktreibern und im Windows Kernel durchaus noch so gearbeitet wird.
Zumindestens im Linux Kernel nicht, da machte Assembler im Jahr 2008 2,47% aus (C: 97,22%):
http://www.heise.de/open/artikel/Ke...en-Code-3-0-wird-Longterm-Kernel-1406404.html

Dir scheint die Komplexität heutiger Software/Hardware irgendwie nicht ganz bewusst zu sein...
 
Ich gebe zu, in meinem Gedankenmodell handelte es sich durchaus um ein Fullscreen Videogame, das da als einzelner Task läuft. Was ja auch im Spielbetrieb theoretisch kein Problem ist, der Spieler wird kaum nebenbei mit Word arbeiten wollen... :)

Ich habe ja auch ein paar Erfahrungen unter Windows mit Visual Studio und der MFC gemacht in den 90er Jahren, damals habe ich auch keinen Assembler mehr verwendet und nicht mehr direkt die Hardware angesprochen. Wie komplex das dann wird, ist mir schon klar.

Das es immer noch 2,5% Assembler im Linux Kernel gibt zeigt ja auch, das selbst dort noch Hardwarenah programmiert wird, ich wette das sind genau die 2,5%, wo es darauf ankommt, der Rest ist dann eben in C geschrieben. Wobei diese 2,5% ja noch gnädig sind, da hier nach Codezeilen gerechnet wird und nicht nach Anteil des asm Codes im fertigen Compilat.

Was die Verschachtelungen der Funktionsaufrufe betrifft: In Konsolen fällt die Treiberschicht weg, da es sich um eine Homogene Hardware handelt, zumindest aus sicht der Software dürfte das so sein. Während also jeder Aufruf in deinem Beispiel so aussieht:

Programm -> OpenGL -> Treiber -> Hardware

oder

Programm -> GDI -> Treiber -> Hardware

dürfte das in der Konsole so laufen:

Programm -> OS-> Hardware

Was auch zum teil erklärt, warum selbst moderne Games noch brauchbar auf den Konsolen laufen, obwohl die viel, viel schwächer als aktuelle PCs sind, selbst bei SPielen die auf dem PC kein simpler Konsolenport sind. Der zweite Vorteil ist, das man sich nicht um Unterschiede in der Hardware scheren muss.

Aber letztendlich brauchst DU mich von meinem Assembler Traum nicht mehr abbringen, ich habe nicht vor, Gameengines zu bauen oder im Kernel rum zu fummeln, daher hat mir das hier schonmal soweit geholfen, das ich mich mit dieser C++/C# Geschichte auseinandersetzen muss ist vielleicht auch eine Sache der Gewöhnung.

Da Du immer OpenGL erwähnst, wird das unter Windows eigentlich noch ordentlich unterstützt? Oder erinner ich mich da richtig und die Treiber unterstützen das heute kaum noch?
 
Zuletzt bearbeitet:
Also braucht man wegen OpenGL heute keine Bedenken mehr haben? Das währe ja schön!

Ich kann mich halt nur erinnern, das ich unter Vista mal ernsthafte Probleme hatte, eine OpenGL Anwendung ans Laufen zu bekommen, auf einem PC mit einer ATI Grafikkarte.

Nehmen wir mal theoretisch an, ich habe ein kleines Spielchen mit OpenGL programmiert, läuft das "Out of the Box" auf jedem Windows 7 PC mit installierter Graka oder muss der Anwender da vorher noch etwas installieren, was selber nicht im normalen Windows oder passendem Grafiktreiber vorhanden ist?

Wie sieht es eigentlich mit den Intel Grafikkernen aus, unterstützen die auch OpenGL? Das währe ja auch wichtig.

Der Vorteil von OpenGL liegt für mich in der Offenheit und Verfügbarkeit auf allerlei Plattformen, wenn das also heute ohne Problemchen läuft, währe es dem DirectX doch eigentlich klar vorzuziehen.

Die Frage ist nun, warum benutzen so viele Spiele trotzdem DirectX?
 
OpenGL mag zwar auf vielen Systemen laufen, dafür unterstützen nicht alle Karten auch alle Funktionen. Du musst bei OpenGL erst mal abfragen ob die Hardware auch das unterstützt was du machen willst, und diese Exception eben behandeln.

Noch dazu kannst du DirectX nicht mit OpenGL vergleichen. GL steht ja für Graphics Library, also ist es sowas wie Direct3D. DirectX bietet aber noch viel mehr. Von Funktionen die das Input handlen, über Netzwerkcode, Sound usw.

Dein OpenGL Spiel kann out-of-the-box laufen wenn du die entsprechenden Libraries mitlieferst, aber du wirst trotzdem Anpassungen für Plattform aber auch für Hardware machen müssen.
Noch dazu ist OpenGL (wahrscheinlich nicht nur) meiner Meinung nach, natürlich noch etwas komplizierter. Und es gibt auch jede Menge verschiedene Versionen (z.B. für Mobile Geräte wie iPhone etc).

Ich bin sehr froh das es "Wrapper" Frameworks gibt wie cocos2d oder corona. Damit kann man auch ohne OpenGL Code / Kenntnisse schnell tolle Ergebnisse erzielen. XNA ist ähnlich, wenn auch wieder was komplett anderes (schon allein wegen der Content Pipeline).

Aber wenigstens erlaubt Direct3D seit DX10 eine Programmierbare Grafikpipeline. OpenGL sollte das auch können, aber der entsprechenden Version.
 
motzerator schrieb:
Also braucht man wegen OpenGL heute keine Bedenken mehr haben? Das währe ja schön!

Ich kann mich halt nur erinnern, das ich unter Vista mal ernsthafte Probleme hatte, eine OpenGL Anwendung ans Laufen zu bekommen, auf einem PC mit einer ATI Grafikkarte.

Nehmen wir mal theoretisch an, ich habe ein kleines Spielchen mit OpenGL programmiert, läuft das "Out of the Box" auf jedem Windows 7 PC mit installierter Graka oder muss der Anwender da vorher noch etwas installieren, was selber nicht im normalen Windows oder passendem Grafiktreiber vorhanden ist?

Wie sieht es eigentlich mit den Intel Grafikkernen aus, unterstützen die auch OpenGL? Das währe ja auch wichtig.

Der Vorteil von OpenGL liegt für mich in der Offenheit und Verfügbarkeit auf allerlei Plattformen, wenn das also heute ohne Problemchen läuft, währe es dem DirectX doch eigentlich klar vorzuziehen.

Die Frage ist nun, warum benutzen so viele Spiele trotzdem DirectX?

Microsoft hat in vielen Bereichen eine Monopolstellung. Dazu reicht ein Blick in die Industrie, dort werden Produkte von Microsoft überproportional oft verwendet.

Rohde & Schwarz bringt es sogar fertig DirectX für ihre Oszilloskope zu verwenden, obwohl sie Qt nutzen. Qt nutzt bekannterweise OpenGL, aber das Unternehmen hat sich selbst einen Wrapper geschrieben, damit auch DirectX verwendet werden kann, weil dort alles auf Microsoft basiert, die nutzen sogar Embedded XP. :rolleyes:

Wenn du OpenGL lernen möchtest, achte darauf dich auf OpenGL 3 bzw. 4 zu konzentrieren. Gerade bei OpenGL hat es einen Paradigmenwechsel hin zur Shaderprogrammierung gegeben. Das unterscheidet sich grundsätzlich von Version 1 und 2.

Für OpenGL siehe auch GLEW.

http://glew.sourceforge.net/
 
Stefan_Sch schrieb:
Qt nutzt bekannterweise OpenGL

Wie ist das gemeint? Meinst du für das Zeichnen der Widgets selbst? Ansonsten kannst du in einem Qt-Widget einen Canvas problemlos sowohl mit DirectX also auch mit OpenGL betreiben (sprich, dort eine 3D-Welt darstellen).
 
Zurück
Oben