# draw on cubemap with help of geometry shader each triangle covers each cubemap face (why??)

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);


#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?

After trying everything possible I found my mistake:

The shaders are fine, the only thing which is wrong is the frameBufferObject binding. To be honest, the texture to FBO binding.

the only thing I replaced is this:

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);


by the correct method call:

glFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_cubeMapTexture, 0);



The result of the changed code is this: