From 15e60161787224e85172685f74dc0ac195969b51 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Wed, 5 Apr 2023 09:42:28 +0200 Subject: Math: Complete Matrix4f w/ Vec[234]f and adopt it throughout Quaternion, Ray, AABBox, Frustum, Stereo*, ... adding hook to PMVMatrix Motivation was to simplify matrix + vector math usage, ease review and avoid usage bugs. Matrix4f implementation uses dedicated float fields instead of an array. Performance didn't increase much, as JVM >= 11(?) has some optimizations to drop the array bounds check. AMD64 + OpenJDK17 - Matrix4f.mul(a, b) got a roughly ~10% enhancement over FloatUtil.multMatrix(a, b, dest) - Matrix4f.mul(b) roughly ~3% slower than FloatUtil.multMatrix(a, b, dest) - FloatUtil.multMatrix(a, a_off, b, b_off, dest) is considerable slower than all - Matrix4f.invert(..) roughly ~3% slower than FloatUtil.invertMatrix(..) RaspberryPi 4b aarch64 + OpenJDK17 - Matrix4f.mul(a, b) got a roughly ~10% enhancement over FloatUtil.multMatrix(a, b, dest) - Matrix4f.mul(b) roughly ~20% slower than FloatUtil.multMatrix(a, b) - FloatUtil.multMatrix(a, a_off, b, b_off, dest) is considerable slower than all - Matrix4f.invert(..) roughly ~4% slower than FloatUtil.invertMatrix(..) Conclusion - Matrix4f.mul(b) needs to be revised (esp for aarch64) - Matrix4f.invert(..) should also not be slower .. --- .../com/jogamp/opengl/demos/av/MovieSBSStereo.java | 68 ++++++++++------- .../com/jogamp/opengl/demos/av/StereoDemo01.java | 9 ++- .../com/jogamp/opengl/demos/es2/GearsES2.java | 85 ++++++++++++---------- .../jogamp/opengl/demos/graph/GPUTextNewtDemo.java | 2 +- .../demos/graph/GPUTextRendererListenerBase01.java | 3 +- 5 files changed, 95 insertions(+), 72 deletions(-) (limited to 'src/demos') diff --git a/src/demos/com/jogamp/opengl/demos/av/MovieSBSStereo.java b/src/demos/com/jogamp/opengl/demos/av/MovieSBSStereo.java index 3a59216d5..3a0955a05 100644 --- a/src/demos/com/jogamp/opengl/demos/av/MovieSBSStereo.java +++ b/src/demos/com/jogamp/opengl/demos/av/MovieSBSStereo.java @@ -61,9 +61,9 @@ import com.jogamp.opengl.GLExtensions; import com.jogamp.opengl.GLProfile; import com.jogamp.opengl.JoglVersion; import com.jogamp.opengl.demos.graph.TextRendererGLELBase; -import com.jogamp.opengl.math.FloatUtil; +import com.jogamp.opengl.math.Matrix4f; import com.jogamp.opengl.math.Quaternion; -import com.jogamp.opengl.math.VectorUtil; +import com.jogamp.opengl.math.Vec3f; import com.jogamp.opengl.util.CustomGLEventListener; import com.jogamp.opengl.util.GLArrayDataServer; import com.jogamp.opengl.util.PMVMatrix; @@ -641,15 +641,15 @@ public class MovieSBSStereo implements StereoGLEventListener { pmvMatrix.glTranslatef(0, 0, zoom0); } - private final float[] mat4Tmp1 = new float[16]; - private final float[] mat4Tmp2 = new float[16]; - private final float[] vec3Tmp1 = new float[3]; - private final float[] vec3Tmp2 = new float[3]; - private final float[] vec3Tmp3 = new float[3]; + private final Matrix4f mat4Tmp1 = new Matrix4f(); + private final Matrix4f mat4Tmp2 = new Matrix4f(); + private final Vec3f vec3Tmp1 = new Vec3f(); + private final Vec3f vec3Tmp2 = new Vec3f(); + private final Vec3f vec3Tmp3 = new Vec3f(); GLArrayDataServer interleavedVBOCurrent = null; - private static final float[] vec3ScalePos = new float[] { 4f, 4f, 4f }; + private static final float scalePos = 4f; @Override public void reshapeForEye(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height, @@ -663,26 +663,38 @@ public class MovieSBSStereo implements StereoGLEventListener { if(null == mPlayer) { return; } if(null == st) { return; } - pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION); - final float[] mat4Projection = FloatUtil.makePerspective(mat4Tmp1, 0, true, eyeParam.fovhv, zNear, zFar); - pmvMatrix.glLoadMatrixf(mat4Projection, 0); - - pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); - final Quaternion rollPitchYaw = new Quaternion(); - final float[] shiftedEyePos = rollPitchYaw.rotateVector(vec3Tmp1, 0, viewerPose.position, 0); - VectorUtil.scaleVec3(shiftedEyePos, shiftedEyePos, vec3ScalePos); // amplify viewerPose position - VectorUtil.addVec3(shiftedEyePos, shiftedEyePos, eyeParam.positionOffset); - - rollPitchYaw.mult(viewerPose.orientation); - final float[] up = rollPitchYaw.rotateVector(vec3Tmp2, 0, VectorUtil.VEC3_UNIT_Y, 0); - final float[] forward = rollPitchYaw.rotateVector(vec3Tmp3, 0, VectorUtil.VEC3_UNIT_Z_NEG, 0); - final float[] center = VectorUtil.addVec3(forward, shiftedEyePos, forward); - - final float[] mLookAt = FloatUtil.makeLookAt(mat4Tmp1, 0, shiftedEyePos, 0, center, 0, up, 0, mat4Tmp2); - final float[] mViewAdjust = FloatUtil.makeTranslation(mat4Tmp2, true, eyeParam.distNoseToPupilX, eyeParam.distMiddleToPupilY, eyeParam.eyeReliefZ); - final float[] mat4Modelview = FloatUtil.multMatrix(mViewAdjust, mLookAt); - pmvMatrix.glLoadMatrixf(mat4Modelview, 0); - pmvMatrix.glTranslatef(0, 0, zoom0); + { + // + // Projection + // + final Matrix4f mat4 = new Matrix4f(); + pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION); + mat4.setToPerspective(eyeParam.fovhv, zNear, zFar); + pmvMatrix.glLoadMatrixf(mat4); + + // + // Modelview + // + pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); + final Quaternion rollPitchYaw = new Quaternion(); + // private final float eyeYaw = FloatUtil.PI; // 180 degrees in radians + // rollPitchYaw.rotateByAngleY(eyeYaw); + final Vec3f shiftedEyePos = rollPitchYaw.rotateVector(viewerPose.position, vec3Tmp1); + shiftedEyePos.scale(scalePos); // amplify viewerPose position + shiftedEyePos.add(eyeParam.positionOffset); + + rollPitchYaw.mult(viewerPose.orientation); + final Vec3f up = rollPitchYaw.rotateVector(Vec3f.UNIT_Y, vec3Tmp2); + final Vec3f forward = rollPitchYaw.rotateVector(Vec3f.UNIT_Z_NEG, vec3Tmp3); // -> center + final Vec3f center = forward.add(shiftedEyePos); + + final Matrix4f mLookAt = mat4Tmp2.setToLookAt(shiftedEyePos, center, up, mat4Tmp1); + mat4.mul( mat4Tmp1.setToTranslation( eyeParam.distNoseToPupilX, + eyeParam.distMiddleToPupilY, + eyeParam.eyeReliefZ ), mLookAt); + mat4.translate(0, 0, zoom0, mat4Tmp1); + pmvMatrix.glLoadMatrixf(mat4); + } st.useProgram(gl, true); st.uniform(gl, pmvMatrixUniform); st.useProgram(gl, false); diff --git a/src/demos/com/jogamp/opengl/demos/av/StereoDemo01.java b/src/demos/com/jogamp/opengl/demos/av/StereoDemo01.java index 88a49a09a..139c9f140 100644 --- a/src/demos/com/jogamp/opengl/demos/av/StereoDemo01.java +++ b/src/demos/com/jogamp/opengl/demos/av/StereoDemo01.java @@ -52,6 +52,7 @@ import com.jogamp.newt.event.KeyEvent; import com.jogamp.newt.opengl.GLWindow; import com.jogamp.newt.opengl.util.stereo.StereoDeviceUtil; import com.jogamp.opengl.math.FovHVHalves; +import com.jogamp.opengl.math.Vec3f; import com.jogamp.opengl.util.Animator; import com.jogamp.opengl.util.AnimatorBase; import com.jogamp.opengl.util.av.GLMediaPlayer; @@ -289,9 +290,9 @@ public class StereoDemo01 { } final boolean usesLenses = 0 != ( StereoDeviceRenderer.DISTORTION_BARREL & stereoDevice.getMinimumDistortionBits() ); - final float[] eyePositionOffset = null != movieSimple && usesLenses ? new float[] { 0f, 0.3f, 0f } // better fixed movie position w/ lenses - : stereoDevice.getDefaultEyePositionOffset(); // default - System.err.println("Eye Position Offset: "+Arrays.toString(eyePositionOffset)); + final Vec3f eyePositionOffset = null != movieSimple && usesLenses ? new Vec3f( 0f, 0.3f, 0f ) // better fixed movie position w/ lenses + : stereoDevice.getDefaultEyePositionOffset(); // default + System.err.println("Eye Position Offset: "+eyePositionOffset); final int textureUnit = 0; final int reqDistortionBits; @@ -382,7 +383,7 @@ public class StereoDemo01 { System.err.println("Window.1.surfaceSize: "+window.getSurfaceWidth()+" x "+window.getSurfaceHeight()); if( useAnimator ) { - animator.setUpdateFPSFrames(60, System.err); + animator.setUpdateFPSFrames(60*10, System.err); } final long t0 = System.currentTimeMillis(); diff --git a/src/demos/com/jogamp/opengl/demos/es2/GearsES2.java b/src/demos/com/jogamp/opengl/demos/es2/GearsES2.java index 02c451e9f..5ad6ede76 100644 --- a/src/demos/com/jogamp/opengl/demos/es2/GearsES2.java +++ b/src/demos/com/jogamp/opengl/demos/es2/GearsES2.java @@ -33,9 +33,9 @@ import com.jogamp.newt.event.GestureHandler.GestureEvent; import com.jogamp.opengl.GLRendererQuirks; import com.jogamp.opengl.JoglVersion; import com.jogamp.opengl.demos.GearsObject; -import com.jogamp.opengl.math.FloatUtil; +import com.jogamp.opengl.math.Matrix4f; import com.jogamp.opengl.math.Quaternion; -import com.jogamp.opengl.math.VectorUtil; +import com.jogamp.opengl.math.Vec3f; import com.jogamp.opengl.util.CustomGLEventListener; import com.jogamp.opengl.util.PMVMatrix; import com.jogamp.opengl.util.TileRendererBase; @@ -397,49 +397,58 @@ public class GearsES2 implements StereoGLEventListener, TileRendererBase.TileRen } // private boolean useAndroidDebug = false; - private final float[] mat4Tmp1 = new float[16]; - private final float[] mat4Tmp2 = new float[16]; - private final float[] vec3Tmp1 = new float[3]; - private final float[] vec3Tmp2 = new float[3]; - private final float[] vec3Tmp3 = new float[3]; + private final Matrix4f mat4Tmp1 = new Matrix4f(); + private final Matrix4f mat4Tmp2 = new Matrix4f(); + private final Vec3f vec3Tmp1 = new Vec3f(); + private final Vec3f vec3Tmp2 = new Vec3f(); + private final Vec3f vec3Tmp3 = new Vec3f(); - private static final float[] vec3ScalePos = new float[] { 20f, 20f, 20f }; + private static final float scalePos = 20f; @Override public void reshapeForEye(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height, final EyeParameter eyeParam, final ViewerPose viewerPose) { final GL2ES2 gl = drawable.getGL().getGL2ES2(); - pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION); - final float[] mat4Projection = FloatUtil.makePerspective(mat4Tmp1, 0, true, eyeParam.fovhv, zNear, zFar); - if( flipVerticalInGLOrientation && gl.getContext().getGLDrawable().isGLOriented() ) { - pmvMatrix.glLoadIdentity(); - pmvMatrix.glScalef(1f, -1f, 1f); - pmvMatrix.glMultMatrixf(mat4Projection, 0); - } else { - pmvMatrix.glLoadMatrixf(mat4Projection, 0); - } - - pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); - final Quaternion rollPitchYaw = new Quaternion(); - // private final float eyeYaw = FloatUtil.PI; // 180 degrees in radians - // rollPitchYaw.rotateByAngleY(eyeYaw); - // final float[] shiftedEyePos = rollPitchYaw.rotateVector(vec3Tmp1, 0, viewerPose.position, 0); - final float[] shiftedEyePos = VectorUtil.copyVec3(vec3Tmp1, 0, viewerPose.position, 0); - VectorUtil.scaleVec3(shiftedEyePos, shiftedEyePos, vec3ScalePos); // amplify viewerPose position - VectorUtil.addVec3(shiftedEyePos, shiftedEyePos, eyeParam.positionOffset); - - rollPitchYaw.mult(viewerPose.orientation); - final float[] up = rollPitchYaw.rotateVector(vec3Tmp2, 0, VectorUtil.VEC3_UNIT_Y, 0); - final float[] forward = rollPitchYaw.rotateVector(vec3Tmp3, 0, VectorUtil.VEC3_UNIT_Z_NEG, 0); - final float[] center = VectorUtil.addVec3(forward, shiftedEyePos, forward); - - final float[] mLookAt = FloatUtil.makeLookAt(mat4Tmp1, 0, shiftedEyePos, 0, center, 0, up, 0, mat4Tmp2); - final float[] mViewAdjust = FloatUtil.makeTranslation(mat4Tmp2, true, eyeParam.distNoseToPupilX, eyeParam.distMiddleToPupilY, eyeParam.eyeReliefZ); - final float[] mat4Modelview = FloatUtil.multMatrix(mViewAdjust, mLookAt); - - pmvMatrix.glLoadMatrixf(mat4Modelview, 0); - pmvMatrix.glTranslatef(0.0f, 0.0f, -zViewDist); + { + // + // Projection + // + final Matrix4f mat4 = new Matrix4f(); + pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION); + if( flipVerticalInGLOrientation && gl.getContext().getGLDrawable().isGLOriented() ) { + mat4Tmp1.setToScale(1f, -1f, 1f); + mat4Tmp2.setToPerspective(eyeParam.fovhv, zNear, zFar); + mat4.mul(mat4Tmp1, mat4Tmp2); + } else { + mat4.setToPerspective(eyeParam.fovhv, zNear, zFar); + } + pmvMatrix.glLoadMatrixf(mat4); + + // + // Modelview + // + pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); + final Quaternion rollPitchYaw = new Quaternion(); + // private final float eyeYaw = FloatUtil.PI; // 180 degrees in radians + // rollPitchYaw.rotateByAngleY(eyeYaw); + // final Vec3f shiftedEyePos = rollPitchYaw.rotateVector(viewerPose.position, vec3Tmp1); + final Vec3f shiftedEyePos = vec3Tmp1.set(viewerPose.position); + shiftedEyePos.scale(scalePos); // amplify viewerPose position + shiftedEyePos.add(eyeParam.positionOffset); + + rollPitchYaw.mult(viewerPose.orientation); + final Vec3f up = rollPitchYaw.rotateVector(Vec3f.UNIT_Y, vec3Tmp2); + final Vec3f forward = rollPitchYaw.rotateVector(Vec3f.UNIT_Z_NEG, vec3Tmp3); // -> center + final Vec3f center = forward.add(shiftedEyePos); + + final Matrix4f mLookAt = mat4Tmp2.setToLookAt(shiftedEyePos, center, up, mat4Tmp1); + mat4.mul( mat4Tmp1.setToTranslation( eyeParam.distNoseToPupilX, + eyeParam.distMiddleToPupilY, + eyeParam.eyeReliefZ ), mLookAt); + mat4.translate(0, 0, -zViewDist, mat4Tmp1); + pmvMatrix.glLoadMatrixf(mat4); + } st.useProgram(gl, true); st.uniform(gl, pmvMatrixUniform); st.useProgram(gl, false); diff --git a/src/demos/com/jogamp/opengl/demos/graph/GPUTextNewtDemo.java b/src/demos/com/jogamp/opengl/demos/graph/GPUTextNewtDemo.java index ad5434b09..5952326c8 100644 --- a/src/demos/com/jogamp/opengl/demos/graph/GPUTextNewtDemo.java +++ b/src/demos/com/jogamp/opengl/demos/graph/GPUTextNewtDemo.java @@ -155,7 +155,7 @@ public class GPUTextNewtDemo { final AABBox fontNameBox = font2.getMetricBounds(GPUTextRendererListenerBase01.textX1); System.err.println("GPU Text Newt Demo: "+font2.fullString()); System.err.println("GPU Text Newt Demo: screen-dpi: "+sDPI[0]+"x"+sDPI[1]+", font "+font_ptpi+" pt, "+font_ppi+" pixel"); - System.err.println("GPU Text Newt Demo: textX2: "+fontNameBox+" em, "+fontNameBox.scale(font_ppi, new float[3])+" px"); + System.err.println("GPU Text Newt Demo: textX2: "+fontNameBox+" em, "+fontNameBox.scale(font_ppi)+" px"); final MonitorDevice monitor = window.getMainMonitor(); System.err.println("GPU Text Newt Demo: "+monitor); // window.setSurfaceSize((int)(fontNameBox.getWidth()*1.1f), (int)(fontNameBox.getHeight()*2f)); diff --git a/src/demos/com/jogamp/opengl/demos/graph/GPUTextRendererListenerBase01.java b/src/demos/com/jogamp/opengl/demos/graph/GPUTextRendererListenerBase01.java index dadbcd373..cab25b83d 100644 --- a/src/demos/com/jogamp/opengl/demos/graph/GPUTextRendererListenerBase01.java +++ b/src/demos/com/jogamp/opengl/demos/graph/GPUTextRendererListenerBase01.java @@ -51,6 +51,7 @@ import com.jogamp.newt.Window; import com.jogamp.newt.event.KeyEvent; import com.jogamp.newt.event.KeyListener; import com.jogamp.newt.opengl.GLWindow; +import com.jogamp.opengl.math.Vec3f; import com.jogamp.opengl.math.geom.AABBox; import com.jogamp.opengl.util.PMVMatrix; @@ -491,7 +492,7 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB System.err.println("Matrix: " + getXTran() + "/" + getYTran() + " x"+getZTran() + " @"+getAngle() +" fontSize "+fontSizeCenter); if(bbox) { System.err.println("bbox em: "+font.getMetricBounds(text2)); - System.err.println("bbox px: "+font.getMetricBounds(text2).scale(nearPlaneS * FontScale.toPixels(fontSizeCenter, dpiV), new float[3])); + System.err.println("bbox px: "+font.getMetricBounds(text2).scale( nearPlaneS * FontScale.toPixels(fontSizeCenter, dpiV) ) ); } } -- cgit v1.2.3