Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

stef

Treue Seele

  • »stef« ist der Autor dieses Themas

Beiträge: 246

Wohnort: Kassel

Beruf: Softwareentwickler

  • Private Nachricht senden

11

10.07.2012, 22:05

Zitat

Natürlich kann man das so "lösen". Der Punkt ist, dass man mit jeder derartigen Lösung zwangsweise unnötigen Overhead in Kauf nimmt...


Den man gegenüber dem eigentlichem Renderaufwand getrost vernachlässigen kann.
(Hatte ich ja schon mal mit Binds in einer For-Schleife probiert)

Zitat

Es geht eher darum, dass man dadurch (ungewollt) einen globalen Zustand ändert.


Was soll ungewollt geändert werden ? Wenn du eine Resource benötigst machst du ein Bind, wenn du sie benutzt hast machst du den Bind rückgängig. Wenn du das konsequent durchziehst hat du keine Probleme.

Zitat

Der Punkt ist, dass OpenGL eben nicht mit OOP im herkömmlichen Sinn kompatibel ist. Das ist aber gar nicht mein Hauptkritikpunkt, das imo wirklich große Problem, ist der globale Zustand, der hinter allem steckt...

Direct3D ist genau wie OpenGL als Satemachine aufgebaut. Zugegeben es gibt Methoden mit denen man Resourcen wie z.B. Texturen direkt manipulieren kann. Das eigentliche Rendern funktioniert aber genau wie bei OpenGL. An Stelle von Bind benutzt man halt SetTexture oder SetStreamSource. Hier werden ebenfalls globale States gesetzt.

Zitat

Exakt und das ist nicht nur eine unerschöpfliche Quelle für unglaublich lustige Bugs, sondern disqualifiziert die API von vornherein für Multithreading.


EDIT: Ok, natürlich ist Multithreading mit OpenGL, zumindest in gewissem Rahmen (asynchrones Ressourcenmanagement), möglich, allerdings imo sehr anstregend. Für multithreaded Rendering gibt's immer noch keine Lösung...




DirectX11 ermöglicht durch asynchrones aufrufen von Renderfunktionen (Command Lists) ein einfaches nutzen der GPU Rechenzeiten auf Applikationsseite. Da ist die API in der Tat OpenGL überlegen. Aber machen wir uns nichts vor, ein wirkliches Paralleles Rendern ist auch damit noch nicht möglich. Die GPU (auch kaskadierte) ist und bleibt eine Exklusivresource die alle Renderjobs seriell ausführt.


Bezüglich OO allgemein: DirectX hat gegenüber OpenGL den Vorteil das es nur auf einer Plattform eingesetzt wird. OpenGL ist eine Plattformübergreifende API. Deshalb ist sie in C umgesetzt weil das immer noch am einfachsten in allen Umgebungen (z.B. JAVA) zu integrieren ist. Das sollte man bei der Diskusion beachten.
"In C++ it's harder to shoot yourself in the foot, but when you do, you blow off your whole leg." — Bjarne Stroustrup.

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »stef« (11.07.2012, 08:00)


dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

12

10.07.2012, 22:22

Was soll ungewollt geändert werden ? Wenn du eine Resource benötigst machst du ein Bind, wenn du sie benutzt hast machst du den Bind rückgängig. Wenn du das konsequent durchziehst hat du keine Probleme.

Die Probleme, die daraus entstehen können, sind z.B. der Form: Code vergisst unter gewissen Umständen, die idealerweise auch nur ganz selten auftreten, irgendwo einen State zurückzusetzen und auf einmal funktioniert irgendetwas völlig anderes am komplett anderen Ende der Anwendung nicht mehr. Kann mit Direct3D auch passieren, gibt dort aufgrund des besseren Designs aber wesentlich weniger Potential für solche Fehler.

Direct3D ist genau wie OpenGL als Satemachine aufgebaut. Zugegeben es gibt Methoden mit denen man Resourcen wie z.B. Texturen direkt manipulieren kann. Das eigentliche Rendern funktioniert aber genau wie bei OpenGL. An Stelle von Bind benutzt man halt SetTexture oder SetStreamSource. Hier werden ebenfalls globale States gesetzt.

