cube map help please

I am playing around with cube maps. For starters I wanted to implement a skybox. I’ve checked a previous post and wrote code that should work, according to that post, but it doesnt. Some code follows:

Here I build the VBO contents:


static GLfloat const mc(1/M_SQRTTHREE);

GLfloat GLSkyboxa::vertices[][3] = {
  {-mc, -mc,  mc}, {mc, -mc,  mc}, {mc, mc,  mc}, {-mc, mc,  mc},
  {-mc, -mc, -mc}, {mc, -mc, -mc}, {mc, mc, -mc}, {-mc, mc, -mc}
  };

GLfloat GLSkyboxa::texcoords[][3] = {
  {-mc, -mc,  mc}, {mc, -mc,  mc}, {mc, mc,  mc}, {-mc, mc,  mc},
  {-mc, -mc, -mc}, {mc, -mc, -mc}, {mc, mc, -mc}, {-mc, mc, -mc}
  };

GLbyte GLSkyboxa::indices[] = { 0, 1, 4, 5, 7, 6, 2, 5, 2, 1, 2, 0, 3, 4, 3,
  7, 2 };

and setup it up here, please ignore the debug calls:


  glGenVertexArrays(1, &array_object);
  glGenBuffers(1, &buffer_object);

  gl_check_error();

  glBindVertexArray(array_object);
  GL_DEBUG();

  glBindBuffer(GL_ARRAY_BUFFER, buffer_object);
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer_object);
  GL_DEBUG();

  glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
  glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0,
    sizeof(vertices) + static_cast<GLbyte const*>(0));
  GL_DEBUG();

  glEnableVertexAttribArray(0);
  glEnableVertexAttribArray(1);
  GL_DEBUG();

  gl_check_error();

  glBufferData(GL_ARRAY_BUFFER, sizeof(vertices) + sizeof(texcoords) +
    sizeof(indices), 0, GL_STATIC_DRAW);
  GL_DEBUG();

  glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
  GL_DEBUG();

  glBufferSubData(GL_ARRAY_BUFFER, sizeof(vertices), sizeof(texcoords),
    texcoords);
  GL_DEBUG();

  glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, sizeof(vertices) +
    sizeof(texcoords), sizeof(indices), indices);
  GL_DEBUG();

  gl_check_error();

Then it’s off to rendering, the texture variable is a wrapper object wrapping cube map textures.


void GLSkyboxa::render(enum BoxType r)
{
  texture.bind();

  glBindVertexArray(array_object);
  GL_DEBUG();

  switch (r)
  {
    case FULL:
    {
      glDrawElements(GL_TRIANGLE_STRIP, 17, GL_UNSIGNED_BYTE,
        sizeof(vertices) + sizeof(texcoords) + static_cast<GLbyte const*>(0));
      GL_DEBUG();

      break;
    }
    case HALF:
    {
      glDrawElements(GL_TRIANGLE_STRIP, 15, GL_UNSIGNED_BYTE,
        sizeof(vertices) + sizeof(texcoords) + 2 +
        static_cast<GLbyte const*>(0));
      GL_DEBUG();

      break;
    }
  }
}

The vertex shader:


uniform mat4 model_view_matrix;
uniform mat4 projection_matrix;

in vec3 in_position;
in vec3 in_texcoords;

varying vec3 out_texcoords;

void main()
{
  out_texcoords = in_texcoords;

  gl_Position = projection_matrix * model_view_matrix *
    vec4(in_position, 1);
}

The fragment shader:


uniform samplerCube texture0; 

in vec3 out_texcoords;

void main()
{
  gl_FragColor = vec4(1, 1, 1, 1) - textureCube(texture0, out_texcoords);

// difference because otherwise all faces stay black
}

Now for my own debug findings. I only get a white cube out of my program. Texture coordinates are interpolated across the triangles (I checked by setting gl_FragColor = out_texcoords). I’ve verified that the cube texture faces do not contain only black textels. Maybe my misunderstanding of texture coordinates is at fault:

  • I don’t know how the texture coordinate vector is interpolated across the triangles (perhaps linearly?)

  • what does the spec specify, when it says:

At texture generation time, the interpolated per-fragment (s,t,r) selects one cube face 2D image based on the largest magnitude coordinate (the major axis).

By magnitude, does it mean ‘absolute value’ or maybe something else?

Of course GL does not return any error, but the cube is all white.

Are you sure you created the cubemap properly? Make sure it doesn’t use MIPMAP_LINEAR filtering if you don’t upload the mipmaps with glTexImage2d.

All I can say is that there aren’t zeros in the 6 face textures, the GL does not return any errors to me and I did not upload any mipmaps for it at all (only level 0 textures).

OMG, it works… The problem was that my code did not load ALL the necessary 6 cube faces and nvidia’s GL consequently did not allow meaningful sampling (I only got zeros).

Anyway, loading a cube texture out of a 2D texture now works.