diff options
author | Sven Gothel <[email protected]> | 2014-03-14 07:50:20 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2014-03-14 07:50:20 +0100 |
commit | b3fb80b4e03818f1f7dfdddd1ffcb01e6a0a8acc (patch) | |
tree | 4c1de742b4e9d4a7a2f1981ba6a2fd358622099d | |
parent | 3a3bbd87955321d790ba0f63402c573047304b1a (diff) |
Math and PMVMatrix: Cleanup and Refine
- Added final qualifier where possible
- Refined API doc
- FloatUtil:
- Add machine EPSILON
- fixed value and runtime computed (real machEps)
- incl. isZero(..), isEqual(..)
- Add makeRotationAxis(..)
- Moved from PMVMatrix for reusage
- Add makeRotationEuler(..)
- New, not recommended due to Gimbal-Lock
- Add copyMatrix[Column|Row](..)
- Add more PI variations and trigo-func float mappings
- Removed cross and normalize, use VectorUtil!
VectorUtil:
- Add copyVec*
- Add equals and isZero w/ and w/o EPSILON
- Add distance[Square]
- Add length[Square]
PMVMatrix:
- Removed 'destroy' method in favor of making most fields 'final'.
AffineTransform:
- Added AABBox transform
- Public multiply
15 files changed, 705 insertions, 437 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java b/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java index d2976357d..6177a6b2d 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java +++ b/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java @@ -37,23 +37,23 @@ import com.jogamp.common.os.Platform; * Basic Float math utility functions. * <p> * Implementation assumes linear matrix layout in column-major order - * matching OpenGL's implementation, translation matrix example: + * matching OpenGL's implementation, illustration: * <pre> - Row-Major Order: - 1 0 0 x - 0 1 0 y - 0 0 1 z - 0 0 0 1 - * </pre> - * <pre> - Column-Major Order: - 1 0 0 0 - 0 1 0 0 - 0 0 1 0 - x y z 1 + Row-Major Column-Major (OpenGL): + + | 0 1 2 3 | | 0 4 8 12 | + | | | | + | 4 5 6 7 | | 1 5 9 13 | + M = | | M = | | + | 8 9 10 11 | | 2 6 10 14 | + | | | | + | 12 13 14 15 | | 3 7 11 15 | * </pre> * </p> * <p> + * See <a href="http://web.archive.org/web/20041029003853/http://www.j3d.org/matrix_faq/matrfaq_latest.html">Matrix-FAQ</a> + * </p> + * <p> * Derived from ProjectFloat.java - Created 11-jan-2004 * </p> * @@ -113,6 +113,92 @@ public class FloatUtil { } /** + * Make a rotation matrix from the given axis and angle in radians. + * @see <a href="http://web.archive.org/web/20041029003853/http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q38">Matrix-FAQ Q38</a> + */ + public static final void makeRotationAxis(final float angrad, float x, float y, float z, final float[] mat, final int mat_offset, final float[] tmpVec3f) { + final float c = cos(angrad); + final float ic= 1.0f - c; + final float s = sin(angrad); + + tmpVec3f[0]=x; tmpVec3f[1]=y; tmpVec3f[2]=z; + VectorUtil.normalize(tmpVec3f); + x = tmpVec3f[0]; y = tmpVec3f[1]; z = tmpVec3f[2]; + + // Rotation matrix (Row Order): + // xx(1-c)+c xy(1-c)+zs xz(1-c)-ys 0 + // xy(1-c)-zs yy(1-c)+c yz(1-c)+xs 0 + // xz(1-c)+ys yz(1-c)-xs zz(1-c)+c 0 + // 0 0 0 1 + final float xy = x*y; + final float xz = x*z; + final float xs = x*s; + final float ys = y*s; + final float yz = y*z; + final float zs = z*s; + mat[0+0*4+mat_offset] = x*x*ic+c; + mat[1+0*4+mat_offset] = xy*ic+zs; + mat[2+0*4+mat_offset] = xz*ic-ys; + + mat[0+1*4+mat_offset] = xy*ic-zs; + mat[1+1*4+mat_offset] = y*y*ic+c; + mat[2+1*4+mat_offset] = yz*ic+xs; + + mat[0+2*4+mat_offset] = xz*ic+ys; + mat[1+2*4+mat_offset] = yz*ic-xs; + mat[2+2*4+mat_offset] = z*z*ic+c; + } + + /** + * Make a concatenated rotation matrix in column-major order from the given Euler rotation angles in radians. + * <p> + * The rotations are applied in the given order: + * <ul> + * <li>y - heading</li> + * <li>z - attitude</li> + * <li>x - bank</li> + * </ul> + * </p> + * @param bankX the Euler pitch angle in radians. (rotation about the X axis) + * @param headingY the Euler yaw angle in radians. (rotation about the Y axis) + * @param attitudeZ the Euler roll angle in radians. (rotation about the Z axis) + * <p> + * Implementation does not use Quaternion and hence is exposed to + * <a href="http://web.archive.org/web/20041029003853/http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q34">Gimbal-Lock</a> + * </p> + * @see <a href="http://web.archive.org/web/20041029003853/http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q36">Matrix-FAQ Q36</a> + * @see <a href="http://www.euclideanspace.com/maths/geometry/rotations/conversions/eulerToMatrix/index.htm">euclideanspace.com-eulerToMatrix</a> + */ + public static final void makeRotationEuler(final float bankX, final float headingY, final float attitudeZ, final float[] mat, final int mat_offset) { + // Assuming the angles are in radians. + final float ch = cos(headingY); + final float sh = sin(headingY); + final float ca = cos(attitudeZ); + final float sa = sin(attitudeZ); + final float cb = cos(bankX); + final float sb = sin(bankX); + + mat[0+0*4+mat_offset] = ch*ca; + mat[0+1*4+mat_offset] = sh*sb - ch*sa*cb; + mat[0+2*4+mat_offset] = ch*sa*sb + sh*cb; + mat[1+0*4+mat_offset] = sa; + mat[1+1*4+mat_offset] = ca*cb; + mat[1+2*4+mat_offset] = -ca*sb; + mat[2+0*4+mat_offset] = -sh*ca; + mat[2+1*4+mat_offset] = sh*sa*cb + ch*sb; + mat[2+2*4+mat_offset] = -sh*sa*sb + ch*cb; + + mat[3+0*4+mat_offset] = 0; + mat[3+1*4+mat_offset] = 0; + mat[3+2*4+mat_offset] = 0; + + mat[0+3*4+mat_offset] = 0; + mat[1+3*4+mat_offset] = 0; + mat[2+3*4+mat_offset] = 0; + mat[3+3*4+mat_offset] = 1; + } + + /** * @param a 4x4 matrix in column-major order * @param b 4x4 matrix in column-major order * @param d result a*b in column-major order @@ -252,79 +338,6 @@ public class FloatUtil { } /** - * Normalize vector - * - * @param v makes len(v)==1 - */ - public static final void normalize(float[] v) { - float r = (float) Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); - - if ( r == 0.0 || r == 1.0) { - return; - } - - r = 1.0f / r; - - v[0] *= r; - v[1] *= r; - v[2] *= r; - } - - /** - * Normalize vector - * - * @param v makes len(v)==1 - */ - public static final void normalize(FloatBuffer v) { - final int vPos = v.position(); - - float r = (float) Math.sqrt(v.get(0+vPos) * v.get(0+vPos) + - v.get(1+vPos) * v.get(1+vPos) + - v.get(2+vPos) * v.get(2+vPos)); - - if ( r == 0.0 || r == 1.0) { - return; - } - - r = 1.0f / r; - - v.put(0+vPos, v.get(0+vPos) * r); - v.put(1+vPos, v.get(1+vPos) * r); - v.put(2+vPos, v.get(2+vPos) * r); - } - - - /** - * Calculate cross-product of 2 vector - * - * @param v1 3-component vector - * @param v2 3-component vector - * @param result v1 X v2 - */ - public static final void cross(float[] v1, float[] v2, float[] result) { - result[0] = v1[1] * v2[2] - v1[2] * v2[1]; - result[1] = v1[2] * v2[0] - v1[0] * v2[2]; - result[2] = v1[0] * v2[1] - v1[1] * v2[0]; - } - - /** - * Calculate cross-product of 2 vector - * - * @param v1 3-component vector - * @param v2 3-component vector - * @param result v1 X v2 - */ - public static final void cross(FloatBuffer v1, FloatBuffer v2, FloatBuffer result) { - final int v1Pos = v1.position(); - final int v2Pos = v2.position(); - final int rPos = result.position(); - - result.put(0+rPos, v1.get(1+v1Pos) * v2.get(2+v2Pos) - v1.get(2+v1Pos) * v2.get(1+v2Pos)); - result.put(1+rPos, v1.get(2+v1Pos) * v2.get(0+v2Pos) - v1.get(0+v1Pos) * v2.get(2+v2Pos)); - result.put(2+rPos, v1.get(0+v1Pos) * v2.get(1+v2Pos) - v1.get(1+v1Pos) * v2.get(0+v2Pos)); - } - - /** * @param m_in 4x4 matrix in column-major order * @param m_in_off * @param v_in 4-component column-vector @@ -412,6 +425,46 @@ public class FloatUtil { } /** + * Copy the named column of the given column-major matrix to v_out. + * <p> + * v_out may be 3 or 4 components long, hence the 4th row may not be stored. + * </p> + * @param m_in input column-major matrix + * @param m_in_off offset to input matrix + * @param column named column to copy + * @param v_out the column-vector storage, at least 3 components long + * @param v_out_off offset to storage + */ + public static final void copyMatrixColumn(final float[] m_in, final int m_in_off, final int column, final float[] v_out, final int v_out_off) { + v_out[0+v_out_off]=m_in[0+column*4+m_in_off]; + v_out[1+v_out_off]=m_in[1+column*4+m_in_off]; + v_out[2+v_out_off]=m_in[2+column*4+m_in_off]; + if( v_out.length > 3+v_out_off ) { + v_out[3+v_out_off]=m_in[3+column*4+m_in_off]; + } + } + + /** + * Copy the named row of the given column-major matrix to v_out. + * <p> + * v_out may be 3 or 4 components long, hence the 4th column may not be stored. + * </p> + * @param m_in input column-major matrix + * @param m_in_off offset to input matrix + * @param row named row to copy + * @param v_out the row-vector storage, at least 3 components long + * @param v_out_off offset to storage + */ + public static final void copyMatrixRow(final float[] m_in, final int m_in_off, final int row, final float[] v_out, final int v_out_off) { + v_out[0+v_out_off]=m_in[row+0*4+m_in_off]; + v_out[1+v_out_off]=m_in[row+1*4+m_in_off]; + v_out[2+v_out_off]=m_in[row+2*4+m_in_off]; + if( v_out.length > 3+v_out_off ) { + v_out[3+v_out_off]=m_in[row+3*4+m_in_off]; + } + } + + /** * @param sb optional passed StringBuilder instance to be used * @param f the format string of one floating point, i.e. "%10.5f", see {@link java.util.Formatter} * @param a mxn matrix (rows x columns) @@ -570,20 +623,129 @@ public class FloatUtil { return sb; } + @SuppressWarnings("unused") + private static void calculateMachineEpsilonFloat() { + final long t0; + if( DEBUG_EPSILON ) { + t0 = Platform.currentTimeMillis(); + } + float machEps = 1.0f; + int i=0; + do { + machEps /= 2.0f; + i++; + } while (1.0f + (machEps / 2.0f) != 1.0f); + machEpsilon = machEps; + if( DEBUG_EPSILON ) { + final long t1 = Platform.currentTimeMillis(); + System.err.println("MachineEpsilon: "+machEpsilon+", in "+i+" iterations within "+(t1-t0)+" ms"); + } + } + private static volatile boolean machEpsilonAvail = false; + private static float machEpsilon = 0f; + private static final boolean DEBUG_EPSILON = false; + + /** + * Return computed machine Epsilon value. + * <p> + * The machine Epsilon value is computed once. + * </p> + * <p> + * On a reference machine the result was {@link #EPSILON} in 23 iterations. + * </p> + * @see #EPSILON + */ + public static float getMachineEpsilon() { + if( !machEpsilonAvail ) { + synchronized(FloatUtil.class) { + if( !machEpsilonAvail ) { + machEpsilonAvail = true; + calculateMachineEpsilonFloat(); + } + } + } + return machEpsilon; + } + public static final float E = 2.7182818284590452354f; + /** The value PI, i.e. 180 degrees in radians. */ public static final float PI = 3.14159265358979323846f; - public static float abs(float a) { return java.lang.Math.abs(a); } + /** The value 2PI, i.e. 360 degrees in radians. */ + public static final float TWO_PI = 2f * PI; + + /** The value PI/2, i.e. 90 degrees in radians. */ + public static final float HALF_PI = PI / 2f; + + /** The value PI/4, i.e. 45 degrees in radians. */ + public static final float QUARTER_PI = PI / 4f; + + /** The value PI^2. */ + public final static float SQUARED_PI = PI * PI; + + /** + * Epsilon for floating point {@value}, as once computed via {@link #getMachineEpsilon()} on an AMD-64 CPU. + * <p> + * Definition of machine epsilon guarantees that: + * <pre> + * 1.0f + EPSILON != 1.0f + * </pre> + * In other words: <i>machEps</i> is the maximum relative error of the chosen rounding procedure. + * </p> + * <p> + * A number can be considered zero if it is in the range (or in the set): + * <pre> + * <b>MaybeZeroSet</b> e ]-<i>machEps</i> .. <i>machEps</i>[ <i>(exclusive)</i> + * </pre> + * While comparing floating point values, <i>machEps</i> allows to clip the relative error: + * <pre> + * boolean isZero = afloat < EPSILON; + * boolean isNotZero = afloat >= EPSILON; + * + * boolean isEqual = abs(bfloat - afloat) < EPSILON; + * boolean isNotEqual = abs(bfloat - afloat) >= EPSILON; + * </pre> + * </p> + * @see #equals(float, float, float) + * @see #isZero(float, float) + */ + public static final float EPSILON = 1.1920929E-7f; // Float.MIN_VALUE == 1.4e-45f ; double EPSILON 2.220446049250313E-16d + + /** + * Return true if both values are equal, i.e. their absolute delta < <code>epsilon</code>. + * @see #EPSILON + */ + public static boolean equals(final float a, final float b, final float epsilon) { + return Math.abs(a - b) < epsilon; + } + + /** + * Return true if value is zero, i.e. it's absolute value < <code>epsilon</code>. + * @see #EPSILON + */ + public static boolean isZero(final float a, final float epsilon) { + return Math.abs(a) < epsilon; + } + + public static float abs(final float a) { return java.lang.Math.abs(a); } + + public static float pow(final float a, final float b) { return (float) java.lang.Math.pow(a, b); } + + public static float sin(final float a) { return (float) java.lang.Math.sin(a); } + + public static float asin(final float a) { return (float) java.lang.Math.asin(a); } + + public static float cos(final float a) { return (float) java.lang.Math.cos(a); } - public static float pow(float a, float b) { return (float) java.lang.Math.pow(a, b); } + public static float acos(final float a) { return (float) java.lang.Math.acos(a); } - public static float sin(float a) { return (float) java.lang.Math.sin(a); } + public static float tan(final float a) { return (float) java.lang.Math.tan(a); } - public static float cos(float a) { return (float) java.lang.Math.cos(a); } + public static float atan(final float a) { return (float) java.lang.Math.atan(a); } - public static float acos(float a) { return (float) java.lang.Math.acos(a); } + public static float atan2(final float y, final float x) { return (float) java.lang.Math.atan2(y, x); } - public static float sqrt(float a) { return (float) java.lang.Math.sqrt(a); } + public static float sqrt(final float a) { return (float) java.lang.Math.sqrt(a); } }
\ No newline at end of file diff --git a/src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java b/src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java index 734b7459b..ff16fba79 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java +++ b/src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java @@ -31,6 +31,9 @@ import java.util.ArrayList; public class VectorUtil { + /** Zero vector */ + public static final float[] ZERO = new float[] { 0f, 0f, 0f }; + public enum Winding { CW(-1), CCW(1); @@ -43,41 +46,171 @@ public class VectorUtil { public static final int COLLINEAR = 0; + /** + * Copies a vector of length 3 + * @param dst output vector + * @param dstOffset offset of dst in array + * @param src input vector + * @param srcOffset offset of src in array + * @return copied output vector for chaining + */ + public static float[] copyVec3(final float[] dst, int dstOffset, final float[] src, int srcOffset) + { + System.arraycopy(src, srcOffset, dst, dstOffset, 3); + return dst; + } + + /** + * Copies a vector of length 4 + * @param dst output vector + * @param dstOffset offset of dst in array + * @param src input vector + * @param srcOffset offset of src in array + * @return copied output vector for chaining + */ + public static float[] copyVec4(final float[] dst, int dstOffset, final float[] src, int srcOffset) + { + System.arraycopy(src, srcOffset, dst, dstOffset, 4); + return dst; + } + + /** + * Return true if both vectors are equal, no {@link FloatUtil#EPSILON} is taken into consideration. + */ + public static boolean equals(final float[] vec1, int vec1Offset, final float[] vec2, int vec2Offset) { + return vec1[0+vec1Offset] == vec2[0+vec2Offset] && + vec1[1+vec1Offset] == vec2[1+vec2Offset] && + vec1[2+vec1Offset] == vec2[2+vec2Offset]; + } + + /** + * Return true if both vectors are equal, i.e. their absolute delta < <code>epsilon</code>. + * @see FloatUtil#EPSILON + */ + public static boolean equals(final float[] vec1, int vec1Offset, final float[] vec2, int vec2Offset, final float epsilon) { + return Math.abs(vec1[0+vec1Offset] - vec2[0+vec2Offset]) < epsilon && + Math.abs(vec1[1+vec1Offset] - vec2[1+vec2Offset]) < epsilon && + Math.abs(vec1[2+vec1Offset] - vec2[2+vec2Offset]) < epsilon ; + } + + /** + * Return true if vector is zero, no {@link FloatUtil#EPSILON} is taken into consideration. + */ + public static boolean isZero(final float[] vec, final int vecOffset) { + return 0f == vec[0+vecOffset] && 0f == vec[1+vecOffset] && 0f == vec[2+vecOffset]; + } + + /** + * Return true if vector is zero, i.e. it's absolute components < <code>epsilon</code>. + * @see FloatUtil#EPSILON + */ + public static boolean isZero(final float[] vec, final int vecOffset, final float epsilon) { + return isZero(vec[0+vecOffset], vec[1+vecOffset], vec[2+vecOffset], epsilon); + } + + /** + * Return true if all three vector components are zero, i.e. it's their absolute value < <code>epsilon</code>. + * @see FloatUtil#EPSILON + */ + public static boolean isZero(final float x, final float y, final float z, final float epsilon) { + return Math.abs(x) < epsilon && + Math.abs(y) < epsilon && + Math.abs(z) < epsilon ; + } + + /** + * Return the squared distance between the given two points described vector v1 and v2. + * <p> + * When comparing the relative distance between two points it is usually sufficient to compare the squared + * distances, thus avoiding an expensive square root operation. + * </p> + */ + public static float distanceSquared(final float[] v1, final float[] v2) { + final float dx = v1[0] - v2[0]; + final float dy = v1[1] - v2[1]; + final float dz = v1[2] - v2[2]; + return dx * dx + dy * dy + dz * dz; + } + + /** + * Return the distance between the given two points described vector v1 and v2. + */ + public static float distance(final float[] v1, final float[] v2) { + return FloatUtil.sqrt(distanceSquared(v1, v2)); + } + /** compute the dot product of two points * @param vec1 vector 1 * @param vec2 vector 2 * @return the dot product as float */ - public static float dot(float[] vec1, float[] vec2) + public static float dot(final float[] vec1, final float[] vec2) { return (vec1[0]*vec2[0] + vec1[1]*vec2[1] + vec1[2]*vec2[2]); } /** + * Compute the squared length of a vector, a.k.a the squared <i>norm</i> + */ + public static float lengthSquared(final float[] vec) { + return vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2]; + } + /** + * Compute the length of a vector, a.k.a the <i>norm</i> + */ + public static float length(final float[] vec) { + return FloatUtil.sqrt(lengthSquared(vec)); + } + + /** * Normalize a vector + * @param result output vector * @param vector input vector - * @return normalized vector + * @return normalized output vector */ - public static float[] normalize(final float[] result, float[] vector) - { - final float d = FloatUtil.sqrt(vector[0]*vector[0] + vector[1]*vector[1] + vector[2]*vector[2]); - if(d> 0.0f) - { - result[0] = vector[0]/d; - result[1] = vector[1]/d; - result[2] = vector[2]/d; + public static float[] normalize(final float[] result, final float[] vector) { + final float lengthSq = lengthSquared(vector); + if ( FloatUtil.isZero(lengthSq, FloatUtil.EPSILON) ) { + result[0] = 0f; + result[1] = 0f; + result[2] = 0f; + } else { + final float invSqr = 1f / FloatUtil.sqrt(lengthSq); + result[0] = vector[0] * invSqr; + result[1] = vector[1] * invSqr; + result[2] = vector[2] * invSqr; } return result; } /** + * Normalize a vector in place + * @param result output vector + * @param vector input vector + * @return normalized output vector + */ + public static float[] normalize(final float[] vector) { + final float lengthSq = lengthSquared(vector); + if ( FloatUtil.isZero(lengthSq, FloatUtil.EPSILON) ) { + vector[0] = 0f; + vector[1] = 0f; + vector[2] = 0f; + } else { + final float invSqr = 1f / FloatUtil.sqrt(lengthSq); + vector[0] *= invSqr; + vector[1] *= invSqr; + vector[2] *= invSqr; + } + return vector; + } + + /** * Scales a vector by param using given result float[] * @param result vector for the result * @param vector input vector * @param scale single scale constant for all vector components */ - public static float[] scale(float[] result, float[] vector, float scale) - { + public static float[] scale(final float[] result, final float[] vector, final float scale) { result[0] = vector[0] * scale; result[1] = vector[1] * scale; result[2] = vector[2] * scale; @@ -90,7 +223,7 @@ public class VectorUtil { * @param scale 3 component scale constant for each vector component * @return given result vector */ - public static float[] scale(float[] result, float[] vector, float[] scale) + public static float[] scale(final float[] result, final float[] vector, final float[] scale) { result[0] = vector[0] * scale[0]; result[1] = vector[1] * scale[1]; @@ -99,13 +232,12 @@ public class VectorUtil { } /** - * Adds to vectors + * Adds two vectors * @param v1 vector 1 * @param v2 vector 2 * @return v1 + v2 */ - public static float[] vectorAdd(float[] result, float[] v1, float[] v2) - { + public static float[] vectorAdd(final float[] result, final float[] v1, final float[] v2) { result[0] = v1[0] + v2[0]; result[1] = v1[1] + v2[1]; result[2] = v1[2] + v2[2]; @@ -113,17 +245,29 @@ public class VectorUtil { } /** + * Subtracts two vectors + * @param v1 vector 1 + * @param v2 vector 2 + * @return v1 - v2 + */ + public static float[] vectorSub(final float[] result, final float[] v1, final float[] v2) { + result[0] = v1[0] - v2[0]; + result[1] = v1[1] - v2[1]; + result[2] = v1[2] - v2[2]; + return result; + } + + /** * cross product vec1 x vec2 - * @param vec1 vector 1 - * @param vec2 vecttor 2 + * @param v1 vector 1 + * @param v2 vector 2 * @return the resulting vector */ - public static float[] cross(final float[] result, float[] vec1, float[] vec2) + public static float[] cross(final float[] result, final float[] v1, final float[] v2) { - result[0] = vec2[2]*vec1[1] - vec2[1]*vec1[2]; - result[1] = vec2[0]*vec1[2] - vec2[2]*vec1[0]; - result[2] = vec2[1]*vec1[0] - vec2[0]*vec1[1]; - + result[0] = v1[1] * v2[2] - v1[2] * v2[1]; + result[1] = v1[2] * v2[0] - v1[0] * v2[2]; + result[2] = v1[0] * v2[1] - v1[1] * v2[0]; return result; } @@ -132,7 +276,7 @@ public class VectorUtil { * @param vec vector(x,y,z) * @return result */ - public static float[] colMatrixVectorMult(final float[] result, float[] colMatrix, float[] vec) + public static float[] colMatrixVectorMult(final float[] result, final float[] colMatrix, final float[] vec) { result[0] = vec[0]*colMatrix[0] + vec[1]*colMatrix[4] + vec[2]*colMatrix[8] + colMatrix[12]; result[1] = vec[0]*colMatrix[1] + vec[1]*colMatrix[5] + vec[2]*colMatrix[9] + colMatrix[13]; @@ -146,7 +290,7 @@ public class VectorUtil { * @param vec vector(x,y,z) * @return result */ - public static float[] rowMatrixVectorMult(final float[] result, float[] rawMatrix, float[] vec) + public static float[] rowMatrixVectorMult(final float[] result, final float[] rawMatrix, final float[] vec) { result[0] = vec[0]*rawMatrix[0] + vec[1]*rawMatrix[1] + vec[2]*rawMatrix[2] + rawMatrix[3]; result[1] = vec[0]*rawMatrix[4] + vec[1]*rawMatrix[5] + vec[2]*rawMatrix[6] + rawMatrix[7]; @@ -160,7 +304,7 @@ public class VectorUtil { * @param p2 second vale * @return midpoint */ - public static float mid(float p1, float p2) + public static float mid(final float p1, final float p2) { return (p1+p2)/2.0f; } @@ -171,7 +315,7 @@ public class VectorUtil { * @param p2 second point * @return midpoint */ - public static float[] mid(final float[] result, float[] p1, float[] p2) + public static float[] mid(final float[] result, final float[] p1, final float[] p2) { result[0] = (p1[0] + p2[0])*0.5f; result[1] = (p1[1] + p2[1])*0.5f; @@ -180,22 +324,13 @@ public class VectorUtil { return result; } - /** Compute the norm of a vector - * @param vec vector - * @return vorm - */ - public static float norm(float[] vec) - { - return FloatUtil.sqrt(vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2]); - } - /** Compute distance between 2 points * @param p0 a ref point on the line * @param vec vector representing the direction of the line * @param point the point to compute the relative distance of * @return distance float */ - public static float computeLength(float[] p0, float[] point) + public static float computeLength(final float[] p0, final float[] point) { final float w0 = point[0]-p0[0]; final float w1 = point[1]-p0[1]; @@ -209,7 +344,7 @@ public class VectorUtil { * @param v2 vertex 2 * @return */ - public static boolean checkEquality(float[] v1, float[] v2) + public static boolean checkEquality(final float[] v1, final float[] v2) { return Float.compare(v1[0], v2[0]) == 0 && Float.compare(v1[1], v2[1]) == 0 && @@ -221,7 +356,7 @@ public class VectorUtil { * @param v2 vertex 2 * @return */ - public static boolean checkEqualityVec2(float[] v1, float[] v2) + public static boolean checkEqualityVec2(final float[] v1, final float[] v2) { return Float.compare(v1[0], v2[0]) == 0 && Float.compare(v1[1], v2[1]) == 0 ; @@ -233,7 +368,7 @@ public class VectorUtil { * @param c vector 3 * @return the determinant value */ - public static float computeDeterminant(float[] a, float[] b, float[] c) + public static float computeDeterminant(final float[] a, final float[] b, final float[] c) { return a[0]*b[1]*c[2] + a[1]*b[2]*c[0] + a[2]*b[0]*c[1] - a[0]*b[2]*c[1] - a[1]*b[0]*c[2] - a[2]*b[1]*c[0]; } @@ -244,7 +379,7 @@ public class VectorUtil { * @param v3 vertex 3 * @return true if collinear, false otherwise */ - public static boolean checkCollinear(float[] v1, float[] v2, float[] v3) + public static boolean checkCollinear(final float[] v1, final float[] v2, final float[] v3) { return (computeDeterminant(v1, v2, v3) == VectorUtil.COLLINEAR); } @@ -254,7 +389,7 @@ public class VectorUtil { * @param v1 vertex 1 * @param v2 vertex2 2 */ - public static void computeVector(float[] vector, float[] v1, float[] v2) { + public static void computeVector(final float[] vector, final float[] v1, final float[] v2) { vector[0] = v2[0] - v1[0]; vector[1] = v2[1] - v1[1]; vector[2] = v2[2] - v1[2]; @@ -268,7 +403,7 @@ public class VectorUtil { * @return true if the vertex d is inside the circle defined by the * vertices a, b, c. from paper by Guibas and Stolfi (1985). */ - public static boolean inCircle(Vert2fImmutable a, Vert2fImmutable b, Vert2fImmutable c, Vert2fImmutable d) { + public static boolean inCircle(final Vert2fImmutable a, final Vert2fImmutable b, final Vert2fImmutable c, final Vert2fImmutable d) { final float[] A = a.getCoord(); final float[] B = b.getCoord(); final float[] C = c.getCoord(); @@ -286,7 +421,7 @@ public class VectorUtil { * @return compute twice the area of the oriented triangle (a,b,c), the area * is positive if the triangle is oriented counterclockwise. */ - public static float triArea(Vert2fImmutable a, Vert2fImmutable b, Vert2fImmutable c){ + public static float triArea(final Vert2fImmutable a, final Vert2fImmutable b, final Vert2fImmutable c){ final float[] A = a.getCoord(); final float[] B = b.getCoord(); final float[] C = c.getCoord(); @@ -300,7 +435,7 @@ public class VectorUtil { * @return compute twice the area of the oriented triangle (a,b,c), the area * is positive if the triangle is oriented counterclockwise. */ - public static float triArea(float[] A, float[] B, float[] C){ + public static float triArea(final float[] A, final float[] B, final float[] C){ return (B[0] - A[0]) * (C[1] - A[1]) - (B[1] - A[1])*(C[0] - A[0]); } @@ -312,9 +447,9 @@ public class VectorUtil { * @param p the vertex in question * @return true if p is in triangle (a, b, c), false otherwise. */ - public static boolean vertexInTriangle(float[] a, float[] b, float[] c, - float[] p, - float[] ac, float[] ab, float[] ap){ + public static boolean vertexInTriangle(final float[] a, final float[] b, final float[] c, + final float[] p, + final float[] ac, final float[] ab, final float[] ap){ // Compute vectors computeVector(ac, a, c); //v0 computeVector(ab, a, b); //v1 @@ -350,9 +485,9 @@ public class VectorUtil { * @param tmpAP * @return true if p1 or p2 or p3 is in triangle (a, b, c), false otherwise. */ - public static boolean vertexInTriangle3(float[] a, float[] b, float[] c, - float[] p1, float[] p2, float[] p3, - float[] tmpAC, float[] tmpAB, float[] tmpAP){ + public static boolean vertexInTriangle3(final float[] a, final float[] b, final float[] c, + final float[] p1, final float[] p2, final float[] p3, + final float[] tmpAC, final float[] tmpAB, final float[] tmpAP){ // Compute vectors computeVector(tmpAC, a, c); //v0 computeVector(tmpAB, a, b); //v1 @@ -412,7 +547,7 @@ public class VectorUtil { * @param c third vertex * @return true if the points a,b,c are in a ccw order */ - public static boolean ccw(Vert2fImmutable a, Vert2fImmutable b, Vert2fImmutable c){ + public static boolean ccw(final Vert2fImmutable a, final Vert2fImmutable b, final Vert2fImmutable c){ return triArea(a,b,c) > 0; } @@ -422,7 +557,7 @@ public class VectorUtil { * @param c third vertex * @return Winding */ - public static Winding getWinding(Vert2fImmutable a, Vert2fImmutable b, Vert2fImmutable c) { + public static Winding getWinding(final Vert2fImmutable a, final Vert2fImmutable b, final Vert2fImmutable c) { return triArea(a,b,c) > 0 ? Winding.CCW : Winding.CW ; } @@ -430,7 +565,7 @@ public class VectorUtil { * @param vertices * @return positive area if ccw else negative area value */ - public static float area(ArrayList<? extends Vert2fImmutable> vertices) { + public static float area(final ArrayList<? extends Vert2fImmutable> vertices) { final int n = vertices.size(); float area = 0.0f; for (int p = n - 1, q = 0; q < n; p = q++) @@ -446,7 +581,7 @@ public class VectorUtil { * @param vertices array of Vertices * @return CCW or CW {@link Winding} */ - public static Winding getWinding(ArrayList<? extends Vert2fImmutable> vertices) { + public static Winding getWinding(final ArrayList<? extends Vert2fImmutable> vertices) { return area(vertices) >= 0 ? Winding.CCW : Winding.CW ; } @@ -458,7 +593,7 @@ public class VectorUtil { * @param d vertex 2 of second segment * @return the intersection coordinates if the segments intersect, otherwise returns null */ - public static float[] seg2SegIntersection(final float[] result, Vert2fImmutable a, Vert2fImmutable b, Vert2fImmutable c, Vert2fImmutable d) { + public static float[] seg2SegIntersection(final float[] result, final Vert2fImmutable a, final Vert2fImmutable b, final Vert2fImmutable c, final Vert2fImmutable d) { final float determinant = (a.getX()-b.getX())*(c.getY()-d.getY()) - (a.getY()-b.getY())*(c.getX()-d.getX()); if (determinant == 0) @@ -487,7 +622,7 @@ public class VectorUtil { * @param d vertex 2 of second segment * @return true if the segments intersect, otherwise returns false */ - public static boolean testSeg2SegIntersection(Vert2fImmutable a, Vert2fImmutable b, Vert2fImmutable c, Vert2fImmutable d) { + public static boolean testSeg2SegIntersection(final Vert2fImmutable a, final Vert2fImmutable b, final Vert2fImmutable c, final Vert2fImmutable d) { final float[] A = a.getCoord(); final float[] B = b.getCoord(); final float[] C = c.getCoord(); @@ -520,7 +655,7 @@ public class VectorUtil { * @return the intersection coordinates if the lines intersect, otherwise * returns null */ - public static float[] line2lineIntersection(final float[] result, Vert2fImmutable a, Vert2fImmutable b, Vert2fImmutable c, Vert2fImmutable d) { + public static float[] line2lineIntersection(final float[] result, final Vert2fImmutable a, final Vert2fImmutable b, final Vert2fImmutable c, final Vert2fImmutable d) { final float determinant = (a.getX()-b.getX())*(c.getY()-d.getY()) - (a.getY()-b.getY())*(c.getX()-d.getX()); if (determinant == 0) @@ -545,7 +680,7 @@ public class VectorUtil { * @param e vertex 2 of first segment * @return true if the segment intersects at least one segment of the triangle, false otherwise */ - public static boolean testTri2SegIntersection(Vert2fImmutable a, Vert2fImmutable b, Vert2fImmutable c, Vert2fImmutable d, Vert2fImmutable e){ + public static boolean testTri2SegIntersection(final Vert2fImmutable a, final Vert2fImmutable b, final Vert2fImmutable c, final Vert2fImmutable d, final Vert2fImmutable e){ return testSeg2SegIntersection(a, b, d, e) || testSeg2SegIntersection(b, c, d, e) || testSeg2SegIntersection(a, c, d, e) ; diff --git a/src/jogl/classes/com/jogamp/opengl/math/geom/Frustum.java b/src/jogl/classes/com/jogamp/opengl/math/geom/Frustum.java index fb311083f..8b4eba222 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/geom/Frustum.java +++ b/src/jogl/classes/com/jogamp/opengl/math/geom/Frustum.java @@ -186,8 +186,8 @@ public class Frustum { * </p> */ public void updateByPMV(float[] pmv, int pmv_off) { - // Left: a = m41 + m11, b = m42 + m12, c = m43 + m13, d = m44 + m14 - [1..4] row-major - // Left: a = m30 + m00, b = m31 + m01, c = m32 + m02, d = m33 + m03 - [0..3] row-major + // Left: a = m41 + m11, b = m42 + m12, c = m43 + m13, d = m44 + m14 - [1..4] column-major + // Left: a = m30 + m00, b = m31 + m01, c = m32 + m02, d = m33 + m03 - [0..3] column-major { final Plane p = planes[LEFT]; final float[] p_n = p.n; @@ -197,8 +197,8 @@ public class Frustum { p.d = pmv[ pmv_off + 3 + 3 * 4 ] + pmv[ pmv_off + 0 + 3 * 4 ]; } - // Right: a = m41 - m11, b = m42 - m12, c = m43 - m13, d = m44 - m14 - [1..4] row-major - // Right: a = m30 - m00, b = m31 - m01, c = m32 - m02, d = m33 - m03 - [0..3] row-major + // Right: a = m41 - m11, b = m42 - m12, c = m43 - m13, d = m44 - m14 - [1..4] column-major + // Right: a = m30 - m00, b = m31 - m01, c = m32 - m02, d = m33 - m03 - [0..3] column-major { final Plane p = planes[RIGHT]; final float[] p_n = p.n; @@ -208,8 +208,8 @@ public class Frustum { p.d = pmv[ pmv_off + 3 + 3 * 4 ] - pmv[ pmv_off + 0 + 3 * 4 ]; } - // Bottom: a = m41 + m21, b = m42 + m22, c = m43 + m23, d = m44 + m24 - [1..4] row-major - // Bottom: a = m30 + m10, b = m31 + m11, c = m32 + m12, d = m33 + m13 - [0..3] row-major + // Bottom: a = m41 + m21, b = m42 + m22, c = m43 + m23, d = m44 + m24 - [1..4] column-major + // Bottom: a = m30 + m10, b = m31 + m11, c = m32 + m12, d = m33 + m13 - [0..3] column-major { final Plane p = planes[BOTTOM]; final float[] p_n = p.n; @@ -219,8 +219,8 @@ public class Frustum { p.d = pmv[ pmv_off + 3 + 3 * 4 ] + pmv[ pmv_off + 1 + 3 * 4 ]; } - // Top: a = m41 - m21, b = m42 - m22, c = m43 - m23, d = m44 - m24 - [1..4] row-major - // Top: a = m30 - m10, b = m31 - m11, c = m32 - m12, d = m33 - m13 - [0..3] row-major + // Top: a = m41 - m21, b = m42 - m22, c = m43 - m23, d = m44 - m24 - [1..4] column-major + // Top: a = m30 - m10, b = m31 - m11, c = m32 - m12, d = m33 - m13 - [0..3] column-major { final Plane p = planes[TOP]; final float[] p_n = p.n; @@ -230,8 +230,8 @@ public class Frustum { p.d = pmv[ pmv_off + 3 + 3 * 4 ] - pmv[ pmv_off + 1 + 3 * 4 ]; } - // Near: a = m41 + m31, b = m42 + m32, c = m43 + m33, d = m44 + m34 - [1..4] row-major - // Near: a = m30 + m20, b = m31 + m21, c = m32 + m22, d = m33 + m23 - [0..3] row-major + // Near: a = m41 + m31, b = m42 + m32, c = m43 + m33, d = m44 + m34 - [1..4] column-major + // Near: a = m30 + m20, b = m31 + m21, c = m32 + m22, d = m33 + m23 - [0..3] column-major { final Plane p = planes[NEAR]; final float[] p_n = p.n; @@ -241,8 +241,8 @@ public class Frustum { p.d = pmv[ pmv_off + 3 + 3 * 4 ] + pmv[ pmv_off + 2 + 3 * 4 ]; } - // Far: a = m41 - m31, b = m42 - m32, c = m43 - m33, d = m44 - m34 - [1..4] row-major - // Far: a = m30 - m20, b = m31 - m21, c = m32 + m22, d = m33 + m23 - [0..3] row-major + // Far: a = m41 - m31, b = m42 - m32, c = m43 - m33, d = m44 - m34 - [1..4] column-major + // Far: a = m30 - m20, b = m31 - m21, c = m32 + m22, d = m33 + m23 - [0..3] column-major { final Plane p = planes[FAR]; final float[] p_n = p.n; diff --git a/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java b/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java index 270bf34f6..2001f8cdf 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java +++ b/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java @@ -247,10 +247,11 @@ public class PMVMatrix implements GLMatrixFunc { } FloatUtil.makeIdentityf(matrixIdent); - vec3f = new float[3]; + tmpVec3f = new float[3]; + tmpMatrix = new float[16]; + matrixRot = new float[16]; matrixMult = new float[16]; matrixTrans = new float[16]; - matrixRot = new float[16]; matrixScale = new float[16]; matrixOrtho = new float[16]; matrixFrustum = new float[16]; @@ -277,45 +278,12 @@ public class PMVMatrix implements GLMatrixFunc { requestMask = 0; matrixMode = GL_MODELVIEW; - mulPMV = null; frustum = null; } /** @see #PMVMatrix(boolean) */ public final boolean usesBackingArray() { return usesBackingArray; } - public final void destroy() { - if(null!=projectFloat) { - projectFloat.destroy(); projectFloat=null; - } - - matrixBuffer=null; - matrixBuffer=null; matrixPMvMvit=null; matrixPMvMvi=null; matrixPMv=null; - matrixP=null; matrixTex=null; matrixMv=null; matrixMvi=null; matrixMvit=null; - - vec3f = null; - matrixMult = null; - matrixTrans = null; - matrixRot = null; - matrixScale = null; - matrixOrtho = null; - matrixFrustum = null; - - if(null!=matrixPStack) { - matrixPStack=null; - } - if(null!=matrixMvStack) { - matrixMvStack=null; - } - if(null!=matrixPStack) { - matrixPStack=null; - } - if(null!=matrixTStack) { - matrixTStack=null; - } - } - - /** Returns the current matrix-mode, one of {@link GLMatrixFunc#GL_MODELVIEW GL_MODELVIEW}, {@link GLMatrixFunc#GL_PROJECTION GL_PROJECTION} or {@link GL#GL_TEXTURE GL_TEXTURE}. */ public final int glGetMatrixMode() { return matrixMode; @@ -651,11 +619,11 @@ public class PMVMatrix implements GLMatrixFunc { @Override public final void glTranslatef(final float x, final float y, final float z) { - // Translation matrix: - // 1 0 0 x - // 0 1 0 y - // 0 0 1 z - // 0 0 0 1 + // Translation matrix (Column Order): + // 1 0 0 0 + // 0 1 0 0 + // 0 0 1 0 + // x y z 1 matrixTrans[0+4*3] = x; matrixTrans[1+4*3] = y; matrixTrans[2+4*3] = z; @@ -663,45 +631,15 @@ public class PMVMatrix implements GLMatrixFunc { } @Override - public final void glRotatef(final float angdeg, float x, float y, float z) { - final float angrad = angdeg * (float) Math.PI / 180.0f; - final float c = (float)Math.cos(angrad); - final float ic= 1.0f - c; - final float s = (float)Math.sin(angrad); - - vec3f[0]=x; vec3f[1]=y; vec3f[2]=z; - FloatUtil.normalize(vec3f); - x = vec3f[0]; y = vec3f[1]; z = vec3f[2]; - - // Rotation matrix: - // xx(1-c)+c xy(1-c)+zs xz(1-c)-ys 0 - // xy(1-c)-zs yy(1-c)+c yz(1-c)+xs 0 - // xz(1-c)+ys yz(1-c)-xs zz(1-c)+c 0 - // 0 0 0 1 - final float xy = x*y; - final float xz = x*z; - final float xs = x*s; - final float ys = y*s; - final float yz = y*z; - final float zs = z*s; - matrixRot[0*4+0] = x*x*ic+c; - matrixRot[0*4+1] = xy*ic+zs; - matrixRot[0*4+2] = xz*ic-ys; - - matrixRot[1*4+0] = xy*ic-zs; - matrixRot[1*4+1] = y*y*ic+c; - matrixRot[1*4+2] = yz*ic+xs; - - matrixRot[2*4+0] = xz*ic+ys; - matrixRot[2*4+1] = yz*ic-xs; - matrixRot[2*4+2] = z*z*ic+c; - + public final void glRotatef(final float angdeg, final float x, final float y, final float z) { + final float angrad = angdeg * FloatUtil.PI / 180.0f; + FloatUtil.makeRotationAxis(angrad, x, y, z, matrixRot, 0, tmpVec3f); glMultMatrixf(matrixRot, 0); } @Override public final void glScalef(final float x, final float y, final float z) { - // Scale matrix: + // Scale matrix (Any Order): // x 0 0 0 // 0 y 0 0 // 0 0 z 0 @@ -715,11 +653,11 @@ public class PMVMatrix implements GLMatrixFunc { @Override public final void glOrthof(final float left, final float right, final float bottom, final float top, final float zNear, final float zFar) { - // Ortho matrix: - // 2/dx 0 0 tx - // 0 2/dy 0 ty - // 0 0 2/dz tz - // 0 0 0 1 + // Ortho matrix (Column Order): + // 2/dx 0 0 0 + // 0 2/dy 0 0 + // 0 0 2/dz 0 + // tx ty tz 1 final float dx=right-left; final float dy=top-bottom; final float dz=zFar-zNear; @@ -745,11 +683,11 @@ public class PMVMatrix implements GLMatrixFunc { if(left==right || top==bottom) { throw new GLException("GL_INVALID_VALUE: top,bottom and left,right must not be equal"); } - // Frustum matrix: - // 2*zNear/dx 0 A 0 - // 0 2*zNear/dy B 0 - // 0 0 C D - // 0 0 -1 0 + // Frustum matrix (Column Order): + // 2*zNear/dx 0 0 0 + // 0 2*zNear/dy 0 0 + // A B C -1 + // 0 0 D 0 final float zNear2 = 2.0f*zNear; final float dx=right-left; final float dy=top-bottom; @@ -1041,10 +979,9 @@ public class PMVMatrix implements GLMatrixFunc { if( 0 != ( dirtyBits & ( DIRTY_FRUSTUM & requestMask ) ) ) { if( null == frustum ) { frustum = new Frustum(); - mulPMV = new float[16]; } - FloatUtil.multMatrixf(matrixP, matrixMv, mulPMV, 0); - frustum.updateByPMV(mulPMV, 0); + FloatUtil.multMatrixf(matrixP, matrixMv, tmpMatrix, 0); + frustum.updateByPMV(tmpMatrix, 0); dirtyBits &= ~DIRTY_FRUSTUM; mod = true; } @@ -1118,17 +1055,17 @@ public class PMVMatrix implements GLMatrixFunc { return res; } - protected final float[] matrixBufferArray; protected final boolean usesBackingArray; - protected Buffer matrixBuffer; - protected FloatBuffer matrixIdent, matrixPMvMvit, matrixPMvMvi, matrixPMv, matrixP, matrixTex, matrixMv, matrixMvi, matrixMvit; - protected float[] matrixMult, matrixTrans, matrixRot, matrixScale, matrixOrtho, matrixFrustum, vec3f; - protected FloatStack matrixTStack, matrixPStack, matrixMvStack; + protected final float[] matrixBufferArray; + protected final Buffer matrixBuffer; + protected final FloatBuffer matrixIdent, matrixPMvMvit, matrixPMvMvi, matrixPMv, matrixP, matrixTex, matrixMv, matrixMvi, matrixMvit; + protected final float[] matrixMult, matrixTrans, matrixRot, matrixScale, matrixOrtho, matrixFrustum, tmpVec3f; + protected final float[] tmpMatrix; + protected final FloatStack matrixTStack, matrixPStack, matrixMvStack; + protected final ProjectFloat projectFloat; protected int matrixMode = GL_MODELVIEW; protected int modifiedBits = MODIFIED_ALL; protected int dirtyBits = DIRTY_ALL; // contains the dirty bits, i.e. hinting for update operation protected int requestMask = 0; // may contain the requested dirty bits: DIRTY_INVERSE_MODELVIEW | DIRTY_INVERSE_TRANSPOSED_MODELVIEW - protected ProjectFloat projectFloat; - protected float[] mulPMV; // premultiplied PMV protected Frustum frustum; } diff --git a/src/jogl/classes/jogamp/graph/geom/plane/AffineTransform.java b/src/jogl/classes/jogamp/graph/geom/plane/AffineTransform.java index 621802c36..362c29204 100644 --- a/src/jogl/classes/jogamp/graph/geom/plane/AffineTransform.java +++ b/src/jogl/classes/jogamp/graph/geom/plane/AffineTransform.java @@ -24,6 +24,7 @@ package jogamp.graph.geom.plane; import com.jogamp.graph.geom.Vertex; import com.jogamp.graph.geom.Vertex.Factory; import com.jogamp.opengl.math.FloatUtil; +import com.jogamp.opengl.math.geom.AABBox; public class AffineTransform implements Cloneable { @@ -355,27 +356,63 @@ public class AffineTransform implements Cloneable { /** * Multiply matrix of two AffineTransform objects. * The first argument's {@link Vertex.Factory} is being used. + * @param tL - the AffineTransform object is a multiplicand (left argument) + * @param tR - the AffineTransform object is a multiplier (right argument) * - * @param t1 - the AffineTransform object is a multiplicand - * @param t2 - the AffineTransform object is a multiplier - * @return an AffineTransform object that is a result of t1 multiplied by matrix t2. + * @return A new AffineTransform object containing the result of [tL] X [tR]. */ - AffineTransform multiply(AffineTransform t1, AffineTransform t2) { - return new AffineTransform(t1.pointFactory, - t1.m00 * t2.m00 + t1.m10 * t2.m01, // m00 - t1.m00 * t2.m10 + t1.m10 * t2.m11, // m01 - t1.m01 * t2.m00 + t1.m11 * t2.m01, // m10 - t1.m01 * t2.m10 + t1.m11 * t2.m11, // m11 - t1.m02 * t2.m00 + t1.m12 * t2.m01 + t2.m02, // m02 - t1.m02 * t2.m10 + t1.m12 * t2.m11 + t2.m12);// m12 + public final static AffineTransform multiply(final AffineTransform tL, final AffineTransform tR) { + return new AffineTransform(tR.pointFactory, + tR.m00 * tL.m00 + tR.m10 * tL.m01, // m00 + tR.m00 * tL.m10 + tR.m10 * tL.m11, // m10 + tR.m01 * tL.m00 + tR.m11 * tL.m01, // m01 + tR.m01 * tL.m10 + tR.m11 * tL.m11, // m11 + tR.m02 * tL.m00 + tR.m12 * tL.m01 + tL.m02, // m02 + tR.m02 * tL.m10 + tR.m12 * tL.m11 + tL.m12);// m12 } - public final void concatenate(AffineTransform t) { - setTransform(multiply(t, this)); + /** + * Concatenates the given matrix to this. + * <p> + * Implementations performs the matrix multiplication: + * <pre> + * [this] = [this] X [tR] + * </pre> + * </p> + * @param tR the right-argument of the matrix multiplication + */ + public final void concatenate(AffineTransform tR) { + // setTransform(multiply(this, tR)); + type = TYPE_UNKNOWN; + setTransform( + tR.m00 * m00 + tR.m10 * m01, // m00 + tR.m00 * m10 + tR.m10 * m11, // m10 + tR.m01 * m00 + tR.m11 * m01, // m01 + tR.m01 * m10 + tR.m11 * m11, // m11 + tR.m02 * m00 + tR.m12 * m01 + m02, // m02 + tR.m02 * m10 + tR.m12 * m11 + m12);// m12 } - public final void preConcatenate(AffineTransform t) { - setTransform(multiply(this, t)); + /** + * Pre-concatenates the given matrix to this. + * <p> + * Implementations performs the matrix multiplication: + * <pre> + * [this] = [tL] X [this] + * </pre> + * </p> + * @param tL the left-argument of the matrix multiplication + */ + public final void preConcatenate(AffineTransform tL) { + // setTransform(multiply(tL, this)); + type = TYPE_UNKNOWN; + setTransform( + m00 * tL.m00 + m10 * tL.m01, // m00 + m00 * tL.m10 + m10 * tL.m11, // m10 + m01 * tL.m00 + m11 * tL.m01, // m01 + m01 * tL.m10 + m11 * tL.m11, // m11 + m02 * tL.m00 + m12 * tL.m01 + tL.m02, // m02 + m02 * tL.m10 + m12 * tL.m11 + tL.m12);// m12 } public final AffineTransform createInverse() throws NoninvertibleTransformException { @@ -394,6 +431,17 @@ public class AffineTransform implements Cloneable { ); } + public final AABBox transform(final AABBox src, AABBox dst) { + if (dst == null) { + dst = new AABBox(); + } + final float[] srcLo = src.getLow(); + final float[] srcHi = src.getHigh(); + dst.setSize(srcLo[0] * m00 + srcLo[1] * m01 + m02, srcLo[0] * m10 + srcLo[1] * m11 + m12, srcLo[2], + srcHi[0] * m00 + srcHi[1] * m01 + m02, srcHi[0] * m10 + srcHi[1] * m11 + m12, srcHi[2]); + return dst; + } + public final Vertex transform(final Vertex src, Vertex dst) { if (dst == null) { dst = pointFactory.create(src.getId(), src.isOnCurve(), src.getTexCoord()); diff --git a/src/jogl/classes/jogamp/opengl/ProjectFloat.java b/src/jogl/classes/jogamp/opengl/ProjectFloat.java index d4fd1c935..80c142429 100644 --- a/src/jogl/classes/jogamp/opengl/ProjectFloat.java +++ b/src/jogl/classes/jogamp/opengl/ProjectFloat.java @@ -123,6 +123,7 @@ import javax.media.opengl.fixedfunc.GLMatrixFunc; import com.jogamp.common.nio.Buffers; import com.jogamp.opengl.math.FloatUtil; +import com.jogamp.opengl.math.VectorUtil; /** * ProjectFloat.java @@ -407,14 +408,14 @@ public class ProjectFloat { up[1] = upy; up[2] = upz; - FloatUtil.normalize(forward); + VectorUtil.normalize(forward); /* Side = forward x up */ - FloatUtil.cross(forward, up, side); - FloatUtil.normalize(side); + VectorUtil.cross(side, forward, up); + VectorUtil.normalize(side); /* Recompute up as: up = side x forward */ - FloatUtil.cross(side, forward, up); + VectorUtil.cross(up, side, forward); FloatUtil.makeIdentityf(matrixBuf); final int mPos = matrixBuf.position(); diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/GLSLTextureRaster.java b/src/jogl/classes/jogamp/opengl/util/glsl/GLSLTextureRaster.java index dba408554..09da8c9ee 100644 --- a/src/jogl/classes/jogamp/opengl/util/glsl/GLSLTextureRaster.java +++ b/src/jogl/classes/jogamp/opengl/util/glsl/GLSLTextureRaster.java @@ -147,10 +147,7 @@ public class GLSLTextureRaster { if(null != pmvMatrixUniform) { pmvMatrixUniform = null; } - if(null != pmvMatrix) { - pmvMatrix.destroy(); - pmvMatrix=null; - } + pmvMatrix=null; if(null != interleavedVBO) { interleavedVBO.destroy(gl); interleavedVBO=null; diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/FixedFuncHook.java b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/FixedFuncHook.java index 458a9c94f..ff8006cf8 100644 --- a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/FixedFuncHook.java +++ b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/FixedFuncHook.java @@ -101,9 +101,6 @@ public class FixedFuncHook implements GLLightingFunc, GLMatrixFunc, GLPointerFun public void destroy() { fixedFunction.destroy(gl); fixedFunction = null; - if(ownsPMVMatrix) { - pmvMatrix.destroy(); - } pmvMatrix=null; gl=null; } diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/PointsDemoES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/PointsDemoES2.java index 52af4916c..573c91636 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/PointsDemoES2.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/PointsDemoES2.java @@ -54,9 +54,9 @@ public class PointsDemoES2 extends PointsDemo { final int edge = 8; // 8*8 /** vec4[2]: { (sz, smooth, attnMinSz, attnMaxSz), (attnCoeff(3), attnFadeTs) } */ private static final String mgl_PointParams = "mgl_PointParams"; - + /** ( pointSize, pointSmooth, attn. pointMinSize, attn. pointMaxSize ) , ( attenuation coefficients 1f 0f 0f, attenuation fade theshold 1f ) */ - private final FloatBuffer pointParams = Buffers.newDirectFloatBuffer(new float[] { 1.0f, 0.0f, 0.0f, 4096.0f, 1.0f, 0.0f, 0.0f, 1.0f }); + private final FloatBuffer pointParams = Buffers.newDirectFloatBuffer(new float[] { 1.0f, 0.0f, 0.0f, 4096.0f, 1.0f, 0.0f, 0.0f, 1.0f }); public PointsDemoES2(int swapInterval) { this.swapInterval = swapInterval; @@ -65,29 +65,29 @@ public class PointsDemoES2 extends PointsDemo { public PointsDemoES2() { this.swapInterval = 1; } - - public void setSmoothPoints(boolean v) { - pointParams.put(1, v ? 1.0f : 0.0f); + + public void setSmoothPoints(boolean v) { + pointParams.put(1, v ? 1.0f : 0.0f); } - + public void setPointParams(float minSize, float maxSize, float distAttenConst, float distAttenLinear, float distAttenQuadratic, float fadeThreshold) { pointParams.put(2, minSize); pointParams.put(3, maxSize); pointParams.put(4+0, distAttenConst); pointParams.put(4+1, distAttenLinear); pointParams.put(4+2, distAttenQuadratic); - pointParams.put(4+3, fadeThreshold); + pointParams.put(4+3, fadeThreshold); } - + public void init(GLAutoDrawable glad) { GL2ES2 gl = glad.getGL().getGL2ES2(); - + System.err.println("GL_VENDOR: " + gl.glGetString(GL.GL_VENDOR)); System.err.println("GL_RENDERER: " + gl.glGetString(GL.GL_RENDERER)); System.err.println("GL_VERSION: " + gl.glGetString(GL.GL_VERSION)); System.err.println("GL GLSL: "+gl.hasGLSL()+", has-compiler-func: "+gl.isFunctionAvailable("glCompileShader")+", version "+(gl.hasGLSL() ? gl.glGetString(GL2ES2.GL_SHADING_LANGUAGE_VERSION) : "none")); System.err.println("GL Profile: "+gl.getGLProfile()); - + st = new ShaderState(); st.setVerbose(true); final ShaderCode vp0 = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, this.getClass(), "shader", @@ -100,23 +100,23 @@ public class PointsDemoES2 extends PointsDemo { sp0.add(gl, vp0, System.err); sp0.add(gl, fp0, System.err); st.attachShaderProgram(gl, sp0, true); - + // setup mgl_PMVMatrix pmvMatrix = new PMVMatrix(); pmvMatrix.glMatrixMode(PMVMatrix.GL_PROJECTION); pmvMatrix.glLoadIdentity(); pmvMatrix.glMatrixMode(PMVMatrix.GL_MODELVIEW); - pmvMatrix.glLoadIdentity(); + pmvMatrix.glLoadIdentity(); pmvMatrixUniform = new GLUniformData("mgl_PMVMatrix", 4, 4, pmvMatrix.glGetPMvMatrixf()); // P, Mv st.ownUniform(pmvMatrixUniform); - st.uniform(gl, pmvMatrixUniform); - + st.uniform(gl, pmvMatrixUniform); + st.uniform(gl, new GLUniformData(mgl_PointParams, 4, pointParams)); - + final GLUniformData colorStaticUniform = new GLUniformData("mgl_ColorStatic", 4, Buffers.newDirectFloatBuffer(new float[] { 1.0f, 1.0f, 1.0f, 1.0f }) ); st.uniform(gl, colorStaticUniform); st.ownUniform(colorStaticUniform); - + // Allocate Vertex Array vertices = GLArrayDataServer.createGLSL("mgl_Vertex", 3, GL.GL_FLOAT, false, edge*edge, GL.GL_STATIC_DRAW); pointSizes = GLArrayDataServer.createGLSL("mgl_PointSize", 1, GL.GL_FLOAT, false, edge*edge, GL.GL_STATIC_DRAW); @@ -139,7 +139,7 @@ public class PointsDemoES2 extends PointsDemo { // OpenGL Render Settings gl.glEnable(GL2ES2.GL_DEPTH_TEST); - st.useProgram(gl, false); + st.useProgram(gl, false); } public void display(GLAutoDrawable glad) { @@ -150,17 +150,17 @@ public class PointsDemoES2 extends PointsDemo { pmvMatrix.glMatrixMode(PMVMatrix.GL_MODELVIEW); pmvMatrix.glLoadIdentity(); pmvMatrix.glTranslatef(0, 0, -10); - st.uniform(gl, pmvMatrixUniform); + st.uniform(gl, pmvMatrixUniform); GLUniformData ud = st.getUniform(mgl_PointParams); if(null!=ud) { - // same data object + // same data object st.uniform(gl, ud); } - + vertices.enableBuffer(gl, true); pointSizes.enableBuffer(gl, true); - + if(gl.isGL2GL3()) { gl.glEnable(GL2GL3.GL_VERTEX_PROGRAM_POINT_SIZE); } @@ -171,11 +171,11 @@ public class PointsDemoES2 extends PointsDemo { gl.glBlendFunc ( GL.GL_SRC_ALPHA, GL.GL_ONE ); gl.glDrawArrays(GL.GL_POINTS, 0, edge*edge); - + if(gl.isGL2GL3()) { gl.glDisable(GL2GL3.GL_VERTEX_PROGRAM_POINT_SIZE); } - + pointSizes.enableBuffer(gl, false); vertices.enableBuffer(gl, false); st.useProgram(gl, false); @@ -184,11 +184,11 @@ public class PointsDemoES2 extends PointsDemo { public void reshape(GLAutoDrawable glad, int x, int y, int width, int height) { // Thread.dumpStack(); GL2ES2 gl = glad.getGL().getGL2ES2(); - - if(-1 != swapInterval) { + + if(-1 != swapInterval) { gl.setSwapInterval(swapInterval); // in case switching the drawable (impl. may bound attribute there) } - + st.useProgram(gl, true); // Set location in front of camera pmvMatrix.glMatrixMode(PMVMatrix.GL_PROJECTION); @@ -203,7 +203,6 @@ public class PointsDemoES2 extends PointsDemo { GL2ES2 gl = glad.getGL().getGL2ES2(); st.destroy(gl); st = null; - pmvMatrix.destroy(); pmvMatrix = null; - } + } } diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java index 715a97d63..9f850c35b 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java @@ -62,17 +62,17 @@ public class RedSquareES2 implements GLEventListener, TileRendererBase.TileRende public RedSquareES2() { this.swapInterval = 1; } - + @Override public void addTileRendererNotify(TileRendererBase tr) { tileRendererInUse = tr; doRotateBeforePrinting = doRotate; - setDoRotation(false); + setDoRotation(false); } @Override public void removeTileRendererNotify(TileRendererBase tr) { tileRendererInUse = null; - setDoRotation(doRotateBeforePrinting); + setDoRotation(doRotateBeforePrinting); } @Override public void startTileRendering(TileRendererBase tr) { @@ -82,16 +82,16 @@ public class RedSquareES2 implements GLEventListener, TileRendererBase.TileRende public void endTileRendering(TileRendererBase tr) { System.err.println("RedSquareES2.endTileRendering: "+tr); } - + public void setAspect(float aspect) { this.aspect = aspect; } public void setDoRotation(boolean rotate) { this.doRotate = rotate; } public void setClearBuffers(boolean v) { clearBuffers = v; } - + @Override public void init(GLAutoDrawable glad) { System.err.println(Thread.currentThread()+" RedSquareES2.init: tileRendererInUse "+tileRendererInUse); final GL2ES2 gl = glad.getGL().getGL2ES2(); - + System.err.println("RedSquareES2 init on "+Thread.currentThread()); System.err.println("Chosen GLCapabilities: " + glad.getChosenGLCapabilities()); System.err.println("INIT GL IS: " + gl.getClass().getName()); @@ -112,17 +112,17 @@ public class RedSquareES2 implements GLEventListener, TileRendererBase.TileRende sp0.add(gl, vp0, System.err); sp0.add(gl, fp0, System.err); st.attachShaderProgram(gl, sp0, true); - + // setup mgl_PMVMatrix pmvMatrix = new PMVMatrix(); pmvMatrix.glMatrixMode(PMVMatrix.GL_PROJECTION); pmvMatrix.glLoadIdentity(); pmvMatrix.glMatrixMode(PMVMatrix.GL_MODELVIEW); - pmvMatrix.glLoadIdentity(); + pmvMatrix.glLoadIdentity(); pmvMatrixUniform = new GLUniformData("mgl_PMVMatrix", 4, 4, pmvMatrix.glGetPMvMatrixf()); // P, Mv st.ownUniform(pmvMatrixUniform); - st.uniform(gl, pmvMatrixUniform); - + st.uniform(gl, pmvMatrixUniform); + // Allocate Vertex Array vertices = GLArrayDataServer.createGLSL("mgl_Vertex", 3, GL.GL_FLOAT, false, 4, GL.GL_STATIC_DRAW); vertices.putf(-2); vertices.putf( 2); vertices.putf( 0); @@ -132,20 +132,20 @@ public class RedSquareES2 implements GLEventListener, TileRendererBase.TileRende vertices.seal(gl, true); st.ownAttribute(vertices, true); vertices.enableBuffer(gl, false); - + // Allocate Color Array colors= GLArrayDataServer.createGLSL("mgl_Color", 4, GL.GL_FLOAT, false, 4, GL.GL_STATIC_DRAW); colors.putf(1); colors.putf(0); colors.putf(0); colors.putf(1); colors.putf(0); colors.putf(0); colors.putf(1); colors.putf(1); colors.putf(1); colors.putf(0); colors.putf(0); colors.putf(1); colors.putf(1); colors.putf(0); colors.putf(0); colors.putf(1); - colors.seal(gl, true); + colors.seal(gl, true); st.ownAttribute(colors, true); colors.enableBuffer(gl, false); - + // OpenGL Render Settings gl.glEnable(GL2ES2.GL_DEPTH_TEST); - st.useProgram(gl, false); + st.useProgram(gl, false); t0 = System.currentTimeMillis(); System.err.println(Thread.currentThread()+" RedSquareES2.init FIN"); @@ -173,11 +173,11 @@ public class RedSquareES2 implements GLEventListener, TileRendererBase.TileRende pmvMatrix.glLoadIdentity(); pmvMatrix.glTranslatef(0, 0, -10); if(doRotate) { - float ang = ((float) (t1 - t0) * 360.0F) / 4000.0F; + float ang = ((t1 - t0) * 360.0F) / 4000.0F; pmvMatrix.glRotatef(ang, 0, 0, 1); pmvMatrix.glRotatef(ang, 0, 1, 0); } - st.uniform(gl, pmvMatrixUniform); + st.uniform(gl, pmvMatrixUniform); // Draw a square vertices.enableBuffer(gl, true); @@ -191,39 +191,39 @@ public class RedSquareES2 implements GLEventListener, TileRendererBase.TileRende @Override public void reshape(GLAutoDrawable glad, int x, int y, int width, int height) { final GL2ES2 gl = glad.getGL().getGL2ES2(); - if(-1 != swapInterval) { + if(-1 != swapInterval) { gl.setSwapInterval(swapInterval); } reshapeImpl(gl, x, y, width, height, width, height); } - + @Override public void reshapeTile(TileRendererBase tr, - int tileX, int tileY, int tileWidth, int tileHeight, + int tileX, int tileY, int tileWidth, int tileHeight, int imageWidth, int imageHeight) { final GL2ES2 gl = tr.getAttachedDrawable().getGL().getGL2ES2(); gl.setSwapInterval(0); reshapeImpl(gl, tileX, tileY, tileWidth, tileHeight, imageWidth, imageHeight); } - + void reshapeImpl(GL2ES2 gl, int tileX, int tileY, int tileWidth, int tileHeight, int imageWidth, int imageHeight) { System.err.println(Thread.currentThread()+" RedSquareES2.reshape "+tileX+"/"+tileY+" "+tileWidth+"x"+tileHeight+" of "+imageWidth+"x"+imageHeight+", swapInterval "+swapInterval+", drawable 0x"+Long.toHexString(gl.getContext().getGLDrawable().getHandle())+", tileRendererInUse "+tileRendererInUse); // Thread.dumpStack(); if( !gl.hasGLSL() ) { return; } - + st.useProgram(gl, true); // Set location in front of camera pmvMatrix.glMatrixMode(PMVMatrix.GL_PROJECTION); pmvMatrix.glLoadIdentity(); - + // compute projection parameters 'normal' perspective final float fovy=45f; final float aspect2 = ( (float) imageWidth / (float) imageHeight ) / aspect; final float zNear=1f; final float zFar=100f; - + // compute projection parameters 'normal' frustum final float top=(float)Math.tan(fovy*((float)Math.PI)/360.0f)*zNear; final float bottom=-1.0f*top; @@ -231,18 +231,18 @@ public class RedSquareES2 implements GLEventListener, TileRendererBase.TileRende final float right=aspect2*top; final float w = right - left; final float h = top - bottom; - + // compute projection parameters 'tiled' final float l = left + tileX * w / imageWidth; final float r = l + tileWidth * w / imageWidth; final float b = bottom + tileY * h / imageHeight; final float t = b + tileHeight * h / imageHeight; - + pmvMatrix.glFrustumf(l, r, b, t, zNear, zFar); //pmvMatrix.glOrthof(-4.0f, 4.0f, -4.0f, 4.0f, 1.0f, 100.0f); st.uniform(gl, pmvMatrixUniform); st.useProgram(gl, false); - + System.err.println(Thread.currentThread()+" RedSquareES2.reshape FIN"); } @@ -255,8 +255,7 @@ public class RedSquareES2 implements GLEventListener, TileRendererBase.TileRende } st.destroy(gl); st = null; - pmvMatrix.destroy(); pmvMatrix = null; System.err.println(Thread.currentThread()+" RedSquareES2.dispose FIN"); - } + } } diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareMappedES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareMappedES2.java index f0c9fc6ed..113cbee26 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareMappedES2.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareMappedES2.java @@ -274,7 +274,6 @@ public class RedSquareMappedES2 implements GLEventListener, TileRendererBase.Til } st.destroy(gl); st = null; - pmvMatrix.destroy(); pmvMatrix = null; System.err.println(Thread.currentThread()+" RedSquareES2.dispose FIN"); } diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureDraw01ES2Listener.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureDraw01ES2Listener.java index 8aa3a006c..fb30ef6b5 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureDraw01ES2Listener.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureDraw01ES2Listener.java @@ -3,14 +3,14 @@ * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR @@ -20,12 +20,12 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of JogAmp Community. */ - + package com.jogamp.opengl.test.junit.jogl.demos.es2; import java.nio.FloatBuffer; @@ -53,15 +53,15 @@ public class TextureDraw01ES2Listener implements GLEventListener, TextureDraw01A Texture texture; int textureUnit; boolean keepTextureBound; - + ShaderState st; PMVMatrix pmvMatrix; GLUniformData pmvMatrixUniform; GLArrayDataServer interleavedVBO; float[] clearColor = new float[] { 1.0f, 1.0f, 1.0f, 1.0f }; - + /** - * + * * @param td * @param textureUnit of range [0..] */ @@ -70,7 +70,7 @@ public class TextureDraw01ES2Listener implements GLEventListener, TextureDraw01A this.textureUnit = textureUnit; this.keepTextureBound = false; } - + public void setClearColor(float[] clearColor) { this.clearColor = clearColor; } @@ -83,7 +83,7 @@ public class TextureDraw01ES2Listener implements GLEventListener, TextureDraw01A public Texture getTexture( ) { return this.texture; } - + /** public void setTextureData(GL gl, TextureData textureData ) { if(null!=texture) { @@ -95,21 +95,21 @@ public class TextureDraw01ES2Listener implements GLEventListener, TextureDraw01A } this.textureData = textureData; this.texture = TextureIO.newTexture(this.textureData); - + // fix VBO ! } */ static final String shaderBasename = "texture01_xxx"; - + private void initShader(GL2ES2 gl, boolean use_program) { // Create & Compile the shader objects - ShaderCode rsVp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, this.getClass(), + ShaderCode rsVp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, this.getClass(), "shader", "shader/bin", shaderBasename, true); - ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, this.getClass(), + ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, this.getClass(), "shader", "shader/bin", shaderBasename, true); rsVp.defaultShaderCustomization(gl, true, true); rsFp.defaultShaderCustomization(gl, true, true); - + // Create & Link the shader program ShaderProgram sp = new ShaderProgram(); sp.add(rsVp); @@ -122,24 +122,24 @@ public class TextureDraw01ES2Listener implements GLEventListener, TextureDraw01A st = new ShaderState(); st.attachShaderProgram(gl, sp, use_program); } - + @Override public void init(GLAutoDrawable glad) { if(null!=textureData) { this.texture = TextureIO.newTexture(glad.getGL(), textureData); } GL2ES2 gl = glad.getGL().getGL2ES2(); - + initShader(gl, true); - + // setup mgl_PMVMatrix pmvMatrix = new PMVMatrix(); pmvMatrix.glMatrixMode(PMVMatrix.GL_PROJECTION); pmvMatrix.glLoadIdentity(); pmvMatrix.glMatrixMode(PMVMatrix.GL_MODELVIEW); - pmvMatrix.glLoadIdentity(); + pmvMatrix.glLoadIdentity(); pmvMatrixUniform = new GLUniformData("mgl_PMVMatrix", 4, 4, pmvMatrix.glGetPMvMatrixf()); // P, Mv - + st.ownUniform(pmvMatrixUniform); if(!st.uniform(gl, pmvMatrixUniform)) { throw new GLException("Error setting PMVMatrix in shader: "+st); @@ -150,31 +150,31 @@ public class TextureDraw01ES2Listener implements GLEventListener, TextureDraw01A // fetch the flipped texture coordinates texture.getImageTexCoords().getST_LB_RB_LT_RT(s_quadTexCoords, 0, 1f, 1f); - + interleavedVBO = GLArrayDataServer.createGLSLInterleaved(3+4+2, GL.GL_FLOAT, false, 3*4, GL.GL_STATIC_DRAW); - { - interleavedVBO.addGLSLSubArray("mgl_Vertex", 3, GL.GL_ARRAY_BUFFER); - interleavedVBO.addGLSLSubArray("mgl_Color", 4, GL.GL_ARRAY_BUFFER); + { + interleavedVBO.addGLSLSubArray("mgl_Vertex", 3, GL.GL_ARRAY_BUFFER); + interleavedVBO.addGLSLSubArray("mgl_Color", 4, GL.GL_ARRAY_BUFFER); //interleavedVBO.addGLSLSubArray("mgl_Normal", 3, GL.GL_ARRAY_BUFFER); interleavedVBO.addGLSLSubArray("mgl_MultiTexCoord", 2, GL.GL_ARRAY_BUFFER); FloatBuffer ib = (FloatBuffer)interleavedVBO.getBuffer(); - + for(int i=0; i<4; i++) { ib.put(s_quadVertices, i*3, 3); - ib.put(s_quadColors, i*4, 4); + ib.put(s_quadColors, i*4, 4); //ib.put(s_cubeNormals, i*3, 3); ib.put(s_quadTexCoords, i*2, 2); - } + } } interleavedVBO.seal(gl, true); interleavedVBO.enableBuffer(gl, false); st.ownAttribute(interleavedVBO, true); - + // OpenGL Render Settings gl.glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]); gl.glEnable(GL2ES2.GL_DEPTH_TEST); - + if( keepTextureBound && null != texture ) { gl.glActiveTexture(GL.GL_TEXTURE0 + textureUnit); texture.enable(gl); @@ -186,21 +186,21 @@ public class TextureDraw01ES2Listener implements GLEventListener, TextureDraw01A @Override public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { GL2ES2 gl = drawable.getGL().getGL2ES2(); - + // Clear background to white gl.glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]); if(null != st) { pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION); pmvMatrix.glLoadIdentity(); pmvMatrix.glOrthof(-1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 10.0f); - + pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); pmvMatrix.glLoadIdentity(); - + st.useProgram(gl, true); st.uniform(gl, pmvMatrixUniform); st.useProgram(gl, false); - } + } } @Override @@ -215,7 +215,6 @@ public class TextureDraw01ES2Listener implements GLEventListener, TextureDraw01A } pmvMatrixUniform = null; - pmvMatrix.destroy(); pmvMatrix=null; st.destroy(gl); st=null; @@ -227,38 +226,38 @@ public class TextureDraw01ES2Listener implements GLEventListener, TextureDraw01A gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); - st.useProgram(gl, true); + st.useProgram(gl, true); interleavedVBO.enableBuffer(gl, true); if( !keepTextureBound && null != texture ) { - gl.glActiveTexture(GL.GL_TEXTURE0 + textureUnit); + gl.glActiveTexture(GL.GL_TEXTURE0 + textureUnit); texture.enable(gl); texture.bind(gl); } - + gl.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, 4); - + if( !keepTextureBound && null != texture ) { texture.disable(gl); } - interleavedVBO.enableBuffer(gl, false); + interleavedVBO.enableBuffer(gl, false); st.useProgram(gl, false); } - - private static final float[] s_quadVertices = { + + private static final float[] s_quadVertices = { -1f, -1f, 0f, // LB 1f, -1f, 0f, // RB -1f, 1f, 0f, // LT - 1f, 1f, 0f // RT + 1f, 1f, 0f // RT }; - private static final float[] s_quadColors = { + private static final float[] s_quadColors = { 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f }; - private static final float[] s_quadTexCoords = { + private static final float[] s_quadTexCoords = { 0f, 0f, // LB 1f, 0f, // RB - 0f, 1f, // LT + 0f, 1f, // LT 1f, 1f // RT }; } diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureSequenceCubeES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureSequenceCubeES2.java index 79e0655e3..cdee78fe9 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureSequenceCubeES2.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureSequenceCubeES2.java @@ -348,10 +348,7 @@ public class TextureSequenceCubeES2 implements GLEventListener { texSeq = null; pmvMatrixUniform = null; - if( null != pmvMatrix ) { - pmvMatrix.destroy(); - pmvMatrix=null; - } + pmvMatrix=null; if( null != st ) { st.destroy(gl); st=null; diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java index 6cee4066b..cb78165be 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java @@ -713,7 +713,6 @@ public class MovieSimple implements GLEventListener { } pmvMatrixUniform = null; if(null != pmvMatrix) { - pmvMatrix.destroy(); pmvMatrix=null; } if(null != st) { diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl3/GeomShader01TextureGL3.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl3/GeomShader01TextureGL3.java index e69286311..13f299aeb 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl3/GeomShader01TextureGL3.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl3/GeomShader01TextureGL3.java @@ -3,14 +3,14 @@ * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR @@ -20,7 +20,7 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of JogAmp Community. @@ -60,10 +60,10 @@ import com.jogamp.opengl.util.texture.TextureIO; * geometry shader. * </p> * <p> - * If the <code>XYZ flipping</code> geometry shader functions properly, + * If the <code>XYZ flipping</code> geometry shader functions properly, * the texture will be flipped horizontally and vertically. - * </p> - * + * </p> + * * @author Chuck Ritola December 2012 * @author Sven Gothel (GL3 core, pass-though, core geometry shader) */ @@ -77,7 +77,7 @@ public class GeomShader01TextureGL3 implements GLEventListener { static final String shaderBasename = "texture01_xxx"; static final String[] geomShaderBaseNames = new String[] { "passthrough01_xxx", "flipXYZ01_xxx" }; - + public GeomShader01TextureGL3(int geomShader) { this.geomShader = geomShader; } @@ -100,22 +100,22 @@ public class GeomShader01TextureGL3 implements GLEventListener { if( !ShaderUtil.isGeometryShaderSupported(gl) ) { throw new RuntimeException("GL object not >= 3.2, i.e. no geometry shader support.: "+gl); } - } + } final GL3 gl = drawable.getGL().getGL3(); final ShaderProgram sp; { final ShaderCode vs, gs, fs; - vs = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, this.getClass(), + vs = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, this.getClass(), "shader", "shader/bin", shaderBasename, true); - gs = ShaderCode.create(gl, GL3.GL_GEOMETRY_SHADER, this.getClass(), + gs = ShaderCode.create(gl, GL3.GL_GEOMETRY_SHADER, this.getClass(), "shader", "shader/bin", geomShaderBaseNames[geomShader], true); - fs = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, this.getClass(), - "shader", "shader/bin", shaderBasename, true); + fs = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, this.getClass(), + "shader", "shader/bin", shaderBasename, true); vs.defaultShaderCustomization(gl, true, true); gs.defaultShaderCustomization(gl, true, true); fs.defaultShaderCustomization(gl, true, true); - + sp = new ShaderProgram(); sp.add(gl, vs, System.err); sp.add(gl, gs, System.err); @@ -124,20 +124,20 @@ public class GeomShader01TextureGL3 implements GLEventListener { throw new GLException("Couldn't link program: "+sp); } } - + st=new ShaderState(); st.attachShaderProgram(gl, sp, true); - + // setup mgl_PMVMatrix pmvMatrix = new PMVMatrix(); pmvMatrix.glMatrixMode(PMVMatrix.GL_PROJECTION); pmvMatrix.glLoadIdentity(); pmvMatrix.glMatrixMode(PMVMatrix.GL_MODELVIEW); - pmvMatrix.glLoadIdentity(); + pmvMatrix.glLoadIdentity(); pmvMatrixUniform = new GLUniformData("mgl_PMVMatrix", 4, 4, pmvMatrix.glGetPMvMatrixf()); // P, Mv st.ownUniform(pmvMatrixUniform); - st.uniform(gl, pmvMatrixUniform); - + st.uniform(gl, pmvMatrixUniform); + st.ownUniform(pmvMatrixUniform); if(!st.uniform(gl, pmvMatrixUniform)) { throw new GLException("Error setting PMVMatrix in shader: "+st); @@ -154,13 +154,13 @@ public class GeomShader01TextureGL3 implements GLEventListener { if(null == texture) { throw new RuntimeException("Could not load test texture"); } - + // Tri order: // TL, BL, BR // TL, TR, BR { int i=0; - TextureCoords tc = texture.getImageTexCoords(); + TextureCoords tc = texture.getImageTexCoords(); s_triTexCoords[i++] = tc.left(); s_triTexCoords[i++] = tc.top(); s_triTexCoords[i++] = tc.left(); s_triTexCoords[i++] = tc.bottom(); s_triTexCoords[i++] = tc.right(); s_triTexCoords[i++] = tc.bottom(); @@ -168,25 +168,25 @@ public class GeomShader01TextureGL3 implements GLEventListener { s_triTexCoords[i++] = tc.right(); s_triTexCoords[i++] = tc.top(); s_triTexCoords[i++] = tc.right(); s_triTexCoords[i++] = tc.bottom(); } - + interleavedVBO = GLArrayDataServer.createGLSLInterleaved(2+4+2, GL.GL_FLOAT, false, 3*6, GL.GL_STATIC_DRAW); - { + { interleavedVBO.addGLSLSubArray("mgl_Vertex", 2, GL.GL_ARRAY_BUFFER); interleavedVBO.addGLSLSubArray("mgl_Color", 4, GL.GL_ARRAY_BUFFER); interleavedVBO.addGLSLSubArray("mgl_MultiTexCoord", 2, GL.GL_ARRAY_BUFFER); FloatBuffer ib = (FloatBuffer)interleavedVBO.getBuffer(); - + for(int i=0; i<6; i++) { ib.put(s_triVertices, i*2, 2); ib.put(s_triColors, i*4, 4); ib.put(s_triTexCoords, i*2, 2); - } + } } interleavedVBO.seal(gl, true); interleavedVBO.enableBuffer(gl, false); st.ownAttribute(interleavedVBO, true); - + gl.glClearColor(0f, 0f, 0f, 0f); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); st.useProgram(gl, false); @@ -202,7 +202,7 @@ public class GeomShader01TextureGL3 implements GLEventListener { texData.destroy(); return res; } - + @Override public void dispose(GLAutoDrawable drawable) { final GL3 gl = drawable.getGL().getGL3(); @@ -213,19 +213,18 @@ public class GeomShader01TextureGL3 implements GLEventListener { if(null != st) { pmvMatrixUniform = null; - pmvMatrix.destroy(); pmvMatrix=null; st.destroy(gl); st=null; } } - + @Override public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { GL3 gl = drawable.getGL().getGL3(); - + gl.setSwapInterval(1); - + // Clear background to white gl.glClearColor(1.0f, 1.0f, 1.0f, 0.4f); @@ -233,42 +232,42 @@ public class GeomShader01TextureGL3 implements GLEventListener { pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION); pmvMatrix.glLoadIdentity(); pmvMatrix.glOrthof(-1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 10.0f); - + pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); pmvMatrix.glLoadIdentity(); - + st.useProgram(gl, true); st.uniform(gl, pmvMatrixUniform); st.useProgram(gl, false); - } + } } - + @Override public void display(GLAutoDrawable drawable) { final GL3 gl = drawable.getGL().getGL3(); - + gl.glClear(GL.GL_DEPTH_BUFFER_BIT | GL.GL_COLOR_BUFFER_BIT); if(null != st) { //Draw the image as a pseudo-quad using two triangles - st.useProgram(gl, true); + st.useProgram(gl, true); interleavedVBO.enableBuffer(gl, true); gl.glActiveTexture(GL.GL_TEXTURE0); texture.enable(gl); texture.bind(gl); - + gl.glDrawArrays(GL.GL_TRIANGLES, 0, 6); - - texture.disable(gl); - interleavedVBO.enableBuffer(gl, false); + + texture.disable(gl); + interleavedVBO.enableBuffer(gl, false); st.useProgram(gl, false); } }//end display() - - private static final float[] s_triVertices = { + + private static final float[] s_triVertices = { -1f, 1f, // TL -1f, -1f, // BL - 1f, -1f, // BR + 1f, -1f, // BR -1f, 1f, // TL 1f, 1f, // TR 1f, -1f // BR @@ -281,13 +280,13 @@ public class GeomShader01TextureGL3 implements GLEventListener { 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f }; - private static final float[] s_triTexCoords = { + private static final float[] s_triTexCoords = { 0f, 1f, // TL 0f, 0f, // BL - 1f, 0f, // BR + 1f, 0f, // BR 0f, 1f, // TL 1f, 1f, // TR 1f, 0f // BR }; - + }//end Test |