// die sichtbare Szene wird in die PrimaryScreenTexture gerendert:
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D,
PrimaryScreenTexture->TextureID, 0);
// das zugehörige Tiefenabbild wird in die PrimaryCameraDepthTexture
// gerendert:
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1,GL_TEXTURE_2D,
PrimaryCameraDepthTexture->TextureID, 0);
Hinweis:
GLuint maxbuffers;
glGetIntergeri(GL_MAX_COLOR_ATTACHMENTS, &maxbuffers);
das eigentliche Szenenbild:
// Framebuffer vor der Benutzung binden:
glBindFramebuffer(GL_FRAMEBUFFER, PrimaryScreenFrameBuffer);
glViewport(0, 0, g_screenwidth, g_screenheight);
// Render Target (PrimaryScreenTexture) auswählen:
glDrawBuffer(GL_COLOR_ATTACHMENT0);
glClearColor(pBackgroundColor->x, pBackgroundColor->y, pBackgroundColor->z,
pBackgroundColor->w);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Framebuffer nach der Benutzung wieder abkoppeln:
glBindFramebuffer(GL_FRAMEBUFFER, 0);
das zum Szenenbild zugehörige Tiefenabbild:
// Framebuffer vor der Benutzung binden:
glBindFramebuffer(GL_FRAMEBUFFER, PrimaryScreenFrameBuffer);
glViewport(0, 0, g_screenwidth, g_screenheight);
// Render Target (PrimaryCameraDepthTexture) auswählen:
glDrawBuffer(GL_COLOR_ATTACHMENT1);
glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Framebuffer nach der Benutzung wieder abkoppeln:
glBindFramebuffer(GL_FRAMEBUFFER, 0);
Nachdem die Render Targets für die Aufnahme des neuen Szenenbilds vorbereitet sind, können wir auswählen, welche der Targets im Verlauf des aktuellen Render-Durchgangs wann verwendet werden sollen. Beispielsweise setzen wir für die Hintergrunddarstellung sceneColorOnly auf true, denn natürlich benötigen wir keinen Tiefenabbild des Hintergrundes.
// Framebuffer vor der Benutzung binden:
glBindFramebuffer(GL_FRAMEBUFFER, PrimaryScreenFrameBuffer);
if(sceneColorOnly == true)
{
// Render Target (PrimaryScreenTexture) auswählen:
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
glViewport(0, 0, g_screenwidth, g_screenheight);
}
else
{
// mehrere Render Targets (PrimaryScreenTexture,
// PrimaryCameraDepthTexture) auswählen:
GLenum buffers[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
glDrawBuffers(2, buffers);
glViewport(0, 0, g_screenwidth, g_screenheight);
}
Soll nun ein Fragment Shader in mehrere Render Targets schreiben können, benötigen wir zunächst eine entsprechende Anzahl von Output-Variablen (gs_FragColor[2]). In unserem Beispiel schreibt gs_FragColor[0] in die PrimaryScreenTexture, da wir in buffers[] GL_COLOR_ATTACHMENT0 als ersten Render Buffer festgelegt haben. Dementsprechend schreibt gs_FragColor[1] in die PrimaryCameraDepthTexture, da wir in buffers[] GL_COLOR_ATTACHMENT1 als zweiten Render Buffer festgelegt haben.
// Output Variablen: out vec4 gs_FragColor[2]; void main() { // GL_COLOR_ATTACHMENT0: gs_FragColor[0] = vec4(0.0, 1.0, 0.0, 1.0); // GL_COLOR_ATTACHMENT1: gs_FragColor[1] = vec4(0.0, 0.0, 1.0, 1.0); }
Hinweis:
Für die Ausführung dieses Programmbeispiels muss der Treiber Ihrer Grafikkarte die OpenGL Version 3.3 unterstützen.
Visual C++ 2010: DemoWithOpenGL2010_Tut18