Frustum Question - I'm in a little problem

Started by
5 comments, last by Sneftel 18 years, 8 months ago
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
Advertisement
there is no calculus here, only trig. I'll post a derivation once I get back from work.

Tim
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]);
}

thanks!

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);
...
}

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 :):

/** * 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
Please don't crosspost. One post is sufficient.

This topic is closed to new replies.

Advertisement