Reputation: 31
Vector3d nearC(0,0,0 -w);
Vector3d farC(0,0,0-x);
double width = y/2;
double height = z/2;
double angleOfHeight = atan(height/w);
double angleOfWidth = atan(width/w);
double adjustedHeight = tan(angleOfHeight) * x;
double adjustedWidth = tan(angleOfWidth) * x;
nearC[0] - width, nearC[1] - height, nearC[2]
nearC[0] - width, nearC[1] + height, nearC[2]
nearC[0] + width, nearC[1] + height, nearC[2]
nearC[0] + width, nearC[1] - height, nearC[2]
farC[0] - adjustedWidth, farC[1] - adjustedHeight, farC[2]
farC[0] - adjustedWidth, farC[1] + adjustedHeight, farC[2]
farC[0] + adjustedWidth, farC[1] + adjustedHeight, farC[2]
farC[0] + adjustedWidth, farC[1] - adjustedHeight, farC[2]
Above is my frustum in view coordinates. View Matrix is:
0 0 -1 0
0 1 0 -1
1 0 0 -10
0 0 0 1
All of it is right, we have a sheet.
I can't for the life of me figure how to get that frustum in canonical viewing volume. I've run through every perspective projection I could find. Current is this:
s, 0, 0, 0,
0, s, 0, 0,
0, 0, -(f+ne)/(f-ne), 2*f*ne/(f-ne),
0, 0, 1, 0;
double s = 1/tan(angleOfView * 0.5 * M_PI / 180);
I'm missing a step or something, right? Or a few steps?
Sorry to sound so hopeless now, been spinning wheels a while on this.
Any help appreciated.
Upvotes: 1
Views: 614
Reputation: 51835
Lest start with the perspective projection. The common way in old GL is to use gluPerspective
.
for that we need znear,zfar,FOV
and aspect ratio of view. For more info see:
Calculating the perspective projection matrix according to the view plane
I am used to use FOVx (viewing angle in x
axis). To compute that you need to look at your frustrum from above looking at xz plane (in camera space):
so:
tan(FOVx/2) = znear_width / 2*focal_length
FOVx = 2*atan(znear_width / 2*focal_length)
the focal length can be computed by computing the intersection of frustrum edge lines. Or by using triangle similarity. The second is easier to write:
zfar_width/2*(|zfar-znear|+focal_length) = znear_width/2*(focal_length)
zfar_width/(|zfar-znear|+focal_length) = znear_width/(focal_length)
focal_length = (|zfar-znear|+focal_length)*znear_width/zfar_width
focal_length - focal_length*znear_width/zfar_width = |zfar-znear|*znear_width/zfar_width
focal_length*(1-(znear_width/zfar_width)) = |zfar-znear|*znear_width/zfar_width
focal_length = (|zfar-znear|*znear_width/zfar_width) / (1-(znear_width/zfar_width))
and that is all we need so:
focal_length = (|zfar-znear|*znear_width/zfar_width) / (1-(znear_width/zfar_width))
FOVx = 2*atan(znear_width / 2*focal_length)
FOVx*=180.0/M_PI; // convert to degrees
aspect=znear_width/znear_height;
gluPerspective(FOVx/aspect,aspect,znear,zfar);
just be aware of that |zfar-znear|
is perpendicular distance between the planes !!! So if you do not have axis aligned ones then you need to compute that using dot product and normal ...
Upvotes: 2