Water reflections

I’ve a problem to make reflective water with render to texture. The problem is that the reflected cube isn’t under the original cube but it’s translated and rotated of some units. Can anyone tell me why this happens?

Here’s the code:

void CreateBox(int textureID, float x, float y, float z, float width,
float height, float length, float uscale, float vscale)
{
glEnable( GL_TEXTURE_2D );
if(textureID >= 0)
glBindTexture(GL_TEXTURE_2D, texture[textureID]);

// This centers the box around (x, y, z)
x = x - width / 2;
y = y - height / 2;
z = z - length / 2;

// Start drawing the side as a QUAD
glBegin(GL_QUADS);

// Assign the texture coordinates and vertices for the BACK Side
glTexCoord2f(0.0f, 0.0f); glVertex3f(x, y, z);
glTexCoord2f(0.0f, vscale); glVertex3f(x, y + height, z);
glTexCoord2f(uscale, vscale); glVertex3f(x + width, y + height, z);
glTexCoord2f(uscale, 0.0f); glVertex3f(x + width, y, z);

// Assign the texture coordinates and vertices for the FRONT Side
glTexCoord2f(uscale, 0.0f); glVertex3f(x, y, z + length);
glTexCoord2f(uscale, vscale); glVertex3f(x, y + height, z + length);
glTexCoord2f(0.0f, vscale); glVertex3f(x + width, y + height, z + length);
glTexCoord2f(0.0f, 0.0f); glVertex3f(x + width, y, z + length);

// Assign the texture coordinates and vertices for the BOTTOM Side
glTexCoord2f(uscale, 0.0f); glVertex3f(x, y, z);
glTexCoord2f(uscale, vscale); glVertex3f(x, y, z + length);
glTexCoord2f(0.0f, vscale); glVertex3f(x + width, y, z + length);
glTexCoord2f(0.0f, 0.0f); glVertex3f(x + width, y, z);

// Assign the texture coordinates and vertices for the TOP Side
glTexCoord2f(uscale, vscale); glVertex3f(x, y + height, z);
glTexCoord2f(uscale, 0.0f); glVertex3f(x, y + height, z + length);
glTexCoord2f(0.0f, 0.0f); glVertex3f(x + width, y + height, z + length);
glTexCoord2f(0.0f, vscale); glVertex3f(x + width, y + height, z);

// Assign the texture coordinates and vertices for the LEFT Side
glTexCoord2f(uscale, 0.0f); glVertex3f(x, y, z);
glTexCoord2f(0.0f, 0.0f); glVertex3f(x, y, z + length);
glTexCoord2f(0.0f, vscale); glVertex3f(x, y + height, z + length);
glTexCoord2f(uscale, vscale); glVertex3f(x, y + height, z);

// Assign the texture coordinates and vertices for the RIGHT Side
glTexCoord2f(0.0f, 0.0f); glVertex3f(x + width, y, z);
glTexCoord2f(uscale, 0.0f); glVertex3f(x + width, y, z + length);
glTexCoord2f(uscale, vscale); glVertex3f(x + width, y + height, z + length);
glTexCoord2f(0.0f, vscale); glVertex3f(x + width, y + height, z);

// Stop drawing quads
glEnd();
}

void RenderToWaterTexture ( void )
{
double ClipPlane[] = { 0, 1, 0, 0 };

glViewport( 0, 0, 512, 512 );

glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glLoadIdentity();

gluLookAt( 0, 4, 15, 0, 0, 0, 0, 1, 0 );

glScalef( 1, -1, 1 );

glEnable( GL_CLIP_PLANE0 );
glClipPlane( GL_CLIP_PLANE0, ClipPlane );
CreateBox( 2, 0, 5, 0, 5, 5, 5, 1, 1 );
glDisable( GL_CLIP_PLANE0 );

glBindTexture( GL_TEXTURE_2D, texture[0] );
glCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, 512, 512 );

glViewport( 0, 0, 800, 600 );
}

void DrawWater ( void )
{
glActiveTextureARB( GL_TEXTURE0_ARB );
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, texture[0] );

glActiveTextureARB( GL_TEXTURE1_ARB );
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, texture[1] );

glBegin( GL_QUADS );
glMultiTexCoord2fARB( GL_TEXTURE0_ARB, 0, 0 );
glMultiTexCoord2fARB( GL_TEXTURE1_ARB, 0, 0 );
glVertex3f( -10, 0, -10 );

glMultiTexCoord2fARB( GL_TEXTURE0_ARB, 1, 0 );
glMultiTexCoord2fARB( GL_TEXTURE1_ARB, 1, 0 );
glVertex3f( 10, 0, -10 );

glMultiTexCoord2fARB( GL_TEXTURE0_ARB, 1, 1 );
glMultiTexCoord2fARB( GL_TEXTURE1_ARB, 1, 1 );
glVertex3f( 10, 0, 10 );

glMultiTexCoord2fARB( GL_TEXTURE0_ARB, 0, 1 );
glMultiTexCoord2fARB( GL_TEXTURE1_ARB, 0, 1 );
glVertex3f( -10, 0, 10 );
glEnd();

glActiveTextureARB( GL_TEXTURE1_ARB );
glDisable( GL_TEXTURE_2D );

glActiveTextureARB( GL_TEXTURE0_ARB );
glDisable( GL_TEXTURE_2D );
}

Forgive me if I get this wrong, as I couldn’t be arsed reading your code very carefully, but you probably want to load the inverse upper 3x3 of the modelview matrix into your texture matrix.

float m[16];
glGetFloatfv(GL_MODELVIEW, &m);
float im[16];
im[0]=m[0];
im[1]=m[4];
im[2]=m[8];
…etc.etc.etc.
im[12]=im[13]=im[14]=0.0f;

glMatrixMode(GL_TEXTURE);
glLoadMatrixf(im);

forgive me if some of the syntax is wrong + ideally you wouldn’t read the modelview matrix back from OpenGL, as you should have a current copy of it yourself in your app, but you probably haven’t.