2009-03-06 10 views
0

Ich habe einige OpenGL-Code, der sich über verschiedene Hardware inkonsistent verhält. Ich habe einige Code bekam das:Selbstreferenzierende Renderbuffer in OpenGL

  1. einen Puffer übertragen Erstellt und bindet eine Textur seiner Farbpuffer (Texture A)
  2. Sets dieser Puffer als aktiv machen, und passt die Darstellungs usw.
  3. Aktiviert ein Pixelshader (in diesem Fall Gaußsche Unschärfe).
  4. Zeichnet ein Quad auf Vollbild mit Textur A auf.
  5. Löst die Bindung der renderbuffer usw.

Auf meiner Entwicklung Maschine das funktioniert gut und hat die beabsichtigte Wirkung der Textur „in place“ Unschärfe jedoch auf andere Hardware dies nicht zu funktionieren scheinen.

Ich habe es auf zwei Möglichkeiten bekommen.

A) Einen Renderspeicher rendern zu lassen soll nicht funktionieren, und funktioniert nur auf meinem Entwicklungscomputer aufgrund einer Art Zufallsgenerator.

Oder

B) sollte dieser Ansatz funktioniert, aber etwas anderes schief läuft.

Irgendwelche Ideen? Ehrlich gesagt hatte ich Schwierigkeiten, Einzelheiten zu diesem Thema zu finden.

Antwort

2

A) ist die richtige Antwort. Rendering in den gleichen Puffer beim Lesen von es ist undefiniert. Es könnte funktionieren, es könnte nicht - was genau passiert ist.

In OpenGLs Fall hat framebuffer_object extension Abschnitt "4.4.3 Rendern, wenn ein Bild eines gebundenen Texturobjekts auch an den Framebuffer angehängt wird" was sagt, was passiert (im Grunde, undefined). In Direct3D9 beschwert sich die Debug-Laufzeitumgebung lautstark, wenn Sie dieses Setup verwenden (aber es funktioniert je nach Hardware/Treiber). In D3D10 löst die Laufzeit immer das Ziel, das als Ziel verwendet wird, denke ich.

Warum ist das nicht definiert? Einer der Gründe, warum GPUs so schnell sind, ist, dass sie viele Annahmen treffen können. Zum Beispiel können sie annehmen, dass Einheiten, die Pixel holen, nicht mit Einheiten kommunizieren müssen, die Pixel schreiben. So kann eine Oberfläche gelesen werden, N Zyklen später ist das Lesen abgeschlossen, N Zyklen später beendet der Pixel-Shader seine Ausführung, dann wird er in einige Ausgabe-Merge-Buffer auf der GPU gelegt und schließlich wird er irgendwann in den Speicher geschrieben. Hinzu kommt, dass die GPUs in "undefinierter" Reihenfolge gerastert werden (eine GPU könnte in Zeilen gerastert werden, eine andere in einer cache-freundlichen Reihenfolge, eine andere in völlig anderer Reihenfolge), sodass Sie nicht wissen, welche Teile der Oberfläche geschrieben werden zu erst.

Sie sollten also mehrere Puffer erstellen. In blur/glow Fall, zwei ist in der Regel genug - Render in zuerst, dann lesen & verwischen, dass beim Schreiben in die Sekunde. Wiederholen Sie diesen Vorgang bei Bedarf in Ping-Pong-Weise.

+0

Danke, ich habe mich bei meinen eigenen Recherchen darauf gestützt, obwohl ich keine konkrete Antwort bekommen konnte. – Brandorf

+0

@brandorf: Ich habe einen Link zur Framebuffer-Objektspezifikation hinzugefügt, in der steht, dass das Ergebnis nicht definiert ist. – NeARAZ

0

In einigen speziellen Fällen könnte sogar der Backbuffer ausreichen. Du machst einfach keinen glClear, und was du vorher gezeichnet hast, ist immer noch da. Der Nachteil ist natürlich, dass man nicht wirklich vom Backbuffer lesen kann. Aber für Effekte wie Ein- und Ausblenden funktioniert das.