I want to do some complicated stuff but have problems with my geometry shader / FBO bindings. To hold it as easy as possible I reduced the code to a minimum. If this works, I could continue the hard part. So don't wonder, why I am trying to do it in this way...
The "easy" thing:
I have two triangles (a quad) which are going over the whole screen from (-1,-1,0) to (1,1,0). Inside my geometry shader I want to copy these two triangles six times to cover all six faces of my cubemap. BTW: I don't need a depth or stencil buffer.
Lets look at the cubemap texture generation:
glGenTextures(1, &m_cubeMapTexture);
glBindTexture(GL_TEXTURE_CUBE_MAP, m_cubeMapTexture);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
checkGLError();
// set textures
for (int i = 0; i < 6; ++i)
glTexImage2D(static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i), 0, GL_RGB, 2048, 2048, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
This texture will be plugged into a frameBufferObject in the following way:
glGenFramebuffers(1, &m_cubeMapFBO);
glBindFramebuffer(GL_FRAMEBUFFER, m_cubeMapFBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X, m_cubeMapTexture, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, m_cubeMapTexture, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, m_cubeMapTexture, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, m_cubeMapTexture, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT4, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, m_cubeMapTexture, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT5, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, m_cubeMapTexture, 0);
static const GLuint draw_buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3, GL_COLOR_ATTACHMENT4, GL_COLOR_ATTACHMENT5 };
glDrawBuffers(6, draw_buffers);
The vertex shader:
#version 420
in vec3 POSITION;
out VS_OUT
{
vec3 position;
} vs_out;
void main()
{
vs_out.position = POSITION;
}
Just take the input and pass it to the geometry shader
Lets continue with the geometry shader:
#version 420
layout (triangles) in;
layout (triangle_strip, max_vertices = 36) out;
uniform mat3 orientation[6];
in VS_OUT
{
vec3 position;
} gs_in[];
out GS_OUT
{
vec3 position;
} gs_out;
void main()
{
for (int i = 0; i < 6; ++i)
{
gl_Layer = i;
gl_Position = vec4(gs_in[0].position, 1.0f);
gs_out.position = orientation[i] * vec3(gs_in[0].position.xy, 1.0f);
EmitVertex();
gl_Layer = i;
gl_Position = vec4(gs_in[1].position, 1.0f);
gs_out.position = orientation[i] * vec3(gs_in[1].position.xy, 1.0f);
EmitVertex();
gl_Layer = i;
gl_Position = vec4(gs_in[2].position, 1.0f);
gs_out.position = orientation[i] * vec3(gs_in[2].position.xy, 1.0f);
EmitVertex();
EndPrimitive();
}
}
The for loop creates each triangle six times (one for each cubemap face "gl_Layer = i"). the gl_Position is the input quad without any transformations. the gs_out.position is rotated by the orientation matrix (a rotation matrix for each face). This gs_out.position should be interpolated within the fragment shader.
Last, but not least: The fragment shader
#version 420
in GS_OUT
{
vec3 position;
} fs_in;
out vec4 color;
void main()
{
color = vec4(fs_in.position, 1.0f);
}
The interpolated fs_in.position will be stored into the cubemap.
If you just look at the code and try to imagine what the output should be, you'll end up to say: "That is the RGB cube + the minus part which is stored in the cubemap."
And now I'll show you the output:
My first intention was changing the "orientation" matrices but I noticed, that this is not the problem: By changing the for loop counter within my geometry shader to "for (int i = 0; i < 1; ++i)" I got the following output:
So there are only the two triangles, which are not copied anymore and each cubemap face is colored in the same way. gl_Layer was only set to zero but the other layers are also colored. How can that be? How can I change the code, so that only the face "gl_Layer" will be colored?