gluPerspective
BlitzMax Forums/OpenGL Module/gluPerspective
| ||
gluPerspective() takes the vertical fov, aspect, and near and far view ranges. I want the viewport to always use the same horizontal fov, and adjust the vertical fov so that it isn't stretched, regardless of the viewport height. Viewport width=1024 Viewport height=768 desired horizontal fov=90 degrees The aspect is the width divided by the height, which is 1024/768=1.33333333. I tried this: gluPerspective 90.0/1.3333333,1.3333333,near,far But this did not give me a little less than 90 degrees view in the horizontal direction. The only way I could get a perfect 90-degree view in the horizontal direction was like this: gluPerspective 90.0/1.3333333,1.5,near,far What's going on here? I noticed that 90.0/1.3333333/1.5=45.0, which might be significant. Then I tried using glFrustum: glfrustum -nearrange/zoom,nearrange/zoom,-nearrange/aspect/zoom,nearrange/aspect/zoom,nearrange,farrange When zoom=1.0, I get a perfect 90-degree fov in the horizontal direction. However, when I try changing zoom to 2.0, for a 45-degree fov, I get a somewhat larger fov in the horizontal direction (approximately 50-60 degrees). |
| ||
Well, after drawing it out on paper I saw that this takes a little trig to do. I have never seen a mention of precision zooming with the frustum, so I will post my solution here. With zoom=1.0, the horizontal fov will be 90.0. With a zoom of 2.0, the horizontal fov will be 45.0 degrees. The vertical fov is dependent on viewport height. The aspect is the viewport width divided by the viewport height: zoom#=2.0 // for a 45-degree fov. Use 1.0 for 90 degrees. aspect#=width#/height# theta#=Tan(45.0/zoom#) // temporary angle value glfrustum -nearrange#*theta#,nearrange#*theta#,-nearrange#/aspect#*theta#,nearrange#/aspect#*theta#,nearrange#,farrange# |
| ||
Here's an alternative to gluPerspective that takes the fovx as a parameter instead of the fovy. All other params stay the same.Function Perspective( fovx:Float, ratio:Float, near:Float, far:Float ) Local x:Float=Tan(fovx/2.0)*near Local y:Float=x/ratio glFrustum -x,x,-y,y,near,far End FunctionHope it's of some use to you. |
| ||
Here's manual versions of gluPerspective (methods in my camera type), glh.. sets the FOV horizontally, glv vertically. Might be of help.Method glhPerspective() ' Local xmin:Double, xmax:Double, ymin:Double, ymax:Double Local m:Double[16] xmax = zNear * Tan(fov*.5) xmin = -xmax ymin = xmin / aspect ymax = xmax / aspect m[0] = (2 * zNear) / (xmax - xmin) m[5] = (2 * zNear) / (ymax - ymin) m[10]= -(zFar + zNear) / (zFar - zNear) m[2] = (xmax + xmin) / (xmax - xmin) m[6] = (ymax + ymin) / (ymax - ymin) m[11] = -1 m[14] = -(2 * zFar * zNear) / (zFar - zNear); glMultMatrixd m End Method Method glvPerspective() Local xmin:Double, xmax:Double, ymin:Double, ymax:Double Local m:Double[16] xmax = zNear * Tan(fov*.5) xmin = -xmax ymin = xmin / aspect ymax = xmax / aspect m[0] = (2 * zNear) / (xmax - xmin) m[5] = (2 * zNear) / (ymax - ymin) m[10]= -(zFar + zNear) / (zFar - zNear) m[2] = (xmax + xmin) / (xmax - xmin) m[6] = (ymax + ymin) / (ymax - ymin) m[11] = -aspect m[14] = -(2 * zFar * zNear) / (zFar - zNear); glMultMatrixd m End Method |
| ||
I figured it out for glfrustum, which I will just stick with. The zoom component is particularly important, and I recommend anyone setting up and opengl camera use what I write in my second post. |