Cubemapped skybox problem

Hi,

I am rendering a skybox using a cubemap. Since the positive and negative y faces are oriented strangely (i.e., mirrored and flipped) compared to the other x and z faces, my rendering code manipulates the glTexCoord3f() calls to fix this. The skybox renders correctly on my WinXP box with a 9700Pro (cat 4.5 drivers). However I notice intermittent white dots appearing along some of the seams between cube faces. Since I am already using GL_CLAMP_TO_EDGE for the cubemap I am a bit puzzled as to why this is happening. I tested it on another WinXP box with a Geforce2 (old det 43 driver) and the white dots were not as noticeable – but they were still present. Since this problem is appearing on both machines I’m pretty sure that I’ve screwed up my code somewhere :smiley:

Here’s the code I use to render my skybox. I’ve already bound the cubemap elsewhere to texture unit zero.

 
GLvoid RenderSkybox(GLfloat width, GLfloat height, GLfloat depth)
{
    GLfloat dx = width * 0.5f;
    GLfloat dy = height * 0.5f;
    GLfloat dz = depth * 0.5f;

    glPushAttrib(GL_FOG_BIT | GL_DEPTH_BUFFER_BIT | GL_LIGHTING_BIT);
    glDisable(GL_FOG);
    glDisable(GL_LIGHTING);
    glDisable(GL_DEPTH_TEST);

    glBegin(GL_QUADS);

    // Front (negative Z) face.
    glTexCoord3f( dx, -dy, -dz); glVertex3f(-dx, -dy, -dz);
    glTexCoord3f(-dx, -dy, -dz); glVertex3f( dx, -dy, -dz);
    glTexCoord3f(-dx,  dy, -dz); glVertex3f( dx,  dy, -dz);
    glTexCoord3f( dx,  dy, -dz); glVertex3f(-dx,  dy, -dz);

    // Back (positive Z) face.
    glTexCoord3f(-dx, -dy,  dz); glVertex3f( dx, -dy,  dz);
    glTexCoord3f( dx, -dy,  dz); glVertex3f(-dx, -dy,  dz);
    glTexCoord3f( dx,  dy,  dz); glVertex3f(-dx,  dy,  dz);
    glTexCoord3f(-dx,  dy,  dz); glVertex3f( dx,  dy,  dz);

    // Bottom (negative Y) face.
    glTexCoord3f( dx, -dy, -dz); glVertex3f(-dx, -dy,  dz);
    glTexCoord3f(-dx, -dy, -dz); glVertex3f( dx, -dy,  dz);
    glTexCoord3f(-dx, -dy,  dz); glVertex3f( dx, -dy, -dz);
    glTexCoord3f( dx, -dy,  dz); glVertex3f(-dx, -dy, -dz);

    // Top (positive Y) face.
    glTexCoord3f( dx,  dy,  dz); glVertex3f(-dx,  dy, -dz);
    glTexCoord3f(-dx,  dy,  dz); glVertex3f( dx,  dy, -dz);
    glTexCoord3f(-dx,  dy, -dz); glVertex3f( dx,  dy,  dz);
    glTexCoord3f( dx,  dy, -dz); glVertex3f(-dx,  dy,  dz);

    // Left (negative X) face.
    glTexCoord3f( dx, -dy,  dz); glVertex3f( dx, -dy, -dz);
    glTexCoord3f( dx, -dy, -dz); glVertex3f( dx, -dy,  dz);
    glTexCoord3f( dx,  dy, -dz); glVertex3f( dx,  dy,  dz);
    glTexCoord3f( dx,  dy,  dz); glVertex3f( dx,  dy, -dz);

    // Right (positive X) face.
    glTexCoord3f(-dx, -dy, -dz); glVertex3f(-dx, -dy,  dz);
    glTexCoord3f(-dx, -dy,  dz); glVertex3f(-dx, -dy, -dz);
    glTexCoord3f(-dx,  dy,  dz); glVertex3f(-dx,  dy, -dz);
    glTexCoord3f(-dx,  dy, -dz); glVertex3f(-dx,  dy,  dz);

    glEnd();
    glPopAttrib();
}

Any ideas?

Originally posted by dpoon:
Any ideas?
ill start with a question:
youre using cubemapping, so why on earth would you even bother to render a box? either draw 6 quads with 2d textures or one quad with cubemapping. but i dont see the point in doing both which seems to be nothing but pointless extra work per face.

glEnable(GL_TEXTURE_CUBE_MAP_ARB);
/*no need to clear color buffer if we draw all over it (yes, unlike clearing the depth buffer this does make a difference on my machine.. in fact, drawing the quad and clearing the color buffer seem to take pretty much the same time)*/
glDisable(GL_DEPTH_TEST);
glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, SkyCube);
	
Vector3 vec(Camera.Forward), v;
Vector3 up(Camera.Up);
//yFac = half the frustum height at z=1
up*=Camera.yFac;
Vector3 right(Camera.Right);
//same for width.. point is to have a screen sized quad
right*=Camera.xFac;

glBegin(GL_QUADS);
/*confused? Vector3 has a float* cast operation so it can be used with all the x3fv functions*/
glTexCoord3fv(v=vec-right+up);
glVertex3fv(v+Camera.Position);
glTexCoord3fv(v=vec-right-up);
glVertex3fv(v+Camera.Position);
glTexCoord3fv(v=vec+right-up);
glVertex3fv(v+Camera.Position);
glTexCoord3fv(v=vec+right+up);
glVertex3fv(v+Camera.Position);
glEnd();

glEnable(GL_DEPTH_TEST);

guessing from your code you should be fine if you
a) forget drawing anything but the front face
b) set the modelview to identity
c) multiply <dx,dy,dz> with the cameras transformation matrix (minus translation) for texture coords.
or as alternative:
multiply the texture matrix with the cameras matrix minus the translation

so a cleaned up version would be

glEnable(GL_TEXTURE_CUBE_MAP_ARB);
glDisable(GL_DEPTH_TEST);
glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, SkyCube);
		
glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_TEXTURE);
glLoadMatrixf(Camera.Right);

glBegin(GL_QUADS);
/*4d texcoords to force w=0, so we dont need to remove the translation part from the cam matrix*/
glTexCoord4f(-Camera.xFac, Camera.yFac, 1, 0);
glVertex3f(-Camera.xFac, Camera.yFac, 1);
glTexCoord4f(-Camera.xFac, -Camera.yFac, 1, 0);
glVertex3f(-Camera.xFac, -Camera.yFac, 1);
glTexCoord4f(Camera.xFac, -Camera.yFac, 1, 0);
glVertex3f(Camera.xFac, -Camera.yFac, 1);
glTexCoord4f(Camera.xFac, Camera.yFac, 1, 0);
glVertex3f(Camera.xFac, Camera.yFac, 1);
glEnd();

glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glEnable(GL_DEPTH_TEST);

Also, ensure that you have set GL_CLAMP_TO_EDGE_EXT for s and t.