Soll ich glEnable und glDisable rufen jedes Mal, wenn ich etwas ziehen?

StackOverflow https://stackoverflow.com/questions/802079

  •  03-07-2019
  •  | 
  •  

Frage

Wie oft sollte ich anrufen OpenGL-Funktionen wie glEnable() oder glEnableClientState() und ihre entsprechenden glDisable Pendants? Sind sie bedeutete zu Beginn der Anwendung aufgerufen einmal werden, oder sollte ich halten sie deaktiviert und ermöglichen nur die Funktionen, die ich sofort zum Zeichnen etwas brauchen? Gibt es einen Unterschied in der Leistung?

War es hilfreich?

Lösung

"Das hängt davon ab."

Wenn Du ganz App nutzt nur eine Kombination von Aktivierungs- / Deaktivierungszuständen, dann mit allen Mitteln es gerade am Anfang eingerichtet und geht.

Die meisten realen Anwendungen benötigen, zu mischen und dann sind Sie gezwungen glEnable() nennen einige bestimmten Zustand (s) zu aktivieren, führen Sie die Auslosung Anrufe, dann glDisable() sie wieder, wenn Sie fertig sind, um „die Bühne zu räumen“ .

Zustand-Sortieranlage, state-Tracking und viele Optimierungsschemata von diesem Stamm, der als Zustandsschalt manchmal teuer ist.

Andere Tipps

Wenn Sie feststellen, dass Sie den Wert der Zustandsvariablen werden häufig überprüft und anschließend glEnable / glDisable Aufruf können Sie in der Lage sein, die Dinge ein wenig, indem Sie das Attribut Stapel (glPushAttrib / glPopAttrib) aufzuräumen.

Das Attribut-Stack können Sie Bereiche des Codes isolieren und so, dass Änderungen in einer Abschnitten zuzuschreiben hat keinen Einfluss auf das Attribut Zustand in den anderen Abschnitten.

void drawObject1(){
  glPushAttrib(GL_ENABLE_BIT);

  glEnable(GL_DEPTH_TEST);
  glEnable(GL_LIGHTING);    

  /* Isolated Region 1 */

  glPopAttrib();
}        

void drawObject2(){
  glPushAttrib(GL_ENABLE_BIT);

  glEnable(GL_FOG);
  glEnable(GL_GL_POINT_SMOOTH);    

   /* Isolated Region 2 */

  glPopAttrib();
}    

void drawScene(){
  drawObject1();
  drawObject2();
}

Obwohl GL_LIGHTING und GL_DEPTH_TEST gesetzt sind in drawObject1 ihren Zustand nicht zu drawObject2 erhalten. In Abwesenheit von glPushAttrib wäre dies nicht der Fall sein. Auch -. Beachten Sie, dass es keine Notwendigkeit glDisable am Ende der Funktionsaufrufe ist zu nennen, glPopAttrib macht den Job

Soweit Leistung, der Aufwand aufgrund einzelner Funktionsaufrufe an glEnable / glDisable minimal ist. Wenn Sie, dass Handling viel Staat brauchen werden Sie wahrscheinlich benötigen, um Ihre eigenen Staat Manager erstellen oder zahlreiche Anrufe zu glGetInteger ... und dann entsprechend handeln machen. Der hinzugefügte Maschinen und Kontrollfluss könnte aus dem Code weniger transparent, härter zu debuggen und schwieriger zu warten. Diese Probleme können machen andere, fruchtbare, Optimierungen schwieriger.

Die Zuschreibung Stapel kann bei der Aufrechterhaltung der Abstraktionsschichten unterstützen und Bereiche der Isolation erstellen.

glPushAttrib manpage

Zu allererst, welche OpenGL-Version verwenden Sie? Und welche Generation von Grafik-Hardware ist Ihre Zielgruppe hat? Mit diesem Wissen würde es leichter macht eine richtige Antwort zu geben. Meine Antwort geht davon aus OpenGL 2.1.

OpenGL ist eine Zustandsmaschine, was bedeutet, dass, wenn ein Zustand geändert wird, wird dieser Zustand „Strom“, bis sie geändert wieder explizit vom Programmierer mit einem neuen OpenGL-API-Aufruf gemacht. Ausnahmen von dieser Regel gibt, wie Client-Zustandsarray ruft die aktuellen Vertex Farbe undefiniert machen. Aber das sind die Ausnahmen, die die Regel definieren.

