1
\$\begingroup\$

This question is related to another question of mine on StackOverflow.

The problem I'm facing is that while I'm rendering to a cubemap in a single pass using a geometry shader (like I show in my other question) only the positive X face of the cube map actually gets rendered.

Using NSight I could see that actually also my negative X face is being rendered (with the right color looking to the pixel history), but then it results to be completely black, like if the fragment is discarded.

Doing some tests, I've found that this problem may be due to a glViewport call that I do when I bind the framebuffer of the destination cube map as the rendering target. My destination cube map is a 256x256 pixels cube map (every face is 256x256 pixels wide) and calling glViewport(0, 0, 256, 256) doesn't work (it renders only the positive X face like I said befare), but calling glViewport(0, 0, 181, 181) and below (with width and height less than 181) also the negative X face is rendered. Every call to glViewport passing width and height more than 181 doesn't work.

Could this be a driver problem? I'm facing this problem ONLY when rendering to the cube map bound to the framebuffer as GL_TEXTURE_CUBE_MAP target, if I bind every face with GL_TEXTURE_CUBE_MAP_POSITIVE_X, ... as target and draw to it there's no problem.


UPDATE

This is my geometry shader (this handles only the positive and negative X faces):

#version 330 core

layout(points) in;
layout(triangle_strip, max_vertices = 8) out;

out vec3 frag_textureCoord;

void main()
{
    const vec4 positions[4] = vec4[4] ( vec4(-1.0, -1.0, 0.0, 1.0),
                                        vec4( 1.0, -1.0, 0.0, 1.0),
                                        vec4(-1.0,  1.0, 0.0, 1.0),
                                        vec4( 1.0,  1.0, 0.0, 1.0) );

    // Positive X
    gl_Layer = 0;                   
    gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);
    frag_textureCoord = vec3(1.0,  1.0, -1.0);
    EmitVertex();

    gl_Position = vec4( 1.0, -1.0, 0.0, 1.0);
    frag_textureCoord = vec3(1.0,  1.0,  1.0);
    EmitVertex();

    gl_Position = vec4(-1.0,  1.0, 0.0, 1.0);
    frag_textureCoord = vec3(1.0, -1.0, -1.0);
    EmitVertex();

    gl_Position = vec4( 1.0,  1.0, 0.0, 1.0);
    frag_textureCoord = vec3(1.0, -1.0,  1.0);
    EmitVertex();                
    EndPrimitive();

    // Negative X
    gl_Layer = 1;                   
    gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);
    frag_textureCoord = vec3(-1.0,  1.0, -1.0);
    EmitVertex();

    gl_Position = vec4( 1.0, -1.0, 0.0, 1.0);
    frag_textureCoord = vec3(-1.0,  1.0,  1.0);
    EmitVertex();

    gl_Position = vec4(-1.0,  1.0, 0.0, 1.0);
    frag_textureCoord = vec3(-1.0, -1.0, -1.0);
    EmitVertex();

    gl_Position = vec4( 1.0,  1.0, 0.0, 1.0);
    frag_textureCoord = vec3(-1.0, -1.0,  1.0);
    EmitVertex();                  
    EndPrimitive();
}

This is how I create the destination cubemap and its framebuffer:

// Destination cube map creation
glGenTextures(1, &_destinationCubeMapTextureID);
glBindTexture(GL_TEXTURE_CUBE_MAP, _destinationCubeMapTextureID);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

for (size_t face = 0; face < 6; face++)
    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + (unsigned int)face, 0, GL_RGBA16F, 256, 256, 0, GL_RGBA, GL_FLOAT, nullptr);

glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 8);
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);

glBindTexture(GL_TEXTURE_CUBE_MAP, 0);

// Destination depth map creation
glGenTextures(1, &_destinationDepthCubeMapTextureID);
glBindTexture(GL_TEXTURE_CUBE_MAP, _destinationDepthCubeMapTextureID);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

for (size_t face = 0; face < 6; face++)
    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + (unsigned int)face, 0, GL_DEPTH_COMPONENT24, 256, 256, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr);

glBindTexture(GL_TEXTURE_CUBE_MAP, 0);

// Destination framebuffer creation
glGenFramebuffers(1, &_destinationFrameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, _destinationFrameBuffer);

glFramebufferTexture(GL_FRAMEBUFFER, attachment, _destinationCubeMapTextureID, 0);
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, _destinationDepthCubeMapTextureID, 0);

glDrawBuffers(1, &drawBuffer);

This is basically how I bind the cubemap framebuffer to draw and how I send the draw command:

void BindTextureTarget()
{
    glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _destinationFrameBuffer);

    glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _destinationCubeMapTextureID, 0);
    glViewport(0, 0, 256, 256);
}


...
glUseProgram(programID);

BindTextureTarget();

glClear(GL_COLOR_BUFFER_BIT);
glClearColor(0.0, 0.0, 0.0, 0.0);

pointVertexArray.Enable();
glDrawArrays(GL_POINTS, 0, 1);
\$\endgroup\$
  • \$\begingroup\$ I noticed 181 is the highest number less than 256 divided by the square root of 2 - if you have two 181x181 textures then you have less than 256x256 pixels but if you have two 182x182 textures then you have more than 256x256 pixels. But that should have nothing to do with anything... \$\endgroup\$ – immibis Sep 27 '16 at 3:01
-1
\$\begingroup\$

First of all, please put a simple version of your code here so I can fix it for you.

But for now, there is lots of reason you can't render correctly in your cube map:

  • Early use of texture (use flush and finish to make sure your using a completed frame buffer)
  • Maybe your texture and frame buffer format are mismatched.

There is lots of other problematic things that might be your answer, but I must see your code first.

And I must say something else that your way of writing geometry shader, is not very recommended, if you put code in your question i can help you with that too.

\$\endgroup\$
  • \$\begingroup\$ All right, thank you very much. I'll update my question with the geometry shader and I'll add some of the cose I use to prepare and to draw to the cubemap (it's a lot of code so I'll put only the parts regarding cubemaps handling) \$\endgroup\$ – zeb Jun 9 '16 at 13:17
  • 1
    \$\begingroup\$ Are you sure that glFlush/glFinish are necessary? I was not able to find any reference saying so. For example, stackoverflow.com/a/2143752/2752075 , opengl.org/wiki/GLAPI/glFinish and opengl.org/wiki/GLAPI/glFlush say nothing about framebuffers. \$\endgroup\$ – HolyBlackCat Jun 9 '16 at 13:51
  • \$\begingroup\$ Yeah, I don't think that glFlush and glFinish are the source of my problem. \$\endgroup\$ – zeb Jun 9 '16 at 17:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.