aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderProgram.java
diff options
context:
space:
mode:
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.java86
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;