einmal zu Beginn der Anwendung “ nicht viel Sinn machen, denn es gibt Zeiten, die Sie benötigen, um Ihre OpenGL-Kontext zu zerstören, während die Anwendung noch läuft. Ich nehme an, Sie bedeuten nur nach jedem Fenster Schöpfung. Das funktioniert für Zustand, den Sie später nicht ändern müssen. Beispiel:. Wenn alle Zeichenaufrufe die gleichen Vertex-Array-Daten verwenden, brauchen Sie nicht danach, sie mit glDisableClientState deaktivieren

Es gibt eine Menge aktivieren / deaktivieren Zustand im Zusammenhang mit der alten Fest Funktion Pipeline. Die einfache Erlösung hierfür ist: Verwenden Sie Shadern! Wenn Sie eine ganze Generation von Karten höchstens fünf Jahre alt, Ziel, ahmt es wahrscheinlich die Fixed-Function-Pipeline mit Shadern sowieso. Durch Shadern verwenden, sind Sie in mehr oder weniger vollständige Kontrolle dessen, was während der Transformation und Rasterisierung Stadien passiert, und Sie können Ihre eigene „Zustände“ mit Uniformen, die sehr billig sind machen zu ändern / aktualisieren.

Das Wissen, dass OpenGL eine Zustandsmaschine ist wie oben schon gesagt sollte deutlich machen, dass man sollte sich bemühen, die Zustandsänderungen auf ein Minimum zu halten, solange es möglich ist. Allerdings gibt es wahrscheinlich andere Dinge, die Systemleistung beeinträchtigt, viel mehr als aktivieren / deaktivieren Zustand Anrufe. Wenn Sie über sie wissen wollen, lesen Sie unten.


Die Kosten der staatlichen nicht , die mit den alten Festfunktionszustand Anrufen und was nicht einfach ist, aktivieren / deaktivieren Zustand kann weit in den Kosten unterscheiden. Bemerkenswerter Shadern Verknüpfung und Bindungsnamen ( „Namen“ von Texturen, Programme, Puffer-Objekten) sind in der Regel recht teuer. Aus diesem Grund viele Spiele und Anwendungen verwendet, um die Auslosung der Reihenfolge ihrer Maschen zu sortieren nach der Textur. Auf diese Weise haben sie die gleiche Textur zweimal nicht binden müssen. Heutzutage jedoch das gleiche gilt für Shader-Programme. Sie wollen nicht das gleiche Shader-Programm zweimal binden, wenn Sie nicht haben. Auch nicht alle Funktionen in einer bestimmten OpenGL Version sind Hardware auf allen Karten beschleunigt, auch wenn die Anbieter dieser Karten behaupten, sie OpenGL kompatibel sind. Als konform bedeutet, dass sie die Spezifikation folgen, nicht, dass sie notwendigerweise effizient alle featurs laufen. Einige der Funktionen wie glHistogram und glMinMax von GL__ ARB __imaging sollte in diesem Zusammenhang nicht vergessen werden.


Fazit: Es sei denn, es gibt einen offensichtlichen Grund nicht, Shadern zu benutzen! Es erspart Ihnen viel uncecessary Zustand nennt, da Sie Uniformen stattdessen verwenden können. OpenGL Shadern für rund etwa sechs Jahren gerade gewesen wissen Sie. Auch der Aufwand für Aktivierungs- / Deaktivierungszustandsänderungen kann ein Problem sein, aber in der Regel gibt es viel mehr zu gewinnen von anderen, teureren Zustandsänderungen zu optimieren, wie glUseProgram, glCompileShader, glLinkProgram, glBindBuffer und glBindTexture.

P. S: OpenGL 3.0 der Client-Zustand aktivieren / deaktivieren Anrufe entfernt. Sie werden implizit aktiviert als Zeichenanordnungen der einzige Weg ist in dieser Version zu ziehen. Immediate-Modus wurde entfernt. gl..Pointer Anrufe wurden ebenfalls entfernt, da man wirklich glVertexAttribPointer gerade braucht.

Eine Daumenregel, die ich gelehrt wurde gesagt, dass es fast immer billiger, nur aktivieren / deaktivieren nach Belieben anstatt den aktuellen Zustand überprüfen und ändern nur wenn nötig.

Das heißt, Marc Antwort ist etwas, das auf jeden Fall funktionieren soll.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top