You’re on the right track, but it’s important to start with the “default” GL view for this to work. Think of it as transforming the frustum with the camera, so that they’re attached.
The camera matrix itself is simply the modelview matrix after all the camera transforms have been applied. You can grab it with glGetFloatv( GL_MODELVIEW_MATRIX, MV ), for example.
Here’s one way to create a frustum in the default GL view:
void createFrustum( float FOV, float zNear, float zFar, float MV[16], Plane frustum[6] )
{
// Default frustum looking down -z axis
float a = FOV * M_PI / 360;
float c = cosf(a);
float s = sinf(a);
Plane planes[4] =
{
Plane( +c, +0, -s, +0 ), // Left
Plane( -c, +0, -s, +0 ), // Right
Plane( +0, +c, -s, +0 ), // Bottom
Plane( +0, -c, -s, +0 ), // Top
};
// Transform into world-space
for( int i = 0; i < 4; i++ )
frustum[i] = transformFrustumPlane( MV, planes[i] );
}
And here’s a way to transform the plane into world-space:
Plane transformFrustumPlane( float M[16], Plane P )
{
float x = P.x*M[0] + P.y*M[1] + P.z*M[2];
float y = P.x*M[4] + P.y*M[5] + P.z*M[6];
float z = P.x*M[8] + P.y*M[9] + P.z*M[10];
float w = P.x*M[12]+ P.y*M[13]+ P.z*M[14] + P.w;
return Plane( x, y, z, w );
}
There’s a section in the Red Book that talks about transforming normals and planes if your interested in some of the math behind this. Normally you need to transform normals with the inverse transpose of the matrix that transforms points. But in the case of the camera matrix (already the inverse of the matrix that orients the camera in the world), we can take a short-cut, or two.
I store my planes as Ax + By + Cz = D, so I hope I didn’t miss a sign somewhere after converting.
Hope this helps.