summaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/com/jogamp
diff options
context:
space:
mode:
Diffstat (limited to 'src/jogl/classes/com/jogamp')
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderCode.java26
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderProgram.java193
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderState.java19
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderUtil.java23
4 files changed, 145 insertions, 116 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 c735de468..20b032a41 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderCode.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderCode.java
@@ -155,9 +155,9 @@ public class ShaderCode {
return res;
}
}
- Set binFmts = ShaderUtil.getShaderBinaryFormats(gl);
- for(Iterator iter=binFmts.iterator(); null==res && iter.hasNext(); ) {
- int bFmt = ((Integer)(iter.next())).intValue();
+ Set<Integer> binFmts = ShaderUtil.getShaderBinaryFormats(gl);
+ for(Iterator<Integer> iter=binFmts.iterator(); null==res && iter.hasNext(); ) {
+ int bFmt = iter.next().intValue();
String bFmtPath = getBinarySubPath(bFmt);
if(null==bFmtPath) continue;
binFileName = binRoot + '/' + bFmtPath + '/' + basename + "." + getFileSuffix(true, type);
@@ -174,16 +174,8 @@ public class ShaderCode {
/**
* returns the uniq shader id as an integer
- * @see #key()
*/
- public int id() { return id.intValue(); }
-
- /**
- * returns the uniq shader id as an Integer
- *
- * @see #id()
- */
- public Integer key() { return id; }
+ public int id() { return id; }
public int shaderType() { return shaderType; }
public String shaderTypeStr() { return shaderTypeStr(shaderType); }
@@ -239,7 +231,7 @@ public class ShaderCode {
shaderSource=null;
shaderBinaryFormat=-1;
shaderType=-1;
- id=null;
+ id=-1;
}
public boolean equals(Object obj) {
@@ -250,7 +242,7 @@ public class ShaderCode {
return false;
}
public int hashCode() {
- return id.intValue();
+ return id;
}
public String toString() {
StringBuffer buf = new StringBuffer("ShaderCode [id="+id+", type="+shaderTypeStr()+", valid="+valid+", shader: ");
@@ -359,12 +351,12 @@ public class ShaderCode {
protected int shaderBinaryFormat = -1;
protected IntBuffer shader = null;
protected int shaderType = -1;
- protected Integer id = null;
+ protected int id = -1;
protected boolean valid=false;
- private static synchronized Integer getNextID() {
- return new Integer(nextID++);
+ private static synchronized int getNextID() {
+ return nextID++;
}
protected static int nextID = 1;
}
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 b6908c1a1..b622571e7 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderProgram.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderProgram.java
@@ -30,11 +30,12 @@ package com.jogamp.opengl.util.glsl;
import javax.media.opengl.*;
-import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.io.PrintStream;
public class ShaderProgram {
+
public ShaderProgram() {
id = getNextID();
}
@@ -51,16 +52,8 @@ public class ShaderProgram {
/**
* returns the uniq shader id as an integer
- * @see #key()
- */
- public int id() { return id.intValue(); }
-
- /**
- * returns the uniq shader id as an Integer
- *
- * @see #id()
*/
- public Integer key() { return id; }
+ public int id() { return id; }
/**
* Detaches all shader codes and deletes the program.
@@ -88,15 +81,18 @@ public class ShaderProgram {
* If releaseShaderToo is true, destroys the shader codes as well.
*/
public synchronized void release(GL2ES2 gl, boolean releaseShaderToo) {
- glUseProgram(gl, false);
- for(Iterator iter=shaderMap.values().iterator(); iter.hasNext(); ) {
- ShaderCode shaderCode = (ShaderCode) iter.next();
- ShaderUtil.detachShader(gl, shaderProgram, shaderCode.shader());
+ useProgram(gl, false);
+ for(Iterator<ShaderCode> iter=allShaderCode.iterator(); iter.hasNext(); ) {
+ ShaderCode shaderCode = iter.next();
+ if(attachedShaderCode.remove(shaderCode)) {
+ ShaderUtil.detachShader(gl, shaderProgram, shaderCode.shader());
+ }
if(releaseShaderToo) {
shaderCode.destroy(gl);
}
}
- shaderMap.clear();
+ allShaderCode.clear();
+ attachedShaderCode.clear();
gl.glDeleteProgram(shaderProgram);
shaderProgram=-1;
}
@@ -106,35 +102,78 @@ public class ShaderProgram {
//
/**
- * Adds a new shader to a this non running program.
- *
- * @return false if the program is in use, or the shader already exist,
- * otherwise true.
+ * 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>
*/
- public synchronized boolean add(ShaderCode shaderCode) {
- if(shaderMap.containsKey(shaderCode.key())) return false;
- shaderMap.put(shaderCode.key(), shaderCode);
- return true;
+ public synchronized void add(ShaderCode shaderCode) throws GLException {
+ allShaderCode.add(shaderCode);
}
+ public synchronized boolean contains(ShaderCode shaderCode) {
+ return allShaderCode.contains(shaderCode);
+ }
+
+ /**
+ * Warning slow O(n) operation ..
+ * @param id
+ * @return
+ */
public synchronized ShaderCode getShader(int id) {
- return (ShaderCode) shaderMap.get(new Integer(id));
+ for(Iterator<ShaderCode> iter=allShaderCode.iterator(); iter.hasNext(); ) {
+ ShaderCode shaderCode = iter.next();
+ if(shaderCode.id() == id) {
+ return shaderCode;
+ }
+ }
+ return null;
}
//
- // Program handling
+ // ShaderCode / Program handling
//
/**
- * Replace a shader in a 'running' program.
- * Refetches all previously bin/get attribute names
- * and resets all attribute data as well
+ * Creates the empty GL program object using {@link GL2ES2#glCreateProgram()}
+ *
+ * @param gl
+ */
+ public synchronized final void init(GL2ES2 gl) {
+ if(0>shaderProgram) {
+ shaderProgram = gl.glCreateProgram();
+ }
+ }
+
+ /**
+ * 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( allShaderCode.add(shaderCode) ) {
+ if(!shaderCode.compile(gl, verboseOut)) {
+ return false;
+ }
+ if(attachedShaderCode.add(shaderCode)) {
+ ShaderUtil.attachShader(gl, shaderProgram, shaderCode.shader());
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Replace a shader in a program and re-links the program.
*
* @param gl
- * @param oldShaderID the to be replace Shader
+ * @param oldShader the to be replace Shader
* @param newShader the new ShaderCode
- * @param verboseOut the optional verbose outputstream
- * @throws GLException is the program is not linked
+ * @param verboseOut the optional verbose output stream
+ *
+ * @return true if all steps are valid, shader compilation, attachment and linking; otherwise false.
*
* @see ShaderState#glEnableVertexAttribArray
* @see ShaderState#glDisableVertexAttribArray
@@ -145,47 +184,44 @@ public class ShaderProgram {
* @see ShaderState#glResetAllVertexAttributes
* @see ShaderState#glResetAllVertexAttributes
*/
- public synchronized boolean glReplaceShader(GL2ES2 gl, int oldShaderID, ShaderCode newShader, PrintStream verboseOut) {
- if(!programLinked) throw new GLException("Program is not linked");
- boolean shaderWasInUse = programInUse;
- glUseProgram(gl, false);
+ public synchronized boolean replaceShader(GL2ES2 gl, ShaderCode oldShader, ShaderCode newShader, PrintStream verboseOut) {
+ init(gl);
+
if(!newShader.compile(gl, verboseOut)) {
return false;
- }
- if(oldShaderID>=0) {
- ShaderCode oldShader = (ShaderCode) shaderMap.remove(new Integer(oldShaderID));
- if(null!=oldShader) {
+ }
+
+ 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);
-
- ShaderUtil.attachShader(gl, shaderProgram, newShader.shader());
- gl.glLinkProgram(shaderProgram);
- if ( ! ShaderUtil.isProgramValid(gl, shaderProgram, System.err) ) {
- return false;
+ if(attachedShaderCode.add(newShader)) {
+ ShaderUtil.attachShader(gl, shaderProgram, newShader.shader());
}
-
- if(shaderWasInUse) {
- glUseProgram(gl, true);
+
+ gl.glLinkProgram(shaderProgram);
+
+ programLinked = ShaderUtil.isProgramValid(gl, shaderProgram, System.err);
+ if ( programLinked && shaderWasInUse ) {
+ useProgram(gl, true);
}
- return true;
+ return programLinked;
}
/**
- * Creates the empty GL program object using {@link GL2ES2#glCreateProgram()}
- *
- * @param gl
- */
- public final void init(GL2ES2 gl) {
- if(0>shaderProgram) {
- shaderProgram = gl.glCreateProgram();
- }
- }
-
- /**
- * Compiles and links the shader code to the program.
- * Within this process, all GL resources (shader and program objects) are created if necessary.
+ * 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
@@ -194,18 +230,16 @@ public class ShaderProgram {
* @see #init(GL2ES2)
*/
public synchronized boolean link(GL2ES2 gl, PrintStream verboseOut) {
- if(programLinked) throw new GLException("Program is already linked");
+ init(gl);
- if(0>shaderProgram) {
- shaderProgram = gl.glCreateProgram();
- }
-
- for(Iterator iter=shaderMap.values().iterator(); iter.hasNext(); ) {
- ShaderCode shaderCode = (ShaderCode) iter.next();
+ for(Iterator<ShaderCode> iter=allShaderCode.iterator(); iter.hasNext(); ) {
+ final ShaderCode shaderCode = iter.next();
if(!shaderCode.compile(gl, verboseOut)) {
return false;
}
- ShaderUtil.attachShader(gl, shaderProgram, shaderCode.shader());
+ if(attachedShaderCode.add(shaderCode)) {
+ ShaderUtil.attachShader(gl, shaderProgram, shaderCode.shader());
+ }
}
// Link the program
@@ -225,40 +259,37 @@ public class ShaderProgram {
}
public int hashCode() {
- return id.intValue();
+ return id;
}
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("ShaderProgram[id="+id);
buf.append(", linked="+programLinked+", inUse="+programInUse+", program: "+shaderProgram+", [");
- for(Iterator iter=shaderMap.values().iterator(); iter.hasNext(); ) {
- buf.append((ShaderCode) iter.next());
+ for(Iterator<ShaderCode> iter=allShaderCode.iterator(); iter.hasNext(); ) {
+ buf.append(iter.next());
buf.append(" ");
}
buf.append("]");
return buf.toString();
}
- protected synchronized void glUseProgram(GL2ES2 gl, boolean on) {
+ protected 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);
programInUse = on;
-
- //Throwable tX = new Throwable("Info: ShaderProgram.glUseProgram: "+on);
- //tX.printStackTrace();
-
}
protected boolean programLinked = false;
protected boolean programInUse = false;
protected int shaderProgram=-1;
- protected HashMap shaderMap = new HashMap();
- protected Integer id = null;
+ protected HashSet<ShaderCode> allShaderCode = new HashSet<ShaderCode>();
+ protected HashSet<ShaderCode> attachedShaderCode = new HashSet<ShaderCode>();
+ protected int id = -1;
- private static synchronized Integer getNextID() {
- return new Integer(nextID++);
+ private static synchronized int getNextID() {
+ return nextID++;
}
protected static int nextID = 1;
}
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 d3f224a2a..de77a1941 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderState.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderState.java
@@ -139,7 +139,7 @@ public class ShaderState {
public synchronized void glUseProgram(GL2ES2 gl, boolean on) {
if(null==shaderProgram) { throw new GLException("No program is attached"); }
if(on) {
- shaderProgram.glUseProgram(gl, true);
+ shaderProgram.useProgram(gl, true);
// update the current ShaderState to the TLS ..
gl.getContext().attachObject(ShaderState.class.getName(), this);
if(resetAllShaderData) {
@@ -148,7 +148,7 @@ public class ShaderState {
glResetAllUniforms(gl);
}
} else {
- shaderProgram.glUseProgram(gl, false);
+ shaderProgram.useProgram(gl, false);
}
}
@@ -204,7 +204,7 @@ public class ShaderState {
if(shaderProgram.linked()) {
glUseProgram(gl, true);
if(!prgInUse) {
- shaderProgram.glUseProgram(gl, false);
+ shaderProgram.useProgram(gl, false);
}
}
}
@@ -249,7 +249,7 @@ public class ShaderState {
if(null!=shaderProgram) {
prgInUse = shaderProgram.inUse();
if(!prgInUse) {
- shaderProgram.glUseProgram(gl, true);
+ shaderProgram.useProgram(gl, true);
}
}
glReleaseAllVertexAttributes(gl);
@@ -258,7 +258,7 @@ public class ShaderState {
if(releaseProgramToo) {
shaderProgram.release(gl, releaseShaderToo);
} else if(!prgInUse) {
- shaderProgram.glUseProgram(gl, false);
+ shaderProgram.useProgram(gl, false);
}
}
}
@@ -512,6 +512,9 @@ public class ShaderState {
if(null==shaderProgram) throw new GLException("No program is attached");
if(0 > data.getLocation()) {
glGetAttribLocation(gl, data);
+ } else {
+ // ensure data is the current bound one
+ vertexAttribMap2Data.put(data.getName(), data);
}
return glEnableVertexAttribArray(gl, data.getName(), data.getLocation());
}
@@ -608,7 +611,11 @@ public class ShaderState {
// if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
if(0 > data.getLocation()) {
glGetAttribLocation(gl, data);
- }
+ } /* else {
+ // Already achieved by glEnableVertexAttribArray(..)
+ // ensure data is the current bound one
+ vertexAttribMap2Data.put(data.getName(), data);
+ } */
if(0 <= data.getLocation()) {
// only pass the data, if the attribute exists in the current shader
if(DEBUG) {
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderUtil.java b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderUtil.java
index 3a5a24116..c81e1f961 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderUtil.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderUtil.java
@@ -51,7 +51,7 @@ public class ShaderUtil {
public abstract boolean isProgramValid(GL gl, int programObj);
public abstract boolean isProgramValid(GL gl, int programObj, PrintStream verboseOut);
public abstract void createShader(GL gl, int type, IntBuffer shaders);
- public abstract Set getShaderBinaryFormats(GL gl);
+ public abstract Set<Integer> getShaderBinaryFormats(GL gl);
public abstract boolean isShaderCompilerAvailable(GL gl);
public abstract void shaderSource(GL gl, int shader, java.lang.String[] source);
public abstract void shaderSource(GL gl, IntBuffer shaders, java.lang.String[][] sources);
@@ -74,7 +74,7 @@ public class ShaderUtil {
public String getShaderInfoLog(GL _gl, int shaderObj) {
GL2ES2 gl = _gl.getGL2ES2();
int[] infoLogLength=new int[1];
- gl.glGetShaderiv(shaderObj, gl.GL_INFO_LOG_LENGTH, infoLogLength, 0);
+ gl.glGetShaderiv(shaderObj, GL2ES2.GL_INFO_LOG_LENGTH, infoLogLength, 0);
if(infoLogLength[0]==0) {
return "(no info log)";
@@ -89,7 +89,7 @@ public class ShaderUtil {
public String getProgramInfoLog(GL _gl, int programObj) {
GL2ES2 gl = _gl.getGL2ES2();
int[] infoLogLength=new int[1];
- gl.glGetProgramiv(programObj, gl.GL_INFO_LOG_LENGTH, infoLogLength, 0);
+ gl.glGetProgramiv(programObj, GL2ES2.GL_INFO_LOG_LENGTH, infoLogLength, 0);
if(infoLogLength[0]==0) {
return "(no info log)";
@@ -143,14 +143,13 @@ public class ShaderUtil {
public boolean isProgramValid(GL _gl, int programObj, PrintStream verboseOut) {
GL2ES2 gl = _gl.getGL2ES2();
- int[] ires = new int[1];
if(!gl.glIsProgram(programObj)) {
if(null!=verboseOut) {
verboseOut.println("Program name invalid: "+programObj);
}
return false;
}
- if(!isProgramStatusValid(gl, programObj, gl.GL_LINK_STATUS)) {
+ if(!isProgramStatusValid(gl, programObj, GL2ES2.GL_LINK_STATUS)) {
if(null!=verboseOut) {
verboseOut.println("Program link failed: "+programObj+"\n\t"+ getProgramInfoLog(gl, programObj));
}
@@ -159,7 +158,7 @@ public class ShaderUtil {
if ( !gl.isGLES2() || isShaderCompilerAvailable(gl) ) {
// failed on APX2500 (ES2.0, no compiler) for valid programs
gl.glValidateProgram(programObj);
- if(!isProgramStatusValid(gl, programObj, gl.GL_VALIDATE_STATUS)) {
+ if(!isProgramStatusValid(gl, programObj, GL2ES2.GL_VALIDATE_STATUS)) {
if(null!=verboseOut) {
verboseOut.println("Program validation failed: "+programObj+"\n\t"+ getProgramInfoLog(gl, programObj));
}
@@ -177,15 +176,15 @@ public class ShaderUtil {
}
private Boolean shaderCompilerAvailable = null;
- private Set shaderBinaryFormats = null;
+ private Set<Integer> shaderBinaryFormats = null;
- public Set getShaderBinaryFormats(GL _gl) {
+ public Set<Integer> getShaderBinaryFormats(GL _gl) {
GL2ES2 gl = _gl.getGL2ES2();
if(null==shaderBinaryFormats) {
gl.getContext().validateCurrent();
int[] param = new int[1];
- shaderBinaryFormats = new HashSet();
+ shaderBinaryFormats = new HashSet<Integer>();
if (gl.isGLES2()) {
gl.glGetIntegerv(GL2ES2.GL_NUM_SHADER_BINARY_FORMATS, param, 0);
@@ -207,7 +206,7 @@ public class ShaderUtil {
GL2ES2 gl = _gl.getGL2ES2();
if(null==shaderCompilerAvailable) {
gl.getContext().validateCurrent();
- Set bfs = getShaderBinaryFormats(gl);
+ Set<Integer> bfs = getShaderBinaryFormats(gl);
if(gl.isGLES2()) {
byte[] param = new byte[1];
gl.glGetBooleanv(GL2ES2.GL_SHADER_COMPILER, param, 0);
@@ -366,7 +365,7 @@ public class ShaderUtil {
verboseOut.println("createAndCompileShader: CompileShader failed, GL Error: 0x"+Integer.toHexString(err));
}
- return isShaderStatusValid(gl, shader, gl.GL_COMPILE_STATUS, verboseOut) && err == GL.GL_NO_ERROR;
+ return isShaderStatusValid(gl, shader, GL2ES2.GL_COMPILE_STATUS, verboseOut) && err == GL.GL_NO_ERROR;
}
}
@@ -411,7 +410,7 @@ public class ShaderUtil {
getImpl(gl).createShader(gl, type, shaders);
}
- public static Set getShaderBinaryFormats(GL gl) {
+ public static Set<Integer> getShaderBinaryFormats(GL gl) {
return getImpl(gl).getShaderBinaryFormats(gl);
}