2014-05-29 6 views
6

Ich implementiere in Android und nativem C++ eine Szenenzeichnung für Android mit egl 1.1. Derzeit mit Android glSurfaceView - die mir erlaubt, zu einem Back-Buffer, der am Ende von "onDrawFrame" angezeigt wird - wenn der Back-Buffer und der Front-Buffer vertauscht sind.Pufferinhalt nach eglSwapBuffers speichern

Mein Problem ist das - Ich muss in der Lage sein, den Backbuffer anzuzeigen und weiterschreiben, als ob ich nicht getauscht habe. Der Grund für diese Nachfrage ist, dass die Szene sehr groß ist, und es ist nicht möglich jeden Frame zu bauen, auch nicht auf das Ende der Zeichnung zu warten - da der Benutzer zu lange warten muss.

Mit anderen Worten - ich muss die Szene inkrementell bauen. Zu einem bestimmten Zeitpunkt während des Renderings, ich entscheide, es ist Zeit und ich rufe , die den gezeichneten Inhalt aus dem Backbuffer anzeigt, aber wenn ich weiter schreibe, schreibe ich offensichtlich in den 'ehemaligen-Front-Puffer', der out ist Sync .. (ohne die Dinge, die ich bisher gezeichnet habe).

Soweit ich sehe, ist meine einzige Option, den Backbuffer vor dem Swappen zu kopieren. pseudo:

  1. Draw
  2. Kopieren Back Buffer auf Temp Buffer
  3. Swap
  4. Copy Temp Puffer (der neue) zurück Puffer
  5. mehr Dinge Draw-Back-Puffer sichern Puffer
  6. Und so weiter ...

Meine Frage - Gibt es eine Möglichkeit, Schritte 2,4 zu tun?

  • Ist glCopyPixels nützlich in diesem Fall? Beispiel?
  • Ist glBlitFramebuffer?

Oder nähere ich mich dem alles falsch?

Dinge, die ich tat schon:

  • ich EGL_SWAP_BEHAVIOR-EGL_BUFFER_PRESERVED versucht Einstellung, aber es scheint nur auf bestimmten Geräten zu arbeiten (wie im khronos notes beschrieben):

Einige Oberflächen erlauben Anwendungen zur Kontrolle, ob der Farbpufferinhalt erhalten bleibt

  • Die Szene in jedem Bild neu rendern - nicht möglich. Ich habe oft gelesen, dass dies empfohlen wird.

Antwort

2

Ihre allgemeine Vorgehensweise ist korrekt.Die Verwendung von glBlitFramebuffer() ist wahrscheinlich hilfreicher, da glCopyPixels nur einige Unterrechtecke des Puffers in eine andere Position im selben Puffer kopiert.

Allerdings kann ich von einer potenziell besseren Ansatz denken, zumindest wenn OES_framebuffer_object verfügbar:

  1. Unentschieden Textur oder einem benutzerdefinierten renderbuffer
  2. machen Texturpuffer/blit renderbuffer zu Rücken an Rücken Puffer
  3. Swap
  4. Update Textur/renderbuffer
  5. Textur machen Puffer/blit renderbuffer zu Rücken an Rücken Puffer
  6. Swap
  7. [... und so weiter ...]

diese Weise werden Sie keine Kopie/update/Copy/Swap-Zyklus mit 2 Kopien pro Frame, sondern nur Aktualisierung/Kopie/Tausche mit einer einzigen zusätzlichen Kopie.

+0

Vielen Dank für die Antwort. Würdest du etwas näher darauf eingehen? Welche Methode sollte ich für die Schritte 1,2 verwenden? Ich bin sehr neu in der Verwendung von gl (Portierung plattformübergreifender Code zu Android .. - versuchen, eine Alternative zu IOS 'presentRenderbuffer' zu finden) –

+0

@DrorFichman: Vielleicht [diese GL Wiki-Seite] (http://www.opengl.org/wiki/Framebuffer_Object) kann dir helfen. Es erklärt die Grundlagen von FBOs (und das gilt auch für GLES, es ist nur ein bisschen begrenzter dort). Wenn Sie also Ihr Programm starten, erstellen Sie einen FBO, hängen Sie einen Render-Puffer oder eine Textur als Farbpuffer an. Vielleicht brauchst du auch einen Tiefenpuffer. Für Schritt 1 binden Sie einfach den FBO, und das Rendering wird ausgeführt. Für Schritt 2 verwenden Sie entweder 'glBlitFramebuffer', oder wenn Sie eine Textur und keinen Render-Puffer anfügen, rendern Sie nur einen Vollbildschirm-Vierer mit dieser angewendeten Textur. – derhass