Der State ist bei Direct3D eben genau nicht global, sondern in einem Objekt gekapselt. Ich kann im selben Thread mit beliebig vielen Devices und Contexts tun, was auch immer mir in den Sinn kommt, ohne irgendwo ständig über meine eigenen Füße zu stolpern...

DirectX11 ermöglicht durch asynchrones aufrufen von Renderfunktionen (Command Lists) ein einfaches nutzen der GPU Rechenzeiten auf Applikationsseite. Da ist die API in der Tat OpenGL überlegen. Aber machen wir uns nichts vor, ein wirkliches Paralleles Rendern ist auch damit noch nicht möglich. Die GPU (auch kaskadierte) ist und bleibt eine Exklusivresource die alle Renderjobs seriell ausführt.

Direct3D erlaubt mir, den Overhead auf CPU Seite zu parallelisieren. Dass der Command Stream zur GPU natürlich seriell sein muss, ist logisch, denn ein völlig paralleles Rendern würde kaum Sinn machen, da normalerweise die Reihenfolge eben wichtig ist. Wobei sich das mit den nächsten GPU Generationen voraussichtlich drastisch ändert wird. Kepler bietet schon bis zu 32 parallele Command Streams. Und so wie es aussieht, werden GPUs in sehr naher Zukunft völlig preemptable sein...

Bezüglich OO allgemein: DirectX hat gegenüber OpenGL den Vorteil das es nur auf einer Plattform eingesetzt wird. OpenGL ist eine Plattformübergreifende API. Deshalb ist sie in C umgesetzt weil das immer noch am einfachsten in allen Umgebungen (z.B. JAVA) zu integrieren ist. Das sollte man bei der Diskusion beachten.

Man kann auch in C ordentlich objektorientiert programmieren. OpenGL macht es z.B. bei den Shadern sogar einigermaßen richtig. Leider ist das aber eben die Ausnahme und nicht die Regel...

Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von »dot« (10.07.2012, 22:36)


stef

Treue Seele

  • »stef« ist der Autor dieses Themas

Beiträge: 246

Wohnort: Kassel

Beruf: Softwareentwickler

  • Private Nachricht senden

13

10.07.2012, 22:36

Zitat

Der State ist bei Direct3D eben genau nicht global, sondern in einem Objekt gekapselt. Ich kann im selben Thread mit beliebig vielen Devices und Contexts tun, was auch immer mir in den Sinn kommt, ohne irgendwo ständig über meine eigenen Füße zu stolpern...


Möchte ich bezweifeln. Wenn du einmal SetTexture aufgerufen hast gillt die Texture (globaler Sate) für alle Draw, Render usw. Funktionen bis eine ander Textur gesetzt ist. In der Zeit wo die Texture gesetzt ist kannst du damit nicht alles machen was du willst ohne die Ausgabe zu beeinflußen.


Zitat

Direct3D erlaubt mir, den Overhead auf CPU Seite zu parallelisieren. Dass der Command Stream zur GPU natürlich seriell sein muss, ist logisch, denn ein völlig paralleles Rendern würde kaum Sinn machen, da normalerweise die Reihenfolge eben wichtig ist.


Das außerdem !

Zitat

Man kann auch in C objektorientiert programmieren. OpenGL macht es z.B. bei den Shadern sogar einigermaßen richtig.


Shaderobjekte werden unter OpenGL mit Use an Stelle von Bind angesprochen. Ansonnsten ist die Mechanik aber die gleiche (Handle auf Programm usw.). Was genau ist da denn anderst ?
"In C++ it's harder to shoot yourself in the foot, but when you do, you blow off your whole leg." — Bjarne Stroustrup.

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

14

10.07.2012, 22:42

Zitat

OpenGL macht es z.B. bei den Shadern sogar einigermaßen richtig

Äh wieso?
Läuft genauso ab wie mit dem Rest.

Zitat

Deshalb ist sie[OpenGL] in C umgesetzt.

Muss nicht sein.
Die Hardwarehhersteller nuzen zwar höchstwahrscheinlich C, aber es ist kein Zwang.

Ich kann eine OpenGL-API genauso in C++ oder Pascal programmieren.



Noch zu der Parallelisierbarkeit:
Sein wir doch mal ehrlich, hast du schonmal parallelisiert mit Dx gearbeitet?
Den Renderthread vom Spielethread getrennt habe ich auch schon und das geht auch in Ogl.
Aber mit mehreren Threads an der selben Ausgabe rendern?
Das kommt mir ohnehin komisch vor, da das Rendern ein hoch serieller Prozess ist.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

