diff options
16 files changed, 794 insertions, 445 deletions
diff --git a/src/demos/com/jogamp/opengl/demos/es2/GearsES2.java b/src/demos/com/jogamp/opengl/demos/es2/GearsES2.java index 76ee32301..194397a37 100644 --- a/src/demos/com/jogamp/opengl/demos/es2/GearsES2.java +++ b/src/demos/com/jogamp/opengl/demos/es2/GearsES2.java @@ -231,9 +231,9 @@ public class GearsES2 implements StereoGLEventListener, TileRendererBase.TileRen // Use debug pipeline // drawable.setGL(new DebugGL(drawable.getGL())); - pmvMatrix = new PMVMatrix(); + pmvMatrix = new PMVMatrix(PMVMatrix.INVERSE_MODELVIEW | PMVMatrix.INVERSE_TRANSPOSED_MODELVIEW); st.attachObject("pmvMatrix", pmvMatrix); - pmvMatrixUniform = new GLUniformData("pmvMatrix", 4, 4, pmvMatrix.getSyncPMvMvitMat()); // P, Mv, Mvi and Mvit + pmvMatrixUniform = new GLUniformData("pmvMatrix", 4, 4, pmvMatrix.getSyncPMvMviMvitMat()); // P, Mv, Mvi and Mvit st.ownUniform(pmvMatrixUniform); st.uniform(gl, pmvMatrixUniform); diff --git a/src/demos/com/jogamp/opengl/demos/es2/GearsObjectES2.java b/src/demos/com/jogamp/opengl/demos/es2/GearsObjectES2.java index 3aa6696df..9caa4418a 100644 --- a/src/demos/com/jogamp/opengl/demos/es2/GearsObjectES2.java +++ b/src/demos/com/jogamp/opengl/demos/es2/GearsObjectES2.java @@ -123,11 +123,7 @@ public class GearsObjectES2 extends GearsObject { pmvMatrix.glPushMatrix(); pmvMatrix.glTranslatef(x, y, 0f); pmvMatrix.glRotatef(angle, 0f, 0f, 1f); - if( pmvMatrix.update() ) { - st.uniform(gl, pmvMatrixUniform); - } else { - throw new InternalError("PMVMatrix.update() returns false after mutable operations"); - } + st.uniform(gl, pmvMatrixUniform); // automatic sync + update of Mvi + Mvit colorUniform.setData(gearColor); st.uniform(gl, colorUniform); diff --git a/src/graphui/classes/com/jogamp/graph/ui/Group.java b/src/graphui/classes/com/jogamp/graph/ui/Group.java index cfc8dd534..aa6952031 100644 --- a/src/graphui/classes/com/jogamp/graph/ui/Group.java +++ b/src/graphui/classes/com/jogamp/graph/ui/Group.java @@ -147,7 +147,7 @@ public class Group extends Shape implements Container { } } - private final boolean doFrustumCulling = true; // FIXME + private final boolean doFrustumCulling = false; // FIXME @Override protected final void drawImpl0(final GL2ES2 gl, final RegionRenderer renderer, final int[] sampleCount, final float[] rgba) { diff --git a/src/graphui/classes/com/jogamp/graph/ui/Shape.java b/src/graphui/classes/com/jogamp/graph/ui/Shape.java index 0f6b0ec28..10532d462 100644 --- a/src/graphui/classes/com/jogamp/graph/ui/Shape.java +++ b/src/graphui/classes/com/jogamp/graph/ui/Shape.java @@ -527,8 +527,7 @@ public abstract class Shape { final Vec3f high = box.getHigh(); final Vec3f low = box.getLow(); - // Efficiently reuse matPMv and temporary PMVMatrix storage - final Matrix4f matPMv = pmv.mulPMvMat(pmv.getTmp1Mat()); + final Matrix4f matPMv = pmv.getPMvMat(); if( Matrix4f.mapObjToWin(high, matPMv, viewport, winCoordHigh) ) { if( Matrix4f.mapObjToWin(low, matPMv, viewport, winCoordLow) ) { surfaceSize[0] = (int)Math.abs(winCoordHigh.x() - winCoordLow.x()); @@ -706,14 +705,9 @@ public abstract class Shape { public Vec3f winToShapeCoord(final PMVMatrix pmv, final Recti viewport, final int glWinX, final int glWinY, final Vec3f objPos) { final Vec3f ctr = box.getCenter(); - // Efficiently reuse matPMv and temporary PMVMatrix storage - final Matrix4f matPMv = pmv.mulPMvMat(pmv.getTmp1Mat()); - if( Matrix4f.mapObjToWin(ctr, matPMv, viewport, objPos) ) { + if( Matrix4f.mapObjToWin(ctr, pmv.getPMvMat(), viewport, objPos) ) { final float winZ = objPos.z(); - if( !matPMv.invert() ) { - return null; - } - if( Matrix4f.mapWinToObj(glWinX, glWinY, winZ, matPMv, viewport, objPos, pmv.getTmp2Mat()) ) { + if( Matrix4f.mapWinToObj(glWinX, glWinY, winZ, pmv.getPMviMat(), viewport, objPos) ) { return objPos; } } diff --git a/src/jogl/classes/com/jogamp/opengl/math/Matrix4f.java b/src/jogl/classes/com/jogamp/opengl/math/Matrix4f.java index a06d5cefc..67d7d48c1 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/Matrix4f.java +++ b/src/jogl/classes/com/jogamp/opengl/math/Matrix4f.java @@ -1791,18 +1791,19 @@ public class Matrix4f { * @param winx * @param winy * @param winz - * @param invPMv inverse [projection] x [modelview] matrix, i.e. Inv(P x Mv) + * @param invPMv inverse [projection] x [modelview] matrix, i.e. Inv(P x Mv), if null method returns false * @param viewport Rect4i viewport * @param objPos 3 component object coordinate, the result - * @param mat4Tmp 16 component matrix for temp storage - * @return true if successful, otherwise false (failed to invert matrix, or becomes infinity due to zero z) + * @return true if successful, otherwise false (null invert matrix, or becomes infinity due to zero z) */ public static boolean mapWinToObj(final float winx, final float winy, final float winz, final Matrix4f invPMv, final Recti viewport, - final Vec3f objPos, - final Matrix4f mat4Tmp) + final Vec3f objPos) { + if( null == invPMv ) { + return false; + } final Vec4f winPos = new Vec4f(winx, winy, winz, 1f); // Map x and y from window coordinates @@ -1833,18 +1834,19 @@ public class Matrix4f { * @param winy * @param winz1 * @param winz2 - * @param invPMv inverse [projection] x [modelview] matrix, i.e. Inv(P x Mv) + * @param invPMv inverse [projection] x [modelview] matrix, i.e. Inv(P x Mv), if null method returns false * @param viewport Rect4i viewport vector * @param objPos1 3 component object coordinate, the result - * @param mat4Tmp 16 component matrix for temp storage - * @return true if successful, otherwise false (failed to invert matrix, or becomes infinity due to zero z) + * @return true if successful, otherwise false (null invert matrix, or becomes infinity due to zero z) */ public static boolean mapWinToObj(final float winx, final float winy, final float winz1, final float winz2, final Matrix4f invPMv, final Recti viewport, - final Vec3f objPos1, final Vec3f objPos2, - final Matrix4f mat4Tmp) + final Vec3f objPos1, final Vec3f objPos2) { + if( null == invPMv ) { + return false; + } final Vec4f winPos = new Vec4f(winx, winy, winz1, 1f); // Map x and y from window coordinates @@ -1928,6 +1930,49 @@ public class Matrix4f { } /** + * Map window coordinates to object coordinates. + * <p> + * Traditional <code>gluUnProject4</code> implementation. + * </p> + * + * @param winx + * @param winy + * @param winz + * @param clipw + * @param invPMv inverse [projection] x [modelview] matrix, i.e. Inv(P x Mv), if null method returns false + * @param viewport Rect4i viewport vector + * @param near + * @param far + * @param obj_pos 4 component object coordinate, the result + * @return true if successful, otherwise false (null invert matrix, or becomes infinity due to zero z) + */ + public static boolean mapWinToObj4(final float winx, final float winy, final float winz, final float clipw, + final Matrix4f invPMv, + final Recti viewport, + final float near, final float far, + final Vec4f objPos) + { + if( null == invPMv ) { + return false; + } + final Vec4f winPos = new Vec4f(winx, winy, winz, clipw); + + // Map x and y from window coordinates + winPos.add(-viewport.x(), -viewport.y(), -near, 0f).scale(1f/viewport.width(), 1f/viewport.height(), 1f/(far-near), 1f); + + // Map to range -1 to 1 + winPos.scale(2f, 2f, 2f, 1f).add(-1f, -1f, -1f, 0f); + + // objPos = Inv(P x Mv) * winPos + invPMv.mulVec4f(winPos, objPos); + + if ( objPos.w() == 0.0f ) { + return false; + } + return true; + } + + /** * Map two window coordinates w/ shared X/Y and distinctive Z * to a {@link Ray}. The resulting {@link Ray} maybe used for <i>picking</i> * using a {@link AABBox#getRayIntersection(Vec3f, Ray, float, boolean)}. @@ -1952,8 +1997,7 @@ public class Matrix4f { * @return true if successful, otherwise false (failed to invert matrix, or becomes z is infinity) */ public static boolean mapWinToRay(final float winx, final float winy, final float winz0, final float winz1, - final Matrix4f mMv, - final Matrix4f mP, + final Matrix4f mMv, final Matrix4f mP, final Recti viewport, final Ray ray, final Matrix4f mat4Tmp1, final Matrix4f mat4Tmp2) { @@ -1963,8 +2007,40 @@ public class Matrix4f { return false; } - if( mapWinToObj(winx, winy, winz0, winz1, invPMv, viewport, - ray.orig, ray.dir, mat4Tmp2) ) { + if( mapWinToObj(winx, winy, winz0, winz1, invPMv, viewport, ray.orig, ray.dir) ) { + ray.dir.sub(ray.orig).normalize(); + return true; + } else { + return false; + } + } + + /** + * Map two window coordinates w/ shared X/Y and distinctive Z + * to a {@link Ray}. The resulting {@link Ray} maybe used for <i>picking</i> + * using a {@link AABBox#getRayIntersection(Vec3f, Ray, float, boolean)}. + * <p> + * Notes for picking <i>winz0</i> and <i>winz1</i>: + * <ul> + * <li>see {@link FloatUtil#getZBufferEpsilon(int, float, float)}</li> + * <li>see {@link FloatUtil#getZBufferValue(int, float, float, float)}</li> + * <li>see {@link FloatUtil#getOrthoWinZ(float, float, float)}</li> + * </ul> + * </p> + * @param winx + * @param winy + * @param winz0 + * @param winz1 + * @param invPMv inverse [projection] x [modelview] matrix, i.e. Inv(P x Mv), if null method returns false + * @param viewport Rect4i viewport + * @param ray storage for the resulting {@link Ray} + * @return true if successful, otherwise false (null invert matrix, or becomes z is infinity) + */ + public static boolean mapWinToRay(final float winx, final float winy, final float winz0, final float winz1, + final Matrix4f invPMv, + final Recti viewport, + final Ray ray) { + if( mapWinToObj(winx, winy, winz0, winz1, invPMv, viewport, ray.orig, ray.dir) ) { ray.dir.sub(ray.orig).normalize(); return true; } else { diff --git a/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java b/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java index 0cba41f65..c9400889b 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java +++ b/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java @@ -118,14 +118,18 @@ public final class PMVMatrix implements GLMatrixFunc { /** Bit value stating all is modified */ public static final int MODIFIED_ALL = MODIFIED_PROJECTION | MODIFIED_MODELVIEW | MODIFIED_TEXTURE ; - /** Bit value stating a dirty {@link #getMviMat() inverse modelview matrix (Mvi)}. */ - public static final int DIRTY_INVERSE_MODELVIEW = 1 << 0; - /** Bit value stating a dirty {@link #getMvitMat() inverse transposed modelview matrix (Mvit)}. */ - public static final int DIRTY_INVERSE_TRANSPOSED_MODELVIEW = 1 << 1; - /** Bit value stating a dirty {@link #getFrustum() frustum}. */ - public static final int DIRTY_FRUSTUM = 1 << 2; - /** Bit value stating all is dirty */ - public static final int DIRTY_ALL = DIRTY_INVERSE_MODELVIEW | DIRTY_INVERSE_TRANSPOSED_MODELVIEW | DIRTY_FRUSTUM; + /** Bit value for {@link #getMviMat() inverse modelview matrix (Mvi)}, updated via {@link #update()}. */ + public static final int INVERSE_MODELVIEW = 1 << 1; + /** Bit value for {@link #getMvitMat() inverse transposed modelview matrix (Mvit)}, updated via {@link #update()}. */ + public static final int INVERSE_TRANSPOSED_MODELVIEW = 1 << 2; + /** Bit value for {@link #getFrustum() frustum} and updated by {@link #getFrustum()}. */ + public static final int FRUSTUM = 1 << 3; + /** Bit value for {@link #getPMvMat() pre-multiplied P * Mv}, updated by {@link #getPMvMat()}. */ + public static final int PREMUL_PMV = 1 << 4; + /** Bit value for {@link #getPMviMat() pre-multiplied invert(P * Mv)}, updated by {@link #getPMviMat()}. */ + public static final int PREMUL_PMVI = 1 << 5; + /** Manual bits not covered by {@link #update()} but {@link #getFrustum()}, {@link #FRUSTUM}, {@link #getPMvMat()}, {@link #PREMUL_PMV}, {@link #getPMviMat()}, {@link #PREMUL_PMVI}, etc. */ + public static final int MANUAL_BITS = FRUSTUM | PREMUL_PMV | PREMUL_PMVI; /** * @param matrixModeName One of {@link GLMatrixFunc#GL_MODELVIEW GL_MODELVIEW}, {@link GLMatrixFunc#GL_PROJECTION GL_PROJECTION} or {@link GL#GL_TEXTURE GL_TEXTURE} @@ -193,58 +197,131 @@ public final class PMVMatrix implements GLMatrixFunc { /** * Creates an instance of PMVMatrix. * <p> + * This constructor only sets up an instance w/o additional {@link #INVERSE_MODELVIEW} or {@link #INVERSE_TRANSPOSED_MODELVIEW}. + * </p> + * <p> * Implementation uses non-direct non-NIO Buffers with guaranteed backing array, - * which allows faster access in Java computation. + * which are synchronized to the actual Matrix4f instances. + * This allows faster access in Java computation. * </p> + * @see #PMVMatrix(int) */ public PMVMatrix() { - // I Identity - // T Texture - // P Projection - // Mv ModelView - // Mvi Modelview-Inverse - // Mvit Modelview-Inverse-Transpose - - // actual underlying Matrix4f data - matP = new Matrix4f(); - matMv = new Matrix4f(); - matMvi = new Matrix4f(); - matMvit = new Matrix4f(); - matTex = new Matrix4f(); - - // float back buffer for GPU, Matrix4f -> matrixStore via SyncedBuffer - matrixStore = new float[5*16]; - - // FloatBuffer for single Matrix4f back-buffer - matrixP = Buffers.slice2Float(matrixStore, mP_offset, 1*16); // P - matrixMv = Buffers.slice2Float(matrixStore, mMv_offset, 1*16); // Mv - matrixMvi = Buffers.slice2Float(matrixStore, mMvi_offset, 1*16); // Mvi - matrixMvit = Buffers.slice2Float(matrixStore, mMvit_offset, 1*16); // Mvit - matrixTex = Buffers.slice2Float(matrixStore, mTex_offset, 1*16); // T - - // FloatBuffer for aggregated multiple Matrix4f back-buffer - matrixPMvMvit = Buffers.slice2Float(matrixStore, mP_offset, 4*16); // P + Mv + Mvi + Mvit - matrixPMvMvi = Buffers.slice2Float(matrixStore, mP_offset, 3*16); // P + Mv + Mvi - matrixPMv = Buffers.slice2Float(matrixStore, mP_offset, 2*16); // P + Mv - - matPSync = new SyncBuffer0(matP, matrixP); // mP_offset - matMvSync = new SyncBuffer1(matMv, matrixMv, mMv_offset); - matMviSync = new SyncBuffer1(matMvi, matrixMvi, mMvi_offset); - matMvitSync = new SyncBuffer1(matMvit, matrixMvit, mMvit_offset); - matTexSync = new SyncBuffer1(matTex, matrixTex, mTex_offset); - - matPMvMvitSync = new SyncBufferN(new Matrix4f[] { matP, matMv, matMvi, matMvit }, matrixPMvMvit, mP_offset); - matPMvMviSync = new SyncBufferN(new Matrix4f[] { matP, matMv, matMvi }, matrixPMvMvi, mP_offset); - matPMvSync = new SyncBufferN(new Matrix4f[] { matP, matMv }, matrixPMv, mP_offset); - - mat4Tmp1 = new Matrix4f(); - mat4Tmp2 = new Matrix4f(); - vec3Tmp1 = new Vec3f(); - vec4Tmp1 = new Vec4f(); - - reset(); - - frustum = null; + this(0); + } + + /** + * Creates an instance of PMVMatrix. + * <p> + * Additional derived matrices can be requested via `derivedMatrices`, i.e. + * - {@link #INVERSE_MODELVIEW} + * - {@link #INVERSE_TRANSPOSED_MODELVIEW} + * </p> + * <p> + * Implementation uses non-direct non-NIO Buffers with guaranteed backing array, + * which are synchronized to the actual Matrix4f instances. + * This allows faster access in Java computation. + * </p> + * @param derivedMatrices additional matrices can be requested by passing bits {@link #INVERSE_MODELVIEW} and {@link #INVERSE_TRANSPOSED_MODELVIEW}. + * @see #getReqBits() + * @see #isReqDirty() + * @see #getDirtyBits() + * @see #update() + */ + public PMVMatrix(final int derivedMatrices) { + // I Identity + // T Texture + // P Projection + // Mv ModelView + // Mvi Modelview-Inverse + // Mvit Modelview-Inverse-Transpose + { + int mask = 0; + if( 0 != ( derivedMatrices & ( INVERSE_MODELVIEW | INVERSE_TRANSPOSED_MODELVIEW ) ) ) { + mask |= INVERSE_MODELVIEW; + } + if( 0 != ( derivedMatrices & INVERSE_TRANSPOSED_MODELVIEW ) ) { + mask |= INVERSE_TRANSPOSED_MODELVIEW; + } + requestBits = mask; + } + + // actual underlying Matrix4f count + int mcount = 3; + + // actual underlying Matrix4f data + matP = new Matrix4f(); + matMv = new Matrix4f(); + matTex = new Matrix4f(); + + if( 0 != ( requestBits & INVERSE_MODELVIEW ) ) { + matMvi = new Matrix4f(); + mMvi_offset = 2*16; + ++mcount; + } else { + matMvi = null; + mMvi_offset = -1; + } + if( 0 != ( requestBits & INVERSE_TRANSPOSED_MODELVIEW ) ) { + matMvit = new Matrix4f(); + mMvit_offset = 3*16; + ++mcount; + } else { + matMvit = null; + mMvit_offset = -1; + } + mTex_offset = (mcount-1)*16; // last one + + // float back buffer for GPU, Matrix4f -> matrixStore via SyncedBuffer + matrixStore = new float[mcount*16]; + + // FloatBuffer for single Matrix4f back-buffer + bufP = Buffers.slice2Float(matrixStore, mP_offset, 1*16); // P + syncP = new SyncBuffer0(matP, bufP); // mP_offset + + bufMv = Buffers.slice2Float(matrixStore, mMv_offset, 1*16); // Mv + syncMv = new SyncBuffer1(matMv, bufMv, mMv_offset); + + bufP_Mv = Buffers.slice2Float(matrixStore, mP_offset, 2*16); // P + Mv + syncP_Mv = new SyncBufferN(new Matrix4f[] { matP, matMv }, bufP_Mv, mP_offset); + + bufTex = Buffers.slice2Float(matrixStore, mTex_offset, 1*16); // T + syncT = new SyncBuffer1(matTex, bufTex, mTex_offset); + + if( null != matMvi ) { + bufMvi = Buffers.slice2Float(matrixStore, mMvi_offset, 1*16); // Mvi + bufP_Mv_Mvi = Buffers.slice2Float(matrixStore, mP_offset, 3*16); // P + Mv + Mvi + syncMvi = new SyncBuffer1U(matMvi, bufMvi, mMvi_offset); + syncP_Mv_Mvi = new SyncBufferNU(new Matrix4f[] { matP, matMv, matMvi }, bufP_Mv_Mvi, mP_offset); + } else { + bufMvi = null; + bufP_Mv_Mvi = null; + syncMvi = null; + syncP_Mv_Mvi = null; + } + if( null != matMvit ) { + bufMvit = Buffers.slice2Float(matrixStore, mMvit_offset, 1*16); // Mvit + bufP_Mv_Mvi_Mvit = Buffers.slice2Float(matrixStore, mP_offset, 4*16); // P + Mv + Mvi + Mvit + syncMvit = new SyncBuffer1U(matMvit, bufMvit, mMvit_offset); + syncP_Mv_Mvi_Mvit = new SyncBufferNU(new Matrix4f[] { matP, matMv, matMvi, matMvit }, bufP_Mv_Mvi_Mvit, mP_offset); + } else { + bufMvit = null; + bufP_Mv_Mvi_Mvit = null; + syncMvit = null; + syncP_Mv_Mvi_Mvit = null; + } + + mat4Tmp1 = new Matrix4f(); + vec3Tmp1 = new Vec3f(); + vec4Tmp1 = new Vec4f(); + + mat4Tmp2 = null; // on demand + matPMv = null; // on demand + matPMvi = null; // on demand + matPMviOK = false; + frustum = null; // on demand + + reset(); } /** @@ -260,8 +337,7 @@ public final class PMVMatrix implements GLMatrixFunc { matTex.loadIdentity(); modifiedBits = MODIFIED_ALL; - dirtyBits = DIRTY_ALL; - requestMask = 0; + dirtyBits = requestBits | MANUAL_BITS; matrixMode = GL_MODELVIEW; } @@ -275,40 +351,18 @@ public final class PMVMatrix implements GLMatrixFunc { // /** - * Return the first temporary Matrix4f exposed to be reused for efficiency. - * <p> - * Temporary storage is only used by this class within single method calls, - * hence has no side-effects. - * </p> - */ - public final Matrix4f getTmp1Mat() { return mat4Tmp1; } - - /** * Return the second temporary Matrix4f exposed to be reused for efficiency. * <p> * Temporary storage is only used by this class within single method calls, * hence has no side-effects. * </p> */ - public final Matrix4f getTmp2Mat() { return mat4Tmp2; } - - /** - * Return the first temporary Vec3f exposed to be reused for efficiency. - * <p> - * Temporary storage is only used by this class within single method calls, - * hence has no side-effects. - * </p> - */ - public final Vec3f getTmp1Vec3f() { return vec3Tmp1; } - - /** - * Return the first temporary Vec4f exposed to be reused for efficiency. - * <p> - * Temporary storage is only used by this class within single method calls, - * hence has no side-effects. - * </p> - */ - public final Vec4f getTmp1Vec4f() { return vec4Tmp1; } + private final Matrix4f getTmp2Mat() { + if( null == mat4Tmp2 ) { + mat4Tmp2 = new Matrix4f(); + } + return mat4Tmp2; + } // // Regular Matrix4f access as well as their SyncedBuffer counterpart SyncedMatrix and SyncedMatrices @@ -331,7 +385,7 @@ public final class PMVMatrix implements GLMatrixFunc { * </p> */ public final SyncMatrix4f getSyncTMat() { - return matTexSync; + return syncT; } /** @@ -351,7 +405,7 @@ public final class PMVMatrix implements GLMatrixFunc { * </p> */ public final SyncMatrix4f getSyncPMat() { - return matPSync; + return syncP; } /** @@ -371,126 +425,103 @@ public final class PMVMatrix implements GLMatrixFunc { * </p> */ public final SyncMatrix4f getSyncMvMat() { - return matMvSync; + return syncMv; } /** - * Returns the inverse {@link GLMatrixFunc#GL_MODELVIEW_MATRIX modelview matrix} (Mvi). + * Returns {@link SyncMatrices4f} of 2 matrices within one FloatBuffer: {@link #getPMat() P} and {@link #getMvMat() Mv}. * <p> - * Method enables the Mvi matrix update, and performs it's update w/o clearing the modified bits. + * See <a href="#storageDetails"> matrix storage details</a>. * </p> + */ + public final SyncMatrices4f getSyncPMvMat() { + return syncP_Mv; + } + + /** + * Returns the inverse {@link GLMatrixFunc#GL_MODELVIEW_MATRIX modelview matrix} (Mvi) if requested. * <p> - * See {@link #update()} and <a href="#storageDetails"> matrix storage details</a>. + * See <a href="#storageDetails"> matrix storage details</a>. * </p> - * @see #update() - * @see #clearAllUpdateRequests() + * @throws IllegalArgumentException if {@link #INVERSE_MODELVIEW} has not been requested in ctor {@link #PMVMatrix(int)}. */ public final Matrix4f getMviMat() { - requestMask |= DIRTY_INVERSE_MODELVIEW ; + if( 0 == ( INVERSE_MODELVIEW & requestBits ) ) { + throw new IllegalArgumentException("Not requested in ctor"); + } updateImpl(false); return matMvi; } /** - * Returns the {@link SyncMatrix} of inverse {@link GLMatrixFunc#GL_MODELVIEW_MATRIX modelview matrix} (Mvi). + * Returns the {@link SyncMatrix} of inverse {@link GLMatrixFunc#GL_MODELVIEW_MATRIX modelview matrix} (Mvi) if requested. * <p> - * Method enables the Mvi matrix update, and performs it's update w/o clearing the modified bits. - * </p> - * <p> - * See {@link #update()} and <a href="#storageDetails"> matrix storage details</a>. + * See <a href="#storageDetails"> matrix storage details</a>. * </p> - * @see #update() - * @see #clearAllUpdateRequests() + * @throws IllegalArgumentException if {@link #INVERSE_MODELVIEW} has not been requested in ctor {@link #PMVMatrix(int)}. */ public final SyncMatrix4f getSyncMviMat() { - requestMask |= DIRTY_INVERSE_MODELVIEW ; - updateImpl(false); - return matMviSync; + if( 0 == ( INVERSE_MODELVIEW & requestBits ) ) { + throw new IllegalArgumentException("Not requested in ctor"); + } + return syncMvi; } /** - * Returns the inverse transposed {@link GLMatrixFunc#GL_MODELVIEW_MATRIX modelview matrix} (Mvit). - * <p> - * Method enables the Mvit matrix update, and performs it's update w/o clearing the modified bits. - * </p> + * Returns the inverse transposed {@link GLMatrixFunc#GL_MODELVIEW_MATRIX modelview matrix} (Mvit) if requested. * <p> - * See {@link #update()} and <a href="#storageDetails"> matrix storage details</a>. + * See <a href="#storageDetails"> matrix storage details</a>. * </p> - * @see #update() - * @see #clearAllUpdateRequests() + * @throws IllegalArgumentException if {@link #INVERSE_TRANSPOSED_MODELVIEW} has not been requested in ctor {@link #PMVMatrix(int)}. */ public final Matrix4f getMvitMat() { - requestMask |= DIRTY_INVERSE_TRANSPOSED_MODELVIEW ; + if( 0 == ( INVERSE_TRANSPOSED_MODELVIEW & requestBits ) ) { + throw new IllegalArgumentException("Not requested in ctor"); + } updateImpl(false); return matMvit; } /** - * Returns the {@link SyncMatrix} of inverse transposed {@link GLMatrixFunc#GL_MODELVIEW_MATRIX modelview matrix} (Mvit). - * <p> - * Method enables the Mvit matrix update, and performs it's update w/o clearing the modified bits. - * </p> + * Returns the {@link SyncMatrix} of inverse transposed {@link GLMatrixFunc#GL_MODELVIEW_MATRIX modelview matrix} (Mvit) if requested. * <p> - * See {@link #update()} and <a href="#storageDetails"> matrix storage details</a>. + * See <a href="#storageDetails"> matrix storage details</a>. * </p> - * @see #update() - * @see #clearAllUpdateRequests() + * @throws IllegalArgumentException if {@link #INVERSE_TRANSPOSED_MODELVIEW} has not been requested in ctor {@link #PMVMatrix(int)}. */ public final SyncMatrix4f getSyncMvitMat() { - requestMask |= DIRTY_INVERSE_TRANSPOSED_MODELVIEW ; - updateImpl(false); - return matMvitSync; + if( 0 == ( INVERSE_TRANSPOSED_MODELVIEW & requestBits ) ) { + throw new IllegalArgumentException("Not requested in ctor"); + } + return syncMvit; } /** - * Returns {@link SyncMatrices4f} of 2 matrices within one FloatBuffer: {@link #getPMat() P} and {@link #getMvMat() Mv}. + * Returns {@link SyncMatrices4f} of 3 matrices within one FloatBuffer: {@link #getPMat() P}, {@link #getMvMat() Mv} and {@link #getMviMat() Mvi} if requested. * <p> * See <a href="#storageDetails"> matrix storage details</a>. * </p> - */ - public final SyncMatrices4f getSyncPMvMat() { - return matPMvSync; - } - - /** - * Returns {@link SyncMatrices4f} of 3 matrices within one FloatBuffer: {@link #getPMat() P}, {@link #getMvMat() Mv} and {@link #getMviMat() Mvi}. - * <p> - * Method enables the Mvi matrix update, and performs it's update w/o clearing the modified bits. - * </p> - * <p> - * See {@link #update()} and <a href="#storageDetails"> matrix storage details</a>. - * </p> - * @see #update() - * @see #clearAllUpdateRequests() + * @throws IllegalArgumentException if {@link #INVERSE_MODELVIEW} has not been requested in ctor {@link #PMVMatrix(int)}. */ public final SyncMatrices4f getSyncPMvMviMat() { - requestMask |= DIRTY_INVERSE_MODELVIEW ; - updateImpl(false); - return matPMvMviSync; + if( 0 == ( INVERSE_MODELVIEW & requestBits ) ) { + throw new IllegalArgumentException("Not requested in ctor"); + } + return syncP_Mv_Mvi; } /** - * Returns {@link SyncMatrices4f} of 4 matrices within one FloatBuffer: {@link #getPMat() P}, {@link #getMvMat() Mv}, {@link #getMviMat() Mvi} and {@link #getMvitMat() Mvit}. - * <p> - * Method enables the Mvi and Mvit matrix update, and performs it's update w/o clearing the modified bits. - * </p> + * Returns {@link SyncMatrices4f} of 4 matrices within one FloatBuffer: {@link #getPMat() P}, {@link #getMvMat() Mv}, {@link #getMviMat() Mvi} and {@link #getMvitMat() Mvit} if requested. * <p> - * See {@link #update()} and <a href="#storageDetails"> matrix storage details</a>. + * See <a href="#storageDetails"> matrix storage details</a>. * </p> - * @see #update() - * @see #clearAllUpdateRequests() + * @throws IllegalArgumentException if {@link #INVERSE_TRANSPOSED_MODELVIEW} has not been requested in ctor {@link #PMVMatrix(int)}. */ - public final SyncMatrices4f getSyncPMvMvitMat() { - requestMask |= DIRTY_INVERSE_MODELVIEW | DIRTY_INVERSE_TRANSPOSED_MODELVIEW ; - updateImpl(false); - return matPMvMvitSync; - } - - /** Returns the frustum, derived from projection * modelview */ - public final Frustum getFrustum() { - requestMask |= DIRTY_FRUSTUM; - updateImpl(false); - return frustum; + public final SyncMatrices4f getSyncPMvMviMvitMat() { + if( 0 == ( INVERSE_TRANSPOSED_MODELVIEW & requestBits ) ) { + throw new IllegalArgumentException("Not requested in ctor"); + } + return syncP_Mv_Mvi_Mvit; } /** @@ -678,11 +709,11 @@ public final class PMVMatrix implements GLMatrixFunc { public final void glLoadMatrixf(final float[] values, final int offset) { if(matrixMode==GL_MODELVIEW) { matMv.load(values, offset); - dirtyBits |= DIRTY_INVERSE_MODELVIEW | DIRTY_INVERSE_TRANSPOSED_MODELVIEW | DIRTY_FRUSTUM ; + dirtyBits |= requestBits | MANUAL_BITS ; modifiedBits |= MODIFIED_MODELVIEW; } else if(matrixMode==GL_PROJECTION) { matP.load(values, offset); - dirtyBits |= DIRTY_FRUSTUM ; + dirtyBits |= MANUAL_BITS ; modifiedBits |= MODIFIED_PROJECTION; } else if(matrixMode==GL.GL_TEXTURE) { matTex.load(values, offset); @@ -695,11 +726,11 @@ public final class PMVMatrix implements GLMatrixFunc { final int spos = m.position(); if(matrixMode==GL_MODELVIEW) { matMv.load(m); - dirtyBits |= DIRTY_INVERSE_MODELVIEW | DIRTY_INVERSE_TRANSPOSED_MODELVIEW | DIRTY_FRUSTUM ; + dirtyBits |= requestBits | MANUAL_BITS ; modifiedBits |= MODIFIED_MODELVIEW; } else if(matrixMode==GL_PROJECTION) { matP.load(m); - dirtyBits |= DIRTY_FRUSTUM ; + dirtyBits |= MANUAL_BITS ; modifiedBits |= MODIFIED_PROJECTION; } else if(matrixMode==GL.GL_TEXTURE) { matTex.load(m); @@ -717,11 +748,11 @@ public final class PMVMatrix implements GLMatrixFunc { public final void glLoadMatrixf(final Matrix4f m) { if(matrixMode==GL_MODELVIEW) { matMv.load(m); - dirtyBits |= DIRTY_INVERSE_MODELVIEW | DIRTY_INVERSE_TRANSPOSED_MODELVIEW | DIRTY_FRUSTUM ; + dirtyBits |= requestBits | MANUAL_BITS ; modifiedBits |= MODIFIED_MODELVIEW; } else if(matrixMode==GL_PROJECTION) { matP.load(m); - dirtyBits |= DIRTY_FRUSTUM ; + dirtyBits |= MANUAL_BITS ; modifiedBits |= MODIFIED_PROJECTION; } else if(matrixMode==GL.GL_TEXTURE) { matTex.load(m); @@ -738,11 +769,11 @@ public final class PMVMatrix implements GLMatrixFunc { public final void glLoadMatrix(final Quaternion quat) { if(matrixMode==GL_MODELVIEW) { matMv.setToRotation(quat); - dirtyBits |= DIRTY_INVERSE_MODELVIEW | DIRTY_INVERSE_TRANSPOSED_MODELVIEW | DIRTY_FRUSTUM ; + dirtyBits |= requestBits | MANUAL_BITS ; modifiedBits |= MODIFIED_MODELVIEW; } else if(matrixMode==GL_PROJECTION) { matP.setToRotation(quat); - dirtyBits |= DIRTY_FRUSTUM ; + dirtyBits |= MANUAL_BITS ; modifiedBits |= MODIFIED_PROJECTION; } else if(matrixMode==GL.GL_TEXTURE) { matTex.setToRotation(quat); @@ -754,10 +785,15 @@ public final class PMVMatrix implements GLMatrixFunc { public final void glPopMatrix() { if(matrixMode==GL_MODELVIEW) { matMv.pop(); + dirtyBits |= requestBits | MANUAL_BITS ; + modifiedBits |= MODIFIED_MODELVIEW; } else if(matrixMode==GL_PROJECTION) { matP.pop(); + dirtyBits |= MANUAL_BITS ; + modifiedBits |= MODIFIED_PROJECTION; } else if(matrixMode==GL.GL_TEXTURE) { matTex.pop(); + modifiedBits |= MODIFIED_TEXTURE; } } @@ -776,11 +812,11 @@ public final class PMVMatrix implements GLMatrixFunc { public final void glLoadIdentity() { if(matrixMode==GL_MODELVIEW) { matMv.loadIdentity(); - dirtyBits |= DIRTY_INVERSE_MODELVIEW | DIRTY_INVERSE_TRANSPOSED_MODELVIEW | DIRTY_FRUSTUM ; + dirtyBits |= requestBits | MANUAL_BITS ; modifiedBits |= MODIFIED_MODELVIEW; } else if(matrixMode==GL_PROJECTION) { matP.loadIdentity(); - dirtyBits |= DIRTY_FRUSTUM ; + dirtyBits |= MANUAL_BITS ; modifiedBits |= MODIFIED_PROJECTION; } else if(matrixMode==GL.GL_TEXTURE) { matTex.loadIdentity(); @@ -788,17 +824,16 @@ public final class PMVMatrix implements GLMatrixFunc { } } - @SuppressWarnings("deprecation") @Override public final void glMultMatrixf(final FloatBuffer m) { final int spos = m.position(); if(matrixMode==GL_MODELVIEW) { matMv.mul( mat4Tmp1.load( m ) ); - dirtyBits |= DIRTY_INVERSE_MODELVIEW | DIRTY_INVERSE_TRANSPOSED_MODELVIEW | DIRTY_FRUSTUM ; + dirtyBits |= requestBits | MANUAL_BITS ; modifiedBits |= MODIFIED_MODELVIEW; } else if(matrixMode==GL_PROJECTION) { matP.mul( mat4Tmp1.load( m ) ); - dirtyBits |= DIRTY_FRUSTUM ; + dirtyBits |= MANUAL_BITS ; modifiedBits |= MODIFIED_PROJECTION; } else if(matrixMode==GL.GL_TEXTURE) { matTex.mul( mat4Tmp1.load( m ) ); @@ -811,11 +846,11 @@ public final class PMVMatrix implements GLMatrixFunc { public final void glMultMatrixf(final float[] m, final int m_offset) { if(matrixMode==GL_MODELVIEW) { matMv.mul( mat4Tmp1.load( m, m_offset ) ); - dirtyBits |= DIRTY_INVERSE_MODELVIEW | DIRTY_INVERSE_TRANSPOSED_MODELVIEW | DIRTY_FRUSTUM ; + dirtyBits |= requestBits | MANUAL_BITS ; modifiedBits |= MODIFIED_MODELVIEW; } else if(matrixMode==GL_PROJECTION) { matP.mul( mat4Tmp1.load( m, m_offset ) ); - dirtyBits |= DIRTY_FRUSTUM ; + dirtyBits |= MANUAL_BITS ; modifiedBits |= MODIFIED_PROJECTION; } else if(matrixMode==GL.GL_TEXTURE) { matTex.mul( mat4Tmp1.load( m, m_offset ) ); @@ -834,11 +869,11 @@ public final class PMVMatrix implements GLMatrixFunc { public final PMVMatrix glMultMatrixf(final Matrix4f m) { if(matrixMode==GL_MODELVIEW) { matMv.mul( m ); - dirtyBits |= DIRTY_INVERSE_MODELVIEW | DIRTY_INVERSE_TRANSPOSED_MODELVIEW | DIRTY_FRUSTUM ; + dirtyBits |= requestBits | MANUAL_BITS ; modifiedBits |= MODIFIED_MODELVIEW; } else if(matrixMode==GL_PROJECTION) { matP.mul( m ); - dirtyBits |= DIRTY_FRUSTUM ; + dirtyBits |= MANUAL_BITS ; modifiedBits |= MODIFIED_PROJECTION; } else if(matrixMode==GL.GL_TEXTURE) { matTex.mul( m ); @@ -955,7 +990,7 @@ public final class PMVMatrix implements GLMatrixFunc { * with the eye, object and orientation. */ public final void gluLookAt(final Vec3f eye, final Vec3f center, final Vec3f up) { - glMultMatrixf( mat4Tmp1.setToLookAt(eye, center, up, mat4Tmp2) ); + glMultMatrixf( mat4Tmp1.setToLookAt(eye, center, up, getTmp2Mat()) ); } /** @@ -988,7 +1023,7 @@ public final class PMVMatrix implements GLMatrixFunc { */ public final boolean gluUnProject(final float winx, final float winy, final float winz, final Recti viewport, final Vec3f objPos) { - if( Matrix4f.mapWinToObj(winx, winy, winz, matMv, matP, viewport, objPos, mat4Tmp1) ) { + if( Matrix4f.mapWinToObj(winx, winy, winz, getPMviMat(), viewport, objPos) ) { return true; } else { return false; @@ -1015,7 +1050,7 @@ public final class PMVMatrix implements GLMatrixFunc { final Recti viewport, final float near, final float far, final Vec4f objPos) { - if( Matrix4f.mapWinToObj4(winx, winy, winz, clipw, matMv, matP, viewport, near, far, objPos, mat4Tmp1) ) { + if( Matrix4f.mapWinToObj4(winx, winy, winz, clipw, getPMviMat(), viewport, near, far, objPos) ) { return true; } else { return false; @@ -1023,27 +1058,6 @@ public final class PMVMatrix implements GLMatrixFunc { } /** - * Make given matrix the <i>pick</i> matrix based on given parameters. - * <p> - * Traditional <code>gluPickMatrix</code> implementation. - * </p> - * <p> - * See {@link Matrix4f#setToPick(float, float, float, float, Recti, int, Matrix4f) for details. - * </p> - * @param x the center x-component of a picking region in window coordinates - * @param y the center y-component of a picking region in window coordinates - * @param deltaX the width of the picking region in window coordinates. - * @param deltaY the height of the picking region in window coordinates. - * @param viewport Rect4i viewport vector - */ - public final void gluPickMatrix(final float x, final float y, - final float deltaX, final float deltaY, final Recti viewport) { - if( null != mat4Tmp1.setToPick(x, y, deltaX, deltaY, viewport, mat4Tmp2) ) { - glMultMatrixf( mat4Tmp1 ); - } - } - - /** * Map two window coordinates w/ shared X/Y and distinctive Z * to a {@link Ray}. The resulting {@link Ray} maybe used for <i>picking</i> * using a {@link AABBox#getRayIntersection(Vec3f, Ray, float, boolean) bounding box}. @@ -1065,40 +1079,88 @@ public final class PMVMatrix implements GLMatrixFunc { */ public final boolean gluUnProjectRay(final float winx, final float winy, final float winz0, final float winz1, final Recti viewport, final Ray ray) { - return Matrix4f.mapWinToRay(winx, winy, winz0, winz1, matMv, matP, viewport, ray, mat4Tmp1, mat4Tmp2); + return Matrix4f.mapWinToRay(winx, winy, winz0, winz1, getPMviMat(), viewport, ray); + } + + /** + * Make given matrix the <i>pick</i> matrix based on given parameters. + * <p> + * Traditional <code>gluPickMatrix</code> implementation. + * </p> + * <p> + * See {@link Matrix4f#setToPick(float, float, float, float, Recti, int, Matrix4f) for details. + * </p> + * @param x the center x-component of a picking region in window coordinates + * @param y the center y-component of a picking region in window coordinates + * @param deltaX the width of the picking region in window coordinates. + * @param deltaY the height of the picking region in window coordinates. + * @param viewport Rect4i viewport vector + */ + public final void gluPickMatrix(final float x, final float y, + final float deltaX, final float deltaY, final Recti viewport) { + if( null != mat4Tmp1.setToPick(x, y, deltaX, deltaY, viewport, getTmp2Mat()) ) { + glMultMatrixf( mat4Tmp1 ); + } } public StringBuilder toString(StringBuilder sb, final String f) { if(null == sb) { sb = new StringBuilder(); } - final boolean mviDirty = 0 != (DIRTY_INVERSE_MODELVIEW & dirtyBits); - final boolean mvitDirty = 0 != (DIRTY_INVERSE_TRANSPOSED_MODELVIEW & dirtyBits); - final boolean frustumDirty = 0 != (DIRTY_FRUSTUM & dirtyBits); - final boolean mviReq = 0 != (DIRTY_INVERSE_MODELVIEW & requestMask); - final boolean mvitReq = 0 != (DIRTY_INVERSE_TRANSPOSED_MODELVIEW & requestMask); - final boolean frustumReq = 0 != (DIRTY_FRUSTUM & requestMask); + final boolean pmvDirty = 0 != (PREMUL_PMV & dirtyBits); + final boolean pmvUsed = null != matPMv; + + final boolean pmviDirty = 0 != (PREMUL_PMVI & dirtyBits); + final boolean pmviUsed = null != matPMvi; + + final boolean frustumDirty = 0 != (FRUSTUM & dirtyBits); + final boolean frustumUsed = null != frustum; + + final boolean mviDirty = 0 != (INVERSE_MODELVIEW & dirtyBits); + final boolean mviReq = 0 != (INVERSE_MODELVIEW & requestBits); + + final boolean mvitDirty = 0 != (INVERSE_TRANSPOSED_MODELVIEW & dirtyBits); + final boolean mvitReq = 0 != (INVERSE_TRANSPOSED_MODELVIEW & requestBits); + final boolean modP = 0 != ( MODIFIED_PROJECTION & modifiedBits ); final boolean modMv = 0 != ( MODIFIED_MODELVIEW & modifiedBits ); final boolean modT = 0 != ( MODIFIED_TEXTURE & modifiedBits ); + int count = 3; // P, Mv, T sb.append("PMVMatrix[modified[P ").append(modP).append(", Mv ").append(modMv).append(", T ").append(modT); - sb.append("], dirty/req[Mvi ").append(mviDirty).append("/").append(mviReq).append(", Mvit ").append(mvitDirty).append("/").append(mvitReq).append(", Frustum ").append(frustumDirty).append("/").append(frustumReq).append("]").append(PlatformPropsImpl.NEWLINE); + sb.append("], dirty/used[PMv ").append(pmvDirty).append("/").append(pmvUsed).append(", Pmvi ").append(pmviDirty).append("/").append(pmviUsed).append(", Frustum ").append(frustumDirty).append("/").append(frustumUsed); + sb.append("], dirty/req[Mvi ").append(mviDirty).append("/").append(mviReq).append(", Mvit ").append(mvitDirty).append("/").append(mvitReq).append("]").append(PlatformPropsImpl.NEWLINE); sb.append(", Projection").append(PlatformPropsImpl.NEWLINE); matP.toString(sb, null, f); sb.append(", Modelview").append(PlatformPropsImpl.NEWLINE); matMv.toString(sb, null, f); sb.append(", Texture").append(PlatformPropsImpl.NEWLINE); matTex.toString(sb, null, f); - if( 0 != ( requestMask & DIRTY_INVERSE_MODELVIEW ) ) { + if( null != matPMv ) { + sb.append(", P * Mv").append(PlatformPropsImpl.NEWLINE); + matPMv.toString(sb, null, f); + ++count; + } + if( null != matPMvi ) { + sb.append(", P * Mv").append(PlatformPropsImpl.NEWLINE); + matPMvi.toString(sb, null, f); + ++count; + } + if( mviReq ) { sb.append(", Inverse Modelview").append(PlatformPropsImpl.NEWLINE); matMvi.toString(sb, null, f); + ++count; } - if( 0 != ( requestMask & DIRTY_INVERSE_TRANSPOSED_MODELVIEW ) ) { + if( mvitReq ) { sb.append(", Inverse Transposed Modelview").append(PlatformPropsImpl.NEWLINE); matMvit.toString(sb, null, f); + ++count; } - sb.append("]"); + int tmpCount = 1; + if( null != mat4Tmp2 ) { + ++tmpCount; + } + sb.append(", matrices "+count+" + "+tmpCount+" temp = "+(count+tmpCount)+"]"); return sb; } @@ -1118,6 +1180,8 @@ public final class PMVMatrix implements GLMatrixFunc { * @see #MODIFIED_PROJECTION * @see #MODIFIED_MODELVIEW * @see #MODIFIED_TEXTURE + * @see #getDirtyBits() + * @see #isReqDirty() */ public final int getModifiedBits(final boolean clear) { final int r = modifiedBits; @@ -1128,21 +1192,28 @@ public final class PMVMatrix implements GLMatrixFunc { } /** - * Returns the dirty bits due to mutable operations. + * Returns the dirty bits due to mutable operations, + * i.e. + * - {@link #INVERSE_MODELVIEW} (if requested) + * - {@link #INVERSE_TRANSPOSED_MODELVIEW} (if requested) + * - {@link #FRUSTUM} (always, cleared via {@link #getFrustum()} * <p> - * A dirty bit is set , if the corresponding matrix had been modified by a mutable operation - * since last {@link #update()} call. The latter clears the dirty state only if the dirty matrix (Mvi or Mvit) or {@link Frustum} - * has been requested by one of the {@link #getMviMat() Mvi get}, {@link #getMvitMat() Mvit get} - * or {@link #getFrustum() Frustum get} methods. + * A dirty bit is set, if the corresponding matrix had been modified by a mutable operation + * since last {@link #update()} call and requested in the constructor {@link #PMVMatrix(int)}. + * </p> + * <p> + * {@link #update()} clears the dirty state for the matrices and {@link #getFrustum()} for {@link #FRUSTUM}. * </p> * - * @see #DIRTY_INVERSE_MODELVIEW - * @see #DIRTY_INVERSE_TRANSPOSED_MODELVIEW - * @see #DIRTY_FRUSTUM + * @see #isReqDirty() + * @see #INVERSE_MODELVIEW + * @see #INVERSE_TRANSPOSED_MODELVIEW + * @see #FRUSTUM + * @see #PMVMatrix(int) * @see #getMviMat() * @see #getMvitMat() - * @see #glGetPMvMviMatrixf() - * @see #glGetPMvMvitMatrixf() + * @see #getSyncPMvMviMat() + * @see #getSyncPMvMviMvitMat() * @see #getFrustum() */ public final int getDirtyBits() { @@ -1150,162 +1221,237 @@ public final class PMVMatrix implements GLMatrixFunc { } /** - * Returns the request bit mask, which uses bit values equal to the dirty mask. + * Returns true if the one of the {@link #getReqBits() requested bits} are are set dirty due to mutable operations, + * i.e. at least one of + * - {@link #INVERSE_MODELVIEW} + * - {@link #INVERSE_TRANSPOSED_MODELVIEW} + * <p> + * A dirty bit is set, if the corresponding matrix had been modified by a mutable operation + * since last {@link #update()} call and requested in the constructor {@link #PMVMatrix(int)}. + * </p> * <p> - * The request bit mask is set by one of the {@link #getMviMat() Mvi get}, {@link #getMvitMat() Mvit get} - * or {@link #getFrustum() Frustum get} methods. + * {@link #update()} clears the dirty state for the matrices and {@link #getFrustum()} for {@link #FRUSTUM}. * </p> * - * @see #clearAllUpdateRequests() - * @see #DIRTY_INVERSE_MODELVIEW - * @see #DIRTY_INVERSE_TRANSPOSED_MODELVIEW - * @see #DIRTY_FRUSTUM + * @see #INVERSE_MODELVIEW + * @see #INVERSE_TRANSPOSED_MODELVIEW + * @see #PMVMatrix(int) * @see #getMviMat() * @see #getMvitMat() - * @see #glGetPMvMviMatrixf() - * @see #glGetPMvMvitMatrixf() - * @see #getFrustum() + * @see #getSyncPMvMviMat() + * @see #getSyncPMvMviMvitMat() */ - public final int getRequestMask() { - return requestMask; + public final boolean isReqDirty() { + return 0 != ( requestBits & dirtyBits ); } - /** - * Clears all {@link #update()} requests of the Mvi and Mvit matrix and Frustum - * after it has been enabled by one of the {@link #getMviMat() Mvi get}, {@link #getMvitMat() Mvit get} - * or {@link #getFrustum() Frustum get} methods. + * Returns the request bit mask, which uses bit values equal to the dirty mask + * and may contain + * - {@link #INVERSE_MODELVIEW} + * - {@link #INVERSE_TRANSPOSED_MODELVIEW} * <p> - * Allows user to disable subsequent Mvi, Mvit and {@link Frustum} updates if no more required. + * The request bit mask is set by in the constructor {@link #PMVMatrix(int)}. * </p> * + * @see #INVERSE_MODELVIEW + * @see #INVERSE_TRANSPOSED_MODELVIEW + * @see #PMVMatrix(int) * @see #getMviMat() * @see #getMvitMat() - * @see #glGetPMvMviMatrixf() - * @see #glGetPMvMvitMatrixf() + * @see #getSyncPMvMviMat() + * @see #getSyncPMvMviMvitMat() * @see #getFrustum() - * @see #getRequestMask() */ - public final void clearAllUpdateRequests() { - requestMask &= ~DIRTY_ALL; + public final int getReqBits() { + return requestBits; + } + + /** + * Returns the pre-multiplied projection x modelview, P x Mv. + * <p> + * This {@link Matrix4f} instance should be re-fetched via this method and not locally stored + * to have it updated from a potential modification of underlying projection and/or modelview matrix. + * {@link #update()} has no effect on this {@link Matrix4f}. + * </p> + * <p> + * This pre-multipled P x Mv is considered dirty, if its corresponding + * {@link #getPMat() P matrix} or {@link #getMvMat() Mv matrix} has been modified since its last update. + * </p> + * @see #update() + */ + public final Matrix4f getPMvMat() { + if( 0 != ( dirtyBits & PREMUL_PMV ) ) { + if( null == matPMv ) { + matPMv = new Matrix4f(); + } + matPMv.mul(matP, matMv); + dirtyBits &= ~PREMUL_PMV; + } + return matPMv; + } + + /** + * Returns the pre-multiplied inverse projection x modelview, + * if {@link Matrix4f#invert(Matrix4f)} succeeded, otherwise `null`. + * <p> + * This {@link Matrix4f} instance should be re-fetched via this method and not locally stored + * to have it updated from a potential modification of underlying projection and/or modelview matrix. + * {@link #update()} has no effect on this {@link Matrix4f}. + * </p> + * <p> + * This pre-multipled invert(P x Mv) is considered dirty, if its corresponding + * {@link #getPMat() P matrix} or {@link #getMvMat() Mv matrix} has been modified since its last update. + * </p> + * @see #update() + */ + public final Matrix4f getPMviMat() { + if( 0 != ( dirtyBits & PREMUL_PMVI ) ) { + if( null == matPMvi ) { + matPMvi = new Matrix4f(); + } + final Matrix4f mPMv = getPMvMat(); + matPMviOK = matPMvi.invert(mPMv); + dirtyBits &= ~PREMUL_PMVI; + } + return matPMviOK ? matPMvi : null; + } + + /** + * Returns the frustum, derived from projection x modelview. + * <p> + * This {@link Frustum} instance should be re-fetched via this method and not locally stored + * to have it updated from a potential modification of underlying projection and/or modelview matrix. + * {@link #update()} has no effect on this {@link Frustum}. + * </p> + * <p> + * The {@link Frustum} is considered dirty, if its corresponding + * {@link #getPMat() P matrix} or {@link #getMvMat() Mv matrix} has been modified since its last update. + * </p> + * @see #update() + */ + public final Frustum getFrustum() { + if( 0 != ( dirtyBits & FRUSTUM ) ) { + if( null == frustum ) { + frustum = new Frustum(); + } + final Matrix4f mPMv = getPMvMat(); + frustum.updateFrustumPlanes(mPMv); + dirtyBits &= ~FRUSTUM; + } + return frustum; } /** * Update the derived {@link #getMviMat() inverse modelview (Mvi)}, - * {@link #getMvitMat() inverse transposed modelview (Mvit)} matrices and {@link Frustum} - * <b>if</b> they are dirty <b>and</b> they were requested - * by one of the {@link #getMviMat() Mvi get}, {@link #getMvitMat() Mvit get} - * or {@link #getFrustum() Frustum get} methods. + * {@link #getMvitMat() inverse transposed modelview (Mvit)} matrices + * <b>if</b> they {@link #isReqDirty() are dirty} <b>and</b> + * requested via the constructor {@link #PMVMatrix(int)}.<br/> + * Hence updates the following dirty bits. + * - {@link #INVERSE_MODELVIEW} + * - {@link #INVERSE_TRANSPOSED_MODELVIEW} * <p> - * The Mvi and Mvit matrices and {@link Frustum} are considered dirty, if their corresponding + * The {@link Frustum} is updated only via {@link #getFrustum()} separately. + * </p> + * <p> + * The Mvi and Mvit matrices are considered dirty, if their corresponding * {@link #getMvMat() Mv matrix} has been modified since their last update. * </p> * <p> - * Method should be called manually in case mutable operations has been called + * Method is automatically called by {@link SyncMatrix4f} and {@link SyncMatrices4f} + * instances {@link SyncAction} as retrieved by e.g. {@link #getSyncMvitMat()}. + * This ensures an automatic update cycle if used with {@link GLUniformData}. + * </p> + * <p> + * Method may be called manually in case mutable operations has been called * and caller operates on already fetched references, i.e. not calling - * {@link #getMviMat() Mvi get}, {@link #getMvitMat() Mvit get} - * or {@link #getFrustum() Frustum get} etc anymore. + * {@link #getMviMat()}, {@link #getMvitMat()} anymore. * </p> * <p> - * This method clears the modified bits like {@link #getModifiedBits(boolean) getModifiedBits(true)}, + * Method clears the modified bits like {@link #getModifiedBits(boolean) getModifiedBits(true)}, * which are set by any mutable operation. The modified bits have no impact * on this method, but the return value. * </p> * * @return true if any matrix has been modified since last update call or - * if the derived matrices Mvi and Mvit or {@link Frustum} were updated, otherwise false. + * if the derived matrices Mvi and Mvit were updated, otherwise false. * In other words, method returns true if any matrix used by the caller must be updated, * e.g. uniforms in a shader program. * * @see #getModifiedBits(boolean) - * @see #MODIFIED_PROJECTION - * @see #MODIFIED_MODELVIEW - * @see #MODIFIED_TEXTURE - * @see #DIRTY_INVERSE_MODELVIEW - * @see #DIRTY_INVERSE_TRANSPOSED_MODELVIEW - * @see #DIRTY_FRUSTUM + * @see #isReqDirty() + * @see #INVERSE_MODELVIEW + * @see #INVERSE_TRANSPOSED_MODELVIEW + * @see #PMVMatrix(int) * @see #getMviMat() * @see #getMvitMat() - * @see #glGetPMvMviMatrixf() - * @see #glGetPMvMvitMatrixf() - * @see #getFrustum() - * @see #clearAllUpdateRequests() + * @see #getSyncPMvMviMat() + * @see #getSyncPMvMviMvitMat() */ public final boolean update() { return updateImpl(true); } - private final boolean updateImpl(final boolean clearModBits) { - boolean mod = 0 != modifiedBits; - if(clearModBits) { - modifiedBits = 0; - } - - if( 0 != ( dirtyBits & ( DIRTY_FRUSTUM & requestMask ) ) ) { - if( null == frustum ) { - frustum = new Frustum(); - } - mat4Tmp1.mul(matP, matMv); - frustum.updateFrustumPlanes(mat4Tmp1); - dirtyBits &= ~DIRTY_FRUSTUM; - mod = true; - } - - if( 0 == ( dirtyBits & requestMask ) ) { - return mod; // nothing more requested which may have been dirty - } - - return setMviMvit() || mod; - } // // private // - private static final String msgCantComputeInverse = "Invalid source Mv matrix, can't compute inverse"; - private final boolean setMviMvit() { - boolean res = false; - if( 0 != ( dirtyBits & DIRTY_INVERSE_MODELVIEW ) ) { // only if dirt; always requested at this point, see update() + private final boolean updateImpl(final boolean clearModBits) { + boolean mod = 0 != modifiedBits; + if( clearModBits ) { + modifiedBits = 0; + } + if( 0 != ( requestBits & ( ( dirtyBits & ( INVERSE_MODELVIEW | INVERSE_TRANSPOSED_MODELVIEW ) ) ) ) ) { // only if dirt requested & dirty if( !matMvi.invert(matMv) ) { throw new GLException(msgCantComputeInverse); } - dirtyBits &= ~DIRTY_INVERSE_MODELVIEW; - res = true; + dirtyBits &= ~INVERSE_MODELVIEW; + mod = true; } - if( 0 != ( requestMask & ( dirtyBits & DIRTY_INVERSE_TRANSPOSED_MODELVIEW ) ) ) { // only if requested & dirty + if( 0 != ( requestBits & ( dirtyBits & INVERSE_TRANSPOSED_MODELVIEW ) ) ) { // only if requested & dirty matMvit.transpose(matMvi); - dirtyBits &= ~DIRTY_INVERSE_TRANSPOSED_MODELVIEW; - res = true; + dirtyBits &= ~INVERSE_TRANSPOSED_MODELVIEW; + mod = true; } - return res; + return mod; } + private static final String msgCantComputeInverse = "Invalid source Mv matrix, can't compute inverse"; private final Matrix4f matP; private final Matrix4f matMv; + private final Matrix4f matTex; + private final Matrix4f matMvi; private final Matrix4f matMvit; - private final Matrix4f matTex; private static final int mP_offset = 0*16; private static final int mMv_offset = 1*16; - private static final int mMvi_offset = 2*16; - private static final int mMvit_offset = 3*16; - private static final int mTex_offset = 4*16; + private final int mMvi_offset; + private final int mMvit_offset; + private final int mTex_offset; private final float[] matrixStore; - private final FloatBuffer matrixP, matrixMv, matrixMvi, matrixMvit, matrixTex; - private final FloatBuffer matrixPMvMvit, matrixPMvMvi, matrixPMv; - private final SyncMatrix4f matPSync, matMvSync, matMviSync, matMvitSync, matTexSync; - private final SyncMatrices4f matPMvMvitSync, matPMvMviSync, matPMvSync; + private final FloatBuffer bufP, bufMv, bufTex; + private final FloatBuffer bufMvi, bufMvit; + private final FloatBuffer bufP_Mv, bufP_Mv_Mvi, bufP_Mv_Mvi_Mvit; - private final Matrix4f mat4Tmp1, mat4Tmp2; + private final SyncMatrix4f syncP, syncMv, syncT; + private final SyncMatrix4f syncMvi, syncMvit; + private final SyncMatrices4f syncP_Mv, syncP_Mv_Mvi, syncP_Mv_Mvi_Mvit; + + private final Matrix4f mat4Tmp1; private final Vec3f vec3Tmp1; private final Vec4f vec4Tmp1; private int matrixMode = GL_MODELVIEW; private int modifiedBits = MODIFIED_ALL; - private int dirtyBits = DIRTY_ALL; // contains the dirty bits, i.e. hinting for update operation - private int requestMask = 0; // may contain the requested dirty bits: DIRTY_INVERSE_MODELVIEW | DIRTY_INVERSE_TRANSPOSED_MODELVIEW + private int dirtyBits = 0; // contains the dirty bits, i.e. hinting for update operation + private final int requestBits; // may contain the requested bits: INVERSE_MODELVIEW | INVERSE_TRANSPOSED_MODELVIEW + private Matrix4f mat4Tmp2; + private Matrix4f matPMv; + private Matrix4f matPMvi; + private boolean matPMviOK; private Frustum frustum; private abstract class PMVSyncBuffer implements SyncMatrix4f { @@ -1359,42 +1505,88 @@ public final class PMVMatrix implements GLMatrixFunc { @Override public SyncAction getAction() { return action; } } - private final class SyncBufferN implements SyncMatrices4f { - private final Matrix4f[] mats; - private final FloatBuffer fbuf; + private final class SyncBuffer1U extends PMVSyncBuffer { private final int offset; private final SyncAction action = new SyncAction() { @Override public void sync() { - int ioff = offset; - for(int i=0; i<mats.length; ++i, ioff+=16) { - mats[i].get(matrixStore, ioff); - } + updateImpl(true); + mat.get(matrixStore, offset); } }; - public SyncBufferN(final Matrix4f[] ms, final FloatBuffer fbuf, final int offset) { - this.mats = ms; - this.fbuf = fbuf; + public SyncBuffer1U(final Matrix4f m, final FloatBuffer fbuf, final int offset) { + super(m, fbuf); this.offset = offset; } @Override public SyncAction getAction() { return action; } + } + + private abstract class PMVSyncBufferN implements SyncMatrices4f { + protected final Matrix4f[] mats; + private final FloatBuffer fbuf; + + public PMVSyncBufferN(final Matrix4f[] ms, final FloatBuffer fbuf) { + this.mats = ms; + this.fbuf = fbuf; + } @Override - public Buffer getBuffer() { return fbuf; } + public final Buffer getBuffer() { return fbuf; } @Override - public SyncBuffer sync() { getAction().sync(); return this; } + public final SyncBuffer sync() { getAction().sync(); return this; } @Override - public Buffer getSyncBuffer() { getAction().sync(); return fbuf; } + public final Buffer getSyncBuffer() { getAction().sync(); return fbuf; } @Override public Matrix4f[] getMatrices() { return mats; } @Override - public FloatBuffer getSyncFloats() { getAction().sync(); return fbuf; } + public final FloatBuffer getSyncFloats() { getAction().sync(); return fbuf; } + } + private final class SyncBufferN extends PMVSyncBufferN { + private final int offset; + private final SyncAction action = new SyncAction() { + @Override + public void sync() { + int ioff = offset; + for(int i=0; i<mats.length; ++i, ioff+=16) { + mats[i].get(matrixStore, ioff); + } + } + }; + + public SyncBufferN(final Matrix4f[] ms, final FloatBuffer fbuf, final int offset) { + super(ms, fbuf); + this.offset = offset; + } + + @Override + public SyncAction getAction() { return action; } + } + private final class SyncBufferNU extends PMVSyncBufferN { + private final int offset; + private final SyncAction action = new SyncAction() { + @Override + public void sync() { + updateImpl(true); + int ioff = offset; + for(int i=0; i<mats.length; ++i, ioff+=16) { + mats[i].get(matrixStore, ioff); + } + } + }; + + public SyncBufferNU(final Matrix4f[] ms, final FloatBuffer fbuf, final int offset) { + super(ms, fbuf); + this.offset = offset; + } + + @Override + public SyncAction getAction() { return action; } } } diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PMSAAES2.java b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PMSAAES2.java index bc5fe7d11..d970b7029 100644 --- a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PMSAAES2.java +++ b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PMSAAES2.java @@ -383,7 +383,6 @@ public final class VBORegion2PMSAAES2 extends GLRegion { private final AABBox drawWinBox = new AABBox(); private final Recti drawView = new Recti(); - private final Matrix4f drawMat4PMv = new Matrix4f(); private static final int border = 2; // surrounding border, i.e. width += 2*border, height +=2*border @@ -426,8 +425,7 @@ public final class VBORegion2PMSAAES2 extends GLRegion { drawView.setWidth(vpWidth); drawView.setHeight(vpHeight); - renderer.getMatrix().mulPMvMat(drawMat4PMv); - box.mapToWindow(drawWinBox, drawMat4PMv, drawView, true /* useCenterZ */); + box.mapToWindow(drawWinBox, renderer.getMatrix().getPMvMat(), drawView, true /* useCenterZ */); winWidth = drawWinBox.getWidth(); winHeight = drawWinBox.getHeight(); diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PVBAAES2.java b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PVBAAES2.java index a7fce3a92..889f4448d 100644 --- a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PVBAAES2.java +++ b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PVBAAES2.java @@ -444,7 +444,6 @@ public final class VBORegion2PVBAAES2 extends GLRegion { private final AABBox drawWinBox = new AABBox(); private final Recti drawView = new Recti(); - private final Matrix4f drawMat4PMv = new Matrix4f(); private static final int border = 2; // surrounding border, i.e. width += 2*border, height +=2*border @@ -487,8 +486,7 @@ public final class VBORegion2PVBAAES2 extends GLRegion { drawView.setWidth(vpWidth); drawView.setHeight(vpHeight); - renderer.getMatrix().mulPMvMat(drawMat4PMv); - box.mapToWindow(drawWinBox, drawMat4PMv, drawView, true /* useCenterZ */); + box.mapToWindow(drawWinBox, renderer.getMatrix().getPMvMat(), drawView, true /* useCenterZ */); winWidth = drawWinBox.getWidth(); winHeight = drawWinBox.getHeight(); 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 9cd8c863f..998406856 100644 --- a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/FixedFuncHook.java +++ b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/FixedFuncHook.java @@ -70,7 +70,7 @@ public class FixedFuncHook implements GLLightingFunc, GLMatrixFunc, GLPointerFun this.pmvMatrix = pmvMatrix; } else { this.ownsPMVMatrix = true; - this.pmvMatrix = new PMVMatrix(); + this.pmvMatrix = new PMVMatrix(PMVMatrix.INVERSE_MODELVIEW | PMVMatrix.INVERSE_TRANSPOSED_MODELVIEW); } fixedFunction = new FixedFuncPipeline(this.gl, mode, this.pmvMatrix); } @@ -91,7 +91,7 @@ public class FixedFuncHook implements GLLightingFunc, GLMatrixFunc, GLPointerFun this.pmvMatrix = pmvMatrix; } else { this.ownsPMVMatrix = true; - this.pmvMatrix = new PMVMatrix(); + this.pmvMatrix = new PMVMatrix(PMVMatrix.INVERSE_MODELVIEW | PMVMatrix.INVERSE_TRANSPOSED_MODELVIEW); } fixedFunction = new FixedFuncPipeline(this.gl, mode, this.pmvMatrix, shaderRootClass, shaderSrcRoot, diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/FixedFuncPipeline.java b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/FixedFuncPipeline.java index 6b7317dd6..c9e2664ba 100644 --- a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/FixedFuncPipeline.java +++ b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/FixedFuncPipeline.java @@ -56,6 +56,7 @@ import com.jogamp.common.util.IntIntHashMap; import com.jogamp.common.util.PropertyAccess; import com.jogamp.opengl.util.PMVMatrix; import com.jogamp.opengl.util.SyncBuffer; +import com.jogamp.opengl.util.SyncMatrices4f; import com.jogamp.opengl.util.glsl.ShaderCode; import com.jogamp.opengl.util.glsl.ShaderProgram; import com.jogamp.opengl.util.glsl.ShaderState; @@ -813,13 +814,13 @@ public class FixedFuncPipeline { } GLUniformData ud; - if( pmvMatrix.update() ) { + if( pmvMatrix.isReqDirty() ) { ud = shaderState.getUniform(mgl_PMVMatrix); if(null!=ud) { - final SyncBuffer m; + final SyncMatrices4f m; if(ShaderSelectionMode.COLOR_TEXTURE8_LIGHT_PER_VERTEX == currentShaderSelectionMode || ShaderSelectionMode.COLOR_LIGHT_PER_VERTEX== currentShaderSelectionMode ) { - m = pmvMatrix.getSyncPMvMvitMat(); + m = pmvMatrix.getSyncPMvMviMvitMat(); } else { m = pmvMatrix.getSyncPMvMat(); } @@ -827,7 +828,7 @@ public class FixedFuncPipeline { ud.setData(m); } // same data object .. - shaderState.uniform(gl, ud); + shaderState.uniform(gl, ud); // automatic sync + update of Mvi + Mvit } else { throw new GLException("Failed to update: mgl_PMVMatrix"); } @@ -1113,7 +1114,7 @@ public class FixedFuncPipeline { shaderState.attachShaderProgram(gl, selectShaderProgram(gl, requestedShaderSelectionMode), true); // mandatory .. - if(!shaderState.uniform(gl, new GLUniformData(mgl_PMVMatrix, 4, 4, pmvMatrix.getSyncPMvMvitMat()))) { + if(!shaderState.uniform(gl, new GLUniformData(mgl_PMVMatrix, 4, 4, pmvMatrix.getSyncPMvMviMvitMat()))) { throw new GLException("Error setting PMVMatrix in shader: "+this); } diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java index b466f460f..b0f89eb1a 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java @@ -231,9 +231,9 @@ public class GearsES2 implements StereoGLEventListener, TileRendererBase.TileRen // Use debug pipeline // drawable.setGL(new DebugGL(drawable.getGL())); - pmvMatrix = new PMVMatrix(); + pmvMatrix = new PMVMatrix(PMVMatrix.INVERSE_MODELVIEW | PMVMatrix.INVERSE_TRANSPOSED_MODELVIEW); st.attachObject("pmvMatrix", pmvMatrix); - pmvMatrixUniform = new GLUniformData("pmvMatrix", 4, 4, pmvMatrix.getSyncPMvMvitMat()); // P, Mv, Mvi and Mvit + pmvMatrixUniform = new GLUniformData("pmvMatrix", 4, 4, pmvMatrix.getSyncPMvMviMvitMat()); // P, Mv, Mvi and Mvit st.ownUniform(pmvMatrixUniform); st.uniform(gl, pmvMatrixUniform); diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsObjectES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsObjectES2.java index a74b6e6f1..33ef7477c 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsObjectES2.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsObjectES2.java @@ -124,11 +124,7 @@ public class GearsObjectES2 extends GearsObject { pmvMatrix.glPushMatrix(); pmvMatrix.glTranslatef(x, y, 0f); pmvMatrix.glRotatef(angle, 0f, 0f, 1f); - if( pmvMatrix.update() ) { - st.uniform(gl, pmvMatrixUniform); - } else { - throw new InternalError("PMVMatrix.update() returns false after mutable operations"); - } + st.uniform(gl, pmvMatrixUniform); // automatic sync + update of Mvi + Mvit colorUniform.setData(gearColor); st.uniform(gl, colorUniform); diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl4/TriangleInstancedRendererWithShaderState.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl4/TriangleInstancedRendererWithShaderState.java index c7f04531e..9799ee6b6 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl4/TriangleInstancedRendererWithShaderState.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl4/TriangleInstancedRendererWithShaderState.java @@ -139,7 +139,6 @@ public class TriangleInstancedRendererWithShaderState implements GLEventListener float winScale = 0.1f; if(view != null) winScale = view.getScale(); projectionMatrix.glScalef(winScale, winScale, winScale); - projectionMatrix.update(); st.uniform(gl, projectionMatrixUniform); projectionMatrix.glPopMatrix(); diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl4/TrianglesInstancedRendererHardcoded.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl4/TrianglesInstancedRendererHardcoded.java index fee3c7f4f..aa2a0ee6a 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl4/TrianglesInstancedRendererHardcoded.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl4/TrianglesInstancedRendererHardcoded.java @@ -99,7 +99,6 @@ public class TrianglesInstancedRendererHardcoded implements GLEventListener { winScale = view.getScale(); } projectionMatrix.glScalef(winScale, winScale, winScale); - projectionMatrix.update(); gl.glUniformMatrix4fv(projectionMatrixLocation, 1, false, projectionMatrix.getSyncPMat().getSyncFloats()); projectionMatrix.glPopMatrix(); generateTriangleTransform(); diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/math/TestMatrix4fProject01NOUI.java b/src/test/com/jogamp/opengl/test/junit/jogl/math/TestMatrix4fProject01NOUI.java index f32894818..b22bf9ad7 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/math/TestMatrix4fProject01NOUI.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/math/TestMatrix4fProject01NOUI.java @@ -140,7 +140,7 @@ public class TestMatrix4fProject01NOUI extends JunitTracer { mat4P.load( m.getMat(GLMatrixFunc.GL_PROJECTION_MATRIX) ); Assert.assertEquals(new Matrix4f(mat4Mv_f16), mat4Mv); Assert.assertEquals(new Matrix4f(mat4P_f16), mat4P); - Assert.assertEquals(mat4Mv, m.getMviMat()); + Assert.assertEquals(mat4Mv, m.getMvMat()); Assert.assertEquals(mat4P, m.getPMat()); m.gluProject(new Vec3f(1f, 0f, 0f), viewport, winA00); @@ -165,7 +165,7 @@ public class TestMatrix4fProject01NOUI extends JunitTracer { mat4P.load( m.getMat(GLMatrixFunc.GL_PROJECTION_MATRIX) ); Assert.assertEquals(new Matrix4f(mat4Mv_f16), mat4Mv); Assert.assertEquals(new Matrix4f(mat4P_f16), mat4P); - Assert.assertEquals(mat4Mv, m.getMviMat()); + Assert.assertEquals(mat4Mv, m.getMvMat()); Assert.assertEquals(mat4P, m.getPMat()); m.gluProject(new Vec3f(1f, 0f, 0f), viewport, winA10); diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/math/TestPMVMatrix01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/math/TestPMVMatrix01NEWT.java index d2abbb4c8..7119a7c48 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/math/TestPMVMatrix01NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/math/TestPMVMatrix01NEWT.java @@ -49,7 +49,6 @@ import org.junit.runners.MethodSorters; import com.jogamp.opengl.math.FloatUtil; import com.jogamp.opengl.math.Matrix4f; -import com.jogamp.opengl.math.geom.Frustum; import com.jogamp.opengl.test.junit.util.MiscUtils; import com.jogamp.opengl.test.junit.util.UITestCase; import com.jogamp.opengl.util.PMVMatrix; @@ -136,20 +135,103 @@ public class TestPMVMatrix01NEWT extends UITestCase { /** * Test using traditional access workflow, i.e. 1) operation 2) get-matrix references * <p> + * No Mvi nor Mvit being used. + * </p> + */ + @Test + public void test01aTraditionalAccess() { + Matrix4f p, mv; + final PMVMatrix pmv = new PMVMatrix(); + System.err.println("test01a.P0: "+pmv.toString()); + + Assert.assertEquals(0, pmv.getReqBits()); + Assert.assertEquals(false, pmv.isReqDirty()); + Assert.assertTrue(0 != pmv.getDirtyBits()); + Assert.assertEquals(PMVMatrix.MANUAL_BITS, pmv.getDirtyBits()); + + // + // Action #0 + // + final Matrix4f ident; + { + pmv.glMatrixMode(GLMatrixFunc.GL_PROJECTION); + pmv.glLoadIdentity(); + ident = pmv.getPMat(); + + pmv.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); + pmv.glLoadIdentity(); + } + Assert.assertTrue(0 != pmv.getModifiedBits(true)); // clear & test + Assert.assertTrue(0 == pmv.getModifiedBits(false)); // clear & test + Assert.assertTrue(0 != pmv.getDirtyBits()); + Assert.assertEquals(false, pmv.isReqDirty()); + Assert.assertEquals(PMVMatrix.MANUAL_BITS, pmv.getDirtyBits()); + + // + // Action #1 + // + pmv.glTranslatef(1f, 2f, 3f); // all dirty ! + Assert.assertTrue("Modified bits zero", 0 != pmv.getModifiedBits(true)); // clear & test + Assert.assertTrue("Dirty bits clean, "+pmv.toString(), 0 != pmv.getDirtyBits()); + System.err.println("test01a.P1: "+pmv.toString()); + + Assert.assertEquals(false, pmv.isReqDirty()); + Assert.assertTrue(0 != pmv.getDirtyBits()); + Assert.assertEquals(PMVMatrix.MANUAL_BITS, pmv.getDirtyBits()); + Assert.assertEquals("Update has been perfomed, but non requested", false, pmv.update()); // nothing has been requested + // System.err.println("P2: "+pmv.toString()); + + // + // Get + // + p = pmv.getPMat(); + MiscUtils.assertMatrix4fEquals("P not identity, "+pmv.toString(), ident, p, epsilon); + mv = pmv.getMvMat(); + MiscUtils.assertMatrix4fEquals("Mv not translated123, "+pmv.toString(), translated123C, mv, epsilon); + { + IllegalArgumentException e = null; + try { + pmv.getMviMat(); + } catch(final IllegalArgumentException iae) { + e = iae; + } + Assert.assertNotNull(e); + } + Assert.assertEquals(PMVMatrix.MANUAL_BITS, pmv.getDirtyBits()); + Assert.assertNotNull(pmv.getFrustum()); // FIXME: Test Frustum value! + Assert.assertNotNull(pmv.getPMvMat()); // FIXME: Test value! + Assert.assertNotNull(pmv.getPMviMat()); // FIXME: Test value! + Assert.assertEquals(0, pmv.getDirtyBits()); + // System.err.println("P3: "+pmv.toString()); + + // + // Action #2 + // + pmv.glLoadIdentity(); // all dirty + Assert.assertTrue(0 != pmv.getModifiedBits(true)); // clear & test + Assert.assertEquals(PMVMatrix.MANUAL_BITS, pmv.getDirtyBits()); + System.err.println("test01a.PX: "+pmv.toString()); + } + + /** + * Test using traditional access workflow, i.e. 1) operation 2) get-matrix references + * <p> * The Mvi, Mvit and Frustum dirty-bits and request-mask will be validated. * </p> */ @Test - public void test01MviUpdateTraditionalAccess() { + public void test01bTraditionalAccess() { Matrix4f p, mv, mvi, mvit; - Frustum frustum; - boolean b; - final PMVMatrix pmv = new PMVMatrix(); - // System.err.println("P0: "+pmv.toString()); + final PMVMatrix pmv = new PMVMatrix(PMVMatrix.INVERSE_MODELVIEW | PMVMatrix.INVERSE_TRANSPOSED_MODELVIEW); + System.err.println("test01b.P0: "+pmv.toString()); + + Assert.assertEquals(PMVMatrix.INVERSE_MODELVIEW | PMVMatrix.INVERSE_TRANSPOSED_MODELVIEW, pmv.getReqBits()); + Assert.assertTrue(0 != pmv.getDirtyBits()); + Assert.assertEquals(true, pmv.isReqDirty()); + Assert.assertEquals(PMVMatrix.INVERSE_MODELVIEW | PMVMatrix.INVERSE_TRANSPOSED_MODELVIEW | PMVMatrix.MANUAL_BITS, pmv.getDirtyBits()); Assert.assertTrue("Dirty bits clean, "+pmv.toString(), 0 != pmv.getDirtyBits()); - Assert.assertEquals("Remaining dirty bits not Mvi|Mvit|Frustum, "+pmv.toString(), PMVMatrix.DIRTY_INVERSE_MODELVIEW|PMVMatrix.DIRTY_INVERSE_TRANSPOSED_MODELVIEW | PMVMatrix.DIRTY_FRUSTUM, pmv.getDirtyBits()); - Assert.assertEquals("Request bits not zero, "+pmv.toString(), 0, pmv.getRequestMask()); + Assert.assertEquals("Remaining dirty bits not Mvi|Mvit|Frustum, "+pmv.toString(), PMVMatrix.INVERSE_MODELVIEW | PMVMatrix.INVERSE_TRANSPOSED_MODELVIEW | PMVMatrix.MANUAL_BITS, pmv.getDirtyBits()); // // Action #0 @@ -165,8 +247,7 @@ public class TestPMVMatrix01NEWT extends UITestCase { } Assert.assertTrue("Modified bits zero", 0 != pmv.getModifiedBits(true)); // clear & test Assert.assertTrue("Dirty bits clean, "+pmv.toString(), 0 != pmv.getDirtyBits()); - Assert.assertEquals("Remaining dirty bits not Mvi|Mvit|Frustum, "+pmv.toString(), PMVMatrix.DIRTY_INVERSE_MODELVIEW|PMVMatrix.DIRTY_INVERSE_TRANSPOSED_MODELVIEW | PMVMatrix.DIRTY_FRUSTUM, pmv.getDirtyBits()); - Assert.assertEquals("Request bits not zero, "+pmv.toString(), 0, pmv.getRequestMask()); + Assert.assertEquals("Remaining dirty bits not Mvi|Mvit|Frustum, "+pmv.toString(), PMVMatrix.INVERSE_MODELVIEW|PMVMatrix.INVERSE_TRANSPOSED_MODELVIEW | PMVMatrix.MANUAL_BITS, pmv.getDirtyBits()); // // Action #1 @@ -174,15 +255,19 @@ public class TestPMVMatrix01NEWT extends UITestCase { pmv.glTranslatef(1f, 2f, 3f); // all dirty ! Assert.assertTrue("Modified bits zero", 0 != pmv.getModifiedBits(true)); // clear & test Assert.assertTrue("Dirty bits clean, "+pmv.toString(), 0 != pmv.getDirtyBits()); - Assert.assertEquals("Remaining dirty bits not Mvi|Mvit|Frustum, "+pmv.toString(), PMVMatrix.DIRTY_INVERSE_MODELVIEW|PMVMatrix.DIRTY_INVERSE_TRANSPOSED_MODELVIEW | PMVMatrix.DIRTY_FRUSTUM, pmv.getDirtyBits()); - Assert.assertEquals("Request bits not zero, "+pmv.toString(), 0, pmv.getRequestMask()); - // System.err.println("P1: "+pmv.toString()); - - b = pmv.update(); // will not clean dirty bits, since no request has been made -> false - Assert.assertEquals("Update has been perfomed, but non requested", false, b); - Assert.assertTrue("Dirty bits clean, "+pmv.toString(), 0 != pmv.getDirtyBits()); - Assert.assertEquals("Remaining dirty bits not Mvi|Mvit|Frustum, "+pmv.toString(), PMVMatrix.DIRTY_INVERSE_MODELVIEW|PMVMatrix.DIRTY_INVERSE_TRANSPOSED_MODELVIEW | PMVMatrix.DIRTY_FRUSTUM, pmv.getDirtyBits()); - Assert.assertEquals("Request bits not zero, "+pmv.toString(), 0, pmv.getRequestMask()); + Assert.assertEquals("Remaining dirty bits not Mvi|Mvit|Frustum, "+pmv.toString(), PMVMatrix.INVERSE_MODELVIEW|PMVMatrix.INVERSE_TRANSPOSED_MODELVIEW | PMVMatrix.MANUAL_BITS, pmv.getDirtyBits()); + System.err.println("test01b.P1: "+pmv.toString()); + + Assert.assertEquals(PMVMatrix.INVERSE_MODELVIEW | PMVMatrix.INVERSE_TRANSPOSED_MODELVIEW | PMVMatrix.MANUAL_BITS, pmv.getDirtyBits()); + Assert.assertEquals(true, pmv.isReqDirty()); + Assert.assertEquals(true, pmv.update()); + Assert.assertEquals(PMVMatrix.MANUAL_BITS, pmv.getDirtyBits()); + Assert.assertEquals(false, pmv.isReqDirty()); + Assert.assertNotNull(pmv.getFrustum()); // FIXME: Test Frustum value! + Assert.assertNotNull(pmv.getPMvMat()); // FIXME: Test value! + Assert.assertNotNull(pmv.getPMviMat()); // FIXME: Test value! + Assert.assertEquals(0, pmv.getDirtyBits()); + Assert.assertEquals(false, pmv.isReqDirty()); // System.err.println("P2: "+pmv.toString()); // @@ -194,19 +279,20 @@ public class TestPMVMatrix01NEWT extends UITestCase { MiscUtils.assertMatrix4fEquals("Mv not translated123, "+pmv.toString(), translated123C, mv, epsilon); mvi = pmv.getMviMat(); MiscUtils.assertMatrix4fEquals("Mvi not translated123, "+pmv.toString(), translated123I, mvi, epsilon); - Assert.assertEquals("Request bit Mvi not set, "+pmv.toString(), PMVMatrix.DIRTY_INVERSE_MODELVIEW, pmv.getRequestMask()); - Assert.assertEquals("Remaining dirty bits not Mvit|Frustum, "+pmv.toString(), PMVMatrix.DIRTY_INVERSE_TRANSPOSED_MODELVIEW | PMVMatrix.DIRTY_FRUSTUM, pmv.getDirtyBits()); - - frustum = pmv.getFrustum(); - Assert.assertNotNull("Frustum is null"+pmv.toString(), frustum); // FIXME: Test Frustum value! - Assert.assertEquals("Remaining dirty bits not Mvit, "+pmv.toString(), PMVMatrix.DIRTY_INVERSE_TRANSPOSED_MODELVIEW, pmv.getDirtyBits()); - Assert.assertEquals("Request bits Mvi|Frustum not set, "+pmv.toString(), PMVMatrix.DIRTY_INVERSE_MODELVIEW | PMVMatrix.DIRTY_FRUSTUM, pmv.getRequestMask()); + Assert.assertEquals(0, pmv.getDirtyBits()); + Assert.assertEquals(false, pmv.isReqDirty()); + + Assert.assertNotNull(pmv.getFrustum()); // FIXME: Test Frustum value! + Assert.assertNotNull(pmv.getPMvMat()); // FIXME: Test value! + Assert.assertNotNull(pmv.getPMviMat()); // FIXME: Test value! + Assert.assertEquals(0, pmv.getDirtyBits()); + Assert.assertEquals(false, pmv.isReqDirty()); // System.err.println("P3: "+pmv.toString()); mvit = pmv.getMvitMat(); MiscUtils.assertMatrix4fEquals("Mvit not translated123, "+pmv.toString()+pmv.toString(), translated123IT, mvit, epsilon); - Assert.assertTrue("Dirty bits not clean, "+pmv.toString(), 0 == pmv.getDirtyBits()); - Assert.assertEquals("Request bits Mvi|Mvit|Frustum not set, "+pmv.toString(), PMVMatrix.DIRTY_INVERSE_MODELVIEW | PMVMatrix.DIRTY_INVERSE_TRANSPOSED_MODELVIEW | PMVMatrix.DIRTY_FRUSTUM, pmv.getRequestMask()); + Assert.assertEquals(0, pmv.getDirtyBits()); + Assert.assertEquals(false, pmv.isReqDirty()); // System.err.println("P4: "+pmv.toString()); // @@ -214,24 +300,31 @@ public class TestPMVMatrix01NEWT extends UITestCase { // pmv.glLoadIdentity(); // all dirty Assert.assertTrue("Modified bits zero", 0 != pmv.getModifiedBits(true)); // clear & test - Assert.assertTrue("Dirty bits clean, "+pmv.toString(), 0 != pmv.getDirtyBits()); - Assert.assertEquals("Remaining dirty bits not Mvi|Mvit|Frustum, "+pmv.toString(), PMVMatrix.DIRTY_INVERSE_MODELVIEW|PMVMatrix.DIRTY_INVERSE_TRANSPOSED_MODELVIEW | PMVMatrix.DIRTY_FRUSTUM, pmv.getDirtyBits()); - Assert.assertEquals("Request bits Mvi|Mvit|Frustum not set, "+pmv.toString(), PMVMatrix.DIRTY_INVERSE_MODELVIEW | PMVMatrix.DIRTY_INVERSE_TRANSPOSED_MODELVIEW | PMVMatrix.DIRTY_FRUSTUM, pmv.getRequestMask()); + Assert.assertTrue(0 != pmv.getDirtyBits()); + Assert.assertEquals(true, pmv.isReqDirty()); + Assert.assertEquals(PMVMatrix.INVERSE_MODELVIEW | PMVMatrix.INVERSE_TRANSPOSED_MODELVIEW | PMVMatrix.MANUAL_BITS, pmv.getDirtyBits()); + System.err.println("test01b.P2: "+pmv.toString()); MiscUtils.assertMatrix4fEquals("P not identity, "+pmv.toString(), ident, p, epsilon); MiscUtils.assertMatrix4fEquals("Mv not identity, "+pmv.toString(), ident, mv, epsilon); MiscUtils.assertMatrix4fNotEqual("Mvi already identity w/o update, "+pmv.toString(), ident, mvi, epsilon); MiscUtils.assertMatrix4fNotEqual("Mvit already identity w/o update, "+pmv.toString(), ident, mvit, epsilon); MiscUtils.assertMatrix4fEquals("Mvi not translated123, "+pmv.toString()+pmv.toString(), translated123I, mvi, epsilon); MiscUtils.assertMatrix4fEquals("Mvit not translated123, "+pmv.toString()+pmv.toString(), translated123IT, mvit, epsilon); - Assert.assertNotNull("Frustum is null"+pmv.toString(), frustum); // FIXME: Test Frustum value! - b = pmv.update(); // will clean dirty bits, since request has been made -> true - Assert.assertEquals("Update has not been perfomed, but requested", true, b); - Assert.assertTrue("Dirty bits not clean, "+pmv.toString(), 0 == pmv.getDirtyBits()); - Assert.assertEquals("Request bits Mvi|Mvit|Frustum not set, "+pmv.toString(), PMVMatrix.DIRTY_INVERSE_MODELVIEW | PMVMatrix.DIRTY_INVERSE_TRANSPOSED_MODELVIEW | PMVMatrix.DIRTY_FRUSTUM, pmv.getRequestMask()); + Assert.assertEquals(true, pmv.update()); + Assert.assertTrue(0 != pmv.getDirtyBits()); + Assert.assertEquals(false, pmv.isReqDirty()); + Assert.assertEquals(PMVMatrix.MANUAL_BITS, pmv.getDirtyBits()); + MiscUtils.assertMatrix4fEquals("Mvi not identity after update, "+pmv.toString(), ident, mvi, epsilon); MiscUtils.assertMatrix4fEquals("Mvit not identity after update, "+pmv.toString(), ident, mvit, epsilon); - Assert.assertNotNull("Frustum is null"+pmv.toString(), frustum); // FIXME: Test Frustum value! + + Assert.assertNotNull(pmv.getFrustum()); // FIXME: Test Frustum value! + Assert.assertNotNull(pmv.getPMvMat()); // FIXME: Test value! + Assert.assertNotNull(pmv.getPMviMat()); // FIXME: Test value! + Assert.assertEquals(0, pmv.getDirtyBits()); + Assert.assertEquals(false, pmv.isReqDirty()); + System.err.println("test01b.PX: "+pmv.toString()); } /** @@ -243,14 +336,13 @@ public class TestPMVMatrix01NEWT extends UITestCase { @Test public void test02MviUpdateShaderAccess() { final Matrix4f p, mv, mvi, mvit; - Frustum frustum; - boolean b; - final PMVMatrix pmv = new PMVMatrix(); + final PMVMatrix pmv = new PMVMatrix(PMVMatrix.INVERSE_MODELVIEW | PMVMatrix.INVERSE_TRANSPOSED_MODELVIEW); // System.err.println("P0: "+pmv.toString()); - Assert.assertTrue("Dirty bits clean, "+pmv.toString(), 0 != pmv.getDirtyBits()); - Assert.assertEquals("Remaining dirty bits not Mvi|Mvit|Frustum, "+pmv.toString(), PMVMatrix.DIRTY_INVERSE_MODELVIEW|PMVMatrix.DIRTY_INVERSE_TRANSPOSED_MODELVIEW | PMVMatrix.DIRTY_FRUSTUM, pmv.getDirtyBits()); - Assert.assertEquals("Request bits not zero, "+pmv.toString(), 0, pmv.getRequestMask()); + Assert.assertEquals(PMVMatrix.INVERSE_MODELVIEW | PMVMatrix.INVERSE_TRANSPOSED_MODELVIEW, pmv.getReqBits()); + Assert.assertTrue(0 != pmv.getDirtyBits()); + Assert.assertEquals(true, pmv.isReqDirty()); + Assert.assertEquals(PMVMatrix.INVERSE_MODELVIEW | PMVMatrix.INVERSE_TRANSPOSED_MODELVIEW | PMVMatrix.MANUAL_BITS, pmv.getDirtyBits()); // // Action #0 @@ -266,9 +358,17 @@ public class TestPMVMatrix01NEWT extends UITestCase { } // System.err.println("P0: "+pmv.toString()); Assert.assertTrue("Modified bits zero", 0 != pmv.getModifiedBits(true)); // clear & test - Assert.assertTrue("Dirty bits clean, "+pmv.toString(), 0 != pmv.getDirtyBits()); - Assert.assertEquals("Remaining dirty bits not Mvi|Mvit|Frustum, "+pmv.toString(), PMVMatrix.DIRTY_INVERSE_MODELVIEW|PMVMatrix.DIRTY_INVERSE_TRANSPOSED_MODELVIEW | PMVMatrix.DIRTY_FRUSTUM, pmv.getDirtyBits()); - Assert.assertEquals("Request bits not zero, "+pmv.toString(), 0, pmv.getRequestMask()); + + Assert.assertEquals(PMVMatrix.INVERSE_MODELVIEW | PMVMatrix.INVERSE_TRANSPOSED_MODELVIEW | PMVMatrix.MANUAL_BITS, pmv.getDirtyBits()); + Assert.assertEquals(true, pmv.isReqDirty()); + Assert.assertEquals(true, pmv.update()); + Assert.assertEquals(PMVMatrix.MANUAL_BITS, pmv.getDirtyBits()); + Assert.assertEquals(false, pmv.isReqDirty()); + Assert.assertNotNull(pmv.getFrustum()); // FIXME: Test Frustum value! + Assert.assertNotNull(pmv.getPMvMat()); // FIXME: Test value! + Assert.assertNotNull(pmv.getPMviMat()); // FIXME: Test value! + Assert.assertEquals(0, pmv.getDirtyBits()); + Assert.assertEquals(false, pmv.isReqDirty()); // System.err.println("P1: "+pmv.toString()); // @@ -278,23 +378,18 @@ public class TestPMVMatrix01NEWT extends UITestCase { MiscUtils.assertMatrix4fEquals("P not identity, "+pmv.toString(), ident, p, epsilon); mv = pmv.getMvMat(); MiscUtils.assertMatrix4fEquals("Mv not identity, "+pmv.toString(), ident, mv, epsilon); - Assert.assertTrue("Dirty bits clean, "+pmv.toString(), 0 != pmv.getDirtyBits()); - Assert.assertEquals("Request bits not zero, "+pmv.toString(), 0, pmv.getRequestMask()); + Assert.assertEquals(0, pmv.getDirtyBits()); + Assert.assertEquals(false, pmv.isReqDirty()); mvi = pmv.getMviMat(); MiscUtils.assertMatrix4fEquals("Mvi not identity, "+pmv.toString(), ident, mvi, epsilon); - Assert.assertEquals("Remaining dirty bits not Mvit|Frustum, "+pmv.toString(), PMVMatrix.DIRTY_INVERSE_TRANSPOSED_MODELVIEW | PMVMatrix.DIRTY_FRUSTUM, pmv.getDirtyBits()); - Assert.assertEquals("Request bit Mvi not set, "+pmv.toString(), PMVMatrix.DIRTY_INVERSE_MODELVIEW, pmv.getRequestMask()); + Assert.assertEquals(0, pmv.getDirtyBits()); + Assert.assertEquals(false, pmv.isReqDirty()); mvit = pmv.getMvitMat(); MiscUtils.assertMatrix4fEquals("Mvi not identity, "+pmv.toString(), ident, mvit, epsilon); - Assert.assertEquals("Remaining dirty bits not Frustum, "+pmv.toString(), PMVMatrix.DIRTY_FRUSTUM, pmv.getDirtyBits()); - Assert.assertEquals("Request bits Mvi and Mvit not set, "+pmv.toString(), PMVMatrix.DIRTY_INVERSE_MODELVIEW | PMVMatrix.DIRTY_INVERSE_TRANSPOSED_MODELVIEW, pmv.getRequestMask()); - - frustum = pmv.getFrustum(); - Assert.assertNotNull("Frustum is null"+pmv.toString(), frustum); // FIXME: Test Frustum value! - Assert.assertTrue("Dirty bits not clean, "+pmv.toString(), 0 == pmv.getDirtyBits()); - Assert.assertEquals("Request bits Mvi|Mvit|Frustum not set, "+pmv.toString(), PMVMatrix.DIRTY_INVERSE_MODELVIEW | PMVMatrix.DIRTY_INVERSE_TRANSPOSED_MODELVIEW | PMVMatrix.DIRTY_FRUSTUM, pmv.getRequestMask()); + Assert.assertEquals(0, pmv.getDirtyBits()); + Assert.assertEquals(false, pmv.isReqDirty()); // // Action #1 @@ -302,27 +397,32 @@ public class TestPMVMatrix01NEWT extends UITestCase { pmv.glTranslatef(1f, 2f, 3f); // all dirty ! Assert.assertTrue("Modified bits zero", 0 != pmv.getModifiedBits(true)); // clear & test Assert.assertTrue("Dirty bits clean, "+pmv.toString(), 0 != pmv.getDirtyBits()); - Assert.assertEquals("Remaining dirty bits not Mvi|Mvit|Frustum, "+pmv.toString(), PMVMatrix.DIRTY_INVERSE_MODELVIEW|PMVMatrix.DIRTY_INVERSE_TRANSPOSED_MODELVIEW | PMVMatrix.DIRTY_FRUSTUM, pmv.getDirtyBits()); + Assert.assertEquals("Remaining dirty bits not Mvi|Mvit|Frustum, "+pmv.toString(), PMVMatrix.INVERSE_MODELVIEW|PMVMatrix.INVERSE_TRANSPOSED_MODELVIEW | PMVMatrix.MANUAL_BITS, pmv.getDirtyBits()); MiscUtils.assertMatrix4fEquals("P not identity, "+pmv.toString()+pmv.toString(), ident, p, epsilon); MiscUtils.assertMatrix4fEquals("Mv not translated123, "+pmv.toString()+pmv.toString(), translated123C, mv, epsilon); MiscUtils.assertMatrix4fNotEqual("Mvi already translated123 w/o update, "+pmv.toString()+pmv.toString(), translated123I, mvi, epsilon); MiscUtils.assertMatrix4fNotEqual("Mvit already translated123 w/o update, "+pmv.toString()+pmv.toString(), translated123IT, mvit, epsilon); MiscUtils.assertMatrix4fEquals("Mvi not identity, "+pmv.toString()+pmv.toString(), ident, mvi, epsilon); MiscUtils.assertMatrix4fEquals("Mvit not identity, "+pmv.toString()+pmv.toString(), ident, mvit, epsilon); - Assert.assertNotNull("Frustum is null"+pmv.toString(), frustum); // FIXME: Test Frustum value! - b = pmv.update(); // will clean dirty bits, since all requests has been made -> true - Assert.assertEquals("Update has not been perfomed, but requested", true, b); - Assert.assertTrue("Dirty bits not clean, "+pmv.toString(), 0 == pmv.getDirtyBits()); - Assert.assertEquals("Request bits Mvi|Mvit|Frustum not set, "+pmv.toString(), PMVMatrix.DIRTY_INVERSE_MODELVIEW | PMVMatrix.DIRTY_INVERSE_TRANSPOSED_MODELVIEW | PMVMatrix.DIRTY_FRUSTUM, pmv.getRequestMask()); + Assert.assertEquals(PMVMatrix.INVERSE_MODELVIEW | PMVMatrix.INVERSE_TRANSPOSED_MODELVIEW | PMVMatrix.MANUAL_BITS, pmv.getDirtyBits()); + Assert.assertEquals(true, pmv.isReqDirty()); + Assert.assertEquals(true, pmv.update()); // will clean dirty bits, since all requests has been made -> true + Assert.assertEquals(PMVMatrix.MANUAL_BITS, pmv.getDirtyBits()); + Assert.assertEquals(false, pmv.isReqDirty()); + Assert.assertNotNull(pmv.getFrustum()); // FIXME: Test Frustum value! + Assert.assertNotNull(pmv.getPMvMat()); // FIXME: Test value! + Assert.assertNotNull(pmv.getPMviMat()); // FIXME: Test value! + Assert.assertEquals(0, pmv.getDirtyBits()); + Assert.assertEquals(false, pmv.isReqDirty()); MiscUtils.assertMatrix4fEquals("Mvi not translated123, "+pmv.toString()+pmv.toString(), translated123I, mvi, epsilon); MiscUtils.assertMatrix4fEquals("Mvit not translated123, "+pmv.toString()+pmv.toString(), translated123IT, mvit, epsilon); // System.err.println("P2: "+pmv.toString()); } @Test - public void test03MvTranslate() { - final Matrix4f pmvMv; + public void test10MvTranslate() { + final Matrix4f pmvMv = new Matrix4f(); // final Matrix4f pmvMvi, pmvMvit; { final PMVMatrix pmv = new PMVMatrix(); @@ -332,7 +432,7 @@ public class TestPMVMatrix01NEWT extends UITestCase { pmv.glLoadIdentity(); pmv.glTranslatef(5f, 6f, 7f); - pmvMv = pmv.getMvMat(); + pmvMv.load(pmv.getMvMat()); // pmvMvi = pmv.glGetMviMatrixf(); // pmvMvit = pmv.glGetMvitMatrixf(); } @@ -361,8 +461,8 @@ public class TestPMVMatrix01NEWT extends UITestCase { } @Test - public void test04MvTranslateRotate() { - final Matrix4f pmvMv; + public void test11MvTranslateRotate() { + final Matrix4f pmvMv = new Matrix4f(); // final Matrix4f pmvMvi, pmvMvit; { final PMVMatrix pmv = new PMVMatrix(); @@ -373,7 +473,7 @@ public class TestPMVMatrix01NEWT extends UITestCase { pmv.glTranslatef(5f, 6f, 7f); pmv.glRotatef(90f, 1f, 0f, 0f); - pmvMv = pmv.getMvMat(); + pmvMv.load(pmv.getMvMat()); // pmvMvi = pmv.glGetMviMatrixf(); // pmvMvit = pmv.glGetMvitMatrixf(); } |