diff options
author | Sven Gothel <[email protected]> | 2013-05-17 04:52:32 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2013-05-17 04:52:32 +0200 |
commit | 33abeb8097a8f80acd1a4ce94b4866e5dc41f0c0 (patch) | |
tree | 263bfc8987a159bec0f4d1cfec2427f6a5660189 /src/jogl | |
parent | 31e72d2f2d953352b2a8c83368039ecca8139d49 (diff) |
Fix Bug 737: Add shader default precision for GLSL [1.30 .. 1.50[ - See GLSL Spec [1.30 - 1.40].
Diffstat (limited to 'src/jogl')
6 files changed, 138 insertions, 32 deletions
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..80a7efaec 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. @@ -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,74 @@ 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"; + + /** + * 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 VersionNumber glslVersion = gl.getContext().getGLSLVersionNumber(); + 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( glslVersion.compareTo(GLContext.Version130) >= 0 && glslVersion.compareTo(GLContext.Version150) < 0 ) { + // 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; + } + /** * Default customization of this shader source code. * <p> @@ -835,18 +900,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/javax/media/opengl/GLContext.java b/src/jogl/classes/javax/media/opengl/GLContext.java index bbe8d602b..ab966a70d 100644 --- a/src/jogl/classes/javax/media/opengl/GLContext.java +++ b/src/jogl/classes/javax/media/opengl/GLContext.java @@ -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); @@ -733,27 +746,24 @@ public abstract class GLContext { return "#version " + ctxGLSLVersion.getMajor() + ( minor < 10 ? "0"+minor : minor ) + "\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 + 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; + return new VersionNumber(glMajorVersion, glMinorVersion * 10, 0); // GL M.N -> GLSL M.N } } diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java index f16834d28..8c9c12e21 100644 --- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java +++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java @@ -1056,9 +1056,7 @@ public abstract class GLContextImpl extends GLContext { } } 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); } } } diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java index 666cd30af..b90609ff1 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java @@ -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)) { 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); } |