diff options
author | Sven Gothel <[email protected]> | 2014-07-05 08:27:03 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2014-07-05 08:27:03 +0200 |
commit | bda482e4eee76a5ba2139645682ae64dadacbc6b (patch) | |
tree | 51f67d3734276114754bff02bbde2217fc0fb797 /src/jogl/classes/com/jogamp | |
parent | f8f0f051604721bceaee214b8e5218fd47d2eb9e (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.
Diffstat (limited to 'src/jogl/classes/com/jogamp')
3 files changed, 56 insertions, 61 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 ); } /** |