Greetings OpenGL gurus,
I have been trying to use texture 2d arrays as render targets, but only the first layer turns out correct. Attached are some code snippits from a test application I created to work out the problem, I could not figure out how to attach the entire program as a zip file.
What I was expecting is to see a red triangle in the first layer, and a green one in the second layer. The red triangle appears correct, but the second layer is empty, as if it is being cleared but the triangle is not being drawn.
Does anyone have experience using these are render targets and can point out where I went wrong?
void CreateRenderTarget()
{
glGenTextures(1, &g_RenderTarget.color_texture);
glBindTexture(GL_TEXTURE_2D_ARRAY, g_RenderTarget.color_texture);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 0);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, g_Width, g_Height, 2, 0, GL_BGRA, GL_UNSIGNED_BYTE, 0);
glGenTextures(1, &g_RenderTarget.depth_stencil_texture);
glBindTexture(GL_TEXTURE_2D_ARRAY, g_RenderTarget.depth_stencil_texture);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 0);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH24_STENCIL8, g_Width, g_Height, 2, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0);
glGenFramebuffers(1, &g_RenderTarget.rt);
glBindFramebuffer(GL_FRAMEBUFFER, g_RenderTarget.rt);
glBindTexture(GL_TEXTURE_2D_ARRAY, g_RenderTarget.color_texture);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, g_RenderTarget.color_texture, 0);
glBindTexture(GL_TEXTURE_2D_ARRAY, g_RenderTarget.depth_stencil_texture);
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, g_RenderTarget.depth_stencil_texture, 0);
GLenum fbok = glCheckFramebufferStatus(GL_FRAMEBUFFER);
_ASSERT(fbok == GL_FRAMEBUFFER_COMPLETE);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
_ASSERT(glGetError() == GL_NO_ERROR);
}
void DoFrame()
{
GLint old_draw_buffer;
glGetIntegerv(GL_DRAW_BUFFER, &old_draw_buffer);
glDisable(GL_BLEND);
glClearDepth(1.0f);
glFrontFace(GL_CCW);
glDisable(GL_CULL_FACE);
glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
// Draw to render target.
glBindFramebuffer(GL_FRAMEBUFFER, g_RenderTarget.rt);
GLenum draw_buffer = GL_COLOR_ATTACHMENT0;
glDrawBuffers(1, &draw_buffer);
glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
glViewport(0, 0, g_Width, g_Height);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glBindVertexArray(g_DrawToTextureGeometry.vao);
glUseProgram(g_DrawToTextureShader.program);
glDrawArrays(GL_TRIANGLES, 0, 3);
// Draw contents of render target onto screen.
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDrawBuffer((GLenum)old_draw_buffer);
glClearColor(0.8f, 0.8f, 0.8f, 1.0f);
glViewport(0, 0, g_Width, g_Height);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glBindVertexArray(g_DrawToScreenGeometry.vao);
glUseProgram(g_DrawToScreenShader.program);
glBindTexture(GL_TEXTURE_2D_ARRAY, g_RenderTarget.color_texture);
glUniform1i(g_DrawToScreenShader.input_texture_handle, 0);
glUniform1f(g_DrawToScreenShader.which_layer_handle, (float)g_WhichLayer);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
glBindVertexArray(0);
SwapBuffers(g_DC);
_ASSERT(glGetError() == GL_NO_ERROR);
}
#version 150
layout(triangles) in;
layout(triangle_strip, max_vertices = 6) out;
out float flag_gs2ps;
void main()
{
// First layer
gl_Position = gl_in[0].gl_Position;
flag_gs2ps = 0.0;
gl_Layer = 0;
EmitVertex();
gl_Position = gl_in[1].gl_Position;
flag_gs2ps = 0.0;
gl_Layer = 0;
EmitVertex();
gl_Position = gl_in[2].gl_Position;
flag_gs2ps = 0.0;
gl_Layer = 0;
EmitVertex();
EndPrimitive();
// Second layer
gl_Position = gl_in[0].gl_Position;
flag_gs2ps = 1.0;
gl_Layer = 1;
EmitVertex();
gl_Position = gl_in[1].gl_Position;
flag_gs2ps = 1.0;
gl_Layer = 1;
EmitVertex();
gl_Position = gl_in[2].gl_Position;
flag_gs2ps = 1.0;
gl_Layer = 1;
EmitVertex();
EndPrimitive();
}
#version 150
in float flag_gs2ps;
out vec4 color_psout;
void main()
{
if (flag_gs2ps < 0.5)
color_psout.rgb = vec3(1.0, 0.2, 0.2);
else if (flag_gs2ps < 1.5)
color_psout.rgb = vec3(0.2, 1.0, 0.2);
else
color_psout.rgb = vec3(0.2, 0.2, 1.0);
color_psout.a = 1.0;
}
Thank you for the assistance.