Frustum Question - I'm in a little problem
Hi all!
- I do the following with OpenGL:
gluPerspective(45.0f,(GLfloat)256.0/(GLfloat)192.0,0.1f,100.0f);
- So from that you should know:
- My Height Angle is 45 degrees
- Screen Width is 256
- screen Height is 192
- Near plane at z = 0.1
- Far plane is at z = 100.0
- my question is: How do I gather all of this data to calculate
the frustum's planes?
I'm looking for the real calculus equations, and not by extracting
data from Projection and ModelView matrices like most tutorials show.
- question number 2:
Not too long ago I stumbled with this code for Frustum calculation:
look at it and please answer, how can I modify it so it will take
into consideration the Height angle of FOV of my choise,
so it will have compatiability with openGL' gluPerspective,
or how can I make perspective of OpenGL that will have similar
calculus as this code.
I know I'm a bit confused, but a good explanation of the following calculus, and
especially on why it doesn't work like OpenGL does with constant angle would
be helpful.
#define Screen_Width 256
#define Screen_Height 192
double fieldofview = 2.0;
double xscreenscale = Screen_Width / 2;
double yscreenscale = Screen_Height / 2;
double maxscale = max(xscreenscale , yscreenscale );
void SetUpFrustum(void)
{
double angle, s, c;
point_t normal;
angle = atan(2.0 / fieldofview * maxscale / xscreenscale);
s = sin(angle);
c = cos(angle);
// Left clip plane
normal.v[0] = s;
normal.v[1] = 0;
normal.v[2] = c;
SetWorldspaceClipPlane(&normal, &frustumplanes[0]);
// Right clip plane
normal.v[0] = -s;
SetWorldspaceClipPlane(&normal, &frustumplanes[1]);
angle = atan(2.0 / fieldofview * maxscale / yscreenscale);
s = sin(angle);
c = cos(angle);
// Bottom clip plane
normal.v[0] = 0;
normal.v[1] = s;
normal.v[2] = c;
SetWorldspaceClipPlane(&normal, &frustumplanes[2]);
// Top clip plane
normal.v[1] = -s;
SetWorldspaceClipPlane(&normal, &frustumplanes[3]);
}
anyaway, thanks in advance.
your help is important
I'm currently using a derivation of this same function in a project (original code by M. Abrash). The height angle is determined by "yscreenscale" which is vertical_resolution / fieldofview. As you change the vertical screen size, this function will calculate the proper frustum planes. It works great.
Here's what my function looks like...
void SetUpFrustum(void)
{
Flt xangle, yangle, s, c;
Vec normal;
xangle = atan(2.0 / fieldofview * maxscale / xscreenscale );
s = sin(xangle);
c = cos(xangle);
normal[0] = s;
normal[1] = 0;
normal[2] = c;
VecCopy(normal, frustumplanes[0]);
normal[0] = -s;
VecCopy(normal, frustumplanes[1]);
yangle = atan(2.0 / fieldofview * maxscale / yscreenscale );
s = sin(yangle);
c = cos(yangle);
normal[0] = 0;
normal[1] = -s;
normal[2] = c;
VecCopy(normal, frustumplanes[2]);
normal[1] = s;
VecCopy(normal, frustumplanes[3]);
MakeVector(0.0, 0.0, frontPlaneDistance, frustumplanes[4]);
}
Here's what my function looks like...
void SetUpFrustum(void)
{
Flt xangle, yangle, s, c;
Vec normal;
xangle = atan(2.0 / fieldofview * maxscale / xscreenscale );
s = sin(xangle);
c = cos(xangle);
normal[0] = s;
normal[1] = 0;
normal[2] = c;
VecCopy(normal, frustumplanes[0]);
normal[0] = -s;
VecCopy(normal, frustumplanes[1]);
yangle = atan(2.0 / fieldofview * maxscale / yscreenscale );
s = sin(yangle);
c = cos(yangle);
normal[0] = 0;
normal[1] = -s;
normal[2] = c;
VecCopy(normal, frustumplanes[2]);
normal[1] = s;
VecCopy(normal, frustumplanes[3]);
MakeVector(0.0, 0.0, frontPlaneDistance, frustumplanes[4]);
}
thanks!
but you still didn't answer my question.
I need compitability between OpenGL's perspective to the frustum generation code
cheers, tomer
but you still didn't answer my question.
I need compitability between OpenGL's perspective to the frustum generation code
cheers, tomer
I wrote and tested some simple code to allow passing the viewing angle in degrees to SetUpFrustum(). Does this help at all?
#define degtorad(a) (((double)(a)) * 3.14159/180.0)
void SetUpFrustum(double angle)
{
fieldofview = 2.0 * tan( degtorad(angle) / 2.0);
...
}
#define degtorad(a) (((double)(a)) * 3.14159/180.0)
void SetUpFrustum(double angle)
{
fieldofview = 2.0 * tan( degtorad(angle) / 2.0);
...
}
Here my code to create a frustum object from 2 different approaches (I also have one for perspective correct stereo, but I don't think you care about that :):
The main idea is to convert to l,r,t,b,n,f format first. That's much more powerful and (IMO) easier to understand than the FOV version...
You can use glFrustum to create a matrix from the l,r,t,b,n,f values of the frustum.
The relevant portions of my plane class:
Note that my plane class maintains two different (redundant) representation of a plane: base/normal and plane equation (a,b,c,d) I don't know which one you need.
Anyway, you should the solution to your problem from these code snippets...
Tom
/** * calculate frustum from FOV/aspect **/void afrustum::setValues(float fov, float aspect, float n, float f){ float t = n * (float)tan(DEG2RAD(fov) * 0.5); float b = -t; float l = b * aspect; float r = t * aspect; setValues(t, b, l, r, n, f);};/** * calculate frustum from tblrnf **/void afrustum::setValues(float t, float b, float l, float r, float n, float f){ top = t; bottom = b; left = l; right = r; nr = n; fr = f; n = -n; f = -f; left_p = aplane(avector(0.0f, 0.0f, 0.0f), avector(l , b , n), avector(l , t , n)); right_p = aplane(avector(0.0f, 0.0f, 0.0f), avector(r , b , n), avector(r , t , n)); top_p = aplane(avector(0.0f, 0.0f, 0.0f), avector(l , t , n), avector(r , t , n)); bottom_p = aplane(avector(0.0f, 0.0f, 0.0f), avector(l , b , n), avector(r , b , n)); near_p = aplane(avector(0.0f, 0.0f, n), avector(1.0f, 0.0, n), avector(0.0f, 1.0f, n)); far_p = aplane(avector(0.0f, 0.0f, f), avector(1.0f, 0.0, f), avector(0.0f, 1.0f, f));};
The main idea is to convert to l,r,t,b,n,f format first. That's much more powerful and (IMO) easier to understand than the FOV version...
You can use glFrustum to create a matrix from the l,r,t,b,n,f values of the frustum.
The relevant portions of my plane class:
float a,b,c,d;avector base, normal, pt1, pt2;inline void get_equation(){ a = normal.x; b = normal.y; c = normal.z; d = -(a * base.x + b * base.y + c * base.z);};inline void get_normal(){ // the ^ operator is the cross product... normal = (pt1 - base) ^ (base - pt2); normal.normalize();};/** * create aplane from base point + normal vector * * @param b base vertex of the plane (point on the plane) * @param n normal vector of the plane **/aplane(avector b, avector n){ base = b; normal = n; pt1 = avector(); pt2 = avector(); normal.normalize(); get_equation();};/** * create aplane from base point + 2 vectors on the plane * * @param b base vertex of the plane (point on the plane) * @param p1 first plane vector (vector from b parallel to the plane) * @param p2 second plane vactor (vector on the plane, perpendicular to p1) **/aplane(avector b, avector p1, avector p2){ base = b; pt1 = p1; pt2 = p2; get_normal(); get_equation();};
Note that my plane class maintains two different (redundant) representation of a plane: base/normal and plane equation (a,b,c,d) I don't know which one you need.
Anyway, you should the solution to your problem from these code snippets...
Tom
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement