2012-03-27 15 views
0

Ich erstelle eine sehr Render-teure Szene in opengl (mit Vertex-Puffer-Objekte) und während alle Objekte an Ort und Stelle bleiben, möchte ich etwas wie eine "glatte Verfolgung" der Objekte tun. Das heißt: Lassen Sie die Objekte, wo sie sind, und bewegen Sie die Kamera/den Blickpunkt mit einer bestimmten konstanten Geschwindigkeit nach links oder rechts. Momentan mache ich das, indem ich glTranslatef in meiner draw Funktion nenne, gefolgt von einem Code, der alle Objekte neu zeichnet. Dies ist jedoch sehr teuer (viele Objekte!). Gibt es eine Möglichkeit, die Kamera einfach zu bewegen, ohne die gesamte Szene neu zu zeichnen?ist es möglich, die Kamera nur in OpenGL zu bewegen, ohne die Szene neu zu zeichnen?

+3

Welche Sprache? Wenn dir die Sprache egal ist, entferne * all *, anstatt jede mögliche Bindung von opengl hinzuzufügen. –

+0

@ DavidRodríguez-dribeas Ich habe meinen Code in Python und C implementiert, aber es gibt keinen großen Unterschied in Bezug auf die Leistung. – memyself

+1

Wie _kann_ es möglich sein? Wenn sich die Kamera bewegt, ändert sich die Ansicht jedes Objekts in irgendeiner Weise. – leftaroundabout

Antwort

4

Es gibt keine Kamera in OpenGL. Oder wenn du wirklich denken willst, dass es da ist, dann musst du erkennen, dass die "Kamera" in OpenGL am Ursprung bleibt und immer in die gleiche Richtung schaut. Der "Kamera" -Effekt wird simuliert, indem alle Objekte in der Welt bewegt und gedreht werden, während die "Kamera" am Ursprung sitzt.

Also, wenn Sie die "Kamera" bewegen wollen, müssen Sie wirklich die Welt (oder alle Objekte der Welt) bewegen. Mit anderen Worten, es gibt wirklich keine Möglichkeit, "die Kamera zu bewegen, ohne alle Objekte neu zu zeichnen". Eine Option, wenn Sie wirklich wollen, wäre, die Szene auf eine Textur zu rendern, die größer als der Bildschirm ist, und dann die Textur zu verschieben, um die Bewegung der "Kamera" zu simulieren. Beachten Sie, dass wenn Sie eine perspektivische Projektion verwenden, wird es sehr falsch aussehen, wenn Sie dies tun. Dies sieht nur dann gut aus, wenn Sie eine orthographische Projektion verwenden.

Es klingt jedoch, als ob Sie im Sofortmodus zeichnen, was eine uralte und langsame Methode ist. Sie sollten moderne Draw-Aufrufe mit Shadern und Vertex-Array-Objekten/Vertex-Puffer-Objekten verwenden.

+0

danke! Ich benutze tatsächlich Vertex-Puffer-Objekte, aber da ich so viele davon habe, dauert das Rendern immer noch eine Menge Zeit! (siehe meinen obigen Beispielcode) – memyself

1

Hmm, du könnte die Szene auf eine Textur rendern, die größer ist als das Ansichtsfenster. Schieben Sie dann das Ansichtsfenster auf diese Textur. Wenn Sie sich den Kanten der Textur nähern, müssen Sie die Szene neu zeichnen, aber nicht jeden Frame. jedoch

Beachten Sie, dass dies hat mehrere Nachteile:

  • da die Wahrnehmung von Tiefe auf der Position der Kamera hängt die Kamera zu bewegen, ohne dass die Tiefeninformation Aktualisierung könnte zur Folge haben unerwünschte und noticable visuelle Artefakte wie die Szene erscheint flach usw.

  • Sie konnten die Kamera nicht drehen, da dann die visuellen Artefakte noch mehr sichtbar wären oder das Ansichtsfenster den strukturierten Raum verlassen könnte.

Als Alternative versuchen Sie, Ihre Szenenzeichnung zu optimieren. Es gibt mehrere Ansätze, dies zu tun, von denen einige sind:

  • Occlusion Culling
  • Rendering flache imposters/Sprites für weit entfernte Objekte
  • Verringerung der Ansichtstiefe
  • Verwendung Vertex- und Indexpuffer
  • Instancing
  • usw.

Bearbeiten:

Erinnern Sie Ihre Frage scheint es wie die glTranslatef usw. Anrufe könnte das Problem sein.In modernen OpenGL (sowie Direct3D) Anwendungen würden Sie die Matrizen selbst berechnen (vielleicht mit OpenCL aber nichtglTranslatef usw.), speichern Sie sie und übergeben Sie sie an die Shader, um die Objekte zu rendern.

Was könnte essen Leistung könnte die Matrix Berechnungen sein, wenn sie bei jedem Update durchgeführt werden. Wenn sich Ihre Objekte nicht sehr oft bewegen, sollten Sie die Matrizen nur berechnen, wenn sie sich bewegen, und beim Zeichnen einfach an OpenGL übergeben. Für eine weitere Optimierung sollten Sie vielleicht über die Lokalität der Daten nachdenken, um Cache-Fehler zu reduzieren usw. - aber das ist eine bereits sehr niedrige Optimierung.

Um die Antwort zusammenzufassen: Versuchen Sie nicht, die Anzahl der Frame-Updates zu reduzieren, sondern versuchen Sie, die einzelnen Updates zu optimieren. Wenn sich die "Kamera" bewegt, müssen Sie die Ansicht aktualisieren (d. H. Neu rendern) und somit ist Ihre einzige Option, die für diese Aktualisierungen erforderliche Arbeit zu reduzieren.

+0

Ich verwende bereits Vertex-Puffer-Objekte und muss daher die Daten nicht mehr an die GPU senden. Da ich aber so viele Objekte habe, bringt das Aufrufen aller 'gl *' - Funktionen meine Leistung zum Erliegen. Wie könnte "Instanziierung" hier helfen? – memyself

+0

@memyself Nun, das Instancing könnte die Anzahl der Vertex-/Index-Puffer-Zugriffe reduzieren, wenn Sie mehrere Exemplare derselben Form an verschiedenen Orten gezeichnet haben. Abgesehen davon, dass Sie in modernen Grafikanwendungen 'glTranslate' und dergleichen nicht verwenden sollten, werde ich in meiner Antwort weitere Informationen hinzufügen. Versuchen Sie außerdem zu profilieren, welche Funktionen Ihre Leistung tatsächlich auffressen. – Thomas

0

Nein, die gesamte Szene muss neu gezeichnet werden.

Der Aufruf glTranslatef ändert die Modellansichtsmatrix, die die erste Matrix ist, in die Ihre Geometrie umgewandelt wird. Ändern der Matrix bedeutet, dass alles in der Pipeline nach der Matrix wäre ungültig, die, weil es der erste Schritt wäre praktisch alles. Durch das Übersetzen, anstatt die "Kamera" zu bewegen, ist es mehr wie das Bewegen der ganzen Welt und die Kamera bleibt still.

Neben OpenGL (und Video-Hardware) funktioniert einfach nicht in der Art, wie Sie wollen.

Es gibt eine Technik namens Billboarding, die verwendet wird, um Geometrie zu rendern, die weit entfernt ist. Die Geometrie wird zu einer Textur gerendert, die dann beim Rendern der Hauptszene als Sprite verwendet wird. Solange die Kamera nahe an dem Punkt bleibt, an dem die Reklametafel erzeugt wurde, ist der Fehler akzeptabel (oder nicht wahrnehmbar). Die Szene wird immer noch in jedem Frame gerendert, aber Sie betrügen etwas. Dies wird normalerweise für weit entferntes Gelände und Bäume verwendet.

Bilboarding ist nicht etwas, das Sie durch die Geräusche der Dinge betrachten sollten, weil es ziemlich schwer ist, richtig zu machen. Um die Leistung zu verbessern, betrachten Sie zuerst Vertex-Pufferobjekte und Frustum Culling.

+0

Oder nicht VBOs, scheint, dass Sie sie bereits verwenden. Versuchen Sie State-Sortierung und Detaillierungstechniken. – eyesathousand

+0

Wenn Sie durch die Geschwindigkeit der Zeichenaufrufe begrenzt sind und Sie viele kleine VBOs haben (wenn es Sinn macht), können Sie die Leistung verbessern. Wenn Sie durch die Geschwindigkeit der GPU beschränkt sind, verbessert die Statussortierung die Cache-Lokalität in der GPU und verhindert Statusänderungen. – eyesathousand

+0

ja, ich habe viele kleine VBOs. Das Rendern der gleichen Anzahl von Objekten mit weniger VBOs ist viel schneller. Leider muss ich die Ansicht alle 20ms verschieben und neue Objekte zeichnen. Deshalb habe ich beschlossen, alle Objekte in VBOs zu zerlegen, die meinem 20ms Aktualisierungsintervall entsprechen. Auf diese Weise entferne ich einfach einen VBO und füge einen neuen hinzu. aber ich muss immer noch alle zeichnen. Wie könnte dies verbessert werden? – memyself

3

Ich bin Schaffung eine sehr teure Szene in machen opengl

Nein, haben Sie nicht. Du bist Zeichnung eine sehr komplexe Szene. Aber OpenGL funktioniert nicht mit Szenen. OpenGL bietet Ihnen Punkte, Linien und Dreiecke und zeichnet sie nach Ihren Befehlen zu einem zweidimensionalen Framebuffer. Aber sobald Sie die Zeichnung Befehle gesendet haben, und die Geometrie wurde gezeichnet OpenGL hat keine Erinnerung mehr von dem, was Sie ihm gesagt haben.

Was Sie am Ende haben, ist ein Bild. Wenn Sie irgendeinen Aspekt davon ändern wollen, und sei es nur der Aussichtspunkt, müssen Sie die ganze Sache neu zeichnen.

+0

ok, danke für deine Erklärung! – memyself

Verwandte Themen