summaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/com/jogamp
diff options
context:
space:
mode:
Diffstat (limited to 'src/jogl/classes/com/jogamp')
-rw-r--r--src/jogl/classes/com/jogamp/graph/curve/opengl/Renderer.java35
-rw-r--r--src/jogl/classes/com/jogamp/graph/font/FontFactory.java16
-rw-r--r--src/jogl/classes/com/jogamp/opengl/FBObject.java15
-rw-r--r--src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java42
-rw-r--r--src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java51
-rw-r--r--src/jogl/classes/com/jogamp/opengl/math/Quaternion.java449
-rw-r--r--src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java52
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/GLArrayDataWrapper.java2
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/GLPixelBuffer.java11
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java24
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderCode.java142
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderProgram.java4
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderState.java2
13 files changed, 554 insertions, 291 deletions
diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/Renderer.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/Renderer.java
index fcccf592e..998129551 100644
--- a/src/jogl/classes/com/jogamp/graph/curve/opengl/Renderer.java
+++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/Renderer.java
@@ -33,6 +33,7 @@ import javax.media.opengl.GL2ES2;
import javax.media.opengl.GLException;
import javax.media.opengl.fixedfunc.GLMatrixFunc;
+import com.jogamp.opengl.util.glsl.ShaderCode;
import com.jogamp.opengl.util.glsl.ShaderState;
import com.jogamp.opengl.util.PMVMatrix;
@@ -263,21 +264,31 @@ public abstract class Renderer {
return true;
}
- protected String getVertexShaderName(GL2ES2 gl) {
- return "curverenderer01" + getShaderGLVersionSuffix(gl);
+ protected String getVertexShaderName() {
+ return "curverenderer" + getImplVersion();
}
- protected String getFragmentShaderName(GL2ES2 gl) {
- final String type = "01" ; // Region.isNonUniformWeight(renderModes) ? "02" : "01" ;
- final String pass = Region.isVBAA(renderModes) ? "b" : "a" ;
- return "curverenderer" + type + pass + getShaderGLVersionSuffix(gl);
+ protected String getFragmentShaderName() {
+ final String version = getImplVersion();
+ final String pass = Region.isVBAA(renderModes) ? "-2pass" : "-1pass" ;
+ final String weight = Region.isNonUniformWeight(renderModes) ? "-weight" : "" ;
+ return "curverenderer" + version + pass + weight;
}
-
- protected String getShaderGLVersionSuffix(GL2ES2 gl) {
- if(gl.isGLES2()) {
- return "-es2";
+
+ // FIXME: Really required to have sampler2D def. precision ? If not, we can drop getFragmentShaderPrecision(..) and use default ShaderCode ..
+ public static final String es2_precision_fp = "\nprecision mediump float;\nprecision mediump int;\nprecision mediump sampler2D;\n";
+
+ protected String getFragmentShaderPrecision(GL2ES2 gl) {
+ if( gl.isGLES2() ) {
+ return es2_precision_fp;
}
- return "-gl2";
- }
+ if( ShaderCode.requiresGL3DefaultPrecision(gl) ) {
+ return ShaderCode.gl3_default_precision_fp;
+ }
+ return null;
+ }
+ protected String getImplVersion() {
+ return "01";
+ }
} \ No newline at end of file
diff --git a/src/jogl/classes/com/jogamp/graph/font/FontFactory.java b/src/jogl/classes/com/jogamp/graph/font/FontFactory.java
index 33d487355..bbdfc0e9f 100644
--- a/src/jogl/classes/com/jogamp/graph/font/FontFactory.java
+++ b/src/jogl/classes/com/jogamp/graph/font/FontFactory.java
@@ -33,13 +33,23 @@ import java.net.URLConnection;
import com.jogamp.common.util.PropertyAccess;
import com.jogamp.common.util.ReflectionUtil;
-import com.jogamp.common.util.SecurityUtil;
import jogamp.graph.font.FontConstructor;
import jogamp.graph.font.JavaFontLoader;
import jogamp.graph.font.UbuntuFontLoader;
+/**
+ * The optional property <i>jogamp.graph.font.ctor</i>
+ * allows user to specify the {@link FontConstructor} implementation.
+ * <p>
+ * Default {@link FontConstructor} is {@link jogamp.graph.font.typecast.TypecastFontConstructor},
+ * i.e. using our internal <i>typecast</i> branch.
+ * </p>
+ */
public class FontFactory {
+ private static final String FontConstructorPropKey = "jogamp.graph.font.ctor";
+ private static final String DefaultFontConstructor = "jogamp.graph.font.typecast.TypecastFontConstructor";
+
/** Ubuntu is the default font family */
public static final int UBUNTU = 0;
@@ -54,9 +64,9 @@ public class FontFactory {
* "jogamp.graph.font.typecast.TypecastFontFactory" (default)
* "jogamp.graph.font.ttf.TTFFontImpl"
*/
- String fontImplName = PropertyAccess.getProperty("FontImpl", true, SecurityUtil.getCommonAccessControlContext(FontFactory.class));
+ String fontImplName = PropertyAccess.getProperty(FontConstructorPropKey, true);
if(null == fontImplName) {
- fontImplName = "jogamp.graph.font.typecast.TypecastFontConstructor";
+ fontImplName = DefaultFontConstructor;
}
fontConstr = (FontConstructor) ReflectionUtil.createInstance(fontImplName, FontFactory.class.getClassLoader());
}
diff --git a/src/jogl/classes/com/jogamp/opengl/FBObject.java b/src/jogl/classes/com/jogamp/opengl/FBObject.java
index 6f2ac3e35..7060bb7d1 100644
--- a/src/jogl/classes/com/jogamp/opengl/FBObject.java
+++ b/src/jogl/classes/com/jogamp/opengl/FBObject.java
@@ -60,7 +60,6 @@ import com.jogamp.opengl.FBObject.Attachment.Type;
*/
public class FBObject {
protected static final boolean DEBUG = Debug.debug("FBObject");
- private static final boolean forceMinimumFBOSupport = Debug.isPropertyDefined("jogl.fbo.force.min", true);
private static final boolean FBOResizeQuirk = false;
private static enum DetachAction { NONE, DISPOSE, RECREATE };
@@ -813,6 +812,7 @@ public class FBObject {
maxColorAttachments = 1;
if( fullFBOSupport || NV_fbo_color_attachments ) {
try {
+ val[0] = 0;
gl.glGetIntegerv(GL2ES2.GL_MAX_COLOR_ATTACHMENTS, val, 0);
realMaxColorAttachments = 1 <= val[0] ? val[0] : 1; // cap minimum to 1
} catch (GLException gle) { gle.printStackTrace(); }
@@ -823,15 +823,10 @@ public class FBObject {
colorAttachmentCount = 0;
maxSamples = gl.getMaxRenderbufferSamples();
- if(!forceMinimumFBOSupport) {
- gl.glGetIntegerv(GL.GL_MAX_TEXTURE_SIZE, val, 0);
- maxTextureSize = val[0];
- gl.glGetIntegerv(GL.GL_MAX_RENDERBUFFER_SIZE, val, 0);
- maxRenderbufferSize = val[0];
- } else {
- maxTextureSize = 2048;
- maxRenderbufferSize = 2048;
- }
+ gl.glGetIntegerv(GL.GL_MAX_TEXTURE_SIZE, val, 0);
+ maxTextureSize = val[0];
+ gl.glGetIntegerv(GL.GL_MAX_RENDERBUFFER_SIZE, val, 0);
+ maxRenderbufferSize = val[0];
checkPreGLError(gl);
diff --git a/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java b/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java
index 78bd62e42..36893f5ec 100644
--- a/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java
+++ b/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java
@@ -27,6 +27,8 @@
*/
package com.jogamp.opengl;
+import java.util.List;
+
/**
* GLRendererQuirks contains information of known bugs of various GL renderer.
* This information allows us to workaround them.
@@ -151,14 +153,36 @@ public class GLRendererQuirks {
*/
public static final int NeedCurrCtx4ARBCreateContext = 10;
+ /**
+ * No full FBO support, i.e. not compliant w/
+ * <ul>
+ * <li>GL_ARB_framebuffer_object</li>
+ * <li>EXT_framebuffer_object</li>
+ * <li>EXT_framebuffer_multisample</li>
+ * <li>EXT_framebuffer_blit</li>
+ * <li>EXT_packed_depth_stencil</li>
+ * </ul>.
+ * Drivers known exposing such bug:
+ * <ul>
+ * <li>Mesa <i>7.12-devel</i> on Windows with VMware <i>SVGA3D</i> renderer:
+ * <ul>
+ * <li>GL_VERSION: <i>2.1 Mesa 7.12-devel (git-d6c318e)</i> </li>
+ * <li>GL_RENDERER: <i>Gallium 0.4 on SVGA3D; build: RELEASE;</i> </li>
+ * </ul></li>
+ * </ul>
+ * Quirk can also be enabled via property: <code>jogl.fbo.force.min</code>.
+ */
+ public static final int NoFullFBOSupport = 11;
+
/** Number of quirks known. */
- public static final int COUNT = 11;
+ public static final int COUNT = 12;
private static final String[] _names = new String[] { "NoDoubleBufferedPBuffer", "NoDoubleBufferedBitmap", "NoSetSwapInterval",
"NoOffscreenBitmap", "NoSetSwapIntervalPostRetarget", "GLSLBuggyDiscard",
"GLNonCompliant", "GLFlushBeforeRelease", "DontCloseX11Display",
- "NeedCurrCtx4ARBPixFmtQueries", "NeedCurrCtx4ARBCreateContext"
+ "NeedCurrCtx4ARBPixFmtQueries", "NeedCurrCtx4ARBCreateContext",
+ "NoFullFBOSupport"
};
private final int _bitmask;
@@ -183,6 +207,20 @@ public class GLRendererQuirks {
}
/**
+ * @param quirks a list of valid quirks
+ * @throws IllegalArgumentException if one of the quirks is out of range
+ */
+ public GLRendererQuirks(List<Integer> quirks) throws IllegalArgumentException {
+ int bitmask = 0;
+ for(int i=0; i<quirks.size(); i++) {
+ final int quirk = quirks.get(i);
+ validateQuirk(quirk);
+ bitmask |= 1 << quirk;
+ }
+ _bitmask = bitmask;
+ }
+
+ /**
* @param quirk the quirk to be tested
* @return true if quirk exist, otherwise false
* @throws IllegalArgumentException if quirk is out of range
diff --git a/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java b/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java
index 9a51c32b3..f3f44f15a 100644
--- a/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java
+++ b/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java
@@ -113,6 +113,22 @@ public class FloatUtil {
}
/**
+ * @param a 4x4 matrix in column-major order (also result)
+ * @param b 4x4 matrix in column-major order
+ */
+ public static final void multMatrixf(final float[] a, int a_off, final float[] b, int b_off) {
+ for (int i = 0; i < 4; i++) {
+ // one row in column-major order
+ final int a_off_i = a_off+i;
+ final float ai0=a[a_off_i+0*4], ai1=a[a_off_i+1*4], ai2=a[a_off_i+2*4], ai3=a[a_off_i+3*4]; // row-i of a
+ a[a_off_i+0*4] = ai0 * b[b_off+0+0*4] + ai1 * b[b_off+1+0*4] + ai2 * b[b_off+2+0*4] + ai3 * b[b_off+3+0*4] ;
+ a[a_off_i+1*4] = ai0 * b[b_off+0+1*4] + ai1 * b[b_off+1+1*4] + ai2 * b[b_off+2+1*4] + ai3 * b[b_off+3+1*4] ;
+ a[a_off_i+2*4] = ai0 * b[b_off+0+2*4] + ai1 * b[b_off+1+2*4] + ai2 * b[b_off+2+2*4] + ai3 * b[b_off+3+2*4] ;
+ a[a_off_i+3*4] = ai0 * b[b_off+0+3*4] + ai1 * b[b_off+1+3*4] + ai2 * b[b_off+2+3*4] + ai3 * b[b_off+3+3*4] ;
+ }
+ }
+
+ /**
* @param a 4x4 matrix in column-major order
* @param b 4x4 matrix in column-major order
* @param d result a*b in column-major order
@@ -146,6 +162,23 @@ public class FloatUtil {
d.put(dP+i+3*4 , ai0 * b[b_off+0+3*4] + ai1 * b[b_off+1+3*4] + ai2 * b[b_off+2+3*4] + ai3 * b[b_off+3+3*4] );
}
}
+
+ /**
+ * @param a 4x4 matrix in column-major order (also result)
+ * @param b 4x4 matrix in column-major order
+ */
+ public static final void multMatrixf(final FloatBuffer a, final float[] b, int b_off) {
+ final int aP = a.position();
+ for (int i = 0; i < 4; i++) {
+ // one row in column-major order
+ final int aP_i = aP+i;
+ final float ai0=a.get(aP_i+0*4), ai1=a.get(aP_i+1*4), ai2=a.get(aP_i+2*4), ai3=a.get(aP_i+3*4); // row-i of a
+ a.put(aP_i+0*4 , ai0 * b[b_off+0+0*4] + ai1 * b[b_off+1+0*4] + ai2 * b[b_off+2+0*4] + ai3 * b[b_off+3+0*4] );
+ a.put(aP_i+1*4 , ai0 * b[b_off+0+1*4] + ai1 * b[b_off+1+1*4] + ai2 * b[b_off+2+1*4] + ai3 * b[b_off+3+1*4] );
+ a.put(aP_i+2*4 , ai0 * b[b_off+0+2*4] + ai1 * b[b_off+1+2*4] + ai2 * b[b_off+2+2*4] + ai3 * b[b_off+3+2*4] );
+ a.put(aP_i+3*4 , ai0 * b[b_off+0+3*4] + ai1 * b[b_off+1+3*4] + ai2 * b[b_off+2+3*4] + ai3 * b[b_off+3+3*4] );
+ }
+ }
/**
* @param a 4x4 matrix in column-major order
@@ -167,6 +200,24 @@ public class FloatUtil {
}
/**
+ * @param a 4x4 matrix in column-major order (also result)
+ * @param b 4x4 matrix in column-major order
+ */
+ public static final void multMatrixf(final FloatBuffer a, final FloatBuffer b) {
+ final int aP = a.position();
+ final int bP = b.position();
+ for (int i = 0; i < 4; i++) {
+ // one row in column-major order
+ final int aP_i = aP+i;
+ final float ai0=a.get(aP_i+0*4), ai1=a.get(aP_i+1*4), ai2=a.get(aP_i+2*4), ai3=a.get(aP_i+3*4); // row-i of a
+ a.put(aP_i+0*4 , ai0 * b.get(bP+0+0*4) + ai1 * b.get(bP+1+0*4) + ai2 * b.get(bP+2+0*4) + ai3 * b.get(bP+3+0*4) );
+ a.put(aP_i+1*4 , ai0 * b.get(bP+0+1*4) + ai1 * b.get(bP+1+1*4) + ai2 * b.get(bP+2+1*4) + ai3 * b.get(bP+3+1*4) );
+ a.put(aP_i+2*4 , ai0 * b.get(bP+0+2*4) + ai1 * b.get(bP+1+2*4) + ai2 * b.get(bP+2+2*4) + ai3 * b.get(bP+3+2*4) );
+ a.put(aP_i+3*4 , ai0 * b.get(bP+0+3*4) + ai1 * b.get(bP+1+3*4) + ai2 * b.get(bP+2+3*4) + ai3 * b.get(bP+3+3*4) );
+ }
+ }
+
+ /**
* @param a 4x4 matrix in column-major order
* @param b 4x4 matrix in column-major order
* @param d result a*b in column-major order
diff --git a/src/jogl/classes/com/jogamp/opengl/math/Quaternion.java b/src/jogl/classes/com/jogamp/opengl/math/Quaternion.java
index 0cc5f5ae7..d5ffe2da4 100644
--- a/src/jogl/classes/com/jogamp/opengl/math/Quaternion.java
+++ b/src/jogl/classes/com/jogamp/opengl/math/Quaternion.java
@@ -27,191 +27,204 @@
*/
package com.jogamp.opengl.math;
-
-
public class Quaternion {
- protected float x,y,z,w;
-
- public Quaternion(){
+ protected float x, y, z, w;
+ public Quaternion() {
+ setIdentity();
}
+ public Quaternion(Quaternion q) {
+ x = q.x;
+ y = q.y;
+ z = q.z;
+ w = q.w;
+ }
+
public Quaternion(float x, float y, float z, float w) {
this.x = x;
this.y = y;
this.z = z;
this.w = w;
}
-
- /** Constructor to create a rotation based quaternion from two vectors
+
+ /**
+ * Constructor to create a rotation based quaternion from two vectors
+ *
* @param vector1
* @param vector2
*/
- public Quaternion(float[] vector1, float[] vector2)
- {
- float theta = (float)FloatUtil.acos(dot(vector1, vector2));
- float[] cross = cross(vector1,vector2);
- cross = normalizeVec(cross);
-
- this.x = (float)FloatUtil.sin(theta/2)*cross[0];
- this.y = (float)FloatUtil.sin(theta/2)*cross[1];
- this.z = (float)FloatUtil.sin(theta/2)*cross[2];
- this.w = (float)FloatUtil.cos(theta/2);
- this.normalize();
+ public Quaternion(float[] vector1, float[] vector2) {
+ final float theta = FloatUtil.acos(VectorUtil.dot(vector1, vector2));
+ final float[] cross = VectorUtil.cross(vector1, vector2);
+ fromAxis(cross, theta);
}
- /** Transform the rotational quaternion to axis based rotation angles
- * @return new float[4] with ,theta,Rx,Ry,Rz
+ /***
+ * Constructor to create a rotation based quaternion from axis vector and angle
+ * @param vector axis vector
+ * @param angle rotation angle (rads)
+ * @see #fromAxis(float[], float)
*/
- public float[] toAxis()
- {
- float[] vec = new float[4];
- float scale = (float)FloatUtil.sqrt(x * x + y * y + z * z);
- vec[0] =(float) FloatUtil.acos(w) * 2.0f;
- vec[1] = x / scale;
- vec[2] = y / scale;
- vec[3] = z / scale;
- return vec;
+ public Quaternion(float[] vector, float angle) {
+ fromAxis(vector, angle);
}
- /** Normalize a vector
- * @param vector input vector
- * @return normalized vector
+ /***
+ * Initialize this quaternion with given axis vector and rotation angle
+ *
+ * @param vector axis vector
+ * @param angle rotation angle (rads)
*/
- private float[] normalizeVec(float[] vector)
- {
- float[] newVector = new float[3];
-
- float d = FloatUtil.sqrt(vector[0]*vector[0] + vector[1]*vector[1] + vector[2]*vector[2]);
- if(d> 0.0f)
- {
- newVector[0] = vector[0]/d;
- newVector[1] = vector[1]/d;
- newVector[2] = vector[2]/d;
- }
- return newVector;
+ public void fromAxis(float[] vector, float angle) {
+ final float halfangle = angle * 0.5f;
+ final float sin = FloatUtil.sin(halfangle);
+ final float[] nv = VectorUtil.normalize(vector);
+ x = (nv[0] * sin);
+ y = (nv[1] * sin);
+ z = (nv[2] * sin);
+ w = FloatUtil.cos(halfangle);
}
- /** compute the dot product of two points
- * @param vec1 vector 1
- * @param vec2 vector 2
- * @return the dot product as float
+
+ /**
+ * Transform the rotational quaternion to axis based rotation angles
+ *
+ * @return new float[4] with ,theta,Rx,Ry,Rz
*/
- private float dot(float[] vec1, float[] vec2)
- {
- return (vec1[0]*vec2[0] + vec1[1]*vec2[1] + vec1[2]*vec2[2]);
+ public float[] toAxis() {
+ final float[] vec = new float[4];
+ final float scale = FloatUtil.sqrt(x * x + y * y + z * z);
+ vec[0] = FloatUtil.acos(w) * 2.0f;
+ vec[1] = x / scale;
+ vec[2] = y / scale;
+ vec[3] = z / scale;
+ return vec;
}
- /** cross product vec1 x vec2
- * @param vec1 vector 1
- * @param vec2 vecttor 2
- * @return the resulting vector
- */
- private float[] cross(float[] vec1, float[] vec2)
- {
- float[] out = new float[3];
-
- out[0] = vec2[2]*vec1[1] - vec2[1]*vec1[2];
- out[1] = vec2[0]*vec1[2] - vec2[2]*vec1[0];
- out[2] = vec2[1]*vec1[0] - vec2[0]*vec1[1];
- return out;
- }
public float getW() {
return w;
}
+
public void setW(float w) {
this.w = w;
}
+
public float getX() {
return x;
}
+
public void setX(float x) {
this.x = x;
}
+
public float getY() {
return y;
}
+
public void setY(float y) {
this.y = y;
}
+
public float getZ() {
return z;
}
+
public void setZ(float z) {
this.z = z;
}
- /** Add a quaternion
+ /**
+ * Add a quaternion
+ *
* @param q quaternion
*/
- public void add(Quaternion q)
- {
- x+=q.x;
- y+=q.y;
- z+=q.z;
+ public void add(Quaternion q) {
+ x += q.x;
+ y += q.y;
+ z += q.z;
}
-
- /** Subtract a quaternion
+
+ /**
+ * Subtract a quaternion
+ *
* @param q quaternion
*/
- public void subtract(Quaternion q)
- {
- x-=q.x;
- y-=q.y;
- z-=q.z;
+ public void subtract(Quaternion q) {
+ x -= q.x;
+ y -= q.y;
+ z -= q.z;
}
-
- /** Divide a quaternion by a constant
+
+ /**
+ * Divide a quaternion by a constant
+ *
* @param n a float to divide by
*/
- public void divide(float n)
- {
- x/=n;
- y/=n;
- z/=n;
+ public void divide(float n) {
+ x /= n;
+ y /= n;
+ z /= n;
}
-
- /** Multiply this quaternion by
- * the param quaternion
+
+ /**
+ * Multiply this quaternion by the param quaternion
+ *
* @param q a quaternion to multiply with
*/
- public void mult(Quaternion q)
- {
- float w1 = w*q.w - x*q.x - y*q.y - z*q.z;
+ public void mult(Quaternion q) {
+ final float w1 = w * q.w - x * q.x - y * q.y - z * q.z;
- float x1 = w*q.x + x*q.w + y*q.z - z*q.y;
- float y1 = w*q.y - x*q.z + y*q.w + z*q.x;
- float z1 = w*q.z + x*q.y - y*q.x + z*q.w;
+ final float x1 = w * q.x + x * q.w + y * q.z - z * q.y;
+ final float y1 = w * q.y - x * q.z + y * q.w + z * q.x;
+ final float z1 = w * q.z + x * q.y - y * q.x + z * q.w;
w = w1;
x = x1;
y = y1;
- z = z1;
+ z = z1;
}
-
- /** Multiply a quaternion by a constant
+
+ /**
+ * Multiply a quaternion by a constant
+ *
* @param n a float constant
*/
- public void mult(float n)
- {
- x*=n;
- y*=n;
- z*=n;
+ public void mult(float n) {
+ x *= n;
+ y *= n;
+ z *= n;
}
- /** Normalize a quaternion required if
- * to be used as a rotational quaternion
+ /***
+ * Rotate given vector by this quaternion
+ *
+ * @param vector input vector
+ * @return rotated vector
*/
- public void normalize()
- {
- float norme = (float)FloatUtil.sqrt(w*w + x*x + y*y + z*z);
- if (norme == 0.0f)
- {
- w = 1.0f;
- x = y = z = 0.0f;
- }
- else
- {
- float recip = 1.0f/norme;
+ public float[] mult(float[] vector) {
+ // TODO : optimize
+ final float[] res = new float[3];
+ final Quaternion a = new Quaternion(vector[0], vector[1], vector[2], 0.0f);
+ final Quaternion b = new Quaternion(this);
+ final Quaternion c = new Quaternion(this);
+ b.inverse();
+ a.mult(b);
+ c.mult(a);
+ res[0] = c.x;
+ res[1] = c.y;
+ res[2] = c.z;
+ return res;
+ }
+
+ /**
+ * Normalize a quaternion required if to be used as a rotational quaternion
+ */
+ public void normalize() {
+ final float norme = (float) FloatUtil.sqrt(w * w + x * x + y * y + z * z);
+ if (norme == 0.0f) {
+ setIdentity();
+ } else {
+ final float recip = 1.0f / norme;
w *= recip;
x *= recip;
@@ -219,42 +232,42 @@ public class Quaternion {
z *= recip;
}
}
-
- /** Invert the quaternion If rotational,
- * will produce a the inverse rotation
+
+ /**
+ * Invert the quaternion If rotational, will produce a the inverse rotation
*/
- public void inverse()
- {
- float norm = w*w + x*x + y*y + z*z;
+ public void inverse() {
+ final float norm = w * w + x * x + y * y + z * z;
- float recip = 1.0f/norm;
+ final float recip = 1.0f / norm;
w *= recip;
- x = -1*x*recip;
- y = -1*y*recip;
- z = -1*z*recip;
+ x = -1 * x * recip;
+ y = -1 * y * recip;
+ z = -1 * z * recip;
}
-
- /** Transform this quaternion to a
- * 4x4 column matrix representing the rotation
- * @return new float[16] column matrix 4x4
+
+ /**
+ * Transform this quaternion to a 4x4 column matrix representing the
+ * rotation
+ *
+ * @return new float[16] column matrix 4x4
*/
- public float[] toMatrix()
- {
- float[] matrix = new float[16];
- matrix[0] = 1.0f - 2*y*y - 2*z*z;
- matrix[1] = 2*x*y + 2*w*z;
- matrix[2] = 2*x*z - 2*w*y;
+ public float[] toMatrix() {
+ final float[] matrix = new float[16];
+ matrix[0] = 1.0f - 2 * y * y - 2 * z * z;
+ matrix[1] = 2 * x * y + 2 * w * z;
+ matrix[2] = 2 * x * z - 2 * w * y;
matrix[3] = 0;
- matrix[4] = 2*x*y - 2*w*z;
- matrix[5] = 1.0f - 2*x*x - 2*z*z;
- matrix[6] = 2*y*z + 2*w*x;
+ matrix[4] = 2 * x * y - 2 * w * z;
+ matrix[5] = 1.0f - 2 * x * x - 2 * z * z;
+ matrix[6] = 2 * y * z + 2 * w * x;
matrix[7] = 0;
- matrix[8] = 2*x*z + 2*w*y;
- matrix[9] = 2*y*z - 2*w*x;
- matrix[10] = 1.0f - 2*x*x - 2*y*y;
+ matrix[8] = 2 * x * z + 2 * w * y;
+ matrix[9] = 2 * y * z - 2 * w * x;
+ matrix[10] = 1.0f - 2 * x * x - 2 * y * y;
matrix[11] = 0;
matrix[12] = 0;
@@ -263,15 +276,18 @@ public class Quaternion {
matrix[15] = 1;
return matrix;
}
-
- /** Set this quaternion from a Sphereical interpolation
- * of two param quaternion, used mostly for rotational animation.
- * <p>
- * Note: Method does not normalize this quaternion!
- * </p>
- * <p>
- * See http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/
- * </p>
+
+ /**
+ * Set this quaternion from a Sphereical interpolation of two param
+ * quaternion, used mostly for rotational animation.
+ * <p>
+ * Note: Method does not normalize this quaternion!
+ * </p>
+ * <p>
+ * See http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/
+ * quaternions/slerp/
+ * </p>
+ *
* @param a initial quaternion
* @param b target quaternion
* @param t float between 0 and 1 representing interp.
@@ -279,7 +295,7 @@ public class Quaternion {
public void slerp(Quaternion a, Quaternion b, float t) {
final float cosom = a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
final float t1 = 1.0f - t;
-
+
// if the two quaternions are close, just use linear interpolation
if (cosom >= 0.95f) {
x = a.x * t1 + b.x * t;
@@ -288,8 +304,9 @@ public class Quaternion {
w = a.w * t1 + b.w * t;
return;
}
-
- // the quaternions are nearly opposite, we can pick any axis normal to a,b
+
+ // the quaternions are nearly opposite, we can pick any axis normal to
+ // a,b
// to do the rotation
if (cosom <= -0.99f) {
x = 0.5f * (a.x + b.x);
@@ -298,94 +315,112 @@ public class Quaternion {
w = 0.5f * (a.w + b.w);
return;
}
-
+
// cosom is now withion range of acos, do a SLERP
final float sinom = FloatUtil.sqrt(1.0f - cosom * cosom);
final float omega = FloatUtil.acos(cosom);
-
+
final float scla = FloatUtil.sin(t1 * omega) / sinom;
- final float sclb = FloatUtil.sin( t * omega) / sinom;
-
+ final float sclb = FloatUtil.sin(t * omega) / sinom;
+
x = a.x * scla + b.x * sclb;
y = a.y * scla + b.y * sclb;
z = a.z * scla + b.z * sclb;
w = a.w * scla + b.w * sclb;
}
-
- /** Check if this quaternion is empty, ie (0,0,0,1)
+
+ /**
+ * Check if this quaternion is empty, ie (0,0,0,1)
+ *
* @return true if empty, false otherwise
+ * @deprecated use {@link #isIdentity()} instead
*/
- public boolean isEmpty()
- {
- if (w==1 && x==0 && y==0 && z==0)
+ @Deprecated
+ public boolean isEmpty() {
+ if (w == 1 && x == 0 && y == 0 && z == 0)
return true;
return false;
}
-
- /** Check if this quaternion represents an identity
- * matrix, for rotation.
+
+ /**
+ * Check if this quaternion represents an identity matrix, for rotation.
+ *
* @return true if it is an identity rep., false otherwise
*/
- public boolean isIdentity()
- {
- if (w==0 && x==0 && y==0 && z==0)
- return true;
- return false;
+ public boolean isIdentity() {
+ return w == 1 && x == 0 && y == 0 && z == 0;
}
- /** compute the quaternion from a 3x3 column matrix
- * @param m 3x3 column matrix
+ /***
+ * Set this quaternion to identity (x=0,y=0,z=0,w=1)
+ */
+ public void setIdentity() {
+ x = y = z = 0;
+ w = 1;
+ }
+
+ /**
+ * compute the quaternion from a 3x3 column matrix
+ *
+ * @param m 3x3 column matrix
*/
public void setFromMatrix(float[] m) {
- float T= m[0] + m[4] + m[8] + 1;
- if (T>0){
- float S = 0.5f / (float)FloatUtil.sqrt(T);
+ final float T = m[0] + m[4] + m[8] + 1;
+ if (T > 0) {
+ final float S = 0.5f / (float) FloatUtil.sqrt(T);
w = 0.25f / S;
- x = ( m[5] - m[7]) * S;
- y = ( m[6] - m[2]) * S;
- z = ( m[1] - m[3] ) * S;
- }
- else{
- if ((m[0] > m[4])&(m[0] > m[8])) {
- float S = FloatUtil.sqrt( 1.0f + m[0] - m[4] - m[8] ) * 2f; // S=4*qx
+ x = (m[5] - m[7]) * S;
+ y = (m[6] - m[2]) * S;
+ z = (m[1] - m[3]) * S;
+ } else {
+ if ((m[0] > m[4]) & (m[0] > m[8])) {
+ final float S = FloatUtil.sqrt(1.0f + m[0] - m[4] - m[8]) * 2f; // S=4*qx
w = (m[7] - m[5]) / S;
x = 0.25f * S;
- y = (m[3] + m[1]) / S;
- z = (m[6] + m[2]) / S;
- }
- else if (m[4] > m[8]) {
- float S = FloatUtil.sqrt( 1.0f + m[4] - m[0] - m[8] ) * 2f; // S=4*qy
+ y = (m[3] + m[1]) / S;
+ z = (m[6] + m[2]) / S;
+ } else if (m[4] > m[8]) {
+ final float S = FloatUtil.sqrt(1.0f + m[4] - m[0] - m[8]) * 2f; // S=4*qy
w = (m[6] - m[2]) / S;
- x = (m[3] + m[1]) / S;
+ x = (m[3] + m[1]) / S;
y = 0.25f * S;
- z = (m[7] + m[5]) / S;
- }
- else {
- float S = FloatUtil.sqrt( 1.0f + m[8] - m[0] - m[4] ) * 2f; // S=4*qz
+ z = (m[7] + m[5]) / S;
+ } else {
+ final float S = FloatUtil.sqrt(1.0f + m[8] - m[0] - m[4]) * 2f; // S=4*qz
w = (m[3] - m[1]) / S;
- x = (m[6] + m[2]) / S;
- y = (m[7] + m[5]) / S;
+ x = (m[6] + m[2]) / S;
+ y = (m[7] + m[5]) / S;
z = 0.25f * S;
- }
+ }
}
}
-
- /** Check if the the 3x3 matrix (param) is in fact
- * an affine rotational matrix
+
+ /**
+ * Check if the the 3x3 matrix (param) is in fact an affine rotational
+ * matrix
+ *
* @param m 3x3 column matrix
* @return true if representing a rotational matrix, false otherwise
*/
public boolean isRotationMatrix(float[] m) {
- double epsilon = 0.01; // margin to allow for rounding errors
- if (FloatUtil.abs(m[0]*m[3] + m[3]*m[4] + m[6]*m[7]) > epsilon) return false;
- if (FloatUtil.abs(m[0]*m[2] + m[3]*m[5] + m[6]*m[8]) > epsilon) return false;
- if (FloatUtil.abs(m[1]*m[2] + m[4]*m[5] + m[7]*m[8]) > epsilon) return false;
- if (FloatUtil.abs(m[0]*m[0] + m[3]*m[3] + m[6]*m[6] - 1) > epsilon) return false;
- if (FloatUtil.abs(m[1]*m[1] + m[4]*m[4] + m[7]*m[7] - 1) > epsilon) return false;
- if (FloatUtil.abs(m[2]*m[2] + m[5]*m[5] + m[8]*m[8] - 1) > epsilon) return false;
- return (FloatUtil.abs(determinant(m)-1) < epsilon);
+ final double epsilon = 0.01; // margin to allow for rounding errors
+ if (FloatUtil.abs(m[0] * m[3] + m[3] * m[4] + m[6] * m[7]) > epsilon)
+ return false;
+ if (FloatUtil.abs(m[0] * m[2] + m[3] * m[5] + m[6] * m[8]) > epsilon)
+ return false;
+ if (FloatUtil.abs(m[1] * m[2] + m[4] * m[5] + m[7] * m[8]) > epsilon)
+ return false;
+ if (FloatUtil.abs(m[0] * m[0] + m[3] * m[3] + m[6] * m[6] - 1) > epsilon)
+ return false;
+ if (FloatUtil.abs(m[1] * m[1] + m[4] * m[4] + m[7] * m[7] - 1) > epsilon)
+ return false;
+ if (FloatUtil.abs(m[2] * m[2] + m[5] * m[5] + m[8] * m[8] - 1) > epsilon)
+ return false;
+ return (FloatUtil.abs(determinant(m) - 1) < epsilon);
}
+
private float determinant(float[] m) {
- return m[0]*m[4]*m[8] + m[3]*m[7]*m[2] + m[6]*m[1]*m[5] - m[0]*m[7]*m[5] - m[3]*m[1]*m[8] - m[6]*m[4]*m[2];
+ return m[0] * m[4] * m[8] + m[3] * m[7] * m[2] + m[6] * m[1] * m[5]
+ - m[0] * m[7] * m[5] - m[3] * m[1] * m[8] - m[6] * m[4] * m[2];
}
}
diff --git a/src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java b/src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java
index 5a75d016a..0033afeaa 100644
--- a/src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java
+++ b/src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java
@@ -292,21 +292,21 @@ public class VectorUtil {
*/
public static boolean vertexInTriangle(float[] a, float[] b, float[] c, float[] p){
// Compute vectors
- float[] ac = computeVector(a, c); //v0
- float[] ab = computeVector(a, b); //v1
- float[] ap = computeVector(a, p); //v2
+ final float[] ac = computeVector(a, c); //v0
+ final float[] ab = computeVector(a, b); //v1
+ final float[] ap = computeVector(a, p); //v2
// Compute dot products
- float dot00 = dot(ac, ac);
- float dot01 = dot(ac, ab);
- float dot02 = dot(ac, ap);
- float dot11 = dot(ab, ab);
- float dot12 = dot(ab, ap);
+ final float dot00 = dot(ac, ac);
+ final float dot01 = dot(ac, ab);
+ final float dot02 = dot(ac, ap);
+ final float dot11 = dot(ab, ab);
+ final float dot12 = dot(ab, ap);
// Compute barycentric coordinates
- float invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
- float u = (dot11 * dot02 - dot01 * dot12) * invDenom;
- float v = (dot00 * dot12 - dot01 * dot02) * invDenom;
+ final float invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
+ final float u = (dot11 * dot02 - dot01 * dot12) * invDenom;
+ final float v = (dot00 * dot12 - dot01 * dot02) * invDenom;
// Check if point is in triangle
return (u >= 0) && (v >= 0) && (u + v < 1);
@@ -337,12 +337,12 @@ public class VectorUtil {
* @return positive area if ccw else negative area value
*/
public static float area(ArrayList<? extends Vert2fImmutable> vertices) {
- int n = vertices.size();
+ final int n = vertices.size();
float area = 0.0f;
for (int p = n - 1, q = 0; q < n; p = q++)
{
- float[] pCoord = vertices.get(p).getCoord();
- float[] qCoord = vertices.get(q).getCoord();
+ final float[] pCoord = vertices.get(p).getCoord();
+ final float[] qCoord = vertices.get(q).getCoord();
area += pCoord[0] * qCoord[1] - qCoord[0] * pCoord[1];
}
return area;
@@ -366,18 +366,18 @@ public class VectorUtil {
* returns null
*/
public static float[] seg2SegIntersection(Vert2fImmutable a, Vert2fImmutable b, Vert2fImmutable c, Vert2fImmutable d) {
- float determinant = (a.getX()-b.getX())*(c.getY()-d.getY()) - (a.getY()-b.getY())*(c.getX()-d.getX());
+ final float determinant = (a.getX()-b.getX())*(c.getY()-d.getY()) - (a.getY()-b.getY())*(c.getX()-d.getX());
if (determinant == 0)
return null;
- float alpha = (a.getX()*b.getY()-a.getY()*b.getX());
- float beta = (c.getX()*d.getY()-c.getY()*d.getY());
- float xi = ((c.getX()-d.getX())*alpha-(a.getX()-b.getX())*beta)/determinant;
- float yi = ((c.getY()-d.getY())*alpha-(a.getY()-b.getY())*beta)/determinant;
+ final float alpha = (a.getX()*b.getY()-a.getY()*b.getX());
+ final float beta = (c.getX()*d.getY()-c.getY()*d.getY());
+ final float xi = ((c.getX()-d.getX())*alpha-(a.getX()-b.getX())*beta)/determinant;
+ final float yi = ((c.getY()-d.getY())*alpha-(a.getY()-b.getY())*beta)/determinant;
- float gamma = (xi - a.getX())/(b.getX() - a.getX());
- float gamma1 = (xi - c.getX())/(d.getX() - c.getX());
+ final float gamma = (xi - a.getX())/(b.getX() - a.getX());
+ final float gamma1 = (xi - c.getX())/(d.getX() - c.getX());
if(gamma <= 0 || gamma >= 1) return null;
if(gamma1 <= 0 || gamma1 >= 1) return null;
@@ -393,15 +393,15 @@ public class VectorUtil {
* returns null
*/
public static float[] line2lineIntersection(Vert2fImmutable a, Vert2fImmutable b, Vert2fImmutable c, Vert2fImmutable d) {
- float determinant = (a.getX()-b.getX())*(c.getY()-d.getY()) - (a.getY()-b.getY())*(c.getX()-d.getX());
+ final float determinant = (a.getX()-b.getX())*(c.getY()-d.getY()) - (a.getY()-b.getY())*(c.getX()-d.getX());
if (determinant == 0)
return null;
- float alpha = (a.getX()*b.getY()-a.getY()*b.getX());
- float beta = (c.getX()*d.getY()-c.getY()*d.getY());
- float xi = ((c.getX()-d.getX())*alpha-(a.getX()-b.getX())*beta)/determinant;
- float yi = ((c.getY()-d.getY())*alpha-(a.getY()-b.getY())*beta)/determinant;
+ final float alpha = (a.getX()*b.getY()-a.getY()*b.getX());
+ final float beta = (c.getX()*d.getY()-c.getY()*d.getY());
+ final float xi = ((c.getX()-d.getX())*alpha-(a.getX()-b.getX())*beta)/determinant;
+ final float yi = ((c.getY()-d.getY())*alpha-(a.getY()-b.getY())*beta)/determinant;
return new float[]{xi,yi,0};
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataWrapper.java b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataWrapper.java
index f3fa5012f..f8b17501e 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataWrapper.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataWrapper.java
@@ -246,7 +246,9 @@ public class GLArrayDataWrapper implements GLArrayData {
case GL.GL_SHORT:
case GL.GL_UNSIGNED_SHORT:
return ShortBuffer.class;
+ case GL.GL_UNSIGNED_INT:
case GL2ES1.GL_FIXED:
+ case GL2ES2.GL_INT:
return IntBuffer.class;
case GL.GL_FLOAT:
return FloatBuffer.class;
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLPixelBuffer.java b/src/jogl/classes/com/jogamp/opengl/util/GLPixelBuffer.java
index 6b9d3bf2c..b0fc7f332 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLPixelBuffer.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLPixelBuffer.java
@@ -212,7 +212,7 @@ public class GLPixelBuffer {
this.bufferElemSize = Buffers.sizeOfBufferElem(buffer);
}
- /** Is not {@link #dispose()} and has {@link #byteSize} &gt; 0. */
+ /** Is not {@link #dispose() disposed} and has {@link #byteSize} &gt; 0. */
public boolean isValid() {
return !disposed && 0 < byteSize;
}
@@ -240,8 +240,8 @@ public class GLPixelBuffer {
}
/**
- * Returns true, if implementation requires a new buffer based on the new size
- * due to pixel alignment or byte size or if {@link #isValid() invalid}, otherwise false.
+ * Returns true, if {@link #isValid() invalid} or implementation requires a new buffer based on the new size
+ * due to pixel alignment or byte size, otherwise false.
* <p>
* It is assumed that <code>pixelAttributes</code>, <code>depth</code> and <code>pack</code> stays the same!
* </p>
@@ -257,11 +257,12 @@ public class GLPixelBuffer {
* @see GLPixelBufferProvider#allocate(GL, GLPixelAttributes, int, int, int, boolean, int)
*/
public boolean requiresNewBuffer(GL gl, int newWidth, int newHeight, int minByteSize) {
- return !isValid() || this.byteSize < minByteSize;
+ return !isValid() || byteSize < minByteSize;
}
- /** Dispose resources. */
+ /** Dispose resources. See {@link #isValid()}. */
public void dispose() {
+ disposed = true;
buffer.clear();
}
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java b/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java
index bfc03d019..58151856f 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java
@@ -488,7 +488,7 @@ public class PMVMatrix implements GLMatrixFunc {
if(matrixGetName==GL_MATRIX_MODE) {
params.put((float)matrixMode);
} else {
- FloatBuffer matrix = glGetMatrixf(matrixGetName);
+ final FloatBuffer matrix = glGetMatrixf(matrixGetName);
params.put(matrix); // matrix -> params
matrix.reset();
}
@@ -500,7 +500,7 @@ public class PMVMatrix implements GLMatrixFunc {
if(matrixGetName==GL_MATRIX_MODE) {
params[params_offset]=(float)matrixMode;
} else {
- FloatBuffer matrix = glGetMatrixf(matrixGetName);
+ final FloatBuffer matrix = glGetMatrixf(matrixGetName);
matrix.get(params, params_offset, 16); // matrix -> params
matrix.reset();
}
@@ -619,15 +619,15 @@ public class PMVMatrix implements GLMatrixFunc {
@Override
public final void glMultMatrixf(final FloatBuffer m) {
if(matrixMode==GL_MODELVIEW) {
- FloatUtil.multMatrixf(matrixMv, m, matrixMv);
+ FloatUtil.multMatrixf(matrixMv, m);
dirtyBits |= DIRTY_INVERSE_MODELVIEW | DIRTY_INVERSE_TRANSPOSED_MODELVIEW | DIRTY_FRUSTUM ;
modifiedBits |= MODIFIED_MODELVIEW;
} else if(matrixMode==GL_PROJECTION) {
- FloatUtil.multMatrixf(matrixP, m, matrixP);
+ FloatUtil.multMatrixf(matrixP, m);
dirtyBits |= DIRTY_FRUSTUM ;
modifiedBits |= MODIFIED_PROJECTION;
} else if(matrixMode==GL.GL_TEXTURE) {
- FloatUtil.multMatrixf(matrixTex, m, matrixTex);
+ FloatUtil.multMatrixf(matrixTex, m);
modifiedBits |= MODIFIED_TEXTURE;
}
}
@@ -635,15 +635,15 @@ public class PMVMatrix implements GLMatrixFunc {
@Override
public final void glMultMatrixf(float[] m, int m_offset) {
if(matrixMode==GL_MODELVIEW) {
- FloatUtil.multMatrixf(matrixMv, m, m_offset, matrixMv);
+ FloatUtil.multMatrixf(matrixMv, m, m_offset);
dirtyBits |= DIRTY_INVERSE_MODELVIEW | DIRTY_INVERSE_TRANSPOSED_MODELVIEW | DIRTY_FRUSTUM ;
modifiedBits |= MODIFIED_MODELVIEW;
} else if(matrixMode==GL_PROJECTION) {
- FloatUtil.multMatrixf(matrixP, m, m_offset, matrixP);
+ FloatUtil.multMatrixf(matrixP, m, m_offset);
dirtyBits |= DIRTY_FRUSTUM ;
modifiedBits |= MODIFIED_PROJECTION;
} else if(matrixMode==GL.GL_TEXTURE) {
- FloatUtil.multMatrixf(matrixTex, m, m_offset, matrixTex);
+ FloatUtil.multMatrixf(matrixTex, m, m_offset);
modifiedBits |= MODIFIED_TEXTURE;
}
}
@@ -813,8 +813,8 @@ public class PMVMatrix implements GLMatrixFunc {
float[] win_pos, int win_pos_offset ) {
if(usesBackingArray) {
return projectFloat.gluProject(objx, objy, objz,
- matrixMv.array(), 0,
- matrixP.array(), 0,
+ matrixMv.array(), matrixMv.position(),
+ matrixP.array(), matrixP.position(),
viewport, viewport_offset,
win_pos, win_pos_offset);
} else {
@@ -843,8 +843,8 @@ public class PMVMatrix implements GLMatrixFunc {
float[] obj_pos, int obj_pos_offset) {
if(usesBackingArray) {
return projectFloat.gluUnProject(winx, winy, winz,
- matrixMv.array(), 0,
- matrixP.array(), 0,
+ matrixMv.array(), matrixMv.position(),
+ matrixP.array(), matrixP.position(),
viewport, viewport_offset,
obj_pos, obj_pos_offset);
} else {
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderCode.java b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderCode.java
index 1e552c17f..edc3d2677 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderCode.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderCode.java
@@ -54,6 +54,7 @@ import jogamp.opengl.Debug;
import com.jogamp.common.nio.Buffers;
import com.jogamp.common.util.IOUtil;
+import com.jogamp.common.util.VersionNumber;
/**
* Convenient shader code class to use and instantiate vertex or fragment programs.
@@ -683,7 +684,7 @@ public class ShaderCode {
*
* @param shaderIdx the shader index to be used.
* @param position in shader source segments of shader <code>shaderIdx</code>
- * @param data the text to be inserted. Shall end with an EOL '\n' character.
+ * @param data the text to be inserted. Shall end with an EOL '\n' character
* @return index after the inserted <code>data</code>
*
* @throws IllegalStateException if the shader source's CharSequence is immutable, i.e. not of type <code>StringBuilder</code>
@@ -716,6 +717,7 @@ public class ShaderCode {
return -1;
}
+ @SuppressWarnings("resource")
private static int readShaderSource(Class<?> context, URLConnection conn, StringBuilder result, int lineno) throws IOException {
if(DEBUG_CODE) {
if(0 == lineno) {
@@ -823,11 +825,94 @@ public class ShaderCode {
}
// Shall we use: #ifdef GL_FRAGMENT_PRECISION_HIGH .. #endif for using highp in fragment shader if avail ?
- /** {@value #es2_default_precision_vp} */
+ /** Default precision of {@link GL#isGLES2() ES2} for {@link GL2ES2#GL_VERTEX_SHADER vertex-shader}: {@value #es2_default_precision_vp} */
public static final String es2_default_precision_vp = "\nprecision highp float;\nprecision highp int;\n";
- /** {@value #es2_default_precision_fp} */
+ /** Default precision of {@link GL#isGLES2() ES2} for {@link GL2ES2#GL_FRAGMENT_SHADER fragment-shader}: {@value #es2_default_precision_fp} */
public static final String es2_default_precision_fp = "\nprecision mediump float;\nprecision mediump int;\n/*precision lowp sampler2D;*/\n";
+ /** Default precision of GLSL &ge; 1.30 as required until &lt; 1.50 for {@link GL2ES2#GL_VERTEX_SHADER vertex-shader} or {@link GL3#GL_GEOMETRY_SHADER geometry-shader}: {@value #gl3_default_precision_vp_gp}. See GLSL Spec 1.30-1.50 Section 4.5.3. */
+ public static final String gl3_default_precision_vp_gp = "\nprecision highp float;\nprecision highp int;\n";
+ /** Default precision of GLSL &ge; 1.30 as required until &lt; 1.50 for {@link GL2ES2#GL_FRAGMENT_SHADER fragment-shader}: {@value #gl3_default_precision_fp}. See GLSL Spec 1.30-1.50 Section 4.5.3. */
+ public static final String gl3_default_precision_fp = "\nprecision highp float;\nprecision mediump int;\n/*precision mediump sampler2D;*/\n";
+
+ /** Prefer <code>enable</code> over <code>require</code>, since it won't force a failure. */
+ public static final String extOESDerivativesEnable = "#extension GL_OES_standard_derivatives : enable\n";
+
+ /**
+ * Add GLSL version at the head of this shader source code.
+ * <p>
+ * Note: The shader source to be edit must be created using a mutable StringBuilder.
+ * </p>
+ * @param gl a GL context, which must have been made current once
+ * @return the index after the inserted data, maybe 0 if nothing has be inserted.
+ */
+ public final int addGLSLVersion(GL2ES2 gl) {
+ return insertShaderSource(0, 0, gl.getContext().getGLSLVersionString());
+ }
+
+ /**
+ * Adds default precision to source code at given position if required, i.e.
+ * {@link #es2_default_precision_vp}, {@link #es2_default_precision_fp},
+ * {@link #gl3_default_precision_vp_gp}, {@link #gl3_default_precision_fp} or none,
+ * depending on the {@link GLContext#getGLSLVersionNumber() GLSL version} being used.
+ * <p>
+ * Note: The shader source to be edit must be created using a mutable StringBuilder.
+ * </p>
+ * @param gl a GL context, which must have been made current once
+ * @param pos position within this mutable shader source.
+ * @return the index after the inserted data, maybe 0 if nothing has be inserted.
+ */
+ public final int addDefaultShaderPrecision(GL2ES2 gl, int pos) {
+ final String defaultPrecision;
+ if( gl.isGLES2() ) {
+ switch ( shaderType ) {
+ case GL2ES2.GL_VERTEX_SHADER:
+ defaultPrecision = es2_default_precision_vp; break;
+ case GL2ES2.GL_FRAGMENT_SHADER:
+ defaultPrecision = es2_default_precision_vp; break;
+ default:
+ defaultPrecision = null;
+ break;
+ }
+ } else if( requiresGL3DefaultPrecision(gl) ) {
+ // GLSL [ 1.30 .. 1.50 [ needs at least fragement float default precision!
+ switch ( shaderType ) {
+ case GL2ES2.GL_VERTEX_SHADER:
+ case GL3.GL_GEOMETRY_SHADER:
+ defaultPrecision = gl3_default_precision_vp_gp; break;
+ case GL2ES2.GL_FRAGMENT_SHADER:
+ defaultPrecision = gl3_default_precision_fp; break;
+ default:
+ defaultPrecision = null;
+ break;
+ }
+ } else {
+ defaultPrecision = null;
+ }
+ if( null != defaultPrecision ) {
+ pos = insertShaderSource(0, pos, defaultPrecision);
+ }
+ return pos;
+ }
+
+ /** Returns true, if GLSL version requires default precision, i.e. ES2 or GLSL [1.30 .. 1.50[. */
+ public static final boolean requiresDefaultPrecision(GL2ES2 gl) {
+ if( gl.isGLES2() ) {
+ return true;
+ }
+ return requiresGL3DefaultPrecision(gl);
+ }
+
+ /** Returns true, if GL3 GLSL version requires default precision, i.e. GLSL [1.30 .. 1.50[. */
+ public static final boolean requiresGL3DefaultPrecision(GL2ES2 gl) {
+ if( gl.isGL3() ) {
+ final VersionNumber glslVersion = gl.getContext().getGLSLVersionNumber();
+ return glslVersion.compareTo(GLContext.Version130) >= 0 && glslVersion.compareTo(GLContext.Version150) < 0 ;
+ } else {
+ return false;
+ }
+ }
+
/**
* Default customization of this shader source code.
* <p>
@@ -835,18 +920,51 @@ public class ShaderCode {
* </p>
* @param gl a GL context, which must have been made current once
* @param preludeVersion if true {@link GLContext#getGLSLVersionString()} is preluded, otherwise not.
- * @param es2DefaultPrecision optional default precision source code line(s) preluded if not null and if {@link GL#isGLES()}.
+ * @param addDefaultPrecision if <code>true</code> default precision source code line(s) are added, i.e.
+ * {@link #es2_default_precision_vp}, {@link #es2_default_precision_fp},
+ * {@link #gl3_default_precision_vp_gp}, {@link #gl3_default_precision_fp} or none,
+ * depending on the {@link GLContext#getGLSLVersionNumber() GLSL version} being used.
+ * @return the index after the inserted data, maybe 0 if nothing has be inserted.
+ * @see #addGLSLVersion(GL2ES2)
+ * @see #addDefaultShaderPrecision(GL2ES2, int)
+ */
+ public final int defaultShaderCustomization(GL2ES2 gl, boolean preludeVersion, boolean addDefaultPrecision) {
+ int pos;
+ if( preludeVersion ) {
+ pos = addGLSLVersion(gl);
+ } else {
+ pos = 0;
+ }
+ if( addDefaultPrecision ) {
+ pos = addDefaultShaderPrecision(gl, pos);
+ }
+ return pos;
+ }
+
+ /**
+ * Default customization of this shader source code.
+ * <p>
+ * Note: The shader source to be edit must be created using a mutable StringBuilder.
+ * </p>
+ * @param gl a GL context, which must have been made current once
+ * @param preludeVersion if true {@link GLContext#getGLSLVersionString()} is preluded, otherwise not.
+ * @param esDefaultPrecision optional default precision source code line(s) preluded if not null and if {@link GL#isGLES()}.
* You may use {@link #es2_default_precision_fp} for fragment shader and {@link #es2_default_precision_vp} for vertex shader.
* @return the index after the inserted data, maybe 0 if nothing has be inserted.
+ * @see #addGLSLVersion(GL2ES2)
+ * @see #addDefaultShaderPrecision(GL2ES2, int)
*/
- public final int defaultShaderCustomization(GL2ES2 gl, boolean preludeVersion, String es2DefaultPrecision) {
- int pos = 0;
- if(preludeVersion) {
- final String glslVersion_prelude = gl.getContext().getGLSLVersionString();
- pos = insertShaderSource(0, pos, glslVersion_prelude);
- }
- if( gl.isGLES() && null != es2DefaultPrecision ) {
- pos = insertShaderSource(0, pos, es2DefaultPrecision);
+ public final int defaultShaderCustomization(GL2ES2 gl, boolean preludeVersion, String esDefaultPrecision) {
+ int pos;
+ if( preludeVersion ) {
+ pos = addGLSLVersion(gl);
+ } else {
+ pos = 0;
+ }
+ if( gl.isGLES2() && null != esDefaultPrecision ) {
+ pos = insertShaderSource(0, pos, esDefaultPrecision);
+ } else {
+ pos = addDefaultShaderPrecision(gl, pos);
}
return pos;
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderProgram.java b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderProgram.java
index 9cade1e90..1337a7e2b 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderProgram.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderProgram.java
@@ -85,7 +85,9 @@ public class ShaderProgram {
* If <code>destroyShaderCode</code> is true it destroys the shader codes as well.
*/
public synchronized void release(GL2ES2 gl, boolean destroyShaderCode) {
- useProgram(gl, false);
+ if( programLinked ) {
+ useProgram(gl, false);
+ }
for(Iterator<ShaderCode> iter=allShaderCode.iterator(); iter.hasNext(); ) {
ShaderCode shaderCode = iter.next();
if(attachedShaderCode.remove(shaderCode)) {
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderState.java b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderState.java
index a221cd51e..968391976 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderState.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderState.java
@@ -231,7 +231,7 @@ public class ShaderState {
* @see ShaderProgram#release(GL2ES2, boolean)
*/
public synchronized void release(GL2ES2 gl, boolean destroyBoundAttributes, boolean destroyShaderProgram, boolean destroyShaderCode) {
- if(null!=shaderProgram) {
+ if(null!=shaderProgram && shaderProgram.linked() ) {
shaderProgram.useProgram(gl, false);
}
if(destroyBoundAttributes) {