15

10.07.2012, 22:43

Zitat

Der State ist bei Direct3D eben genau nicht global, sondern in einem Objekt gekapselt. Ich kann im selben Thread mit beliebig vielen Devices und Contexts tun, was auch immer mir in den Sinn kommt, ohne irgendwo ständig über meine eigenen Füße zu stolpern...


Möchte ich bezweifeln. Wenn du einmal SetTexture aufgerufen hast gillt die Texture (globaler Sate) für alle Draw, Render usw. Funktionen bis eine ander Textur gesetzt ist. In der Zeit wo die Texture gesetzt ist kannst du damit nicht alles machen was du willst ohne die Ausgabe zu beeinflußen.

Der State gilt für meinen aktuellen Context, der in Direct3D, im Gegensatz zu OpenGL, allerdings nicht global ist, sondern ein Objekt. Ich kann im selben Thread mit beliebig vielen Devices und Kontexten arbeiten (geht in OpenGL auch, wenn man die damit verbundenen Schmerzen in Kauf nimmt), genauso wie mehrere Threads gleichzeitig auf dem gleichen Device bzw. Context arbeiten können (geht in OpenGL, zumindest unter Windows, nicht).

Zitat

Man kann auch in C objektorientiert programmieren. OpenGL macht es z.B. bei den Shadern sogar einigermaßen richtig.


Shaderobjekte werden unter OpenGL mit Use an Stelle von Bind angesprochen. Ansonnsten ist die Mechanik aber die gleiche (Handle auf Programm usw.). Was genau ist da denn anderst ?

Dass die entsprechenden Funktionen nicht von einem globalen Bind Target abhängen, sondern direkt auf dem Objekt arbeiten, so wie man das eben normalerweise macht. Die neuere Schwester-API OpenCL, ja selbst die uralte WinAPI, zieht das z.b. sehr konsequent durch...

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

16

10.07.2012, 22:46

Zitat

Dass die entsprechenden Funktionen nicht von einem globalen Bind Target abhängen

Äh, eigentlich schon.
Versuch zb. mal den Uniformwert einer Variable eines ungebundenen Shaders zu ändern.

stef

Treue Seele

  • »stef« ist der Autor dieses Themas

Beiträge: 246

Wohnort: Kassel

Beruf: Softwareentwickler

  • Private Nachricht senden

17

10.07.2012, 22:47

Zitat

Ich kann eine OpenGL-API genauso in C++ oder Pascal programmieren.


Der Punkt ist das du eine C++ Schnittstelle mit This-Calls, Templates und Exceptions schwer, wenn nicht gar nicht auf andere Umgebungen (z.B. Java auf Android) heben kannst.
"In C++ it's harder to shoot yourself in the foot, but when you do, you blow off your whole leg." — Bjarne Stroustrup.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

18

10.07.2012, 22:50

Zitat

Dass die entsprechenden Funktionen nicht von einem globalen Bind Target abhängen

Äh, eigentlich schon.
Versuch zb. mal den Uniformwert einer Variable eines ungebundenen Shaders zu ändern.

Ja, wie gesagt, leider nur die Ausnahme und nicht die Regel, bei Uniforms isses auch schon wieder vorbei. Aber zumindest die Interaktion mit den Shader und Program Objekten an sich funktioniert so (glShaderSource(), glLinkProgram() etc.), sonst wäre das Ganze ja am Ende noch konsistent... ;)

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

19

10.07.2012, 22:51

Zitat

Der Punkt ist das du eine C++ Schnittstelle mit This-Calls, Templates und Exceptions schwer, wenn nicht gar nicht auf andere Umgebungen (z.B. Java auf Android) heben kannst.

Du meinst, dass OpenGL keine Features aus C++ nach außen verwendet.
Es ist aber nicht garantiert, dass OpenGL nicht mit C++ zb. programmiert ist.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

20

10.07.2012, 22:53

OpenGL ist mit gar nichts Programmiert, denn OpenGL ist nichts weiter als eine Spezifikation. Man kann nur hoffen, dass Grafiktreiber mittlerweile in C++ geschrieben werden und nicht in purem C...

Werbeanzeige