I am trying to render to all 6 faces of cubemap with a single drawcall.The GL cubemap is attached to an offscreen frame buffer object.The result I am getting is only the face number zero is affected by both frame buffer clear color and the fragment shader output.The goal is to use geometry shader which is invoked 6 times (once per face),then the gl_InstanceID is assigned to built-in gl_Layer.Fragment shader stage would read gl_Layer value and shade the raster based on in.It is expected that all 6 faced will be painted with a unique color that depends on gl_Layer value.
For the tests to see that I am getting correct gl_layer value I'm trying to render the layer id into the alpha channel of the texture by the following fragment shader:
#version 430
// Ouput data
layout(location = 0) out vec4 color;
in int gl_Layer;
void main(){
color = vec4(0.5,0.5,0.5,float(gl_Layer)/255.0);
}
The vertex shader basically do nothing:
#version 430
in vec3 position;
void main(){
gl_Position = vec4(position, 1.0);
}
and the geometry shader executes 6 times, render a unit square (covers the whole viewport) and sets gl_Layer according to gl_InvocationID:
#version 430
layout(triangles, invocations = 6) in;
layout(triangle_strip, max_vertices = 4) out;
out int gl_Layer;
void main()
{
const vec2 vert_data[4] = vec2[]( vec2(-1.0, 1.0), vec2(-1.0, -1.0), vec2(1.0, 1.0), vec2(1.0, -1.0) );
for(int i=0; i<4; i++)
{
gl_Layer = gl_InvocationID;
gl_Position = vec4(vert_data[i].xy,0,1);
EmitVertex();
}
EndPrimitive();
}
and finally, this is how I set the texture and the framebuffer:
glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &fbtextures_count);
// how many textures to create? depends on complexity of your effects.
glActiveTexture(GL_TEXTURE0);
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glGenTextures(1, &fbcubetexture);
GLenum target = GL_TEXTURE_CUBE_MAP;
// initializing color maps
glBindTexture(target, fbcubetexture);
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
initData(255,255, 255);
for (int i = 0; i < 6; i++)
{
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA8, cube_s, cube_s, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
}
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, fbcubetexture, 0);
GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0 };
glDrawBuffers(1, drawBuffers);
glReadBuffer(GL_COLOR_ATTACHMENT0);
glDrawBuffer(GL_COLOR_ATTACHMENT0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
I am reading the faces colors on the client with:
for (int i = 0; i < 6; i++)
{
glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA,GL_UNSIGNED_BYTE, data);
}
The result I get for GL_TEXTURE_CUBE_MAP_POSITIVE_X, is correct. but the rest of the face stay with the same first initialized value.I also debugged using NVIDIA NSIGHT where the whole cubemap texture is seen with only one face painted.
I read tens of examples which show how to use gl_Layer id for multi-target rendering through geometry shader but all of them do it differently.
For example,it is not clear if it is enough to attach cubemap texture to a single render target of FBO,or each face must be attached to a different render target?
Should glFramebufferTexture be used to bind the attachments or glFramebufferTexture2D ?
When cubemap is attached to the framebuffer is glClearColor supposed to clear all the faces to some color or just the first one?
What do I miss here?Anyone can show how to do it the right way?
System specs:
GPU:NVIDIA GeForce 960 GTX Windows7 64bit MSVC120
I can't prove this is the problem. But it is certainly one problem:
for(int i=0; i<4; i++)
You said that your GS takes triangles
as inputs. Well, those only have three vertices, not 4. So your triangle strip will have a bad vertex in it.
When looping over items in a GS, it's always safer to do this:
for(int i = 0; i < gl_in.length(); i++)
That way, if you change the input primitive type, your length automatically gets updated.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With