diff options
Diffstat (limited to 'src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderProgram.java')
-rw-r--r-- | src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderProgram.java | 86 |
1 files changed, 50 insertions, 36 deletions
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 14ea7d2b8..b289b41e2 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderProgram.java +++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderProgram.java @@ -37,7 +37,7 @@ import java.util.Iterator; import java.io.PrintStream; public class ShaderProgram { - + public ShaderProgram() { id = getNextID(); } @@ -50,6 +50,7 @@ public class ShaderProgram { return programInUse; } + /** Returns the shader program name, which is non zero if valid. */ public int program() { return shaderProgram; } /** @@ -84,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)) { @@ -96,9 +99,9 @@ public class ShaderProgram { } allShaderCode.clear(); attachedShaderCode.clear(); - if(0<=shaderProgram) { + if( 0 != shaderProgram ) { gl.glDeleteProgram(shaderProgram); - shaderProgram=-1; + shaderProgram=0; } } @@ -108,7 +111,7 @@ public class ShaderProgram { /** * Adds a new shader to this program. - * + * * <p>This command does not compile and attach the shader, * use {@link #add(GL2ES2, ShaderCode)} for this purpose.</p> */ @@ -119,7 +122,7 @@ public class ShaderProgram { public synchronized boolean contains(ShaderCode shaderCode) { return allShaderCode.contains(shaderCode); } - + /** * Warning slow O(n) operation .. * @param id @@ -140,30 +143,33 @@ public class ShaderProgram { // /** - * Creates the empty GL program object using {@link GL2ES2#glCreateProgram()} - * + * Creates the empty GL program object using {@link GL2ES2#glCreateProgram()}, + * if not already created. + * * @param gl + * @return true if shader program is valid, i.e. not zero */ - public synchronized final void init(GL2ES2 gl) { - if(0>shaderProgram) { + public synchronized final boolean init(GL2ES2 gl) { + if( 0 == shaderProgram ) { shaderProgram = gl.glCreateProgram(); } + return 0 != shaderProgram; } - + /** * Adds a new shader to a this non running program. * * <p>Compiles and attaches the shader, if not done yet.</p> - * + * * @return true if the shader was successfully added, false if compilation failed. */ public synchronized boolean add(GL2ES2 gl, ShaderCode shaderCode, PrintStream verboseOut) { - init(gl); + if( !init(gl) ) { return false; } if( allShaderCode.add(shaderCode) ) { - if(!shaderCode.compile(gl, verboseOut)) { + if( !shaderCode.compile(gl, verboseOut) ) { return false; } - if(attachedShaderCode.add(shaderCode)) { + if( attachedShaderCode.add(shaderCode) ) { ShaderUtil.attachShader(gl, shaderProgram, shaderCode.shader()); } } @@ -173,11 +179,11 @@ public class ShaderProgram { /** * Replace a shader in a program and re-links the program. * - * @param gl + * @param gl * @param oldShader the to be replace Shader * @param newShader the new ShaderCode * @param verboseOut the optional verbose output stream - * + * * @return true if all steps are valid, shader compilation, attachment and linking; otherwise false. * * @see ShaderState#glEnableVertexAttribArray @@ -190,31 +196,29 @@ public class ShaderProgram { * @see ShaderState#glResetAllVertexAttributes */ public synchronized boolean replaceShader(GL2ES2 gl, ShaderCode oldShader, ShaderCode newShader, PrintStream verboseOut) { - init(gl); - - if(!newShader.compile(gl, verboseOut)) { + if(!init(gl) || !newShader.compile(gl, verboseOut)) { return false; } - + boolean shaderWasInUse = inUse(); if(shaderWasInUse) { useProgram(gl, false); } - + if(null != oldShader && allShaderCode.remove(oldShader)) { if(attachedShaderCode.remove(oldShader)) { ShaderUtil.detachShader(gl, shaderProgram, oldShader.shader()); } } - + add(newShader); if(attachedShaderCode.add(newShader)) { ShaderUtil.attachShader(gl, shaderProgram, newShader.shader()); } - + gl.glLinkProgram(shaderProgram); - - programLinked = ShaderUtil.isProgramLinkStatusValid(gl, shaderProgram, System.err); + + programLinked = ShaderUtil.isProgramLinkStatusValid(gl, shaderProgram, verboseOut); if ( programLinked && shaderWasInUse ) { useProgram(gl, true); } @@ -223,23 +227,27 @@ public class ShaderProgram { /** * Links the shader code to the program. - * + * * <p>Compiles and attaches the shader code to the program if not done by yet</p> - * + * * <p>Within this process, all GL resources (shader and program objects) are created if necessary.</p> - * + * * @param gl * @param verboseOut * @return true if program was successfully linked and is valid, otherwise false - * + * * @see #init(GL2ES2) */ public synchronized boolean link(GL2ES2 gl, PrintStream verboseOut) { - init(gl); + if( !init(gl) ) { + programLinked = false; // mark unlinked due to user attempt to [re]link + return false; + } for(Iterator<ShaderCode> iter=allShaderCode.iterator(); iter.hasNext(); ) { final ShaderCode shaderCode = iter.next(); if(!shaderCode.compile(gl, verboseOut)) { + programLinked = false; // mark unlinked due to user attempt to [re]link return false; } if(attachedShaderCode.add(shaderCode)) { @@ -250,11 +258,12 @@ public class ShaderProgram { // Link the program gl.glLinkProgram(shaderProgram); - programLinked = ShaderUtil.isProgramLinkStatusValid(gl, shaderProgram, System.err); + programLinked = ShaderUtil.isProgramLinkStatusValid(gl, shaderProgram, verboseOut); return programLinked; } + @Override public boolean equals(Object obj) { if(this == obj) { return true; } if(obj instanceof ShaderProgram) { @@ -263,6 +272,7 @@ public class ShaderProgram { return false; } + @Override public int hashCode() { return id; } @@ -279,7 +289,8 @@ public class ShaderProgram { sb.append("]"); return sb; } - + + @Override public String toString() { return toString(null).toString(); } @@ -291,17 +302,20 @@ public class ShaderProgram { public synchronized boolean validateProgram(GL2ES2 gl, PrintStream verboseOut) { return ShaderUtil.isProgramExecStatusValid(gl, shaderProgram, verboseOut); } - + public synchronized void useProgram(GL2ES2 gl, boolean on) { if(!programLinked) { throw new GLException("Program is not linked"); } if(programInUse==on) { return; } - gl.glUseProgram(on?shaderProgram:0); + if( 0 == shaderProgram ) { + on = false; + } + gl.glUseProgram( on ? shaderProgram : 0 ); programInUse = on; } protected boolean programLinked = false; protected boolean programInUse = false; - protected int shaderProgram=-1; + protected int shaderProgram = 0; // non zero is valid! protected HashSet<ShaderCode> allShaderCode = new HashSet<ShaderCode>(); protected HashSet<ShaderCode> attachedShaderCode = new HashSet<ShaderCode>(); protected int id = -1; |