diff options
Diffstat (limited to 'src/jogl')
55 files changed, 1085 insertions, 799 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} > 0. */ + /** Is not {@link #dispose() disposed} and has {@link #byteSize} > 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 ≥ 1.30 as required until < 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 ≥ 1.30 as required until < 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) { diff --git a/src/jogl/classes/javax/media/opengl/GLContext.java b/src/jogl/classes/javax/media/opengl/GLContext.java index bbe8d602b..cc37da0ff 100644 --- a/src/jogl/classes/javax/media/opengl/GLContext.java +++ b/src/jogl/classes/javax/media/opengl/GLContext.java @@ -42,7 +42,7 @@ package javax.media.opengl; import java.nio.IntBuffer; import java.util.HashMap; -import java.util.HashSet; +import java.util.IdentityHashMap; import java.util.Iterator; import java.util.Set; @@ -118,6 +118,19 @@ public abstract class GLContext { /** Indicates that a newly-created context was made current during the last call to {@link #makeCurrent makeCurrent}. */ public static final int CONTEXT_CURRENT_NEW = 2; + /* Version 1.00, i.e. GLSL 1.00 for ES 2.0. */ + public static final VersionNumber Version100 = new VersionNumber(1, 0, 0); + /* Version 1.10, i.e. GLSL 1.10 for GL 2.0. */ + public static final VersionNumber Version110 = new VersionNumber(1, 10, 0); + /* Version 1.20, i.e. GLSL 1.20 for GL 2.1. */ + public static final VersionNumber Version120 = new VersionNumber(1, 20, 0); + /* Version 1.30, i.e. GLSL 1.30 for GL 3.0. */ + public static final VersionNumber Version130 = new VersionNumber(1, 30, 0); + /* Version 1.40, i.e. GLSL 1.40 for GL 3.1. */ + public static final VersionNumber Version140 = new VersionNumber(1, 40, 0); + /* Version 1.50, i.e. GLSL 1.50 for GL 3.2. */ + public static final VersionNumber Version150 = new VersionNumber(1, 50, 0); + /** Version 3.2. As an OpenGL version, it qualifies for geometry shader */ public static final VersionNumber Version32 = new VersionNumber(3, 2, 0); @@ -716,9 +729,19 @@ public abstract class GLContext { /** * Returns the GLSL version string as to be used in a shader program, including a terminating newline '\n', - * i.e.: + * i.e. for desktop * <pre> * #version 110 + * .. + * #version 150 + * #version 330 + * ... + * </pre> + * And for ES: + * <pre> + * #version 100 + * #version 300 es + * .. * </pre> * <p> * If context has not been made current yet, a string of zero length is returned. @@ -730,31 +753,31 @@ public abstract class GLContext { return ""; } final int minor = ctxGLSLVersion.getMinor(); - return "#version " + ctxGLSLVersion.getMajor() + ( minor < 10 ? "0"+minor : minor ) + "\n" ; + final String esSuffix = isGLES() && ctxGLSLVersion.compareTo(Version30) >= 0 ? " es" : ""; + return "#version " + ctxGLSLVersion.getMajor() + ( minor < 10 ? "0"+minor : minor ) + esSuffix + "\n" ; } - protected static final void getStaticGLSLVersionNumber(int glMajorVersion, int glMinorVersion, int ctxOptions, int[] res) { + protected static final VersionNumber getStaticGLSLVersionNumber(int glMajorVersion, int glMinorVersion, int ctxOptions) { if( 0 != ( CTX_PROFILE_ES & ctxOptions ) ) { - res[0] = 1; res[1] = 0; // ES 2.0 -> GLSL 1.00 + if( 3 > glMajorVersion ) { + return Version100; // ES 2.0 -> GLSL 1.00 + } } else if( 1 == glMajorVersion ) { - res[0] = 1; res[1] = 10; // GL 1.x -> GLSL 1.10 + return Version110; // GL 1.x -> GLSL 1.10 } else if( 2 == glMajorVersion ) { - res[0] = 1; switch ( glMinorVersion ) { - case 0: res[1] = 10; break; // GL 2.0 -> GLSL 1.10 - default: res[1] = 20; break; // GL 2.1 -> GLSL 1.20 + case 0: return Version110; // GL 2.0 -> GLSL 1.10 + default: return Version120; // GL 2.1 -> GLSL 1.20 } } else if( 3 == glMajorVersion && 2 >= glMinorVersion ) { - res[0] = 1; switch ( glMinorVersion ) { - case 0: res[1] = 30; break; // GL 3.0 -> GLSL 1.30 - case 1: res[1] = 40; break; // GL 3.1 -> GLSL 1.40 - default: res[1] = 50; break; // GL 3.2 -> GLSL 1.50 + case 0: return Version130; // GL 3.0 -> GLSL 1.30 + case 1: return Version140; // GL 3.1 -> GLSL 1.40 + default: return Version150; // GL 3.2 -> GLSL 1.50 } - } else { // >= 3.3 - res[0] = glMajorVersion; // GL M.N -> GLSL M.N - res[1] = glMinorVersion * 10; } + // The new default: GL >= 3.3, ES >= 3.0 + return new VersionNumber(glMajorVersion, glMinorVersion * 10, 0); // GL M.N -> GLSL M.N } /** @@ -813,15 +836,15 @@ public abstract class GLContext { * </p> */ public final boolean hasFullFBOSupport() { - return !FORCE_MIN_FBO_SUPPORT && hasBasicFBOSupport() && - ( isGL3() || // GL >= 3.0 - isExtensionAvailable(GLExtensions.ARB_framebuffer_object) || // ARB_framebuffer_object - ( isExtensionAvailable(GLExtensions.EXT_framebuffer_object) && // All EXT_framebuffer_object* - isExtensionAvailable(GLExtensions.EXT_framebuffer_multisample) && - isExtensionAvailable(GLExtensions.EXT_framebuffer_blit) && - isExtensionAvailable(GLExtensions.EXT_packed_depth_stencil) - ) - ) ; + return hasBasicFBOSupport() && !hasRendererQuirk(GLRendererQuirks.NoFullFBOSupport) && + ( isGL3() || // GL >= 3.0 + isExtensionAvailable(GLExtensions.ARB_framebuffer_object) || // ARB_framebuffer_object + ( isExtensionAvailable(GLExtensions.EXT_framebuffer_object) && // All EXT_framebuffer_object* + isExtensionAvailable(GLExtensions.EXT_framebuffer_multisample) && + isExtensionAvailable(GLExtensions.EXT_framebuffer_blit) && + isExtensionAvailable(GLExtensions.EXT_packed_depth_stencil) + ) + ) ; } /** @@ -1199,12 +1222,12 @@ public abstract class GLContext { /** * @see #getDeviceVersionAvailableKey(javax.media.nativewindow.AbstractGraphicsDevice, int, int) */ - protected static /*final*/ HashMap<String, Integer> deviceVersionAvailable = new HashMap<String, Integer>(); + protected static final IdentityHashMap<String, Integer> deviceVersionAvailable = new IdentityHashMap<String, Integer>(); /** * @see #getUniqueDeviceString(javax.media.nativewindow.AbstractGraphicsDevice) */ - private static /*final*/ HashSet<String> deviceVersionsAvailableSet = new HashSet<String>(); + private static final IdentityHashMap<String, String> deviceVersionsAvailableSet = new IdentityHashMap<String, String>(); /** clears the device/context mappings as well as the GL/GLX proc address tables. */ protected static void shutdown() { @@ -1215,17 +1238,16 @@ public abstract class GLContext { protected static boolean getAvailableGLVersionsSet(AbstractGraphicsDevice device) { synchronized ( deviceVersionsAvailableSet ) { - return deviceVersionsAvailableSet.contains(device.getUniqueID()); + return deviceVersionsAvailableSet.containsKey(device.getUniqueID()); } } protected static void setAvailableGLVersionsSet(AbstractGraphicsDevice device) { synchronized ( deviceVersionsAvailableSet ) { - String devKey = device.getUniqueID(); - if ( deviceVersionsAvailableSet.contains(devKey) ) { + final String devKey = device.getUniqueID(); + if( null != deviceVersionsAvailableSet.put(devKey, devKey) ) { throw new InternalError("Already set: "+devKey); } - deviceVersionsAvailableSet.add(devKey); if (DEBUG) { System.err.println(getThreadName() + ": createContextARB: SET mappedVersionsAvailableSet "+devKey); System.err.println(GLContext.dumpAvailableGLVersions(null).toString()); @@ -1233,8 +1255,13 @@ public abstract class GLContext { } } + /** + * Returns a unique String object using {@link String#intern()} for the given arguments, + * which object reference itself can be used as a key. + */ protected static String getDeviceVersionAvailableKey(AbstractGraphicsDevice device, int major, int profile) { - return device.getUniqueID() + "-" + toHexString(composeBits(major, profile, 0)); + final String r = device.getUniqueID() + "-" + toHexString(composeBits(major, profile, 0)); + return r.intern(); } /** @@ -1262,10 +1289,10 @@ public abstract class GLContext { System.err.println("GLContext.mapAvailableGLVersion: "+device+": "+getGLVersion(reqMajor, 0, profile, null)+" -> "+getGLVersion(resMajor, resMinor, resCtp, null)); // Thread.dumpStack(); } - final String key = getDeviceVersionAvailableKey(device, reqMajor, profile); + final String objectKey = getDeviceVersionAvailableKey(device, reqMajor, profile); final Integer val = new Integer(composeBits(resMajor, resMinor, resCtp)); synchronized(deviceVersionAvailable) { - return deviceVersionAvailable.put( key, val ); + return deviceVersionAvailable.put( objectKey, val ); } } @@ -1305,10 +1332,10 @@ public abstract class GLContext { * @return the available GL version as encoded with {@link #composeBits(int, int, int), otherwise <code>null</code> */ protected static Integer getAvailableGLVersion(AbstractGraphicsDevice device, int reqMajor, int reqProfile) { - String key = getDeviceVersionAvailableKey(device, reqMajor, reqProfile); + final String objectKey = getDeviceVersionAvailableKey(device, reqMajor, reqProfile); Integer val; synchronized(deviceVersionAvailable) { - val = deviceVersionAvailable.get( key ); + val = deviceVersionAvailable.get( objectKey ); } return val; } diff --git a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java index dbf6df0de..55ad85c9c 100644 --- a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java +++ b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java @@ -211,7 +211,15 @@ public abstract class GLDrawableFactory { // The latter requires shutdown at JVM-Shutdown only. synchronized(glDrawableFactories) { for(int i=0; i<glDrawableFactories.size(); i++) { - glDrawableFactories.get(i).destroy(); + final GLDrawableFactory gldf = glDrawableFactories.get(i); + try { + gldf.destroy(); + } catch (Throwable t) { + System.err.println("GLDrawableFactory.shutdownImpl: Catched Exception during shutdown of "+gldf.getClass().getName()); + if( DEBUG ) { + t.printStackTrace(); + } + } } glDrawableFactories.clear(); diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java index 7359e1b47..b11f359be 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java @@ -978,7 +978,6 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing private final AWTGLPixelBufferProvider pixelBufferProvider; private final boolean useSingletonBuffer; private AWTGLPixelBuffer pixelBuffer; - private boolean pixelBufferCheckSize; // One of these is used to store the read back pixels before storing // in the BufferedImage @@ -1160,14 +1159,10 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing if( useSingletonBuffer ) { // attempt to fetch the latest AWTGLPixelBuffer pixelBuffer = (AWTGLPixelBuffer) ((SingletonGLPixelBufferProvider)pixelBufferProvider).getSingleBuffer(pixelAttribs); } - if( pixelBufferCheckSize ) { - pixelBufferCheckSize = false; - if( null != pixelBuffer && pixelBuffer.requiresNewBuffer(gl, panelWidth, panelHeight, 0) ) { - pixelBuffer.dispose(); - pixelBuffer = null; - } + if( null != pixelBuffer && pixelBuffer.requiresNewBuffer(gl, panelWidth, panelHeight, 0) ) { + pixelBuffer.dispose(); + pixelBuffer = null; } - if ( null == pixelBuffer ) { if (0 >= panelWidth || 0 >= panelHeight ) { return; @@ -1300,8 +1295,6 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing } } } - - pixelBufferCheckSize = true; return _drawable.isRealized(); } diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/RegionRendererImpl01.java b/src/jogl/classes/jogamp/graph/curve/opengl/RegionRendererImpl01.java index 2884aca2f..7f5afcd02 100644 --- a/src/jogl/classes/jogamp/graph/curve/opengl/RegionRendererImpl01.java +++ b/src/jogl/classes/jogamp/graph/curve/opengl/RegionRendererImpl01.java @@ -46,22 +46,25 @@ public class RegionRendererImpl01 extends RegionRenderer { } - @Override - protected String getFragmentShaderName(GL2ES2 gl) { - final String type = Region.isNonUniformWeight(renderModes) ? "02" : "01" ; - final String pass = Region.isVBAA(renderModes) ? "b" : "a" ; - return "curverenderer" + type + pass + getShaderGLVersionSuffix(gl); - } - protected boolean initShaderProgram(GL2ES2 gl) { final ShaderState st = rs.getShaderState(); - ShaderCode rsVp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, RegionRendererImpl01.class, "shader", - "shader/bin", getVertexShaderName(gl), false); - ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, RegionRendererImpl01.class, "shader", - "shader/bin", getFragmentShaderName(gl), false); - - ShaderProgram sp = new ShaderProgram(); + final ShaderCode rsVp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, RegionRendererImpl01.class, "shader", + "shader/bin", getVertexShaderName(), true); + final ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, RegionRendererImpl01.class, "shader", + "shader/bin", getFragmentShaderName(), true); + rsVp.defaultShaderCustomization(gl, true, true); + // rsFp.defaultShaderCustomization(gl, true, true); + int pos = rsFp.addGLSLVersion(gl); + if( gl.isGLES2() ) { + pos = rsFp.insertShaderSource(0, pos, ShaderCode.extOESDerivativesEnable); + } + final String rsFpDefPrecision = getFragmentShaderPrecision(gl); + if( null != rsFpDefPrecision ) { + rsFp.insertShaderSource(0, pos, rsFpDefPrecision); + } + + final ShaderProgram sp = new ShaderProgram(); sp.add(rsVp); sp.add(rsFp); diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/TextRendererImpl01.java b/src/jogl/classes/jogamp/graph/curve/opengl/TextRendererImpl01.java index 0cf424cd2..81c421371 100644 --- a/src/jogl/classes/jogamp/graph/curve/opengl/TextRendererImpl01.java +++ b/src/jogl/classes/jogamp/graph/curve/opengl/TextRendererImpl01.java @@ -49,12 +49,22 @@ public class TextRendererImpl01 extends TextRenderer { protected boolean initShaderProgram(GL2ES2 gl){ final ShaderState st = rs.getShaderState(); - ShaderCode rsVp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, TextRendererImpl01.class, "shader", - "shader/bin", getVertexShaderName(gl), false); - ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, TextRendererImpl01.class, "shader", - "shader/bin", getFragmentShaderName(gl), false); + final ShaderCode rsVp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, TextRendererImpl01.class, "shader", + "shader/bin", getVertexShaderName(), true); + final ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, TextRendererImpl01.class, "shader", + "shader/bin", getFragmentShaderName(), true); + rsVp.defaultShaderCustomization(gl, true, true); + // rsFp.defaultShaderCustomization(gl, true, true); + int pos = rsFp.addGLSLVersion(gl); + if( gl.isGLES2() ) { + pos = rsFp.insertShaderSource(0, pos, ShaderCode.extOESDerivativesEnable); + } + final String rsFpDefPrecision = getFragmentShaderPrecision(gl); + if( null != rsFpDefPrecision ) { + rsFp.insertShaderSource(0, pos, rsFpDefPrecision); + } - ShaderProgram sp = new ShaderProgram(); + final ShaderProgram sp = new ShaderProgram(); sp.add(rsVp); sp.add(rsFp); diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer02a-xxx.fp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-1pass-weight.fp index d31bafb5a..7643dab7b 100644 --- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer02a-xxx.fp +++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-1pass-weight.fp @@ -4,6 +4,13 @@ // 1-pass shader w/ weight
//
+#if __VERSION__ >= 130
+ #define varying in
+ out vec4 mgl_FragColor;
+#else
+ #define mgl_FragColor gl_FragColor
+#endif
+
#include uniforms.glsl
#include varyings.glsl
@@ -44,5 +51,5 @@ void main (void) }
}
- gl_FragColor = vec4(c, alpha);
+ mgl_FragColor = vec4(c, alpha);
}
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01a-xxx.fp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-1pass.fp index f3a88adef..e12eef4b1 100644 --- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01a-xxx.fp +++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-1pass.fp @@ -4,6 +4,13 @@ // 1-pass shader w/o weight // +#if __VERSION__ >= 130 + #define varying in + out vec4 mgl_FragColor; +#else + #define mgl_FragColor gl_FragColor +#endif + #include uniforms.glsl #include varyings.glsl @@ -38,5 +45,5 @@ void main (void) } } - gl_FragColor = vec4(c, alpha); + mgl_FragColor = vec4(c, alpha); } diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer02b-xxx.fp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass-weight.fp index be738498c..06edbeaee 100644 --- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer02b-xxx.fp +++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass-weight.fp @@ -4,6 +4,13 @@ // 2-pass shader w/ weight
//
+#if __VERSION__ >= 130
+ #define varying in
+ out vec4 mgl_FragColor;
+#else
+ #define mgl_FragColor gl_FragColor
+#endif
+
#include uniforms.glsl
#include varyings.glsl
@@ -48,10 +55,11 @@ void main (void) t += texture2D(gcu_TextureUnit, rtex + 4.0*size*(vec2(0, 1)))*tex_weights.w;
t += texture2D(gcu_TextureUnit, rtex - 4.0*size*(vec2(0, 1)))*tex_weights.w;
- /** discard freezes NV tegra2 compiler
+ #if 0
if(t.w == 0.0) {
- discard;
- } */
+ discard; // discard freezes NV tegra2 compiler
+ }
+ #endif
c = t.xyz;
alpha = gcu_Alpha * t.w;
@@ -84,5 +92,5 @@ void main (void) }
}
- gl_FragColor = vec4(c, alpha);
+ mgl_FragColor = vec4(c, alpha);
}
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01b-xxx.fp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass.fp index 879e41e4c..07a005709 100644 --- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01b-xxx.fp +++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass.fp @@ -4,6 +4,13 @@ // 2-pass shader w/o weight // +#if __VERSION__ >= 130 + #define varying in + out vec4 mgl_FragColor; +#else + #define mgl_FragColor gl_FragColor +#endif + #include uniforms.glsl #include varyings.glsl @@ -49,10 +56,11 @@ void main (void) t += texture2D(gcu_TextureUnit, rtex + 4.0*size*(vec2(0, 1)))*tex_weights.w; t += texture2D(gcu_TextureUnit, rtex - 4.0*size*(vec2(0, 1)))*tex_weights.w; - /** discard freezes NV tegra2 compiler + #if 0 if(t.w == 0.0){ - discard; - } */ + discard; // discard freezes NV tegra2 compiler + } + #endif c = t.xyz; alpha = gcu_Alpha * t.w; @@ -78,5 +86,5 @@ void main (void) } } - gl_FragColor = vec4(c, alpha); + mgl_FragColor = vec4(c, alpha); } diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-es2-merged.vp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-es2-merged.vp deleted file mode 100644 index 8fb985d69..000000000 --- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-es2-merged.vp +++ /dev/null @@ -1,19 +0,0 @@ -//Copyright 2010 JogAmp Community. All rights reserved. - -#ifdef GL_ES - precision highp float; - precision highp int; -#endif - -uniform mat4 gcu_PMVMatrix[3]; // P, Mv, and Mvi -varying vec2 gcv_TexCoord; - -attribute vec4 gca_Vertices; -attribute vec2 gca_TexCoords; - - -void main(void) -{ - gl_Position = gcu_PMVMatrix[0] * gcu_PMVMatrix[1] * gca_Vertices; - gcv_TexCoord = gca_TexCoords; -} diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-es2.vp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-es2.vp deleted file mode 100644 index a5dc158ad..000000000 --- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-es2.vp +++ /dev/null @@ -1,9 +0,0 @@ -//Copyright 2010 JogAmp Community. All rights reserved. - -#version 100 - -precision highp float; -precision highp int; - -#include curverenderer01-xxx.vp - diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-gl2.vp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-gl2.vp deleted file mode 100644 index 1ac33e8b3..000000000 --- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-gl2.vp +++ /dev/null @@ -1,6 +0,0 @@ -//Copyright 2010 JogAmp Community. All rights reserved. - -#version 110 - -#include curverenderer01-xxx.vp - diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-xxx.vp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01.vp index 64a6835ec..4b5c8b1e2 100644 --- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-xxx.vp +++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01.vp @@ -1,5 +1,10 @@ //Copyright 2010 JogAmp Community. All rights reserved. +#if __VERSION__ >= 130 + #define attribute in + #define varying out +#endif + #include uniforms.glsl #include attributes.glsl #include varyings.glsl diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01a-es2-merged.fp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01a-es2-merged.fp deleted file mode 100644 index a57d8fc62..000000000 --- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01a-es2-merged.fp +++ /dev/null @@ -1,52 +0,0 @@ -//Copyright 2010 JogAmp Community. All rights reserved. - -#ifdef GL_ES - precision mediump float; - precision mediump int; -#endif - -uniform mat4 gcu_PMVMatrix[3]; // P, Mv, and Mvi -uniform vec3 gcu_ColorStatic; -uniform float gcu_Alpha; - -varying vec2 gcv_TexCoord; - -const vec3 b_color = vec3(1.0, 1.0, 1.0); - -void main (void) -{ - vec2 rtex = vec2(abs(gcv_TexCoord.x),abs(gcv_TexCoord.y)); - vec3 c = gcu_ColorStatic; - - float alpha = 0.0; - - if((gcv_TexCoord.x == 0.0) && (gcv_TexCoord.y == 0.0)) { - alpha = gcu_Alpha; - } - else if ((gcv_TexCoord.x > 0.0) && (rtex.y > 0.0 || rtex.x == 1.0)) { - vec2 dtx = dFdx(rtex); - vec2 dty = dFdy(rtex); - - rtex.y -= 0.1; - - if(rtex.y < 0.0) { - rtex.y = 0.0; - } - - vec2 f = vec2((dtx.y - dtx.x + 2.0*rtex.x*dtx.x), (dty.y - dty.x + 2.0*rtex.x*dty.x)); - float position = rtex.y - (rtex.x * (1.0 - rtex.x)); - float d = position/(length(f)); - - float a = (0.5 - d * sign(gcv_TexCoord.y)); - - if (a >= 1.0) { - alpha = gcu_Alpha; - } else if (a <= 0.0) { - alpha=0.0; - } else { - alpha = gcu_Alpha * a; - } - } - - gl_FragColor = vec4(c, alpha); -} diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01a-es2.fp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01a-es2.fp deleted file mode 100644 index e693891a6..000000000 --- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01a-es2.fp +++ /dev/null @@ -1,13 +0,0 @@ -//Copyright 2010 JogAmp Community. All rights reserved. - -#version 100 - -// we require dFdx/dFdy -// #extension OES_standard_derivatives : require -#extension GL_OES_standard_derivatives : enable - -precision mediump float; -precision mediump int; - -#include curverenderer01a-xxx.fp - diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01a-gl2.fp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01a-gl2.fp deleted file mode 100644 index d187fea24..000000000 --- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01a-gl2.fp +++ /dev/null @@ -1,6 +0,0 @@ -//Copyright 2010 JogAmp Community. All rights reserved. - -#version 110 - -#include curverenderer01a-xxx.fp - diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01b-es2.fp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01b-es2.fp deleted file mode 100644 index d4748722d..000000000 --- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01b-es2.fp +++ /dev/null @@ -1,14 +0,0 @@ -//Copyright 2010 JogAmp Community. All rights reserved. - -#version 100 - -// we require dFdx/dFdy -// #extension OES_standard_derivatives : require -#extension GL_OES_standard_derivatives : enable - -precision mediump float; -precision mediump int; -precision mediump sampler2D; // default is lowp - -#include curverenderer01b-xxx.fp - diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01b-gl2.fp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01b-gl2.fp deleted file mode 100644 index 01e08ff30..000000000 --- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01b-gl2.fp +++ /dev/null @@ -1,6 +0,0 @@ -//Copyright 2010 JogAmp Community. All rights reserved. - -#version 110 - -#include curverenderer01b-xxx.fp - diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer02a-es2.fp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer02a-es2.fp deleted file mode 100644 index 240a6c30f..000000000 --- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer02a-es2.fp +++ /dev/null @@ -1,14 +0,0 @@ -//Copyright 2010 JogAmp Community. All rights reserved. - -#version 100 - -// we require dFdx/dFdy -// #extension OES_standard_derivatives : require -#extension GL_OES_standard_derivatives : enable - -precision mediump float; -precision mediump int; -precision mediump sampler2D; // default is lowp - -#include curverenderer02a-xxx.fp - diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer02a-gl2.fp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer02a-gl2.fp deleted file mode 100644 index 01715daa5..000000000 --- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer02a-gl2.fp +++ /dev/null @@ -1,6 +0,0 @@ -//Copyright 2010 JogAmp Community. All rights reserved. - -#version 110 - -#include curverenderer02a-xxx.fp - diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer02b-es2.fp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer02b-es2.fp deleted file mode 100644 index 884e75674..000000000 --- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer02b-es2.fp +++ /dev/null @@ -1,14 +0,0 @@ -//Copyright 2010 JogAmp Community. All rights reserved. - -#version 100 - -// we require dFdx/dFdy -// #extension OES_standard_derivatives : require -#extension GL_OES_standard_derivatives : enable - -precision mediump float; -precision mediump int; -precision mediump sampler2D; // default is lowp - -#include curverenderer02b-xxx.fp - diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer02b-gl2.fp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer02b-gl2.fp deleted file mode 100644 index b1cc72188..000000000 --- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer02b-gl2.fp +++ /dev/null @@ -1,6 +0,0 @@ -//Copyright 2010 JogAmp Community. All rights reserved. - -#version 110 - -#include curverenderer02b-xxx.fp - diff --git a/src/jogl/classes/jogamp/graph/font/typecast/TypecastFontConstructor.java b/src/jogl/classes/jogamp/graph/font/typecast/TypecastFontConstructor.java index 0f762e79c..8479c08ca 100644 --- a/src/jogl/classes/jogamp/graph/font/typecast/TypecastFontConstructor.java +++ b/src/jogl/classes/jogamp/graph/font/typecast/TypecastFontConstructor.java @@ -71,7 +71,7 @@ public class TypecastFontConstructor implements FontConstructor { int len=0; Font f = null; try { - tf = IOUtil.createTempFile( "jogl.font", ".ttf", false, null); + tf = IOUtil.createTempFile( "jogl.font", ".ttf", false); len = IOUtil.copyURLConn2File(fconn, tf); if(len==0) { tf.delete(); diff --git a/src/jogl/classes/jogamp/opengl/Debug.java b/src/jogl/classes/jogamp/opengl/Debug.java index 4287c1960..f87f1bb3f 100644 --- a/src/jogl/classes/jogamp/opengl/Debug.java +++ b/src/jogl/classes/jogamp/opengl/Debug.java @@ -1,5 +1,6 @@ /* - * Copyright (c) 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -39,6 +40,9 @@ package jogamp.opengl; +import java.security.AccessController; +import java.security.PrivilegedAction; + import com.jogamp.common.util.PropertyAccess; /** Helper routines for logging and debugging. */ @@ -49,7 +53,12 @@ public class Debug extends PropertyAccess { private static final boolean debugAll; static { - PropertyAccess.addTrustedPrefix("jogl.", Debug.class); + AccessController.doPrivileged(new PrivilegedAction<Object>() { + public Object run() { + PropertyAccess.addTrustedPrefix("jogl."); + return null; + } } ); + verbose = isPropertyDefined("jogl.verbose", true); debugAll = isPropertyDefined("jogl.debug", true); if (verbose) { @@ -60,18 +69,6 @@ public class Debug extends PropertyAccess { } } - public static final boolean isPropertyDefined(final String property, final boolean jnlpAlias) { - return PropertyAccess.isPropertyDefined(property, jnlpAlias, null); - } - - public static String getProperty(final String property, final boolean jnlpAlias) { - return PropertyAccess.getProperty(property, jnlpAlias, null); - } - - public static final boolean getBooleanProperty(final String property, final boolean jnlpAlias) { - return PropertyAccess.getBooleanProperty(property, jnlpAlias, null); - } - public static boolean verbose() { return verbose; } diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java index f16834d28..cab629c3a 100644 --- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java +++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java @@ -1048,17 +1048,15 @@ public abstract class GLContextImpl extends GLContext { if(useGL) { ctxGLSLVersion = VersionNumber.zeroVersion; if( hasGLSL() ) { // >= ES2 || GL2.0 - final String glslVersion = gl.glGetString(GL2ES2.GL_SHADING_LANGUAGE_VERSION); + final String glslVersion = isGLES() ? null : gl.glGetString(GL2ES2.GL_SHADING_LANGUAGE_VERSION) ; // Use static GLSL version for ES to be safe! if( null != glslVersion ) { - ctxGLSLVersion = new VersionNumber(glslVersion, "."); + ctxGLSLVersion = new VersionNumber(glslVersion); if( ctxGLSLVersion.getMajor() < 1 ) { ctxGLSLVersion = VersionNumber.zeroVersion; // failed .. } } if( ctxGLSLVersion.isZero() ) { - final int[] sver = new int[2]; - getStaticGLSLVersionNumber(major, minor, ctxOptions, sver); - ctxGLSLVersion = new VersionNumber(sver[0], sver[1], 0); + ctxGLSLVersion = getStaticGLSLVersionNumber(major, minor, ctxOptions); } } } @@ -1506,7 +1504,7 @@ public abstract class GLContextImpl extends GLContext { } private final void setRendererQuirks(final AbstractGraphicsDevice adevice, int major, int minor, int ctp, final VersionNumberString vendorVersion) { - int[] quirks = new int[GLRendererQuirks.COUNT]; + int[] quirks = new int[GLRendererQuirks.COUNT + 1]; // + 1 ( NoFullFBOSupport ) int i = 0; final String MesaSP = "Mesa "; @@ -1515,6 +1513,7 @@ public abstract class GLContextImpl extends GLContext { final boolean isDriverMesa = glRenderer.contains(MesaSP) || glRenderer.contains("Gallium "); final boolean isDriverATICatalyst = !isDriverMesa && ( glVendor.contains("ATI Technologies") || glRenderer.startsWith("ATI ") ); final boolean isDriverNVIDIAGeForce = !isDriverMesa && ( glVendor.contains("NVIDIA Corporation") || glRenderer.contains("NVIDIA ") ); + // // OS related quirks // @@ -1585,6 +1584,44 @@ public abstract class GLContextImpl extends GLContext { } // + // Windowing Toolkit related quirks + // + if( NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(true) ) { + // + // X11 + // + { + // + // Quirk: DontCloseX11Display + // + final int quirk = GLRendererQuirks.DontCloseX11Display; + if( glRenderer.contains(MesaSP) ) { + if ( glRenderer.contains("X11") && vendorVersion.compareTo(Version80) < 0 ) { + if(DEBUG) { + System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: X11 Renderer=" + glRenderer + ", Version=[vendor " + vendorVersion + ", GL " + glVersion+"]"); + } + quirks[i++] = quirk; + } + } else if( isDriverATICatalyst ) { + { + if(DEBUG) { + System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: X11 Renderer=" + glRenderer); + } + quirks[i++] = quirk; + } + } else if( jogamp.nativewindow.x11.X11Util.getMarkAllDisplaysUnclosable() ) { + { + if(DEBUG) { + System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: X11Util Downstream"); + } + quirks[i++] = quirk; + } + } + } + } + + + // // RENDERER related quirks // if( isDriverMesa ) { @@ -1603,7 +1640,7 @@ public abstract class GLContextImpl extends GLContext { } quirks[i++] = quirk; } - if( glRenderer.contains("Intel(R)") && compatCtx && ( major>3 || major==3 && minor>=1 ) ) + if( glRenderer.contains("Intel(R)") && compatCtx && ( major > 3 || major == 3 && minor >= 1 ) ) { // FIXME: Apply vendor version constraints! final int quirk = GLRendererQuirks.GLNonCompliant; @@ -1612,37 +1649,30 @@ public abstract class GLContextImpl extends GLContext { } quirks[i++] = quirk; } - } - - // - // Quirk: DontCloseX11Display - // - if( NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(true) ) { - final int quirk = GLRendererQuirks.DontCloseX11Display; - if( glRenderer.contains(MesaSP) ) { - if ( glRenderer.contains("X11") && vendorVersion.compareTo(Version80) < 0 ) { - if(DEBUG) { - System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: X11 Renderer=" + glRenderer + ", Version=[vendor " + vendorVersion + ", GL " + glVersion+"]"); - } - quirks[i++] = quirk; - } - } else if( isDriverATICatalyst ) { - { - if(DEBUG) { - System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: X11 Renderer=" + glRenderer); - } - quirks[i++] = quirk; - } - } else if( jogamp.nativewindow.x11.X11Util.getMarkAllDisplaysUnclosable() ) { - { + if( Platform.getOSType() == Platform.OSType.WINDOWS && glRenderer.contains("SVGA3D") ) + { + final VersionNumber mesaSafeFBOVersion = new VersionNumber(8, 0, 0); + if ( vendorVersion.compareTo(mesaSafeFBOVersion) < 0 ) { // includes: vendorVersion.isZero() + final int quirk = GLRendererQuirks.NoFullFBOSupport; if(DEBUG) { - System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: X11Util Downstream"); + System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: OS "+Platform.getOSType() + " / Renderer " + glRenderer + " / Mesa-Version "+vendorVersion); } quirks[i++] = quirk; } } } + // + // Property related quirks + // + if( FORCE_MIN_FBO_SUPPORT ) { + final int quirk = GLRendererQuirks.NoFullFBOSupport; + if(DEBUG) { + System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: property"); + } + quirks[i++] = quirk; + } + glRendererQuirks = new GLRendererQuirks(quirks, 0, i); } diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java b/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java index 177c465da..8be910c1a 100644 --- a/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java +++ b/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java @@ -531,10 +531,10 @@ public class GLDrawableHelper { } } - private final void init(GLEventListener l, GLAutoDrawable drawable, boolean sendReshape) { + private final void init(GLEventListener l, GLAutoDrawable drawable, boolean sendReshape, boolean setViewport) { l.init(drawable); if(sendReshape) { - reshape(l, drawable, 0, 0, drawable.getWidth(), drawable.getHeight(), true /* setViewport */, false /* checkInit */); + reshape(l, drawable, 0, 0, drawable.getWidth(), drawable.getHeight(), setViewport, false /* checkInit */); } } @@ -545,33 +545,40 @@ public class GLDrawableHelper { public final void init(GLAutoDrawable drawable, boolean sendReshape) { synchronized(listenersLock) { final ArrayList<GLEventListener> _listeners = listeners; - for (int i=0; i < _listeners.size(); i++) { - final GLEventListener listener = _listeners.get(i) ; - - // If make ctx current, invoked by invokGL(..), results in a new ctx, init gets called. - // This may happen not just for initial setup, but for ctx recreation due to resource change (drawable/window), - // hence it must be called unconditional, always. - listenersToBeInit.remove(listener); // remove if exist, avoiding dbl init - init( listener, drawable, sendReshape); + final int listenerCount = _listeners.size(); + if( listenerCount > 0 ) { + for (int i=0; i < listenerCount; i++) { + final GLEventListener listener = _listeners.get(i) ; + + // If make ctx current, invoked by invokGL(..), results in a new ctx, init gets called. + // This may happen not just for initial setup, but for ctx recreation due to resource change (drawable/window), + // hence it must be called unconditional, always. + listenersToBeInit.remove(listener); // remove if exist, avoiding dbl init + init( listener, drawable, sendReshape, 0==i /* setViewport */); + } + } else { + // Expose same GL initialization if not using GLEventListener + drawable.getGL().glViewport(0, 0, drawable.getWidth(), drawable.getHeight()); } } } public final void display(GLAutoDrawable drawable) { displayImpl(drawable); - if(!execGLRunnables(drawable)) { + if( glRunnables.size()>0 && !execGLRunnables(drawable) ) { // glRunnables volatile OK; execGL.. only executed if size > 0 displayImpl(drawable); } } private final void displayImpl(GLAutoDrawable drawable) { synchronized(listenersLock) { final ArrayList<GLEventListener> _listeners = listeners; - for (int i=0; i < _listeners.size(); i++) { + final int listenerCount = _listeners.size(); + for (int i=0; i < listenerCount; i++) { final GLEventListener listener = _listeners.get(i) ; // GLEventListener may need to be init, // in case this one is added after the realization of the GLAutoDrawable if( listenersToBeInit.remove(listener) ) { - init( listener, drawable, true /* sendReshape */) ; + init( listener, drawable, true /* sendReshape */, listenersToBeInit.size() + 1 == listenerCount /* setViewport if 1st init */ ); } listener.display(drawable); } @@ -585,7 +592,7 @@ public class GLDrawableHelper { // in case this one is added after the realization of the GLAutoDrawable synchronized(listenersLock) { if( listenersToBeInit.remove(listener) ) { - init( listener, drawable, false /* sendReshape */) ; + listener.init(drawable); } } } @@ -598,29 +605,27 @@ public class GLDrawableHelper { public final void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { synchronized(listenersLock) { for (int i=0; i < listeners.size(); i++) { - reshape((GLEventListener) listeners.get(i), drawable, x, y, width, height, 0==i, true); + reshape((GLEventListener) listeners.get(i), drawable, x, y, width, height, 0==i /* setViewport */, true /* checkInit */); } } } - private final boolean execGLRunnables(GLAutoDrawable drawable) { + private final boolean execGLRunnables(GLAutoDrawable drawable) { // glRunnables.size()>0 boolean res = true; - if(glRunnables.size()>0) { // volatile OK - // swap one-shot list asap - final ArrayList<GLRunnableTask> _glRunnables; - synchronized(glRunnablesLock) { - if(glRunnables.size()>0) { - _glRunnables = glRunnables; - glRunnables = new ArrayList<GLRunnableTask>(); - } else { - _glRunnables = null; - } + // swap one-shot list asap + final ArrayList<GLRunnableTask> _glRunnables; + synchronized(glRunnablesLock) { + if(glRunnables.size()>0) { + _glRunnables = glRunnables; + glRunnables = new ArrayList<GLRunnableTask>(); + } else { + _glRunnables = null; } - - if(null!=_glRunnables) { - for (int i=0; i < _glRunnables.size(); i++) { - res = _glRunnables.get(i).run(drawable) && res; - } + } + + if(null!=_glRunnables) { + for (int i=0; i < _glRunnables.size(); i++) { + res = _glRunnables.get(i).run(drawable) && res; } } return res; diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java b/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java index 877e7b60b..e1088da29 100644 --- a/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java +++ b/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java @@ -116,6 +116,7 @@ public abstract class GLDrawableImpl implements GLDrawable { * {@link GL#glFlush()} has been called already and * the implementation may execute implementation specific code. * </p> + * @param doubleBuffered indicates whether double buffering is enabled, see above. */ protected abstract void swapBuffersImpl(boolean doubleBuffered); diff --git a/src/jogl/classes/jogamp/opengl/GLDynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/GLDynamicLibraryBundleInfo.java index 4c82fc2b3..a2e3b3175 100644 --- a/src/jogl/classes/jogamp/opengl/GLDynamicLibraryBundleInfo.java +++ b/src/jogl/classes/jogamp/opengl/GLDynamicLibraryBundleInfo.java @@ -36,11 +36,21 @@ public abstract class GLDynamicLibraryBundleInfo implements DynamicLibraryBundle protected GLDynamicLibraryBundleInfo() { } - /** default **/ - @Override - public boolean shallLinkGlobal() { return false; } - - /** default **/ + /** + * Returns <code>true</code>, + * since we might load a desktop GL library and allow symbol access to subsequent libs. + * <p> + * This respects old DRI requirements: + * <pre> + * http://dri.sourceforge.net/doc/DRIuserguide.html + * </pre> + * </p> + */ + public boolean shallLinkGlobal() { return true; } + + /** + * Default value: <code>false</code>. + */ @Override public boolean shallLookupGlobal() { return false; } diff --git a/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java b/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java index 85f63b52c..27024d4e1 100644 --- a/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java +++ b/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java @@ -52,7 +52,10 @@ public class GLFBODrawableImpl extends GLDrawableImpl implements GLFBODrawable { private int fboIBack; // points to GL_BACK buffer private int fboIFront; // points to GL_FRONT buffer private int pendingFBOReset = -1; + /** Indicated whether the FBO is bound. */ private boolean fboBound; + /** Indicated whether the FBO is swapped, resets to false after makeCurrent -> contextMadeCurrent. */ + private boolean fboSwapped; /** dump fboResetQuirk info only once pre ClassLoader and only in DEBUG mode */ private static volatile boolean resetQuirkInfoDumped = false; @@ -139,21 +142,20 @@ public class GLFBODrawableImpl extends GLDrawableImpl implements GLFBODrawable { } } fbos[fboIFront].resetSamplingSink(gl); - fboBound = false; + fbos[0].formatToGLCapabilities(chosenFBOCaps); chosenFBOCaps.setDoubleBuffered( chosenFBOCaps.getDoubleBuffered() || samples > 0 ); - - initialized = true; } else { - initialized = false; - for(int i=0; i<fbos.length; i++) { fbos[i].destroy(gl); } fbos=null; - fboBound = false; - pendingFBOReset = -1; } + fboBound = false; + fboSwapped = false; + pendingFBOReset = -1; + initialized = realize; + if(DEBUG) { System.err.println("GLFBODrawableImpl.initialize("+realize+"): "+this); Thread.dumpStack(); @@ -230,6 +232,7 @@ public class GLFBODrawableImpl extends GLDrawableImpl implements GLFBODrawable { ourContext.makeCurrent(); gl.glFinish(); // sync GL command stream fboBound = false; // clear bound-flag immediatly, caused by contextMadeCurrent(..) - otherwise we would swap @ release + fboSwapped = false; try { final int maxSamples = gl.getMaxRenderbufferSamples(); newSamples = newSamples <= maxSamples ? newSamples : maxSamples; @@ -340,10 +343,12 @@ public class GLFBODrawableImpl extends GLDrawableImpl implements GLFBODrawable { } fbos[fboIBack].bind(gl); fboBound = true; - } else if( fboBound ) { + fboSwapped = false; + } else if( fboBound && !fboSwapped ) { swapFBOImpl(glc); swapFBOImplPost(glc); fboBound=false; + fboSwapped=true; if(DEBUG_SWAP) { System.err.println("Post FBO swap(@release): done"); } @@ -353,14 +358,16 @@ public class GLFBODrawableImpl extends GLDrawableImpl implements GLFBODrawable { @Override protected void swapBuffersImpl(boolean doubleBuffered) { final GLContext ctx = GLContext.getCurrent(); - boolean doPostSwap = false; + boolean doPostSwap; if( null != ctx && ctx.getGLDrawable() == this && fboBound ) { swapFBOImpl(ctx); doPostSwap = true; - fboBound=false; + fboSwapped = true; if(DEBUG_SWAP) { System.err.println("Post FBO swap(@swap): done"); } + } else { + doPostSwap = false; } if( null != swapBufferContext ) { swapBufferContext.swapBuffers(doubleBuffered); diff --git a/src/jogl/classes/jogamp/opengl/GLVersionNumber.java b/src/jogl/classes/jogamp/opengl/GLVersionNumber.java index 990698667..cea3ac4ab 100644 --- a/src/jogl/classes/jogamp/opengl/GLVersionNumber.java +++ b/src/jogl/classes/jogamp/opengl/GLVersionNumber.java @@ -28,98 +28,62 @@ package jogamp.opengl; -import java.util.StringTokenizer; - -import javax.media.opengl.GLContext; - +import com.jogamp.common.util.VersionNumber; import com.jogamp.common.util.VersionNumberString; /** * A class for storing and comparing OpenGL version numbers. * This only works for desktop OpenGL at the moment. */ -class GLVersionNumber extends VersionNumberString { +public class GLVersionNumber extends VersionNumberString { private final boolean valid; - private GLVersionNumber(int[] val, String versionString, boolean valid) { - super(val[0], val[1], val[2], versionString); + private GLVersionNumber(int[] val, int strEnd, short state, String versionString, boolean valid) { + super(val[0], val[1], val[2], strEnd, state, versionString); this.valid = valid; } - public static GLVersionNumber create(String versionString) { + private static java.util.regex.Pattern getUnderscorePattern() { + if( null == _Pattern ) { // volatile dbl-checked-locking OK + synchronized( VersionNumber.class ) { + if( null == _Pattern ) { + _Pattern = getVersionNumberPattern("_"); + } + } + } + return _Pattern; + } + private static volatile java.util.regex.Pattern _Pattern = null; + + public static final GLVersionNumber create(String versionString) { int[] val = new int[] { 0, 0, 0 }; - try { - if (versionString.startsWith("GL_VERSION_")) { - StringTokenizer tok = new StringTokenizer(versionString, "_"); - tok.nextToken(); // GL_ - tok.nextToken(); // VERSION_ - if (!tok.hasMoreTokens()) { - val[0] = 0; + int strEnd = 0; + short state = 0; + boolean valid = false; + if (versionString != null && versionString.length() > 0) { + try { + final java.util.regex.Pattern versionPattern; + if (versionString.startsWith("GL_VERSION_")) { + versionPattern = getUnderscorePattern(); } else { - val[0] = Integer.valueOf(tok.nextToken()).intValue(); - if (!tok.hasMoreTokens()) { - val[1] = 0; - } else { - val[1] = Integer.valueOf(tok.nextToken()).intValue(); - if (!tok.hasMoreTokens()) { - val[2] = 0; - } else { - val[2] = Integer.valueOf(tok.nextToken()).intValue(); - } - } - } - } else { - int radix = 10; - if (versionString.length() > 2) { - if (Character.isDigit(versionString.charAt(0)) && versionString.charAt(1) == '.' && Character.isDigit(versionString.charAt(2))) { - val[0] = Character.digit(versionString.charAt(0), radix); - val[1] = Character.digit(versionString.charAt(2), radix); - // See if there's version-specific information which might - // imply a more recent OpenGL version - StringTokenizer tok = new StringTokenizer(versionString, " "); - if (tok.hasMoreTokens()) { - tok.nextToken(); - if (tok.hasMoreTokens()) { - String token = tok.nextToken(); - int i = 0; - while (i < token.length() && !Character.isDigit(token.charAt(i))) { - i++; - } - if (i < token.length() - 2 && Character.isDigit(token.charAt(i)) && token.charAt(i + 1) == '.' && Character.isDigit(token.charAt(i + 2))) { - int altMajor = Character.digit(token.charAt(i), radix); - int altMinor = Character.digit(token.charAt(i + 2), radix); - // Avoid possibly confusing situations by putting some - // constraints on the upgrades we do to the major and - // minor versions - if ( (altMajor == val[0] && altMinor > val[1]) || altMajor == val[0] + 1 ) { - if( GLContext.isValidGLVersion(altMajor, altMinor) ) { - val[0] = altMajor; - val[1] = altMinor; - } - } - } - } - } - } + versionPattern = VersionNumberString.getDefaultVersionNumberPattern(); } + final VersionNumberString version = new VersionNumberString(versionString, versionPattern); + strEnd = version.endOfStringMatch(); + val[0] = version.getMajor(); + val[1] = version.getMinor(); + state = (short) ( ( version.hasMajor() ? VersionNumber.HAS_MAJOR : (short)0 ) | + ( version.hasMinor() ? VersionNumber.HAS_MINOR : (short)0 ) ); + valid = version.hasMajor() && version.hasMinor(); // Requires at least a defined major and minor version component! + } catch (Exception e) { + e.printStackTrace(); + System.err.println("Info: ExtensionAvailabilityCache: FunctionAvailabilityCache.Version.<init>: " + e); + val[0] = 1; + val[1] = 0; } - return new GLVersionNumber(val, versionString, true); - } catch (Exception e) { - e.printStackTrace(); - // FIXME: refactor desktop OpenGL dependencies and make this - // class work properly for OpenGL ES - System.err.println("Info: ExtensionAvailabilityCache: FunctionAvailabilityCache.Version.<init>: " + e); - val[0] = 1; - val[1] = 0; - /* - throw (IllegalArgumentException) - new IllegalArgumentException( - "Illegally formatted version identifier: \"" + versionString + "\"") - .initCause(e); - */ - } - return new GLVersionNumber(val, versionString, false); + } + return new GLVersionNumber(val, strEnd, state, versionString, valid); } public final boolean isValid() { @@ -131,6 +95,7 @@ class GLVersionNumber extends VersionNumberString { * <code>GL_VERSION</code> string if exists, otherwise the {@link VersionNumberString#zeroVersion zero version} instance. * <pre> * 2.1 Mesa 7.0.3-rc2 -> 7.0.3 (7.0.3-rc2) + * 2.1 Mesa 7.12-devel (git-d6c318e) -> 7.12.0 (7.12-devel) * 4.2.12171 Compatibility Profile Context 9.01.8 -> 9.1.8 (9.01.8) * 4.2.12198 Compatibility Profile Context 12.102.3.0 -> 12.102.3 (12.102.3.0) * 4.3.0 NVIDIA 310.32 -> 310.32 (310.32) @@ -139,18 +104,25 @@ class GLVersionNumber extends VersionNumberString { public static final VersionNumberString createVendorVersion(String versionString) { if (versionString == null || versionString.length() <= 0) { return null; - } - final String[] strings = versionString.trim().split("\\s+"); - if ( strings.length <= 0 ) { - return null; } - // Test all segments backwards from [len-1..1], skipping the 1st entry (GL version) - // If a segment represents a valid VersionNumber - use it. - for(int i=strings.length-1; i>=1; i--) { - final String s = strings[i]; - final VersionNumberString version = new VersionNumberString(s, "."); - if( !version.isZero() ) { - return version; + + // Skip the 1st GL version + String str; + { + final GLVersionNumber glv = create(versionString); + str = versionString.substring(glv.endOfStringMatch()); + } + + while ( str.length() > 0 ) { + final VersionNumberString version = new VersionNumberString(str, getDefaultVersionNumberPattern()); + final int eosm = version.endOfStringMatch(); + if( 0 < eosm ) { + if( version.hasMajor() && version.hasMinor() ) { // Requires at least a defined major and minor version component! + return version; + } + str = str.substring( eosm ); + } else { + break; // no match } } return VersionNumberString.zeroVersion; diff --git a/src/jogl/classes/jogamp/opengl/egl/DesktopES2DynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/egl/DesktopES2DynamicLibraryBundleInfo.java index cddd142e9..771d16d46 100644 --- a/src/jogl/classes/jogamp/opengl/egl/DesktopES2DynamicLibraryBundleInfo.java +++ b/src/jogl/classes/jogamp/opengl/egl/DesktopES2DynamicLibraryBundleInfo.java @@ -47,16 +47,6 @@ public class DesktopES2DynamicLibraryBundleInfo extends GLDynamicLibraryBundleIn super(); } - /** - * Might be a desktop GL library, and might need to allow symbol access to subsequent libs. - * - * This respects old DRI requirements:<br> - * <pre> - * http://dri.sourceforge.net/doc/DRIuserguide.html - * </pre> - */ - public boolean shallLinkGlobal() { return true; } - public final List<String> getToolGetProcAddressFuncNameList() { List<String> res = new ArrayList<String>(); res.add("eglGetProcAddress"); diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/egl/EGLDynamicLibraryBundleInfo.java index fe9d7573d..26b199ea2 100644 --- a/src/jogl/classes/jogamp/opengl/egl/EGLDynamicLibraryBundleInfo.java +++ b/src/jogl/classes/jogamp/opengl/egl/EGLDynamicLibraryBundleInfo.java @@ -29,6 +29,7 @@ package jogamp.opengl.egl; import com.jogamp.common.os.AndroidVersion; +import com.jogamp.common.os.Platform; import java.util.*; @@ -52,19 +53,12 @@ public abstract class EGLDynamicLibraryBundleInfo extends GLDynamicLibraryBundle } /** - * Might be a desktop GL library, and might need to allow symbol access to subsequent libs. - * - * This respects old DRI requirements:<br> - * <pre> - * http://dri.sourceforge.net/doc/DRIuserguide.html - * </pre> + * Returns <code>true</code> on <code>Android</code>, + * and <code>false</code> otherwise. */ @Override - public boolean shallLinkGlobal() { return true; } - - @Override public boolean shallLookupGlobal() { - if ( AndroidVersion.isAvailable ) { + if ( Platform.OSType.ANDROID == Platform.OS_TYPE ) { // Android requires global symbol lookup return true; } diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java index 666cd30af..6b086ce44 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java @@ -81,7 +81,7 @@ import com.jogamp.opengl.util.glsl.ShaderCode; import com.jogamp.opengl.util.glsl.ShaderProgram; public class MacOSXCGLContext extends GLContextImpl -{ +{ // Abstract interface for implementation of this context (either // NSOpenGL-based or CGL-based) protected interface GLBackendImpl { @@ -149,8 +149,8 @@ public class MacOSXCGLContext extends GLContextImpl "../../shader", "../../shader/bin", shaderBasename, true); final ShaderCode fp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, MacOSXCGLContext.class, "../../shader", "../../shader/bin", shaderBasename, true); - vp.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_vp); - fp.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_fp); + vp.defaultShaderCustomization(gl, true, true); + fp.defaultShaderCustomization(gl, true, true); sp.add(vp); sp.add(fp); if(!sp.link(gl, System.err)) { @@ -939,7 +939,7 @@ public class MacOSXCGLContext extends GLContextImpl if(0 == cglCtx) { throw new InternalError("Null CGLContext for: "+this); } - int err = CGL.CGLLockContext(cglCtx); + final int err = CGL.CGLLockContext(cglCtx); if(CGL.kCGLNoError == err) { validatePBufferConfig(ctx); // required to handle pbuffer change ASAP return CGL.makeCurrentContext(ctx); @@ -1000,6 +1000,8 @@ public class MacOSXCGLContext extends GLContextImpl CGL.setNSOpenGLLayerSwapInterval(l, interval); if( 0 < interval ) { vsyncTimeout = interval * screenVSyncTimeout + 1000; // +1ms + } else { + vsyncTimeout = 1 * screenVSyncTimeout + 1000; // +1ms } if(DEBUG) { System.err.println("NS setSwapInterval: "+interval+" -> "+vsyncTimeout+" micros"); } } @@ -1008,6 +1010,14 @@ public class MacOSXCGLContext extends GLContextImpl } private int skipSync=0; + /** TODO: Remove after discussion + private boolean perfIterReset = false; + private int perfIter = 0; + private long waitGLS = 0; + private long finishGLS = 0; + private long frameXS = 0; + private long lastFrameStart = 0; + */ @Override public boolean swapBuffers() { @@ -1036,6 +1046,45 @@ public class MacOSXCGLContext extends GLContextImpl res = CGL.flushBuffer(contextHandle); if(res) { if(0 == skipSync) { + /** TODO: Remove after discussion + perfIter++; + if( !perfIterReset && 100 == perfIter ) { + perfIterReset = true; + perfIter = 1; + waitGLS = 0; + finishGLS = 0; + frameXS = 0; + } + final long lastFramePeriod0 = TimeUnit.NANOSECONDS.toMicros(System.nanoTime()) - lastFrameStart; + gl.glFinish(); // Require to finish previous GL rendering to give CALayer proper result + final long lastFramePeriod1 = TimeUnit.NANOSECONDS.toMicros(System.nanoTime()) - lastFrameStart; + + // If v-sync is disabled, frames will be drawn as quickly as possible w/o delay, + // while still synchronizing w/ CALayer. + // If v-sync is enabled wait until next swap interval (v-sync). + CGL.waitUntilNSOpenGLLayerIsReady(cmd.nsOpenGLLayer, vsyncTimeout); + final long lastFramePeriodX = TimeUnit.NANOSECONDS.toMicros(System.nanoTime()) - lastFrameStart; + + final long finishGL = lastFramePeriod1 - lastFramePeriod0; + final long waitGL = lastFramePeriodX - lastFramePeriod1; + finishGLS += finishGL; + waitGLS += waitGL; + frameXS += lastFramePeriodX; + + System.err.println("XXX["+perfIter+"] TO "+vsyncTimeout/1000+" ms, "+ + "lFrame0 "+lastFramePeriod0/1000+" ms, "+ + "lFrameX "+lastFramePeriodX/1000+" / "+frameXS/1000+" ~"+(frameXS/perfIter)/1000.0+" ms, "+ + "finishGL "+finishGL/1000+" / "+finishGLS/1000+" ~"+(finishGLS/perfIter)/1000.0+" ms, "+ + "waitGL "+waitGL/1000+" / "+waitGLS/1000+" ~"+(waitGLS/perfIter)/1000.0+" ms"); + */ + // + // Required(?) to finish previous GL rendering to give CALayer proper result, + // i.e. synchronize both threads each w/ their GLContext sharing same resources. + // + // FIXME: IMHO this synchronization should be implicitly performed via 'CGL.flushBuffer(contextHandle)' above, + // in case this will be determined a driver bug - use a QUIRK entry in GLRendererQuirks! + gl.glFinish(); + // If v-sync is disabled, frames will be drawn as quickly as possible w/o delay, // while still synchronizing w/ CALayer. // If v-sync is enabled wait until next swap interval (v-sync). @@ -1050,6 +1099,7 @@ public class MacOSXCGLContext extends GLContextImpl // trigger CALayer to update incl. possible surface change (new pbuffer handle) CGL.setNSOpenGLLayerNeedsDisplayPBuffer(cmd.nsOpenGLLayer, drawable.getHandle()); } + // lastFrameStart = TimeUnit.NANOSECONDS.toMicros(System.nanoTime()); } } else { res = true; diff --git a/src/jogl/classes/jogamp/opengl/openal/av/ALDummyUsage.java b/src/jogl/classes/jogamp/opengl/openal/av/ALDummyUsage.java new file mode 100644 index 000000000..69223d0b9 --- /dev/null +++ b/src/jogl/classes/jogamp/opengl/openal/av/ALDummyUsage.java @@ -0,0 +1,19 @@ +package jogamp.opengl.openal.av; + +import jogamp.opengl.util.av.impl.FFMPEGMediaPlayer; + +import com.jogamp.openal.AL; +import com.jogamp.openal.JoalVersion; + +/** + * Demo JOAL usage w/ av dependency, i.e. FFMPEGMediaPlayer .. + */ +public class ALDummyUsage { + static AL al; + static FFMPEGMediaPlayer.PixelFormat pfmt; + + public static void main(String args[]) { + System.err.println("JOGL> Hello JOAL"); + System.err.println("JOAL: "+JoalVersion.getInstance().toString()); + } +} diff --git a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGDynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGDynamicLibraryBundleInfo.java index 35342669f..0971ac78e 100644 --- a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGDynamicLibraryBundleInfo.java +++ b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGDynamicLibraryBundleInfo.java @@ -28,6 +28,8 @@ package jogamp.opengl.util.av.impl; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -133,7 +135,10 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo { static boolean initSingleton() { return ready; } private static boolean initSymbols() { - final DynamicLibraryBundle dl = new DynamicLibraryBundle(new FFMPEGDynamicLibraryBundleInfo()); + final DynamicLibraryBundle dl = AccessController.doPrivileged(new PrivilegedAction<DynamicLibraryBundle>() { + public DynamicLibraryBundle run() { + return new DynamicLibraryBundle(new FFMPEGDynamicLibraryBundleInfo()); + } } ); final boolean avutilLoaded = dl.isToolLibLoaded(0); final boolean avformatLoaded = dl.isToolLibLoaded(1); final boolean avcodecLoaded = dl.isToolLibLoaded(2); diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/GLSLTextureRaster.java b/src/jogl/classes/jogamp/opengl/util/glsl/GLSLTextureRaster.java index 20c251635..eaf8dc30a 100644 --- a/src/jogl/classes/jogamp/opengl/util/glsl/GLSLTextureRaster.java +++ b/src/jogl/classes/jogamp/opengl/util/glsl/GLSLTextureRaster.java @@ -69,8 +69,8 @@ public class GLSLTextureRaster { shaderSrcPath, shaderBinPath, shaderBasename, true); final ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, this.getClass(), shaderSrcPath, shaderBinPath, shaderBasename, true); - rsVp.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_vp); - rsFp.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_fp); + rsVp.defaultShaderCustomization(gl, true, true); + rsFp.defaultShaderCustomization(gl, true, true); // Create & Link the shader program sp = new ShaderProgram(); 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 cc58f2363..f4f20ac7c 100644 --- a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/FixedFuncPipeline.java +++ b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/FixedFuncPipeline.java @@ -943,8 +943,8 @@ public class FixedFuncPipeline { private static final String constMaxTextures8 = "#define MAX_TEXTURE_UNITS 8\n"; private final void customizeShader(GL2ES2 gl, ShaderCode vp, ShaderCode fp, String maxTextureDefine) { - int rsVpPos = vp.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_vp); - int rsFpPos = fp.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_fp); + int rsVpPos = vp.defaultShaderCustomization(gl, true, true); + int rsFpPos = fp.defaultShaderCustomization(gl, true, true); vp.insertShaderSource(0, rsVpPos, maxTextureDefine); fp.insertShaderSource(0, rsFpPos, maxTextureDefine); } diff --git a/src/jogl/classes/jogamp/opengl/util/jpeg/JPEGDecoder.java b/src/jogl/classes/jogamp/opengl/util/jpeg/JPEGDecoder.java index 251291a14..833771dd1 100644 --- a/src/jogl/classes/jogamp/opengl/util/jpeg/JPEGDecoder.java +++ b/src/jogl/classes/jogamp/opengl/util/jpeg/JPEGDecoder.java @@ -301,13 +301,15 @@ public class JPEGDecoder { private final ArrayHashSet<Integer> compIDs; private final ComponentIn[] comps; private final int compCount; + /** quantization tables */ + final int[][] qtt; int maxCompID; int maxH; int maxV; int mcusPerLine; int mcusPerColumn; - Frame(boolean progressive, int precision, int scanLines, int samplesPerLine, int componentsCount) { + Frame(boolean progressive, int precision, int scanLines, int samplesPerLine, int componentsCount, int[][] qtt) { this.progressive = progressive; this.precision = precision; this.scanLines = scanLines; @@ -315,6 +317,7 @@ public class JPEGDecoder { compIDs = new ArrayHashSet<Integer>(componentsCount); comps = new ComponentIn[componentsCount]; this.compCount = componentsCount; + this.qtt = qtt; } private final void checkBounds(int idx) { @@ -322,6 +325,17 @@ public class JPEGDecoder { throw new CodecException("Idx out of bounds "+idx+", "+this); } } + public final void validateComponents() { + for(int i=0; i<compCount; i++) { + final ComponentIn c = comps[i]; + if( null == c ) { + throw new CodecException("Component["+i+"] null"); + } + if( null == this.qtt[c.qttIdx] ) { + throw new CodecException("Component["+i+"].qttIdx -> null QTT"); + } + } + } public final int getCompCount() { return compCount; } public final int getMaxCompID() { return maxCompID; } @@ -357,7 +371,8 @@ public class JPEGDecoder { /** The JPEG encoded components */ class ComponentIn { final int h, v; - final int[] quantizationTable; + /** index to frame.qtt[] */ + final int qttIdx; int blocksPerColumn; int blocksPerColumnForMcu; int blocksPerLine; @@ -368,10 +383,10 @@ public class JPEGDecoder { BinObj huffmanTableAC; BinObj huffmanTableDC; - ComponentIn(int h, int v, int[] quantizationTable) { + ComponentIn(int h, int v, int qttIdx) { this.h = h; this.v = v; - this.quantizationTable = quantizationTable; + this.qttIdx = qttIdx; } public final void allocateBlocks(int blocksPerColumn, int blocksPerColumnForMcu, int blocksPerLine, int blocksPerLineForMcu) { @@ -389,7 +404,7 @@ public class JPEGDecoder { } public final String toString() { - return "CompIn[h "+h+", v "+v+", blocks["+blocksPerColumn+", mcu "+blocksPerColumnForMcu+"]["+blocksPerLine+", mcu "+blocksPerLineForMcu+"][64]]"; + return "CompIn[h "+h+", v "+v+", qttIdx "+qttIdx+", blocks["+blocksPerColumn+", mcu "+blocksPerColumnForMcu+"]["+blocksPerLine+", mcu "+blocksPerLineForMcu+"][64]]"; } } @@ -526,12 +541,14 @@ public class JPEGDecoder { } public synchronized JPEGDecoder parse(final InputStream inputStream) throws IOException { clear(inputStream); - Frame frame = null; - int resetInterval = 0; - int[][] quantizationTables = new int[0x0F][]; // 4 bits - ArrayList<Frame> frames = new ArrayList<Frame>(); + + final int[][] quantizationTables = new int[0x0F][]; // 4 bits final BinObj[] huffmanTablesAC = new BinObj[0x0F]; // Huffman table spec - 4 bits final BinObj[] huffmanTablesDC = new BinObj[0x0F]; // Huffman table spec - 4 bits + // final ArrayList<Frame> frames = new ArrayList<Frame>(); // JAU: max 1-frame + + Frame frame = null; + int resetInterval = 0; int fileMarker = readUint16(); if ( fileMarker != M_SOI ) { throw new CodecException("SOI not found, but has marker "+toHexString(fileMarker)); @@ -579,6 +596,7 @@ public class JPEGDecoder { while( count < quantizationTablesLength ) { final int quantizationTableSpec = readUint8(); count++; final int precisionID = quantizationTableSpec >> 4; + final int tableIdx = quantizationTableSpec & 0x0F; final int[] tableData = new int[64]; if ( precisionID == 0 ) { // 8 bit values for (int j = 0; j < 64; j++) { @@ -591,12 +609,15 @@ public class JPEGDecoder { tableData[z] = readUint16(); count+=2; } } else { - throw new CodecException("DQT: invalid table precision "+precisionID+", quantizationTableSpec "+quantizationTableSpec); + throw new CodecException("DQT: invalid table precision "+precisionID+", quantizationTableSpec "+quantizationTableSpec+", idx "+tableIdx); } - quantizationTables[quantizationTableSpec & 0x0F] = tableData; + quantizationTables[tableIdx] = tableData; + if( DEBUG ) { + System.err.println("JPEG.parse.QTT["+tableIdx+"]: spec "+quantizationTableSpec+", precision "+precisionID+", data "+count+"/"+quantizationTablesLength); + } } if(count!=quantizationTablesLength){ - throw new CodecException("ERROR: QTT format error [count!=Length]"); + throw new CodecException("ERROR: QTT format error [count!=Length]: "+count+"/"+quantizationTablesLength); } fileMarker = 0; // consumed and get-next } @@ -604,6 +625,9 @@ public class JPEGDecoder { case M_SOF0: case M_SOF2: { + if( null != frame ) { // JAU: max 1-frame + throw new CodecException("only single frame JPEGs supported"); + } int count = 0; final int sofLen = readUint16(); count+=2; // header length; final int componentsCount; @@ -613,7 +637,7 @@ public class JPEGDecoder { final int scanLines = readUint16(); count+=2; final int samplesPerLine = readUint16(); count+=2; componentsCount = readUint8(); count++; - frame = new Frame(progressive, precision, scanLines, samplesPerLine, componentsCount); + frame = new Frame(progressive, precision, scanLines, samplesPerLine, componentsCount, quantizationTables); width = frame.samplesPerLine; height = frame.scanLines; } @@ -622,14 +646,15 @@ public class JPEGDecoder { final int temp = readUint8(); count++; final int h = temp >> 4; final int v = temp & 0x0F; - final int qId = readUint8(); count++; - frame.putOrdered(componentId, new ComponentIn(h, v, quantizationTables[qId])); + final int qttIdx = readUint8(); count++; + final ComponentIn compIn = new ComponentIn(h, v, qttIdx); + frame.putOrdered(componentId, compIn); } if(count!=sofLen){ throw new CodecException("ERROR: SOF format error [count!=Length]"); } prepareComponents(frame); - frames.add(frame); + // frames.add(frame); // JAU: max 1-frame if(DEBUG) { System.err.println("JPG.parse.SOF[02]: Got frame "+frame); } fileMarker = 0; // consumed and get-next } @@ -711,14 +736,21 @@ public class JPEGDecoder { } } if(DEBUG) { System.err.println("JPG.parse.2: End of parsing input "+this); } + /** // JAU: max 1-frame if ( frames.size() != 1 ) { - throw new CodecException("only single frame JPEGs supported"); + throw new CodecException("only single frame JPEGs supported "+this); + } */ + if( null == frame ) { + throw new CodecException("no single frame found in stream "+this); } + frame.validateComponents(); final int compCount = frame.getCompCount(); this.components = new ComponentOut[compCount]; for (int i = 0; i < compCount; i++) { final ComponentIn component = frame.getCompByIndex(i); + // System.err.println("JPG.parse.buildComponentData["+i+"]: "+component); // JAU + // System.err.println("JPG.parse.buildComponentData["+i+"]: "+frame); // JAU this.components[i] = new ComponentOut( output.buildComponentData(frame, component), (float)component.h / (float)frame.maxH, (float)component.v / (float)frame.maxV ); @@ -834,12 +866,14 @@ public class JPEGDecoder { final byte[] r = new byte[64]; for (int blockRow = 0; blockRow < blocksPerColumn; blockRow++) { - int scanLine = blockRow << 3; + final int scanLine = blockRow << 3; + // System.err.println("JPG.buildComponentData: row "+blockRow+"/"+blocksPerColumn+" -> scanLine "+scanLine); // JAU for (int i = 0; i < 8; i++) { lines.add(new byte[samplesPerLine]); } for (int blockCol = 0; blockCol < blocksPerLine; blockCol++) { - quantizeAndInverse(component.getBlock(blockRow, blockCol), r, R, component.quantizationTable); + // System.err.println("JPG.buildComponentData: col "+blockCol+"/"+blocksPerLine+", comp.qttIdx "+component.qttIdx+", qtt "+frame.qtt[component.qttIdx]); // JAU + quantizeAndInverse(component.getBlock(blockRow, blockCol), r, R, frame.qtt[component.qttIdx]); final int sample = blockCol << 3; int offset = 0; diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDynamicLibraryBundleInfo.java index 108c157a8..6083f209c 100644 --- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDynamicLibraryBundleInfo.java +++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDynamicLibraryBundleInfo.java @@ -60,15 +60,6 @@ public class X11GLXDynamicLibraryBundleInfo extends DesktopGLDynamicLibraryBundl return libsList; } - /** - * This respects old DRI requirements:<br> - * <pre> - * http://dri.sourceforge.net/doc/DRIuserguide.html - * </pre> - */ - @Override - public boolean shallLinkGlobal() { return true; } - @Override public final List<String> getToolGetProcAddressFuncNameList() { List<String> res = new ArrayList<String>(); diff --git a/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m b/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m index 6738364a7..046171efc 100644 --- a/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m +++ b/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m @@ -818,40 +818,39 @@ static const GLfloat gl_verts[] = { - (void)waitUntilRenderSignal: (long) to_micros { - BOOL ready = NO; - int wr = 0; + struct timespec t0, to_until; + BOOL tooLate; + int wr; + if( 0 >= to_micros ) { + to_micros = 16666 + 1000; // defaults to 1/60s + 1ms + NSLog(@"MyNSOpenGLContext::waitUntilRenderSignal: to_micros was zero, using defaults"); + } pthread_mutex_lock(&renderLock); - SYNC_PRINT("{W %ld us", to_micros); - do { - if(0 >= swapInterval) { - ready = YES; - } - if(NO == ready) { - #ifdef DBG_SYNC - struct timespec t0, t1, td, td2; - timespec_now(&t0); - #endif - if( 0 >= to_micros ) { - to_micros = 16666 + 1000; // defaults to 1/60s + 1ms - NSLog(@"MyNSOpenGLContext::waitUntilRenderSignal: to_micros was zero, using defaults"); - } - struct timespec to_abs = lastWaitTime; - timespec_addmicros(&to_abs, to_micros); - #ifdef DBG_SYNC - timespec_subtract(&td, &to_abs, &t0); - fprintf(stderr, ", (%ld) / ", timespec_milliseconds(&td)); - #endif - wr = pthread_cond_timedwait(&renderSignal, &renderLock, &to_abs); - #ifdef DBG_SYNC - timespec_now(&t1); - timespec_subtract(&td, &t1, &t0); - timespec_subtract(&td2, &t1, &lastWaitTime); - fprintf(stderr, "(%ld) / (%ld) ms", timespec_milliseconds(&td), timespec_milliseconds(&td2)); - #endif - ready = YES; + timespec_now(&t0); + to_until = lastWaitTime; + timespec_addmicros(&to_until, to_micros); + tooLate = timespec_compare(&to_until, &t0) < 0; + #ifdef DBG_SYNC + struct timespec td_until; + timespec_subtract(&td_until, &to_until, &t0); + SYNC_PRINT("{W %ld ms, to %ld ms, late %d", to_micros/1000, timespec_milliseconds(&td_until), tooLate); + #endif + if( 0 < swapInterval ) { + if( tooLate ) { + // adjust! + to_until = t0; + timespec_addmicros(&to_until, to_micros); } - } while (NO == ready && 0 == wr) ; - SYNC_PRINT("-%d-%d-%d}", shallDraw, wr, ready); + wr = pthread_cond_timedwait(&renderSignal, &renderLock, &to_until); + #ifdef DBG_SYNC + struct timespec t1, td, td2; + timespec_now(&t1); + timespec_subtract(&td, &t1, &t0); + timespec_subtract(&td2, &t1, &lastWaitTime); + fprintf(stderr, "(%ld) / (%ld) ms", timespec_milliseconds(&td), timespec_milliseconds(&td2)); + #endif + } + SYNC_PRINT("-%d-%d}\n", shallDraw, wr); timespec_now(&lastWaitTime); pthread_mutex_unlock(&renderLock); } diff --git a/src/jogl/native/timespec.c b/src/jogl/native/timespec.c index 50f0ca8c5..a69f4635e 100644 --- a/src/jogl/native/timespec.c +++ b/src/jogl/native/timespec.c @@ -75,3 +75,8 @@ long timespec_milliseconds(struct timespec *a) { return a->tv_sec*1000 + a->tv_nsec/1000000; } + +long timespec_microseconds(struct timespec *a) +{ + return a->tv_sec*1000000 + a->tv_nsec/1000; +} diff --git a/src/jogl/native/timespec.h b/src/jogl/native/timespec.h index f900bfa16..a621562b9 100644 --- a/src/jogl/native/timespec.h +++ b/src/jogl/native/timespec.h @@ -17,4 +17,7 @@ void timespec_subtract(struct timespec *r, struct timespec *a, struct timespec * /** convert the timespec into milliseconds (may overflow) */ long timespec_milliseconds(struct timespec *a); +/** convert the timespec into microseconds (may overflow) */ +long timespec_microseconds(struct timespec *a); + #endif /* _timespec_h */ |