GL EXT framebuffer object
(Mehr Informationen/weitere Artikel) {{{1}}} |
Inhaltsverzeichnis
EXT_framebuffer_object
Die Orginalspezifikation finden Sie unter "Ressourcen" am Ende des Artikels. |
Abfragestring
GL_EXT_framebuffer_object
Beschreibung
Diese Extension stellt ein Interface bereit, um in Ziele zu rendern, welche nicht vom Fenstersystem bereitgestellt wurden. Sie ähneln damit den PBuffern, nur muss man sich hier nicht mit plattformabhängigen und langsamen wgl/glX-Befehlen herumplagen. Auch die lästigen Context-Switches entfallen.
Diese neuen Renderziele sind so genannte Framebufferobjekte. Sie selbst stellen aber noch keine Puffer bereit, daher kann man an sie Renderbuffer und Texturen binden. Dies ist möglich für die bisherigen logischen Standard-GL Puffertypen: Color-, Depth- und Stencilbuffer.
Ein Binden eines Framebufferbildes an den Accumationbuffer wird hier auf eine spätere Extension verschoben. |
Wenn ein Framebufferbild an den Framebuffer gebunden wurde, dient es als Quelle für Readoperationen wie glReadPixels und als Ziel für Fragmentoperationen.
Durch die Einführung von Framebufferbildern als Renderziel wird Rendern in nicht sichtbare Bereiche (offscreen rendering) ermöglicht.
Weiterhin wird das Rendern in Texturen dahingehend vereinfacht, dass man das Texturbild als Framebufferbild binden kann und so direkt in die Textur rendern kann. Dies geschieht, indem man durch die Angabe von Mipmap-Level, Cubemap-Fläche (für Cubemap Texturen) und einem Z-Offset (nur bei 3D Texturen) ein bestimmtes Bild eines Texturobjekts wählt.
Die "Render To Texture Semantik" ist vergleichbar mit dem klassischen Rendern in den Framebuffer mit anschließendem Aufruf von glCopyTexSubImage. Vorteil der neuen Methode ist, dass man das selbe Ergebnis erhält, dabei aber auf das Kopieren der Daten verzichten kann.
Verwendung
Im Folgenden soll anhand einem einfachen Beispiel die Funktionsweise der GL_EXT_framebuffer_object-Extension erklärt werden. Ziel: Es sollen eine 3D-Szene in den Framebuffer gezeichnet werden, der diese dann in eine Textur packt und diese für spätere Verwendungen zur Verfügung stellt.
Initialisierung
Das Framebufferobjekt wird meißt beim Erzeugen des Fenster (speziell in Delphi der Form) initialisiert. Bei der Entwicklung der Extension wurde darauf geachtet, dass dies "herkömmlichen" Vorgängen - wie dem Anlegen einer Textur - ähnlich abläuft. Zuerst wird das Framebufferobjekt generiert:
var
fb: GLuint;
(...)
glGenFramebuffersEXT(1, @fb);
Anschließend müssen noch ein Renderbufferobjekt und eine Textur angelegt werden:
render_buf, tex: GLuint;
(...)
glGenRenderbuffersEXT(1, @render_buf);
glGenTextures(1, @tex);
Nun wird das Framebufferobjekt fb und die Textur tex aktiv geschalten, man erkennt, dass die Handhabung sich sehr stark ähnelt:
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
glBindTexture(GL_TEXTURE_2D, color_tex);
(Analog zu Texturen wird mit glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0) das Framebufferobjekt wieder deaktiviert. {Wenn man es technisch ganz genau sieht, wird mit der 0 wieder der Standard-Framebuffer verwendet.} )
Jetzt muss man die Textur erzeugen und ihre Parameter einstellen, hier kommen die "üblichen Verdächtigen" zur Anwendung:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 512, 512, 0, GL_RGB, GL_UNSIGNED_BYTE, nil);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
Nun werden Framebuffer, Textur und Renderbuffer verbunden:
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_2D, color_tex, 0);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, render_rb);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, 512, 512);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
GL_RENDERBUFFER_EXT, render_rb);
Da in den letzten Schritten einige sehr implementations-spezifische Dinge eingestellt wurden, bei denen es aufgrund diverser Inkompatibilitäten zu Probleme kommen kann, wird die hilfreiche Funktion glCheckFramebufferStatusEXT mitgeliefert. Als Argument erhält sie die Konstante GL_FRAMEBUFFER_EXT und liefert je nach Zustand des aktuellen Framebufferobjektes eine der folgenden Konstanten:
- FRAMEBUFFER_COMPLETE
- FRAMEBUFFER_INCOMPLETE_ATTACHMENT
- FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT
- FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT
- FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT
- FRAMEBUFFER_INCOMPLETE_FORMATS_EXT
- FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT
- FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT
- FRAMEBUFFER_UNSUPPORTED
- FRAMEBUFFER_STATUS_ERROR
FRAMEBUFFER_UNSUPPORTED weist zum Beispiel auf falsche Formate für Texturen und/oder Buffer hin. Welche Eigenschaften für FRAMEBUFFER_COMPLETE nötig sind, hängt von der Implementation - also Grafikkartenhersteller, Treiber, etc - ab und lässt sich nicht pauschal festlegen.
Zeichenroutine
In der Zeichenroutine lässt sich die Extension auch sehr einfach handhaben.
Zuerst aktiviert man wieder das Framebufferobjekt, in das gezeichnet werden soll:
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
Anschließend kann man einfach seinen üblichen Zeichen-Code aufrufen beziehungsweise den Teil davon, den man als Textur haben will. Ist man damit fertig, schaltet man das Framebufferobjekt wieder ab (glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0)) und kann dann ganz nach Belieben die Textur tex verwenden.
Anwendungsmöglichkeiten
- High-Dynamic-Range-Rendering, oft als HDR-Rendering abgekürzt
- Allgemein Postfilter-Effekte wie Fish-Eye, (Motion-) Blur, ...
- Off-Screen-Rendering
- Performancesteigerung durch einmaliges Rendern in eine Textur, die dann über mehrere Frames verwendet wird
- ...
Neue Funktionen
- glIsRenderbufferEXT
- glBindRenderbufferEXT
- glDeleteRenderbuffersEXT
- glGenRenderbuffersEXT
- glRenderbufferStorageEXT
- glGetRenderbufferParameterivEXT
- glIsFramebufferEXT
- glBindFramebufferEXT
- glDeleteFramebuffersEXT
- glGenFramebuffersEXT
- glCheckFramebufferStatusEXT
- glFramebufferTexture1DEXT
- glFramebufferTexture2DEXT
- glFramebufferTexture3DEXT
- glFramebufferRenderbufferEXT
- glGetFramebufferAttachmentParameterivEXT
- glGenerateMipmapEXT
Neue Tokens
Neue Parameterwerte
Für den target Parameter von glBindFramebufferEXT, glCheckFramebufferStatusEXT, glFramebufferTexture{1D|2D|3D}EXT, glFramebufferRenderbufferEXT und glGetFramebufferAttachmentParameterivEXT:
- GL_FRAMEBUFFER_EXT
Für den target Parameter von glBindRenderbufferEXT, glRenderbufferStorateEXT und glGetRenderbufferParameterivEXT und als Rückgabewert von glGetFramebufferAttachmentParamterivEXT:
- GL_RENDERBUFFER_EXT
Für den internalformat Parameter von glRenderbufferStorageEXT:
- GL_STENCIL_INDEX1_EXT
- GL_STENCIL_INDEX4_EXT
- GL_STENCIL_INDEX8_EXT
- GL_STENCIL_INDEX16_EXT
Für den pname Parameter von glGetRenderbufferParameterivEXT:
- GL_RENDERBUFFER_WIDTH_EXT
- GL_RENDERBUFFER_HEIGHT_EXT
- GL_RENDERBUFFER_INTERNAL_FORMAT_EXT
- GL_RENDERBUFFER_RED_SIZE_EXT
- GL_RENDERBUFFER_GREEN_SIZE_EXT
- GL_RENDERBUFFER_BLUE_SIZE_EXT
- GL_RENDERBUFFER_ALPHA_SIZE_EXT
- GL_RENDERBUFFER_DEPTH_SIZE_EXT
- GL_RENDERBUFFER_STENCIL_SIZE_EXT
Für den pname Parameter von glGetFramebufferAttachmentParameterivEXT:
- GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT
- GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT
- GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT
- GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT
- GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT
Für den attachment Parameter von glFramebufferTexture{1D|2D|3D}EXT, glFramebufferRenderbufferEXT und glGetFramebufferAttachmentParameterivEXT:
- GL_COLOR_ATTACHMENT0_EXT
- GL_COLOR_ATTACHMENT1_EXT
- GL_COLOR_ATTACHMENT2_EXT
- GL_COLOR_ATTACHMENT3_EXT
- GL_COLOR_ATTACHMENT4_EXT
- GL_COLOR_ATTACHMENT5_EXT
- GL_COLOR_ATTACHMENT6_EXT
- GL_COLOR_ATTACHMENT7_EXT
- GL_COLOR_ATTACHMENT8_EXT
- GL_COLOR_ATTACHMENT9_EXT
- GL_COLOR_ATTACHMENT10_EXT
- GL_COLOR_ATTACHMENT11_EXT
- GL_COLOR_ATTACHMENT12_EXT
- GL_COLOR_ATTACHMENT13_EXT
- GL_COLOR_ATTACHMENT14_EXT
- GL_COLOR_ATTACHMENT15_EXT
- GL_DEPTH_ATTACHMENT_EXT
- GL_STENCIL_ATTACHMENT_EXT
Als Rückgabewerte von glCheckFramebufferStatusEXT:
- GL_FRAMEBUFFER_COMPLETE_EXT
- GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT
- GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT
- GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT
- GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT
- GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT
- GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT
- GL_FRAMEBUFFER_UNSUPPORTED_EXT
Als Parameter von glGetIntegerv:
- GL_FRAMEBUFFER_BINDING_EXT
- GL_RENDERBUFFER_BINDING_EXT
- GL_MAX_COLOR_ATTACHMENTS_EXT
- GL_MAX_RENDERBUFFER_SIZE_EXT
Als Rückgabewert von glGetError:
- GL_INVALID_FRAMEBUFFER_OPERATION_EXT
Neue States
Abhängigkeiten
- OpenGL 1.1
Ressourcen
http://www.opengl.org/documentation/extensions/EXT_framebuffer_object.txt http://download.nvidia.com/developer/presentations/2005/GDC/OpenGL_Day/OpenGL_FrameBuffer_Object.pdf