Warum wird OpenGL ursprünglich als Zustandsmaschine entworfen? [closed]

8

Während meiner OpenGL Erfahrung habe ich oft vergessen einige Zustände einzustellen. Ich denke, State Machine ist heute vielleicht kein gutes Design. Aber jetzt muss es kompatibel sein. Und ich weiß auch, dass DirectX in den frühen Tagen auch eine Staatsmaschine war. Ich würde gerne wissen, warum OpenGL und DirectX ursprünglich als State-Machine entwickelt wurden?

    
Shen Yang 04.03.2013, 03:14
quelle

2 Antworten

21

Es ist nicht klar, was Leute meinen, wenn sie sich auf "Staatsmaschine" beziehen, da sie nie erklären, was das Gegenteil ist. Also werde ich sowohl generell als auch spezifisch in Bezug auf OpenGL "State Machine" gegen aktuelle D3D "keine State Machine" sprechen.

Sowohl OpenGL als auch Direct3D verwenden den globalen Status. Jeder Rendering-Befehl erfordert, dass Sie eine Reihe von Status festlegen.

Um in beiden APIs zu rendern, müssen Sie eine Menge globalen Status festlegen. Sie müssen festlegen, welche Shader Sie verwenden werden. Sie müssen die aktuellen Parameter festlegen, mit denen Sie diese Uniformen verwenden möchten. Wenn Sie Texturen verwenden, müssen Sie diese einrichten. Sie müssen Ihre aktuellen Ansichtsfensterparameter festlegen. Und so weiter.

Der Grund für diese Art von "Zustandsmaschine" ist einfach: So funktioniert die Hardware im Allgemeinen.

Jedes Statusbit repräsentiert einige Register in der GPU. Diese Register sind state . Shader müssen geladen werden, um zu rendern. Sie müssen die Viewport-Register festlegen. Sie müssen festlegen, welche Texturadressregister Sie verwenden. Und so weiter. Daher sind die APIs Zustandsautomaten, da die GPU eine Zustandsmaschine ist.

Sie könnten sich vorstellen, dass dies mit einem Rendering-Befehl geschehen würde. Aber sieh dir nur an, wie viele Objekte du passieren musst. Sie müssten eine Reihe von Shadern, eine Reihe von Texturen, Ihre Eckpunktdaten, Ihren Framebuffer, Ihre Ansichtsfenstereinstellungen, Ihre Mischeinstellungen usw. übergeben.

Stattdessen müssen Sie mit den APIs das tun, was die GPU tut. Du hast all diese Sachen vorher eingestellt.

Außerdem wird dadurch die API schneller . Warum? Weil die API jetzt weiß, welchen Status Sie verwenden. Wenn Sie verschiedene Teile eines Gitters mit verschiedenen Texturen rendern möchten, können Sie Framebuffer, Ansichtsfenster, Vertex-Daten usw. beibehalten. Die einzige Sache, die Sie zwischen ihnen ändern, ist, welche Texturen Sie verwenden.

Wenn Sie einen riesigen Draw-Aufruf mit Dutzenden von Parametern verwendet haben, muss sich die API nun jeden Parameter ansehen, um zu sehen, ob er mit dem letzten Zeichenaufruf übereinstimmt. Und wenn nicht, muss es die GPU-Register aktualisieren.

Nun zu den Unterschieden zwischen OpenGL und D3D. In diesem Fall besteht der Unterschied darin, wie sie Objekte behandeln.

D3D ist objektbasiert, da Funktionen, die Objekte modifizieren, das Objekt als Parameter annehmen. Außerdem sind die meisten D3D-Objekte unveränderlich ; Sobald Sie sie erstellt haben, können Sie die meisten ihrer Einstellungen nicht ändern. Sobald Sie eine Textur mit einer bestimmten Größe, Format usw. erstellt haben, ist es fertig. Sie können es nicht mit einer anderen Größe / Format / etc neu zuweisen, ohne das Objekt zu löschen und ein neues zu erstellen.

OpenGL ist statusbasiert. Das bedeutet, dass OpenGL-Funktionen, die Objekte modifizieren (zum größten Teil), das Objekt nicht als Parameter verwenden.

Dies ist kein "Design", sondern einfach OpenGLs strikte Einhaltung der Abwärtskompatibilität. Objekte in OpenGL sind nur Fragmente des globalen Zustands; so sind sie definiert. Warum?

Weil ursprünglich, in OpenGL 1.0, keine Objekte (neben Display-Listen) waren. Ja, nicht einmal Texturobjekte . Als sie entschieden, dass das dumm war und dass sie Objekte brauchten, beschlossen sie, sie rückwärtskompatibel zu implementieren. Jeder benutzte bereits Funktionen, die auf dem globalen Status operierten. Sie haben also gesagt, dass Sie den globalen Status außer Kraft setzen, indem Sie ein Objekt binden. Die Funktionen, die den globalen Status änderten, ändern nun den Status des Objekts.

Auf diese Weise könnten sie Objekte in die API einführen, ohne auch eine Reihe neuer Funktionen einzuführen, die nur mit Objekten funktionieren. Code, der vorher funktioniert hat, könnte daher mit Objekten arbeiten, die nur sehr wenig optimiert sind, anstatt eine nicht-triviale Neuschreibung des Codes zu erzwingen. Es bedeutet auch, dass sie, wenn sie neue Funktionen einführen müssen, die auf Texturen stoßen, mit und ohne Objekte arbeiten würden. Somit war es sowohl rückwärts als auch vorwärts kompatibel.

Die meisten OpenGL-Objekte funktionieren auf diese Weise : Wenn Sie sie ändern möchten, müssen Sie sie binden und dann die "globaler" Zustand.

    
Nicol Bolas 04.03.2013 06:19
quelle
9

Von Ссылка :

  

Der Grund, warum OpenGL wie eine Zustandsmaschine funktioniert, besteht darin, zu vermeiden, dass bei jedem Funktionsaufruf viele Argumente übergeben werden müssen.

     

Minimale Argumentpassage

     

Die Kommunikation zwischen einem Anwendungsprogramm und OpenGL muss schließlich den Workstation-Datenbus an die Grafikhardware übergeben. Der Datenbus ist typischerweise viel langsamer als die Workstation-CPU und Grafikhardware und kann daher oft der Flaschenhals bei Hochgeschwindigkeitsgrafiken sein. Um die höchstmögliche Geschwindigkeit aufrechtzuerhalten, übergibt OpenGL in seinen Funktionsaufrufen so wenig Argumente wie möglich, wie aus der Überprüfung der OpenGL-Dokumentation ersichtlich ist. Alle Aufrufe setzen voraus, dass viele interne Variablen zuvor auf die gewünschten Werte gesetzt wurden.

    
Dan Ross 04.03.2013 04:57
quelle

Tags und Links