Hi all, I’ve gone through Mr Eric Lengyel’s tutorial on Oblique near-plane clipping, but I can’t get it working. Here’s what I’m doing:
void HT_Graphics::ModifyProjectionMatrix(CVector4& clipPlane)
{
float matrix[16];
CVector4 q;
float mat1[16];
float mat2[16];
glGetFloatv(GL_MODELVIEW_MATRIX, mat1);
CMatrix::mat4_inverseOrth(mat2, mat1);
CMatrix::mat4_transpose(mat1, mat2);
float xplane[4];
CMatrix::plane_transform(xplane, clipPlane.v, mat1);
CVector4 resVec(xplane[0], xplane[1], xplane[2], xplane[3]);
// Grab the current projection matrix from OpenGL
glGetFloatv(GL_PROJECTION_MATRIX, matrix);
// Calculate the clip-space corner point opposite the clipping plane
// as (sgn(clipPlane.x), sgn(clipPlane.y), 1, 1) and
// transform it into camera space by multiplying it
// by the inverse of the projection matrix
q.x = (sgn(resVec.x) + matrix[8]) / matrix[0];
q.y = (sgn(resVec.y) + matrix[9]) / matrix[5];
q.z = -1.0f;
q.w = (1.0f + matrix[10]) / matrix[14];
// Calculate the scaled plane vector
CVector4 c = resVec * (2.0f / (resVec * q));
// Replace the third row of the projection matrix
matrix[2] = c.x;
matrix[6] = c.y;
matrix[10] = c.z + 1.0f;
matrix[14] = c.w;
// Load it back into OpenGL
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(matrix);
glMatrixMode(GL_MODELVIEW);
}
static inline void plane_transform(float* dst, float* src, float* matrix)
{
#define M(ROW,COL) matrix[((COL)*4)+(ROW)]
dst[0] = src[0] * M(0,0) + src[1] * M(1,0) + src[2] * M(2,0) + src[3] * M(3,0);
dst[1] = src[0] * M(0,1) + src[1] * M(1,1) + src[2] * M(2,1) + src[3] * M(3,1);
dst[2] = src[0] * M(0,2) + src[1] * M(1,2) + src[2] * M(2,2) + src[3] * M(3,2);
dst[3] = src[0] * M(0,3) + src[1] * M(1,3) + src[2] * M(2,3) + src[3] * M(3,3);
#undef M
}
static inline void mat4_transpose(float* dst, float* src)
{
dst[0]=src[0];
dst[1]=src[4];
dst[2]=src[8];
dst[3]=src[12];
dst[4]=src[1];
dst[5]=src[5];
dst[6]=src[9];
dst[7]=src[13];
dst[8]=src[2];
dst[9]=src[6];
dst[10]=src[10];
dst[11]=src[14];
dst[12]=src[3];
dst[13]=src[7];
dst[14]=src[11];
dst[15]=src[15];
}
static inline void mat4_inverseOrth(float* dst, float* src)
{
dst[0]=src[0];
dst[1]=src[4];
dst[2]=src[8];
dst[3]=0.0f;
dst[4]=src[1];
dst[5]=src[5];
dst[6]=src[9];
dst[7]=0.0f;
dst[8]=src[2];
dst[9]=src[6];
dst[10]=src[10];
dst[11]=0.0f;
dst[12]=-src[12]*src[0]-src[13]*src[1]-src[14]*src[2];
dst[13]=-src[12]*src[4]-src[13]*src[5]-src[14]*src[6];
dst[14]=-src[12]*src[8]-src[13]*src[9]-src[14]*src[10];
dst[15]=1.0f;
}
...
isReflection = true;
framesComputeReflection = 0;
// *** calculate reflection ***********************************************************
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frameBufferReflection);
glViewport(0,0, REFLECTION_TEXTURE_SIZE, REFLECTION_TEXTURE_SIZE);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(pos.x, pos.y, pos.z,
view.x, view.y, view.z,
up.x, up.y, up.z);
glPushMatrix();
if(pos.y > waterHeight)
{
glTranslatef(0.0f, waterHeight * 2.0f, 0.0f);
glScalef(1.0, -1.0, 1.0);
glCullFace(GL_FRONT);
ModifyProjectionMatrix(CVector4(0.0, 1.0, 0.0, -waterHeight));
// render scene to reflection texture
HT_Graphics::SetActiveShaderProgram(HT_Constants::SH_NONE);
m_skybox->Render(pos.x, pos.y, pos.z, engineconfig->farPlane-10.0f, engineconfig->farPlane-10.0f, engineconfig->farPlane-10.0f);
if(engineconfig->reflectionsFull)
{
m_mapI->Render();
}
ResetProjectionMatrix();
glCullFace(GL_BACK);
}
else
{
ModifyProjectionMatrix(CVector4(0.0, 1.0, 0.0, waterHeight));
if(engineconfig->reflectionsFull)
{
m_mapI->Render();
}
ResetProjectionMatrix();
}
glPopMatrix();
glBindTexture(GL_TEXTURE_2D, reflTex);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
...
I don’t know what’s gone wrong
What I do is I pass the clipping plane equation as world coordinates (as for the glClipPlane function), and I transform the coordinates to eye coords using inverse transpose modelview matrix. Then I modify the projection matrix accordingly as described in Mr Lengyel’s article.
Here’s a shot of the problem
The plane still seems to “follow” the camera, and doesn’t clip along the surface of the water (the brick wall is actually a “reflection” of the bottom of the pool, and the black thing is a clipped region)
Anybody got a clue?
Thanks a lot
HardTop