summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2014-07-05 08:27:03 +0200
committerSven Gothel <[email protected]>2014-07-05 08:27:03 +0200
commitbda482e4eee76a5ba2139645682ae64dadacbc6b (patch)
tree51f67d3734276114754bff02bbde2217fc0fb797
parentf8f0f051604721bceaee214b8e5218fd47d2eb9e (diff)
Fix FloatUtil.makePerspective(..): The tan(fovy/2) shall be used, not tan(fovy), fix callers; Simplify FloatUtil.makePerspective(..FovHVHalves..)
Fix FloatUtil.makePerspective(..): The tan(fovy/2) shall be used, not tan(fovy), fix callers - This bug didn't hit (yet), since callers already performed the division (degree -> radian) by falsly claiming the passed value is in radian - where it was actually fov/2 in radians. Simplify FloatUtil.makePerspective(..FovHVHalves..) - Due to the fix above, it became pretty clear that the makeFrustum(..) method can be utilized. Simply apply all our tan-half-fov values on zNear.
-rw-r--r--src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java65
-rw-r--r--src/jogl/classes/com/jogamp/opengl/math/FovHVHalves.java39
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java13
-rw-r--r--src/jogl/classes/jogamp/opengl/ProjectFloat.java11
-rw-r--r--src/oculusvr/classes/jogamp/opengl/oculusvr/OVRUtil.java16
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/stereo/StereoDemo01.java2
6 files changed, 71 insertions, 75 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java b/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java
index 3c6a867e6..d2e535eaf 100644
--- a/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java
+++ b/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java
@@ -558,18 +558,18 @@ public final class FloatUtil {
* @param m_offset offset in given array <i>m</i>, i.e. start of the 4x4 matrix
* @param initM if true, given matrix will be initialized w/ identity matrix,
* otherwise only the frustum fields are set.
- * @param fovy angle in radians
+ * @param fovy_rad angle in radians
* @param aspect
* @param zNear
* @param zFar
* @return given matrix for chaining
*/
public static float[] makePerspective(final float[] m, final int m_off, final boolean initM,
- final float fovy, final float aspect, final float zNear, final float zFar) {
- final float top=(float)Math.tan(fovy)*zNear;
- final float bottom=-1.0f*top;
- final float left=aspect*bottom;
- final float right=aspect*top;
+ final float fovy_rad, final float aspect, final float zNear, final float zFar) {
+ final float top = tan(fovy_rad/2f) * zNear; // use tangent of half-fov !
+ final float bottom = -1.0f * top;
+ final float left = aspect * bottom;
+ final float right = aspect * top;
return makeFrustum(m, m_off, initM, left, right, bottom, top, zNear, zFar);
}
@@ -591,53 +591,12 @@ public final class FloatUtil {
*/
public static float[] makePerspective(final float[] m, final int m_offset, final boolean initM,
final FovHVHalves fovhv, final float zNear, final float zFar) {
- if( initM ) {
- // m[m_offset+0+4*0] = 1f;
- m[m_offset+1+4*0] = 0f;
- m[m_offset+2+4*0] = 0f;
- m[m_offset+3+4*0] = 0f;
-
- m[m_offset+0+4*1] = 0f;
- // m[m_offset+1+4*1] = 1f;
- m[m_offset+2+4*1] = 0f;
- m[m_offset+3+4*1] = 0f;
-
- // m[m_offset+0+4*2] = 0f;
- // m[m_offset+1+4*2] = 0f;
- // m[m_offset+2+4*2] = 1f;
- // m[m_offset+3+4*2] = 0f;
-
- m[m_offset+0+4*3] = 0f;
- m[m_offset+1+4*3] = 0f;
- // m[m_offset+2+4*3] = 0f;
- // m[m_offset+3+4*3] = 1f;
- }
-
- final float projScaleX = 2.0f / ( fovhv.left + fovhv.right );
- final float projScaleY = 2.0f / ( fovhv.top + fovhv.bottom );
- final float projOffsetX = ( fovhv.left - fovhv.right ) * projScaleX * 0.5f;
- final float projOffsetY = -1f * ( fovhv.top - fovhv.bottom ) * projScaleY * 0.5f;
-
- // Produces X result, mapping clip edges to [-w,+w]
- m[m_offset+0+4*0] = projScaleX;
- m[m_offset+0+4*2] = -1f * projOffsetX;
-
- // Produces Y result, mapping clip edges to [-w,+w] (Y=up)
- m[m_offset+1+4*1] = projScaleY;
- m[m_offset+1+4*2] = -1f * projOffsetY;
-
- // Custom Z-buffer result .. same as frustum matrix!
- m[m_offset+2+4*2] = -1.0f*(zFar+zNear)/(zFar-zNear);
- m[m_offset+2+4*3] = -2.0f*(zFar*zNear)/(zFar-zNear);
- // alternative:
- // m[m_offset+2+4*2] = -1.0f * zFar / (zNear - zFar);
- // m[m_offset+2+4*3] = (zFar * zNear) / (zNear - zFar);
-
- // Produces W result (= Z in)
- m[m_offset+3+4*2] = -1.0f;
- m[m_offset+3+4*3] = 0f;
-
- return m;
+ final FovHVHalves fovhvTan = fovhv.getInTangents(); // use tangent of half-fov !
+ final float top = fovhvTan.top * zNear;
+ final float bottom = -1.0f * fovhvTan.bottom * zNear;
+ final float left = -1.0f * fovhvTan.left * zNear;
+ final float right = fovhvTan.right * zNear;
+ return makeFrustum(m, m_offset, initM, left, right, bottom, top, zNear, zFar);
}
/**
diff --git a/src/jogl/classes/com/jogamp/opengl/math/FovHVHalves.java b/src/jogl/classes/com/jogamp/opengl/math/FovHVHalves.java
index 18bba8c45..786d146e6 100644
--- a/src/jogl/classes/com/jogamp/opengl/math/FovHVHalves.java
+++ b/src/jogl/classes/com/jogamp/opengl/math/FovHVHalves.java
@@ -48,7 +48,10 @@ public final class FovHVHalves {
/**
* Constructor for one {@link FovHVHalves} instance.
- *
+ * <p>
+ * It is recommended to pass and store values in tangent
+ * if used for perspective FOV calculations, since it will avoid conversion to tangent later on.
+ * </p>
* @param left half horizontal FOV, left side, in tangent or radians
* @param right half horizontal FOV, right side, in tangent or radians
* @param top half vertical FOV, top side, in tangent or radians
@@ -73,11 +76,26 @@ public final class FovHVHalves {
* @param verticalFov whole vertical FOV in radians
*/
public static FovHVHalves createByRadians(final float horizontalFov, final float verticalFov) {
- final float halfHorizFovTan = (float)Math.tan(horizontalFov/2f);
- final float halfVertFovTan = (float)Math.tan(verticalFov/2f);
+ final float halfHorizFovTan = FloatUtil.tan(horizontalFov/2f);
+ final float halfVertFovTan = FloatUtil.tan(verticalFov/2f);
return new FovHVHalves(halfHorizFovTan, halfHorizFovTan, halfVertFovTan, halfVertFovTan, true);
}
+ /**
+ * Returns this instance values <i>in tangent</i> values.
+ * <p>
+ * If this instance is {@link #inTangents} already, method returns this instance,
+ * otherwise a newly created instance w/ converted values to tangent.
+ * </p>
+ */
+ public final FovHVHalves getInTangents() {
+ if( inTangents ) {
+ return this;
+ } else {
+ return new FovHVHalves(FloatUtil.tan(left), FloatUtil.tan(right), FloatUtil.tan(top), FloatUtil.tan(bottom), true);
+ }
+ }
+
/** Returns the full horizontal FOV, i.e. {@link #left} + {@link #right}. */
public final float horzFov() { return left+right; }
@@ -85,6 +103,19 @@ public final class FovHVHalves {
public final float vertFov() { return top+bottom; }
public final String toString() {
- return "FovHVHalves["+(inTangents?"tangents":"radians")+": "+left+" l, "+right+" r, "+top+" t, "+bottom+" b]";
+ return "FovHVH["+(inTangents?"tangents":"radians")+": "+left+" l, "+right+" r, "+top+" t, "+bottom+" b]";
+ }
+ public final String toStringInDegrees() {
+ final float f = 180.0f / FloatUtil.PI;
+ final String storedAs = inTangents?"tangents":"radians";
+ if( inTangents ) {
+ final float aleft = FloatUtil.atan(left);
+ final float aright = FloatUtil.atan(right);
+ final float atop = FloatUtil.atan(top);
+ final float abottom = FloatUtil.atan(bottom);
+ return "FovHVH[degrees: "+aleft*f+" l, "+aright*f+" r, "+atop*f+" t, "+abottom*f+" b, stored-as: "+storedAs+"]";
+ } else {
+ return "FovHVH[degrees: "+left*f+" l, "+right*f+" r, "+top*f+" t, "+bottom*f+" b, stored-as: "+storedAs+"]";
+ }
}
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java b/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java
index 39608b116..289183b8e 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java
@@ -644,8 +644,8 @@ public final class PMVMatrix implements GLMatrixFunc {
}
@Override
- public final void glRotatef(final float angdeg, final float x, final float y, final float z) {
- glMultMatrixf(FloatUtil.makeRotationAxis(mat4Tmp1, 0, angdeg * FloatUtil.PI / 180.0f, x, y, z, mat4Tmp2), 0);
+ public final void glRotatef(final float ang_deg, final float x, final float y, final float z) {
+ glMultMatrixf(FloatUtil.makeRotationAxis(mat4Tmp1, 0, ang_deg * FloatUtil.PI / 180.0f, x, y, z, mat4Tmp2), 0);
}
/**
@@ -671,9 +671,14 @@ public final class PMVMatrix implements GLMatrixFunc {
/**
* {@link #glMultMatrixf(FloatBuffer) Multiply} the {@link #glGetMatrixMode() current matrix} with the perspective/frustum matrix.
+ *
+ * @param fovy_deg fov angle in degrees
+ * @param aspect aspect ratio
+ * @param zNear
+ * @param zFar
*/
- public final void gluPerspective(final float fovy, final float aspect, final float zNear, final float zFar) {
- glMultMatrixf( FloatUtil.makePerspective(mat4Tmp1, 0, true, fovy*((float)Math.PI)/360.0f, aspect, zNear, zFar), 0 );
+ public final void gluPerspective(final float fovy_deg, final float aspect, final float zNear, final float zFar) {
+ glMultMatrixf( FloatUtil.makePerspective(mat4Tmp1, 0, true, fovy_deg * FloatUtil.PI / 180.0f, aspect, zNear, zFar), 0 );
}
/**
diff --git a/src/jogl/classes/jogamp/opengl/ProjectFloat.java b/src/jogl/classes/jogamp/opengl/ProjectFloat.java
index 2c7989237..5921eb9a9 100644
--- a/src/jogl/classes/jogamp/opengl/ProjectFloat.java
+++ b/src/jogl/classes/jogamp/opengl/ProjectFloat.java
@@ -165,13 +165,13 @@ public class ProjectFloat {
/**
* Method gluPerspective.
*
- * @param fovy angle in degrees
+ * @param fovy_deg fov angle in degrees
* @param aspect
* @param zNear
* @param zFar
*/
- public void gluPerspective(final GLMatrixFunc gl, final float fovy, final float aspect, final float zNear, final float zFar) {
- gl.glMultMatrixf(FloatUtil.makePerspective(mat4Tmp1, 0, true, fovy / 2 * (float) Math.PI / 180, aspect, zNear, zFar), 0);
+ public void gluPerspective(final GLMatrixFunc gl, final float fovy_deg, final float aspect, final float zNear, final float zFar) {
+ gl.glMultMatrixf(FloatUtil.makePerspective(mat4Tmp1, 0, true, fovy_deg * FloatUtil.PI / 180.0f, aspect, zNear, zFar), 0);
}
/**
@@ -235,6 +235,7 @@ public class ProjectFloat {
/**
* Map object coordinates to window coordinates.
*/
+ @SuppressWarnings("deprecation")
public boolean gluProject(final float objx, final float objy, final float objz,
final FloatBuffer modelMatrix,
final FloatBuffer projMatrix,
@@ -283,6 +284,7 @@ public class ProjectFloat {
*
* @return
*/
+ @SuppressWarnings("deprecation")
public boolean gluProject(final float objx, final float objy, final float objz,
final FloatBuffer modelMatrix,
final FloatBuffer projMatrix,
@@ -365,6 +367,7 @@ public class ProjectFloat {
* @param obj_pos_offset
* @return true if successful, otherwise false (failed to invert matrix, or becomes z is infinity)
*/
+ @SuppressWarnings("deprecation")
public boolean gluUnProject(final float winx, final float winy, final float winz,
final FloatBuffer modelMatrix,
final FloatBuffer projMatrix,
@@ -422,6 +425,7 @@ public class ProjectFloat {
*
* @return true if successful, otherwise false (failed to invert matrix, or becomes z is infinity)
*/
+ @SuppressWarnings("deprecation")
public boolean gluUnProject(final float winx, final float winy, final float winz,
final FloatBuffer modelMatrix,
final FloatBuffer projMatrix,
@@ -523,6 +527,7 @@ public class ProjectFloat {
*
* @return true if successful, otherwise false (failed to invert matrix, or becomes z is infinity)
*/
+ @SuppressWarnings("deprecation")
public boolean gluUnProject4(final float winx, final float winy, final float winz, final float clipw,
final FloatBuffer modelMatrix, final FloatBuffer projMatrix,
final IntBuffer viewport,
diff --git a/src/oculusvr/classes/jogamp/opengl/oculusvr/OVRUtil.java b/src/oculusvr/classes/jogamp/opengl/oculusvr/OVRUtil.java
index 4de05fc92..48222ea97 100644
--- a/src/oculusvr/classes/jogamp/opengl/oculusvr/OVRUtil.java
+++ b/src/oculusvr/classes/jogamp/opengl/oculusvr/OVRUtil.java
@@ -122,17 +122,11 @@ public class OVRUtil {
}
public static ovrFovPort getOVRFovPort(final FovHVHalves fovHVHalves) {
final ovrFovPort tanHalfFov = ovrFovPort.create();
- if( fovHVHalves.inTangents ) {
- tanHalfFov.setLeftTan(fovHVHalves.left);
- tanHalfFov.setRightTan(fovHVHalves.right);
- tanHalfFov.setUpTan(fovHVHalves.top);
- tanHalfFov.setDownTan(fovHVHalves.bottom);
- } else {
- tanHalfFov.setLeftTan((float)Math.tan(fovHVHalves.left));
- tanHalfFov.setRightTan((float)Math.tan(fovHVHalves.right));
- tanHalfFov.setUpTan((float)Math.tan(fovHVHalves.top));
- tanHalfFov.setDownTan((float)Math.tan(fovHVHalves.bottom));
- }
+ final FovHVHalves fovHVHalvesTan = fovHVHalves.getInTangents();
+ tanHalfFov.setLeftTan(fovHVHalvesTan.left);
+ tanHalfFov.setRightTan(fovHVHalvesTan.right);
+ tanHalfFov.setUpTan(fovHVHalvesTan.top);
+ tanHalfFov.setDownTan(fovHVHalvesTan.bottom);
return tanHalfFov;
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/stereo/StereoDemo01.java b/src/test/com/jogamp/opengl/test/junit/jogl/stereo/StereoDemo01.java
index c4db20f37..b33b18358 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/stereo/StereoDemo01.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/stereo/StereoDemo01.java
@@ -237,7 +237,9 @@ public class StereoDemo01 {
// EyePos.y = ovrHmd_GetFloat(HMD, OVR_KEY_EYE_HEIGHT, EyePos.y);
final FovHVHalves[] defaultEyeFov = stereoDevice.getDefaultFOV();
System.err.println("Default Fov[0]: "+defaultEyeFov[0]);
+ System.err.println("Default Fov[0]: "+defaultEyeFov[0].toStringInDegrees());
System.err.println("Default Fov[1]: "+defaultEyeFov[1]);
+ System.err.println("Default Fov[1]: "+defaultEyeFov[1].toStringInDegrees());
final float[] eyePositionOffset = null == movieSimple ? StereoDevice.DEFAULT_EYE_POSITION_OFFSET // default
: new float[] { 0f, 0.3f, 0f }; // better fixed movie position